OpenProject is the leading open source project management software.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
openproject/app/assets/javascripts/vendor/ckeditor/ckeditor.js.map

1 lines
4.2 MiB

{"version":3,"sources":["webpack://OPEditor/webpack/universalModuleDefinition","webpack://OPEditor/webpack/bootstrap","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/ckeditorerror.js","webpack://OPEditor/./node_modules/style-loader/lib/addStyles.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/log.js","webpack://OPEditor/./node_modules/markdown-it/lib/common/utils.js","webpack://OPEditor/./node_modules/lodash-es/_root.js","webpack://OPEditor/./node_modules/lodash-es/_nodeUtil.js","webpack://OPEditor/./node_modules/lodash-es/isBuffer.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/version.js","webpack://OPEditor/./node_modules/lodash-es/_freeGlobal.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/node_modules/@ckeditor/ckeditor5-core/theme/icons/object-right.svg","webpack://OPEditor/(webpack)/buildin/global.js","webpack://OPEditor/(webpack)/buildin/harmony-module.js","webpack://OPEditor/./node_modules/uc.micro/categories/P/regex.js","webpack://OPEditor/./node_modules/markdown-it/lib/ruler.js","webpack://OPEditor/./node_modules/markdown-it/lib/token.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/node_modules/@ckeditor/ckeditor5-core/theme/icons/object-full-width.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/node_modules/@ckeditor/ckeditor5-core/theme/icons/object-left.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/node_modules/@ckeditor/ckeditor5-core/theme/icons/object-center.svg","webpack://OPEditor/./src/icons/source.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/theme/code.css?0e59","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-heading/theme/heading.css?a27e","webpack://OPEditor/./node_modules/markdown-it/lib/common/entities.js","webpack://OPEditor/./node_modules/mdurl/index.js","webpack://OPEditor/./node_modules/uc.micro/properties/Any/regex.js","webpack://OPEditor/./node_modules/uc.micro/categories/Cc/regex.js","webpack://OPEditor/./node_modules/uc.micro/categories/Z/regex.js","webpack://OPEditor/./node_modules/markdown-it/lib/common/html_re.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_inline/strikethrough.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_inline/emphasis.js","webpack://OPEditor/./node_modules/lodash-es/stubFalse.js","webpack://OPEditor/./node_modules/lodash-es/_cloneBuffer.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-widget/theme/icons/drag-handler.svg","webpack://OPEditor/./src/icons/edit.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/node_modules/@ckeditor/ckeditor5-core/theme/icons/image.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/theme/icons/image_placeholder.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-undo/theme/icons/undo.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-undo/theme/icons/redo.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/bold.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/code.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/strikethrough.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/italic.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-block-quote/node_modules/@ckeditor/ckeditor5-core/theme/icons/quote.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/icons/dropdown-arrow.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/node_modules/@ckeditor/ckeditor5-core/theme/icons/check.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/node_modules/@ckeditor/ckeditor5-core/theme/icons/cancel.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/node_modules/@ckeditor/ckeditor5-core/theme/icons/low-vision.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/node_modules/@ckeditor/ckeditor5-core/theme/icons/check.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/node_modules/@ckeditor/ckeditor5-core/theme/icons/cancel.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/theme/icons/unlink.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/node_modules/@ckeditor/ckeditor5-core/theme/icons/pencil.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/theme/icons/link.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-list/theme/icons/numberedlist.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-list/theme/icons/bulletedlist.svg","webpack://OPEditor/./src/icons/help.svg","webpack://OPEditor/./src/icons/code-block.svg","webpack://OPEditor/./src/icons/preview.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/theme/icons/table.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/theme/icons/table-column.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/theme/icons/table-row.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/theme/icons/table-merge-cell.svg","webpack://OPEditor/./src/icons/wysiwyg.svg","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/theme/placeholder.css?66af","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/theme/placeholder.css","webpack://OPEditor/./node_modules/style-loader/lib/urls.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/globals/globals.css?1f37","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/globals/globals.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/editorui/editorui.css?0a5d","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/editorui/editorui.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/label/label.css?9c0f","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/label/label.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/panel/stickypanel.css?0caa","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/panel/stickypanel.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/toolbar/toolbar.css?8b79","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/toolbar/toolbar.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-editor-classic/theme/classiceditor.css?73ea","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-editor-classic/theme/classiceditor.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/icon/icon.css?8bf2","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/icon/icon.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/tooltip/tooltip.css?5a2e","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/tooltip/tooltip.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/button/button.css?d6ed","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/button/button.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-widget/theme/widget.css?7391","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-widget/theme/widget.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/panel/balloonpanel.css?31d4","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/panel/balloonpanel.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/theme/imageuploadprogress.css?8d37","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/theme/imageuploadprogress.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/theme/imageuploadicon.css?3de7","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/theme/imageuploadicon.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/theme/imageuploadloader.css?d654","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/theme/imageuploadloader.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/theme/code.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-block-quote/theme/blockquote.css?d156","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-block-quote/theme/blockquote.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/dropdown/dropdown.css?d866","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/dropdown/dropdown.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/list/list.css?2849","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/list/list.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/button/switchbutton.css?fa6e","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/button/switchbutton.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/dropdown/toolbardropdown.css?dcf3","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/dropdown/toolbardropdown.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/dropdown/listdropdown.css?dc17","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/dropdown/listdropdown.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-heading/theme/heading.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/labeledinput/labeledinput.css?2c3d","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/labeledinput/labeledinput.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/inputtext/inputtext.css?3d59","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/theme/components/inputtext/inputtext.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/theme/textalternativeform.css?5c5d","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/theme/textalternativeform.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/theme/image.css?89fc","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/theme/image.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/theme/imagecaption.css?3c32","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/theme/imagecaption.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/theme/imagestyle.css?0777","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/theme/imagestyle.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/theme/link.css?2fc5","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/theme/link.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/theme/linkform.css?1bc3","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/theme/linkform.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/theme/linkactions.css?478c","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/theme/linkactions.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/theme/tableediting.css?4664","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/theme/tableediting.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/theme/inserttable.css?acc3","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/theme/inserttable.css","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/theme/table.css?95e1","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/theme/table.css","webpack://OPEditor/./node_modules/markdown-it/index.js","webpack://OPEditor/./node_modules/markdown-it/lib/index.js","webpack://OPEditor/./node_modules/mdurl/encode.js","webpack://OPEditor/./node_modules/mdurl/decode.js","webpack://OPEditor/./node_modules/mdurl/format.js","webpack://OPEditor/./node_modules/mdurl/parse.js","webpack://OPEditor/./node_modules/uc.micro/index.js","webpack://OPEditor/./node_modules/uc.micro/categories/Cf/regex.js","webpack://OPEditor/./node_modules/markdown-it/lib/helpers/index.js","webpack://OPEditor/./node_modules/markdown-it/lib/helpers/parse_link_label.js","webpack://OPEditor/./node_modules/markdown-it/lib/helpers/parse_link_destination.js","webpack://OPEditor/./node_modules/markdown-it/lib/helpers/parse_link_title.js","webpack://OPEditor/./node_modules/markdown-it/lib/renderer.js","webpack://OPEditor/./node_modules/markdown-it/lib/parser_core.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_core/normalize.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_core/block.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_core/inline.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_core/linkify.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_core/replacements.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_core/smartquotes.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_core/state_core.js","webpack://OPEditor/./node_modules/markdown-it/lib/parser_block.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_block/table.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_block/code.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_block/fence.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_block/blockquote.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_block/hr.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_block/list.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_block/reference.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_block/heading.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_block/lheading.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_block/html_block.js","webpack://OPEditor/./node_modules/markdown-it/lib/common/html_blocks.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_block/paragraph.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_block/state_block.js","webpack://OPEditor/./node_modules/markdown-it/lib/parser_inline.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_inline/text.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_inline/newline.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_inline/escape.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_inline/backticks.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_inline/link.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_inline/image.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_inline/autolink.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_inline/html_inline.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_inline/entity.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_inline/balance_pairs.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_inline/text_collapse.js","webpack://OPEditor/./node_modules/markdown-it/lib/rules_inline/state_inline.js","webpack://OPEditor/./node_modules/linkify-it/index.js","webpack://OPEditor/./node_modules/linkify-it/lib/re.js","webpack://OPEditor/./node_modules/node-libs-browser/node_modules/punycode/punycode.js","webpack://OPEditor/(webpack)/buildin/module.js","webpack://OPEditor/./node_modules/markdown-it/lib/presets/default.js","webpack://OPEditor/./node_modules/markdown-it/lib/presets/zero.js","webpack://OPEditor/./node_modules/markdown-it/lib/presets/commonmark.js","webpack://OPEditor/./forked/ckeditor5-mention/theme/mentionui.css?ad14","webpack://OPEditor/./forked/ckeditor5-mention/theme/mentionui.css","webpack://OPEditor/./forked/ckeditor5-mention/theme/mention.css?2457","webpack://OPEditor/./forked/ckeditor5-mention/theme/mention.css","webpack://OPEditor/./node_modules/lodash-es/_Symbol.js","webpack://OPEditor/./node_modules/lodash-es/_getRawTag.js","webpack://OPEditor/./node_modules/lodash-es/_objectToString.js","webpack://OPEditor/./node_modules/lodash-es/_baseGetTag.js","webpack://OPEditor/./node_modules/lodash-es/_overArg.js","webpack://OPEditor/./node_modules/lodash-es/_getPrototype.js","webpack://OPEditor/./node_modules/lodash-es/isObjectLike.js","webpack://OPEditor/./node_modules/lodash-es/isPlainObject.js","webpack://OPEditor/./node_modules/lodash-es/_listCacheClear.js","webpack://OPEditor/./node_modules/lodash-es/eq.js","webpack://OPEditor/./node_modules/lodash-es/_assocIndexOf.js","webpack://OPEditor/./node_modules/lodash-es/_listCacheDelete.js","webpack://OPEditor/./node_modules/lodash-es/_listCacheGet.js","webpack://OPEditor/./node_modules/lodash-es/_listCacheHas.js","webpack://OPEditor/./node_modules/lodash-es/_listCacheSet.js","webpack://OPEditor/./node_modules/lodash-es/_ListCache.js","webpack://OPEditor/./node_modules/lodash-es/_stackClear.js","webpack://OPEditor/./node_modules/lodash-es/_stackDelete.js","webpack://OPEditor/./node_modules/lodash-es/_stackGet.js","webpack://OPEditor/./node_modules/lodash-es/_stackHas.js","webpack://OPEditor/./node_modules/lodash-es/isObject.js","webpack://OPEditor/./node_modules/lodash-es/isFunction.js","webpack://OPEditor/./node_modules/lodash-es/_coreJsData.js","webpack://OPEditor/./node_modules/lodash-es/_isMasked.js","webpack://OPEditor/./node_modules/lodash-es/_toSource.js","webpack://OPEditor/./node_modules/lodash-es/_baseIsNative.js","webpack://OPEditor/./node_modules/lodash-es/_getValue.js","webpack://OPEditor/./node_modules/lodash-es/_getNative.js","webpack://OPEditor/./node_modules/lodash-es/_Map.js","webpack://OPEditor/./node_modules/lodash-es/_nativeCreate.js","webpack://OPEditor/./node_modules/lodash-es/_hashClear.js","webpack://OPEditor/./node_modules/lodash-es/_hashDelete.js","webpack://OPEditor/./node_modules/lodash-es/_hashGet.js","webpack://OPEditor/./node_modules/lodash-es/_hashHas.js","webpack://OPEditor/./node_modules/lodash-es/_hashSet.js","webpack://OPEditor/./node_modules/lodash-es/_Hash.js","webpack://OPEditor/./node_modules/lodash-es/_mapCacheClear.js","webpack://OPEditor/./node_modules/lodash-es/_isKeyable.js","webpack://OPEditor/./node_modules/lodash-es/_getMapData.js","webpack://OPEditor/./node_modules/lodash-es/_mapCacheDelete.js","webpack://OPEditor/./node_modules/lodash-es/_mapCacheGet.js","webpack://OPEditor/./node_modules/lodash-es/_mapCacheHas.js","webpack://OPEditor/./node_modules/lodash-es/_mapCacheSet.js","webpack://OPEditor/./node_modules/lodash-es/_MapCache.js","webpack://OPEditor/./node_modules/lodash-es/_stackSet.js","webpack://OPEditor/./node_modules/lodash-es/_Stack.js","webpack://OPEditor/./node_modules/lodash-es/_arrayEach.js","webpack://OPEditor/./node_modules/lodash-es/_defineProperty.js","webpack://OPEditor/./node_modules/lodash-es/_baseAssignValue.js","webpack://OPEditor/./node_modules/lodash-es/_assignValue.js","webpack://OPEditor/./node_modules/lodash-es/_copyObject.js","webpack://OPEditor/./node_modules/lodash-es/_baseTimes.js","webpack://OPEditor/./node_modules/lodash-es/_baseIsArguments.js","webpack://OPEditor/./node_modules/lodash-es/isArguments.js","webpack://OPEditor/./node_modules/lodash-es/isArray.js","webpack://OPEditor/./node_modules/lodash-es/_isIndex.js","webpack://OPEditor/./node_modules/lodash-es/isLength.js","webpack://OPEditor/./node_modules/lodash-es/_baseIsTypedArray.js","webpack://OPEditor/./node_modules/lodash-es/_baseUnary.js","webpack://OPEditor/./node_modules/lodash-es/isTypedArray.js","webpack://OPEditor/./node_modules/lodash-es/_arrayLikeKeys.js","webpack://OPEditor/./node_modules/lodash-es/_isPrototype.js","webpack://OPEditor/./node_modules/lodash-es/_nativeKeys.js","webpack://OPEditor/./node_modules/lodash-es/_baseKeys.js","webpack://OPEditor/./node_modules/lodash-es/isArrayLike.js","webpack://OPEditor/./node_modules/lodash-es/keys.js","webpack://OPEditor/./node_modules/lodash-es/_baseAssign.js","webpack://OPEditor/./node_modules/lodash-es/_nativeKeysIn.js","webpack://OPEditor/./node_modules/lodash-es/_baseKeysIn.js","webpack://OPEditor/./node_modules/lodash-es/keysIn.js","webpack://OPEditor/./node_modules/lodash-es/_baseAssignIn.js","webpack://OPEditor/./node_modules/lodash-es/_copyArray.js","webpack://OPEditor/./node_modules/lodash-es/_arrayFilter.js","webpack://OPEditor/./node_modules/lodash-es/stubArray.js","webpack://OPEditor/./node_modules/lodash-es/_getSymbols.js","webpack://OPEditor/./node_modules/lodash-es/_copySymbols.js","webpack://OPEditor/./node_modules/lodash-es/_arrayPush.js","webpack://OPEditor/./node_modules/lodash-es/_getSymbolsIn.js","webpack://OPEditor/./node_modules/lodash-es/_copySymbolsIn.js","webpack://OPEditor/./node_modules/lodash-es/_baseGetAllKeys.js","webpack://OPEditor/./node_modules/lodash-es/_getAllKeys.js","webpack://OPEditor/./node_modules/lodash-es/_getAllKeysIn.js","webpack://OPEditor/./node_modules/lodash-es/_DataView.js","webpack://OPEditor/./node_modules/lodash-es/_Promise.js","webpack://OPEditor/./node_modules/lodash-es/_Set.js","webpack://OPEditor/./node_modules/lodash-es/_WeakMap.js","webpack://OPEditor/./node_modules/lodash-es/_getTag.js","webpack://OPEditor/./node_modules/lodash-es/_initCloneArray.js","webpack://OPEditor/./node_modules/lodash-es/_Uint8Array.js","webpack://OPEditor/./node_modules/lodash-es/_cloneArrayBuffer.js","webpack://OPEditor/./node_modules/lodash-es/_cloneDataView.js","webpack://OPEditor/./node_modules/lodash-es/_cloneRegExp.js","webpack://OPEditor/./node_modules/lodash-es/_cloneSymbol.js","webpack://OPEditor/./node_modules/lodash-es/_cloneTypedArray.js","webpack://OPEditor/./node_modules/lodash-es/_initCloneByTag.js","webpack://OPEditor/./node_modules/lodash-es/_baseCreate.js","webpack://OPEditor/./node_modules/lodash-es/_initCloneObject.js","webpack://OPEditor/./node_modules/lodash-es/_baseIsMap.js","webpack://OPEditor/./node_modules/lodash-es/isMap.js","webpack://OPEditor/./node_modules/lodash-es/_baseIsSet.js","webpack://OPEditor/./node_modules/lodash-es/isSet.js","webpack://OPEditor/./node_modules/lodash-es/_baseClone.js","webpack://OPEditor/./node_modules/lodash-es/cloneDeepWith.js","webpack://OPEditor/./node_modules/lodash-es/isElement.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/config.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/spy.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/eventinfo.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/uid.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/priorities.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/emittermixin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/mix.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/comparearrays.js","webpack://OPEditor/./node_modules/lodash-es/clone.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/node.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/text.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/textproxy.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/objecttomap.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/isiterable.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/matcher.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/element.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/containerelement.js","webpack://OPEditor/./node_modules/lodash-es/identity.js","webpack://OPEditor/./node_modules/lodash-es/_apply.js","webpack://OPEditor/./node_modules/lodash-es/_overRest.js","webpack://OPEditor/./node_modules/lodash-es/constant.js","webpack://OPEditor/./node_modules/lodash-es/_baseSetToString.js","webpack://OPEditor/./node_modules/lodash-es/_shortOut.js","webpack://OPEditor/./node_modules/lodash-es/_setToString.js","webpack://OPEditor/./node_modules/lodash-es/_baseRest.js","webpack://OPEditor/./node_modules/lodash-es/_isIterateeCall.js","webpack://OPEditor/./node_modules/lodash-es/_createAssigner.js","webpack://OPEditor/./node_modules/lodash-es/assignIn.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/observablemixin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/editableelement.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/rooteditableelement.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/treewalker.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/position.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/range.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/count.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/selection.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/documentselection.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/collection.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/document.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/attributeelement.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/emptyelement.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/env.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/keyboard.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/uielement.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/documentfragment.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/downcastwriter.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/istext.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/filler.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/fastdiff.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/diff.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/insertat.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/remove.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/isnode.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/renderer.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/global.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/indexof.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/getancestors.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/domconverter.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/getcommonancestor.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/iswindow.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/emittermixin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/observer.js","webpack://OPEditor/./node_modules/lodash-es/_setCacheAdd.js","webpack://OPEditor/./node_modules/lodash-es/_setCacheHas.js","webpack://OPEditor/./node_modules/lodash-es/_SetCache.js","webpack://OPEditor/./node_modules/lodash-es/_arraySome.js","webpack://OPEditor/./node_modules/lodash-es/_cacheHas.js","webpack://OPEditor/./node_modules/lodash-es/_equalArrays.js","webpack://OPEditor/./node_modules/lodash-es/_mapToArray.js","webpack://OPEditor/./node_modules/lodash-es/_setToArray.js","webpack://OPEditor/./node_modules/lodash-es/_equalByTag.js","webpack://OPEditor/./node_modules/lodash-es/_equalObjects.js","webpack://OPEditor/./node_modules/lodash-es/_baseIsEqualDeep.js","webpack://OPEditor/./node_modules/lodash-es/_baseIsEqual.js","webpack://OPEditor/./node_modules/lodash-es/isEqualWith.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/mutationobserver.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/domeventdata.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/domeventobserver.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/keyobserver.js","webpack://OPEditor/./node_modules/lodash-es/now.js","webpack://OPEditor/./node_modules/lodash-es/isSymbol.js","webpack://OPEditor/./node_modules/lodash-es/toNumber.js","webpack://OPEditor/./node_modules/lodash-es/debounce.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/fakeselectionobserver.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/selectionobserver.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/focusobserver.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/compositionobserver.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/isrange.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/getborderwidths.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/rect.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/scroll.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/view.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/tomap.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/node.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/text.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/textproxy.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/nodelist.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/element.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/treewalker.js","webpack://OPEditor/./node_modules/lodash-es/last.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/position.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/range.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/conversion/mapper.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/conversion/modelconsumable.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/conversion/downcastdispatcher.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/selection.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/liverange.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/documentselection.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/conversion/conversionhelpers.js","webpack://OPEditor/./node_modules/lodash-es/cloneDeep.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/conversion/downcasthelpers.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/conversion/upcasthelpers.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/controller/editingcontroller.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-editor-classic/node_modules/@ckeditor/ckeditor5-core/src/plugincollection.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-editor-classic/node_modules/@ckeditor/ckeditor5-core/src/commandcollection.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/translation-service.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/locale.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/conversion/viewconsumable.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/schema.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/conversion/upcastdispatcher.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/controller/datacontroller.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/conversion/conversion.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/batch.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/operation.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/documentfragment.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/utils.js","webpack://OPEditor/./node_modules/lodash-es/isEqual.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/attributeoperation.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/detachoperation.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/moveoperation.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/insertoperation.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/markeroperation.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/renameoperation.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/rootattributeoperation.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/mergeoperation.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/splitoperation.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/rootelement.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/writer.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/differ.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/history.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/unicode.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/document.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/markercollection.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/liveposition.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/utils/insertcontent.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/utils/deletecontent.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/utils/modifyselection.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/utils/getselectedcontent.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/utils/selection-post-fixer.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/model.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/keystrokehandler.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-editor-classic/node_modules/@ckeditor/ckeditor5-core/src/editingkeystrokehandler.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-editor-classic/node_modules/@ckeditor/ckeditor5-core/src/editor/editor.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-editor-classic/node_modules/@ckeditor/ckeditor5-core/src/editor/utils/dataapimixin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-editor-classic/node_modules/@ckeditor/ckeditor5-core/src/editor/utils/elementapimixin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/setdatainelement.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/dataprocessor/basichtmlwriter.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/componentfactory.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/focustracker.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-editor-classic/node_modules/@ckeditor/ckeditor5-core/src/editor/editorui.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/placeholder.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/elementreplacer.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-editor-classic/src/classiceditorui.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/toolbar/normalizetoolbarconfig.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/toolbar/enabletoolbarkeyboardfocus.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/viewcollection.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/template.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/view.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/editorui/editoruiview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/label/labelview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/editorui/boxed/boxededitoruiview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/editableui/editableuiview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/editableui/inline/inlineeditableuiview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/tounit.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/panel/sticky/stickypanelview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/focuscycler.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/toolbar/toolbarseparatorview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/toolbar/toolbarview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/bindings/preventdefault.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-editor-classic/src/classiceditoruiview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-editor-classic/src/classiceditor.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-editor-classic/node_modules/@ckeditor/ckeditor5-core/src/editor/utils/attachtoform.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/getdatafromelement.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/icon/iconview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/tooltip/tooltipview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/button/buttonview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-core/node_modules/@ckeditor/ckeditor5-utils/src/spy.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-core/node_modules/@ckeditor/ckeditor5-utils/src/eventinfo.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-core/node_modules/@ckeditor/ckeditor5-utils/src/priorities.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-core/node_modules/@ckeditor/ckeditor5-utils/src/emittermixin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-core/node_modules/@ckeditor/ckeditor5-utils/src/uid.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-core/node_modules/@ckeditor/ckeditor5-utils/src/ckeditorerror.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-core/node_modules/@ckeditor/ckeditor5-utils/src/observablemixin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-core/node_modules/@ckeditor/ckeditor5-utils/src/mix.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-widget/src/highlightstack.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-widget/src/utils.js","webpack://OPEditor/./src/plugins/op-macro-toc-plugin.js","webpack://OPEditor/./src/plugins/op-macro-embedded-table/utils.js","webpack://OPEditor/./src/plugins/op-context/op-context.js","webpack://OPEditor/./src/plugins/op-macro-embedded-table/embedded-table-editing.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-widget/node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/mouseobserver.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-widget/src/widget.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/position.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/dom/getpositionedancestor.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/panel/balloon/balloonpanelview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon.js","webpack://OPEditor/./src/helpers/create-toolbar-edit-button.js","webpack://OPEditor/./src/helpers/create-toolbar.js","webpack://OPEditor/./src/plugins/op-macro-embedded-table/embedded-table-toolbar.js","webpack://OPEditor/./src/plugins/op-macro-wp-button/utils.js","webpack://OPEditor/./src/plugins/op-macro-wp-button/op-macro-wp-button-editing.js","webpack://OPEditor/./src/plugins/op-macro-wp-button/op-macro-wp-button-toolbar.js","webpack://OPEditor/./src/plugins/op-macro-wiki-include/utils.js","webpack://OPEditor/./src/plugins/op-macro-wiki-include/op-macro-wiki-include-editing.js","webpack://OPEditor/./src/plugins/op-macro-wiki-include/op-macro-wiki-include-toolbar.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-upload/node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-upload/node_modules/@ckeditor/ckeditor5-core/src/pendingactions.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-upload/src/filereader.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-upload/src/filerepository.js","webpack://OPEditor/./src/plugins/op-upload-resource-adapter.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-upload/src/ui/filedialogbuttonview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imageupload/utils.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imageupload/imageuploadui.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imageupload/imageuploadprogress.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/notification/notification.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/upcastwriter.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/node_modules/@ckeditor/ckeditor5-core/src/command.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/image/utils.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imageupload/imageuploadcommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imageupload/imageuploadediting.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imageupload.js","webpack://OPEditor/./src/plugins/op-macro-child-pages/utils.js","webpack://OPEditor/./src/plugins/op-macro-child-pages/op-macro-child-pages-editing.js","webpack://OPEditor/./src/plugins/op-macro-child-pages/op-macro-child-pages-toolbar.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-essentials/node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-clipboard/node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-clipboard/src/datatransfer.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardobserver.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/viewtoplaintext.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboard.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/normalizeclipboarddata.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/plaintexttohtml.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-enter/node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-enter/node_modules/@ckeditor/ckeditor5-core/src/command.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-enter/src/entercommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-enter/src/enterobserver.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-enter/src/enter.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-enter/src/shiftentercommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-enter/src/shiftenter.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-typing/node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-typing/node_modules/@ckeditor/ckeditor5-core/src/command.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-typing/src/utils/changebuffer.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-typing/src/inputcommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-typing/src/utils/injectunsafekeystrokeshandling.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-typing/src/utils/utils.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/difftochanges.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-typing/src/utils/injecttypingmutationshandling.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-typing/src/input.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-typing/src/deletecommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-typing/src/deleteobserver.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-typing/src/utils/injectandroidbackspacemutationshandling.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-typing/src/delete.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-typing/src/typing.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-undo/node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-undo/node_modules/@ckeditor/ckeditor5-core/src/command.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/nooperation.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/model/operation/transform.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-undo/src/basecommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-undo/src/undocommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-undo/src/redocommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-undo/src/undoediting.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-undo/src/undoui.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-undo/src/undo.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/utils.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-autoformat/src/blockautoformatediting.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-autoformat/src/inlineautoformatediting.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-autoformat/node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-autoformat/src/autoformat.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/node_modules/@ckeditor/ckeditor5-core/src/command.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldediting.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldui.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/src/code/codeediting.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/src/code/codeui.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughediting.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughui.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicediting.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicui.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-block-quote/node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-block-quote/node_modules/@ckeditor/ckeditor5-core/src/command.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-utils/src/first.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquotecommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteediting.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteui.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-heading/node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-paragraph/node_modules/@ckeditor/ckeditor5-core/src/command.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-paragraph/src/paragraphcommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-paragraph/node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-paragraph/src/paragraph.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-heading/node_modules/@ckeditor/ckeditor5-core/src/command.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-heading/src/headingcommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-heading/src/headingediting.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/model.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/dropdown/dropdownpanelview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/dropdown/dropdownview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/dropdown/button/dropdownbuttonview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/list/listview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/list/listitemview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/list/listseparatorview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/button/switchbuttonview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/bindings/clickoutsidehandler.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/dropdown/utils.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-heading/src/headingui.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-heading/src/utils.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/image/imageloadobserver.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/image/converters.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/image/imageinsertcommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/image/imageediting.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/imagetextalternativecommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/imagetextalternativeediting.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/labeledinput/labeledinputview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/inputtext/inputtextview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-ui/src/bindings/submithandler.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/ui/textalternativeformview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/image/ui/utils.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/imagetextalternativeui.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imagecaption/utils.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imagecaption/imagecaptionediting.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imagestyle/imagestylecommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imagestyle/converters.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imagestyle/utils.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imagestyle/imagestyleediting.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imagestyle/imagestyleui.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-widget/src/widgettoolbarrepository.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/node_modules/@ckeditor/ckeditor5-core/src/command.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/src/findlinkrange.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/src/linkcommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/src/unlinkcommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/src/utils.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/utils/bindtwostepcarettoattribute.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/src/linkediting.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/clickobserver.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/src/ui/linkformview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/src/ui/linkactionsview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/src/linkui.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-list/node_modules/@ckeditor/ckeditor5-core/src/command.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-list/src/listcommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-list/src/indentcommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-list/node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-list/src/utils.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-list/src/converters.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-list/src/listediting.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-list/src/listui.js","webpack://OPEditor/./src/plugins/code-block/widget.js","webpack://OPEditor/./src/plugins/code-block/click-observer.js","webpack://OPEditor/./src/plugins/code-block/code-block-editing.js","webpack://OPEditor/./src/plugins/code-block/converters.js","webpack://OPEditor/./src/plugins/code-block/code-block-toolbar.js","webpack://OPEditor/./src/helpers/button-disabler.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/node_modules/@ckeditor/ckeditor5-core/src/plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/commands/utils.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/converters/upcasttable.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/tablewalker.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/utils.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/converters/downcast.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/node_modules/@ckeditor/ckeditor5-core/src/command.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/commands/inserttablecommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/commands/insertrowcommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/commands/insertcolumncommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/commands/splitcellcommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/commands/mergecellcommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/commands/removerowcommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/commands/removecolumncommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/commands/setheaderrowcommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/commands/setheadercolumncommand.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/tableutils.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/converters/table-layout-post-fixer.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/converters/table-cell-content-post-fixer.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/converters/tablecell-post-fixer.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/tableediting.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/ui/inserttableview.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/tableui.js","webpack://OPEditor/./node_modules/turndown-plugin-gfm/lib/turndown-plugin-gfm.es.js","webpack://OPEditor/./node_modules/turndown/lib/turndown.es.js","webpack://OPEditor/./src/commonmark/utils/preprocessor.js","webpack://OPEditor/./src/commonmark/commonmarkdataprocessor.js","webpack://OPEditor/./src/commonmark/utils/paragraph-in-lists.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-core/src/command.js","webpack://OPEditor/./forked/ckeditor5-mention/src/mentioncommand.js","webpack://OPEditor/./forked/ckeditor5-mention/src/mentionediting.js","webpack://OPEditor/./forked/ckeditor5-mention/src/textwatcher.js","webpack://OPEditor/./forked/ckeditor5-mention/src/ui/mentionsview.js","webpack://OPEditor/./forked/ckeditor5-mention/src/ui/domwrapperview.js","webpack://OPEditor/./forked/ckeditor5-mention/src/ui/mentionlistitemview.js","webpack://OPEditor/./forked/ckeditor5-mention/src/mentionui.js","webpack://OPEditor/./src/op-plugins.js","webpack://OPEditor/./src/plugins/op-macro-embedded-table/embedded-table-plugin.js","webpack://OPEditor/./src/plugins/op-macro-wp-button/op-macro-wp-button-plugin.js","webpack://OPEditor/./src/plugins/op-macro-wiki-include/op-macro-wiki-include-plugin.js","webpack://OPEditor/./src/plugins/op-macro-child-pages/op-macro-child-pages-plugin.js","webpack://OPEditor/./src/plugins/op-upload-plugin.js","webpack://OPEditor/./src/plugins/op-attachment-listener-plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-essentials/src/essentials.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/src/code.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquote.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-heading/src/heading.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/image.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imagecaption.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imagestyle.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-image/src/imagetoolbar.js","webpack://OPEditor/./src/plugins/op-image-attachment-lookup/op-image-attachment-lookup-plugin.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-link/src/link.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-list/src/list.js","webpack://OPEditor/./forked/ckeditor5-mention/src/mention.js","webpack://OPEditor/./src/mentions/mentions-caster.js","webpack://OPEditor/./src/plugins/op-help-link-plugin/op-help-link-plugin.js","webpack://OPEditor/./src/plugins/code-block/code-block.js","webpack://OPEditor/./src/plugins/op-preview.plugin.js","webpack://OPEditor/./src/plugins/op-source-code.plugin.js","webpack://OPEditor/./src/commonmark/commonmark.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/table.js","webpack://OPEditor/./node_modules/@ckeditor/ckeditor5-table/src/tabletoolbar.js","webpack://OPEditor/./src/plugins/op-macro-list-plugin.js","webpack://OPEditor/./src/op-config-customizer.js","webpack://OPEditor/./src/mentions/mentions-item-renderer.js","webpack://OPEditor/./src/op-ckeditor-config.js","webpack://OPEditor/./src/mentions/user-mentions.js","webpack://OPEditor/./src/mentions/work-package-mentions.js","webpack://OPEditor/./src/op-ckeditor.js"],"names":["root","factory","exports","module","define","amd","window","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","__webpack_exports__","CKEditorError","attachLinkToDocumentation","DOCUMENTATION_URL","Error","[object Object]","message","data","JSON","stringify","super","this","error","matchedErrorName","match","stylesInDom","isOldIE","fn","memo","apply","arguments","memoize","document","all","atob","getElement","target","parent","styleTarget","querySelector","HTMLIFrameElement","contentDocument","head","e","singleton","singletonCounter","stylesInsertedAtTop","fixUrls","addStylesToDom","styles","options","length","item","domStyle","id","refs","j","parts","push","addStyle","listToStyles","list","newStyles","base","part","css","media","sourceMap","insertStyleElement","style","insertInto","lastStyleElementInsertedAtTop","insertAt","nextSibling","insertBefore","appendChild","firstChild","before","removeStyleElement","parentNode","removeChild","idx","indexOf","splice","createStyleElement","createElement","undefined","attrs","type","nonce","nc","getNonce","addAttrs","el","keys","forEach","setAttribute","obj","update","remove","result","transform","default","styleIndex","applyToSingletonTag","URL","createObjectURL","revokeObjectURL","Blob","btoa","link","rel","createLinkElement","autoFixUrls","convertToAbsoluteUrls","unescape","encodeURIComponent","blob","oldSrc","href","styleSheet","cssText","createTextNode","newObj","DEBUG","newList","mayRemove","replaceText","textStore","index","replacement","filter","Boolean","join","cssNode","childNodes","_ckeditorerror__WEBPACK_IMPORTED_MODULE_0__","log","console","warn","_hasOwnProperty","has","isValidEntityCode","fromCodePoint","surrogate1","surrogate2","String","fromCharCode","UNESCAPE_MD_RE","UNESCAPE_ALL_RE","RegExp","source","DIGITAL_ENTITY_TEST_RE","entities","HTML_ESCAPE_TEST_RE","HTML_ESCAPE_REPLACE_RE","HTML_REPLACEMENTS","&","<",">","\"","replaceUnsafeChar","ch","REGEXP_ESCAPE_RE","UNICODE_PUNCT_RE","lib","mdurl","ucmicro","assign","Array","slice","TypeError","isString","toString","_class","unescapeMd","str","replace","unescapeAll","escaped","entity","code","charCodeAt","test","toLowerCase","parseInt","replaceEntityPattern","escapeHtml","arrayReplaceAt","src","pos","newElements","concat","isSpace","isWhiteSpace","isMdAsciiPunct","isPunctChar","escapeRE","normalizeReference","trim","toUpperCase","_freeGlobal_js__WEBPACK_IMPORTED_MODULE_0__","freeSelf","self","Function","freeExports","nodeType","freeModule","freeProcess","process","nodeUtil","types","require","binding","_root_js__WEBPACK_IMPORTED_MODULE_0__","_stubFalse_js__WEBPACK_IMPORTED_MODULE_1__","Buffer","isBuffer","global","_log__WEBPACK_IMPORTED_MODULE_0__","ckeditor5_package_json__WEBPACK_IMPORTED_MODULE_1__","windowOrGlobal","CKEDITOR_VERSION","freeGlobal","g","originalModule","webpackPolyfill","children","Ruler","__rules__","__cache__","__find__","__compile__","chains","rule","enabled","alt","altName","chain","at","opt","beforeName","ruleName","after","afterName","enable","ignoreInvalid","isArray","enableOnly","disable","getRules","chainName","Token","tag","nesting","map","level","content","markup","info","meta","block","hidden","attrIndex","len","attrPush","attrData","attrSet","attrGet","attrJoin","hmr","locals","encode","decode","format","parse","open_tag","close_tag","HTML_TAG_RE","HTML_OPEN_CLOSE_TAG_RE","tokenize","state","silent","scanned","start","marker","scanDelims","delimiters","jump","token","tokens","end","open","can_open","close","can_close","postProcess","startDelim","endDelim","loneMarkers","max","pop","isStrong","allocUnsafe","buffer","isDeep","constructor","copy","location","baseUrl","protocol","host","currentDir","pathname","fullMatch","origUrl","newUrl","unquotedOrigUrl","$1","utils","helpers","Renderer","ParserCore","ParserBlock","ParserInline","LinkifyIt","punycode","config","zero","commonmark","BAD_PROTO_RE","GOOD_DATA_RE","validateLink","url","RECODE_HOSTNAME_FOR","normalizeLink","parsed","hostname","toASCII","er","normalizeLinkText","toUnicode","MarkdownIt","presetName","inline","core","renderer","linkify","configure","set","presets","components","rules","ruler","rules2","ruler2","missed","use","plugin","args","env","State","render","parseInline","inlineMode","renderInline","encodeCache","string","exclude","keepEscaped","nextCode","cache","defaultChars","getEncodeCache","componentChars","decodeCache","getDecodeCache","seq","b1","b2","b3","b4","chr","slashes","auth","port","search","hash","Url","protocolPattern","portPattern","simplePathPattern","unwise","autoEscape","nonHostChars","hostEndingChars","hostnamePartPattern","hostnamePartStart","hostlessProtocol","javascript","javascript:","slashedProtocol","http","https","ftp","gopher","file","http:","https:","ftp:","gopher:","file:","slashesDenoteHost","lowerProto","hec","rest","split","simplePath","exec","proto","substr","atSign","hostEnd","lastIndexOf","parseHost","ipv6Hostname","hostparts","newpart","k","validParts","notHost","bit","unshift","qm","u","Any","Cc","Cf","P","Z","parseLinkLabel","parseLinkDestination","parseLinkTitle","disableNested","found","prevPos","labelEnd","posMax","oldPos","md","skipToken","ok","lines","default_rules","code_inline","slf","renderAttrs","code_block","fence","highlighted","tmpAttrs","tmpToken","langName","highlight","langPrefix","image","renderInlineAsText","renderToken","hardbreak","xhtmlOut","softbreak","breaks","text","html_block","html_inline","nextToken","needLf","_rules","Core","NEWLINES_RE","NULL_RE","tok","isLinkOpen","isLinkClose","currentToken","nodes","ln","lastPos","htmlLinkLevel","fullUrl","urlText","links","blockTokens","pretest","schema","lastIndex","RARE_RE","SCOPED_ABBR_TEST_RE","SCOPED_ABBR_RE","SCOPED_ABBR","tm","replaceFn","replace_scoped","inlineTokens","inside_autolink","replace_rare","blkIdx","typographer","QUOTE_TEST_RE","QUOTE_RE","APOSTROPHE","replaceAt","process_inlines","thisLevel","lastChar","nextChar","isLastPunctChar","isNextPunctChar","isLastWhiteSpace","isNextWhiteSpace","canOpen","canClose","isSingle","stack","openQuote","closeQuote","OUTER","single","quotes","StateCore","startLine","endLine","line","hasEmptyLines","maxNesting","skipEmptyLines","sCount","blkIndent","tight","isEmpty","outTokens","lineMax","getLine","bMarks","eMarks","escapedSplit","escapes","backTicked","lastBackTick","substring","lineText","nextLine","columns","columnCount","aligns","tableLines","tbodyLines","tShift","last","getLines","params","mem","haveEndMarker","skipChars","skipSpaces","adjustTab","initial","lastLineEmpty","offset","oldBMarks","oldBSCount","oldIndent","oldParentType","oldSCount","oldTShift","spaceAfterMarker","terminate","terminatorRules","wasOutdented","oldLineMax","bsCount","parentType","cnt","skipBulletListMarker","skipOrderedListMarker","contentStart","indent","indentAfterMarker","isOrdered","itemLines","listLines","listTokIdx","markerCharCode","markerValue","oldLIndent","oldTight","posAfterMarker","prevEmptyEnd","isTerminatingParagraph","Number","Math","min","markTightParagraphs","_endLine","destEndPos","destEndLineNo","label","res","title","references","tmp","skipSpacesBack","skipCharsBack","block_names","HTML_SEQUENCES","html","StateBlock","indent_found","ddIndent","from","begin","keepLastLF","lineIndent","first","queue","lineStart","_rules2","pending","pushPending","isTerminatorChar","pmax","ESCAPED","matchStart","matchEnd","labelStart","ref","parseReference","EMAIL_RE","AUTOLINK_RE","tail","linkMatch","emailMatch","lc","isLetter","DIGITAL_RE","NAMED_RE","lastDelim","currDelim","curr","StateInline","pendingLevel","canSplitWord","count","left_flanking","right_flanking","isFunction","defaultOptions","fuzzyLink","fuzzyEmail","fuzzyIP","defaultSchemas","validate","re","src_auth","src_host_port_strict","src_path","//","no_http","src_domain","src_domain_root","src_port","src_host_terminator","mailto:","mailto","src_email_name","src_host_strict","tlds_2ch_src_re","tlds_default","compile","__opts__","tlds","__tlds__","untpl","tpl","src_tlds","onCompile","__tlds_replaced__","src_xn","email_fuzzy","tpl_email_fuzzy","link_fuzzy","tpl_link_fuzzy","link_no_ip_fuzzy","tpl_link_no_ip_fuzzy","host_fuzzy_test","tpl_host_fuzzy_test","aliases","schemaError","val","__compiled__","__schemas__","compiled","isObject","isRegExp","createValidator","normalize","alias","slist","schema_test","src_ZPCc","schema_search","__index__","__text_cache__","resetScanCache","createMatch","shift","__last_index__","__schema__","raw","schemas","reduce","acc","isOptionsObj","add","definition","ml","me","next","tld_pos","testSchemaAt","keepOld","sort","arr","reverse","opts","src_Any","src_Cc","src_Z","src_P","src_ZCc","src_pseudo_letter","src_ip4","src_host","tpl_host_fuzzy","tpl_host_no_ip_fuzzy","tpl_host_fuzzy_strict","tpl_host_port_fuzzy_strict","tpl_host_port_no_ip_fuzzy_strict","__WEBPACK_AMD_DEFINE_RESULT__","maxInt","tMin","tMax","skew","damp","initialBias","initialN","delimiter","regexPunycode","regexNonASCII","regexSeparators","errors","overflow","not-basic","invalid-input","baseMinusTMin","floor","stringFromCharCode","RangeError","array","mapDomain","ucs2decode","extra","output","counter","ucs2encode","basicToDigit","codePoint","digitToBasic","digit","flag","adapt","delta","numPoints","firstTime","input","out","basic","oldi","w","baseMinusT","inputLength","bias","handledCPCount","basicLength","q","currentValue","handledCPCountPlusOne","qMinusT","version","ucs2","deprecate","paths","_Symbol","_root","objectProto","_getRawTag_hasOwnProperty","nativeObjectToString","symToStringTag","_getRawTag","isOwn","unmasked","_objectToString_nativeObjectToString","_objectToString","nullTag","undefinedTag","_baseGetTag_symToStringTag","_baseGetTag","_overArg","func","arg","_getPrototype","getPrototypeOf","lodash_es_isObjectLike","objectTag","funcProto","isPlainObject_objectProto","funcToString","isPlainObject_hasOwnProperty","objectCtorString","lodash_es_isPlainObject","Ctor","_listCacheClear","__data__","size","lodash_es_eq","other","_assocIndexOf","_listCacheDelete","_listCacheGet","_listCacheHas","_listCacheSet","ListCache","entries","clear","entry","_ListCache","_stackClear","_stackDelete","_stackGet","_stackHas","lodash_es_isObject","asyncTag","funcTag","genTag","proxyTag","lodash_es_isFunction","_coreJsData","maskSrcKey","uid","IE_PROTO","_isMasked","_toSource_funcToString","_toSource","reIsHostCtor","_baseIsNative_funcProto","_baseIsNative_objectProto","_baseIsNative_funcToString","_baseIsNative_hasOwnProperty","reIsNative","_baseIsNative","_getValue","_getNative","_Map","_nativeCreate","_hashClear","_hashDelete","HASH_UNDEFINED","_hashGet_hasOwnProperty","_hashGet","_hashHas_hasOwnProperty","_hashHas","_hashSet_HASH_UNDEFINED","_hashSet","Hash","_Hash","_mapCacheClear","_isKeyable","_getMapData","_mapCacheDelete","_mapCacheGet","_mapCacheHas","_mapCacheSet","MapCache","_MapCache","LARGE_ARRAY_SIZE","_stackSet","pairs","Stack","_Stack","_arrayEach","iteratee","_defineProperty","_baseAssignValue","configurable","writable","_assignValue_hasOwnProperty","_assignValue","objValue","_copyObject","props","customizer","isNew","newValue","_baseTimes","argsTag","_baseIsArguments","isArguments_objectProto","isArguments_hasOwnProperty","propertyIsEnumerable","lodash_es_isArguments","lodash_es_isArray","MAX_SAFE_INTEGER","reIsUint","_isIndex","isLength_MAX_SAFE_INTEGER","lodash_es_isLength","typedArrayTags","_baseIsTypedArray","_baseUnary","nodeIsTypedArray","_nodeUtil","isTypedArray","lodash_es_isTypedArray","_arrayLikeKeys_hasOwnProperty","_arrayLikeKeys","inherited","isArr","isArg","isBuff","isType","skipIndexes","_isPrototype_objectProto","_isPrototype","_nativeKeys","_baseKeys_hasOwnProperty","_baseKeys","lodash_es_isArrayLike","lodash_es_keys","_baseAssign","_nativeKeysIn","_baseKeysIn_hasOwnProperty","_baseKeysIn","isProto","lodash_es_keysIn","_baseAssignIn","_copyArray","_arrayFilter","predicate","resIndex","lodash_es_stubArray","_getSymbols_propertyIsEnumerable","nativeGetSymbols","getOwnPropertySymbols","_getSymbols","symbol","_copySymbols","_arrayPush","values","_getSymbolsIn","_copySymbolsIn","_baseGetAllKeys","keysFunc","symbolsFunc","_getAllKeys","_getAllKeysIn","_DataView","_Promise","_Set","_WeakMap","dataViewCtorString","mapCtorString","promiseCtorString","setCtorString","weakMapCtorString","getTag","ArrayBuffer","resolve","ctorString","_getTag","_initCloneArray_hasOwnProperty","_initCloneArray","_Uint8Array","Uint8Array","_cloneArrayBuffer","arrayBuffer","byteLength","_cloneDataView","dataView","byteOffset","reFlags","_cloneRegExp","regexp","symbolProto","symbolValueOf","valueOf","_cloneSymbol","_cloneTypedArray","typedArray","_initCloneByTag_boolTag","_initCloneByTag_dateTag","_initCloneByTag_mapTag","_initCloneByTag_numberTag","_initCloneByTag_regexpTag","_initCloneByTag_setTag","_initCloneByTag_stringTag","symbolTag","_initCloneByTag_arrayBufferTag","_initCloneByTag_dataViewTag","_initCloneByTag_float32Tag","_initCloneByTag_float64Tag","_initCloneByTag_int8Tag","_initCloneByTag_int16Tag","_initCloneByTag_int32Tag","_initCloneByTag_uint8Tag","_initCloneByTag_uint8ClampedTag","_initCloneByTag_uint16Tag","_initCloneByTag_uint32Tag","_initCloneByTag","objectCreate","_baseCreate","_initCloneObject","_baseIsMap_mapTag","_baseIsMap","nodeIsMap","isMap","lodash_es_isMap","_baseIsSet_setTag","_baseIsSet","nodeIsSet","isSet","lodash_es_isSet","CLONE_DEEP_FLAG","CLONE_FLAT_FLAG","CLONE_SYMBOLS_FLAG","_baseClone_argsTag","_baseClone_funcTag","_baseClone_genTag","_baseClone_objectTag","cloneableTags","_baseClone","baseClone","bitmask","isFlat","isFull","isFunc","_cloneBuffer","stacked","subValue","keysIn","cloneDeepWith_CLONE_DEEP_FLAG","cloneDeepWith_CLONE_SYMBOLS_FLAG","lodash_es_cloneDeepWith","lodash_es_isElement","config_Config","configurations","defaultConfigurations","_config","_setObjectToTarget","_setToTarget","_getFromSource","isDefine","leaveDOMReferences","cloneConfig","configuration","src_spy","spy","called","eventinfo_EventInfo","path","stop","off","uid_uid","uuid","random","src_priorities","priority","normal","highest","high","low","lowest","_listeningTo","_emitterId","emittermixin","event","callback","listenTo","wasFired","stopListening","emitter","emitterInfo","eventCallbacks","emitters","_getEmitterId","_setEmitterId","emitterId","callbacks","eventName","events","getEvents","childEventName","newEventNodes","childEvents","node","createEventNamespace","lists","getCallbacksListsForNamespace","callbackDefinition","added","removeCallback","eventOrInfo","eventInfo","getCallbacksForEvent","_events","callbackArgs","_delegations","destinations","passAllDestinations","fireDelegatedEvents","return","to","nameOrFunction","Map","delete","eventNode","callbacksLists","childCallbacksLists","fireArgs","delegatedInfo","fire","mix","baseClass","mixins","mixin","getOwnPropertyNames","sourceDescriptor","getOwnPropertyDescriptor","compareArrays","a","b","minLen","clone_CLONE_SYMBOLS_FLAG","lodash_es_clone","node_Node","getChildIndex","ckeditorerror","getChild","previousSibling","includeSelf","parentFirst","ancestors","ancestorsA","getAncestors","ancestorsB","thisPath","getPath","nodePath","isBefore","_removeChildren","_fireChange","json","text_Text","_textData","is","_data","otherNode","textproxy_TextProxy","textNode","offsetInText","offsetSize","isPartial","objectToMap","isIterable","iterator","Matcher","pattern","_patterns","classes","element","singleElement","isElementMatching","results","matchName","attributes","patterns","hasAttribute","attribute","getAttribute","matchAttributes","getClassNames","hasClass","matchClasses","hasStyle","getStyle","matchStyles","element_Element","_attrs","parseAttributes","_children","_insertChild","_classes","Set","classString","parseClasses","_styles","parseInlineStyles","_customProperties","childCount","styleString","otherElement","className","matcher","deep","childrenClone","child","getChildren","_clone","cloned","getFillerOffset","items","_remove","howMany","stylesMap","stylesString","quoteType","propertyNameStart","propertyValueStart","propertyName","charAt","char","propertyValue","classesSet","classesString","classArray","containerelement_ContainerElement","lastChild","lodash_es_identity","_apply","thisArg","nativeMax","_overRest","otherArgs","lodash_es_constant","_baseSetToString","HOT_COUNT","HOT_SPAN","nativeNow","Date","now","_setToString","lastCalled","stamp","remaining","_shortOut","_baseRest","_isIterateeCall","lodash_es_assignIn","assigner","sources","guard","_createAssigner","observablePropertiesSymbol","boundObservablesSymbol","boundPropertiesSymbol","ObservableMixin","initObservable","properties","oldValue","bindProperties","isStringArray","boundProperties","bindings","bindTo","toMany","bindToMany","_observable","_bindProperties","_to","_bindings","unbindProperties","boundObservables","toObservable","toProperty","toProperties","toPropertyBindings","boundObservable","methodName","originalMethod","on","evt","observablemixin","observable","parsedArgs","lastObservable","parseBindToArgs","bindingsKeys","numberOfBindings","toBindings","updateBoundObservableProperty","attachBindToListeners","toPropertyName","bindingsToObservable","updateBoundObservables","updateBindToBound","observables","observableAndAttributePairs","getBindingTargets","every","documentSymbol","editableelement_EditableElement","getCustomProperty","_document","_setCustomProperty","isFocused","selection","editableElement","rootNameSymbol","rooteditableelement_RootEditableElement","rootName","_name","treewalker_TreeWalker","boundaries","startPosition","direction","position","position_Position","_createAt","singleCharacters","shallow","ignoreElementEnd","_boundaryStartParent","_boundaryEndParent","skip","done","prevPosition","_next","_previous","clone","previousPosition","isAtEnd","_createAfter","_formatReturnValue","charactersCount","textLength","textProxy","isAtStart","_createBefore","startOffset","nextPosition","isEqual","nodeAfter","nodeBefore","endOffset","editable","shifted","treeWalker","otherPosition","compareWith","otherPath","itemOrPosition","range_Range","isCollapsed","getLastMatchingPosition","enlargeTrimSkip","isAfter","nodeAfterStart","nodeBeforeEnd","otherRange","loose","containsStart","containsPosition","containsEnd","ranges","isIntersecting","commonRangeStart","commonRangeEnd","getCommonAncestor","startElement","endElement","getShiftedBy","_createFromParentsAndOffsets","_createFromPositionAndShift","count_count","_","selection_Selection","selectable","placeOrOffset","_ranges","_lastRangeBackward","_isFake","_fakeSelectionLabel","setTo","isFake","fakeSelectionLabel","anchor","range","focus","rangeCount","isBackward","firstRange","getFirstRange","lastRange","getLastRange","otherSelection","thisRange","numOfRangesA","getRanges","rangeA","getTrimmed","rangeB","_setRanges","_setFakeOptions","documentselection_DocumentSelection","fake","backward","_createIn","_createOn","newFocus","_addRange","newRanges","isLastBackward","_pushRange","storedRange","addedRange","intersectingRange","_selection","delegate","getFirstPosition","getLastPosition","getSelectedElement","isSimilar","setFocus","collection_Collection","_items","_itemMap","_idProperty","idProperty","_bindToExternalToInternalMap","WeakMap","_bindToInternalToExternalMap","_skippedIndexesFromExternal","itemId","idOrIndex","itemOrId","subject","itemDoesNotExist","externalItem","ctx","find","_bindToCollection","externalCollection","as","Class","_setUpBindToBinding","using","callbackOrProperty","addItem","isExternalBoundToThis","externalItemBound","finalIndex","skipped","getIndex","document_Document","roots","_postFixers","postFixer","destroy","writer","wasFixed","DEFAULT_PRIORITY","attributeelement_AttributeElement","attributeelement_getFillerOffset","_priority","_id","_clonesGroup","nonUiChildrenCount","emptyelement_EmptyElement","emptyelement_getFillerOffset","userAgent","navigator","src_env","isMac","isEdge","isGecko","isSafari","macGlyphsToModifiers","⌘","⇧","⌥","modifiersToMacGlyphs","ctrl","keyCodes","arrowleft","arrowup","arrowright","arrowdown","backspace","enter","space","esc","tab","cmd","letter","generateKnownKeyCodes","getCode","keyCode","altKey","ctrlKey","shiftKey","parseKeystroke","keystroke","splitKeystrokeText","sum","uielement_UIElement","uielement_getFillerOffset","domDocument","toDomElement","domElement","getAttributeKeys","injectUiElementHandling","view","domConverter","domSelection","domTarget","ownerDocument","defaultView","getSelection","domSelectionCollapsed","getRangeAt","collapsed","domParent","focusNode","domOffset","focusOffset","viewPosition","domPositionToView","jumpedOverAnyUiElement","nextViewPosition","newDomPosition","viewPositionToDom","collapse","extend","jumpOverUiElement","documentfragment_DocumentFragment","documentfragment_normalize","downcastwriter_DowncastWriter","_cloneGroups","_setTo","_setFocus","attributeElement","renderFunction","uiElement","_setAttribute","_removeAttribute","_addClass","_removeClass","_setStyle","_removeStyle","_removeCustomProperty","positionOrRange","_breakAttributes","_breakAttributesRange","newElement","insert","sourceRange","targetPosition","move","positionOffset","positionParent","_removeFromClonedElementsGroup","mergeAttributes","mergeTextNodes","_appendChild","prev","newPosition","validateNodesToInsert","validNodesToInsert","some","validNode","container","getParentContainer","insertionPosition","_addToClonedElementsGroup","endPosition","rangeOrItem","validateRangeContainer","breakStart","breakEnd","parentContainer","removed","mergePosition","walker","getWalker","current","rangeToRemove","parentElement","ancestor","countBefore","_hasNonUiChildren","_wrapPosition","viewSelection","setSelection","_wrapRange","newRange","_unwrapChildren","newName","viewElement","getAttributes","groupName","wrapElement","wrapPositions","isText","isAttribute","isUI","_wrapAttributeElement","shouldABeOutsideB","newAttribute","_wrapChildren","offsetChange","unwrapElement","unwrapPositions","unwrapped","_unwrapAttributeElement","movePositionToTextNode","breakTextNode","fakePosition","createAttributeElement","POSITIVE_INFINITY","wrapRange","wrap","wrapper","toWrap","canBeJoined","getStyleNames","setStyle","addClass","toUnwrap","removeAttribute","removeClass","removeStyle","forceSplitText","rangeStart","rangeEnd","isContainerOrFragment","offsetAfter","clonedNode","nodesToMove","group","getIdentity","textToMove","t1","t2","nodeBeforeLength","startContainer","endContainer","istext_isText","BR_FILLER","fillerBr","dataset","ckeFiller","NBSP_FILLER","INLINE_FILLER_LENGTH","INLINE_FILLER","startsWithFiller","domNode","isInlineFiller","domText","getDataWithoutFiller","templateBlockFillers","isBlockFiller","blockFiller","templateBlockFiller","isEqualNode","jumpOverInlineFiller","fastDiff","cmp","atomicChanges","changeIndexes","arr1","arr2","firstIndex","findFirstDifferenceIndex","lastIndexOld","lastIndexNew","oldArrayReversed","cutAndReverse","newArrayReversed","findChangeBoundaryIndexes","newLength","fill","changeIndexesToAtomicChanges","newArray","changeIndexesToChanges","diff_diff","aLength","bLength","_insert","_delete","es","fp","snake","y1","y2","dir","y","x","insertat_insertAt","nodeToInsert","remove_remove","isNode","Document","Node","renderer_Renderer","domDocuments","markedAttributes","markedChildren","markedTexts","_inlineFiller","_fakeSelectionContainer","mapViewToDom","inlineFillerPosition","_updateChildrenMappings","_isSelectionInInlineFiller","_removeInlineFiller","_getInlineFillerPosition","_needsInlineFillerAtSelection","_updateAttrs","_updateChildren","_updateText","fillerDomPosition","addInlineFiller","_updateSelection","_updateFocus","actualDomChildren","expectedDomChildren","viewChildrenToDom","withChildren","diff","_diffNodeLists","actions","_findReplaceActions","equal","action","insertIndex","deleteIndex","viewChild","_updateElementMappings","unbindDomElement","bindElements","firstPos","selectionPosition","domFillerNode","selectionParent","selectionOffset","findAncestor","isEditable","viewText","findCorrespondingDomText","newDomText","viewToDom","actualText","expectedText","filler","insertData","deleteData","domAttrKeys","attr","viewAttrKeys","nodesToUnbind","_markDescendantTextToSync","domToView","domChildList","fakeSelectionContainer","childList","filterOutFakeSelectionContainer","actualDomChild","expectedDomChild","actualDom","expectedDom","newActions","actualSlice","expectedSlice","areSimilar","viewNode","_removeDomSelection","_removeFakeSelection","domRoot","_updateFakeSelection","_updateDomSelection","top","left","width","textContent","domRange","createRange","removeAllRanges","selectNodeContents","addRange","bindFakeSelection","_domSelectionNeedsUpdate","ELEMENT_NODE","childAtOffset","tagName","fixGeckoSelectionAfterBr","isDomSelectionCorrect","oldViewSelection","domSelectionToView","doc","activeDomElement","activeElement","mapDomToView","domParentOrArray","nodeAfterFiller","fillerNode","node1","node2","DOCUMENT_NODE","domconverter_DomConverter","preElements","blockElements","_domToViewMapping","_viewToDomMapping","_fakeSelectionMapping","viewDocumentSelection","domFragment","viewFragment","textData","_processDataFromViewText","createDocumentFragment","bindDocumentFragments","fillerPositionOffset","childView","viewRange","domStart","domEnd","setStart","setEnd","viewParent","domBefore","domAfter","getParentUIElement","_processDataFromDomText","isComment","isDocumentFragment","viewName","keepOriginalCase","domChildrenToView","domChild","fakeSelectionToView","isDomSelectionBackward","viewRanges","domRangeToView","viewStart","viewEnd","findCorrespondingViewText","viewBefore","domElementOrDocumentFragment","isElement","documentFragmentOrElement","viewEditable","domEditable","scrollX","scrollY","scrollPositions","forEachDomNodeAncestor","scrollLeft","scrollTop","scrollTo","DOCUMENT_FRAGMENT_NODE","COMMENT_NODE","anchorNode","anchorOffset","detach","_isDomSelectionPositionCorrect","includes","prevNode","_getTouchingViewTextNode","_nodeEndsWithSpace","_hasDomParentOfType","_getTouchingInlineDomNode","nextNode","shouldLeftTrim","_checkShouldLeftTrimDomText","shouldRightTrim","_checkShouldRightTrimDomText","Text","getNext","topmostParent","createTreeWalker","NodeFilter","SHOW_TEXT","SHOW_ELEMENT","acceptNode","FILTER_ACCEPT","FILTER_SKIP","currentNode","touchingNode","lca","nodeA","nodeB","boundaryParent","parents","isWindow","stringifiedObject","dom_emittermixin","proxy","_getProxyEmitter","emittermixin_ProxyEmitter","attach","listeningEmitter","listenedToEmitterId","_getEmitterListenedTo","getNodeUID","_domNode","_domListeners","domListener","_createDomListener","useCapture","addEventListener","removeListener","domEvt","removeEventListener","Observer","isEnabled","_setCacheAdd_HASH_UNDEFINED","_setCacheAdd","_setCacheHas","SetCache","_SetCache","_arraySome","_cacheHas","COMPARE_PARTIAL_FLAG","COMPARE_UNORDERED_FLAG","_equalArrays","equalFunc","arrLength","othLength","seen","arrValue","othValue","compared","othIndex","_mapToArray","_setToArray","_equalByTag_COMPARE_PARTIAL_FLAG","_equalByTag_COMPARE_UNORDERED_FLAG","_equalByTag_boolTag","_equalByTag_dateTag","_equalByTag_errorTag","_equalByTag_mapTag","_equalByTag_numberTag","_equalByTag_regexpTag","_equalByTag_setTag","_equalByTag_stringTag","_equalByTag_symbolTag","_equalByTag_arrayBufferTag","_equalByTag_dataViewTag","_equalByTag_symbolProto","_equalByTag_symbolValueOf","_equalByTag","convert","_equalObjects_COMPARE_PARTIAL_FLAG","_equalObjects_hasOwnProperty","_equalObjects","objProps","objLength","skipCtor","objCtor","othCtor","_baseIsEqualDeep_COMPARE_PARTIAL_FLAG","_baseIsEqualDeep_argsTag","_baseIsEqualDeep_arrayTag","_baseIsEqualDeep_objectTag","_baseIsEqualDeep_hasOwnProperty","_baseIsEqualDeep","objIsArr","othIsArr","objTag","othTag","objIsObj","othIsObj","isSameTag","objIsWrapped","othIsWrapped","objUnwrapped","othUnwrapped","_baseIsEqual","baseIsEqual","lodash_es_isEqualWith","mutationobserver_MutationObserver","characterData","characterDataOldValue","subtree","_renderer","_domElements","_mutationObserver","MutationObserver","_onMutations","takeRecords","observe","disconnect","domMutations","mutatedTexts","mutatedElements","mutation","_isBogusBrMutation","oldText","newText","viewMutations","mutatedText","markToSync","viewChildren","newViewChildren","sameNodes","oldChildren","newChildren","viewSelectionAnchor","viewSelectionFocus","child1","child2","forceRender","addedNode","removedNodes","addedNodes","domeventdata_DomEventData","domEvent","additionalData","preventDefault","stopPropagation","domeventobserver_DomEventObserver","domEventType","onDomEvent","eventType","keyobserver_KeyObserver","metaKey","lodash_es_now","isSymbol_symbolTag","lodash_es_isSymbol","NAN","reTrim","reIsBadHex","reIsBinary","reIsOctal","freeParseInt","lodash_es_toNumber","isBinary","FUNC_ERROR_TEXT","debounce_nativeMax","nativeMin","lodash_es_debounce","wait","lastArgs","lastThis","maxWait","timerId","lastCallTime","lastInvokeTime","leading","maxing","trailing","invokeFunc","time","shouldInvoke","timeSinceLastCall","timerExpired","trailingEdge","setTimeout","timeWaiting","remainingWait","debounced","isInvoking","leadingEdge","cancel","clearTimeout","flush","fakeselectionobserver_FakeSelectionObserver","_fireSelectionChangeDoneDebounced","_isArrowKeyCode","_handleSelectionMove","newSelection","oldSelection","selectionobserver_SelectionObserver","mutationObserver","getObserver","_documents","WeakSet","_clearInfiniteLoopInterval","setInterval","_clearInfiniteLoop","_loopbackCounter","_handleSelectionChange","clearInterval","isReadOnly","newViewSelection","focusobserver_FocusObserver","_renderTimeoutId","selectedEditable","compositionobserver_CompositionObserver","isComposing","isRange","getBorderWidths","getComputedStyle","borderTopWidth","right","borderRightWidth","bottom","borderBottomWidth","borderLeftWidth","rectProperties","rect_Rect","isSourceRange","_source","sourceNode","body","contains","copyRectProperties","getDomRangeRects","getBoundingClientRect","innerWidth","innerHeight","height","anotherRect","rect","getIntersection","getArea","visibleRect","isBody","commonAncestorContainer","parentRect","intersectionRect","prop","intersectRect","scrollBarWidth","scrollBarHeight","documentElement","clientWidth","clientHeight","borderWidths","offsetWidth","offsetHeight","moveBy","rects","clientRects","getClientRects","elementOrRange","scrollViewportToShowTarget","viewportOffset","targetWindow","getWindow","currentWindow","currentFrame","firstAncestorToScroll","scrollAncestorsToShowRect","getParentElement","getRectRelativeToWindow","targetRect","scrollWindowToShowRect","frameElement","targetShiftedDownRect","targetShiftedUpRect","viewportRect","excludeScrollbarsAndBorders","isAbove","isBelow","isLeftOf","isRightOf","getRect","parentWindow","firstRect","secondRect","relativeWindow","frame","frameRect","scrollAncestorsToShowTarget","view_View","domRoots","_initialDomRootAttributes","_observers","_ongoingChange","_postFixersInProgress","_renderingDisabled","_hasChangedSinceTheLastRendering","_writer","addObserver","injectQuirksHandling","_render","viewRoot","getRoot","initialDomRootAttributes","updateContenteditableAttribute","change","observer","viewRangeToDom","isRenderingInProgress","callbackResult","_callPostFixers","disableObservers","enableObservers","toMap","model_node_Node","getChildStartOffset","model_text_Text","toJSON","model_textproxy_TextProxy","nodelist_NodeList","_nodes","_insertNodes","maxOffset","getNodeIndex","getNodeStartOffset","totalOffset","nodeList","indexStart","model_element_Element","getNode","offsetToIndex","relativePath","element_normalize","_removeNodes","fromJSON","model_treewalker_TreeWalker","model_position_Position","stickiness","_visitedParent","prevVisitedParent","formatReturnValue","offsetInTextNode","lodash_es_last","newOffset","diffAt","leftParent","getParentPath","operation","_getTransformedByInsertOperation","_getTransformedByMoveOperation","_getTransformedBySplitOperation","_getTransformedByMergeOperation","_getTransformedByInsertion","_getTransformedByMove","sourcePosition","movedRange","_getCombined","splitPosition","moveTargetPosition","graveyardPosition","_getTransformedByDeletion","deletionPosition","deletePosition","transformed","insertPosition","combined","graveyard","model_range_Range","getCommonPath","posParent","operations","getTransformedByOperation","containsRange","spread","newPos","moveRange","differenceSet","getDifference","difference","common","transformedCommon","newStart","newEnd","refIndex","mapper_Mapper","_modelToViewMapping","_viewToModelMapping","_viewToModelLengthCallbacks","_markerNameToElements","viewContainer","modelPosition","_findPositionIn","viewBlock","findMappedViewAncestor","modelParent","modelOffset","_toModelOffset","modelElement","toModelElement","toViewElement","elements","toModelPosition","modelRange","toViewPosition","mapper","isPhantom","boundElements","getElementsWithSameId","viewElementName","lengthCallback","viewOffset","getModelLength","expectedOffset","lastLength","_moveViewPositionToTextNode","modelconsumable_ModelConsumable","_consumable","_textProxyRegistry","_normalizeConsumableType","_getSymbolForTextProxy","itemConsumables","startMap","endMap","_addSymbolForTextProxy","downcastdispatcher_DowncastDispatcher","conversionApi","dispatcher","differ","getMarkersToRemove","convertMarkerRemove","getChanges","convertInsert","convertRemove","convertAttribute","attributeKey","attributeOldValue","attributeNewValue","getMarkersToAdd","convertMarkerAdd","consumable","_createInsertConsumable","_testAndFire","_clearConversionApi","_createConsumableForRange","markers","markersAtSelection","getMarkersAtPosition","_createSelectionConsumable","markerRange","getRange","shouldMarkerChangeBeConverted","markerName","getItems","containsItem","model_selection_Selection","anyNewRange","oldRange","_removeAllRanges","directChange","_popRange","attributeKeys","visited","startBlock","getParentBlock","isUnvisitedBlockContainer","endBlock","isTouching","selected","getSelectedBlocks","parentBlock","findAncestorBlock","limitStartPosition","limitEndPosition","_checkRange","model","isBlock","hasParentLimit","isLimit","liverange_LiveRange","isDocumentOperation","_createFromRanges","boundariesChanged","contentChanged","doesOperationChangeRangeContent","toRange","storePrefix","model_documentselection_DocumentSelection","documentselection_LiveSelection","hasOwnRange","isGravityOverridden","getTopMostBlocks","containsEntireContent","_getStoredAttributes","overrideGravity","restoreGravity","startsWith","_model","_attributePriority","_fixGraveyardRangesData","_hasChangedRange","_overriddenGravityRegister","_validateSelectionRange","_updateMarkers","_updateAttributes","liveRange","_fixGraveyardSelection","batch","changeParent","isNoLongerEmpty","enqueueChange","storedAttributes","clearAttributesStoredInElement","_getDefaultRange","optionsOrPlaceOrOffset","_refreshAttributes","overrideUid","_prepareRange","fromRange","selectionRange","clearAll","newAttributes","_getSurroundingAttributes","oldAttributes","_setAttributesTo","changed","newKey","oldKey","getAttrsIfCharacter","removedRangeStart","positionCandidate","getNearestSelectionRange","ConversionHelpers","dispatchers","_dispatchers","conversionHelper","cloneDeep_CLONE_DEEP_FLAG","cloneDeep_CLONE_SYMBOLS_FLAG","lodash_es_cloneDeep","downcasthelpers_DowncastHelpers","normalizeToElementConfig","elementCreator","consume","insertElement","converterPriority","downcastElementToElement","modelValue","getFromAttributeCreator","oldViewElement","newViewElement","viewWriter","toViewRange","unwrap","downcastAttributeToElement","normalizeToAttributeConfig","attributeCreator","oldAttribute","changeAttribute","downcastAttributeToAttribute","isOpening","viewStartElement","viewEndElement","bindElementToMarker","insertUIElement","markerNameToElements","unbindElementsFromMarkerName","createRangeOn","clearClonedElementsGroup","downcastMarkerToElement","highlightDescriptor","descriptor","prepareDescriptor","createViewElementFromHighlightDescriptor","rangeAfterWrap","highlightText","highlightElement","viewHighlightElement","removeHighlight","downcastMarkerToHighlight","viewElementType","modelData","viewElementDefinition","createContainerElement","createUIElement","createViewElementFromDefinition","modelAttributeValue","upcasthelpers_UpcastHelpers","upcastElementToElement","normalizeModelAttributeConfig","converter","prepareToAttributeConverter","elementName","getViewElementNameFromConfig","upcastElementToAttribute","viewKey","normalized","keyName","normalizeViewAttributeKeyValueConfig","upcastAttributeToAttribute","oldModel","modelWriter","data-name","normalizeToMarkerConfig","upcastElementToMarker","matcherResult","viewItem","getModelElement","splitResult","splitToAllowedParent","modelCursor","convertChildren","createPositionAt","getSplitParts","createPositionBefore","createPositionAfter","cursorParent","prepareToElementConverter","viewAttributeKeyToCopy","defaultModelValue","modelKey","onlyViewNameIsDefined","modelAttribute","checkAttribute","setAttributeOn","editingcontroller_EditingController","downcastDispatcher","_disableRendering","convertChanges","convertSelection","modelSelection","toModelRange","convertSelectionChange","createText","modelEnd","createRangeIn","unbindViewElement","brokenPosition","breakAttributes","plugincollection_PluginCollection","editor","availablePlugins","_editor","_availablePlugins","_plugins","PluginConstructor","pluginName","errorMsg","plugins","removePlugins","that","loading","loaded","pluginConstructors","mapToAvailableConstructors","removePluginConstructors","missingPlugins","pluginNameOrConstructor","getPluginConstructor","getMissingPluginNames","Promise","reject","loadPlugin","then","initPlugins","requires","RequiredPluginConstructorOrName","RequiredPluginConstructor","requiredBy","_add","instantiatePlugin","catch","err","loadedPlugins","method","promise","PluginConstructorOrName","promises","pluginInstance","plugin1","plugin2","commandcollection_CommandCollection","_commands","commandName","command","execute","commands","translate","language","translationKey","numberOfLanguages","CKEDITOR_TRANSLATIONS","hasTranslation","locale_Locale","_t","translatedString","ViewConsumable","_consumables","consumables","elementConsumables","viewconsumable_ViewElementConsumables","revert","instance","consumablesFromElement","createFrom","_canConsumeName","_test","_consume","_revert","consumableName","schema_Schema","_sourceDefinitions","_attributeProperties","decorate","SchemaContext","getDefinition","itemName","_clearCache","_compiledDefinitions","_compile","getDefinitions","def","isInline","context","_checkContextMatch","attributeName","allowAttributes","positionOrBaseElement","elementToMerge","checkMerge","checkChild","childDef","retValue","getAttributeProperties","selectionOrRangeOrPosition","rangeCommonAncestor","getMinimalFlatRanges","convertToMinimalFlatRanges","_getValidRangesForRange","backwardWalker","forwardWalker","forward","step","combineWalkers","removeDisallowedAttributes","compiledDefinitions","sourceRules","itemNames","compileBaseItemRule","compileAllowContentOf","compileAllowWhere","compileAllowAttributesOf","compileInheritPropertiesFrom","cleanUpAllowIn","cleanUpAllowAttributes","contextItemIndex","contextItem","getItem","allowIn","parentRule","mapContextItem","query","getNames","endsWith","sourceItemRules","itemRule","allowContentOf","allowWhere","allowAttributesOf","inheritTypesFrom","sourceItemRule","typeNames","copyTypes","copyProperty","inheritFrom","inheritAllFrom","makeInheritAllWork","allowContentOfItemName","getAllowedChildren","allowedItem","allowWhereItemName","allowedIn","allowAttributeOfItem","inheritAttributes","inheritPropertiesOfItem","existingItems","itemToCheck","getValues","ctxItem","upcastdispatcher_UpcastDispatcher","_splitParts","_modelCursor","convertItem","_convertItem","_convertChildren","_splitToAllowedParent","_getSplitParts","contextDefinition","append","createContextTree","store","documentFragment","_removeEmptyElements","modelItem","markerElements","markerElement","currentPosition","extractMarkersFromModelFragment","nextModelCursor","allowedParent","findAllowedParent","treeWalkerValue","originalPart","splitPart","_registerSplitPair","anyRemoved","datacontroller_DataController","dataProcessor","processor","upcastDispatcher","_checkIfRootsExists","hasContent","ignoreWhitespaces","modelElementOrFragment","viewDocumentFragment","toView","toData","clearBindings","elementRange","intersection","_getMarkersRelativeToElement","initialData","main","modelRoot","newData","removeSelectionAttribute","toModel","viewElementOrFragment","rootNames","getRootNames","conversion_Conversion","downcastDispatchers","upcastDispatchers","_helpers","_downcast","_createConversionHelpers","isDowncast","_upcast","for","elementToElement","_getAllUpcastDefinitions","attributeToElement","elementToAttribute","attributeToAttribute","_getUpcastDefinition","upcastAlso","upcastAlsoItem","Batch","baseVersion","op","Operation","__className","model_documentfragment_DocumentFragment","model_documentfragment_normalize","_normalizeNodes","_splitNodeAtPosition","_mergeNodesAtIndex","_move","_haveSameAttributes","mergedNode","offsetDiff","firstPart","secondPart","iteratorA","iteratorB","lodash_es_isEqual","attributeoperation_AttributeOperation","detachoperation_DetachOperation","moveoperation_MoveOperation","newTargetPosition","getMovedRangeStart","sourceElement","targetElement","sourceOffset","targetOffset","insertoperation_InsertOperation","shouldReceiveAttributes","gyPosition","originalNodes","markeroperation_MarkerOperation","affectsData","_markers","renameoperation_RenameOperation","oldName","rootattributeoperation_RootAttributeOperation","mergeoperation_MergeOperation","splitoperation_SplitOperation","mergedElement","getInsertionPosition","splitElement","rootelement_RootElement","_doc","writer_Writer","_assertWriterUsedCorrectly","isSameTree","addOperation","applyOperation","rangeRootPosition","addMarker","usingOperation","itemOrRange","setAttributeOnRange","setAttributeOnItem","removeAttributesFromItem","_addOperationForAffectedMarkers","flat","applyRemoveOperation","_merge","_mergeDetached","createPositionFromPath","createSelection","merge","renameOperation","limitElement","firstSplitElement","firstCopyElement","elementOrString","shiftedRange","applyMarkerOperation","_set","markerOrName","currentMarker","_refresh","hasUsingOperationDefined","affectsDataDefined","currentRange","updatedRange","managedUsingOperations","keyOrObjectOrIterable","_setSelectionAttribute","keyOrIterableOfKeys","_removeSelectionAttribute","_overrideGravity","_restoreGravity","storeKey","_getStoreAttributeKey","_currentWriter","isAffected","elementBefore","elementAfter","affectedOnLeft","affectedOnRight","updateMarker","valueBefore","valueAfter","lastSplitPosition","previousValue","rootA","rootB","differ_Differ","markerCollection","_markerCollection","_changesInElement","_elementSnapshots","_changedMarkers","_changeCount","_cachedChanges","_cachedChangesWithGraveyard","_isInInsertedElement","_markInsert","_markAttribute","sourceParentInserted","targetParentInserted","_markRemove","getMarkersIntersectingRange","bufferMarkerChange","graveyardParent","mergedIntoElement","buffered","includeChangesInGraveyard","diffSet","changes","snapshotChildren","elementChildren","_getChildrenSnapshot","_generateActionsFromChanges","_getInsertDiff","_getRemoveDiff","elementAttributes","snapshotAttributes","_getAttributesDiff","changeCount","prevDiff","thisDiff","isConsecutiveTextRemove","isConsecutiveTextAdd","isConsecutiveAttributeChange","_changesInGraveyardFilter","changeItem","_markChange","_removeAllNestedChanges","_makeSnapshot","_getChangesForElement","_handleChange","inc","nodesToHandle","old","incEnd","oldEnd","intersectionLength","howManyAfter","attributePart","diffs","snapshot","oldChildrenLength","oldChildrenHandled","repeat","posInGy","rangeInGy","History","_operations","_undoPairs","_undoneOperations","undoneOperation","undoingOperation","isInsideSurrogatePair","character","isHighSurrogateHalf","isLowSurrogateHalf","isInsideCombinedSymbol","isCombiningMark","graveyardName","model_document_Document","history","_hasSelectionChangedFromTheLastChangeBlock","createRoot","bufferOperation","_hasDocumentChangedFromTheLastChangeBlock","hasDataChanges","reset","defaultRoot","_getDefaultRoot","validateTextNodePosition","rangeBoundary","markercollection_MarkerCollection","markercollection_Marker","oldMarker","hasChanged","_attachLiveRange","_managedUsingOperations","_affectsData","_destroyMarker","prefix","_detachLiveRange","_liveRange","stopDelegating","liveposition_LivePosition","oldPosition","toPosition","insertcontent_Insertion","canMergeWith","_filterAttributesOf","_affectedStart","_affectedEnd","parentContext","_handleNode","isFirst","isLast","nodeToSelect","_handleObject","_checkAndSplitToAllowedPosition","_mergeSiblingsOf","_handleDisallowedNode","_tryAutoparagraphing","handleNodes","livePos","fromPosition","_setAffectedBoundaries","mergeLeft","_canMergeLeft","mergeRight","_canMergeRight","mergePosLeft","mergePosRight","livePosition","paragraph","_getAllowedIn","tempPos","deleteContent","selRange","doNotResetEntireContent","getLimitElement","shouldEntireContentBeReplacedWithParagraph","insertParagraph","replaceEntireContentWithParagraph","startPos","endPos","leaveUnmerged","mergeBranches","startParent","endParent","leftPos","rightPos","rangeToCheck","checkCanBeMerged","parentToRemove","collapseSelectionAt","isTextAllowed","isParagraphAllowed","shouldAutoparagraph","validSelectionRange","doNotAutoparagraph","wordBoundaryCharacters","modifySelection","isForward","unit","searchEnd","getSearchRange","tryExtendingTo","setSelectionFocus","isAtWordBoundary","isAtNodeBoundary","boundaryChar","getCorrectWordBreakPosition","getCorrectPosition","offsetToCheck","removeRangeContent","parentsToCheck","itemRange","parentToCheck","removeRange","injectSelectionPostFixer","registerPostFixer","correctedRange","tryFixingRange","fixedRanges","selectionStart","selectionEnd","selectionPostFixer","originalPosition","nearestSelectionRange","fixedPosition","tryFixingCollapsedRange","isTextAllowedOnStart","isTextAllowedOnEnd","startLimitElement","endLimitElement","startIsOnBlock","endIsOnBlock","checkSelectionOnNonLimitElements","isStartObject","fixedStart","isEndObject","fixedEnd","isStartInLimit","isEndInLimit","bothInSameParent","expandStart","isInObject","expandEnd","findOutermostLimitAncestor","tryFixingNonCollapsedRage","startingNode","isLimitNode","model_Model","_pendingChanges","_validate","register","addChildCheck","childDefinition","_runPendingChanges","batchOrType","_execute","insertion","nodesToInsert","getSelectionRange","affectedRange","getAffectedRange","insertContent","frag","commonPath","commonParent","getNodeByPath","flatSubtreeRange","appendText","leftExcessRange","getSelectedContent","rangeOrElement","intersectingMarker","ret","currentBatch","callbackReturnValue","_handleChangeBlock","keystrokehandler_KeystrokeHandler","_listener","keyEvtData","editingkeystrokehandler_EditingKeystrokeHandler","evtData","editor_Editor","builtinPlugins","defaultConfig","locale","once","editing","conversion","addAlias","keystrokes","extraPlugins","init","readyPromise","dataapimixin","elementapimixin","HTMLTextAreaElement","innerHTML","setDataInElement","BasicHtmlWriter","fragment","implementation","createHTMLDocument","htmldataprocessor_HtmlDataProcessor","_domParser","DOMParser","_domConverter","_htmlWriter","getHtml","_toDom","parseFromString","componentfactory_ComponentFactory","_components","originalName","getNormalized","focustracker_FocusTracker","_elements","_nextEventLoopTimeout","_focus","_blur","focusedElement","editorui_EditorUI","componentFactory","focusTracker","_editableElements","documentPlaceholders","enablePlaceholder","isDirectHost","updateDocumentPlaceholders","hidePlaceholder","placeholders","wasViewModified","updatePlaceholder","hostElement","getChildPlaceholderHostSubstitute","isEmptyish","selectionAnchor","needsPlaceholder","showPlaceholder","ElementReplacer","_replacedElements","display","classiceditorui_ClassicEditorUI","_toolbarConfig","normalizeToolbarConfig","_elementReplacer","replacementElement","editingView","editingRoot","attachDomRoot","_initPlaceholder","_initToolbar","restore","detachDomRoot","stickyPanel","limiterElement","viewportTopOffset","toolbar","fillFromConfig","origin","originKeystrokeHandler","originFocusTracker","beforeFocus","afterBlur","enableToolbarKeyboardFocus","placeholderText","viewcollection_ViewCollection","isRendered","_parentElement","elementOrDocFragment","viewcollection_isStringArray","dest","evtName","xhtmlNs","template_Template","template_normalize","template_clone","_isRendered","_revertData","_renderNode","intoFragment","isApplying","revertData","_revertTemplateFromNode","isView","isTemplate","eventNameOrFunctionOrAttribute","TemplateToBinding","eventNameOrFunction","if","valueIfTrue","TemplateIfBinding","template","extendTemplate","extendObjectValueArray","eventListeners","childIndex","isInvalid","_renderText","_renderElement","createElementNS","_renderAttributes","_renderElementChildren","_setUpListeners","hasTemplateBinding","_bindToObservable","updater","getTextUpdater","attrName","attrValue","domAttrValue","attrNs","valueToBind","shouldExtend","getAttributeUpdater","_renderStyleAttribute","isFalsy","arrayValueReducer","setAttributeNS","styleName","styleValue","getStyleUpdater","isViewCollection","setParent","childRevertData","revertBindings","schemaItem","domEvtName","domSelector","activateDomEventListener","syncValueSchemaValue","templateBinding","activateAttributeListener","revertBinding","TemplateBinding","matches","getValue","getValueSchemaValue","removeAttributeNS","normalizePlainTextDefinition","normalizeTextDefinition","listeners","arrayify","normalizeListeners","normalizeAttributes","cur","ext","src_view_View","_viewCollections","_unboundChildren","createCollection","collection","bindTemplate","_bindTemplate","registerChild","getViews","editoruiview_EditorUIView","_renderBodyCollection","_bodyCollectionContainer","bodyElement","class","labelview_LabelView","setTemplate","boxededitoruiview_BoxedEditorUIView","ariaLabelUid","_voiceLabelView","_createVoiceLabel","role","lang","aria-labelledby","voiceLabel","editableuiview_EditableUIView","_editableElement","_hasExternalElement","_editingView","_updateIsFocusedClasses","updateAfterRender","inlineeditableuiview_InlineEditableUIView","toUnit","toPx","stickypanelview_StickyPanelView","_contentPanelPlaceholder","isSticky","_panelRect","_contentPanel","_hasViewportTopOffset","_isStickyToTheLimiter","limiterBottomOffset","marginLeft","_checkIfShouldBeSticky","panelRect","limiterRect","_limiterRect","isActive","_marginLeft","FocusCycler","keystrokeHandler","focusables","isFocusable","_getFocusableItem","previous","viewIndex","focused","collectionLength","toolbarseparatorview_ToolbarSeparatorView","toolbarview_ToolbarView","_focusCycler","focusPrevious","focusNext","mousedown","focusFirst","focusLast","classiceditoruiview_ClassicEditorUIView","classiceditor_ClassicEditor","sourceElementOrData","ui","updateSourceElement","form","originalSubmit","onSubmit","submit","attachToForm","getDataFromElement","getInitialData","iconview_IconView","viewBox","_updateXMLContent","_colorFillPaths","svg","fillColor","querySelectorAll","tooltipview_TooltipView","buttonview_ButtonView","tooltipView","_createTooltipView","labelView","_createLabelView","iconView","_getTooltipString","tabindex","aria-disabled","aria-pressed","click","icon","tooltip","getEnvKeystrokeText","ckeditor5_utils_src_spy","src_eventinfo_EventInfo","ckeditor5_utils_src_priorities","emittermixin_listeningTo","emittermixin_emitterId","src_emittermixin","emittermixin_getEmitterId","src_uid_uid","emittermixin_setEmitterId","emittermixin_getEvents","emittermixin_createEventNamespace","emittermixin_getCallbacksListsForNamespace","emittermixin_removeCallback","emittermixin_getCallbacksForEvent","emittermixin_fireDelegatedEvents","observablemixin_observablePropertiesSymbol","observablemixin_boundObservablesSymbol","observablemixin_boundPropertiesSymbol","observablemixin_ObservableMixin","observablemixin_initObservable","observablemixin_isStringArray","observablemixin_bindTo","observablemixin_bindToMany","src_observablemixin","observablemixin_parseBindToArgs","observablemixin_updateBoundObservableProperty","observablemixin_attachBindToListeners","observablemixin_updateBoundObservables","observablemixin_updateBindToBound","observablemixin_getBindingTargets","mix_mix","Plugin","HighlightStack","_stack","oldTop","_insertDescriptor","newTop","compareDescriptors","oldDescriptor","newDescriptor","_removeDescriptor","findIndex","shouldABeBeforeB","classesToString","WIDGET_CLASS_NAME","WIDGET_SELECTED_CLASS_NAME","isWidget","toWidget","setCustomProperty","utils_getFillerOffset","labelOrCreator","setLabel","hasSelectionHandler","selectionHandler","drag_handler_default","addSelectionHandler","setHighlightHandling","normalizeToArray","getLabel","labelCreator","toWidgetEditable","findOptimalInsertionPosition","selectedElement","firstBlock","positionAfter","op_macro_toc_plugin_OPMacroTocPlugin","buttonName","createTocViewElement","createTocDataElement","withText","tocElement","I18n","placeholder","embeddedTableSymbol","isEmbeddedTableWidgetSelected","isEmbeddedTableWidget","getOPService","getPluginContext","services","getOPResource","getOPPath","pathName","embedded_table_editing_EmbeddedTableEditing","pluginContext","button","macro_text","queryProps","opEmbeddedTableQuery","toEmbeddedTableWidget","createEmbeddedTableView","createEmbeddedTableDataElement","runInZone","externalQueryConfiguration","show","newQuery","data-query-props","plugin_Plugin","mouseobserver_MouseObserver","selectAllKeystrokeCode","widget_Widget","viewDocument","_previouslySelected","_clearPreviouslySelectedWidgets","lastMarked","isChild","_onMousedown","_onKeydown","_handleDelete","domEventData","isInsideNestedEditable","detail","_setSelectionOverElement","wasHandled","isArrowKeyCode","isSelectAllKeyCode","_handleEnterKey","_selectAllNestedEditableContent","_selectAllContent","_handleArrowKeys","objectElement","_getObjectElementNextToSelection","previousNode","nodeToRemove","objectElement2","isBackwards","shouldInsertParagraph","paragraphLimit","documentSelection","widgetParent","probe","widget","src_plugin_Plugin","getOptimalPosition","positions","limiter","fitInViewport","positionedElementAncestor","getPositionedAncestor","elementRect","bestPosition","getVisible","bestPositionRect","bestPositionName","maxLimiterIntersectArea","maxViewportIntersectArea","elementRectArea","positionName","positionRect","getPosition","limiterIntersectArea","viewportIntersectArea","limiterViewportIntersectRect","getIntersectionArea","setBestPosition","getBestPosition","getAbsoluteRectCoordinates","ancestorPosition","ancestorBorderWidths","moveTo","balloonpanelview_toPx","defaultLimiterElement","balloonpanelview_BalloonPanelView","isVisible","defaultPositions","positionOptions","southArrowNorth","southArrowNorthWest","southArrowNorthEast","northArrowSouth","northArrowSouthWest","northArrowSouthEast","_getOptimalPosition","unpin","_pinWhenIsVisibleCallback","_startPinning","_stopPinning","hide","attachTo","getDomElement","scrollTarget","isWithinScrollTarget","isLimiterWithinScrollTarget","getNorthTop","balloonRect","arrowVerticalOffset","getSouthTop","arrowHorizontalOffset","northWestArrowSouth","northWestArrowSouthWest","northWestArrowSouthEast","northEastArrowSouth","northEastArrowSouthEast","northEastArrowSouthWest","southWestArrowNorth","southWestArrowNorthWest","southWestArrowNorthEast","southEastArrowNorth","southEastArrowNorthEast","southEastArrowNorthWest","contextualballoon_ContextualBalloon","positionLimiter","visibleView","hasView","_show","pin","_getBalloonPosition","balloonClassName","createToolbarEditButton","edit_default","create_toolbar_balloonClassName","createEditToolbar","config_namespace","isWidgetSelected","toolbarConfig","_balloon","_toolbar","_checkIsVisible","_isVisible","selectionCallback","balloon","getBalloonPositionData","updatePosition","repositionContextualBalloon","_hideToolbar","embedded_table_toolbar_EmbeddedTableToolbar","currentQuery","wpButtonMacroSymbol","isWpButtonMacroWidgetSelected","isWpButtonMacroWidget","op_macro_wp_button_editing_OPMacroWpButtonEditing","createMacroViewElement","data-type","data-classes","macros","configureWorkPackageButton","typename","macroLabel","toWpButtonMacroWidget","op_macro_wp_button_toolbar_OPMacroWpButtonToolbar","macroService","wikiIncludeMacroSymbol","isWikiIncludeMacroWidgetSelected","isWikiIncludeMacroWidget","op_macro_wiki_include_editing_OPWikiIncludePageEditing","page","modelAttributeToView","data-page","configureWikiPageInclude","setPlaceholderContent","placeholderContainer","toWikiIncludeMacroWidget","pageLabel","pageLabelContainer","placeholderContent","op_macro_wiki_include_toolbar_OPWikiIncludePageToolbar","newPage","ckeditor5_core_src_plugin_Plugin","pendingactions_PendingActions","_actions","hasAny","FileReader","reader","_reader","onprogress","total","onload","onerror","onabort","readAsDataURL","abort","filerepository_FileRepository","loaders","_updatePendingAction","_loadersMap","_pendingAction","uploaded","fileOrPromise","createUploadAdapter","loader","filerepository_FileLoader","aggregatedUploaded","aggregatedTotal","uploadTotal","fileOrPromiseOrLoader","getLoader","_destroy","pendingActions","getMessage","uploadedPercent","filePromise","uploadAdapterCreator","_filePromiseWrapper","_createFilePromiseWrapper","_adapter","status","read","upload","uploadResponse","isFulfilled","rejecter","resolver","OpUploadResourceAdapter","resource","uploadAttachments","resourceContext","buildResponse","uploadUrl","_ckeditor_ckeditor5_core_src_plugin_Plugin","filedialogbuttonview_FileDialogButtonView","buttonView","_fileInputView","filedialogbuttonview_FileInputView","accept","multiple","files","isImageType","fetchLocalImage","imageSrc","fetch","mimeType","getImageMimeType","filename","File","createFileFromBlob","imageuploadui_ImageUploadUI","acceptedType","allowMultipleFiles","image_default","imagesToUpload","imageuploadprogress_ImageUploadProgress","image_placeholder_default","uploadStatusChange","modelImage","uploadId","fileRepository","viewFigure","_startAppearEffect","_showPlaceholder","_hidePlaceholder","progressBar","_createProgressBar","_showProgressBar","completeIcon","_showCompleteIcon","_removeUIElement","_hideProgressBar","_stopAppearEffect","viewImg","_getUIElement","_createPlaceholder","imageFigure","uniqueProperty","notification_Notification","alert","_showNotification","namespace","upcastwriter_UpcastWriter","removeChildren","oldElement","insertChild","Command","_disableStack","refresh","forceDisabled","clearForceDisabled","forceDisable","getSelectedImageWidget","isImageWidget","isImage","insertImage","imageElement","insertAtSelection","isImageAllowed","getInsertImageParent","isImageAllowedInParent","checkSelectionOnObject","isInOtherImage","imageuploadcommand_ImageUploadCommand","filesToUpload","uploadImage","createLoader","imageuploadediting_ImageUploadEditing","dataTransfer","getData","isHtmlIncluded","images","targetRanges","fetchableImages","isLocalImage","fetchableImage","isInGraveyard","_readAndUpload","notification","setAttributes","uploadStatus","_parseAndSetSrcsetAttributeOnImage","clean","showWarning","destroyLoader","maxWidth","srcsetAttribute","isNaN","imageupload_ImageUpload","childPagesMacroSymbol","isChildPagesMacroWidgetSelected","isChildPagesMacroWidget","op_macro_child_pages_editing_OPChildPagesEditing","includeParent","data-include-parent","toChildPagesMacroWidget","includeParentText","op_macro_child_pages_toolbar_OPChildPagesToolbar","pageAttribute","configureChildPages","macroConf","node_modules_ckeditor_ckeditor5_core_src_plugin_Plugin","ckeditor5_clipboard_node_modules_ckeditor_ckeditor5_core_src_plugin_Plugin","DataTransfer","nativeDataTransfer","kind","getAsFile","getFiles","_native","setData","clipboardobserver_ClipboardObserver","handleInput","dropRange","clipboardData","domDoc","clientX","clientY","caretRangeFromPoint","rangeParent","rangeOffset","getDropViewRange","smallPaddingElements","clipboard_Clipboard","modelDocument","onCopyCut","_htmlDataProcessor","spaces","normalizeClipboardData","plainTextToHtml","scrollToTheSelection","dataController","modelFragment","viewToPlainText","childText","ckeditor5_enter_node_modules_ckeditor_ckeditor5_core_src_plugin_Plugin","command_Command","command_forceDisable","entercommand_EnterCommand","isSelectionEmpty","splitBlock","isContainedWithinOneElement","enterBlock","splitPos","enterobserver_EnterObserver","isSoft","enter_Enter","shiftentercommand_ShiftEnterCommand","insertBreak","softBreakAction","anchorPos","isInsideLimitElement","breakLineElement","shiftenter_ShiftEnter","createEmptyElement","ckeditor5_typing_node_modules_ckeditor_ckeditor5_core_src_plugin_Plugin","src_command_Command","src_command_forceDisable","ChangeBuffer","limit","isLocked","_changeCallback","_batch","_reset","_selectionChangeCallback","createBatch","ignoreLock","inputcommand_InputCommand","undoStepSize","_buffer","textInsertions","resultRange","isCollapsedRange","lock","insertText","unlock","injectUnsafeKeystrokesHandling","latestCompositionSelection","inputCommand","deleteSelectionContent","isSelectionUnchanged","keyData","safeKeycodes","isSafeKeystroke","handleKeydown","isFlatSelection","containerChildrenMutated","mutations","getSingleTextNodeChange","lastOperation","pushLast","isContinuationOf","expected","diffToChanges","compareChildNodes","oldChild","newChild","injecttypingmutationshandling_MutationHandler","_handleContainerChildrenMutations","_handleTextMutation","_handleTextNodeInsertion","mutationsCommonAncestor","commonAncestor","getMutationsContainer","domMutationCommonAncestor","freshDomConverter","modelFromCurrentDom","currentModel","modelFromDomChildren","currentModelChildren","lastDomChild","lastCurrentChild","isSafeForTextMutation","diffResult","firstChangeAt","insertions","deletions","calculateChanges","modelSelectionRange","viewPos","modelPos","insertedText","lastChangeAt","input_Input","handle","injectTypingMutationsHandling","deletecommand_DeleteCommand","_shouldEntireContentBeReplacedWithParagraph","sequence","_replaceEntireContentWithParagraph","limitElementFirstChild","deleteobserver_DeleteObserver","hasWordModifier","domEvtData","injectAndroidBackspaceMutationsHandling","selectionChangeToleranceMs","previousSelection","currentSelection","latestSelectionChangeMs","childrenBefore","childrenAfter","hasOnlyContainers","hasDelete","hasInsert","containsContainersRemoval","handleContainerRemovalMutations","delete_Delete","typing_Typing","ckeditor5_undo_node_modules_ckeditor_ckeditor5_core_src_plugin_Plugin","ckeditor5_core_src_command_Command","ckeditor5_core_src_command_forceDisable","nooperation_NoOperation","transformations","setTransformation","OperationA","OperationB","transformationFunction","aGroup","noUpdateTransformation","transform_transform","getTransformation","aIsStrong","aWasUndone","bWasUndone","abRelation","baRelation","transformSets","operationsA","operationsB","nextTransformIndex","nextBaseVersionA","nextBaseVersionB","originalOperationsACount","originalOperationsBCount","contextFactory","transform_ContextFactory","useRelations","forceWeakRemove","setOriginalOperations","opA","indexB","opB","newOpsA","getContext","newOpsB","updateRelation","newOpA","padWithNoOps","brokenOperationsACount","brokenOperationsBCount","updateBaseVersions","_history","_useRelations","_forceWeakRemove","_originalOperations","_relations","takeFrom","originalOperation","_setRelation","affectedLeft","affectedRight","side","wasInLeftElement","wasStartBeforeMergedElement","wasEndBeforeMergedElement","wasInRightElement","_wasUndone","_getRelation","originalOp","wasUndone","isUndoneOperation","origB","undoneB","getUndoneOperation","origA","relationsA","relation","_getComplementaryAttributeOperations","insertOperation","insertValue","_moveTargetIntoMovedRange","_makeMoveOperationsFromRanges","hasSameParentAs","moveOp","_breakRangeByMoveOperation","aNewRange","aToGraveyard","bToGraveyard","removedRange","mergeInside","mergeSplittingElement","getReversed","aCompB","shouldSpread","rightRange","movesGraveyardElement","gyMoveSource","splitNodesMoveSource","gyMoveTarget","gyMove","splitNodesMoveTargetPath","splitNodesMoveTarget","splitNodesMove","splitPath","additionalSplit","rangeToMove","gyElementMoved","newParentPosition","newTargetPath","howManyRemoved","aInGraveyard","bInGraveyard","newPositionPath","basecommand_BaseCommand","_createdBatches","docSelection","selectionRanges","transformSelectionRange","batchToUndo","undoingBatch","operationsToUndo","operationToUndo","nextBaseVersion","historyOperations","getOperations","reversedOperations","setOperationAsUndone","getTransformedByOperations","undocommand_UndoCommand","batchIndex","_undo","_restoreSelection","redocommand_RedoCommand","redoingBatch","undoediting_UndoEditing","_batchRegistry","_undoCommand","_redoCommand","addBatch","clearStack","undoneBatch","undoui_UndoUI","_addButton","undo_default","redo_default","Icon","undo_Undo","ckeditor5_adapter_ckfinder_node_modules_ckeditor_ckeditor5_core_src_plugin_Plugin","TOKEN_COOKIE_NAME","TOKEN_LENGTH","tokenCharset","getCsrfToken","cookie","pair","decodeURIComponent","getCookie","randValues","crypto","getRandomValues","generateToken","setCookie","uploadadapter_UploadAdapter","_initRequest","_initListeners","_sendRequest","xhr","XMLHttpRequest","responseType","genericError","response","lengthComputable","FormData","send","blockautoformatediting_BlockAutoformatEditing","callbackOrCommand","InlineAutoformatEditing","testRegexpOrCallback","attributeOrCallback","regExp","testCallback","formatCallback","1","leftDel","2","3","rightDel","delStart","delEnd","rangesToFormat","validRanges","getValidRanges","getText","testOutput","testOutputToRanges","rangesToRemove","arrays","ckeditor5_autoformat_node_modules_ckeditor_ckeditor5_core_src_plugin_Plugin","getCallbackFunctionForInlineAutoformat","ckeditor5_basic_styles_node_modules_ckeditor_ckeditor5_core_src_plugin_Plugin","_ckeditor_ckeditor5_core_src_command_Command","_ckeditor_ckeditor5_core_src_command_forceDisable","attributecommand_AttributeCommand","_getValueFromFirstAllowedNode","checkAttributeInSelection","forceValue","setSelectionAttribute","BOLD","boldediting_BoldEditing","setAttributeProperties","isFormatting","font-weight","boldui_BOLD","boldui_BoldUI","bold_default","CODE","codeediting_CodeEditing","word-wrap","codeui_CODE","codeui_CodeUI","code_default","STRIKETHROUGH","strikethroughediting_StrikethroughEditing","text-decoration","strikethroughui_STRIKETHROUGH","strikethroughui_StrikethroughUI","strikethrough_default","ITALIC","italicediting_ItalicEditing","font-style","italicui_ITALIC","italicui_ItalicUI","italic_default","ckeditor5_block_quote_node_modules_ckeditor_ckeditor5_core_src_plugin_Plugin","node_modules_ckeditor_ckeditor5_core_src_command_Command","node_modules_ckeditor_ckeditor5_core_src_command_forceDisable","first_first","iterable","iteratorItem","blockquotecommand_BlockQuoteCommand","_checkEnabled","blocks","_removeQuote","findQuote","blocksToQuote","checkCanBeQuoted","_applyQuote","getRangesOfBlockGroups","groupRange","positionBefore","quotesToMerge","quote","currentQuote","nextQuote","elementOrPosition","nextBlock","isBQAllowed","isBlockAllowedInBQ","blockquoteediting_BlockQuoteEditing","blockquoteui_BlockQuoteUI","quote_default","ckeditor5_heading_node_modules_ckeditor_ckeditor5_core_src_plugin_Plugin","ckeditor5_paragraph_node_modules_ckeditor_ckeditor5_core_src_command_Command","ckeditor5_paragraph_node_modules_ckeditor_ckeditor5_core_src_command_forceDisable","paragraphcommand_ParagraphCommand","checkCanBecomeParagraph","rename","ckeditor5_paragraph_node_modules_ckeditor_ckeditor5_core_src_plugin_Plugin","paragraph_Paragraph","paragraphLikeElements","isParagraphable","wrapInParagraph","_autoparagraphEmptyRoots","createContext","ckeditor5_heading_node_modules_ckeditor_ckeditor5_core_src_command_Command","ckeditor5_heading_node_modules_ckeditor_ckeditor5_core_src_command_forceDisable","headingcommand_HeadingCommand","modelElements","heading","checkCanBecomeHeading","defaultModelElement","headingediting_HeadingEditing","option","_addDefaultH1Conversion","enterCommand","src_model_Model","dropdownpanelview_DropdownPanelView","selectstart","dropdownview_DropdownView","panelView","isOpen","panelPosition","defaultPanelPositions","southEast","southWest","northEast","northWest","closeDropdown","buttonRect","dropdownbuttonview_DropdownButtonView","arrowView","_createArrowView","aria-haspopup","dropdown_arrow_default","listview_ListView","listitemview_ListItemView","listseparatorview_ListSeparatorView","switchbuttonview_SwitchButtonView","toggleSwitchView","_createToggleView","clickOutsideHandler","activator","contextElements","contextElement","createDropdown","ButtonClass","dropdownView","closeDropdownOnBlur","closeDropdownOnExecute","focusDropdownContentsOnArrows","addDefaultBehavior","addListToDropdown","listView","listItemView","headingui_HeadingUI","localizedTitles","Paragraph","Heading 1","Heading 2","Heading 3","Heading 4","Heading 5","Heading 6","getLocalizedOptions","defaultTitle","dropdownTooltip","titles","itemDefinitions","headingCommand","paragraphCommand","commandValue","isOn","areEnabled","para","whichModel","imageloadobserver_ImageLoadObserver","_observedElements","_updateObservedElements","_fireEvents","modelToViewAttributeConverter","img","imageinsertcommand_ImageInsertCommand","imageediting_ImageEditing","createImageViewElement","altText","toImageWidget","srcset","srcsetAttributeConverter","viewImage","conversionResult","viewFigureToModel","emptyElement","figure","imagetextalternativecommand_ImageTextAlternativeCommand","imagetextalternativeediting_ImageTextAlternativeEditing","labeledinputview_LabeledInputView","InputView","inputUid","statusUid","inputView","_createInputView","statusView","_createStatusView","errorText","infoText","ariaDesribedById","select","inputtextview_InputTextView","readonly","aria-invalid","aria-describedby","setValue","submitHandler","textalternativeformview_TextAlternativeFormView","labeledInput","_createLabeledInputView","saveButtonView","_createButton","check_default","cancelButtonView","cancel_default","_focusables","v","utils_getBalloonPositionData","imagetextalternativeui_ImageTextAlternativeUI","_createForm","_form","low_vision_default","_showForm","_hideForm","utils_repositionContextualBalloon","focusEditable","imagetextalternative_ImageTextAlternative","getCaptionFromImage","imageModelElement","matchImageCaption","imagecaptionediting_ImageCaptionEditing","_insertMissingModelCaptionElement","captionModelToView","createCaptionForEditing","createEditableElement","captionElementCreator","_fixCaptionVisibility","_updateCaptionVisibility","lastCaption","_lastSelectedCaption","viewCaption","modelCaption","getParentCaption","showCaption","hideCaptionIfEmpty","viewModified","nodeFinder","imagesWithoutCaption","nestedItem","appendElement","captionElement","insertViewCaptionAndBind","caption","imagestylecommand_ImageStyleCommand","_defaultStyle","isDefault","attributeValue","getStyleByName","defaultStyles","full","object_full_width_default","object_right_default","alignLeft","object_left_default","alignCenter","object_center_default","alignRight","defaultIcons","center","normalizeImageStyles","configuredStyles","_normalizeStyle","defaultStyle","extendedStyle","imagestyleediting_ImageStyleEditing","modelToViewConverter","newStyle","oldStyle","modelToViewStyleAttribute","filteredStyles","viewFigureElement","modelImageElement","viewToModelStyleAttribute","imagestyleui_ImageStyleUI","localizedDefaultStylesTitles","Full size image","Side image","Left aligned image","Centered image","Right aligned image","translatedStyles","translateStyles","componentName","widgettoolbarrepository_WidgetToolbarRepository","balloonToolbar","widgettoolbarrepository_isWidgetSelected","_toolbarDefinitions","_updateToolbarsVisibility","toolbarId","getRelatedElement","toolbarView","maxRelatedElementDepth","deepestRelatedElement","deepestToolbarDefinition","relatedElement","relatedElementDepth","_showToolbar","toolbarDefinition","_isToolbarVisible","widgettoolbarrepository_getBalloonPositionData","widgettoolbarrepository_repositionContextualBalloon","ckeditor5_link_node_modules_ckeditor_ckeditor5_core_src_plugin_Plugin","ckeditor5_link_node_modules_ckeditor_ckeditor5_core_src_command_Command","ckeditor5_link_node_modules_ckeditor_ckeditor5_core_src_command_forceDisable","findLinkRange","_findBound","lookBack","lastNode","linkcommand_LinkCommand","linkRange","unlinkcommand_UnlinkCommand","rangesToUnlink","ATTRIBUTE_WHITESPACES","SAFE_URL","linkElement","ensureSafeUrl","isSafeUrl","TwoStepCaretHandler","_modelSelection","_overrideUid","_isNextGravityRestorationSkipped","_isGravityOverridden","isAtBoundary","_hasSelectionAttribute","isBetweenDifferentValues","_preventCaretMovement","isAtStartBoundary","isAtEndBoundary","_setSelectionAttributeFromTheNodeBefore","isStepAfterTheAttributeBoundary","_skipNextAutomaticGravityRestoration","overrideSelectionGravity","restoreSelectionGravity","isAttrBefore","isAttrAfter","HIGHLIGHT_CLASS","linkediting_LinkEditing","twoStepCaretHandler","arrowRightPressed","arrowLeftPressed","isMovementHandled","handleForwardMovement","handleBackwardMovement","bindTwoStepCaretToAttribute","_setupLinkHighlight","highlightedLinks","clickobserver_ClickObserver","linkformview_LinkFormView","urlInputView","_createUrlInput","icons_check_default","icons_cancel_default","linkactionsview_LinkActionsView","previewButtonView","_createPreviewButton","unlinkButtonView","unlink_default","editButtonView","pencil_default","linkKeystroke","linkui_LinkUI","actionsView","_createActionsView","formView","_createFormView","_createToolbarLinkButton","_enableUserBalloonInteractions","linkCommand","unlinkCommand","_addFormView","_hideUI","_removeFormView","_showUI","icons_link_default","_getSelectedLinkElement","_areActionsVisible","_isUIVisible","_areActionsInPanel","_getBalloonPositionData","_isFormInPanel","_addActionsView","_startUpdatingUI","_isUIInPanel","prevSelectedLink","prevSelectionParent","getSelectionParent","selectedLink","targetLink","findLinkElementAncestor","startLink","endLink","isLinkElement","ckeditor5_list_node_modules_ckeditor_ckeditor5_core_src_command_Command","ckeditor5_list_node_modules_ckeditor_ckeditor5_core_src_command_forceDisable","listcommand_ListCommand","checkCanBecomeListItem","turnOff","currentIndent","newIndent","listIndent","lowestIndent","_fixType","listType","listItem","startingItem","indentcommand_IndentCommand","indentDirection","_indentBy","itemsToChange","lastItem","ckeditor5_list_node_modules_ckeditor_ckeditor5_core_src_plugin_Plugin","getListItemFillerOffset","hasOnlyLists","modelViewInsertion","injectViewList","createViewListItemElement","viewList","generateLiInUl","modelViewRemove","breakContainer","viewListPrev","mergeViewLists","hoistNestedLists","modelViewChangeType","listName","modelViewChangeIndent","modelViewSplitOnInsert","removeStart","removeEnd","previousList","mergePos","modelViewMergeAfter","viewItemPrev","viewItemNext","viewModelConverter","conversionStore","listItemModel","convertedChild","wasSplit","findNextListItem","viewToModelListItemChildrenConverter","cleanList","cleanListItem","foundList","firstNode","modelToViewPosition","topmostViewList","modelIndentPasteFixer","refItem","indentChange","getSiblingListItem","sameIndent","smallerIndent","itemIndent","firstList","secondList","mergeContainers","injectedItem","injectedList","prevItem","positionAfterUiElements","prevView","breakPosition","nextViewList","lastSubChild","modelChild","nextIndent","modelRemoveStartPosition","viewRemoveStartPosition","viewRemovedItem","prevModelItem","foo","prevIndent","prevViewList","listediting_ListEditing","itemToListHead","applied","_addListToFix","listHead","_fixListIndents","_fixListTypes","maxIndent","fixBy","typesStack","modelChangePostFixer","registerViewToModelLength","getViewListItemLength","modelNode","modelLength","viewToModelPosition","firstPosition","getCommandExecuter","listui_ListUI","numberedlist_default","bulletedlist_default","codeBlockSymbol","isCodeBlockWidget","isCodeBlockWidgetSelected","createCodeBlockWidget","renderCodeBlockContent","toCodeBlockWidget","langElement","setTextNode","empty_text","click_observer_DoubleClickObserver","code_block_editing_CodeBlockEditing","codeBlock","modelCodeBlock","viewCodeBlockToModel","codeBlockContentToView","preElement","codeElement","langContent","contentElement","modelCodeBlockToView","editCodeBlock","languageClass","code_block_default","code_block_toolbar_CodeBlockToolbar","getToolbarItems","__currentlyDisabled","disableItems","except","jQuery","each","toDisable","enableItems","toEnable","ckeditor5_table_node_modules_ckeditor_ckeditor5_core_src_plugin_Plugin","parentName","updateNumericAttribute","defaultValue","createEmptyTableCell","tableCell","upcastTable","viewTable","rows","headingRows","headingColumns","tableMeta","headRows","bodyRows","firstTheadElement","tableChild","trs","tr","headingCols","scanRowForHeadingColumns","scanTable","table","row","upcastTableCell","viewTableCell","th","TableWalker","startRow","endRow","includeSpanned","column","_skipRows","_row","_column","_cell","_spannedCells","_isOverEndRow","_isSpanned","currentColumn","outValue","_formatOutValue","_shouldSkipRow","_shouldSkipColumn","cell","colspan","rowspan","_recordSpans","cellIndex","rowIsBelowStartRow","rowIsMarkedAsSkipped","isCurrentColumn","isPreviousThatOverlapsColumn","columnToUpdate","_markSpannedCell","rowToUpdate","isTableWidget","getSelectedTableWidget","getTableWidgetAncestor","parentTable","downcastInsertTable","asWidget","figureElement","tableElement","tableWidget","toTableWidget","tableWalker","tableAttributes","viewRows","tableWalkerValue","tableSection","getOrCreateTableSection","getSectionName","tableRow","trElement","createTr","createViewTableCellElement","downcastInsertRow","getViewTable","downcastInsertCell","rowIndex","downcastTableHeadingRowsChange","oldRows","newRows","rowsToMove","isBetween","moveViewRowsToTableSection","renameViewTableCell","removeTableSectionIfEmpty","renameViewTableCellIfRequired","lower","upper","downcastTableHeadingColumnsChange","oldColumns","newColumns","lastColumnToCheck","desiredCellElementName","viewCell","renamedCell","getCellElementName","cellElementName","cellElement","isSingleParagraph","hasAnyAttribute","innerParagraph","paragraphInsertPosition","fakeParagraph","sectionName","viewTableSection","getExistingTableSectionElement","tableChildElement","createTableSection","viewTableRow","ckeditor5_table_node_modules_ckeditor_ckeditor5_core_src_command_Command","ckeditor5_table_node_modules_ckeditor_ckeditor5_core_src_command_forceDisable","inserttablecommand_InsertTableCommand","validParent","getInsertTableParent","tableUtils","createTable","insertrowcommand_InsertRowCommand","order","tableParent","insertRows","insertcolumncommand_InsertColumnCommand","getCellLocation","insertColumns","splitcellcommand_SplitCellCommand","isHorizontally","splitCellHorizontally","splitCellVertically","mergecellcommand_MergeCellCommand","isHorizontal","cellToMerge","_getMergeableCell","isMergeNext","cellToExpand","cellToRemove","removedTableCellRow","mergecellcommand_isEmpty","mergeTableCells","spanAttribute","cellSpan","cellToMergeSpan","removedRowIndex","overlapsRemovedRow","removeEmptyRow","horizontalCell","cellOnLeft","cellOnRight","leftCellColumn","rightCellColumn","leftCellSpan","getHorizontalCell","currentCellRowSpan","rowOfCellToMerge","tableMap","mergeColumn","cellToMergeData","getVerticalCell","span","removerowcommand_RemoveRowCommand","currentRow","cellsToMove","rowspanToSet","targetRow","previousCell","cellToMove","removecolumncommand_RemoveColumnCommand","getColumns","removedColumn","setheaderrowcommand_SetHeaderRowCommand","isInTable","_isInHeading","currentHeadingRows","selectionRow","headingRowsToSet","cellsToSplit","getOverlappingCells","splitHorizontally","newRowspan","spanToSet","columnIndex","setheadercolumncommand_SetHeaderColumnCommand","currentHeadingColumns","selectionColumn","headingColumnsToSet","tableutils_TableUtils","createEmptyRows","rowsToInsert","tableIterator","cellsToInsert","columnsToInsert","tableColumns","createCells","skipRow","numberOfCells","newCellsSpan","updatedSpan","breakSpanEvenly","newCellsAttributes","splitCellColumn","cellsToUpdate","splitCellRow","cellColumn","tableCellToInsert","cells","injectTableLayoutPostFixer","analyzedTables","isTableAttributeEntry","fixTableCellsRowspan","fixTableRowsSizes","tableLayoutPostFixer","cellsToTrim","maxRows","isInHeader","rowLimit","findCellsToTrim","rowsLengths","lengths","getRowsLengths","tableSize","maxColumns","isAttributeType","injectTableCellContentPostFixer","fixTableCellContent","fixTable","fixTableRow","tableCellContentsPostFixer","textNodes","injectTableCellPostFixer","elementsToCheck","elementsWithChangedAttributes","isSpanOrP","isTdOrTh","changedChildren","childrenToCheck","getElementsToCheck","ensureProperElementName","updateRangesInViewSelection","tableCellPostFixer","currentViewElement","modelParagraph","expectedViewElementName","isOnlyChild","hasAttributes","getExpectedElementName","renamedViewElement","tableediting_TableEditing","_handleTabOnSelectedTable","_getTabHandler","currentRowIndex","currentCellIndex","isFirstCellInRow","isLastCellInRow","isLastRow","cellToFocus","nextRow","previousRow","inserttableview_InsertTableView","boxView","inserttableview_TableSizeGridBoxView","_highlightGridBoxes","mouseover","tableui_TableUI","table_default","insertTableView","bindIsOn","_prepareDropdown","table_column_default","table_row_default","table_merge_cell_default","addListOption","highlightRegExp","highlightedCodeBlock","turndownService","addRule","nodeName","turndown_plugin_gfm_es_indexOf","isHeadingRow","isFirstTbody","turndown_plugin_gfm_es_cell","taskListItems","checked","borderCells","alignMap","border","align","voidElements","isVoid","voidSelector","turndown_es_rules","Rules","_keep","blankRule","blankReplacement","keepReplacement","defaultRule","defaultReplacement","findRule","filterValue","turndown_es_remove","turndown_es_next","isPre","lineBreak","br","hLevel","headingStyle","blockquote","lastElementChild","bulletListMarker","indentedCodeBlock","codeBlockStyle","fencedCodeBlock","horizontalRule","hr","inlineLink","linkStyle","referenceLink","reference","linkReferenceStyle","emphasis","emDelimiter","strong","strongDelimiter","hasSiblings","isCodeBlock","leadingSpace","trailingSpace","keep","forNode","isBlank","turndown_es_root","_htmlParser","HTMLParser","Parser","canParse","canParseHTMLNatively","JSDOM","createHTMLParser","RootNode","getElementById","cloneNode","prevText","prevVoid","collapseWhitespace","turndown_es_Node","isCode","hasVoid","flankingWhitespace","hasLeading","hasTrailing","isFlankedByWhitespace","sibling","isFlanked","nodeValue","leadingNewLinesRegExp","trailingNewLinesRegExp","TurndownService","defaults","outerHTML","destination","escape","whitespace","string1","string2","separator","newlines","maxNewlines","separatingNewlines","turndown","canConvert","accumulator","turndown_es","hasParentOfType","tagNames","originalSrcAttribute","commonmarkdataprocessor_CommonMarkDataProcessor","_htmlDP","createNodeIterator","removeParagraphsInLists","allowed_whitespace_nodes","allowed_raw_nodes","textNodesPreprocessor","FILTER_REJECT","linkPreprocessor","_content","node_modules_ckeditor_ckeditor5_core_src_command_Command_0","node_modules_ckeditor_ckeditor5_core_src_command_forceDisable_0","mentioncommand_MentionCommand","mentionData","mention","mentionID","mentionText","_addMentionAttributes","_text","currentAttributes","attributesWithMention","mentionediting_MentionEditing","_toMentionAttribute","createViewMentionElement","wasChanged","nodeAfterInsertedTextNode","checkAndFix","insertedNode","nodeAfterInserted","removePartialMentionPostFixer","isBrokenMentionNode","extendAttributeOnMentionPostFixer","isNodeBeforeAText","selectionMentionAttributePostFixer","baseMentionData","_uid","viewElementOrMention","dataMention","data-mention","TextWatcher","textMatcherCallback","textMatcher","debouncedMatcher","debounce","matched","hasMatch","_startListening","_getText","_evaluateTextBeforeSelection","textHasMatch","mentionsview_MentionsView","indexToGet","_isItemVisibleInScrolledArea","offsetTop","domwrapperview_DomWrapperView","classList","mentionlistitemview_MentionListItemView","VERTICAL_SPACING","mentionui_MentionUI","_creatPanelView","_mentionsView","_createMentionView","_mentionsConfigurations","feeds","isHandledKey","selectNext","selectPrevious","executeSelected","_hidePanelAndRemoveMarker","mentionDescription","feed","minimumCharacters","allowedPrefixes","feedCallback","createFeedCallback","watcher","_setupTextWatcherForFeed","itemRenderer","withArrow","mentionsView","_renderItem","_getWatcher","createTextMatcher","totalLength","feedText","createPattern","createTestCallback","hasMention","matchedTextLength","mentionMarker","_getFeed","feedItem","_showPanel","markerMarker","_getBalloonPanelPositionData","selectFirst","removeMarker","_getItemRenderer","renderResult","caret_se","caret_ne","caret_sw","caret_nw","getBalloonPanelPositions","feedItems","filteredItems","opMacroPlugins","opImageUploadPlugins","urls","removeDeletedImage","_addListAutoformats","_addBasicStylesAutoformats","_addHeadingAutoformats","_addBlockQuoteAutoformats","boldCallback","italicCallback","codeCallback","lookupDownloadLocationByName","replaceImageAttachmentsByName","replaceNamedAttachmentWithUrl","data-user-id","toMentionAttribute","userId","helpURL","help_default","previewing","unregisterPreview","preview_default","showPreview","preview","$reference","$editable","$mainEditor","$previewWrapper","siblings","previewService","getAndShowPreview","getOPPreviewContext","api","v3","previewMarkup","ajax","response_type","contentType","disablePreviewing","inSourceMode","labels","wysiwyg","source_default","hideSource","$sourceWrapper","wysiwyg_default","showSource","widgetToolbarRepository","tableContentToolbarItems","deprecatedTableContentToolbarItems","tableToolbarItems","disabledPluginNames","dropdownItems","macroPlugin","buttons","addToolbarToDropdown","isVertical","configurationCustomizer","editorClass","openProject","canAddAttachments","disableAllMacros","disabledMacros","customItemRenderer","itemElement","OPMacroEmbeddedTable","OPMacroWpButton","OPWikiIncludePage","OPCodeBlock","OPChildPages","queryText","_type","project_id","project","idFromLink","principals","OpenProject","urlRoot","getJSON","_embedded","user","displayText","scope","wp","to_s","op_ckeditor_ConstrainedEditor","op_ckeditor_FullEditor","OPConstrainedEditor","OPClassicEditor","createCustomized"],"mappings":"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","file":"ckeditor.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"OPEditor\"] = factory();\n\telse\n\t\troot[\"OPEditor\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 193);\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/ckeditorerror\n */\n\n/**\n * URL to the documentation with error codes.\n */\nexport const DOCUMENTATION_URL =\n\t'https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/error-codes.html';\n\n/**\n * The CKEditor error class.\n *\n * All errors will be shortened during the minification process in order to reduce the code size.\n * Therefore, all error messages should be documented in the same way as those in {@link module:utils/log}.\n *\n * Read more in the {@link module:utils/log} module.\n *\n * @extends Error\n */\nexport default class CKEditorError extends Error {\n\t/**\n\t * Creates an instance of the CKEditorError class.\n\t *\n\t * Read more about error logging in the {@link module:utils/log} module.\n\t *\n\t * @param {String} message The error message in an `error-name: Error message.` format.\n\t * During the minification process the \"Error message\" part will be removed to limit the code size\n\t * and a link to this error documentation will be added to the `message`.\n\t * @param {Object} [data] Additional data describing the error. A stringified version of this object\n\t * will be appended to the error message, so the data are quickly visible in the console. The original\n\t * data object will also be later available under the {@link #data} property.\n\t */\n\tconstructor( message, data ) {\n\t\tmessage = attachLinkToDocumentation( message );\n\n\t\tif ( data ) {\n\t\t\tmessage += ' ' + JSON.stringify( data );\n\t\t}\n\n\t\tsuper( message );\n\n\t\t/**\n\t\t * @member {String}\n\t\t */\n\t\tthis.name = 'CKEditorError';\n\n\t\t/**\n\t\t * The additional error data passed to the constructor. Undefined if none was passed.\n\t\t *\n\t\t * @member {Object|undefined}\n\t\t */\n\t\tthis.data = data;\n\t}\n\n\t/**\n\t * Checks if error is an instance of CKEditorError class.\n\t *\n\t * @param {Object} error Object to check.\n\t * @returns {Boolean}\n\t */\n\tstatic isCKEditorError( error ) {\n\t\treturn error instanceof CKEditorError;\n\t}\n}\n\n/**\n * Attaches link to the documentation at the end of the error message.\n *\n * @param {String} message Message to be logged.\n * @returns {String}\n */\nexport function attachLinkToDocumentation( message ) {\n\tconst matchedErrorName = message.match( /^([^:]+):/ );\n\n\tif ( !matchedErrorName ) {\n\t\treturn message;\n\t}\n\n\treturn message + ` Read more: ${ DOCUMENTATION_URL }#error-${ matchedErrorName[ 1 ] }\\n`;\n}\n","/*\n\tMIT License http://www.opensource.org/licenses/mit-license.php\n\tAuthor Tobias Koppers @sokra\n*/\n\nvar stylesInDom = {};\n\nvar\tmemoize = function (fn) {\n\tvar memo;\n\n\treturn function () {\n\t\tif (typeof memo === \"undefined\") memo = fn.apply(this, arguments);\n\t\treturn memo;\n\t};\n};\n\nvar isOldIE = memoize(function () {\n\t// Test for IE <= 9 as proposed by Browserhacks\n\t// @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805\n\t// Tests for existence of standard globals is to allow style-loader\n\t// to operate correctly into non-standard environments\n\t// @see https://github.com/webpack-contrib/style-loader/issues/177\n\treturn window && document && document.all && !window.atob;\n});\n\nvar getTarget = function (target, parent) {\n if (parent){\n return parent.querySelector(target);\n }\n return document.querySelector(target);\n};\n\nvar getElement = (function (fn) {\n\tvar memo = {};\n\n\treturn function(target, parent) {\n // If passing function in options, then use it for resolve \"head\" element.\n // Useful for Shadow Root style i.e\n // {\n // insertInto: function () { return document.querySelector(\"#foo\").shadowRoot }\n // }\n if (typeof target === 'function') {\n return target();\n }\n if (typeof memo[target] === \"undefined\") {\n\t\t\tvar styleTarget = getTarget.call(this, target, parent);\n\t\t\t// Special case to return head of iframe instead of iframe itself\n\t\t\tif (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n\t\t\t\ttry {\n\t\t\t\t\t// This will throw an exception if access to iframe is blocked\n\t\t\t\t\t// due to cross-origin restrictions\n\t\t\t\t\tstyleTarget = styleTarget.contentDocument.head;\n\t\t\t\t} catch(e) {\n\t\t\t\t\tstyleTarget = null;\n\t\t\t\t}\n\t\t\t}\n\t\t\tmemo[target] = styleTarget;\n\t\t}\n\t\treturn memo[target]\n\t};\n})();\n\nvar singleton = null;\nvar\tsingletonCounter = 0;\nvar\tstylesInsertedAtTop = [];\n\nvar\tfixUrls = require(\"./urls\");\n\nmodule.exports = function(list, options) {\n\tif (typeof DEBUG !== \"undefined\" && DEBUG) {\n\t\tif (typeof document !== \"object\") throw new Error(\"The style-loader cannot be used in a non-browser environment\");\n\t}\n\n\toptions = options || {};\n\n\toptions.attrs = typeof options.attrs === \"object\" ? options.attrs : {};\n\n\t// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>\n\t// tags it will allow on a page\n\tif (!options.singleton && typeof options.singleton !== \"boolean\") options.singleton = isOldIE();\n\n\t// By default, add <style> tags to the <head> element\n if (!options.insertInto) options.insertInto = \"head\";\n\n\t// By default, add <style> tags to the bottom of the target\n\tif (!options.insertAt) options.insertAt = \"bottom\";\n\n\tvar styles = listToStyles(list, options);\n\n\taddStylesToDom(styles, options);\n\n\treturn function update (newList) {\n\t\tvar mayRemove = [];\n\n\t\tfor (var i = 0; i < styles.length; i++) {\n\t\t\tvar item = styles[i];\n\t\t\tvar domStyle = stylesInDom[item.id];\n\n\t\t\tdomStyle.refs--;\n\t\t\tmayRemove.push(domStyle);\n\t\t}\n\n\t\tif(newList) {\n\t\t\tvar newStyles = listToStyles(newList, options);\n\t\t\taddStylesToDom(newStyles, options);\n\t\t}\n\n\t\tfor (var i = 0; i < mayRemove.length; i++) {\n\t\t\tvar domStyle = mayRemove[i];\n\n\t\t\tif(domStyle.refs === 0) {\n\t\t\t\tfor (var j = 0; j < domStyle.parts.length; j++) domStyle.parts[j]();\n\n\t\t\t\tdelete stylesInDom[domStyle.id];\n\t\t\t}\n\t\t}\n\t};\n};\n\nfunction addStylesToDom (styles, options) {\n\tfor (var i = 0; i < styles.length; i++) {\n\t\tvar item = styles[i];\n\t\tvar domStyle = stylesInDom[item.id];\n\n\t\tif(domStyle) {\n\t\t\tdomStyle.refs++;\n\n\t\t\tfor(var j = 0; j < domStyle.parts.length; j++) {\n\t\t\t\tdomStyle.parts[j](item.parts[j]);\n\t\t\t}\n\n\t\t\tfor(; j < item.parts.length; j++) {\n\t\t\t\tdomStyle.parts.push(addStyle(item.parts[j], options));\n\t\t\t}\n\t\t} else {\n\t\t\tvar parts = [];\n\n\t\t\tfor(var j = 0; j < item.parts.length; j++) {\n\t\t\t\tparts.push(addStyle(item.parts[j], options));\n\t\t\t}\n\n\t\t\tstylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};\n\t\t}\n\t}\n}\n\nfunction listToStyles (list, options) {\n\tvar styles = [];\n\tvar newStyles = {};\n\n\tfor (var i = 0; i < list.length; i++) {\n\t\tvar item = list[i];\n\t\tvar id = options.base ? item[0] + options.base : item[0];\n\t\tvar css = item[1];\n\t\tvar media = item[2];\n\t\tvar sourceMap = item[3];\n\t\tvar part = {css: css, media: media, sourceMap: sourceMap};\n\n\t\tif(!newStyles[id]) styles.push(newStyles[id] = {id: id, parts: [part]});\n\t\telse newStyles[id].parts.push(part);\n\t}\n\n\treturn styles;\n}\n\nfunction insertStyleElement (options, style) {\n\tvar target = getElement(options.insertInto)\n\n\tif (!target) {\n\t\tthrow new Error(\"Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid.\");\n\t}\n\n\tvar lastStyleElementInsertedAtTop = stylesInsertedAtTop[stylesInsertedAtTop.length - 1];\n\n\tif (options.insertAt === \"top\") {\n\t\tif (!lastStyleElementInsertedAtTop) {\n\t\t\ttarget.insertBefore(style, target.firstChild);\n\t\t} else if (lastStyleElementInsertedAtTop.nextSibling) {\n\t\t\ttarget.insertBefore(style, lastStyleElementInsertedAtTop.nextSibling);\n\t\t} else {\n\t\t\ttarget.appendChild(style);\n\t\t}\n\t\tstylesInsertedAtTop.push(style);\n\t} else if (options.insertAt === \"bottom\") {\n\t\ttarget.appendChild(style);\n\t} else if (typeof options.insertAt === \"object\" && options.insertAt.before) {\n\t\tvar nextSibling = getElement(options.insertAt.before, target);\n\t\ttarget.insertBefore(style, nextSibling);\n\t} else {\n\t\tthrow new Error(\"[Style Loader]\\n\\n Invalid value for parameter 'insertAt' ('options.insertAt') found.\\n Must be 'top', 'bottom', or Object.\\n (https://github.com/webpack-contrib/style-loader#insertat)\\n\");\n\t}\n}\n\nfunction removeStyleElement (style) {\n\tif (style.parentNode === null) return false;\n\tstyle.parentNode.removeChild(style);\n\n\tvar idx = stylesInsertedAtTop.indexOf(style);\n\tif(idx >= 0) {\n\t\tstylesInsertedAtTop.splice(idx, 1);\n\t}\n}\n\nfunction createStyleElement (options) {\n\tvar style = document.createElement(\"style\");\n\n\tif(options.attrs.type === undefined) {\n\t\toptions.attrs.type = \"text/css\";\n\t}\n\n\tif(options.attrs.nonce === undefined) {\n\t\tvar nonce = getNonce();\n\t\tif (nonce) {\n\t\t\toptions.attrs.nonce = nonce;\n\t\t}\n\t}\n\n\taddAttrs(style, options.attrs);\n\tinsertStyleElement(options, style);\n\n\treturn style;\n}\n\nfunction createLinkElement (options) {\n\tvar link = document.createElement(\"link\");\n\n\tif(options.attrs.type === undefined) {\n\t\toptions.attrs.type = \"text/css\";\n\t}\n\toptions.attrs.rel = \"stylesheet\";\n\n\taddAttrs(link, options.attrs);\n\tinsertStyleElement(options, link);\n\n\treturn link;\n}\n\nfunction addAttrs (el, attrs) {\n\tObject.keys(attrs).forEach(function (key) {\n\t\tel.setAttribute(key, attrs[key]);\n\t});\n}\n\nfunction getNonce() {\n\tif (typeof __webpack_nonce__ === 'undefined') {\n\t\treturn null;\n\t}\n\n\treturn __webpack_nonce__;\n}\n\nfunction addStyle (obj, options) {\n\tvar style, update, remove, result;\n\n\t// If a transform function was defined, run it on the css\n\tif (options.transform && obj.css) {\n\t result = typeof options.transform === 'function'\n\t\t ? options.transform(obj.css) \n\t\t : options.transform.default(obj.css);\n\n\t if (result) {\n\t \t// If transform returns a value, use that instead of the original css.\n\t \t// This allows running runtime transformations on the css.\n\t \tobj.css = result;\n\t } else {\n\t \t// If the transform function returns a falsy value, don't add this css.\n\t \t// This allows conditional loading of css\n\t \treturn function() {\n\t \t\t// noop\n\t \t};\n\t }\n\t}\n\n\tif (options.singleton) {\n\t\tvar styleIndex = singletonCounter++;\n\n\t\tstyle = singleton || (singleton = createStyleElement(options));\n\n\t\tupdate = applyToSingletonTag.bind(null, style, styleIndex, false);\n\t\tremove = applyToSingletonTag.bind(null, style, styleIndex, true);\n\n\t} else if (\n\t\tobj.sourceMap &&\n\t\ttypeof URL === \"function\" &&\n\t\ttypeof URL.createObjectURL === \"function\" &&\n\t\ttypeof URL.revokeObjectURL === \"function\" &&\n\t\ttypeof Blob === \"function\" &&\n\t\ttypeof btoa === \"function\"\n\t) {\n\t\tstyle = createLinkElement(options);\n\t\tupdate = updateLink.bind(null, style, options);\n\t\tremove = function () {\n\t\t\tremoveStyleElement(style);\n\n\t\t\tif(style.href) URL.revokeObjectURL(style.href);\n\t\t};\n\t} else {\n\t\tstyle = createStyleElement(options);\n\t\tupdate = applyToTag.bind(null, style);\n\t\tremove = function () {\n\t\t\tremoveStyleElement(style);\n\t\t};\n\t}\n\n\tupdate(obj);\n\n\treturn function updateStyle (newObj) {\n\t\tif (newObj) {\n\t\t\tif (\n\t\t\t\tnewObj.css === obj.css &&\n\t\t\t\tnewObj.media === obj.media &&\n\t\t\t\tnewObj.sourceMap === obj.sourceMap\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tupdate(obj = newObj);\n\t\t} else {\n\t\t\tremove();\n\t\t}\n\t};\n}\n\nvar replaceText = (function () {\n\tvar textStore = [];\n\n\treturn function (index, replacement) {\n\t\ttextStore[index] = replacement;\n\n\t\treturn textStore.filter(Boolean).join('\\n');\n\t};\n})();\n\nfunction applyToSingletonTag (style, index, remove, obj) {\n\tvar css = remove ? \"\" : obj.css;\n\n\tif (style.styleSheet) {\n\t\tstyle.styleSheet.cssText = replaceText(index, css);\n\t} else {\n\t\tvar cssNode = document.createTextNode(css);\n\t\tvar childNodes = style.childNodes;\n\n\t\tif (childNodes[index]) style.removeChild(childNodes[index]);\n\n\t\tif (childNodes.length) {\n\t\t\tstyle.insertBefore(cssNode, childNodes[index]);\n\t\t} else {\n\t\t\tstyle.appendChild(cssNode);\n\t\t}\n\t}\n}\n\nfunction applyToTag (style, obj) {\n\tvar css = obj.css;\n\tvar media = obj.media;\n\n\tif(media) {\n\t\tstyle.setAttribute(\"media\", media)\n\t}\n\n\tif(style.styleSheet) {\n\t\tstyle.styleSheet.cssText = css;\n\t} else {\n\t\twhile(style.firstChild) {\n\t\t\tstyle.removeChild(style.firstChild);\n\t\t}\n\n\t\tstyle.appendChild(document.createTextNode(css));\n\t}\n}\n\nfunction updateLink (link, options, obj) {\n\tvar css = obj.css;\n\tvar sourceMap = obj.sourceMap;\n\n\t/*\n\t\tIf convertToAbsoluteUrls isn't defined, but sourcemaps are enabled\n\t\tand there is no publicPath defined then lets turn convertToAbsoluteUrls\n\t\ton by default. Otherwise default to the convertToAbsoluteUrls option\n\t\tdirectly\n\t*/\n\tvar autoFixUrls = options.convertToAbsoluteUrls === undefined && sourceMap;\n\n\tif (options.convertToAbsoluteUrls || autoFixUrls) {\n\t\tcss = fixUrls(css);\n\t}\n\n\tif (sourceMap) {\n\t\t// http://stackoverflow.com/a/26603875\n\t\tcss += \"\\n/*# sourceMappingURL=data:application/json;base64,\" + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + \" */\";\n\t}\n\n\tvar blob = new Blob([css], { type: \"text/css\" });\n\n\tvar oldSrc = link.href;\n\n\tlink.href = URL.createObjectURL(blob);\n\n\tif(oldSrc) URL.revokeObjectURL(oldSrc);\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* global console */\n\n/**\n * @module utils/log\n */\n\nimport { attachLinkToDocumentation } from './ckeditorerror';\n\n/**\n * The logging module.\n *\n * This object features two functions that should be used across CKEditor code base to log errors and warnings.\n * Despite being an overridable interface for native `console.*` this module serves also the goal to limit the\n * code size of a minified CKEditor package. During minification process the messages will be shortened and\n * links to their documentation will be logged to the console.\n *\n * All errors and warning should be documented in the following way:\n *\n *\t\t/**\n *\t\t * Error thrown when a plugin cannot be loaded due to JavaScript errors, lack of plugins with a given name, etc.\n *\t\t *\n *\t\t * @error plugin-load\n *\t\t * @param pluginName The name of the plugin that could not be loaded.\n *\t\t * @param moduleName The name of the module which tried to load this plugin.\n *\t\t * /\n *\t\tlog.error( 'plugin-load: It was not possible to load the \"{$pluginName}\" plugin in module \"{$moduleName}', {\n *\t\t\tpluginName: 'foo',\n *\t\t\tmoduleName: 'bar'\n *\t\t} );\n *\n * ### Warning vs Error vs Throw\n *\n * * Whenever a potentially incorrect situation occurs, which does not directly lead to an incorrect behavior,\n * log a warning.\n * * Whenever an incorrect situation occurs, but the app may continue working (although perhaps incorrectly),\n * log an error.\n * * Whenever it's really bad and it does not make sense to continue working, throw a {@link module:utils/ckeditorerror~CKEditorError}.\n *\n * @namespace\n */\nconst log = {\n\t/**\n\t * Logs an error to the console.\n\t *\n\t * Read more about error logging in the {@link module:utils/log} module.\n\t *\n\t * @param {String} message The error message in an `error-name: Error message.` format.\n\t * During the minification process the \"Error message\" part will be removed to limit the code size\n\t * and a link to this error documentation will be logged to the console.\n\t * @param {Object} [data] Additional data describing the error.\n\t */\n\terror( message, data ) {\n\t\tconsole.error( attachLinkToDocumentation( message ), data );\n\t},\n\n\t/**\n\t * Logs a warning to the console.\n\t *\n\t * Read more about error logging in the {@link module:utils/log} module.\n\t *\n\t * @param {String} message The warning message in a `warning-name: Warning message.` format.\n\t * During the minification process the \"Warning message\" part will be removed to limit the code size\n\t * and a link to this error documentation will be logged to the console.\n\t * @param {Object} [data] Additional data describing the warning.\n\t */\n\twarn( message, data ) {\n\t\tconsole.warn( attachLinkToDocumentation( message ), data );\n\t}\n};\n\nexport default log;\n","// Utilities\n//\n'use strict';\n\n\nfunction _class(obj) { return Object.prototype.toString.call(obj); }\n\nfunction isString(obj) { return _class(obj) === '[object String]'; }\n\nvar _hasOwnProperty = Object.prototype.hasOwnProperty;\n\nfunction has(object, key) {\n return _hasOwnProperty.call(object, key);\n}\n\n// Merge objects\n//\nfunction assign(obj /*from1, from2, from3, ...*/) {\n var sources = Array.prototype.slice.call(arguments, 1);\n\n sources.forEach(function (source) {\n if (!source) { return; }\n\n if (typeof source !== 'object') {\n throw new TypeError(source + 'must be object');\n }\n\n Object.keys(source).forEach(function (key) {\n obj[key] = source[key];\n });\n });\n\n return obj;\n}\n\n// Remove element from array and put another array at those position.\n// Useful for some operations with tokens\nfunction arrayReplaceAt(src, pos, newElements) {\n return [].concat(src.slice(0, pos), newElements, src.slice(pos + 1));\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nfunction isValidEntityCode(c) {\n /*eslint no-bitwise:0*/\n // broken sequence\n if (c >= 0xD800 && c <= 0xDFFF) { return false; }\n // never used\n if (c >= 0xFDD0 && c <= 0xFDEF) { return false; }\n if ((c & 0xFFFF) === 0xFFFF || (c & 0xFFFF) === 0xFFFE) { return false; }\n // control codes\n if (c >= 0x00 && c <= 0x08) { return false; }\n if (c === 0x0B) { return false; }\n if (c >= 0x0E && c <= 0x1F) { return false; }\n if (c >= 0x7F && c <= 0x9F) { return false; }\n // out of range\n if (c > 0x10FFFF) { return false; }\n return true;\n}\n\nfunction fromCodePoint(c) {\n /*eslint no-bitwise:0*/\n if (c > 0xffff) {\n c -= 0x10000;\n var surrogate1 = 0xd800 + (c >> 10),\n surrogate2 = 0xdc00 + (c & 0x3ff);\n\n return String.fromCharCode(surrogate1, surrogate2);\n }\n return String.fromCharCode(c);\n}\n\n\nvar UNESCAPE_MD_RE = /\\\\([!\"#$%&'()*+,\\-.\\/:;<=>?@[\\\\\\]^_`{|}~])/g;\nvar ENTITY_RE = /&([a-z#][a-z0-9]{1,31});/gi;\nvar UNESCAPE_ALL_RE = new RegExp(UNESCAPE_MD_RE.source + '|' + ENTITY_RE.source, 'gi');\n\nvar DIGITAL_ENTITY_TEST_RE = /^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i;\n\nvar entities = require('./entities');\n\nfunction replaceEntityPattern(match, name) {\n var code = 0;\n\n if (has(entities, name)) {\n return entities[name];\n }\n\n if (name.charCodeAt(0) === 0x23/* # */ && DIGITAL_ENTITY_TEST_RE.test(name)) {\n code = name[1].toLowerCase() === 'x' ?\n parseInt(name.slice(2), 16)\n :\n parseInt(name.slice(1), 10);\n if (isValidEntityCode(code)) {\n return fromCodePoint(code);\n }\n }\n\n return match;\n}\n\n/*function replaceEntities(str) {\n if (str.indexOf('&') < 0) { return str; }\n\n return str.replace(ENTITY_RE, replaceEntityPattern);\n}*/\n\nfunction unescapeMd(str) {\n if (str.indexOf('\\\\') < 0) { return str; }\n return str.replace(UNESCAPE_MD_RE, '$1');\n}\n\nfunction unescapeAll(str) {\n if (str.indexOf('\\\\') < 0 && str.indexOf('&') < 0) { return str; }\n\n return str.replace(UNESCAPE_ALL_RE, function (match, escaped, entity) {\n if (escaped) { return escaped; }\n return replaceEntityPattern(match, entity);\n });\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nvar HTML_ESCAPE_TEST_RE = /[&<>\"]/;\nvar HTML_ESCAPE_REPLACE_RE = /[&<>\"]/g;\nvar HTML_REPLACEMENTS = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;'\n};\n\nfunction replaceUnsafeChar(ch) {\n return HTML_REPLACEMENTS[ch];\n}\n\nfunction escapeHtml(str) {\n if (HTML_ESCAPE_TEST_RE.test(str)) {\n return str.replace(HTML_ESCAPE_REPLACE_RE, replaceUnsafeChar);\n }\n return str;\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nvar REGEXP_ESCAPE_RE = /[.?*+^$[\\]\\\\(){}|-]/g;\n\nfunction escapeRE(str) {\n return str.replace(REGEXP_ESCAPE_RE, '\\\\$&');\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nfunction isSpace(code) {\n switch (code) {\n case 0x09:\n case 0x20:\n return true;\n }\n return false;\n}\n\n// Zs (unicode class) || [\\t\\f\\v\\r\\n]\nfunction isWhiteSpace(code) {\n if (code >= 0x2000 && code <= 0x200A) { return true; }\n switch (code) {\n case 0x09: // \\t\n case 0x0A: // \\n\n case 0x0B: // \\v\n case 0x0C: // \\f\n case 0x0D: // \\r\n case 0x20:\n case 0xA0:\n case 0x1680:\n case 0x202F:\n case 0x205F:\n case 0x3000:\n return true;\n }\n return false;\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n/*eslint-disable max-len*/\nvar UNICODE_PUNCT_RE = require('uc.micro/categories/P/regex');\n\n// Currently without astral characters support.\nfunction isPunctChar(ch) {\n return UNICODE_PUNCT_RE.test(ch);\n}\n\n\n// Markdown ASCII punctuation characters.\n//\n// !, \", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \\, ], ^, _, `, {, |, }, or ~\n// http://spec.commonmark.org/0.15/#ascii-punctuation-character\n//\n// Don't confuse with unicode punctuation !!! It lacks some chars in ascii range.\n//\nfunction isMdAsciiPunct(ch) {\n switch (ch) {\n case 0x21/* ! */:\n case 0x22/* \" */:\n case 0x23/* # */:\n case 0x24/* $ */:\n case 0x25/* % */:\n case 0x26/* & */:\n case 0x27/* ' */:\n case 0x28/* ( */:\n case 0x29/* ) */:\n case 0x2A/* * */:\n case 0x2B/* + */:\n case 0x2C/* , */:\n case 0x2D/* - */:\n case 0x2E/* . */:\n case 0x2F/* / */:\n case 0x3A/* : */:\n case 0x3B/* ; */:\n case 0x3C/* < */:\n case 0x3D/* = */:\n case 0x3E/* > */:\n case 0x3F/* ? */:\n case 0x40/* @ */:\n case 0x5B/* [ */:\n case 0x5C/* \\ */:\n case 0x5D/* ] */:\n case 0x5E/* ^ */:\n case 0x5F/* _ */:\n case 0x60/* ` */:\n case 0x7B/* { */:\n case 0x7C/* | */:\n case 0x7D/* } */:\n case 0x7E/* ~ */:\n return true;\n default:\n return false;\n }\n}\n\n// Hepler to unify [reference labels].\n//\nfunction normalizeReference(str) {\n // use .toUpperCase() instead of .toLowerCase()\n // here to avoid a conflict with Object.prototype\n // members (most notably, `__proto__`)\n return str.trim().replace(/\\s+/g, ' ').toUpperCase();\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n// Re-export libraries commonly used in both markdown-it and its plugins,\n// so plugins won't have to depend on them explicitly, which reduces their\n// bundled size (e.g. a browser build).\n//\nexports.lib = {};\nexports.lib.mdurl = require('mdurl');\nexports.lib.ucmicro = require('uc.micro');\n\nexports.assign = assign;\nexports.isString = isString;\nexports.has = has;\nexports.unescapeMd = unescapeMd;\nexports.unescapeAll = unescapeAll;\nexports.isValidEntityCode = isValidEntityCode;\nexports.fromCodePoint = fromCodePoint;\n// exports.replaceEntities = replaceEntities;\nexports.escapeHtml = escapeHtml;\nexports.arrayReplaceAt = arrayReplaceAt;\nexports.isSpace = isSpace;\nexports.isWhiteSpace = isWhiteSpace;\nexports.isMdAsciiPunct = isMdAsciiPunct;\nexports.isPunctChar = isPunctChar;\nexports.escapeRE = escapeRE;\nexports.normalizeReference = normalizeReference;\n","import freeGlobal from './_freeGlobal.js';\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nexport default root;\n","import freeGlobal from './_freeGlobal.js';\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Detect free variable `process` from Node.js. */\nvar freeProcess = moduleExports && freeGlobal.process;\n\n/** Used to access faster Node.js helpers. */\nvar nodeUtil = (function() {\n try {\n // Use `util.types` for Node.js 10+.\n var types = freeModule && freeModule.require && freeModule.require('util').types;\n\n if (types) {\n return types;\n }\n\n // Legacy `process.binding('util')` for Node.js < 10.\n return freeProcess && freeProcess.binding && freeProcess.binding('util');\n } catch (e) {}\n}());\n\nexport default nodeUtil;\n","import root from './_root.js';\nimport stubFalse from './stubFalse.js';\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;\n\n/**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = nativeIsBuffer || stubFalse;\n\nexport default isBuffer;\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/version\n */\n\n/* globals window, global */\n\nimport log from './log';\nimport { version } from 'ckeditor5/package.json';\n\nconst windowOrGlobal = typeof window === 'object' ? window : global;\n\nif ( windowOrGlobal.CKEDITOR_VERSION ) {\n\t/**\n\t * This error is thrown when due to a mistake in how CKEditor 5 was installed or initialized, some\n\t * of its modules were duplicated (evaluated and executed twice). Module duplication leads to inevitable runtime\n\t * errors.\n\t *\n\t * There are many situations in which some modules can be loaded twice. In the worst case scenario,\n\t * you may need to check your project for each of those issues and fix them all.\n\t *\n\t * # Trying to add a plugin to an existing build\n\t *\n\t * If you import an existing CKEditor 5 build and a plugin like this:\n\t *\n\t *\t\timport ClassicEditor from '@ckeditor/ckeditor5-build-classic';\n\t *\t\timport Highlight from '@ckeditor/ckeditor5-highlight/src/highlight';\n\t *\n\t * Then your project loads some CKEditor 5 packages twice. How does it happen?\n\t *\n\t * The build package contains a file which is already compiled with webpack,\n\t * meaning that it contains all the necessary code from e.g. `@ckeditor/ckeditor5-engine` and `@ckeditor/ckeditor5-utils`.\n\t *\n\t * However, the `Highlight` plugin imports some of the modules from those packages too. If you ask webpack to\n\t * build such a project, you will end up with those modules being included (and run) twice – first, because they are\n\t * included inside the build package, and second because they are required by the `Highlight` plugin.\n\t *\n\t * Therefore, **you must never add plugins to an existing build** unless your plugin has no dependencies.\n\t *\n\t * Adding plugins to a build is done by taking the source version of this build (so, before it was built with webpack)\n\t * and adding plugins there. In this situation, webpack will know that it only needs to load each plugins once.\n\t *\n\t * Read more in the {@glink builds/guides/integration/installing-plugins \"Installing plugins\"} guide.\n\t *\n\t * # Confused an editor build with an editor implementation\n\t *\n\t * This scenario is very similar to the previous one, but has a different origin.\n\t *\n\t * Let's assume, that you wanted to use CKEditor 5 from source, as explained in the\n\t * {@glink builds/guides/integration/advanced-setup#scenario-2-building-from-source \"Building from source\"} section\n\t * or in the {@glink framework/guides/quick-start \"Quick start\"} guide of the CKEditor 5 Framework.\n\t *\n\t * The correct way to do so is to import an editor and plugins and run them together like this:\n\t *\n\t *\t\timport ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';\n\t *\t\timport Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';\n\t *\t\timport Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';\n\t *\t\timport Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';\n\t *\t\timport Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';\n\t *\n\t *\t\tClassicEditor\n\t *\t\t\t.create( document.querySelector( '#editor' ), {\n\t *\t\t\t\tplugins: [ Essentials, Paragraph, Bold, Italic ],\n\t *\t\t\t\ttoolbar: [ 'bold', 'italic' ]\n\t *\t\t\t} )\n\t *\t\t\t.then( editor => {\n\t *\t\t\t\tconsole.log( 'Editor was initialized', editor );\n\t *\t\t\t} )\n\t *\t\t\t.catch( error => {\n\t *\t\t\t\tconsole.error( error.stack );\n\t *\t\t\t} );\n\t *\n\t * However, you might have mistakenly import a build instead of a source `ClassicEditor`. In which case\n\t * your imports will look like this:\n\t *\n\t *\t\timport ClassicEditor from '@ckeditor/ckeditor5-build-classic';\n\t *\t\timport Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';\n\t *\t\timport Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';\n\t *\t\timport Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';\n\t *\t\timport Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';\n\t *\n\t * This creates the same situation as in the previous section because you use a build together with source plugins.\n\t *\n\t * Remember: `@ckeditor/ckeditor5-build-*` packages contain editor builds and `@ckeditor/ckeditor5-editor-*` source editors.\n\t *\n\t * # Loading two+ builds on one page\n\t *\n\t * If you use CKEditor 5 builds, you might have loaded two (or more) `ckeditor.js` files in one web page\n\t * – check your web page for duplicated `<script>` elements or make sure your page builder/bundler includes CKEditor only once.\n\t *\n\t * If you want to use two different types of editors at once, see the\n\t * {@glink builds/guides/integration/advanced-setup#scenario-3-using-two-different-editors \"Using two different editors\"}\n\t * section.\n\t *\n\t * # Using outdated packages\n\t *\n\t * Building CKEditor 5 from source require using multiple npm packages. Those packages have their dependencies\n\t * to other packages. If you use the latest version of let's say `@ckeditor/ckeditor5-editor-classic` with\n\t * and outdated version of `@ckeditor/ckeditor5-image`, npm or yarn will need to install two different versions of\n\t * `@ckeditor/ckeditor5-core` because `@ckeditor/ckeditor5-editor-classic` and `@ckeditor/ckeditor5-image` may require\n\t * different versions of the core package.\n\t *\n\t * The solution to this issue is to update all packages to their latest version. We recommend\n\t * using tools like [`node-check-updates`](https://www.npmjs.com/package/npm-check-updates) which simplify this process.\n\t *\n\t * # Conflicting version of dependencies\n\t *\n\t * This is a special case of the previous scenario. If you use CKEditor 5 with some 3rd party plugins,\n\t * it may happen that even if you use the latest versions of the official packages and the latest version of\n\t * those 3rd party packages, there will be a conflict between some of their dependencies.\n\t *\n\t * Such a problem can be resolved by either downgrading CKEditor 5 packages (which we do not recommend) or\n\t * asking the author of the 3rd party package to upgrade its depdendencies (or forking his project and doing this yourself).\n\t *\n\t * # Packages were duplicated in `node_modules`\n\t *\n\t * In some situations, especially when calling `npm install` multiple times, it may happen\n\t * than npm will not correctly \"deduplicate\" packages.\n\t *\n\t * Normally, npm deduplicates all packages so e.g. `@ckeditor/ckeditor5-core` is installed only once in `node_modules/`.\n\t * However, it was known to fail to do so from time to time.\n\t *\n\t * We recommend checking if any of the below steps helps:\n\t *\n\t * * `rm -rf node_modules && npm install` to make sure you have a clean `node_modules/` – this step\n\t * is known to help in majority of cases,\n\t * * if you use `yarn.lock` or `package-lock.json`, remove it before `npm install`,\n\t * * check whether all CKEditor 5 packages are up to date and reinstall them\n\t * if you changed anything (`rm -rf node_modules && npm install`).\n\t *\n\t * If all packages are correct and compatible with each other the above steps are known to help. If not, you may\n\t * try to check with `npm ls` how many times packages like `@ckeditor/ckeditor5-core`, `@ckeditor/ckeditor5-engine` and\n\t *`@ckeditor/ckeditor5-utils` are installed. If more than once, verify which package causes that.\n\t *\n\t * @error ckeditor-duplicated-modules\n\t */\n\tlog.error( 'ckeditor-duplicated-modules: Some CKEditor 5 modules are duplicated.' );\n} else {\n\twindowOrGlobal.CKEDITOR_VERSION = version;\n}\n","/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nexport default freeGlobal;\n","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2 4.5V3h16v1.5zm0 3V6h5.674v1.5zm0 3V9h5.674v1.5zm0 3V12h5.674v1.5zm8.5-6V12h6V7.5h-6zM9.682 6h7.636c.377 0 .682.407.682.91v5.68c0 .503-.305.91-.682.91H9.682c-.377 0-.682-.407-.682-.91V6.91c0-.503.305-.91.682-.91zM2 16.5V15h16v1.5z\\\"/></svg>\"","var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n","module.exports = function(originalModule) {\n\tif (!originalModule.webpackPolyfill) {\n\t\tvar module = Object.create(originalModule);\n\t\t// module.parent = undefined by default\n\t\tif (!module.children) module.children = [];\n\t\tObject.defineProperty(module, \"loaded\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.l;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"id\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.i;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"exports\", {\n\t\t\tenumerable: true\n\t\t});\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n};\n","module.exports=/[!-#%-\\*,-\\/:;\\?@\\[-\\]_\\{\\}\\xA1\\xA7\\xAB\\xB6\\xB7\\xBB\\xBF\\u037E\\u0387\\u055A-\\u055F\\u0589\\u058A\\u05BE\\u05C0\\u05C3\\u05C6\\u05F3\\u05F4\\u0609\\u060A\\u060C\\u060D\\u061B\\u061E\\u061F\\u066A-\\u066D\\u06D4\\u0700-\\u070D\\u07F7-\\u07F9\\u0830-\\u083E\\u085E\\u0964\\u0965\\u0970\\u09FD\\u0A76\\u0AF0\\u0C84\\u0DF4\\u0E4F\\u0E5A\\u0E5B\\u0F04-\\u0F12\\u0F14\\u0F3A-\\u0F3D\\u0F85\\u0FD0-\\u0FD4\\u0FD9\\u0FDA\\u104A-\\u104F\\u10FB\\u1360-\\u1368\\u1400\\u166D\\u166E\\u169B\\u169C\\u16EB-\\u16ED\\u1735\\u1736\\u17D4-\\u17D6\\u17D8-\\u17DA\\u1800-\\u180A\\u1944\\u1945\\u1A1E\\u1A1F\\u1AA0-\\u1AA6\\u1AA8-\\u1AAD\\u1B5A-\\u1B60\\u1BFC-\\u1BFF\\u1C3B-\\u1C3F\\u1C7E\\u1C7F\\u1CC0-\\u1CC7\\u1CD3\\u2010-\\u2027\\u2030-\\u2043\\u2045-\\u2051\\u2053-\\u205E\\u207D\\u207E\\u208D\\u208E\\u2308-\\u230B\\u2329\\u232A\\u2768-\\u2775\\u27C5\\u27C6\\u27E6-\\u27EF\\u2983-\\u2998\\u29D8-\\u29DB\\u29FC\\u29FD\\u2CF9-\\u2CFC\\u2CFE\\u2CFF\\u2D70\\u2E00-\\u2E2E\\u2E30-\\u2E4E\\u3001-\\u3003\\u3008-\\u3011\\u3014-\\u301F\\u3030\\u303D\\u30A0\\u30FB\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA673\\uA67E\\uA6F2-\\uA6F7\\uA874-\\uA877\\uA8CE\\uA8CF\\uA8F8-\\uA8FA\\uA8FC\\uA92E\\uA92F\\uA95F\\uA9C1-\\uA9CD\\uA9DE\\uA9DF\\uAA5C-\\uAA5F\\uAADE\\uAADF\\uAAF0\\uAAF1\\uABEB\\uFD3E\\uFD3F\\uFE10-\\uFE19\\uFE30-\\uFE52\\uFE54-\\uFE61\\uFE63\\uFE68\\uFE6A\\uFE6B\\uFF01-\\uFF03\\uFF05-\\uFF0A\\uFF0C-\\uFF0F\\uFF1A\\uFF1B\\uFF1F\\uFF20\\uFF3B-\\uFF3D\\uFF3F\\uFF5B\\uFF5D\\uFF5F-\\uFF65]|\\uD800[\\uDD00-\\uDD02\\uDF9F\\uDFD0]|\\uD801\\uDD6F|\\uD802[\\uDC57\\uDD1F\\uDD3F\\uDE50-\\uDE58\\uDE7F\\uDEF0-\\uDEF6\\uDF39-\\uDF3F\\uDF99-\\uDF9C]|\\uD803[\\uDF55-\\uDF59]|\\uD804[\\uDC47-\\uDC4D\\uDCBB\\uDCBC\\uDCBE-\\uDCC1\\uDD40-\\uDD43\\uDD74\\uDD75\\uDDC5-\\uDDC8\\uDDCD\\uDDDB\\uDDDD-\\uDDDF\\uDE38-\\uDE3D\\uDEA9]|\\uD805[\\uDC4B-\\uDC4F\\uDC5B\\uDC5D\\uDCC6\\uDDC1-\\uDDD7\\uDE41-\\uDE43\\uDE60-\\uDE6C\\uDF3C-\\uDF3E]|\\uD806[\\uDC3B\\uDE3F-\\uDE46\\uDE9A-\\uDE9C\\uDE9E-\\uDEA2]|\\uD807[\\uDC41-\\uDC45\\uDC70\\uDC71\\uDEF7\\uDEF8]|\\uD809[\\uDC70-\\uDC74]|\\uD81A[\\uDE6E\\uDE6F\\uDEF5\\uDF37-\\uDF3B\\uDF44]|\\uD81B[\\uDE97-\\uDE9A]|\\uD82F\\uDC9F|\\uD836[\\uDE87-\\uDE8B]|\\uD83A[\\uDD5E\\uDD5F]/","/**\n * class Ruler\n *\n * Helper class, used by [[MarkdownIt#core]], [[MarkdownIt#block]] and\n * [[MarkdownIt#inline]] to manage sequences of functions (rules):\n *\n * - keep rules in defined order\n * - assign the name to each rule\n * - enable/disable rules\n * - add/replace rules\n * - allow assign rules to additional named chains (in the same)\n * - cacheing lists of active rules\n *\n * You will not need use this class directly until write plugins. For simple\n * rules control use [[MarkdownIt.disable]], [[MarkdownIt.enable]] and\n * [[MarkdownIt.use]].\n **/\n'use strict';\n\n\n/**\n * new Ruler()\n **/\nfunction Ruler() {\n // List of added rules. Each element is:\n //\n // {\n // name: XXX,\n // enabled: Boolean,\n // fn: Function(),\n // alt: [ name2, name3 ]\n // }\n //\n this.__rules__ = [];\n\n // Cached rule chains.\n //\n // First level - chain name, '' for default.\n // Second level - diginal anchor for fast filtering by charcodes.\n //\n this.__cache__ = null;\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Helper methods, should not be used directly\n\n\n// Find rule index by name\n//\nRuler.prototype.__find__ = function (name) {\n for (var i = 0; i < this.__rules__.length; i++) {\n if (this.__rules__[i].name === name) {\n return i;\n }\n }\n return -1;\n};\n\n\n// Build rules lookup cache\n//\nRuler.prototype.__compile__ = function () {\n var self = this;\n var chains = [ '' ];\n\n // collect unique names\n self.__rules__.forEach(function (rule) {\n if (!rule.enabled) { return; }\n\n rule.alt.forEach(function (altName) {\n if (chains.indexOf(altName) < 0) {\n chains.push(altName);\n }\n });\n });\n\n self.__cache__ = {};\n\n chains.forEach(function (chain) {\n self.__cache__[chain] = [];\n self.__rules__.forEach(function (rule) {\n if (!rule.enabled) { return; }\n\n if (chain && rule.alt.indexOf(chain) < 0) { return; }\n\n self.__cache__[chain].push(rule.fn);\n });\n });\n};\n\n\n/**\n * Ruler.at(name, fn [, options])\n * - name (String): rule name to replace.\n * - fn (Function): new rule function.\n * - options (Object): new rule options (not mandatory).\n *\n * Replace rule by name with new function & options. Throws error if name not\n * found.\n *\n * ##### Options:\n *\n * - __alt__ - array with names of \"alternate\" chains.\n *\n * ##### Example\n *\n * Replace existing typographer replacement rule with new one:\n *\n * ```javascript\n * var md = require('markdown-it')();\n *\n * md.core.ruler.at('replacements', function replace(state) {\n * //...\n * });\n * ```\n **/\nRuler.prototype.at = function (name, fn, options) {\n var index = this.__find__(name);\n var opt = options || {};\n\n if (index === -1) { throw new Error('Parser rule not found: ' + name); }\n\n this.__rules__[index].fn = fn;\n this.__rules__[index].alt = opt.alt || [];\n this.__cache__ = null;\n};\n\n\n/**\n * Ruler.before(beforeName, ruleName, fn [, options])\n * - beforeName (String): new rule will be added before this one.\n * - ruleName (String): name of added rule.\n * - fn (Function): rule function.\n * - options (Object): rule options (not mandatory).\n *\n * Add new rule to chain before one with given name. See also\n * [[Ruler.after]], [[Ruler.push]].\n *\n * ##### Options:\n *\n * - __alt__ - array with names of \"alternate\" chains.\n *\n * ##### Example\n *\n * ```javascript\n * var md = require('markdown-it')();\n *\n * md.block.ruler.before('paragraph', 'my_rule', function replace(state) {\n * //...\n * });\n * ```\n **/\nRuler.prototype.before = function (beforeName, ruleName, fn, options) {\n var index = this.__find__(beforeName);\n var opt = options || {};\n\n if (index === -1) { throw new Error('Parser rule not found: ' + beforeName); }\n\n this.__rules__.splice(index, 0, {\n name: ruleName,\n enabled: true,\n fn: fn,\n alt: opt.alt || []\n });\n\n this.__cache__ = null;\n};\n\n\n/**\n * Ruler.after(afterName, ruleName, fn [, options])\n * - afterName (String): new rule will be added after this one.\n * - ruleName (String): name of added rule.\n * - fn (Function): rule function.\n * - options (Object): rule options (not mandatory).\n *\n * Add new rule to chain after one with given name. See also\n * [[Ruler.before]], [[Ruler.push]].\n *\n * ##### Options:\n *\n * - __alt__ - array with names of \"alternate\" chains.\n *\n * ##### Example\n *\n * ```javascript\n * var md = require('markdown-it')();\n *\n * md.inline.ruler.after('text', 'my_rule', function replace(state) {\n * //...\n * });\n * ```\n **/\nRuler.prototype.after = function (afterName, ruleName, fn, options) {\n var index = this.__find__(afterName);\n var opt = options || {};\n\n if (index === -1) { throw new Error('Parser rule not found: ' + afterName); }\n\n this.__rules__.splice(index + 1, 0, {\n name: ruleName,\n enabled: true,\n fn: fn,\n alt: opt.alt || []\n });\n\n this.__cache__ = null;\n};\n\n/**\n * Ruler.push(ruleName, fn [, options])\n * - ruleName (String): name of added rule.\n * - fn (Function): rule function.\n * - options (Object): rule options (not mandatory).\n *\n * Push new rule to the end of chain. See also\n * [[Ruler.before]], [[Ruler.after]].\n *\n * ##### Options:\n *\n * - __alt__ - array with names of \"alternate\" chains.\n *\n * ##### Example\n *\n * ```javascript\n * var md = require('markdown-it')();\n *\n * md.core.ruler.push('my_rule', function replace(state) {\n * //...\n * });\n * ```\n **/\nRuler.prototype.push = function (ruleName, fn, options) {\n var opt = options || {};\n\n this.__rules__.push({\n name: ruleName,\n enabled: true,\n fn: fn,\n alt: opt.alt || []\n });\n\n this.__cache__ = null;\n};\n\n\n/**\n * Ruler.enable(list [, ignoreInvalid]) -> Array\n * - list (String|Array): list of rule names to enable.\n * - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.\n *\n * Enable rules with given names. If any rule name not found - throw Error.\n * Errors can be disabled by second param.\n *\n * Returns list of found rule names (if no exception happened).\n *\n * See also [[Ruler.disable]], [[Ruler.enableOnly]].\n **/\nRuler.prototype.enable = function (list, ignoreInvalid) {\n if (!Array.isArray(list)) { list = [ list ]; }\n\n var result = [];\n\n // Search by name and enable\n list.forEach(function (name) {\n var idx = this.__find__(name);\n\n if (idx < 0) {\n if (ignoreInvalid) { return; }\n throw new Error('Rules manager: invalid rule name ' + name);\n }\n this.__rules__[idx].enabled = true;\n result.push(name);\n }, this);\n\n this.__cache__ = null;\n return result;\n};\n\n\n/**\n * Ruler.enableOnly(list [, ignoreInvalid])\n * - list (String|Array): list of rule names to enable (whitelist).\n * - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.\n *\n * Enable rules with given names, and disable everything else. If any rule name\n * not found - throw Error. Errors can be disabled by second param.\n *\n * See also [[Ruler.disable]], [[Ruler.enable]].\n **/\nRuler.prototype.enableOnly = function (list, ignoreInvalid) {\n if (!Array.isArray(list)) { list = [ list ]; }\n\n this.__rules__.forEach(function (rule) { rule.enabled = false; });\n\n this.enable(list, ignoreInvalid);\n};\n\n\n/**\n * Ruler.disable(list [, ignoreInvalid]) -> Array\n * - list (String|Array): list of rule names to disable.\n * - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.\n *\n * Disable rules with given names. If any rule name not found - throw Error.\n * Errors can be disabled by second param.\n *\n * Returns list of found rule names (if no exception happened).\n *\n * See also [[Ruler.enable]], [[Ruler.enableOnly]].\n **/\nRuler.prototype.disable = function (list, ignoreInvalid) {\n if (!Array.isArray(list)) { list = [ list ]; }\n\n var result = [];\n\n // Search by name and disable\n list.forEach(function (name) {\n var idx = this.__find__(name);\n\n if (idx < 0) {\n if (ignoreInvalid) { return; }\n throw new Error('Rules manager: invalid rule name ' + name);\n }\n this.__rules__[idx].enabled = false;\n result.push(name);\n }, this);\n\n this.__cache__ = null;\n return result;\n};\n\n\n/**\n * Ruler.getRules(chainName) -> Array\n *\n * Return array of active functions (rules) for given chain name. It analyzes\n * rules configuration, compiles caches if not exists and returns result.\n *\n * Default chain name is `''` (empty string). It can't be skipped. That's\n * done intentionally, to keep signature monomorphic for high speed.\n **/\nRuler.prototype.getRules = function (chainName) {\n if (this.__cache__ === null) {\n this.__compile__();\n }\n\n // Chain can be empty, if rules disabled. But we still have to return Array.\n return this.__cache__[chainName] || [];\n};\n\nmodule.exports = Ruler;\n","// Token class\n\n'use strict';\n\n\n/**\n * class Token\n **/\n\n/**\n * new Token(type, tag, nesting)\n *\n * Create new token and fill passed properties.\n **/\nfunction Token(type, tag, nesting) {\n /**\n * Token#type -> String\n *\n * Type of the token (string, e.g. \"paragraph_open\")\n **/\n this.type = type;\n\n /**\n * Token#tag -> String\n *\n * html tag name, e.g. \"p\"\n **/\n this.tag = tag;\n\n /**\n * Token#attrs -> Array\n *\n * Html attributes. Format: `[ [ name1, value1 ], [ name2, value2 ] ]`\n **/\n this.attrs = null;\n\n /**\n * Token#map -> Array\n *\n * Source map info. Format: `[ line_begin, line_end ]`\n **/\n this.map = null;\n\n /**\n * Token#nesting -> Number\n *\n * Level change (number in {-1, 0, 1} set), where:\n *\n * - `1` means the tag is opening\n * - `0` means the tag is self-closing\n * - `-1` means the tag is closing\n **/\n this.nesting = nesting;\n\n /**\n * Token#level -> Number\n *\n * nesting level, the same as `state.level`\n **/\n this.level = 0;\n\n /**\n * Token#children -> Array\n *\n * An array of child nodes (inline and img tokens)\n **/\n this.children = null;\n\n /**\n * Token#content -> String\n *\n * In a case of self-closing tag (code, html, fence, etc.),\n * it has contents of this tag.\n **/\n this.content = '';\n\n /**\n * Token#markup -> String\n *\n * '*' or '_' for emphasis, fence string for fence, etc.\n **/\n this.markup = '';\n\n /**\n * Token#info -> String\n *\n * fence infostring\n **/\n this.info = '';\n\n /**\n * Token#meta -> Object\n *\n * A place for plugins to store an arbitrary data\n **/\n this.meta = null;\n\n /**\n * Token#block -> Boolean\n *\n * True for block-level tokens, false for inline tokens.\n * Used in renderer to calculate line breaks\n **/\n this.block = false;\n\n /**\n * Token#hidden -> Boolean\n *\n * If it's true, ignore this element when rendering. Used for tight lists\n * to hide paragraphs.\n **/\n this.hidden = false;\n}\n\n\n/**\n * Token.attrIndex(name) -> Number\n *\n * Search attribute index by name.\n **/\nToken.prototype.attrIndex = function attrIndex(name) {\n var attrs, i, len;\n\n if (!this.attrs) { return -1; }\n\n attrs = this.attrs;\n\n for (i = 0, len = attrs.length; i < len; i++) {\n if (attrs[i][0] === name) { return i; }\n }\n return -1;\n};\n\n\n/**\n * Token.attrPush(attrData)\n *\n * Add `[ name, value ]` attribute to list. Init attrs if necessary\n **/\nToken.prototype.attrPush = function attrPush(attrData) {\n if (this.attrs) {\n this.attrs.push(attrData);\n } else {\n this.attrs = [ attrData ];\n }\n};\n\n\n/**\n * Token.attrSet(name, value)\n *\n * Set `name` attribute to `value`. Override old value if exists.\n **/\nToken.prototype.attrSet = function attrSet(name, value) {\n var idx = this.attrIndex(name),\n attrData = [ name, value ];\n\n if (idx < 0) {\n this.attrPush(attrData);\n } else {\n this.attrs[idx] = attrData;\n }\n};\n\n\n/**\n * Token.attrGet(name)\n *\n * Get the value of attribute `name`, or null if it does not exist.\n **/\nToken.prototype.attrGet = function attrGet(name) {\n var idx = this.attrIndex(name), value = null;\n if (idx >= 0) {\n value = this.attrs[idx][1];\n }\n return value;\n};\n\n\n/**\n * Token.attrJoin(name, value)\n *\n * Join value to existing attribute via space. Or create new attribute if not\n * exists. Useful to operate with token classes.\n **/\nToken.prototype.attrJoin = function attrJoin(name, value) {\n var idx = this.attrIndex(name);\n\n if (idx < 0) {\n this.attrPush([ name, value ]);\n } else {\n this.attrs[idx][1] = this.attrs[idx][1] + ' ' + value;\n }\n};\n\n\nmodule.exports = Token;\n","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2 4.5V3h16v1.5zm2.5 3V12h11V7.5h-11zM4.061 6H15.94c.586 0 1.061.407 1.061.91v5.68c0 .503-.475.91-1.061.91H4.06c-.585 0-1.06-.407-1.06-.91V6.91C3 6.406 3.475 6 4.061 6zM2 16.5V15h16v1.5z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" clip-rule=\\\"evenodd\\\" stroke-linejoin=\\\"round\\\" stroke-miterlimit=\\\"1.414\\\"><path d=\\\"M18 4.5V3H2v1.5h16zm0 3V6h-5.674v1.5H18zm0 3V9h-5.674v1.5H18zm0 3V12h-5.674v1.5H18zm-8.5-6V12h-6V7.5h6zm.818-1.5H2.682C2.305 6 2 6.407 2 6.91v5.68c0 .503.305.91.682.91h7.636c.377 0 .682-.407.682-.91V6.91c0-.503-.305-.91-.682-.91zM18 16.5V15H2v1.5h16z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2 4.5V3h16v1.5zm4.5 3V12h7V7.5h-7zM5.758 6h8.484c.419 0 .758.407.758.91v5.681c0 .502-.34.909-.758.909H5.758c-.419 0-.758-.407-.758-.91V6.91c0-.503.34-.91.758-.91zM2 16.5V15h16v1.5z\\\"/></svg>\"","module.exports = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\" standalone=\\\"no\\\"?>\\n<svg\\n xmlns:dc=\\\"http://purl.org/dc/elements/1.1/\\\"\\n xmlns:cc=\\\"http://creativecommons.org/ns#\\\"\\n xmlns:rdf=\\\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\\\"\\n xmlns:svg=\\\"http://www.w3.org/2000/svg\\\"\\n xmlns=\\\"http://www.w3.org/2000/svg\\\"\\n xmlns:sodipodi=\\\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\\\"\\n xmlns:inkscape=\\\"http://www.inkscape.org/namespaces/inkscape\\\"\\n class=\\\"ck ck-icon ck-button__icon\\\"\\n viewBox=\\\"0 0 20 20\\\"\\n version=\\\"1.1\\\"\\n id=\\\"svg10\\\"\\n sodipodi:docname=\\\"source.svg\\\"\\n inkscape:version=\\\"0.92.3 (2405546, 2018-03-11)\\\">\\n <defs\\n id=\\\"defs14\\\" />\\n <sodipodi:namedview\\n pagecolor=\\\"#ffffff\\\"\\n bordercolor=\\\"#666666\\\"\\n borderopacity=\\\"1\\\"\\n objecttolerance=\\\"10\\\"\\n gridtolerance=\\\"10\\\"\\n guidetolerance=\\\"10\\\"\\n inkscape:pageopacity=\\\"0\\\"\\n inkscape:pageshadow=\\\"2\\\"\\n inkscape:window-width=\\\"640\\\"\\n inkscape:window-height=\\\"480\\\"\\n id=\\\"namedview12\\\"\\n showgrid=\\\"false\\\"\\n inkscape:zoom=\\\"33.37544\\\"\\n inkscape:cx=\\\"10.656564\\\"\\n inkscape:cy=\\\"13.670445\\\"\\n inkscape:current-layer=\\\"svg10\\\" />\\n <g\\n id=\\\"g8\\\"\\n style=\\\"fill:#000000;fill-rule:evenodd\\\"\\n transform=\\\"matrix(0.8751128,0,0,0.8751128,4.2423992,5.525391)\\\">\\n <g\\n id=\\\"g6\\\"\\n style=\\\"fill:#000000\\\">\\n <g\\n transform=\\\"translate(2,5.6)\\\"\\n id=\\\"g4\\\"\\n style=\\\"fill:#000000\\\">\\n <path\\n d=\\\"M 10.5,0.1 15.7,4 v 1.3 l -5.6,4 C 10,9.5 9.8,9.5 9.6,9.5 9.3,9.4 9,8.8 9,8.5 L 9.3,8.1 14,4.6 9.5,1.4 9.3,1.2 C 9.2,0.9 9.2,0.6 9.3,0.4 9.5,0.2 9.8,0 10.1,0 a 0.8,0.8 0 0 1 0.4,0.1 z M 5.3,0.1 0,4 v 1.3 l 5.6,4 C 5.7,9.5 5.9,9.5 6.1,9.5 6.4,9.4 6.8,8.8 6.7,8.5 6.7,8.4 6.7,8.2 6.5,8.1 L 1.5,4.6 6.2,1.4 6.4,1.2 C 6.5,0.9 6.5,0.6 6.4,0.4 6.2,0.2 5.9,0 5.6,0 A 0.8,0.8 0 0 0 5.3,0.1 Z\\\"\\n id=\\\"path2\\\"\\n inkscape:connector-curvature=\\\"0\\\"\\n style=\\\"fill:#000000\\\" />\\n </g>\\n </g>\\n </g>\\n <metadata\\n id=\\\"metadata4596\\\">\\n <rdf:RDF>\\n <cc:Work\\n rdf:about=\\\"\\\">\\n <dc:title></dc:title>\\n <dc:format>image/svg+xml</dc:format>\\n <dc:type\\n rdf:resource=\\\"http://purl.org/dc/dcmitype/StillImage\\\" />\\n </cc:Work>\\n </rdf:RDF>\\n </metadata>\\n <path\\n style=\\\"stroke-width:0.0390625\\\"\\n d=\\\"M 1.2772336,0.02277222 V 20.022772 H 6.2381712 V 18.225897 H 3.0741087 V 1.8196472 h 8.2031253 l 3.554687,3.59375 v 3.5546875 h 1.796875 V 4.6712097 L 12.019421,0.02277222 Z\\\"\\n id=\\\"path2-3\\\"\\n inkscape:connector-curvature=\\\"0\\\" />\\n</svg>\\n\"","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./code.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./code.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./code.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./heading.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./heading.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./heading.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","// HTML5 entities map: { name -> utf16string }\n//\n'use strict';\n\n/*eslint quotes:0*/\nmodule.exports = require('entities/maps/entities.json');\n","'use strict';\n\n\nmodule.exports.encode = require('./encode');\nmodule.exports.decode = require('./decode');\nmodule.exports.format = require('./format');\nmodule.exports.parse = require('./parse');\n","module.exports=/[\\0-\\uD7FF\\uE000-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]/","module.exports=/[\\0-\\x1F\\x7F-\\x9F]/","module.exports=/[ \\xA0\\u1680\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000]/","// Regexps to match html elements\n\n'use strict';\n\nvar attr_name = '[a-zA-Z_:][a-zA-Z0-9:._-]*';\n\nvar unquoted = '[^\"\\'=<>`\\\\x00-\\\\x20]+';\nvar single_quoted = \"'[^']*'\";\nvar double_quoted = '\"[^\"]*\"';\n\nvar attr_value = '(?:' + unquoted + '|' + single_quoted + '|' + double_quoted + ')';\n\nvar attribute = '(?:\\\\s+' + attr_name + '(?:\\\\s*=\\\\s*' + attr_value + ')?)';\n\nvar open_tag = '<[A-Za-z][A-Za-z0-9\\\\-]*' + attribute + '*\\\\s*\\\\/?>';\n\nvar close_tag = '<\\\\/[A-Za-z][A-Za-z0-9\\\\-]*\\\\s*>';\nvar comment = '<!---->|<!--(?:-?[^>-])(?:-?[^-])*-->';\nvar processing = '<[?].*?[?]>';\nvar declaration = '<![A-Z]+\\\\s+[^>]*>';\nvar cdata = '<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?\\\\]\\\\]>';\n\nvar HTML_TAG_RE = new RegExp('^(?:' + open_tag + '|' + close_tag + '|' + comment +\n '|' + processing + '|' + declaration + '|' + cdata + ')');\nvar HTML_OPEN_CLOSE_TAG_RE = new RegExp('^(?:' + open_tag + '|' + close_tag + ')');\n\nmodule.exports.HTML_TAG_RE = HTML_TAG_RE;\nmodule.exports.HTML_OPEN_CLOSE_TAG_RE = HTML_OPEN_CLOSE_TAG_RE;\n","// ~~strike through~~\n//\n'use strict';\n\n\n// Insert each marker as a separate text token, and add it to delimiter list\n//\nmodule.exports.tokenize = function strikethrough(state, silent) {\n var i, scanned, token, len, ch,\n start = state.pos,\n marker = state.src.charCodeAt(start);\n\n if (silent) { return false; }\n\n if (marker !== 0x7E/* ~ */) { return false; }\n\n scanned = state.scanDelims(state.pos, true);\n len = scanned.length;\n ch = String.fromCharCode(marker);\n\n if (len < 2) { return false; }\n\n if (len % 2) {\n token = state.push('text', '', 0);\n token.content = ch;\n len--;\n }\n\n for (i = 0; i < len; i += 2) {\n token = state.push('text', '', 0);\n token.content = ch + ch;\n\n state.delimiters.push({\n marker: marker,\n jump: i,\n token: state.tokens.length - 1,\n level: state.level,\n end: -1,\n open: scanned.can_open,\n close: scanned.can_close\n });\n }\n\n state.pos += scanned.length;\n\n return true;\n};\n\n\n// Walk through delimiter list and replace text tokens with tags\n//\nmodule.exports.postProcess = function strikethrough(state) {\n var i, j,\n startDelim,\n endDelim,\n token,\n loneMarkers = [],\n delimiters = state.delimiters,\n max = state.delimiters.length;\n\n for (i = 0; i < max; i++) {\n startDelim = delimiters[i];\n\n if (startDelim.marker !== 0x7E/* ~ */) {\n continue;\n }\n\n if (startDelim.end === -1) {\n continue;\n }\n\n endDelim = delimiters[startDelim.end];\n\n token = state.tokens[startDelim.token];\n token.type = 's_open';\n token.tag = 's';\n token.nesting = 1;\n token.markup = '~~';\n token.content = '';\n\n token = state.tokens[endDelim.token];\n token.type = 's_close';\n token.tag = 's';\n token.nesting = -1;\n token.markup = '~~';\n token.content = '';\n\n if (state.tokens[endDelim.token - 1].type === 'text' &&\n state.tokens[endDelim.token - 1].content === '~') {\n\n loneMarkers.push(endDelim.token - 1);\n }\n }\n\n // If a marker sequence has an odd number of characters, it's splitted\n // like this: `~~~~~` -> `~` + `~~` + `~~`, leaving one marker at the\n // start of the sequence.\n //\n // So, we have to move all those markers after subsequent s_close tags.\n //\n while (loneMarkers.length) {\n i = loneMarkers.pop();\n j = i + 1;\n\n while (j < state.tokens.length && state.tokens[j].type === 's_close') {\n j++;\n }\n\n j--;\n\n if (i !== j) {\n token = state.tokens[j];\n state.tokens[j] = state.tokens[i];\n state.tokens[i] = token;\n }\n }\n};\n","// Process *this* and _that_\n//\n'use strict';\n\n\n// Insert each marker as a separate text token, and add it to delimiter list\n//\nmodule.exports.tokenize = function emphasis(state, silent) {\n var i, scanned, token,\n start = state.pos,\n marker = state.src.charCodeAt(start);\n\n if (silent) { return false; }\n\n if (marker !== 0x5F /* _ */ && marker !== 0x2A /* * */) { return false; }\n\n scanned = state.scanDelims(state.pos, marker === 0x2A);\n\n for (i = 0; i < scanned.length; i++) {\n token = state.push('text', '', 0);\n token.content = String.fromCharCode(marker);\n\n state.delimiters.push({\n // Char code of the starting marker (number).\n //\n marker: marker,\n\n // Total length of these series of delimiters.\n //\n length: scanned.length,\n\n // An amount of characters before this one that's equivalent to\n // current one. In plain English: if this delimiter does not open\n // an emphasis, neither do previous `jump` characters.\n //\n // Used to skip sequences like \"*****\" in one step, for 1st asterisk\n // value will be 0, for 2nd it's 1 and so on.\n //\n jump: i,\n\n // A position of the token this delimiter corresponds to.\n //\n token: state.tokens.length - 1,\n\n // Token level.\n //\n level: state.level,\n\n // If this delimiter is matched as a valid opener, `end` will be\n // equal to its position, otherwise it's `-1`.\n //\n end: -1,\n\n // Boolean flags that determine if this delimiter could open or close\n // an emphasis.\n //\n open: scanned.can_open,\n close: scanned.can_close\n });\n }\n\n state.pos += scanned.length;\n\n return true;\n};\n\n\n// Walk through delimiter list and replace text tokens with tags\n//\nmodule.exports.postProcess = function emphasis(state) {\n var i,\n startDelim,\n endDelim,\n token,\n ch,\n isStrong,\n delimiters = state.delimiters,\n max = state.delimiters.length;\n\n for (i = max - 1; i >= 0; i--) {\n startDelim = delimiters[i];\n\n if (startDelim.marker !== 0x5F/* _ */ && startDelim.marker !== 0x2A/* * */) {\n continue;\n }\n\n // Process only opening markers\n if (startDelim.end === -1) {\n continue;\n }\n\n endDelim = delimiters[startDelim.end];\n\n // If the previous delimiter has the same marker and is adjacent to this one,\n // merge those into one strong delimiter.\n //\n // `<em><em>whatever</em></em>` -> `<strong>whatever</strong>`\n //\n isStrong = i > 0 &&\n delimiters[i - 1].end === startDelim.end + 1 &&\n delimiters[i - 1].token === startDelim.token - 1 &&\n delimiters[startDelim.end + 1].token === endDelim.token + 1 &&\n delimiters[i - 1].marker === startDelim.marker;\n\n ch = String.fromCharCode(startDelim.marker);\n\n token = state.tokens[startDelim.token];\n token.type = isStrong ? 'strong_open' : 'em_open';\n token.tag = isStrong ? 'strong' : 'em';\n token.nesting = 1;\n token.markup = isStrong ? ch + ch : ch;\n token.content = '';\n\n token = state.tokens[endDelim.token];\n token.type = isStrong ? 'strong_close' : 'em_close';\n token.tag = isStrong ? 'strong' : 'em';\n token.nesting = -1;\n token.markup = isStrong ? ch + ch : ch;\n token.content = '';\n\n if (isStrong) {\n state.tokens[delimiters[i - 1].token].content = '';\n state.tokens[delimiters[startDelim.end + 1].token].content = '';\n i--;\n }\n }\n};\n","/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nexport default stubFalse;\n","import root from './_root.js';\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined,\n allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;\n\n/**\n * Creates a clone of `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\nfunction cloneBuffer(buffer, isDeep) {\n if (isDeep) {\n return buffer.slice();\n }\n var length = buffer.length,\n result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);\n\n buffer.copy(result);\n return result;\n}\n\nexport default cloneBuffer;\n","module.exports = \"<svg viewBox=\\\"0 0 16 16\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M4 0v1H1v3H0V.5A.5.5 0 0 1 .5 0H4zm8 0h3.5a.5.5 0 0 1 .5.5V4h-1V1h-3V0zM4 16H.5a.5.5 0 0 1-.5-.5V12h1v3h3v1zm8 0v-1h3v-3h1v3.5a.5.5 0 0 1-.5.5H12z\\\"/><path fill-opacity=\\\".256\\\" d=\\\"M1 1h14v14H1z\\\"/><g class=\\\"ck-icon__selected-indicator\\\"><path d=\\\"M7 0h2v1H7V0zM0 7h1v2H0V7zm15 0h1v2h-1V7zm-8 8h2v1H7v-1z\\\"/><path fill-opacity=\\\".254\\\" d=\\\"M1 1h14v14H1z\\\"/></g></svg>\"","module.exports = \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 20 20\\\" width=\\\"20\\\" height=\\\"20\\\"><path d=\\\"M1.586 18.227l.398-2.753.398-2.753 2.355 2.388 2.355 2.355-2.753.365zM14.954 8.01l-7.099 7.065-.763-.796 7.065-7.066-1.592-1.559L5.5 12.721l-.763-.796 7.065-7.066-.796-.796-7.861 7.862 4.71 4.71 7.861-7.828zm3.25-1.56c.398-.397.398-1.094-.033-1.525L15.02 1.775c-.431-.432-1.128-.465-1.526-.034l-.1.1-1.525 1.493 4.71 4.71 1.526-1.493-.033-.033c.033-.033.099-.033.132-.066z\\\"/></svg>\\n\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M6.91 10.54c.26-.23.64-.21.88.03l3.36 3.14 2.23-2.06a.64.64 0 0 1 .87 0l2.52 2.97V4.5H3.2v10.12l3.71-4.08zm10.27-7.51c.6 0 1.09.47 1.09 1.05v11.84c0 .59-.49 1.06-1.09 1.06H2.79c-.6 0-1.09-.47-1.09-1.06V4.08c0-.58.49-1.05 1.1-1.05h14.38zm-5.22 5.56a1.96 1.96 0 1 1 3.4-1.96 1.96 1.96 0 0 1-3.4 1.96z\\\"/></svg>\"","module.exports = \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 700 250\\\"><rect rx=\\\"4\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M5.042 9.367l2.189 1.837a.75.75 0 0 1-.965 1.149l-3.788-3.18a.747.747 0 0 1-.21-.284.75.75 0 0 1 .17-.945L6.23 4.762a.75.75 0 1 1 .964 1.15L4.863 7.866h8.917A.75.75 0 0 1 14 7.9a4 4 0 1 1-1.477 7.718l.344-1.489a2.5 2.5 0 1 0 1.094-4.73l.008-.032H5.042z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M14.958 9.367l-2.189 1.837a.75.75 0 0 0 .965 1.149l3.788-3.18a.747.747 0 0 0 .21-.284.75.75 0 0 0-.17-.945L13.77 4.762a.75.75 0 1 0-.964 1.15l2.331 1.955H6.22A.75.75 0 0 0 6 7.9a4 4 0 1 0 1.477 7.718l-.344-1.489A2.5 2.5 0 1 1 6.039 9.4l-.008-.032h8.927z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M10.187 17H5.773c-.637 0-1.092-.138-1.364-.415-.273-.277-.409-.718-.409-1.323V4.738c0-.617.14-1.062.419-1.332.279-.27.73-.406 1.354-.406h4.68c.69 0 1.288.041 1.793.124.506.083.96.242 1.36.478.341.197.644.447.906.75a3.262 3.262 0 0 1 .808 2.162c0 1.401-.722 2.426-2.167 3.075C15.05 10.175 16 11.315 16 13.01a3.756 3.756 0 0 1-2.296 3.504 6.1 6.1 0 0 1-1.517.377c-.571.073-1.238.11-2 .11zm-.217-6.217H7v4.087h3.069c1.977 0 2.965-.69 2.965-2.072 0-.707-.256-1.22-.768-1.537-.512-.319-1.277-.478-2.296-.478zM7 5.13v3.619h2.606c.729 0 1.292-.067 1.69-.2a1.6 1.6 0 0 0 .91-.765c.165-.267.247-.566.247-.897 0-.707-.26-1.176-.778-1.409-.519-.232-1.31-.348-2.375-.348H7z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M12.5 5.7l5.2 3.9v1.3l-5.6 4c-.1.2-.3.2-.5.2-.3-.1-.6-.7-.6-1l.3-.4 4.7-3.5L11.5 7l-.2-.2c-.1-.3-.1-.6 0-.8.2-.2.5-.4.8-.4a.8.8 0 0 1 .4.1zm-5.2 0L2 9.6v1.3l5.6 4c.1.2.3.2.5.2.3-.1.7-.7.6-1 0-.1 0-.3-.2-.4l-5-3.5L8.2 7l.2-.2c.1-.3.1-.6 0-.8-.2-.2-.5-.4-.8-.4a.8.8 0 0 0-.3.1z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M7 16.4c-.8-.4-1.5-.9-2.2-1.5a.6.6 0 0 1-.2-.5l.3-.6h1c1 1.2 2.1 1.7 3.7 1.7 1 0 1.8-.3 2.3-.6.6-.4.6-1.2.6-1.3.2-1.2-.9-2.1-.9-2.1h2.1c.3.7.4 1.2.4 1.7v.8l-.6 1.2c-.6.8-1.1 1-1.6 1.2a6 6 0 0 1-2.4.6c-1 0-1.8-.3-2.5-.6zM6.8 9L6 8.3c-.4-.5-.5-.8-.5-1.6 0-.7.1-1.3.5-1.8.4-.6 1-1 1.6-1.3a6.3 6.3 0 0 1 4.7 0 4 4 0 0 1 1.7 1l.3.7c0 .1.2.4-.2.7-.4.2-.9.1-1 0a3 3 0 0 0-1.2-1c-.4-.2-1-.3-2-.4-.7 0-1.4.2-2 .6-.8.6-1 .8-1 1.5 0 .8.5 1 1.2 1.5.6.4 1.1.7 1.9 1H6.8z\\\"/><path d=\\\"M3 10.5V9h14v1.5z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M9.586 14.633l.021.004c-.036.335.095.655.393.962.082.083.173.15.274.201h1.474a.6.6 0 1 1 0 1.2H5.304a.6.6 0 0 1 0-1.2h1.15c.474-.07.809-.182 1.005-.334.157-.122.291-.32.404-.597l2.416-9.55a1.053 1.053 0 0 0-.281-.823 1.12 1.12 0 0 0-.442-.296H8.15a.6.6 0 0 1 0-1.2h6.443a.6.6 0 1 1 0 1.2h-1.195c-.376.056-.65.155-.823.296-.215.175-.423.439-.623.79l-2.366 9.347z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M3 10.423a6.5 6.5 0 0 1 6.056-6.408l.038.67C6.448 5.423 5.354 7.663 5.22 10H9c.552 0 .5.432.5.986v4.511c0 .554-.448.503-1 .503h-5c-.552 0-.5-.449-.5-1.003v-4.574zm8 0a6.5 6.5 0 0 1 6.056-6.408l.038.67c-2.646.739-3.74 2.979-3.873 5.315H17c.552 0 .5.432.5.986v4.511c0 .554-.448.503-1 .503h-5c-.552 0-.5-.449-.5-1.003v-4.574z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 10 10\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M.941 4.523a.75.75 0 1 1 1.06-1.06l3.006 3.005 3.005-3.005a.75.75 0 1 1 1.06 1.06l-3.549 3.55a.75.75 0 0 1-1.168-.136L.941 4.523z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M6.972 16.615a.997.997 0 0 1-.744-.292l-4.596-4.596a1 1 0 1 1 1.414-1.414l3.926 3.926 9.937-9.937a1 1 0 0 1 1.414 1.415L7.717 16.323a.997.997 0 0 1-.745.292z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M11.591 10.177l4.243 4.242a1 1 0 0 1-1.415 1.415l-4.242-4.243-4.243 4.243a1 1 0 0 1-1.414-1.415l4.243-4.242L4.52 5.934A1 1 0 0 1 5.934 4.52l4.243 4.243 4.242-4.243a1 1 0 1 1 1.415 1.414l-4.243 4.243z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M5.085 6.22L2.943 4.078a.75.75 0 1 1 1.06-1.06l2.592 2.59A11.094 11.094 0 0 1 10 5.068c4.738 0 8.578 3.101 8.578 5.083 0 1.197-1.401 2.803-3.555 3.887l1.714 1.713a.75.75 0 0 1-.09 1.138.488.488 0 0 1-.15.084.75.75 0 0 1-.821-.16L6.17 7.304c-.258.11-.51.233-.757.365l6.239 6.24-.006.005.78.78c-.388.094-.78.166-1.174.215l-1.11-1.11h.011L4.55 8.197a7.2 7.2 0 0 0-.665.514l-.112.098 4.897 4.897-.005.006 1.276 1.276a10.164 10.164 0 0 1-1.477-.117l-.479-.479-.009.009-4.863-4.863-.022.031a2.563 2.563 0 0 0-.124.2c-.043.077-.08.158-.108.241a.534.534 0 0 0-.028.133.29.29 0 0 0 .008.072.927.927 0 0 0 .082.226c.067.133.145.26.234.379l3.242 3.365.025.01.59.623c-3.265-.918-5.59-3.155-5.59-4.668 0-1.194 1.448-2.838 3.663-3.93zm7.07.531a4.632 4.632 0 0 1 1.108 5.992l.345.344.046-.018a9.313 9.313 0 0 0 2-1.112c.256-.187.5-.392.727-.613.137-.134.27-.277.392-.431.072-.091.141-.185.203-.286.057-.093.107-.19.148-.292a.72.72 0 0 0 .036-.12.29.29 0 0 0 .008-.072.492.492 0 0 0-.028-.133.999.999 0 0 0-.036-.096 2.165 2.165 0 0 0-.071-.145 2.917 2.917 0 0 0-.125-.2 3.592 3.592 0 0 0-.263-.335 5.444 5.444 0 0 0-.53-.523 7.955 7.955 0 0 0-1.054-.768 9.766 9.766 0 0 0-1.879-.891c-.337-.118-.68-.219-1.027-.301zm-2.85.21l-.069.002a.508.508 0 0 0-.254.097.496.496 0 0 0-.104.679.498.498 0 0 0 .326.199l.045.005c.091.003.181.003.272.012a2.45 2.45 0 0 1 2.017 1.513c.024.061.043.125.069.185a.494.494 0 0 0 .45.287h.008a.496.496 0 0 0 .35-.158.482.482 0 0 0 .13-.335.638.638 0 0 0-.048-.219 3.379 3.379 0 0 0-.36-.723 3.438 3.438 0 0 0-2.791-1.543l-.028-.001h-.013z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M6.972 16.615a.997.997 0 0 1-.744-.292l-4.596-4.596a1 1 0 1 1 1.414-1.414l3.926 3.926 9.937-9.937a1 1 0 0 1 1.414 1.415L7.717 16.323a.997.997 0 0 1-.745.292z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M11.591 10.177l4.243 4.242a1 1 0 0 1-1.415 1.415l-4.242-4.243-4.243 4.243a1 1 0 0 1-1.414-1.415l4.243-4.242L4.52 5.934A1 1 0 0 1 5.934 4.52l4.243 4.243 4.242-4.243a1 1 0 1 1 1.415 1.414l-4.243 4.243z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M11.077 15l.991-1.416a.75.75 0 1 1 1.229.86l-1.148 1.64a.748.748 0 0 1-.217.206 5.251 5.251 0 0 1-8.503-5.955.741.741 0 0 1 .12-.274l1.147-1.639a.75.75 0 1 1 1.228.86L4.933 10.7l.006.003a3.75 3.75 0 0 0 6.132 4.294l.006.004zm5.494-5.335a.748.748 0 0 1-.12.274l-1.147 1.639a.75.75 0 1 1-1.228-.86l.86-1.23a3.75 3.75 0 0 0-6.144-4.301l-.86 1.229a.75.75 0 0 1-1.229-.86l1.148-1.64a.748.748 0 0 1 .217-.206 5.251 5.251 0 0 1 8.503 5.955zm-4.563-2.532a.75.75 0 0 1 .184 1.045l-3.155 4.505a.75.75 0 1 1-1.229-.86l3.155-4.506a.75.75 0 0 1 1.045-.184zm4.919 10.562l-1.414 1.414a.75.75 0 1 1-1.06-1.06l1.414-1.415-1.415-1.414a.75.75 0 0 1 1.061-1.06l1.414 1.414 1.414-1.415a.75.75 0 0 1 1.061 1.061l-1.414 1.414 1.414 1.415a.75.75 0 0 1-1.06 1.06l-1.415-1.414z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M7.3 17.37l-.061.088a1.518 1.518 0 0 1-.934.535l-4.178.663-.806-4.153a1.495 1.495 0 0 1 .187-1.058l.056-.086L8.77 2.639c.958-1.351 2.803-1.076 4.296-.03 1.497 1.047 2.387 2.693 1.433 4.055L7.3 17.37zM9.14 4.728l-5.545 8.346 3.277 2.294 5.544-8.346L9.14 4.728zM6.07 16.512l-3.276-2.295.53 2.73 2.746-.435zM9.994 3.506L13.271 5.8c.316-.452-.16-1.333-1.065-1.966-.905-.634-1.895-.78-2.212-.328zM8 18.5L9.375 17H19v1.5H8z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M11.077 15l.991-1.416a.75.75 0 1 1 1.229.86l-1.148 1.64a.748.748 0 0 1-.217.206 5.251 5.251 0 0 1-8.503-5.955.741.741 0 0 1 .12-.274l1.147-1.639a.75.75 0 1 1 1.228.86L4.933 10.7l.006.003a3.75 3.75 0 0 0 6.132 4.294l.006.004zm5.494-5.335a.748.748 0 0 1-.12.274l-1.147 1.639a.75.75 0 1 1-1.228-.86l.86-1.23a3.75 3.75 0 0 0-6.144-4.301l-.86 1.229a.75.75 0 0 1-1.229-.86l1.148-1.64a.748.748 0 0 1 .217-.206 5.251 5.251 0 0 1 8.503 5.955zm-4.563-2.532a.75.75 0 0 1 .184 1.045l-3.155 4.505a.75.75 0 1 1-1.229-.86l3.155-4.506a.75.75 0 0 1 1.045-.184z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M7 5.75c0 .414.336.75.75.75h9.5a.75.75 0 1 0 0-1.5h-9.5a.75.75 0 0 0-.75.75zM3.5 3v5H2V3.7H1v-1h2.5V3zM.343 17.857l2.59-3.257H2.92a.6.6 0 1 0-1.04 0H.302a2 2 0 1 1 3.995 0h-.001c-.048.405-.16.734-.333.988-.175.254-.59.692-1.244 1.312H4.3v1h-4l.043-.043zM7 14.75a.75.75 0 0 1 .75-.75h9.5a.75.75 0 1 1 0 1.5h-9.5a.75.75 0 0 1-.75-.75z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M7 5.75c0 .414.336.75.75.75h9.5a.75.75 0 1 0 0-1.5h-9.5a.75.75 0 0 0-.75.75zm-6 0C1 4.784 1.777 4 2.75 4c.966 0 1.75.777 1.75 1.75 0 .966-.777 1.75-1.75 1.75C1.784 7.5 1 6.723 1 5.75zm6 9c0 .414.336.75.75.75h9.5a.75.75 0 1 0 0-1.5h-9.5a.75.75 0 0 0-.75.75zm-6 0c0-.966.777-1.75 1.75-1.75.966 0 1.75.777 1.75 1.75 0 .966-.777 1.75-1.75 1.75-.966 0-1.75-.777-1.75-1.75z\\\"/></svg>\"","module.exports = \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M415.462 96.978c-88.1-88.1-230.824-88.1-318.924 0-87.22 87.22-87.22 229.943 0 318.044 88.1 88.1 230.824 88.1 318.924 0 87.22-88.1 87.22-230.824 0-318.044zM246.31 437.047c-24.668 0-44.05-20.263-44.05-44.05 0-24.669 19.382-44.05 44.05-44.05 24.668 0 44.05 19.381 44.05 44.05 0 23.787-20.263 44.05-44.05 44.05zm30.835-154.176v23.787c0 12.334-4.405 16.74-15.858 16.74h-32.597c-11.453 0-15.858-4.406-15.858-16.74v-53.742c0-14.096 14.096-18.5 26.43-22.025 2.643-.88 6.167-1.762 8.81-2.643 16.74-6.167 26.43-13.215 26.43-30.835 0-6.167 0-23.787-29.073-23.787-17.62 0-33.478 7.048-43.17 10.572-5.285 2.643-7.929 3.524-11.453 3.524-5.286 0-10.572-4.405-11.453-9.691L167.9 148.958c-.88-2.643-.88-5.286-.88-7.048 0-21.145 66.075-33.479 88.1-33.479 55.503 0 93.387 36.122 93.387 88.982 0 58.146-44.05 75.767-71.362 85.458z\\\"/></svg>\"","module.exports = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\" standalone=\\\"no\\\"?>\\n<svg\\n xmlns:dc=\\\"http://purl.org/dc/elements/1.1/\\\"\\n xmlns:cc=\\\"http://creativecommons.org/ns#\\\"\\n xmlns:rdf=\\\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\\\"\\n xmlns:svg=\\\"http://www.w3.org/2000/svg\\\"\\n xmlns=\\\"http://www.w3.org/2000/svg\\\"\\n xmlns:sodipodi=\\\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\\\"\\n xmlns:inkscape=\\\"http://www.inkscape.org/namespaces/inkscape\\\"\\n class=\\\"ck ck-icon ck-button__icon\\\"\\n viewBox=\\\"0 0 20 20\\\"\\n version=\\\"1.1\\\"\\n id=\\\"svg10\\\"\\n sodipodi:docname=\\\"code-block.svg\\\"\\n inkscape:version=\\\"0.92.3 (2405546, 2018-03-11)\\\">\\n <defs\\n id=\\\"defs14\\\" />\\n <sodipodi:namedview\\n pagecolor=\\\"#ffffff\\\"\\n bordercolor=\\\"#666666\\\"\\n borderopacity=\\\"1\\\"\\n objecttolerance=\\\"10\\\"\\n gridtolerance=\\\"10\\\"\\n guidetolerance=\\\"10\\\"\\n inkscape:pageopacity=\\\"0\\\"\\n inkscape:pageshadow=\\\"2\\\"\\n inkscape:window-width=\\\"640\\\"\\n inkscape:window-height=\\\"480\\\"\\n id=\\\"namedview12\\\"\\n showgrid=\\\"false\\\"\\n inkscape:zoom=\\\"33.37544\\\"\\n inkscape:cx=\\\"10.656564\\\"\\n inkscape:cy=\\\"13.670445\\\"\\n inkscape:current-layer=\\\"svg10\\\" />\\n <g\\n id=\\\"g8\\\"\\n style=\\\"fill:none;fill-rule:evenodd\\\"\\n transform=\\\"matrix(0.8751128,0,0,0.8751128,1.3360704,0.91121972)\\\">\\n <g\\n id=\\\"g6\\\"\\n style=\\\"fill:#353535\\\">\\n <g\\n transform=\\\"translate(2,5.6)\\\"\\n id=\\\"g4\\\">\\n <path\\n d=\\\"M 10.5,0.1 15.7,4 v 1.3 l -5.6,4 C 10,9.5 9.8,9.5 9.6,9.5 9.3,9.4 9,8.8 9,8.5 L 9.3,8.1 14,4.6 9.5,1.4 9.3,1.2 C 9.2,0.9 9.2,0.6 9.3,0.4 9.5,0.2 9.8,0 10.1,0 a 0.8,0.8 0 0 1 0.4,0.1 z M 5.3,0.1 0,4 v 1.3 l 5.6,4 C 5.7,9.5 5.9,9.5 6.1,9.5 6.4,9.4 6.8,8.8 6.7,8.5 6.7,8.4 6.7,8.2 6.5,8.1 L 1.5,4.6 6.2,1.4 6.4,1.2 C 6.5,0.9 6.5,0.6 6.4,0.4 6.2,0.2 5.9,0 5.6,0 A 0.8,0.8 0 0 0 5.3,0.1 Z\\\"\\n id=\\\"path2\\\"\\n inkscape:connector-curvature=\\\"0\\\" />\\n </g>\\n </g>\\n </g>\\n <path\\n style=\\\"color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#353535;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.09228408;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate\\\"\\n d=\\\"M 0.22004104,0.22004104 V 0.76600468 19.779959 H 19.779959 V 0.22004104 Z M 1.3119682,1.3119682 H 18.688032 V 18.688032 H 1.3119682 Z\\\"\\n id=\\\"rect3722\\\"\\n inkscape:connector-curvature=\\\"0\\\" />\\n <metadata\\n id=\\\"metadata4596\\\">\\n <rdf:RDF>\\n <cc:Work\\n rdf:about=\\\"\\\">\\n <dc:title></dc:title>\\n <dc:format>image/svg+xml</dc:format>\\n <dc:type\\n rdf:resource=\\\"http://purl.org/dc/dcmitype/StillImage\\\" />\\n </cc:Work>\\n </rdf:RDF>\\n </metadata>\\n</svg>\\n\"","module.exports = \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\" width=\\\"20\\\"><path d=\\\"M124 334v14c84 139 279 139 362 0v-14c-83-139-278-139-362 0zm181 91c-46 0-83-38-83-84s37-83 83-83c47 0 84 37 84 83s-37 84-84 84zm42-84c0 23-19 42-42 42s-41-19-41-42 18-42 41-42 42 19 42 42zm83-254L312-32H37v512h127v-46H83V14h210l91 92v91h46V87z\\\"/></svg>\\n\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M3 6v3h4V6H3zm0 4v3h4v-3H3zm0 4v3h4v-3H3zm5 3h4v-3H8v3zm5 0h4v-3h-4v3zm4-4v-3h-4v3h4zm0-4V6h-4v3h4zm1.5 8a1.5 1.5 0 0 1-1.5 1.5H3A1.5 1.5 0 0 1 1.5 17V4c.222-.863 1.068-1.5 2-1.5h13c.932 0 1.778.637 2 1.5v13zM12 13v-3H8v3h4zm0-4V6H8v3h4z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2.5 1h15A1.5 1.5 0 0 1 19 2.5v15a1.5 1.5 0 0 1-1.5 1.5h-15A1.5 1.5 0 0 1 1 17.5v-15A1.5 1.5 0 0 1 2.5 1zM2 2v16h16V2H2z\\\" opacity=\\\".6\\\"/><path d=\\\"M18 7v1H2V7h16zm0 5v1H2v-1h16z\\\" opacity=\\\".6\\\"/><path d=\\\"M14 1v18a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V1a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1zm-2 1H8v4h4V2zm0 6H8v4h4V8zm0 6H8v4h4v-4z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2.5 1h15A1.5 1.5 0 0 1 19 2.5v15a1.5 1.5 0 0 1-1.5 1.5h-15A1.5 1.5 0 0 1 1 17.5v-15A1.5 1.5 0 0 1 2.5 1zM2 2v16h16V2H2z\\\" opacity=\\\".6\\\"/><path d=\\\"M7 2h1v16H7V2zm5 0h1v16h-1V2z\\\" opacity=\\\".6\\\"/><path d=\\\"M1 6h18a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1zm1 2v4h4V8H2zm6 0v4h4V8H8zm6 0v4h4V8h-4z\\\"/></svg>\"","module.exports = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2.5 1h15A1.5 1.5 0 0 1 19 2.5v15a1.5 1.5 0 0 1-1.5 1.5h-15A1.5 1.5 0 0 1 1 17.5v-15A1.5 1.5 0 0 1 2.5 1zM2 2v16h16V2H2z\\\" opacity=\\\".6\\\"/><path d=\\\"M7 2h1v16H7V2zm5 0h1v7h-1V2zm6 5v1H2V7h16zM8 12v1H2v-1h6z\\\" opacity=\\\".6\\\"/><path d=\\\"M7 7h12a1 1 0 0 1 1 1v11a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1zm1 2v9h10V9H8z\\\"/></svg>\"","module.exports = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\" standalone=\\\"no\\\"?>\\n<svg\\n xmlns:dc=\\\"http://purl.org/dc/elements/1.1/\\\"\\n xmlns:cc=\\\"http://creativecommons.org/ns#\\\"\\n xmlns:rdf=\\\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\\\"\\n xmlns:svg=\\\"http://www.w3.org/2000/svg\\\"\\n xmlns=\\\"http://www.w3.org/2000/svg\\\"\\n xmlns:sodipodi=\\\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\\\"\\n xmlns:inkscape=\\\"http://www.inkscape.org/namespaces/inkscape\\\"\\n viewBox=\\\"0 0 512 512\\\"\\n version=\\\"1.1\\\"\\n id=\\\"svg4\\\"\\n sodipodi:docname=\\\"wysiwyg.svg\\\"\\n inkscape:version=\\\"0.92.3 (2405546, 2018-03-11)\\\">\\n <metadata\\n id=\\\"metadata10\\\">\\n <rdf:RDF>\\n <cc:Work\\n rdf:about=\\\"\\\">\\n <dc:format>image/svg+xml</dc:format>\\n <dc:type\\n rdf:resource=\\\"http://purl.org/dc/dcmitype/StillImage\\\" />\\n </cc:Work>\\n </rdf:RDF>\\n </metadata>\\n <defs\\n id=\\\"defs8\\\" />\\n <sodipodi:namedview\\n pagecolor=\\\"#ffffff\\\"\\n bordercolor=\\\"#666666\\\"\\n borderopacity=\\\"1\\\"\\n objecttolerance=\\\"10\\\"\\n gridtolerance=\\\"10\\\"\\n guidetolerance=\\\"10\\\"\\n inkscape:pageopacity=\\\"0\\\"\\n inkscape:pageshadow=\\\"2\\\"\\n inkscape:window-width=\\\"640\\\"\\n inkscape:window-height=\\\"480\\\"\\n id=\\\"namedview6\\\"\\n showgrid=\\\"false\\\"\\n inkscape:zoom=\\\"1.3037281\\\"\\n inkscape:cx=\\\"252.52639\\\"\\n inkscape:cy=\\\"155.86537\\\"\\n inkscape:current-layer=\\\"svg4\\\" />\\n <path\\n d=\\\"m 166.9714,230.61312 h 185 v 31 h -185 z m 1,-61 h 185 v 32 h -185 z m 0,-61 h 185 v 32 h -185 z m 289,5 -118,-118.0000009 H 63.971404 V 507.61312 H 457.9714 v -394 z m -347,348 V 41.613119 h 210 l 92,92.000001 v 328 z\\\"\\n id=\\\"path2\\\"\\n inkscape:connector-curvature=\\\"0\\\"\\n sodipodi:nodetypes=\\\"cccccccccccccccccccccccccccc\\\" />\\n <rect\\n style=\\\"fill:#000000;fill-opacity:1;stroke:#353535;stroke-opacity:1\\\"\\n id=\\\"rect832\\\"\\n width=\\\"184.08746\\\"\\n height=\\\"112.75357\\\"\\n x=\\\"169.51387\\\"\\n y=\\\"313.33896\\\" />\\n</svg>\\n\"","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./placeholder.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./placeholder.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./placeholder.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck.ck-placeholder:before,.ck .ck-placeholder:before{content:attr(data-placeholder);pointer-events:none;cursor:text;color:var(--ck-color-engine-placeholder-text)}\"","\n/**\n * When source maps are enabled, `style-loader` uses a link element with a data-uri to\n * embed the css on the page. This breaks all relative urls because now they are relative to a\n * bundle instead of the current page.\n *\n * One solution is to only use full urls, but that may be impossible.\n *\n * Instead, this function \"fixes\" the relative urls to be absolute according to the current page location.\n *\n * A rudimentary test suite is located at `test/fixUrls.js` and can be run via the `npm test` command.\n *\n */\n\nmodule.exports = function (css) {\n // get current location\n var location = typeof window !== \"undefined\" && window.location;\n\n if (!location) {\n throw new Error(\"fixUrls requires window.location\");\n }\n\n\t// blank or null?\n\tif (!css || typeof css !== \"string\") {\n\t return css;\n }\n\n var baseUrl = location.protocol + \"//\" + location.host;\n var currentDir = baseUrl + location.pathname.replace(/\\/[^\\/]*$/, \"/\");\n\n\t// convert each url(...)\n\t/*\n\tThis regular expression is just a way to recursively match brackets within\n\ta string.\n\n\t /url\\s*\\( = Match on the word \"url\" with any whitespace after it and then a parens\n\t ( = Start a capturing group\n\t (?: = Start a non-capturing group\n\t [^)(] = Match anything that isn't a parentheses\n\t | = OR\n\t \\( = Match a start parentheses\n\t (?: = Start another non-capturing groups\n\t [^)(]+ = Match anything that isn't a parentheses\n\t | = OR\n\t \\( = Match a start parentheses\n\t [^)(]* = Match anything that isn't a parentheses\n\t \\) = Match a end parentheses\n\t ) = End Group\n *\\) = Match anything and then a close parens\n ) = Close non-capturing group\n * = Match anything\n ) = Close capturing group\n\t \\) = Match a close parens\n\n\t /gi = Get all matches, not the first. Be case insensitive.\n\t */\n\tvar fixedCss = css.replace(/url\\s*\\(((?:[^)(]|\\((?:[^)(]+|\\([^)(]*\\))*\\))*)\\)/gi, function(fullMatch, origUrl) {\n\t\t// strip quotes (if they exist)\n\t\tvar unquotedOrigUrl = origUrl\n\t\t\t.trim()\n\t\t\t.replace(/^\"(.*)\"$/, function(o, $1){ return $1; })\n\t\t\t.replace(/^'(.*)'$/, function(o, $1){ return $1; });\n\n\t\t// already a full url? no change\n\t\tif (/^(#|data:|http:\\/\\/|https:\\/\\/|file:\\/\\/\\/|\\s*$)/i.test(unquotedOrigUrl)) {\n\t\t return fullMatch;\n\t\t}\n\n\t\t// convert the url to a full url\n\t\tvar newUrl;\n\n\t\tif (unquotedOrigUrl.indexOf(\"//\") === 0) {\n\t\t \t//TODO: should we add protocol?\n\t\t\tnewUrl = unquotedOrigUrl;\n\t\t} else if (unquotedOrigUrl.indexOf(\"/\") === 0) {\n\t\t\t// path should be relative to the base url\n\t\t\tnewUrl = baseUrl + unquotedOrigUrl; // already starts with '/'\n\t\t} else {\n\t\t\t// path should be relative to current directory\n\t\t\tnewUrl = currentDir + unquotedOrigUrl.replace(/^\\.\\//, \"\"); // Strip leading './'\n\t\t}\n\n\t\t// send back the fixed url(...)\n\t\treturn \"url(\" + JSON.stringify(newUrl) + \")\";\n\t});\n\n\t// send back the fixed css\n\treturn fixedCss;\n};\n","\nvar content = require(\"!!../../../../postcss-loader/src/index.js??ref--5-1!./globals.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../../postcss-loader/src/index.js??ref--5-1!./globals.css\", function() {\n\t\tvar newContent = require(\"!!../../../../postcss-loader/src/index.js??ref--5-1!./globals.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck-hidden{display:none!important}.ck.ck-reset,.ck.ck-reset_all,.ck.ck-reset_all *{box-sizing:border-box;width:auto;height:auto;position:static}:root{--ck-z-default:1;--ck-z-modal:calc(var(--ck-z-default) + 999);--ck-color-base-foreground:#fafafa;--ck-color-base-background:#fff;--ck-color-base-border:#c4c4c4;--ck-color-base-action:#61b045;--ck-color-base-focus:#6cb5f9;--ck-color-base-text:#333;--ck-color-base-active:#198cf0;--ck-color-base-active-focus:#0e7fe1;--ck-color-base-error:#db3700;--ck-color-focus-border:#47a4f5;--ck-color-focus-shadow:rgba(119,186,248,0.5);--ck-color-focus-disabled-shadow:rgba(119,186,248,0.3);--ck-color-focus-error-shadow:rgba(255,64,31,0.3);--ck-color-text:var(--ck-color-base-text);--ck-color-shadow-drop:rgba(0,0,0,0.15);--ck-color-shadow-drop-active:rgba(0,0,0,0.2);--ck-color-shadow-inner:rgba(0,0,0,0.1);--ck-color-button-default-background:transparent;--ck-color-button-default-hover-background:#e6e6e6;--ck-color-button-default-active-background:#d9d9d9;--ck-color-button-default-active-shadow:#bfbfbf;--ck-color-button-default-disabled-background:transparent;--ck-color-button-on-background:#dedede;--ck-color-button-on-hover-background:#c4c4c4;--ck-color-button-on-active-background:#bababa;--ck-color-button-on-active-shadow:#a1a1a1;--ck-color-button-on-disabled-background:#dedede;--ck-color-button-action-background:var(--ck-color-base-action);--ck-color-button-action-hover-background:#579e3d;--ck-color-button-action-active-background:#53973b;--ck-color-button-action-active-shadow:#498433;--ck-color-button-action-disabled-background:#7ec365;--ck-color-button-action-text:var(--ck-color-base-background);--ck-color-button-save:#008a00;--ck-color-button-cancel:#db3700;--ck-color-switch-button-off-background:#b0b0b0;--ck-color-switch-button-on-background:var(--ck-color-button-action-background);--ck-color-switch-button-inner-background:var(--ck-color-base-background);--ck-color-dropdown-panel-background:var(--ck-color-base-background);--ck-color-dropdown-panel-border:var(--ck-color-base-border);--ck-color-input-background:var(--ck-color-base-background);--ck-color-input-border:#c7c7c7;--ck-color-input-error-border:var(--ck-color-base-error);--ck-color-input-text:var(--ck-color-base-text);--ck-color-input-disabled-background:#f2f2f2;--ck-color-input-disabled-border:#c7c7c7;--ck-color-input-disabled-text:#5c5c5c;--ck-color-list-background:var(--ck-color-base-background);--ck-color-list-button-hover-background:var(--ck-color-button-default-hover-background);--ck-color-list-button-on-background:var(--ck-color-base-active);--ck-color-list-button-on-background-focus:var(--ck-color-base-active-focus);--ck-color-list-button-on-text:var(--ck-color-base-background);--ck-color-panel-background:var(--ck-color-base-background);--ck-color-panel-border:var(--ck-color-base-border);--ck-color-toolbar-background:var(--ck-color-base-foreground);--ck-color-toolbar-border:var(--ck-color-base-border);--ck-color-tooltip-background:var(--ck-color-base-text);--ck-color-tooltip-text:var(--ck-color-base-background);--ck-color-engine-placeholder-text:#707070;--ck-color-upload-bar-background:#6cb5f9;--ck-color-upload-infinite-background:rgba(0,0,0,0.1);--ck-color-link-default:#0000f0;--ck-color-link-selected-background:rgba(31,177,255,0.1);--ck-disabled-opacity:.5;--ck-focus-outer-shadow-geometry:0 0 0 3px;--ck-focus-outer-shadow:var(--ck-focus-outer-shadow-geometry) var(--ck-color-focus-shadow);--ck-focus-disabled-outer-shadow:var(--ck-focus-outer-shadow-geometry) var(--ck-color-focus-disabled-shadow);--ck-focus-error-outer-shadow:var(--ck-focus-outer-shadow-geometry) var(--ck-color-focus-error-shadow);--ck-focus-ring:1px solid var(--ck-color-focus-border);--ck-font-size-base:13px;--ck-line-height-base:1.84615;--ck-font-face:Helvetica,Arial,Tahoma,Verdana,Sans-Serif;--ck-font-size-tiny:0.7em;--ck-font-size-small:0.75em;--ck-font-size-normal:1em;--ck-font-size-big:1.4em;--ck-font-size-large:1.8em;--ck-ui-component-min-height:2.3em}.ck.ck-reset,.ck.ck-reset_all,.ck.ck-reset_all *{margin:0;padding:0;border:0;background:transparent;text-decoration:none;vertical-align:middle;transition:none;word-wrap:break-word}.ck.ck-reset_all,.ck.ck-reset_all *{border-collapse:collapse;font:normal normal normal var(--ck-font-size-base)/var(--ck-line-height-base) var(--ck-font-face);color:var(--ck-color-text);text-align:left;white-space:nowrap;cursor:auto;float:none}.ck.ck-reset_all .ck-rtl *{text-align:right}.ck.ck-reset_all iframe{vertical-align:inherit}.ck.ck-reset_all textarea{white-space:pre-wrap}.ck.ck-reset_all input[type=password],.ck.ck-reset_all input[type=text],.ck.ck-reset_all textarea{cursor:text}.ck.ck-reset_all input[type=password][disabled],.ck.ck-reset_all input[type=text][disabled],.ck.ck-reset_all textarea[disabled]{cursor:default}.ck.ck-reset_all fieldset{padding:10px;border:2px groove #dfdee3}.ck.ck-reset_all button::-moz-focus-inner{padding:0;border:0}:root{--ck-border-radius:2px;--ck-inner-shadow:2px 2px 3px var(--ck-color-shadow-inner) inset;--ck-drop-shadow:0 1px 2px 1px var(--ck-color-shadow-drop);--ck-drop-shadow-active:0 3px 6px 1px var(--ck-color-shadow-drop-active);--ck-spacing-unit:0.6em;--ck-spacing-large:calc(var(--ck-spacing-unit)*1.5);--ck-spacing-standard:var(--ck-spacing-unit);--ck-spacing-medium:calc(var(--ck-spacing-unit)*0.8);--ck-spacing-small:calc(var(--ck-spacing-unit)*0.5);--ck-spacing-tiny:calc(var(--ck-spacing-unit)*0.3);--ck-spacing-extra-tiny:calc(var(--ck-spacing-unit)*0.16)}\"","\nvar content = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./editorui.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./editorui.css\", function() {\n\t\tvar newContent = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./editorui.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck.ck-editor__editable:not(.ck-editor__nested-editable){border-radius:0}.ck-rounded-corners .ck.ck-editor__editable:not(.ck-editor__nested-editable),.ck.ck-editor__editable:not(.ck-editor__nested-editable).ck-rounded-corners{border-radius:var(--ck-border-radius)}.ck.ck-editor__editable:not(.ck-editor__nested-editable).ck-focused{outline:none;border:var(--ck-focus-ring);box-shadow:var(--ck-inner-shadow),0 0}.ck.ck-editor__editable_inline{overflow:auto;padding:0 var(--ck-spacing-standard);border:1px solid transparent}.ck.ck-editor__editable_inline>:first-child{margin-top:var(--ck-spacing-large)}.ck.ck-editor__editable_inline>:last-child{margin-bottom:var(--ck-spacing-large)}.ck.ck-balloon-panel.ck-toolbar-container[class*=arrow_n]:after{border-bottom-color:var(--ck-color-base-foreground)}.ck.ck-balloon-panel.ck-toolbar-container[class*=arrow_s]:after{border-top-color:var(--ck-color-base-foreground)}\"","\nvar content = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./label.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./label.css\", function() {\n\t\tvar newContent = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./label.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck.ck-label{display:block}.ck.ck-voice-label{display:none}.ck.ck-label{font-weight:700}\"","\nvar content = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./stickypanel.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./stickypanel.css\", function() {\n\t\tvar newContent = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./stickypanel.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck.ck-sticky-panel .ck-sticky-panel__content_sticky{z-index:var(--ck-z-modal);position:fixed;top:0}.ck.ck-sticky-panel .ck-sticky-panel__content_sticky_bottom-limit{top:auto;position:absolute}.ck.ck-sticky-panel .ck-sticky-panel__content_sticky{box-shadow:var(--ck-drop-shadow),0 0;border-width:0 1px 1px;border-top-left-radius:0;border-top-right-radius:0}\"","\nvar content = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./toolbar.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./toolbar.css\", function() {\n\t\tvar newContent = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./toolbar.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck.ck-toolbar{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;display:flex;flex-flow:row wrap;align-items:center}.ck.ck-toolbar.ck-toolbar_vertical{flex-direction:column}.ck.ck-toolbar.ck-toolbar_floating{flex-wrap:nowrap}.ck.ck-toolbar__separator{display:inline-block}.ck.ck-toolbar__newline{display:block;width:100%}.ck.ck-toolbar{border-radius:0}.ck-rounded-corners .ck.ck-toolbar,.ck.ck-toolbar.ck-rounded-corners{border-radius:var(--ck-border-radius)}.ck.ck-toolbar{background:var(--ck-color-toolbar-background);padding:0 var(--ck-spacing-small);border:1px solid var(--ck-color-toolbar-border)}.ck.ck-toolbar>*{margin-right:var(--ck-spacing-small);margin-top:var(--ck-spacing-small);margin-bottom:var(--ck-spacing-small)}.ck.ck-toolbar.ck-toolbar_vertical{padding:0}.ck.ck-toolbar.ck-toolbar_vertical>*{width:100%;margin:0;border-radius:0;border:0}.ck.ck-toolbar>:last-child{margin-right:0}.ck-toolbar-container .ck.ck-toolbar{border:0}.ck.ck-toolbar__separator{align-self:stretch;width:1px;margin-top:0;margin-bottom:0;background:var(--ck-color-toolbar-border)}.ck.ck-toolbar__newline{margin:0}\"","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./classiceditor.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./classiceditor.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./classiceditor.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck.ck-editor{position:relative}.ck.ck-editor .ck-editor__top .ck-sticky-panel .ck-toolbar{z-index:var(--ck-z-modal)}.ck.ck-editor__top .ck-sticky-panel .ck-toolbar{border-radius:0}.ck-rounded-corners .ck.ck-editor__top .ck-sticky-panel .ck-toolbar,.ck.ck-editor__top .ck-sticky-panel .ck-toolbar.ck-rounded-corners{border-radius:var(--ck-border-radius);border-bottom-left-radius:0;border-bottom-right-radius:0}.ck.ck-editor__top .ck-sticky-panel .ck-toolbar{border-bottom-width:0}.ck.ck-editor__top .ck-sticky-panel .ck-sticky-panel__content_sticky .ck-toolbar{border-bottom-width:1px;border-radius:0}.ck-rounded-corners .ck.ck-editor__top .ck-sticky-panel .ck-sticky-panel__content_sticky .ck-toolbar,.ck.ck-editor__top .ck-sticky-panel .ck-sticky-panel__content_sticky .ck-toolbar.ck-rounded-corners{border-radius:var(--ck-border-radius);border-radius:0}.ck.ck-editor__main>.ck-editor__editable{background:var(--ck-color-base-background);border-radius:0}.ck-rounded-corners .ck.ck-editor__main>.ck-editor__editable,.ck.ck-editor__main>.ck-editor__editable.ck-rounded-corners{border-radius:var(--ck-border-radius);border-top-left-radius:0;border-top-right-radius:0}.ck.ck-editor__main>.ck-editor__editable:not(.ck-focused){border-color:var(--ck-color-base-border)}\"","\nvar content = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./icon.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./icon.css\", function() {\n\t\tvar newContent = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./icon.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck.ck-icon{vertical-align:middle}:root{--ck-icon-size:calc(var(--ck-line-height-base)*var(--ck-font-size-normal))}.ck.ck-icon{width:var(--ck-icon-size);height:var(--ck-icon-size);font-size:.8333350694em;will-change:transform}.ck.ck-icon,.ck.ck-icon *{color:inherit;cursor:inherit}.ck.ck-icon :not([fill]){fill:currentColor}\"","\nvar content = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./tooltip.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./tooltip.css\", function() {\n\t\tvar newContent = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./tooltip.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck.ck-tooltip,.ck.ck-tooltip .ck-tooltip__text:after{position:absolute;pointer-events:none;-webkit-backface-visibility:hidden}.ck-tooltip{visibility:hidden;opacity:0;display:none;z-index:var(--ck-z-modal)}.ck-tooltip .ck-tooltip__text{display:inline-block}.ck-tooltip .ck-tooltip__text:after{content:\\\"\\\";width:0;height:0}:root{--ck-tooltip-arrow-size:5px}.ck.ck-tooltip{left:50%}.ck.ck-tooltip.ck-tooltip_s{bottom:calc(-1*var(--ck-tooltip-arrow-size));transform:translateY(100%)}.ck.ck-tooltip.ck-tooltip_s .ck-tooltip__text:after{top:calc(-1*var(--ck-tooltip-arrow-size));transform:translateX(-50%);border-left-color:transparent;border-bottom-color:var(--ck-color-tooltip-background);border-right-color:transparent;border-top-color:transparent;border-left-width:var(--ck-tooltip-arrow-size);border-bottom-width:var(--ck-tooltip-arrow-size);border-right-width:var(--ck-tooltip-arrow-size);border-top-width:0}.ck.ck-tooltip.ck-tooltip_n{top:calc(-1*var(--ck-tooltip-arrow-size));transform:translateY(-100%)}.ck.ck-tooltip.ck-tooltip_n .ck-tooltip__text:after{bottom:calc(-1*var(--ck-tooltip-arrow-size));transform:translateX(-50%);border-left-color:transparent;border-bottom-color:transparent;border-right-color:transparent;border-top-color:var(--ck-color-tooltip-background);border-left-width:var(--ck-tooltip-arrow-size);border-bottom-width:0;border-right-width:var(--ck-tooltip-arrow-size);border-top-width:var(--ck-tooltip-arrow-size)}.ck.ck-tooltip .ck-tooltip__text{border-radius:0}.ck-rounded-corners .ck.ck-tooltip .ck-tooltip__text,.ck.ck-tooltip .ck-tooltip__text.ck-rounded-corners{border-radius:var(--ck-border-radius)}.ck.ck-tooltip .ck-tooltip__text{font-size:.9em;line-height:1.5;color:var(--ck-color-tooltip-text);padding:var(--ck-spacing-small) var(--ck-spacing-medium);background:var(--ck-color-tooltip-background);position:relative;left:-50%}.ck.ck-tooltip .ck-tooltip__text:after{border-style:solid;left:50%}.ck.ck-tooltip,.ck.ck-tooltip .ck-tooltip__text:after{transition:opacity .2s ease-in-out .2s}\"","\nvar content = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./button.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./button.css\", function() {\n\t\tvar newContent = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./button.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck.ck-button,a.ck.ck-button{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.ck.ck-button .ck-tooltip,a.ck.ck-button .ck-tooltip{display:block}@media (hover:none){.ck.ck-button .ck-tooltip,a.ck.ck-button .ck-tooltip{display:none}}.ck.ck-button,a.ck.ck-button{position:relative;display:inline-flex;align-items:center;justify-content:left}.ck.ck-button.ck-button_with-text .ck-button__label,a.ck.ck-button.ck-button_with-text .ck-button__label{display:inline-block}.ck.ck-button:not(.ck-button_with-text),a.ck.ck-button:not(.ck-button_with-text){justify-content:center}.ck.ck-button:hover .ck-tooltip,a.ck.ck-button:hover .ck-tooltip{visibility:visible;opacity:1}.ck.ck-button .ck-button__label,.ck.ck-button:focus:not(:hover) .ck-tooltip,a.ck.ck-button .ck-button__label,a.ck.ck-button:focus:not(:hover) .ck-tooltip{display:none}.ck.ck-button,a.ck.ck-button{background:var(--ck-color-button-default-background)}.ck.ck-button:not(.ck-disabled):hover,a.ck.ck-button:not(.ck-disabled):hover{background:var(--ck-color-button-default-hover-background)}.ck.ck-button:not(.ck-disabled):active,a.ck.ck-button:not(.ck-disabled):active{background:var(--ck-color-button-default-active-background);box-shadow:inset 0 2px 2px var(--ck-color-button-default-active-shadow)}.ck.ck-button.ck-disabled,a.ck.ck-button.ck-disabled{background:var(--ck-color-button-default-disabled-background)}.ck.ck-button,a.ck.ck-button{border-radius:0}.ck-rounded-corners .ck.ck-button,.ck-rounded-corners a.ck.ck-button,.ck.ck-button.ck-rounded-corners,a.ck.ck-button.ck-rounded-corners{border-radius:var(--ck-border-radius)}.ck.ck-button,a.ck.ck-button{white-space:nowrap;cursor:default;vertical-align:middle;padding:var(--ck-spacing-tiny);text-align:center;min-width:var(--ck-ui-component-min-height);min-height:var(--ck-ui-component-min-height);line-height:1;font-size:inherit;border:1px solid transparent;transition:box-shadow .2s ease-in-out;-webkit-appearance:none}.ck.ck-button:active,.ck.ck-button:focus,a.ck.ck-button:active,a.ck.ck-button:focus{outline:none;border:var(--ck-focus-ring);box-shadow:var(--ck-focus-outer-shadow),0 0;border-color:transparent}.ck.ck-button.ck-disabled:active,.ck.ck-button.ck-disabled:focus,a.ck.ck-button.ck-disabled:active,a.ck.ck-button.ck-disabled:focus{box-shadow:var(--ck-focus-disabled-outer-shadow),0 0}.ck.ck-button.ck-disabled .ck-button__icon,a.ck.ck-button.ck-disabled .ck-button__icon{opacity:var(--ck-disabled-opacity)}.ck.ck-button.ck-disabled .ck-button__label,a.ck.ck-button.ck-disabled .ck-button__label{opacity:var(--ck-disabled-opacity)}.ck.ck-button.ck-button_with-text,a.ck.ck-button.ck-button_with-text{padding:var(--ck-spacing-tiny) var(--ck-spacing-standard)}.ck.ck-button.ck-button_with-text .ck-button__icon,a.ck.ck-button.ck-button_with-text .ck-button__icon{margin-left:calc(-1*var(--ck-spacing-small));margin-right:var(--ck-spacing-small)}.ck.ck-button.ck-on,a.ck.ck-button.ck-on{background:var(--ck-color-button-on-background)}.ck.ck-button.ck-on:not(.ck-disabled):hover,a.ck.ck-button.ck-on:not(.ck-disabled):hover{background:var(--ck-color-button-on-hover-background)}.ck.ck-button.ck-on:not(.ck-disabled):active,a.ck.ck-button.ck-on:not(.ck-disabled):active{background:var(--ck-color-button-on-active-background);box-shadow:inset 0 2px 2px var(--ck-color-button-on-active-shadow)}.ck.ck-button.ck-on.ck-disabled,a.ck.ck-button.ck-on.ck-disabled{background:var(--ck-color-button-on-disabled-background)}.ck.ck-button.ck-button-save,a.ck.ck-button.ck-button-save{color:var(--ck-color-button-save)}.ck.ck-button.ck-button-cancel,a.ck.ck-button.ck-button-cancel{color:var(--ck-color-button-cancel)}.ck.ck-button .ck-button__icon use,.ck.ck-button .ck-button__icon use *,a.ck.ck-button .ck-button__icon use,a.ck.ck-button .ck-button__icon use *{color:inherit}.ck.ck-button .ck-button__label,a.ck.ck-button .ck-button__label{font-size:inherit;font-weight:inherit;color:inherit;cursor:inherit;vertical-align:middle}.ck.ck-button-action,a.ck.ck-button-action{background:var(--ck-color-button-action-background)}.ck.ck-button-action:not(.ck-disabled):hover,a.ck.ck-button-action:not(.ck-disabled):hover{background:var(--ck-color-button-action-hover-background)}.ck.ck-button-action:not(.ck-disabled):active,a.ck.ck-button-action:not(.ck-disabled):active{background:var(--ck-color-button-action-active-background);box-shadow:inset 0 2px 2px var(--ck-color-button-action-active-shadow)}.ck.ck-button-action.ck-disabled,a.ck.ck-button-action.ck-disabled{background:var(--ck-color-button-action-disabled-background)}.ck.ck-button-action,a.ck.ck-button-action{color:var(--ck-color-button-action-text)}.ck.ck-button-bold,a.ck.ck-button-bold{font-weight:700}\"","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./widget.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./widget.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./widget.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck .ck-widget.ck-widget_with-selection-handler{position:relative}.ck .ck-widget.ck-widget_with-selection-handler .ck-widget__selection-handler{visibility:hidden;position:absolute}.ck .ck-widget.ck-widget_with-selection-handler .ck-widget__selection-handler .ck-icon{display:block}.ck .ck-widget.ck-widget_with-selection-handler.ck-widget_selected .ck-widget__selection-handler,.ck .ck-widget.ck-widget_with-selection-handler:hover .ck-widget__selection-handler{visibility:visible}:root{--ck-widget-outline-thickness:3px;--ck-widget-handler-icon-size:16px;--ck-widget-handler-animation-duration:200ms;--ck-widget-handler-animation-curve:ease;--ck-color-widget-blurred-border:#dedede;--ck-color-widget-hover-border:#ffc83d;--ck-color-widget-editable-focus-background:var(--ck-color-base-background);--ck-color-widget-drag-handler-icon-color:var(--ck-color-base-background)}.ck .ck-widget{outline-width:var(--ck-widget-outline-thickness);outline-style:solid;outline-color:transparent;transition:outline-color var(--ck-widget-handler-animation-duration) var(--ck-widget-handler-animation-curve)}.ck .ck-widget.ck-widget_selected,.ck .ck-widget.ck-widget_selected:hover{outline:var(--ck-widget-outline-thickness) solid var(--ck-color-focus-border)}.ck .ck-widget:hover{outline-color:var(--ck-color-widget-hover-border)}.ck .ck-editor__nested-editable{border:1px solid transparent}.ck .ck-editor__nested-editable.ck-editor__nested-editable_focused,.ck .ck-editor__nested-editable:focus{outline:none;border:var(--ck-focus-ring);box-shadow:var(--ck-inner-shadow),0 0;background-color:var(--ck-color-widget-editable-focus-background)}.ck-editor__editable>.ck-widget.ck-widget_with-selection-handler:first-child,.ck-editor__editable blockquote>.ck-widget.ck-widget_with-selection-handler:first-child{margin-top:calc(1em + var(--ck-widget-handler-icon-size))}.ck .ck-widget.ck-widget_with-selection-handler .ck-widget__selection-handler{padding:4px;box-sizing:border-box;background-color:transparent;opacity:0;transition:background-color var(--ck-widget-handler-animation-duration) var(--ck-widget-handler-animation-curve),visibility var(--ck-widget-handler-animation-duration) var(--ck-widget-handler-animation-curve),opacity var(--ck-widget-handler-animation-duration) var(--ck-widget-handler-animation-curve);border-radius:var(--ck-border-radius) var(--ck-border-radius) 0 0;transform:translateY(-100%);left:calc(0px - var(--ck-widget-outline-thickness))}.ck .ck-widget.ck-widget_with-selection-handler .ck-widget__selection-handler:hover .ck-icon .ck-icon__selected-indicator{opacity:1}.ck .ck-widget.ck-widget_with-selection-handler .ck-widget__selection-handler .ck-icon{width:var(--ck-widget-handler-icon-size);height:var(--ck-widget-handler-icon-size);color:var(--ck-color-widget-drag-handler-icon-color)}.ck .ck-widget.ck-widget_with-selection-handler .ck-widget__selection-handler .ck-icon .ck-icon__selected-indicator{opacity:0;transition:opacity .3s var(--ck-widget-handler-animation-curve)}.ck .ck-widget.ck-widget_with-selection-handler.ck-widget_selected .ck-widget__selection-handler,.ck .ck-widget.ck-widget_with-selection-handler.ck-widget_selected:hover .ck-widget__selection-handler{opacity:1;background-color:var(--ck-color-focus-border)}.ck .ck-widget.ck-widget_with-selection-handler.ck-widget_selected .ck-widget__selection-handler .ck-icon .ck-icon__selected-indicator,.ck .ck-widget.ck-widget_with-selection-handler.ck-widget_selected:hover .ck-widget__selection-handler .ck-icon .ck-icon__selected-indicator{opacity:1}.ck .ck-widget.ck-widget_with-selection-handler:hover .ck-widget__selection-handler{opacity:1;background-color:var(--ck-color-widget-hover-border)}.ck-editor__editable.ck-blurred .ck-widget.ck-widget_selected,.ck-editor__editable.ck-blurred .ck-widget.ck-widget_selected:hover{outline-color:var(--ck-color-widget-blurred-border)}.ck-editor__editable.ck-blurred .ck-widget.ck-widget_selected .ck-widget__selection-handler,.ck-editor__editable.ck-blurred .ck-widget.ck-widget_selected .ck-widget__selection-handler:hover,.ck-editor__editable.ck-blurred .ck-widget.ck-widget_selected:hover .ck-widget__selection-handler,.ck-editor__editable.ck-blurred .ck-widget.ck-widget_selected:hover .ck-widget__selection-handler:hover{background:var(--ck-color-widget-blurred-border)}.ck-editor__editable.ck-read-only .ck-widget{--ck-widget-outline-thickness:0}\"","\nvar content = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./balloonpanel.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./balloonpanel.css\", function() {\n\t\tvar newContent = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./balloonpanel.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \":root{--ck-balloon-panel-arrow-z-index:calc(var(--ck-z-default) - 3)}.ck.ck-balloon-panel{display:none;position:absolute;z-index:var(--ck-z-modal)}.ck.ck-balloon-panel.ck-balloon-panel_with-arrow:after,.ck.ck-balloon-panel.ck-balloon-panel_with-arrow:before{content:\\\"\\\";position:absolute}.ck.ck-balloon-panel.ck-balloon-panel_with-arrow:before{z-index:var(--ck-balloon-panel-arrow-z-index)}.ck.ck-balloon-panel.ck-balloon-panel_with-arrow:after{z-index:calc(var(--ck-balloon-panel-arrow-z-index) + 1)}.ck.ck-balloon-panel[class*=arrow_n]:before{z-index:var(--ck-balloon-panel-arrow-z-index)}.ck.ck-balloon-panel[class*=arrow_n]:after{z-index:calc(var(--ck-balloon-panel-arrow-z-index) + 1)}.ck.ck-balloon-panel[class*=arrow_s]:before{z-index:var(--ck-balloon-panel-arrow-z-index)}.ck.ck-balloon-panel[class*=arrow_s]:after{z-index:calc(var(--ck-balloon-panel-arrow-z-index) + 1)}.ck.ck-balloon-panel.ck-balloon-panel_visible{display:block}:root{--ck-balloon-arrow-offset:2px;--ck-balloon-arrow-height:10px;--ck-balloon-arrow-half-width:8px}.ck.ck-balloon-panel{border-radius:0}.ck-rounded-corners .ck.ck-balloon-panel,.ck.ck-balloon-panel.ck-rounded-corners{border-radius:var(--ck-border-radius)}.ck.ck-balloon-panel{box-shadow:var(--ck-drop-shadow),0 0;min-height:15px;background:var(--ck-color-panel-background);border:1px solid var(--ck-color-panel-border)}.ck.ck-balloon-panel.ck-balloon-panel_with-arrow:after,.ck.ck-balloon-panel.ck-balloon-panel_with-arrow:before{width:0;height:0;border-style:solid}.ck.ck-balloon-panel[class*=arrow_n]:after,.ck.ck-balloon-panel[class*=arrow_n]:before{border-left-width:var(--ck-balloon-arrow-half-width);border-bottom-width:var(--ck-balloon-arrow-height);border-right-width:var(--ck-balloon-arrow-half-width);border-top-width:0}.ck.ck-balloon-panel[class*=arrow_n]:before{border-bottom-color:var(--ck-color-panel-border)}.ck.ck-balloon-panel[class*=arrow_n]:after,.ck.ck-balloon-panel[class*=arrow_n]:before{border-left-color:transparent;border-right-color:transparent;border-top-color:transparent}.ck.ck-balloon-panel[class*=arrow_n]:after{border-bottom-color:var(--ck-color-panel-background);margin-top:var(--ck-balloon-arrow-offset)}.ck.ck-balloon-panel[class*=arrow_s]:after,.ck.ck-balloon-panel[class*=arrow_s]:before{border-left-width:var(--ck-balloon-arrow-half-width);border-bottom-width:0;border-right-width:var(--ck-balloon-arrow-half-width);border-top-width:var(--ck-balloon-arrow-height)}.ck.ck-balloon-panel[class*=arrow_s]:before{border-top-color:var(--ck-color-panel-border)}.ck.ck-balloon-panel[class*=arrow_s]:after,.ck.ck-balloon-panel[class*=arrow_s]:before{border-left-color:transparent;border-bottom-color:transparent;border-right-color:transparent}.ck.ck-balloon-panel[class*=arrow_s]:after{border-top-color:var(--ck-color-panel-background);margin-bottom:var(--ck-balloon-arrow-offset)}.ck.ck-balloon-panel.ck-balloon-panel_arrow_n:after,.ck.ck-balloon-panel.ck-balloon-panel_arrow_n:before{left:50%;margin-left:calc(-1*var(--ck-balloon-arrow-half-width));top:calc(-1*var(--ck-balloon-arrow-height))}.ck.ck-balloon-panel.ck-balloon-panel_arrow_nw:after,.ck.ck-balloon-panel.ck-balloon-panel_arrow_nw:before{left:calc(2*var(--ck-balloon-arrow-half-width));top:calc(-1*var(--ck-balloon-arrow-height))}.ck.ck-balloon-panel.ck-balloon-panel_arrow_ne:after,.ck.ck-balloon-panel.ck-balloon-panel_arrow_ne:before{right:calc(2*var(--ck-balloon-arrow-half-width));top:calc(-1*var(--ck-balloon-arrow-height))}.ck.ck-balloon-panel.ck-balloon-panel_arrow_s:after,.ck.ck-balloon-panel.ck-balloon-panel_arrow_s:before{left:50%;margin-left:calc(-1*var(--ck-balloon-arrow-half-width));bottom:calc(-1*var(--ck-balloon-arrow-height))}.ck.ck-balloon-panel.ck-balloon-panel_arrow_sw:after,.ck.ck-balloon-panel.ck-balloon-panel_arrow_sw:before{left:calc(2*var(--ck-balloon-arrow-half-width));bottom:calc(-1*var(--ck-balloon-arrow-height))}.ck.ck-balloon-panel.ck-balloon-panel_arrow_se:after,.ck.ck-balloon-panel.ck-balloon-panel_arrow_se:before{right:calc(2*var(--ck-balloon-arrow-half-width));bottom:calc(-1*var(--ck-balloon-arrow-height))}\"","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./imageuploadprogress.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./imageuploadprogress.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./imageuploadprogress.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck-content .image{position:relative;overflow:hidden}.ck-content .image .ck-progress-bar{position:absolute;top:0;left:0}:root{--ck-image-upload-progress-line-width:30px}.ck-content .image.ck-appear{animation:fadeIn .7s}.ck-content .image .ck-progress-bar{height:2px;width:0;background:var(--ck-color-upload-bar-background);transition:width .1s}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}\"","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./imageuploadicon.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./imageuploadicon.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./imageuploadicon.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck-image-upload-complete-icon{display:block;position:absolute;top:10px;right:10px;border-radius:50%}.ck-image-upload-complete-icon:after{content:\\\"\\\";position:absolute}:root{--ck-color-image-upload-icon:#fff;--ck-color-image-upload-icon-background:#008a00;--ck-image-upload-icon-size:20px;--ck-image-upload-icon-width:2px}.ck-image-upload-complete-icon{width:var(--ck-image-upload-icon-size);height:var(--ck-image-upload-icon-size);opacity:0;background:var(--ck-color-image-upload-icon-background);animation-name:ck-upload-complete-icon-show,ck-upload-complete-icon-hide;animation-fill-mode:forwards,forwards;animation-duration:.5s,.5s;font-size:var(--ck-image-upload-icon-size);animation-delay:0ms,3s}.ck-image-upload-complete-icon:after{left:25%;top:50%;opacity:0;height:0;width:0;transform:scaleX(-1) rotate(135deg);transform-origin:left top;border-top:var(--ck-image-upload-icon-width) solid var(--ck-color-image-upload-icon);border-right:var(--ck-image-upload-icon-width) solid var(--ck-color-image-upload-icon);animation-name:ck-upload-complete-icon-check;animation-duration:.5s;animation-delay:.5s;animation-fill-mode:forwards;box-sizing:border-box}@keyframes ck-upload-complete-icon-show{0%{opacity:0}to{opacity:1}}@keyframes ck-upload-complete-icon-hide{0%{opacity:1}to{opacity:0}}@keyframes ck-upload-complete-icon-check{0%{opacity:1;width:0;height:0}33%{width:.3em;height:0}to{opacity:1;width:.3em;height:.45em}}\"","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./imageuploadloader.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./imageuploadloader.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./imageuploadloader.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck .ck-upload-placeholder-loader{position:absolute;display:flex;align-items:center;justify-content:center;top:0;left:0}.ck .ck-upload-placeholder-loader:before{content:\\\"\\\";position:relative}:root{--ck-color-upload-placeholder-loader:#b3b3b3;--ck-upload-placeholder-loader-size:32px}.ck .ck-image-upload-placeholder{width:100%;margin:0}.ck .ck-upload-placeholder-loader{width:100%;height:100%}.ck .ck-upload-placeholder-loader:before{width:var(--ck-upload-placeholder-loader-size);height:var(--ck-upload-placeholder-loader-size);border-radius:50%;border-top:3px solid var(--ck-color-upload-placeholder-loader);border-right:2px solid transparent;animation:ck-upload-placeholder-loader 1s linear infinite}@keyframes ck-upload-placeholder-loader{to{transform:rotate(1turn)}}\"","module.exports = \".ck-content code{background-color:hsla(0,0%,78%,.3);padding:.15em;border-radius:2px}\"","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./blockquote.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./blockquote.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./blockquote.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck-content blockquote{overflow:hidden;padding-right:1.5em;padding-left:1.5em;margin-left:0;font-style:italic;border-left:5px solid #ccc}\"","\nvar content = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./dropdown.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./dropdown.css\", function() {\n\t\tvar newContent = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./dropdown.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck.ck-dropdown{display:inline-block;position:relative}.ck.ck-dropdown .ck-dropdown__arrow{pointer-events:none;z-index:var(--ck-z-default)}.ck.ck-dropdown .ck-button.ck-dropdown__button{width:100%}.ck.ck-dropdown .ck-button.ck-dropdown__button.ck-on .ck-tooltip{display:none}.ck.ck-dropdown .ck-dropdown__panel{-webkit-backface-visibility:hidden;display:none;z-index:var(--ck-z-modal);position:absolute}.ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel-visible{display:inline-block;will-change:transform}.ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_ne,.ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_nw{bottom:100%}.ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_se,.ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_sw{transform:translate3d(0,100%,0)}.ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_ne,.ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_se{left:0}.ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_nw,.ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_sw{right:0}:root{--ck-dropdown-arrow-size:calc(0.5*var(--ck-icon-size))}.ck.ck-dropdown{font-size:inherit}.ck.ck-dropdown .ck-dropdown__arrow{right:var(--ck-spacing-standard);width:var(--ck-dropdown-arrow-size);margin-left:var(--ck-spacing-small)}.ck.ck-dropdown.ck-disabled .ck-dropdown__arrow{opacity:var(--ck-disabled-opacity)}.ck.ck-dropdown .ck-button.ck-dropdown__button:not(.ck-button_with-text){padding-left:var(--ck-spacing-small)}.ck.ck-dropdown .ck-button.ck-dropdown__button.ck-disabled .ck-button__label{opacity:var(--ck-disabled-opacity)}.ck.ck-dropdown .ck-button.ck-dropdown__button.ck-on{border-bottom-left-radius:0;border-bottom-right-radius:0}.ck.ck-dropdown .ck-button.ck-dropdown__button .ck-button__label{width:7em;overflow:hidden;text-overflow:ellipsis}.ck.ck-dropdown__panel{box-shadow:var(--ck-drop-shadow),0 0;border-radius:0}.ck-rounded-corners .ck.ck-dropdown__panel,.ck.ck-dropdown__panel.ck-rounded-corners{border-radius:var(--ck-border-radius);border-top-left-radius:0}.ck.ck-dropdown__panel{background:var(--ck-color-dropdown-panel-background);border:1px solid var(--ck-color-dropdown-panel-border);bottom:0;min-width:100%}\"","\nvar content = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./list.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./list.css\", function() {\n\t\tvar newContent = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./list.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck.ck-list{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;display:flex;flex-direction:column}.ck.ck-list .ck-list__item,.ck.ck-list .ck-list__separator{display:block}.ck.ck-list .ck-list__item>:focus{position:relative;z-index:var(--ck-z-default)}.ck.ck-list{border-radius:0}.ck-rounded-corners .ck.ck-list,.ck.ck-list.ck-rounded-corners{border-radius:var(--ck-border-radius)}.ck.ck-list{list-style-type:none;background:var(--ck-color-list-background)}.ck.ck-list__item{cursor:default;min-width:12em}.ck.ck-list__item .ck-button{min-height:unset;width:100%;text-align:left;border-radius:0;border:0;padding:calc(0.2*var(--ck-line-height-base)*var(--ck-font-size-base)) calc(0.4*var(--ck-line-height-base)*var(--ck-font-size-base))}.ck.ck-list__item .ck-button .ck-button__label{line-height:calc(1.2*var(--ck-line-height-base)*var(--ck-font-size-base))}.ck.ck-list__item .ck-button:active{box-shadow:none}.ck.ck-list__item .ck-button.ck-on{background:var(--ck-color-list-button-on-background);color:var(--ck-color-list-button-on-text)}.ck.ck-list__item .ck-button.ck-on:hover:not(ck-disabled){background:var(--ck-color-list-button-on-background-focus)}.ck.ck-list__item .ck-button.ck-on:active{box-shadow:none}.ck.ck-list__item .ck-button:hover:not(.ck-disabled){background:var(--ck-color-list-button-hover-background)}.ck.ck-list__item .ck-switchbutton.ck-on{background:var(--ck-color-list-background);color:inherit}.ck.ck-list__item .ck-switchbutton.ck-on:hover:not(ck-disabled){background:var(--ck-color-list-button-hover-background);color:inherit}.ck.ck-list__separator{height:1px;width:100%;background:var(--ck-color-base-border)}\"","\nvar content = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./switchbutton.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./switchbutton.css\", function() {\n\t\tvar newContent = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./switchbutton.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck.ck-button.ck-switchbutton .ck-button__toggle,.ck.ck-button.ck-switchbutton .ck-button__toggle .ck-button__toggle__inner{display:block}:root{--ck-switch-button-toggle-width:2.6153846154em;--ck-switch-button-toggle-inner-size:1.0769230769em;--ck-switch-button-toggle-spacing:1px}.ck.ck-button.ck-switchbutton .ck-button__label{margin-right:calc(2*var(--ck-spacing-large))}.ck.ck-button.ck-switchbutton.ck-disabled .ck-button__toggle{opacity:var(--ck-disabled-opacity)}.ck.ck-button.ck-switchbutton .ck-button__toggle{border-radius:0}.ck-rounded-corners .ck.ck-button.ck-switchbutton .ck-button__toggle,.ck.ck-button.ck-switchbutton .ck-button__toggle.ck-rounded-corners{border-radius:var(--ck-border-radius)}.ck.ck-button.ck-switchbutton .ck-button__toggle{margin-left:auto;transition:background .4s ease;width:var(--ck-switch-button-toggle-width);background:var(--ck-color-switch-button-off-background)}.ck.ck-button.ck-switchbutton .ck-button__toggle .ck-button__toggle__inner{border-radius:0}.ck-rounded-corners .ck.ck-button.ck-switchbutton .ck-button__toggle .ck-button__toggle__inner,.ck.ck-button.ck-switchbutton .ck-button__toggle .ck-button__toggle__inner.ck-rounded-corners{border-radius:var(--ck-border-radius);border-radius:calc(0.5*var(--ck-border-radius))}.ck.ck-button.ck-switchbutton .ck-button__toggle .ck-button__toggle__inner{margin:var(--ck-switch-button-toggle-spacing);width:var(--ck-switch-button-toggle-inner-size);height:var(--ck-switch-button-toggle-inner-size);background:var(--ck-color-switch-button-inner-background);transition:transform .3s ease}.ck.ck-button.ck-switchbutton.ck-on .ck-button__toggle{background:var(--ck-color-switch-button-on-background)}.ck.ck-button.ck-switchbutton.ck-on .ck-button__toggle .ck-button__toggle__inner{transform:translateX(1.3846153847em)}\"","\nvar content = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./toolbardropdown.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./toolbardropdown.css\", function() {\n\t\tvar newContent = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./toolbardropdown.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck.ck-toolbar-dropdown .ck-toolbar{flex-wrap:nowrap}.ck.ck-toolbar-dropdown .ck-dropdown__panel .ck-button:focus{z-index:calc(var(--ck-z-default) + 1)}.ck.ck-toolbar-dropdown .ck-toolbar{border:0}\"","\nvar content = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./listdropdown.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./listdropdown.css\", function() {\n\t\tvar newContent = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./listdropdown.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck.ck-dropdown .ck-dropdown__panel .ck-list{border-radius:0}.ck-rounded-corners .ck.ck-dropdown .ck-dropdown__panel .ck-list,.ck.ck-dropdown .ck-dropdown__panel .ck-list.ck-rounded-corners{border-radius:var(--ck-border-radius);border-top-left-radius:0}.ck.ck-dropdown .ck-dropdown__panel .ck-list .ck-list__item:first-child .ck-button{border-radius:0}.ck-rounded-corners .ck.ck-dropdown .ck-dropdown__panel .ck-list .ck-list__item:first-child .ck-button,.ck.ck-dropdown .ck-dropdown__panel .ck-list .ck-list__item:first-child .ck-button.ck-rounded-corners{border-radius:var(--ck-border-radius);border-top-left-radius:0;border-bottom-left-radius:0;border-bottom-right-radius:0}.ck.ck-dropdown .ck-dropdown__panel .ck-list .ck-list__item:last-child .ck-button{border-radius:0}.ck-rounded-corners .ck.ck-dropdown .ck-dropdown__panel .ck-list .ck-list__item:last-child .ck-button,.ck.ck-dropdown .ck-dropdown__panel .ck-list .ck-list__item:last-child .ck-button.ck-rounded-corners{border-radius:var(--ck-border-radius);border-top-left-radius:0;border-top-right-radius:0}\"","module.exports = \".ck.ck-heading_heading1{font-size:20px}.ck.ck-heading_heading2{font-size:17px}.ck.ck-heading_heading3{font-size:14px}.ck[class*=ck-heading_heading]{font-weight:700}.ck.ck-dropdown.ck-heading-dropdown .ck-dropdown__button .ck-button__label{width:8em}.ck.ck-dropdown.ck-heading-dropdown .ck-dropdown__panel .ck-list__item{min-width:18em}\"","\nvar content = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./labeledinput.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./labeledinput.css\", function() {\n\t\tvar newContent = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./labeledinput.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck.ck-labeled-input .ck-labeled-input__status{font-size:var(--ck-font-size-small);margin-top:var(--ck-spacing-small);white-space:normal}.ck.ck-labeled-input .ck-labeled-input__status_error{color:var(--ck-color-base-error)}\"","\nvar content = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./inputtext.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./inputtext.css\", function() {\n\t\tvar newContent = require(\"!!../../../../../postcss-loader/src/index.js??ref--5-1!./inputtext.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \":root{--ck-input-text-width:18em}.ck.ck-input-text{border-radius:0}.ck-rounded-corners .ck.ck-input-text,.ck.ck-input-text.ck-rounded-corners{border-radius:var(--ck-border-radius)}.ck.ck-input-text{box-shadow:var(--ck-inner-shadow),0 0;background:var(--ck-color-input-background);border:1px solid var(--ck-color-input-border);padding:var(--ck-spacing-extra-tiny) var(--ck-spacing-medium);min-width:var(--ck-input-text-width);min-height:var(--ck-ui-component-min-height);transition-property:box-shadow,border;transition:.2s ease-in-out}.ck.ck-input-text:focus{outline:none;border:var(--ck-focus-ring);box-shadow:var(--ck-focus-outer-shadow),var(--ck-inner-shadow)}.ck.ck-input-text[readonly]{border:1px solid var(--ck-color-input-disabled-border);background:var(--ck-color-input-disabled-background);color:var(--ck-color-input-disabled-text)}.ck.ck-input-text[readonly]:focus{box-shadow:var(--ck-focus-disabled-outer-shadow),var(--ck-inner-shadow)}.ck.ck-input-text.ck-error{border-color:var(--ck-color-input-error-border);animation:ck-text-input-shake .3s ease both}.ck.ck-input-text.ck-error:focus{box-shadow:var(--ck-focus-error-outer-shadow),var(--ck-inner-shadow)}@keyframes ck-text-input-shake{20%{transform:translateX(-2px)}40%{transform:translateX(2px)}60%{transform:translateX(-1px)}80%{transform:translateX(1px)}}\"","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./textalternativeform.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./textalternativeform.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./textalternativeform.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck.ck-text-alternative-form{display:flex;flex-direction:row;flex-wrap:nowrap}.ck.ck-text-alternative-form .ck-labeled-input{display:inline-block}.ck.ck-text-alternative-form .ck-label{display:none}@media screen and (max-width:600px){.ck.ck-text-alternative-form{flex-wrap:wrap}.ck.ck-text-alternative-form .ck-labeled-input{flex-basis:100%}.ck.ck-text-alternative-form .ck-button{flex-basis:50%}}.ck.ck-text-alternative-form{padding:var(--ck-spacing-standard)}.ck.ck-text-alternative-form:focus{outline:none}.ck.ck-text-alternative-form>:not(:first-child){margin-left:var(--ck-spacing-standard)}@media screen and (max-width:600px){.ck.ck-text-alternative-form{padding:0;width:calc(0.8*var(--ck-input-text-width))}.ck.ck-text-alternative-form .ck-labeled-input{margin:var(--ck-spacing-standard) var(--ck-spacing-standard) 0}.ck.ck-text-alternative-form .ck-labeled-input .ck-input-text{min-width:0;width:100%}.ck.ck-text-alternative-form .ck-button{padding:var(--ck-spacing-standard);margin-top:var(--ck-spacing-standard);margin-left:0;border-radius:0;border:0;border-top:1px solid var(--ck-color-base-border)}.ck.ck-text-alternative-form .ck-button:first-of-type{border-right:1px solid var(--ck-color-base-border)}}\"","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./image.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./image.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./image.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck-content .image{clear:both;text-align:center;margin:1em 0}.ck-content .image>img{display:block;margin:0 auto;max-width:100%}\"","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./imagecaption.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./imagecaption.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./imagecaption.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck-content .image>figcaption{color:#333;background-color:#f7f7f7;padding:.6em;font-size:.75em;outline-offset:-1px}\"","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./imagestyle.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./imagestyle.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./imagestyle.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \":root{--ck-image-style-spacing:1.5em}.ck-content .image-style-align-center,.ck-content .image-style-align-left,.ck-content .image-style-align-right,.ck-content .image-style-side{max-width:50%}.ck-content .image-style-side{float:right;margin-left:var(--ck-image-style-spacing)}.ck-content .image-style-align-left{float:left;margin-right:var(--ck-image-style-spacing)}.ck-content .image-style-align-center{margin-left:auto;margin-right:auto}.ck-content .image-style-align-right{float:right;margin-left:var(--ck-image-style-spacing)}\"","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./link.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./link.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./link.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck .ck-link_selected{background:var(--ck-color-link-selected-background)}\"","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./linkform.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./linkform.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./linkform.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck.ck-link-form{display:flex;flex-direction:row;flex-wrap:nowrap}.ck.ck-link-form .ck-label{display:none}@media screen and (max-width:600px){.ck.ck-link-form{flex-wrap:wrap}.ck.ck-link-form .ck-labeled-input{flex-basis:100%}.ck.ck-link-form .ck-button{flex-basis:50%}}.ck.ck-link-form{padding:var(--ck-spacing-standard)}.ck.ck-link-form:focus{outline:none}.ck.ck-link-form>:not(:first-child){margin-left:var(--ck-spacing-standard)}@media screen and (max-width:600px){.ck.ck-link-form{padding:0;width:calc(0.8*var(--ck-input-text-width))}.ck.ck-link-form .ck-labeled-input{margin:var(--ck-spacing-standard) var(--ck-spacing-standard) 0}.ck.ck-link-form .ck-labeled-input .ck-input-text{min-width:0;width:100%}.ck.ck-link-form .ck-button{padding:var(--ck-spacing-standard);margin-top:var(--ck-spacing-standard);margin-left:0;border-radius:0;border:0;border-top:1px solid var(--ck-color-base-border)}.ck.ck-link-form .ck-button:first-of-type{border-right:1px solid var(--ck-color-base-border)}}\"","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./linkactions.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./linkactions.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./linkactions.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck.ck-link-actions{display:flex;flex-direction:row;flex-wrap:nowrap}.ck.ck-link-actions .ck-link-actions__preview{display:inline-block}.ck.ck-link-actions .ck-link-actions__preview .ck-button__label{overflow:hidden}@media screen and (max-width:600px){.ck.ck-link-actions{flex-wrap:wrap}.ck.ck-link-actions .ck-link-actions__preview{flex-basis:100%}.ck.ck-link-actions .ck-button:not(.ck-link-actions__preview){flex-basis:50%}}.ck.ck-link-actions{padding:var(--ck-spacing-standard)}.ck.ck-link-actions .ck-button.ck-link-actions__preview{padding-left:0;padding-right:0}.ck.ck-link-actions .ck-button.ck-link-actions__preview,.ck.ck-link-actions .ck-button.ck-link-actions__preview:active,.ck.ck-link-actions .ck-button.ck-link-actions__preview:focus,.ck.ck-link-actions .ck-button.ck-link-actions__preview:hover{background:none}.ck.ck-link-actions .ck-button.ck-link-actions__preview:active{box-shadow:none}.ck.ck-link-actions .ck-button.ck-link-actions__preview:focus .ck-button__label{text-decoration:underline}.ck.ck-link-actions .ck-button.ck-link-actions__preview .ck-button__label{padding:0 var(--ck-spacing-medium);color:var(--ck-color-link-default);text-overflow:ellipsis;cursor:pointer;max-width:var(--ck-input-text-width);min-width:3em;text-align:center}.ck.ck-link-actions .ck-button.ck-link-actions__preview .ck-button__label:hover{text-decoration:underline}.ck.ck-link-actions:focus{outline:none}.ck.ck-link-actions .ck-button:not(.ck-link-actions__preview){margin-left:var(--ck-spacing-standard)}@media screen and (max-width:600px){.ck.ck-link-actions{padding:0;width:calc(0.8*var(--ck-input-text-width))}.ck.ck-link-actions .ck-button.ck-link-actions__preview{margin:var(--ck-spacing-standard) var(--ck-spacing-standard) 0}.ck.ck-link-actions .ck-button.ck-link-actions__preview .ck-button__label{min-width:0;max-width:100%}.ck.ck-link-actions .ck-button:not(.ck-link-actions__preview){padding:var(--ck-spacing-standard);margin-top:var(--ck-spacing-standard);margin-left:0;border-radius:0;border:0;border-top:1px solid var(--ck-color-base-border)}.ck.ck-link-actions .ck-button:not(.ck-link-actions__preview):first-of-type{border-right:1px solid var(--ck-color-base-border)}}\"","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./tableediting.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./tableediting.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./tableediting.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \":root{--ck-color-table-focused-cell-background:#f5fafe}.ck-widget.table td.ck-editor__nested-editable.ck-editor__nested-editable_focused,.ck-widget.table th.ck-editor__nested-editable.ck-editor__nested-editable_focused{background:var(--ck-color-table-focused-cell-background);border-style:none;outline:1px solid var(--ck-color-focus-border);outline-offset:-1px}\"","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./inserttable.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./inserttable.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./inserttable.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \":root{--ck-insert-table-dropdown-padding:10px;--ck-insert-table-dropdown-box-height:11px;--ck-insert-table-dropdown-box-width:12px;--ck-insert-table-dropdown-box-margin:1px;--ck-insert-table-dropdown-box-border-color:#bfbfbf;--ck-insert-table-dropdown-box-border-active-color:#53a0e4;--ck-insert-table-dropdown-box-active-background:#c7e5ff}.ck .ck-insert-table-dropdown__grid{display:flex;flex-direction:row;flex-wrap:wrap;width:calc(var(--ck-insert-table-dropdown-box-width)*10 + var(--ck-insert-table-dropdown-box-margin)*20 + var(--ck-insert-table-dropdown-padding)*2);padding:var(--ck-insert-table-dropdown-padding) var(--ck-insert-table-dropdown-padding) 0}.ck .ck-insert-table-dropdown__label{text-align:center}.ck .ck-insert-table-dropdown-grid-box{width:var(--ck-insert-table-dropdown-box-width);height:var(--ck-insert-table-dropdown-box-height);margin:var(--ck-insert-table-dropdown-box-margin);border:1px solid var(--ck-insert-table-dropdown-box-border-color);border-radius:1px}.ck .ck-insert-table-dropdown-grid-box.ck-on{border-color:var(--ck-insert-table-dropdown-box-border-active-color);background:var(--ck-insert-table-dropdown-box-active-background)}\"","\nvar content = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./table.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../postcss-loader/src/index.js??ref--5-1!./table.css\", function() {\n\t\tvar newContent = require(\"!!../../../postcss-loader/src/index.js??ref--5-1!./table.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \".ck-content .table{margin:1em auto;display:table}.ck-content .table table{border-collapse:collapse;border-spacing:0;border:1px double #b3b3b3}.ck-content .table table td,.ck-content .table table th{min-width:2em;padding:.4em;border-color:#d9d9d9}.ck-content .table table th{font-weight:700;background:#fafafa}\"","'use strict';\n\n\nmodule.exports = require('./lib/');\n","// Main parser class\n\n'use strict';\n\n\nvar utils = require('./common/utils');\nvar helpers = require('./helpers');\nvar Renderer = require('./renderer');\nvar ParserCore = require('./parser_core');\nvar ParserBlock = require('./parser_block');\nvar ParserInline = require('./parser_inline');\nvar LinkifyIt = require('linkify-it');\nvar mdurl = require('mdurl');\nvar punycode = require('punycode');\n\n\nvar config = {\n 'default': require('./presets/default'),\n zero: require('./presets/zero'),\n commonmark: require('./presets/commonmark')\n};\n\n////////////////////////////////////////////////////////////////////////////////\n//\n// This validator can prohibit more than really needed to prevent XSS. It's a\n// tradeoff to keep code simple and to be secure by default.\n//\n// If you need different setup - override validator method as you wish. Or\n// replace it with dummy function and use external sanitizer.\n//\n\nvar BAD_PROTO_RE = /^(vbscript|javascript|file|data):/;\nvar GOOD_DATA_RE = /^data:image\\/(gif|png|jpeg|webp);/;\n\nfunction validateLink(url) {\n // url should be normalized at this point, and existing entities are decoded\n var str = url.trim().toLowerCase();\n\n return BAD_PROTO_RE.test(str) ? (GOOD_DATA_RE.test(str) ? true : false) : true;\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n\nvar RECODE_HOSTNAME_FOR = [ 'http:', 'https:', 'mailto:' ];\n\nfunction normalizeLink(url) {\n var parsed = mdurl.parse(url, true);\n\n if (parsed.hostname) {\n // Encode hostnames in urls like:\n // `http://host/`, `https://host/`, `mailto:user@host`, `//host/`\n //\n // We don't encode unknown schemas, because it's likely that we encode\n // something we shouldn't (e.g. `skype:name` treated as `skype:host`)\n //\n if (!parsed.protocol || RECODE_HOSTNAME_FOR.indexOf(parsed.protocol) >= 0) {\n try {\n parsed.hostname = punycode.toASCII(parsed.hostname);\n } catch (er) { /**/ }\n }\n }\n\n return mdurl.encode(mdurl.format(parsed));\n}\n\nfunction normalizeLinkText(url) {\n var parsed = mdurl.parse(url, true);\n\n if (parsed.hostname) {\n // Encode hostnames in urls like:\n // `http://host/`, `https://host/`, `mailto:user@host`, `//host/`\n //\n // We don't encode unknown schemas, because it's likely that we encode\n // something we shouldn't (e.g. `skype:name` treated as `skype:host`)\n //\n if (!parsed.protocol || RECODE_HOSTNAME_FOR.indexOf(parsed.protocol) >= 0) {\n try {\n parsed.hostname = punycode.toUnicode(parsed.hostname);\n } catch (er) { /**/ }\n }\n }\n\n return mdurl.decode(mdurl.format(parsed));\n}\n\n\n/**\n * class MarkdownIt\n *\n * Main parser/renderer class.\n *\n * ##### Usage\n *\n * ```javascript\n * // node.js, \"classic\" way:\n * var MarkdownIt = require('markdown-it'),\n * md = new MarkdownIt();\n * var result = md.render('# markdown-it rulezz!');\n *\n * // node.js, the same, but with sugar:\n * var md = require('markdown-it')();\n * var result = md.render('# markdown-it rulezz!');\n *\n * // browser without AMD, added to \"window\" on script load\n * // Note, there are no dash.\n * var md = window.markdownit();\n * var result = md.render('# markdown-it rulezz!');\n * ```\n *\n * Single line rendering, without paragraph wrap:\n *\n * ```javascript\n * var md = require('markdown-it')();\n * var result = md.renderInline('__markdown-it__ rulezz!');\n * ```\n **/\n\n/**\n * new MarkdownIt([presetName, options])\n * - presetName (String): optional, `commonmark` / `zero`\n * - options (Object)\n *\n * Creates parser instanse with given config. Can be called without `new`.\n *\n * ##### presetName\n *\n * MarkdownIt provides named presets as a convenience to quickly\n * enable/disable active syntax rules and options for common use cases.\n *\n * - [\"commonmark\"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/commonmark.js) -\n * configures parser to strict [CommonMark](http://commonmark.org/) mode.\n * - [default](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/default.js) -\n * similar to GFM, used when no preset name given. Enables all available rules,\n * but still without html, typographer & autolinker.\n * - [\"zero\"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/zero.js) -\n * all rules disabled. Useful to quickly setup your config via `.enable()`.\n * For example, when you need only `bold` and `italic` markup and nothing else.\n *\n * ##### options:\n *\n * - __html__ - `false`. Set `true` to enable HTML tags in source. Be careful!\n * That's not safe! You may need external sanitizer to protect output from XSS.\n * It's better to extend features via plugins, instead of enabling HTML.\n * - __xhtmlOut__ - `false`. Set `true` to add '/' when closing single tags\n * (`<br />`). This is needed only for full CommonMark compatibility. In real\n * world you will need HTML output.\n * - __breaks__ - `false`. Set `true` to convert `\\n` in paragraphs into `<br>`.\n * - __langPrefix__ - `language-`. CSS language class prefix for fenced blocks.\n * Can be useful for external highlighters.\n * - __linkify__ - `false`. Set `true` to autoconvert URL-like text to links.\n * - __typographer__ - `false`. Set `true` to enable [some language-neutral\n * replacement](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/replacements.js) +\n * quotes beautification (smartquotes).\n * - __quotes__ - `“”‘’`, String or Array. Double + single quotes replacement\n * pairs, when typographer enabled and smartquotes on. For example, you can\n * use `'«»„“'` for Russian, `'„“‚‘'` for German, and\n * `['«\\xA0', '\\xA0»', '‹\\xA0', '\\xA0›']` for French (including nbsp).\n * - __highlight__ - `null`. Highlighter function for fenced code blocks.\n * Highlighter `function (str, lang)` should return escaped HTML. It can also\n * return empty string if the source was not changed and should be escaped\n * externaly. If result starts with <pre... internal wrapper is skipped.\n *\n * ##### Example\n *\n * ```javascript\n * // commonmark mode\n * var md = require('markdown-it')('commonmark');\n *\n * // default mode\n * var md = require('markdown-it')();\n *\n * // enable everything\n * var md = require('markdown-it')({\n * html: true,\n * linkify: true,\n * typographer: true\n * });\n * ```\n *\n * ##### Syntax highlighting\n *\n * ```js\n * var hljs = require('highlight.js') // https://highlightjs.org/\n *\n * var md = require('markdown-it')({\n * highlight: function (str, lang) {\n * if (lang && hljs.getLanguage(lang)) {\n * try {\n * return hljs.highlight(lang, str, true).value;\n * } catch (__) {}\n * }\n *\n * return ''; // use external default escaping\n * }\n * });\n * ```\n *\n * Or with full wrapper override (if you need assign class to `<pre>`):\n *\n * ```javascript\n * var hljs = require('highlight.js') // https://highlightjs.org/\n *\n * // Actual default values\n * var md = require('markdown-it')({\n * highlight: function (str, lang) {\n * if (lang && hljs.getLanguage(lang)) {\n * try {\n * return '<pre class=\"hljs\"><code>' +\n * hljs.highlight(lang, str, true).value +\n * '</code></pre>';\n * } catch (__) {}\n * }\n *\n * return '<pre class=\"hljs\"><code>' + md.utils.escapeHtml(str) + '</code></pre>';\n * }\n * });\n * ```\n *\n **/\nfunction MarkdownIt(presetName, options) {\n if (!(this instanceof MarkdownIt)) {\n return new MarkdownIt(presetName, options);\n }\n\n if (!options) {\n if (!utils.isString(presetName)) {\n options = presetName || {};\n presetName = 'default';\n }\n }\n\n /**\n * MarkdownIt#inline -> ParserInline\n *\n * Instance of [[ParserInline]]. You may need it to add new rules when\n * writing plugins. For simple rules control use [[MarkdownIt.disable]] and\n * [[MarkdownIt.enable]].\n **/\n this.inline = new ParserInline();\n\n /**\n * MarkdownIt#block -> ParserBlock\n *\n * Instance of [[ParserBlock]]. You may need it to add new rules when\n * writing plugins. For simple rules control use [[MarkdownIt.disable]] and\n * [[MarkdownIt.enable]].\n **/\n this.block = new ParserBlock();\n\n /**\n * MarkdownIt#core -> Core\n *\n * Instance of [[Core]] chain executor. You may need it to add new rules when\n * writing plugins. For simple rules control use [[MarkdownIt.disable]] and\n * [[MarkdownIt.enable]].\n **/\n this.core = new ParserCore();\n\n /**\n * MarkdownIt#renderer -> Renderer\n *\n * Instance of [[Renderer]]. Use it to modify output look. Or to add rendering\n * rules for new token types, generated by plugins.\n *\n * ##### Example\n *\n * ```javascript\n * var md = require('markdown-it')();\n *\n * function myToken(tokens, idx, options, env, self) {\n * //...\n * return result;\n * };\n *\n * md.renderer.rules['my_token'] = myToken\n * ```\n *\n * See [[Renderer]] docs and [source code](https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.js).\n **/\n this.renderer = new Renderer();\n\n /**\n * MarkdownIt#linkify -> LinkifyIt\n *\n * [linkify-it](https://github.com/markdown-it/linkify-it) instance.\n * Used by [linkify](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/linkify.js)\n * rule.\n **/\n this.linkify = new LinkifyIt();\n\n /**\n * MarkdownIt#validateLink(url) -> Boolean\n *\n * Link validation function. CommonMark allows too much in links. By default\n * we disable `javascript:`, `vbscript:`, `file:` schemas, and almost all `data:...` schemas\n * except some embedded image types.\n *\n * You can change this behaviour:\n *\n * ```javascript\n * var md = require('markdown-it')();\n * // enable everything\n * md.validateLink = function () { return true; }\n * ```\n **/\n this.validateLink = validateLink;\n\n /**\n * MarkdownIt#normalizeLink(url) -> String\n *\n * Function used to encode link url to a machine-readable format,\n * which includes url-encoding, punycode, etc.\n **/\n this.normalizeLink = normalizeLink;\n\n /**\n * MarkdownIt#normalizeLinkText(url) -> String\n *\n * Function used to decode link url to a human-readable format`\n **/\n this.normalizeLinkText = normalizeLinkText;\n\n\n // Expose utils & helpers for easy acces from plugins\n\n /**\n * MarkdownIt#utils -> utils\n *\n * Assorted utility functions, useful to write plugins. See details\n * [here](https://github.com/markdown-it/markdown-it/blob/master/lib/common/utils.js).\n **/\n this.utils = utils;\n\n /**\n * MarkdownIt#helpers -> helpers\n *\n * Link components parser functions, useful to write plugins. See details\n * [here](https://github.com/markdown-it/markdown-it/blob/master/lib/helpers).\n **/\n this.helpers = utils.assign({}, helpers);\n\n\n this.options = {};\n this.configure(presetName);\n\n if (options) { this.set(options); }\n}\n\n\n/** chainable\n * MarkdownIt.set(options)\n *\n * Set parser options (in the same format as in constructor). Probably, you\n * will never need it, but you can change options after constructor call.\n *\n * ##### Example\n *\n * ```javascript\n * var md = require('markdown-it')()\n * .set({ html: true, breaks: true })\n * .set({ typographer, true });\n * ```\n *\n * __Note:__ To achieve the best possible performance, don't modify a\n * `markdown-it` instance options on the fly. If you need multiple configurations\n * it's best to create multiple instances and initialize each with separate\n * config.\n **/\nMarkdownIt.prototype.set = function (options) {\n utils.assign(this.options, options);\n return this;\n};\n\n\n/** chainable, internal\n * MarkdownIt.configure(presets)\n *\n * Batch load of all options and compenent settings. This is internal method,\n * and you probably will not need it. But if you with - see available presets\n * and data structure [here](https://github.com/markdown-it/markdown-it/tree/master/lib/presets)\n *\n * We strongly recommend to use presets instead of direct config loads. That\n * will give better compatibility with next versions.\n **/\nMarkdownIt.prototype.configure = function (presets) {\n var self = this, presetName;\n\n if (utils.isString(presets)) {\n presetName = presets;\n presets = config[presetName];\n if (!presets) { throw new Error('Wrong `markdown-it` preset \"' + presetName + '\", check name'); }\n }\n\n if (!presets) { throw new Error('Wrong `markdown-it` preset, can\\'t be empty'); }\n\n if (presets.options) { self.set(presets.options); }\n\n if (presets.components) {\n Object.keys(presets.components).forEach(function (name) {\n if (presets.components[name].rules) {\n self[name].ruler.enableOnly(presets.components[name].rules);\n }\n if (presets.components[name].rules2) {\n self[name].ruler2.enableOnly(presets.components[name].rules2);\n }\n });\n }\n return this;\n};\n\n\n/** chainable\n * MarkdownIt.enable(list, ignoreInvalid)\n * - list (String|Array): rule name or list of rule names to enable\n * - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.\n *\n * Enable list or rules. It will automatically find appropriate components,\n * containing rules with given names. If rule not found, and `ignoreInvalid`\n * not set - throws exception.\n *\n * ##### Example\n *\n * ```javascript\n * var md = require('markdown-it')()\n * .enable(['sub', 'sup'])\n * .disable('smartquotes');\n * ```\n **/\nMarkdownIt.prototype.enable = function (list, ignoreInvalid) {\n var result = [];\n\n if (!Array.isArray(list)) { list = [ list ]; }\n\n [ 'core', 'block', 'inline' ].forEach(function (chain) {\n result = result.concat(this[chain].ruler.enable(list, true));\n }, this);\n\n result = result.concat(this.inline.ruler2.enable(list, true));\n\n var missed = list.filter(function (name) { return result.indexOf(name) < 0; });\n\n if (missed.length && !ignoreInvalid) {\n throw new Error('MarkdownIt. Failed to enable unknown rule(s): ' + missed);\n }\n\n return this;\n};\n\n\n/** chainable\n * MarkdownIt.disable(list, ignoreInvalid)\n * - list (String|Array): rule name or list of rule names to disable.\n * - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.\n *\n * The same as [[MarkdownIt.enable]], but turn specified rules off.\n **/\nMarkdownIt.prototype.disable = function (list, ignoreInvalid) {\n var result = [];\n\n if (!Array.isArray(list)) { list = [ list ]; }\n\n [ 'core', 'block', 'inline' ].forEach(function (chain) {\n result = result.concat(this[chain].ruler.disable(list, true));\n }, this);\n\n result = result.concat(this.inline.ruler2.disable(list, true));\n\n var missed = list.filter(function (name) { return result.indexOf(name) < 0; });\n\n if (missed.length && !ignoreInvalid) {\n throw new Error('MarkdownIt. Failed to disable unknown rule(s): ' + missed);\n }\n return this;\n};\n\n\n/** chainable\n * MarkdownIt.use(plugin, params)\n *\n * Load specified plugin with given params into current parser instance.\n * It's just a sugar to call `plugin(md, params)` with curring.\n *\n * ##### Example\n *\n * ```javascript\n * var iterator = require('markdown-it-for-inline');\n * var md = require('markdown-it')()\n * .use(iterator, 'foo_replace', 'text', function (tokens, idx) {\n * tokens[idx].content = tokens[idx].content.replace(/foo/g, 'bar');\n * });\n * ```\n **/\nMarkdownIt.prototype.use = function (plugin /*, params, ... */) {\n var args = [ this ].concat(Array.prototype.slice.call(arguments, 1));\n plugin.apply(plugin, args);\n return this;\n};\n\n\n/** internal\n * MarkdownIt.parse(src, env) -> Array\n * - src (String): source string\n * - env (Object): environment sandbox\n *\n * Parse input string and returns list of block tokens (special token type\n * \"inline\" will contain list of inline tokens). You should not call this\n * method directly, until you write custom renderer (for example, to produce\n * AST).\n *\n * `env` is used to pass data between \"distributed\" rules and return additional\n * metadata like reference info, needed for the renderer. It also can be used to\n * inject data in specific cases. Usually, you will be ok to pass `{}`,\n * and then pass updated object to renderer.\n **/\nMarkdownIt.prototype.parse = function (src, env) {\n if (typeof src !== 'string') {\n throw new Error('Input data should be a String');\n }\n\n var state = new this.core.State(src, this, env);\n\n this.core.process(state);\n\n return state.tokens;\n};\n\n\n/**\n * MarkdownIt.render(src [, env]) -> String\n * - src (String): source string\n * - env (Object): environment sandbox\n *\n * Render markdown string into html. It does all magic for you :).\n *\n * `env` can be used to inject additional metadata (`{}` by default).\n * But you will not need it with high probability. See also comment\n * in [[MarkdownIt.parse]].\n **/\nMarkdownIt.prototype.render = function (src, env) {\n env = env || {};\n\n return this.renderer.render(this.parse(src, env), this.options, env);\n};\n\n\n/** internal\n * MarkdownIt.parseInline(src, env) -> Array\n * - src (String): source string\n * - env (Object): environment sandbox\n *\n * The same as [[MarkdownIt.parse]] but skip all block rules. It returns the\n * block tokens list with the single `inline` element, containing parsed inline\n * tokens in `children` property. Also updates `env` object.\n **/\nMarkdownIt.prototype.parseInline = function (src, env) {\n var state = new this.core.State(src, this, env);\n\n state.inlineMode = true;\n this.core.process(state);\n\n return state.tokens;\n};\n\n\n/**\n * MarkdownIt.renderInline(src [, env]) -> String\n * - src (String): source string\n * - env (Object): environment sandbox\n *\n * Similar to [[MarkdownIt.render]] but for single paragraph content. Result\n * will NOT be wrapped into `<p>` tags.\n **/\nMarkdownIt.prototype.renderInline = function (src, env) {\n env = env || {};\n\n return this.renderer.render(this.parseInline(src, env), this.options, env);\n};\n\n\nmodule.exports = MarkdownIt;\n","\n'use strict';\n\n\nvar encodeCache = {};\n\n\n// Create a lookup array where anything but characters in `chars` string\n// and alphanumeric chars is percent-encoded.\n//\nfunction getEncodeCache(exclude) {\n var i, ch, cache = encodeCache[exclude];\n if (cache) { return cache; }\n\n cache = encodeCache[exclude] = [];\n\n for (i = 0; i < 128; i++) {\n ch = String.fromCharCode(i);\n\n if (/^[0-9a-z]$/i.test(ch)) {\n // always allow unencoded alphanumeric characters\n cache.push(ch);\n } else {\n cache.push('%' + ('0' + i.toString(16).toUpperCase()).slice(-2));\n }\n }\n\n for (i = 0; i < exclude.length; i++) {\n cache[exclude.charCodeAt(i)] = exclude[i];\n }\n\n return cache;\n}\n\n\n// Encode unsafe characters with percent-encoding, skipping already\n// encoded sequences.\n//\n// - string - string to encode\n// - exclude - list of characters to ignore (in addition to a-zA-Z0-9)\n// - keepEscaped - don't encode '%' in a correct escape sequence (default: true)\n//\nfunction encode(string, exclude, keepEscaped) {\n var i, l, code, nextCode, cache,\n result = '';\n\n if (typeof exclude !== 'string') {\n // encode(string, keepEscaped)\n keepEscaped = exclude;\n exclude = encode.defaultChars;\n }\n\n if (typeof keepEscaped === 'undefined') {\n keepEscaped = true;\n }\n\n cache = getEncodeCache(exclude);\n\n for (i = 0, l = string.length; i < l; i++) {\n code = string.charCodeAt(i);\n\n if (keepEscaped && code === 0x25 /* % */ && i + 2 < l) {\n if (/^[0-9a-f]{2}$/i.test(string.slice(i + 1, i + 3))) {\n result += string.slice(i, i + 3);\n i += 2;\n continue;\n }\n }\n\n if (code < 128) {\n result += cache[code];\n continue;\n }\n\n if (code >= 0xD800 && code <= 0xDFFF) {\n if (code >= 0xD800 && code <= 0xDBFF && i + 1 < l) {\n nextCode = string.charCodeAt(i + 1);\n if (nextCode >= 0xDC00 && nextCode <= 0xDFFF) {\n result += encodeURIComponent(string[i] + string[i + 1]);\n i++;\n continue;\n }\n }\n result += '%EF%BF%BD';\n continue;\n }\n\n result += encodeURIComponent(string[i]);\n }\n\n return result;\n}\n\nencode.defaultChars = \";/?:@&=+$,-_.!~*'()#\";\nencode.componentChars = \"-_.!~*'()\";\n\n\nmodule.exports = encode;\n","\n'use strict';\n\n\n/* eslint-disable no-bitwise */\n\nvar decodeCache = {};\n\nfunction getDecodeCache(exclude) {\n var i, ch, cache = decodeCache[exclude];\n if (cache) { return cache; }\n\n cache = decodeCache[exclude] = [];\n\n for (i = 0; i < 128; i++) {\n ch = String.fromCharCode(i);\n cache.push(ch);\n }\n\n for (i = 0; i < exclude.length; i++) {\n ch = exclude.charCodeAt(i);\n cache[ch] = '%' + ('0' + ch.toString(16).toUpperCase()).slice(-2);\n }\n\n return cache;\n}\n\n\n// Decode percent-encoded string.\n//\nfunction decode(string, exclude) {\n var cache;\n\n if (typeof exclude !== 'string') {\n exclude = decode.defaultChars;\n }\n\n cache = getDecodeCache(exclude);\n\n return string.replace(/(%[a-f0-9]{2})+/gi, function(seq) {\n var i, l, b1, b2, b3, b4, chr,\n result = '';\n\n for (i = 0, l = seq.length; i < l; i += 3) {\n b1 = parseInt(seq.slice(i + 1, i + 3), 16);\n\n if (b1 < 0x80) {\n result += cache[b1];\n continue;\n }\n\n if ((b1 & 0xE0) === 0xC0 && (i + 3 < l)) {\n // 110xxxxx 10xxxxxx\n b2 = parseInt(seq.slice(i + 4, i + 6), 16);\n\n if ((b2 & 0xC0) === 0x80) {\n chr = ((b1 << 6) & 0x7C0) | (b2 & 0x3F);\n\n if (chr < 0x80) {\n result += '\\ufffd\\ufffd';\n } else {\n result += String.fromCharCode(chr);\n }\n\n i += 3;\n continue;\n }\n }\n\n if ((b1 & 0xF0) === 0xE0 && (i + 6 < l)) {\n // 1110xxxx 10xxxxxx 10xxxxxx\n b2 = parseInt(seq.slice(i + 4, i + 6), 16);\n b3 = parseInt(seq.slice(i + 7, i + 9), 16);\n\n if ((b2 & 0xC0) === 0x80 && (b3 & 0xC0) === 0x80) {\n chr = ((b1 << 12) & 0xF000) | ((b2 << 6) & 0xFC0) | (b3 & 0x3F);\n\n if (chr < 0x800 || (chr >= 0xD800 && chr <= 0xDFFF)) {\n result += '\\ufffd\\ufffd\\ufffd';\n } else {\n result += String.fromCharCode(chr);\n }\n\n i += 6;\n continue;\n }\n }\n\n if ((b1 & 0xF8) === 0xF0 && (i + 9 < l)) {\n // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx\n b2 = parseInt(seq.slice(i + 4, i + 6), 16);\n b3 = parseInt(seq.slice(i + 7, i + 9), 16);\n b4 = parseInt(seq.slice(i + 10, i + 12), 16);\n\n if ((b2 & 0xC0) === 0x80 && (b3 & 0xC0) === 0x80 && (b4 & 0xC0) === 0x80) {\n chr = ((b1 << 18) & 0x1C0000) | ((b2 << 12) & 0x3F000) | ((b3 << 6) & 0xFC0) | (b4 & 0x3F);\n\n if (chr < 0x10000 || chr > 0x10FFFF) {\n result += '\\ufffd\\ufffd\\ufffd\\ufffd';\n } else {\n chr -= 0x10000;\n result += String.fromCharCode(0xD800 + (chr >> 10), 0xDC00 + (chr & 0x3FF));\n }\n\n i += 9;\n continue;\n }\n }\n\n result += '\\ufffd';\n }\n\n return result;\n });\n}\n\n\ndecode.defaultChars = ';/?:@&=+$,#';\ndecode.componentChars = '';\n\n\nmodule.exports = decode;\n","\n'use strict';\n\n\nmodule.exports = function format(url) {\n var result = '';\n\n result += url.protocol || '';\n result += url.slashes ? '//' : '';\n result += url.auth ? url.auth + '@' : '';\n\n if (url.hostname && url.hostname.indexOf(':') !== -1) {\n // ipv6 address\n result += '[' + url.hostname + ']';\n } else {\n result += url.hostname || '';\n }\n\n result += url.port ? ':' + url.port : '';\n result += url.pathname || '';\n result += url.search || '';\n result += url.hash || '';\n\n return result;\n};\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\n//\n// Changes from joyent/node:\n//\n// 1. No leading slash in paths,\n// e.g. in `url.parse('http://foo?bar')` pathname is ``, not `/`\n//\n// 2. Backslashes are not replaced with slashes,\n// so `http:\\\\example.org\\` is treated like a relative path\n//\n// 3. Trailing colon is treated like a part of the path,\n// i.e. in `http://example.org:foo` pathname is `:foo`\n//\n// 4. Nothing is URL-encoded in the resulting object,\n// (in joyent/node some chars in auth and paths are encoded)\n//\n// 5. `url.parse()` does not have `parseQueryString` argument\n//\n// 6. Removed extraneous result properties: `host`, `path`, `query`, etc.,\n// which can be constructed using other parts of the url.\n//\n\n\nfunction Url() {\n this.protocol = null;\n this.slashes = null;\n this.auth = null;\n this.port = null;\n this.hostname = null;\n this.hash = null;\n this.search = null;\n this.pathname = null;\n}\n\n// Reference: RFC 3986, RFC 1808, RFC 2396\n\n// define these here so at least they only have to be\n// compiled once on the first module load.\nvar protocolPattern = /^([a-z0-9.+-]+:)/i,\n portPattern = /:[0-9]*$/,\n\n // Special case for a simple path URL\n simplePathPattern = /^(\\/\\/?(?!\\/)[^\\?\\s]*)(\\?[^\\s]*)?$/,\n\n // RFC 2396: characters reserved for delimiting URLs.\n // We actually just auto-escape these.\n delims = [ '<', '>', '\"', '`', ' ', '\\r', '\\n', '\\t' ],\n\n // RFC 2396: characters not allowed for various reasons.\n unwise = [ '{', '}', '|', '\\\\', '^', '`' ].concat(delims),\n\n // Allowed by RFCs, but cause of XSS attacks. Always escape these.\n autoEscape = [ '\\'' ].concat(unwise),\n // Characters that are never ever allowed in a hostname.\n // Note that any invalid chars are also handled, but these\n // are the ones that are *expected* to be seen, so we fast-path\n // them.\n nonHostChars = [ '%', '/', '?', ';', '#' ].concat(autoEscape),\n hostEndingChars = [ '/', '?', '#' ],\n hostnameMaxLen = 255,\n hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,\n hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,\n // protocols that can allow \"unsafe\" and \"unwise\" chars.\n /* eslint-disable no-script-url */\n // protocols that never have a hostname.\n hostlessProtocol = {\n 'javascript': true,\n 'javascript:': true\n },\n // protocols that always contain a // bit.\n slashedProtocol = {\n 'http': true,\n 'https': true,\n 'ftp': true,\n 'gopher': true,\n 'file': true,\n 'http:': true,\n 'https:': true,\n 'ftp:': true,\n 'gopher:': true,\n 'file:': true\n };\n /* eslint-enable no-script-url */\n\nfunction urlParse(url, slashesDenoteHost) {\n if (url && url instanceof Url) { return url; }\n\n var u = new Url();\n u.parse(url, slashesDenoteHost);\n return u;\n}\n\nUrl.prototype.parse = function(url, slashesDenoteHost) {\n var i, l, lowerProto, hec, slashes,\n rest = url;\n\n // trim before proceeding.\n // This is to support parse stuff like \" http://foo.com \\n\"\n rest = rest.trim();\n\n if (!slashesDenoteHost && url.split('#').length === 1) {\n // Try fast path regexp\n var simplePath = simplePathPattern.exec(rest);\n if (simplePath) {\n this.pathname = simplePath[1];\n if (simplePath[2]) {\n this.search = simplePath[2];\n }\n return this;\n }\n }\n\n var proto = protocolPattern.exec(rest);\n if (proto) {\n proto = proto[0];\n lowerProto = proto.toLowerCase();\n this.protocol = proto;\n rest = rest.substr(proto.length);\n }\n\n // figure out if it's got a host\n // user@server is *always* interpreted as a hostname, and url\n // resolution will treat //foo/bar as host=foo,path=bar because that's\n // how the browser resolves relative URLs.\n if (slashesDenoteHost || proto || rest.match(/^\\/\\/[^@\\/]+@[^@\\/]+/)) {\n slashes = rest.substr(0, 2) === '//';\n if (slashes && !(proto && hostlessProtocol[proto])) {\n rest = rest.substr(2);\n this.slashes = true;\n }\n }\n\n if (!hostlessProtocol[proto] &&\n (slashes || (proto && !slashedProtocol[proto]))) {\n\n // there's a hostname.\n // the first instance of /, ?, ;, or # ends the host.\n //\n // If there is an @ in the hostname, then non-host chars *are* allowed\n // to the left of the last @ sign, unless some host-ending character\n // comes *before* the @-sign.\n // URLs are obnoxious.\n //\n // ex:\n // http://a@b@c/ => user:a@b host:c\n // http://a@b?@c => user:a host:c path:/?@c\n\n // v0.12 TODO(isaacs): This is not quite how Chrome does things.\n // Review our test case against browsers more comprehensively.\n\n // find the first instance of any hostEndingChars\n var hostEnd = -1;\n for (i = 0; i < hostEndingChars.length; i++) {\n hec = rest.indexOf(hostEndingChars[i]);\n if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) {\n hostEnd = hec;\n }\n }\n\n // at this point, either we have an explicit point where the\n // auth portion cannot go past, or the last @ char is the decider.\n var auth, atSign;\n if (hostEnd === -1) {\n // atSign can be anywhere.\n atSign = rest.lastIndexOf('@');\n } else {\n // atSign must be in auth portion.\n // http://a@b/c@d => host:b auth:a path:/c@d\n atSign = rest.lastIndexOf('@', hostEnd);\n }\n\n // Now we have a portion which is definitely the auth.\n // Pull that off.\n if (atSign !== -1) {\n auth = rest.slice(0, atSign);\n rest = rest.slice(atSign + 1);\n this.auth = auth;\n }\n\n // the host is the remaining to the left of the first non-host char\n hostEnd = -1;\n for (i = 0; i < nonHostChars.length; i++) {\n hec = rest.indexOf(nonHostChars[i]);\n if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) {\n hostEnd = hec;\n }\n }\n // if we still have not hit it, then the entire thing is a host.\n if (hostEnd === -1) {\n hostEnd = rest.length;\n }\n\n if (rest[hostEnd - 1] === ':') { hostEnd--; }\n var host = rest.slice(0, hostEnd);\n rest = rest.slice(hostEnd);\n\n // pull out port.\n this.parseHost(host);\n\n // we've indicated that there is a hostname,\n // so even if it's empty, it has to be present.\n this.hostname = this.hostname || '';\n\n // if hostname begins with [ and ends with ]\n // assume that it's an IPv6 address.\n var ipv6Hostname = this.hostname[0] === '[' &&\n this.hostname[this.hostname.length - 1] === ']';\n\n // validate a little.\n if (!ipv6Hostname) {\n var hostparts = this.hostname.split(/\\./);\n for (i = 0, l = hostparts.length; i < l; i++) {\n var part = hostparts[i];\n if (!part) { continue; }\n if (!part.match(hostnamePartPattern)) {\n var newpart = '';\n for (var j = 0, k = part.length; j < k; j++) {\n if (part.charCodeAt(j) > 127) {\n // we replace non-ASCII char with a temporary placeholder\n // we need this to make sure size of hostname is not\n // broken by replacing non-ASCII by nothing\n newpart += 'x';\n } else {\n newpart += part[j];\n }\n }\n // we test again with ASCII char only\n if (!newpart.match(hostnamePartPattern)) {\n var validParts = hostparts.slice(0, i);\n var notHost = hostparts.slice(i + 1);\n var bit = part.match(hostnamePartStart);\n if (bit) {\n validParts.push(bit[1]);\n notHost.unshift(bit[2]);\n }\n if (notHost.length) {\n rest = notHost.join('.') + rest;\n }\n this.hostname = validParts.join('.');\n break;\n }\n }\n }\n }\n\n if (this.hostname.length > hostnameMaxLen) {\n this.hostname = '';\n }\n\n // strip [ and ] from the hostname\n // the host field still retains them, though\n if (ipv6Hostname) {\n this.hostname = this.hostname.substr(1, this.hostname.length - 2);\n }\n }\n\n // chop off from the tail first.\n var hash = rest.indexOf('#');\n if (hash !== -1) {\n // got a fragment string.\n this.hash = rest.substr(hash);\n rest = rest.slice(0, hash);\n }\n var qm = rest.indexOf('?');\n if (qm !== -1) {\n this.search = rest.substr(qm);\n rest = rest.slice(0, qm);\n }\n if (rest) { this.pathname = rest; }\n if (slashedProtocol[lowerProto] &&\n this.hostname && !this.pathname) {\n this.pathname = '';\n }\n\n return this;\n};\n\nUrl.prototype.parseHost = function(host) {\n var port = portPattern.exec(host);\n if (port) {\n port = port[0];\n if (port !== ':') {\n this.port = port.substr(1);\n }\n host = host.substr(0, host.length - port.length);\n }\n if (host) { this.hostname = host; }\n};\n\nmodule.exports = urlParse;\n","'use strict';\n\nexports.Any = require('./properties/Any/regex');\nexports.Cc = require('./categories/Cc/regex');\nexports.Cf = require('./categories/Cf/regex');\nexports.P = require('./categories/P/regex');\nexports.Z = require('./categories/Z/regex');\n","module.exports=/[\\xAD\\u0600-\\u0605\\u061C\\u06DD\\u070F\\u08E2\\u180E\\u200B-\\u200F\\u202A-\\u202E\\u2060-\\u2064\\u2066-\\u206F\\uFEFF\\uFFF9-\\uFFFB]|\\uD804[\\uDCBD\\uDCCD]|\\uD82F[\\uDCA0-\\uDCA3]|\\uD834[\\uDD73-\\uDD7A]|\\uDB40[\\uDC01\\uDC20-\\uDC7F]/","// Just a shortcut for bulk export\n'use strict';\n\n\nexports.parseLinkLabel = require('./parse_link_label');\nexports.parseLinkDestination = require('./parse_link_destination');\nexports.parseLinkTitle = require('./parse_link_title');\n","// Parse link label\n//\n// this function assumes that first character (\"[\") already matches;\n// returns the end of the label\n//\n'use strict';\n\nmodule.exports = function parseLinkLabel(state, start, disableNested) {\n var level, found, marker, prevPos,\n labelEnd = -1,\n max = state.posMax,\n oldPos = state.pos;\n\n state.pos = start + 1;\n level = 1;\n\n while (state.pos < max) {\n marker = state.src.charCodeAt(state.pos);\n if (marker === 0x5D /* ] */) {\n level--;\n if (level === 0) {\n found = true;\n break;\n }\n }\n\n prevPos = state.pos;\n state.md.inline.skipToken(state);\n if (marker === 0x5B /* [ */) {\n if (prevPos === state.pos - 1) {\n // increase level if we find text `[`, which is not a part of any token\n level++;\n } else if (disableNested) {\n state.pos = oldPos;\n return -1;\n }\n }\n }\n\n if (found) {\n labelEnd = state.pos;\n }\n\n // restore old state\n state.pos = oldPos;\n\n return labelEnd;\n};\n","// Parse link destination\n//\n'use strict';\n\n\nvar isSpace = require('../common/utils').isSpace;\nvar unescapeAll = require('../common/utils').unescapeAll;\n\n\nmodule.exports = function parseLinkDestination(str, pos, max) {\n var code, level,\n lines = 0,\n start = pos,\n result = {\n ok: false,\n pos: 0,\n lines: 0,\n str: ''\n };\n\n if (str.charCodeAt(pos) === 0x3C /* < */) {\n pos++;\n while (pos < max) {\n code = str.charCodeAt(pos);\n if (code === 0x0A /* \\n */ || isSpace(code)) { return result; }\n if (code === 0x3E /* > */) {\n result.pos = pos + 1;\n result.str = unescapeAll(str.slice(start + 1, pos));\n result.ok = true;\n return result;\n }\n if (code === 0x5C /* \\ */ && pos + 1 < max) {\n pos += 2;\n continue;\n }\n\n pos++;\n }\n\n // no closing '>'\n return result;\n }\n\n // this should be ... } else { ... branch\n\n level = 0;\n while (pos < max) {\n code = str.charCodeAt(pos);\n\n if (code === 0x20) { break; }\n\n // ascii control characters\n if (code < 0x20 || code === 0x7F) { break; }\n\n if (code === 0x5C /* \\ */ && pos + 1 < max) {\n pos += 2;\n continue;\n }\n\n if (code === 0x28 /* ( */) {\n level++;\n }\n\n if (code === 0x29 /* ) */) {\n if (level === 0) { break; }\n level--;\n }\n\n pos++;\n }\n\n if (start === pos) { return result; }\n if (level !== 0) { return result; }\n\n result.str = unescapeAll(str.slice(start, pos));\n result.lines = lines;\n result.pos = pos;\n result.ok = true;\n return result;\n};\n","// Parse link title\n//\n'use strict';\n\n\nvar unescapeAll = require('../common/utils').unescapeAll;\n\n\nmodule.exports = function parseLinkTitle(str, pos, max) {\n var code,\n marker,\n lines = 0,\n start = pos,\n result = {\n ok: false,\n pos: 0,\n lines: 0,\n str: ''\n };\n\n if (pos >= max) { return result; }\n\n marker = str.charCodeAt(pos);\n\n if (marker !== 0x22 /* \" */ && marker !== 0x27 /* ' */ && marker !== 0x28 /* ( */) { return result; }\n\n pos++;\n\n // if opening marker is \"(\", switch it to closing marker \")\"\n if (marker === 0x28) { marker = 0x29; }\n\n while (pos < max) {\n code = str.charCodeAt(pos);\n if (code === marker) {\n result.pos = pos + 1;\n result.lines = lines;\n result.str = unescapeAll(str.slice(start + 1, pos));\n result.ok = true;\n return result;\n } else if (code === 0x0A) {\n lines++;\n } else if (code === 0x5C /* \\ */ && pos + 1 < max) {\n pos++;\n if (str.charCodeAt(pos) === 0x0A) {\n lines++;\n }\n }\n\n pos++;\n }\n\n return result;\n};\n","/**\n * class Renderer\n *\n * Generates HTML from parsed token stream. Each instance has independent\n * copy of rules. Those can be rewritten with ease. Also, you can add new\n * rules if you create plugin and adds new token types.\n **/\n'use strict';\n\n\nvar assign = require('./common/utils').assign;\nvar unescapeAll = require('./common/utils').unescapeAll;\nvar escapeHtml = require('./common/utils').escapeHtml;\n\n\n////////////////////////////////////////////////////////////////////////////////\n\nvar default_rules = {};\n\n\ndefault_rules.code_inline = function (tokens, idx, options, env, slf) {\n var token = tokens[idx];\n\n return '<code' + slf.renderAttrs(token) + '>' +\n escapeHtml(tokens[idx].content) +\n '</code>';\n};\n\n\ndefault_rules.code_block = function (tokens, idx, options, env, slf) {\n var token = tokens[idx];\n\n return '<pre' + slf.renderAttrs(token) + '><code>' +\n escapeHtml(tokens[idx].content) +\n '</code></pre>\\n';\n};\n\n\ndefault_rules.fence = function (tokens, idx, options, env, slf) {\n var token = tokens[idx],\n info = token.info ? unescapeAll(token.info).trim() : '',\n langName = '',\n highlighted, i, tmpAttrs, tmpToken;\n\n if (info) {\n langName = info.split(/\\s+/g)[0];\n }\n\n if (options.highlight) {\n highlighted = options.highlight(token.content, langName) || escapeHtml(token.content);\n } else {\n highlighted = escapeHtml(token.content);\n }\n\n if (highlighted.indexOf('<pre') === 0) {\n return highlighted + '\\n';\n }\n\n // If language exists, inject class gently, without modifying original token.\n // May be, one day we will add .clone() for token and simplify this part, but\n // now we prefer to keep things local.\n if (info) {\n i = token.attrIndex('class');\n tmpAttrs = token.attrs ? token.attrs.slice() : [];\n\n if (i < 0) {\n tmpAttrs.push([ 'class', options.langPrefix + langName ]);\n } else {\n tmpAttrs[i][1] += ' ' + options.langPrefix + langName;\n }\n\n // Fake token just to render attributes\n tmpToken = {\n attrs: tmpAttrs\n };\n\n return '<pre><code' + slf.renderAttrs(tmpToken) + '>'\n + highlighted\n + '</code></pre>\\n';\n }\n\n\n return '<pre><code' + slf.renderAttrs(token) + '>'\n + highlighted\n + '</code></pre>\\n';\n};\n\n\ndefault_rules.image = function (tokens, idx, options, env, slf) {\n var token = tokens[idx];\n\n // \"alt\" attr MUST be set, even if empty. Because it's mandatory and\n // should be placed on proper position for tests.\n //\n // Replace content with actual value\n\n token.attrs[token.attrIndex('alt')][1] =\n slf.renderInlineAsText(token.children, options, env);\n\n return slf.renderToken(tokens, idx, options);\n};\n\n\ndefault_rules.hardbreak = function (tokens, idx, options /*, env */) {\n return options.xhtmlOut ? '<br />\\n' : '<br>\\n';\n};\ndefault_rules.softbreak = function (tokens, idx, options /*, env */) {\n return options.breaks ? (options.xhtmlOut ? '<br />\\n' : '<br>\\n') : '\\n';\n};\n\n\ndefault_rules.text = function (tokens, idx /*, options, env */) {\n return escapeHtml(tokens[idx].content);\n};\n\n\ndefault_rules.html_block = function (tokens, idx /*, options, env */) {\n return tokens[idx].content;\n};\ndefault_rules.html_inline = function (tokens, idx /*, options, env */) {\n return tokens[idx].content;\n};\n\n\n/**\n * new Renderer()\n *\n * Creates new [[Renderer]] instance and fill [[Renderer#rules]] with defaults.\n **/\nfunction Renderer() {\n\n /**\n * Renderer#rules -> Object\n *\n * Contains render rules for tokens. Can be updated and extended.\n *\n * ##### Example\n *\n * ```javascript\n * var md = require('markdown-it')();\n *\n * md.renderer.rules.strong_open = function () { return '<b>'; };\n * md.renderer.rules.strong_close = function () { return '</b>'; };\n *\n * var result = md.renderInline(...);\n * ```\n *\n * Each rule is called as independent static function with fixed signature:\n *\n * ```javascript\n * function my_token_render(tokens, idx, options, env, renderer) {\n * // ...\n * return renderedHTML;\n * }\n * ```\n *\n * See [source code](https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.js)\n * for more details and examples.\n **/\n this.rules = assign({}, default_rules);\n}\n\n\n/**\n * Renderer.renderAttrs(token) -> String\n *\n * Render token attributes to string.\n **/\nRenderer.prototype.renderAttrs = function renderAttrs(token) {\n var i, l, result;\n\n if (!token.attrs) { return ''; }\n\n result = '';\n\n for (i = 0, l = token.attrs.length; i < l; i++) {\n result += ' ' + escapeHtml(token.attrs[i][0]) + '=\"' + escapeHtml(token.attrs[i][1]) + '\"';\n }\n\n return result;\n};\n\n\n/**\n * Renderer.renderToken(tokens, idx, options) -> String\n * - tokens (Array): list of tokens\n * - idx (Numbed): token index to render\n * - options (Object): params of parser instance\n *\n * Default token renderer. Can be overriden by custom function\n * in [[Renderer#rules]].\n **/\nRenderer.prototype.renderToken = function renderToken(tokens, idx, options) {\n var nextToken,\n result = '',\n needLf = false,\n token = tokens[idx];\n\n // Tight list paragraphs\n if (token.hidden) {\n return '';\n }\n\n // Insert a newline between hidden paragraph and subsequent opening\n // block-level tag.\n //\n // For example, here we should insert a newline before blockquote:\n // - a\n // >\n //\n if (token.block && token.nesting !== -1 && idx && tokens[idx - 1].hidden) {\n result += '\\n';\n }\n\n // Add token name, e.g. `<img`\n result += (token.nesting === -1 ? '</' : '<') + token.tag;\n\n // Encode attributes, e.g. `<img src=\"foo\"`\n result += this.renderAttrs(token);\n\n // Add a slash for self-closing tags, e.g. `<img src=\"foo\" /`\n if (token.nesting === 0 && options.xhtmlOut) {\n result += ' /';\n }\n\n // Check if we need to add a newline after this tag\n if (token.block) {\n needLf = true;\n\n if (token.nesting === 1) {\n if (idx + 1 < tokens.length) {\n nextToken = tokens[idx + 1];\n\n if (nextToken.type === 'inline' || nextToken.hidden) {\n // Block-level tag containing an inline tag.\n //\n needLf = false;\n\n } else if (nextToken.nesting === -1 && nextToken.tag === token.tag) {\n // Opening tag + closing tag of the same type. E.g. `<li></li>`.\n //\n needLf = false;\n }\n }\n }\n }\n\n result += needLf ? '>\\n' : '>';\n\n return result;\n};\n\n\n/**\n * Renderer.renderInline(tokens, options, env) -> String\n * - tokens (Array): list on block tokens to renter\n * - options (Object): params of parser instance\n * - env (Object): additional data from parsed input (references, for example)\n *\n * The same as [[Renderer.render]], but for single token of `inline` type.\n **/\nRenderer.prototype.renderInline = function (tokens, options, env) {\n var type,\n result = '',\n rules = this.rules;\n\n for (var i = 0, len = tokens.length; i < len; i++) {\n type = tokens[i].type;\n\n if (typeof rules[type] !== 'undefined') {\n result += rules[type](tokens, i, options, env, this);\n } else {\n result += this.renderToken(tokens, i, options);\n }\n }\n\n return result;\n};\n\n\n/** internal\n * Renderer.renderInlineAsText(tokens, options, env) -> String\n * - tokens (Array): list on block tokens to renter\n * - options (Object): params of parser instance\n * - env (Object): additional data from parsed input (references, for example)\n *\n * Special kludge for image `alt` attributes to conform CommonMark spec.\n * Don't try to use it! Spec requires to show `alt` content with stripped markup,\n * instead of simple escaping.\n **/\nRenderer.prototype.renderInlineAsText = function (tokens, options, env) {\n var result = '';\n\n for (var i = 0, len = tokens.length; i < len; i++) {\n if (tokens[i].type === 'text') {\n result += tokens[i].content;\n } else if (tokens[i].type === 'image') {\n result += this.renderInlineAsText(tokens[i].children, options, env);\n }\n }\n\n return result;\n};\n\n\n/**\n * Renderer.render(tokens, options, env) -> String\n * - tokens (Array): list on block tokens to renter\n * - options (Object): params of parser instance\n * - env (Object): additional data from parsed input (references, for example)\n *\n * Takes token stream and generates HTML. Probably, you will never need to call\n * this method directly.\n **/\nRenderer.prototype.render = function (tokens, options, env) {\n var i, len, type,\n result = '',\n rules = this.rules;\n\n for (i = 0, len = tokens.length; i < len; i++) {\n type = tokens[i].type;\n\n if (type === 'inline') {\n result += this.renderInline(tokens[i].children, options, env);\n } else if (typeof rules[type] !== 'undefined') {\n result += rules[tokens[i].type](tokens, i, options, env, this);\n } else {\n result += this.renderToken(tokens, i, options, env);\n }\n }\n\n return result;\n};\n\nmodule.exports = Renderer;\n","/** internal\n * class Core\n *\n * Top-level rules executor. Glues block/inline parsers and does intermediate\n * transformations.\n **/\n'use strict';\n\n\nvar Ruler = require('./ruler');\n\n\nvar _rules = [\n [ 'normalize', require('./rules_core/normalize') ],\n [ 'block', require('./rules_core/block') ],\n [ 'inline', require('./rules_core/inline') ],\n [ 'linkify', require('./rules_core/linkify') ],\n [ 'replacements', require('./rules_core/replacements') ],\n [ 'smartquotes', require('./rules_core/smartquotes') ]\n];\n\n\n/**\n * new Core()\n **/\nfunction Core() {\n /**\n * Core#ruler -> Ruler\n *\n * [[Ruler]] instance. Keep configuration of core rules.\n **/\n this.ruler = new Ruler();\n\n for (var i = 0; i < _rules.length; i++) {\n this.ruler.push(_rules[i][0], _rules[i][1]);\n }\n}\n\n\n/**\n * Core.process(state)\n *\n * Executes core chain rules.\n **/\nCore.prototype.process = function (state) {\n var i, l, rules;\n\n rules = this.ruler.getRules('');\n\n for (i = 0, l = rules.length; i < l; i++) {\n rules[i](state);\n }\n};\n\nCore.prototype.State = require('./rules_core/state_core');\n\n\nmodule.exports = Core;\n","// Normalize input string\n\n'use strict';\n\n\nvar NEWLINES_RE = /\\r[\\n\\u0085]?|[\\u2424\\u2028\\u0085]/g;\nvar NULL_RE = /\\u0000/g;\n\n\nmodule.exports = function inline(state) {\n var str;\n\n // Normalize newlines\n str = state.src.replace(NEWLINES_RE, '\\n');\n\n // Replace NULL characters\n str = str.replace(NULL_RE, '\\uFFFD');\n\n state.src = str;\n};\n","'use strict';\n\n\nmodule.exports = function block(state) {\n var token;\n\n if (state.inlineMode) {\n token = new state.Token('inline', '', 0);\n token.content = state.src;\n token.map = [ 0, 1 ];\n token.children = [];\n state.tokens.push(token);\n } else {\n state.md.block.parse(state.src, state.md, state.env, state.tokens);\n }\n};\n","'use strict';\n\nmodule.exports = function inline(state) {\n var tokens = state.tokens, tok, i, l;\n\n // Parse inlines\n for (i = 0, l = tokens.length; i < l; i++) {\n tok = tokens[i];\n if (tok.type === 'inline') {\n state.md.inline.parse(tok.content, state.md, state.env, tok.children);\n }\n }\n};\n","// Replace link-like texts with link nodes.\n//\n// Currently restricted by `md.validateLink()` to http/https/ftp\n//\n'use strict';\n\n\nvar arrayReplaceAt = require('../common/utils').arrayReplaceAt;\n\n\nfunction isLinkOpen(str) {\n return /^<a[>\\s]/i.test(str);\n}\nfunction isLinkClose(str) {\n return /^<\\/a\\s*>/i.test(str);\n}\n\n\nmodule.exports = function linkify(state) {\n var i, j, l, tokens, token, currentToken, nodes, ln, text, pos, lastPos,\n level, htmlLinkLevel, url, fullUrl, urlText,\n blockTokens = state.tokens,\n links;\n\n if (!state.md.options.linkify) { return; }\n\n for (j = 0, l = blockTokens.length; j < l; j++) {\n if (blockTokens[j].type !== 'inline' ||\n !state.md.linkify.pretest(blockTokens[j].content)) {\n continue;\n }\n\n tokens = blockTokens[j].children;\n\n htmlLinkLevel = 0;\n\n // We scan from the end, to keep position when new tags added.\n // Use reversed logic in links start/end match\n for (i = tokens.length - 1; i >= 0; i--) {\n currentToken = tokens[i];\n\n // Skip content of markdown links\n if (currentToken.type === 'link_close') {\n i--;\n while (tokens[i].level !== currentToken.level && tokens[i].type !== 'link_open') {\n i--;\n }\n continue;\n }\n\n // Skip content of html tag links\n if (currentToken.type === 'html_inline') {\n if (isLinkOpen(currentToken.content) && htmlLinkLevel > 0) {\n htmlLinkLevel--;\n }\n if (isLinkClose(currentToken.content)) {\n htmlLinkLevel++;\n }\n }\n if (htmlLinkLevel > 0) { continue; }\n\n if (currentToken.type === 'text' && state.md.linkify.test(currentToken.content)) {\n\n text = currentToken.content;\n links = state.md.linkify.match(text);\n\n // Now split string to nodes\n nodes = [];\n level = currentToken.level;\n lastPos = 0;\n\n for (ln = 0; ln < links.length; ln++) {\n\n url = links[ln].url;\n fullUrl = state.md.normalizeLink(url);\n if (!state.md.validateLink(fullUrl)) { continue; }\n\n urlText = links[ln].text;\n\n // Linkifier might send raw hostnames like \"example.com\", where url\n // starts with domain name. So we prepend http:// in those cases,\n // and remove it afterwards.\n //\n if (!links[ln].schema) {\n urlText = state.md.normalizeLinkText('http://' + urlText).replace(/^http:\\/\\//, '');\n } else if (links[ln].schema === 'mailto:' && !/^mailto:/i.test(urlText)) {\n urlText = state.md.normalizeLinkText('mailto:' + urlText).replace(/^mailto:/, '');\n } else {\n urlText = state.md.normalizeLinkText(urlText);\n }\n\n pos = links[ln].index;\n\n if (pos > lastPos) {\n token = new state.Token('text', '', 0);\n token.content = text.slice(lastPos, pos);\n token.level = level;\n nodes.push(token);\n }\n\n token = new state.Token('link_open', 'a', 1);\n token.attrs = [ [ 'href', fullUrl ] ];\n token.level = level++;\n token.markup = 'linkify';\n token.info = 'auto';\n nodes.push(token);\n\n token = new state.Token('text', '', 0);\n token.content = urlText;\n token.level = level;\n nodes.push(token);\n\n token = new state.Token('link_close', 'a', -1);\n token.level = --level;\n token.markup = 'linkify';\n token.info = 'auto';\n nodes.push(token);\n\n lastPos = links[ln].lastIndex;\n }\n if (lastPos < text.length) {\n token = new state.Token('text', '', 0);\n token.content = text.slice(lastPos);\n token.level = level;\n nodes.push(token);\n }\n\n // replace current node\n blockTokens[j].children = tokens = arrayReplaceAt(tokens, i, nodes);\n }\n }\n }\n};\n","// Simple typographyc replacements\n//\n// (c) (C) → ©\n// (tm) (TM) → ™\n// (r) (R) → ®\n// +- → ±\n// (p) (P) -> §\n// ... → … (also ?.... → ?.., !.... → !..)\n// ???????? → ???, !!!!! → !!!, `,,` → `,`\n// -- → &ndash;, --- → &mdash;\n//\n'use strict';\n\n// TODO:\n// - fractionals 1/2, 1/4, 3/4 -> ½, ¼, ¾\n// - miltiplication 2 x 4 -> 2 × 4\n\nvar RARE_RE = /\\+-|\\.\\.|\\?\\?\\?\\?|!!!!|,,|--/;\n\n// Workaround for phantomjs - need regex without /g flag,\n// or root check will fail every second time\nvar SCOPED_ABBR_TEST_RE = /\\((c|tm|r|p)\\)/i;\n\nvar SCOPED_ABBR_RE = /\\((c|tm|r|p)\\)/ig;\nvar SCOPED_ABBR = {\n c: '©',\n r: '®',\n p: '§',\n tm: '™'\n};\n\nfunction replaceFn(match, name) {\n return SCOPED_ABBR[name.toLowerCase()];\n}\n\nfunction replace_scoped(inlineTokens) {\n var i, token, inside_autolink = 0;\n\n for (i = inlineTokens.length - 1; i >= 0; i--) {\n token = inlineTokens[i];\n\n if (token.type === 'text' && !inside_autolink) {\n token.content = token.content.replace(SCOPED_ABBR_RE, replaceFn);\n }\n\n if (token.type === 'link_open' && token.info === 'auto') {\n inside_autolink--;\n }\n\n if (token.type === 'link_close' && token.info === 'auto') {\n inside_autolink++;\n }\n }\n}\n\nfunction replace_rare(inlineTokens) {\n var i, token, inside_autolink = 0;\n\n for (i = inlineTokens.length - 1; i >= 0; i--) {\n token = inlineTokens[i];\n\n if (token.type === 'text' && !inside_autolink) {\n if (RARE_RE.test(token.content)) {\n token.content = token.content\n .replace(/\\+-/g, '±')\n // .., ..., ....... -> …\n // but ?..... & !..... -> ?.. & !..\n .replace(/\\.{2,}/g, '…').replace(/([?!])…/g, '$1..')\n .replace(/([?!]){4,}/g, '$1$1$1').replace(/,{2,}/g, ',')\n // em-dash\n .replace(/(^|[^-])---([^-]|$)/mg, '$1\\u2014$2')\n // en-dash\n .replace(/(^|\\s)--(\\s|$)/mg, '$1\\u2013$2')\n .replace(/(^|[^-\\s])--([^-\\s]|$)/mg, '$1\\u2013$2');\n }\n }\n\n if (token.type === 'link_open' && token.info === 'auto') {\n inside_autolink--;\n }\n\n if (token.type === 'link_close' && token.info === 'auto') {\n inside_autolink++;\n }\n }\n}\n\n\nmodule.exports = function replace(state) {\n var blkIdx;\n\n if (!state.md.options.typographer) { return; }\n\n for (blkIdx = state.tokens.length - 1; blkIdx >= 0; blkIdx--) {\n\n if (state.tokens[blkIdx].type !== 'inline') { continue; }\n\n if (SCOPED_ABBR_TEST_RE.test(state.tokens[blkIdx].content)) {\n replace_scoped(state.tokens[blkIdx].children);\n }\n\n if (RARE_RE.test(state.tokens[blkIdx].content)) {\n replace_rare(state.tokens[blkIdx].children);\n }\n\n }\n};\n","// Convert straight quotation marks to typographic ones\n//\n'use strict';\n\n\nvar isWhiteSpace = require('../common/utils').isWhiteSpace;\nvar isPunctChar = require('../common/utils').isPunctChar;\nvar isMdAsciiPunct = require('../common/utils').isMdAsciiPunct;\n\nvar QUOTE_TEST_RE = /['\"]/;\nvar QUOTE_RE = /['\"]/g;\nvar APOSTROPHE = '\\u2019'; /* ’ */\n\n\nfunction replaceAt(str, index, ch) {\n return str.substr(0, index) + ch + str.substr(index + 1);\n}\n\nfunction process_inlines(tokens, state) {\n var i, token, text, t, pos, max, thisLevel, item, lastChar, nextChar,\n isLastPunctChar, isNextPunctChar, isLastWhiteSpace, isNextWhiteSpace,\n canOpen, canClose, j, isSingle, stack, openQuote, closeQuote;\n\n stack = [];\n\n for (i = 0; i < tokens.length; i++) {\n token = tokens[i];\n\n thisLevel = tokens[i].level;\n\n for (j = stack.length - 1; j >= 0; j--) {\n if (stack[j].level <= thisLevel) { break; }\n }\n stack.length = j + 1;\n\n if (token.type !== 'text') { continue; }\n\n text = token.content;\n pos = 0;\n max = text.length;\n\n /*eslint no-labels:0,block-scoped-var:0*/\n OUTER:\n while (pos < max) {\n QUOTE_RE.lastIndex = pos;\n t = QUOTE_RE.exec(text);\n if (!t) { break; }\n\n canOpen = canClose = true;\n pos = t.index + 1;\n isSingle = (t[0] === \"'\");\n\n // Find previous character,\n // default to space if it's the beginning of the line\n //\n lastChar = 0x20;\n\n if (t.index - 1 >= 0) {\n lastChar = text.charCodeAt(t.index - 1);\n } else {\n for (j = i - 1; j >= 0; j--) {\n if (tokens[j].type === 'softbreak' || tokens[j].type === 'hardbreak') break; // lastChar defaults to 0x20\n if (tokens[j].type !== 'text') continue;\n\n lastChar = tokens[j].content.charCodeAt(tokens[j].content.length - 1);\n break;\n }\n }\n\n // Find next character,\n // default to space if it's the end of the line\n //\n nextChar = 0x20;\n\n if (pos < max) {\n nextChar = text.charCodeAt(pos);\n } else {\n for (j = i + 1; j < tokens.length; j++) {\n if (tokens[j].type === 'softbreak' || tokens[j].type === 'hardbreak') break; // nextChar defaults to 0x20\n if (tokens[j].type !== 'text') continue;\n\n nextChar = tokens[j].content.charCodeAt(0);\n break;\n }\n }\n\n isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));\n isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));\n\n isLastWhiteSpace = isWhiteSpace(lastChar);\n isNextWhiteSpace = isWhiteSpace(nextChar);\n\n if (isNextWhiteSpace) {\n canOpen = false;\n } else if (isNextPunctChar) {\n if (!(isLastWhiteSpace || isLastPunctChar)) {\n canOpen = false;\n }\n }\n\n if (isLastWhiteSpace) {\n canClose = false;\n } else if (isLastPunctChar) {\n if (!(isNextWhiteSpace || isNextPunctChar)) {\n canClose = false;\n }\n }\n\n if (nextChar === 0x22 /* \" */ && t[0] === '\"') {\n if (lastChar >= 0x30 /* 0 */ && lastChar <= 0x39 /* 9 */) {\n // special case: 1\"\" - count first quote as an inch\n canClose = canOpen = false;\n }\n }\n\n if (canOpen && canClose) {\n // treat this as the middle of the word\n canOpen = false;\n canClose = isNextPunctChar;\n }\n\n if (!canOpen && !canClose) {\n // middle of word\n if (isSingle) {\n token.content = replaceAt(token.content, t.index, APOSTROPHE);\n }\n continue;\n }\n\n if (canClose) {\n // this could be a closing quote, rewind the stack to get a match\n for (j = stack.length - 1; j >= 0; j--) {\n item = stack[j];\n if (stack[j].level < thisLevel) { break; }\n if (item.single === isSingle && stack[j].level === thisLevel) {\n item = stack[j];\n\n if (isSingle) {\n openQuote = state.md.options.quotes[2];\n closeQuote = state.md.options.quotes[3];\n } else {\n openQuote = state.md.options.quotes[0];\n closeQuote = state.md.options.quotes[1];\n }\n\n // replace token.content *before* tokens[item.token].content,\n // because, if they are pointing at the same token, replaceAt\n // could mess up indices when quote length != 1\n token.content = replaceAt(token.content, t.index, closeQuote);\n tokens[item.token].content = replaceAt(\n tokens[item.token].content, item.pos, openQuote);\n\n pos += closeQuote.length - 1;\n if (item.token === i) { pos += openQuote.length - 1; }\n\n text = token.content;\n max = text.length;\n\n stack.length = j;\n continue OUTER;\n }\n }\n }\n\n if (canOpen) {\n stack.push({\n token: i,\n pos: t.index,\n single: isSingle,\n level: thisLevel\n });\n } else if (canClose && isSingle) {\n token.content = replaceAt(token.content, t.index, APOSTROPHE);\n }\n }\n }\n}\n\n\nmodule.exports = function smartquotes(state) {\n /*eslint max-depth:0*/\n var blkIdx;\n\n if (!state.md.options.typographer) { return; }\n\n for (blkIdx = state.tokens.length - 1; blkIdx >= 0; blkIdx--) {\n\n if (state.tokens[blkIdx].type !== 'inline' ||\n !QUOTE_TEST_RE.test(state.tokens[blkIdx].content)) {\n continue;\n }\n\n process_inlines(state.tokens[blkIdx].children, state);\n }\n};\n","// Core state object\n//\n'use strict';\n\nvar Token = require('../token');\n\n\nfunction StateCore(src, md, env) {\n this.src = src;\n this.env = env;\n this.tokens = [];\n this.inlineMode = false;\n this.md = md; // link to parser instance\n}\n\n// re-export Token class to use in core rules\nStateCore.prototype.Token = Token;\n\n\nmodule.exports = StateCore;\n","/** internal\n * class ParserBlock\n *\n * Block-level tokenizer.\n **/\n'use strict';\n\n\nvar Ruler = require('./ruler');\n\n\nvar _rules = [\n // First 2 params - rule name & source. Secondary array - list of rules,\n // which can be terminated by this one.\n [ 'table', require('./rules_block/table'), [ 'paragraph', 'reference' ] ],\n [ 'code', require('./rules_block/code') ],\n [ 'fence', require('./rules_block/fence'), [ 'paragraph', 'reference', 'blockquote', 'list' ] ],\n [ 'blockquote', require('./rules_block/blockquote'), [ 'paragraph', 'reference', 'blockquote', 'list' ] ],\n [ 'hr', require('./rules_block/hr'), [ 'paragraph', 'reference', 'blockquote', 'list' ] ],\n [ 'list', require('./rules_block/list'), [ 'paragraph', 'reference', 'blockquote' ] ],\n [ 'reference', require('./rules_block/reference') ],\n [ 'heading', require('./rules_block/heading'), [ 'paragraph', 'reference', 'blockquote' ] ],\n [ 'lheading', require('./rules_block/lheading') ],\n [ 'html_block', require('./rules_block/html_block'), [ 'paragraph', 'reference', 'blockquote' ] ],\n [ 'paragraph', require('./rules_block/paragraph') ]\n];\n\n\n/**\n * new ParserBlock()\n **/\nfunction ParserBlock() {\n /**\n * ParserBlock#ruler -> Ruler\n *\n * [[Ruler]] instance. Keep configuration of block rules.\n **/\n this.ruler = new Ruler();\n\n for (var i = 0; i < _rules.length; i++) {\n this.ruler.push(_rules[i][0], _rules[i][1], { alt: (_rules[i][2] || []).slice() });\n }\n}\n\n\n// Generate tokens for input range\n//\nParserBlock.prototype.tokenize = function (state, startLine, endLine) {\n var ok, i,\n rules = this.ruler.getRules(''),\n len = rules.length,\n line = startLine,\n hasEmptyLines = false,\n maxNesting = state.md.options.maxNesting;\n\n while (line < endLine) {\n state.line = line = state.skipEmptyLines(line);\n if (line >= endLine) { break; }\n\n // Termination condition for nested calls.\n // Nested calls currently used for blockquotes & lists\n if (state.sCount[line] < state.blkIndent) { break; }\n\n // If nesting level exceeded - skip tail to the end. That's not ordinary\n // situation and we should not care about content.\n if (state.level >= maxNesting) {\n state.line = endLine;\n break;\n }\n\n // Try all possible rules.\n // On success, rule should:\n //\n // - update `state.line`\n // - update `state.tokens`\n // - return true\n\n for (i = 0; i < len; i++) {\n ok = rules[i](state, line, endLine, false);\n if (ok) { break; }\n }\n\n // set state.tight if we had an empty line before current tag\n // i.e. latest empty line should not count\n state.tight = !hasEmptyLines;\n\n // paragraph might \"eat\" one newline after it in nested lists\n if (state.isEmpty(state.line - 1)) {\n hasEmptyLines = true;\n }\n\n line = state.line;\n\n if (line < endLine && state.isEmpty(line)) {\n hasEmptyLines = true;\n line++;\n state.line = line;\n }\n }\n};\n\n\n/**\n * ParserBlock.parse(str, md, env, outTokens)\n *\n * Process input string and push block tokens into `outTokens`\n **/\nParserBlock.prototype.parse = function (src, md, env, outTokens) {\n var state;\n\n if (!src) { return; }\n\n state = new this.State(src, md, env, outTokens);\n\n this.tokenize(state, state.line, state.lineMax);\n};\n\n\nParserBlock.prototype.State = require('./rules_block/state_block');\n\n\nmodule.exports = ParserBlock;\n","// GFM table, non-standard\n\n'use strict';\n\nvar isSpace = require('../common/utils').isSpace;\n\n\nfunction getLine(state, line) {\n var pos = state.bMarks[line] + state.blkIndent,\n max = state.eMarks[line];\n\n return state.src.substr(pos, max - pos);\n}\n\nfunction escapedSplit(str) {\n var result = [],\n pos = 0,\n max = str.length,\n ch,\n escapes = 0,\n lastPos = 0,\n backTicked = false,\n lastBackTick = 0;\n\n ch = str.charCodeAt(pos);\n\n while (pos < max) {\n if (ch === 0x60/* ` */) {\n if (backTicked) {\n // make \\` close code sequence, but not open it;\n // the reason is: `\\` is correct code block\n backTicked = false;\n lastBackTick = pos;\n } else if (escapes % 2 === 0) {\n backTicked = true;\n lastBackTick = pos;\n }\n } else if (ch === 0x7c/* | */ && (escapes % 2 === 0) && !backTicked) {\n result.push(str.substring(lastPos, pos));\n lastPos = pos + 1;\n }\n\n if (ch === 0x5c/* \\ */) {\n escapes++;\n } else {\n escapes = 0;\n }\n\n pos++;\n\n // If there was an un-closed backtick, go back to just after\n // the last backtick, but as if it was a normal character\n if (pos === max && backTicked) {\n backTicked = false;\n pos = lastBackTick + 1;\n }\n\n ch = str.charCodeAt(pos);\n }\n\n result.push(str.substring(lastPos));\n\n return result;\n}\n\n\nmodule.exports = function table(state, startLine, endLine, silent) {\n var ch, lineText, pos, i, nextLine, columns, columnCount, token,\n aligns, t, tableLines, tbodyLines;\n\n // should have at least two lines\n if (startLine + 2 > endLine) { return false; }\n\n nextLine = startLine + 1;\n\n if (state.sCount[nextLine] < state.blkIndent) { return false; }\n\n // if it's indented more than 3 spaces, it should be a code block\n if (state.sCount[nextLine] - state.blkIndent >= 4) { return false; }\n\n // first character of the second line should be '|', '-', ':',\n // and no other characters are allowed but spaces;\n // basically, this is the equivalent of /^[-:|][-:|\\s]*$/ regexp\n\n pos = state.bMarks[nextLine] + state.tShift[nextLine];\n if (pos >= state.eMarks[nextLine]) { return false; }\n\n ch = state.src.charCodeAt(pos++);\n if (ch !== 0x7C/* | */ && ch !== 0x2D/* - */ && ch !== 0x3A/* : */) { return false; }\n\n while (pos < state.eMarks[nextLine]) {\n ch = state.src.charCodeAt(pos);\n\n if (ch !== 0x7C/* | */ && ch !== 0x2D/* - */ && ch !== 0x3A/* : */ && !isSpace(ch)) { return false; }\n\n pos++;\n }\n\n lineText = getLine(state, startLine + 1);\n\n columns = lineText.split('|');\n aligns = [];\n for (i = 0; i < columns.length; i++) {\n t = columns[i].trim();\n if (!t) {\n // allow empty columns before and after table, but not in between columns;\n // e.g. allow ` |---| `, disallow ` ---||--- `\n if (i === 0 || i === columns.length - 1) {\n continue;\n } else {\n return false;\n }\n }\n\n if (!/^:?-+:?$/.test(t)) { return false; }\n if (t.charCodeAt(t.length - 1) === 0x3A/* : */) {\n aligns.push(t.charCodeAt(0) === 0x3A/* : */ ? 'center' : 'right');\n } else if (t.charCodeAt(0) === 0x3A/* : */) {\n aligns.push('left');\n } else {\n aligns.push('');\n }\n }\n\n lineText = getLine(state, startLine).trim();\n if (lineText.indexOf('|') === -1) { return false; }\n if (state.sCount[startLine] - state.blkIndent >= 4) { return false; }\n columns = escapedSplit(lineText.replace(/^\\||\\|$/g, ''));\n\n // header row will define an amount of columns in the entire table,\n // and align row shouldn't be smaller than that (the rest of the rows can)\n columnCount = columns.length;\n if (columnCount > aligns.length) { return false; }\n\n if (silent) { return true; }\n\n token = state.push('table_open', 'table', 1);\n token.map = tableLines = [ startLine, 0 ];\n\n token = state.push('thead_open', 'thead', 1);\n token.map = [ startLine, startLine + 1 ];\n\n token = state.push('tr_open', 'tr', 1);\n token.map = [ startLine, startLine + 1 ];\n\n for (i = 0; i < columns.length; i++) {\n token = state.push('th_open', 'th', 1);\n token.map = [ startLine, startLine + 1 ];\n if (aligns[i]) {\n token.attrs = [ [ 'style', 'text-align:' + aligns[i] ] ];\n }\n\n token = state.push('inline', '', 0);\n token.content = columns[i].trim();\n token.map = [ startLine, startLine + 1 ];\n token.children = [];\n\n token = state.push('th_close', 'th', -1);\n }\n\n token = state.push('tr_close', 'tr', -1);\n token = state.push('thead_close', 'thead', -1);\n\n token = state.push('tbody_open', 'tbody', 1);\n token.map = tbodyLines = [ startLine + 2, 0 ];\n\n for (nextLine = startLine + 2; nextLine < endLine; nextLine++) {\n if (state.sCount[nextLine] < state.blkIndent) { break; }\n\n lineText = getLine(state, nextLine).trim();\n if (lineText.indexOf('|') === -1) { break; }\n if (state.sCount[nextLine] - state.blkIndent >= 4) { break; }\n columns = escapedSplit(lineText.replace(/^\\||\\|$/g, ''));\n\n token = state.push('tr_open', 'tr', 1);\n for (i = 0; i < columnCount; i++) {\n token = state.push('td_open', 'td', 1);\n if (aligns[i]) {\n token.attrs = [ [ 'style', 'text-align:' + aligns[i] ] ];\n }\n\n token = state.push('inline', '', 0);\n token.content = columns[i] ? columns[i].trim() : '';\n token.children = [];\n\n token = state.push('td_close', 'td', -1);\n }\n token = state.push('tr_close', 'tr', -1);\n }\n token = state.push('tbody_close', 'tbody', -1);\n token = state.push('table_close', 'table', -1);\n\n tableLines[1] = tbodyLines[1] = nextLine;\n state.line = nextLine;\n return true;\n};\n","// Code block (4 spaces padded)\n\n'use strict';\n\n\nmodule.exports = function code(state, startLine, endLine/*, silent*/) {\n var nextLine, last, token;\n\n if (state.sCount[startLine] - state.blkIndent < 4) { return false; }\n\n last = nextLine = startLine + 1;\n\n while (nextLine < endLine) {\n if (state.isEmpty(nextLine)) {\n nextLine++;\n continue;\n }\n\n if (state.sCount[nextLine] - state.blkIndent >= 4) {\n nextLine++;\n last = nextLine;\n continue;\n }\n break;\n }\n\n state.line = last;\n\n token = state.push('code_block', 'code', 0);\n token.content = state.getLines(startLine, last, 4 + state.blkIndent, true);\n token.map = [ startLine, state.line ];\n\n return true;\n};\n","// fences (``` lang, ~~~ lang)\n\n'use strict';\n\n\nmodule.exports = function fence(state, startLine, endLine, silent) {\n var marker, len, params, nextLine, mem, token, markup,\n haveEndMarker = false,\n pos = state.bMarks[startLine] + state.tShift[startLine],\n max = state.eMarks[startLine];\n\n // if it's indented more than 3 spaces, it should be a code block\n if (state.sCount[startLine] - state.blkIndent >= 4) { return false; }\n\n if (pos + 3 > max) { return false; }\n\n marker = state.src.charCodeAt(pos);\n\n if (marker !== 0x7E/* ~ */ && marker !== 0x60 /* ` */) {\n return false;\n }\n\n // scan marker length\n mem = pos;\n pos = state.skipChars(pos, marker);\n\n len = pos - mem;\n\n if (len < 3) { return false; }\n\n markup = state.src.slice(mem, pos);\n params = state.src.slice(pos, max);\n\n if (params.indexOf(String.fromCharCode(marker)) >= 0) { return false; }\n\n // Since start is found, we can report success here in validation mode\n if (silent) { return true; }\n\n // search end of block\n nextLine = startLine;\n\n for (;;) {\n nextLine++;\n if (nextLine >= endLine) {\n // unclosed block should be autoclosed by end of document.\n // also block seems to be autoclosed by end of parent\n break;\n }\n\n pos = mem = state.bMarks[nextLine] + state.tShift[nextLine];\n max = state.eMarks[nextLine];\n\n if (pos < max && state.sCount[nextLine] < state.blkIndent) {\n // non-empty line with negative indent should stop the list:\n // - ```\n // test\n break;\n }\n\n if (state.src.charCodeAt(pos) !== marker) { continue; }\n\n if (state.sCount[nextLine] - state.blkIndent >= 4) {\n // closing fence should be indented less than 4 spaces\n continue;\n }\n\n pos = state.skipChars(pos, marker);\n\n // closing code fence must be at least as long as the opening one\n if (pos - mem < len) { continue; }\n\n // make sure tail has spaces only\n pos = state.skipSpaces(pos);\n\n if (pos < max) { continue; }\n\n haveEndMarker = true;\n // found!\n break;\n }\n\n // If a fence has heading spaces, they should be removed from its inner block\n len = state.sCount[startLine];\n\n state.line = nextLine + (haveEndMarker ? 1 : 0);\n\n token = state.push('fence', 'code', 0);\n token.info = params;\n token.content = state.getLines(startLine + 1, nextLine, len, true);\n token.markup = markup;\n token.map = [ startLine, state.line ];\n\n return true;\n};\n","// Block quotes\n\n'use strict';\n\nvar isSpace = require('../common/utils').isSpace;\n\n\nmodule.exports = function blockquote(state, startLine, endLine, silent) {\n var adjustTab,\n ch,\n i,\n initial,\n l,\n lastLineEmpty,\n lines,\n nextLine,\n offset,\n oldBMarks,\n oldBSCount,\n oldIndent,\n oldParentType,\n oldSCount,\n oldTShift,\n spaceAfterMarker,\n terminate,\n terminatorRules,\n token,\n wasOutdented,\n oldLineMax = state.lineMax,\n pos = state.bMarks[startLine] + state.tShift[startLine],\n max = state.eMarks[startLine];\n\n // if it's indented more than 3 spaces, it should be a code block\n if (state.sCount[startLine] - state.blkIndent >= 4) { return false; }\n\n // check the block quote marker\n if (state.src.charCodeAt(pos++) !== 0x3E/* > */) { return false; }\n\n // we know that it's going to be a valid blockquote,\n // so no point trying to find the end of it in silent mode\n if (silent) { return true; }\n\n // skip spaces after \">\" and re-calculate offset\n initial = offset = state.sCount[startLine] + pos - (state.bMarks[startLine] + state.tShift[startLine]);\n\n // skip one optional space after '>'\n if (state.src.charCodeAt(pos) === 0x20 /* space */) {\n // ' > test '\n // ^ -- position start of line here:\n pos++;\n initial++;\n offset++;\n adjustTab = false;\n spaceAfterMarker = true;\n } else if (state.src.charCodeAt(pos) === 0x09 /* tab */) {\n spaceAfterMarker = true;\n\n if ((state.bsCount[startLine] + offset) % 4 === 3) {\n // ' >\\t test '\n // ^ -- position start of line here (tab has width===1)\n pos++;\n initial++;\n offset++;\n adjustTab = false;\n } else {\n // ' >\\t test '\n // ^ -- position start of line here + shift bsCount slightly\n // to make extra space appear\n adjustTab = true;\n }\n } else {\n spaceAfterMarker = false;\n }\n\n oldBMarks = [ state.bMarks[startLine] ];\n state.bMarks[startLine] = pos;\n\n while (pos < max) {\n ch = state.src.charCodeAt(pos);\n\n if (isSpace(ch)) {\n if (ch === 0x09) {\n offset += 4 - (offset + state.bsCount[startLine] + (adjustTab ? 1 : 0)) % 4;\n } else {\n offset++;\n }\n } else {\n break;\n }\n\n pos++;\n }\n\n oldBSCount = [ state.bsCount[startLine] ];\n state.bsCount[startLine] = state.sCount[startLine] + 1 + (spaceAfterMarker ? 1 : 0);\n\n lastLineEmpty = pos >= max;\n\n oldSCount = [ state.sCount[startLine] ];\n state.sCount[startLine] = offset - initial;\n\n oldTShift = [ state.tShift[startLine] ];\n state.tShift[startLine] = pos - state.bMarks[startLine];\n\n terminatorRules = state.md.block.ruler.getRules('blockquote');\n\n oldParentType = state.parentType;\n state.parentType = 'blockquote';\n wasOutdented = false;\n\n // Search the end of the block\n //\n // Block ends with either:\n // 1. an empty line outside:\n // ```\n // > test\n //\n // ```\n // 2. an empty line inside:\n // ```\n // >\n // test\n // ```\n // 3. another tag:\n // ```\n // > test\n // - - -\n // ```\n for (nextLine = startLine + 1; nextLine < endLine; nextLine++) {\n // check if it's outdented, i.e. it's inside list item and indented\n // less than said list item:\n //\n // ```\n // 1. anything\n // > current blockquote\n // 2. checking this line\n // ```\n if (state.sCount[nextLine] < state.blkIndent) wasOutdented = true;\n\n pos = state.bMarks[nextLine] + state.tShift[nextLine];\n max = state.eMarks[nextLine];\n\n if (pos >= max) {\n // Case 1: line is not inside the blockquote, and this line is empty.\n break;\n }\n\n if (state.src.charCodeAt(pos++) === 0x3E/* > */ && !wasOutdented) {\n // This line is inside the blockquote.\n\n // skip spaces after \">\" and re-calculate offset\n initial = offset = state.sCount[nextLine] + pos - (state.bMarks[nextLine] + state.tShift[nextLine]);\n\n // skip one optional space after '>'\n if (state.src.charCodeAt(pos) === 0x20 /* space */) {\n // ' > test '\n // ^ -- position start of line here:\n pos++;\n initial++;\n offset++;\n adjustTab = false;\n spaceAfterMarker = true;\n } else if (state.src.charCodeAt(pos) === 0x09 /* tab */) {\n spaceAfterMarker = true;\n\n if ((state.bsCount[nextLine] + offset) % 4 === 3) {\n // ' >\\t test '\n // ^ -- position start of line here (tab has width===1)\n pos++;\n initial++;\n offset++;\n adjustTab = false;\n } else {\n // ' >\\t test '\n // ^ -- position start of line here + shift bsCount slightly\n // to make extra space appear\n adjustTab = true;\n }\n } else {\n spaceAfterMarker = false;\n }\n\n oldBMarks.push(state.bMarks[nextLine]);\n state.bMarks[nextLine] = pos;\n\n while (pos < max) {\n ch = state.src.charCodeAt(pos);\n\n if (isSpace(ch)) {\n if (ch === 0x09) {\n offset += 4 - (offset + state.bsCount[nextLine] + (adjustTab ? 1 : 0)) % 4;\n } else {\n offset++;\n }\n } else {\n break;\n }\n\n pos++;\n }\n\n lastLineEmpty = pos >= max;\n\n oldBSCount.push(state.bsCount[nextLine]);\n state.bsCount[nextLine] = state.sCount[nextLine] + 1 + (spaceAfterMarker ? 1 : 0);\n\n oldSCount.push(state.sCount[nextLine]);\n state.sCount[nextLine] = offset - initial;\n\n oldTShift.push(state.tShift[nextLine]);\n state.tShift[nextLine] = pos - state.bMarks[nextLine];\n continue;\n }\n\n // Case 2: line is not inside the blockquote, and the last line was empty.\n if (lastLineEmpty) { break; }\n\n // Case 3: another tag found.\n terminate = false;\n for (i = 0, l = terminatorRules.length; i < l; i++) {\n if (terminatorRules[i](state, nextLine, endLine, true)) {\n terminate = true;\n break;\n }\n }\n\n if (terminate) {\n // Quirk to enforce \"hard termination mode\" for paragraphs;\n // normally if you call `tokenize(state, startLine, nextLine)`,\n // paragraphs will look below nextLine for paragraph continuation,\n // but if blockquote is terminated by another tag, they shouldn't\n state.lineMax = nextLine;\n\n if (state.blkIndent !== 0) {\n // state.blkIndent was non-zero, we now set it to zero,\n // so we need to re-calculate all offsets to appear as\n // if indent wasn't changed\n oldBMarks.push(state.bMarks[nextLine]);\n oldBSCount.push(state.bsCount[nextLine]);\n oldTShift.push(state.tShift[nextLine]);\n oldSCount.push(state.sCount[nextLine]);\n state.sCount[nextLine] -= state.blkIndent;\n }\n\n break;\n }\n\n oldBMarks.push(state.bMarks[nextLine]);\n oldBSCount.push(state.bsCount[nextLine]);\n oldTShift.push(state.tShift[nextLine]);\n oldSCount.push(state.sCount[nextLine]);\n\n // A negative indentation means that this is a paragraph continuation\n //\n state.sCount[nextLine] = -1;\n }\n\n oldIndent = state.blkIndent;\n state.blkIndent = 0;\n\n token = state.push('blockquote_open', 'blockquote', 1);\n token.markup = '>';\n token.map = lines = [ startLine, 0 ];\n\n state.md.block.tokenize(state, startLine, nextLine);\n\n token = state.push('blockquote_close', 'blockquote', -1);\n token.markup = '>';\n\n state.lineMax = oldLineMax;\n state.parentType = oldParentType;\n lines[1] = state.line;\n\n // Restore original tShift; this might not be necessary since the parser\n // has already been here, but just to make sure we can do that.\n for (i = 0; i < oldTShift.length; i++) {\n state.bMarks[i + startLine] = oldBMarks[i];\n state.tShift[i + startLine] = oldTShift[i];\n state.sCount[i + startLine] = oldSCount[i];\n state.bsCount[i + startLine] = oldBSCount[i];\n }\n state.blkIndent = oldIndent;\n\n return true;\n};\n","// Horizontal rule\n\n'use strict';\n\nvar isSpace = require('../common/utils').isSpace;\n\n\nmodule.exports = function hr(state, startLine, endLine, silent) {\n var marker, cnt, ch, token,\n pos = state.bMarks[startLine] + state.tShift[startLine],\n max = state.eMarks[startLine];\n\n // if it's indented more than 3 spaces, it should be a code block\n if (state.sCount[startLine] - state.blkIndent >= 4) { return false; }\n\n marker = state.src.charCodeAt(pos++);\n\n // Check hr marker\n if (marker !== 0x2A/* * */ &&\n marker !== 0x2D/* - */ &&\n marker !== 0x5F/* _ */) {\n return false;\n }\n\n // markers can be mixed with spaces, but there should be at least 3 of them\n\n cnt = 1;\n while (pos < max) {\n ch = state.src.charCodeAt(pos++);\n if (ch !== marker && !isSpace(ch)) { return false; }\n if (ch === marker) { cnt++; }\n }\n\n if (cnt < 3) { return false; }\n\n if (silent) { return true; }\n\n state.line = startLine + 1;\n\n token = state.push('hr', 'hr', 0);\n token.map = [ startLine, state.line ];\n token.markup = Array(cnt + 1).join(String.fromCharCode(marker));\n\n return true;\n};\n","// Lists\n\n'use strict';\n\nvar isSpace = require('../common/utils').isSpace;\n\n\n// Search `[-+*][\\n ]`, returns next pos after marker on success\n// or -1 on fail.\nfunction skipBulletListMarker(state, startLine) {\n var marker, pos, max, ch;\n\n pos = state.bMarks[startLine] + state.tShift[startLine];\n max = state.eMarks[startLine];\n\n marker = state.src.charCodeAt(pos++);\n // Check bullet\n if (marker !== 0x2A/* * */ &&\n marker !== 0x2D/* - */ &&\n marker !== 0x2B/* + */) {\n return -1;\n }\n\n if (pos < max) {\n ch = state.src.charCodeAt(pos);\n\n if (!isSpace(ch)) {\n // \" -test \" - is not a list item\n return -1;\n }\n }\n\n return pos;\n}\n\n// Search `\\d+[.)][\\n ]`, returns next pos after marker on success\n// or -1 on fail.\nfunction skipOrderedListMarker(state, startLine) {\n var ch,\n start = state.bMarks[startLine] + state.tShift[startLine],\n pos = start,\n max = state.eMarks[startLine];\n\n // List marker should have at least 2 chars (digit + dot)\n if (pos + 1 >= max) { return -1; }\n\n ch = state.src.charCodeAt(pos++);\n\n if (ch < 0x30/* 0 */ || ch > 0x39/* 9 */) { return -1; }\n\n for (;;) {\n // EOL -> fail\n if (pos >= max) { return -1; }\n\n ch = state.src.charCodeAt(pos++);\n\n if (ch >= 0x30/* 0 */ && ch <= 0x39/* 9 */) {\n\n // List marker should have no more than 9 digits\n // (prevents integer overflow in browsers)\n if (pos - start >= 10) { return -1; }\n\n continue;\n }\n\n // found valid marker\n if (ch === 0x29/* ) */ || ch === 0x2e/* . */) {\n break;\n }\n\n return -1;\n }\n\n\n if (pos < max) {\n ch = state.src.charCodeAt(pos);\n\n if (!isSpace(ch)) {\n // \" 1.test \" - is not a list item\n return -1;\n }\n }\n return pos;\n}\n\nfunction markTightParagraphs(state, idx) {\n var i, l,\n level = state.level + 2;\n\n for (i = idx + 2, l = state.tokens.length - 2; i < l; i++) {\n if (state.tokens[i].level === level && state.tokens[i].type === 'paragraph_open') {\n state.tokens[i + 2].hidden = true;\n state.tokens[i].hidden = true;\n i += 2;\n }\n }\n}\n\n\nmodule.exports = function list(state, startLine, endLine, silent) {\n var ch,\n contentStart,\n i,\n indent,\n indentAfterMarker,\n initial,\n isOrdered,\n itemLines,\n l,\n listLines,\n listTokIdx,\n markerCharCode,\n markerValue,\n max,\n nextLine,\n offset,\n oldIndent,\n oldLIndent,\n oldParentType,\n oldTShift,\n oldTight,\n pos,\n posAfterMarker,\n prevEmptyEnd,\n start,\n terminate,\n terminatorRules,\n token,\n isTerminatingParagraph = false,\n tight = true;\n\n // if it's indented more than 3 spaces, it should be a code block\n if (state.sCount[startLine] - state.blkIndent >= 4) { return false; }\n\n // limit conditions when list can interrupt\n // a paragraph (validation mode only)\n if (silent && state.parentType === 'paragraph') {\n // Next list item should still terminate previous list item;\n //\n // This code can fail if plugins use blkIndent as well as lists,\n // but I hope the spec gets fixed long before that happens.\n //\n if (state.tShift[startLine] >= state.blkIndent) {\n isTerminatingParagraph = true;\n }\n }\n\n // Detect list type and position after marker\n if ((posAfterMarker = skipOrderedListMarker(state, startLine)) >= 0) {\n isOrdered = true;\n start = state.bMarks[startLine] + state.tShift[startLine];\n markerValue = Number(state.src.substr(start, posAfterMarker - start - 1));\n\n // If we're starting a new ordered list right after\n // a paragraph, it should start with 1.\n if (isTerminatingParagraph && markerValue !== 1) return false;\n\n } else if ((posAfterMarker = skipBulletListMarker(state, startLine)) >= 0) {\n isOrdered = false;\n\n } else {\n return false;\n }\n\n // If we're starting a new unordered list right after\n // a paragraph, first line should not be empty.\n if (isTerminatingParagraph) {\n if (state.skipSpaces(posAfterMarker) >= state.eMarks[startLine]) return false;\n }\n\n // We should terminate list on style change. Remember first one to compare.\n markerCharCode = state.src.charCodeAt(posAfterMarker - 1);\n\n // For validation mode we can terminate immediately\n if (silent) { return true; }\n\n // Start list\n listTokIdx = state.tokens.length;\n\n if (isOrdered) {\n token = state.push('ordered_list_open', 'ol', 1);\n if (markerValue !== 1) {\n token.attrs = [ [ 'start', markerValue ] ];\n }\n\n } else {\n token = state.push('bullet_list_open', 'ul', 1);\n }\n\n token.map = listLines = [ startLine, 0 ];\n token.markup = String.fromCharCode(markerCharCode);\n\n //\n // Iterate list items\n //\n\n nextLine = startLine;\n prevEmptyEnd = false;\n terminatorRules = state.md.block.ruler.getRules('list');\n\n oldParentType = state.parentType;\n state.parentType = 'list';\n\n while (nextLine < endLine) {\n pos = posAfterMarker;\n max = state.eMarks[nextLine];\n\n initial = offset = state.sCount[nextLine] + posAfterMarker - (state.bMarks[startLine] + state.tShift[startLine]);\n\n while (pos < max) {\n ch = state.src.charCodeAt(pos);\n\n if (ch === 0x09) {\n offset += 4 - (offset + state.bsCount[nextLine]) % 4;\n } else if (ch === 0x20) {\n offset++;\n } else {\n break;\n }\n\n pos++;\n }\n\n contentStart = pos;\n\n if (contentStart >= max) {\n // trimming space in \"- \\n 3\" case, indent is 1 here\n indentAfterMarker = 1;\n } else {\n indentAfterMarker = offset - initial;\n }\n\n // If we have more than 4 spaces, the indent is 1\n // (the rest is just indented code block)\n if (indentAfterMarker > 4) { indentAfterMarker = 1; }\n\n // \" - test\"\n // ^^^^^ - calculating total length of this thing\n indent = initial + indentAfterMarker;\n\n // Run subparser & write tokens\n token = state.push('list_item_open', 'li', 1);\n token.markup = String.fromCharCode(markerCharCode);\n token.map = itemLines = [ startLine, 0 ];\n\n oldIndent = state.blkIndent;\n oldTight = state.tight;\n oldTShift = state.tShift[startLine];\n oldLIndent = state.sCount[startLine];\n state.blkIndent = indent;\n state.tight = true;\n state.tShift[startLine] = contentStart - state.bMarks[startLine];\n state.sCount[startLine] = offset;\n\n if (contentStart >= max && state.isEmpty(startLine + 1)) {\n // workaround for this case\n // (list item is empty, list terminates before \"foo\"):\n // ~~~~~~~~\n // -\n //\n // foo\n // ~~~~~~~~\n state.line = Math.min(state.line + 2, endLine);\n } else {\n state.md.block.tokenize(state, startLine, endLine, true);\n }\n\n // If any of list item is tight, mark list as tight\n if (!state.tight || prevEmptyEnd) {\n tight = false;\n }\n // Item become loose if finish with empty line,\n // but we should filter last element, because it means list finish\n prevEmptyEnd = (state.line - startLine) > 1 && state.isEmpty(state.line - 1);\n\n state.blkIndent = oldIndent;\n state.tShift[startLine] = oldTShift;\n state.sCount[startLine] = oldLIndent;\n state.tight = oldTight;\n\n token = state.push('list_item_close', 'li', -1);\n token.markup = String.fromCharCode(markerCharCode);\n\n nextLine = startLine = state.line;\n itemLines[1] = nextLine;\n contentStart = state.bMarks[startLine];\n\n if (nextLine >= endLine) { break; }\n\n //\n // Try to check if list is terminated or continued.\n //\n if (state.sCount[nextLine] < state.blkIndent) { break; }\n\n // fail if terminating block found\n terminate = false;\n for (i = 0, l = terminatorRules.length; i < l; i++) {\n if (terminatorRules[i](state, nextLine, endLine, true)) {\n terminate = true;\n break;\n }\n }\n if (terminate) { break; }\n\n // fail if list has another type\n if (isOrdered) {\n posAfterMarker = skipOrderedListMarker(state, nextLine);\n if (posAfterMarker < 0) { break; }\n } else {\n posAfterMarker = skipBulletListMarker(state, nextLine);\n if (posAfterMarker < 0) { break; }\n }\n\n if (markerCharCode !== state.src.charCodeAt(posAfterMarker - 1)) { break; }\n }\n\n // Finalize list\n if (isOrdered) {\n token = state.push('ordered_list_close', 'ol', -1);\n } else {\n token = state.push('bullet_list_close', 'ul', -1);\n }\n token.markup = String.fromCharCode(markerCharCode);\n\n listLines[1] = nextLine;\n state.line = nextLine;\n\n state.parentType = oldParentType;\n\n // mark paragraphs tight if needed\n if (tight) {\n markTightParagraphs(state, listTokIdx);\n }\n\n return true;\n};\n","'use strict';\n\n\nvar normalizeReference = require('../common/utils').normalizeReference;\nvar isSpace = require('../common/utils').isSpace;\n\n\nmodule.exports = function reference(state, startLine, _endLine, silent) {\n var ch,\n destEndPos,\n destEndLineNo,\n endLine,\n href,\n i,\n l,\n label,\n labelEnd,\n oldParentType,\n res,\n start,\n str,\n terminate,\n terminatorRules,\n title,\n lines = 0,\n pos = state.bMarks[startLine] + state.tShift[startLine],\n max = state.eMarks[startLine],\n nextLine = startLine + 1;\n\n // if it's indented more than 3 spaces, it should be a code block\n if (state.sCount[startLine] - state.blkIndent >= 4) { return false; }\n\n if (state.src.charCodeAt(pos) !== 0x5B/* [ */) { return false; }\n\n // Simple check to quickly interrupt scan on [link](url) at the start of line.\n // Can be useful on practice: https://github.com/markdown-it/markdown-it/issues/54\n while (++pos < max) {\n if (state.src.charCodeAt(pos) === 0x5D /* ] */ &&\n state.src.charCodeAt(pos - 1) !== 0x5C/* \\ */) {\n if (pos + 1 === max) { return false; }\n if (state.src.charCodeAt(pos + 1) !== 0x3A/* : */) { return false; }\n break;\n }\n }\n\n endLine = state.lineMax;\n\n // jump line-by-line until empty one or EOF\n terminatorRules = state.md.block.ruler.getRules('reference');\n\n oldParentType = state.parentType;\n state.parentType = 'reference';\n\n for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) {\n // this would be a code block normally, but after paragraph\n // it's considered a lazy continuation regardless of what's there\n if (state.sCount[nextLine] - state.blkIndent > 3) { continue; }\n\n // quirk for blockquotes, this line should already be checked by that rule\n if (state.sCount[nextLine] < 0) { continue; }\n\n // Some tags can terminate paragraph without empty line.\n terminate = false;\n for (i = 0, l = terminatorRules.length; i < l; i++) {\n if (terminatorRules[i](state, nextLine, endLine, true)) {\n terminate = true;\n break;\n }\n }\n if (terminate) { break; }\n }\n\n str = state.getLines(startLine, nextLine, state.blkIndent, false).trim();\n max = str.length;\n\n for (pos = 1; pos < max; pos++) {\n ch = str.charCodeAt(pos);\n if (ch === 0x5B /* [ */) {\n return false;\n } else if (ch === 0x5D /* ] */) {\n labelEnd = pos;\n break;\n } else if (ch === 0x0A /* \\n */) {\n lines++;\n } else if (ch === 0x5C /* \\ */) {\n pos++;\n if (pos < max && str.charCodeAt(pos) === 0x0A) {\n lines++;\n }\n }\n }\n\n if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A/* : */) { return false; }\n\n // [label]: destination 'title'\n // ^^^ skip optional whitespace here\n for (pos = labelEnd + 2; pos < max; pos++) {\n ch = str.charCodeAt(pos);\n if (ch === 0x0A) {\n lines++;\n } else if (isSpace(ch)) {\n /*eslint no-empty:0*/\n } else {\n break;\n }\n }\n\n // [label]: destination 'title'\n // ^^^^^^^^^^^ parse this\n res = state.md.helpers.parseLinkDestination(str, pos, max);\n if (!res.ok) { return false; }\n\n href = state.md.normalizeLink(res.str);\n if (!state.md.validateLink(href)) { return false; }\n\n pos = res.pos;\n lines += res.lines;\n\n // save cursor state, we could require to rollback later\n destEndPos = pos;\n destEndLineNo = lines;\n\n // [label]: destination 'title'\n // ^^^ skipping those spaces\n start = pos;\n for (; pos < max; pos++) {\n ch = str.charCodeAt(pos);\n if (ch === 0x0A) {\n lines++;\n } else if (isSpace(ch)) {\n /*eslint no-empty:0*/\n } else {\n break;\n }\n }\n\n // [label]: destination 'title'\n // ^^^^^^^ parse this\n res = state.md.helpers.parseLinkTitle(str, pos, max);\n if (pos < max && start !== pos && res.ok) {\n title = res.str;\n pos = res.pos;\n lines += res.lines;\n } else {\n title = '';\n pos = destEndPos;\n lines = destEndLineNo;\n }\n\n // skip trailing spaces until the rest of the line\n while (pos < max) {\n ch = str.charCodeAt(pos);\n if (!isSpace(ch)) { break; }\n pos++;\n }\n\n if (pos < max && str.charCodeAt(pos) !== 0x0A) {\n if (title) {\n // garbage at the end of the line after title,\n // but it could still be a valid reference if we roll back\n title = '';\n pos = destEndPos;\n lines = destEndLineNo;\n while (pos < max) {\n ch = str.charCodeAt(pos);\n if (!isSpace(ch)) { break; }\n pos++;\n }\n }\n }\n\n if (pos < max && str.charCodeAt(pos) !== 0x0A) {\n // garbage at the end of the line\n return false;\n }\n\n label = normalizeReference(str.slice(1, labelEnd));\n if (!label) {\n // CommonMark 0.20 disallows empty labels\n return false;\n }\n\n // Reference can not terminate anything. This check is for safety only.\n /*istanbul ignore if*/\n if (silent) { return true; }\n\n if (typeof state.env.references === 'undefined') {\n state.env.references = {};\n }\n if (typeof state.env.references[label] === 'undefined') {\n state.env.references[label] = { title: title, href: href };\n }\n\n state.parentType = oldParentType;\n\n state.line = startLine + lines + 1;\n return true;\n};\n","// heading (#, ##, ...)\n\n'use strict';\n\nvar isSpace = require('../common/utils').isSpace;\n\n\nmodule.exports = function heading(state, startLine, endLine, silent) {\n var ch, level, tmp, token,\n pos = state.bMarks[startLine] + state.tShift[startLine],\n max = state.eMarks[startLine];\n\n // if it's indented more than 3 spaces, it should be a code block\n if (state.sCount[startLine] - state.blkIndent >= 4) { return false; }\n\n ch = state.src.charCodeAt(pos);\n\n if (ch !== 0x23/* # */ || pos >= max) { return false; }\n\n // count heading level\n level = 1;\n ch = state.src.charCodeAt(++pos);\n while (ch === 0x23/* # */ && pos < max && level <= 6) {\n level++;\n ch = state.src.charCodeAt(++pos);\n }\n\n if (level > 6 || (pos < max && !isSpace(ch))) { return false; }\n\n if (silent) { return true; }\n\n // Let's cut tails like ' ### ' from the end of string\n\n max = state.skipSpacesBack(max, pos);\n tmp = state.skipCharsBack(max, 0x23, pos); // #\n if (tmp > pos && isSpace(state.src.charCodeAt(tmp - 1))) {\n max = tmp;\n }\n\n state.line = startLine + 1;\n\n token = state.push('heading_open', 'h' + String(level), 1);\n token.markup = '########'.slice(0, level);\n token.map = [ startLine, state.line ];\n\n token = state.push('inline', '', 0);\n token.content = state.src.slice(pos, max).trim();\n token.map = [ startLine, state.line ];\n token.children = [];\n\n token = state.push('heading_close', 'h' + String(level), -1);\n token.markup = '########'.slice(0, level);\n\n return true;\n};\n","// lheading (---, ===)\n\n'use strict';\n\n\nmodule.exports = function lheading(state, startLine, endLine/*, silent*/) {\n var content, terminate, i, l, token, pos, max, level, marker,\n nextLine = startLine + 1, oldParentType,\n terminatorRules = state.md.block.ruler.getRules('paragraph');\n\n // if it's indented more than 3 spaces, it should be a code block\n if (state.sCount[startLine] - state.blkIndent >= 4) { return false; }\n\n oldParentType = state.parentType;\n state.parentType = 'paragraph'; // use paragraph to match terminatorRules\n\n // jump line-by-line until empty one or EOF\n for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) {\n // this would be a code block normally, but after paragraph\n // it's considered a lazy continuation regardless of what's there\n if (state.sCount[nextLine] - state.blkIndent > 3) { continue; }\n\n //\n // Check for underline in setext header\n //\n if (state.sCount[nextLine] >= state.blkIndent) {\n pos = state.bMarks[nextLine] + state.tShift[nextLine];\n max = state.eMarks[nextLine];\n\n if (pos < max) {\n marker = state.src.charCodeAt(pos);\n\n if (marker === 0x2D/* - */ || marker === 0x3D/* = */) {\n pos = state.skipChars(pos, marker);\n pos = state.skipSpaces(pos);\n\n if (pos >= max) {\n level = (marker === 0x3D/* = */ ? 1 : 2);\n break;\n }\n }\n }\n }\n\n // quirk for blockquotes, this line should already be checked by that rule\n if (state.sCount[nextLine] < 0) { continue; }\n\n // Some tags can terminate paragraph without empty line.\n terminate = false;\n for (i = 0, l = terminatorRules.length; i < l; i++) {\n if (terminatorRules[i](state, nextLine, endLine, true)) {\n terminate = true;\n break;\n }\n }\n if (terminate) { break; }\n }\n\n if (!level) {\n // Didn't find valid underline\n return false;\n }\n\n content = state.getLines(startLine, nextLine, state.blkIndent, false).trim();\n\n state.line = nextLine + 1;\n\n token = state.push('heading_open', 'h' + String(level), 1);\n token.markup = String.fromCharCode(marker);\n token.map = [ startLine, state.line ];\n\n token = state.push('inline', '', 0);\n token.content = content;\n token.map = [ startLine, state.line - 1 ];\n token.children = [];\n\n token = state.push('heading_close', 'h' + String(level), -1);\n token.markup = String.fromCharCode(marker);\n\n state.parentType = oldParentType;\n\n return true;\n};\n","// HTML block\n\n'use strict';\n\n\nvar block_names = require('../common/html_blocks');\nvar HTML_OPEN_CLOSE_TAG_RE = require('../common/html_re').HTML_OPEN_CLOSE_TAG_RE;\n\n// An array of opening and corresponding closing sequences for html tags,\n// last argument defines whether it can terminate a paragraph or not\n//\nvar HTML_SEQUENCES = [\n [ /^<(script|pre|style)(?=(\\s|>|$))/i, /<\\/(script|pre|style)>/i, true ],\n [ /^<!--/, /-->/, true ],\n [ /^<\\?/, /\\?>/, true ],\n [ /^<![A-Z]/, />/, true ],\n [ /^<!\\[CDATA\\[/, /\\]\\]>/, true ],\n [ new RegExp('^</?(' + block_names.join('|') + ')(?=(\\\\s|/?>|$))', 'i'), /^$/, true ],\n [ new RegExp(HTML_OPEN_CLOSE_TAG_RE.source + '\\\\s*$'), /^$/, false ]\n];\n\n\nmodule.exports = function html_block(state, startLine, endLine, silent) {\n var i, nextLine, token, lineText,\n pos = state.bMarks[startLine] + state.tShift[startLine],\n max = state.eMarks[startLine];\n\n // if it's indented more than 3 spaces, it should be a code block\n if (state.sCount[startLine] - state.blkIndent >= 4) { return false; }\n\n if (!state.md.options.html) { return false; }\n\n if (state.src.charCodeAt(pos) !== 0x3C/* < */) { return false; }\n\n lineText = state.src.slice(pos, max);\n\n for (i = 0; i < HTML_SEQUENCES.length; i++) {\n if (HTML_SEQUENCES[i][0].test(lineText)) { break; }\n }\n\n if (i === HTML_SEQUENCES.length) { return false; }\n\n if (silent) {\n // true if this sequence can be a terminator, false otherwise\n return HTML_SEQUENCES[i][2];\n }\n\n nextLine = startLine + 1;\n\n // If we are here - we detected HTML block.\n // Let's roll down till block end.\n if (!HTML_SEQUENCES[i][1].test(lineText)) {\n for (; nextLine < endLine; nextLine++) {\n if (state.sCount[nextLine] < state.blkIndent) { break; }\n\n pos = state.bMarks[nextLine] + state.tShift[nextLine];\n max = state.eMarks[nextLine];\n lineText = state.src.slice(pos, max);\n\n if (HTML_SEQUENCES[i][1].test(lineText)) {\n if (lineText.length !== 0) { nextLine++; }\n break;\n }\n }\n }\n\n state.line = nextLine;\n\n token = state.push('html_block', '', 0);\n token.map = [ startLine, nextLine ];\n token.content = state.getLines(startLine, nextLine, state.blkIndent, true);\n\n return true;\n};\n","// List of valid html blocks names, accorting to commonmark spec\n// http://jgm.github.io/CommonMark/spec.html#html-blocks\n\n'use strict';\n\n\nmodule.exports = [\n 'address',\n 'article',\n 'aside',\n 'base',\n 'basefont',\n 'blockquote',\n 'body',\n 'caption',\n 'center',\n 'col',\n 'colgroup',\n 'dd',\n 'details',\n 'dialog',\n 'dir',\n 'div',\n 'dl',\n 'dt',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'frame',\n 'frameset',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'head',\n 'header',\n 'hr',\n 'html',\n 'iframe',\n 'legend',\n 'li',\n 'link',\n 'main',\n 'menu',\n 'menuitem',\n 'meta',\n 'nav',\n 'noframes',\n 'ol',\n 'optgroup',\n 'option',\n 'p',\n 'param',\n 'section',\n 'source',\n 'summary',\n 'table',\n 'tbody',\n 'td',\n 'tfoot',\n 'th',\n 'thead',\n 'title',\n 'tr',\n 'track',\n 'ul'\n];\n","// Paragraph\n\n'use strict';\n\n\nmodule.exports = function paragraph(state, startLine/*, endLine*/) {\n var content, terminate, i, l, token, oldParentType,\n nextLine = startLine + 1,\n terminatorRules = state.md.block.ruler.getRules('paragraph'),\n endLine = state.lineMax;\n\n oldParentType = state.parentType;\n state.parentType = 'paragraph';\n\n // jump line-by-line until empty one or EOF\n for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) {\n // this would be a code block normally, but after paragraph\n // it's considered a lazy continuation regardless of what's there\n if (state.sCount[nextLine] - state.blkIndent > 3) { continue; }\n\n // quirk for blockquotes, this line should already be checked by that rule\n if (state.sCount[nextLine] < 0) { continue; }\n\n // Some tags can terminate paragraph without empty line.\n terminate = false;\n for (i = 0, l = terminatorRules.length; i < l; i++) {\n if (terminatorRules[i](state, nextLine, endLine, true)) {\n terminate = true;\n break;\n }\n }\n if (terminate) { break; }\n }\n\n content = state.getLines(startLine, nextLine, state.blkIndent, false).trim();\n\n state.line = nextLine;\n\n token = state.push('paragraph_open', 'p', 1);\n token.map = [ startLine, state.line ];\n\n token = state.push('inline', '', 0);\n token.content = content;\n token.map = [ startLine, state.line ];\n token.children = [];\n\n token = state.push('paragraph_close', 'p', -1);\n\n state.parentType = oldParentType;\n\n return true;\n};\n","// Parser state class\n\n'use strict';\n\nvar Token = require('../token');\nvar isSpace = require('../common/utils').isSpace;\n\n\nfunction StateBlock(src, md, env, tokens) {\n var ch, s, start, pos, len, indent, offset, indent_found;\n\n this.src = src;\n\n // link to parser instance\n this.md = md;\n\n this.env = env;\n\n //\n // Internal state vartiables\n //\n\n this.tokens = tokens;\n\n this.bMarks = []; // line begin offsets for fast jumps\n this.eMarks = []; // line end offsets for fast jumps\n this.tShift = []; // offsets of the first non-space characters (tabs not expanded)\n this.sCount = []; // indents for each line (tabs expanded)\n\n // An amount of virtual spaces (tabs expanded) between beginning\n // of each line (bMarks) and real beginning of that line.\n //\n // It exists only as a hack because blockquotes override bMarks\n // losing information in the process.\n //\n // It's used only when expanding tabs, you can think about it as\n // an initial tab length, e.g. bsCount=21 applied to string `\\t123`\n // means first tab should be expanded to 4-21%4 === 3 spaces.\n //\n this.bsCount = [];\n\n // block parser variables\n this.blkIndent = 0; // required block content indent\n // (for example, if we are in list)\n this.line = 0; // line index in src\n this.lineMax = 0; // lines count\n this.tight = false; // loose/tight mode for lists\n this.ddIndent = -1; // indent of the current dd block (-1 if there isn't any)\n\n // can be 'blockquote', 'list', 'root', 'paragraph' or 'reference'\n // used in lists to determine if they interrupt a paragraph\n this.parentType = 'root';\n\n this.level = 0;\n\n // renderer\n this.result = '';\n\n // Create caches\n // Generate markers.\n s = this.src;\n indent_found = false;\n\n for (start = pos = indent = offset = 0, len = s.length; pos < len; pos++) {\n ch = s.charCodeAt(pos);\n\n if (!indent_found) {\n if (isSpace(ch)) {\n indent++;\n\n if (ch === 0x09) {\n offset += 4 - offset % 4;\n } else {\n offset++;\n }\n continue;\n } else {\n indent_found = true;\n }\n }\n\n if (ch === 0x0A || pos === len - 1) {\n if (ch !== 0x0A) { pos++; }\n this.bMarks.push(start);\n this.eMarks.push(pos);\n this.tShift.push(indent);\n this.sCount.push(offset);\n this.bsCount.push(0);\n\n indent_found = false;\n indent = 0;\n offset = 0;\n start = pos + 1;\n }\n }\n\n // Push fake entry to simplify cache bounds checks\n this.bMarks.push(s.length);\n this.eMarks.push(s.length);\n this.tShift.push(0);\n this.sCount.push(0);\n this.bsCount.push(0);\n\n this.lineMax = this.bMarks.length - 1; // don't count last fake line\n}\n\n// Push new token to \"stream\".\n//\nStateBlock.prototype.push = function (type, tag, nesting) {\n var token = new Token(type, tag, nesting);\n token.block = true;\n\n if (nesting < 0) { this.level--; }\n token.level = this.level;\n if (nesting > 0) { this.level++; }\n\n this.tokens.push(token);\n return token;\n};\n\nStateBlock.prototype.isEmpty = function isEmpty(line) {\n return this.bMarks[line] + this.tShift[line] >= this.eMarks[line];\n};\n\nStateBlock.prototype.skipEmptyLines = function skipEmptyLines(from) {\n for (var max = this.lineMax; from < max; from++) {\n if (this.bMarks[from] + this.tShift[from] < this.eMarks[from]) {\n break;\n }\n }\n return from;\n};\n\n// Skip spaces from given position.\nStateBlock.prototype.skipSpaces = function skipSpaces(pos) {\n var ch;\n\n for (var max = this.src.length; pos < max; pos++) {\n ch = this.src.charCodeAt(pos);\n if (!isSpace(ch)) { break; }\n }\n return pos;\n};\n\n// Skip spaces from given position in reverse.\nStateBlock.prototype.skipSpacesBack = function skipSpacesBack(pos, min) {\n if (pos <= min) { return pos; }\n\n while (pos > min) {\n if (!isSpace(this.src.charCodeAt(--pos))) { return pos + 1; }\n }\n return pos;\n};\n\n// Skip char codes from given position\nStateBlock.prototype.skipChars = function skipChars(pos, code) {\n for (var max = this.src.length; pos < max; pos++) {\n if (this.src.charCodeAt(pos) !== code) { break; }\n }\n return pos;\n};\n\n// Skip char codes reverse from given position - 1\nStateBlock.prototype.skipCharsBack = function skipCharsBack(pos, code, min) {\n if (pos <= min) { return pos; }\n\n while (pos > min) {\n if (code !== this.src.charCodeAt(--pos)) { return pos + 1; }\n }\n return pos;\n};\n\n// cut lines range from source.\nStateBlock.prototype.getLines = function getLines(begin, end, indent, keepLastLF) {\n var i, lineIndent, ch, first, last, queue, lineStart,\n line = begin;\n\n if (begin >= end) {\n return '';\n }\n\n queue = new Array(end - begin);\n\n for (i = 0; line < end; line++, i++) {\n lineIndent = 0;\n lineStart = first = this.bMarks[line];\n\n if (line + 1 < end || keepLastLF) {\n // No need for bounds check because we have fake entry on tail.\n last = this.eMarks[line] + 1;\n } else {\n last = this.eMarks[line];\n }\n\n while (first < last && lineIndent < indent) {\n ch = this.src.charCodeAt(first);\n\n if (isSpace(ch)) {\n if (ch === 0x09) {\n lineIndent += 4 - (lineIndent + this.bsCount[line]) % 4;\n } else {\n lineIndent++;\n }\n } else if (first - lineStart < this.tShift[line]) {\n // patched tShift masked characters to look like spaces (blockquotes, list markers)\n lineIndent++;\n } else {\n break;\n }\n\n first++;\n }\n\n if (lineIndent > indent) {\n // partially expanding tabs in code blocks, e.g '\\t\\tfoobar'\n // with indent=2 becomes ' \\tfoobar'\n queue[i] = new Array(lineIndent - indent + 1).join(' ') + this.src.slice(first, last);\n } else {\n queue[i] = this.src.slice(first, last);\n }\n }\n\n return queue.join('');\n};\n\n// re-export Token class to use in block rules\nStateBlock.prototype.Token = Token;\n\n\nmodule.exports = StateBlock;\n","/** internal\n * class ParserInline\n *\n * Tokenizes paragraph content.\n **/\n'use strict';\n\n\nvar Ruler = require('./ruler');\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Parser rules\n\nvar _rules = [\n [ 'text', require('./rules_inline/text') ],\n [ 'newline', require('./rules_inline/newline') ],\n [ 'escape', require('./rules_inline/escape') ],\n [ 'backticks', require('./rules_inline/backticks') ],\n [ 'strikethrough', require('./rules_inline/strikethrough').tokenize ],\n [ 'emphasis', require('./rules_inline/emphasis').tokenize ],\n [ 'link', require('./rules_inline/link') ],\n [ 'image', require('./rules_inline/image') ],\n [ 'autolink', require('./rules_inline/autolink') ],\n [ 'html_inline', require('./rules_inline/html_inline') ],\n [ 'entity', require('./rules_inline/entity') ]\n];\n\nvar _rules2 = [\n [ 'balance_pairs', require('./rules_inline/balance_pairs') ],\n [ 'strikethrough', require('./rules_inline/strikethrough').postProcess ],\n [ 'emphasis', require('./rules_inline/emphasis').postProcess ],\n [ 'text_collapse', require('./rules_inline/text_collapse') ]\n];\n\n\n/**\n * new ParserInline()\n **/\nfunction ParserInline() {\n var i;\n\n /**\n * ParserInline#ruler -> Ruler\n *\n * [[Ruler]] instance. Keep configuration of inline rules.\n **/\n this.ruler = new Ruler();\n\n for (i = 0; i < _rules.length; i++) {\n this.ruler.push(_rules[i][0], _rules[i][1]);\n }\n\n /**\n * ParserInline#ruler2 -> Ruler\n *\n * [[Ruler]] instance. Second ruler used for post-processing\n * (e.g. in emphasis-like rules).\n **/\n this.ruler2 = new Ruler();\n\n for (i = 0; i < _rules2.length; i++) {\n this.ruler2.push(_rules2[i][0], _rules2[i][1]);\n }\n}\n\n\n// Skip single token by running all rules in validation mode;\n// returns `true` if any rule reported success\n//\nParserInline.prototype.skipToken = function (state) {\n var ok, i, pos = state.pos,\n rules = this.ruler.getRules(''),\n len = rules.length,\n maxNesting = state.md.options.maxNesting,\n cache = state.cache;\n\n\n if (typeof cache[pos] !== 'undefined') {\n state.pos = cache[pos];\n return;\n }\n\n if (state.level < maxNesting) {\n for (i = 0; i < len; i++) {\n // Increment state.level and decrement it later to limit recursion.\n // It's harmless to do here, because no tokens are created. But ideally,\n // we'd need a separate private state variable for this purpose.\n //\n state.level++;\n ok = rules[i](state, true);\n state.level--;\n\n if (ok) { break; }\n }\n } else {\n // Too much nesting, just skip until the end of the paragraph.\n //\n // NOTE: this will cause links to behave incorrectly in the following case,\n // when an amount of `[` is exactly equal to `maxNesting + 1`:\n //\n // [[[[[[[[[[[[[[[[[[[[[foo]()\n //\n // TODO: remove this workaround when CM standard will allow nested links\n // (we can replace it by preventing links from being parsed in\n // validation mode)\n //\n state.pos = state.posMax;\n }\n\n if (!ok) { state.pos++; }\n cache[pos] = state.pos;\n};\n\n\n// Generate tokens for input range\n//\nParserInline.prototype.tokenize = function (state) {\n var ok, i,\n rules = this.ruler.getRules(''),\n len = rules.length,\n end = state.posMax,\n maxNesting = state.md.options.maxNesting;\n\n while (state.pos < end) {\n // Try all possible rules.\n // On success, rule should:\n //\n // - update `state.pos`\n // - update `state.tokens`\n // - return true\n\n if (state.level < maxNesting) {\n for (i = 0; i < len; i++) {\n ok = rules[i](state, false);\n if (ok) { break; }\n }\n }\n\n if (ok) {\n if (state.pos >= end) { break; }\n continue;\n }\n\n state.pending += state.src[state.pos++];\n }\n\n if (state.pending) {\n state.pushPending();\n }\n};\n\n\n/**\n * ParserInline.parse(str, md, env, outTokens)\n *\n * Process input string and push inline tokens into `outTokens`\n **/\nParserInline.prototype.parse = function (str, md, env, outTokens) {\n var i, rules, len;\n var state = new this.State(str, md, env, outTokens);\n\n this.tokenize(state);\n\n rules = this.ruler2.getRules('');\n len = rules.length;\n\n for (i = 0; i < len; i++) {\n rules[i](state);\n }\n};\n\n\nParserInline.prototype.State = require('./rules_inline/state_inline');\n\n\nmodule.exports = ParserInline;\n","// Skip text characters for text token, place those to pending buffer\n// and increment current pos\n\n'use strict';\n\n\n// Rule to skip pure text\n// '{}$%@~+=:' reserved for extentions\n\n// !, \", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \\, ], ^, _, `, {, |, }, or ~\n\n// !!!! Don't confuse with \"Markdown ASCII Punctuation\" chars\n// http://spec.commonmark.org/0.15/#ascii-punctuation-character\nfunction isTerminatorChar(ch) {\n switch (ch) {\n case 0x0A/* \\n */:\n case 0x21/* ! */:\n case 0x23/* # */:\n case 0x24/* $ */:\n case 0x25/* % */:\n case 0x26/* & */:\n case 0x2A/* * */:\n case 0x2B/* + */:\n case 0x2D/* - */:\n case 0x3A/* : */:\n case 0x3C/* < */:\n case 0x3D/* = */:\n case 0x3E/* > */:\n case 0x40/* @ */:\n case 0x5B/* [ */:\n case 0x5C/* \\ */:\n case 0x5D/* ] */:\n case 0x5E/* ^ */:\n case 0x5F/* _ */:\n case 0x60/* ` */:\n case 0x7B/* { */:\n case 0x7D/* } */:\n case 0x7E/* ~ */:\n return true;\n default:\n return false;\n }\n}\n\nmodule.exports = function text(state, silent) {\n var pos = state.pos;\n\n while (pos < state.posMax && !isTerminatorChar(state.src.charCodeAt(pos))) {\n pos++;\n }\n\n if (pos === state.pos) { return false; }\n\n if (!silent) { state.pending += state.src.slice(state.pos, pos); }\n\n state.pos = pos;\n\n return true;\n};\n\n// Alternative implementation, for memory.\n//\n// It costs 10% of performance, but allows extend terminators list, if place it\n// to `ParcerInline` property. Probably, will switch to it sometime, such\n// flexibility required.\n\n/*\nvar TERMINATOR_RE = /[\\n!#$%&*+\\-:<=>@[\\\\\\]^_`{}~]/;\n\nmodule.exports = function text(state, silent) {\n var pos = state.pos,\n idx = state.src.slice(pos).search(TERMINATOR_RE);\n\n // first char is terminator -> empty text\n if (idx === 0) { return false; }\n\n // no terminator -> text till end of string\n if (idx < 0) {\n if (!silent) { state.pending += state.src.slice(pos); }\n state.pos = state.src.length;\n return true;\n }\n\n if (!silent) { state.pending += state.src.slice(pos, pos + idx); }\n\n state.pos += idx;\n\n return true;\n};*/\n","// Proceess '\\n'\n\n'use strict';\n\nvar isSpace = require('../common/utils').isSpace;\n\n\nmodule.exports = function newline(state, silent) {\n var pmax, max, pos = state.pos;\n\n if (state.src.charCodeAt(pos) !== 0x0A/* \\n */) { return false; }\n\n pmax = state.pending.length - 1;\n max = state.posMax;\n\n // ' \\n' -> hardbreak\n // Lookup in pending chars is bad practice! Don't copy to other rules!\n // Pending string is stored in concat mode, indexed lookups will cause\n // convertion to flat mode.\n if (!silent) {\n if (pmax >= 0 && state.pending.charCodeAt(pmax) === 0x20) {\n if (pmax >= 1 && state.pending.charCodeAt(pmax - 1) === 0x20) {\n state.pending = state.pending.replace(/ +$/, '');\n state.push('hardbreak', 'br', 0);\n } else {\n state.pending = state.pending.slice(0, -1);\n state.push('softbreak', 'br', 0);\n }\n\n } else {\n state.push('softbreak', 'br', 0);\n }\n }\n\n pos++;\n\n // skip heading spaces for next line\n while (pos < max && isSpace(state.src.charCodeAt(pos))) { pos++; }\n\n state.pos = pos;\n return true;\n};\n","// Process escaped chars and hardbreaks\n\n'use strict';\n\nvar isSpace = require('../common/utils').isSpace;\n\nvar ESCAPED = [];\n\nfor (var i = 0; i < 256; i++) { ESCAPED.push(0); }\n\n'\\\\!\"#$%&\\'()*+,./:;<=>?@[]^_`{|}~-'\n .split('').forEach(function (ch) { ESCAPED[ch.charCodeAt(0)] = 1; });\n\n\nmodule.exports = function escape(state, silent) {\n var ch, pos = state.pos, max = state.posMax;\n\n if (state.src.charCodeAt(pos) !== 0x5C/* \\ */) { return false; }\n\n pos++;\n\n if (pos < max) {\n ch = state.src.charCodeAt(pos);\n\n if (ch < 256 && ESCAPED[ch] !== 0) {\n if (!silent) { state.pending += state.src[pos]; }\n state.pos += 2;\n return true;\n }\n\n if (ch === 0x0A) {\n if (!silent) {\n state.push('hardbreak', 'br', 0);\n }\n\n pos++;\n // skip leading whitespaces from next line\n while (pos < max) {\n ch = state.src.charCodeAt(pos);\n if (!isSpace(ch)) { break; }\n pos++;\n }\n\n state.pos = pos;\n return true;\n }\n }\n\n if (!silent) { state.pending += '\\\\'; }\n state.pos++;\n return true;\n};\n","// Parse backticks\n\n'use strict';\n\nmodule.exports = function backtick(state, silent) {\n var start, max, marker, matchStart, matchEnd, token,\n pos = state.pos,\n ch = state.src.charCodeAt(pos);\n\n if (ch !== 0x60/* ` */) { return false; }\n\n start = pos;\n pos++;\n max = state.posMax;\n\n while (pos < max && state.src.charCodeAt(pos) === 0x60/* ` */) { pos++; }\n\n marker = state.src.slice(start, pos);\n\n matchStart = matchEnd = pos;\n\n while ((matchStart = state.src.indexOf('`', matchEnd)) !== -1) {\n matchEnd = matchStart + 1;\n\n while (matchEnd < max && state.src.charCodeAt(matchEnd) === 0x60/* ` */) { matchEnd++; }\n\n if (matchEnd - matchStart === marker.length) {\n if (!silent) {\n token = state.push('code_inline', 'code', 0);\n token.markup = marker;\n token.content = state.src.slice(pos, matchStart)\n .replace(/[ \\n]+/g, ' ')\n .trim();\n }\n state.pos = matchEnd;\n return true;\n }\n }\n\n if (!silent) { state.pending += marker; }\n state.pos += marker.length;\n return true;\n};\n","// Process [link](<to> \"stuff\")\n\n'use strict';\n\nvar normalizeReference = require('../common/utils').normalizeReference;\nvar isSpace = require('../common/utils').isSpace;\n\n\nmodule.exports = function link(state, silent) {\n var attrs,\n code,\n label,\n labelEnd,\n labelStart,\n pos,\n res,\n ref,\n title,\n token,\n href = '',\n oldPos = state.pos,\n max = state.posMax,\n start = state.pos,\n parseReference = true;\n\n if (state.src.charCodeAt(state.pos) !== 0x5B/* [ */) { return false; }\n\n labelStart = state.pos + 1;\n labelEnd = state.md.helpers.parseLinkLabel(state, state.pos, true);\n\n // parser failed to find ']', so it's not a valid link\n if (labelEnd < 0) { return false; }\n\n pos = labelEnd + 1;\n if (pos < max && state.src.charCodeAt(pos) === 0x28/* ( */) {\n //\n // Inline link\n //\n\n // might have found a valid shortcut link, disable reference parsing\n parseReference = false;\n\n // [link]( <href> \"title\" )\n // ^^ skipping these spaces\n pos++;\n for (; pos < max; pos++) {\n code = state.src.charCodeAt(pos);\n if (!isSpace(code) && code !== 0x0A) { break; }\n }\n if (pos >= max) { return false; }\n\n // [link]( <href> \"title\" )\n // ^^^^^^ parsing link destination\n start = pos;\n res = state.md.helpers.parseLinkDestination(state.src, pos, state.posMax);\n if (res.ok) {\n href = state.md.normalizeLink(res.str);\n if (state.md.validateLink(href)) {\n pos = res.pos;\n } else {\n href = '';\n }\n }\n\n // [link]( <href> \"title\" )\n // ^^ skipping these spaces\n start = pos;\n for (; pos < max; pos++) {\n code = state.src.charCodeAt(pos);\n if (!isSpace(code) && code !== 0x0A) { break; }\n }\n\n // [link]( <href> \"title\" )\n // ^^^^^^^ parsing link title\n res = state.md.helpers.parseLinkTitle(state.src, pos, state.posMax);\n if (pos < max && start !== pos && res.ok) {\n title = res.str;\n pos = res.pos;\n\n // [link]( <href> \"title\" )\n // ^^ skipping these spaces\n for (; pos < max; pos++) {\n code = state.src.charCodeAt(pos);\n if (!isSpace(code) && code !== 0x0A) { break; }\n }\n } else {\n title = '';\n }\n\n if (pos >= max || state.src.charCodeAt(pos) !== 0x29/* ) */) {\n // parsing a valid shortcut link failed, fallback to reference\n parseReference = true;\n }\n pos++;\n }\n\n if (parseReference) {\n //\n // Link reference\n //\n if (typeof state.env.references === 'undefined') { return false; }\n\n if (pos < max && state.src.charCodeAt(pos) === 0x5B/* [ */) {\n start = pos + 1;\n pos = state.md.helpers.parseLinkLabel(state, pos);\n if (pos >= 0) {\n label = state.src.slice(start, pos++);\n } else {\n pos = labelEnd + 1;\n }\n } else {\n pos = labelEnd + 1;\n }\n\n // covers label === '' and label === undefined\n // (collapsed reference link and shortcut reference link respectively)\n if (!label) { label = state.src.slice(labelStart, labelEnd); }\n\n ref = state.env.references[normalizeReference(label)];\n if (!ref) {\n state.pos = oldPos;\n return false;\n }\n href = ref.href;\n title = ref.title;\n }\n\n //\n // We found the end of the link, and know for a fact it's a valid link;\n // so all that's left to do is to call tokenizer.\n //\n if (!silent) {\n state.pos = labelStart;\n state.posMax = labelEnd;\n\n token = state.push('link_open', 'a', 1);\n token.attrs = attrs = [ [ 'href', href ] ];\n if (title) {\n attrs.push([ 'title', title ]);\n }\n\n state.md.inline.tokenize(state);\n\n token = state.push('link_close', 'a', -1);\n }\n\n state.pos = pos;\n state.posMax = max;\n return true;\n};\n","// Process ![image](<src> \"title\")\n\n'use strict';\n\nvar normalizeReference = require('../common/utils').normalizeReference;\nvar isSpace = require('../common/utils').isSpace;\n\n\nmodule.exports = function image(state, silent) {\n var attrs,\n code,\n content,\n label,\n labelEnd,\n labelStart,\n pos,\n ref,\n res,\n title,\n token,\n tokens,\n start,\n href = '',\n oldPos = state.pos,\n max = state.posMax;\n\n if (state.src.charCodeAt(state.pos) !== 0x21/* ! */) { return false; }\n if (state.src.charCodeAt(state.pos + 1) !== 0x5B/* [ */) { return false; }\n\n labelStart = state.pos + 2;\n labelEnd = state.md.helpers.parseLinkLabel(state, state.pos + 1, false);\n\n // parser failed to find ']', so it's not a valid link\n if (labelEnd < 0) { return false; }\n\n pos = labelEnd + 1;\n if (pos < max && state.src.charCodeAt(pos) === 0x28/* ( */) {\n //\n // Inline link\n //\n\n // [link]( <href> \"title\" )\n // ^^ skipping these spaces\n pos++;\n for (; pos < max; pos++) {\n code = state.src.charCodeAt(pos);\n if (!isSpace(code) && code !== 0x0A) { break; }\n }\n if (pos >= max) { return false; }\n\n // [link]( <href> \"title\" )\n // ^^^^^^ parsing link destination\n start = pos;\n res = state.md.helpers.parseLinkDestination(state.src, pos, state.posMax);\n if (res.ok) {\n href = state.md.normalizeLink(res.str);\n if (state.md.validateLink(href)) {\n pos = res.pos;\n } else {\n href = '';\n }\n }\n\n // [link]( <href> \"title\" )\n // ^^ skipping these spaces\n start = pos;\n for (; pos < max; pos++) {\n code = state.src.charCodeAt(pos);\n if (!isSpace(code) && code !== 0x0A) { break; }\n }\n\n // [link]( <href> \"title\" )\n // ^^^^^^^ parsing link title\n res = state.md.helpers.parseLinkTitle(state.src, pos, state.posMax);\n if (pos < max && start !== pos && res.ok) {\n title = res.str;\n pos = res.pos;\n\n // [link]( <href> \"title\" )\n // ^^ skipping these spaces\n for (; pos < max; pos++) {\n code = state.src.charCodeAt(pos);\n if (!isSpace(code) && code !== 0x0A) { break; }\n }\n } else {\n title = '';\n }\n\n if (pos >= max || state.src.charCodeAt(pos) !== 0x29/* ) */) {\n state.pos = oldPos;\n return false;\n }\n pos++;\n } else {\n //\n // Link reference\n //\n if (typeof state.env.references === 'undefined') { return false; }\n\n if (pos < max && state.src.charCodeAt(pos) === 0x5B/* [ */) {\n start = pos + 1;\n pos = state.md.helpers.parseLinkLabel(state, pos);\n if (pos >= 0) {\n label = state.src.slice(start, pos++);\n } else {\n pos = labelEnd + 1;\n }\n } else {\n pos = labelEnd + 1;\n }\n\n // covers label === '' and label === undefined\n // (collapsed reference link and shortcut reference link respectively)\n if (!label) { label = state.src.slice(labelStart, labelEnd); }\n\n ref = state.env.references[normalizeReference(label)];\n if (!ref) {\n state.pos = oldPos;\n return false;\n }\n href = ref.href;\n title = ref.title;\n }\n\n //\n // We found the end of the link, and know for a fact it's a valid link;\n // so all that's left to do is to call tokenizer.\n //\n if (!silent) {\n content = state.src.slice(labelStart, labelEnd);\n\n state.md.inline.parse(\n content,\n state.md,\n state.env,\n tokens = []\n );\n\n token = state.push('image', 'img', 0);\n token.attrs = attrs = [ [ 'src', href ], [ 'alt', '' ] ];\n token.children = tokens;\n token.content = content;\n\n if (title) {\n attrs.push([ 'title', title ]);\n }\n }\n\n state.pos = pos;\n state.posMax = max;\n return true;\n};\n","// Process autolinks '<protocol:...>'\n\n'use strict';\n\n\n/*eslint max-len:0*/\nvar EMAIL_RE = /^<([a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)>/;\nvar AUTOLINK_RE = /^<([a-zA-Z][a-zA-Z0-9+.\\-]{1,31}):([^<>\\x00-\\x20]*)>/;\n\n\nmodule.exports = function autolink(state, silent) {\n var tail, linkMatch, emailMatch, url, fullUrl, token,\n pos = state.pos;\n\n if (state.src.charCodeAt(pos) !== 0x3C/* < */) { return false; }\n\n tail = state.src.slice(pos);\n\n if (tail.indexOf('>') < 0) { return false; }\n\n if (AUTOLINK_RE.test(tail)) {\n linkMatch = tail.match(AUTOLINK_RE);\n\n url = linkMatch[0].slice(1, -1);\n fullUrl = state.md.normalizeLink(url);\n if (!state.md.validateLink(fullUrl)) { return false; }\n\n if (!silent) {\n token = state.push('link_open', 'a', 1);\n token.attrs = [ [ 'href', fullUrl ] ];\n token.markup = 'autolink';\n token.info = 'auto';\n\n token = state.push('text', '', 0);\n token.content = state.md.normalizeLinkText(url);\n\n token = state.push('link_close', 'a', -1);\n token.markup = 'autolink';\n token.info = 'auto';\n }\n\n state.pos += linkMatch[0].length;\n return true;\n }\n\n if (EMAIL_RE.test(tail)) {\n emailMatch = tail.match(EMAIL_RE);\n\n url = emailMatch[0].slice(1, -1);\n fullUrl = state.md.normalizeLink('mailto:' + url);\n if (!state.md.validateLink(fullUrl)) { return false; }\n\n if (!silent) {\n token = state.push('link_open', 'a', 1);\n token.attrs = [ [ 'href', fullUrl ] ];\n token.markup = 'autolink';\n token.info = 'auto';\n\n token = state.push('text', '', 0);\n token.content = state.md.normalizeLinkText(url);\n\n token = state.push('link_close', 'a', -1);\n token.markup = 'autolink';\n token.info = 'auto';\n }\n\n state.pos += emailMatch[0].length;\n return true;\n }\n\n return false;\n};\n","// Process html tags\n\n'use strict';\n\n\nvar HTML_TAG_RE = require('../common/html_re').HTML_TAG_RE;\n\n\nfunction isLetter(ch) {\n /*eslint no-bitwise:0*/\n var lc = ch | 0x20; // to lower case\n return (lc >= 0x61/* a */) && (lc <= 0x7a/* z */);\n}\n\n\nmodule.exports = function html_inline(state, silent) {\n var ch, match, max, token,\n pos = state.pos;\n\n if (!state.md.options.html) { return false; }\n\n // Check start\n max = state.posMax;\n if (state.src.charCodeAt(pos) !== 0x3C/* < */ ||\n pos + 2 >= max) {\n return false;\n }\n\n // Quick fail on second char\n ch = state.src.charCodeAt(pos + 1);\n if (ch !== 0x21/* ! */ &&\n ch !== 0x3F/* ? */ &&\n ch !== 0x2F/* / */ &&\n !isLetter(ch)) {\n return false;\n }\n\n match = state.src.slice(pos).match(HTML_TAG_RE);\n if (!match) { return false; }\n\n if (!silent) {\n token = state.push('html_inline', '', 0);\n token.content = state.src.slice(pos, pos + match[0].length);\n }\n state.pos += match[0].length;\n return true;\n};\n","// Process html entity - &#123;, &#xAF;, &quot;, ...\n\n'use strict';\n\nvar entities = require('../common/entities');\nvar has = require('../common/utils').has;\nvar isValidEntityCode = require('../common/utils').isValidEntityCode;\nvar fromCodePoint = require('../common/utils').fromCodePoint;\n\n\nvar DIGITAL_RE = /^&#((?:x[a-f0-9]{1,8}|[0-9]{1,8}));/i;\nvar NAMED_RE = /^&([a-z][a-z0-9]{1,31});/i;\n\n\nmodule.exports = function entity(state, silent) {\n var ch, code, match, pos = state.pos, max = state.posMax;\n\n if (state.src.charCodeAt(pos) !== 0x26/* & */) { return false; }\n\n if (pos + 1 < max) {\n ch = state.src.charCodeAt(pos + 1);\n\n if (ch === 0x23 /* # */) {\n match = state.src.slice(pos).match(DIGITAL_RE);\n if (match) {\n if (!silent) {\n code = match[1][0].toLowerCase() === 'x' ? parseInt(match[1].slice(1), 16) : parseInt(match[1], 10);\n state.pending += isValidEntityCode(code) ? fromCodePoint(code) : fromCodePoint(0xFFFD);\n }\n state.pos += match[0].length;\n return true;\n }\n } else {\n match = state.src.slice(pos).match(NAMED_RE);\n if (match) {\n if (has(entities, match[1])) {\n if (!silent) { state.pending += entities[match[1]]; }\n state.pos += match[0].length;\n return true;\n }\n }\n }\n }\n\n if (!silent) { state.pending += '&'; }\n state.pos++;\n return true;\n};\n","// For each opening emphasis-like marker find a matching closing one\n//\n'use strict';\n\n\nmodule.exports = function link_pairs(state) {\n var i, j, lastDelim, currDelim,\n delimiters = state.delimiters,\n max = state.delimiters.length;\n\n for (i = 0; i < max; i++) {\n lastDelim = delimiters[i];\n\n if (!lastDelim.close) { continue; }\n\n j = i - lastDelim.jump - 1;\n\n while (j >= 0) {\n currDelim = delimiters[j];\n\n if (currDelim.open &&\n currDelim.marker === lastDelim.marker &&\n currDelim.end < 0 &&\n currDelim.level === lastDelim.level) {\n\n // typeofs are for backward compatibility with plugins\n var odd_match = (currDelim.close || lastDelim.open) &&\n typeof currDelim.length !== 'undefined' &&\n typeof lastDelim.length !== 'undefined' &&\n (currDelim.length + lastDelim.length) % 3 === 0;\n\n if (!odd_match) {\n lastDelim.jump = i - j;\n lastDelim.open = false;\n currDelim.end = i;\n currDelim.jump = 0;\n break;\n }\n }\n\n j -= currDelim.jump + 1;\n }\n }\n};\n","// Merge adjacent text nodes into one, and re-calculate all token levels\n//\n'use strict';\n\n\nmodule.exports = function text_collapse(state) {\n var curr, last,\n level = 0,\n tokens = state.tokens,\n max = state.tokens.length;\n\n for (curr = last = 0; curr < max; curr++) {\n // re-calculate levels\n level += tokens[curr].nesting;\n tokens[curr].level = level;\n\n if (tokens[curr].type === 'text' &&\n curr + 1 < max &&\n tokens[curr + 1].type === 'text') {\n\n // collapse two adjacent text nodes\n tokens[curr + 1].content = tokens[curr].content + tokens[curr + 1].content;\n } else {\n if (curr !== last) { tokens[last] = tokens[curr]; }\n\n last++;\n }\n }\n\n if (curr !== last) {\n tokens.length = last;\n }\n};\n","// Inline parser state\n\n'use strict';\n\n\nvar Token = require('../token');\nvar isWhiteSpace = require('../common/utils').isWhiteSpace;\nvar isPunctChar = require('../common/utils').isPunctChar;\nvar isMdAsciiPunct = require('../common/utils').isMdAsciiPunct;\n\n\nfunction StateInline(src, md, env, outTokens) {\n this.src = src;\n this.env = env;\n this.md = md;\n this.tokens = outTokens;\n\n this.pos = 0;\n this.posMax = this.src.length;\n this.level = 0;\n this.pending = '';\n this.pendingLevel = 0;\n\n this.cache = {}; // Stores { start: end } pairs. Useful for backtrack\n // optimization of pairs parse (emphasis, strikes).\n\n this.delimiters = []; // Emphasis-like delimiters\n}\n\n\n// Flush pending text\n//\nStateInline.prototype.pushPending = function () {\n var token = new Token('text', '', 0);\n token.content = this.pending;\n token.level = this.pendingLevel;\n this.tokens.push(token);\n this.pending = '';\n return token;\n};\n\n\n// Push new token to \"stream\".\n// If pending text exists - flush it as text token\n//\nStateInline.prototype.push = function (type, tag, nesting) {\n if (this.pending) {\n this.pushPending();\n }\n\n var token = new Token(type, tag, nesting);\n\n if (nesting < 0) { this.level--; }\n token.level = this.level;\n if (nesting > 0) { this.level++; }\n\n this.pendingLevel = this.level;\n this.tokens.push(token);\n return token;\n};\n\n\n// Scan a sequence of emphasis-like markers, and determine whether\n// it can start an emphasis sequence or end an emphasis sequence.\n//\n// - start - position to scan from (it should point at a valid marker);\n// - canSplitWord - determine if these markers can be found inside a word\n//\nStateInline.prototype.scanDelims = function (start, canSplitWord) {\n var pos = start, lastChar, nextChar, count, can_open, can_close,\n isLastWhiteSpace, isLastPunctChar,\n isNextWhiteSpace, isNextPunctChar,\n left_flanking = true,\n right_flanking = true,\n max = this.posMax,\n marker = this.src.charCodeAt(start);\n\n // treat beginning of the line as a whitespace\n lastChar = start > 0 ? this.src.charCodeAt(start - 1) : 0x20;\n\n while (pos < max && this.src.charCodeAt(pos) === marker) { pos++; }\n\n count = pos - start;\n\n // treat end of the line as a whitespace\n nextChar = pos < max ? this.src.charCodeAt(pos) : 0x20;\n\n isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));\n isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));\n\n isLastWhiteSpace = isWhiteSpace(lastChar);\n isNextWhiteSpace = isWhiteSpace(nextChar);\n\n if (isNextWhiteSpace) {\n left_flanking = false;\n } else if (isNextPunctChar) {\n if (!(isLastWhiteSpace || isLastPunctChar)) {\n left_flanking = false;\n }\n }\n\n if (isLastWhiteSpace) {\n right_flanking = false;\n } else if (isLastPunctChar) {\n if (!(isNextWhiteSpace || isNextPunctChar)) {\n right_flanking = false;\n }\n }\n\n if (!canSplitWord) {\n can_open = left_flanking && (!right_flanking || isLastPunctChar);\n can_close = right_flanking && (!left_flanking || isNextPunctChar);\n } else {\n can_open = left_flanking;\n can_close = right_flanking;\n }\n\n return {\n can_open: can_open,\n can_close: can_close,\n length: count\n };\n};\n\n\n// re-export Token class to use in block rules\nStateInline.prototype.Token = Token;\n\n\nmodule.exports = StateInline;\n","'use strict';\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Helpers\n\n// Merge objects\n//\nfunction assign(obj /*from1, from2, from3, ...*/) {\n var sources = Array.prototype.slice.call(arguments, 1);\n\n sources.forEach(function (source) {\n if (!source) { return; }\n\n Object.keys(source).forEach(function (key) {\n obj[key] = source[key];\n });\n });\n\n return obj;\n}\n\nfunction _class(obj) { return Object.prototype.toString.call(obj); }\nfunction isString(obj) { return _class(obj) === '[object String]'; }\nfunction isObject(obj) { return _class(obj) === '[object Object]'; }\nfunction isRegExp(obj) { return _class(obj) === '[object RegExp]'; }\nfunction isFunction(obj) { return _class(obj) === '[object Function]'; }\n\n\nfunction escapeRE(str) { return str.replace(/[.?*+^$[\\]\\\\(){}|-]/g, '\\\\$&'); }\n\n////////////////////////////////////////////////////////////////////////////////\n\n\nvar defaultOptions = {\n fuzzyLink: true,\n fuzzyEmail: true,\n fuzzyIP: false\n};\n\n\nfunction isOptionsObj(obj) {\n return Object.keys(obj || {}).reduce(function (acc, k) {\n return acc || defaultOptions.hasOwnProperty(k);\n }, false);\n}\n\n\nvar defaultSchemas = {\n 'http:': {\n validate: function (text, pos, self) {\n var tail = text.slice(pos);\n\n if (!self.re.http) {\n // compile lazily, because \"host\"-containing variables can change on tlds update.\n self.re.http = new RegExp(\n '^\\\\/\\\\/' + self.re.src_auth + self.re.src_host_port_strict + self.re.src_path, 'i'\n );\n }\n if (self.re.http.test(tail)) {\n return tail.match(self.re.http)[0].length;\n }\n return 0;\n }\n },\n 'https:': 'http:',\n 'ftp:': 'http:',\n '//': {\n validate: function (text, pos, self) {\n var tail = text.slice(pos);\n\n if (!self.re.no_http) {\n // compile lazily, because \"host\"-containing variables can change on tlds update.\n self.re.no_http = new RegExp(\n '^' +\n self.re.src_auth +\n // Don't allow single-level domains, because of false positives like '//test'\n // with code comments\n '(?:localhost|(?:(?:' + self.re.src_domain + ')\\\\.)+' + self.re.src_domain_root + ')' +\n self.re.src_port +\n self.re.src_host_terminator +\n self.re.src_path,\n\n 'i'\n );\n }\n\n if (self.re.no_http.test(tail)) {\n // should not be `://` & `///`, that protects from errors in protocol name\n if (pos >= 3 && text[pos - 3] === ':') { return 0; }\n if (pos >= 3 && text[pos - 3] === '/') { return 0; }\n return tail.match(self.re.no_http)[0].length;\n }\n return 0;\n }\n },\n 'mailto:': {\n validate: function (text, pos, self) {\n var tail = text.slice(pos);\n\n if (!self.re.mailto) {\n self.re.mailto = new RegExp(\n '^' + self.re.src_email_name + '@' + self.re.src_host_strict, 'i'\n );\n }\n if (self.re.mailto.test(tail)) {\n return tail.match(self.re.mailto)[0].length;\n }\n return 0;\n }\n }\n};\n\n/*eslint-disable max-len*/\n\n// RE pattern for 2-character tlds (autogenerated by ./support/tlds_2char_gen.js)\nvar tlds_2ch_src_re = 'a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnoruvwxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eosuw]|s[abcdeghijklmnortuvxyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|y[et]|z[amw]';\n\n// DON'T try to make PRs with changes. Extend TLDs with LinkifyIt.tlds() instead\nvar tlds_default = 'biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф'.split('|');\n\n/*eslint-enable max-len*/\n\n////////////////////////////////////////////////////////////////////////////////\n\nfunction resetScanCache(self) {\n self.__index__ = -1;\n self.__text_cache__ = '';\n}\n\nfunction createValidator(re) {\n return function (text, pos) {\n var tail = text.slice(pos);\n\n if (re.test(tail)) {\n return tail.match(re)[0].length;\n }\n return 0;\n };\n}\n\nfunction createNormalizer() {\n return function (match, self) {\n self.normalize(match);\n };\n}\n\n// Schemas compiler. Build regexps.\n//\nfunction compile(self) {\n\n // Load & clone RE patterns.\n var re = self.re = require('./lib/re')(self.__opts__);\n\n // Define dynamic patterns\n var tlds = self.__tlds__.slice();\n\n self.onCompile();\n\n if (!self.__tlds_replaced__) {\n tlds.push(tlds_2ch_src_re);\n }\n tlds.push(re.src_xn);\n\n re.src_tlds = tlds.join('|');\n\n function untpl(tpl) { return tpl.replace('%TLDS%', re.src_tlds); }\n\n re.email_fuzzy = RegExp(untpl(re.tpl_email_fuzzy), 'i');\n re.link_fuzzy = RegExp(untpl(re.tpl_link_fuzzy), 'i');\n re.link_no_ip_fuzzy = RegExp(untpl(re.tpl_link_no_ip_fuzzy), 'i');\n re.host_fuzzy_test = RegExp(untpl(re.tpl_host_fuzzy_test), 'i');\n\n //\n // Compile each schema\n //\n\n var aliases = [];\n\n self.__compiled__ = {}; // Reset compiled data\n\n function schemaError(name, val) {\n throw new Error('(LinkifyIt) Invalid schema \"' + name + '\": ' + val);\n }\n\n Object.keys(self.__schemas__).forEach(function (name) {\n var val = self.__schemas__[name];\n\n // skip disabled methods\n if (val === null) { return; }\n\n var compiled = { validate: null, link: null };\n\n self.__compiled__[name] = compiled;\n\n if (isObject(val)) {\n if (isRegExp(val.validate)) {\n compiled.validate = createValidator(val.validate);\n } else if (isFunction(val.validate)) {\n compiled.validate = val.validate;\n } else {\n schemaError(name, val);\n }\n\n if (isFunction(val.normalize)) {\n compiled.normalize = val.normalize;\n } else if (!val.normalize) {\n compiled.normalize = createNormalizer();\n } else {\n schemaError(name, val);\n }\n\n return;\n }\n\n if (isString(val)) {\n aliases.push(name);\n return;\n }\n\n schemaError(name, val);\n });\n\n //\n // Compile postponed aliases\n //\n\n aliases.forEach(function (alias) {\n if (!self.__compiled__[self.__schemas__[alias]]) {\n // Silently fail on missed schemas to avoid errons on disable.\n // schemaError(alias, self.__schemas__[alias]);\n return;\n }\n\n self.__compiled__[alias].validate =\n self.__compiled__[self.__schemas__[alias]].validate;\n self.__compiled__[alias].normalize =\n self.__compiled__[self.__schemas__[alias]].normalize;\n });\n\n //\n // Fake record for guessed links\n //\n self.__compiled__[''] = { validate: null, normalize: createNormalizer() };\n\n //\n // Build schema condition\n //\n var slist = Object.keys(self.__compiled__)\n .filter(function (name) {\n // Filter disabled & fake schemas\n return name.length > 0 && self.__compiled__[name];\n })\n .map(escapeRE)\n .join('|');\n // (?!_) cause 1.5x slowdown\n self.re.schema_test = RegExp('(^|(?!_)(?:[><\\uff5c]|' + re.src_ZPCc + '))(' + slist + ')', 'i');\n self.re.schema_search = RegExp('(^|(?!_)(?:[><\\uff5c]|' + re.src_ZPCc + '))(' + slist + ')', 'ig');\n\n self.re.pretest = RegExp(\n '(' + self.re.schema_test.source + ')|(' + self.re.host_fuzzy_test.source + ')|@',\n 'i'\n );\n\n //\n // Cleanup\n //\n\n resetScanCache(self);\n}\n\n/**\n * class Match\n *\n * Match result. Single element of array, returned by [[LinkifyIt#match]]\n **/\nfunction Match(self, shift) {\n var start = self.__index__,\n end = self.__last_index__,\n text = self.__text_cache__.slice(start, end);\n\n /**\n * Match#schema -> String\n *\n * Prefix (protocol) for matched string.\n **/\n this.schema = self.__schema__.toLowerCase();\n /**\n * Match#index -> Number\n *\n * First position of matched string.\n **/\n this.index = start + shift;\n /**\n * Match#lastIndex -> Number\n *\n * Next position after matched string.\n **/\n this.lastIndex = end + shift;\n /**\n * Match#raw -> String\n *\n * Matched string.\n **/\n this.raw = text;\n /**\n * Match#text -> String\n *\n * Notmalized text of matched string.\n **/\n this.text = text;\n /**\n * Match#url -> String\n *\n * Normalized url of matched string.\n **/\n this.url = text;\n}\n\nfunction createMatch(self, shift) {\n var match = new Match(self, shift);\n\n self.__compiled__[match.schema].normalize(match, self);\n\n return match;\n}\n\n\n/**\n * class LinkifyIt\n **/\n\n/**\n * new LinkifyIt(schemas, options)\n * - schemas (Object): Optional. Additional schemas to validate (prefix/validator)\n * - options (Object): { fuzzyLink|fuzzyEmail|fuzzyIP: true|false }\n *\n * Creates new linkifier instance with optional additional schemas.\n * Can be called without `new` keyword for convenience.\n *\n * By default understands:\n *\n * - `http(s)://...` , `ftp://...`, `mailto:...` & `//...` links\n * - \"fuzzy\" links and emails (example.com, foo@bar.com).\n *\n * `schemas` is an object, where each key/value describes protocol/rule:\n *\n * - __key__ - link prefix (usually, protocol name with `:` at the end, `skype:`\n * for example). `linkify-it` makes shure that prefix is not preceeded with\n * alphanumeric char and symbols. Only whitespaces and punctuation allowed.\n * - __value__ - rule to check tail after link prefix\n * - _String_ - just alias to existing rule\n * - _Object_\n * - _validate_ - validator function (should return matched length on success),\n * or `RegExp`.\n * - _normalize_ - optional function to normalize text & url of matched result\n * (for example, for @twitter mentions).\n *\n * `options`:\n *\n * - __fuzzyLink__ - recognige URL-s without `http(s):` prefix. Default `true`.\n * - __fuzzyIP__ - allow IPs in fuzzy links above. Can conflict with some texts\n * like version numbers. Default `false`.\n * - __fuzzyEmail__ - recognize emails without `mailto:` prefix.\n *\n **/\nfunction LinkifyIt(schemas, options) {\n if (!(this instanceof LinkifyIt)) {\n return new LinkifyIt(schemas, options);\n }\n\n if (!options) {\n if (isOptionsObj(schemas)) {\n options = schemas;\n schemas = {};\n }\n }\n\n this.__opts__ = assign({}, defaultOptions, options);\n\n // Cache last tested result. Used to skip repeating steps on next `match` call.\n this.__index__ = -1;\n this.__last_index__ = -1; // Next scan position\n this.__schema__ = '';\n this.__text_cache__ = '';\n\n this.__schemas__ = assign({}, defaultSchemas, schemas);\n this.__compiled__ = {};\n\n this.__tlds__ = tlds_default;\n this.__tlds_replaced__ = false;\n\n this.re = {};\n\n compile(this);\n}\n\n\n/** chainable\n * LinkifyIt#add(schema, definition)\n * - schema (String): rule name (fixed pattern prefix)\n * - definition (String|RegExp|Object): schema definition\n *\n * Add new rule definition. See constructor description for details.\n **/\nLinkifyIt.prototype.add = function add(schema, definition) {\n this.__schemas__[schema] = definition;\n compile(this);\n return this;\n};\n\n\n/** chainable\n * LinkifyIt#set(options)\n * - options (Object): { fuzzyLink|fuzzyEmail|fuzzyIP: true|false }\n *\n * Set recognition options for links without schema.\n **/\nLinkifyIt.prototype.set = function set(options) {\n this.__opts__ = assign(this.__opts__, options);\n return this;\n};\n\n\n/**\n * LinkifyIt#test(text) -> Boolean\n *\n * Searches linkifiable pattern and returns `true` on success or `false` on fail.\n **/\nLinkifyIt.prototype.test = function test(text) {\n // Reset scan cache\n this.__text_cache__ = text;\n this.__index__ = -1;\n\n if (!text.length) { return false; }\n\n var m, ml, me, len, shift, next, re, tld_pos, at_pos;\n\n // try to scan for link with schema - that's the most simple rule\n if (this.re.schema_test.test(text)) {\n re = this.re.schema_search;\n re.lastIndex = 0;\n while ((m = re.exec(text)) !== null) {\n len = this.testSchemaAt(text, m[2], re.lastIndex);\n if (len) {\n this.__schema__ = m[2];\n this.__index__ = m.index + m[1].length;\n this.__last_index__ = m.index + m[0].length + len;\n break;\n }\n }\n }\n\n if (this.__opts__.fuzzyLink && this.__compiled__['http:']) {\n // guess schemaless links\n tld_pos = text.search(this.re.host_fuzzy_test);\n if (tld_pos >= 0) {\n // if tld is located after found link - no need to check fuzzy pattern\n if (this.__index__ < 0 || tld_pos < this.__index__) {\n if ((ml = text.match(this.__opts__.fuzzyIP ? this.re.link_fuzzy : this.re.link_no_ip_fuzzy)) !== null) {\n\n shift = ml.index + ml[1].length;\n\n if (this.__index__ < 0 || shift < this.__index__) {\n this.__schema__ = '';\n this.__index__ = shift;\n this.__last_index__ = ml.index + ml[0].length;\n }\n }\n }\n }\n }\n\n if (this.__opts__.fuzzyEmail && this.__compiled__['mailto:']) {\n // guess schemaless emails\n at_pos = text.indexOf('@');\n if (at_pos >= 0) {\n // We can't skip this check, because this cases are possible:\n // 192.168.1.1@gmail.com, my.in@example.com\n if ((me = text.match(this.re.email_fuzzy)) !== null) {\n\n shift = me.index + me[1].length;\n next = me.index + me[0].length;\n\n if (this.__index__ < 0 || shift < this.__index__ ||\n (shift === this.__index__ && next > this.__last_index__)) {\n this.__schema__ = 'mailto:';\n this.__index__ = shift;\n this.__last_index__ = next;\n }\n }\n }\n }\n\n return this.__index__ >= 0;\n};\n\n\n/**\n * LinkifyIt#pretest(text) -> Boolean\n *\n * Very quick check, that can give false positives. Returns true if link MAY BE\n * can exists. Can be used for speed optimization, when you need to check that\n * link NOT exists.\n **/\nLinkifyIt.prototype.pretest = function pretest(text) {\n return this.re.pretest.test(text);\n};\n\n\n/**\n * LinkifyIt#testSchemaAt(text, name, position) -> Number\n * - text (String): text to scan\n * - name (String): rule (schema) name\n * - position (Number): text offset to check from\n *\n * Similar to [[LinkifyIt#test]] but checks only specific protocol tail exactly\n * at given position. Returns length of found pattern (0 on fail).\n **/\nLinkifyIt.prototype.testSchemaAt = function testSchemaAt(text, schema, pos) {\n // If not supported schema check requested - terminate\n if (!this.__compiled__[schema.toLowerCase()]) {\n return 0;\n }\n return this.__compiled__[schema.toLowerCase()].validate(text, pos, this);\n};\n\n\n/**\n * LinkifyIt#match(text) -> Array|null\n *\n * Returns array of found link descriptions or `null` on fail. We strongly\n * recommend to use [[LinkifyIt#test]] first, for best speed.\n *\n * ##### Result match description\n *\n * - __schema__ - link schema, can be empty for fuzzy links, or `//` for\n * protocol-neutral links.\n * - __index__ - offset of matched text\n * - __lastIndex__ - index of next char after mathch end\n * - __raw__ - matched text\n * - __text__ - normalized text\n * - __url__ - link, generated from matched text\n **/\nLinkifyIt.prototype.match = function match(text) {\n var shift = 0, result = [];\n\n // Try to take previous element from cache, if .test() called before\n if (this.__index__ >= 0 && this.__text_cache__ === text) {\n result.push(createMatch(this, shift));\n shift = this.__last_index__;\n }\n\n // Cut head if cache was used\n var tail = shift ? text.slice(shift) : text;\n\n // Scan string until end reached\n while (this.test(tail)) {\n result.push(createMatch(this, shift));\n\n tail = tail.slice(this.__last_index__);\n shift += this.__last_index__;\n }\n\n if (result.length) {\n return result;\n }\n\n return null;\n};\n\n\n/** chainable\n * LinkifyIt#tlds(list [, keepOld]) -> this\n * - list (Array): list of tlds\n * - keepOld (Boolean): merge with current list if `true` (`false` by default)\n *\n * Load (or merge) new tlds list. Those are user for fuzzy links (without prefix)\n * to avoid false positives. By default this algorythm used:\n *\n * - hostname with any 2-letter root zones are ok.\n * - biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф\n * are ok.\n * - encoded (`xn--...`) root zones are ok.\n *\n * If list is replaced, then exact match for 2-chars root zones will be checked.\n **/\nLinkifyIt.prototype.tlds = function tlds(list, keepOld) {\n list = Array.isArray(list) ? list : [ list ];\n\n if (!keepOld) {\n this.__tlds__ = list.slice();\n this.__tlds_replaced__ = true;\n compile(this);\n return this;\n }\n\n this.__tlds__ = this.__tlds__.concat(list)\n .sort()\n .filter(function (el, idx, arr) {\n return el !== arr[idx - 1];\n })\n .reverse();\n\n compile(this);\n return this;\n};\n\n/**\n * LinkifyIt#normalize(match)\n *\n * Default normalizer (if schema does not define it's own).\n **/\nLinkifyIt.prototype.normalize = function normalize(match) {\n\n // Do minimal possible changes by default. Need to collect feedback prior\n // to move forward https://github.com/markdown-it/linkify-it/issues/1\n\n if (!match.schema) { match.url = 'http://' + match.url; }\n\n if (match.schema === 'mailto:' && !/^mailto:/i.test(match.url)) {\n match.url = 'mailto:' + match.url;\n }\n};\n\n\n/**\n * LinkifyIt#onCompile()\n *\n * Override to modify basic RegExp-s.\n **/\nLinkifyIt.prototype.onCompile = function onCompile() {\n};\n\n\nmodule.exports = LinkifyIt;\n","'use strict';\n\n\nmodule.exports = function (opts) {\n var re = {};\n\n // Use direct extract instead of `regenerate` to reduse browserified size\n re.src_Any = require('uc.micro/properties/Any/regex').source;\n re.src_Cc = require('uc.micro/categories/Cc/regex').source;\n re.src_Z = require('uc.micro/categories/Z/regex').source;\n re.src_P = require('uc.micro/categories/P/regex').source;\n\n // \\p{\\Z\\P\\Cc\\CF} (white spaces + control + format + punctuation)\n re.src_ZPCc = [ re.src_Z, re.src_P, re.src_Cc ].join('|');\n\n // \\p{\\Z\\Cc} (white spaces + control)\n re.src_ZCc = [ re.src_Z, re.src_Cc ].join('|');\n\n // Experimental. List of chars, completely prohibited in links\n // because can separate it from other part of text\n var text_separators = '[><\\uff5c]';\n\n // All possible word characters (everything without punctuation, spaces & controls)\n // Defined via punctuation & spaces to save space\n // Should be something like \\p{\\L\\N\\S\\M} (\\w but without `_`)\n re.src_pseudo_letter = '(?:(?!' + text_separators + '|' + re.src_ZPCc + ')' + re.src_Any + ')';\n // The same as abothe but without [0-9]\n // var src_pseudo_letter_non_d = '(?:(?![0-9]|' + src_ZPCc + ')' + src_Any + ')';\n\n ////////////////////////////////////////////////////////////////////////////////\n\n re.src_ip4 =\n\n '(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)';\n\n // Prohibit any of \"@/[]()\" in user/pass to avoid wrong domain fetch.\n re.src_auth = '(?:(?:(?!' + re.src_ZCc + '|[@/\\\\[\\\\]()]).)+@)?';\n\n re.src_port =\n\n '(?::(?:6(?:[0-4]\\\\d{3}|5(?:[0-4]\\\\d{2}|5(?:[0-2]\\\\d|3[0-5])))|[1-5]?\\\\d{1,4}))?';\n\n re.src_host_terminator =\n\n '(?=$|' + text_separators + '|' + re.src_ZPCc + ')(?!-|_|:\\\\d|\\\\.-|\\\\.(?!$|' + re.src_ZPCc + '))';\n\n re.src_path =\n\n '(?:' +\n '[/?#]' +\n '(?:' +\n '(?!' + re.src_ZCc + '|' + text_separators + '|[()[\\\\]{}.,\"\\'?!\\\\-]).|' +\n '\\\\[(?:(?!' + re.src_ZCc + '|\\\\]).)*\\\\]|' +\n '\\\\((?:(?!' + re.src_ZCc + '|[)]).)*\\\\)|' +\n '\\\\{(?:(?!' + re.src_ZCc + '|[}]).)*\\\\}|' +\n '\\\\\"(?:(?!' + re.src_ZCc + '|[\"]).)+\\\\\"|' +\n \"\\\\'(?:(?!\" + re.src_ZCc + \"|[']).)+\\\\'|\" +\n \"\\\\'(?=\" + re.src_pseudo_letter + '|[-]).|' + // allow `I'm_king` if no pair found\n '\\\\.{2,3}[a-zA-Z0-9%/]|' + // github has ... in commit range links. Restrict to\n // - english\n // - percent-encoded\n // - parts of file path\n // until more examples found.\n '\\\\.(?!' + re.src_ZCc + '|[.]).|' +\n (opts && opts['---'] ?\n '\\\\-(?!--(?:[^-]|$))(?:-*)|' // `---` => long dash, terminate\n :\n '\\\\-+|'\n ) +\n '\\\\,(?!' + re.src_ZCc + ').|' + // allow `,,,` in paths\n '\\\\!(?!' + re.src_ZCc + '|[!]).|' +\n '\\\\?(?!' + re.src_ZCc + '|[?]).' +\n ')+' +\n '|\\\\/' +\n ')?';\n\n re.src_email_name =\n\n '[\\\\-;:&=\\\\+\\\\$,\\\\\"\\\\.a-zA-Z0-9_]+';\n\n re.src_xn =\n\n 'xn--[a-z0-9\\\\-]{1,59}';\n\n // More to read about domain names\n // http://serverfault.com/questions/638260/\n\n re.src_domain_root =\n\n // Allow letters & digits (http://test1)\n '(?:' +\n re.src_xn +\n '|' +\n re.src_pseudo_letter + '{1,63}' +\n ')';\n\n re.src_domain =\n\n '(?:' +\n re.src_xn +\n '|' +\n '(?:' + re.src_pseudo_letter + ')' +\n '|' +\n '(?:' + re.src_pseudo_letter + '(?:-|' + re.src_pseudo_letter + '){0,61}' + re.src_pseudo_letter + ')' +\n ')';\n\n re.src_host =\n\n '(?:' +\n // Don't need IP check, because digits are already allowed in normal domain names\n // src_ip4 +\n // '|' +\n '(?:(?:(?:' + re.src_domain + ')\\\\.)*' + re.src_domain/*_root*/ + ')' +\n ')';\n\n re.tpl_host_fuzzy =\n\n '(?:' +\n re.src_ip4 +\n '|' +\n '(?:(?:(?:' + re.src_domain + ')\\\\.)+(?:%TLDS%))' +\n ')';\n\n re.tpl_host_no_ip_fuzzy =\n\n '(?:(?:(?:' + re.src_domain + ')\\\\.)+(?:%TLDS%))';\n\n re.src_host_strict =\n\n re.src_host + re.src_host_terminator;\n\n re.tpl_host_fuzzy_strict =\n\n re.tpl_host_fuzzy + re.src_host_terminator;\n\n re.src_host_port_strict =\n\n re.src_host + re.src_port + re.src_host_terminator;\n\n re.tpl_host_port_fuzzy_strict =\n\n re.tpl_host_fuzzy + re.src_port + re.src_host_terminator;\n\n re.tpl_host_port_no_ip_fuzzy_strict =\n\n re.tpl_host_no_ip_fuzzy + re.src_port + re.src_host_terminator;\n\n\n ////////////////////////////////////////////////////////////////////////////////\n // Main rules\n\n // Rude test fuzzy links by host, for quick deny\n re.tpl_host_fuzzy_test =\n\n 'localhost|www\\\\.|\\\\.\\\\d{1,3}\\\\.|(?:\\\\.(?:%TLDS%)(?:' + re.src_ZPCc + '|>|$))';\n\n re.tpl_email_fuzzy =\n\n '(^|' + text_separators + '|\\\\(|' + re.src_ZCc + ')(' + re.src_email_name + '@' + re.tpl_host_fuzzy_strict + ')';\n\n re.tpl_link_fuzzy =\n // Fuzzy link can't be prepended with .:/\\- and non punctuation.\n // but can start with > (markdown blockquote)\n '(^|(?![.:/\\\\-_@])(?:[$+<=>^`|\\uff5c]|' + re.src_ZPCc + '))' +\n '((?![$+<=>^`|\\uff5c])' + re.tpl_host_port_fuzzy_strict + re.src_path + ')';\n\n re.tpl_link_no_ip_fuzzy =\n // Fuzzy link can't be prepended with .:/\\- and non punctuation.\n // but can start with > (markdown blockquote)\n '(^|(?![.:/\\\\-_@])(?:[$+<=>^`|\\uff5c]|' + re.src_ZPCc + '))' +\n '((?![$+<=>^`|\\uff5c])' + re.tpl_host_port_no_ip_fuzzy_strict + re.src_path + ')';\n\n return re;\n};\n","/*! https://mths.be/punycode v1.4.1 by @mathias */\n;(function(root) {\n\n\t/** Detect free variables */\n\tvar freeExports = typeof exports == 'object' && exports &&\n\t\t!exports.nodeType && exports;\n\tvar freeModule = typeof module == 'object' && module &&\n\t\t!module.nodeType && module;\n\tvar freeGlobal = typeof global == 'object' && global;\n\tif (\n\t\tfreeGlobal.global === freeGlobal ||\n\t\tfreeGlobal.window === freeGlobal ||\n\t\tfreeGlobal.self === freeGlobal\n\t) {\n\t\troot = freeGlobal;\n\t}\n\n\t/**\n\t * The `punycode` object.\n\t * @name punycode\n\t * @type Object\n\t */\n\tvar punycode,\n\n\t/** Highest positive signed 32-bit float value */\n\tmaxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1\n\n\t/** Bootstring parameters */\n\tbase = 36,\n\ttMin = 1,\n\ttMax = 26,\n\tskew = 38,\n\tdamp = 700,\n\tinitialBias = 72,\n\tinitialN = 128, // 0x80\n\tdelimiter = '-', // '\\x2D'\n\n\t/** Regular expressions */\n\tregexPunycode = /^xn--/,\n\tregexNonASCII = /[^\\x20-\\x7E]/, // unprintable ASCII chars + non-ASCII chars\n\tregexSeparators = /[\\x2E\\u3002\\uFF0E\\uFF61]/g, // RFC 3490 separators\n\n\t/** Error messages */\n\terrors = {\n\t\t'overflow': 'Overflow: input needs wider integers to process',\n\t\t'not-basic': 'Illegal input >= 0x80 (not a basic code point)',\n\t\t'invalid-input': 'Invalid input'\n\t},\n\n\t/** Convenience shortcuts */\n\tbaseMinusTMin = base - tMin,\n\tfloor = Math.floor,\n\tstringFromCharCode = String.fromCharCode,\n\n\t/** Temporary variable */\n\tkey;\n\n\t/*--------------------------------------------------------------------------*/\n\n\t/**\n\t * A generic error utility function.\n\t * @private\n\t * @param {String} type The error type.\n\t * @returns {Error} Throws a `RangeError` with the applicable error message.\n\t */\n\tfunction error(type) {\n\t\tthrow new RangeError(errors[type]);\n\t}\n\n\t/**\n\t * A generic `Array#map` utility function.\n\t * @private\n\t * @param {Array} array The array to iterate over.\n\t * @param {Function} callback The function that gets called for every array\n\t * item.\n\t * @returns {Array} A new array of values returned by the callback function.\n\t */\n\tfunction map(array, fn) {\n\t\tvar length = array.length;\n\t\tvar result = [];\n\t\twhile (length--) {\n\t\t\tresult[length] = fn(array[length]);\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * A simple `Array#map`-like wrapper to work with domain name strings or email\n\t * addresses.\n\t * @private\n\t * @param {String} domain The domain name or email address.\n\t * @param {Function} callback The function that gets called for every\n\t * character.\n\t * @returns {Array} A new string of characters returned by the callback\n\t * function.\n\t */\n\tfunction mapDomain(string, fn) {\n\t\tvar parts = string.split('@');\n\t\tvar result = '';\n\t\tif (parts.length > 1) {\n\t\t\t// In email addresses, only the domain name should be punycoded. Leave\n\t\t\t// the local part (i.e. everything up to `@`) intact.\n\t\t\tresult = parts[0] + '@';\n\t\t\tstring = parts[1];\n\t\t}\n\t\t// Avoid `split(regex)` for IE8 compatibility. See #17.\n\t\tstring = string.replace(regexSeparators, '\\x2E');\n\t\tvar labels = string.split('.');\n\t\tvar encoded = map(labels, fn).join('.');\n\t\treturn result + encoded;\n\t}\n\n\t/**\n\t * Creates an array containing the numeric code points of each Unicode\n\t * character in the string. While JavaScript uses UCS-2 internally,\n\t * this function will convert a pair of surrogate halves (each of which\n\t * UCS-2 exposes as separate characters) into a single code point,\n\t * matching UTF-16.\n\t * @see `punycode.ucs2.encode`\n\t * @see <https://mathiasbynens.be/notes/javascript-encoding>\n\t * @memberOf punycode.ucs2\n\t * @name decode\n\t * @param {String} string The Unicode input string (UCS-2).\n\t * @returns {Array} The new array of code points.\n\t */\n\tfunction ucs2decode(string) {\n\t\tvar output = [],\n\t\t counter = 0,\n\t\t length = string.length,\n\t\t value,\n\t\t extra;\n\t\twhile (counter < length) {\n\t\t\tvalue = string.charCodeAt(counter++);\n\t\t\tif (value >= 0xD800 && value <= 0xDBFF && counter < length) {\n\t\t\t\t// high surrogate, and there is a next character\n\t\t\t\textra = string.charCodeAt(counter++);\n\t\t\t\tif ((extra & 0xFC00) == 0xDC00) { // low surrogate\n\t\t\t\t\toutput.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);\n\t\t\t\t} else {\n\t\t\t\t\t// unmatched surrogate; only append this code unit, in case the next\n\t\t\t\t\t// code unit is the high surrogate of a surrogate pair\n\t\t\t\t\toutput.push(value);\n\t\t\t\t\tcounter--;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\toutput.push(value);\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t}\n\n\t/**\n\t * Creates a string based on an array of numeric code points.\n\t * @see `punycode.ucs2.decode`\n\t * @memberOf punycode.ucs2\n\t * @name encode\n\t * @param {Array} codePoints The array of numeric code points.\n\t * @returns {String} The new Unicode string (UCS-2).\n\t */\n\tfunction ucs2encode(array) {\n\t\treturn map(array, function(value) {\n\t\t\tvar output = '';\n\t\t\tif (value > 0xFFFF) {\n\t\t\t\tvalue -= 0x10000;\n\t\t\t\toutput += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);\n\t\t\t\tvalue = 0xDC00 | value & 0x3FF;\n\t\t\t}\n\t\t\toutput += stringFromCharCode(value);\n\t\t\treturn output;\n\t\t}).join('');\n\t}\n\n\t/**\n\t * Converts a basic code point into a digit/integer.\n\t * @see `digitToBasic()`\n\t * @private\n\t * @param {Number} codePoint The basic numeric code point value.\n\t * @returns {Number} The numeric value of a basic code point (for use in\n\t * representing integers) in the range `0` to `base - 1`, or `base` if\n\t * the code point does not represent a value.\n\t */\n\tfunction basicToDigit(codePoint) {\n\t\tif (codePoint - 48 < 10) {\n\t\t\treturn codePoint - 22;\n\t\t}\n\t\tif (codePoint - 65 < 26) {\n\t\t\treturn codePoint - 65;\n\t\t}\n\t\tif (codePoint - 97 < 26) {\n\t\t\treturn codePoint - 97;\n\t\t}\n\t\treturn base;\n\t}\n\n\t/**\n\t * Converts a digit/integer into a basic code point.\n\t * @see `basicToDigit()`\n\t * @private\n\t * @param {Number} digit The numeric value of a basic code point.\n\t * @returns {Number} The basic code point whose value (when used for\n\t * representing integers) is `digit`, which needs to be in the range\n\t * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is\n\t * used; else, the lowercase form is used. The behavior is undefined\n\t * if `flag` is non-zero and `digit` has no uppercase form.\n\t */\n\tfunction digitToBasic(digit, flag) {\n\t\t// 0..25 map to ASCII a..z or A..Z\n\t\t// 26..35 map to ASCII 0..9\n\t\treturn digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);\n\t}\n\n\t/**\n\t * Bias adaptation function as per section 3.4 of RFC 3492.\n\t * https://tools.ietf.org/html/rfc3492#section-3.4\n\t * @private\n\t */\n\tfunction adapt(delta, numPoints, firstTime) {\n\t\tvar k = 0;\n\t\tdelta = firstTime ? floor(delta / damp) : delta >> 1;\n\t\tdelta += floor(delta / numPoints);\n\t\tfor (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {\n\t\t\tdelta = floor(delta / baseMinusTMin);\n\t\t}\n\t\treturn floor(k + (baseMinusTMin + 1) * delta / (delta + skew));\n\t}\n\n\t/**\n\t * Converts a Punycode string of ASCII-only symbols to a string of Unicode\n\t * symbols.\n\t * @memberOf punycode\n\t * @param {String} input The Punycode string of ASCII-only symbols.\n\t * @returns {String} The resulting string of Unicode symbols.\n\t */\n\tfunction decode(input) {\n\t\t// Don't use UCS-2\n\t\tvar output = [],\n\t\t inputLength = input.length,\n\t\t out,\n\t\t i = 0,\n\t\t n = initialN,\n\t\t bias = initialBias,\n\t\t basic,\n\t\t j,\n\t\t index,\n\t\t oldi,\n\t\t w,\n\t\t k,\n\t\t digit,\n\t\t t,\n\t\t /** Cached calculation results */\n\t\t baseMinusT;\n\n\t\t// Handle the basic code points: let `basic` be the number of input code\n\t\t// points before the last delimiter, or `0` if there is none, then copy\n\t\t// the first basic code points to the output.\n\n\t\tbasic = input.lastIndexOf(delimiter);\n\t\tif (basic < 0) {\n\t\t\tbasic = 0;\n\t\t}\n\n\t\tfor (j = 0; j < basic; ++j) {\n\t\t\t// if it's not a basic code point\n\t\t\tif (input.charCodeAt(j) >= 0x80) {\n\t\t\t\terror('not-basic');\n\t\t\t}\n\t\t\toutput.push(input.charCodeAt(j));\n\t\t}\n\n\t\t// Main decoding loop: start just after the last delimiter if any basic code\n\t\t// points were copied; start at the beginning otherwise.\n\n\t\tfor (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {\n\n\t\t\t// `index` is the index of the next character to be consumed.\n\t\t\t// Decode a generalized variable-length integer into `delta`,\n\t\t\t// which gets added to `i`. The overflow checking is easier\n\t\t\t// if we increase `i` as we go, then subtract off its starting\n\t\t\t// value at the end to obtain `delta`.\n\t\t\tfor (oldi = i, w = 1, k = base; /* no condition */; k += base) {\n\n\t\t\t\tif (index >= inputLength) {\n\t\t\t\t\terror('invalid-input');\n\t\t\t\t}\n\n\t\t\t\tdigit = basicToDigit(input.charCodeAt(index++));\n\n\t\t\t\tif (digit >= base || digit > floor((maxInt - i) / w)) {\n\t\t\t\t\terror('overflow');\n\t\t\t\t}\n\n\t\t\t\ti += digit * w;\n\t\t\t\tt = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);\n\n\t\t\t\tif (digit < t) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tbaseMinusT = base - t;\n\t\t\t\tif (w > floor(maxInt / baseMinusT)) {\n\t\t\t\t\terror('overflow');\n\t\t\t\t}\n\n\t\t\t\tw *= baseMinusT;\n\n\t\t\t}\n\n\t\t\tout = output.length + 1;\n\t\t\tbias = adapt(i - oldi, out, oldi == 0);\n\n\t\t\t// `i` was supposed to wrap around from `out` to `0`,\n\t\t\t// incrementing `n` each time, so we'll fix that now:\n\t\t\tif (floor(i / out) > maxInt - n) {\n\t\t\t\terror('overflow');\n\t\t\t}\n\n\t\t\tn += floor(i / out);\n\t\t\ti %= out;\n\n\t\t\t// Insert `n` at position `i` of the output\n\t\t\toutput.splice(i++, 0, n);\n\n\t\t}\n\n\t\treturn ucs2encode(output);\n\t}\n\n\t/**\n\t * Converts a string of Unicode symbols (e.g. a domain name label) to a\n\t * Punycode string of ASCII-only symbols.\n\t * @memberOf punycode\n\t * @param {String} input The string of Unicode symbols.\n\t * @returns {String} The resulting Punycode string of ASCII-only symbols.\n\t */\n\tfunction encode(input) {\n\t\tvar n,\n\t\t delta,\n\t\t handledCPCount,\n\t\t basicLength,\n\t\t bias,\n\t\t j,\n\t\t m,\n\t\t q,\n\t\t k,\n\t\t t,\n\t\t currentValue,\n\t\t output = [],\n\t\t /** `inputLength` will hold the number of code points in `input`. */\n\t\t inputLength,\n\t\t /** Cached calculation results */\n\t\t handledCPCountPlusOne,\n\t\t baseMinusT,\n\t\t qMinusT;\n\n\t\t// Convert the input in UCS-2 to Unicode\n\t\tinput = ucs2decode(input);\n\n\t\t// Cache the length\n\t\tinputLength = input.length;\n\n\t\t// Initialize the state\n\t\tn = initialN;\n\t\tdelta = 0;\n\t\tbias = initialBias;\n\n\t\t// Handle the basic code points\n\t\tfor (j = 0; j < inputLength; ++j) {\n\t\t\tcurrentValue = input[j];\n\t\t\tif (currentValue < 0x80) {\n\t\t\t\toutput.push(stringFromCharCode(currentValue));\n\t\t\t}\n\t\t}\n\n\t\thandledCPCount = basicLength = output.length;\n\n\t\t// `handledCPCount` is the number of code points that have been handled;\n\t\t// `basicLength` is the number of basic code points.\n\n\t\t// Finish the basic string - if it is not empty - with a delimiter\n\t\tif (basicLength) {\n\t\t\toutput.push(delimiter);\n\t\t}\n\n\t\t// Main encoding loop:\n\t\twhile (handledCPCount < inputLength) {\n\n\t\t\t// All non-basic code points < n have been handled already. Find the next\n\t\t\t// larger one:\n\t\t\tfor (m = maxInt, j = 0; j < inputLength; ++j) {\n\t\t\t\tcurrentValue = input[j];\n\t\t\t\tif (currentValue >= n && currentValue < m) {\n\t\t\t\t\tm = currentValue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,\n\t\t\t// but guard against overflow\n\t\t\thandledCPCountPlusOne = handledCPCount + 1;\n\t\t\tif (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {\n\t\t\t\terror('overflow');\n\t\t\t}\n\n\t\t\tdelta += (m - n) * handledCPCountPlusOne;\n\t\t\tn = m;\n\n\t\t\tfor (j = 0; j < inputLength; ++j) {\n\t\t\t\tcurrentValue = input[j];\n\n\t\t\t\tif (currentValue < n && ++delta > maxInt) {\n\t\t\t\t\terror('overflow');\n\t\t\t\t}\n\n\t\t\t\tif (currentValue == n) {\n\t\t\t\t\t// Represent delta as a generalized variable-length integer\n\t\t\t\t\tfor (q = delta, k = base; /* no condition */; k += base) {\n\t\t\t\t\t\tt = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);\n\t\t\t\t\t\tif (q < t) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tqMinusT = q - t;\n\t\t\t\t\t\tbaseMinusT = base - t;\n\t\t\t\t\t\toutput.push(\n\t\t\t\t\t\t\tstringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))\n\t\t\t\t\t\t);\n\t\t\t\t\t\tq = floor(qMinusT / baseMinusT);\n\t\t\t\t\t}\n\n\t\t\t\t\toutput.push(stringFromCharCode(digitToBasic(q, 0)));\n\t\t\t\t\tbias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);\n\t\t\t\t\tdelta = 0;\n\t\t\t\t\t++handledCPCount;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t++delta;\n\t\t\t++n;\n\n\t\t}\n\t\treturn output.join('');\n\t}\n\n\t/**\n\t * Converts a Punycode string representing a domain name or an email address\n\t * to Unicode. Only the Punycoded parts of the input will be converted, i.e.\n\t * it doesn't matter if you call it on a string that has already been\n\t * converted to Unicode.\n\t * @memberOf punycode\n\t * @param {String} input The Punycoded domain name or email address to\n\t * convert to Unicode.\n\t * @returns {String} The Unicode representation of the given Punycode\n\t * string.\n\t */\n\tfunction toUnicode(input) {\n\t\treturn mapDomain(input, function(string) {\n\t\t\treturn regexPunycode.test(string)\n\t\t\t\t? decode(string.slice(4).toLowerCase())\n\t\t\t\t: string;\n\t\t});\n\t}\n\n\t/**\n\t * Converts a Unicode string representing a domain name or an email address to\n\t * Punycode. Only the non-ASCII parts of the domain name will be converted,\n\t * i.e. it doesn't matter if you call it with a domain that's already in\n\t * ASCII.\n\t * @memberOf punycode\n\t * @param {String} input The domain name or email address to convert, as a\n\t * Unicode string.\n\t * @returns {String} The Punycode representation of the given domain name or\n\t * email address.\n\t */\n\tfunction toASCII(input) {\n\t\treturn mapDomain(input, function(string) {\n\t\t\treturn regexNonASCII.test(string)\n\t\t\t\t? 'xn--' + encode(string)\n\t\t\t\t: string;\n\t\t});\n\t}\n\n\t/*--------------------------------------------------------------------------*/\n\n\t/** Define the public API */\n\tpunycode = {\n\t\t/**\n\t\t * A string representing the current Punycode.js version number.\n\t\t * @memberOf punycode\n\t\t * @type String\n\t\t */\n\t\t'version': '1.4.1',\n\t\t/**\n\t\t * An object of methods to convert from JavaScript's internal character\n\t\t * representation (UCS-2) to Unicode code points, and back.\n\t\t * @see <https://mathiasbynens.be/notes/javascript-encoding>\n\t\t * @memberOf punycode\n\t\t * @type Object\n\t\t */\n\t\t'ucs2': {\n\t\t\t'decode': ucs2decode,\n\t\t\t'encode': ucs2encode\n\t\t},\n\t\t'decode': decode,\n\t\t'encode': encode,\n\t\t'toASCII': toASCII,\n\t\t'toUnicode': toUnicode\n\t};\n\n\t/** Expose `punycode` */\n\t// Some AMD build optimizers, like r.js, check for specific condition patterns\n\t// like the following:\n\tif (\n\t\ttypeof define == 'function' &&\n\t\ttypeof define.amd == 'object' &&\n\t\tdefine.amd\n\t) {\n\t\tdefine('punycode', function() {\n\t\t\treturn punycode;\n\t\t});\n\t} else if (freeExports && freeModule) {\n\t\tif (module.exports == freeExports) {\n\t\t\t// in Node.js, io.js, or RingoJS v0.8.0+\n\t\t\tfreeModule.exports = punycode;\n\t\t} else {\n\t\t\t// in Narwhal or RingoJS v0.7.0-\n\t\t\tfor (key in punycode) {\n\t\t\t\tpunycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// in Rhino or a web browser\n\t\troot.punycode = punycode;\n\t}\n\n}(this));\n","module.exports = function(module) {\n\tif (!module.webpackPolyfill) {\n\t\tmodule.deprecate = function() {};\n\t\tmodule.paths = [];\n\t\t// module.parent = undefined by default\n\t\tif (!module.children) module.children = [];\n\t\tObject.defineProperty(module, \"loaded\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.l;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"id\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.i;\n\t\t\t}\n\t\t});\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n};\n","// markdown-it default options\n\n'use strict';\n\n\nmodule.exports = {\n options: {\n html: false, // Enable HTML tags in source\n xhtmlOut: false, // Use '/' to close single tags (<br />)\n breaks: false, // Convert '\\n' in paragraphs into <br>\n langPrefix: 'language-', // CSS language prefix for fenced blocks\n linkify: false, // autoconvert URL-like texts to links\n\n // Enable some language-neutral replacements + quotes beautification\n typographer: false,\n\n // Double + single quotes replacement pairs, when typographer enabled,\n // and smartquotes on. Could be either a String or an Array.\n //\n // For example, you can use '«»„“' for Russian, '„“‚‘' for German,\n // and ['«\\xA0', '\\xA0»', '‹\\xA0', '\\xA0›'] for French (including nbsp).\n quotes: '\\u201c\\u201d\\u2018\\u2019', /* “”‘’ */\n\n // Highlighter function. Should return escaped HTML,\n // or '' if the source string is not changed and should be escaped externaly.\n // If result starts with <pre... internal wrapper is skipped.\n //\n // function (/*str, lang*/) { return ''; }\n //\n highlight: null,\n\n maxNesting: 100 // Internal protection, recursion limit\n },\n\n components: {\n\n core: {},\n block: {},\n inline: {}\n }\n};\n","// \"Zero\" preset, with nothing enabled. Useful for manual configuring of simple\n// modes. For example, to parse bold/italic only.\n\n'use strict';\n\n\nmodule.exports = {\n options: {\n html: false, // Enable HTML tags in source\n xhtmlOut: false, // Use '/' to close single tags (<br />)\n breaks: false, // Convert '\\n' in paragraphs into <br>\n langPrefix: 'language-', // CSS language prefix for fenced blocks\n linkify: false, // autoconvert URL-like texts to links\n\n // Enable some language-neutral replacements + quotes beautification\n typographer: false,\n\n // Double + single quotes replacement pairs, when typographer enabled,\n // and smartquotes on. Could be either a String or an Array.\n //\n // For example, you can use '«»„“' for Russian, '„“‚‘' for German,\n // and ['«\\xA0', '\\xA0»', '‹\\xA0', '\\xA0›'] for French (including nbsp).\n quotes: '\\u201c\\u201d\\u2018\\u2019', /* “”‘’ */\n\n // Highlighter function. Should return escaped HTML,\n // or '' if the source string is not changed and should be escaped externaly.\n // If result starts with <pre... internal wrapper is skipped.\n //\n // function (/*str, lang*/) { return ''; }\n //\n highlight: null,\n\n maxNesting: 20 // Internal protection, recursion limit\n },\n\n components: {\n\n core: {\n rules: [\n 'normalize',\n 'block',\n 'inline'\n ]\n },\n\n block: {\n rules: [\n 'paragraph'\n ]\n },\n\n inline: {\n rules: [\n 'text'\n ],\n rules2: [\n 'balance_pairs',\n 'text_collapse'\n ]\n }\n }\n};\n","// Commonmark default options\n\n'use strict';\n\n\nmodule.exports = {\n options: {\n html: true, // Enable HTML tags in source\n xhtmlOut: true, // Use '/' to close single tags (<br />)\n breaks: false, // Convert '\\n' in paragraphs into <br>\n langPrefix: 'language-', // CSS language prefix for fenced blocks\n linkify: false, // autoconvert URL-like texts to links\n\n // Enable some language-neutral replacements + quotes beautification\n typographer: false,\n\n // Double + single quotes replacement pairs, when typographer enabled,\n // and smartquotes on. Could be either a String or an Array.\n //\n // For example, you can use '«»„“' for Russian, '„“‚‘' for German,\n // and ['«\\xA0', '\\xA0»', '‹\\xA0', '\\xA0›'] for French (including nbsp).\n quotes: '\\u201c\\u201d\\u2018\\u2019', /* “”‘’ */\n\n // Highlighter function. Should return escaped HTML,\n // or '' if the source string is not changed and should be escaped externaly.\n // If result starts with <pre... internal wrapper is skipped.\n //\n // function (/*str, lang*/) { return ''; }\n //\n highlight: null,\n\n maxNesting: 20 // Internal protection, recursion limit\n },\n\n components: {\n\n core: {\n rules: [\n 'normalize',\n 'block',\n 'inline'\n ]\n },\n\n block: {\n rules: [\n 'blockquote',\n 'code',\n 'fence',\n 'heading',\n 'hr',\n 'html_block',\n 'lheading',\n 'list',\n 'reference',\n 'paragraph'\n ]\n },\n\n inline: {\n rules: [\n 'autolink',\n 'backticks',\n 'emphasis',\n 'entity',\n 'escape',\n 'html_inline',\n 'image',\n 'link',\n 'newline',\n 'text'\n ],\n rules2: [\n 'balance_pairs',\n 'emphasis',\n 'text_collapse'\n ]\n }\n }\n};\n","\nvar content = require(\"!!../../../node_modules/postcss-loader/src/index.js??ref--5-1!./mentionui.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/postcss-loader/src/index.js??ref--5-1!./mentionui.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/postcss-loader/src/index.js??ref--5-1!./mentionui.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \":root{--ck-mention-list-max-height:300px}.ck.ck-mentions{max-height:var(--ck-mention-list-max-height);overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain}.ck.ck-mentions>.ck-list__item{overflow:hidden;flex-shrink:0}\"","\nvar content = require(\"!!../../../node_modules/postcss-loader/src/index.js??ref--5-1!./mention.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"singleton\":true,\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/postcss-loader/src/index.js??ref--5-1!./mention.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/postcss-loader/src/index.js??ref--5-1!./mention.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","module.exports = \":root{--ck-color-mention-background:rgba(153,0,48,0.1);--ck-color-mention-text:#990030}.ck-content .mention{background:var(--ck-color-mention-background);color:var(--ck-color-mention-text)}\"","import root from './_root.js';\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nexport default Symbol;\n","import Symbol from './_Symbol.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nexport default getRawTag;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nexport default objectToString;\n","import Symbol from './_Symbol.js';\nimport getRawTag from './_getRawTag.js';\nimport objectToString from './_objectToString.js';\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nexport default baseGetTag;\n","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nexport default overArg;\n","import overArg from './_overArg.js';\n\n/** Built-in value references. */\nvar getPrototype = overArg(Object.getPrototypeOf, Object);\n\nexport default getPrototype;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nexport default isObjectLike;\n","import baseGetTag from './_baseGetTag.js';\nimport getPrototype from './_getPrototype.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to infer the `Object` constructor. */\nvar objectCtorString = funcToString.call(Object);\n\n/**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\nfunction isPlainObject(value) {\n if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n return false;\n }\n var proto = getPrototype(value);\n if (proto === null) {\n return true;\n }\n var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n funcToString.call(Ctor) == objectCtorString;\n}\n\nexport default isPlainObject;\n","/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\nexport default listCacheClear;\n","/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nexport default eq;\n","import eq from './eq.js';\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\nexport default assocIndexOf;\n","import assocIndexOf from './_assocIndexOf.js';\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n --this.size;\n return true;\n}\n\nexport default listCacheDelete;\n","import assocIndexOf from './_assocIndexOf.js';\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\nexport default listCacheGet;\n","import assocIndexOf from './_assocIndexOf.js';\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n}\n\nexport default listCacheHas;\n","import assocIndexOf from './_assocIndexOf.js';\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n ++this.size;\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\nexport default listCacheSet;\n","import listCacheClear from './_listCacheClear.js';\nimport listCacheDelete from './_listCacheDelete.js';\nimport listCacheGet from './_listCacheGet.js';\nimport listCacheHas from './_listCacheHas.js';\nimport listCacheSet from './_listCacheSet.js';\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\nexport default ListCache;\n","import ListCache from './_ListCache.js';\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n this.__data__ = new ListCache;\n this.size = 0;\n}\n\nexport default stackClear;\n","/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n}\n\nexport default stackDelete;\n","/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\nexport default stackGet;\n","/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\nexport default stackHas;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nexport default isObject;\n","import baseGetTag from './_baseGetTag.js';\nimport isObject from './isObject.js';\n\n/** `Object#toString` result references. */\nvar asyncTag = '[object AsyncFunction]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n proxyTag = '[object Proxy]';\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nexport default isFunction;\n","import root from './_root.js';\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\nexport default coreJsData;\n","import coreJsData from './_coreJsData.js';\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\nexport default isMasked;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nexport default toSource;\n","import isFunction from './isFunction.js';\nimport isMasked from './_isMasked.js';\nimport isObject from './isObject.js';\nimport toSource from './_toSource.js';\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\nexport default baseIsNative;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nexport default getValue;\n","import baseIsNative from './_baseIsNative.js';\nimport getValue from './_getValue.js';\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\nexport default getNative;\n","import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar Map = getNative(root, 'Map');\n\nexport default Map;\n","import getNative from './_getNative.js';\n\n/* Built-in method references that are verified to be native. */\nvar nativeCreate = getNative(Object, 'create');\n\nexport default nativeCreate;\n","import nativeCreate from './_nativeCreate.js';\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n this.size = 0;\n}\n\nexport default hashClear;\n","/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\nexport default hashDelete;\n","import nativeCreate from './_nativeCreate.js';\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\nexport default hashGet;\n","import nativeCreate from './_nativeCreate.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n}\n\nexport default hashHas;\n","import nativeCreate from './_nativeCreate.js';\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n this.size += this.has(key) ? 0 : 1;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\nexport default hashSet;\n","import hashClear from './_hashClear.js';\nimport hashDelete from './_hashDelete.js';\nimport hashGet from './_hashGet.js';\nimport hashHas from './_hashHas.js';\nimport hashSet from './_hashSet.js';\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\nexport default Hash;\n","import Hash from './_Hash.js';\nimport ListCache from './_ListCache.js';\nimport Map from './_Map.js';\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.size = 0;\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n}\n\nexport default mapCacheClear;\n","/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nexport default isKeyable;\n","import isKeyable from './_isKeyable.js';\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\nexport default getMapData;\n","import getMapData from './_getMapData.js';\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n var result = getMapData(this, key)['delete'](key);\n this.size -= result ? 1 : 0;\n return result;\n}\n\nexport default mapCacheDelete;\n","import getMapData from './_getMapData.js';\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return getMapData(this, key).get(key);\n}\n\nexport default mapCacheGet;\n","import getMapData from './_getMapData.js';\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n return getMapData(this, key).has(key);\n}\n\nexport default mapCacheHas;\n","import getMapData from './_getMapData.js';\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n var data = getMapData(this, key),\n size = data.size;\n\n data.set(key, value);\n this.size += data.size == size ? 0 : 1;\n return this;\n}\n\nexport default mapCacheSet;\n","import mapCacheClear from './_mapCacheClear.js';\nimport mapCacheDelete from './_mapCacheDelete.js';\nimport mapCacheGet from './_mapCacheGet.js';\nimport mapCacheHas from './_mapCacheHas.js';\nimport mapCacheSet from './_mapCacheSet.js';\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\nexport default MapCache;\n","import ListCache from './_ListCache.js';\nimport Map from './_Map.js';\nimport MapCache from './_MapCache.js';\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n var data = this.__data__;\n if (data instanceof ListCache) {\n var pairs = data.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n this.size = ++data.size;\n return this;\n }\n data = this.__data__ = new MapCache(pairs);\n }\n data.set(key, value);\n this.size = data.size;\n return this;\n}\n\nexport default stackSet;\n","import ListCache from './_ListCache.js';\nimport stackClear from './_stackClear.js';\nimport stackDelete from './_stackDelete.js';\nimport stackGet from './_stackGet.js';\nimport stackHas from './_stackHas.js';\nimport stackSet from './_stackSet.js';\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n var data = this.__data__ = new ListCache(entries);\n this.size = data.size;\n}\n\n// Add methods to `Stack`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\nexport default Stack;\n","/**\n * A specialized version of `_.forEach` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\nfunction arrayEach(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (iteratee(array[index], index, array) === false) {\n break;\n }\n }\n return array;\n}\n\nexport default arrayEach;\n","import getNative from './_getNative.js';\n\nvar defineProperty = (function() {\n try {\n var func = getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n}());\n\nexport default defineProperty;\n","import defineProperty from './_defineProperty.js';\n\n/**\n * The base implementation of `assignValue` and `assignMergeValue` without\n * value checks.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction baseAssignValue(object, key, value) {\n if (key == '__proto__' && defineProperty) {\n defineProperty(object, key, {\n 'configurable': true,\n 'enumerable': true,\n 'value': value,\n 'writable': true\n });\n } else {\n object[key] = value;\n }\n}\n\nexport default baseAssignValue;\n","import baseAssignValue from './_baseAssignValue.js';\nimport eq from './eq.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n}\n\nexport default assignValue;\n","import assignValue from './_assignValue.js';\nimport baseAssignValue from './_baseAssignValue.js';\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n var isNew = !object;\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : undefined;\n\n if (newValue === undefined) {\n newValue = source[key];\n }\n if (isNew) {\n baseAssignValue(object, key, newValue);\n } else {\n assignValue(object, key, newValue);\n }\n }\n return object;\n}\n\nexport default copyObject;\n","/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\nexport default baseTimes;\n","import baseGetTag from './_baseGetTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]';\n\n/**\n * The base implementation of `_.isArguments`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n */\nfunction baseIsArguments(value) {\n return isObjectLike(value) && baseGetTag(value) == argsTag;\n}\n\nexport default baseIsArguments;\n","import baseIsArguments from './_baseIsArguments.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nvar isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n !propertyIsEnumerable.call(value, 'callee');\n};\n\nexport default isArguments;\n","/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nexport default isArray;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nexport default isIndex;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nexport default isLength;\n","import baseGetTag from './_baseGetTag.js';\nimport isLength from './isLength.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values of typed arrays. */\nvar typedArrayTags = {};\ntypedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\ntypedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\ntypedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\ntypedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\ntypedArrayTags[uint32Tag] = true;\ntypedArrayTags[argsTag] = typedArrayTags[arrayTag] =\ntypedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\ntypedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\ntypedArrayTags[errorTag] = typedArrayTags[funcTag] =\ntypedArrayTags[mapTag] = typedArrayTags[numberTag] =\ntypedArrayTags[objectTag] = typedArrayTags[regexpTag] =\ntypedArrayTags[setTag] = typedArrayTags[stringTag] =\ntypedArrayTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.isTypedArray` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n */\nfunction baseIsTypedArray(value) {\n return isObjectLike(value) &&\n isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n}\n\nexport default baseIsTypedArray;\n","/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\nexport default baseUnary;\n","import baseIsTypedArray from './_baseIsTypedArray.js';\nimport baseUnary from './_baseUnary.js';\nimport nodeUtil from './_nodeUtil.js';\n\n/* Node.js helper references. */\nvar nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n/**\n * Checks if `value` is classified as a typed array.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n * @example\n *\n * _.isTypedArray(new Uint8Array);\n * // => true\n *\n * _.isTypedArray([]);\n * // => false\n */\nvar isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\nexport default isTypedArray;\n","import baseTimes from './_baseTimes.js';\nimport isArguments from './isArguments.js';\nimport isArray from './isArray.js';\nimport isBuffer from './isBuffer.js';\nimport isIndex from './_isIndex.js';\nimport isTypedArray from './isTypedArray.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n var isArr = isArray(value),\n isArg = !isArr && isArguments(value),\n isBuff = !isArr && !isArg && isBuffer(value),\n isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n skipIndexes = isArr || isArg || isBuff || isType,\n result = skipIndexes ? baseTimes(value.length, String) : [],\n length = result.length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (\n // Safari 9 has enumerable `arguments.length` in strict mode.\n key == 'length' ||\n // Node.js 0.10 has enumerable non-index properties on buffers.\n (isBuff && (key == 'offset' || key == 'parent')) ||\n // PhantomJS 2 has enumerable non-index properties on typed arrays.\n (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n // Skip index properties.\n isIndex(key, length)\n ))) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default arrayLikeKeys;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\nexport default isPrototype;\n","import overArg from './_overArg.js';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = overArg(Object.keys, Object);\n\nexport default nativeKeys;\n","import isPrototype from './_isPrototype.js';\nimport nativeKeys from './_nativeKeys.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default baseKeys;\n","import isFunction from './isFunction.js';\nimport isLength from './isLength.js';\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\nexport default isArrayLike;\n","import arrayLikeKeys from './_arrayLikeKeys.js';\nimport baseKeys from './_baseKeys.js';\nimport isArrayLike from './isArrayLike.js';\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\nexport default keys;\n","import copyObject from './_copyObject.js';\nimport keys from './keys.js';\n\n/**\n * The base implementation of `_.assign` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssign(object, source) {\n return object && copyObject(source, keys(source), object);\n}\n\nexport default baseAssign;\n","/**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction nativeKeysIn(object) {\n var result = [];\n if (object != null) {\n for (var key in Object(object)) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default nativeKeysIn;\n","import isObject from './isObject.js';\nimport isPrototype from './_isPrototype.js';\nimport nativeKeysIn from './_nativeKeysIn.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeysIn(object) {\n if (!isObject(object)) {\n return nativeKeysIn(object);\n }\n var isProto = isPrototype(object),\n result = [];\n\n for (var key in object) {\n if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default baseKeysIn;\n","import arrayLikeKeys from './_arrayLikeKeys.js';\nimport baseKeysIn from './_baseKeysIn.js';\nimport isArrayLike from './isArrayLike.js';\n\n/**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\nfunction keysIn(object) {\n return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);\n}\n\nexport default keysIn;\n","import copyObject from './_copyObject.js';\nimport keysIn from './keysIn.js';\n\n/**\n * The base implementation of `_.assignIn` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssignIn(object, source) {\n return object && copyObject(source, keysIn(source), object);\n}\n\nexport default baseAssignIn;\n","/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\nexport default copyArray;\n","/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nexport default arrayFilter;\n","/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\nexport default stubArray;\n","import arrayFilter from './_arrayFilter.js';\nimport stubArray from './stubArray.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n if (object == null) {\n return [];\n }\n object = Object(object);\n return arrayFilter(nativeGetSymbols(object), function(symbol) {\n return propertyIsEnumerable.call(object, symbol);\n });\n};\n\nexport default getSymbols;\n","import copyObject from './_copyObject.js';\nimport getSymbols from './_getSymbols.js';\n\n/**\n * Copies own symbols of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\nfunction copySymbols(source, object) {\n return copyObject(source, getSymbols(source), object);\n}\n\nexport default copySymbols;\n","/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\nexport default arrayPush;\n","import arrayPush from './_arrayPush.js';\nimport getPrototype from './_getPrototype.js';\nimport getSymbols from './_getSymbols.js';\nimport stubArray from './stubArray.js';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own and inherited enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {\n var result = [];\n while (object) {\n arrayPush(result, getSymbols(object));\n object = getPrototype(object);\n }\n return result;\n};\n\nexport default getSymbolsIn;\n","import copyObject from './_copyObject.js';\nimport getSymbolsIn from './_getSymbolsIn.js';\n\n/**\n * Copies own and inherited symbols of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\nfunction copySymbolsIn(source, object) {\n return copyObject(source, getSymbolsIn(source), object);\n}\n\nexport default copySymbolsIn;\n","import arrayPush from './_arrayPush.js';\nimport isArray from './isArray.js';\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\nexport default baseGetAllKeys;\n","import baseGetAllKeys from './_baseGetAllKeys.js';\nimport getSymbols from './_getSymbols.js';\nimport keys from './keys.js';\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n}\n\nexport default getAllKeys;\n","import baseGetAllKeys from './_baseGetAllKeys.js';\nimport getSymbolsIn from './_getSymbolsIn.js';\nimport keysIn from './keysIn.js';\n\n/**\n * Creates an array of own and inherited enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeysIn(object) {\n return baseGetAllKeys(object, keysIn, getSymbolsIn);\n}\n\nexport default getAllKeysIn;\n","import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView');\n\nexport default DataView;\n","import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar Promise = getNative(root, 'Promise');\n\nexport default Promise;\n","import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar Set = getNative(root, 'Set');\n\nexport default Set;\n","import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar WeakMap = getNative(root, 'WeakMap');\n\nexport default WeakMap;\n","import DataView from './_DataView.js';\nimport Map from './_Map.js';\nimport Promise from './_Promise.js';\nimport Set from './_Set.js';\nimport WeakMap from './_WeakMap.js';\nimport baseGetTag from './_baseGetTag.js';\nimport toSource from './_toSource.js';\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n setTag = '[object Set]',\n weakMapTag = '[object WeakMap]';\n\nvar dataViewTag = '[object DataView]';\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = baseGetTag(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : '';\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n}\n\nexport default getTag;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Initializes an array clone.\n *\n * @private\n * @param {Array} array The array to clone.\n * @returns {Array} Returns the initialized clone.\n */\nfunction initCloneArray(array) {\n var length = array.length,\n result = new array.constructor(length);\n\n // Add properties assigned by `RegExp#exec`.\n if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n result.index = array.index;\n result.input = array.input;\n }\n return result;\n}\n\nexport default initCloneArray;\n","import root from './_root.js';\n\n/** Built-in value references. */\nvar Uint8Array = root.Uint8Array;\n\nexport default Uint8Array;\n","import Uint8Array from './_Uint8Array.js';\n\n/**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\nfunction cloneArrayBuffer(arrayBuffer) {\n var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n return result;\n}\n\nexport default cloneArrayBuffer;\n","import cloneArrayBuffer from './_cloneArrayBuffer.js';\n\n/**\n * Creates a clone of `dataView`.\n *\n * @private\n * @param {Object} dataView The data view to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned data view.\n */\nfunction cloneDataView(dataView, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n}\n\nexport default cloneDataView;\n","/** Used to match `RegExp` flags from their coerced string values. */\nvar reFlags = /\\w*$/;\n\n/**\n * Creates a clone of `regexp`.\n *\n * @private\n * @param {Object} regexp The regexp to clone.\n * @returns {Object} Returns the cloned regexp.\n */\nfunction cloneRegExp(regexp) {\n var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n result.lastIndex = regexp.lastIndex;\n return result;\n}\n\nexport default cloneRegExp;\n","import Symbol from './_Symbol.js';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * Creates a clone of the `symbol` object.\n *\n * @private\n * @param {Object} symbol The symbol object to clone.\n * @returns {Object} Returns the cloned symbol object.\n */\nfunction cloneSymbol(symbol) {\n return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n}\n\nexport default cloneSymbol;\n","import cloneArrayBuffer from './_cloneArrayBuffer.js';\n\n/**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\nfunction cloneTypedArray(typedArray, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n}\n\nexport default cloneTypedArray;\n","import cloneArrayBuffer from './_cloneArrayBuffer.js';\nimport cloneDataView from './_cloneDataView.js';\nimport cloneRegExp from './_cloneRegExp.js';\nimport cloneSymbol from './_cloneSymbol.js';\nimport cloneTypedArray from './_cloneTypedArray.js';\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/**\n * Initializes an object clone based on its `toStringTag`.\n *\n * **Note:** This function only supports cloning values with tags of\n * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.\n *\n * @private\n * @param {Object} object The object to clone.\n * @param {string} tag The `toStringTag` of the object to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneByTag(object, tag, isDeep) {\n var Ctor = object.constructor;\n switch (tag) {\n case arrayBufferTag:\n return cloneArrayBuffer(object);\n\n case boolTag:\n case dateTag:\n return new Ctor(+object);\n\n case dataViewTag:\n return cloneDataView(object, isDeep);\n\n case float32Tag: case float64Tag:\n case int8Tag: case int16Tag: case int32Tag:\n case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n return cloneTypedArray(object, isDeep);\n\n case mapTag:\n return new Ctor;\n\n case numberTag:\n case stringTag:\n return new Ctor(object);\n\n case regexpTag:\n return cloneRegExp(object);\n\n case setTag:\n return new Ctor;\n\n case symbolTag:\n return cloneSymbol(object);\n }\n}\n\nexport default initCloneByTag;\n","import isObject from './isObject.js';\n\n/** Built-in value references. */\nvar objectCreate = Object.create;\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} proto The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nvar baseCreate = (function() {\n function object() {}\n return function(proto) {\n if (!isObject(proto)) {\n return {};\n }\n if (objectCreate) {\n return objectCreate(proto);\n }\n object.prototype = proto;\n var result = new object;\n object.prototype = undefined;\n return result;\n };\n}());\n\nexport default baseCreate;\n","import baseCreate from './_baseCreate.js';\nimport getPrototype from './_getPrototype.js';\nimport isPrototype from './_isPrototype.js';\n\n/**\n * Initializes an object clone.\n *\n * @private\n * @param {Object} object The object to clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneObject(object) {\n return (typeof object.constructor == 'function' && !isPrototype(object))\n ? baseCreate(getPrototype(object))\n : {};\n}\n\nexport default initCloneObject;\n","import getTag from './_getTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]';\n\n/**\n * The base implementation of `_.isMap` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n */\nfunction baseIsMap(value) {\n return isObjectLike(value) && getTag(value) == mapTag;\n}\n\nexport default baseIsMap;\n","import baseIsMap from './_baseIsMap.js';\nimport baseUnary from './_baseUnary.js';\nimport nodeUtil from './_nodeUtil.js';\n\n/* Node.js helper references. */\nvar nodeIsMap = nodeUtil && nodeUtil.isMap;\n\n/**\n * Checks if `value` is classified as a `Map` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n * @example\n *\n * _.isMap(new Map);\n * // => true\n *\n * _.isMap(new WeakMap);\n * // => false\n */\nvar isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;\n\nexport default isMap;\n","import getTag from './_getTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar setTag = '[object Set]';\n\n/**\n * The base implementation of `_.isSet` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n */\nfunction baseIsSet(value) {\n return isObjectLike(value) && getTag(value) == setTag;\n}\n\nexport default baseIsSet;\n","import baseIsSet from './_baseIsSet.js';\nimport baseUnary from './_baseUnary.js';\nimport nodeUtil from './_nodeUtil.js';\n\n/* Node.js helper references. */\nvar nodeIsSet = nodeUtil && nodeUtil.isSet;\n\n/**\n * Checks if `value` is classified as a `Set` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n * @example\n *\n * _.isSet(new Set);\n * // => true\n *\n * _.isSet(new WeakSet);\n * // => false\n */\nvar isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;\n\nexport default isSet;\n","import Stack from './_Stack.js';\nimport arrayEach from './_arrayEach.js';\nimport assignValue from './_assignValue.js';\nimport baseAssign from './_baseAssign.js';\nimport baseAssignIn from './_baseAssignIn.js';\nimport cloneBuffer from './_cloneBuffer.js';\nimport copyArray from './_copyArray.js';\nimport copySymbols from './_copySymbols.js';\nimport copySymbolsIn from './_copySymbolsIn.js';\nimport getAllKeys from './_getAllKeys.js';\nimport getAllKeysIn from './_getAllKeysIn.js';\nimport getTag from './_getTag.js';\nimport initCloneArray from './_initCloneArray.js';\nimport initCloneByTag from './_initCloneByTag.js';\nimport initCloneObject from './_initCloneObject.js';\nimport isArray from './isArray.js';\nimport isBuffer from './isBuffer.js';\nimport isMap from './isMap.js';\nimport isObject from './isObject.js';\nimport isSet from './isSet.js';\nimport keys from './keys.js';\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_DEEP_FLAG = 1,\n CLONE_FLAT_FLAG = 2,\n CLONE_SYMBOLS_FLAG = 4;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values supported by `_.clone`. */\nvar cloneableTags = {};\ncloneableTags[argsTag] = cloneableTags[arrayTag] =\ncloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\ncloneableTags[boolTag] = cloneableTags[dateTag] =\ncloneableTags[float32Tag] = cloneableTags[float64Tag] =\ncloneableTags[int8Tag] = cloneableTags[int16Tag] =\ncloneableTags[int32Tag] = cloneableTags[mapTag] =\ncloneableTags[numberTag] = cloneableTags[objectTag] =\ncloneableTags[regexpTag] = cloneableTags[setTag] =\ncloneableTags[stringTag] = cloneableTags[symbolTag] =\ncloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\ncloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\ncloneableTags[errorTag] = cloneableTags[funcTag] =\ncloneableTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n * traversed objects.\n *\n * @private\n * @param {*} value The value to clone.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Deep clone\n * 2 - Flatten inherited properties\n * 4 - Clone symbols\n * @param {Function} [customizer] The function to customize cloning.\n * @param {string} [key] The key of `value`.\n * @param {Object} [object] The parent object of `value`.\n * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n * @returns {*} Returns the cloned value.\n */\nfunction baseClone(value, bitmask, customizer, key, object, stack) {\n var result,\n isDeep = bitmask & CLONE_DEEP_FLAG,\n isFlat = bitmask & CLONE_FLAT_FLAG,\n isFull = bitmask & CLONE_SYMBOLS_FLAG;\n\n if (customizer) {\n result = object ? customizer(value, key, object, stack) : customizer(value);\n }\n if (result !== undefined) {\n return result;\n }\n if (!isObject(value)) {\n return value;\n }\n var isArr = isArray(value);\n if (isArr) {\n result = initCloneArray(value);\n if (!isDeep) {\n return copyArray(value, result);\n }\n } else {\n var tag = getTag(value),\n isFunc = tag == funcTag || tag == genTag;\n\n if (isBuffer(value)) {\n return cloneBuffer(value, isDeep);\n }\n if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n result = (isFlat || isFunc) ? {} : initCloneObject(value);\n if (!isDeep) {\n return isFlat\n ? copySymbolsIn(value, baseAssignIn(result, value))\n : copySymbols(value, baseAssign(result, value));\n }\n } else {\n if (!cloneableTags[tag]) {\n return object ? value : {};\n }\n result = initCloneByTag(value, tag, isDeep);\n }\n }\n // Check for circular references and return its corresponding clone.\n stack || (stack = new Stack);\n var stacked = stack.get(value);\n if (stacked) {\n return stacked;\n }\n stack.set(value, result);\n\n if (isSet(value)) {\n value.forEach(function(subValue) {\n result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));\n });\n\n return result;\n }\n\n if (isMap(value)) {\n value.forEach(function(subValue, key) {\n result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));\n });\n\n return result;\n }\n\n var keysFunc = isFull\n ? (isFlat ? getAllKeysIn : getAllKeys)\n : (isFlat ? keysIn : keys);\n\n var props = isArr ? undefined : keysFunc(value);\n arrayEach(props || value, function(subValue, key) {\n if (props) {\n key = subValue;\n subValue = value[key];\n }\n // Recursively populate clone (susceptible to call stack limits).\n assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));\n });\n return result;\n}\n\nexport default baseClone;\n","import baseClone from './_baseClone.js';\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_DEEP_FLAG = 1,\n CLONE_SYMBOLS_FLAG = 4;\n\n/**\n * This method is like `_.cloneWith` except that it recursively clones `value`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to recursively clone.\n * @param {Function} [customizer] The function to customize cloning.\n * @returns {*} Returns the deep cloned value.\n * @see _.cloneWith\n * @example\n *\n * function customizer(value) {\n * if (_.isElement(value)) {\n * return value.cloneNode(true);\n * }\n * }\n *\n * var el = _.cloneDeepWith(document.body, customizer);\n *\n * console.log(el === document.body);\n * // => false\n * console.log(el.nodeName);\n * // => 'BODY'\n * console.log(el.childNodes.length);\n * // => 20\n */\nfunction cloneDeepWith(value, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);\n}\n\nexport default cloneDeepWith;\n","import isObjectLike from './isObjectLike.js';\nimport isPlainObject from './isPlainObject.js';\n\n/**\n * Checks if `value` is likely a DOM element.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.\n * @example\n *\n * _.isElement(document.body);\n * // => true\n *\n * _.isElement('<body>');\n * // => false\n */\nfunction isElement(value) {\n return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);\n}\n\nexport default isElement;\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/config\n */\n\nimport { isPlainObject, isElement, cloneDeepWith } from 'lodash-es';\n\n/**\n * Handles a configuration dictionary.\n */\nexport default class Config {\n\t/**\n\t * Creates an instance of the {@link ~Config} class.\n\t *\n\t * @param {Object} [configurations] The initial configurations to be set. Usually, provided by the user.\n\t * @param {Object} [defaultConfigurations] The default configurations. Usually, provided by the system.\n\t */\n\tconstructor( configurations, defaultConfigurations ) {\n\t\t/**\n\t\t * Store for the whole configuration.\n\t\t *\n\t\t * @private\n\t\t * @member {Object}\n\t\t */\n\t\tthis._config = {};\n\n\t\t// Set default configuration.\n\t\tif ( defaultConfigurations ) {\n\t\t\tthis.define( defaultConfigurations );\n\t\t}\n\n\t\t// Set initial configuration.\n\t\tif ( configurations ) {\n\t\t\tthis._setObjectToTarget( this._config, configurations );\n\t\t}\n\t}\n\n\t/**\n\t * Set configuration values.\n\t *\n\t * It accepts both a name/value pair or an object, which properties and values will be used to set\n\t * configurations.\n\t *\n\t * It also accepts setting a \"deep configuration\" by using dots in the name. For example, `'resize.width'` sets\n\t * the value for the `width` configuration in the `resize` subset.\n\t *\n\t *\t\tconfig.set( 'width', 500 );\n\t *\t\tconfig.set( 'toolbar.collapsed', true );\n\t *\n\t *\t\t// Equivalent to:\n\t *\t\tconfig.set( {\n\t *\t\t\twidth: 500\n\t *\t\t\ttoolbar: {\n\t *\t\t\t\tcollapsed: true\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * Passing an object as the value will amend the configuration, not replace it.\n\t *\n\t *\t\tconfig.set( 'toolbar', {\n\t *\t\t\tcollapsed: true,\n\t *\t\t} );\n\t *\n\t *\t\tconfig.set( 'toolbar', {\n\t *\t\t\tcolor: 'red',\n\t *\t\t} );\n\t *\n\t *\t\tconfig.get( 'toolbar.collapsed' ); // true\n\t *\t\tconfig.get( 'toolbar.color' ); // 'red'\n\t *\n\t * @param {String|Object} name The configuration name or an object from which take properties as\n\t * configuration entries. Configuration names are case-sensitive.\n\t * @param {*} value The configuration value. Used if a name is passed.\n\t */\n\tset( name, value ) {\n\t\tthis._setToTarget( this._config, name, value );\n\t}\n\n\t/**\n\t * Does exactly the same as {@link #set} with one exception – passed configuration extends\n\t * existing one, but does not overwrite already defined values.\n\t *\n\t * This method is supposed to be called by plugin developers to setup plugin's configurations. It would be\n\t * rarely used for other needs.\n\t *\n\t * @param {String|Object} name The configuration name or an object from which take properties as\n\t * configuration entries. Configuration names are case-sensitive.\n\t * @param {*} value The configuration value. Used if a name is passed.\n\t */\n\tdefine( name, value ) {\n\t\tconst isDefine = true;\n\n\t\tthis._setToTarget( this._config, name, value, isDefine );\n\t}\n\n\t/**\n\t * Gets the value for a configuration entry.\n\t *\n\t *\t\tconfig.get( 'name' );\n\t *\n\t * Deep configurations can be retrieved by separating each part with a dot.\n\t *\n\t *\t\tconfig.get( 'toolbar.collapsed' );\n\t *\n\t * @param {String} name The configuration name. Configuration names are case-sensitive.\n\t * @returns {*} The configuration value or `undefined` if the configuration entry was not found.\n\t */\n\tget( name ) {\n\t\treturn this._getFromSource( this._config, name );\n\t}\n\n\t/**\n\t * Saves passed configuration to the specified target (nested object).\n\t *\n\t * @private\n\t * @param {Object} target Nested config object.\n\t * @param {String|Object} name The configuration name or an object from which take properties as\n\t * configuration entries. Configuration names are case-sensitive.\n\t * @param {*} value The configuration value. Used if a name is passed.\n\t * @param {Boolean} [isDefine=false] Define if passed configuration should overwrite existing one.\n\t */\n\t_setToTarget( target, name, value, isDefine = false ) {\n\t\t// In case of an object, iterate through it and call `_setToTarget` again for each property.\n\t\tif ( isPlainObject( name ) ) {\n\t\t\tthis._setObjectToTarget( target, name, isDefine );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// The configuration name should be split into parts if it has dots. E.g. `resize.width` -> [`resize`, `width`].\n\t\tconst parts = name.split( '.' );\n\n\t\t// Take the name of the configuration out of the parts. E.g. `resize.width` -> `width`.\n\t\tname = parts.pop();\n\n\t\t// Iterate over parts to check if currently stored configuration has proper structure.\n\t\tfor ( const part of parts ) {\n\t\t\t// If there is no object for specified part then create one.\n\t\t\tif ( !isPlainObject( target[ part ] ) ) {\n\t\t\t\ttarget[ part ] = {};\n\t\t\t}\n\n\t\t\t// Nested object becomes a target.\n\t\t\ttarget = target[ part ];\n\t\t}\n\n\t\t// In case of value is an object.\n\t\tif ( isPlainObject( value ) ) {\n\t\t\t// We take care of proper config structure.\n\t\t\tif ( !isPlainObject( target[ name ] ) ) {\n\t\t\t\ttarget[ name ] = {};\n\t\t\t}\n\n\t\t\ttarget = target[ name ];\n\n\t\t\t// And iterate through this object calling `_setToTarget` again for each property.\n\t\t\tthis._setObjectToTarget( target, value, isDefine );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Do nothing if we are defining configuration for non empty name.\n\t\tif ( isDefine && typeof target[ name ] != 'undefined' ) {\n\t\t\treturn;\n\t\t}\n\n\t\ttarget[ name ] = value;\n\t}\n\n\t/**\n\t * Get specified configuration from specified source (nested object).\n\t *\n\t * @private\n\t * @param {Object} source level of nested object.\n\t * @param {String} name The configuration name. Configuration names are case-sensitive.\n\t * @returns {*} The configuration value or `undefined` if the configuration entry was not found.\n\t */\n\t_getFromSource( source, name ) {\n\t\t// The configuration name should be split into parts if it has dots. E.g. `resize.width` -> [`resize`, `width`].\n\t\tconst parts = name.split( '.' );\n\n\t\t// Take the name of the configuration out of the parts. E.g. `resize.width` -> `width`.\n\t\tname = parts.pop();\n\n\t\t// Iterate over parts to check if currently stored configuration has proper structure.\n\t\tfor ( const part of parts ) {\n\t\t\tif ( !isPlainObject( source[ part ] ) ) {\n\t\t\t\tsource = null;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Nested object becomes a source.\n\t\t\tsource = source[ part ];\n\t\t}\n\n\t\t// Always returns undefined for non existing configuration.\n\t\treturn source ? cloneConfig( source[ name ] ) : undefined;\n\t}\n\n\t/**\n\t * Iterates through passed object and calls {@link #_setToTarget} method with object key and value for each property.\n\t *\n\t * @private\n\t * @param {Object} target Nested config object.\n\t * @param {Object} configuration Configuration data set\n\t * @param {Boolean} [isDefine] Defines if passed configuration is default configuration or not.\n\t */\n\t_setObjectToTarget( target, configuration, isDefine ) {\n\t\tObject.keys( configuration ).forEach( key => {\n\t\t\tthis._setToTarget( target, key, configuration[ key ], isDefine );\n\t\t} );\n\t}\n}\n\n// Clones configuration object or value.\n// @param {*} source Source configuration\n// @returns {*} Cloned configuration value.\nfunction cloneConfig( source ) {\n\treturn cloneDeepWith( source, leaveDOMReferences );\n}\n\n// A customizer function for cloneDeepWith.\n// It will leave references to DOM Elements instead of cloning them.\n//\n// @param {*} value\n// @returns {Element|undefined}\nfunction leaveDOMReferences( value ) {\n\treturn isElement( value ) ? value : undefined;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/spy\n */\n\n/**\n * Creates a spy function (ala Sinon.js) that can be used to inspect call to it.\n *\n * The following are the present features:\n *\n * * spy.called: property set to `true` if the function has been called at least once.\n *\n * @returns {Function} The spy function.\n */\nfunction spy() {\n\treturn function spy() {\n\t\tspy.called = true;\n\t};\n}\n\nexport default spy;\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/eventinfo\n */\n\nimport spy from './spy';\n\n/**\n * The event object passed to event callbacks. It is used to provide information about the event as well as a tool to\n * manipulate it.\n */\nexport default class EventInfo {\n\t/**\n\t * @param {Object} source The emitter.\n\t * @param {String} name The event name.\n\t */\n\tconstructor( source, name ) {\n\t\t/**\n\t\t * The object that fired the event.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Object}\n\t\t */\n\t\tthis.source = source;\n\n\t\t/**\n\t\t * The event name.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.name = name;\n\n\t\t/**\n\t\t * Path this event has followed. See {@link module:utils/emittermixin~EmitterMixin#delegate}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Array.<Object>}\n\t\t */\n\t\tthis.path = [];\n\n\t\t// The following methods are defined in the constructor because they must be re-created per instance.\n\n\t\t/**\n\t\t * Stops the event emitter to call further callbacks for this event interaction.\n\t\t *\n\t\t * @method #stop\n\t\t */\n\t\tthis.stop = spy();\n\n\t\t/**\n\t\t * Removes the current callback from future interactions of this event.\n\t\t *\n\t\t * @method #off\n\t\t */\n\t\tthis.off = spy();\n\n\t\t/**\n\t\t * The value which will be returned by {@link module:utils/emittermixin~EmitterMixin#fire}.\n\t\t *\n\t\t * It's `undefined` by default and can be changed by an event listener:\n\t\t *\n\t\t *\t\tdataController.fire( 'getSelectedContent', ( evt ) => {\n\t\t *\t\t\t// This listener will make `dataController.fire( 'getSelectedContent' )`\n\t\t *\t\t\t// always return an empty DocumentFragment.\n\t\t *\t\t\tevt.return = new DocumentFragment();\n\t\t *\n\t\t *\t\t\t// Make sure no other listeners are executed.\n\t\t *\t\t\tevt.stop();\n\t\t *\t\t} );\n\t\t *\n\t\t * @member #return\n\t\t */\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/uid\n */\n\n/**\n * Returns a unique id. This id consist of an 'e' character and a randomly generated string of 32 aphanumeric characters.\n * Each character in uid string represents a hexadecimal digit (base 16).\n *\n * @returns {String} A hexadecimal number representing the id.\n */\nexport default function uid() {\n\tlet uuid = 'e'; // Make sure that id does not start with number.\n\n\tfor ( let i = 0; i < 8; i++ ) {\n\t\tuuid += Math.floor( ( 1 + Math.random() ) * 0x10000 ).toString( 16 ).substring( 1 );\n\t}\n\n\treturn uuid;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/priorities\n */\n\n/**\n * String representing a priority value.\n *\n * @typedef {'highest'|'high'|'normal'|'low'|'lowest'} module:utils/priorities~PriorityString\n */\n\n/**\n * Provides group of constants to use instead of hardcoding numeric priority values.\n *\n * @namespace\n */\nconst priorities = {\n\t/**\n\t * Converts a string with priority name to it's numeric value. If `Number` is given, it just returns it.\n\t *\n\t * @static\n\t * @param {module:utils/priorities~PriorityString|Number} priority Priority to convert.\n\t * @returns {Number} Converted priority.\n\t */\n\tget( priority ) {\n\t\tif ( typeof priority != 'number' ) {\n\t\t\treturn this[ priority ] || this.normal;\n\t\t} else {\n\t\t\treturn priority;\n\t\t}\n\t},\n\n\thighest: 100000,\n\thigh: 1000,\n\tnormal: 0,\n\tlow: -1000,\n\tlowest: -100000\n};\n\nexport default priorities;\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/emittermixin\n */\n\nimport EventInfo from './eventinfo';\nimport uid from './uid';\nimport priorities from './priorities';\n\n// To check if component is loaded more than once.\nimport './version';\n\nconst _listeningTo = Symbol( 'listeningTo' );\nconst _emitterId = Symbol( 'emitterId' );\n\n/**\n * Mixin that injects the {@link ~Emitter events API} into its host.\n *\n * @mixin EmitterMixin\n * @implements module:utils/emittermixin~Emitter\n */\nconst EmitterMixin = {\n\t/**\n\t * @inheritDoc\n\t */\n\ton( event, callback, options = {} ) {\n\t\tthis.listenTo( this, event, callback, options );\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tonce( event, callback, options ) {\n\t\tlet wasFired = false;\n\n\t\tconst onceCallback = function( event, ...args ) {\n\t\t\t// Ensure the callback is called only once even if the callback itself leads to re-firing the event\n\t\t\t// (which would call the callback again).\n\t\t\tif ( !wasFired ) {\n\t\t\t\twasFired = true;\n\n\t\t\t\t// Go off() at the first call.\n\t\t\t\tevent.off();\n\n\t\t\t\t// Go with the original callback.\n\t\t\t\tcallback.call( this, event, ...args );\n\t\t\t}\n\t\t};\n\n\t\t// Make a similar on() call, simply replacing the callback.\n\t\tthis.listenTo( this, event, onceCallback, options );\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\toff( event, callback ) {\n\t\tthis.stopListening( this, event, callback );\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tlistenTo( emitter, event, callback, options = {} ) {\n\t\tlet emitterInfo, eventCallbacks;\n\n\t\t// _listeningTo contains a list of emitters that this object is listening to.\n\t\t// This list has the following format:\n\t\t//\n\t\t// _listeningTo: {\n\t\t// emitterId: {\n\t\t// emitter: emitter,\n\t\t// callbacks: {\n\t\t// event1: [ callback1, callback2, ... ]\n\t\t// ....\n\t\t// }\n\t\t// },\n\t\t// ...\n\t\t// }\n\n\t\tif ( !this[ _listeningTo ] ) {\n\t\t\tthis[ _listeningTo ] = {};\n\t\t}\n\n\t\tconst emitters = this[ _listeningTo ];\n\n\t\tif ( !_getEmitterId( emitter ) ) {\n\t\t\t_setEmitterId( emitter );\n\t\t}\n\n\t\tconst emitterId = _getEmitterId( emitter );\n\n\t\tif ( !( emitterInfo = emitters[ emitterId ] ) ) {\n\t\t\temitterInfo = emitters[ emitterId ] = {\n\t\t\t\temitter,\n\t\t\t\tcallbacks: {}\n\t\t\t};\n\t\t}\n\n\t\tif ( !( eventCallbacks = emitterInfo.callbacks[ event ] ) ) {\n\t\t\teventCallbacks = emitterInfo.callbacks[ event ] = [];\n\t\t}\n\n\t\teventCallbacks.push( callback );\n\n\t\t// Finally register the callback to the event.\n\t\tcreateEventNamespace( emitter, event );\n\t\tconst lists = getCallbacksListsForNamespace( emitter, event );\n\t\tconst priority = priorities.get( options.priority );\n\n\t\tconst callbackDefinition = {\n\t\t\tcallback,\n\t\t\tpriority\n\t\t};\n\n\t\t// Add the callback to all callbacks list.\n\t\tfor ( const callbacks of lists ) {\n\t\t\t// Add the callback to the list in the right priority position.\n\t\t\tlet added = false;\n\n\t\t\tfor ( let i = 0; i < callbacks.length; i++ ) {\n\t\t\t\tif ( callbacks[ i ].priority < priority ) {\n\t\t\t\t\tcallbacks.splice( i, 0, callbackDefinition );\n\t\t\t\t\tadded = true;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add at the end, if right place was not found.\n\t\t\tif ( !added ) {\n\t\t\t\tcallbacks.push( callbackDefinition );\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstopListening( emitter, event, callback ) {\n\t\tconst emitters = this[ _listeningTo ];\n\t\tlet emitterId = emitter && _getEmitterId( emitter );\n\t\tconst emitterInfo = emitters && emitterId && emitters[ emitterId ];\n\t\tconst eventCallbacks = emitterInfo && event && emitterInfo.callbacks[ event ];\n\n\t\t// Stop if nothing has been listened.\n\t\tif ( !emitters || ( emitter && !emitterInfo ) || ( event && !eventCallbacks ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// All params provided. off() that single callback.\n\t\tif ( callback ) {\n\t\t\tremoveCallback( emitter, event, callback );\n\t\t}\n\t\t// Only `emitter` and `event` provided. off() all callbacks for that event.\n\t\telse if ( eventCallbacks ) {\n\t\t\twhile ( ( callback = eventCallbacks.pop() ) ) {\n\t\t\t\tremoveCallback( emitter, event, callback );\n\t\t\t}\n\n\t\t\tdelete emitterInfo.callbacks[ event ];\n\t\t}\n\t\t// Only `emitter` provided. off() all events for that emitter.\n\t\telse if ( emitterInfo ) {\n\t\t\tfor ( event in emitterInfo.callbacks ) {\n\t\t\t\tthis.stopListening( emitter, event );\n\t\t\t}\n\t\t\tdelete emitters[ emitterId ];\n\t\t}\n\t\t// No params provided. off() all emitters.\n\t\telse {\n\t\t\tfor ( emitterId in emitters ) {\n\t\t\t\tthis.stopListening( emitters[ emitterId ].emitter );\n\t\t\t}\n\t\t\tdelete this[ _listeningTo ];\n\t\t}\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tfire( eventOrInfo, ...args ) {\n\t\tconst eventInfo = eventOrInfo instanceof EventInfo ? eventOrInfo : new EventInfo( this, eventOrInfo );\n\t\tconst event = eventInfo.name;\n\t\tlet callbacks = getCallbacksForEvent( this, event );\n\n\t\t// Record that the event passed this emitter on its path.\n\t\teventInfo.path.push( this );\n\n\t\t// Handle event listener callbacks first.\n\t\tif ( callbacks ) {\n\t\t\t// Arguments passed to each callback.\n\t\t\tconst callbackArgs = [ eventInfo, ...args ];\n\n\t\t\t// Copying callbacks array is the easiest and most secure way of preventing infinite loops, when event callbacks\n\t\t\t// are added while processing other callbacks. Previous solution involved adding counters (unique ids) but\n\t\t\t// failed if callbacks were added to the queue before currently processed callback.\n\t\t\t// If this proves to be too inefficient, another method is to change `.on()` so callbacks are stored if same\n\t\t\t// event is currently processed. Then, `.fire()` at the end, would have to add all stored events.\n\t\t\tcallbacks = Array.from( callbacks );\n\n\t\t\tfor ( let i = 0; i < callbacks.length; i++ ) {\n\t\t\t\tcallbacks[ i ].callback.apply( this, callbackArgs );\n\n\t\t\t\t// Remove the callback from future requests if off() has been called.\n\t\t\t\tif ( eventInfo.off.called ) {\n\t\t\t\t\t// Remove the called mark for the next calls.\n\t\t\t\t\tdelete eventInfo.off.called;\n\n\t\t\t\t\tremoveCallback( this, event, callbacks[ i ].callback );\n\t\t\t\t}\n\n\t\t\t\t// Do not execute next callbacks if stop() was called.\n\t\t\t\tif ( eventInfo.stop.called ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Delegate event to other emitters if needed.\n\t\tif ( this._delegations ) {\n\t\t\tconst destinations = this._delegations.get( event );\n\t\t\tconst passAllDestinations = this._delegations.get( '*' );\n\n\t\t\tif ( destinations ) {\n\t\t\t\tfireDelegatedEvents( destinations, eventInfo, args );\n\t\t\t}\n\n\t\t\tif ( passAllDestinations ) {\n\t\t\t\tfireDelegatedEvents( passAllDestinations, eventInfo, args );\n\t\t\t}\n\t\t}\n\n\t\treturn eventInfo.return;\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdelegate( ...events ) {\n\t\treturn {\n\t\t\tto: ( emitter, nameOrFunction ) => {\n\t\t\t\tif ( !this._delegations ) {\n\t\t\t\t\tthis._delegations = new Map();\n\t\t\t\t}\n\n\t\t\t\t// Originally there was a for..of loop which unfortunately caused an error in Babel that didn't allow\n\t\t\t\t// build an application. See: https://github.com/ckeditor/ckeditor5-react/issues/40.\n\t\t\t\tevents.forEach( eventName => {\n\t\t\t\t\tconst destinations = this._delegations.get( eventName );\n\n\t\t\t\t\tif ( !destinations ) {\n\t\t\t\t\t\tthis._delegations.set( eventName, new Map( [ [ emitter, nameOrFunction ] ] ) );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdestinations.set( emitter, nameOrFunction );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t};\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstopDelegating( event, emitter ) {\n\t\tif ( !this._delegations ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !event ) {\n\t\t\tthis._delegations.clear();\n\t\t} else if ( !emitter ) {\n\t\t\tthis._delegations.delete( event );\n\t\t} else {\n\t\t\tconst destinations = this._delegations.get( event );\n\n\t\t\tif ( destinations ) {\n\t\t\t\tdestinations.delete( emitter );\n\t\t\t}\n\t\t}\n\t}\n};\n\nexport default EmitterMixin;\n\n/**\n * Emitter/listener interface.\n *\n * Can be easily implemented by a class by mixing the {@link module:utils/emittermixin~EmitterMixin} mixin.\n *\n * @interface Emitter\n */\n\n/**\n * Registers a callback function to be executed when an event is fired.\n *\n * Shorthand for {@link #listenTo `this.listenTo( this, event, callback, options )`} (it makes the emitter\n * listen on itself).\n *\n * @method #on\n * @param {String} event The name of the event.\n * @param {Function} callback The function to be called on event.\n * @param {Object} [options={}] Additional options.\n * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of this event callback. The higher\n * the priority value the sooner the callback will be fired. Events having the same priority are called in the\n * order they were added.\n */\n\n/**\n * Registers a callback function to be executed on the next time the event is fired only. This is similar to\n * calling {@link #on} followed by {@link #off} in the callback.\n *\n * @method #once\n * @param {String} event The name of the event.\n * @param {Function} callback The function to be called on event.\n * @param {Object} [options={}] Additional options.\n * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of this event callback. The higher\n * the priority value the sooner the callback will be fired. Events having the same priority are called in the\n * order they were added.\n */\n\n/**\n * Stops executing the callback on the given event.\n * Shorthand for {@link #stopListening `this.stopListening( this, event, callback )`}.\n *\n * @method #off\n * @param {String} event The name of the event.\n * @param {Function} callback The function to stop being called.\n */\n\n/**\n * Registers a callback function to be executed when an event is fired in a specific (emitter) object.\n *\n * Events can be grouped in namespaces using `:`.\n * When namespaced event is fired, it additionally fires all callbacks for that namespace.\n *\n *\t\t// myEmitter.on( ... ) is a shorthand for myEmitter.listenTo( myEmitter, ... ).\n *\t\tmyEmitter.on( 'myGroup', genericCallback );\n *\t\tmyEmitter.on( 'myGroup:myEvent', specificCallback );\n *\n *\t\t// genericCallback is fired.\n *\t\tmyEmitter.fire( 'myGroup' );\n *\t\t// both genericCallback and specificCallback are fired.\n *\t\tmyEmitter.fire( 'myGroup:myEvent' );\n *\t\t// genericCallback is fired even though there are no callbacks for \"foo\".\n *\t\tmyEmitter.fire( 'myGroup:foo' );\n *\n * An event callback can {@link module:utils/eventinfo~EventInfo#stop stop the event} and\n * set the {@link module:utils/eventinfo~EventInfo#return return value} of the {@link #fire} method.\n *\n * @method #listenTo\n * @param {module:utils/emittermixin~Emitter} emitter The object that fires the event.\n * @param {String} event The name of the event.\n * @param {Function} callback The function to be called on event.\n * @param {Object} [options={}] Additional options.\n * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of this event callback. The higher\n * the priority value the sooner the callback will be fired. Events having the same priority are called in the\n * order they were added.\n */\n\n/**\n * Stops listening for events. It can be used at different levels:\n *\n * * To stop listening to a specific callback.\n * * To stop listening to a specific event.\n * * To stop listening to all events fired by a specific object.\n * * To stop listening to all events fired by all objects.\n *\n * @method #stopListening\n * @param {module:utils/emittermixin~Emitter} [emitter] The object to stop listening to. If omitted, stops it for all objects.\n * @param {String} [event] (Requires the `emitter`) The name of the event to stop listening to. If omitted, stops it\n * for all events from `emitter`.\n * @param {Function} [callback] (Requires the `event`) The function to be removed from the call list for the given\n * `event`.\n */\n\n/**\n * Fires an event, executing all callbacks registered for it.\n *\n * The first parameter passed to callbacks is an {@link module:utils/eventinfo~EventInfo} object,\n * followed by the optional `args` provided in the `fire()` method call.\n *\n * @method #fire\n * @param {String|module:utils/eventinfo~EventInfo} eventOrInfo The name of the event or `EventInfo` object if event is delegated.\n * @param {...*} [args] Additional arguments to be passed to the callbacks.\n * @returns {*} By default the method returns `undefined`. However, the return value can be changed by listeners\n * through modification of the {@link module:utils/eventinfo~EventInfo#return `evt.return`}'s property (the event info\n * is the first param of every callback).\n */\n\n/**\n * Delegates selected events to another {@link module:utils/emittermixin~Emitter}. For instance:\n *\n *\t\temitterA.delegate( 'eventX' ).to( emitterB );\n *\t\temitterA.delegate( 'eventX', 'eventY' ).to( emitterC );\n *\n * then `eventX` is delegated (fired by) `emitterB` and `emitterC` along with `data`:\n *\n *\t\temitterA.fire( 'eventX', data );\n *\n * and `eventY` is delegated (fired by) `emitterC` along with `data`:\n *\n *\t\temitterA.fire( 'eventY', data );\n *\n * @method #delegate\n * @param {...String} events Event names that will be delegated to another emitter.\n * @returns {module:utils/emittermixin~EmitterMixinDelegateChain}\n */\n\n/**\n * Stops delegating events. It can be used at different levels:\n *\n * * To stop delegating all events.\n * * To stop delegating a specific event to all emitters.\n * * To stop delegating a specific event to a specific emitter.\n *\n * @method #stopDelegating\n * @param {String} [event] The name of the event to stop delegating. If omitted, stops it all delegations.\n * @param {module:utils/emittermixin~Emitter} [emitter] (requires `event`) The object to stop delegating a particular event to.\n * If omitted, stops delegation of `event` to all emitters.\n */\n\n/**\n * Checks if `listeningEmitter` listens to an emitter with given `listenedToEmitterId` and if so, returns that emitter.\n * If not, returns `null`.\n *\n * @protected\n * @param {module:utils/emittermixin~EmitterMixin} listeningEmitter Emitter that listens.\n * @param {String} listenedToEmitterId Unique emitter id of emitter listened to.\n * @returns {module:utils/emittermixin~EmitterMixin|null}\n */\nexport function _getEmitterListenedTo( listeningEmitter, listenedToEmitterId ) {\n\tif ( listeningEmitter[ _listeningTo ] && listeningEmitter[ _listeningTo ][ listenedToEmitterId ] ) {\n\t\treturn listeningEmitter[ _listeningTo ][ listenedToEmitterId ].emitter;\n\t}\n\n\treturn null;\n}\n\n/**\n * Sets emitter's unique id.\n *\n * **Note:** `_emitterId` can be set only once.\n *\n * @protected\n * @param {module:utils/emittermixin~EmitterMixin} emitter Emitter for which id will be set.\n * @param {String} [id] Unique id to set. If not passed, random unique id will be set.\n */\nexport function _setEmitterId( emitter, id ) {\n\tif ( !emitter[ _emitterId ] ) {\n\t\temitter[ _emitterId ] = id || uid();\n\t}\n}\n\n/**\n * Returns emitter's unique id.\n *\n * @protected\n * @param {module:utils/emittermixin~EmitterMixin} emitter Emitter which id will be returned.\n */\nexport function _getEmitterId( emitter ) {\n\treturn emitter[ _emitterId ];\n}\n\n// Gets the internal `_events` property of the given object.\n// `_events` property store all lists with callbacks for registered event names.\n// If there were no events registered on the object, empty `_events` object is created.\nfunction getEvents( source ) {\n\tif ( !source._events ) {\n\t\tObject.defineProperty( source, '_events', {\n\t\t\tvalue: {}\n\t\t} );\n\t}\n\n\treturn source._events;\n}\n\n// Creates event node for generic-specific events relation architecture.\nfunction makeEventNode() {\n\treturn {\n\t\tcallbacks: [],\n\t\tchildEvents: []\n\t};\n}\n\n// Creates an architecture for generic-specific events relation.\n// If needed, creates all events for given eventName, i.e. if the first registered event\n// is foo:bar:abc, it will create foo:bar:abc, foo:bar and foo event and tie them together.\n// It also copies callbacks from more generic events to more specific events when\n// specific events are created.\nfunction createEventNamespace( source, eventName ) {\n\tconst events = getEvents( source );\n\n\t// First, check if the event we want to add to the structure already exists.\n\tif ( events[ eventName ] ) {\n\t\t// If it exists, we don't have to do anything.\n\t\treturn;\n\t}\n\n\t// In other case, we have to create the structure for the event.\n\t// Note, that we might need to create intermediate events too.\n\t// I.e. if foo:bar:abc is being registered and we only have foo in the structure,\n\t// we need to also register foo:bar.\n\n\t// Currently processed event name.\n\tlet name = eventName;\n\t// Name of the event that is a child event for currently processed event.\n\tlet childEventName = null;\n\n\t// Array containing all newly created specific events.\n\tconst newEventNodes = [];\n\n\t// While loop can't check for ':' index because we have to handle generic events too.\n\t// In each loop, we truncate event name, going from the most specific name to the generic one.\n\t// I.e. foo:bar:abc -> foo:bar -> foo.\n\twhile ( name !== '' ) {\n\t\tif ( events[ name ] ) {\n\t\t\t// If the currently processed event name is already registered, we can be sure\n\t\t\t// that it already has all the structure created, so we can break the loop here\n\t\t\t// as no more events need to be registered.\n\t\t\tbreak;\n\t\t}\n\n\t\t// If this event is not yet registered, create a new object for it.\n\t\tevents[ name ] = makeEventNode();\n\t\t// Add it to the array with newly created events.\n\t\tnewEventNodes.push( events[ name ] );\n\n\t\t// Add previously processed event name as a child of this event.\n\t\tif ( childEventName ) {\n\t\t\tevents[ name ].childEvents.push( childEventName );\n\t\t}\n\n\t\tchildEventName = name;\n\t\t// If `.lastIndexOf()` returns -1, `.substr()` will return '' which will break the loop.\n\t\tname = name.substr( 0, name.lastIndexOf( ':' ) );\n\t}\n\n\tif ( name !== '' ) {\n\t\t// If name is not empty, we found an already registered event that was a parent of the\n\t\t// event we wanted to register.\n\n\t\t// Copy that event's callbacks to newly registered events.\n\t\tfor ( const node of newEventNodes ) {\n\t\t\tnode.callbacks = events[ name ].callbacks.slice();\n\t\t}\n\n\t\t// Add last newly created event to the already registered event.\n\t\tevents[ name ].childEvents.push( childEventName );\n\t}\n}\n\n// Gets an array containing callbacks list for a given event and it's more specific events.\n// I.e. if given event is foo:bar and there is also foo:bar:abc event registered, this will\n// return callback list of foo:bar and foo:bar:abc (but not foo).\nfunction getCallbacksListsForNamespace( source, eventName ) {\n\tconst eventNode = getEvents( source )[ eventName ];\n\n\tif ( !eventNode ) {\n\t\treturn [];\n\t}\n\n\tlet callbacksLists = [ eventNode.callbacks ];\n\n\tfor ( let i = 0; i < eventNode.childEvents.length; i++ ) {\n\t\tconst childCallbacksLists = getCallbacksListsForNamespace( source, eventNode.childEvents[ i ] );\n\n\t\tcallbacksLists = callbacksLists.concat( childCallbacksLists );\n\t}\n\n\treturn callbacksLists;\n}\n\n// Get the list of callbacks for a given event, but only if there any callbacks have been registered.\n// If there are no callbacks registered for given event, it checks if this is a specific event and looks\n// for callbacks for it's more generic version.\nfunction getCallbacksForEvent( source, eventName ) {\n\tlet event;\n\n\tif ( !source._events || !( event = source._events[ eventName ] ) || !event.callbacks.length ) {\n\t\t// There are no callbacks registered for specified eventName.\n\t\t// But this could be a specific-type event that is in a namespace.\n\t\tif ( eventName.indexOf( ':' ) > -1 ) {\n\t\t\t// If the eventName is specific, try to find callback lists for more generic event.\n\t\t\treturn getCallbacksForEvent( source, eventName.substr( 0, eventName.lastIndexOf( ':' ) ) );\n\t\t} else {\n\t\t\t// If this is a top-level generic event, return null;\n\t\t\treturn null;\n\t\t}\n\t}\n\n\treturn event.callbacks;\n}\n\n// Fires delegated events for given map of destinations.\n//\n// @private\n// * @param {Map.<utils.Emitter>} destinations A map containing `[ {@link utils.Emitter}, \"event name\" ]` pair destinations.\n// * @param {utils.EventInfo} eventInfo The original event info object.\n// * @param {Array.<*>} fireArgs Arguments the original event was fired with.\nfunction fireDelegatedEvents( destinations, eventInfo, fireArgs ) {\n\tfor ( let [ emitter, name ] of destinations ) {\n\t\tif ( !name ) {\n\t\t\tname = eventInfo.name;\n\t\t} else if ( typeof name == 'function' ) {\n\t\t\tname = name( eventInfo.name );\n\t\t}\n\n\t\tconst delegatedInfo = new EventInfo( eventInfo.source, name );\n\n\t\tdelegatedInfo.path = [ ...eventInfo.path ];\n\n\t\temitter.fire( delegatedInfo, ...fireArgs );\n\t}\n}\n\n// Removes callback from emitter for given event.\n//\n// @param {module:utils/emittermixin~Emitter} emitter\n// @param {String} event\n// @param {Function} callback\nfunction removeCallback( emitter, event, callback ) {\n\tconst lists = getCallbacksListsForNamespace( emitter, event );\n\n\tfor ( const callbacks of lists ) {\n\t\tfor ( let i = 0; i < callbacks.length; i++ ) {\n\t\t\tif ( callbacks[ i ].callback == callback ) {\n\t\t\t\t// Remove the callback from the list (fixing the next index).\n\t\t\t\tcallbacks.splice( i, 1 );\n\t\t\t\ti--;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * The return value of {@link ~EmitterMixin#delegate}.\n *\n * @interface module:utils/emittermixin~EmitterMixinDelegateChain\n */\n\n/**\n * Selects destination for {@link module:utils/emittermixin~EmitterMixin#delegate} events.\n *\n * @method #to\n * @param {module:utils/emittermixin~Emitter} emitter An `EmitterMixin` instance which is the destination for delegated events.\n * @param {String|Function} [nameOrFunction] A custom event name or function which converts the original name string.\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/mix\n */\n\n/**\n * Copies enumerable properties and symbols from the objects given as 2nd+ parameters to the\n * prototype of first object (a constructor).\n *\n *\t\tclass Editor {\n *\t\t\t...\n *\t\t}\n *\n *\t\tconst SomeMixin = {\n *\t\t\ta() {\n *\t\t\t\treturn 'a';\n *\t\t\t}\n *\t\t};\n *\n *\t\tmix( Editor, SomeMixin, ... );\n *\n *\t\tnew Editor().a(); // -> 'a'\n *\n * Note: Properties which already exist in the base class will not be overriden.\n *\n * @param {Function} [baseClass] Class which prototype will be extended.\n * @param {Object} [...mixins] Objects from which to get properties.\n */\nexport default function mix( baseClass, ...mixins ) {\n\tmixins.forEach( mixin => {\n\t\tObject.getOwnPropertyNames( mixin ).concat( Object.getOwnPropertySymbols( mixin ) )\n\t\t\t.forEach( key => {\n\t\t\t\tif ( key in baseClass.prototype ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst sourceDescriptor = Object.getOwnPropertyDescriptor( mixin, key );\n\t\t\t\tsourceDescriptor.enumerable = false;\n\n\t\t\t\tObject.defineProperty( baseClass.prototype, key, sourceDescriptor );\n\t\t\t} );\n\t} );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/comparearrays\n */\n\n/**\n * Compares how given arrays relate to each other. One array can be: same as another array, prefix of another array\n * or completely different. If arrays are different, first index at which they differ is returned. Otherwise,\n * a flag specifying the relation is returned. Flags are negative numbers, so whenever a number >= 0 is returned\n * it means that arrays differ.\n *\n *\t\tcompareArrays( [ 0, 2 ], [ 0, 2 ] );\t\t// 'same'\n *\t\tcompareArrays( [ 0, 2 ], [ 0, 2, 1 ] );\t\t// 'prefix'\n *\t\tcompareArrays( [ 0, 2 ], [ 0 ] );\t\t\t// 'extension'\n *\t\tcompareArrays( [ 0, 2 ], [ 1, 2 ] );\t\t// 0\n *\t\tcompareArrays( [ 0, 2 ], [ 0, 1 ] );\t\t// 1\n *\n * @param {Array} a Array that is compared.\n * @param {Array} b Array to compare with.\n * @returns {module:utils/comparearrays~ArrayRelation} How array `a` is related to `b`.\n */\nexport default function compareArrays( a, b ) {\n\tconst minLen = Math.min( a.length, b.length );\n\n\tfor ( let i = 0; i < minLen; i++ ) {\n\t\tif ( a[ i ] != b[ i ] ) {\n\t\t\t// The arrays are different.\n\t\t\treturn i;\n\t\t}\n\t}\n\n\t// Both arrays were same at all points.\n\tif ( a.length == b.length ) {\n\t\t// If their length is also same, they are the same.\n\t\treturn 'same';\n\t} else if ( a.length < b.length ) {\n\t\t// Compared array is shorter so it is a prefix of the other array.\n\t\treturn 'prefix';\n\t} else {\n\t\t// Compared array is longer so it is an extension of the other array.\n\t\treturn 'extension';\n\t}\n}\n\n/**\n * @typedef {'extension'|'same'|'prefix'} module:utils/comparearrays~ArrayRelation\n */\n","import baseClone from './_baseClone.js';\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_SYMBOLS_FLAG = 4;\n\n/**\n * Creates a shallow clone of `value`.\n *\n * **Note:** This method is loosely based on the\n * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)\n * and supports cloning arrays, array buffers, booleans, date objects, maps,\n * numbers, `Object` objects, regexes, sets, strings, symbols, and typed\n * arrays. The own enumerable properties of `arguments` objects are cloned\n * as plain objects. An empty object is returned for uncloneable values such\n * as error objects, functions, DOM nodes, and WeakMaps.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to clone.\n * @returns {*} Returns the cloned value.\n * @see _.cloneDeep\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var shallow = _.clone(objects);\n * console.log(shallow[0] === objects[0]);\n * // => true\n */\nfunction clone(value) {\n return baseClone(value, CLONE_SYMBOLS_FLAG);\n}\n\nexport default clone;\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/node\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport compareArrays from '@ckeditor/ckeditor5-utils/src/comparearrays';\nimport { clone } from 'lodash-es';\n\n// To check if component is loaded more than once.\nimport '@ckeditor/ckeditor5-utils/src/version';\n\n/**\n * Abstract tree view node class.\n *\n * This is an abstract class. Its constructor should not be used directly.\n * Use the {@link module:engine/view/element~Element} class to create view elements\n * or {@link module:engine/view/text~Text} class to create view text nodes.\n *\n * @abstract\n */\nexport default class Node {\n\t/**\n\t * Creates a tree view node.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Parent element. Null by default. Set by {@link module:engine/view/element~Element#_insertChild}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment|null}\n\t\t */\n\t\tthis.parent = null;\n\t}\n\n\t/**\n\t * Index of the node in the parent element or null if the node has no parent.\n\t *\n\t * Accessing this property throws an error if this node's parent element does not contain it.\n\t * This means that view tree got broken.\n\t *\n\t * @readonly\n\t * @type {Number|null}\n\t */\n\tget index() {\n\t\tlet pos;\n\n\t\tif ( !this.parent ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// No parent or child doesn't exist in parent's children.\n\t\tif ( ( pos = this.parent.getChildIndex( this ) ) == -1 ) {\n\t\t\t/**\n\t\t\t * The node's parent does not contain this node. It means that the document tree is corrupted.\n\t\t\t *\n\t\t\t * @error view-node-not-found-in-parent\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-node-not-found-in-parent: The node\\'s parent does not contain this node.' );\n\t\t}\n\n\t\treturn pos;\n\t}\n\n\t/**\n\t * Node's next sibling, or `null` if it is the last child.\n\t *\n\t * @readonly\n\t * @type {module:engine/view/node~Node|null}\n\t */\n\tget nextSibling() {\n\t\tconst index = this.index;\n\n\t\treturn ( index !== null && this.parent.getChild( index + 1 ) ) || null;\n\t}\n\n\t/**\n\t * Node's previous sibling, or `null` if it is the first child.\n\t *\n\t * @readonly\n\t * @type {module:engine/view/node~Node|null}\n\t */\n\tget previousSibling() {\n\t\tconst index = this.index;\n\n\t\treturn ( index !== null && this.parent.getChild( index - 1 ) ) || null;\n\t}\n\n\t/**\n\t * Top-most ancestor of the node. If the node has no parent it is the root itself.\n\t *\n\t * @readonly\n\t * @type {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment}\n\t */\n\tget root() {\n\t\tlet root = this; // eslint-disable-line consistent-this\n\n\t\twhile ( root.parent ) {\n\t\t\troot = root.parent;\n\t\t}\n\n\t\treturn root;\n\t}\n\n\t/**\n\t * {@link module:engine/view/document~Document View document} that owns this node, or `null` if the node is inside\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragment}.\n\t *\n\t * @readonly\n\t * @type {module:engine/view/document~Document|null}\n\t */\n\tget document() {\n\t\t// Parent might be Node, null or DocumentFragment.\n\t\tif ( this.parent instanceof Node ) {\n\t\t\treturn this.parent.document;\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Gets a path to the node. The path is an array containing indices of consecutive ancestors of this node,\n\t * beginning from {@link module:engine/view/node~Node#root root}, down to this node's index.\n\t *\n\t *\t\tconst abc = downcastWriter.createText( 'abc' );\n\t *\t\tconst foo = downcastWriter.createText( 'foo' );\n\t *\t\tconst h1 = downcastWriter.createElement( 'h1', null, downcastWriter.createText( 'header' ) );\n\t *\t\tconst p = downcastWriter.createElement( 'p', null, [ abc, foo ] );\n\t *\t\tconst div = downcastWriter.createElement( 'div', null, [ h1, p ] );\n\t *\t\tfoo.getPath(); // Returns [ 1, 3 ]. `foo` is in `p` which is in `div`. `p` starts at offset 1, while `foo` at 3.\n\t *\t\th1.getPath(); // Returns [ 0 ].\n\t *\t\tdiv.getPath(); // Returns [].\n\t *\n\t * @returns {Array.<Number>} The path.\n\t */\n\tgetPath() {\n\t\tconst path = [];\n\t\tlet node = this; // eslint-disable-line consistent-this\n\n\t\twhile ( node.parent ) {\n\t\t\tpath.unshift( node.index );\n\t\t\tnode = node.parent;\n\t\t}\n\n\t\treturn path;\n\t}\n\n\t/**\n\t * Returns ancestors array of this node.\n\t *\n\t * @param {Object} options Options object.\n\t * @param {Boolean} [options.includeSelf=false] When set to `true` this node will be also included in parent's array.\n\t * @param {Boolean} [options.parentFirst=false] When set to `true`, array will be sorted from node's parent to root element,\n\t * otherwise root element will be the first item in the array.\n\t * @returns {Array} Array with ancestors.\n\t */\n\tgetAncestors( options = { includeSelf: false, parentFirst: false } ) {\n\t\tconst ancestors = [];\n\t\tlet parent = options.includeSelf ? this : this.parent;\n\n\t\twhile ( parent ) {\n\t\t\tancestors[ options.parentFirst ? 'push' : 'unshift' ]( parent );\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn ancestors;\n\t}\n\n\t/**\n\t * Returns a {@link module:engine/view/element~Element} or {@link module:engine/view/documentfragment~DocumentFragment}\n\t * which is a common ancestor of both nodes.\n\t *\n\t * @param {module:engine/view/node~Node} node The second node.\n\t * @param {Object} options Options object.\n\t * @param {Boolean} [options.includeSelf=false] When set to `true` both nodes will be considered \"ancestors\" too.\n\t * Which means that if e.g. node A is inside B, then their common ancestor will be B.\n\t * @returns {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment|null}\n\t */\n\tgetCommonAncestor( node, options = {} ) {\n\t\tconst ancestorsA = this.getAncestors( options );\n\t\tconst ancestorsB = node.getAncestors( options );\n\n\t\tlet i = 0;\n\n\t\twhile ( ancestorsA[ i ] == ancestorsB[ i ] && ancestorsA[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i === 0 ? null : ancestorsA[ i - 1 ];\n\t}\n\n\t/**\n\t * Returns whether this node is before given node. `false` is returned if nodes are in different trees (for example,\n\t * in different {@link module:engine/view/documentfragment~DocumentFragment}s).\n\t *\n\t * @param {module:engine/view/node~Node} node Node to compare with.\n\t * @returns {Boolean}\n\t */\n\tisBefore( node ) {\n\t\t// Given node is not before this node if they are same.\n\t\tif ( this == node ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Return `false` if it is impossible to compare nodes.\n\t\tif ( this.root !== node.root ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst thisPath = this.getPath();\n\t\tconst nodePath = node.getPath();\n\n\t\tconst result = compareArrays( thisPath, nodePath );\n\n\t\tswitch ( result ) {\n\t\t\tcase 'prefix':\n\t\t\t\treturn true;\n\n\t\t\tcase 'extension':\n\t\t\t\treturn false;\n\n\t\t\tdefault:\n\t\t\t\treturn thisPath[ result ] < nodePath[ result ];\n\t\t}\n\t}\n\n\t/**\n\t * Returns whether this node is after given node. `false` is returned if nodes are in different trees (for example,\n\t * in different {@link module:engine/view/documentfragment~DocumentFragment}s).\n\t *\n\t * @param {module:engine/view/node~Node} node Node to compare with.\n\t * @returns {Boolean}\n\t */\n\tisAfter( node ) {\n\t\t// Given node is not before this node if they are same.\n\t\tif ( this == node ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Return `false` if it is impossible to compare nodes.\n\t\tif ( this.root !== node.root ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// In other cases, just check if the `node` is before, and return the opposite.\n\t\treturn !this.isBefore( node );\n\t}\n\n\t/**\n\t * Removes node from parent.\n\t *\n\t * @protected\n\t */\n\t_remove() {\n\t\tthis.parent._removeChildren( this.index );\n\t}\n\n\t/**\n\t * @protected\n\t * @param {module:engine/view/document~ChangeType} type Type of the change.\n\t * @param {module:engine/view/node~Node} node Changed node.\n\t * @fires change\n\t */\n\t_fireChange( type, node ) {\n\t\tthis.fire( 'change:' + type, node );\n\n\t\tif ( this.parent ) {\n\t\t\tthis.parent._fireChange( type, node );\n\t\t}\n\t}\n\n\t/**\n\t * Custom toJSON method to solve child-parent circular dependencies.\n\t *\n\t * @returns {Object} Clone of this object with the parent property removed.\n\t */\n\ttoJSON() {\n\t\tconst json = clone( this );\n\n\t\t// Due to circular references we need to remove parent reference.\n\t\tdelete json.parent;\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Checks whether this view object is of the given type.\n\t *\n\t * This method is useful when processing view tree objects that are of unknown type. For example, a function\n\t * may return {@link module:engine/view/documentfragment~DocumentFragment} or {@link module:engine/view/node~Node}\n\t * that can be either text node or element. This method can be used to check what kind of object is returned.\n\t *\n\t *\t\tobj.is( 'node' ); // true for any node, false for document fragment and text fragment\n\t *\t\tobj.is( 'documentFragment' ); // true for document fragment, false for any node\n\t *\t\tobj.is( 'element' ); // true for any element, false for text node or document fragment\n\t *\t\tobj.is( 'element', 'p' ); // true only for element which name is 'p'\n\t *\t\tobj.is( 'p' ); // shortcut for obj.is( 'element', 'p' )\n\t *\t\tobj.is( 'text' ); // true for text node, false for element and document fragment\n\t *\n\t * @param {'element'|'containerElement'|'attributeElement'|'emptyElement'|'uiElement'|\n\t * 'rootElement'|'documentFragment'|'text'|'textProxy'} type\n\t * @returns {Boolean}\n\t */\n\tis( type ) {\n\t\treturn type == 'node';\n\t}\n\n\t/**\n\t * Clones this node.\n\t *\n\t * @protected\n\t * @method #_clone\n\t * @returns {module:engine/view/node~Node} Clone of this node.\n\t */\n\n\t/**\n\t * Checks if provided node is similar to this node.\n\t *\n\t * @method #isSimilar\n\t * @returns {Boolean} True if nodes are similar.\n\t */\n}\n\n/**\n * Fired when list of {@link module:engine/view/element~Element elements} children changes.\n *\n * Change event is bubbled – it is fired on all ancestors.\n *\n * @event change:children\n * @param {module:engine/view/node~Node} changedNode\n */\n\n/**\n * Fired when list of {@link module:engine/view/element~Element elements} attributes changes.\n *\n * Change event is bubbled – it is fired on all ancestors.\n *\n * @event change:attributes\n * @param {module:engine/view/node~Node} changedNode\n */\n\n/**\n * Fired when {@link module:engine/view/text~Text text nodes} data changes.\n *\n * Change event is bubbled – it is fired on all ancestors.\n *\n * @event change:text\n * @param {module:engine/view/node~Node} changedNode\n */\n\n/**\n * @event change\n */\n\nmix( Node, EmitterMixin );\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/text\n */\n\nimport Node from './node';\n\n/**\n * Tree view text node.\n *\n * The constructor of this class shouldn't be used directly. To create new Text instances\n * use the {@link module:engine/view/downcastwriter~DowncastWriter#createText `DowncastWriter#createText()`}\n * method when working on data downcasted from the model or the\n * {@link module:engine/view/upcastwriter~UpcastWriter#createText `UpcastWriter#createText()`}\n * method when working on non-semantic views.\n *\n * @extends module:engine/view/node~Node\n */\nexport default class Text extends Node {\n\t/**\n\t * Creates a tree view text node.\n\t *\n\t * @protected\n\t * @param {String} data The text's data.\n\t */\n\tconstructor( data ) {\n\t\tsuper();\n\n\t\t/**\n\t\t * The text content.\n\t\t *\n\t\t * Setting the data fires the {@link module:engine/view/node~Node#event:change:text change event}.\n\t\t *\n\t\t * @protected\n\t\t * @member {String} module:engine/view/text~Text#_textData\n\t\t */\n\t\tthis._textData = data;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tis( type ) {\n\t\treturn type == 'text' || super.is( type );\n\t}\n\n\t/**\n\t * The text content.\n\t *\n\t * @readonly\n\t * @type {String}\n\t */\n\tget data() {\n\t\treturn this._textData;\n\t}\n\n\t/**\n\t * This getter is required when using the addition assignment operator on protected property:\n\t *\n\t *\t\tconst foo = downcastWriter.createText( 'foo' );\n\t *\t\tconst bar = downcastWriter.createText( 'bar' );\n\t *\n\t *\t\tfoo._data += bar.data; // executes: `foo._data = foo._data + bar.data`\n\t *\t\tconsole.log( foo.data ); // prints: 'foobar'\n\t *\n\t * If the protected getter didn't exist, `foo._data` will return `undefined` and result of the merge will be invalid.\n\t *\n\t * @protected\n\t * @type {String}\n\t */\n\tget _data() {\n\t\treturn this.data;\n\t}\n\n\t/**\n\t * Sets data and fires the {@link module:engine/view/node~Node#event:change:text change event}.\n\t *\n\t * @protected\n\t * @fires change:text\n\t * @param {String} data New data for the text node.\n\t */\n\tset _data( data ) {\n\t\tthis._fireChange( 'text', this );\n\n\t\tthis._textData = data;\n\t}\n\n\t/**\n\t * Checks if this text node is similar to other text node.\n\t * Both nodes should have the same data to be considered as similar.\n\t *\n\t * @param {module:engine/view/text~Text} otherNode Node to check if it is same as this node.\n\t * @returns {Boolean}\n\t */\n\tisSimilar( otherNode ) {\n\t\tif ( !( otherNode instanceof Text ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn this === otherNode || this.data === otherNode.data;\n\t}\n\n\t/**\n\t * Clones this node.\n\t *\n\t * @protected\n\t * @returns {module:engine/view/text~Text} Text node that is a clone of this node.\n\t */\n\t_clone() {\n\t\treturn new Text( this.data );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/textproxy\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * TextProxy is a wrapper for substring of {@link module:engine/view/text~Text}. Instance of this class is created by\n * {@link module:engine/view/treewalker~TreeWalker} when only a part of {@link module:engine/view/text~Text} needs to be returned.\n *\n * `TextProxy` has an API similar to {@link module:engine/view/text~Text Text} and allows to do most of the common tasks performed\n * on view nodes.\n *\n * **Note:** Some `TextProxy` instances may represent whole text node, not just a part of it.\n * See {@link module:engine/view/textproxy~TextProxy#isPartial}.\n *\n * **Note:** `TextProxy` is a readonly interface.\n *\n * **Note:** `TextProxy` instances are created on the fly basing on the current state of parent {@link module:engine/view/text~Text}.\n * Because of this it is highly unrecommended to store references to `TextProxy instances because they might get\n * invalidated due to operations on Document. Also TextProxy is not a {@link module:engine/view/node~Node} so it can not be\n * inserted as a child of {@link module:engine/view/element~Element}.\n *\n * `TextProxy` instances are created by {@link module:engine/view/treewalker~TreeWalker view tree walker}. You should not need to create\n * an instance of this class by your own.\n */\nexport default class TextProxy {\n\t/**\n\t * Creates a text proxy.\n\t *\n\t * @protected\n\t * @param {module:engine/view/text~Text} textNode Text node which part is represented by this text proxy.\n\t * @param {Number} offsetInText Offset in {@link module:engine/view/textproxy~TextProxy#textNode text node}\n\t * from which the text proxy starts.\n\t * @param {Number} length Text proxy length, that is how many text node's characters, starting from `offsetInText` it represents.\n\t * @constructor\n\t */\n\tconstructor( textNode, offsetInText, length ) {\n\t\t/**\n\t\t * Reference to the {@link module:engine/view/text~Text} element which TextProxy is a substring.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/text~Text} module:engine/view/textproxy~TextProxy#textNode\n\t\t */\n\t\tthis.textNode = textNode;\n\n\t\tif ( offsetInText < 0 || offsetInText > textNode.data.length ) {\n\t\t\t/**\n\t\t\t * Given offsetInText value is incorrect.\n\t\t\t *\n\t\t\t * @error view-textproxy-wrong-offsetintext\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-textproxy-wrong-offsetintext: Given offsetInText value is incorrect.' );\n\t\t}\n\n\t\tif ( length < 0 || offsetInText + length > textNode.data.length ) {\n\t\t\t/**\n\t\t\t * Given length value is incorrect.\n\t\t\t *\n\t\t\t * @error view-textproxy-wrong-length\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-textproxy-wrong-length: Given length value is incorrect.' );\n\t\t}\n\n\t\t/**\n\t\t * Text data represented by this text proxy.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String} module:engine/view/textproxy~TextProxy#data\n\t\t */\n\t\tthis.data = textNode.data.substring( offsetInText, offsetInText + length );\n\n\t\t/**\n\t\t * Offset in the `textNode` where this `TextProxy` instance starts.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} module:engine/view/textproxy~TextProxy#offsetInText\n\t\t */\n\t\tthis.offsetInText = offsetInText;\n\t}\n\n\t/**\n\t * Offset size of this node.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget offsetSize() {\n\t\treturn this.data.length;\n\t}\n\n\t/**\n\t * Flag indicating whether `TextProxy` instance covers only part of the original {@link module:engine/view/text~Text text node}\n\t * (`true`) or the whole text node (`false`).\n\t *\n\t * This is `false` when text proxy starts at the very beginning of {@link module:engine/view/textproxy~TextProxy#textNode textNode}\n\t * ({@link module:engine/view/textproxy~TextProxy#offsetInText offsetInText} equals `0`) and text proxy sizes is equal to\n\t * text node size.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isPartial() {\n\t\treturn this.data.length !== this.textNode.data.length;\n\t}\n\n\t/**\n\t * Parent of this text proxy, which is same as parent of text node represented by this text proxy.\n\t *\n\t * @readonly\n\t * @type {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment|null}\n\t */\n\tget parent() {\n\t\treturn this.textNode.parent;\n\t}\n\n\t/**\n\t * Root of this text proxy, which is same as root of text node represented by this text proxy.\n\t *\n\t * @readonly\n\t * @type {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment}\n\t */\n\tget root() {\n\t\treturn this.textNode.root;\n\t}\n\n\t/**\n\t * {@link module:engine/view/document~Document View document} that owns this text proxy, or `null` if the text proxy is inside\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragment}.\n\t *\n\t * @readonly\n\t * @type {module:engine/view/document~Document|null}\n\t */\n\tget document() {\n\t\treturn this.textNode.document;\n\t}\n\n\t/**\n\t * Checks whether given view tree object is of given type.\n\t *\n\t * Read more in {@link module:engine/view/node~Node#is}.\n\t *\n\t * @param {String} type\n\t * @returns {Boolean}\n\t */\n\tis( type ) {\n\t\treturn type == 'textProxy';\n\t}\n\n\t/**\n\t * Returns ancestors array of this text proxy.\n\t *\n\t * @param {Object} options Options object.\n\t * @param {Boolean} [options.includeSelf=false] When set to `true` {#textNode} will be also included in parent's array.\n\t * @param {Boolean} [options.parentFirst=false] When set to `true`, array will be sorted from text proxy parent to\n\t * root element, otherwise root element will be the first item in the array.\n\t * @returns {Array} Array with ancestors.\n\t */\n\tgetAncestors( options = { includeSelf: false, parentFirst: false } ) {\n\t\tconst ancestors = [];\n\t\tlet parent = options.includeSelf ? this.textNode : this.parent;\n\n\t\twhile ( parent !== null ) {\n\t\t\tancestors[ options.parentFirst ? 'push' : 'unshift' ]( parent );\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn ancestors;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/objecttomap\n */\n\n/**\n * Transforms object to map.\n *\n *\t\tconst map = objectToMap( { 'foo': 1, 'bar': 2 } );\n *\t\tmap.get( 'foo' ); // 1\n *\n * @param {Object} obj Object to transform.\n * @returns {Map} Map created from object.\n */\nexport default function objectToMap( obj ) {\n\tconst map = new Map();\n\n\tfor ( const key in obj ) {\n\t\tmap.set( key, obj[ key ] );\n\t}\n\n\treturn map;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/isiterable\n */\n\n/**\n * Checks if value implements iterator interface.\n *\n * @param {*} value The value to check.\n * @returns {Boolean} True if value implements iterator interface.\n */\nexport default function isIterable( value ) {\n\treturn !!( value && value[ Symbol.iterator ] );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/matcher\n */\n\n/**\n * View matcher class.\n * Instance of this class can be used to find {@link module:engine/view/element~Element elements} that match given pattern.\n */\nexport default class Matcher {\n\t/**\n\t * Creates new instance of Matcher.\n\t *\n\t * @param {String|RegExp|Object} [pattern] Match patterns. See {@link module:engine/view/matcher~Matcher#add add method} for\n\t * more information.\n\t */\n\tconstructor( ...pattern ) {\n\t\t/**\n\t\t * @private\n\t\t * @type {Array<String|RegExp|Object>}\n\t\t */\n\t\tthis._patterns = [];\n\n\t\tthis.add( ...pattern );\n\t}\n\n\t/**\n\t * Adds pattern or patterns to matcher instance.\n\t *\n\t *\t\t// String.\n\t *\t\tmatcher.add( 'div' );\n\t *\n\t *\t\t// Regular expression.\n\t *\t\tmatcher.add( /^\\w/ );\n\t *\n\t *\t\t// Single class.\n\t *\t\tmatcher.add( {\n\t *\t\t\tclasses: 'foobar'\n\t *\t\t} );\n\t *\n\t * See {@link module:engine/view/matcher~MatcherPattern} for more examples.\n\t *\n\t * Multiple patterns can be added in one call:\n\t *\n\t * \t\tmatcher.add( 'div', { classes: 'foobar' } );\n\t *\n\t * @param {Object|String|RegExp|Function} pattern Object describing pattern details. If string or regular expression\n\t * is provided it will be used to match element's name. Pattern can be also provided in a form\n\t * of a function - then this function will be called with each {@link module:engine/view/element~Element element} as a parameter.\n\t * Function's return value will be stored under `match` key of the object returned from\n\t * {@link module:engine/view/matcher~Matcher#match match} or {@link module:engine/view/matcher~Matcher#matchAll matchAll} methods.\n\t * @param {String|RegExp} [pattern.name] Name or regular expression to match element's name.\n\t * @param {Object} [pattern.attributes] Object with key-value pairs representing attributes to match. Each object key\n\t * represents attribute name. Value under that key can be either:\n\t * * `true` - then attribute is just required (can be empty),\n\t * * a string - then attribute has to be equal, or\n\t * * a regular expression - then attribute has to match the expression.\n\t * @param {String|RegExp|Array} [pattern.classes] Class name or array of class names to match. Each name can be\n\t * provided in a form of string or regular expression.\n\t * @param {Object} [pattern.styles] Object with key-value pairs representing styles to match. Each object key\n\t * represents style name. Value under that key can be either a string or a regular expression and it will be used\n\t * to match style value.\n\t */\n\tadd( ...pattern ) {\n\t\tfor ( let item of pattern ) {\n\t\t\t// String or RegExp pattern is used as element's name.\n\t\t\tif ( typeof item == 'string' || item instanceof RegExp ) {\n\t\t\t\titem = { name: item };\n\t\t\t}\n\n\t\t\t// Single class name/RegExp can be provided.\n\t\t\tif ( item.classes && ( typeof item.classes == 'string' || item.classes instanceof RegExp ) ) {\n\t\t\t\titem.classes = [ item.classes ];\n\t\t\t}\n\n\t\t\tthis._patterns.push( item );\n\t\t}\n\t}\n\n\t/**\n\t * Matches elements for currently stored patterns. Returns match information about first found\n\t * {@link module:engine/view/element~Element element}, otherwise returns `null`.\n\t *\n\t * Example of returned object:\n\t *\n\t *\t\t{\n\t *\t\t\telement: <instance of found element>,\n\t *\t\t\tpattern: <pattern used to match found element>,\n\t *\t\t\tmatch: {\n\t *\t\t\t\tname: true,\n\t *\t\t\t\tattributes: [ 'title', 'href' ],\n\t *\t\t\t\tclasses: [ 'foo' ],\n\t *\t\t\t\tstyles: [ 'color', 'position' ]\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t * @see module:engine/view/matcher~Matcher#add\n\t * @see module:engine/view/matcher~Matcher#matchAll\n\t * @param {...module:engine/view/element~Element} element View element to match against stored patterns.\n\t * @returns {Object|null} result\n\t * @returns {module:engine/view/element~Element} result.element Matched view element.\n\t * @returns {Object|String|RegExp|Function} result.pattern Pattern that was used to find matched element.\n\t * @returns {Object} result.match Object representing matched element parts.\n\t * @returns {Boolean} [result.match.name] True if name of the element was matched.\n\t * @returns {Array} [result.match.attributes] Array with matched attribute names.\n\t * @returns {Array} [result.match.classes] Array with matched class names.\n\t * @returns {Array} [result.match.styles] Array with matched style names.\n\t */\n\tmatch( ...element ) {\n\t\tfor ( const singleElement of element ) {\n\t\t\tfor ( const pattern of this._patterns ) {\n\t\t\t\tconst match = isElementMatching( singleElement, pattern );\n\n\t\t\t\tif ( match ) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\telement: singleElement,\n\t\t\t\t\t\tpattern,\n\t\t\t\t\t\tmatch\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Matches elements for currently stored patterns. Returns array of match information with all found\n\t * {@link module:engine/view/element~Element elements}. If no element is found - returns `null`.\n\t *\n\t * @see module:engine/view/matcher~Matcher#add\n\t * @see module:engine/view/matcher~Matcher#match\n\t * @param {...module:engine/view/element~Element} element View element to match against stored patterns.\n\t * @returns {Array.<Object>|null} Array with match information about found elements or `null`. For more information\n\t * see {@link module:engine/view/matcher~Matcher#match match method} description.\n\t */\n\tmatchAll( ...element ) {\n\t\tconst results = [];\n\n\t\tfor ( const singleElement of element ) {\n\t\t\tfor ( const pattern of this._patterns ) {\n\t\t\t\tconst match = isElementMatching( singleElement, pattern );\n\n\t\t\t\tif ( match ) {\n\t\t\t\t\tresults.push( {\n\t\t\t\t\t\telement: singleElement,\n\t\t\t\t\t\tpattern,\n\t\t\t\t\t\tmatch\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn results.length > 0 ? results : null;\n\t}\n\n\t/**\n\t * Returns the name of the element to match if there is exactly one pattern added to the matcher instance\n\t * and it matches element name defined by `string` (not `RegExp`). Otherwise, returns `null`.\n\t *\n\t * @returns {String|null} Element name trying to match.\n\t */\n\tgetElementName() {\n\t\tif ( this._patterns.length !== 1 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst pattern = this._patterns[ 0 ];\n\t\tconst name = pattern.name;\n\n\t\treturn ( typeof pattern != 'function' && name && !( name instanceof RegExp ) ) ? name : null;\n\t}\n}\n\n// Returns match information if {@link module:engine/view/element~Element element} is matching provided pattern.\n// If element cannot be matched to provided pattern - returns `null`.\n//\n// @param {module:engine/view/element~Element} element\n// @param {Object|String|RegExp|Function} pattern\n// @returns {Object|null} Returns object with match information or null if element is not matching.\nfunction isElementMatching( element, pattern ) {\n\t// If pattern is provided as function - return result of that function;\n\tif ( typeof pattern == 'function' ) {\n\t\treturn pattern( element );\n\t}\n\n\tconst match = {};\n\t// Check element's name.\n\tif ( pattern.name ) {\n\t\tmatch.name = matchName( pattern.name, element.name );\n\n\t\tif ( !match.name ) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t// Check element's attributes.\n\tif ( pattern.attributes ) {\n\t\tmatch.attributes = matchAttributes( pattern.attributes, element );\n\n\t\tif ( !match.attributes ) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t// Check element's classes.\n\tif ( pattern.classes ) {\n\t\tmatch.classes = matchClasses( pattern.classes, element );\n\n\t\tif ( !match.classes ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Check element's styles.\n\tif ( pattern.styles ) {\n\t\tmatch.styles = matchStyles( pattern.styles, element );\n\n\t\tif ( !match.styles ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn match;\n}\n\n// Checks if name can be matched by provided pattern.\n//\n// @param {String|RegExp} pattern\n// @param {String} name\n// @returns {Boolean} Returns `true` if name can be matched, `false` otherwise.\nfunction matchName( pattern, name ) {\n\t// If pattern is provided as RegExp - test against this regexp.\n\tif ( pattern instanceof RegExp ) {\n\t\treturn pattern.test( name );\n\t}\n\n\treturn pattern === name;\n}\n\n// Checks if attributes of provided element can be matched against provided patterns.\n//\n// @param {Object} patterns Object with information about attributes to match. Each key of the object will be\n// used as attribute name. Value of each key can be a string or regular expression to match against attribute value.\n// @param {module:engine/view/element~Element} element Element which attributes will be tested.\n// @returns {Array|null} Returns array with matched attribute names or `null` if no attributes were matched.\nfunction matchAttributes( patterns, element ) {\n\tconst match = [];\n\n\tfor ( const name in patterns ) {\n\t\tconst pattern = patterns[ name ];\n\n\t\tif ( element.hasAttribute( name ) ) {\n\t\t\tconst attribute = element.getAttribute( name );\n\n\t\t\tif ( pattern === true ) {\n\t\t\t\tmatch.push( name );\n\t\t\t} else if ( pattern instanceof RegExp ) {\n\t\t\t\tif ( pattern.test( attribute ) ) {\n\t\t\t\t\tmatch.push( name );\n\t\t\t\t} else {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t} else if ( attribute === pattern ) {\n\t\t\t\tmatch.push( name );\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\treturn match;\n}\n\n// Checks if classes of provided element can be matched against provided patterns.\n//\n// @param {Array.<String|RegExp>} patterns Array of strings or regular expressions to match against element's classes.\n// @param {module:engine/view/element~Element} element Element which classes will be tested.\n// @returns {Array|null} Returns array with matched class names or `null` if no classes were matched.\nfunction matchClasses( patterns, element ) {\n\tconst match = [];\n\n\tfor ( const pattern of patterns ) {\n\t\tif ( pattern instanceof RegExp ) {\n\t\t\tconst classes = element.getClassNames();\n\n\t\t\tfor ( const name of classes ) {\n\t\t\t\tif ( pattern.test( name ) ) {\n\t\t\t\t\tmatch.push( name );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( match.length === 0 ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t} else if ( element.hasClass( pattern ) ) {\n\t\t\tmatch.push( pattern );\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\treturn match;\n}\n\n// Checks if styles of provided element can be matched against provided patterns.\n//\n// @param {Object} patterns Object with information about styles to match. Each key of the object will be\n// used as style name. Value of each key can be a string or regular expression to match against style value.\n// @param {module:engine/view/element~Element} element Element which styles will be tested.\n// @returns {Array|null} Returns array with matched style names or `null` if no styles were matched.\nfunction matchStyles( patterns, element ) {\n\tconst match = [];\n\n\tfor ( const name in patterns ) {\n\t\tconst pattern = patterns[ name ];\n\n\t\tif ( element.hasStyle( name ) ) {\n\t\t\tconst style = element.getStyle( name );\n\n\t\t\tif ( pattern instanceof RegExp ) {\n\t\t\t\tif ( pattern.test( style ) ) {\n\t\t\t\t\tmatch.push( name );\n\t\t\t\t} else {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t} else if ( style === pattern ) {\n\t\t\t\tmatch.push( name );\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\treturn match;\n}\n\n/**\n * An entity that is a valid pattern recognized by a matcher. `MatcherPattern` is used by {@link ~Matcher} to recognize\n * if a view element fits in a group of view elements described by the pattern.\n *\n * `MatcherPattern` can be given as a `String`, a `RegExp`, an `Object` or a `Function`.\n *\n * If `MatcherPattern` is given as a `String` or `RegExp`, it will match any view element that has a matching name:\n *\n *\t\t// Match any element with name equal to 'div'.\n *\t\tconst pattern = 'div';\n *\n *\t\t// Match any element which name starts on 'p'.\n *\t\tconst pattern = /^p/;\n *\n * If `MatcherPattern` is given as an `Object`, all the object's properties will be matched with view element properties.\n *\n *\t\t// Match view element's name.\n *\t\tconst pattern = { name: /^p/ };\n *\n *\t\t// Match view element which has matching attributes.\n *\t\tconst pattern = {\n *\t\t\tattributes: {\n *\t\t\t\ttitle: 'foobar',\t// Attribute title should equal 'foobar'.\n *\t\t\t\tfoo: /^\\w+/,\t\t// Attribute foo should match /^\\w+/ regexp.\n *\t\t\t\tbar: true\t\t\t// Attribute bar should be set (can be empty).\n *\t\t\t}\n *\t\t};\n *\n *\t\t// Match view element which has given class.\n *\t\tconst pattern = {\n *\t\t\tclasses: 'foobar'\n *\t\t};\n *\n *\t\t// Match view element class using regular expression.\n *\t\tconst pattern = {\n *\t\t\tclasses: /foo.../\n *\t\t};\n *\n *\t\t// Multiple classes to match.\n *\t\tconst pattern = {\n *\t\t\tclasses: [ 'baz', 'bar', /foo.../ ]\n *\t\t};\n *\n *\t\t// Match view element which has given styles.\n *\t\tconst pattern = {\n *\t\t\tstyles: {\n *\t\t\t\tposition: 'absolute',\n *\t\t\t\tcolor: /^\\w*blue$/\n *\t\t\t}\n *\t\t};\n *\n *\t\t// Pattern with multiple properties.\n *\t\tconst pattern = {\n *\t\t\tname: 'span',\n *\t\t\tstyles: {\n *\t\t\t\t'font-weight': 'bold'\n *\t\t\t},\n *\t\t\tclasses: 'highlighted'\n *\t\t};\n *\n * If `MatcherPattern` is given as a `Function`, the function takes a view element as a first and only parameter and\n * the function should decide whether that element matches. If so, it should return what part of the view element has been matched.\n * Otherwise, the function should return `null`. The returned result will be included in `match` property of the object\n * returned by {@link ~Matcher#match} call.\n *\n *\t\t// Match an empty <div> element.\n *\t\tconst pattern = element => {\n *\t\t\tif ( element.name == 'div' && element.childCount > 0 ) {\n *\t\t\t\t// Return which part of the element was matched.\n *\t\t\t\treturn { name: true };\n *\t\t\t}\n *\n *\t\t\treturn null;\n *\t\t};\n *\n *\t\t// Match a <p> element with big font (\"heading-like\" element).\n *\t\tconst pattern = element => {\n *\t\t\tif ( element.name == 'p' ) {\n *\t\t\t\tconst fontSize = element.getStyle( 'font-size' );\n *\t\t\t\tconst size = fontSize.match( /(\\d+)/px );\n *\n *\t\t\t\tif ( size && Number( size[ 1 ] ) > 26 ) {\n *\t\t\t\t\treturn { name: true, attribute: [ 'font-size' ] };\n *\t\t\t\t}\n *\t\t\t}\n *\n *\t\t\treturn null;\n *\t\t};\n *\n * `MatcherPattern` is defined in a way that it is a superset of {@link module:engine/view/elementdefinition~ElementDefinition},\n * that is, every `ElementDefinition` also can be used as a `MatcherPattern`.\n *\n * @typedef {String|RegExp|Object|Function} module:engine/view/matcher~MatcherPattern\n *\n * @property {String|RegExp} [name] View element name to match.\n * @property {String|RegExp|Array.<String|RegExp>} [classes] View element's class name(s) to match.\n * @property {Object} [styles] Object with key-value pairs representing styles to match.\n * Each object key represents style name. Value can be given as `String` or `RegExp`.\n * @property {Object} [attributes] Object with key-value pairs representing attributes to match.\n * Each object key represents attribute name. Value can be given as `String` or `RegExp`.\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/element\n */\n\nimport Node from './node';\nimport Text from './text';\nimport TextProxy from './textproxy';\nimport objectToMap from '@ckeditor/ckeditor5-utils/src/objecttomap';\nimport isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';\nimport Matcher from './matcher';\nimport { isPlainObject } from 'lodash-es';\n\n/**\n * View element.\n *\n * The editing engine does not define a fixed semantics of its elements (it is \"DTD-free\").\n * This is why the type of the {@link module:engine/view/element~Element} need to\n * be defined by the feature developer. When creating an element you should use one of the following methods:\n *\n * * {@link module:engine/view/downcastwriter~DowncastWriter#createContainerElement `downcastWriter#createContainerElement()`}\n * in order to create a {@link module:engine/view/containerelement~ContainerElement},\n * * {@link module:engine/view/downcastwriter~DowncastWriter#createAttributeElement `downcastWriter#createAttributeElement()`}\n * in order to create a {@link module:engine/view/attributeelement~AttributeElement},\n * * {@link module:engine/view/downcastwriter~DowncastWriter#createEmptyElement `downcastWriter#createEmptyElement()`}\n * in order to create a {@link module:engine/view/emptyelement~EmptyElement}.\n * * {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement `downcastWriter#createUIElement()`}\n * in order to create a {@link module:engine/view/uielement~UIElement}.\n * * {@link module:engine/view/downcastwriter~DowncastWriter#createEditableElement `downcastWriter#createEditableElement()`}\n * in order to create a {@link module:engine/view/editableelement~EditableElement}.\n *\n * Note that for view elements which are not created from the model, like elements from mutations, paste or\n * {@link module:engine/controller/datacontroller~DataController#set data.set} it is not possible to define the type of the element.\n * In such cases the {@link module:engine/view/upcastwriter~UpcastWriter#createElement `UpcastWriter#createElement()`} method\n * should be used to create generic view elements.\n *\n * @extends module:engine/view/node~Node\n */\nexport default class Element extends Node {\n\t/**\n\t * Creates a view element.\n\t *\n\t * Attributes can be passed in various formats:\n\t *\n\t *\t\tnew Element( 'div', { class: 'editor', contentEditable: 'true' } ); // object\n\t *\t\tnew Element( 'div', [ [ 'class', 'editor' ], [ 'contentEditable', 'true' ] ] ); // map-like iterator\n\t *\t\tnew Element( 'div', mapOfAttributes ); // map\n\t *\n\t * @protected\n\t * @param {String} name Node name.\n\t * @param {Object|Iterable} [attrs] Collection of attributes.\n\t * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children]\n\t * A list of nodes to be inserted into created element.\n\t */\n\tconstructor( name, attrs, children ) {\n\t\tsuper();\n\n\t\t/**\n\t\t * Name of the element.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.name = name;\n\n\t\t/**\n\t\t * Map of attributes, where attributes names are keys and attributes values are values.\n\t\t *\n\t\t * @protected\n\t\t * @member {Map} #_attrs\n\t\t */\n\t\tthis._attrs = parseAttributes( attrs );\n\n\t\t/**\n\t\t * Array of child nodes.\n\t\t *\n\t\t * @protected\n\t\t * @member {Array.<module:engine/view/node~Node>}\n\t\t */\n\t\tthis._children = [];\n\n\t\tif ( children ) {\n\t\t\tthis._insertChild( 0, children );\n\t\t}\n\n\t\t/**\n\t\t * Set of classes associated with element instance.\n\t\t *\n\t\t * @protected\n\t\t * @member {Set}\n\t\t */\n\t\tthis._classes = new Set();\n\n\t\tif ( this._attrs.has( 'class' ) ) {\n\t\t\t// Remove class attribute and handle it by class set.\n\t\t\tconst classString = this._attrs.get( 'class' );\n\t\t\tparseClasses( this._classes, classString );\n\t\t\tthis._attrs.delete( 'class' );\n\t\t}\n\n\t\t/**\n\t\t * Map of styles.\n\t\t *\n\t\t * @protected\n\t\t * @member {Map} module:engine/view/element~Element#_styles\n\t\t */\n\t\tthis._styles = new Map();\n\n\t\tif ( this._attrs.has( 'style' ) ) {\n\t\t\t// Remove style attribute and handle it by styles map.\n\t\t\tparseInlineStyles( this._styles, this._attrs.get( 'style' ) );\n\t\t\tthis._attrs.delete( 'style' );\n\t\t}\n\n\t\t/**\n\t\t * Map of custom properties.\n\t\t * Custom properties can be added to element instance, will be cloned but not rendered into DOM.\n\t\t *\n\t\t * @protected\n\t\t * @member {Map}\n\t\t */\n\t\tthis._customProperties = new Map();\n\t}\n\n\t/**\n\t * Number of element's children.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget childCount() {\n\t\treturn this._children.length;\n\t}\n\n\t/**\n\t * Is `true` if there are no nodes inside this element, `false` otherwise.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isEmpty() {\n\t\treturn this._children.length === 0;\n\t}\n\n\t/**\n\t * Checks whether this view object is of the given type.\n\t *\n\t *\t\tobj.is( 'element' ); // true\n\t *\t\tobj.is( 'li' ); // true\n\t *\t\tobj.is( 'element', 'li' ); // true\n\t *\t\tobj.is( 'text' ); // false\n\t *\t\tobj.is( 'element', 'img' ); // false\n\t *\n\t * Read more in {@link module:engine/view/node~Node#is `Node#is()`}.\n\t *\n\t * @param {String} type\n\t * @param {String} [name] Element name.\n\t * @returns {Boolean}\n\t */\n\tis( type, name = null ) {\n\t\tif ( !name ) {\n\t\t\treturn type == 'element' || type == this.name || super.is( type );\n\t\t} else {\n\t\t\treturn type == 'element' && name == this.name;\n\t\t}\n\t}\n\n\t/**\n\t * Gets child at the given index.\n\t *\n\t * @param {Number} index Index of child.\n\t * @returns {module:engine/view/node~Node} Child node.\n\t */\n\tgetChild( index ) {\n\t\treturn this._children[ index ];\n\t}\n\n\t/**\n\t * Gets index of the given child node. Returns `-1` if child node is not found.\n\t *\n\t * @param {module:engine/view/node~Node} node Child node.\n\t * @returns {Number} Index of the child node.\n\t */\n\tgetChildIndex( node ) {\n\t\treturn this._children.indexOf( node );\n\t}\n\n\t/**\n\t * Gets child nodes iterator.\n\t *\n\t * @returns {Iterable.<module:engine/view/node~Node>} Child nodes iterator.\n\t */\n\tgetChildren() {\n\t\treturn this._children[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Returns an iterator that contains the keys for attributes. Order of inserting attributes is not preserved.\n\t *\n\t * @returns {Iterable.<String>} Keys for attributes.\n\t */\n\t* getAttributeKeys() {\n\t\tif ( this._classes.size > 0 ) {\n\t\t\tyield 'class';\n\t\t}\n\n\t\tif ( this._styles.size > 0 ) {\n\t\t\tyield 'style';\n\t\t}\n\n\t\tyield* this._attrs.keys();\n\t}\n\n\t/**\n\t * Returns iterator that iterates over this element's attributes.\n\t *\n\t * Attributes are returned as arrays containing two items. First one is attribute key and second is attribute value.\n\t * This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t *\n\t * @returns {Iterable.<*>}\n\t */\n\t* getAttributes() {\n\t\tyield* this._attrs.entries();\n\n\t\tif ( this._classes.size > 0 ) {\n\t\t\tyield [ 'class', this.getAttribute( 'class' ) ];\n\t\t}\n\n\t\tif ( this._styles.size > 0 ) {\n\t\t\tyield [ 'style', this.getAttribute( 'style' ) ];\n\t\t}\n\t}\n\n\t/**\n\t * Gets attribute by key. If attribute is not present - returns undefined.\n\t *\n\t * @param {String} key Attribute key.\n\t * @returns {String|undefined} Attribute value.\n\t */\n\tgetAttribute( key ) {\n\t\tif ( key == 'class' ) {\n\t\t\tif ( this._classes.size > 0 ) {\n\t\t\t\treturn [ ...this._classes ].join( ' ' );\n\t\t\t}\n\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif ( key == 'style' ) {\n\t\t\tif ( this._styles.size > 0 ) {\n\t\t\t\tlet styleString = '';\n\n\t\t\t\tfor ( const [ property, value ] of this._styles ) {\n\t\t\t\t\tstyleString += `${ property }:${ value };`;\n\t\t\t\t}\n\n\t\t\t\treturn styleString;\n\t\t\t}\n\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn this._attrs.get( key );\n\t}\n\n\t/**\n\t * Returns a boolean indicating whether an attribute with the specified key exists in the element.\n\t *\n\t * @param {String} key Attribute key.\n\t * @returns {Boolean} `true` if attribute with the specified key exists in the element, false otherwise.\n\t */\n\thasAttribute( key ) {\n\t\tif ( key == 'class' ) {\n\t\t\treturn this._classes.size > 0;\n\t\t}\n\n\t\tif ( key == 'style' ) {\n\t\t\treturn this._styles.size > 0;\n\t\t}\n\n\t\treturn this._attrs.has( key );\n\t}\n\n\t/**\n\t * Checks if this element is similar to other element.\n\t * Both elements should have the same name and attributes to be considered as similar. Two similar elements\n\t * can contain different set of children nodes.\n\t *\n\t * @param {module:engine/view/element~Element} otherElement\n\t * @returns {Boolean}\n\t */\n\tisSimilar( otherElement ) {\n\t\tif ( !( otherElement instanceof Element ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If exactly the same Element is provided - return true immediately.\n\t\tif ( this === otherElement ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Check element name.\n\t\tif ( this.name != otherElement.name ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check number of attributes, classes and styles.\n\t\tif ( this._attrs.size !== otherElement._attrs.size || this._classes.size !== otherElement._classes.size ||\n\t\t\tthis._styles.size !== otherElement._styles.size ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check if attributes are the same.\n\t\tfor ( const [ key, value ] of this._attrs ) {\n\t\t\tif ( !otherElement._attrs.has( key ) || otherElement._attrs.get( key ) !== value ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Check if classes are the same.\n\t\tfor ( const className of this._classes ) {\n\t\t\tif ( !otherElement._classes.has( className ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Check if styles are the same.\n\t\tfor ( const [ property, value ] of this._styles ) {\n\t\t\tif ( !otherElement._styles.has( property ) || otherElement._styles.get( property ) !== value ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns true if class is present.\n\t * If more then one class is provided - returns true only when all classes are present.\n\t *\n\t *\t\telement.hasClass( 'foo' ); // Returns true if 'foo' class is present.\n\t *\t\telement.hasClass( 'foo', 'bar' ); // Returns true if 'foo' and 'bar' classes are both present.\n\t *\n\t * @param {...String} className\n\t */\n\thasClass( ...className ) {\n\t\tfor ( const name of className ) {\n\t\t\tif ( !this._classes.has( name ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns iterator that contains all class names.\n\t *\n\t * @returns {Iterable.<String>}\n\t */\n\tgetClassNames() {\n\t\treturn this._classes.keys();\n\t}\n\n\t/**\n\t * Returns style value for given property.\n\t * Undefined is returned if style does not exist.\n\t *\n\t * @param {String} property\n\t * @returns {String|undefined}\n\t */\n\tgetStyle( property ) {\n\t\treturn this._styles.get( property );\n\t}\n\n\t/**\n\t * Returns iterator that contains all style names.\n\t *\n\t * @returns {Iterable.<String>}\n\t */\n\tgetStyleNames() {\n\t\treturn this._styles.keys();\n\t}\n\n\t/**\n\t * Returns true if style keys are present.\n\t * If more then one style property is provided - returns true only when all properties are present.\n\t *\n\t *\t\telement.hasStyle( 'color' ); // Returns true if 'border-top' style is present.\n\t *\t\telement.hasStyle( 'color', 'border-top' ); // Returns true if 'color' and 'border-top' styles are both present.\n\t *\n\t * @param {...String} property\n\t */\n\thasStyle( ...property ) {\n\t\tfor ( const name of property ) {\n\t\t\tif ( !this._styles.has( name ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns ancestor element that match specified pattern.\n\t * Provided patterns should be compatible with {@link module:engine/view/matcher~Matcher Matcher} as it is used internally.\n\t *\n\t * @see module:engine/view/matcher~Matcher\n\t * @param {Object|String|RegExp|Function} patterns Patterns used to match correct ancestor.\n\t * See {@link module:engine/view/matcher~Matcher}.\n\t * @returns {module:engine/view/element~Element|null} Found element or `null` if no matching ancestor was found.\n\t */\n\tfindAncestor( ...patterns ) {\n\t\tconst matcher = new Matcher( ...patterns );\n\t\tlet parent = this.parent;\n\n\t\twhile ( parent ) {\n\t\t\tif ( matcher.match( parent ) ) {\n\t\t\t\treturn parent;\n\t\t\t}\n\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Returns the custom property value for the given key.\n\t *\n\t * @param {String|Symbol} key\n\t * @returns {*}\n\t */\n\tgetCustomProperty( key ) {\n\t\treturn this._customProperties.get( key );\n\t}\n\n\t/**\n\t * Returns an iterator which iterates over this element's custom properties.\n\t * Iterator provides `[ key, value ]` pairs for each stored property.\n\t *\n\t * @returns {Iterable.<*>}\n\t */\n\t* getCustomProperties() {\n\t\tyield* this._customProperties.entries();\n\t}\n\n\t/**\n\t * Returns identity string based on element's name, styles, classes and other attributes.\n\t * Two elements that {@link #isSimilar are similar} will have same identity string.\n\t * It has the following format:\n\t *\n\t *\t\t'name class=\"class1,class2\" style=\"style1:value1;style2:value2\" attr1=\"val1\" attr2=\"val2\"'\n \t *\n\t * For example:\n\t *\n\t *\t\tconst element = writer.createContainerElement( 'foo', {\n\t *\t\t\tbanana: '10',\n\t *\t\t\tapple: '20',\n\t *\t\t\tstyle: 'color: red; border-color: white;',\n\t *\t\t\tclass: 'baz'\n\t *\t\t} );\n\t *\n\t *\t\t// returns 'foo class=\"baz\" style=\"border-color:white;color:red\" apple=\"20\" banana=\"10\"'\n\t *\t\telement.getIdentity();\n\t *\n\t * NOTE: Classes, styles and other attributes are sorted alphabetically.\n\t *\n\t * @returns {String}\n\t */\n\tgetIdentity() {\n\t\tconst classes = Array.from( this._classes ).sort().join( ',' );\n\t\tconst styles = Array.from( this._styles ).map( i => `${ i[ 0 ] }:${ i[ 1 ] }` ).sort().join( ';' );\n\t\tconst attributes = Array.from( this._attrs ).map( i => `${ i[ 0 ] }=\"${ i[ 1 ] }\"` ).sort().join( ' ' );\n\n\t\treturn this.name +\n\t\t\t( classes == '' ? '' : ` class=\"${ classes }\"` ) +\n\t\t\t( styles == '' ? '' : ` style=\"${ styles }\"` ) +\n\t\t\t( attributes == '' ? '' : ` ${ attributes }` );\n\t}\n\n\t/**\n\t * Clones provided element.\n\t *\n\t * @protected\n\t * @param {Boolean} [deep=false] If set to `true` clones element and all its children recursively. When set to `false`,\n\t * element will be cloned without any children.\n\t * @returns {module:engine/view/element~Element} Clone of this element.\n\t */\n\t_clone( deep = false ) {\n\t\tconst childrenClone = [];\n\n\t\tif ( deep ) {\n\t\t\tfor ( const child of this.getChildren() ) {\n\t\t\t\tchildrenClone.push( child._clone( deep ) );\n\t\t\t}\n\t\t}\n\n\t\t// ContainerElement and AttributeElement should be also cloned properly.\n\t\tconst cloned = new this.constructor( this.name, this._attrs, childrenClone );\n\n\t\t// Classes and styles are cloned separately - this solution is faster than adding them back to attributes and\n\t\t// parse once again in constructor.\n\t\tcloned._classes = new Set( this._classes );\n\t\tcloned._styles = new Map( this._styles );\n\n\t\t// Clone custom properties.\n\t\tcloned._customProperties = new Map( this._customProperties );\n\n\t\t// Clone filler offset method.\n\t\t// We can't define this method in a prototype because it's behavior which\n\t\t// is changed by e.g. toWidget() function from ckeditor5-widget. Perhaps this should be one of custom props.\n\t\tcloned.getFillerOffset = this.getFillerOffset;\n\n\t\treturn cloned;\n\t}\n\n\t/**\n\t * {@link module:engine/view/element~Element#_insertChild Insert} a child node or a list of child nodes at the end of this node\n\t * and sets the parent of these nodes to this element.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#insert\n\t * @protected\n\t * @param {module:engine/view/item~Item|Iterable.<module:engine/view/item~Item>} items Items to be inserted.\n\t * @fires module:engine/view/node~Node#change\n\t * @returns {Number} Number of appended nodes.\n\t */\n\t_appendChild( items ) {\n\t\treturn this._insertChild( this.childCount, items );\n\t}\n\n\t/**\n\t * Inserts a child node or a list of child nodes on the given index and sets the parent of these nodes to\n\t * this element.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#insert\n\t * @protected\n\t * @param {Number} index Position where nodes should be inserted.\n\t * @param {module:engine/view/item~Item|Iterable.<module:engine/view/item~Item>} items Items to be inserted.\n\t * @fires module:engine/view/node~Node#change\n\t * @returns {Number} Number of inserted nodes.\n\t */\n\t_insertChild( index, items ) {\n\t\tthis._fireChange( 'children', this );\n\t\tlet count = 0;\n\n\t\tconst nodes = normalize( items );\n\n\t\tfor ( const node of nodes ) {\n\t\t\t// If node that is being added to this element is already inside another element, first remove it from the old parent.\n\t\t\tif ( node.parent !== null ) {\n\t\t\t\tnode._remove();\n\t\t\t}\n\n\t\t\tnode.parent = this;\n\n\t\t\tthis._children.splice( index, 0, node );\n\t\t\tindex++;\n\t\t\tcount++;\n\t\t}\n\n\t\treturn count;\n\t}\n\n\t/**\n\t * Removes number of child nodes starting at the given index and set the parent of these nodes to `null`.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#remove\n\t * @protected\n\t * @param {Number} index Number of the first node to remove.\n\t * @param {Number} [howMany=1] Number of nodes to remove.\n\t * @fires module:engine/view/node~Node#change\n\t * @returns {Array.<module:engine/view/node~Node>} The array of removed nodes.\n\t */\n\t_removeChildren( index, howMany = 1 ) {\n\t\tthis._fireChange( 'children', this );\n\n\t\tfor ( let i = index; i < index + howMany; i++ ) {\n\t\t\tthis._children[ i ].parent = null;\n\t\t}\n\n\t\treturn this._children.splice( index, howMany );\n\t}\n\n\t/**\n\t * Adds or overwrite attribute with a specified key and value.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#setAttribute\n\t * @protected\n\t * @param {String} key Attribute key.\n\t * @param {String} value Attribute value.\n\t * @fires module:engine/view/node~Node#change\n\t */\n\t_setAttribute( key, value ) {\n\t\tvalue = String( value );\n\n\t\tthis._fireChange( 'attributes', this );\n\n\t\tif ( key == 'class' ) {\n\t\t\tparseClasses( this._classes, value );\n\t\t} else if ( key == 'style' ) {\n\t\t\tparseInlineStyles( this._styles, value );\n\t\t} else {\n\t\t\tthis._attrs.set( key, value );\n\t\t}\n\t}\n\n\t/**\n\t * Removes attribute from the element.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#removeAttribute\n\t * @protected\n\t * @param {String} key Attribute key.\n\t * @returns {Boolean} Returns true if an attribute existed and has been removed.\n\t * @fires module:engine/view/node~Node#change\n\t */\n\t_removeAttribute( key ) {\n\t\tthis._fireChange( 'attributes', this );\n\n\t\t// Remove class attribute.\n\t\tif ( key == 'class' ) {\n\t\t\tif ( this._classes.size > 0 ) {\n\t\t\t\tthis._classes.clear();\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\t// Remove style attribute.\n\t\tif ( key == 'style' ) {\n\t\t\tif ( this._styles.size > 0 ) {\n\t\t\t\tthis._styles.clear();\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\t// Remove other attributes.\n\t\treturn this._attrs.delete( key );\n\t}\n\n\t/**\n\t * Adds specified class.\n\t *\n\t *\t\telement._addClass( 'foo' ); // Adds 'foo' class.\n\t *\t\telement._addClass( [ 'foo', 'bar' ] ); // Adds 'foo' and 'bar' classes.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#addClass\n\t * @protected\n\t * @param {Array.<String>|String} className\n\t * @fires module:engine/view/node~Node#change\n\t */\n\t_addClass( className ) {\n\t\tthis._fireChange( 'attributes', this );\n\n\t\tclassName = Array.isArray( className ) ? className : [ className ];\n\t\tclassName.forEach( name => this._classes.add( name ) );\n\t}\n\n\t/**\n\t * Removes specified class.\n\t *\n\t *\t\telement._removeClass( 'foo' ); // Removes 'foo' class.\n\t *\t\telement._removeClass( [ 'foo', 'bar' ] ); // Removes both 'foo' and 'bar' classes.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#removeClass\n\t * @protected\n\t * @param {Array.<String>|String} className\n\t * @fires module:engine/view/node~Node#change\n\t */\n\t_removeClass( className ) {\n\t\tthis._fireChange( 'attributes', this );\n\n\t\tclassName = Array.isArray( className ) ? className : [ className ];\n\t\tclassName.forEach( name => this._classes.delete( name ) );\n\t}\n\n\t/**\n\t * Adds style to the element.\n\t *\n\t *\t\telement._setStyle( 'color', 'red' );\n\t *\t\telement._setStyle( {\n\t *\t\t\tcolor: 'red',\n\t *\t\t\tposition: 'fixed'\n\t *\t\t} );\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#setStyle\n\t * @protected\n\t * @param {String|Object} property Property name or object with key - value pairs.\n\t * @param {String} [value] Value to set. This parameter is ignored if object is provided as the first parameter.\n\t * @fires module:engine/view/node~Node#change\n\t */\n\t_setStyle( property, value ) {\n\t\tthis._fireChange( 'attributes', this );\n\n\t\tif ( isPlainObject( property ) ) {\n\t\t\tconst keys = Object.keys( property );\n\n\t\t\tfor ( const key of keys ) {\n\t\t\t\tthis._styles.set( key, property[ key ] );\n\t\t\t}\n\t\t} else {\n\t\t\tthis._styles.set( property, value );\n\t\t}\n\t}\n\n\t/**\n\t * Removes specified style.\n\t *\n\t *\t\telement._removeStyle( 'color' ); // Removes 'color' style.\n\t *\t\telement._removeStyle( [ 'color', 'border-top' ] ); // Removes both 'color' and 'border-top' styles.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#removeStyle\n\t * @protected\n\t * @param {Array.<String>|String} property\n\t * @fires module:engine/view/node~Node#change\n\t */\n\t_removeStyle( property ) {\n\t\tthis._fireChange( 'attributes', this );\n\n\t\tproperty = Array.isArray( property ) ? property : [ property ];\n\t\tproperty.forEach( name => this._styles.delete( name ) );\n\t}\n\n\t/**\n\t * Sets a custom property. Unlike attributes, custom properties are not rendered to the DOM,\n\t * so they can be used to add special data to elements.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#setCustomProperty\n\t * @protected\n\t * @param {String|Symbol} key\n\t * @param {*} value\n\t */\n\t_setCustomProperty( key, value ) {\n\t\tthis._customProperties.set( key, value );\n\t}\n\n\t/**\n\t * Removes the custom property stored under the given key.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#removeCustomProperty\n\t * @protected\n\t * @param {String|Symbol} key\n\t * @returns {Boolean} Returns true if property was removed.\n\t */\n\t_removeCustomProperty( key ) {\n\t\treturn this._customProperties.delete( key );\n\t}\n\n\t/**\n\t * Returns block {@link module:engine/view/filler filler} offset or `null` if block filler is not needed.\n\t *\n\t * @abstract\n\t * @method module:engine/view/element~Element#getFillerOffset\n\t */\n}\n\n// Parses attributes provided to the element constructor before they are applied to an element. If attributes are passed\n// as an object (instead of `Map`), the object is transformed to the map. Attributes with `null` value are removed.\n// Attributes with non-`String` value are converted to `String`.\n//\n// @param {Object|Map} attrs Attributes to parse.\n// @returns {Map} Parsed attributes.\nfunction parseAttributes( attrs ) {\n\tif ( isPlainObject( attrs ) ) {\n\t\tattrs = objectToMap( attrs );\n\t} else {\n\t\tattrs = new Map( attrs );\n\t}\n\n\tfor ( const [ key, value ] of attrs ) {\n\t\tif ( value === null ) {\n\t\t\tattrs.delete( key );\n\t\t} else if ( typeof value != 'string' ) {\n\t\t\tattrs.set( key, String( value ) );\n\t\t}\n\t}\n\n\treturn attrs;\n}\n\n// Parses inline styles and puts property - value pairs into styles map.\n// Styles map is cleared before insertion.\n//\n// @param {Map.<String, String>} stylesMap Map to insert parsed properties and values.\n// @param {String} stylesString Styles to parse.\nfunction parseInlineStyles( stylesMap, stylesString ) {\n\t// `null` if no quote was found in input string or last found quote was a closing quote. See below.\n\tlet quoteType = null;\n\tlet propertyNameStart = 0;\n\tlet propertyValueStart = 0;\n\tlet propertyName = null;\n\n\tstylesMap.clear();\n\n\t// Do not set anything if input string is empty.\n\tif ( stylesString === '' ) {\n\t\treturn;\n\t}\n\n\t// Fix inline styles that do not end with `;` so they are compatible with algorithm below.\n\tif ( stylesString.charAt( stylesString.length - 1 ) != ';' ) {\n\t\tstylesString = stylesString + ';';\n\t}\n\n\t// Seek the whole string for \"special characters\".\n\tfor ( let i = 0; i < stylesString.length; i++ ) {\n\t\tconst char = stylesString.charAt( i );\n\n\t\tif ( quoteType === null ) {\n\t\t\t// No quote found yet or last found quote was a closing quote.\n\t\t\tswitch ( char ) {\n\t\t\t\tcase ':':\n\t\t\t\t\t// Most of time colon means that property name just ended.\n\t\t\t\t\t// Sometimes however `:` is found inside property value (for example in background image url).\n\t\t\t\t\tif ( !propertyName ) {\n\t\t\t\t\t\t// Treat this as end of property only if property name is not already saved.\n\t\t\t\t\t\t// Save property name.\n\t\t\t\t\t\tpropertyName = stylesString.substr( propertyNameStart, i - propertyNameStart );\n\t\t\t\t\t\t// Save this point as the start of property value.\n\t\t\t\t\t\tpropertyValueStart = i + 1;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase '\"':\n\t\t\t\tcase '\\'':\n\t\t\t\t\t// Opening quote found (this is an opening quote, because `quoteType` is `null`).\n\t\t\t\t\tquoteType = char;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase ';': {\n\t\t\t\t\t// Property value just ended.\n\t\t\t\t\t// Use previously stored property value start to obtain property value.\n\t\t\t\t\tconst propertyValue = stylesString.substr( propertyValueStart, i - propertyValueStart );\n\n\t\t\t\t\tif ( propertyName ) {\n\t\t\t\t\t\t// Save parsed part.\n\t\t\t\t\t\tstylesMap.set( propertyName.trim(), propertyValue.trim() );\n\t\t\t\t\t}\n\n\t\t\t\t\tpropertyName = null;\n\n\t\t\t\t\t// Save this point as property name start. Property name starts immediately after previous property value ends.\n\t\t\t\t\tpropertyNameStart = i + 1;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if ( char === quoteType ) {\n\t\t\t// If a quote char is found and it is a closing quote, mark this fact by `null`-ing `quoteType`.\n\t\t\tquoteType = null;\n\t\t}\n\t}\n}\n\n// Parses class attribute and puts all classes into classes set.\n// Classes set s cleared before insertion.\n//\n// @param {Set.<String>} classesSet Set to insert parsed classes.\n// @param {String} classesString String with classes to parse.\nfunction parseClasses( classesSet, classesString ) {\n\tconst classArray = classesString.split( /\\s+/ );\n\tclassesSet.clear();\n\tclassArray.forEach( name => classesSet.add( name ) );\n}\n\n// Converts strings to Text and non-iterables to arrays.\n//\n// @param {String|module:engine/view/item~Item|Iterable.<String|module:engine/view/item~Item>}\n// @returns {Iterable.<module:engine/view/node~Node>}\nfunction normalize( nodes ) {\n\t// Separate condition because string is iterable.\n\tif ( typeof nodes == 'string' ) {\n\t\treturn [ new Text( nodes ) ];\n\t}\n\n\tif ( !isIterable( nodes ) ) {\n\t\tnodes = [ nodes ];\n\t}\n\n\t// Array.from to enable .map() on non-arrays.\n\treturn Array.from( nodes )\n\t\t.map( node => {\n\t\t\tif ( typeof node == 'string' ) {\n\t\t\t\treturn new Text( node );\n\t\t\t}\n\n\t\t\tif ( node instanceof TextProxy ) {\n\t\t\t\treturn new Text( node.data );\n\t\t\t}\n\n\t\t\treturn node;\n\t\t} );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/containerelement\n */\n\nimport Element from './element';\n\n/**\n * Containers are elements which define document structure. They define boundaries for\n * {@link module:engine/view/attributeelement~AttributeElement attributes}. They are mostly used for block elements like `<p>` or `<div>`.\n *\n * Editing engine does not define a fixed HTML DTD. This is why a feature developer needs to choose between various\n * types (container element, {@link module:engine/view/attributeelement~AttributeElement attribute element},\n * {@link module:engine/view/emptyelement~EmptyElement empty element}, etc) when developing a feature.\n *\n * The container element should be your default choice when writing a converter, unless:\n *\n * * this element represents a model text attribute (then use {@link module:engine/view/attributeelement~AttributeElement}),\n * * this is an empty element like `<img>` (then use {@link module:engine/view/emptyelement~EmptyElement}),\n * * this is a root element,\n * * this is a nested editable element (then use {@link module:engine/view/editableelement~EditableElement}).\n *\n * To create a new container element instance use the\n * {@link module:engine/view/downcastwriter~DowncastWriter#createContainerElement `DowncastWriter#createContainerElement()`}\n * method.\n *\n * @extends module:engine/view/element~Element\n */\nexport default class ContainerElement extends Element {\n\t/**\n\t * Creates a container element.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createContainerElement\n\t * @see module:engine/view/element~Element\n\t * @protected\n\t */\n\tconstructor( name, attrs, children ) {\n\t\tsuper( name, attrs, children );\n\n\t\t/**\n\t\t * Returns block {@link module:engine/view/filler filler} offset or `null` if block filler is not needed.\n\t\t *\n\t\t * @method #getFillerOffset\n\t\t * @returns {Number|null} Block filler offset or `null` if block filler is not needed.\n\t\t */\n\t\tthis.getFillerOffset = getFillerOffset;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tis( type, name = null ) {\n\t\tif ( !name ) {\n\t\t\treturn type == 'containerElement' || super.is( type );\n\t\t} else {\n\t\t\treturn ( type == 'containerElement' && name == this.name ) || super.is( type, name );\n\t\t}\n\t}\n}\n\n/**\n * Returns block {@link module:engine/view/filler filler} offset or `null` if block filler is not needed.\n *\n * @returns {Number|null} Block filler offset or `null` if block filler is not needed.\n */\nexport function getFillerOffset() {\n\tconst children = [ ...this.getChildren() ];\n\tconst lastChild = children[ this.childCount - 1 ];\n\n\t// Block filler is required after a `<br>` if it's the last element in its container. See #1422.\n\tif ( lastChild && lastChild.is( 'element', 'br' ) ) {\n\t\treturn this.childCount;\n\t}\n\n\tfor ( const child of children ) {\n\t\t// If there's any non-UI element – don't render the bogus.\n\t\tif ( !child.is( 'uiElement' ) ) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t// If there are only UI elements – render the bogus at the end of the element.\n\treturn this.childCount;\n}\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nexport default identity;\n","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nexport default apply;\n","import apply from './_apply.js';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * A specialized version of `baseRest` which transforms the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @param {Function} transform The rest array transform.\n * @returns {Function} Returns the new function.\n */\nfunction overRest(func, start, transform) {\n start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n index = -1;\n var otherArgs = Array(start + 1);\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = transform(array);\n return apply(func, this, otherArgs);\n };\n}\n\nexport default overRest;\n","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nexport default constant;\n","import constant from './constant.js';\nimport defineProperty from './_defineProperty.js';\nimport identity from './identity.js';\n\n/**\n * The base implementation of `setToString` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar baseSetToString = !defineProperty ? identity : function(func, string) {\n return defineProperty(func, 'toString', {\n 'configurable': true,\n 'enumerable': false,\n 'value': constant(string),\n 'writable': true\n });\n};\n\nexport default baseSetToString;\n","/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nexport default shortOut;\n","import baseSetToString from './_baseSetToString.js';\nimport shortOut from './_shortOut.js';\n\n/**\n * Sets the `toString` method of `func` to return `string`.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar setToString = shortOut(baseSetToString);\n\nexport default setToString;\n","import identity from './identity.js';\nimport overRest from './_overRest.js';\nimport setToString from './_setToString.js';\n\n/**\n * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\nfunction baseRest(func, start) {\n return setToString(overRest(func, start, identity), func + '');\n}\n\nexport default baseRest;\n","import eq from './eq.js';\nimport isArrayLike from './isArrayLike.js';\nimport isIndex from './_isIndex.js';\nimport isObject from './isObject.js';\n\n/**\n * Checks if the given arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n * else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n if (!isObject(object)) {\n return false;\n }\n var type = typeof index;\n if (type == 'number'\n ? (isArrayLike(object) && isIndex(index, object.length))\n : (type == 'string' && index in object)\n ) {\n return eq(object[index], value);\n }\n return false;\n}\n\nexport default isIterateeCall;\n","import baseRest from './_baseRest.js';\nimport isIterateeCall from './_isIterateeCall.js';\n\n/**\n * Creates a function like `_.assign`.\n *\n * @private\n * @param {Function} assigner The function to assign values.\n * @returns {Function} Returns the new assigner function.\n */\nfunction createAssigner(assigner) {\n return baseRest(function(object, sources) {\n var index = -1,\n length = sources.length,\n customizer = length > 1 ? sources[length - 1] : undefined,\n guard = length > 2 ? sources[2] : undefined;\n\n customizer = (assigner.length > 3 && typeof customizer == 'function')\n ? (length--, customizer)\n : undefined;\n\n if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n customizer = length < 3 ? undefined : customizer;\n length = 1;\n }\n object = Object(object);\n while (++index < length) {\n var source = sources[index];\n if (source) {\n assigner(object, source, index, customizer);\n }\n }\n return object;\n });\n}\n\nexport default createAssigner;\n","import copyObject from './_copyObject.js';\nimport createAssigner from './_createAssigner.js';\nimport keysIn from './keysIn.js';\n\n/**\n * This method is like `_.assign` except that it iterates over own and\n * inherited source properties.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @alias extend\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.assign\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * function Bar() {\n * this.c = 3;\n * }\n *\n * Foo.prototype.b = 2;\n * Bar.prototype.d = 4;\n *\n * _.assignIn({ 'a': 0 }, new Foo, new Bar);\n * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }\n */\nvar assignIn = createAssigner(function(object, source) {\n copyObject(source, keysIn(source), object);\n});\n\nexport default assignIn;\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/observablemixin\n */\n\nimport EmitterMixin from './emittermixin';\nimport CKEditorError from './ckeditorerror';\nimport { extend, isObject } from 'lodash-es';\n\nconst observablePropertiesSymbol = Symbol( 'observableProperties' );\nconst boundObservablesSymbol = Symbol( 'boundObservables' );\nconst boundPropertiesSymbol = Symbol( 'boundProperties' );\n\n/**\n * Mixin that injects the \"observable properties\" and data binding functionality described in the\n * {@link ~Observable} interface.\n *\n * Read more about the concept of observables in the:\n * * {@glink framework/guides/architecture/core-editor-architecture#event-system-and-observables \"Event system and observables\"}\n * section of the {@glink framework/guides/architecture/core-editor-architecture \"Core editor architecture\"} guide,\n * * {@glink framework/guides/deep-dive/observables \"Observables\" deep dive} guide.\n *\n * @mixin ObservableMixin\n * @mixes module:utils/emittermixin~EmitterMixin\n * @implements module:utils/observablemixin~Observable\n */\nconst ObservableMixin = {\n\t/**\n\t * @inheritDoc\n\t */\n\tset( name, value ) {\n\t\t// If the first parameter is an Object, iterate over its properties.\n\t\tif ( isObject( name ) ) {\n\t\t\tObject.keys( name ).forEach( property => {\n\t\t\t\tthis.set( property, name[ property ] );\n\t\t\t}, this );\n\n\t\t\treturn;\n\t\t}\n\n\t\tinitObservable( this );\n\n\t\tconst properties = this[ observablePropertiesSymbol ];\n\n\t\tif ( ( name in this ) && !properties.has( name ) ) {\n\t\t\t/**\n\t\t\t * Cannot override an existing property.\n\t\t\t *\n\t\t\t * This error is thrown when trying to {@link ~Observable#set set} an property with\n\t\t\t * a name of an already existing property. For example:\n\t\t\t *\n\t\t\t *\t\tlet observable = new Model();\n\t\t\t *\t\tobservable.property = 1;\n\t\t\t *\t\tobservable.set( 'property', 2 );\t\t\t// throws\n\t\t\t *\n\t\t\t *\t\tobservable.set( 'property', 1 );\n\t\t\t *\t\tobservable.set( 'property', 2 );\t\t\t// ok, because this is an existing property.\n\t\t\t *\n\t\t\t * @error observable-set-cannot-override\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'observable-set-cannot-override: Cannot override an existing property.' );\n\t\t}\n\n\t\tObject.defineProperty( this, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget() {\n\t\t\t\treturn properties.get( name );\n\t\t\t},\n\n\t\t\tset( value ) {\n\t\t\t\tconst oldValue = properties.get( name );\n\n\t\t\t\t// Fire `set` event before the new value will be set to make it possible\n\t\t\t\t// to override observable property without affecting `change` event.\n\t\t\t\t// See https://github.com/ckeditor/ckeditor5-utils/issues/171.\n\t\t\t\tlet newValue = this.fire( 'set:' + name, name, value, oldValue );\n\n\t\t\t\tif ( newValue === undefined ) {\n\t\t\t\t\tnewValue = value;\n\t\t\t\t}\n\n\t\t\t\t// Allow undefined as an initial value like A.define( 'x', undefined ) (#132).\n\t\t\t\t// Note: When properties map has no such own property, then its value is undefined.\n\t\t\t\tif ( oldValue !== newValue || !properties.has( name ) ) {\n\t\t\t\t\tproperties.set( name, newValue );\n\t\t\t\t\tthis.fire( 'change:' + name, name, newValue, oldValue );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\tthis[ name ] = value;\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tbind( ...bindProperties ) {\n\t\tif ( !bindProperties.length || !isStringArray( bindProperties ) ) {\n\t\t\t/**\n\t\t\t * All properties must be strings.\n\t\t\t *\n\t\t\t * @error observable-bind-wrong-properties\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'observable-bind-wrong-properties: All properties must be strings.' );\n\t\t}\n\n\t\tif ( ( new Set( bindProperties ) ).size !== bindProperties.length ) {\n\t\t\t/**\n\t\t\t * Properties must be unique.\n\t\t\t *\n\t\t\t * @error observable-bind-duplicate-properties\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'observable-bind-duplicate-properties: Properties must be unique.' );\n\t\t}\n\n\t\tinitObservable( this );\n\n\t\tconst boundProperties = this[ boundPropertiesSymbol ];\n\n\t\tbindProperties.forEach( propertyName => {\n\t\t\tif ( boundProperties.has( propertyName ) ) {\n\t\t\t\t/**\n\t\t\t\t * Cannot bind the same property more that once.\n\t\t\t\t *\n\t\t\t\t * @error observable-bind-rebind\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'observable-bind-rebind: Cannot bind the same property more that once.' );\n\t\t\t}\n\t\t} );\n\n\t\tconst bindings = new Map();\n\n\t\t// @typedef {Object} Binding\n\t\t// @property {Array} property Property which is bound.\n\t\t// @property {Array} to Array of observable–property components of the binding (`{ observable: ..., property: .. }`).\n\t\t// @property {Array} callback A function which processes `to` components.\n\t\tbindProperties.forEach( a => {\n\t\t\tconst binding = { property: a, to: [] };\n\n\t\t\tboundProperties.set( a, binding );\n\t\t\tbindings.set( a, binding );\n\t\t} );\n\n\t\t// @typedef {Object} BindChain\n\t\t// @property {Function} to See {@link ~ObservableMixin#_bindTo}.\n\t\t// @property {Function} toMany See {@link ~ObservableMixin#_bindToMany}.\n\t\t// @property {module:utils/observablemixin~Observable} _observable The observable which initializes the binding.\n\t\t// @property {Array} _bindProperties Array of `_observable` properties to be bound.\n\t\t// @property {Array} _to Array of `to()` observable–properties (`{ observable: toObservable, properties: ...toProperties }`).\n\t\t// @property {Map} _bindings Stores bindings to be kept in\n\t\t// {@link ~ObservableMixin#_boundProperties}/{@link ~ObservableMixin#_boundObservables}\n\t\t// initiated in this binding chain.\n\t\treturn {\n\t\t\tto: bindTo,\n\t\t\ttoMany: bindToMany,\n\n\t\t\t_observable: this,\n\t\t\t_bindProperties: bindProperties,\n\t\t\t_to: [],\n\t\t\t_bindings: bindings\n\t\t};\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tunbind( ...unbindProperties ) {\n\t\t// Nothing to do here if not inited yet.\n\t\tif ( !( observablePropertiesSymbol in this ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst boundProperties = this[ boundPropertiesSymbol ];\n\t\tconst boundObservables = this[ boundObservablesSymbol ];\n\n\t\tif ( unbindProperties.length ) {\n\t\t\tif ( !isStringArray( unbindProperties ) ) {\n\t\t\t\t/**\n\t\t\t\t * Properties must be strings.\n\t\t\t\t *\n\t\t\t\t * @error observable-unbind-wrong-properties\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'observable-unbind-wrong-properties: Properties must be strings.' );\n\t\t\t}\n\n\t\t\tunbindProperties.forEach( propertyName => {\n\t\t\t\tconst binding = boundProperties.get( propertyName );\n\n\t\t\t\t// Nothing to do if the binding is not defined\n\t\t\t\tif ( !binding ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlet toObservable, toProperty, toProperties, toPropertyBindings;\n\n\t\t\t\tbinding.to.forEach( to => {\n\t\t\t\t\t// TODO: ES6 destructuring.\n\t\t\t\t\ttoObservable = to[ 0 ];\n\t\t\t\t\ttoProperty = to[ 1 ];\n\t\t\t\t\ttoProperties = boundObservables.get( toObservable );\n\t\t\t\t\ttoPropertyBindings = toProperties[ toProperty ];\n\n\t\t\t\t\ttoPropertyBindings.delete( binding );\n\n\t\t\t\t\tif ( !toPropertyBindings.size ) {\n\t\t\t\t\t\tdelete toProperties[ toProperty ];\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !Object.keys( toProperties ).length ) {\n\t\t\t\t\t\tboundObservables.delete( toObservable );\n\t\t\t\t\t\tthis.stopListening( toObservable, 'change' );\n\t\t\t\t\t}\n\t\t\t\t} );\n\n\t\t\t\tboundProperties.delete( propertyName );\n\t\t\t} );\n\t\t} else {\n\t\t\tboundObservables.forEach( ( bindings, boundObservable ) => {\n\t\t\t\tthis.stopListening( boundObservable, 'change' );\n\t\t\t} );\n\n\t\t\tboundObservables.clear();\n\t\t\tboundProperties.clear();\n\t\t}\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdecorate( methodName ) {\n\t\tconst originalMethod = this[ methodName ];\n\n\t\tif ( !originalMethod ) {\n\t\t\t/**\n\t\t\t * Cannot decorate an undefined method.\n\t\t\t *\n\t\t\t * @error observablemixin-cannot-decorate-undefined\n\t\t\t * @param {Object} object The object which method should be decorated.\n\t\t\t * @param {String} methodName Name of the method which does not exist.\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'observablemixin-cannot-decorate-undefined: Cannot decorate an undefined method.',\n\t\t\t\t{ object: this, methodName }\n\t\t\t);\n\t\t}\n\n\t\tthis.on( methodName, ( evt, args ) => {\n\t\t\tevt.return = originalMethod.apply( this, args );\n\t\t} );\n\n\t\tthis[ methodName ] = function( ...args ) {\n\t\t\treturn this.fire( methodName, args );\n\t\t};\n\t}\n};\n\nextend( ObservableMixin, EmitterMixin );\n\nexport default ObservableMixin;\n\n// Init symbol properties needed to for the observable mechanism to work.\n//\n// @private\n// @param {module:utils/observablemixin~ObservableMixin} observable\nfunction initObservable( observable ) {\n\t// Do nothing if already inited.\n\tif ( observablePropertiesSymbol in observable ) {\n\t\treturn;\n\t}\n\n\t// The internal hash containing the observable's state.\n\t//\n\t// @private\n\t// @type {Map}\n\tObject.defineProperty( observable, observablePropertiesSymbol, {\n\t\tvalue: new Map()\n\t} );\n\n\t// Map containing bindings to external observables. It shares the binding objects\n\t// (`{ observable: A, property: 'a', to: ... }`) with {@link module:utils/observablemixin~ObservableMixin#_boundProperties} and\n\t// it is used to observe external observables to update own properties accordingly.\n\t// See {@link module:utils/observablemixin~ObservableMixin#bind}.\n\t//\n\t//\t\tA.bind( 'a', 'b', 'c' ).to( B, 'x', 'y', 'x' );\n\t//\t\tconsole.log( A._boundObservables );\n\t//\n\t//\t\t\tMap( {\n\t//\t\t\t\tB: {\n\t//\t\t\t\t\tx: Set( [\n\t//\t\t\t\t\t\t{ observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\t\t\t{ observable: A, property: 'c', to: [ [ B, 'x' ] ] }\n\t//\t\t\t\t\t] ),\n\t//\t\t\t\t\ty: Set( [\n\t//\t\t\t\t\t\t{ observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n\t//\t\t\t\t\t] )\n\t//\t\t\t\t}\n\t//\t\t\t} )\n\t//\n\t//\t\tA.bind( 'd' ).to( B, 'z' ).to( C, 'w' ).as( callback );\n\t//\t\tconsole.log( A._boundObservables );\n\t//\n\t//\t\t\tMap( {\n\t//\t\t\t\tB: {\n\t//\t\t\t\t\tx: Set( [\n\t//\t\t\t\t\t\t{ observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\t\t\t{ observable: A, property: 'c', to: [ [ B, 'x' ] ] }\n\t//\t\t\t\t\t] ),\n\t//\t\t\t\t\ty: Set( [\n\t//\t\t\t\t\t\t{ observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n\t//\t\t\t\t\t] ),\n\t//\t\t\t\t\tz: Set( [\n\t//\t\t\t\t\t\t{ observable: A, property: 'd', to: [ [ B, 'z' ], [ C, 'w' ] ], callback: callback }\n\t//\t\t\t\t\t] )\n\t//\t\t\t\t},\n\t//\t\t\t\tC: {\n\t//\t\t\t\t\tw: Set( [\n\t//\t\t\t\t\t\t{ observable: A, property: 'd', to: [ [ B, 'z' ], [ C, 'w' ] ], callback: callback }\n\t//\t\t\t\t\t] )\n\t//\t\t\t\t}\n\t//\t\t\t} )\n\t//\n\t// @private\n\t// @type {Map}\n\tObject.defineProperty( observable, boundObservablesSymbol, {\n\t\tvalue: new Map()\n\t} );\n\n\t// Object that stores which properties of this observable are bound and how. It shares\n\t// the binding objects (`{ observable: A, property: 'a', to: ... }`) with {@link utils.ObservableMixin#_boundObservables}.\n\t// This data structure is a reverse of {@link utils.ObservableMixin#_boundObservables} and it is helpful for\n\t// {@link utils.ObservableMixin#unbind}.\n\t//\n\t// See {@link utils.ObservableMixin#bind}.\n\t//\n\t//\t\tA.bind( 'a', 'b', 'c' ).to( B, 'x', 'y', 'x' );\n\t//\t\tconsole.log( A._boundProperties );\n\t//\n\t//\t\t\tMap( {\n\t//\t\t\t\ta: { observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\tb: { observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n\t//\t\t\t\tc: { observable: A, property: 'c', to: [ [ B, 'x' ] ] }\n\t//\t\t\t} )\n\t//\n\t//\t\tA.bind( 'd' ).to( B, 'z' ).to( C, 'w' ).as( callback );\n\t//\t\tconsole.log( A._boundProperties );\n\t//\n\t//\t\t\tMap( {\n\t//\t\t\t\ta: { observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\tb: { observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n\t//\t\t\t\tc: { observable: A, property: 'c', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\td: { observable: A, property: 'd', to: [ [ B, 'z' ], [ C, 'w' ] ], callback: callback }\n\t//\t\t\t} )\n\t//\n\t// @private\n\t// @type {Map}\n\tObject.defineProperty( observable, boundPropertiesSymbol, {\n\t\tvalue: new Map()\n\t} );\n}\n\n// A chaining for {@link module:utils/observablemixin~ObservableMixin#bind} providing `.to()` interface.\n//\n// @private\n// @param {...[Observable|String|Function]} args Arguments of the `.to( args )` binding.\nfunction bindTo( ...args ) {\n\tconst parsedArgs = parseBindToArgs( ...args );\n\tconst bindingsKeys = Array.from( this._bindings.keys() );\n\tconst numberOfBindings = bindingsKeys.length;\n\n\t// Eliminate A.bind( 'x' ).to( B, C )\n\tif ( !parsedArgs.callback && parsedArgs.to.length > 1 ) {\n\t\t/**\n\t\t * Binding multiple observables only possible with callback.\n\t\t *\n\t\t * @error observable-bind-no-callback\n\t\t */\n\t\tthrow new CKEditorError( 'observable-bind-to-no-callback: Binding multiple observables only possible with callback.' );\n\t}\n\n\t// Eliminate A.bind( 'x', 'y' ).to( B, callback )\n\tif ( numberOfBindings > 1 && parsedArgs.callback ) {\n\t\t/**\n\t\t * Cannot bind multiple properties and use a callback in one binding.\n\t\t *\n\t\t * @error observable-bind-to-extra-callback\n\t\t */\n\t\tthrow new CKEditorError( 'observable-bind-to-extra-callback: Cannot bind multiple properties and use a callback in one binding.' );\n\t}\n\n\tparsedArgs.to.forEach( to => {\n\t\t// Eliminate A.bind( 'x', 'y' ).to( B, 'a' )\n\t\tif ( to.properties.length && to.properties.length !== numberOfBindings ) {\n\t\t\t/**\n\t\t\t * The number of properties must match.\n\t\t\t *\n\t\t\t * @error observable-bind-to-properties-length\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'observable-bind-to-properties-length: The number of properties must match.' );\n\t\t}\n\n\t\t// When no to.properties specified, observing source properties instead i.e.\n\t\t// A.bind( 'x', 'y' ).to( B ) -> Observe B.x and B.y\n\t\tif ( !to.properties.length ) {\n\t\t\tto.properties = this._bindProperties;\n\t\t}\n\t} );\n\n\tthis._to = parsedArgs.to;\n\n\t// Fill {@link BindChain#_bindings} with callback. When the callback is set there's only one binding.\n\tif ( parsedArgs.callback ) {\n\t\tthis._bindings.get( bindingsKeys[ 0 ] ).callback = parsedArgs.callback;\n\t}\n\n\tattachBindToListeners( this._observable, this._to );\n\n\t// Update observable._boundProperties and observable._boundObservables.\n\tupdateBindToBound( this );\n\n\t// Set initial values of bound properties.\n\tthis._bindProperties.forEach( propertyName => {\n\t\tupdateBoundObservableProperty( this._observable, propertyName );\n\t} );\n}\n\n// Binds to an attribute in a set of iterable observables.\n//\n// @private\n// @param {Array.<Observable>} observables\n// @param {String} attribute\n// @param {Function} callback\nfunction bindToMany( observables, attribute, callback ) {\n\tif ( this._bindings.size > 1 ) {\n\t\t/**\n\t\t * Binding one attribute to many observables only possible with one attribute.\n\t\t *\n\t\t * @error observable-bind-to-many-not-one-binding\n\t\t */\n\t\tthrow new CKEditorError( 'observable-bind-to-many-not-one-binding: Cannot bind multiple properties with toMany().' );\n\t}\n\n\tthis.to(\n\t\t// Bind to #attribute of each observable...\n\t\t...getBindingTargets( observables, attribute ),\n\t\t// ...using given callback to parse attribute values.\n\t\tcallback\n\t);\n}\n\n// Returns an array of binding components for\n// {@link Observable#bind} from a set of iterable observables.\n//\n// @param {Array.<Observable>} observables\n// @param {String} attribute\n// @returns {Array.<String|Observable>}\nfunction getBindingTargets( observables, attribute ) {\n\tconst observableAndAttributePairs = observables.map( observable => [ observable, attribute ] );\n\n\t// Merge pairs to one-dimension array of observables and attributes.\n\treturn Array.prototype.concat.apply( [], observableAndAttributePairs );\n}\n\n// Check if all entries of the array are of `String` type.\n//\n// @private\n// @param {Array} arr An array to be checked.\n// @returns {Boolean}\nfunction isStringArray( arr ) {\n\treturn arr.every( a => typeof a == 'string' );\n}\n\n// Parses and validates {@link Observable#bind}`.to( args )` arguments and returns\n// an object with a parsed structure. For example\n//\n//\t\tA.bind( 'x' ).to( B, 'a', C, 'b', call );\n//\n// becomes\n//\n//\t\t{\n//\t\t\tto: [\n//\t\t\t\t{ observable: B, properties: [ 'a' ] },\n//\t\t\t\t{ observable: C, properties: [ 'b' ] },\n//\t\t\t],\n//\t\t\tcallback: call\n// \t\t}\n//\n// @private\n// @param {...*} args Arguments of {@link Observable#bind}`.to( args )`.\n// @returns {Object}\nfunction parseBindToArgs( ...args ) {\n\t// Eliminate A.bind( 'x' ).to()\n\tif ( !args.length ) {\n\t\t/**\n\t\t * Invalid argument syntax in `to()`.\n\t\t *\n\t\t * @error observable-bind-to-parse-error\n\t\t */\n\t\tthrow new CKEditorError( 'observable-bind-to-parse-error: Invalid argument syntax in `to()`.' );\n\t}\n\n\tconst parsed = { to: [] };\n\tlet lastObservable;\n\n\tif ( typeof args[ args.length - 1 ] == 'function' ) {\n\t\tparsed.callback = args.pop();\n\t}\n\n\targs.forEach( a => {\n\t\tif ( typeof a == 'string' ) {\n\t\t\tlastObservable.properties.push( a );\n\t\t} else if ( typeof a == 'object' ) {\n\t\t\tlastObservable = { observable: a, properties: [] };\n\t\t\tparsed.to.push( lastObservable );\n\t\t} else {\n\t\t\tthrow new CKEditorError( 'observable-bind-to-parse-error: Invalid argument syntax in `to()`.' );\n\t\t}\n\t} );\n\n\treturn parsed;\n}\n\n// Synchronizes {@link module:utils/observablemixin#_boundObservables} with {@link Binding}.\n//\n// @private\n// @param {Binding} binding A binding to store in {@link Observable#_boundObservables}.\n// @param {Observable} toObservable A observable, which is a new component of `binding`.\n// @param {String} toPropertyName A name of `toObservable`'s property, a new component of the `binding`.\nfunction updateBoundObservables( observable, binding, toObservable, toPropertyName ) {\n\tconst boundObservables = observable[ boundObservablesSymbol ];\n\tconst bindingsToObservable = boundObservables.get( toObservable );\n\tconst bindings = bindingsToObservable || {};\n\n\tif ( !bindings[ toPropertyName ] ) {\n\t\tbindings[ toPropertyName ] = new Set();\n\t}\n\n\t// Pass the binding to a corresponding Set in `observable._boundObservables`.\n\tbindings[ toPropertyName ].add( binding );\n\n\tif ( !bindingsToObservable ) {\n\t\tboundObservables.set( toObservable, bindings );\n\t}\n}\n\n// Synchronizes {@link Observable#_boundProperties} and {@link Observable#_boundObservables}\n// with {@link BindChain}.\n//\n// Assuming the following binding being created\n//\n// \t\tA.bind( 'a', 'b' ).to( B, 'x', 'y' );\n//\n// the following bindings were initialized by {@link Observable#bind} in {@link BindChain#_bindings}:\n//\n// \t\t{\n// \t\t\ta: { observable: A, property: 'a', to: [] },\n// \t\t\tb: { observable: A, property: 'b', to: [] },\n// \t\t}\n//\n// Iterate over all bindings in this chain and fill their `to` properties with\n// corresponding to( ... ) arguments (components of the binding), so\n//\n// \t\t{\n// \t\t\ta: { observable: A, property: 'a', to: [ B, 'x' ] },\n// \t\t\tb: { observable: A, property: 'b', to: [ B, 'y' ] },\n// \t\t}\n//\n// Then update the structure of {@link Observable#_boundObservables} with updated\n// binding, so it becomes:\n//\n// \t\tMap( {\n// \t\t\tB: {\n// \t\t\t\tx: Set( [\n// \t\t\t\t\t{ observable: A, property: 'a', to: [ [ B, 'x' ] ] }\n// \t\t\t\t] ),\n// \t\t\t\ty: Set( [\n// \t\t\t\t\t{ observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n// \t\t\t\t] )\n//\t\t\t}\n// \t\t} )\n//\n// @private\n// @param {BindChain} chain The binding initialized by {@link Observable#bind}.\nfunction updateBindToBound( chain ) {\n\tlet toProperty;\n\n\tchain._bindings.forEach( ( binding, propertyName ) => {\n\t\t// Note: For a binding without a callback, this will run only once\n\t\t// like in A.bind( 'x', 'y' ).to( B, 'a', 'b' )\n\t\t// TODO: ES6 destructuring.\n\t\tchain._to.forEach( to => {\n\t\t\ttoProperty = to.properties[ binding.callback ? 0 : chain._bindProperties.indexOf( propertyName ) ];\n\n\t\t\tbinding.to.push( [ to.observable, toProperty ] );\n\t\t\tupdateBoundObservables( chain._observable, binding, to.observable, toProperty );\n\t\t} );\n\t} );\n}\n\n// Updates an property of a {@link Observable} with a value\n// determined by an entry in {@link Observable#_boundProperties}.\n//\n// @private\n// @param {Observable} observable A observable which property is to be updated.\n// @param {String} propertyName An property to be updated.\nfunction updateBoundObservableProperty( observable, propertyName ) {\n\tconst boundProperties = observable[ boundPropertiesSymbol ];\n\tconst binding = boundProperties.get( propertyName );\n\tlet propertyValue;\n\n\t// When a binding with callback is created like\n\t//\n\t// \t\tA.bind( 'a' ).to( B, 'b', C, 'c', callback );\n\t//\n\t// collect B.b and C.c, then pass them to callback to set A.a.\n\tif ( binding.callback ) {\n\t\tpropertyValue = binding.callback.apply( observable, binding.to.map( to => to[ 0 ][ to[ 1 ] ] ) );\n\t} else {\n\t\tpropertyValue = binding.to[ 0 ];\n\t\tpropertyValue = propertyValue[ 0 ][ propertyValue[ 1 ] ];\n\t}\n\n\tif ( observable.hasOwnProperty( propertyName ) ) {\n\t\tobservable[ propertyName ] = propertyValue;\n\t} else {\n\t\tobservable.set( propertyName, propertyValue );\n\t}\n}\n\n// Starts listening to changes in {@link BindChain._to} observables to update\n// {@link BindChain._observable} {@link BindChain._bindProperties}. Also sets the\n// initial state of {@link BindChain._observable}.\n//\n// @private\n// @param {BindChain} chain The chain initialized by {@link Observable#bind}.\nfunction attachBindToListeners( observable, toBindings ) {\n\ttoBindings.forEach( to => {\n\t\tconst boundObservables = observable[ boundObservablesSymbol ];\n\t\tlet bindings;\n\n\t\t// If there's already a chain between the observables (`observable` listens to\n\t\t// `to.observable`), there's no need to create another `change` event listener.\n\t\tif ( !boundObservables.get( to.observable ) ) {\n\t\t\tobservable.listenTo( to.observable, 'change', ( evt, propertyName ) => {\n\t\t\t\tbindings = boundObservables.get( to.observable )[ propertyName ];\n\n\t\t\t\t// Note: to.observable will fire for any property change, react\n\t\t\t\t// to changes of properties which are bound only.\n\t\t\t\tif ( bindings ) {\n\t\t\t\t\tbindings.forEach( binding => {\n\t\t\t\t\t\tupdateBoundObservableProperty( observable, binding.property );\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t} );\n}\n\n/**\n * Interface which adds \"observable properties\" and data binding functionality.\n *\n * Can be easily implemented by a class by mixing the {@link module:utils/observablemixin~ObservableMixin} mixin.\n *\n * Read more about the usage of this interface in the:\n * * {@glink framework/guides/architecture/core-editor-architecture#event-system-and-observables \"Event system and observables\"}\n * section of the {@glink framework/guides/architecture/core-editor-architecture \"Core editor architecture\"} guide,\n * * {@glink framework/guides/deep-dive/observables \"Observables\" deep dive} guide.\n *\n * @interface Observable\n * @extends module:utils/emittermixin~Emitter\n */\n\n/**\n * Fired when a property changed value.\n *\n *\t\tobservable.set( 'prop', 1 );\n *\n *\t\tobservable.on( 'change:prop', ( evt, propertyName, newValue, oldValue ) => {\n *\t\t\tconsole.log( `${ propertyName } has changed from ${ oldValue } to ${ newValue }` );\n *\t\t} );\n *\n *\t\tobservable.prop = 2; // -> 'prop has changed from 1 to 2'\n *\n * @event change:{property}\n * @param {String} name The property name.\n * @param {*} value The new property value.\n * @param {*} oldValue The previous property value.\n */\n\n/**\n * Fired when a property value is going to be set but is not set yet (before the `change` event is fired).\n *\n * You can control the final value of the property by using\n * the {@link module:utils/eventinfo~EventInfo#return event's `return` property}.\n *\n *\t\tobservable.set( 'prop', 1 );\n *\n *\t\tobservable.on( 'set:prop', ( evt, propertyName, newValue, oldValue ) => {\n *\t\t\tconsole.log( `Value is going to be changed from ${ oldValue } to ${ newValue }` );\n *\t\t\tconsole.log( `Current property value is ${ observable[ propertyName ] }` );\n *\n *\t\t\t// Let's override the value.\n *\t\t\tevt.return = 3;\n *\t\t} );\n *\n *\t\tobservable.on( 'change:prop', ( evt, propertyName, newValue, oldValue ) => {\n *\t\t\tconsole.log( `Value has changed from ${ oldValue } to ${ newValue }` );\n *\t\t} );\n *\n *\t\tobservable.prop = 2; // -> 'Value is going to be changed from 1 to 2'\n *\t\t // -> 'Current property value is 1'\n *\t\t // -> 'Value has changed from 1 to 3'\n *\n * **Note:** Event is fired even when the new value is the same as the old value.\n *\n * @event set:{property}\n * @param {String} name The property name.\n * @param {*} value The new property value.\n * @param {*} oldValue The previous property value.\n */\n\n/**\n * Creates and sets the value of an observable property of this object. Such an property becomes a part\n * of the state and is be observable.\n *\n * It accepts also a single object literal containing key/value pairs with properties to be set.\n *\n * This method throws the `observable-set-cannot-override` error if the observable instance already\n * have a property with the given property name. This prevents from mistakenly overriding existing\n * properties and methods, but means that `foo.set( 'bar', 1 )` may be slightly slower than `foo.bar = 1`.\n *\n * @method #set\n * @param {String|Object} name The property's name or object with `name=>value` pairs.\n * @param {*} [value] The property's value (if `name` was passed in the first parameter).\n */\n\n/**\n * Binds {@link #set obvervable properties} to other objects implementing the\n * {@link module:utils/observablemixin~Observable} interface.\n *\n * Read more in the {@glink framework/guides/deep-dive/observables#property-bindings dedicated guide}\n * covering the topic of property bindings with some additional examples.\n *\n * Let's consider two objects: a `button` and an associated `command` (both `Observable`).\n *\n * A simple property binding could be as follows:\n *\n *\t\tbutton.bind( 'isEnabled' ).to( command, 'isEnabled' );\n *\n * or even shorter:\n *\n *\t\tbutton.bind( 'isEnabled' ).to( command );\n *\n * which works in the following way:\n *\n * * `button.isEnabled` **instantly equals** `command.isEnabled`,\n * * whenever `command.isEnabled` changes, `button.isEnabled` will immediately reflect its value.\n *\n * **Note**: To release the binding use {@link module:utils/observablemixin~Observable#unbind}.\n *\n * You can also \"rename\" the property in the binding by specifying the new name in the `to()` chain:\n *\n *\t\tbutton.bind( 'isEnabled' ).to( command, 'isWorking' );\n *\n * It is possible to bind more than one property at a time to shorten the code:\n *\n *\t\tbutton.bind( 'isEnabled', 'value' ).to( command );\n *\n * which corresponds to:\n *\n *\t\tbutton.bind( 'isEnabled' ).to( command );\n *\t\tbutton.bind( 'value' ).to( command );\n *\n * The binding can include more than one observable, combining multiple data sources in a custom callback:\n *\n *\t\tbutton.bind( 'isEnabled' ).to( command, 'isEnabled', ui, 'isVisible',\n *\t\t\t( isCommandEnabled, isUIVisible ) => isCommandEnabled && isUIVisible );\n *\n * It is also possible to bind to the same property in an array of observables.\n * To bind a `button` to multiple commands (also `Observables`) so that each and every one of them\n * must be enabled for the button to become enabled, use the following code:\n *\n *\t\tbutton.bind( 'isEnabled' ).toMany( [ commandA, commandB, commandC ], 'isEnabled',\n *\t\t\t( isAEnabled, isBEnabled, isCEnabled ) => isAEnabled && isBEnabled && isCEnabled );\n *\n * @method #bind\n * @param {...String} bindProperties Observable properties that will be bound to another observable(s).\n * @returns {Object} The bind chain with the `to()` and `toMany()` methods.\n */\n\n/**\n * Removes the binding created with {@link #bind}.\n *\n *\t\t// Removes the binding for the 'a' property.\n *\t\tA.unbind( 'a' );\n *\n *\t\t// Removes bindings for all properties.\n *\t\tA.unbind();\n *\n * @method #unbind\n * @param {...String} [unbindProperties] Observable properties to be unbound. All the bindings will\n * be released if no properties provided.\n */\n\n/**\n * Turns the given methods of this object into event-based ones. This means that the new method will fire an event\n * (named after the method) and the original action will be plugged as a listener to that event.\n *\n * Read more in the {@glink framework/guides/deep-dive/observables#decorating-object-methods dedicated guide}\n * covering the topic of decorating methods with some additional examples.\n *\n * Decorating the method does not change its behavior (it only adds an event),\n * but it allows to modify it later on by listening to the method's event.\n *\n * For example, to cancel the method execution the event can be {@link module:utils/eventinfo~EventInfo#stop stopped}:\n *\n *\t\tclass Foo {\n *\t\t\tconstructor() {\n *\t\t\t\tthis.decorate( 'method' );\n *\t\t\t}\n *\n *\t\t\tmethod() {\n *\t\t\t\tconsole.log( 'called!' );\n *\t\t\t}\n *\t\t}\n *\n *\t\tconst foo = new Foo();\n *\t\tfoo.on( 'method', ( evt ) => {\n *\t\t\tevt.stop();\n *\t\t}, { priority: 'high' } );\n *\n *\t\tfoo.method(); // Nothing is logged.\n *\n *\n * **Note**: The high {@link module:utils/priorities~PriorityString priority} listener\n * has been used to execute this particular callback before the one which calls the original method\n * (which uses the \"normal\" priority).\n *\n * It is also possible to change the returned value:\n *\n *\t\tfoo.on( 'method', ( evt ) => {\n *\t\t\tevt.return = 'Foo!';\n *\t\t} );\n *\n *\t\tfoo.method(); // -> 'Foo'\n *\n * Finally, it is possible to access and modify the arguments the method is called with:\n *\n *\t\tmethod( a, b ) {\n *\t\t\tconsole.log( `${ a }, ${ b }` );\n *\t\t}\n *\n *\t\t// ...\n *\n *\t\tfoo.on( 'method', ( evt, args ) => {\n *\t\t\targs[ 0 ] = 3;\n *\n *\t\t\tconsole.log( args[ 1 ] ); // -> 2\n *\t\t}, { priority: 'high' } );\n *\n *\t\tfoo.method( 1, 2 ); // -> '3, 2'\n *\n * @method #decorate\n * @param {String} methodName Name of the method to decorate.\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/editableelement\n */\n\nimport ContainerElement from './containerelement';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\n\nconst documentSymbol = Symbol( 'document' );\n\n/**\n * Editable element which can be a {@link module:engine/view/rooteditableelement~RootEditableElement root}\n * or nested editable area in the editor.\n *\n * Editable is automatically read-only when its {@link module:engine/view/document~Document Document} is read-only.\n *\n * The constructor of this class shouldn't be used directly. To create new `EditableElement` use the\n * {@link module:engine/view/downcastwriter~DowncastWriter#createEditableElement `downcastWriter#createEditableElement()`} method.\n *\n * @extends module:engine/view/containerelement~ContainerElement\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class EditableElement extends ContainerElement {\n\t/**\n\t * Creates an editable element.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createEditableElement\n\t * @protected\n\t */\n\tconstructor( name, attrs, children ) {\n\t\tsuper( name, attrs, children );\n\n\t\t/**\n\t\t * Whether the editable is in read-write or read-only mode.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} module:engine/view/editableelement~EditableElement#isReadOnly\n\t\t */\n\t\tthis.set( 'isReadOnly', false );\n\n\t\t/**\n\t\t * Whether the editable is focused.\n\t\t *\n\t\t * This property updates when {@link module:engine/view/document~Document#isFocused document.isFocused} or view\n\t\t * selection is changed.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Boolean} module:engine/view/editableelement~EditableElement#isFocused\n\t\t */\n\t\tthis.set( 'isFocused', false );\n\n\t\t/**\n\t\t * The {@link module:engine/view/document~Document} which is an owner of this root.\n\t\t * Can only by set once.\n\t\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-editableelement-document-already-set`\n\t\t * when document is already set.\n\t\t *\n\t\t * @member {module:engine/view/document~Document} #document\n\t\t */\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tis( type, name = null ) {\n\t\tif ( !name ) {\n\t\t\treturn type == 'editableElement' || super.is( type );\n\t\t} else {\n\t\t\treturn ( type == 'editableElement' && name == this.name ) || super.is( type, name );\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Returns document associated with the editable.\n\t *\n\t * @readonly\n\t * @returns {module:engine/view/document~Document}\n\t */\n\tget document() {\n\t\treturn this.getCustomProperty( documentSymbol );\n\t}\n\n\t/**\n\t * Sets document of this editable element.\n\t *\n\t * @protected\n\t * @param {module:engine/view/document~Document} document\n\t */\n\tset _document( document ) {\n\t\tif ( this.getCustomProperty( documentSymbol ) ) {\n\t\t\t/**\n\t\t\t * View document is already set. It can only be set once.\n\t\t\t *\n\t\t\t * @error view-editableelement-document-already-set\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-editableelement-document-already-set: View document is already set.' );\n\t\t}\n\n\t\tthis._setCustomProperty( documentSymbol, document );\n\n\t\tthis.bind( 'isReadOnly' ).to( document );\n\n\t\tthis.bind( 'isFocused' ).to(\n\t\t\tdocument,\n\t\t\t'isFocused',\n\t\t\tisFocused => isFocused && document.selection.editableElement == this\n\t\t);\n\n\t\t// Update focus state based on selection changes.\n\t\tthis.listenTo( document.selection, 'change', () => {\n\t\t\tthis.isFocused = document.isFocused && document.selection.editableElement == this;\n\t\t} );\n\t}\n}\n\nmix( EditableElement, ObservableMixin );\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/rooteditableelement\n */\n\nimport EditableElement from './editableelement';\n\nconst rootNameSymbol = Symbol( 'rootName' );\n\n/**\n * Class representing a single root in the data view. A root can be either {@link ~RootEditableElement#isReadOnly editable or read-only},\n * but in both cases it is called \"an editable\". Roots can contain other {@link module:engine/view/editableelement~EditableElement\n * editable elements} making them \"nested editables\".\n *\n * @extends module:engine/view/editableelement~EditableElement\n */\nexport default class RootEditableElement extends EditableElement {\n\t/**\n\t * Creates root editable element.\n\t *\n\t * @param {String} name Node name.\n\t */\n\tconstructor( name ) {\n\t\tsuper( name );\n\n\t\t/**\n\t\t * Name of this root inside {@link module:engine/view/document~Document} that is an owner of this root. If no\n\t\t * other name is set, `main` name is used.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.rootName = 'main';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tis( type, name = null ) {\n\t\tif ( !name ) {\n\t\t\treturn type == 'rootElement' || super.is( type );\n\t\t} else {\n\t\t\treturn ( type == 'rootElement' && name == this.name ) || super.is( type, name );\n\t\t}\n\t}\n\n\tget rootName() {\n\t\treturn this.getCustomProperty( rootNameSymbol );\n\t}\n\n\tset rootName( rootName ) {\n\t\tthis._setCustomProperty( rootNameSymbol, rootName );\n\t}\n\n\t/**\n\t * Overrides old element name and sets new one.\n\t * This is needed because view roots are created before they are attached to the DOM.\n\t * The name of the root element is temporary at this stage. It has to be changed when the\n\t * view root element is attached to the DOM element.\n\t *\n\t * @protected\n\t * @param {String} name The new name of element.\n\t */\n\tset _name( name ) {\n\t\tthis.name = name;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/treewalker\n */\n\nimport Element from './element';\nimport Text from './text';\nimport TextProxy from './textproxy';\nimport Position from './position';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Position iterator class. It allows to iterate forward and backward over the document.\n */\nexport default class TreeWalker {\n\t/**\n\t * Creates a range iterator. All parameters are optional, but you have to specify either `boundaries` or `startPosition`.\n\t *\n\t * @constructor\n\t * @param {Object} options Object with configuration.\n\t * @param {module:engine/view/range~Range} [options.boundaries=null] Range to define boundaries of the iterator.\n\t * @param {module:engine/view/position~Position} [options.startPosition] Starting position.\n\t * @param {'forward'|'backward'} [options.direction='forward'] Walking direction.\n\t * @param {Boolean} [options.singleCharacters=false] Flag indicating whether all characters from\n\t * {@link module:engine/view/text~Text} should be returned as one {@link module:engine/view/text~Text} (`false`) ore one by one as\n\t * {@link module:engine/view/textproxy~TextProxy} (`true`).\n\t * @param {Boolean} [options.shallow=false] Flag indicating whether iterator should enter elements or not. If the\n\t * iterator is shallow child nodes of any iterated node will not be returned along with `elementEnd` tag.\n\t * @param {Boolean} [options.ignoreElementEnd=false] Flag indicating whether iterator should ignore `elementEnd`\n\t * tags. If the option is true walker will not return a parent node of start position. If this option is `true`\n\t * each {@link module:engine/view/element~Element} will be returned once, while if the option is `false` they might be returned\n\t * twice: for `'elementStart'` and `'elementEnd'`.\n\t */\n\tconstructor( options = {} ) {\n\t\tif ( !options.boundaries && !options.startPosition ) {\n\t\t\t/**\n\t\t\t * Neither boundaries nor starting position have been defined.\n\t\t\t *\n\t\t\t * @error view-tree-walker-no-start-position\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-tree-walker-no-start-position: Neither boundaries nor starting position have been defined.' );\n\t\t}\n\n\t\tif ( options.direction && options.direction != 'forward' && options.direction != 'backward' ) {\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'view-tree-walker-unknown-direction: Only `backward` and `forward` direction allowed.',\n\t\t\t\t{ direction: options.direction }\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Iterator boundaries.\n\t\t *\n\t\t * When the iterator is walking `'forward'` on the end of boundary or is walking `'backward'`\n\t\t * on the start of boundary, then `{ done: true }` is returned.\n\t\t *\n\t\t * If boundaries are not defined they are set before first and after last child of the root node.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/range~Range} module:engine/view/treewalker~TreeWalker#boundaries\n\t\t */\n\t\tthis.boundaries = options.boundaries || null;\n\n\t\t/**\n\t\t * Iterator position. If start position is not defined then position depends on {@link #direction}. If direction is\n\t\t * `'forward'` position starts form the beginning, when direction is `'backward'` position starts from the end.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/position~Position} module:engine/view/treewalker~TreeWalker#position\n\t\t */\n\t\tif ( options.startPosition ) {\n\t\t\tthis.position = Position._createAt( options.startPosition );\n\t\t} else {\n\t\t\tthis.position = Position._createAt( options.boundaries[ options.direction == 'backward' ? 'end' : 'start' ] );\n\t\t}\n\n\t\t/**\n\t\t * Walking direction. Defaults `'forward'`.\n\t\t *\n\t\t * @readonly\n\t\t * @member {'backward'|'forward'} module:engine/view/treewalker~TreeWalker#direction\n\t\t */\n\t\tthis.direction = options.direction || 'forward';\n\n\t\t/**\n\t\t * Flag indicating whether all characters from {@link module:engine/view/text~Text} should be returned as one\n\t\t * {@link module:engine/view/text~Text} or one by one as {@link module:engine/view/textproxy~TextProxy}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} module:engine/view/treewalker~TreeWalker#singleCharacters\n\t\t */\n\t\tthis.singleCharacters = !!options.singleCharacters;\n\n\t\t/**\n\t\t * Flag indicating whether iterator should enter elements or not. If the iterator is shallow child nodes of any\n\t\t * iterated node will not be returned along with `elementEnd` tag.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} module:engine/view/treewalker~TreeWalker#shallow\n\t\t */\n\t\tthis.shallow = !!options.shallow;\n\n\t\t/**\n\t\t * Flag indicating whether iterator should ignore `elementEnd` tags. If set to `true`, walker will not\n\t\t * return a parent node of the start position. Each {@link module:engine/view/element~Element} will be returned once.\n\t\t * When set to `false` each element might be returned twice: for `'elementStart'` and `'elementEnd'`.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} module:engine/view/treewalker~TreeWalker#ignoreElementEnd\n\t\t */\n\t\tthis.ignoreElementEnd = !!options.ignoreElementEnd;\n\n\t\t/**\n\t\t * Start boundary parent.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/view/node~Node} module:engine/view/treewalker~TreeWalker#_boundaryStartParent\n\t\t */\n\t\tthis._boundaryStartParent = this.boundaries ? this.boundaries.start.parent : null;\n\n\t\t/**\n\t\t * End boundary parent.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/view/node~Node} module:engine/view/treewalker~TreeWalker#_boundaryEndParent\n\t\t */\n\t\tthis._boundaryEndParent = this.boundaries ? this.boundaries.end.parent : null;\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * @returns {Iterable.<module:engine/view/treewalker~TreeWalkerValue>}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Moves {@link #position} in the {@link #direction} skipping values as long as the callback function returns `true`.\n\t *\n\t * For example:\n\t *\n\t * \t\twalker.skip( value => value.type == 'text' ); // <p>{}foo</p> -> <p>foo[]</p>\n\t * \t\twalker.skip( value => true ); // Move the position to the end: <p>{}foo</p> -> <p>foo</p>[]\n\t * \t\twalker.skip( value => false ); // Do not move the position.\n\t *\n\t * @param {Function} skip Callback function. Gets {@link module:engine/view/treewalker~TreeWalkerValue} and should\n\t * return `true` if the value should be skipped or `false` if not.\n\t */\n\tskip( skip ) {\n\t\tlet done, value, prevPosition;\n\n\t\tdo {\n\t\t\tprevPosition = this.position;\n\n\t\t\t( { done, value } = this.next() );\n\t\t} while ( !done && skip( value ) );\n\n\t\tif ( !done ) {\n\t\t\tthis.position = prevPosition;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the next tree walker's value.\n\t *\n\t * @returns {module:engine/view/treewalker~TreeWalkerValue} Object implementing iterator interface, returning\n\t * information about taken step.\n\t */\n\tnext() {\n\t\tif ( this.direction == 'forward' ) {\n\t\t\treturn this._next();\n\t\t} else {\n\t\t\treturn this._previous();\n\t\t}\n\t}\n\n\t/**\n\t * Makes a step forward in view. Moves the {@link #position} to the next position and returns the encountered value.\n\t *\n\t * @private\n\t * @returns {Object}\n\t * @returns {Boolean} return.done `true` if iterator is done, `false` otherwise.\n\t * @returns {module:engine/view/treewalker~TreeWalkerValue} return.value Information about taken step.\n\t */\n\t_next() {\n\t\tlet position = this.position.clone();\n\t\tconst previousPosition = this.position;\n\t\tconst parent = position.parent;\n\n\t\t// We are at the end of the root.\n\t\tif ( parent.parent === null && position.offset === parent.childCount ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// We reached the walker boundary.\n\t\tif ( parent === this._boundaryEndParent && position.offset == this.boundaries.end.offset ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// Get node just after current position.\n\t\tlet node;\n\n\t\t// Text is a specific parent because it contains string instead of child nodes.\n\t\tif ( parent instanceof Text ) {\n\t\t\tif ( position.isAtEnd ) {\n\t\t\t\t// Prevent returning \"elementEnd\" for Text node. Skip that value and return the next walker step.\n\t\t\t\tthis.position = Position._createAfter( parent );\n\n\t\t\t\treturn this._next();\n\t\t\t}\n\n\t\t\tnode = parent.data[ position.offset ];\n\t\t} else {\n\t\t\tnode = parent.getChild( position.offset );\n\t\t}\n\n\t\tif ( node instanceof Element ) {\n\t\t\tif ( !this.shallow ) {\n\t\t\t\tposition = new Position( node, 0 );\n\t\t\t} else {\n\t\t\t\tposition.offset++;\n\t\t\t}\n\n\t\t\tthis.position = position;\n\n\t\t\treturn this._formatReturnValue( 'elementStart', node, previousPosition, position, 1 );\n\t\t} else if ( node instanceof Text ) {\n\t\t\tif ( this.singleCharacters ) {\n\t\t\t\tposition = new Position( node, 0 );\n\t\t\t\tthis.position = position;\n\n\t\t\t\treturn this._next();\n\t\t\t} else {\n\t\t\t\tlet charactersCount = node.data.length;\n\t\t\t\tlet item;\n\n\t\t\t\t// If text stick out of walker range, we need to cut it and wrap in TextProxy.\n\t\t\t\tif ( node == this._boundaryEndParent ) {\n\t\t\t\t\tcharactersCount = this.boundaries.end.offset;\n\t\t\t\t\titem = new TextProxy( node, 0, charactersCount );\n\t\t\t\t\tposition = Position._createAfter( item );\n\t\t\t\t} else {\n\t\t\t\t\titem = new TextProxy( node, 0, node.data.length );\n\t\t\t\t\t// If not just keep moving forward.\n\t\t\t\t\tposition.offset++;\n\t\t\t\t}\n\n\t\t\t\tthis.position = position;\n\n\t\t\t\treturn this._formatReturnValue( 'text', item, previousPosition, position, charactersCount );\n\t\t\t}\n\t\t} else if ( typeof node == 'string' ) {\n\t\t\tlet textLength;\n\n\t\t\tif ( this.singleCharacters ) {\n\t\t\t\ttextLength = 1;\n\t\t\t} else {\n\t\t\t\t// Check if text stick out of walker range.\n\t\t\t\tconst endOffset = parent === this._boundaryEndParent ? this.boundaries.end.offset : parent.data.length;\n\n\t\t\t\ttextLength = endOffset - position.offset;\n\t\t\t}\n\n\t\t\tconst textProxy = new TextProxy( parent, position.offset, textLength );\n\n\t\t\tposition.offset += textLength;\n\t\t\tthis.position = position;\n\n\t\t\treturn this._formatReturnValue( 'text', textProxy, previousPosition, position, textLength );\n\t\t} else {\n\t\t\t// `node` is not set, we reached the end of current `parent`.\n\t\t\tposition = Position._createAfter( parent );\n\t\t\tthis.position = position;\n\n\t\t\tif ( this.ignoreElementEnd ) {\n\t\t\t\treturn this._next();\n\t\t\t} else {\n\t\t\t\treturn this._formatReturnValue( 'elementEnd', parent, previousPosition, position );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Makes a step backward in view. Moves the {@link #position} to the previous position and returns the encountered value.\n\t *\n\t * @private\n\t * @returns {Object}\n\t * @returns {Boolean} return.done True if iterator is done.\n\t * @returns {module:engine/view/treewalker~TreeWalkerValue} return.value Information about taken step.\n\t */\n\t_previous() {\n\t\tlet position = this.position.clone();\n\t\tconst previousPosition = this.position;\n\t\tconst parent = position.parent;\n\n\t\t// We are at the beginning of the root.\n\t\tif ( parent.parent === null && position.offset === 0 ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// We reached the walker boundary.\n\t\tif ( parent == this._boundaryStartParent && position.offset == this.boundaries.start.offset ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// Get node just before current position.\n\t\tlet node;\n\n\t\t// Text {@link module:engine/view/text~Text} element is a specific parent because contains string instead of child nodes.\n\t\tif ( parent instanceof Text ) {\n\t\t\tif ( position.isAtStart ) {\n\t\t\t\t// Prevent returning \"elementStart\" for Text node. Skip that value and return the next walker step.\n\t\t\t\tthis.position = Position._createBefore( parent );\n\n\t\t\t\treturn this._previous();\n\t\t\t}\n\n\t\t\tnode = parent.data[ position.offset - 1 ];\n\t\t} else {\n\t\t\tnode = parent.getChild( position.offset - 1 );\n\t\t}\n\n\t\tif ( node instanceof Element ) {\n\t\t\tif ( !this.shallow ) {\n\t\t\t\tposition = new Position( node, node.childCount );\n\t\t\t\tthis.position = position;\n\n\t\t\t\tif ( this.ignoreElementEnd ) {\n\t\t\t\t\treturn this._previous();\n\t\t\t\t} else {\n\t\t\t\t\treturn this._formatReturnValue( 'elementEnd', node, previousPosition, position );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tposition.offset--;\n\t\t\t\tthis.position = position;\n\n\t\t\t\treturn this._formatReturnValue( 'elementStart', node, previousPosition, position, 1 );\n\t\t\t}\n\t\t} else if ( node instanceof Text ) {\n\t\t\tif ( this.singleCharacters ) {\n\t\t\t\tposition = new Position( node, node.data.length );\n\t\t\t\tthis.position = position;\n\n\t\t\t\treturn this._previous();\n\t\t\t} else {\n\t\t\t\tlet charactersCount = node.data.length;\n\t\t\t\tlet item;\n\n\t\t\t\t// If text stick out of walker range, we need to cut it and wrap in TextProxy.\n\t\t\t\tif ( node == this._boundaryStartParent ) {\n\t\t\t\t\tconst offset = this.boundaries.start.offset;\n\n\t\t\t\t\titem = new TextProxy( node, offset, node.data.length - offset );\n\t\t\t\t\tcharactersCount = item.data.length;\n\t\t\t\t\tposition = Position._createBefore( item );\n\t\t\t\t} else {\n\t\t\t\t\titem = new TextProxy( node, 0, node.data.length );\n\t\t\t\t\t// If not just keep moving backward.\n\t\t\t\t\tposition.offset--;\n\t\t\t\t}\n\n\t\t\t\tthis.position = position;\n\n\t\t\t\treturn this._formatReturnValue( 'text', item, previousPosition, position, charactersCount );\n\t\t\t}\n\t\t} else if ( typeof node == 'string' ) {\n\t\t\tlet textLength;\n\n\t\t\tif ( !this.singleCharacters ) {\n\t\t\t\t// Check if text stick out of walker range.\n\t\t\t\tconst startOffset = parent === this._boundaryStartParent ? this.boundaries.start.offset : 0;\n\n\t\t\t\ttextLength = position.offset - startOffset;\n\t\t\t} else {\n\t\t\t\ttextLength = 1;\n\t\t\t}\n\n\t\t\tposition.offset -= textLength;\n\n\t\t\tconst textProxy = new TextProxy( parent, position.offset, textLength );\n\n\t\t\tthis.position = position;\n\n\t\t\treturn this._formatReturnValue( 'text', textProxy, previousPosition, position, textLength );\n\t\t} else {\n\t\t\t// `node` is not set, we reached the beginning of current `parent`.\n\t\t\tposition = Position._createBefore( parent );\n\t\t\tthis.position = position;\n\n\t\t\treturn this._formatReturnValue( 'elementStart', parent, previousPosition, position, 1 );\n\t\t}\n\t}\n\n\t/**\n\t * Format returned data and adjust `previousPosition` and `nextPosition` if reach the bound of the {@link module:engine/view/text~Text}.\n\t *\n\t * @private\n\t * @param {module:engine/view/treewalker~TreeWalkerValueType} type Type of step.\n\t * @param {module:engine/view/item~Item} item Item between old and new position.\n\t * @param {module:engine/view/position~Position} previousPosition Previous position of iterator.\n\t * @param {module:engine/view/position~Position} nextPosition Next position of iterator.\n\t * @param {Number} [length] Length of the item.\n\t * @returns {module:engine/view/treewalker~TreeWalkerValue}\n\t */\n\t_formatReturnValue( type, item, previousPosition, nextPosition, length ) {\n\t\t// Text is a specific parent, because contains string instead of children.\n\t\t// Walker doesn't enter to the Text except situations when walker is iterating over every single character,\n\t\t// or the bound starts/ends inside the Text. So when the position is at the beginning or at the end of the Text\n\t\t// we move it just before or just after Text.\n\t\tif ( item instanceof TextProxy ) {\n\t\t\t// Position is at the end of Text.\n\t\t\tif ( item.offsetInText + item.data.length == item.textNode.data.length ) {\n\t\t\t\tif ( this.direction == 'forward' && !( this.boundaries && this.boundaries.end.isEqual( this.position ) ) ) {\n\t\t\t\t\tnextPosition = Position._createAfter( item.textNode );\n\t\t\t\t\t// When we change nextPosition of returned value we need also update walker current position.\n\t\t\t\t\tthis.position = nextPosition;\n\t\t\t\t} else {\n\t\t\t\t\tpreviousPosition = Position._createAfter( item.textNode );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Position is at the begining ot the text.\n\t\t\tif ( item.offsetInText === 0 ) {\n\t\t\t\tif ( this.direction == 'backward' && !( this.boundaries && this.boundaries.start.isEqual( this.position ) ) ) {\n\t\t\t\t\tnextPosition = Position._createBefore( item.textNode );\n\t\t\t\t\t// When we change nextPosition of returned value we need also update walker current position.\n\t\t\t\t\tthis.position = nextPosition;\n\t\t\t\t} else {\n\t\t\t\t\tpreviousPosition = Position._createBefore( item.textNode );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tdone: false,\n\t\t\tvalue: {\n\t\t\t\ttype,\n\t\t\t\titem,\n\t\t\t\tpreviousPosition,\n\t\t\t\tnextPosition,\n\t\t\t\tlength\n\t\t\t}\n\t\t};\n\t}\n}\n\n/**\n * Type of the step made by {@link module:engine/view/treewalker~TreeWalker}.\n * Possible values: `'elementStart'` if walker is at the beginning of a node, `'elementEnd'` if walker is at the end\n * of node, or `'text'` if walker traversed over single and multiple characters.\n * For {@link module:engine/view/text~Text} `elementStart` and `elementEnd` is not returned.\n *\n * @typedef {String} module:engine/view/treewalker~TreeWalkerValueType\n */\n\n/**\n * Object returned by {@link module:engine/view/treewalker~TreeWalker} when traversing tree view.\n *\n * @typedef {Object} module:engine/view/treewalker~TreeWalkerValue\n * @property {module:engine/view/treewalker~TreeWalkerValueType} type\n * @property {module:engine/view/item~Item} item Item between the old and the new positions\n * of the tree walker.\n * @property {module:engine/view/position~Position} previousPosition Previous position of the iterator.\n * * Forward iteration: For `'elementEnd'` it is the last position inside the element. For all other types it is the\n * position before the item.\n * * Backward iteration: For `'elementStart'` it is the first position inside the element. For all other types it is\n * the position after item.\n * * If the position is at the beginning or at the end of the {@link module:engine/view/text~Text} it is always moved from the\n * inside of the text to its parent just before or just after that text.\n * @property {module:engine/view/position~Position} nextPosition Next position of the iterator.\n * * Forward iteration: For `'elementStart'` it is the first position inside the element. For all other types it is\n * the position after the item.\n * * Backward iteration: For `'elementEnd'` it is last position inside element. For all other types it is the position\n * before the item.\n * * If the position is at the beginning or at the end of the {@link module:engine/view/text~Text} it is always moved from the\n * inside of the text to its parent just before or just after that text.\n * @property {Number} [length] Length of the item. For `'elementStart'` it is `1`. For `'text'` it is\n * the length of that text. For `'elementEnd'` it is `undefined`.\n */\n\n/**\n * Tree walking directions.\n *\n * @typedef {'forward'|'backward'} module:engine/view/treewalker~TreeWalkerDirection\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/position\n */\n\nimport TreeWalker from './treewalker';\n\nimport compareArrays from '@ckeditor/ckeditor5-utils/src/comparearrays';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport EditableElement from './editableelement';\n\n// To check if component is loaded more than once.\nimport '@ckeditor/ckeditor5-utils/src/version';\n\n/**\n * Position in the view tree. Position is represented by its parent node and an offset in this parent.\n *\n * In order to create a new position instance use the `createPosition*()` factory methods available in:\n *\n * * {@module:engine/view/view~View}\n * * {@module:engine/view/downcastwriter~DowncastWriter}\n * * {@module:engine/view/upcastwriter~UpcastWriter}\n */\nexport default class Position {\n\t/**\n\t * Creates a position.\n\t *\n\t * @param {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment} parent Position parent.\n\t * @param {Number} offset Position offset.\n\t */\n\tconstructor( parent, offset ) {\n\t\t/**\n\t\t * Position parent.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment}\n\t\t * module:engine/view/position~Position#parent\n\t\t */\n\t\tthis.parent = parent;\n\n\t\t/**\n\t\t * Position offset.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} module:engine/view/position~Position#offset\n\t\t */\n\t\tthis.offset = offset;\n\t}\n\n\t/**\n\t * Node directly after the position. Equals `null` when there is no node after position or position is located\n\t * inside text node.\n\t *\n\t * @readonly\n\t * @type {module:engine/view/node~Node|null}\n\t */\n\tget nodeAfter() {\n\t\tif ( this.parent.is( 'text' ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.parent.getChild( this.offset ) || null;\n\t}\n\n\t/**\n\t * Node directly before the position. Equals `null` when there is no node before position or position is located\n\t * inside text node.\n\t *\n\t * @readonly\n\t * @type {module:engine/view/node~Node|null}\n\t */\n\tget nodeBefore() {\n\t\tif ( this.parent.is( 'text' ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.parent.getChild( this.offset - 1 ) || null;\n\t}\n\n\t/**\n\t * Is `true` if position is at the beginning of its {@link module:engine/view/position~Position#parent parent}, `false` otherwise.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isAtStart() {\n\t\treturn this.offset === 0;\n\t}\n\n\t/**\n\t * Is `true` if position is at the end of its {@link module:engine/view/position~Position#parent parent}, `false` otherwise.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isAtEnd() {\n\t\tconst endOffset = this.parent.is( 'text' ) ? this.parent.data.length : this.parent.childCount;\n\n\t\treturn this.offset === endOffset;\n\t}\n\n\t/**\n\t * Position's root, that is the root of the position's parent element.\n\t *\n\t * @readonly\n\t * @type {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment}\n\t */\n\tget root() {\n\t\treturn this.parent.root;\n\t}\n\n\t/**\n\t * {@link module:engine/view/editableelement~EditableElement EditableElement} instance that contains this position, or `null` if\n\t * position is not inside an editable element.\n\t *\n\t * @type {module:engine/view/editableelement~EditableElement|null}\n\t */\n\tget editableElement() {\n\t\tlet editable = this.parent;\n\n\t\twhile ( !( editable instanceof EditableElement ) ) {\n\t\t\tif ( editable.parent ) {\n\t\t\t\teditable = editable.parent;\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\treturn editable;\n\t}\n\n\t/**\n\t * Returns a new instance of Position with offset incremented by `shift` value.\n\t *\n\t * @param {Number} shift How position offset should get changed. Accepts negative values.\n\t * @returns {module:engine/view/position~Position} Shifted position.\n\t */\n\tgetShiftedBy( shift ) {\n\t\tconst shifted = Position._createAt( this );\n\n\t\tconst offset = shifted.offset + shift;\n\t\tshifted.offset = offset < 0 ? 0 : offset;\n\n\t\treturn shifted;\n\t}\n\n\t/**\n\t * Gets the farthest position which matches the callback using\n\t * {@link module:engine/view/treewalker~TreeWalker TreeWalker}.\n\t *\n\t * For example:\n\t *\n\t * \t\tgetLastMatchingPosition( value => value.type == 'text' ); // <p>{}foo</p> -> <p>foo[]</p>\n\t * \t\tgetLastMatchingPosition( value => value.type == 'text', { direction: 'backward' } ); // <p>foo[]</p> -> <p>{}foo</p>\n\t * \t\tgetLastMatchingPosition( value => false ); // Do not move the position.\n\t *\n\t * @param {Function} skip Callback function. Gets {@link module:engine/view/treewalker~TreeWalkerValue} and should\n\t * return `true` if the value should be skipped or `false` if not.\n\t * @param {Object} options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n\t *\n\t * @returns {module:engine/view/position~Position} The position after the last item which matches the `skip` callback test.\n\t */\n\tgetLastMatchingPosition( skip, options = {} ) {\n\t\toptions.startPosition = this;\n\n\t\tconst treeWalker = new TreeWalker( options );\n\t\ttreeWalker.skip( skip );\n\n\t\treturn treeWalker.position;\n\t}\n\n\t/**\n\t * Returns ancestors array of this position, that is this position's parent and it's ancestors.\n\t *\n\t * @returns {Array} Array with ancestors.\n\t */\n\tgetAncestors() {\n\t\tif ( this.parent.is( 'documentFragment' ) ) {\n\t\t\treturn [ this.parent ];\n\t\t} else {\n\t\t\treturn this.parent.getAncestors( { includeSelf: true } );\n\t\t}\n\t}\n\n\t/**\n\t * Returns a {@link module:engine/view/node~Node} or {@link module:engine/view/documentfragment~DocumentFragment}\n\t * which is a common ancestor of both positions.\n\t *\n\t * @param {module:engine/view/position~Position} position\n\t * @returns {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment|null}\n\t */\n\tgetCommonAncestor( position ) {\n\t\tconst ancestorsA = this.getAncestors();\n\t\tconst ancestorsB = position.getAncestors();\n\n\t\tlet i = 0;\n\n\t\twhile ( ancestorsA[ i ] == ancestorsB[ i ] && ancestorsA[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i === 0 ? null : ancestorsA[ i - 1 ];\n\t}\n\n\t/**\n\t * Checks whether this position equals given position.\n\t *\n\t * @param {module:engine/view/position~Position} otherPosition Position to compare with.\n\t * @returns {Boolean} True if positions are same.\n\t */\n\tisEqual( otherPosition ) {\n\t\treturn ( this.parent == otherPosition.parent && this.offset == otherPosition.offset );\n\t}\n\n\t/**\n\t * Checks whether this position is located before given position. When method returns `false` it does not mean that\n\t * this position is after give one. Two positions may be located inside separate roots and in that situation this\n\t * method will still return `false`.\n\t *\n\t * @see module:engine/view/position~Position#isAfter\n\t * @see module:engine/view/position~Position#compareWith\n\t * @param {module:engine/view/position~Position} otherPosition Position to compare with.\n\t * @returns {Boolean} Returns `true` if this position is before given position.\n\t */\n\tisBefore( otherPosition ) {\n\t\treturn this.compareWith( otherPosition ) == 'before';\n\t}\n\n\t/**\n\t * Checks whether this position is located after given position. When method returns `false` it does not mean that\n\t * this position is before give one. Two positions may be located inside separate roots and in that situation this\n\t * method will still return `false`.\n\t *\n\t * @see module:engine/view/position~Position#isBefore\n\t * @see module:engine/view/position~Position#compareWith\n\t * @param {module:engine/view/position~Position} otherPosition Position to compare with.\n\t * @returns {Boolean} Returns `true` if this position is after given position.\n\t */\n\tisAfter( otherPosition ) {\n\t\treturn this.compareWith( otherPosition ) == 'after';\n\t}\n\n\t/**\n\t * Checks whether this position is before, after or in same position that other position. Two positions may be also\n\t * different when they are located in separate roots.\n\t *\n\t * @param {module:engine/view/position~Position} otherPosition Position to compare with.\n\t * @returns {module:engine/view/position~PositionRelation}\n\t */\n\tcompareWith( otherPosition ) {\n\t\tif ( this.root !== otherPosition.root ) {\n\t\t\treturn 'different';\n\t\t}\n\n\t\tif ( this.isEqual( otherPosition ) ) {\n\t\t\treturn 'same';\n\t\t}\n\n\t\t// Get path from root to position's parent element.\n\t\tconst thisPath = this.parent.is( 'node' ) ? this.parent.getPath() : [];\n\t\tconst otherPath = otherPosition.parent.is( 'node' ) ? otherPosition.parent.getPath() : [];\n\n\t\t// Add the positions' offsets to the parents offsets.\n\t\tthisPath.push( this.offset );\n\t\totherPath.push( otherPosition.offset );\n\n\t\t// Compare both path arrays to find common ancestor.\n\t\tconst result = compareArrays( thisPath, otherPath );\n\n\t\tswitch ( result ) {\n\t\t\tcase 'prefix':\n\t\t\t\treturn 'before';\n\n\t\t\tcase 'extension':\n\t\t\t\treturn 'after';\n\n\t\t\tdefault:\n\t\t\t\treturn thisPath[ result ] < otherPath[ result ] ? 'before' : 'after';\n\t\t}\n\t}\n\n\t/**\n\t * Creates a {@link module:engine/view/treewalker~TreeWalker TreeWalker} instance with this positions as a start position.\n\t *\n\t * @param {Object} options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}\n\t * @param {module:engine/view/range~Range} [options.boundaries=null] Range to define boundaries of the iterator.\n\t * @param {Boolean} [options.singleCharacters=false]\n\t * @param {Boolean} [options.shallow=false]\n\t * @param {Boolean} [options.ignoreElementEnd=false]\n\t */\n\tgetWalker( options = {} ) {\n\t\toptions.startPosition = this;\n\n\t\treturn new TreeWalker( options );\n\t}\n\n\tclone() {\n\t\treturn new Position( this.parent, this.offset );\n\t}\n\n\t/**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/view/position~Position position},\n\t * * parent element and offset (offset defaults to `0`),\n\t * * parent element and `'end'` (sets position at the end of that element),\n\t * * {@link module:engine/view/item~Item view item} and `'before'` or `'after'` (sets position before or after given view item).\n\t *\n\t * This method is a shortcut to other constructors such as:\n\t *\n\t * * {@link module:engine/view/position~Position._createBefore},\n\t * * {@link module:engine/view/position~Position._createAfter}.\n\t *\n\t * @protected\n\t * @param {module:engine/view/item~Item|module:engine/view/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tstatic _createAt( itemOrPosition, offset ) {\n\t\tif ( itemOrPosition instanceof Position ) {\n\t\t\treturn new this( itemOrPosition.parent, itemOrPosition.offset );\n\t\t} else {\n\t\t\tconst node = itemOrPosition;\n\n\t\t\tif ( offset == 'end' ) {\n\t\t\t\toffset = node.is( 'text' ) ? node.data.length : node.childCount;\n\t\t\t} else if ( offset == 'before' ) {\n\t\t\t\treturn this._createBefore( node );\n\t\t\t} else if ( offset == 'after' ) {\n\t\t\t\treturn this._createAfter( node );\n\t\t\t} else if ( offset !== 0 && !offset ) {\n\t\t\t\t/**\n\t\t\t\t * {@link module:engine/view/view~View#createPositionAt `View#createPositionAt()`}\n\t\t\t\t * requires the offset to be specified when the first parameter is a view item.\n\t\t\t\t *\n\t\t\t\t * @error view-createPositionAt-offset-required\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'view-createPositionAt-offset-required: ' +\n\t\t\t\t\t'View#createPositionAt() requires the offset when the first parameter is a view item.' );\n\t\t\t}\n\n\t\t\treturn new Position( node, offset );\n\t\t}\n\t}\n\n\t/**\n\t * Creates a new position after given view item.\n\t *\n\t * @protected\n\t * @param {module:engine/view/item~Item} item View item after which the position should be located.\n\t * @returns {module:engine/view/position~Position}\n\t */\n\tstatic _createAfter( item ) {\n\t\t// TextProxy is not a instance of Node so we need do handle it in specific way.\n\t\tif ( item.is( 'textProxy' ) ) {\n\t\t\treturn new Position( item.textNode, item.offsetInText + item.data.length );\n\t\t}\n\n\t\tif ( !item.parent ) {\n\t\t\t/**\n\t\t\t * You can not make a position after a root.\n\t\t\t *\n\t\t\t * @error view-position-after-root\n\t\t\t * @param {module:engine/view/node~Node} root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-position-after-root: You can not make position after root.', { root: item } );\n\t\t}\n\n\t\treturn new Position( item.parent, item.index + 1 );\n\t}\n\n\t/**\n\t * Creates a new position before given view item.\n\t *\n\t * @protected\n\t * @param {module:engine/view/item~Item} item View item before which the position should be located.\n\t * @returns {module:engine/view/position~Position}\n\t */\n\tstatic _createBefore( item ) {\n\t\t// TextProxy is not a instance of Node so we need do handle it in specific way.\n\t\tif ( item.is( 'textProxy' ) ) {\n\t\t\treturn new Position( item.textNode, item.offsetInText );\n\t\t}\n\n\t\tif ( !item.parent ) {\n\t\t\t/**\n\t\t\t * You cannot make a position before a root.\n\t\t\t *\n\t\t\t * @error view-position-before-root\n\t\t\t * @param {module:engine/view/node~Node} root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-position-before-root: You can not make position before root.', { root: item } );\n\t\t}\n\n\t\treturn new Position( item.parent, item.index );\n\t}\n}\n\n/**\n * A flag indicating whether this position is `'before'` or `'after'` or `'same'` as given position.\n * If positions are in different roots `'different'` flag is returned.\n *\n * @typedef {String} module:engine/view/position~PositionRelation\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/range\n */\n\nimport Position from './position';\nimport TreeWalker from './treewalker';\n\n/**\n * Range in the view tree. A range is represented by its start and end {@link module:engine/view/position~Position positions}.\n *\n * In order to create a new position instance use the `createPosition*()` factory methods available in:\n *\n * * {@module:engine/view/view~View}\n * * {@module:engine/view/downcastwriter~DowncastWriter}\n * * {@module:engine/view/upcastwriter~UpcastWriter}\n */\nexport default class Range {\n\t/**\n\t * Creates a range spanning from `start` position to `end` position.\n\t *\n\t * **Note:** Constructor creates it's own {@link module:engine/view/position~Position} instances basing on passed values.\n\t *\n\t * @param {module:engine/view/position~Position} start Start position.\n\t * @param {module:engine/view/position~Position} [end] End position. If not set, range will be collapsed at the `start` position.\n\t */\n\tconstructor( start, end = null ) {\n\t\t/**\n\t\t * Start position.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/position~Position}\n\t\t */\n\t\tthis.start = start.clone();\n\n\t\t/**\n\t\t * End position.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/position~Position}\n\t\t */\n\t\tthis.end = end ? end.clone() : start.clone();\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * Iterates over all {@link module:engine/view/item~Item view items} that are in this range and returns\n\t * them together with additional information like length or {@link module:engine/view/position~Position positions},\n\t * grouped as {@link module:engine/view/treewalker~TreeWalkerValue}.\n\t *\n\t * This iterator uses {@link module:engine/view/treewalker~TreeWalker TreeWalker} with `boundaries` set to this range and\n\t * `ignoreElementEnd` option\n\t * set to `true`.\n\t *\n\t * @returns {Iterable.<module:engine/view/treewalker~TreeWalkerValue>}\n\t */\n\t* [ Symbol.iterator ]() {\n\t\tyield* new TreeWalker( { boundaries: this, ignoreElementEnd: true } );\n\t}\n\n\t/**\n\t * Returns whether the range is collapsed, that is it start and end positions are equal.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isCollapsed() {\n\t\treturn this.start.isEqual( this.end );\n\t}\n\n\t/**\n\t * Returns whether this range is flat, that is if {@link module:engine/view/range~Range#start start} position and\n\t * {@link module:engine/view/range~Range#end end} position are in the same {@link module:engine/view/position~Position#parent parent}.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isFlat() {\n\t\treturn this.start.parent === this.end.parent;\n\t}\n\n\t/**\n\t * Range root element.\n\t *\n\t * @type {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment}\n\t */\n\tget root() {\n\t\treturn this.start.root;\n\t}\n\n\t/**\n\t * Creates a maximal range that has the same content as this range but is expanded in both ways (at the beginning\n\t * and at the end).\n\t *\n\t * For example:\n\t *\n\t *\t\t<p>Foo</p><p><b>{Bar}</b></p> -> <p>Foo</p>[<p><b>Bar</b>]</p>\n\t *\t\t<p><b>foo</b>{bar}<span></span></p> -> <p><b>foo[</b>bar<span></span>]</p>\n\t *\n\t * Note that in the sample above:\n\t *\n\t * - `<p>` have type of {@link module:engine/view/containerelement~ContainerElement},\n\t * - `<b>` have type of {@link module:engine/view/attributeelement~AttributeElement},\n\t * - `<span>` have type of {@link module:engine/view/uielement~UIElement}.\n\t *\n\t * @returns {module:engine/view/range~Range} Enlarged range.\n\t */\n\tgetEnlarged() {\n\t\tlet start = this.start.getLastMatchingPosition( enlargeTrimSkip, { direction: 'backward' } );\n\t\tlet end = this.end.getLastMatchingPosition( enlargeTrimSkip );\n\n\t\t// Fix positions, in case if they are in Text node.\n\t\tif ( start.parent.is( 'text' ) && start.isAtStart ) {\n\t\t\tstart = Position._createBefore( start.parent );\n\t\t}\n\n\t\tif ( end.parent.is( 'text' ) && end.isAtEnd ) {\n\t\t\tend = Position._createAfter( end.parent );\n\t\t}\n\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Creates a minimum range that has the same content as this range but is trimmed in both ways (at the beginning\n\t * and at the end).\n\t *\n\t * For example:\n\t *\n\t *\t\t<p>Foo</p>[<p><b>Bar</b>]</p> -> <p>Foo</p><p><b>{Bar}</b></p>\n\t *\t\t<p><b>foo[</b>bar<span></span>]</p> -> <p><b>foo</b>{bar}<span></span></p>\n\t *\n\t * Note that in the sample above:\n\t *\n\t * - `<p>` have type of {@link module:engine/view/containerelement~ContainerElement},\n\t * - `<b>` have type of {@link module:engine/view/attributeelement~AttributeElement},\n\t * - `<span>` have type of {@link module:engine/view/uielement~UIElement}.\n\t *\n\t * @returns {module:engine/view/range~Range} Shrink range.\n\t */\n\tgetTrimmed() {\n\t\tlet start = this.start.getLastMatchingPosition( enlargeTrimSkip );\n\n\t\tif ( start.isAfter( this.end ) || start.isEqual( this.end ) ) {\n\t\t\treturn new Range( start, start );\n\t\t}\n\n\t\tlet end = this.end.getLastMatchingPosition( enlargeTrimSkip, { direction: 'backward' } );\n\t\tconst nodeAfterStart = start.nodeAfter;\n\t\tconst nodeBeforeEnd = end.nodeBefore;\n\n\t\t// Because TreeWalker prefers positions next to text node, we need to move them manually into these text nodes.\n\t\tif ( nodeAfterStart && nodeAfterStart.is( 'text' ) ) {\n\t\t\tstart = new Position( nodeAfterStart, 0 );\n\t\t}\n\n\t\tif ( nodeBeforeEnd && nodeBeforeEnd.is( 'text' ) ) {\n\t\t\tend = new Position( nodeBeforeEnd, nodeBeforeEnd.data.length );\n\t\t}\n\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Two ranges are equal if their start and end positions are equal.\n\t *\n\t * @param {module:engine/view/range~Range} otherRange Range to compare with.\n\t * @returns {Boolean} `true` if ranges are equal, `false` otherwise\n\t */\n\tisEqual( otherRange ) {\n\t\treturn this == otherRange || ( this.start.isEqual( otherRange.start ) && this.end.isEqual( otherRange.end ) );\n\t}\n\n\t/**\n\t * Checks whether this range contains given {@link module:engine/view/position~Position position}.\n\t *\n\t * @param {module:engine/view/position~Position} position Position to check.\n\t * @returns {Boolean} `true` if given {@link module:engine/view/position~Position position} is contained in this range,\n\t * `false` otherwise.\n\t */\n\tcontainsPosition( position ) {\n\t\treturn position.isAfter( this.start ) && position.isBefore( this.end );\n\t}\n\n\t/**\n\t * Checks whether this range contains given {@link module:engine/view/range~Range range}.\n\t *\n\t * @param {module:engine/view/range~Range} otherRange Range to check.\n\t * @param {Boolean} [loose=false] Whether the check is loose or strict. If the check is strict (`false`), compared range cannot\n\t * start or end at the same position as this range boundaries. If the check is loose (`true`), compared range can start, end or\n\t * even be equal to this range. Note that collapsed ranges are always compared in strict mode.\n\t * @returns {Boolean} `true` if given {@link module:engine/view/range~Range range} boundaries are contained by this range, `false`\n\t * otherwise.\n\t */\n\tcontainsRange( otherRange, loose = false ) {\n\t\tif ( otherRange.isCollapsed ) {\n\t\t\tloose = false;\n\t\t}\n\n\t\tconst containsStart = this.containsPosition( otherRange.start ) || ( loose && this.start.isEqual( otherRange.start ) );\n\t\tconst containsEnd = this.containsPosition( otherRange.end ) || ( loose && this.end.isEqual( otherRange.end ) );\n\n\t\treturn containsStart && containsEnd;\n\t}\n\n\t/**\n\t * Computes which part(s) of this {@link module:engine/view/range~Range range} is not a part of given\n\t * {@link module:engine/view/range~Range range}.\n\t * Returned array contains zero, one or two {@link module:engine/view/range~Range ranges}.\n\t *\n\t * Examples:\n\t *\n\t *\t\tlet foo = downcastWriter.createText( 'foo' );\n\t *\t\tlet img = downcastWriter.createContainerElement( 'img' );\n\t *\t\tlet bar = downcastWriter.createText( 'bar' );\n\t *\t\tlet p = downcastWriter.createContainerElement( 'p', null, [ foo, img, bar ] );\n\t *\n\t *\t\tlet range = view.createRange( view.createPositionAt( foo, 2 ), view.createPositionAt( bar, 1 ); // \"o\", img, \"b\" are in range.\n\t *\t\tlet otherRange = view.createRange( // \"oo\", img, \"ba\" are in range.\n\t *\t\t\tview.createPositionAt( foo, 1 ),\n\t *\t\t\tview.createPositionAt( bar, 2 )\n\t *\t\t);\n\t *\t\tlet transformed = range.getDifference( otherRange );\n\t *\t\t// transformed array has no ranges because `otherRange` contains `range`\n\t *\n\t *\t\totherRange = view.createRange( view.createPositionAt( foo, 1 ), view.createPositionAt( p, 2 ); // \"oo\", img are in range.\n\t *\t\ttransformed = range.getDifference( otherRange );\n\t *\t\t// transformed array has one range: from ( p, 2 ) to ( bar, 1 )\n\t *\n\t *\t\totherRange = view.createRange( view.createPositionAt( p, 1 ), view.createPositionAt( p, 2 ) ); // img is in range.\n\t *\t\ttransformed = range.getDifference( otherRange );\n\t *\t\t// transformed array has two ranges: from ( foo, 1 ) to ( p, 1 ) and from ( p, 2 ) to ( bar, 1 )\n\t *\n\t * @param {module:engine/view/range~Range} otherRange Range to differentiate against.\n\t * @returns {Array.<module:engine/view/range~Range>} The difference between ranges.\n\t */\n\tgetDifference( otherRange ) {\n\t\tconst ranges = [];\n\n\t\tif ( this.isIntersecting( otherRange ) ) {\n\t\t\t// Ranges intersect.\n\n\t\t\tif ( this.containsPosition( otherRange.start ) ) {\n\t\t\t\t// Given range start is inside this range. This means that we have to\n\t\t\t\t// add shrunken range - from the start to the middle of this range.\n\t\t\t\tranges.push( new Range( this.start, otherRange.start ) );\n\t\t\t}\n\n\t\t\tif ( this.containsPosition( otherRange.end ) ) {\n\t\t\t\t// Given range end is inside this range. This means that we have to\n\t\t\t\t// add shrunken range - from the middle of this range to the end.\n\t\t\t\tranges.push( new Range( otherRange.end, this.end ) );\n\t\t\t}\n\t\t} else {\n\t\t\t// Ranges do not intersect, return the original range.\n\t\t\tranges.push( this.clone() );\n\t\t}\n\n\t\treturn ranges;\n\t}\n\n\t/**\n\t * Returns an intersection of this {@link module:engine/view/range~Range range} and given {@link module:engine/view/range~Range range}.\n\t * Intersection is a common part of both of those ranges. If ranges has no common part, returns `null`.\n\t *\n\t * Examples:\n\t *\n\t *\t\tlet foo = downcastWriter.createText( 'foo' );\n\t *\t\tlet img = downcastWriter.createContainerElement( 'img' );\n\t *\t\tlet bar = downcastWriter.createText( 'bar' );\n\t *\t\tlet p = downcastWriter.createContainerElement( 'p', null, [ foo, img, bar ] );\n\t *\n\t *\t\tlet range = view.createRange( view.createPositionAt( foo, 2 ), view.createPositionAt( bar, 1 ); // \"o\", img, \"b\" are in range.\n\t *\t\tlet otherRange = view.createRange( view.createPositionAt( foo, 1 ), view.createPositionAt( p, 2 ); // \"oo\", img are in range.\n\t *\t\tlet transformed = range.getIntersection( otherRange ); // range from ( foo, 1 ) to ( p, 2 ).\n\t *\n\t *\t\totherRange = view.createRange( view.createPositionAt( bar, 1 ), view.createPositionAt( bar, 3 ); \"ar\" is in range.\n\t *\t\ttransformed = range.getIntersection( otherRange ); // null - no common part.\n\t *\n\t * @param {module:engine/view/range~Range} otherRange Range to check for intersection.\n\t * @returns {module:engine/view/range~Range|null} A common part of given ranges or `null` if ranges have no common part.\n\t */\n\tgetIntersection( otherRange ) {\n\t\tif ( this.isIntersecting( otherRange ) ) {\n\t\t\t// Ranges intersect, so a common range will be returned.\n\t\t\t// At most, it will be same as this range.\n\t\t\tlet commonRangeStart = this.start;\n\t\t\tlet commonRangeEnd = this.end;\n\n\t\t\tif ( this.containsPosition( otherRange.start ) ) {\n\t\t\t\t// Given range start is inside this range. This means thaNt we have to\n\t\t\t\t// shrink common range to the given range start.\n\t\t\t\tcommonRangeStart = otherRange.start;\n\t\t\t}\n\n\t\t\tif ( this.containsPosition( otherRange.end ) ) {\n\t\t\t\t// Given range end is inside this range. This means that we have to\n\t\t\t\t// shrink common range to the given range end.\n\t\t\t\tcommonRangeEnd = otherRange.end;\n\t\t\t}\n\n\t\t\treturn new Range( commonRangeStart, commonRangeEnd );\n\t\t}\n\n\t\t// Ranges do not intersect, so they do not have common part.\n\t\treturn null;\n\t}\n\n\t/**\n\t * Creates a {@link module:engine/view/treewalker~TreeWalker TreeWalker} instance with this range as a boundary.\n\t *\n\t * @param {Object} options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n\t * @param {module:engine/view/position~Position} [options.startPosition]\n\t * @param {Boolean} [options.singleCharacters=false]\n\t * @param {Boolean} [options.shallow=false]\n\t * @param {Boolean} [options.ignoreElementEnd=false]\n\t * @returns {module:engine/view/treewalker~TreeWalker}\n\t */\n\tgetWalker( options = {} ) {\n\t\toptions.boundaries = this;\n\n\t\treturn new TreeWalker( options );\n\t}\n\n\t/**\n\t * Returns a {@link module:engine/view/node~Node} or {@link module:engine/view/documentfragment~DocumentFragment}\n\t * which is a common ancestor of range's both ends (in which the entire range is contained).\n\t *\n\t * @returns {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment|null}\n\t */\n\tgetCommonAncestor() {\n\t\treturn this.start.getCommonAncestor( this.end );\n\t}\n\n\t/**\n\t * Clones this range.\n\t *\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tclone() {\n\t\treturn new Range( this.start, this.end );\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all {@link module:engine/view/item~Item view items} that are in this range and returns\n\t * them.\n\t *\n\t * This method uses {@link module:engine/view/treewalker~TreeWalker} with `boundaries` set to this range and `ignoreElementEnd` option\n\t * set to `true`. However it returns only {@link module:engine/view/item~Item items},\n\t * not {@link module:engine/view/treewalker~TreeWalkerValue}.\n\t *\n\t * You may specify additional options for the tree walker. See {@link module:engine/view/treewalker~TreeWalker} for\n\t * a full list of available options.\n\t *\n\t * @param {Object} options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n\t * @returns {Iterable.<module:engine/view/item~Item>}\n\t */\n\t* getItems( options = {} ) {\n\t\toptions.boundaries = this;\n\t\toptions.ignoreElementEnd = true;\n\n\t\tconst treeWalker = new TreeWalker( options );\n\n\t\tfor ( const value of treeWalker ) {\n\t\t\tyield value.item;\n\t\t}\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all {@link module:engine/view/position~Position positions} that are boundaries or\n\t * contained in this range.\n\t *\n\t * This method uses {@link module:engine/view/treewalker~TreeWalker} with `boundaries` set to this range. However it returns only\n\t * {@link module:engine/view/position~Position positions}, not {@link module:engine/view/treewalker~TreeWalkerValue}.\n\t *\n\t * You may specify additional options for the tree walker. See {@link module:engine/view/treewalker~TreeWalker} for\n\t * a full list of available options.\n\t *\n\t * @param {Object} options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n\t * @returns {Iterable.<module:engine/view/position~Position>}\n\t */\n\t* getPositions( options = {} ) {\n\t\toptions.boundaries = this;\n\n\t\tconst treeWalker = new TreeWalker( options );\n\n\t\tyield treeWalker.position;\n\n\t\tfor ( const value of treeWalker ) {\n\t\t\tyield value.nextPosition;\n\t\t}\n\t}\n\n\t/**\n\t * Checks and returns whether this range intersects with the given range.\n\t *\n\t * @param {module:engine/view/range~Range} otherRange Range to compare with.\n\t * @returns {Boolean} True if ranges intersect.\n\t */\n\tisIntersecting( otherRange ) {\n\t\treturn this.start.isBefore( otherRange.end ) && this.end.isAfter( otherRange.start );\n\t}\n\n\t/**\n\t * Creates a range from the given parents and offsets.\n\t *\n\t * @protected\n\t * @param {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment} startElement Start position\n\t * parent element.\n\t * @param {Number} startOffset Start position offset.\n\t * @param {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment} endElement End position\n\t * parent element.\n\t * @param {Number} endOffset End position offset.\n\t * @returns {module:engine/view/range~Range} Created range.\n\t */\n\tstatic _createFromParentsAndOffsets( startElement, startOffset, endElement, endOffset ) {\n\t\treturn new this(\n\t\t\tnew Position( startElement, startOffset ),\n\t\t\tnew Position( endElement, endOffset )\n\t\t);\n\t}\n\n\t/**\n\t * Creates a new range, spreading from specified {@link module:engine/view/position~Position position} to a position moved by\n\t * given `shift`. If `shift` is a negative value, shifted position is treated as the beginning of the range.\n\t *\n\t * @protected\n\t * @param {module:engine/view/position~Position} position Beginning of the range.\n\t * @param {Number} shift How long the range should be.\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tstatic _createFromPositionAndShift( position, shift ) {\n\t\tconst start = position;\n\t\tconst end = position.getShiftedBy( shift );\n\n\t\treturn shift > 0 ? new this( start, end ) : new this( end, start );\n\t}\n\n\t/**\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * @protected\n\t * @param {module:engine/view/element~Element} element Element which is a parent for the range.\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tstatic _createIn( element ) {\n\t\treturn this._createFromParentsAndOffsets( element, 0, element, element.childCount );\n\t}\n\n\t/**\n\t * Creates a range that starts before given {@link module:engine/view/item~Item view item} and ends after it.\n\t *\n\t * @protected\n\t * @param {module:engine/view/item~Item} item\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tstatic _createOn( item ) {\n\t\tconst size = item.is( 'textProxy' ) ? item.offsetSize : 1;\n\n\t\treturn this._createFromPositionAndShift( Position._createBefore( item ), size );\n\t}\n}\n\n// Function used by getEnlarged and getTrimmed methods.\nfunction enlargeTrimSkip( value ) {\n\tif ( value.item.is( 'attributeElement' ) || value.item.is( 'uiElement' ) ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/count\n */\n\n/**\n * Returns the number of items return by the iterator.\n *\n *\t\tcount( [ 1, 2, 3, 4, 5 ] ); // 5;\n *\n * @param {Iterable.<*>} iterator Any iterator.\n * @returns {Number} Number of items returned by that iterator.\n */\nexport default function count( iterator ) {\n\tlet count = 0;\n\n\tfor ( const _ of iterator ) { // eslint-disable-line no-unused-vars\n\t\tcount++;\n\t}\n\n\treturn count;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/selection\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport Range from './range';\nimport Position from './position';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport Node from './node';\nimport Element from './element';\nimport count from '@ckeditor/ckeditor5-utils/src/count';\nimport isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';\nimport DocumentSelection from './documentselection';\n\n/**\n * Class representing an arbirtary selection in the view.\n * See also {@link module:engine/view/documentselection~DocumentSelection}.\n *\n * New selection instances can be created via the constructor or one these methods:\n *\n * * {@link module:engine/view/view~View#createSelection `View#createSelection()`},\n * * {@link module:engine/view/upcastwriter~UpcastWriter#createSelection `UpcastWriter#createSelection()`}.\n *\n * A selection can consist of {@link module:engine/view/range~Range ranges} that can be set by using\n * the {@link module:engine/view/selection~Selection#setTo `Selection#setTo()`} method.\n */\nexport default class Selection {\n\t/**\n\t * Creates new selection instance.\n\t *\n\t * **Note**: The selection constructor is available as a factory method:\n\t *\n\t * * {@link module:engine/view/view~View#createSelection `View#createSelection()`},\n\t * * {@link module:engine/view/upcastwriter~UpcastWriter#createSelection `UpcastWriter#createSelection()`}.\n\t *\n\t * \t\t// Creates empty selection without ranges.\n\t *\t\tconst selection = writer.createSelection();\n\t *\n\t *\t\t// Creates selection at the given range.\n\t *\t\tconst range = writer.createRange( start, end );\n\t *\t\tconst selection = writer.createSelection( range );\n\t *\n\t *\t\t// Creates selection at the given ranges\n\t * \t\tconst ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t *\t\tconst selection = writer.createSelection( ranges );\n\t *\n\t *\t\t// Creates selection from the other selection.\n\t *\t\tconst otherSelection = writer.createSelection();\n\t *\t\tconst selection = writer.createSelection( otherSelection );\n\t *\n\t *\t\t// Creates selection from the document selection.\n\t *\t\tconst selection = writer.createSelection( editor.editing.view.document.selection );\n\t *\n\t * \t\t// Creates selection at the given position.\n\t *\t\tconst position = writer.createPositionFromPath( root, path );\n\t *\t\tconst selection = writer.createSelection( position );\n\t *\n\t *\t\t// Creates collapsed selection at the position of given item and offset.\n\t *\t\tconst paragraph = writer.createContainerElement( 'paragraph' );\n\t *\t\tconst selection = writer.createSelection( paragraph, offset );\n\t *\n\t *\t\t// Creates a range inside an {@link module:engine/view/element~Element element} which starts before the\n\t *\t\t// first child of that element and ends after the last child of that element.\n\t *\t\tconst selection = writer.createSelection( paragraph, 'in' );\n\t *\n\t *\t\t// Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends\n\t *\t\t// just after the item.\n\t *\t\tconst selection = writer.createSelection( paragraph, 'on' );\n\t *\n\t * `Selection`'s constructor allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t *\t\t// Creates backward selection.\n\t *\t\tconst selection = writer.createSelection( range, { backward: true } );\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be properly handled by screen readers).\n\t *\n\t *\t\t// Creates fake selection with label.\n\t *\t\tconst selection = writer.createSelection( range, { fake: true, label: 'foo' } );\n\t *\n\t * @param {module:engine/view/selection~Selectable} [selectable=null]\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Offset or place when selectable is an `Item`.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.backward] Sets this selection instance to be backward.\n\t * @param {Boolean} [options.fake] Sets this selection instance to be marked as `fake`.\n\t * @param {String} [options.label] Label for the fake selection.\n\t */\n\tconstructor( selectable = null, placeOrOffset, options ) {\n\t\t/**\n\t\t * Stores all ranges that are selected.\n\t\t *\n\t\t * @protected\n\t\t * @member {Array.<module:engine/view/range~Range>}\n\t\t */\n\t\tthis._ranges = [];\n\n\t\t/**\n\t\t * Specifies whether the last added range was added as a backward or forward range.\n\t\t *\n\t\t * @protected\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis._lastRangeBackward = false;\n\n\t\t/**\n\t\t * Specifies whether selection instance is fake.\n\t\t *\n\t\t * @private\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis._isFake = false;\n\n\t\t/**\n\t\t * Fake selection's label.\n\t\t *\n\t\t * @private\n\t\t * @member {String}\n\t\t */\n\t\tthis._fakeSelectionLabel = '';\n\n\t\tthis.setTo( selectable, placeOrOffset, options );\n\t}\n\n\t/**\n\t * Returns true if selection instance is marked as `fake`.\n\t *\n\t * @see #setTo\n\t * @returns {Boolean}\n\t */\n\tget isFake() {\n\t\treturn this._isFake;\n\t}\n\n\t/**\n\t * Returns fake selection label.\n\t *\n\t * @see #setTo\n\t * @returns {String}\n\t */\n\tget fakeSelectionLabel() {\n\t\treturn this._fakeSelectionLabel;\n\t}\n\n\t/**\n\t * Selection anchor. Anchor may be described as a position where the selection starts. Together with\n\t * {@link #focus focus} they define the direction of selection, which is important\n\t * when expanding/shrinking selection. Anchor is always the start or end of the most recent added range.\n\t * It may be a bit unintuitive when there are multiple ranges in selection.\n\t *\n\t * @see #focus\n\t * @type {module:engine/view/position~Position}\n\t */\n\tget anchor() {\n\t\tif ( !this._ranges.length ) {\n\t\t\treturn null;\n\t\t}\n\t\tconst range = this._ranges[ this._ranges.length - 1 ];\n\t\tconst anchor = this._lastRangeBackward ? range.end : range.start;\n\n\t\treturn anchor.clone();\n\t}\n\n\t/**\n\t * Selection focus. Focus is a position where the selection ends.\n\t *\n\t * @see #anchor\n\t * @type {module:engine/view/position~Position}\n\t */\n\tget focus() {\n\t\tif ( !this._ranges.length ) {\n\t\t\treturn null;\n\t\t}\n\t\tconst range = this._ranges[ this._ranges.length - 1 ];\n\t\tconst focus = this._lastRangeBackward ? range.start : range.end;\n\n\t\treturn focus.clone();\n\t}\n\n\t/**\n\t * Returns whether the selection is collapsed. Selection is collapsed when there is exactly one range which is\n\t * collapsed.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isCollapsed() {\n\t\treturn this.rangeCount === 1 && this._ranges[ 0 ].isCollapsed;\n\t}\n\n\t/**\n\t * Returns number of ranges in selection.\n\t *\n\t * @type {Number}\n\t */\n\tget rangeCount() {\n\t\treturn this._ranges.length;\n\t}\n\n\t/**\n\t * Specifies whether the {@link #focus} precedes {@link #anchor}.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isBackward() {\n\t\treturn !this.isCollapsed && this._lastRangeBackward;\n\t}\n\n\t/**\n\t * {@link module:engine/view/editableelement~EditableElement EditableElement} instance that contains this selection, or `null`\n\t * if the selection is not inside an editable element.\n\t *\n\t * @type {module:engine/view/editableelement~EditableElement|null}\n\t */\n\tget editableElement() {\n\t\tif ( this.anchor ) {\n\t\t\treturn this.anchor.editableElement;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Returns an iterable that contains copies of all ranges added to the selection.\n\t *\n\t * @returns {Iterable.<module:engine/view/range~Range>}\n\t */\n\t* getRanges() {\n\t\tfor ( const range of this._ranges ) {\n\t\t\tyield range.clone();\n\t\t}\n\t}\n\n\t/**\n\t * Returns copy of the first range in the selection. First range is the one which\n\t * {@link module:engine/view/range~Range#start start} position {@link module:engine/view/position~Position#isBefore is before} start\n\t * position of all other ranges (not to confuse with the first range added to the selection).\n\t * Returns `null` if no ranges are added to selection.\n\t *\n\t * @returns {module:engine/view/range~Range|null}\n\t */\n\tgetFirstRange() {\n\t\tlet first = null;\n\n\t\tfor ( const range of this._ranges ) {\n\t\t\tif ( !first || range.start.isBefore( first.start ) ) {\n\t\t\t\tfirst = range;\n\t\t\t}\n\t\t}\n\n\t\treturn first ? first.clone() : null;\n\t}\n\n\t/**\n\t * Returns copy of the last range in the selection. Last range is the one which {@link module:engine/view/range~Range#end end}\n\t * position {@link module:engine/view/position~Position#isAfter is after} end position of all other ranges (not to confuse\n\t * with the last range added to the selection). Returns `null` if no ranges are added to selection.\n\t *\n\t * @returns {module:engine/view/range~Range|null}\n\t */\n\tgetLastRange() {\n\t\tlet last = null;\n\n\t\tfor ( const range of this._ranges ) {\n\t\t\tif ( !last || range.end.isAfter( last.end ) ) {\n\t\t\t\tlast = range;\n\t\t\t}\n\t\t}\n\n\t\treturn last ? last.clone() : null;\n\t}\n\n\t/**\n\t * Returns copy of the first position in the selection. First position is the position that\n\t * {@link module:engine/view/position~Position#isBefore is before} any other position in the selection ranges.\n\t * Returns `null` if no ranges are added to selection.\n\t *\n\t * @returns {module:engine/view/position~Position|null}\n\t */\n\tgetFirstPosition() {\n\t\tconst firstRange = this.getFirstRange();\n\n\t\treturn firstRange ? firstRange.start.clone() : null;\n\t}\n\n\t/**\n\t * Returns copy of the last position in the selection. Last position is the position that\n\t * {@link module:engine/view/position~Position#isAfter is after} any other position in the selection ranges.\n\t * Returns `null` if no ranges are added to selection.\n\t *\n\t * @returns {module:engine/view/position~Position|null}\n\t */\n\tgetLastPosition() {\n\t\tconst lastRange = this.getLastRange();\n\n\t\treturn lastRange ? lastRange.end.clone() : null;\n\t}\n\n\t/**\n\t * Checks whether, this selection is equal to given selection. Selections are equal if they have same directions,\n\t * same number of ranges and all ranges from one selection equal to a range from other selection.\n\t *\n\t * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} otherSelection\n\t * Selection to compare with.\n\t * @returns {Boolean} `true` if selections are equal, `false` otherwise.\n\t */\n\tisEqual( otherSelection ) {\n\t\tif ( this.isFake != otherSelection.isFake ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this.isFake && this.fakeSelectionLabel != otherSelection.fakeSelectionLabel ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this.rangeCount != otherSelection.rangeCount ) {\n\t\t\treturn false;\n\t\t} else if ( this.rangeCount === 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( !this.anchor.isEqual( otherSelection.anchor ) || !this.focus.isEqual( otherSelection.focus ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor ( const thisRange of this._ranges ) {\n\t\t\tlet found = false;\n\n\t\t\tfor ( const otherRange of otherSelection._ranges ) {\n\t\t\t\tif ( thisRange.isEqual( otherRange ) ) {\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( !found ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Checks whether this selection is similar to given selection. Selections are similar if they have same directions, same\n\t * number of ranges, and all {@link module:engine/view/range~Range#getTrimmed trimmed} ranges from one selection are\n\t * equal to any trimmed range from other selection.\n\t *\n\t * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} otherSelection\n\t * Selection to compare with.\n\t * @returns {Boolean} `true` if selections are similar, `false` otherwise.\n\t */\n\tisSimilar( otherSelection ) {\n\t\tif ( this.isBackward != otherSelection.isBackward ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst numOfRangesA = count( this.getRanges() );\n\t\tconst numOfRangesB = count( otherSelection.getRanges() );\n\n\t\t// If selections have different number of ranges, they cannot be similar.\n\t\tif ( numOfRangesA != numOfRangesB ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If both selections have no ranges, they are similar.\n\t\tif ( numOfRangesA == 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Check if each range in one selection has a similar range in other selection.\n\t\tfor ( let rangeA of this.getRanges() ) {\n\t\t\trangeA = rangeA.getTrimmed();\n\n\t\t\tlet found = false;\n\n\t\t\tfor ( let rangeB of otherSelection.getRanges() ) {\n\t\t\t\trangeB = rangeB.getTrimmed();\n\n\t\t\t\tif ( rangeA.start.isEqual( rangeB.start ) && rangeA.end.isEqual( rangeB.end ) ) {\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// For `rangeA`, neither range in `otherSelection` was similar. So selections are not similar.\n\t\t\tif ( !found ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// There were no ranges that weren't matched. Selections are similar.\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns the selected element. {@link module:engine/view/element~Element Element} is considered as selected if there is only\n\t * one range in the selection, and that range contains exactly one element.\n\t * Returns `null` if there is no selected element.\n\t *\n\t * @returns {module:engine/view/element~Element|null}\n\t */\n\tgetSelectedElement() {\n\t\tif ( this.rangeCount !== 1 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst range = this.getFirstRange();\n\n\t\tlet nodeAfterStart = range.start.nodeAfter;\n\t\tlet nodeBeforeEnd = range.end.nodeBefore;\n\n\t\t// Handle the situation when selection position is at the beginning / at the end of a text node.\n\t\t// In such situation `.nodeAfter` and `.nodeBefore` are `null` but the selection still might be spanning\n\t\t// over one element.\n\t\t//\n\t\t// <p>Foo{<span class=\"widget\"></span>}bar</p> vs <p>Foo[<span class=\"widget\"></span>]bar</p>\n\t\t//\n\t\t// These are basically the same selections, only the difference is if the selection position is at\n\t\t// at the end/at the beginning of a text node or just before/just after the text node.\n\t\t//\n\t\tif ( range.start.parent.is( 'text' ) && range.start.isAtEnd && range.start.parent.nextSibling ) {\n\t\t\tnodeAfterStart = range.start.parent.nextSibling;\n\t\t}\n\n\t\tif ( range.end.parent.is( 'text' ) && range.end.isAtStart && range.end.parent.previousSibling ) {\n\t\t\tnodeBeforeEnd = range.end.parent.previousSibling;\n\t\t}\n\n\t\treturn ( nodeAfterStart instanceof Element && nodeAfterStart == nodeBeforeEnd ) ? nodeAfterStart : null;\n\t}\n\n\t/**\n\t * Sets this selection's ranges and direction to the specified location based on the given\n\t * {@link module:engine/view/selection~Selectable selectable}.\n\t *\n\t *\t\t// Sets selection to the given range.\n\t *\t\tconst range = writer.createRange( start, end );\n\t *\t\tselection.setTo( range );\n\t *\n\t *\t\t// Sets selection to given ranges.\n\t * \t\tconst ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t *\t\tselection.setTo( range );\n\t *\n\t *\t\t// Sets selection to the other selection.\n\t *\t\tconst otherSelection = writer.createSelection();\n\t *\t\tselection.setTo( otherSelection );\n\t *\n\t *\t \t// Sets selection to contents of DocumentSelection.\n\t *\t\tselection.setTo( editor.editing.view.document.selection );\n\t *\n\t * \t\t// Sets collapsed selection at the given position.\n\t *\t\tconst position = writer.createPositionAt( root, path );\n\t *\t\tselection.setTo( position );\n\t *\n\t * \t\t// Sets collapsed selection at the position of given item and offset.\n\t *\t\tselection.setTo( paragraph, offset );\n\t *\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t *\t\tselection.setTo( paragraph, 'in' );\n\t *\n\t * Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends just after the item.\n\t *\n\t *\t\tselection.setTo( paragraph, 'on' );\n\t *\n\t * \t\t// Clears selection. Removes all ranges.\n\t *\t\tselection.setTo( null );\n\t *\n\t * `Selection#setTo()` method allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t *\t\t// Sets selection as backward.\n\t *\t\tselection.setTo( range, { backward: true } );\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be properly handled by screen readers).\n\t *\n\t *\t\t// Creates fake selection with label.\n\t *\t\tselection.setTo( range, { fake: true, label: 'foo' } );\n\t *\n\t * @fires change\n\t * @param {module:engine/view/selection~Selectable} selectable\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Sets place or offset of the selection.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.backward] Sets this selection instance to be backward.\n\t * @param {Boolean} [options.fake] Sets this selection instance to be marked as `fake`.\n\t * @param {String} [options.label] Label for the fake selection.\n\t */\n\tsetTo( selectable, placeOrOffset, options ) {\n\t\tif ( selectable === null ) {\n\t\t\tthis._setRanges( [] );\n\t\t\tthis._setFakeOptions( placeOrOffset );\n\t\t} else if ( selectable instanceof Selection || selectable instanceof DocumentSelection ) {\n\t\t\tthis._setRanges( selectable.getRanges(), selectable.isBackward );\n\t\t\tthis._setFakeOptions( { fake: selectable.isFake, label: selectable.fakeSelectionLabel } );\n\t\t} else if ( selectable instanceof Range ) {\n\t\t\tthis._setRanges( [ selectable ], placeOrOffset && placeOrOffset.backward );\n\t\t\tthis._setFakeOptions( placeOrOffset );\n\t\t} else if ( selectable instanceof Position ) {\n\t\t\tthis._setRanges( [ new Range( selectable ) ] );\n\t\t\tthis._setFakeOptions( placeOrOffset );\n\t\t} else if ( selectable instanceof Node ) {\n\t\t\tconst backward = !!options && !!options.backward;\n\t\t\tlet range;\n\n\t\t\tif ( placeOrOffset === undefined ) {\n\t\t\t\t/**\n\t\t\t\t * selection.setTo requires the second parameter when the first parameter is a node.\n\t\t\t\t *\n\t\t\t\t * @error view-selection-setTo-required-second-parameter\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'view-selection-setTo-required-second-parameter: ' +\n\t\t\t\t\t'selection.setTo requires the second parameter when the first parameter is a node.'\n\t\t\t\t);\n\t\t\t} else if ( placeOrOffset == 'in' ) {\n\t\t\t\trange = Range._createIn( selectable );\n\t\t\t} else if ( placeOrOffset == 'on' ) {\n\t\t\t\trange = Range._createOn( selectable );\n\t\t\t} else {\n\t\t\t\trange = new Range( Position._createAt( selectable, placeOrOffset ) );\n\t\t\t}\n\n\t\t\tthis._setRanges( [ range ], backward );\n\t\t\tthis._setFakeOptions( options );\n\t\t} else if ( isIterable( selectable ) ) {\n\t\t\t// We assume that the selectable is an iterable of ranges.\n\t\t\t// Array.from() is used to prevent setting ranges to the old iterable\n\t\t\tthis._setRanges( selectable, placeOrOffset && placeOrOffset.backward );\n\t\t\tthis._setFakeOptions( placeOrOffset );\n\t\t} else {\n\t\t\t/**\n\t\t\t * Cannot set selection to given place.\n\t\t\t *\n\t\t\t * @error view-selection-setTo-not-selectable\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-selection-setTo-not-selectable: Cannot set selection to given place.' );\n\t\t}\n\n\t\tthis.fire( 'change' );\n\t}\n\n\t/**\n\t * Moves {@link #focus} to the specified location.\n\t *\n\t * The location can be specified in the same form as {@link module:engine/view/view~View#createPositionAt view.createPositionAt()}\n\t * parameters.\n\t *\n\t * @fires change\n\t * @param {module:engine/view/item~Item|module:engine/view/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tsetFocus( itemOrPosition, offset ) {\n\t\tif ( this.anchor === null ) {\n\t\t\t/**\n\t\t\t * Cannot set selection focus if there are no ranges in selection.\n\t\t\t *\n\t\t\t * @error view-selection-setFocus-no-ranges\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'view-selection-setFocus-no-ranges: Cannot set selection focus if there are no ranges in selection.'\n\t\t\t);\n\t\t}\n\n\t\tconst newFocus = Position._createAt( itemOrPosition, offset );\n\n\t\tif ( newFocus.compareWith( this.focus ) == 'same' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst anchor = this.anchor;\n\n\t\tthis._ranges.pop();\n\n\t\tif ( newFocus.compareWith( anchor ) == 'before' ) {\n\t\t\tthis._addRange( new Range( newFocus, anchor ), true );\n\t\t} else {\n\t\t\tthis._addRange( new Range( anchor, newFocus ) );\n\t\t}\n\n\t\tthis.fire( 'change' );\n\t}\n\n\t/**\n\t * Checks whether object is of given type following the convention set by\n\t * {@link module:engine/view/node~Node#is `Node#is()`}.\n\t *\n\t *\t\tconst selection = new Selection( ... );\n\t *\n\t *\t\tselection.is( 'selection' ); // true\n\t *\t\tselection.is( 'node' ); // false\n\t *\t\tselection.is( 'element' ); // false\n\t *\n\t * @param {String} type\n\t * @returns {Boolean}\n\t */\n\tis( type ) {\n\t\treturn type == 'selection';\n\t}\n\n\t/**\n\t * Replaces all ranges that were added to the selection with given array of ranges. Last range of the array\n\t * is treated like the last added range and is used to set {@link #anchor anchor} and {@link #focus focus}.\n\t * Accepts a flag describing in which way the selection is made.\n\t *\n\t * @private\n\t * @param {Iterable.<module:engine/view/range~Range>} newRanges Iterable object of ranges to set.\n\t * @param {Boolean} [isLastBackward=false] Flag describing if last added range was selected forward - from start to end\n\t * (`false`) or backward - from end to start (`true`). Defaults to `false`.\n\t */\n\t_setRanges( newRanges, isLastBackward = false ) {\n\t\t// New ranges should be copied to prevent removing them by setting them to `[]` first.\n\t\t// Only applies to situations when selection is set to the same selection or same selection's ranges.\n\t\tnewRanges = Array.from( newRanges );\n\n\t\tthis._ranges = [];\n\n\t\tfor ( const range of newRanges ) {\n\t\t\tthis._addRange( range );\n\t\t}\n\n\t\tthis._lastRangeBackward = !!isLastBackward;\n\t}\n\n\t/**\n\t * Sets this selection instance to be marked as `fake`. A fake selection does not render as browser native selection\n\t * over selected elements and is hidden to the user. This way, no native selection UI artifacts are displayed to\n\t * the user and selection over elements can be represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM (and be\n\t * properly handled by screen readers).\n\t *\n\t * @private\n\t * @param {Object} [options] Options.\n\t * @param {Boolean} [options.fake] If set to true selection will be marked as `fake`.\n\t * @param {String} [options.label=''] Fake selection label.\n\t */\n\t_setFakeOptions( options = {} ) {\n\t\tthis._isFake = !!options.fake;\n\t\tthis._fakeSelectionLabel = options.fake ? options.label || '' : '';\n\t}\n\n\t/**\n\t * Adds a range to the selection. Added range is copied. This means that passed range is not saved in the\n\t * selection instance and you can safely operate on it.\n\t *\n\t * Accepts a flag describing in which way the selection is made - passed range might be selected from\n\t * {@link module:engine/view/range~Range#start start} to {@link module:engine/view/range~Range#end end}\n\t * or from {@link module:engine/view/range~Range#end end} to {@link module:engine/view/range~Range#start start}.\n\t * The flag is used to set {@link #anchor anchor} and {@link #focus focus} properties.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-selection-range-intersects` if added range intersects\n\t * with ranges already stored in Selection instance.\n\t *\n\t * @private\n\t * @fires change\n\t * @param {module:engine/view/range~Range} range\n\t * @param {Boolean} [isBackward]\n\t */\n\t_addRange( range, isBackward = false ) {\n\t\tif ( !( range instanceof Range ) ) {\n\t\t\t/**\n\t\t\t * Selection range set to an object that is not an instance of {@link module:engine/view/range~Range}.\n\t\t\t *\n\t\t\t * @error view-selection-add-range-not-range\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'view-selection-add-range-not-range: ' +\n\t\t\t\t'Selection range set to an object that is not an instance of view.Range'\n\t\t\t);\n\t\t}\n\n\t\tthis._pushRange( range );\n\t\tthis._lastRangeBackward = !!isBackward;\n\t}\n\n\t/**\n\t * Adds range to selection - creates copy of given range so it can be safely used and modified.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-selection-range-intersects` if added range intersects\n\t * with ranges already stored in selection instance.\n\t *\n\t * @private\n\t * @param {module:engine/view/range~Range} range\n\t */\n\t_pushRange( range ) {\n\t\tfor ( const storedRange of this._ranges ) {\n\t\t\tif ( range.isIntersecting( storedRange ) ) {\n\t\t\t\t/**\n\t\t\t\t * Trying to add a range that intersects with another range from selection.\n\t\t\t\t *\n\t\t\t\t * @error view-selection-range-intersects\n\t\t\t\t * @param {module:engine/view/range~Range} addedRange Range that was added to the selection.\n\t\t\t\t * @param {module:engine/view/range~Range} intersectingRange Range from selection that intersects with `addedRange`.\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'view-selection-range-intersects: Trying to add a range that intersects with another range from selection.',\n\t\t\t\t\t{ addedRange: range, intersectingRange: storedRange }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tthis._ranges.push( new Range( range.start, range.end ) );\n\t}\n\n\t/**\n\t * Fired whenever selection ranges are changed through {@link ~Selection Selection API}.\n\t *\n\t * @event change\n\t */\n}\n\nmix( Selection, EmitterMixin );\n\n/**\n * An entity that is used to set selection.\n *\n * See also {@link module:engine/view/selection~Selection#setTo}\n *\n * @typedef {\n * module:engine/view/selection~Selection|\n * module:engine/view/documentselection~DocumentSelection|\n * module:engine/view/position~Position|\n * Iterable.<module:engine/view/range~Range>|\n * module:engine/view/range~Range|\n * module:engine/view/item~Item|\n * null\n * } module:engine/view/selection~Selectable\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/documentselection\n */\n\nimport Selection from './selection';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\n\n/**\n * Class representing the document selection in the view.\n *\n * Its instance is available in {@link module:engine/view/document~Document#selection `Document#selection`}.\n *\n * It is similar to {@link module:engine/view/selection~Selection} but\n * it has a read-only API and can be modified only by the writer available in\n * the {@link module:engine/view/view~View#change `View#change()`} block\n * (so via {@link module:engine/view/downcastwriter~DowncastWriter#setSelection `DowncastWriter#setSelection()`}).\n */\nexport default class DocumentSelection {\n\t/**\n\t * Creates new DocumentSelection instance.\n\t *\n\t * \t\t// Creates empty selection without ranges.\n\t *\t\tconst selection = new DocumentSelection();\n\t *\n\t *\t\t// Creates selection at the given range.\n\t *\t\tconst range = writer.createRange( start, end );\n\t *\t\tconst selection = new DocumentSelection( range );\n\t *\n\t *\t\t// Creates selection at the given ranges\n\t * \t\tconst ranges = [ writer.createRange( start1, end2 ), writer.createRange( start2, end2 ) ];\n\t *\t\tconst selection = new DocumentSelection( ranges );\n\t *\n\t *\t\t// Creates selection from the other selection.\n\t *\t\tconst otherSelection = writer.createSelection();\n\t *\t\tconst selection = new DocumentSelection( otherSelection );\n\t *\n\t * \t\t// Creates selection at the given position.\n\t *\t\tconst position = writer.createPositionAt( root, offset );\n\t *\t\tconst selection = new DocumentSelection( position );\n\t *\n\t *\t\t// Creates collapsed selection at the position of given item and offset.\n\t *\t\tconst paragraph = writer.createContainerElement( 'paragraph' );\n\t *\t\tconst selection = new DocumentSelection( paragraph, offset );\n\t *\n\t *\t\t// Creates a range inside an {@link module:engine/view/element~Element element} which starts before the\n\t *\t\t// first child of that element and ends after the last child of that element.\n\t *\t\tconst selection = new DocumentSelection( paragraph, 'in' );\n\t *\n\t *\t\t// Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends\n\t *\t\t// just after the item.\n\t *\t\tconst selection = new DocumentSelection( paragraph, 'on' );\n\t *\n\t * `Selection`'s constructor allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t *\t\t// Creates backward selection.\n\t *\t\tconst selection = new DocumentSelection( range, { backward: true } );\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be properly handled by screen readers).\n\t *\n\t *\t\t// Creates fake selection with label.\n\t *\t\tconst selection = new DocumentSelection( range, { fake: true, label: 'foo' } );\n\t *\n\t * @param {module:engine/view/selection~Selectable} [selectable=null]\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Offset or place when selectable is an `Item`.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.backward] Sets this selection instance to be backward.\n\t * @param {Boolean} [options.fake] Sets this selection instance to be marked as `fake`.\n\t * @param {String} [options.label] Label for the fake selection.\n\t */\n\tconstructor( selectable = null, placeOrOffset, options ) {\n\t\t/**\n\t\t * Selection is used internally (`DocumentSelection` is a proxy to that selection).\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/view/selection~Selection}\n\t\t */\n\t\tthis._selection = new Selection();\n\n\t\t// Delegate change event to be fired on DocumentSelection instance.\n\t\tthis._selection.delegate( 'change' ).to( this );\n\n\t\t// Set selection data.\n\t\tthis._selection.setTo( selectable, placeOrOffset, options );\n\t}\n\n\t/**\n\t * Returns true if selection instance is marked as `fake`.\n\t *\n\t * @see #_setTo\n\t * @returns {Boolean}\n\t */\n\tget isFake() {\n\t\treturn this._selection.isFake;\n\t}\n\n\t/**\n\t * Returns fake selection label.\n\t *\n\t * @see #_setTo\n\t * @returns {String}\n\t */\n\tget fakeSelectionLabel() {\n\t\treturn this._selection.fakeSelectionLabel;\n\t}\n\n\t/**\n\t * Selection anchor. Anchor may be described as a position where the selection starts. Together with\n\t * {@link #focus focus} they define the direction of selection, which is important\n\t * when expanding/shrinking selection. Anchor is always the start or end of the most recent added range.\n\t * It may be a bit unintuitive when there are multiple ranges in selection.\n\t *\n\t * @see #focus\n\t * @type {module:engine/view/position~Position}\n\t */\n\tget anchor() {\n\t\treturn this._selection.anchor;\n\t}\n\n\t/**\n\t * Selection focus. Focus is a position where the selection ends.\n\t *\n\t * @see #anchor\n\t * @type {module:engine/view/position~Position}\n\t */\n\tget focus() {\n\t\treturn this._selection.focus;\n\t}\n\n\t/**\n\t * Returns whether the selection is collapsed. Selection is collapsed when there is exactly one range which is\n\t * collapsed.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isCollapsed() {\n\t\treturn this._selection.isCollapsed;\n\t}\n\n\t/**\n\t * Returns number of ranges in selection.\n\t *\n\t * @type {Number}\n\t */\n\tget rangeCount() {\n\t\treturn this._selection.rangeCount;\n\t}\n\n\t/**\n\t * Specifies whether the {@link #focus} precedes {@link #anchor}.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isBackward() {\n\t\treturn this._selection.isBackward;\n\t}\n\n\t/**\n\t * {@link module:engine/view/editableelement~EditableElement EditableElement} instance that contains this selection, or `null`\n\t * if the selection is not inside an editable element.\n\t *\n\t * @type {module:engine/view/editableelement~EditableElement|null}\n\t */\n\tget editableElement() {\n\t\treturn this._selection.editableElement;\n\t}\n\n\t/**\n\t * Used for the compatibility with the {@link module:engine/view/selection~Selection#isEqual} method.\n\t *\n\t * @protected\n\t */\n\tget _ranges() {\n\t\treturn this._selection._ranges;\n\t}\n\n\t/**\n\t * Returns an iterable that contains copies of all ranges added to the selection.\n\t *\n\t * @returns {Iterable.<module:engine/view/range~Range>}\n\t */\n\t* getRanges() {\n\t\tyield* this._selection.getRanges();\n\t}\n\n\t/**\n\t * Returns copy of the first range in the selection. First range is the one which\n\t * {@link module:engine/view/range~Range#start start} position {@link module:engine/view/position~Position#isBefore is before} start\n\t * position of all other ranges (not to confuse with the first range added to the selection).\n\t * Returns `null` if no ranges are added to selection.\n\t *\n\t * @returns {module:engine/view/range~Range|null}\n\t */\n\tgetFirstRange() {\n\t\treturn this._selection.getFirstRange();\n\t}\n\n\t/**\n\t * Returns copy of the last range in the selection. Last range is the one which {@link module:engine/view/range~Range#end end}\n\t * position {@link module:engine/view/position~Position#isAfter is after} end position of all other ranges (not to confuse\n\t * with the last range added to the selection). Returns `null` if no ranges are added to selection.\n\t *\n\t * @returns {module:engine/view/range~Range|null}\n\t */\n\tgetLastRange() {\n\t\treturn this._selection.getLastRange();\n\t}\n\n\t/**\n\t * Returns copy of the first position in the selection. First position is the position that\n\t * {@link module:engine/view/position~Position#isBefore is before} any other position in the selection ranges.\n\t * Returns `null` if no ranges are added to selection.\n\t *\n\t * @returns {module:engine/view/position~Position|null}\n\t */\n\tgetFirstPosition() {\n\t\treturn this._selection.getFirstPosition();\n\t}\n\n\t/**\n\t * Returns copy of the last position in the selection. Last position is the position that\n\t * {@link module:engine/view/position~Position#isAfter is after} any other position in the selection ranges.\n\t * Returns `null` if no ranges are added to selection.\n\t *\n\t * @returns {module:engine/view/position~Position|null}\n\t */\n\tgetLastPosition() {\n\t\treturn this._selection.getLastPosition();\n\t}\n\n\t/**\n\t * Returns the selected element. {@link module:engine/view/element~Element Element} is considered as selected if there is only\n\t * one range in the selection, and that range contains exactly one element.\n\t * Returns `null` if there is no selected element.\n\t *\n\t * @returns {module:engine/view/element~Element|null}\n\t */\n\tgetSelectedElement() {\n\t\treturn this._selection.getSelectedElement();\n\t}\n\n\t/**\n\t * Checks whether, this selection is equal to given selection. Selections are equal if they have same directions,\n\t * same number of ranges and all ranges from one selection equal to a range from other selection.\n\t *\n\t * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} otherSelection\n\t * Selection to compare with.\n\t * @returns {Boolean} `true` if selections are equal, `false` otherwise.\n\t */\n\tisEqual( otherSelection ) {\n\t\treturn this._selection.isEqual( otherSelection );\n\t}\n\n\t/**\n\t * Checks whether this selection is similar to given selection. Selections are similar if they have same directions, same\n\t * number of ranges, and all {@link module:engine/view/range~Range#getTrimmed trimmed} ranges from one selection are\n\t * equal to any trimmed range from other selection.\n\t *\n\t * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} otherSelection\n\t * Selection to compare with.\n\t * @returns {Boolean} `true` if selections are similar, `false` otherwise.\n\t */\n\tisSimilar( otherSelection ) {\n\t\treturn this._selection.isSimilar( otherSelection );\n\t}\n\n\t/**\n\t * Checks whether object is of given type following the convention set by\n\t * {@link module:engine/view/node~Node#is `Node#is()`}.\n\t *\n\t *\t\tconst selection = new DocumentSelection( ... );\n\t *\n\t *\t\tselection.is( 'selection' ); // true\n\t *\t\tselection.is( 'documentSelection' ); // true\n\t *\t\tselection.is( 'node' ); // false\n\t *\t\tselection.is( 'element' ); // false\n\t *\n\t * @param {String} type\n\t * @returns {Boolean}\n\t */\n\tis( type ) {\n\t\treturn type == 'selection' || type == 'documentSelection';\n\t}\n\n\t/**\n\t * Sets this selection's ranges and direction to the specified location based on the given\n\t * {@link module:engine/view/selection~Selectable selectable}.\n\t *\n\t *\t\t// Sets selection to the given range.\n\t *\t\tconst range = writer.createRange( start, end );\n\t *\t\tdocumentSelection._setTo( range );\n\t *\n\t *\t\t// Sets selection to given ranges.\n\t * \t\tconst ranges = [ writer.createRange( start1, end2 ), writer.createRange( start2, end2 ) ];\n\t *\t\tdocumentSelection._setTo( range );\n\t *\n\t *\t\t// Sets selection to the other selection.\n\t *\t\tconst otherSelection = writer.createSelection();\n\t *\t\tdocumentSelection._setTo( otherSelection );\n\t *\n\t * \t\t// Sets collapsed selection at the given position.\n\t *\t\tconst position = writer.createPositionAt( root, offset );\n\t *\t\tdocumentSelection._setTo( position );\n\t *\n\t * \t\t// Sets collapsed selection at the position of given item and offset.\n\t *\t\tdocumentSelection._setTo( paragraph, offset );\n\t *\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t *\t\tdocumentSelection._setTo( paragraph, 'in' );\n\t *\n\t * Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends just after the item.\n\t *\n\t *\t\tdocumentSelection._setTo( paragraph, 'on' );\n\t *\n\t * \t\t// Clears selection. Removes all ranges.\n\t *\t\tdocumentSelection._setTo( null );\n\t *\n\t * `Selection#_setTo()` method allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t *\t\t// Sets selection as backward.\n\t *\t\tdocumentSelection._setTo( range, { backward: true } );\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to des cribe fake selection in DOM\n\t * (and be properly handled by screen readers).\n\t *\n\t *\t\t// Creates fake selection with label.\n\t *\t\tdocumentSelection._setTo( range, { fake: true, label: 'foo' } );\n\t *\n\t * @protected\n\t * @fires change\n\t * @param {module:engine/view/selection~Selectable} selectable\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Sets place or offset of the selection.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.backward] Sets this selection instance to be backward.\n\t * @param {Boolean} [options.fake] Sets this selection instance to be marked as `fake`.\n\t * @param {String} [options.label] Label for the fake selection.\n\t */\n\t_setTo( selectable, placeOrOffset, options ) {\n\t\tthis._selection.setTo( selectable, placeOrOffset, options );\n\t}\n\n\t/**\n\t * Moves {@link #focus} to the specified location.\n\t *\n\t * The location can be specified in the same form as {@link module:engine/view/view~View#createPositionAt view.createPositionAt()}\n\t * parameters.\n\t *\n\t * @protected\n\t * @fires change\n\t * @param {module:engine/view/item~Item|module:engine/view/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\t_setFocus( itemOrPosition, offset ) {\n\t\tthis._selection.setFocus( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Fired whenever selection ranges are changed through {@link ~DocumentSelection Selection API}.\n\t *\n\t * @event change\n\t */\n}\n\nmix( DocumentSelection, EmitterMixin );\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/collection\n */\n\nimport EmitterMixin from './emittermixin';\nimport CKEditorError from './ckeditorerror';\nimport uid from './uid';\nimport mix from './mix';\n\n/**\n * Collections are ordered sets of objects. Items in the collection can be retrieved by their indexes\n * in the collection (like in an array) or by their ids.\n *\n * If an object without an `id` property is being added to the collection, the `id` property will be generated\n * automatically. Note that the automatically generated id is unique only within this single collection instance.\n *\n * By default an item in the collection is identified by its `id` property. The name of the identifier can be\n * configured through the constructor of the collection.\n *\n * @mixes module:utils/emittermixin~EmitterMixin\n */\nexport default class Collection {\n\t/**\n\t * Creates a new Collection instance.\n\t *\n\t * @param {Object} [options={}] The options object.\n\t * @param {String} [options.idProperty='id'] The name of the property which is considered to identify an item.\n\t */\n\tconstructor( options = {} ) {\n\t\t/**\n\t\t * The internal list of items in the collection.\n\t\t *\n\t\t * @private\n\t\t * @member {Object[]}\n\t\t */\n\t\tthis._items = [];\n\n\t\t/**\n\t\t * The internal map of items in the collection.\n\t\t *\n\t\t * @private\n\t\t * @member {Map}\n\t\t */\n\t\tthis._itemMap = new Map();\n\n\t\t/**\n\t\t * The name of the property which is considered to identify an item.\n\t\t *\n\t\t * @private\n\t\t * @member {String}\n\t\t */\n\t\tthis._idProperty = options.idProperty || 'id';\n\n\t\t/**\n\t\t * A helper mapping external items of a bound collection ({@link #bindTo})\n\t\t * and actual items of this collection. It provides information\n\t\t * necessary to properly remove items bound to another collection.\n\t\t *\n\t\t * See {@link #_bindToInternalToExternalMap}.\n\t\t *\n\t\t * @protected\n\t\t * @member {WeakMap}\n\t\t */\n\t\tthis._bindToExternalToInternalMap = new WeakMap();\n\n\t\t/**\n\t\t * A helper mapping items of this collection to external items of a bound collection\n\t\t * ({@link #bindTo}). It provides information necessary to manage the bindings, e.g.\n\t\t * to avoid loops in two–way bindings.\n\t\t *\n\t\t * See {@link #_bindToExternalToInternalMap}.\n\t\t *\n\t\t * @protected\n\t\t * @member {WeakMap}\n\t\t */\n\t\tthis._bindToInternalToExternalMap = new WeakMap();\n\n\t\t/**\n\t\t * Stores indexes of skipped items from bound external collection.\n\t\t *\n\t\t * @private\n\t\t * @member {Array}\n\t\t */\n\t\tthis._skippedIndexesFromExternal = [];\n\n\t\t/**\n\t\t * A collection instance this collection is bound to as a result\n\t\t * of calling {@link #bindTo} method.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:utils/collection~Collection} #_bindToCollection\n\t\t */\n\t}\n\n\t/**\n\t * The number of items available in the collection.\n\t *\n\t * @member {Number} #length\n\t */\n\tget length() {\n\t\treturn this._items.length;\n\t}\n\n\t/**\n\t * Returns the first item from the collection or null when collection is empty.\n\t *\n\t * @returns {Object|null} The first item or `null` if collection is empty.\n\t */\n\tget first() {\n\t\treturn this._items[ 0 ] || null;\n\t}\n\n\t/**\n\t * Returns the last item from the collection or null when collection is empty.\n\t *\n\t * @returns {Object|null} The last item or `null` if collection is empty.\n\t */\n\tget last() {\n\t\treturn this._items[ this.length - 1 ] || null;\n\t}\n\n\t/**\n\t * Adds an item into the collection.\n\t *\n\t * If the item does not have an id, then it will be automatically generated and set on the item.\n\t *\n\t * @chainable\n\t * @param {Object} item\n\t * @param {Number} [index] The position of the item in the collection. The item\n\t * is pushed to the collection when `index` not specified.\n\t * @fires add\n\t */\n\tadd( item, index ) {\n\t\tlet itemId;\n\t\tconst idProperty = this._idProperty;\n\n\t\tif ( ( idProperty in item ) ) {\n\t\t\titemId = item[ idProperty ];\n\n\t\t\tif ( typeof itemId != 'string' ) {\n\t\t\t\t/**\n\t\t\t\t * This item's id should be a string.\n\t\t\t\t *\n\t\t\t\t * @error collection-add-invalid-id\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'collection-add-invalid-id' );\n\t\t\t}\n\n\t\t\tif ( this.get( itemId ) ) {\n\t\t\t\t/**\n\t\t\t\t * This item already exists in the collection.\n\t\t\t\t *\n\t\t\t\t * @error collection-add-item-already-exists\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'collection-add-item-already-exists' );\n\t\t\t}\n\t\t} else {\n\t\t\titem[ idProperty ] = itemId = uid();\n\t\t}\n\n\t\t// TODO: Use ES6 default function argument.\n\t\tif ( index === undefined ) {\n\t\t\tindex = this._items.length;\n\t\t} else if ( index > this._items.length || index < 0 ) {\n\t\t\t/**\n\t\t\t * The index number has invalid value.\n\t\t\t *\n\t\t\t * @error collection-add-item-bad-index\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'collection-add-item-invalid-index' );\n\t\t}\n\n\t\tthis._items.splice( index, 0, item );\n\n\t\tthis._itemMap.set( itemId, item );\n\n\t\tthis.fire( 'add', item, index );\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets item by its id or index.\n\t *\n\t * @param {String|Number} idOrIndex The item id or index in the collection.\n\t * @returns {Object|null} The requested item or `null` if such item does not exist.\n\t */\n\tget( idOrIndex ) {\n\t\tlet item;\n\n\t\tif ( typeof idOrIndex == 'string' ) {\n\t\t\titem = this._itemMap.get( idOrIndex );\n\t\t} else if ( typeof idOrIndex == 'number' ) {\n\t\t\titem = this._items[ idOrIndex ];\n\t\t} else {\n\t\t\t/**\n\t\t\t * Index or id must be given.\n\t\t\t *\n\t\t\t * @error collection-get-invalid-arg\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'collection-get-invalid-arg: Index or id must be given.' );\n\t\t}\n\n\t\treturn item || null;\n\t}\n\n\t/**\n\t * Returns a boolean indicating whether the collection contains an item.\n\t *\n\t * @param {Object|String} itemOrId The item or its id in the collection.\n\t * @returns {Boolean} `true` if the collection contains the item, `false` otherwise.\n\t */\n\thas( itemOrId ) {\n\t\tif ( typeof itemOrId == 'string' ) {\n\t\t\treturn this._itemMap.has( itemOrId );\n\t\t} else { // Object\n\t\t\tconst idProperty = this._idProperty;\n\t\t\tconst id = itemOrId[ idProperty ];\n\n\t\t\treturn this._itemMap.has( id );\n\t\t}\n\t}\n\n\t/**\n\t * Gets index of item in the collection.\n\t * When item is not defined in the collection then index will be equal -1.\n\t *\n\t * @param {Object|String} itemOrId The item or its id in the collection.\n\t * @returns {Number} Index of given item.\n\t */\n\tgetIndex( itemOrId ) {\n\t\tlet item;\n\n\t\tif ( typeof itemOrId == 'string' ) {\n\t\t\titem = this._itemMap.get( itemOrId );\n\t\t} else {\n\t\t\titem = itemOrId;\n\t\t}\n\n\t\treturn this._items.indexOf( item );\n\t}\n\n\t/**\n\t * Removes an item from the collection.\n\t *\n\t * @param {Object|Number|String} subject The item to remove, its id or index in the collection.\n\t * @returns {Object} The removed item.\n\t * @fires remove\n\t */\n\tremove( subject ) {\n\t\tlet index, id, item;\n\t\tlet itemDoesNotExist = false;\n\t\tconst idProperty = this._idProperty;\n\n\t\tif ( typeof subject == 'string' ) {\n\t\t\tid = subject;\n\t\t\titem = this._itemMap.get( id );\n\t\t\titemDoesNotExist = !item;\n\n\t\t\tif ( item ) {\n\t\t\t\tindex = this._items.indexOf( item );\n\t\t\t}\n\t\t} else if ( typeof subject == 'number' ) {\n\t\t\tindex = subject;\n\t\t\titem = this._items[ index ];\n\t\t\titemDoesNotExist = !item;\n\n\t\t\tif ( item ) {\n\t\t\t\tid = item[ idProperty ];\n\t\t\t}\n\t\t} else {\n\t\t\titem = subject;\n\t\t\tid = item[ idProperty ];\n\t\t\tindex = this._items.indexOf( item );\n\t\t\titemDoesNotExist = ( index == -1 || !this._itemMap.get( id ) );\n\t\t}\n\n\t\tif ( itemDoesNotExist ) {\n\t\t\t/**\n\t\t\t * Item not found.\n\t\t\t *\n\t\t\t * @error collection-remove-404\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'collection-remove-404: Item not found.' );\n\t\t}\n\n\t\tthis._items.splice( index, 1 );\n\t\tthis._itemMap.delete( id );\n\n\t\tconst externalItem = this._bindToInternalToExternalMap.get( item );\n\t\tthis._bindToInternalToExternalMap.delete( item );\n\t\tthis._bindToExternalToInternalMap.delete( externalItem );\n\n\t\tthis.fire( 'remove', item, index );\n\n\t\treturn item;\n\t}\n\n\t/**\n\t * Executes the callback for each item in the collection and composes an array or values returned by this callback.\n\t *\n\t * @param {Function} callback\n\t * @param {Object} callback.item\n\t * @param {Number} callback.index\n\t * @param {Object} ctx Context in which the `callback` will be called.\n\t * @returns {Array} The result of mapping.\n\t */\n\tmap( callback, ctx ) {\n\t\treturn this._items.map( callback, ctx );\n\t}\n\n\t/**\n\t * Finds the first item in the collection for which the `callback` returns a true value.\n\t *\n\t * @param {Function} callback\n\t * @param {Object} callback.item\n\t * @param {Number} callback.index\n\t * @param {Object} ctx Context in which the `callback` will be called.\n\t * @returns {Object} The item for which `callback` returned a true value.\n\t */\n\tfind( callback, ctx ) {\n\t\treturn this._items.find( callback, ctx );\n\t}\n\n\t/**\n\t * Returns an array with items for which the `callback` returned a true value.\n\t *\n\t * @param {Function} callback\n\t * @param {Object} callback.item\n\t * @param {Number} callback.index\n\t * @param {Object} ctx Context in which the `callback` will be called.\n\t * @returns {Object[]} The array with matching items.\n\t */\n\tfilter( callback, ctx ) {\n\t\treturn this._items.filter( callback, ctx );\n\t}\n\n\t/**\n\t * Removes all items from the collection and destroys the binding created using\n\t * {@link #bindTo}.\n\t */\n\tclear() {\n\t\tif ( this._bindToCollection ) {\n\t\t\tthis.stopListening( this._bindToCollection );\n\t\t\tthis._bindToCollection = null;\n\t\t}\n\n\t\twhile ( this.length ) {\n\t\t\tthis.remove( 0 );\n\t\t}\n\t}\n\n\t/**\n\t * Binds and synchronizes the collection with another one.\n\t *\n\t * The binding can be a simple factory:\n\t *\n\t *\t\tclass FactoryClass {\n\t *\t\t\tconstructor( data ) {\n\t *\t\t\t\tthis.label = data.label;\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t *\t\tconst source = new Collection( { idProperty: 'label' } );\n\t *\t\tconst target = new Collection();\n\t *\n\t *\t\ttarget.bindTo( source ).as( FactoryClass );\n\t *\n\t *\t\tsource.add( { label: 'foo' } );\n\t *\t\tsource.add( { label: 'bar' } );\n\t *\n\t *\t\tconsole.log( target.length ); // 2\n\t *\t\tconsole.log( target.get( 1 ).label ); // 'bar'\n\t *\n\t *\t\tsource.remove( 0 );\n\t *\t\tconsole.log( target.length ); // 1\n\t *\t\tconsole.log( target.get( 0 ).label ); // 'bar'\n\t *\n\t * or the factory driven by a custom callback:\n\t *\n\t *\t\tclass FooClass {\n\t *\t\t\tconstructor( data ) {\n\t *\t\t\t\tthis.label = data.label;\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t *\t\tclass BarClass {\n\t *\t\t\tconstructor( data ) {\n\t *\t\t\t\tthis.label = data.label;\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t *\t\tconst source = new Collection( { idProperty: 'label' } );\n\t *\t\tconst target = new Collection();\n\t *\n\t *\t\ttarget.bindTo( source ).using( ( item ) => {\n\t *\t\t\tif ( item.label == 'foo' ) {\n\t *\t\t\t\treturn new FooClass( item );\n\t *\t\t\t} else {\n\t *\t\t\t\treturn new BarClass( item );\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t *\t\tsource.add( { label: 'foo' } );\n\t *\t\tsource.add( { label: 'bar' } );\n\t *\n\t *\t\tconsole.log( target.length ); // 2\n\t *\t\tconsole.log( target.get( 0 ) instanceof FooClass ); // true\n\t *\t\tconsole.log( target.get( 1 ) instanceof BarClass ); // true\n\t *\n\t * or the factory out of property name:\n\t *\n\t *\t\tconst source = new Collection( { idProperty: 'label' } );\n\t *\t\tconst target = new Collection();\n\t *\n\t *\t\ttarget.bindTo( source ).using( 'label' );\n\t *\n\t *\t\tsource.add( { label: { value: 'foo' } } );\n\t *\t\tsource.add( { label: { value: 'bar' } } );\n\t *\n\t *\t\tconsole.log( target.length ); // 2\n\t *\t\tconsole.log( target.get( 0 ).value ); // 'foo'\n\t *\t\tconsole.log( target.get( 1 ).value ); // 'bar'\n\t *\n\t * It's possible to skip specified items by returning falsy value:\n\t *\n\t *\t\tconst source = new Collection();\n\t *\t\tconst target = new Collection();\n\t *\n\t *\t\ttarget.bindTo( source ).using( item => {\n\t *\t\t\tif ( item.hidden ) {\n\t *\t\t\t\treturn null;\n\t *\t\t\t}\n\t *\n\t *\t\t\treturn item;\n\t *\t\t} );\n\t *\n\t *\t\tsource.add( { hidden: true } );\n\t *\t\tsource.add( { hidden: false } );\n\t *\n\t *\t\tconsole.log( source.length ); // 2\n\t *\t\tconsole.log( target.length ); // 1\n\t *\n\t * **Note**: {@link #clear} can be used to break the binding.\n\t *\n\t * @param {module:utils/collection~Collection} externalCollection A collection to be bound.\n\t * @returns {Object}\n\t * @returns {module:utils/collection~CollectionBindToChain} The binding chain object.\n\t */\n\tbindTo( externalCollection ) {\n\t\tif ( this._bindToCollection ) {\n\t\t\t/**\n\t\t\t * The collection cannot be bound more than once.\n\t\t\t *\n\t\t\t * @error collection-bind-to-rebind\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'collection-bind-to-rebind: The collection cannot be bound more than once.' );\n\t\t}\n\n\t\tthis._bindToCollection = externalCollection;\n\n\t\treturn {\n\t\t\tas: Class => {\n\t\t\t\tthis._setUpBindToBinding( item => new Class( item ) );\n\t\t\t},\n\n\t\t\tusing: callbackOrProperty => {\n\t\t\t\tif ( typeof callbackOrProperty == 'function' ) {\n\t\t\t\t\tthis._setUpBindToBinding( item => callbackOrProperty( item ) );\n\t\t\t\t} else {\n\t\t\t\t\tthis._setUpBindToBinding( item => item[ callbackOrProperty ] );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Finalizes and activates a binding initiated by {#bindTo}.\n\t *\n\t * @protected\n\t * @param {Function} factory A function which produces collection items.\n\t */\n\t_setUpBindToBinding( factory ) {\n\t\tconst externalCollection = this._bindToCollection;\n\n\t\t// Adds the item to the collection once a change has been done to the external collection.\n\t\t//\n\t\t// @private\n\t\tconst addItem = ( evt, externalItem, index ) => {\n\t\t\tconst isExternalBoundToThis = externalCollection._bindToCollection == this;\n\t\t\tconst externalItemBound = externalCollection._bindToInternalToExternalMap.get( externalItem );\n\n\t\t\t// If an external collection is bound to this collection, which makes it a 2–way binding,\n\t\t\t// and the particular external collection item is already bound, don't add it here.\n\t\t\t// The external item has been created **out of this collection's item** and (re)adding it will\n\t\t\t// cause a loop.\n\t\t\tif ( isExternalBoundToThis && externalItemBound ) {\n\t\t\t\tthis._bindToExternalToInternalMap.set( externalItem, externalItemBound );\n\t\t\t\tthis._bindToInternalToExternalMap.set( externalItemBound, externalItem );\n\t\t\t} else {\n\t\t\t\tconst item = factory( externalItem );\n\n\t\t\t\t// When there is no item we need to remember skipped index first and then we can skip this item.\n\t\t\t\tif ( !item ) {\n\t\t\t\t\tthis._skippedIndexesFromExternal.push( index );\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Lets try to put item at the same index as index in external collection\n\t\t\t\t// but when there are a skipped items in one or both collections we need to recalculate this index.\n\t\t\t\tlet finalIndex = index;\n\n\t\t\t\t// When we try to insert item after some skipped items from external collection we need\n\t\t\t\t// to include this skipped items and decrease index.\n\t\t\t\t//\n\t\t\t\t// For the following example:\n\t\t\t\t// external -> [ 'A', 'B - skipped for internal', 'C - skipped for internal' ]\n\t\t\t\t// internal -> [ A ]\n\t\t\t\t//\n\t\t\t\t// Another item is been added at the end of external collection:\n\t\t\t\t// external.add( 'D' )\n\t\t\t\t// external -> [ 'A', 'B - skipped for internal', 'C - skipped for internal', 'D' ]\n\t\t\t\t//\n\t\t\t\t// We can't just add 'D' to internal at the same index as index in external because\n\t\t\t\t// this will produce empty indexes what is invalid:\n\t\t\t\t// internal -> [ 'A', empty, empty, 'D' ]\n\t\t\t\t//\n\t\t\t\t// So we need to include skipped items and decrease index\n\t\t\t\t// internal -> [ 'A', 'D' ]\n\t\t\t\tfor ( const skipped of this._skippedIndexesFromExternal ) {\n\t\t\t\t\tif ( index > skipped ) {\n\t\t\t\t\t\tfinalIndex--;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// We need to take into consideration that external collection could skip some items from\n\t\t\t\t// internal collection.\n\t\t\t\t//\n\t\t\t\t// For the following example:\n\t\t\t\t// internal -> [ 'A', 'B - skipped for external', 'C - skipped for external' ]\n\t\t\t\t// external -> [ A ]\n\t\t\t\t//\n\t\t\t\t// Another item is been added at the end of external collection:\n\t\t\t\t// external.add( 'D' )\n\t\t\t\t// external -> [ 'A', 'D' ]\n\t\t\t\t//\n\t\t\t\t// We need to include skipped items and place new item after them:\n\t\t\t\t// internal -> [ 'A', 'B - skipped for external', 'C - skipped for external', 'D' ]\n\t\t\t\tfor ( const skipped of externalCollection._skippedIndexesFromExternal ) {\n\t\t\t\t\tif ( finalIndex >= skipped ) {\n\t\t\t\t\t\tfinalIndex++;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis._bindToExternalToInternalMap.set( externalItem, item );\n\t\t\t\tthis._bindToInternalToExternalMap.set( item, externalItem );\n\t\t\t\tthis.add( item, finalIndex );\n\n\t\t\t\t// After adding new element to internal collection we need update indexes\n\t\t\t\t// of skipped items in external collection.\n\t\t\t\tfor ( let i = 0; i < externalCollection._skippedIndexesFromExternal.length; i++ ) {\n\t\t\t\t\tif ( finalIndex <= externalCollection._skippedIndexesFromExternal[ i ] ) {\n\t\t\t\t\t\texternalCollection._skippedIndexesFromExternal[ i ]++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t// Load the initial content of the collection.\n\t\tfor ( const externalItem of externalCollection ) {\n\t\t\taddItem( null, externalItem, externalCollection.getIndex( externalItem ) );\n\t\t}\n\n\t\t// Synchronize the with collection as new items are added.\n\t\tthis.listenTo( externalCollection, 'add', addItem );\n\n\t\t// Synchronize the with collection as new items are removed.\n\t\tthis.listenTo( externalCollection, 'remove', ( evt, externalItem, index ) => {\n\t\t\tconst item = this._bindToExternalToInternalMap.get( externalItem );\n\n\t\t\tif ( item ) {\n\t\t\t\tthis.remove( item );\n\t\t\t}\n\n\t\t\t// After removing element from external collection we need update/remove indexes\n\t\t\t// of skipped items in internal collection.\n\t\t\tthis._skippedIndexesFromExternal = this._skippedIndexesFromExternal.reduce( ( result, skipped ) => {\n\t\t\t\tif ( index < skipped ) {\n\t\t\t\t\tresult.push( skipped - 1 );\n\t\t\t\t}\n\n\t\t\t\tif ( index > skipped ) {\n\t\t\t\t\tresult.push( skipped );\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t}, [] );\n\t\t} );\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * @returns {Iterable.<*>}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this._items[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Fired when an item is added to the collection.\n\t *\n\t * @event add\n\t * @param {Object} item The added item.\n\t */\n\n\t/**\n\t * Fired when an item is removed from the collection.\n\t *\n\t * @event remove\n\t * @param {Object} item The removed item.\n\t * @param {Number} index Index from which item was removed.\n\t */\n}\n\nmix( Collection, EmitterMixin );\n\n/**\n * An object returned by the {@link module:utils/collection~Collection#bindTo `bindTo()`} method\n * providing functions that specify the type of the binding.\n *\n * See the {@link module:utils/collection~Collection#bindTo `bindTo()`} documentation for examples.\n *\n * @interface module:utils/collection~CollectionBindToChain\n */\n\n/**\n * Creates a callback or a property binding.\n *\n * @method #using\n * @param {Function|String} callbackOrProperty When the function is passed, it should return\n * the collection items. When the string is provided, the property value is used to create the bound collection items.\n */\n\n/**\n * Creates the class factory binding in which items of the source collection are passed to\n * the constructor of the specified class.\n *\n * @method #as\n * @param {Function} Class The class constructor used to create instances in the factory.\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/document\n */\n\nimport DocumentSelection from './documentselection';\nimport Collection from '@ckeditor/ckeditor5-utils/src/collection';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\n\n/**\n * Document class creates an abstract layer over the content editable area, contains a tree of view elements and\n * {@link module:engine/view/documentselection~DocumentSelection view selection} associated with this document.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Document {\n\t/**\n\t * Creates a Document instance.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Selection done on this document.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/documentselection~DocumentSelection} module:engine/view/document~Document#selection\n\t\t */\n\t\tthis.selection = new DocumentSelection();\n\n\t\t/**\n\t\t * Roots of the view tree. Collection of the {@link module:engine/view/element~Element view elements}.\n\t\t *\n\t\t * View roots are created as a result of binding between {@link module:engine/view/document~Document#roots} and\n\t\t * {@link module:engine/model/document~Document#roots} and this is handled by\n\t\t * {@link module:engine/controller/editingcontroller~EditingController}, so to create view root we need to create\n\t\t * model root using {@link module:engine/model/document~Document#createRoot}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/collection~Collection} module:engine/view/document~Document#roots\n\t\t */\n\t\tthis.roots = new Collection( { idProperty: 'rootName' } );\n\n\t\t/**\n\t\t * Defines whether document is in read-only mode.\n\t\t *\n\t\t * When document is read-ony then all roots are read-only as well and caret placed inside this root is hidden.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isReadOnly\n\t\t */\n\t\tthis.set( 'isReadOnly', false );\n\n\t\t/**\n\t\t * True if document is focused.\n\t\t *\n\t\t * This property is updated by the {@link module:engine/view/observer/focusobserver~FocusObserver}.\n\t\t * If the {@link module:engine/view/observer/focusobserver~FocusObserver} is disabled this property will not change.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Boolean} module:engine/view/document~Document#isFocused\n\t\t */\n\t\tthis.set( 'isFocused', false );\n\n\t\t/**\n\t\t * True if composition is in progress inside the document.\n\t\t *\n\t\t * This property is updated by the {@link module:engine/view/observer/compositionobserver~CompositionObserver}.\n\t\t * If the {@link module:engine/view/observer/compositionobserver~CompositionObserver} is disabled this property will not change.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Boolean} module:engine/view/document~Document#isComposing\n\t\t */\n\t\tthis.set( 'isComposing', false );\n\n\t\t/**\n\t\t * Post-fixer callbacks registered to the view document.\n\t\t *\n\t\t * @private\n\t\t * @member {Set}\n\t\t */\n\t\tthis._postFixers = new Set();\n\t}\n\n\t/**\n\t * Gets a {@link module:engine/view/document~Document#roots view root element} with the specified name. If the name is not\n\t * specific \"main\" root is returned.\n\t *\n\t * @param {String} [name='main'] Name of the root.\n\t * @returns {module:engine/view/rooteditableelement~RootEditableElement|null} The view root element with the specified name\n\t * or null when there is no root of given name.\n\t */\n\tgetRoot( name = 'main' ) {\n\t\treturn this.roots.get( name );\n\t}\n\n\t/**\n\t * Used to register a post-fixer callback. A post-fixers mechanism allows to update view tree just before rendering\n\t * to the DOM.\n\t *\n\t * Post-fixers are fired just after all changes from the outermost change block were applied but\n\t * before the {@link module:engine/view/view~View#event:render render event} is fired. If a post-fixer callback made\n\t * a change, it should return `true`. When this happens, all post-fixers are fired again to check if something else should\n\t * not be fixed in the new document tree state.\n\t *\n\t * View post-fixers are useful when you wants to update view structure whenever it changes, for instance add some classes\n\t * to elements based on the view structure or selection. However, is you need DOM elements to be already updated, use\n\t * {@link module:engine/view/view~View#event:render render event}.\n\t *\n\t * As a parameter, a post-fixer callback receives a {@link module:engine/view/downcastwriter~DowncastWriter downcast writer}\n\t * instance connected with the executed changes block.\n\t *\n\t * Note that registering a post-fixer won't re-render the editor's view. If the view should change after registering the post-fixer then\n\t * it should be done manually calling `view.forceRender();`.\n\t *\n\t * @param {Function} postFixer\n\t */\n\tregisterPostFixer( postFixer ) {\n\t\tthis._postFixers.add( postFixer );\n\t}\n\n\t/**\n\t * Destroys this instance. Makes sure that all observers are destroyed and listeners removed.\n\t */\n\tdestroy() {\n\t\tthis.roots.map( root => root.destroy() );\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Performs post-fixer loops. Executes post-fixer callbacks as long as none of them has done any changes to the model.\n\t *\n\t * @protected\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer\n\t */\n\t_callPostFixers( writer ) {\n\t\tlet wasFixed = false;\n\n\t\tdo {\n\t\t\tfor ( const callback of this._postFixers ) {\n\t\t\t\twasFixed = callback( writer );\n\n\t\t\t\tif ( wasFixed ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} while ( wasFixed );\n\t}\n\n\t/**\n\t * Event fired whenever document content layout changes. It is fired whenever content is\n\t * {@link module:engine/view/view~View#event:render rendered}, but should be also fired by observers in case of\n\t * other actions which may change layout, for instance when image loads.\n\t *\n\t * @event layoutChanged\n\t */\n}\n\nmix( Document, ObservableMixin );\n\n/**\n * Enum representing type of the change.\n *\n * Possible values:\n *\n * * `children` - for child list changes,\n * * `attributes` - for element attributes changes,\n * * `text` - for text nodes changes.\n *\n * @typedef {String} module:engine/view/document~ChangeType\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/attributeelement\n */\n\nimport Element from './element';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n// Default attribute priority.\nconst DEFAULT_PRIORITY = 10;\n\n/**\n * Attribute elements are used to represent formatting elements in the view (think – `<b>`, `<span style=\"font-size: 2em\">`, etc.).\n * Most often they are created when downcasting model text attributes.\n *\n * Editing engine does not define a fixed HTML DTD. This is why a feature developer needs to choose between various\n * types (container element, {@link module:engine/view/attributeelement~AttributeElement attribute element},\n * {@link module:engine/view/emptyelement~EmptyElement empty element}, etc) when developing a feature.\n *\n * To create a new attribute element instance use the\n * {@link module:engine/view/downcastwriter~DowncastWriter#createAttributeElement `DowncastWriter#createAttributeElement()`} method.\n *\n * @extends module:engine/view/element~Element\n */\nexport default class AttributeElement extends Element {\n\t/**\n\t * Creates an attribute element.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createAttributeElement\n\t * @see module:engine/view/element~Element\n\t * @protected\n\t */\n\tconstructor( name, attrs, children ) {\n\t\tsuper( name, attrs, children );\n\n\t\t/**\n\t\t * Returns block {@link module:engine/view/filler filler} offset or `null` if block filler is not needed.\n\t\t *\n\t\t * @method #getFillerOffset\n\t\t * @returns {Number|null} Block filler offset or `null` if block filler is not needed.\n\t\t */\n\t\tthis.getFillerOffset = getFillerOffset;\n\n\t\t/**\n\t\t * Element priority. Decides in what order elements are wrapped by {@link module:engine/view/downcastwriter~DowncastWriter}.\n\t\t *\n\t\t * @protected\n\t\t * @member {Number}\n\t\t */\n\t\tthis._priority = DEFAULT_PRIORITY;\n\n\t\t/**\n\t\t * Element identifier. If set, it is used by {@link module:engine/view/element~Element#isSimilar},\n\t\t * and then two elements are considered similar if, and only if they have the same `_id`.\n\t\t *\n\t\t * @protected\n\t\t * @member {String|Number}\n\t\t */\n\t\tthis._id = null;\n\n\t\t/**\n\t\t * Keeps all the attribute elements that have the same {@link module:engine/view/attributeelement~AttributeElement#id ids}\n\t\t * and still exist in the view tree.\n\t\t *\n\t\t * This property is managed by {@link module:engine/view/downcastwriter~DowncastWriter}.\n\t\t *\n\t\t * @protected\n\t\t * @member {Set.<module:engine/view/attributeelement~AttributeElement>|null}\n\t\t */\n\t\tthis._clonesGroup = null;\n\t}\n\n\t/**\n\t * Element priority. Decides in what order elements are wrapped by {@link module:engine/view/downcastwriter~DowncastWriter}.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget priority() {\n\t\treturn this._priority;\n\t}\n\n\t/**\n\t * Element identifier. If set, it is used by {@link module:engine/view/element~Element#isSimilar},\n\t * and then two elements are considered similar if, and only if they have the same `id`.\n\t *\n\t * @readonly\n\t * @type {String|Number}\n\t */\n\tget id() {\n\t\treturn this._id;\n\t}\n\n\t/**\n\t * Returns all {@link module:engine/view/attributeelement~AttributeElement attribute elements} that has the\n\t * same {@link module:engine/view/attributeelement~AttributeElement#id id} and are in the view tree (were not removed).\n\t *\n\t * Note: If this element has been removed from the tree, returned set will not include it.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError attribute-element-get-elements-with-same-id-no-id}\n\t * if this element has no `id`.\n\t *\n\t * @returns {Set.<module:engine/view/attributeelement~AttributeElement>} Set containing all the attribute elements\n\t * with the same `id` that were added and not removed from the view tree.\n\t */\n\tgetElementsWithSameId() {\n\t\tif ( this.id === null ) {\n\t\t\t/**\n\t\t\t * Cannot get elements with the same id for an attribute element without id.\n\t\t\t *\n\t\t\t * @error attribute-element-get-elements-with-same-id-no-id\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'attribute-element-get-elements-with-same-id-no-id: ' +\n\t\t\t\t'Cannot get elements with the same id for an attribute element without id.'\n\t\t\t);\n\t\t}\n\n\t\treturn new Set( this._clonesGroup );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tis( type, name = null ) {\n\t\tif ( !name ) {\n\t\t\treturn type == 'attributeElement' || super.is( type );\n\t\t} else {\n\t\t\treturn ( type == 'attributeElement' && name == this.name ) || super.is( type, name );\n\t\t}\n\t}\n\n\t/**\n\t * Checks if this element is similar to other element.\n\t *\n\t * If none of elements has set {@link module:engine/view/attributeelement~AttributeElement#id}, then both elements\n\t * should have the same name, attributes and priority to be considered as similar. Two similar elements can contain\n\t * different set of children nodes.\n\t *\n\t * If at least one element has {@link module:engine/view/attributeelement~AttributeElement#id} set, then both\n\t * elements have to have the same {@link module:engine/view/attributeelement~AttributeElement#id} value to be\n\t * considered similar.\n\t *\n\t * Similarity is important for {@link module:engine/view/downcastwriter~DowncastWriter}. For example:\n\t *\n\t * * two following similar elements can be merged together into one, longer element,\n\t * * {@link module:engine/view/downcastwriter~DowncastWriter#unwrap} checks similarity of passed element and processed element to\n\t * decide whether processed element should be unwrapped,\n\t * * etc.\n\t *\n\t * @param {module:engine/view/element~Element} otherElement\n\t * @returns {Boolean}\n\t */\n\tisSimilar( otherElement ) {\n\t\t// If any element has an `id` set, just compare the ids.\n\t\tif ( this.id !== null || otherElement.id !== null ) {\n\t\t\treturn this.id === otherElement.id;\n\t\t}\n\n\t\treturn super.isSimilar( otherElement ) && this.priority == otherElement.priority;\n\t}\n\n\t/**\n\t * Clones provided element with priority.\n\t *\n\t * @protected\n\t * @param {Boolean} deep If set to `true` clones element and all its children recursively. When set to `false`,\n\t * element will be cloned without any children.\n\t * @returns {module:engine/view/attributeelement~AttributeElement} Clone of this element.\n\t */\n\t_clone( deep ) {\n\t\tconst cloned = super._clone( deep );\n\n\t\t// Clone priority too.\n\t\tcloned._priority = this._priority;\n\n\t\t// And id too.\n\t\tcloned._id = this._id;\n\n\t\treturn cloned;\n\t}\n}\n\n/**\n * Default attribute priority.\n *\n * @member {Number} module:engine/view/attributeelement~AttributeElement.DEFAULT_PRIORITY\n */\nAttributeElement.DEFAULT_PRIORITY = DEFAULT_PRIORITY;\n\n// Returns block {@link module:engine/view/filler~Filler filler} offset or `null` if block filler is not needed.\n//\n// @returns {Number|null} Block filler offset or `null` if block filler is not needed.\nfunction getFillerOffset() {\n\t// <b>foo</b> does not need filler.\n\tif ( nonUiChildrenCount( this ) ) {\n\t\treturn null;\n\t}\n\n\tlet element = this.parent;\n\n\t// <p><b></b></p> needs filler -> <p><b><br></b></p>\n\twhile ( element && element.is( 'attributeElement' ) ) {\n\t\tif ( nonUiChildrenCount( element ) > 1 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\telement = element.parent;\n\t}\n\n\tif ( !element || nonUiChildrenCount( element ) > 1 ) {\n\t\treturn null;\n\t}\n\n\t// Render block filler at the end of element (after all ui elements).\n\treturn this.childCount;\n}\n\n// Returns total count of children that are not {@link module:engine/view/uielement~UIElement UIElements}.\n//\n// @param {module:engine/view/element~Element} element\n// @returns {Number}\nfunction nonUiChildrenCount( element ) {\n\treturn Array.from( element.getChildren() ).filter( element => !element.is( 'uiElement' ) ).length;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/emptyelement\n */\n\nimport Element from './element';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport Node from './node';\n\n/**\n * Empty element class. It is used to represent elements that cannot contain any child nodes (for example `<img>` elements).\n *\n * To create a new empty element use the\n * {@link module:engine/view/downcastwriter~DowncastWriter#createEmptyElement `downcastWriter#createEmptyElement()`} method.\n *\n * @extends module:engine/view/element~Element\n */\nexport default class EmptyElement extends Element {\n\t/**\n\t * Creates new instance of EmptyElement.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-emptyelement-cannot-add` when third parameter is passed,\n\t * to inform that usage of EmptyElement is incorrect (adding child nodes to EmptyElement is forbidden).\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createEmptyElement\n\t * @protected\n\t * @param {String} name Node name.\n\t * @param {Object|Iterable} [attributes] Collection of attributes.\n\t */\n\tconstructor( name, attributes, children ) {\n\t\tsuper( name, attributes, children );\n\n\t\t/**\n\t\t * Returns `null` because filler is not needed for EmptyElements.\n\t\t *\n\t\t * @method #getFillerOffset\n\t\t * @returns {null} Always returns null.\n\t\t */\n\t\tthis.getFillerOffset = getFillerOffset;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tis( type, name = null ) {\n\t\tif ( !name ) {\n\t\t\treturn type == 'emptyElement' || super.is( type );\n\t\t} else {\n\t\t\treturn ( type == 'emptyElement' && name == this.name ) || super.is( type, name );\n\t\t}\n\t}\n\n\t/**\n\t * Overrides {@link module:engine/view/element~Element#_insertChild} method.\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-emptyelement-cannot-add` to prevent\n\t * adding any child nodes to EmptyElement.\n\t *\n\t * @protected\n\t */\n\t_insertChild( index, nodes ) {\n\t\tif ( nodes && ( nodes instanceof Node || Array.from( nodes ).length > 0 ) ) {\n\t\t\t/**\n\t\t\t * Cannot add children to {@link module:engine/view/emptyelement~EmptyElement}.\n\t\t\t *\n\t\t\t * @error view-emptyelement-cannot-add\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-emptyelement-cannot-add: Cannot add child nodes to EmptyElement instance.' );\n\t\t}\n\t}\n}\n\n// Returns `null` because block filler is not needed for EmptyElements.\n//\n// @returns {null}\nfunction getFillerOffset() {\n\treturn null;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* globals navigator:false */\n\n/**\n * @module utils/env\n */\n\nconst userAgent = navigator.userAgent.toLowerCase();\n\n/**\n * A namespace containing environment and browser information.\n *\n * @namespace\n */\nconst env = {\n\t/**\n\t * Indicates that the application is running on Macintosh.\n\t *\n\t * @static\n\t * @member {Boolean} module:utils/env~env#isMac\n\t */\n\tisMac: isMac( userAgent ),\n\n\t/**\n\t * Indicates that the application is running in Microsoft Edge.\n\t *\n\t * @static\n\t * @member {Boolean} module:utils/env~env#isEdge\n\t */\n\tisEdge: isEdge( userAgent ),\n\n\t/**\n\t * Indicates that the application is running in Firefox (Gecko).\n\t *\n\t * @static\n\t * @member {Boolean} module:utils/env~env#isEdge\n\t */\n\tisGecko: isGecko( userAgent ),\n\n\t/**\n\t * Indicates that the application is running in Safari.\n\t *\n\t * @static\n\t * @member {Boolean} module:utils/env~env#isSafari\n\t */\n\tisSafari: isSafari( userAgent )\n};\n\nexport default env;\n\n/**\n * Checks if User Agent represented by the string is running on Macintosh.\n *\n * @param {String} userAgent **Lowercase** `navigator.userAgent` string.\n * @returns {Boolean} Whether User Agent is running on Macintosh or not.\n */\nexport function isMac( userAgent ) {\n\treturn userAgent.indexOf( 'macintosh' ) > -1;\n}\n\n/**\n * Checks if User Agent represented by the string is Microsoft Edge.\n *\n * @param {String} userAgent **Lowercase** `navigator.userAgent` string.\n * @returns {Boolean} Whether User Agent is Edge or not.\n */\nexport function isEdge( userAgent ) {\n\treturn !!userAgent.match( /edge\\/(\\d+.?\\d*)/ );\n}\n\n/**\n * Checks if User Agent represented by the string is Firefox (Gecko).\n *\n * @param {String} userAgent **Lowercase** `navigator.userAgent` string.\n * @returns {Boolean} Whether User Agent is Firefox or not.\n */\nexport function isGecko( userAgent ) {\n\treturn !!userAgent.match( /gecko\\/\\d+/ );\n}\n\n/**\n * Checks if User Agent represented by the string is Safari.\n *\n * @param {String} userAgent **Lowercase** `navigator.userAgent` string.\n * @returns {Boolean} Whether User Agent is Safari or not.\n */\nexport function isSafari( userAgent ) {\n\treturn userAgent.indexOf( ' applewebkit/' ) > -1 && userAgent.indexOf( 'chrome' ) === -1;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * Set of utils related to keyboard support.\n *\n * @module utils/keyboard\n */\n\nimport CKEditorError from './ckeditorerror';\nimport env from './env';\n\nconst macGlyphsToModifiers = {\n\t'⌘': 'ctrl',\n\t'⇧': 'shift',\n\t'⌥': 'alt'\n};\n\nconst modifiersToMacGlyphs = {\n\t'ctrl': '⌘',\n\t'shift': '⇧',\n\t'alt': '⌥'\n};\n\n/**\n * Object with `keyName => keyCode` pairs for a set of known keys.\n *\n * Contains:\n *\n * * `a-z`,\n * * `0-9`,\n * * `f1-f12`,\n * * `arrow(left|up|right|bottom)`,\n * * `backspace`, `delete`, `enter`, `esc`, `tab`,\n * * `ctrl`, `cmd`, `shift`, `alt`.\n */\nexport const keyCodes = generateKnownKeyCodes();\n\n/**\n * Converts a key name or a {@link module:utils/keyboard~KeystrokeInfo keystroke info} into a key code.\n *\n * Note: Key names are matched with {@link module:utils/keyboard~keyCodes} in a case-insensitive way.\n *\n * @param {String|module:utils/keyboard~KeystrokeInfo} Key name (see {@link module:utils/keyboard~keyCodes})\n * or a keystroke data object.\n * @returns {Number} Key or keystroke code.\n */\nexport function getCode( key ) {\n\tlet keyCode;\n\n\tif ( typeof key == 'string' ) {\n\t\tkeyCode = keyCodes[ key.toLowerCase() ];\n\n\t\tif ( !keyCode ) {\n\t\t\t/**\n\t\t\t * Unknown key name. Only key names contained by the {@link module:utils/keyboard~keyCodes} can be used.\n\t\t\t *\n\t\t\t * @errror keyboard-unknown-key\n\t\t\t * @param {String} key\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'keyboard-unknown-key: Unknown key name.', { key } );\n\t\t}\n\t} else {\n\t\tkeyCode = key.keyCode +\n\t\t\t( key.altKey ? keyCodes.alt : 0 ) +\n\t\t\t( key.ctrlKey ? keyCodes.ctrl : 0 ) +\n\t\t\t( key.shiftKey ? keyCodes.shift : 0 );\n\t}\n\n\treturn keyCode;\n}\n\n/**\n * Parses keystroke and returns a keystroke code that will match the code returned by\n * link {@link module:utils/keyboard.getCode} for a corresponding {@link module:utils/keyboard~KeystrokeInfo keystroke info}.\n *\n * The keystroke can be passed in two formats:\n *\n * * as a single string – e.g. `ctrl + A`,\n * * as an array of {@link module:utils/keyboard~keyCodes known key names} and key codes – e.g.:\n * * `[ 'ctrl', 32 ]` (ctrl + space),\n * * `[ 'ctrl', 'a' ]` (ctrl + A).\n *\n * Note: Key names are matched with {@link module:utils/keyboard~keyCodes} in a case-insensitive way.\n *\n * Note: Only keystrokes with a single non-modifier key are supported (e.g. `ctrl+A` is OK, but `ctrl+A+B` is not).\n *\n * @param {String|Array.<Number|String>} keystroke Keystroke definition.\n * @returns {Number} Keystroke code.\n */\nexport function parseKeystroke( keystroke ) {\n\tif ( typeof keystroke == 'string' ) {\n\t\tkeystroke = splitKeystrokeText( keystroke );\n\t}\n\n\treturn keystroke\n\t\t.map( key => ( typeof key == 'string' ) ? getCode( key ) : key )\n\t\t.reduce( ( key, sum ) => sum + key, 0 );\n}\n\n/**\n * It translates any keystroke string text like `\"CTRL+A\"` to an\n * environment–specific keystroke, i.e. `\"⌘A\"` on Mac OSX.\n *\n * @param {String} keystroke Keystroke text.\n * @returns {String} Keystroke text specific for the environment.\n */\nexport function getEnvKeystrokeText( keystroke ) {\n\tif ( !env.isMac ) {\n\t\treturn keystroke;\n\t}\n\n\treturn splitKeystrokeText( keystroke )\n\t\t// Replace modifiers (e.g. \"ctrl\") with Mac glyphs (e.g. \"⌘\") first.\n\t\t.map( key => modifiersToMacGlyphs[ key.toLowerCase() ] || key )\n\n\t\t// Decide whether to put \"+\" between keys in the keystroke or not.\n\t\t.reduce( ( value, key ) => {\n\t\t\tif ( value.slice( -1 ) in macGlyphsToModifiers ) {\n\t\t\t\treturn value + key;\n\t\t\t} else {\n\t\t\t\treturn value + '+' + key;\n\t\t\t}\n\t\t} );\n}\n\nfunction generateKnownKeyCodes() {\n\tconst keyCodes = {\n\t\tarrowleft: 37,\n\t\tarrowup: 38,\n\t\tarrowright: 39,\n\t\tarrowdown: 40,\n\t\tbackspace: 8,\n\t\tdelete: 46,\n\t\tenter: 13,\n\t\tspace: 32,\n\t\tesc: 27,\n\t\ttab: 9,\n\n\t\t// The idea about these numbers is that they do not collide with any real key codes, so we can use them\n\t\t// like bit masks.\n\t\tctrl: 0x110000,\n\t\t// Has the same code as ctrl, because their behaviour should be unified across the editor.\n\t\t// See http://ckeditor.github.io/editor-recommendations/general-policies#ctrl-vs-cmd\n\t\tcmd: 0x110000,\n\t\tshift: 0x220000,\n\t\talt: 0x440000\n\t};\n\n\t// a-z\n\tfor ( let code = 65; code <= 90; code++ ) {\n\t\tconst letter = String.fromCharCode( code );\n\n\t\tkeyCodes[ letter.toLowerCase() ] = code;\n\t}\n\n\t// 0-9\n\tfor ( let code = 48; code <= 57; code++ ) {\n\t\tkeyCodes[ code - 48 ] = code;\n\t}\n\n\t// F1-F12\n\tfor ( let code = 112; code <= 123; code++ ) {\n\t\tkeyCodes[ 'f' + ( code - 111 ) ] = code;\n\t}\n\n\treturn keyCodes;\n}\n\nfunction splitKeystrokeText( keystroke ) {\n\treturn keystroke.split( /\\s*\\+\\s*/ );\n}\n\n/**\n * Information about a keystroke.\n *\n * @interface module:utils/keyboard~KeystrokeInfo\n */\n\n/**\n * The [key code](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode).\n *\n * @member {Number} module:utils/keyboard~KeystrokeInfo#keyCode\n */\n\n/**\n * Whether the <kbd>Alt</kbd> modifier was pressed.\n *\n * @member {Bolean} module:utils/keyboard~KeystrokeInfo#altKey\n */\n\n/**\n * Whether the <kbd>Ctrl</kbd> or <kbd>Cmd</kbd> modifier was pressed.\n *\n * @member {Bolean} module:utils/keyboard~KeystrokeInfo#ctrlKey\n */\n\n/**\n * Whether the <kbd>Shift</kbd> modifier was pressed.\n *\n * @member {Bolean} module:utils/keyboard~KeystrokeInfo#shiftKey\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/uielement\n */\n\nimport Element from './element';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport Node from './node';\nimport { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';\n\n/**\n * UI element class. It should be used to represent editing UI which needs to be injected into the editing view\n * If possible, you should keep your UI outside the editing view. However, if that is not possible,\n * UI elements can be used.\n *\n * How a UI element is rendered is in your control (you pass a callback to\n * {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement `downcastWriter#createUIElement()`}).\n * The editor will ignore your UI element – the selection cannot be placed in it, it is skipped (invisible) when\n * the user modifies the selection by using arrow keys and the editor does not listen to any mutations which\n * happen inside your UI elements.\n *\n * The limitation is that you cannot convert a model element to a UI element. UI elements need to be\n * created for {@link module:engine/model/markercollection~Marker markers} or as additinal elements\n * inside normal {@link module:engine/view/containerelement~ContainerElement container elements}.\n *\n * To create a new UI element use the\n * {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement `downcastWriter#createUIElement()`} method.\n *\n * @extends module:engine/view/element~Element\n */\nexport default class UIElement extends Element {\n\t/**\n\t * Creates new instance of UIElement.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-uielement-cannot-add` when third parameter is passed,\n\t * to inform that usage of UIElement is incorrect (adding child nodes to UIElement is forbidden).\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createUIElement\n\t * @protected\n\t * @param {String} name Node name.\n\t * @param {Object|Iterable} [attributes] Collection of attributes.\n\t */\n\tconstructor( name, attributes, children ) {\n\t\tsuper( name, attributes, children );\n\n\t\t/**\n\t\t * Returns `null` because filler is not needed for UIElements.\n\t\t *\n\t\t * @method #getFillerOffset\n\t\t * @returns {null} Always returns null.\n\t\t */\n\t\tthis.getFillerOffset = getFillerOffset;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tis( type, name = null ) {\n\t\tif ( !name ) {\n\t\t\treturn type == 'uiElement' || super.is( type );\n\t\t} else {\n\t\t\treturn ( type == 'uiElement' && name == this.name ) || super.is( type, name );\n\t\t}\n\t}\n\n\t/**\n\t * Overrides {@link module:engine/view/element~Element#_insertChild} method.\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-uielement-cannot-add` to prevent adding any child nodes\n\t * to UIElement.\n\t *\n\t * @protected\n\t */\n\t_insertChild( index, nodes ) {\n\t\tif ( nodes && ( nodes instanceof Node || Array.from( nodes ).length > 0 ) ) {\n\t\t\t/**\n\t\t\t * Cannot add children to {@link module:engine/view/uielement~UIElement}.\n\t\t\t *\n\t\t\t * @error view-uielement-cannot-add\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-uielement-cannot-add: Cannot add child nodes to UIElement instance.' );\n\t\t}\n\t}\n\n\t/**\n\t * Renders this {@link module:engine/view/uielement~UIElement} to DOM. This method is called by\n\t * {@link module:engine/view/domconverter~DomConverter}.\n\t * Do not use inheritance to create custom rendering method, replace `render()` method instead:\n\t *\n\t *\t\tconst myUIElement = downcastWriter.createUIElement( 'span' );\n\t *\t\tmyUIElement.render = function( domDocument ) {\n\t *\t\t\tconst domElement = this.toDomElement( domDocument );\n\t *\t\t\tdomElement.innerHTML = '<b>this is ui element</b>';\n\t *\n\t *\t\t\treturn domElement;\n\t *\t\t};\n\t *\n\t * @param {Document} domDocument\n\t * @returns {HTMLElement}\n\t */\n\trender( domDocument ) {\n\t\treturn this.toDomElement( domDocument );\n\t}\n\n\t/**\n\t * Creates DOM element based on this view UIElement.\n\t * Note that each time this method is called new DOM element is created.\n\t *\n\t * @param {Document} domDocument\n\t * @returns {HTMLElement}\n\t */\n\ttoDomElement( domDocument ) {\n\t\tconst domElement = domDocument.createElement( this.name );\n\n\t\tfor ( const key of this.getAttributeKeys() ) {\n\t\t\tdomElement.setAttribute( key, this.getAttribute( key ) );\n\t\t}\n\n\t\treturn domElement;\n\t}\n}\n\n/**\n * This function injects UI element handling to the given {@link module:engine/view/document~Document document}.\n *\n * A callback is added to {@link module:engine/view/document~Document#event:keydown document keydown event}.\n * The callback handles the situation when right arrow key is pressed and selection is collapsed before a UI element.\n * Without this handler, it would be impossible to \"jump over\" UI element using right arrow key.\n *\n * @param {module:engine/view/view~View} view View controller to which the quirks handling will be injected.\n */\nexport function injectUiElementHandling( view ) {\n\tview.document.on( 'keydown', ( evt, data ) => jumpOverUiElement( evt, data, view.domConverter ) );\n}\n\n// Returns `null` because block filler is not needed for UIElements.\n//\n// @returns {null}\nfunction getFillerOffset() {\n\treturn null;\n}\n\n// Selection cannot be placed in a `UIElement`. Whenever it is placed there, it is moved before it. This\n// causes a situation when it is impossible to jump over `UIElement` using right arrow key, because the selection\n// ends up in ui element (in DOM) and is moved back to the left. This handler fixes this situation.\nfunction jumpOverUiElement( evt, data, domConverter ) {\n\tif ( data.keyCode == keyCodes.arrowright ) {\n\t\tconst domSelection = data.domTarget.ownerDocument.defaultView.getSelection();\n\t\tconst domSelectionCollapsed = domSelection.rangeCount == 1 && domSelection.getRangeAt( 0 ).collapsed;\n\n\t\t// Jump over UI element if selection is collapsed or shift key is pressed. These are the cases when selection would extend.\n\t\tif ( domSelectionCollapsed || data.shiftKey ) {\n\t\t\tconst domParent = domSelection.focusNode;\n\t\t\tconst domOffset = domSelection.focusOffset;\n\n\t\t\tconst viewPosition = domConverter.domPositionToView( domParent, domOffset );\n\n\t\t\t// In case if dom element is not converted to view or is not mapped or something. Happens for example in some tests.\n\t\t\tif ( viewPosition === null ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Skip all following ui elements.\n\t\t\tlet jumpedOverAnyUiElement = false;\n\n\t\t\tconst nextViewPosition = viewPosition.getLastMatchingPosition( value => {\n\t\t\t\tif ( value.item.is( 'uiElement' ) ) {\n\t\t\t\t\t// Remember that there was at least one ui element.\n\t\t\t\t\tjumpedOverAnyUiElement = true;\n\t\t\t\t}\n\n\t\t\t\t// Jump over ui elements, jump over empty attribute elements, move up from inside of attribute element.\n\t\t\t\tif ( value.item.is( 'uiElement' ) || value.item.is( 'attributeElement' ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\t// Don't jump over text or don't get out of container element.\n\t\t\t\treturn false;\n\t\t\t} );\n\n\t\t\t// If anything has been skipped, fix position.\n\t\t\t// This `if` could be possibly omitted but maybe it is better not to mess with DOM selection if not needed.\n\t\t\tif ( jumpedOverAnyUiElement ) {\n\t\t\t\tconst newDomPosition = domConverter.viewPositionToDom( nextViewPosition );\n\n\t\t\t\tif ( domSelectionCollapsed ) {\n\t\t\t\t\t// Selection was collapsed, so collapse it at further position.\n\t\t\t\t\tdomSelection.collapse( newDomPosition.parent, newDomPosition.offset );\n\t\t\t\t} else {\n\t\t\t\t\t// Selection was not collapse, so extend it instead of collapsing.\n\t\t\t\t\tdomSelection.extend( newDomPosition.parent, newDomPosition.offset );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/documentfragment\n */\n\nimport Text from './text';\nimport TextProxy from './textproxy';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\n\n/**\n * Document fragment.\n *\n * To create a new document fragment instance use the\n * {@link module:engine/view/upcastwriter~UpcastWriter#createDocumentFragment `UpcastWriter#createDocumentFragment()`}\n * method.\n */\nexport default class DocumentFragment {\n\t/**\n\t * Creates new DocumentFragment instance.\n\t *\n\t * @protected\n\t * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children]\n\t * A list of nodes to be inserted into the created document fragment.\n\t */\n\tconstructor( children ) {\n\t\t/**\n\t\t * Array of child nodes.\n\t\t *\n\t\t * @protected\n\t\t * @member {Array.<module:engine/view/element~Element>} module:engine/view/documentfragment~DocumentFragment#_children\n\t\t */\n\t\tthis._children = [];\n\n\t\tif ( children ) {\n\t\t\tthis._insertChild( 0, children );\n\t\t}\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * Iterates over nodes added to this document fragment.\n\t *\n\t * @returns {Iterable.<module:engine/view/node~Node>}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this._children[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Number of child nodes in this document fragment.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget childCount() {\n\t\treturn this._children.length;\n\t}\n\n\t/**\n\t * Is `true` if there are no nodes inside this document fragment, `false` otherwise.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isEmpty() {\n\t\treturn this.childCount === 0;\n\t}\n\n\t/**\n\t * Artificial root of `DocumentFragment`. Returns itself. Added for compatibility reasons.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/documentfragment~DocumentFragment}\n\t */\n\tget root() {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Artificial parent of `DocumentFragment`. Returns `null`. Added for compatibility reasons.\n\t *\n\t * @readonly\n\t * @type {null}\n\t */\n\tget parent() {\n\t\treturn null;\n\t}\n\n\t/**\n\t * Checks whether given view tree object is of given type.\n\t *\n\t * Read more in {@link module:engine/view/node~Node#is}.\n\t *\n\t * @param {String} type\n\t * @returns {Boolean}\n\t */\n\tis( type ) {\n\t\treturn type == 'documentFragment';\n\t}\n\n\t/**\n\t * {@link module:engine/view/documentfragment~DocumentFragment#_insertChild Insert} a child node or a list of child nodes at the end\n\t * and sets the parent of these nodes to this fragment.\n\t *\n\t * @param {module:engine/view/item~Item|Iterable.<module:engine/view/item~Item>} items Items to be inserted.\n\t * @returns {Number} Number of appended nodes.\n\t */\n\t_appendChild( items ) {\n\t\treturn this._insertChild( this.childCount, items );\n\t}\n\n\t/**\n\t * Gets child at the given index.\n\t *\n\t * @param {Number} index Index of child.\n\t * @returns {module:engine/view/node~Node} Child node.\n\t */\n\tgetChild( index ) {\n\t\treturn this._children[ index ];\n\t}\n\n\t/**\n\t * Gets index of the given child node. Returns `-1` if child node is not found.\n\t *\n\t * @param {module:engine/view/node~Node} node Child node.\n\t * @returns {Number} Index of the child node.\n\t */\n\tgetChildIndex( node ) {\n\t\treturn this._children.indexOf( node );\n\t}\n\n\t/**\n\t * Gets child nodes iterator.\n\t *\n\t * @returns {Iterable.<module:engine/view/node~Node>} Child nodes iterator.\n\t */\n\tgetChildren() {\n\t\treturn this._children[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Inserts a child node or a list of child nodes on the given index and sets the parent of these nodes to\n\t * this fragment.\n\t *\n\t * @param {Number} index Position where nodes should be inserted.\n\t * @param {module:engine/view/item~Item|Iterable.<module:engine/view/item~Item>} items Items to be inserted.\n\t * @returns {Number} Number of inserted nodes.\n\t */\n\t_insertChild( index, items ) {\n\t\tthis._fireChange( 'children', this );\n\t\tlet count = 0;\n\n\t\tconst nodes = normalize( items );\n\n\t\tfor ( const node of nodes ) {\n\t\t\t// If node that is being added to this element is already inside another element, first remove it from the old parent.\n\t\t\tif ( node.parent !== null ) {\n\t\t\t\tnode._remove();\n\t\t\t}\n\n\t\t\tnode.parent = this;\n\n\t\t\tthis._children.splice( index, 0, node );\n\t\t\tindex++;\n\t\t\tcount++;\n\t\t}\n\n\t\treturn count;\n\t}\n\n\t/**\n\t * Removes number of child nodes starting at the given index and set the parent of these nodes to `null`.\n\t *\n\t * @param {Number} index Number of the first node to remove.\n\t * @param {Number} [howMany=1] Number of nodes to remove.\n\t * @returns {Array.<module:engine/view/node~Node>} The array of removed nodes.\n\t */\n\t_removeChildren( index, howMany = 1 ) {\n\t\tthis._fireChange( 'children', this );\n\n\t\tfor ( let i = index; i < index + howMany; i++ ) {\n\t\t\tthis._children[ i ].parent = null;\n\t\t}\n\n\t\treturn this._children.splice( index, howMany );\n\t}\n\n\t/**\n\t * Fires `change` event with given type of the change.\n\t *\n\t * @private\n\t * @param {module:engine/view/document~ChangeType} type Type of the change.\n\t * @param {module:engine/view/node~Node} node Changed node.\n\t * @fires module:engine/view/node~Node#change\n\t */\n\t_fireChange( type, node ) {\n\t\tthis.fire( 'change:' + type, node );\n\t}\n}\n\nmix( DocumentFragment, EmitterMixin );\n\n// Converts strings to Text and non-iterables to arrays.\n//\n// @param {String|module:engine/view/item~Item|Iterable.<String|module:engine/view/item~Item>}\n// @returns {Iterable.<module:engine/view/node~Node>}\nfunction normalize( nodes ) {\n\t// Separate condition because string is iterable.\n\tif ( typeof nodes == 'string' ) {\n\t\treturn [ new Text( nodes ) ];\n\t}\n\n\tif ( !isIterable( nodes ) ) {\n\t\tnodes = [ nodes ];\n\t}\n\n\t// Array.from to enable .map() on non-arrays.\n\treturn Array.from( nodes )\n\t\t.map( node => {\n\t\t\tif ( typeof node == 'string' ) {\n\t\t\t\treturn new Text( node );\n\t\t\t}\n\n\t\t\tif ( node instanceof TextProxy ) {\n\t\t\t\treturn new Text( node.data );\n\t\t\t}\n\n\t\t\treturn node;\n\t\t} );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module module:engine/view/downcastwriter\n */\n\nimport Position from './position';\nimport Range from './range';\nimport Selection from './selection';\nimport ContainerElement from './containerelement';\nimport AttributeElement from './attributeelement';\nimport EmptyElement from './emptyelement';\nimport UIElement from './uielement';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport DocumentFragment from './documentfragment';\nimport isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';\nimport Text from './text';\nimport EditableElement from './editableelement';\nimport { isPlainObject } from 'lodash-es';\n\n/**\n * View downcast writer.\n *\n * It provides a set of methods used to manipulate view nodes.\n *\n * Do not create an instance of this writer manually. To modify a view structure, use\n * the {@link module:engine/view/view~View#change `View#change()`} block.\n *\n * The `DowncastWriter` is designed to work with semantic views which are the views that were/are being downcasted from the model.\n * To work with ordinary views (e.g. parsed from a pasted content) use the\n * {@link module:engine/view/upcastwriter~UpcastWriter upcast writer}.\n *\n * Read more about changing the view in the {@glink framework/guides/architecture/editing-engine#changing-the-view Changing the view}\n * section of the {@glink framework/guides/architecture/editing-engine Editing engine architecture} guide.\n */\nexport default class DowncastWriter {\n\tconstructor( document ) {\n\t\t/**\n\t\t * @readonly\n\t\t * @type {module:engine/view/document~Document}\n\t\t */\n\t\tthis.document = document;\n\n\t\t/**\n\t\t * Holds references to the attribute groups that share the same {@link module:engine/view/attributeelement~AttributeElement#id id}.\n\t\t * The keys are `id`s, the values are `Set`s holding {@link module:engine/view/attributeelement~AttributeElement}s.\n\t\t *\n\t\t * @private\n\t\t * @type {Map.<String,Set>}\n\t\t */\n\t\tthis._cloneGroups = new Map();\n\t}\n\n\t/**\n\t * Sets {@link module:engine/view/documentselection~DocumentSelection selection's} ranges and direction to the\n\t * specified location based on the given {@link module:engine/view/selection~Selectable selectable}.\n\t *\n\t * Usage:\n\t *\n\t *\t\t// Sets selection to the given range.\n\t *\t\tconst range = writer.createRange( start, end );\n\t *\t\twriter.setSelection( range );\n\t *\n\t *\t\t// Sets backward selection to the given range.\n\t *\t\tconst range = writer.createRange( start, end );\n\t *\t\twriter.setSelection( range );\n\t *\n\t *\t\t// Sets selection to given ranges.\n\t * \t\tconst ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t *\t\twriter.setSelection( range );\n\t *\n\t *\t\t// Sets selection to the other selection.\n\t *\t\tconst otherSelection = writer.createSelection();\n\t *\t\twriter.setSelection( otherSelection );\n\t *\n\t * \t\t// Sets collapsed selection at the given position.\n\t *\t\tconst position = writer.createPositionFromPath( root, path );\n\t *\t\twriter.setSelection( position );\n\t *\n\t * \t\t// Sets collapsed selection at the position of given item and offset.\n\t *\t\tconst paragraph = writer.createContainerElement( 'paragraph' );\n\t *\t\twriter.setSelection( paragraph, offset );\n\t *\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n \t * that element and ends after the last child of that element.\n\t *\n\t * \t\twriter.setSelection( paragraph, 'in' );\n\t *\n\t * Creates a range on the {@link module:engine/view/item~Item item} which starts before the item and ends just after the item.\n\t *\n\t *\t\twriter.setSelection( paragraph, 'on' );\n\t *\n\t * \t\t// Removes all ranges.\n\t *\t\twriter.setSelection( null );\n\t *\n\t * `DowncastWriter#setSelection()` allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t *\t\t// Sets selection as backward.\n\t *\t\twriter.setSelection( range, { backward: true } );\n\t *\n\t *\t\t// Sets selection as fake.\n\t *\t\t// Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * \t\t// This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * \t\t// represented in other way, for example by applying proper CSS class.\n\t *\t\twriter.setSelection( range, { fake: true } );\n\t *\n\t * \t\t// Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * \t\t// (and be properly handled by screen readers).\n\t *\t\twriter.setSelection( range, { fake: true, label: 'foo' } );\n\t *\n\t * @param {module:engine/view/selection~Selectable} selectable\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Sets place or offset of the selection.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.backward] Sets this selection instance to be backward.\n\t * @param {Boolean} [options.fake] Sets this selection instance to be marked as `fake`.\n\t * @param {String} [options.label] Label for the fake selection.\n\t */\n\tsetSelection( selectable, placeOrOffset, options ) {\n\t\tthis.document.selection._setTo( selectable, placeOrOffset, options );\n\t}\n\n\t/**\n\t * Moves {@link module:engine/view/documentselection~DocumentSelection#focus selection's focus} to the specified location.\n\t *\n\t * The location can be specified in the same form as {@link module:engine/view/view~View#createPositionAt view.createPositionAt()}\n\t * parameters.\n\t *\n\t * @param {module:engine/view/item~Item|module:engine/view/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tsetSelectionFocus( itemOrPosition, offset ) {\n\t\tthis.document.selection._setFocus( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/text~Text text node}.\n\t *\n\t *\t\twriter.createText( 'foo' );\n\t *\n\t * @param {String} data The text's data.\n\t * @returns {module:engine/view/text~Text} The created text node.\n\t */\n\tcreateText( data ) {\n\t\treturn new Text( data );\n\t}\n\n\t/**\n\t * Creates new {@link module:engine/view/attributeelement~AttributeElement}.\n\t *\n\t *\t\twriter.createAttributeElement( 'strong' );\n\t *\t\twriter.createAttributeElement( 'strong', { alignment: 'center' } );\n\t *\n\t *\t\t// Make `<a>` element contain other attributes element so the `<a>` element is not broken.\n\t *\t\twriter.createAttributeElement( 'a', { href: 'foo.bar' }, { priority: 5 } );\n\t *\n\t *\t\t// Set `id` of a marker element so it is not joined or merged with \"normal\" elements.\n\t *\t\twriter.createAttributeElement( 'span', { class: 'myMarker' }, { id: 'marker:my' } );\n\t *\n\t * @param {String} name Name of the element.\n\t * @param {Object} [attributes] Element's attributes.\n\t * @param {Object} [options] Element's options.\n\t * @param {Number} [options.priority] Element's {@link module:engine/view/attributeelement~AttributeElement#priority priority}.\n\t * @param {Number|String} [options.id] Element's {@link module:engine/view/attributeelement~AttributeElement#id id}.\n\t * @returns {module:engine/view/attributeelement~AttributeElement} Created element.\n\t */\n\tcreateAttributeElement( name, attributes, options = {} ) {\n\t\tconst attributeElement = new AttributeElement( name, attributes );\n\n\t\tif ( options.priority ) {\n\t\t\tattributeElement._priority = options.priority;\n\t\t}\n\n\t\tif ( options.id ) {\n\t\t\tattributeElement._id = options.id;\n\t\t}\n\n\t\treturn attributeElement;\n\t}\n\n\t/**\n\t * Creates new {@link module:engine/view/containerelement~ContainerElement}.\n\t *\n\t *\t\twriter.createContainerElement( 'paragraph' );\n\t *\t\twriter.createContainerElement( 'paragraph', { alignment: 'center' } );\n\t *\n\t * @param {String} name Name of the element.\n\t * @param {Object} [attributes] Elements attributes.\n\t * @returns {module:engine/view/containerelement~ContainerElement} Created element.\n\t */\n\tcreateContainerElement( name, attributes ) {\n\t\treturn new ContainerElement( name, attributes );\n\t}\n\n\t/**\n\t * Creates new {@link module:engine/view/editableelement~EditableElement}.\n\t *\n\t *\t\twriter.createEditableElement( 'div' );\n\t *\t\twriter.createEditableElement( 'div', { alignment: 'center' } );\n\t *\n\t * @param {String} name Name of the element.\n\t * @param {Object} [attributes] Elements attributes.\n\t * @returns {module:engine/view/editableelement~EditableElement} Created element.\n\t */\n\tcreateEditableElement( name, attributes ) {\n\t\tconst editableElement = new EditableElement( name, attributes );\n\t\teditableElement._document = this.document;\n\n\t\treturn editableElement;\n\t}\n\n\t/**\n\t * Creates new {@link module:engine/view/emptyelement~EmptyElement}.\n\t *\n\t *\t\twriter.createEmptyElement( 'img' );\n\t *\t\twriter.createEmptyElement( 'img', { alignment: 'center' } );\n\t *\n\t * @param {String} name Name of the element.\n\t * @param {Object} [attributes] Elements attributes.\n\t * @returns {module:engine/view/emptyelement~EmptyElement} Created element.\n\t */\n\tcreateEmptyElement( name, attributes ) {\n\t\treturn new EmptyElement( name, attributes );\n\t}\n\n\t/**\n\t * Creates new {@link module:engine/view/uielement~UIElement}.\n\t *\n\t *\t\twriter.createUIElement( 'span' );\n\t *\t\twriter.createUIElement( 'span', { alignment: 'center' } );\n\t *\n\t * Custom render function can be provided as third parameter:\n\t *\n\t *\t\twriter.createUIElement( 'span', null, function( domDocument ) {\n\t *\t\t\tconst domElement = this.toDomElement( domDocument );\n\t *\t\t\tdomElement.innerHTML = '<b>this is ui element</b>';\n\t *\n\t *\t\t\treturn domElement;\n\t *\t\t} );\n\t *\n\t * @param {String} name Name of the element.\n\t * @param {Object} [attributes] Elements attributes.\n\t * @param {Function} [renderFunction] Custom render function.\n\t * @returns {module:engine/view/uielement~UIElement} Created element.\n\t */\n\tcreateUIElement( name, attributes, renderFunction ) {\n\t\tconst uiElement = new UIElement( name, attributes );\n\n\t\tif ( renderFunction ) {\n\t\t\tuiElement.render = renderFunction;\n\t\t}\n\n\t\treturn uiElement;\n\t}\n\n\t/**\n\t * Adds or overwrite element's attribute with a specified key and value.\n\t *\n\t *\t\twriter.setAttribute( 'href', 'http://ckeditor.com', linkElement );\n\t *\n\t * @param {String} key Attribute key.\n\t * @param {String} value Attribute value.\n\t * @param {module:engine/view/element~Element} element\n\t */\n\tsetAttribute( key, value, element ) {\n\t\telement._setAttribute( key, value );\n\t}\n\n\t/**\n\t * Removes attribute from the element.\n\t *\n\t *\t\twriter.removeAttribute( 'href', linkElement );\n\t *\n\t * @param {String} key Attribute key.\n\t * @param {module:engine/view/element~Element} element\n\t */\n\tremoveAttribute( key, element ) {\n\t\telement._removeAttribute( key );\n\t}\n\n\t/**\n\t * Adds specified class to the element.\n\t *\n\t *\t\twriter.addClass( 'foo', linkElement );\n\t *\t\twriter.addClass( [ 'foo', 'bar' ], linkElement );\n\t *\n\t * @param {Array.<String>|String} className\n\t * @param {module:engine/view/element~Element} element\n\t */\n\taddClass( className, element ) {\n\t\telement._addClass( className );\n\t}\n\n\t/**\n\t * Removes specified class from the element.\n\t *\n\t *\t\twriter.removeClass( 'foo', linkElement );\n\t *\t\twriter.removeClass( [ 'foo', 'bar' ], linkElement );\n\t *\n\t * @param {Array.<String>|String} className\n\t * @param {module:engine/view/element~Element} element\n\t */\n\tremoveClass( className, element ) {\n\t\telement._removeClass( className );\n\t}\n\n\t/**\n\t * Adds style to the element.\n\t *\n\t *\t\twriter.setStyle( 'color', 'red', element );\n\t *\t\twriter.setStyle( {\n\t *\t\t\tcolor: 'red',\n\t *\t\t\tposition: 'fixed'\n\t *\t\t}, element );\n\t *\n\t * @param {String|Object} property Property name or object with key - value pairs.\n\t * @param {String} [value] Value to set. This parameter is ignored if object is provided as the first parameter.\n\t * @param {module:engine/view/element~Element} element Element to set styles on.\n\t */\n\tsetStyle( property, value, element ) {\n\t\tif ( isPlainObject( property ) && element === undefined ) {\n\t\t\telement = value;\n\t\t}\n\n\t\telement._setStyle( property, value );\n\t}\n\n\t/**\n\t * Removes specified style from the element.\n\t *\n\t *\t\twriter.removeStyle( 'color', element ); // Removes 'color' style.\n\t *\t\twriter.removeStyle( [ 'color', 'border-top' ], element ); // Removes both 'color' and 'border-top' styles.\n\t *\n\t * @param {Array.<String>|String} property\n\t * @param {module:engine/view/element~Element} element\n\t */\n\tremoveStyle( property, element ) {\n\t\telement._removeStyle( property );\n\t}\n\n\t/**\n\t * Sets a custom property on element. Unlike attributes, custom properties are not rendered to the DOM,\n\t * so they can be used to add special data to elements.\n\t *\n\t * @param {String|Symbol} key\n\t * @param {*} value\n\t * @param {module:engine/view/element~Element} element\n\t */\n\tsetCustomProperty( key, value, element ) {\n\t\telement._setCustomProperty( key, value );\n\t}\n\n\t/**\n\t * Removes a custom property stored under the given key.\n\t *\n\t * @param {String|Symbol} key\n\t * @param {module:engine/view/element~Element} element\n\t * @returns {Boolean} Returns true if property was removed.\n\t */\n\tremoveCustomProperty( key, element ) {\n\t\treturn element._removeCustomProperty( key );\n\t}\n\n\t/**\n\t * Breaks attribute nodes at provided position or at boundaries of provided range. It breaks attribute elements inside\n\t * up to a container element.\n\t *\n\t * In following examples `<p>` is a container, `<b>` and `<u>` are attribute nodes:\n\t *\n\t * <p>foo<b><u>bar{}</u></b></p> -> <p>foo<b><u>bar</u></b>[]</p>\n\t * <p>foo<b><u>{}bar</u></b></p> -> <p>foo{}<b><u>bar</u></b></p>\n\t * <p>foo<b><u>b{}ar</u></b></p> -> <p>foo<b><u>b</u></b>[]<b><u>ar</u></b></p>\n\t * <p><b>fo{o</b><u>ba}r</u></p> -> <p><b>fo</b><b>o</b><u>ba</u><u>r</u></b></p>\n\t *\n\t * **Note:** {@link module:engine/view/documentfragment~DocumentFragment DocumentFragment} is treated like a container.\n\t *\n\t * **Note:** Difference between {@link module:engine/view/downcastwriter~DowncastWriter#breakAttributes breakAttributes} and\n\t * {@link module:engine/view/downcastwriter~DowncastWriter#breakContainer breakContainer} is that `breakAttributes` breaks all\n\t * {@link module:engine/view/attributeelement~AttributeElement attribute elements} that are ancestors of given `position`,\n\t * up to the first encountered {@link module:engine/view/containerelement~ContainerElement container element}.\n\t * `breakContainer` assumes that given `position` is directly in container element and breaks that container element.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container`\n\t * when {@link module:engine/view/range~Range#start start}\n\t * and {@link module:engine/view/range~Range#end end} positions of a passed range are not placed inside same parent container.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-cannot-break-empty-element`\n\t * when trying to break attributes\n\t * inside {@link module:engine/view/emptyelement~EmptyElement EmptyElement}.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-cannot-break-ui-element`\n\t * when trying to break attributes\n\t * inside {@link module:engine/view/uielement~UIElement UIElement}.\n\t *\n\t * @see module:engine/view/attributeelement~AttributeElement\n\t * @see module:engine/view/containerelement~ContainerElement\n\t * @see module:engine/view/downcastwriter~DowncastWriter#breakContainer\n\t * @param {module:engine/view/position~Position|module:engine/view/range~Range} positionOrRange Position where\n\t * to break attribute elements.\n\t * @returns {module:engine/view/position~Position|module:engine/view/range~Range} New position or range, after breaking the attribute\n\t * elements.\n\t */\n\tbreakAttributes( positionOrRange ) {\n\t\tif ( positionOrRange instanceof Position ) {\n\t\t\treturn this._breakAttributes( positionOrRange );\n\t\t} else {\n\t\t\treturn this._breakAttributesRange( positionOrRange );\n\t\t}\n\t}\n\n\t/**\n\t * Breaks {@link module:engine/view/containerelement~ContainerElement container view element} into two, at the given position. Position\n\t * has to be directly inside container element and cannot be in root. Does not break if position is at the beginning\n\t * or at the end of it's parent element.\n\t *\n\t * <p>foo^bar</p> -> <p>foo</p><p>bar</p>\n\t * <div><p>foo</p>^<p>bar</p></div> -> <div><p>foo</p></div><div><p>bar</p></div>\n\t * <p>^foobar</p> -> ^<p>foobar</p>\n\t * <p>foobar^</p> -> <p>foobar</p>^\n\t *\n\t * **Note:** Difference between {@link module:engine/view/downcastwriter~DowncastWriter#breakAttributes breakAttributes} and\n\t * {@link module:engine/view/downcastwriter~DowncastWriter#breakContainer breakContainer} is that `breakAttributes` breaks all\n\t * {@link module:engine/view/attributeelement~AttributeElement attribute elements} that are ancestors of given `position`,\n\t * up to the first encountered {@link module:engine/view/containerelement~ContainerElement container element}.\n\t * `breakContainer` assumes that given `position` is directly in container element and breaks that container element.\n\t *\n\t * @see module:engine/view/attributeelement~AttributeElement\n\t * @see module:engine/view/containerelement~ContainerElement\n\t * @see module:engine/view/downcastwriter~DowncastWriter#breakAttributes\n\t * @param {module:engine/view/position~Position} position Position where to break element.\n\t * @returns {module:engine/view/position~Position} Position between broken elements. If element has not been broken,\n\t * the returned position is placed either before it or after it.\n\t */\n\tbreakContainer( position ) {\n\t\tconst element = position.parent;\n\n\t\tif ( !( element.is( 'containerElement' ) ) ) {\n\t\t\t/**\n\t\t\t * Trying to break an element which is not a container element.\n\t\t\t *\n\t\t\t * @error view-writer-break-non-container-element\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'view-writer-break-non-container-element: Trying to break an element which is not a container element.'\n\t\t\t);\n\t\t}\n\n\t\tif ( !element.parent ) {\n\t\t\t/**\n\t\t\t * Trying to break root element.\n\t\t\t *\n\t\t\t * @error view-writer-break-root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-writer-break-root: Trying to break root element.' );\n\t\t}\n\n\t\tif ( position.isAtStart ) {\n\t\t\treturn Position._createBefore( element );\n\t\t} else if ( !position.isAtEnd ) {\n\t\t\tconst newElement = element._clone( false );\n\n\t\t\tthis.insert( Position._createAfter( element ), newElement );\n\n\t\t\tconst sourceRange = new Range( position, Position._createAt( element, 'end' ) );\n\t\t\tconst targetPosition = new Position( newElement, 0 );\n\n\t\t\tthis.move( sourceRange, targetPosition );\n\t\t}\n\n\t\treturn Position._createAfter( element );\n\t}\n\n\t/**\n\t * Merges {@link module:engine/view/attributeelement~AttributeElement attribute elements}. It also merges text nodes if needed.\n\t * Only {@link module:engine/view/attributeelement~AttributeElement#isSimilar similar} attribute elements can be merged.\n\t *\n\t * In following examples `<p>` is a container and `<b>` is an attribute element:\n\t *\n\t * <p>foo[]bar</p> -> <p>foo{}bar</p>\n\t * <p><b>foo</b>[]<b>bar</b></p> -> <p><b>foo{}bar</b></p>\n\t * <p><b foo=\"bar\">a</b>[]<b foo=\"baz\">b</b></p> -> <p><b foo=\"bar\">a</b>[]<b foo=\"baz\">b</b></p>\n\t *\n\t * It will also take care about empty attributes when merging:\n\t *\n\t * <p><b>[]</b></p> -> <p>[]</p>\n\t * <p><b>foo</b><i>[]</i><b>bar</b></p> -> <p><b>foo{}bar</b></p>\n\t *\n\t * **Note:** Difference between {@link module:engine/view/downcastwriter~DowncastWriter#mergeAttributes mergeAttributes} and\n\t * {@link module:engine/view/downcastwriter~DowncastWriter#mergeContainers mergeContainers} is that `mergeAttributes` merges two\n\t * {@link module:engine/view/attributeelement~AttributeElement attribute elements} or {@link module:engine/view/text~Text text nodes}\n\t * while `mergeContainer` merges two {@link module:engine/view/containerelement~ContainerElement container elements}.\n\t *\n\t * @see module:engine/view/attributeelement~AttributeElement\n\t * @see module:engine/view/containerelement~ContainerElement\n\t * @see module:engine/view/downcastwriter~DowncastWriter#mergeContainers\n\t * @param {module:engine/view/position~Position} position Merge position.\n\t * @returns {module:engine/view/position~Position} Position after merge.\n\t */\n\tmergeAttributes( position ) {\n\t\tconst positionOffset = position.offset;\n\t\tconst positionParent = position.parent;\n\n\t\t// When inside text node - nothing to merge.\n\t\tif ( positionParent.is( 'text' ) ) {\n\t\t\treturn position;\n\t\t}\n\n\t\t// When inside empty attribute - remove it.\n\t\tif ( positionParent.is( 'attributeElement' ) && positionParent.childCount === 0 ) {\n\t\t\tconst parent = positionParent.parent;\n\t\t\tconst offset = positionParent.index;\n\n\t\t\tpositionParent._remove();\n\t\t\tthis._removeFromClonedElementsGroup( positionParent );\n\n\t\t\treturn this.mergeAttributes( new Position( parent, offset ) );\n\t\t}\n\n\t\tconst nodeBefore = positionParent.getChild( positionOffset - 1 );\n\t\tconst nodeAfter = positionParent.getChild( positionOffset );\n\n\t\t// Position should be placed between two nodes.\n\t\tif ( !nodeBefore || !nodeAfter ) {\n\t\t\treturn position;\n\t\t}\n\n\t\t// When position is between two text nodes.\n\t\tif ( nodeBefore.is( 'text' ) && nodeAfter.is( 'text' ) ) {\n\t\t\treturn mergeTextNodes( nodeBefore, nodeAfter );\n\t\t}\n\t\t// When position is between two same attribute elements.\n\t\telse if ( nodeBefore.is( 'attributeElement' ) && nodeAfter.is( 'attributeElement' ) && nodeBefore.isSimilar( nodeAfter ) ) {\n\t\t\t// Move all children nodes from node placed after selection and remove that node.\n\t\t\tconst count = nodeBefore.childCount;\n\t\t\tnodeBefore._appendChild( nodeAfter.getChildren() );\n\n\t\t\tnodeAfter._remove();\n\t\t\tthis._removeFromClonedElementsGroup( nodeAfter );\n\n\t\t\t// New position is located inside the first node, before new nodes.\n\t\t\t// Call this method recursively to merge again if needed.\n\t\t\treturn this.mergeAttributes( new Position( nodeBefore, count ) );\n\t\t}\n\n\t\treturn position;\n\t}\n\n\t/**\n\t * Merges two {@link module:engine/view/containerelement~ContainerElement container elements} that are before and after given position.\n\t * Precisely, the element after the position is removed and it's contents are moved to element before the position.\n\t *\n\t * <p>foo</p>^<p>bar</p> -> <p>foo^bar</p>\n\t * <div>foo</div>^<p>bar</p> -> <div>foo^bar</div>\n\t *\n\t * **Note:** Difference between {@link module:engine/view/downcastwriter~DowncastWriter#mergeAttributes mergeAttributes} and\n\t * {@link module:engine/view/downcastwriter~DowncastWriter#mergeContainers mergeContainers} is that `mergeAttributes` merges two\n\t * {@link module:engine/view/attributeelement~AttributeElement attribute elements} or {@link module:engine/view/text~Text text nodes}\n\t * while `mergeContainer` merges two {@link module:engine/view/containerelement~ContainerElement container elements}.\n\t *\n\t * @see module:engine/view/attributeelement~AttributeElement\n\t * @see module:engine/view/containerelement~ContainerElement\n\t * @see module:engine/view/downcastwriter~DowncastWriter#mergeAttributes\n\t * @param {module:engine/view/position~Position} position Merge position.\n\t * @returns {module:engine/view/position~Position} Position after merge.\n\t */\n\tmergeContainers( position ) {\n\t\tconst prev = position.nodeBefore;\n\t\tconst next = position.nodeAfter;\n\n\t\tif ( !prev || !next || !prev.is( 'containerElement' ) || !next.is( 'containerElement' ) ) {\n\t\t\t/**\n\t\t\t * Element before and after given position cannot be merged.\n\t\t\t *\n\t\t\t * @error view-writer-merge-containers-invalid-position\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-writer-merge-containers-invalid-position: ' +\n\t\t\t\t'Element before and after given position cannot be merged.' );\n\t\t}\n\n\t\tconst lastChild = prev.getChild( prev.childCount - 1 );\n\t\tconst newPosition = lastChild instanceof Text ? Position._createAt( lastChild, 'end' ) : Position._createAt( prev, 'end' );\n\n\t\tthis.move( Range._createIn( next ), Position._createAt( prev, 'end' ) );\n\t\tthis.remove( Range._createOn( next ) );\n\n\t\treturn newPosition;\n\t}\n\n\t/**\n\t * Insert node or nodes at specified position. Takes care about breaking attributes before insertion\n\t * and merging them afterwards.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-insert-invalid-node` when nodes to insert\n\t * contains instances that are not {@link module:engine/view/text~Text Texts},\n\t * {@link module:engine/view/attributeelement~AttributeElement AttributeElements},\n\t * {@link module:engine/view/containerelement~ContainerElement ContainerElements},\n\t * {@link module:engine/view/emptyelement~EmptyElement EmptyElements} or\n\t * {@link module:engine/view/uielement~UIElement UIElements}.\n\t *\n\t * @param {module:engine/view/position~Position} position Insertion position.\n\t * @param {module:engine/view/text~Text|module:engine/view/attributeelement~AttributeElement|\n\t * module:engine/view/containerelement~ContainerElement|module:engine/view/emptyelement~EmptyElement|\n\t * module:engine/view/uielement~UIElement|Iterable.<module:engine/view/text~Text|\n\t * module:engine/view/attributeelement~AttributeElement|module:engine/view/containerelement~ContainerElement|\n\t * module:engine/view/emptyelement~EmptyElement|module:engine/view/uielement~UIElement>} nodes Node or nodes to insert.\n\t * @returns {module:engine/view/range~Range} Range around inserted nodes.\n\t */\n\tinsert( position, nodes ) {\n\t\tnodes = isIterable( nodes ) ? [ ...nodes ] : [ nodes ];\n\n\t\t// Check if nodes to insert are instances of AttributeElements, ContainerElements, EmptyElements, UIElements or Text.\n\t\tvalidateNodesToInsert( nodes );\n\n\t\tconst container = getParentContainer( position );\n\n\t\tif ( !container ) {\n\t\t\t/**\n\t\t\t * Position's parent container cannot be found.\n\t\t\t *\n\t\t\t * @error view-writer-invalid-position-container\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-writer-invalid-position-container' );\n\t\t}\n\n\t\tconst insertionPosition = this._breakAttributes( position, true );\n\t\tconst length = container._insertChild( insertionPosition.offset, nodes );\n\n\t\tfor ( const node of nodes ) {\n\t\t\tthis._addToClonedElementsGroup( node );\n\t\t}\n\n\t\tconst endPosition = insertionPosition.getShiftedBy( length );\n\t\tconst start = this.mergeAttributes( insertionPosition );\n\n\t\t// When no nodes were inserted - return collapsed range.\n\t\tif ( length === 0 ) {\n\t\t\treturn new Range( start, start );\n\t\t} else {\n\t\t\t// If start position was merged - move end position.\n\t\t\tif ( !start.isEqual( insertionPosition ) ) {\n\t\t\t\tendPosition.offset--;\n\t\t\t}\n\n\t\t\tconst end = this.mergeAttributes( endPosition );\n\n\t\t\treturn new Range( start, end );\n\t\t}\n\t}\n\n\t/**\n\t * Removes provided range from the container.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n\t * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions are not placed inside\n\t * same parent container.\n\t *\n\t * @param {module:engine/view/range~Range|module:engine/view/item~Item} rangeOrItem Range to remove from container\n\t * or an {@link module:engine/view/item~Item item} to remove. If range is provided, after removing, it will be updated\n\t * to a collapsed range showing the new position.\n\t * @returns {module:engine/view/documentfragment~DocumentFragment} Document fragment containing removed nodes.\n\t */\n\tremove( rangeOrItem ) {\n\t\tconst range = rangeOrItem instanceof Range ? rangeOrItem : Range._createOn( rangeOrItem );\n\n\t\tvalidateRangeContainer( range );\n\n\t\t// If range is collapsed - nothing to remove.\n\t\tif ( range.isCollapsed ) {\n\t\t\treturn new DocumentFragment();\n\t\t}\n\n\t\t// Break attributes at range start and end.\n\t\tconst { start: breakStart, end: breakEnd } = this._breakAttributesRange( range, true );\n\t\tconst parentContainer = breakStart.parent;\n\n\t\tconst count = breakEnd.offset - breakStart.offset;\n\n\t\t// Remove nodes in range.\n\t\tconst removed = parentContainer._removeChildren( breakStart.offset, count );\n\n\t\tfor ( const node of removed ) {\n\t\t\tthis._removeFromClonedElementsGroup( node );\n\t\t}\n\n\t\t// Merge after removing.\n\t\tconst mergePosition = this.mergeAttributes( breakStart );\n\t\trange.start = mergePosition;\n\t\trange.end = mergePosition.clone();\n\n\t\t// Return removed nodes.\n\t\treturn new DocumentFragment( removed );\n\t}\n\n\t/**\n\t * Removes matching elements from given range.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n\t * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions are not placed inside\n\t * same parent container.\n\t *\n\t * @param {module:engine/view/range~Range} range Range to clear.\n\t * @param {module:engine/view/element~Element} element Element to remove.\n\t */\n\tclear( range, element ) {\n\t\tvalidateRangeContainer( range );\n\n\t\t// Create walker on given range.\n\t\t// We walk backward because when we remove element during walk it modifies range end position.\n\t\tconst walker = range.getWalker( {\n\t\t\tdirection: 'backward',\n\t\t\tignoreElementEnd: true\n\t\t} );\n\n\t\t// Let's walk.\n\t\tfor ( const current of walker ) {\n\t\t\tconst item = current.item;\n\t\t\tlet rangeToRemove;\n\n\t\t\t// When current item matches to the given element.\n\t\t\tif ( item.is( 'element' ) && element.isSimilar( item ) ) {\n\t\t\t\t// Create range on this element.\n\t\t\t\trangeToRemove = Range._createOn( item );\n\t\t\t\t// When range starts inside Text or TextProxy element.\n\t\t\t} else if ( !current.nextPosition.isAfter( range.start ) && item.is( 'textProxy' ) ) {\n\t\t\t\t// We need to check if parent of this text matches to given element.\n\t\t\t\tconst parentElement = item.getAncestors().find( ancestor => {\n\t\t\t\t\treturn ancestor.is( 'element' ) && element.isSimilar( ancestor );\n\t\t\t\t} );\n\n\t\t\t\t// If it is then create range inside this element.\n\t\t\t\tif ( parentElement ) {\n\t\t\t\t\trangeToRemove = Range._createIn( parentElement );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we have found element to remove.\n\t\t\tif ( rangeToRemove ) {\n\t\t\t\t// We need to check if element range stick out of the given range and truncate if it is.\n\t\t\t\tif ( rangeToRemove.end.isAfter( range.end ) ) {\n\t\t\t\t\trangeToRemove.end = range.end;\n\t\t\t\t}\n\n\t\t\t\tif ( rangeToRemove.start.isBefore( range.start ) ) {\n\t\t\t\t\trangeToRemove.start = range.start;\n\t\t\t\t}\n\n\t\t\t\t// At the end we remove range with found element.\n\t\t\t\tthis.remove( rangeToRemove );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Moves nodes from provided range to target position.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n\t * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions are not placed inside\n\t * same parent container.\n\t *\n\t * @param {module:engine/view/range~Range} sourceRange Range containing nodes to move.\n\t * @param {module:engine/view/position~Position} targetPosition Position to insert.\n\t * @returns {module:engine/view/range~Range} Range in target container. Inserted nodes are placed between\n\t * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions.\n\t */\n\tmove( sourceRange, targetPosition ) {\n\t\tlet nodes;\n\n\t\tif ( targetPosition.isAfter( sourceRange.end ) ) {\n\t\t\ttargetPosition = this._breakAttributes( targetPosition, true );\n\n\t\t\tconst parent = targetPosition.parent;\n\t\t\tconst countBefore = parent.childCount;\n\n\t\t\tsourceRange = this._breakAttributesRange( sourceRange, true );\n\n\t\t\tnodes = this.remove( sourceRange );\n\n\t\t\ttargetPosition.offset += ( parent.childCount - countBefore );\n\t\t} else {\n\t\t\tnodes = this.remove( sourceRange );\n\t\t}\n\n\t\treturn this.insert( targetPosition, nodes );\n\t}\n\n\t/**\n * Wraps elements within range with provided {@link module:engine/view/attributeelement~AttributeElement AttributeElement}.\n * If a collapsed range is provided, it will be wrapped only if it is equal to view selection.\n *\n * If a collapsed range was passed and is same as selection, the selection\n * will be moved to the inside of the wrapped attribute element.\n *\n * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-invalid-range-container`\n * when {@link module:engine/view/range~Range#start}\n * and {@link module:engine/view/range~Range#end} positions are not placed inside same parent container.\n *\n * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-invalid-attribute` when passed attribute element is not\n * an instance of {@link module:engine/view/attributeelement~AttributeElement AttributeElement}.\n *\n * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-nonselection-collapsed-range` when passed range\n * is collapsed and different than view selection.\n *\n * @param {module:engine/view/range~Range} range Range to wrap.\n * @param {module:engine/view/attributeelement~AttributeElement} attribute Attribute element to use as wrapper.\n * @returns {module:engine/view/range~Range} range Range after wrapping, spanning over wrapping attribute element.\n */\n\twrap( range, attribute ) {\n\t\tif ( !( attribute instanceof AttributeElement ) ) {\n\t\t\tthrow new CKEditorError( 'view-writer-wrap-invalid-attribute' );\n\t\t}\n\n\t\tvalidateRangeContainer( range );\n\n\t\tif ( !range.isCollapsed ) {\n\t\t\t// Non-collapsed range. Wrap it with the attribute element.\n\t\t\treturn this._wrapRange( range, attribute );\n\t\t} else {\n\t\t\t// Collapsed range. Wrap position.\n\t\t\tlet position = range.start;\n\n\t\t\tif ( position.parent.is( 'element' ) && !_hasNonUiChildren( position.parent ) ) {\n\t\t\t\tposition = position.getLastMatchingPosition( value => value.item.is( 'uiElement' ) );\n\t\t\t}\n\n\t\t\tposition = this._wrapPosition( position, attribute );\n\t\t\tconst viewSelection = this.document.selection;\n\n\t\t\t// If wrapping position is equal to view selection, move view selection inside wrapping attribute element.\n\t\t\tif ( viewSelection.isCollapsed && viewSelection.getFirstPosition().isEqual( range.start ) ) {\n\t\t\t\tthis.setSelection( position );\n\t\t\t}\n\n\t\t\treturn new Range( position );\n\t\t}\n\t}\n\n\t/**\n\t * Unwraps nodes within provided range from attribute element.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n\t * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions are not placed inside\n\t * same parent container.\n\t *\n\t * @param {module:engine/view/range~Range} range\n\t * @param {module:engine/view/attributeelement~AttributeElement} attribute\n\t */\n\tunwrap( range, attribute ) {\n\t\tif ( !( attribute instanceof AttributeElement ) ) {\n\t\t\t/**\n\t\t\t * Attribute element need to be instance of attribute element.\n\t\t\t *\n\t\t\t * @error view-writer-unwrap-invalid-attribute\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-writer-unwrap-invalid-attribute' );\n\t\t}\n\n\t\tvalidateRangeContainer( range );\n\n\t\t// If range is collapsed - nothing to unwrap.\n\t\tif ( range.isCollapsed ) {\n\t\t\treturn range;\n\t\t}\n\n\t\t// Break attributes at range start and end.\n\t\tconst { start: breakStart, end: breakEnd } = this._breakAttributesRange( range, true );\n\t\tconst parentContainer = breakStart.parent;\n\n\t\t// Unwrap children located between break points.\n\t\tconst newRange = this._unwrapChildren( parentContainer, breakStart.offset, breakEnd.offset, attribute );\n\n\t\t// Merge attributes at the both ends and return a new range.\n\t\tconst start = this.mergeAttributes( newRange.start );\n\n\t\t// If start position was merged - move end position back.\n\t\tif ( !start.isEqual( newRange.start ) ) {\n\t\t\tnewRange.end.offset--;\n\t\t}\n\n\t\tconst end = this.mergeAttributes( newRange.end );\n\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Renames element by creating a copy of renamed element but with changed name and then moving contents of the\n\t * old element to the new one. Keep in mind that this will invalidate all {@link module:engine/view/position~Position positions} which\n\t * has renamed element as {@link module:engine/view/position~Position#parent a parent}.\n\t *\n\t * New element has to be created because `Element#tagName` property in DOM is readonly.\n\t *\n\t * Since this function creates a new element and removes the given one, the new element is returned to keep reference.\n\t *\n\t * @param {String} newName New name for element.\n\t * @param {module:engine/view/containerelement~ContainerElement} viewElement Element to be renamed.\n\t */\n\trename( newName, viewElement ) {\n\t\tconst newElement = new ContainerElement( newName, viewElement.getAttributes() );\n\n\t\tthis.insert( Position._createAfter( viewElement ), newElement );\n\t\tthis.move( Range._createIn( viewElement ), Position._createAt( newElement, 0 ) );\n\t\tthis.remove( Range._createOn( viewElement ) );\n\n\t\treturn newElement;\n\t}\n\n\t/**\n\t * Cleans up memory by removing obsolete cloned elements group from the writer.\n\t *\n\t * Should be used whenever all {@link module:engine/view/attributeelement~AttributeElement attribute elements}\n\t * with the same {@link module:engine/view/attributeelement~AttributeElement#id id} are going to be removed from the view and\n\t * the group will no longer be needed.\n\t *\n\t * Cloned elements group are not removed automatically in case if the group is still needed after all its elements\n\t * were removed from the view.\n\t *\n\t * Keep in mind that group names are equal to the `id` property of the attribute element.\n\t *\n\t * @param {String} groupName Name of the group to clear.\n\t */\n\tclearClonedElementsGroup( groupName ) {\n\t\tthis._cloneGroups.delete( groupName );\n\t}\n\n\t/**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/view/position~Position position},\n\t * * parent element and offset (offset defaults to `0`),\n\t * * parent element and `'end'` (sets position at the end of that element),\n\t * * {@link module:engine/view/item~Item view item} and `'before'` or `'after'` (sets position before or after given view item).\n\t *\n\t * This method is a shortcut to other constructors such as:\n\t *\n\t * * {@link #createPositionBefore},\n\t * * {@link #createPositionAfter},\n\t *\n\t * @param {module:engine/view/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tcreatePositionAt( itemOrPosition, offset ) {\n\t\treturn Position._createAt( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Creates a new position after given view item.\n\t *\n\t * @param {module:engine/view/item~Item} item View item after which the position should be located.\n\t * @returns {module:engine/view/position~Position}\n\t */\n\tcreatePositionAfter( item ) {\n\t\treturn Position._createAfter( item );\n\t}\n\n\t/**\n\t * Creates a new position before given view item.\n\t *\n\t * @param {module:engine/view/item~Item} item View item before which the position should be located.\n\t * @returns {module:engine/view/position~Position}\n\t */\n\tcreatePositionBefore( item ) {\n\t\treturn Position._createBefore( item );\n\t}\n\n\t/**\n\t * Creates a range spanning from `start` position to `end` position.\n\t *\n\t * **Note:** This factory method creates it's own {@link module:engine/view/position~Position} instances basing on passed values.\n\t *\n\t * @param {module:engine/view/position~Position} start Start position.\n\t * @param {module:engine/view/position~Position} [end] End position. If not set, range will be collapsed at `start` position.\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tcreateRange( start, end ) {\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Creates a range that starts before given {@link module:engine/view/item~Item view item} and ends after it.\n\t *\n\t * @param {module:engine/view/item~Item} item\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tcreateRangeOn( item ) {\n\t\treturn Range._createOn( item );\n\t}\n\n\t/**\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * @param {module:engine/view/element~Element} element Element which is a parent for the range.\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tcreateRangeIn( element ) {\n\t\treturn Range._createIn( element );\n\t}\n\n\t/**\n\t Creates new {@link module:engine/view/selection~Selection} instance.\n\t *\n\t * \t\t// Creates empty selection without ranges.\n\t *\t\tconst selection = writer.createSelection();\n\t *\n\t *\t\t// Creates selection at the given range.\n\t *\t\tconst range = writer.createRange( start, end );\n\t *\t\tconst selection = writer.createSelection( range );\n\t *\n\t *\t\t// Creates selection at the given ranges\n\t * \t\tconst ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t *\t\tconst selection = writer.createSelection( ranges );\n\t *\n\t *\t\t// Creates selection from the other selection.\n\t *\t\tconst otherSelection = writer.createSelection();\n\t *\t\tconst selection = writer.createSelection( otherSelection );\n\t *\n\t *\t\t// Creates selection from the document selection.\n\t *\t\tconst selection = writer.createSelection( editor.editing.view.document.selection );\n\t *\n\t * \t\t// Creates selection at the given position.\n\t *\t\tconst position = writer.createPositionFromPath( root, path );\n\t *\t\tconst selection = writer.createSelection( position );\n\t *\n\t *\t\t// Creates collapsed selection at the position of given item and offset.\n\t *\t\tconst paragraph = writer.createContainerElement( 'paragraph' );\n\t *\t\tconst selection = writer.createSelection( paragraph, offset );\n\t *\n\t *\t\t// Creates a range inside an {@link module:engine/view/element~Element element} which starts before the\n\t *\t\t// first child of that element and ends after the last child of that element.\n\t *\t\tconst selection = writer.createSelection( paragraph, 'in' );\n\t *\n\t *\t\t// Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends\n\t *\t\t// just after the item.\n\t *\t\tconst selection = writer.createSelection( paragraph, 'on' );\n\t *\n\t * `Selection`'s constructor allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t *\t\t// Creates backward selection.\n\t *\t\tconst selection = writer.createSelection( range, { backward: true } );\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be properly handled by screen readers).\n\t *\n\t *\t\t// Creates fake selection with label.\n\t *\t\tconst selection = writer.createSelection( range, { fake: true, label: 'foo' } );\n\t *\n\t * @param {module:engine/view/selection~Selectable} [selectable=null]\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Offset or place when selectable is an `Item`.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.backward] Sets this selection instance to be backward.\n\t * @param {Boolean} [options.fake] Sets this selection instance to be marked as `fake`.\n\t * @param {String} [options.label] Label for the fake selection.\n\t * @returns {module:engine/view/selection~Selection}\n\t */\n\tcreateSelection( selectable, placeOrOffset, options ) {\n\t\treturn new Selection( selectable, placeOrOffset, options );\n\t}\n\n\t/**\n\t * Wraps children with provided `wrapElement`. Only children contained in `parent` element between\n\t * `startOffset` and `endOffset` will be wrapped.\n\t *\n\t * @private\n\t * @param {module:engine/view/element~Element} parent\n\t * @param {Number} startOffset\n\t * @param {Number} endOffset\n\t * @param {module:engine/view/element~Element} wrapElement\n\t */\n\t_wrapChildren( parent, startOffset, endOffset, wrapElement ) {\n\t\tlet i = startOffset;\n\t\tconst wrapPositions = [];\n\n\t\twhile ( i < endOffset ) {\n\t\t\tconst child = parent.getChild( i );\n\t\t\tconst isText = child.is( 'text' );\n\t\t\tconst isAttribute = child.is( 'attributeElement' );\n\t\t\tconst isEmpty = child.is( 'emptyElement' );\n\t\t\tconst isUI = child.is( 'uiElement' );\n\n\t\t\t//\n\t\t\t// (In all examples, assume that `wrapElement` is `<span class=\"foo\">` element.)\n\t\t\t//\n\t\t\t// Check if `wrapElement` can be joined with the wrapped element. One of requirements is having same name.\n\t\t\t// If possible, join elements.\n\t\t\t//\n\t\t\t// <p><span class=\"bar\">abc</span></p> --> <p><span class=\"foo bar\">abc</span></p>\n\t\t\t//\n\t\t\tif ( isAttribute && this._wrapAttributeElement( wrapElement, child ) ) {\n\t\t\t\twrapPositions.push(\tnew Position( parent, i ) );\n\t\t\t}\n\t\t\t//\n\t\t\t// Wrap the child if it is not an attribute element or if it is an attribute element that should be inside\n\t\t\t// `wrapElement` (due to priority).\n\t\t\t//\n\t\t\t// <p>abc</p> --> <p><span class=\"foo\">abc</span></p>\n\t\t\t// <p><strong>abc</strong></p> --> <p><span class=\"foo\"><strong>abc</strong></span></p>\n\t\t\t//\n\t\t\telse if ( isText || isEmpty || isUI || ( isAttribute && shouldABeOutsideB( wrapElement, child ) ) ) {\n\t\t\t\t// Clone attribute.\n\t\t\t\tconst newAttribute = wrapElement._clone();\n\n\t\t\t\t// Wrap current node with new attribute.\n\t\t\t\tchild._remove();\n\t\t\t\tnewAttribute._appendChild( child );\n\n\t\t\t\tparent._insertChild( i, newAttribute );\n\t\t\t\tthis._addToClonedElementsGroup( newAttribute );\n\n\t\t\t\twrapPositions.push(\tnew Position( parent, i ) );\n\t\t\t}\n\t\t\t//\n\t\t\t// If other nested attribute is found and it wasn't wrapped (see above), continue wrapping inside it.\n\t\t\t//\n\t\t\t// <p><a href=\"foo.html\">abc</a></p> --> <p><a href=\"foo.html\"><span class=\"foo\">abc</span></a></p>\n\t\t\t//\n\t\t\telse if ( isAttribute ) {\n\t\t\t\tthis._wrapChildren( child, 0, child.childCount, wrapElement );\n\t\t\t}\n\n\t\t\ti++;\n\t\t}\n\n\t\t// Merge at each wrap.\n\t\tlet offsetChange = 0;\n\n\t\tfor ( const position of wrapPositions ) {\n\t\t\tposition.offset -= offsetChange;\n\n\t\t\t// Do not merge with elements outside selected children.\n\t\t\tif ( position.offset == startOffset ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst newPosition = this.mergeAttributes( position );\n\n\t\t\t// If nodes were merged - other merge offsets will change.\n\t\t\tif ( !newPosition.isEqual( position ) ) {\n\t\t\t\toffsetChange++;\n\t\t\t\tendOffset--;\n\t\t\t}\n\t\t}\n\n\t\treturn Range._createFromParentsAndOffsets( parent, startOffset, parent, endOffset );\n\t}\n\n\t/**\n\t * Unwraps children from provided `unwrapElement`. Only children contained in `parent` element between\n\t * `startOffset` and `endOffset` will be unwrapped.\n\t *\n\t * @private\n\t * @param {module:engine/view/element~Element} parent\n\t * @param {Number} startOffset\n\t * @param {Number} endOffset\n\t * @param {module:engine/view/element~Element} unwrapElement\n\t */\n\t_unwrapChildren( parent, startOffset, endOffset, unwrapElement ) {\n\t\tlet i = startOffset;\n\t\tconst unwrapPositions = [];\n\n\t\t// Iterate over each element between provided offsets inside parent.\n\t\t// We don't use tree walker or range iterator because we will be removing and merging potentially multiple nodes,\n\t\t// so it could get messy. It is safer to it manually in this case.\n\t\twhile ( i < endOffset ) {\n\t\t\tconst child = parent.getChild( i );\n\n\t\t\t// Skip all text nodes. There should be no container element's here either.\n\t\t\tif ( !child.is( 'attributeElement' ) ) {\n\t\t\t\ti++;\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t//\n\t\t\t// (In all examples, assume that `unwrapElement` is `<span class=\"foo\">` element.)\n\t\t\t//\n\t\t\t// If the child is similar to the given attribute element, unwrap it - it will be completely removed.\n\t\t\t//\n\t\t\t// <p><span class=\"foo\">abc</span>xyz</p> --> <p>abcxyz</p>\n\t\t\t//\n\t\t\tif ( child.isSimilar( unwrapElement ) ) {\n\t\t\t\tconst unwrapped = child.getChildren();\n\t\t\t\tconst count = child.childCount;\n\n\t\t\t\t// Replace wrapper element with its children\n\t\t\t\tchild._remove();\n\t\t\t\tparent._insertChild( i, unwrapped );\n\n\t\t\t\tthis._removeFromClonedElementsGroup( child );\n\n\t\t\t\t// Save start and end position of moved items.\n\t\t\t\tunwrapPositions.push(\n\t\t\t\t\tnew Position( parent, i ),\n\t\t\t\t\tnew Position( parent, i + count )\n\t\t\t\t);\n\n\t\t\t\t// Skip elements that were unwrapped. Assuming there won't be another element to unwrap in child elements.\n\t\t\t\ti += count;\n\t\t\t\tendOffset += count - 1;\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t//\n\t\t\t// If the child is not similar but is an attribute element, try partial unwrapping - remove the same attributes/styles/classes.\n\t\t\t// Partial unwrapping will happen only if the elements have the same name.\n\t\t\t//\n\t\t\t// <p><span class=\"foo bar\">abc</span>xyz</p> --> <p><span class=\"bar\">abc</span>xyz</p>\n\t\t\t// <p><i class=\"foo\">abc</i>xyz</p> --> <p><i class=\"foo\">abc</i>xyz</p>\n\t\t\t//\n\t\t\tif ( this._unwrapAttributeElement( unwrapElement, child ) ) {\n\t\t\t\tunwrapPositions.push(\n\t\t\t\t\tnew Position( parent, i ),\n\t\t\t\t\tnew Position( parent, i + 1 )\n\t\t\t\t);\n\n\t\t\t\ti++;\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t//\n\t\t\t// If other nested attribute is found, look through it's children for elements to unwrap.\n\t\t\t//\n\t\t\t// <p><i><span class=\"foo\">abc</span></i><p> --> <p><i>abc</i><p>\n\t\t\t//\n\t\t\tthis._unwrapChildren( child, 0, child.childCount, unwrapElement );\n\n\t\t\ti++;\n\t\t}\n\n\t\t// Merge at each unwrap.\n\t\tlet offsetChange = 0;\n\n\t\tfor ( const position of unwrapPositions ) {\n\t\t\tposition.offset -= offsetChange;\n\n\t\t\t// Do not merge with elements outside selected children.\n\t\t\tif ( position.offset == startOffset || position.offset == endOffset ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst newPosition = this.mergeAttributes( position );\n\n\t\t\t// If nodes were merged - other merge offsets will change.\n\t\t\tif ( !newPosition.isEqual( position ) ) {\n\t\t\t\toffsetChange++;\n\t\t\t\tendOffset--;\n\t\t\t}\n\t\t}\n\n\t\treturn Range._createFromParentsAndOffsets( parent, startOffset, parent, endOffset );\n\t}\n\n\t/**\n\t * Helper function for `view.writer.wrap`. Wraps range with provided attribute element.\n\t * This method will also merge newly added attribute element with its siblings whenever possible.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-invalid-attribute` when passed attribute element is not\n\t * an instance of {@link module:engine/view/attributeelement~AttributeElement AttributeElement}.\n\t *\n\t * @private\n\t * @param {module:engine/view/range~Range} range\n\t * @param {module:engine/view/attributeelement~AttributeElement} attribute\n\t * @returns {module:engine/view/range~Range} New range after wrapping, spanning over wrapping attribute element.\n\t */\n\t_wrapRange( range, attribute ) {\n\t\t// Break attributes at range start and end.\n\t\tconst { start: breakStart, end: breakEnd } = this._breakAttributesRange( range, true );\n\t\tconst parentContainer = breakStart.parent;\n\n\t\t// Wrap all children with attribute.\n\t\tconst newRange = this._wrapChildren( parentContainer, breakStart.offset, breakEnd.offset, attribute );\n\n\t\t// Merge attributes at the both ends and return a new range.\n\t\tconst start = this.mergeAttributes( newRange.start );\n\n\t\t// If start position was merged - move end position back.\n\t\tif ( !start.isEqual( newRange.start ) ) {\n\t\t\tnewRange.end.offset--;\n\t\t}\n\t\tconst end = this.mergeAttributes( newRange.end );\n\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Helper function for {@link #wrap}. Wraps position with provided attribute element.\n\t * This method will also merge newly added attribute element with its siblings whenever possible.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-invalid-attribute` when passed attribute element is not\n\t * an instance of {@link module:engine/view/attributeelement~AttributeElement AttributeElement}.\n\t *\n\t * @private\n\t * @param {module:engine/view/position~Position} position\n\t * @param {module:engine/view/attributeelement~AttributeElement} attribute\n\t * @returns {module:engine/view/position~Position} New position after wrapping.\n\t */\n\t_wrapPosition( position, attribute ) {\n\t\t// Return same position when trying to wrap with attribute similar to position parent.\n\t\tif ( attribute.isSimilar( position.parent ) ) {\n\t\t\treturn movePositionToTextNode( position.clone() );\n\t\t}\n\n\t\t// When position is inside text node - break it and place new position between two text nodes.\n\t\tif ( position.parent.is( 'text' ) ) {\n\t\t\tposition = breakTextNode( position );\n\t\t}\n\n\t\t// Create fake element that will represent position, and will not be merged with other attributes.\n\t\tconst fakePosition = this.createAttributeElement();\n\t\tfakePosition._priority = Number.POSITIVE_INFINITY;\n\t\tfakePosition.isSimilar = () => false;\n\n\t\t// Insert fake element in position location.\n\t\tposition.parent._insertChild( position.offset, fakePosition );\n\n\t\t// Range around inserted fake attribute element.\n\t\tconst wrapRange = new Range( position, position.getShiftedBy( 1 ) );\n\n\t\t// Wrap fake element with attribute (it will also merge if possible).\n\t\tthis.wrap( wrapRange, attribute );\n\n\t\t// Remove fake element and place new position there.\n\t\tconst newPosition = new Position( fakePosition.parent, fakePosition.index );\n\t\tfakePosition._remove();\n\n\t\t// If position is placed between text nodes - merge them and return position inside.\n\t\tconst nodeBefore = newPosition.nodeBefore;\n\t\tconst nodeAfter = newPosition.nodeAfter;\n\n\t\tif ( nodeBefore instanceof Text && nodeAfter instanceof Text ) {\n\t\t\treturn mergeTextNodes( nodeBefore, nodeAfter );\n\t\t}\n\n\t\t// If position is next to text node - move position inside.\n\t\treturn movePositionToTextNode( newPosition );\n\t}\n\n\t/**\n\t * \tWraps one {@link module:engine/view/attributeelement~AttributeElement AttributeElement} into another by\n\t * \tmerging them if possible. When merging is possible - all attributes, styles and classes are moved from wrapper\n\t * \telement to element being wrapped.\n\t *\n\t * \t@private\n\t * \t@param {module:engine/view/attributeelement~AttributeElement} wrapper Wrapper AttributeElement.\n\t * \t@param {module:engine/view/attributeelement~AttributeElement} toWrap AttributeElement to wrap using wrapper element.\n\t * \t@returns {Boolean} Returns `true` if elements are merged.\n\t */\n\t_wrapAttributeElement( wrapper, toWrap ) {\n\t\tif ( !canBeJoined( wrapper, toWrap ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Can't merge if name or priority differs.\n\t\tif ( wrapper.name !== toWrap.name || wrapper.priority !== toWrap.priority ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check if attributes can be merged.\n\t\tfor ( const key of wrapper.getAttributeKeys() ) {\n\t\t\t// Classes and styles should be checked separately.\n\t\t\tif ( key === 'class' || key === 'style' ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If some attributes are different we cannot wrap.\n\t\t\tif ( toWrap.hasAttribute( key ) && toWrap.getAttribute( key ) !== wrapper.getAttribute( key ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Check if styles can be merged.\n\t\tfor ( const key of wrapper.getStyleNames() ) {\n\t\t\tif ( toWrap.hasStyle( key ) && toWrap.getStyle( key ) !== wrapper.getStyle( key ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Move all attributes/classes/styles from wrapper to wrapped AttributeElement.\n\t\tfor ( const key of wrapper.getAttributeKeys() ) {\n\t\t\t// Classes and styles should be checked separately.\n\t\t\tif ( key === 'class' || key === 'style' ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Move only these attributes that are not present - other are similar.\n\t\t\tif ( !toWrap.hasAttribute( key ) ) {\n\t\t\t\tthis.setAttribute( key, wrapper.getAttribute( key ), toWrap );\n\t\t\t}\n\t\t}\n\n\t\tfor ( const key of wrapper.getStyleNames() ) {\n\t\t\tif ( !toWrap.hasStyle( key ) ) {\n\t\t\t\tthis.setStyle( key, wrapper.getStyle( key ), toWrap );\n\t\t\t}\n\t\t}\n\n\t\tfor ( const key of wrapper.getClassNames() ) {\n\t\t\tif ( !toWrap.hasClass( key ) ) {\n\t\t\t\tthis.addClass( key, toWrap );\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Unwraps {@link module:engine/view/attributeelement~AttributeElement AttributeElement} from another by removing\n\t * corresponding attributes, classes and styles. All attributes, classes and styles from wrapper should be present\n\t * inside element being unwrapped.\n\t *\n\t * @private\n\t * @param {module:engine/view/attributeelement~AttributeElement} wrapper Wrapper AttributeElement.\n\t * @param {module:engine/view/attributeelement~AttributeElement} toUnwrap AttributeElement to unwrap using wrapper element.\n\t * @returns {Boolean} Returns `true` if elements are unwrapped.\n\t **/\n\t_unwrapAttributeElement( wrapper, toUnwrap ) {\n\t\tif ( !canBeJoined( wrapper, toUnwrap ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Can't unwrap if name or priority differs.\n\t\tif ( wrapper.name !== toUnwrap.name || wrapper.priority !== toUnwrap.priority ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check if AttributeElement has all wrapper attributes.\n\t\tfor ( const key of wrapper.getAttributeKeys() ) {\n\t\t\t// Classes and styles should be checked separately.\n\t\t\tif ( key === 'class' || key === 'style' ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If some attributes are missing or different we cannot unwrap.\n\t\t\tif ( !toUnwrap.hasAttribute( key ) || toUnwrap.getAttribute( key ) !== wrapper.getAttribute( key ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Check if AttributeElement has all wrapper classes.\n\t\tif ( !toUnwrap.hasClass( ...wrapper.getClassNames() ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check if AttributeElement has all wrapper styles.\n\t\tfor ( const key of wrapper.getStyleNames() ) {\n\t\t\t// If some styles are missing or different we cannot unwrap.\n\t\t\tif ( !toUnwrap.hasStyle( key ) || toUnwrap.getStyle( key ) !== wrapper.getStyle( key ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Remove all wrapper's attributes from unwrapped element.\n\t\tfor ( const key of wrapper.getAttributeKeys() ) {\n\t\t\t// Classes and styles should be checked separately.\n\t\t\tif ( key === 'class' || key === 'style' ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tthis.removeAttribute( key, toUnwrap );\n\t\t}\n\n\t\t// Remove all wrapper's classes from unwrapped element.\n\t\tthis.removeClass( Array.from( wrapper.getClassNames() ), toUnwrap );\n\n\t\t// Remove all wrapper's styles from unwrapped element.\n\t\tthis.removeStyle( Array.from( wrapper.getStyleNames() ), toUnwrap );\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Helper function used by other `DowncastWriter` methods. Breaks attribute elements at the boundaries of given range.\n\t *\n\t * @private\n\t * @param {module:engine/view/range~Range} range Range which `start` and `end` positions will be used to break attributes.\n\t * @param {Boolean} [forceSplitText=false] If set to `true`, will break text nodes even if they are directly in container element.\n\t * This behavior will result in incorrect view state, but is needed by other view writing methods which then fixes view state.\n\t * @returns {module:engine/view/range~Range} New range with located at break positions.\n\t */\n\t_breakAttributesRange( range, forceSplitText = false ) {\n\t\tconst rangeStart = range.start;\n\t\tconst rangeEnd = range.end;\n\n\t\tvalidateRangeContainer( range );\n\n\t\t// Break at the collapsed position. Return new collapsed range.\n\t\tif ( range.isCollapsed ) {\n\t\t\tconst position = this._breakAttributes( range.start, forceSplitText );\n\n\t\t\treturn new Range( position, position );\n\t\t}\n\n\t\tconst breakEnd = this._breakAttributes( rangeEnd, forceSplitText );\n\t\tconst count = breakEnd.parent.childCount;\n\t\tconst breakStart = this._breakAttributes( rangeStart, forceSplitText );\n\n\t\t// Calculate new break end offset.\n\t\tbreakEnd.offset += breakEnd.parent.childCount - count;\n\n\t\treturn new Range( breakStart, breakEnd );\n\t}\n\n\t/**\n\t * Helper function used by other `DowncastWriter` methods. Breaks attribute elements at given position.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-cannot-break-empty-element` when break position\n\t * is placed inside {@link module:engine/view/emptyelement~EmptyElement EmptyElement}.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-cannot-break-ui-element` when break position\n\t * is placed inside {@link module:engine/view/uielement~UIElement UIElement}.\n\t *\n\t * @private\n\t * @param {module:engine/view/position~Position} position Position where to break attributes.\n\t * @param {Boolean} [forceSplitText=false] If set to `true`, will break text nodes even if they are directly in container element.\n\t * This behavior will result in incorrect view state, but is needed by other view writing methods which then fixes view state.\n\t * @returns {module:engine/view/position~Position} New position after breaking the attributes.\n\t */\n\t_breakAttributes( position, forceSplitText = false ) {\n\t\tconst positionOffset = position.offset;\n\t\tconst positionParent = position.parent;\n\n\t\t// If position is placed inside EmptyElement - throw an exception as we cannot break inside.\n\t\tif ( position.parent.is( 'emptyElement' ) ) {\n\t\t\t/**\n\t\t\t * Cannot break inside EmptyElement instance.\n\t\t\t *\n\t\t\t * @error view-writer-cannot-break-empty-element\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-writer-cannot-break-empty-element' );\n\t\t}\n\n\t\t// If position is placed inside UIElement - throw an exception as we cannot break inside.\n\t\tif ( position.parent.is( 'uiElement' ) ) {\n\t\t\t/**\n\t\t\t * Cannot break inside UIElement instance.\n\t\t\t *\n\t\t\t * @error view-writer-cannot-break-ui-element\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-writer-cannot-break-ui-element' );\n\t\t}\n\n\t\t// There are no attributes to break and text nodes breaking is not forced.\n\t\tif ( !forceSplitText && positionParent.is( 'text' ) && isContainerOrFragment( positionParent.parent ) ) {\n\t\t\treturn position.clone();\n\t\t}\n\n\t\t// Position's parent is container, so no attributes to break.\n\t\tif ( isContainerOrFragment( positionParent ) ) {\n\t\t\treturn position.clone();\n\t\t}\n\n\t\t// Break text and start again in new position.\n\t\tif ( positionParent.is( 'text' ) ) {\n\t\t\treturn this._breakAttributes( breakTextNode( position ), forceSplitText );\n\t\t}\n\n\t\tconst length = positionParent.childCount;\n\n\t\t// <p>foo<b><u>bar{}</u></b></p>\n\t\t// <p>foo<b><u>bar</u>[]</b></p>\n\t\t// <p>foo<b><u>bar</u></b>[]</p>\n\t\tif ( positionOffset == length ) {\n\t\t\tconst newPosition = new Position( positionParent.parent, positionParent.index + 1 );\n\n\t\t\treturn this._breakAttributes( newPosition, forceSplitText );\n\t\t} else\n\t\t// <p>foo<b><u>{}bar</u></b></p>\n\t\t// <p>foo<b>[]<u>bar</u></b></p>\n\t\t// <p>foo{}<b><u>bar</u></b></p>\n\t\tif ( positionOffset === 0 ) {\n\t\t\tconst newPosition = new Position( positionParent.parent, positionParent.index );\n\n\t\t\treturn this._breakAttributes( newPosition, forceSplitText );\n\t\t}\n\t\t// <p>foo<b><u>b{}ar</u></b></p>\n\t\t// <p>foo<b><u>b[]ar</u></b></p>\n\t\t// <p>foo<b><u>b</u>[]<u>ar</u></b></p>\n\t\t// <p>foo<b><u>b</u></b>[]<b><u>ar</u></b></p>\n\t\telse {\n\t\t\tconst offsetAfter = positionParent.index + 1;\n\n\t\t\t// Break element.\n\t\t\tconst clonedNode = positionParent._clone();\n\n\t\t\t// Insert cloned node to position's parent node.\n\t\t\tpositionParent.parent._insertChild( offsetAfter, clonedNode );\n\t\t\tthis._addToClonedElementsGroup( clonedNode );\n\n\t\t\t// Get nodes to move.\n\t\t\tconst count = positionParent.childCount - positionOffset;\n\t\t\tconst nodesToMove = positionParent._removeChildren( positionOffset, count );\n\n\t\t\t// Move nodes to cloned node.\n\t\t\tclonedNode._appendChild( nodesToMove );\n\n\t\t\t// Create new position to work on.\n\t\t\tconst newPosition = new Position( positionParent.parent, offsetAfter );\n\n\t\t\treturn this._breakAttributes( newPosition, forceSplitText );\n\t\t}\n\t}\n\n\t/**\n\t * Stores the information that an {@link module:engine/view/attributeelement~AttributeElement attribute element} was\n\t * added to the tree. Saves the reference to the group in the given element and updates the group, so other elements\n\t * from the group now keep a reference to the given attribute element.\n\t *\n\t * The clones group can be obtained using {@link module:engine/view/attributeelement~AttributeElement#getElementsWithSameId}.\n\t *\n\t * Does nothing if added element has no {@link module:engine/view/attributeelement~AttributeElement#id id}.\n\t *\n\t * @private\n\t * @param {module:engine/view/attributeelement~AttributeElement} element Attribute element to save.\n\t */\n\t_addToClonedElementsGroup( element ) {\n\t\t// Add only if the element is in document tree.\n\t\tif ( !element.root.is( 'rootElement' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Traverse the element's children recursively to find other attribute elements that also might got inserted.\n\t\t// The loop is at the beginning so we can make fast returns later in the code.\n\t\tif ( element.is( 'element' ) ) {\n\t\t\tfor ( const child of element.getChildren() ) {\n\t\t\t\tthis._addToClonedElementsGroup( child );\n\t\t\t}\n\t\t}\n\n\t\tconst id = element.id;\n\n\t\tif ( !id ) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet group = this._cloneGroups.get( id );\n\n\t\tif ( !group ) {\n\t\t\tgroup = new Set();\n\t\t\tthis._cloneGroups.set( id, group );\n\t\t}\n\n\t\tgroup.add( element );\n\t\telement._clonesGroup = group;\n\t}\n\n\t/**\n\t * Removes all the information about the given {@link module:engine/view/attributeelement~AttributeElement attribute element}\n\t * from its clones group.\n\t *\n\t * Keep in mind, that the element will still keep a reference to the group (but the group will not keep a reference to it).\n\t * This allows to reference the whole group even if the element was already removed from the tree.\n\t *\n\t * Does nothing if the element has no {@link module:engine/view/attributeelement~AttributeElement#id id}.\n\t *\n\t * @private\n\t * @param {module:engine/view/attributeelement~AttributeElement} element Attribute element to remove.\n\t */\n\t_removeFromClonedElementsGroup( element ) {\n\t\t// Traverse the element's children recursively to find other attribute elements that also got removed.\n\t\t// The loop is at the beginning so we can make fast returns later in the code.\n\t\tif ( element.is( 'element' ) ) {\n\t\t\tfor ( const child of element.getChildren() ) {\n\t\t\t\tthis._removeFromClonedElementsGroup( child );\n\t\t\t}\n\t\t}\n\n\t\tconst id = element.id;\n\n\t\tif ( !id ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst group = this._cloneGroups.get( id );\n\n\t\tif ( !group ) {\n\t\t\treturn;\n\t\t}\n\n\t\tgroup.delete( element );\n\t\t// Not removing group from element on purpose!\n\t\t// If other parts of code have reference to this element, they will be able to get references to other elements from the group.\n\t}\n}\n\n// Helper function for `view.writer.wrap`. Checks if given element has any children that are not ui elements.\nfunction _hasNonUiChildren( parent ) {\n\treturn Array.from( parent.getChildren() ).some( child => !child.is( 'uiElement' ) );\n}\n\n/**\n * Attribute element need to be instance of attribute element.\n *\n * @error view-writer-wrap-invalid-attribute\n */\n\n// Returns first parent container of specified {@link module:engine/view/position~Position Position}.\n// Position's parent node is checked as first, then next parents are checked.\n// Note that {@link module:engine/view/documentfragment~DocumentFragment DocumentFragment} is treated like a container.\n//\n// @param {module:engine/view/position~Position} position Position used as a start point to locate parent container.\n// @returns {module:engine/view/containerelement~ContainerElement|module:engine/view/documentfragment~DocumentFragment|undefined}\n// Parent container element or `undefined` if container is not found.\nfunction getParentContainer( position ) {\n\tlet parent = position.parent;\n\n\twhile ( !isContainerOrFragment( parent ) ) {\n\t\tif ( !parent ) {\n\t\t\treturn undefined;\n\t\t}\n\t\tparent = parent.parent;\n\t}\n\n\treturn parent;\n}\n\n// Checks if first {@link module:engine/view/attributeelement~AttributeElement AttributeElement} provided to the function\n// can be wrapped otuside second element. It is done by comparing elements'\n// {@link module:engine/view/attributeelement~AttributeElement#priority priorities}, if both have same priority\n// {@link module:engine/view/element~Element#getIdentity identities} are compared.\n//\n// @param {module:engine/view/attributeelement~AttributeElement} a\n// @param {module:engine/view/attributeelement~AttributeElement} b\n// @returns {Boolean}\nfunction shouldABeOutsideB( a, b ) {\n\tif ( a.priority < b.priority ) {\n\t\treturn true;\n\t} else if ( a.priority > b.priority ) {\n\t\treturn false;\n\t}\n\n\t// When priorities are equal and names are different - use identities.\n\treturn a.getIdentity() < b.getIdentity();\n}\n\n// Returns new position that is moved to near text node. Returns same position if there is no text node before of after\n// specified position.\n//\n//\t\t<p>foo[]</p> -> <p>foo{}</p>\n//\t\t<p>[]foo</p> -> <p>{}foo</p>\n//\n// @param {module:engine/view/position~Position} position\n// @returns {module:engine/view/position~Position} Position located inside text node or same position if there is no text nodes\n// before or after position location.\nfunction movePositionToTextNode( position ) {\n\tconst nodeBefore = position.nodeBefore;\n\n\tif ( nodeBefore && nodeBefore.is( 'text' ) ) {\n\t\treturn new Position( nodeBefore, nodeBefore.data.length );\n\t}\n\n\tconst nodeAfter = position.nodeAfter;\n\n\tif ( nodeAfter && nodeAfter.is( 'text' ) ) {\n\t\treturn new Position( nodeAfter, 0 );\n\t}\n\n\treturn position;\n}\n\n// Breaks text node into two text nodes when possible.\n//\n//\t\t<p>foo{}bar</p> -> <p>foo[]bar</p>\n//\t\t<p>{}foobar</p> -> <p>[]foobar</p>\n//\t\t<p>foobar{}</p> -> <p>foobar[]</p>\n//\n// @param {module:engine/view/position~Position} position Position that need to be placed inside text node.\n// @returns {module:engine/view/position~Position} New position after breaking text node.\nfunction breakTextNode( position ) {\n\tif ( position.offset == position.parent.data.length ) {\n\t\treturn new Position( position.parent.parent, position.parent.index + 1 );\n\t}\n\n\tif ( position.offset === 0 ) {\n\t\treturn new Position( position.parent.parent, position.parent.index );\n\t}\n\n\t// Get part of the text that need to be moved.\n\tconst textToMove = position.parent.data.slice( position.offset );\n\n\t// Leave rest of the text in position's parent.\n\tposition.parent._data = position.parent.data.slice( 0, position.offset );\n\n\t// Insert new text node after position's parent text node.\n\tposition.parent.parent._insertChild( position.parent.index + 1, new Text( textToMove ) );\n\n\t// Return new position between two newly created text nodes.\n\treturn new Position( position.parent.parent, position.parent.index + 1 );\n}\n\n// Merges two text nodes into first node. Removes second node and returns merge position.\n//\n// @param {module:engine/view/text~Text} t1 First text node to merge. Data from second text node will be moved at the end of\n// this text node.\n// @param {module:engine/view/text~Text} t2 Second text node to merge. This node will be removed after merging.\n// @returns {module:engine/view/position~Position} Position after merging text nodes.\nfunction mergeTextNodes( t1, t2 ) {\n\t// Merge text data into first text node and remove second one.\n\tconst nodeBeforeLength = t1.data.length;\n\tt1._data += t2.data;\n\tt2._remove();\n\n\treturn new Position( t1, nodeBeforeLength );\n}\n\n// Checks if provided nodes are valid to insert. Checks if each node is an instance of\n// {@link module:engine/view/text~Text Text} or {@link module:engine/view/attributeelement~AttributeElement AttributeElement},\n// {@link module:engine/view/containerelement~ContainerElement ContainerElement},\n// {@link module:engine/view/emptyelement~EmptyElement EmptyElement} or\n// {@link module:engine/view/uielement~UIElement UIElement}.\n//\n// Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-insert-invalid-node` when nodes to insert\n// contains instances that are not {@link module:engine/view/text~Text Texts},\n// {@link module:engine/view/emptyelement~EmptyElement EmptyElements},\n// {@link module:engine/view/uielement~UIElement UIElements},\n// {@link module:engine/view/attributeelement~AttributeElement AttributeElements} or\n// {@link module:engine/view/containerelement~ContainerElement ContainerElements}.\n//\n// @param Iterable.<module:engine/view/text~Text|module:engine/view/attributeelement~AttributeElement\n// |module:engine/view/containerelement~ContainerElement> nodes\nfunction validateNodesToInsert( nodes ) {\n\tfor ( const node of nodes ) {\n\t\tif ( !validNodesToInsert.some( ( validNode => node instanceof validNode ) ) ) { // eslint-disable-line no-use-before-define\n\t\t\t/**\n\t\t\t * Inserted nodes should be valid to insert. of {@link module:engine/view/attributeelement~AttributeElement AttributeElement},\n\t\t\t * {@link module:engine/view/containerelement~ContainerElement ContainerElement},\n\t\t\t * {@link module:engine/view/emptyelement~EmptyElement EmptyElement},\n\t\t\t * {@link module:engine/view/uielement~UIElement UIElement}, {@link module:engine/view/text~Text Text}.\n\t\t\t *\n\t\t\t * @error view-writer-insert-invalid-node\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-writer-insert-invalid-node' );\n\t\t}\n\n\t\tif ( !node.is( 'text' ) ) {\n\t\t\tvalidateNodesToInsert( node.getChildren() );\n\t\t}\n\t}\n}\n\nconst validNodesToInsert = [ Text, AttributeElement, ContainerElement, EmptyElement, UIElement ];\n\n// Checks if node is ContainerElement or DocumentFragment, because in most cases they should be treated the same way.\n//\n// @param {module:engine/view/node~Node} node\n// @returns {Boolean} Returns `true` if node is instance of ContainerElement or DocumentFragment.\nfunction isContainerOrFragment( node ) {\n\treturn node && ( node.is( 'containerElement' ) || node.is( 'documentFragment' ) );\n}\n\n// Checks if {@link module:engine/view/range~Range#start range start} and {@link module:engine/view/range~Range#end range end} are placed\n// inside same {@link module:engine/view/containerelement~ContainerElement container element}.\n// Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when validation fails.\n//\n// @param {module:engine/view/range~Range} range\nfunction validateRangeContainer( range ) {\n\tconst startContainer = getParentContainer( range.start );\n\tconst endContainer = getParentContainer( range.end );\n\n\tif ( !startContainer || !endContainer || startContainer !== endContainer ) {\n\t\t/**\n\t\t * Range container is invalid. This can happen if {@link module:engine/view/range~Range#start range start} and\n\t\t * {@link module:engine/view/range~Range#end range end} positions are not placed inside same container or\n\t\t * parent container for these positions cannot be found.\n\t\t *\n\t\t * @error view-writer-invalid-range-container\n\t\t */\n\t\tthrow new CKEditorError( 'view-writer-invalid-range-container' );\n\t}\n}\n\n// Checks if two attribute elements can be joined together. Elements can be joined together if, and only if\n// they do not have ids specified.\n//\n// @private\n// @param {module:engine/view/element~Element} a\n// @param {module:engine/view/element~Element} b\n// @returns {Boolean}\nfunction canBeJoined( a, b ) {\n\treturn a.id === null && b.id === null;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/istext\n */\n\n/**\n * Checks if the object is a native DOM Text node.\n *\n * @param {*} obj\n * @returns {Boolean}\n */\nexport default function isText( obj ) {\n\treturn Object.prototype.toString.call( obj ) == '[object Text]';\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* globals window */\n\nimport { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';\nimport isText from '@ckeditor/ckeditor5-utils/src/dom/istext';\n\n/**\n * Set of utils related to block and inline fillers handling.\n *\n * Browsers do not allow to put caret in elements which does not have height. Because of it, we need to fill all\n * empty elements which should be selectable with elements or characters called \"fillers\". Unfortunately there is no one\n * universal filler, this is why two types are uses:\n *\n * * Block filler is an element which fill block elements, like `<p>`. CKEditor uses `<br>` as a block filler during the editing,\n * as browsers do natively. So instead of an empty `<p>` there will be `<p><br></p>`. The advantage of block filler is that\n * it is transparent for the selection, so when the caret is before the `<br>` and user presses right arrow he will be\n * moved to the next paragraph, not after the `<br>`. The disadvantage is that it breaks a block, so it can not be used\n * in the middle of a line of text. The {@link module:engine/view/filler~BR_FILLER `<br>` filler} can be replaced with any other\n * character in the data output, for instance {@link module:engine/view/filler~NBSP_FILLER non-breaking space}.\n *\n * * Inline filler is a filler which does not break a line of text, so it can be used inside the text, for instance in the empty\n * `<b>` surrendered by text: `foo<b></b>bar`, if we want to put the caret there. CKEditor uses a sequence of the zero-width\n * spaces as an {@link module:engine/view/filler~INLINE_FILLER inline filler} having the predetermined\n * {@link module:engine/view/filler~INLINE_FILLER_LENGTH length}. A sequence is used, instead of a single character to\n * avoid treating random zero-width spaces as the inline filler. Disadvantage of the inline filler is that it is not\n * transparent for the selection. The arrow key moves the caret between zero-width spaces characters, so the additional\n * code is needed to handle the caret.\n *\n * Both inline and block fillers are handled by the {@link module:engine/view/renderer~Renderer renderer} and are not present in the\n * view.\n *\n * @module engine/view/filler\n */\n\n/**\n * `<br>` filler creator. This is a function which creates `<br data-cke-filler=\"true\">` element.\n * It defines how the filler is created.\n *\n * @see module:engine/view/filler~NBSP_FILLER\n * @function\n */\nexport const BR_FILLER = domDocument => {\n\tconst fillerBr = domDocument.createElement( 'br' );\n\tfillerBr.dataset.ckeFiller = true;\n\n\treturn fillerBr;\n};\n\n/**\n * Non-breaking space filler creator. This is a function which creates `&nbsp;` text node.\n * It defines how the filler is created.\n *\n * @see module:engine/view/filler~BR_FILLER\n * @function\n */\nexport const NBSP_FILLER = domDocument => domDocument.createTextNode( '\\u00A0' );\n\n/**\n * Length of the {@link module:engine/view/filler~INLINE_FILLER INLINE_FILLER}.\n */\nexport const INLINE_FILLER_LENGTH = 7;\n\n/**\n * Inline filler which is sequence of the zero width spaces.\n */\nexport let INLINE_FILLER = '';\n\nfor ( let i = 0; i < INLINE_FILLER_LENGTH; i++ ) {\n\tINLINE_FILLER += '\\u200b';\n}\n\n/**\n * Checks if the node is a text node which starts with the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n *\n *\t\tstartsWithFiller( document.createTextNode( INLINE_FILLER ) ); // true\n *\t\tstartsWithFiller( document.createTextNode( INLINE_FILLER + 'foo' ) ); // true\n *\t\tstartsWithFiller( document.createTextNode( 'foo' ) ); // false\n *\t\tstartsWithFiller( document.createElement( 'p' ) ); // false\n *\n * @param {Node} domNode DOM node.\n * @returns {Boolean} True if the text node starts with the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n */\nexport function startsWithFiller( domNode ) {\n\treturn isText( domNode ) && ( domNode.data.substr( 0, INLINE_FILLER_LENGTH ) === INLINE_FILLER );\n}\n\n/**\n * Checks if the text node contains only the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n *\n *\t\tisInlineFiller( document.createTextNode( INLINE_FILLER ) ); // true\n *\t\tisInlineFiller( document.createTextNode( INLINE_FILLER + 'foo' ) ); // false\n *\n * @param {Text} domText DOM text node.\n * @returns {Boolean} True if the text node contains only the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n */\nexport function isInlineFiller( domText ) {\n\treturn domText.data.length == INLINE_FILLER_LENGTH && startsWithFiller( domText );\n}\n\n/**\n * Get string data from the text node, removing an {@link module:engine/view/filler~INLINE_FILLER inline filler} from it,\n * if text node contains it.\n *\n *\t\tgetDataWithoutFiller( document.createTextNode( INLINE_FILLER + 'foo' ) ) == 'foo' // true\n *\t\tgetDataWithoutFiller( document.createTextNode( 'foo' ) ) == 'foo' // true\n *\n * @param {Text} domText DOM text node, possible with inline filler.\n * @returns {String} Data without filler.\n */\nexport function getDataWithoutFiller( domText ) {\n\tif ( startsWithFiller( domText ) ) {\n\t\treturn domText.data.slice( INLINE_FILLER_LENGTH );\n\t} else {\n\t\treturn domText.data;\n\t}\n}\n\n// Cache block fillers templates to improve performance.\nconst templateBlockFillers = new WeakMap();\n\n/**\n * Checks if the node is an instance of the block filler of the given type.\n *\n *\t\tconst brFillerInstance = BR_FILLER( document );\n *\t\tisBlockFiller( brFillerInstance, BR_FILLER ); // true\n *\n * @param {Node} domNode DOM node to check.\n * @param {Function} blockFiller Block filler creator.\n * @returns {Boolean} True if text node contains only {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n */\nexport function isBlockFiller( domNode, blockFiller ) {\n\tlet templateBlockFiller = templateBlockFillers.get( blockFiller );\n\n\tif ( !templateBlockFiller ) {\n\t\ttemplateBlockFiller = blockFiller( window.document );\n\t\ttemplateBlockFillers.set( blockFiller, templateBlockFiller );\n\t}\n\n\treturn domNode.isEqualNode( templateBlockFiller );\n}\n\n/**\n * Assign key observer which move cursor from the end of the inline filler to the beginning of it when\n * the left arrow is pressed, so the filler does not break navigation.\n *\n * @param {module:engine/view/view~View} view View controller instance we should inject quirks handling on.\n */\nexport function injectQuirksHandling( view ) {\n\tview.document.on( 'keydown', jumpOverInlineFiller );\n}\n\n// Move cursor from the end of the inline filler to the beginning of it when, so the filler does not break navigation.\nfunction jumpOverInlineFiller( evt, data ) {\n\tif ( data.keyCode == keyCodes.arrowleft ) {\n\t\tconst domSelection = data.domTarget.ownerDocument.defaultView.getSelection();\n\n\t\tif ( domSelection.rangeCount == 1 && domSelection.getRangeAt( 0 ).collapsed ) {\n\t\t\tconst domParent = domSelection.getRangeAt( 0 ).startContainer;\n\t\t\tconst domOffset = domSelection.getRangeAt( 0 ).startOffset;\n\n\t\t\tif ( startsWithFiller( domParent ) && domOffset <= INLINE_FILLER_LENGTH ) {\n\t\t\t\tdomSelection.collapse( domParent, 0 );\n\t\t\t}\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/fastdiff\n */\n\n/**\n * Finds positions of the first and last change in the given string/array and generates a set of changes:\n *\n *\t\tfastDiff( '12a', '12xyza' );\n *\t\t// [ { index: 2, type: 'insert', values: [ 'x', 'y', 'z' ] } ]\n *\n *\t\tfastDiff( '12a', '12aa' );\n *\t\t// [ { index: 3, type: 'insert', values: [ 'a' ] } ]\n *\n *\t\tfastDiff( '12xyza', '12a' );\n *\t\t// [ { index: 2, type: 'delete', howMany: 3 } ]\n *\n *\t\tfastDiff( [ '1', '2', 'a', 'a' ], [ '1', '2', 'a' ] );\n *\t\t// [ { index: 3, type: 'delete', howMany: 1 } ]\n *\n *\t\tfastDiff( [ '1', '2', 'a', 'b', 'c', '3' ], [ '2', 'a', 'b' ] );\n *\t\t// [ { index: 0, type: 'insert', values: [ '2', 'a', 'b' ] }, { index: 3, type: 'delete', howMany: 6 } ]\n *\n * Passed arrays can contain any type of data, however to compare them correctly custom comparator function\n * should be passed as a third parameter:\n *\n *\t\tfastDiff( [ { value: 1 }, { value: 2 } ], [ { value: 1 }, { value: 3 } ], ( a, b ) => {\n *\t\t\treturn a.value === b.value;\n *\t\t} );\n *\t\t// [ { index: 1, type: 'insert', values: [ { value: 3 } ] }, { index: 2, type: 'delete', howMany: 1 } ]\n *\n * The resulted set of changes can be applied to the input in order to transform it into the output, for example:\n *\n *\t\tlet input = '12abc3';\n *\t\tconst output = '2ab';\n *\t\tconst changes = fastDiff( input, output );\n *\n *\t\tchanges.forEach( change => {\n *\t\t\tif ( change.type == 'insert' ) {\n *\t\t\t\tinput = input.substring( 0, change.index ) + change.values.join( '' ) + input.substring( change.index );\n *\t\t\t} else if ( change.type == 'delete' ) {\n *\t\t\t\tinput = input.substring( 0, change.index ) + input.substring( change.index + change.howMany );\n *\t\t\t}\n *\t\t} );\n *\n *\t\t// input equals output now\n *\n * or in case of arrays:\n *\n *\t\tlet input = [ '1', '2', 'a', 'b', 'c', '3' ];\n *\t\tconst output = [ '2', 'a', 'b' ];\n *\t\tconst changes = fastDiff( input, output );\n *\n *\t\tchanges.forEach( change => {\n *\t\t\tif ( change.type == 'insert' ) {\n *\t\t\t\tinput = input.slice( 0, change.index ).concat( change.values, input.slice( change.index ) );\n *\t\t\t} else if ( change.type == 'delete' ) {\n *\t\t\t\tinput = input.slice( 0, change.index ).concat( input.slice( change.index + change.howMany ) );\n *\t\t\t}\n *\t\t} );\n *\n *\t\t// input equals output now\n *\n * By passing `true` as the fourth parameter (`atomicChanges`) the output of this function will become compatible with\n * the {@link module:utils/diff~diff `diff()`} function:\n *\n *\t\tfastDiff( '12a', '12xyza' );\n *\t\t// [ 'equal', 'equal', 'insert', 'insert', 'insert', 'equal' ]\n *\n * The default output format of this function is compatible with the output format of\n * {@link module:utils/difftochanges~diffToChanges `diffToChanges()`}. The `diffToChanges()` input format is, in turn,\n * compatible with the output of {@link module:utils/diff~diff `diff()`}:\n *\n *\t\tconst a = '1234';\n *\t\tconst b = '12xyz34';\n *\n *\t\t// Both calls will return the same results (grouped changes format).\n *\t\tfastDiff( a, b );\n *\t\tdiffToChanges( diff( a, b ) );\n *\n *\t\t// Again, both calls will return the same results (atomic changes format).\n *\t\tfastDiff( a, b, null, true );\n *\t\tdiff( a, b );\n *\n *\n * @param {Array|String} a Input array or string.\n * @param {Array|String} b Input array or string.\n * @param {Function} [cmp] Optional function used to compare array values, by default `===` (strict equal operator) is used.\n * @param {Boolean} [atomicChanges=false] Whether an array of `inset|delete|equal` operations should\n * be returned instead of changes set. This makes this function compatible with {@link module:utils/diff~diff `diff()`}.\n * @returns {Array} Array of changes.\n */\nexport default function fastDiff( a, b, cmp, atomicChanges = false ) {\n\t// Set the comparator function.\n\tcmp = cmp || function( a, b ) {\n\t\treturn a === b;\n\t};\n\n\t// Transform text or any iterable into arrays for easier, consistent processing.\n\tif ( !Array.isArray( a ) ) {\n\t\ta = Array.from( a );\n\t}\n\n\tif ( !Array.isArray( b ) ) {\n\t\tb = Array.from( b );\n\t}\n\n\t// Find first and last change.\n\tconst changeIndexes = findChangeBoundaryIndexes( a, b, cmp );\n\n\t// Transform into changes array.\n\treturn atomicChanges ? changeIndexesToAtomicChanges( changeIndexes, b.length ) : changeIndexesToChanges( b, changeIndexes );\n}\n\n// Finds position of the first and last change in the given arrays. For example:\n//\n//\t\tconst indexes = findChangeBoundaryIndexes( [ '1', '2', '3', '4' ], [ '1', '3', '4', '2', '4' ] );\n//\t\tconsole.log( indexes ); // { firstIndex: 1, lastIndexOld: 3, lastIndexNew: 4 }\n//\n// The above indexes means that in the first array the modified part is `1[23]4` and in the second array it is `1[342]4`.\n// Based on such indexes, array with `insert`/`delete` operations which allows transforming first value into the second one\n// can be generated.\n//\n// @param {Array} arr1\n// @param {Array} arr2\n// @param {Function} cmp Comparator function.\n// @returns {Object}\n// @returns {Number} return.firstIndex Index of the first change in both values (always the same for both).\n// @returns {Number} result.lastIndexOld Index of the last common value in `arr1`.\n// @returns {Number} result.lastIndexNew Index of the last common value in `arr2`.\nfunction findChangeBoundaryIndexes( arr1, arr2, cmp ) {\n\t// Find the first difference between passed values.\n\tconst firstIndex = findFirstDifferenceIndex( arr1, arr2, cmp );\n\n\t// If arrays are equal return -1 indexes object.\n\tif ( firstIndex === -1 ) {\n\t\treturn { firstIndex: -1, lastIndexOld: -1, lastIndexNew: -1 };\n\t}\n\n\t// Remove the common part of each value and reverse them to make it simpler to find the last difference between them.\n\tconst oldArrayReversed = cutAndReverse( arr1, firstIndex );\n\tconst newArrayReversed = cutAndReverse( arr2, firstIndex );\n\n\t// Find the first difference between reversed values.\n\t// It should be treated as \"how many elements from the end the last difference occurred\".\n\t//\n\t// For example:\n\t//\n\t// \t\t\t\tinitial\t->\tafter cut\t-> reversed:\n\t// oldValue:\t'321ba'\t->\t'21ba'\t\t-> 'ab12'\n\t// newValue:\t'31xba'\t->\t'1xba'\t\t-> 'abx1'\n\t// lastIndex:\t\t\t\t\t\t\t-> 2\n\t//\n\t// So the last change occurred two characters from the end of the arrays.\n\tconst lastIndex = findFirstDifferenceIndex( oldArrayReversed, newArrayReversed, cmp );\n\n\t// Use `lastIndex` to calculate proper offset, starting from the beginning (`lastIndex` kind of starts from the end).\n\tconst lastIndexOld = arr1.length - lastIndex;\n\tconst lastIndexNew = arr2.length - lastIndex;\n\n\treturn { firstIndex, lastIndexOld, lastIndexNew };\n}\n\n// Returns a first index on which given arrays differ. If both arrays are the same, -1 is returned.\n//\n// @param {Array} arr1\n// @param {Array} arr2\n// @param {Function} cmp Comparator function.\n// @returns {Number}\nfunction findFirstDifferenceIndex( arr1, arr2, cmp ) {\n\tfor ( let i = 0; i < Math.max( arr1.length, arr2.length ); i++ ) {\n\t\tif ( arr1[ i ] === undefined || arr2[ i ] === undefined || !cmp( arr1[ i ], arr2[ i ] ) ) {\n\t\t\treturn i;\n\t\t}\n\t}\n\n\treturn -1; // Return -1 if arrays are equal.\n}\n\n// Returns a copy of the given array with `howMany` elements removed starting from the beginning and in reversed order.\n//\n// @param {Array} arr Array to be processed.\n// @param {Number} howMany How many elements from array beginning to remove.\n// @returns {Array} Shortened and reversed array.\nfunction cutAndReverse( arr, howMany ) {\n\treturn arr.slice( howMany ).reverse();\n}\n\n// Generates changes array based on change indexes from `findChangeBoundaryIndexes` function. This function will\n// generate array with 0 (no changes), 1 (deletion or insertion) or 2 records (insertion and deletion).\n//\n// @param {Array} newArray New array for which change indexes were calculated.\n// @param {Object} changeIndexes Change indexes object from `findChangeBoundaryIndexes` function.\n// @returns {Array.<Object>} Array of changes compatible with {@link module:utils/difftochanges~diffToChanges} format.\nfunction changeIndexesToChanges( newArray, changeIndexes ) {\n\tconst result = [];\n\tconst { firstIndex, lastIndexOld, lastIndexNew } = changeIndexes;\n\n\t// Order operations as 'insert', 'delete' array to keep compatibility with {@link module:utils/difftochanges~diffToChanges}\n\t// in most cases. However, 'diffToChanges' does not stick to any order so in some cases\n\t// (for example replacing '12345' with 'abcd') it will generate 'delete', 'insert' order.\n\tif ( lastIndexNew - firstIndex > 0 ) {\n\t\tresult.push( {\n\t\t\tindex: firstIndex,\n\t\t\ttype: 'insert',\n\t\t\tvalues: newArray.slice( firstIndex, lastIndexNew )\n\t\t} );\n\t}\n\n\tif ( lastIndexOld - firstIndex > 0 ) {\n\t\tresult.push( {\n\t\t\tindex: firstIndex + ( lastIndexNew - firstIndex ), // Increase index of what was inserted.\n\t\t\ttype: 'delete',\n\t\t\thowMany: lastIndexOld - firstIndex\n\t\t} );\n\t}\n\n\treturn result;\n}\n\n// Generates array with set `equal|insert|delete` operations based on change indexes from `findChangeBoundaryIndexes` function.\n//\n// @param {Object} changeIndexes Change indexes object from `findChangeBoundaryIndexes` function.\n// @param {Number} newLength Length of the new array on which `findChangeBoundaryIndexes` calculated change indexes.\n// @returns {Array.<String>} Array of changes compatible with {@link module:utils/diff~diff} format.\nfunction changeIndexesToAtomicChanges( changeIndexes, newLength ) {\n\tconst { firstIndex, lastIndexOld, lastIndexNew } = changeIndexes;\n\n\t// No changes.\n\tif ( firstIndex === -1 ) {\n\t\treturn Array( newLength ).fill( 'equal' );\n\t}\n\n\tlet result = [];\n\tif ( firstIndex > 0 ) {\n\t\tresult = result.concat( Array( firstIndex ).fill( 'equal' ) );\n\t}\n\n\tif ( lastIndexNew - firstIndex > 0 ) {\n\t\tresult = result.concat( Array( lastIndexNew - firstIndex ).fill( 'insert' ) );\n\t}\n\n\tif ( lastIndexOld - firstIndex > 0 ) {\n\t\tresult = result.concat( Array( lastIndexOld - firstIndex ).fill( 'delete' ) );\n\t}\n\n\tif ( lastIndexNew < newLength ) {\n\t\tresult = result.concat( Array( newLength - lastIndexNew ).fill( 'equal' ) );\n\t}\n\n\treturn result;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/diff\n */\n\nimport fastDiff from '../src/fastdiff';\n\n// The following code is based on the \"O(NP) Sequence Comparison Algorithm\"\n// by Sun Wu, Udi Manber, Gene Myers, Webb Miller.\n\n/**\n * Calculates the difference between two arrays or strings producing an array containing a list of changes\n * necessary to transform input into output.\n *\n *\t\tdiff( 'aba', 'acca' ); // [ 'equal', 'insert', 'insert', 'delete', 'equal' ]\n *\n * This function is based on the \"O(NP) Sequence Comparison Algorithm\" by Sun Wu, Udi Manber, Gene Myers, Webb Miller.\n * Unfortunately, while it gives the most precise results, its to complex for longer strings/arrow (above 200 items).\n * Therefore, `diff()` automatically switches to {@link module:utils/fastdiff~fastDiff `fastDiff()`} when detecting\n * such a scenario. The return formats of both functions are identical.\n *\n * @param {Array|String} a Input array or string.\n * @param {Array|String} b Output array or string.\n * @param {Function} [cmp] Optional function used to compare array values, by default === is used.\n * @returns {Array} Array of changes.\n */\nexport default function diff( a, b, cmp ) {\n\t// Set the comparator function.\n\tcmp = cmp || function( a, b ) {\n\t\treturn a === b;\n\t};\n\n\tconst aLength = a.length;\n\tconst bLength = b.length;\n\n\t// Perform `fastDiff` for longer strings/arrays (see #269).\n\tif ( aLength > 200 || bLength > 200 || aLength + bLength > 300 ) {\n\t\treturn diff.fastDiff( a, b, cmp, true );\n\t}\n\n\t// Temporary action type statics.\n\tlet _insert, _delete;\n\n\t// Swapped the arrays to use the shorter one as the first one.\n\tif ( bLength < aLength ) {\n\t\tconst tmp = a;\n\n\t\ta = b;\n\t\tb = tmp;\n\n\t\t// We swap the action types as well.\n\t\t_insert = 'delete';\n\t\t_delete = 'insert';\n\t} else {\n\t\t_insert = 'insert';\n\t\t_delete = 'delete';\n\t}\n\n\tconst m = a.length;\n\tconst n = b.length;\n\tconst delta = n - m;\n\n\t// Edit scripts, for each diagonal.\n\tconst es = {};\n\t// Furthest points, the furthest y we can get on each diagonal.\n\tconst fp = {};\n\n\tfunction snake( k ) {\n\t\t// We use -1 as an alternative below to handle initial values ( instead of filling the fp with -1 first ).\n\t\t// Furthest points (y) on the diagonal below k.\n\t\tconst y1 = ( fp[ k - 1 ] !== undefined ? fp[ k - 1 ] : -1 ) + 1;\n\t\t// Furthest points (y) on the diagonal above k.\n\t\tconst y2 = fp[ k + 1 ] !== undefined ? fp[ k + 1 ] : -1;\n\t\t// The way we should go to get further.\n\t\tconst dir = y1 > y2 ? -1 : 1;\n\n\t\t// Clone previous changes array (if any).\n\t\tif ( es[ k + dir ] ) {\n\t\t\tes[ k ] = es[ k + dir ].slice( 0 );\n\t\t}\n\n\t\t// Create changes array.\n\t\tif ( !es[ k ] ) {\n\t\t\tes[ k ] = [];\n\t\t}\n\n\t\t// Push the action.\n\t\tes[ k ].push( y1 > y2 ? _insert : _delete );\n\n\t\t// Set the beginning coordinates.\n\t\tlet y = Math.max( y1, y2 );\n\t\tlet x = y - k;\n\n\t\t// Traverse the diagonal as long as the values match.\n\t\twhile ( x < m && y < n && cmp( a[ x ], b[ y ] ) ) {\n\t\t\tx++;\n\t\t\ty++;\n\t\t\t// Push no change action.\n\t\t\tes[ k ].push( 'equal' );\n\t\t}\n\n\t\treturn y;\n\t}\n\n\tlet p = 0;\n\tlet k;\n\n\t// Traverse the graph until we reach the end of the longer string.\n\tdo {\n\t\t// Updates furthest points and edit scripts for diagonals below delta.\n\t\tfor ( k = -p; k < delta; k++ ) {\n\t\t\tfp[ k ] = snake( k );\n\t\t}\n\n\t\t// Updates furthest points and edit scripts for diagonals above delta.\n\t\tfor ( k = delta + p; k > delta; k-- ) {\n\t\t\tfp[ k ] = snake( k );\n\t\t}\n\n\t\t// Updates furthest point and edit script for the delta diagonal.\n\t\t// note that the delta diagonal is the one which goes through the sink (m, n).\n\t\tfp[ delta ] = snake( delta );\n\n\t\tp++;\n\t} while ( fp[ delta ] !== n );\n\n\t// Return the final list of edit changes.\n\t// We remove the first item that represents the action for the injected nulls.\n\treturn es[ delta ].slice( 1 );\n}\n\n// Store the API in static property to easily overwrite it in tests.\n// Too bad dependency injection does not work in Webpack + ES 6 (const) + Babel.\ndiff.fastDiff = fastDiff;\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/insertat\n */\n\n/**\n * Inserts node to the parent at given index.\n *\n * @param {Element} parentElement Parent element.\n * @param {Number} index Insertions index.\n * @param {Node} nodeToInsert Node to insert.\n */\nexport default function insertAt( parentElement, index, nodeToInsert ) {\n\tparentElement.insertBefore( nodeToInsert, parentElement.childNodes[ index ] || null );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/remove\n */\n\n/**\n * Removes given node from parent.\n *\n * @param {Node} node Node to remove.\n */\nexport default function remove( node ) {\n\tconst parent = node.parentNode;\n\n\tif ( parent ) {\n\t\tparent.removeChild( node );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/isnode\n */\n\n/**\n * Checks if the object is a native DOM Node.\n *\n * @param {*} obj\n * @returns {Boolean}\n */\nexport default function isNode( obj ) {\n\tif ( obj ) {\n\t\tif ( obj.defaultView ) {\n\t\t\treturn obj instanceof obj.defaultView.Document;\n\t\t} else if ( obj.ownerDocument && obj.ownerDocument.defaultView ) {\n\t\t\treturn obj instanceof obj.ownerDocument.defaultView.Node;\n\t\t}\n\t}\n\n\treturn false;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* globals Node */\n\n/**\n * @module engine/view/renderer\n */\n\nimport ViewText from './text';\nimport ViewPosition from './position';\nimport { INLINE_FILLER, INLINE_FILLER_LENGTH, startsWithFiller, isInlineFiller, isBlockFiller } from './filler';\n\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport diff from '@ckeditor/ckeditor5-utils/src/diff';\nimport insertAt from '@ckeditor/ckeditor5-utils/src/dom/insertat';\nimport remove from '@ckeditor/ckeditor5-utils/src/dom/remove';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport isText from '@ckeditor/ckeditor5-utils/src/dom/istext';\nimport isNode from '@ckeditor/ckeditor5-utils/src/dom/isnode';\nimport fastDiff from '@ckeditor/ckeditor5-utils/src/fastdiff';\nimport env from '@ckeditor/ckeditor5-utils/src/env';\n\n/**\n * Renderer is responsible for updating the DOM structure and the DOM selection based on\n * the {@link module:engine/view/renderer~Renderer#markToSync information about updated view nodes}.\n * In other words, it renders the view to the DOM.\n *\n * Its main responsibility is to make only the necessary, minimal changes to the DOM. However, unlike in many\n * virtual DOM implementations, the primary reason for doing minimal changes is not the performance but ensuring\n * that native editing features such as text composition, autocompletion, spell checking, selection's x-index are\n * affected as little as possible.\n *\n * Renderer uses {@link module:engine/view/domconverter~DomConverter} to transform view nodes and positions\n * to and from the DOM.\n */\nexport default class Renderer {\n\t/**\n\t * Creates a renderer instance.\n\t *\n\t * @param {module:engine/view/domconverter~DomConverter} domConverter Converter instance.\n\t * @param {module:engine/view/documentselection~DocumentSelection} selection View selection.\n\t */\n\tconstructor( domConverter, selection ) {\n\t\t/**\n\t\t * Set of DOM Documents instances.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Set.<Document>}\n\t\t */\n\t\tthis.domDocuments = new Set();\n\n\t\t/**\n\t\t * Converter instance.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/domconverter~DomConverter}\n\t\t */\n\t\tthis.domConverter = domConverter;\n\n\t\t/**\n\t\t * Set of nodes which attributes changed and may need to be rendered.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Set.<module:engine/view/node~Node>}\n\t\t */\n\t\tthis.markedAttributes = new Set();\n\n\t\t/**\n\t\t * Set of elements which child lists changed and may need to be rendered.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Set.<module:engine/view/node~Node>}\n\t\t */\n\t\tthis.markedChildren = new Set();\n\n\t\t/**\n\t\t * Set of text nodes which text data changed and may need to be rendered.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Set.<module:engine/view/node~Node>}\n\t\t */\n\t\tthis.markedTexts = new Set();\n\n\t\t/**\n\t\t * View selection. Renderer updates DOM selection based on the view selection.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/documentselection~DocumentSelection}\n\t\t */\n\t\tthis.selection = selection;\n\n\t\t/**\n\t\t * Indicates if the view document is focused and selection can be rendered. Selection will not be rendered if\n\t\t * this is set to `false`.\n\t\t *\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis.isFocused = false;\n\n\t\t/**\n\t\t * The text node in which the inline filler was rendered.\n\t\t *\n\t\t * @private\n\t\t * @member {Text}\n\t\t */\n\t\tthis._inlineFiller = null;\n\n\t\t/**\n\t\t * DOM element containing fake selection.\n\t\t *\n\t\t * @private\n\t\t * @type {null|HTMLElement}\n\t\t */\n\t\tthis._fakeSelectionContainer = null;\n\t}\n\n\t/**\n\t * Marks a view node to be updated in the DOM by {@link #render `render()`}.\n\t *\n\t * Note that only view nodes whose parents have corresponding DOM elements need to be marked to be synchronized.\n\t *\n\t * @see #markedAttributes\n\t * @see #markedChildren\n\t * @see #markedTexts\n\t *\n\t * @param {module:engine/view/document~ChangeType} type Type of the change.\n\t * @param {module:engine/view/node~Node} node Node to be marked.\n\t */\n\tmarkToSync( type, node ) {\n\t\tif ( type === 'text' ) {\n\t\t\tif ( this.domConverter.mapViewToDom( node.parent ) ) {\n\t\t\t\tthis.markedTexts.add( node );\n\t\t\t}\n\t\t} else {\n\t\t\t// If the node has no DOM element it is not rendered yet,\n\t\t\t// its children/attributes do not need to be marked to be sync.\n\t\t\tif ( !this.domConverter.mapViewToDom( node ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( type === 'attributes' ) {\n\t\t\t\tthis.markedAttributes.add( node );\n\t\t\t} else if ( type === 'children' ) {\n\t\t\t\tthis.markedChildren.add( node );\n\t\t\t} else {\n\t\t\t\t/**\n\t\t\t\t * Unknown type passed to Renderer.markToSync.\n\t\t\t\t *\n\t\t\t\t * @error renderer-unknown-type\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'view-renderer-unknown-type: Unknown type passed to Renderer.markToSync.' );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Renders all buffered changes ({@link #markedAttributes}, {@link #markedChildren} and {@link #markedTexts}) and\n\t * the current view selection (if needed) to the DOM by applying a minimal set of changes to it.\n\t *\n\t * Renderer tries not to break the text composition (e.g. IME) and x-index of the selection,\n\t * so it does as little as it is needed to update the DOM.\n\t *\n\t * Renderer also handles {@link module:engine/view/filler fillers}. Especially, it checks if the inline filler is needed\n\t * at the selection position and adds or removes it. To prevent breaking text composition inline filler will not be\n\t * removed as long as the selection is in the text node which needed it at first.\n\t */\n\trender() {\n\t\tlet inlineFillerPosition;\n\n\t\t// Refresh mappings.\n\t\tfor ( const element of this.markedChildren ) {\n\t\t\tthis._updateChildrenMappings( element );\n\t\t}\n\n\t\t// There was inline filler rendered in the DOM but it's not\n\t\t// at the selection position any more, so we can remove it\n\t\t// (cause even if it's needed, it must be placed in another location).\n\t\tif ( this._inlineFiller && !this._isSelectionInInlineFiller() ) {\n\t\t\tthis._removeInlineFiller();\n\t\t}\n\n\t\t// If we've got the filler, let's try to guess its position in the view.\n\t\tif ( this._inlineFiller ) {\n\t\t\tinlineFillerPosition = this._getInlineFillerPosition();\n\t\t}\n\t\t// Otherwise, if it's needed, create it at the selection position.\n\t\telse if ( this._needsInlineFillerAtSelection() ) {\n\t\t\tinlineFillerPosition = this.selection.getFirstPosition();\n\n\t\t\t// Do not use `markToSync` so it will be added even if the parent is already added.\n\t\t\tthis.markedChildren.add( inlineFillerPosition.parent );\n\t\t}\n\n\t\tfor ( const element of this.markedAttributes ) {\n\t\t\tthis._updateAttrs( element );\n\t\t}\n\n\t\tfor ( const element of this.markedChildren ) {\n\t\t\tthis._updateChildren( element, { inlineFillerPosition } );\n\t\t}\n\n\t\tfor ( const node of this.markedTexts ) {\n\t\t\tif ( !this.markedChildren.has( node.parent ) && this.domConverter.mapViewToDom( node.parent ) ) {\n\t\t\t\tthis._updateText( node, { inlineFillerPosition } );\n\t\t\t}\n\t\t}\n\n\t\t// Check whether the inline filler is required and where it really is in the DOM.\n\t\t// At this point in most cases it will be in the DOM, but there are exceptions.\n\t\t// For example, if the inline filler was deep in the created DOM structure, it will not be created.\n\t\t// Similarly, if it was removed at the beginning of this function and then neither text nor children were updated,\n\t\t// it will not be present.\n\t\t// Fix those and similar scenarios.\n\t\tif ( inlineFillerPosition ) {\n\t\t\tconst fillerDomPosition = this.domConverter.viewPositionToDom( inlineFillerPosition );\n\t\t\tconst domDocument = fillerDomPosition.parent.ownerDocument;\n\n\t\t\tif ( !startsWithFiller( fillerDomPosition.parent ) ) {\n\t\t\t\t// Filler has not been created at filler position. Create it now.\n\t\t\t\tthis._inlineFiller = addInlineFiller( domDocument, fillerDomPosition.parent, fillerDomPosition.offset );\n\t\t\t} else {\n\t\t\t\t// Filler has been found, save it.\n\t\t\t\tthis._inlineFiller = fillerDomPosition.parent;\n\t\t\t}\n\t\t} else {\n\t\t\t// There is no filler needed.\n\t\t\tthis._inlineFiller = null;\n\t\t}\n\n\t\tthis._updateSelection();\n\t\tthis._updateFocus();\n\n\t\tthis.markedTexts.clear();\n\t\tthis.markedAttributes.clear();\n\t\tthis.markedChildren.clear();\n\t}\n\n\t/**\n\t * Updates mappings of view element's children.\n\t *\n\t * Children that were replaced in the view structure by similar elements (same tag name) are treated as 'replaced'.\n\t * This means that their mappings can be updated so the new view elements are mapped to the existing DOM elements.\n\t * Thanks to that these elements do not need to be re-rendered completely.\n\t *\n\t * @private\n\t * @param {module:engine/view/node~Node} viewElement The view element whose children mappings will be updated.\n\t */\n\t_updateChildrenMappings( viewElement ) {\n\t\tconst domElement = this.domConverter.mapViewToDom( viewElement );\n\n\t\tif ( !domElement ) {\n\t\t\t// If there is no `domElement` it means that it was already removed from DOM and there is no need to process it.\n\t\t\treturn;\n\t\t}\n\n\t\tconst actualDomChildren = this.domConverter.mapViewToDom( viewElement ).childNodes;\n\t\tconst expectedDomChildren = Array.from(\n\t\t\tthis.domConverter.viewChildrenToDom( viewElement, domElement.ownerDocument, { withChildren: false } )\n\t\t);\n\t\tconst diff = this._diffNodeLists( actualDomChildren, expectedDomChildren );\n\t\tconst actions = this._findReplaceActions( diff, actualDomChildren, expectedDomChildren );\n\n\t\tif ( actions.indexOf( 'replace' ) !== -1 ) {\n\t\t\tconst counter = { equal: 0, insert: 0, delete: 0 };\n\n\t\t\tfor ( const action of actions ) {\n\t\t\t\tif ( action === 'replace' ) {\n\t\t\t\t\tconst insertIndex = counter.equal + counter.insert;\n\t\t\t\t\tconst deleteIndex = counter.equal + counter.delete;\n\t\t\t\t\tconst viewChild = viewElement.getChild( insertIndex );\n\n\t\t\t\t\t// The 'uiElement' is a special one and its children are not stored in a view (#799),\n\t\t\t\t\t// so we cannot use it with replacing flow (since it uses view children during rendering\n\t\t\t\t\t// which will always result in rendering empty element).\n\t\t\t\t\tif ( viewChild && !viewChild.is( 'uiElement' ) ) {\n\t\t\t\t\t\tthis._updateElementMappings( viewChild, actualDomChildren[ deleteIndex ] );\n\t\t\t\t\t}\n\n\t\t\t\t\tremove( expectedDomChildren[ insertIndex ] );\n\t\t\t\t\tcounter.equal++;\n\t\t\t\t} else {\n\t\t\t\t\tcounter[ action ]++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Updates mappings of a given view element.\n\t *\n\t * @private\n\t * @param {module:engine/view/node~Node} viewElement The view element whose mappings will be updated.\n\t * @param {Node} domElement The DOM element representing the given view element.\n\t */\n\t_updateElementMappings( viewElement, domElement ) {\n\t\t// Remap 'DomConverter' bindings.\n\t\tthis.domConverter.unbindDomElement( domElement );\n\t\tthis.domConverter.bindElements( domElement, viewElement );\n\n\t\t// View element may have children which needs to be updated, but are not marked, mark them to update.\n\t\tthis.markedChildren.add( viewElement );\n\n\t\t// Because we replace new view element mapping with the existing one, the corresponding DOM element\n\t\t// will not be rerendered. The new view element may have different attributes than the previous one.\n\t\t// Since its corresponding DOM element will not be rerendered, new attributes will not be added\n\t\t// to the DOM, so we need to mark it here to make sure its attributes gets updated. See #1427 for more\n\t\t// detailed case study.\n\t\t// Also there are cases where replaced element is removed from the view structure and then has\n\t\t// its attributes changed or removed. In such cases the element will not be present in `markedAttributes`\n\t\t// and also may be the same (`element.isSimilar()`) as the reused element not having its attributes updated.\n\t\t// To prevent such situations we always mark reused element to have its attributes rerenderd (#1560).\n\t\tthis.markedAttributes.add( viewElement );\n\t}\n\n\t/**\n\t * Gets the position of the inline filler based on the current selection.\n\t * Here, we assume that we know that the filler is needed and\n\t * {@link #_isSelectionInInlineFiller is at the selection position}, and, since it is needed,\n\t * it is somewhere at the selection position.\n\t *\n\t * Note: The filler position cannot be restored based on the filler's DOM text node, because\n\t * when this method is called (before rendering), the bindings will often be broken. View-to-DOM\n\t * bindings are only dependable after rendering.\n\t *\n\t * @private\n\t * @returns {module:engine/view/position~Position}\n\t */\n\t_getInlineFillerPosition() {\n\t\tconst firstPos = this.selection.getFirstPosition();\n\n\t\tif ( firstPos.parent.is( 'text' ) ) {\n\t\t\treturn ViewPosition._createBefore( this.selection.getFirstPosition().parent );\n\t\t} else {\n\t\t\treturn firstPos;\n\t\t}\n\t}\n\n\t/**\n\t * Returns `true` if the selection has not left the inline filler's text node.\n\t * If it is `true`, it means that the filler had been added for a reason and the selection did not\n\t * leave the filler's text node. For example, the user can be in the middle of a composition so it should not be touched.\n\t *\n\t * @private\n\t * @returns {Boolean} `true` if the inline filler and selection are in the same place.\n\t */\n\t_isSelectionInInlineFiller() {\n\t\tif ( this.selection.rangeCount != 1 || !this.selection.isCollapsed ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Note, we can't check if selection's position equals position of the\n\t\t// this._inlineFiller node, because of #663. We may not be able to calculate\n\t\t// the filler's position in the view at this stage.\n\t\t// Instead, we check it the other way – whether selection is anchored in\n\t\t// that text node or next to it.\n\n\t\t// Possible options are:\n\t\t// \"FILLER{}\"\n\t\t// \"FILLERadded-text{}\"\n\t\tconst selectionPosition = this.selection.getFirstPosition();\n\t\tconst position = this.domConverter.viewPositionToDom( selectionPosition );\n\n\t\tif ( position && isText( position.parent ) && startsWithFiller( position.parent ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Removes the inline filler.\n\t *\n\t * @private\n\t */\n\t_removeInlineFiller() {\n\t\tconst domFillerNode = this._inlineFiller;\n\n\t\t// Something weird happened and the stored node doesn't contain the filler's text.\n\t\tif ( !startsWithFiller( domFillerNode ) ) {\n\t\t\t/**\n\t\t\t * The inline filler node was lost. Most likely, something overwrote the filler text node\n\t\t\t * in the DOM.\n\t\t\t *\n\t\t\t * @error view-renderer-filler-was-lost\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-renderer-filler-was-lost: The inline filler node was lost.' );\n\t\t}\n\n\t\tif ( isInlineFiller( domFillerNode ) ) {\n\t\t\tdomFillerNode.parentNode.removeChild( domFillerNode );\n\t\t} else {\n\t\t\tdomFillerNode.data = domFillerNode.data.substr( INLINE_FILLER_LENGTH );\n\t\t}\n\n\t\tthis._inlineFiller = null;\n\t}\n\n\t/**\n\t * Checks if the inline {@link module:engine/view/filler filler} should be added.\n\t *\n\t * @private\n\t * @returns {Boolean} `true` if the inline filler should be added.\n\t */\n\t_needsInlineFillerAtSelection() {\n\t\tif ( this.selection.rangeCount != 1 || !this.selection.isCollapsed ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst selectionPosition = this.selection.getFirstPosition();\n\t\tconst selectionParent = selectionPosition.parent;\n\t\tconst selectionOffset = selectionPosition.offset;\n\n\t\t// If there is no DOM root we do not care about fillers.\n\t\tif ( !this.domConverter.mapViewToDom( selectionParent.root ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( !( selectionParent.is( 'element' ) ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Prevent adding inline filler inside elements with contenteditable=false.\n\t\t// https://github.com/ckeditor/ckeditor5-engine/issues/1170\n\t\tif ( !isEditable( selectionParent ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// We have block filler, we do not need inline one.\n\t\tif ( selectionOffset === selectionParent.getFillerOffset() ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst nodeBefore = selectionPosition.nodeBefore;\n\t\tconst nodeAfter = selectionPosition.nodeAfter;\n\n\t\tif ( nodeBefore instanceof ViewText || nodeAfter instanceof ViewText ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Checks if text needs to be updated and possibly updates it.\n\t *\n\t * @private\n\t * @param {module:engine/view/text~Text} viewText View text to update.\n\t * @param {Object} options\n\t * @param {module:engine/view/position~Position} options.inlineFillerPosition The position where the inline\n\t * filler should be rendered.\n\t */\n\t_updateText( viewText, options ) {\n\t\tconst domText = this.domConverter.findCorrespondingDomText( viewText );\n\t\tconst newDomText = this.domConverter.viewToDom( viewText, domText.ownerDocument );\n\n\t\tconst actualText = domText.data;\n\t\tlet expectedText = newDomText.data;\n\n\t\tconst filler = options.inlineFillerPosition;\n\n\t\tif ( filler && filler.parent == viewText.parent && filler.offset == viewText.index ) {\n\t\t\texpectedText = INLINE_FILLER + expectedText;\n\t\t}\n\n\t\tif ( actualText != expectedText ) {\n\t\t\tconst actions = fastDiff( actualText, expectedText );\n\n\t\t\tfor ( const action of actions ) {\n\t\t\t\tif ( action.type === 'insert' ) {\n\t\t\t\t\tdomText.insertData( action.index, action.values.join( '' ) );\n\t\t\t\t} else { // 'delete'\n\t\t\t\t\tdomText.deleteData( action.index, action.howMany );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if attribute list needs to be updated and possibly updates it.\n\t *\n\t * @private\n\t * @param {module:engine/view/element~Element} viewElement The view element to update.\n\t */\n\t_updateAttrs( viewElement ) {\n\t\tconst domElement = this.domConverter.mapViewToDom( viewElement );\n\n\t\tif ( !domElement ) {\n\t\t\t// If there is no `domElement` it means that 'viewElement' is outdated as its mapping was updated\n\t\t\t// in 'this._updateChildrenMappings()'. There is no need to process it as new view element which\n\t\t\t// replaced old 'viewElement' mapping was also added to 'this.markedAttributes'\n\t\t\t// in 'this._updateChildrenMappings()' so it will be processed separately.\n\t\t\treturn;\n\t\t}\n\n\t\tconst domAttrKeys = Array.from( domElement.attributes ).map( attr => attr.name );\n\t\tconst viewAttrKeys = viewElement.getAttributeKeys();\n\n\t\t// Add or overwrite attributes.\n\t\tfor ( const key of viewAttrKeys ) {\n\t\t\tdomElement.setAttribute( key, viewElement.getAttribute( key ) );\n\t\t}\n\n\t\t// Remove from DOM attributes which do not exists in the view.\n\t\tfor ( const key of domAttrKeys ) {\n\t\t\tif ( !viewElement.hasAttribute( key ) ) {\n\t\t\t\tdomElement.removeAttribute( key );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if elements child list needs to be updated and possibly updates it.\n\t *\n\t * @private\n\t * @param {module:engine/view/element~Element} viewElement View element to update.\n\t * @param {Object} options\n\t * @param {module:engine/view/position~Position} options.inlineFillerPosition The position where the inline\n\t * filler should be rendered.\n\t */\n\t_updateChildren( viewElement, options ) {\n\t\tconst domElement = this.domConverter.mapViewToDom( viewElement );\n\n\t\tif ( !domElement ) {\n\t\t\t// If there is no `domElement` it means that it was already removed from DOM.\n\t\t\t// There is no need to process it. It will be processed when re-inserted.\n\t\t\treturn;\n\t\t}\n\n\t\tconst inlineFillerPosition = options.inlineFillerPosition;\n\t\tconst actualDomChildren = this.domConverter.mapViewToDom( viewElement ).childNodes;\n\t\tconst expectedDomChildren = Array.from(\n\t\t\tthis.domConverter.viewChildrenToDom( viewElement, domElement.ownerDocument, { bind: true, inlineFillerPosition } )\n\t\t);\n\n\t\t// Inline filler element has to be created as it is present in the DOM, but not in the view. It is required\n\t\t// during diffing so text nodes could be compared correctly and also during rendering to maintain\n\t\t// proper order and indexes while updating the DOM.\n\t\tif ( inlineFillerPosition && inlineFillerPosition.parent === viewElement ) {\n\t\t\taddInlineFiller( domElement.ownerDocument, expectedDomChildren, inlineFillerPosition.offset );\n\t\t}\n\n\t\tconst diff = this._diffNodeLists( actualDomChildren, expectedDomChildren );\n\n\t\tlet i = 0;\n\t\tconst nodesToUnbind = new Set();\n\n\t\tfor ( const action of diff ) {\n\t\t\tif ( action === 'insert' ) {\n\t\t\t\tinsertAt( domElement, i, expectedDomChildren[ i ] );\n\t\t\t\ti++;\n\t\t\t} else if ( action === 'delete' ) {\n\t\t\t\tnodesToUnbind.add( actualDomChildren[ i ] );\n\t\t\t\tremove( actualDomChildren[ i ] );\n\t\t\t} else { // 'equal'\n\t\t\t\t// Force updating text nodes inside elements which did not change and do not need to be re-rendered (#1125).\n\t\t\t\tthis._markDescendantTextToSync( this.domConverter.domToView( expectedDomChildren[ i ] ) );\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\n\t\t// Unbind removed nodes. When node does not have a parent it means that it was removed from DOM tree during\n\t\t// comparision with the expected DOM. We don't need to check child nodes, because if child node was reinserted,\n\t\t// it was moved to DOM tree out of the removed node.\n\t\tfor ( const node of nodesToUnbind ) {\n\t\t\tif ( !node.parentNode ) {\n\t\t\t\tthis.domConverter.unbindDomElement( node );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Shorthand for diffing two arrays or node lists of DOM nodes.\n\t *\n\t * @private\n\t * @param {Array.<Node>|NodeList} actualDomChildren Actual DOM children\n\t * @param {Array.<Node>|NodeList} expectedDomChildren Expected DOM children.\n\t * @returns {Array.<String>} The list of actions based on the {@link module:utils/diff~diff} function.\n\t */\n\t_diffNodeLists( actualDomChildren, expectedDomChildren ) {\n\t\tactualDomChildren = filterOutFakeSelectionContainer( actualDomChildren, this._fakeSelectionContainer );\n\n\t\treturn diff( actualDomChildren, expectedDomChildren, sameNodes.bind( null, this.domConverter.blockFiller ) );\n\t}\n\n\t/**\n\t * Finds DOM nodes that were replaced with the similar nodes (same tag name) in the view. All nodes are compared\n\t * within one `insert`/`delete` action group, for example:\n\t *\n\t * \t\tActual DOM:\t\t<p><b>Foo</b>Bar<i>Baz</i><b>Bax</b></p>\n\t * \t\tExpected DOM:\t<p>Bar<b>123</b><i>Baz</i><b>456</b></p>\n\t * \t\tInput actions:\t[ insert, insert, delete, delete, equal, insert, delete ]\n\t * \t\tOutput actions:\t[ insert, replace, delete, equal, replace ]\n\t *\n\t * @private\n\t * @param {Array.<String>} actions Actions array which is a result of the {@link module:utils/diff~diff} function.\n\t * @param {Array.<Node>|NodeList} actualDom Actual DOM children\n\t * @param {Array.<Node>} expectedDom Expected DOM children.\n\t * @returns {Array.<String>} Actions array modified with the `replace` actions.\n\t */\n\t_findReplaceActions( actions, actualDom, expectedDom ) {\n\t\t// If there is no both 'insert' and 'delete' actions, no need to check for replaced elements.\n\t\tif ( actions.indexOf( 'insert' ) === -1 || actions.indexOf( 'delete' ) === -1 ) {\n\t\t\treturn actions;\n\t\t}\n\n\t\tlet newActions = [];\n\t\tlet actualSlice = [];\n\t\tlet expectedSlice = [];\n\n\t\tconst counter = { equal: 0, insert: 0, delete: 0 };\n\n\t\tfor ( const action of actions ) {\n\t\t\tif ( action === 'insert' ) {\n\t\t\t\texpectedSlice.push( expectedDom[ counter.equal + counter.insert ] );\n\t\t\t} else if ( action === 'delete' ) {\n\t\t\t\tactualSlice.push( actualDom[ counter.equal + counter.delete ] );\n\t\t\t} else { // equal\n\t\t\t\tnewActions = newActions.concat( diff( actualSlice, expectedSlice, areSimilar ).map( x => x === 'equal' ? 'replace' : x ) );\n\t\t\t\tnewActions.push( 'equal' );\n\t\t\t\t// Reset stored elements on 'equal'.\n\t\t\t\tactualSlice = [];\n\t\t\t\texpectedSlice = [];\n\t\t\t}\n\t\t\tcounter[ action ]++;\n\t\t}\n\n\t\treturn newActions.concat( diff( actualSlice, expectedSlice, areSimilar ).map( x => x === 'equal' ? 'replace' : x ) );\n\t}\n\n\t/**\n\t * Marks text nodes to be synchronized.\n\t *\n\t * If a text node is passed, it will be marked. If an element is passed, all descendant text nodes inside it will be marked.\n\t *\n\t * @private\n\t * @param {module:engine/view/node~Node} viewNode View node to sync.\n\t */\n\t_markDescendantTextToSync( viewNode ) {\n\t\tif ( !viewNode ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( viewNode.is( 'text' ) ) {\n\t\t\tthis.markedTexts.add( viewNode );\n\t\t} else if ( viewNode.is( 'element' ) ) {\n\t\t\tfor ( const child of viewNode.getChildren() ) {\n\t\t\t\tthis._markDescendantTextToSync( child );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if the selection needs to be updated and possibly updates it.\n\t *\n\t * @private\n\t */\n\t_updateSelection() {\n\t\t// If there is no selection - remove DOM and fake selections.\n\t\tif ( this.selection.rangeCount === 0 ) {\n\t\t\tthis._removeDomSelection();\n\t\t\tthis._removeFakeSelection();\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst domRoot = this.domConverter.mapViewToDom( this.selection.editableElement );\n\n\t\t// Do nothing if there is no focus, or there is no DOM element corresponding to selection's editable element.\n\t\tif ( !this.isFocused || !domRoot ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Render selection.\n\t\tif ( this.selection.isFake ) {\n\t\t\tthis._updateFakeSelection( domRoot );\n\t\t} else {\n\t\t\tthis._removeFakeSelection();\n\t\t\tthis._updateDomSelection( domRoot );\n\t\t}\n\t}\n\n\t/**\n\t * Updates the fake selection.\n\t *\n\t * @private\n\t * @param {HTMLElement} domRoot A valid DOM root where the fake selection container should be added.\n\t */\n\t_updateFakeSelection( domRoot ) {\n\t\tconst domDocument = domRoot.ownerDocument;\n\t\tlet container = this._fakeSelectionContainer;\n\n\t\t// Create fake selection container if one does not exist.\n\t\tif ( !container ) {\n\t\t\tthis._fakeSelectionContainer = container = domDocument.createElement( 'div' );\n\n\t\t\tObject.assign( container.style, {\n\t\t\t\tposition: 'fixed',\n\t\t\t\ttop: 0,\n\t\t\t\tleft: '-9999px',\n\t\t\t\t// See https://github.com/ckeditor/ckeditor5/issues/752.\n\t\t\t\twidth: '42px'\n\t\t\t} );\n\n\t\t\t// Fill it with a text node so we can update it later.\n\t\t\tcontainer.textContent = '\\u00A0';\n\t\t}\n\n\t\tif ( !container.parentElement || container.parentElement != domRoot ) {\n\t\t\tdomRoot.appendChild( container );\n\t\t}\n\n\t\t// Update contents.\n\t\tcontainer.textContent = this.selection.fakeSelectionLabel || '\\u00A0';\n\n\t\t// Update selection.\n\t\tconst domSelection = domDocument.getSelection();\n\t\tconst domRange = domDocument.createRange();\n\n\t\tdomSelection.removeAllRanges();\n\t\tdomRange.selectNodeContents( container );\n\t\tdomSelection.addRange( domRange );\n\n\t\t// Bind fake selection container with current selection.\n\t\tthis.domConverter.bindFakeSelection( container, this.selection );\n\t}\n\n\t/**\n\t * Updates the DOM selection.\n\t *\n\t * @private\n\t * @param {HTMLElement} domRoot A valid DOM root where the DOM selection should be rendered.\n\t */\n\t_updateDomSelection( domRoot ) {\n\t\tconst domSelection = domRoot.ownerDocument.defaultView.getSelection();\n\n\t\t// Let's check whether DOM selection needs updating at all.\n\t\tif ( !this._domSelectionNeedsUpdate( domSelection ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Multi-range selection is not available in most browsers, and, at least in Chrome, trying to\n\t\t// set such selection, that is not continuous, throws an error. Because of that, we will just use anchor\n\t\t// and focus of view selection.\n\t\t// Since we are not supporting multi-range selection, we also do not need to check if proper editable is\n\t\t// selected. If there is any editable selected, it is okay (editable is taken from selection anchor).\n\t\tconst anchor = this.domConverter.viewPositionToDom( this.selection.anchor );\n\t\tconst focus = this.domConverter.viewPositionToDom( this.selection.focus );\n\n\t\t// Focus the new editing host.\n\t\t// Otherwise, FF may throw an error (https://github.com/ckeditor/ckeditor5/issues/721).\n\t\tdomRoot.focus();\n\n\t\tdomSelection.collapse( anchor.parent, anchor.offset );\n\t\tdomSelection.extend( focus.parent, focus.offset );\n\n\t\t// Firefox–specific hack (https://github.com/ckeditor/ckeditor5-engine/issues/1439).\n\t\tif ( env.isGecko ) {\n\t\t\tfixGeckoSelectionAfterBr( focus, domSelection );\n\t\t}\n\t}\n\n\t/**\n\t * Checks whether a given DOM selection needs to be updated.\n\t *\n\t * @private\n\t * @param {Selection} domSelection The DOM selection to check.\n\t * @returns {Boolean}\n\t */\n\t_domSelectionNeedsUpdate( domSelection ) {\n\t\tif ( !this.domConverter.isDomSelectionCorrect( domSelection ) ) {\n\t\t\t// Current DOM selection is in incorrect position. We need to update it.\n\t\t\treturn true;\n\t\t}\n\n\t\tconst oldViewSelection = domSelection && this.domConverter.domSelectionToView( domSelection );\n\n\t\tif ( oldViewSelection && this.selection.isEqual( oldViewSelection ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If selection is not collapsed, it does not need to be updated if it is similar.\n\t\tif ( !this.selection.isCollapsed && this.selection.isSimilar( oldViewSelection ) ) {\n\t\t\t// Selection did not changed and is correct, do not update.\n\t\t\treturn false;\n\t\t}\n\n\t\t// Selections are not similar.\n\t\treturn true;\n\t}\n\n\t/**\n\t * Removes the DOM selection.\n\t *\n\t * @private\n\t */\n\t_removeDomSelection() {\n\t\tfor ( const doc of this.domDocuments ) {\n\t\t\tconst domSelection = doc.getSelection();\n\n\t\t\tif ( domSelection.rangeCount ) {\n\t\t\t\tconst activeDomElement = doc.activeElement;\n\t\t\t\tconst viewElement = this.domConverter.mapDomToView( activeDomElement );\n\n\t\t\t\tif ( activeDomElement && viewElement ) {\n\t\t\t\t\tdoc.getSelection().removeAllRanges();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Removes the fake selection.\n\t *\n\t * @private\n\t */\n\t_removeFakeSelection() {\n\t\tconst container = this._fakeSelectionContainer;\n\n\t\tif ( container ) {\n\t\t\tcontainer.remove();\n\t\t}\n\t}\n\n\t/**\n\t * Checks if focus needs to be updated and possibly updates it.\n\t *\n\t * @private\n\t */\n\t_updateFocus() {\n\t\tif ( this.isFocused ) {\n\t\t\tconst editable = this.selection.editableElement;\n\n\t\t\tif ( editable ) {\n\t\t\t\tthis.domConverter.focus( editable );\n\t\t\t}\n\t\t}\n\t}\n}\n\nmix( Renderer, ObservableMixin );\n\n// Checks if provided element is editable.\n//\n// @private\n// @param {module:engine/view/element~Element} element\n// @returns {Boolean}\nfunction isEditable( element ) {\n\tif ( element.getAttribute( 'contenteditable' ) == 'false' ) {\n\t\treturn false;\n\t}\n\n\tconst parent = element.findAncestor( element => element.hasAttribute( 'contenteditable' ) );\n\n\treturn !parent || parent.getAttribute( 'contenteditable' ) == 'true';\n}\n\n// Adds inline filler at a given position.\n//\n// The position can be given as an array of DOM nodes and an offset in that array,\n// or a DOM parent element and an offset in that element.\n//\n// @private\n// @param {Document} domDocument\n// @param {Element|Array.<Node>} domParentOrArray\n// @param {Number} offset\n// @returns {Text} The DOM text node that contains an inline filler.\nfunction addInlineFiller( domDocument, domParentOrArray, offset ) {\n\tconst childNodes = domParentOrArray instanceof Array ? domParentOrArray : domParentOrArray.childNodes;\n\tconst nodeAfterFiller = childNodes[ offset ];\n\n\tif ( isText( nodeAfterFiller ) ) {\n\t\tnodeAfterFiller.data = INLINE_FILLER + nodeAfterFiller.data;\n\n\t\treturn nodeAfterFiller;\n\t} else {\n\t\tconst fillerNode = domDocument.createTextNode( INLINE_FILLER );\n\n\t\tif ( Array.isArray( domParentOrArray ) ) {\n\t\t\tchildNodes.splice( offset, 0, fillerNode );\n\t\t} else {\n\t\t\tinsertAt( domParentOrArray, offset, fillerNode );\n\t\t}\n\n\t\treturn fillerNode;\n\t}\n}\n\n// Whether two DOM nodes should be considered as similar.\n// Nodes are considered similar if they have the same tag name.\n//\n// @private\n// @param {Node} node1\n// @param {Node} node2\n// @returns {Boolean}\nfunction areSimilar( node1, node2 ) {\n\treturn isNode( node1 ) && isNode( node2 ) &&\n\t\t!isText( node1 ) && !isText( node2 ) &&\n\t\tnode1.tagName.toLowerCase() === node2.tagName.toLowerCase();\n}\n\n// Whether two dom nodes should be considered as the same.\n// Two nodes which are considered the same are:\n//\n//\t\t* Text nodes with the same text.\n//\t\t* Element nodes represented by the same object.\n//\t\t* Two block filler elements.\n//\n// @private\n// @param {Function} blockFiller Block filler creator function, see {@link module:engine/view/domconverter~DomConverter#blockFiller}.\n// @param {Node} node1\n// @param {Node} node2\n// @returns {Boolean}\nfunction sameNodes( blockFiller, actualDomChild, expectedDomChild ) {\n\t// Elements.\n\tif ( actualDomChild === expectedDomChild ) {\n\t\treturn true;\n\t}\n\t// Texts.\n\telse if ( isText( actualDomChild ) && isText( expectedDomChild ) ) {\n\t\treturn actualDomChild.data === expectedDomChild.data;\n\t}\n\t// Block fillers.\n\telse if ( isBlockFiller( actualDomChild, blockFiller ) &&\n\t\tisBlockFiller( expectedDomChild, blockFiller ) ) {\n\t\treturn true;\n\t}\n\n\t// Not matching types.\n\treturn false;\n}\n\n// The following is a Firefox–specific hack (https://github.com/ckeditor/ckeditor5-engine/issues/1439).\n// When the native DOM selection is at the end of the block and preceded by <br /> e.g.\n//\n//\t\t<p>foo<br/>[]</p>\n//\n// which happens a lot when using the soft line break, the browser fails to (visually) move the\n// caret to the new line. A quick fix is as simple as force–refreshing the selection with the same range.\nfunction fixGeckoSelectionAfterBr( focus, domSelection ) {\n\tconst parent = focus.parent;\n\n\t// This fix works only when the focus point is at the very end of an element.\n\t// There is no point in running it in cases unrelated to the browser bug.\n\tif ( parent.nodeType != Node.ELEMENT_NODE || focus.offset != parent.childNodes.length - 1 ) {\n\t\treturn;\n\t}\n\n\tconst childAtOffset = parent.childNodes[ focus.offset ];\n\n\t// To stay on the safe side, the fix being as specific as possible, it targets only the\n\t// selection which is at the very end of the element and preceded by <br />.\n\tif ( childAtOffset && childAtOffset.tagName == 'BR' ) {\n\t\tdomSelection.addRange( domSelection.getRangeAt( 0 ) );\n\t}\n}\n\nfunction filterOutFakeSelectionContainer( domChildList, fakeSelectionContainer ) {\n\tconst childList = Array.from( domChildList );\n\n\tif ( childList.length == 0 || !fakeSelectionContainer ) {\n\t\treturn childList;\n\t}\n\n\tconst last = childList[ childList.length - 1 ];\n\n\tif ( last == fakeSelectionContainer ) {\n\t\tchildList.pop();\n\t}\n\n\treturn childList;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* globals window, document */\n\n/**\n * @module utils/dom/global\n */\n\n/**\n * A helper (module) giving an access to the global DOM objects such as `window` and\n * `document`. Accessing these objects using this helper allows easy and bulletproof\n * testing, i.e. stubbing native properties:\n *\n *\t\timport global from 'ckeditor5/utils/dom/global.js';\n *\n *\t\t// This stub will work for any code using global module.\n *\t\ttestUtils.sinon.stub( global, 'window', {\n *\t\t\tinnerWidth: 10000\n *\t\t} );\n *\n *\t\tconsole.log( global.window.innerWidth );\n */\nexport default { window, document };\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/indexof\n */\n\n/**\n * Returns index of the node in the parent element.\n *\n * @param {Node} node Node which index is tested.\n * @returns {Number} Index of the node in the parent element. Returns 0 if node has no parent.\n */\nexport default function indexOf( node ) {\n\tlet index = 0;\n\n\twhile ( node.previousSibling ) {\n\t\tnode = node.previousSibling;\n\t\tindex++;\n\t}\n\n\treturn index;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* globals Node */\n\n/**\n * @module utils/dom/getancestors\n */\n\n/**\n * Returns all ancestors of given DOM node, starting from the top-most (root). Includes the given node itself. If the\n * node is a part of `DocumentFragment` that `DocumentFragment` will be returned. In contrary, if the node is\n * appended to a `Document`, that `Document` will not be returned (algorithms operating on DOM tree care for `Document#documentElement`\n * at most, which will be returned).\n *\n * @param {Node} node DOM node.\n * @returns {Array.<Node|DocumentFragment>} Array of given `node` parents.\n */\nexport default function getAncestors( node ) {\n\tconst nodes = [];\n\n\t// We are interested in `Node`s `DocumentFragment`s only.\n\twhile ( node && node.nodeType != Node.DOCUMENT_NODE ) {\n\t\tnodes.unshift( node );\n\t\tnode = node.parentNode;\n\t}\n\n\treturn nodes;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/domconverter\n */\n\n/* globals document, Node, NodeFilter, Text */\n\nimport ViewText from './text';\nimport ViewElement from './element';\nimport ViewPosition from './position';\nimport ViewRange from './range';\nimport ViewSelection from './selection';\nimport ViewDocumentFragment from './documentfragment';\nimport ViewTreeWalker from './treewalker';\nimport { BR_FILLER, INLINE_FILLER_LENGTH, isBlockFiller, isInlineFiller, startsWithFiller, getDataWithoutFiller } from './filler';\n\nimport global from '@ckeditor/ckeditor5-utils/src/dom/global';\nimport indexOf from '@ckeditor/ckeditor5-utils/src/dom/indexof';\nimport getAncestors from '@ckeditor/ckeditor5-utils/src/dom/getancestors';\nimport getCommonAncestor from '@ckeditor/ckeditor5-utils/src/dom/getcommonancestor';\nimport isText from '@ckeditor/ckeditor5-utils/src/dom/istext';\nimport { isElement } from 'lodash-es';\n\n/**\n * DomConverter is a set of tools to do transformations between DOM nodes and view nodes. It also handles\n * {@link module:engine/view/domconverter~DomConverter#bindElements binding} these nodes.\n *\n * DomConverter does not check which nodes should be rendered (use {@link module:engine/view/renderer~Renderer}), does not keep a\n * state of a tree nor keeps synchronization between tree view and DOM tree (use {@link module:engine/view/document~Document}).\n *\n * DomConverter keeps DOM elements to View element bindings, so when the converter will be destroyed, the binding will\n * be lost. Two converters will keep separate binding maps, so one tree view can be bound with two DOM trees.\n */\nexport default class DomConverter {\n\t/**\n\t * Creates DOM converter.\n\t *\n\t * @param {Object} options Object with configuration options.\n\t * @param {Function} [options.blockFiller=module:engine/view/filler~BR_FILLER] Block filler creator.\n\t */\n\tconstructor( options = {} ) {\n\t\t// Using WeakMap prevent memory leaks: when the converter will be destroyed all referenced between View and DOM\n\t\t// will be removed. Also because it is a *Weak*Map when both view and DOM elements will be removed referenced\n\t\t// will be also removed, isn't it brilliant?\n\t\t//\n\t\t// Yes, PJ. It is.\n\t\t//\n\t\t// You guys so smart.\n\t\t//\n\t\t// I've been here. Seen stuff. Afraid of code now.\n\n\t\t/**\n\t\t * Block {@link module:engine/view/filler filler} creator, which is used to create all block fillers during the\n\t\t * view to DOM conversion and to recognize block fillers during the DOM to view conversion.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Function} module:engine/view/domconverter~DomConverter#blockFiller\n\t\t */\n\t\tthis.blockFiller = options.blockFiller || BR_FILLER;\n\n\t\t/**\n\t\t * Tag names of DOM `Element`s which are considered pre-formatted elements.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Array.<String>} module:engine/view/domconverter~DomConverter#preElements\n\t\t */\n\t\tthis.preElements = [ 'pre' ];\n\n\t\t/**\n\t\t * Tag names of DOM `Element`s which are considered block elements.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Array.<String>} module:engine/view/domconverter~DomConverter#blockElements\n\t\t */\n\t\tthis.blockElements = [ 'p', 'div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ];\n\n\t\t/**\n\t\t * DOM to View mapping.\n\t\t *\n\t\t * @private\n\t\t * @member {WeakMap} module:engine/view/domconverter~DomConverter#_domToViewMapping\n\t\t */\n\t\tthis._domToViewMapping = new WeakMap();\n\n\t\t/**\n\t\t * View to DOM mapping.\n\t\t *\n\t\t * @private\n\t\t * @member {WeakMap} module:engine/view/domconverter~DomConverter#_viewToDomMapping\n\t\t */\n\t\tthis._viewToDomMapping = new WeakMap();\n\n\t\t/**\n\t\t * Holds mapping between fake selection containers and corresponding view selections.\n\t\t *\n\t\t * @private\n\t\t * @member {WeakMap} module:engine/view/domconverter~DomConverter#_fakeSelectionMapping\n\t\t */\n\t\tthis._fakeSelectionMapping = new WeakMap();\n\t}\n\n\t/**\n\t * Binds given DOM element that represents fake selection to {@link module:engine/view/documentselection~DocumentSelection\n\t * document selection}. Document selection copy is stored and can be retrieved by\n\t * {@link module:engine/view/domconverter~DomConverter#fakeSelectionToView} method.\n\t *\n\t * @param {HTMLElement} domElement\n\t * @param {module:engine/view/documentselection~DocumentSelection} viewDocumentSelection\n\t */\n\tbindFakeSelection( domElement, viewDocumentSelection ) {\n\t\tthis._fakeSelectionMapping.set( domElement, new ViewSelection( viewDocumentSelection ) );\n\t}\n\n\t/**\n\t * Returns {@link module:engine/view/selection~Selection view selection} instance corresponding to\n\t * given DOM element that represents fake selection. Returns `undefined` if binding to given DOM element does not exists.\n\t *\n\t * @param {HTMLElement} domElement\n\t * @returns {module:engine/view/selection~Selection|undefined}\n\t */\n\tfakeSelectionToView( domElement ) {\n\t\treturn this._fakeSelectionMapping.get( domElement );\n\t}\n\n\t/**\n\t * Binds DOM and View elements, so it will be possible to get corresponding elements using\n\t * {@link module:engine/view/domconverter~DomConverter#mapDomToView} and\n\t * {@link module:engine/view/domconverter~DomConverter#mapViewToDom}.\n\t *\n\t * @param {HTMLElement} domElement DOM element to bind.\n\t * @param {module:engine/view/element~Element} viewElement View element to bind.\n\t */\n\tbindElements( domElement, viewElement ) {\n\t\tthis._domToViewMapping.set( domElement, viewElement );\n\t\tthis._viewToDomMapping.set( viewElement, domElement );\n\t}\n\n\t/**\n\t * Unbinds given `domElement` from the view element it was bound to. Unbinding is deep, meaning that all children of\n\t * `domElement` will be unbound too.\n\t *\n\t * @param {HTMLElement} domElement DOM element to unbind.\n\t */\n\tunbindDomElement( domElement ) {\n\t\tconst viewElement = this._domToViewMapping.get( domElement );\n\n\t\tif ( viewElement ) {\n\t\t\tthis._domToViewMapping.delete( domElement );\n\t\t\tthis._viewToDomMapping.delete( viewElement );\n\n\t\t\t// Use Array.from because of MS Edge (#923).\n\t\t\tfor ( const child of Array.from( domElement.childNodes ) ) {\n\t\t\t\tthis.unbindDomElement( child );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Binds DOM and View document fragments, so it will be possible to get corresponding document fragments using\n\t * {@link module:engine/view/domconverter~DomConverter#mapDomToView} and\n\t * {@link module:engine/view/domconverter~DomConverter#mapViewToDom}.\n\t *\n\t * @param {DocumentFragment} domFragment DOM document fragment to bind.\n\t * @param {module:engine/view/documentfragment~DocumentFragment} viewFragment View document fragment to bind.\n\t */\n\tbindDocumentFragments( domFragment, viewFragment ) {\n\t\tthis._domToViewMapping.set( domFragment, viewFragment );\n\t\tthis._viewToDomMapping.set( viewFragment, domFragment );\n\t}\n\n\t/**\n\t * Converts view to DOM. For all text nodes, not bound elements and document fragments new items will\n\t * be created. For bound elements and document fragments function will return corresponding items.\n\t *\n\t * @param {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment} viewNode\n\t * View node or document fragment to transform.\n\t * @param {Document} domDocument Document which will be used to create DOM nodes.\n\t * @param {Object} [options] Conversion options.\n\t * @param {Boolean} [options.bind=false] Determines whether new elements will be bound.\n\t * @param {Boolean} [options.withChildren=true] If `true`, node's and document fragment's children will be converted too.\n\t * @returns {Node|DocumentFragment} Converted node or DocumentFragment.\n\t */\n\tviewToDom( viewNode, domDocument, options = {} ) {\n\t\tif ( viewNode.is( 'text' ) ) {\n\t\t\tconst textData = this._processDataFromViewText( viewNode );\n\n\t\t\treturn domDocument.createTextNode( textData );\n\t\t} else {\n\t\t\tif ( this.mapViewToDom( viewNode ) ) {\n\t\t\t\treturn this.mapViewToDom( viewNode );\n\t\t\t}\n\n\t\t\tlet domElement;\n\n\t\t\tif ( viewNode.is( 'documentFragment' ) ) {\n\t\t\t\t// Create DOM document fragment.\n\t\t\t\tdomElement = domDocument.createDocumentFragment();\n\n\t\t\t\tif ( options.bind ) {\n\t\t\t\t\tthis.bindDocumentFragments( domElement, viewNode );\n\t\t\t\t}\n\t\t\t} else if ( viewNode.is( 'uiElement' ) ) {\n\t\t\t\t// UIElement has its own render() method (see #799).\n\t\t\t\tdomElement = viewNode.render( domDocument );\n\n\t\t\t\tif ( options.bind ) {\n\t\t\t\t\tthis.bindElements( domElement, viewNode );\n\t\t\t\t}\n\n\t\t\t\treturn domElement;\n\t\t\t} else {\n\t\t\t\t// Create DOM element.\n\t\t\t\tdomElement = domDocument.createElement( viewNode.name );\n\n\t\t\t\tif ( options.bind ) {\n\t\t\t\t\tthis.bindElements( domElement, viewNode );\n\t\t\t\t}\n\n\t\t\t\t// Copy element's attributes.\n\t\t\t\tfor ( const key of viewNode.getAttributeKeys() ) {\n\t\t\t\t\tdomElement.setAttribute( key, viewNode.getAttribute( key ) );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( options.withChildren || options.withChildren === undefined ) {\n\t\t\t\tfor ( const child of this.viewChildrenToDom( viewNode, domDocument, options ) ) {\n\t\t\t\t\tdomElement.appendChild( child );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn domElement;\n\t\t}\n\t}\n\n\t/**\n\t * Converts children of the view element to DOM using the\n\t * {@link module:engine/view/domconverter~DomConverter#viewToDom} method.\n\t * Additionally, this method adds block {@link module:engine/view/filler filler} to the list of children, if needed.\n\t *\n\t * @param {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment} viewElement Parent view element.\n\t * @param {Document} domDocument Document which will be used to create DOM nodes.\n\t * @param {Object} options See {@link module:engine/view/domconverter~DomConverter#viewToDom} options parameter.\n\t * @returns {Iterable.<Node>} DOM nodes.\n\t */\n\t* viewChildrenToDom( viewElement, domDocument, options = {} ) {\n\t\tconst fillerPositionOffset = viewElement.getFillerOffset && viewElement.getFillerOffset();\n\t\tlet offset = 0;\n\n\t\tfor ( const childView of viewElement.getChildren() ) {\n\t\t\tif ( fillerPositionOffset === offset ) {\n\t\t\t\tyield this.blockFiller( domDocument );\n\t\t\t}\n\n\t\t\tyield this.viewToDom( childView, domDocument, options );\n\n\t\t\toffset++;\n\t\t}\n\n\t\tif ( fillerPositionOffset === offset ) {\n\t\t\tyield this.blockFiller( domDocument );\n\t\t}\n\t}\n\n\t/**\n\t * Converts view {@link module:engine/view/range~Range} to DOM range.\n\t * Inline and block {@link module:engine/view/filler fillers} are handled during the conversion.\n\t *\n\t * @param {module:engine/view/range~Range} viewRange View range.\n\t * @returns {Range} DOM range.\n\t */\n\tviewRangeToDom( viewRange ) {\n\t\tconst domStart = this.viewPositionToDom( viewRange.start );\n\t\tconst domEnd = this.viewPositionToDom( viewRange.end );\n\n\t\tconst domRange = document.createRange();\n\t\tdomRange.setStart( domStart.parent, domStart.offset );\n\t\tdomRange.setEnd( domEnd.parent, domEnd.offset );\n\n\t\treturn domRange;\n\t}\n\n\t/**\n\t * Converts view {@link module:engine/view/position~Position} to DOM parent and offset.\n\t *\n\t * Inline and block {@link module:engine/view/filler fillers} are handled during the conversion.\n\t * If the converted position is directly before inline filler it is moved inside the filler.\n\t *\n\t * @param {module:engine/view/position~Position} viewPosition View position.\n\t * @returns {Object|null} position DOM position or `null` if view position could not be converted to DOM.\n\t * @returns {Node} position.parent DOM position parent.\n\t * @returns {Number} position.offset DOM position offset.\n\t */\n\tviewPositionToDom( viewPosition ) {\n\t\tconst viewParent = viewPosition.parent;\n\n\t\tif ( viewParent.is( 'text' ) ) {\n\t\t\tconst domParent = this.findCorrespondingDomText( viewParent );\n\n\t\t\tif ( !domParent ) {\n\t\t\t\t// Position is in a view text node that has not been rendered to DOM yet.\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tlet offset = viewPosition.offset;\n\n\t\t\tif ( startsWithFiller( domParent ) ) {\n\t\t\t\toffset += INLINE_FILLER_LENGTH;\n\t\t\t}\n\n\t\t\treturn { parent: domParent, offset };\n\t\t} else {\n\t\t\t// viewParent is instance of ViewElement.\n\t\t\tlet domParent, domBefore, domAfter;\n\n\t\t\tif ( viewPosition.offset === 0 ) {\n\t\t\t\tdomParent = this.mapViewToDom( viewParent );\n\n\t\t\t\tif ( !domParent ) {\n\t\t\t\t\t// Position is in a view element that has not been rendered to DOM yet.\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tdomAfter = domParent.childNodes[ 0 ];\n\t\t\t} else {\n\t\t\t\tconst nodeBefore = viewPosition.nodeBefore;\n\n\t\t\t\tdomBefore = nodeBefore.is( 'text' ) ?\n\t\t\t\t\tthis.findCorrespondingDomText( nodeBefore ) :\n\t\t\t\t\tthis.mapViewToDom( viewPosition.nodeBefore );\n\n\t\t\t\tif ( !domBefore ) {\n\t\t\t\t\t// Position is after a view element that has not been rendered to DOM yet.\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tdomParent = domBefore.parentNode;\n\t\t\t\tdomAfter = domBefore.nextSibling;\n\t\t\t}\n\n\t\t\t// If there is an inline filler at position return position inside the filler. We should never return\n\t\t\t// the position before the inline filler.\n\t\t\tif ( isText( domAfter ) && startsWithFiller( domAfter ) ) {\n\t\t\t\treturn { parent: domAfter, offset: INLINE_FILLER_LENGTH };\n\t\t\t}\n\n\t\t\tconst offset = domBefore ? indexOf( domBefore ) + 1 : 0;\n\n\t\t\treturn { parent: domParent, offset };\n\t\t}\n\t}\n\n\t/**\n\t * Converts DOM to view. For all text nodes, not bound elements and document fragments new items will\n\t * be created. For bound elements and document fragments function will return corresponding items. For\n\t * {@link module:engine/view/filler fillers} `null` will be returned.\n\t * For all DOM elements rendered by {@link module:engine/view/uielement~UIElement} that UIElement will be returned.\n\t *\n\t * @param {Node|DocumentFragment} domNode DOM node or document fragment to transform.\n\t * @param {Object} [options] Conversion options.\n\t * @param {Boolean} [options.bind=false] Determines whether new elements will be bound.\n\t * @param {Boolean} [options.withChildren=true] If `true`, node's and document fragment's children will be converted too.\n\t * @param {Boolean} [options.keepOriginalCase=false] If `false`, node's tag name will be converter to lower case.\n\t * @returns {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment|null} Converted node or document fragment\n\t * or `null` if DOM node is a {@link module:engine/view/filler filler} or the given node is an empty text node.\n\t */\n\tdomToView( domNode, options = {} ) {\n\t\tif ( isBlockFiller( domNode, this.blockFiller ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// When node is inside UIElement return that UIElement as it's view representation.\n\t\tconst uiElement = this.getParentUIElement( domNode, this._domToViewMapping );\n\n\t\tif ( uiElement ) {\n\t\t\treturn uiElement;\n\t\t}\n\n\t\tif ( isText( domNode ) ) {\n\t\t\tif ( isInlineFiller( domNode ) ) {\n\t\t\t\treturn null;\n\t\t\t} else {\n\t\t\t\tconst textData = this._processDataFromDomText( domNode );\n\n\t\t\t\treturn textData === '' ? null : new ViewText( textData );\n\t\t\t}\n\t\t} else if ( this.isComment( domNode ) ) {\n\t\t\treturn null;\n\t\t} else {\n\t\t\tif ( this.mapDomToView( domNode ) ) {\n\t\t\t\treturn this.mapDomToView( domNode );\n\t\t\t}\n\n\t\t\tlet viewElement;\n\n\t\t\tif ( this.isDocumentFragment( domNode ) ) {\n\t\t\t\t// Create view document fragment.\n\t\t\t\tviewElement = new ViewDocumentFragment();\n\n\t\t\t\tif ( options.bind ) {\n\t\t\t\t\tthis.bindDocumentFragments( domNode, viewElement );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Create view element.\n\t\t\t\tconst viewName = options.keepOriginalCase ? domNode.tagName : domNode.tagName.toLowerCase();\n\t\t\t\tviewElement = new ViewElement( viewName );\n\n\t\t\t\tif ( options.bind ) {\n\t\t\t\t\tthis.bindElements( domNode, viewElement );\n\t\t\t\t}\n\n\t\t\t\t// Copy element's attributes.\n\t\t\t\tconst attrs = domNode.attributes;\n\n\t\t\t\tfor ( let i = attrs.length - 1; i >= 0; i-- ) {\n\t\t\t\t\tviewElement._setAttribute( attrs[ i ].name, attrs[ i ].value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( options.withChildren || options.withChildren === undefined ) {\n\t\t\t\tfor ( const child of this.domChildrenToView( domNode, options ) ) {\n\t\t\t\t\tviewElement._appendChild( child );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn viewElement;\n\t\t}\n\t}\n\n\t/**\n\t * Converts children of the DOM element to view nodes using\n\t * the {@link module:engine/view/domconverter~DomConverter#domToView} method.\n\t * Additionally this method omits block {@link module:engine/view/filler filler}, if it exists in the DOM parent.\n\t *\n\t * @param {HTMLElement} domElement Parent DOM element.\n\t * @param {Object} options See {@link module:engine/view/domconverter~DomConverter#domToView} options parameter.\n\t * @returns {Iterable.<module:engine/view/node~Node>} View nodes.\n\t */\n\t* domChildrenToView( domElement, options = {} ) {\n\t\tfor ( let i = 0; i < domElement.childNodes.length; i++ ) {\n\t\t\tconst domChild = domElement.childNodes[ i ];\n\t\t\tconst viewChild = this.domToView( domChild, options );\n\n\t\t\tif ( viewChild !== null ) {\n\t\t\t\tyield viewChild;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Converts DOM selection to view {@link module:engine/view/selection~Selection}.\n\t * Ranges which cannot be converted will be omitted.\n\t *\n\t * @param {Selection} domSelection DOM selection.\n\t * @returns {module:engine/view/selection~Selection} View selection.\n\t */\n\tdomSelectionToView( domSelection ) {\n\t\t// DOM selection might be placed in fake selection container.\n\t\t// If container contains fake selection - return corresponding view selection.\n\t\tif ( domSelection.rangeCount === 1 ) {\n\t\t\tlet container = domSelection.getRangeAt( 0 ).startContainer;\n\n\t\t\t// The DOM selection might be moved to the text node inside the fake selection container.\n\t\t\tif ( isText( container ) ) {\n\t\t\t\tcontainer = container.parentNode;\n\t\t\t}\n\n\t\t\tconst viewSelection = this.fakeSelectionToView( container );\n\n\t\t\tif ( viewSelection ) {\n\t\t\t\treturn viewSelection;\n\t\t\t}\n\t\t}\n\n\t\tconst isBackward = this.isDomSelectionBackward( domSelection );\n\n\t\tconst viewRanges = [];\n\n\t\tfor ( let i = 0; i < domSelection.rangeCount; i++ ) {\n\t\t\t// DOM Range have correct start and end, no matter what is the DOM Selection direction. So we don't have to fix anything.\n\t\t\tconst domRange = domSelection.getRangeAt( i );\n\t\t\tconst viewRange = this.domRangeToView( domRange );\n\n\t\t\tif ( viewRange ) {\n\t\t\t\tviewRanges.push( viewRange );\n\t\t\t}\n\t\t}\n\n\t\treturn new ViewSelection( viewRanges, { backward: isBackward } );\n\t}\n\n\t/**\n\t * Converts DOM Range to view {@link module:engine/view/range~Range}.\n\t * If the start or end position can not be converted `null` is returned.\n\t *\n\t * @param {Range} domRange DOM range.\n\t * @returns {module:engine/view/range~Range|null} View range.\n\t */\n\tdomRangeToView( domRange ) {\n\t\tconst viewStart = this.domPositionToView( domRange.startContainer, domRange.startOffset );\n\t\tconst viewEnd = this.domPositionToView( domRange.endContainer, domRange.endOffset );\n\n\t\tif ( viewStart && viewEnd ) {\n\t\t\treturn new ViewRange( viewStart, viewEnd );\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Converts DOM parent and offset to view {@link module:engine/view/position~Position}.\n\t *\n\t * If the position is inside a {@link module:engine/view/filler filler} which has no corresponding view node,\n\t * position of the filler will be converted and returned.\n\t *\n\t * If the position is inside DOM element rendered by {@link module:engine/view/uielement~UIElement}\n\t * that position will be converted to view position before that UIElement.\n\t *\n\t * If structures are too different and it is not possible to find corresponding position then `null` will be returned.\n\t *\n\t * @param {Node} domParent DOM position parent.\n\t * @param {Number} domOffset DOM position offset.\n\t * @returns {module:engine/view/position~Position} viewPosition View position.\n\t */\n\tdomPositionToView( domParent, domOffset ) {\n\t\tif ( isBlockFiller( domParent, this.blockFiller ) ) {\n\t\t\treturn this.domPositionToView( domParent.parentNode, indexOf( domParent ) );\n\t\t}\n\n\t\t// If position is somewhere inside UIElement - return position before that element.\n\t\tconst viewElement = this.mapDomToView( domParent );\n\n\t\tif ( viewElement && viewElement.is( 'uiElement' ) ) {\n\t\t\treturn ViewPosition._createBefore( viewElement );\n\t\t}\n\n\t\tif ( isText( domParent ) ) {\n\t\t\tif ( isInlineFiller( domParent ) ) {\n\t\t\t\treturn this.domPositionToView( domParent.parentNode, indexOf( domParent ) );\n\t\t\t}\n\n\t\t\tconst viewParent = this.findCorrespondingViewText( domParent );\n\t\t\tlet offset = domOffset;\n\n\t\t\tif ( !viewParent ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( startsWithFiller( domParent ) ) {\n\t\t\t\toffset -= INLINE_FILLER_LENGTH;\n\t\t\t\toffset = offset < 0 ? 0 : offset;\n\t\t\t}\n\n\t\t\treturn new ViewPosition( viewParent, offset );\n\t\t}\n\t\t// domParent instanceof HTMLElement.\n\t\telse {\n\t\t\tif ( domOffset === 0 ) {\n\t\t\t\tconst viewParent = this.mapDomToView( domParent );\n\n\t\t\t\tif ( viewParent ) {\n\t\t\t\t\treturn new ViewPosition( viewParent, 0 );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst domBefore = domParent.childNodes[ domOffset - 1 ];\n\t\t\t\tconst viewBefore = isText( domBefore ) ?\n\t\t\t\t\tthis.findCorrespondingViewText( domBefore ) :\n\t\t\t\t\tthis.mapDomToView( domBefore );\n\n\t\t\t\t// TODO #663\n\t\t\t\tif ( viewBefore && viewBefore.parent ) {\n\t\t\t\t\treturn new ViewPosition( viewBefore.parent, viewBefore.index + 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Returns corresponding view {@link module:engine/view/element~Element Element} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment} for provided DOM element or\n\t * document fragment. If there is no view item {@link module:engine/view/domconverter~DomConverter#bindElements bound}\n\t * to the given DOM - `undefined` is returned.\n\t * For all DOM elements rendered by {@link module:engine/view/uielement~UIElement} that UIElement will be returned.\n\t *\n\t * @param {DocumentFragment|Element} domElementOrDocumentFragment DOM element or document fragment.\n\t * @returns {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment|undefined}\n\t * Corresponding view element, document fragment or `undefined` if no element was bound.\n\t */\n\tmapDomToView( domElementOrDocumentFragment ) {\n\t\treturn this.getParentUIElement( domElementOrDocumentFragment ) || this._domToViewMapping.get( domElementOrDocumentFragment );\n\t}\n\n\t/**\n\t * Finds corresponding text node. Text nodes are not {@link module:engine/view/domconverter~DomConverter#bindElements bound},\n\t * corresponding text node is returned based on the sibling or parent.\n\t *\n\t * If the directly previous sibling is a {@link module:engine/view/domconverter~DomConverter#bindElements bound} element, it is used\n\t * to find the corresponding text node.\n\t *\n\t * If this is a first child in the parent and the parent is a {@link module:engine/view/domconverter~DomConverter#bindElements bound}\n\t * element, it is used to find the corresponding text node.\n\t *\n\t * For all text nodes rendered by {@link module:engine/view/uielement~UIElement} that UIElement will be returned.\n\t *\n\t * Otherwise `null` is returned.\n\t *\n\t * Note that for the block or inline {@link module:engine/view/filler filler} this method returns `null`.\n\t *\n\t * @param {Text} domText DOM text node.\n\t * @returns {module:engine/view/text~Text|null} Corresponding view text node or `null`, if it was not possible to find a\n\t * corresponding node.\n\t */\n\tfindCorrespondingViewText( domText ) {\n\t\tif ( isInlineFiller( domText ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// If DOM text was rendered by UIElement - return that element.\n\t\tconst uiElement = this.getParentUIElement( domText );\n\n\t\tif ( uiElement ) {\n\t\t\treturn uiElement;\n\t\t}\n\n\t\tconst previousSibling = domText.previousSibling;\n\n\t\t// Try to use previous sibling to find the corresponding text node.\n\t\tif ( previousSibling ) {\n\t\t\tif ( !( this.isElement( previousSibling ) ) ) {\n\t\t\t\t// The previous is text or comment.\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst viewElement = this.mapDomToView( previousSibling );\n\n\t\t\tif ( viewElement ) {\n\t\t\t\tconst nextSibling = viewElement.nextSibling;\n\n\t\t\t\t// It might be filler which has no corresponding view node.\n\t\t\t\tif ( nextSibling instanceof ViewText ) {\n\t\t\t\t\treturn viewElement.nextSibling;\n\t\t\t\t} else {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Try to use parent to find the corresponding text node.\n\t\telse {\n\t\t\tconst viewElement = this.mapDomToView( domText.parentNode );\n\n\t\t\tif ( viewElement ) {\n\t\t\t\tconst firstChild = viewElement.getChild( 0 );\n\n\t\t\t\t// It might be filler which has no corresponding view node.\n\t\t\t\tif ( firstChild instanceof ViewText ) {\n\t\t\t\t\treturn firstChild;\n\t\t\t\t} else {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Returns corresponding DOM item for provided {@link module:engine/view/element~Element Element} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment DocumentFragment}.\n\t * To find a corresponding text for {@link module:engine/view/text~Text view Text instance}\n\t * use {@link #findCorrespondingDomText}.\n\t *\n\t * @param {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment} viewNode\n\t * View element or document fragment.\n\t * @returns {Node|DocumentFragment|undefined} Corresponding DOM node or document fragment.\n\t */\n\tmapViewToDom( documentFragmentOrElement ) {\n\t\treturn this._viewToDomMapping.get( documentFragmentOrElement );\n\t}\n\n\t/**\n\t * Finds corresponding text node. Text nodes are not {@link module:engine/view/domconverter~DomConverter#bindElements bound},\n\t * corresponding text node is returned based on the sibling or parent.\n\t *\n\t * If the directly previous sibling is a {@link module:engine/view/domconverter~DomConverter#bindElements bound} element, it is used\n\t * to find the corresponding text node.\n\t *\n\t * If this is a first child in the parent and the parent is a {@link module:engine/view/domconverter~DomConverter#bindElements bound}\n\t * element, it is used to find the corresponding text node.\n\t *\n\t * Otherwise `null` is returned.\n\t *\n\t * @param {module:engine/view/text~Text} viewText View text node.\n\t * @returns {Text|null} Corresponding DOM text node or `null`, if it was not possible to find a corresponding node.\n\t */\n\tfindCorrespondingDomText( viewText ) {\n\t\tconst previousSibling = viewText.previousSibling;\n\n\t\t// Try to use previous sibling to find the corresponding text node.\n\t\tif ( previousSibling && this.mapViewToDom( previousSibling ) ) {\n\t\t\treturn this.mapViewToDom( previousSibling ).nextSibling;\n\t\t}\n\n\t\t// If this is a first node, try to use parent to find the corresponding text node.\n\t\tif ( !previousSibling && viewText.parent && this.mapViewToDom( viewText.parent ) ) {\n\t\t\treturn this.mapViewToDom( viewText.parent ).childNodes[ 0 ];\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Focuses DOM editable that is corresponding to provided {@link module:engine/view/editableelement~EditableElement}.\n\t *\n\t * @param {module:engine/view/editableelement~EditableElement} viewEditable\n\t */\n\tfocus( viewEditable ) {\n\t\tconst domEditable = this.mapViewToDom( viewEditable );\n\n\t\tif ( domEditable && domEditable.ownerDocument.activeElement !== domEditable ) {\n\t\t\t// Save the scrollX and scrollY positions before the focus.\n\t\t\tconst { scrollX, scrollY } = global.window;\n\t\t\tconst scrollPositions = [];\n\n\t\t\t// Save all scrollLeft and scrollTop values starting from domEditable up to\n\t\t\t// document#documentElement.\n\t\t\tforEachDomNodeAncestor( domEditable, node => {\n\t\t\t\tconst { scrollLeft, scrollTop } = node;\n\n\t\t\t\tscrollPositions.push( [ scrollLeft, scrollTop ] );\n\t\t\t} );\n\n\t\t\tdomEditable.focus();\n\n\t\t\t// Restore scrollLeft and scrollTop values starting from domEditable up to\n\t\t\t// document#documentElement.\n\t\t\t// https://github.com/ckeditor/ckeditor5-engine/issues/951\n\t\t\t// https://github.com/ckeditor/ckeditor5-engine/issues/957\n\t\t\tforEachDomNodeAncestor( domEditable, node => {\n\t\t\t\tconst [ scrollLeft, scrollTop ] = scrollPositions.shift();\n\n\t\t\t\tnode.scrollLeft = scrollLeft;\n\t\t\t\tnode.scrollTop = scrollTop;\n\t\t\t} );\n\n\t\t\t// Restore the scrollX and scrollY positions after the focus.\n\t\t\t// https://github.com/ckeditor/ckeditor5-engine/issues/951\n\t\t\tglobal.window.scrollTo( scrollX, scrollY );\n\t\t}\n\t}\n\n\t/**\n\t * Returns `true` when `node.nodeType` equals `Node.ELEMENT_NODE`.\n\t *\n\t * @param {Node} node Node to check.\n\t * @returns {Boolean}\n\t */\n\tisElement( node ) {\n\t\treturn node && node.nodeType == Node.ELEMENT_NODE;\n\t}\n\n\t/**\n\t * Returns `true` when `node.nodeType` equals `Node.DOCUMENT_FRAGMENT_NODE`.\n\t *\n\t * @param {Node} node Node to check.\n\t * @returns {Boolean}\n\t */\n\tisDocumentFragment( node ) {\n\t\treturn node && node.nodeType == Node.DOCUMENT_FRAGMENT_NODE;\n\t}\n\n\t/**\n\t * Returns `true` when `node.nodeType` equals `Node.COMMENT_NODE`.\n\t *\n\t * @param {Node} node Node to check.\n\t * @returns {Boolean}\n\t */\n\tisComment( node ) {\n\t\treturn node && node.nodeType == Node.COMMENT_NODE;\n\t}\n\n\t/**\n\t * Returns `true` if given selection is a backward selection, that is, if it's `focus` is before `anchor`.\n\t *\n\t * @param {Selection} DOM Selection instance to check.\n\t * @returns {Boolean}\n\t */\n\tisDomSelectionBackward( selection ) {\n\t\tif ( selection.isCollapsed ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Since it takes multiple lines of code to check whether a \"DOM Position\" is before/after another \"DOM Position\",\n\t\t// we will use the fact that range will collapse if it's end is before it's start.\n\t\tconst range = document.createRange();\n\n\t\trange.setStart( selection.anchorNode, selection.anchorOffset );\n\t\trange.setEnd( selection.focusNode, selection.focusOffset );\n\n\t\tconst backward = range.collapsed;\n\n\t\trange.detach();\n\n\t\treturn backward;\n\t}\n\n\t/**\n\t * Returns parent {@link module:engine/view/uielement~UIElement} for provided DOM node. Returns `null` if there is no\n\t * parent UIElement.\n\t *\n\t * @param {Node} domNode\n\t * @returns {module:engine/view/uielement~UIElement|null}\n\t */\n\tgetParentUIElement( domNode ) {\n\t\tconst ancestors = getAncestors( domNode );\n\n\t\t// Remove domNode from the list.\n\t\tancestors.pop();\n\n\t\twhile ( ancestors.length ) {\n\t\t\tconst domNode = ancestors.pop();\n\t\t\tconst viewNode = this._domToViewMapping.get( domNode );\n\n\t\t\tif ( viewNode && viewNode.is( 'uiElement' ) ) {\n\t\t\t\treturn viewNode;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Checks if given selection's boundaries are at correct places.\n\t *\n\t * The following places are considered as incorrect for selection boundaries:\n\t * * before or in the middle of the inline filler sequence,\n\t * * inside the DOM element which represents {@link module:engine/view/uielement~UIElement a view ui element}.\n\t *\n\t * @param {Selection} domSelection DOM Selection object to be checked.\n\t * @returns {Boolean} `true` if the given selection is at a correct place, `false` otherwise.\n\t */\n\tisDomSelectionCorrect( domSelection ) {\n\t\treturn this._isDomSelectionPositionCorrect( domSelection.anchorNode, domSelection.anchorOffset ) &&\n\t\t\tthis._isDomSelectionPositionCorrect( domSelection.focusNode, domSelection.focusOffset );\n\t}\n\n\t/**\n\t * Checks if the given DOM position is a correct place for selection boundary. See {@link #isDomSelectionCorrect}.\n\t *\n\t * @private\n\t * @param {Element} domParent Position parent.\n\t * @param {Number} offset Position offset.\n\t * @returns {Boolean} `true` if given position is at a correct place for selection boundary, `false` otherwise.\n\t */\n\t_isDomSelectionPositionCorrect( domParent, offset ) {\n\t\t// If selection is before or in the middle of inline filler string, it is incorrect.\n\t\tif ( isText( domParent ) && startsWithFiller( domParent ) && offset < INLINE_FILLER_LENGTH ) {\n\t\t\t// Selection in a text node, at wrong position (before or in the middle of filler).\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this.isElement( domParent ) && startsWithFiller( domParent.childNodes[ offset ] ) ) {\n\t\t\t// Selection in an element node, before filler text node.\n\t\t\treturn false;\n\t\t}\n\n\t\tconst viewParent = this.mapDomToView( domParent );\n\n\t\t// If selection is in `view.UIElement`, it is incorrect. Note that `mapDomToView()` returns `view.UIElement`\n\t\t// also for any dom element that is inside the view ui element (so we don't need to perform any additional checks).\n\t\tif ( viewParent && viewParent.is( 'uiElement' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Takes text data from a given {@link module:engine/view/text~Text#data} and processes it so\n\t * it is correctly displayed in the DOM.\n\t *\n\t * Following changes are done:\n\t *\n\t * * a space at the beginning is changed to `&nbsp;` if this is the first text node in its container\n\t * element or if a previous text node ends with a space character,\n\t * * space at the end of the text node is changed to `&nbsp;` if this is the last text node in its container,\n\t * * remaining spaces are replaced to a chain of spaces and `&nbsp;` (e.g. `'x x'` becomes `'x &nbsp; x'`).\n\t *\n\t * Content of {@link #preElements} is not processed.\n\t *\n\t * @private\n\t * @param {module:engine/view/text~Text} node View text node to process.\n\t * @returns {String} Processed text data.\n\t */\n\t_processDataFromViewText( node ) {\n\t\tlet data = node.data;\n\n\t\t// If any of node ancestors has a name which is in `preElements` array, then currently processed\n\t\t// view text node is (will be) in preformatted element. We should not change whitespaces then.\n\t\tif ( node.getAncestors().some( parent => this.preElements.includes( parent.name ) ) ) {\n\t\t\treturn data;\n\t\t}\n\n\t\t// 1. Replace the first space with a nbsp if the previous node ends with a space or there is no previous node\n\t\t// (container element boundary).\n\t\tif ( data.charAt( 0 ) == ' ' ) {\n\t\t\tconst prevNode = this._getTouchingViewTextNode( node, false );\n\t\t\tconst prevEndsWithSpace = prevNode && this._nodeEndsWithSpace( prevNode );\n\n\t\t\tif ( prevEndsWithSpace || !prevNode ) {\n\t\t\t\tdata = '\\u00A0' + data.substr( 1 );\n\t\t\t}\n\t\t}\n\n\t\t// 2. Replace the last space with a nbsp if this is the last text node (container element boundary).\n\t\tif ( data.charAt( data.length - 1 ) == ' ' ) {\n\t\t\tconst nextNode = this._getTouchingViewTextNode( node, true );\n\n\t\t\tif ( !nextNode ) {\n\t\t\t\tdata = data.substr( 0, data.length - 1 ) + '\\u00A0';\n\t\t\t}\n\t\t}\n\n\t\treturn data.replace( / {2}/g, ' \\u00A0' );\n\t}\n\n\t/**\n\t * Checks whether given node ends with a space character after changing appropriate space characters to `&nbsp;`s.\n\t *\n\t * @private\n\t * @param {module:engine/view/text~Text} node Node to check.\n\t * @returns {Boolean} `true` if given `node` ends with space, `false` otherwise.\n\t */\n\t_nodeEndsWithSpace( node ) {\n\t\tif ( node.getAncestors().some( parent => this.preElements.includes( parent.name ) ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst data = this._processDataFromViewText( node );\n\n\t\treturn data.charAt( data.length - 1 ) == ' ';\n\t}\n\n\t/**\n\t * Takes text data from native `Text` node and processes it to a correct {@link module:engine/view/text~Text view text node} data.\n\t *\n\t * Following changes are done:\n\t *\n\t * * multiple whitespaces are replaced to a single space,\n\t * * space at the beginning of a text node is removed if it is the first text node in its container\n\t * element or if the previous text node ends with a space character,\n\t * * space at the end of the text node is removed, if it is the last text node in its container.\n\t *\n\t * @param {Node} node DOM text node to process.\n\t * @returns {String} Processed data.\n\t * @private\n\t */\n\t_processDataFromDomText( node ) {\n\t\tlet data = node.data;\n\n\t\tif ( _hasDomParentOfType( node, this.preElements ) ) {\n\t\t\treturn getDataWithoutFiller( node );\n\t\t}\n\n\t\t// Change all consecutive whitespace characters (from the [ \\n\\t\\r] set –\n\t\t// see https://github.com/ckeditor/ckeditor5-engine/issues/822#issuecomment-311670249) to a single space character.\n\t\t// That's how multiple whitespaces are treated when rendered, so we normalize those whitespaces.\n\t\t// We're replacing 1+ (and not 2+) to also normalize singular \\n\\t\\r characters (#822).\n\t\tdata = data.replace( /[ \\n\\t\\r]{1,}/g, ' ' );\n\n\t\tconst prevNode = this._getTouchingInlineDomNode( node, false );\n\t\tconst nextNode = this._getTouchingInlineDomNode( node, true );\n\n\t\tconst shouldLeftTrim = this._checkShouldLeftTrimDomText( prevNode );\n\t\tconst shouldRightTrim = this._checkShouldRightTrimDomText( node, nextNode );\n\n\t\t// If the previous dom text node does not exist or it ends by whitespace character, remove space character from the beginning\n\t\t// of this text node. Such space character is treated as a whitespace.\n\t\tif ( shouldLeftTrim ) {\n\t\t\tdata = data.replace( /^ /, '' );\n\t\t}\n\n\t\t// If the next text node does not exist remove space character from the end of this text node.\n\t\tif ( shouldRightTrim ) {\n\t\t\tdata = data.replace( / $/, '' );\n\t\t}\n\n\t\t// At the beginning and end of a block element, Firefox inserts normal space + <br> instead of non-breaking space.\n\t\t// This means that the text node starts/end with normal space instead of non-breaking space.\n\t\t// This causes a problem because the normal space would be removed in `.replace` calls above. To prevent that,\n\t\t// the inline filler is removed only after the data is initially processed (by the `.replace` above). See ckeditor5#692.\n\t\tdata = getDataWithoutFiller( new Text( data ) );\n\n\t\t// At this point we should have removed all whitespaces from DOM text data.\n\n\t\t// Now we have to change &nbsp; chars, that were in DOM text data because of rendering reasons, to spaces.\n\t\t// First, change all ` \\u00A0` pairs (space + &nbsp;) to two spaces. DOM converter changes two spaces from model/view as\n\t\t// ` \\u00A0` to ensure proper rendering. Since here we convert back, we recognize those pairs and change them\n\t\t// to ` ` which is what we expect to have in model/view.\n\t\tdata = data.replace( / \\u00A0/g, ' ' );\n\n\t\t// Then, change &nbsp; character that is at the beginning of the text node to space character.\n\t\t// As above, that &nbsp; was created for rendering reasons but it's real meaning is just a space character.\n\t\t// We do that replacement only if this is the first node or the previous node ends on whitespace character.\n\t\tif ( shouldLeftTrim ) {\n\t\t\tdata = data.replace( /^\\u00A0/, ' ' );\n\t\t}\n\n\t\t// Since input text data could be: `x_ _`, we would not replace the first &nbsp; after `x` character.\n\t\t// We have to fix it. Since we already change all ` &nbsp;`, we will have something like this at the end of text data:\n\t\t// `x_ _ _` -> `x_ `. Find &nbsp; at the end of string (can be followed only by spaces).\n\t\t// We do that replacement only if this is the last node or the next node starts with &nbsp; or is a <br>.\n\t\tif ( isText( nextNode ) ? nextNode.data.charAt( 0 ) == '\\u00A0' : true ) {\n\t\t\tdata = data.replace( /\\u00A0( *)$/, ' $1' );\n\t\t}\n\n\t\t// At this point, all whitespaces should be removed and all &nbsp; created for rendering reasons should be\n\t\t// changed to normal space. All left &nbsp; are &nbsp; inserted intentionally.\n\t\treturn data;\n\t}\n\n\t/**\n\t * Helper function which checks if a DOM text node, preceded by the given `prevNode` should\n\t * be trimmed from the left side.\n\t *\n\t * @param {Node} prevNode\n\t */\n\t_checkShouldLeftTrimDomText( prevNode ) {\n\t\tif ( !prevNode ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( isElement( prevNode ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn /[^\\S\\u00A0]/.test( prevNode.data.charAt( prevNode.data.length - 1 ) );\n\t}\n\n\t/**\n\t * Helper function which checks if a DOM text node, succeeded by the given `nextNode` should\n\t * be trimmed from the right side.\n\t *\n\t * @param {Node} node\n\t * @param {Node} prevNode\n\t */\n\t_checkShouldRightTrimDomText( node, nextNode ) {\n\t\tif ( nextNode ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn !startsWithFiller( node );\n\t}\n\n\t/**\n\t * Helper function. For given {@link module:engine/view/text~Text view text node}, it finds previous or next sibling\n\t * that is contained in the same container element. If there is no such sibling, `null` is returned.\n\t *\n\t * @param {module:engine/view/text~Text} node Reference node.\n\t * @param {Boolean} getNext\n\t * @returns {module:engine/view/text~Text|null} Touching text node or `null` if there is no next or previous touching text node.\n\t */\n\t_getTouchingViewTextNode( node, getNext ) {\n\t\tconst treeWalker = new ViewTreeWalker( {\n\t\t\tstartPosition: getNext ? ViewPosition._createAfter( node ) : ViewPosition._createBefore( node ),\n\t\t\tdirection: getNext ? 'forward' : 'backward'\n\t\t} );\n\n\t\tfor ( const value of treeWalker ) {\n\t\t\t// ViewContainerElement is found on a way to next ViewText node, so given `node` was first/last\n\t\t\t// text node in its container element.\n\t\t\tif ( value.item.is( 'containerElement' ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\t// <br> found – it works like a block boundary, so do not scan further.\n\t\t\telse if ( value.item.is( 'br' ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\t// Found a text node in the same container element.\n\t\t\telse if ( value.item.is( 'textProxy' ) ) {\n\t\t\t\treturn value.item;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Helper function. For the given text node, it finds the closest touching node which is either\n\t * a text node or a `<br>`. The search is terminated at block element boundaries and if a matching node\n\t * wasn't found so far, `null` is returned.\n\t *\n\t * In the following DOM structure:\n\t *\n\t *\t\t<p>foo<b>bar</b><br>bom</p>\n\t *\n\t * * `foo` doesn't have its previous touching inline node (`null` is returned),\n\t * * `foo`'s next touching inline node is `bar`\n\t * * `bar`'s next touching inline node is `<br>`\n\t *\n\t * This method returns text nodes and `<br>` elements because these types of nodes affect how\n\t * spaces in the given text node need to be converted.\n\t *\n\t * @private\n\t * @param {Text} node\n\t * @param {Boolean} getNext\n\t * @returns {Text|Element|null}\n\t */\n\t_getTouchingInlineDomNode( node, getNext ) {\n\t\tif ( !node.parentNode ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst direction = getNext ? 'nextNode' : 'previousNode';\n\t\tconst document = node.ownerDocument;\n\t\tconst topmostParent = getAncestors( node )[ 0 ];\n\n\t\tconst treeWalker = document.createTreeWalker( topmostParent, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT, {\n\t\t\tacceptNode( node ) {\n\t\t\t\tif ( isText( node ) ) {\n\t\t\t\t\treturn NodeFilter.FILTER_ACCEPT;\n\t\t\t\t}\n\n\t\t\t\tif ( node.tagName == 'BR' ) {\n\t\t\t\t\treturn NodeFilter.FILTER_ACCEPT;\n\t\t\t\t}\n\n\t\t\t\treturn NodeFilter.FILTER_SKIP;\n\t\t\t}\n\t\t} );\n\n\t\ttreeWalker.currentNode = node;\n\n\t\tconst touchingNode = treeWalker[ direction ]();\n\n\t\tif ( touchingNode !== null ) {\n\t\t\tconst lca = getCommonAncestor( node, touchingNode );\n\n\t\t\t// If there is common ancestor between the text node and next/prev text node,\n\t\t\t// and there are no block elements on a way from the text node to that ancestor,\n\t\t\t// and there are no block elements on a way from next/prev text node to that ancestor...\n\t\t\tif (\n\t\t\t\tlca &&\n\t\t\t\t!_hasDomParentOfType( node, this.blockElements, lca ) &&\n\t\t\t\t!_hasDomParentOfType( touchingNode, this.blockElements, lca )\n\t\t\t) {\n\t\t\t\t// Then they are in the same container element.\n\t\t\t\treturn touchingNode;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n}\n\n// Helper function.\n// Used to check if given native `Element` or `Text` node has parent with tag name from `types` array.\n//\n// @param {Node} node\n// @param {Array.<String>} types\n// @param {Boolean} [boundaryParent] Can be given if parents should be checked up to a given element (excluding that element).\n// @returns {Boolean} `true` if such parent exists or `false` if it does not.\nfunction _hasDomParentOfType( node, types, boundaryParent ) {\n\tlet parents = getAncestors( node );\n\n\tif ( boundaryParent ) {\n\t\tparents = parents.slice( parents.indexOf( boundaryParent ) + 1 );\n\t}\n\n\treturn parents.some( parent => parent.tagName && types.includes( parent.tagName.toLowerCase() ) );\n}\n\n// A helper that executes given callback for each DOM node's ancestor, starting from the given node\n// and ending in document#documentElement.\n//\n// @param {Node} node\n// @param {Function} callback A callback to be executed for each ancestor.\nfunction forEachDomNodeAncestor( node, callback ) {\n\twhile ( node && node != global.document ) {\n\t\tcallback( node );\n\t\tnode = node.parentNode;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/getcommonancestor\n */\n\nimport getAncestors from './getancestors';\n\n/**\n * Searches and returns the lowest common ancestor of two given nodes.\n *\n * @param {Node} nodeA First node.\n * @param {Node} nodeB Second node.\n * @returns {Node|DocumentFragment|Document|null} Lowest common ancestor of both nodes or `null` if nodes do not have a common ancestor.\n */\nexport default function getCommonAncestor( nodeA, nodeB ) {\n\tconst ancestorsA = getAncestors( nodeA );\n\tconst ancestorsB = getAncestors( nodeB );\n\n\tlet i = 0;\n\n\t// It does not matter which array is shorter.\n\twhile ( ancestorsA[ i ] == ancestorsB[ i ] && ancestorsA[ i ] ) {\n\t\ti++;\n\t}\n\n\treturn i === 0 ? null : ancestorsA[ i - 1 ];\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/iswindow\n */\n\n/**\n * Checks if the object is a native DOM Window.\n *\n * @param {*} obj\n * @returns {Boolean}\n */\nexport default function isWindow( obj ) {\n\tconst stringifiedObject = Object.prototype.toString.apply( obj );\n\n\t// Returns `true` for the `window` object in browser environments.\n\tif ( stringifiedObject == '[object Window]' ) {\n\t\treturn true;\n\t}\n\n\t// Returns `true` for the `window` object in the Electron environment.\n\tif ( stringifiedObject == '[object global]' ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/emittermixin\n */\n\nimport { default as EmitterMixin, _getEmitterListenedTo, _setEmitterId } from '../emittermixin';\nimport uid from '../uid';\nimport isNode from './isnode';\nimport isWindow from './iswindow';\nimport { extend } from 'lodash-es';\n\n/**\n * Mixin that injects the DOM events API into its host. It provides the API\n * compatible with {@link module:utils/emittermixin~EmitterMixin}.\n *\n * DOM emitter mixin is by default available in the {@link module:ui/view~View} class,\n * but it can also be mixed into any other class:\n *\n *\t\timport mix from '../utils/mix.js';\n *\t\timport DomEmitterMixin from '../utils/dom/emittermixin.js';\n *\n *\t\tclass SomeView {}\n *\t\tmix( SomeView, DomEmitterMixin );\n *\n *\t\tconst view = new SomeView();\n *\t\tview.listenTo( domElement, ( evt, domEvt ) => {\n *\t\t\tconsole.log( evt, domEvt );\n *\t\t} );\n *\n * @mixin EmitterMixin\n * @mixes module:utils/emittermixin~EmitterMixin\n * @implements module:utils/dom/emittermixin~Emitter\n */\nconst DomEmitterMixin = extend( {}, EmitterMixin, {\n\t/**\n\t * Registers a callback function to be executed when an event is fired in a specific Emitter or DOM Node.\n\t * It is backwards compatible with {@link module:utils/emittermixin~EmitterMixin#listenTo}.\n\t *\n\t * @param {module:utils/emittermixin~Emitter|Node} emitter The object that fires the event.\n\t * @param {String} event The name of the event.\n\t * @param {Function} callback The function to be called on event.\n\t * @param {Object} [options={}] Additional options.\n\t * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of this event callback. The higher\n\t * the priority value the sooner the callback will be fired. Events having the same priority are called in the\n\t * order they were added.\n\t * @param {Boolean} [options.useCapture=false] Indicates that events of this type will be dispatched to the registered\n\t * listener before being dispatched to any EventTarget beneath it in the DOM tree.\n\t */\n\tlistenTo( emitter, ...rest ) {\n\t\t// Check if emitter is an instance of DOM Node. If so, replace the argument with\n\t\t// corresponding ProxyEmitter (or create one if not existing).\n\t\tif ( isNode( emitter ) || isWindow( emitter ) ) {\n\t\t\tconst proxy = this._getProxyEmitter( emitter ) || new ProxyEmitter( emitter );\n\n\t\t\tproxy.attach( ...rest );\n\n\t\t\temitter = proxy;\n\t\t}\n\n\t\t// Execute parent class method with Emitter (or ProxyEmitter) instance.\n\t\tEmitterMixin.listenTo.call( this, emitter, ...rest );\n\t},\n\n\t/**\n\t * Stops listening for events. It can be used at different levels:\n\t * It is backwards compatible with {@link module:utils/emittermixin~EmitterMixin#listenTo}.\n\t *\n\t * * To stop listening to a specific callback.\n\t * * To stop listening to a specific event.\n\t * * To stop listening to all events fired by a specific object.\n\t * * To stop listening to all events fired by all object.\n\t *\n\t * @param {module:utils/emittermixin~Emitter|Node} [emitter] The object to stop listening to. If omitted, stops it for all objects.\n\t * @param {String} [event] (Requires the `emitter`) The name of the event to stop listening to. If omitted, stops it\n\t * for all events from `emitter`.\n\t * @param {Function} [callback] (Requires the `event`) The function to be removed from the call list for the given\n\t * `event`.\n\t */\n\tstopListening( emitter, event, callback ) {\n\t\t// Check if emitter is an instance of DOM Node. If so, replace the argument with corresponding ProxyEmitter.\n\t\tif ( isNode( emitter ) || isWindow( emitter ) ) {\n\t\t\tconst proxy = this._getProxyEmitter( emitter );\n\n\t\t\t// Element has no listeners.\n\t\t\tif ( !proxy ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\temitter = proxy;\n\t\t}\n\n\t\t// Execute parent class method with Emitter (or ProxyEmitter) instance.\n\t\tEmitterMixin.stopListening.call( this, emitter, event, callback );\n\n\t\tif ( emitter instanceof ProxyEmitter ) {\n\t\t\temitter.detach( event );\n\t\t}\n\t},\n\n\t/**\n\t * Retrieves ProxyEmitter instance for given DOM Node residing in this Host.\n\t *\n\t * @pivate\n\t * @param {Node} node DOM Node of the ProxyEmitter.\n\t * @returns {module:utils/dom/emittermixin~ProxyEmitter} ProxyEmitter instance or null.\n\t */\n\t_getProxyEmitter( node ) {\n\t\treturn _getEmitterListenedTo( this, getNodeUID( node ) );\n\t}\n} );\n\nexport default DomEmitterMixin;\n\n/**\n * Creates a ProxyEmitter instance. Such an instance is a bridge between a DOM Node firing events\n * and any Host listening to them. It is backwards compatible with {@link module:utils/emittermixin~EmitterMixin#on}.\n *\n * listenTo( click, ... )\n * +-----------------------------------------+\n * | stopListening( ... ) |\n * +----------------------------+ | addEventListener( click, ... )\n * | Host | | +---------------------------------------------+\n * +----------------------------+ | | removeEventListener( click, ... ) |\n * | _listeningTo: { | +----------v-------------+ |\n * | UID: { | | ProxyEmitter | |\n * | emitter: ProxyEmitter, | +------------------------+ +------------v----------+\n * | callbacks: { | | events: { | | Node (HTMLElement) |\n * | click: [ callbacks ] | | click: [ callbacks ] | +-----------------------+\n * | } | | }, | | data-ck-expando: UID |\n * | } | | _domNode: Node, | +-----------------------+\n * | } | | _domListeners: {}, | |\n * | +------------------------+ | | _emitterId: UID | |\n * | | DomEmitterMixin | | +--------------^---------+ |\n * | +------------------------+ | | | |\n * +--------------^-------------+ | +---------------------------------------------+\n * | | click (DOM Event)\n * +-----------------------------------------+\n * fire( click, DOM Event )\n *\n * @mixes module:utils/emittermixin~EmitterMixin\n * @implements module:utils/dom/emittermixin~Emitter\n * @private\n */\nclass ProxyEmitter {\n\t/**\n\t * @param {Node} node DOM Node that fires events.\n\t * @returns {Object} ProxyEmitter instance bound to the DOM Node.\n\t */\n\tconstructor( node ) {\n\t\t// Set emitter ID to match DOM Node \"expando\" property.\n\t\t_setEmitterId( this, getNodeUID( node ) );\n\n\t\t// Remember the DOM Node this ProxyEmitter is bound to.\n\t\tthis._domNode = node;\n\t}\n}\n\nextend( ProxyEmitter.prototype, EmitterMixin, {\n\t/**\n\t * Collection of native DOM listeners.\n\t *\n\t * @private\n\t * @member {Object} module:utils/dom/emittermixin~ProxyEmitter#_domListeners\n\t */\n\n\t/**\n\t * Registers a callback function to be executed when an event is fired.\n\t *\n\t * It attaches a native DOM listener to the DOM Node. When fired,\n\t * a corresponding Emitter event will also fire with DOM Event object as an argument.\n\t *\n\t * @method module:utils/dom/emittermixin~ProxyEmitter#attach\n\t * @param {String} event The name of the event.\n\t * @param {Function} callback The function to be called on event.\n\t * @param {Object} [options={}] Additional options.\n\t * @param {Boolean} [options.useCapture=false] Indicates that events of this type will be dispatched to the registered\n\t * listener before being dispatched to any EventTarget beneath it in the DOM tree.\n\t */\n\tattach( event, callback, options = {} ) {\n\t\t// If the DOM Listener for given event already exist it is pointless\n\t\t// to attach another one.\n\t\tif ( this._domListeners && this._domListeners[ event ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst domListener = this._createDomListener( event, !!options.useCapture );\n\n\t\t// Attach the native DOM listener to DOM Node.\n\t\tthis._domNode.addEventListener( event, domListener, !!options.useCapture );\n\n\t\tif ( !this._domListeners ) {\n\t\t\tthis._domListeners = {};\n\t\t}\n\n\t\t// Store the native DOM listener in this ProxyEmitter. It will be helpful\n\t\t// when stopping listening to the event.\n\t\tthis._domListeners[ event ] = domListener;\n\t},\n\n\t/**\n\t * Stops executing the callback on the given event.\n\t *\n\t * @method module:utils/dom/emittermixin~ProxyEmitter#detach\n\t * @param {String} event The name of the event.\n\t */\n\tdetach( event ) {\n\t\tlet events;\n\n\t\t// Remove native DOM listeners which are orphans. If no callbacks\n\t\t// are awaiting given event, detach native DOM listener from DOM Node.\n\t\t// See: {@link attach}.\n\n\t\tif ( this._domListeners[ event ] && ( !( events = this._events[ event ] ) || !events.callbacks.length ) ) {\n\t\t\tthis._domListeners[ event ].removeListener();\n\t\t}\n\t},\n\n\t/**\n\t * Creates a native DOM listener callback. When the native DOM event\n\t * is fired it will fire corresponding event on this ProxyEmitter.\n\t * Note: A native DOM Event is passed as an argument.\n\t *\n\t * @private\n\t * @method module:utils/dom/emittermixin~ProxyEmitter#_createDomListener\n\t * @param {String} event The name of the event.\n\t * @param {Boolean} useCapture Indicates whether the listener was created for capturing event.\n\t * @returns {Function} The DOM listener callback.\n\t */\n\t_createDomListener( event, useCapture ) {\n\t\tconst domListener = domEvt => {\n\t\t\tthis.fire( event, domEvt );\n\t\t};\n\n\t\t// Supply the DOM listener callback with a function that will help\n\t\t// detach it from the DOM Node, when it is no longer necessary.\n\t\t// See: {@link detach}.\n\t\tdomListener.removeListener = () => {\n\t\t\tthis._domNode.removeEventListener( event, domListener, useCapture );\n\t\t\tdelete this._domListeners[ event ];\n\t\t};\n\n\t\treturn domListener;\n\t}\n} );\n\n// Gets an unique DOM Node identifier. The identifier will be set if not defined.\n//\n// @private\n// @param {Node} node\n// @returns {String} UID for given DOM Node.\nfunction getNodeUID( node ) {\n\treturn node[ 'data-ck-expando' ] || ( node[ 'data-ck-expando' ] = uid() );\n}\n\n/**\n * Interface representing classes which mix in {@link module:utils/dom/emittermixin~EmitterMixin}.\n *\n * @interface Emitter\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/observer\n */\n\nimport DomEmitterMixin from '@ckeditor/ckeditor5-utils/src/dom/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * Abstract base observer class. Observers are classes which listen to DOM events, do the preliminary\n * processing and fire events on the {@link module:engine/view/document~Document} objects.\n * Observers can also add features to the view, for instance by updating its status or marking elements\n * which need refresh on DOM events.\n *\n * @abstract\n */\nexport default class Observer {\n\t/**\n\t * Creates an instance of the observer.\n\t *\n\t * @param {module:engine/view/view~View} view\n\t */\n\tconstructor( view ) {\n\t\t/**\n\t\t * Instance of the view controller.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/view~View}\n\t\t */\n\t\tthis.view = view;\n\n\t\t/**\n\t\t * Reference to the {@link module:engine/view/document~Document} object.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/document~Document}\n\t\t */\n\t\tthis.document = view.document;\n\n\t\t/**\n\t\t * State of the observer. If it is disabled events will not be fired.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis.isEnabled = false;\n\t}\n\n\t/**\n\t * Enables the observer. This method is called when the observer is registered to the\n\t * {@link module:engine/view/view~View} and after {@link module:engine/view/view~View#forceRender rendering}\n\t * (all observers are {@link #disable disabled} before rendering).\n\t *\n\t * A typical use case for disabling observers is that mutation observers need to be disabled for the rendering.\n\t * However, a child class may not need to be disabled, so it can implement an empty method.\n\t *\n\t * @see module:engine/view/observer/observer~Observer#disable\n\t */\n\tenable() {\n\t\tthis.isEnabled = true;\n\t}\n\n\t/**\n\t * Disables the observer. This method is called before\n\t * {@link module:engine/view/view~View#forceRender rendering} to prevent firing events during rendering.\n\t *\n\t * @see module:engine/view/observer/observer~Observer#enable\n\t */\n\tdisable() {\n\t\tthis.isEnabled = false;\n\t}\n\n\t/**\n\t * Disables and destroys the observer, among others removes event listeners created by the observer.\n\t */\n\tdestroy() {\n\t\tthis.disable();\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Starts observing the given root element.\n\t *\n\t * @method #observe\n\t * @param {HTMLElement} domElement\n\t * @param {String} name The name of the root element.\n\t */\n}\n\nmix( Observer, DomEmitterMixin );\n","/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\nexport default setCacheAdd;\n","/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\nexport default setCacheHas;\n","import MapCache from './_MapCache.js';\nimport setCacheAdd from './_setCacheAdd.js';\nimport setCacheHas from './_setCacheHas.js';\n\n/**\n *\n * Creates an array cache object to store unique values.\n *\n * @private\n * @constructor\n * @param {Array} [values] The values to cache.\n */\nfunction SetCache(values) {\n var index = -1,\n length = values == null ? 0 : values.length;\n\n this.__data__ = new MapCache;\n while (++index < length) {\n this.add(values[index]);\n }\n}\n\n// Add methods to `SetCache`.\nSetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\nSetCache.prototype.has = setCacheHas;\n\nexport default SetCache;\n","/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\nexport default arraySome;\n","/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\nexport default cacheHas;\n","import SetCache from './_SetCache.js';\nimport arraySome from './_arraySome.js';\nimport cacheHas from './_cacheHas.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * A specialized version of `baseIsEqualDeep` for arrays with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Array} array The array to compare.\n * @param {Array} other The other array to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `array` and `other` objects.\n * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n */\nfunction equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n arrLength = array.length,\n othLength = other.length;\n\n if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(array);\n if (stacked && stack.get(other)) {\n return stacked == other;\n }\n var index = -1,\n result = true,\n seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n stack.set(array, other);\n stack.set(other, array);\n\n // Ignore non-index properties.\n while (++index < arrLength) {\n var arrValue = array[index],\n othValue = other[index];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, arrValue, index, other, array, stack)\n : customizer(arrValue, othValue, index, array, other, stack);\n }\n if (compared !== undefined) {\n if (compared) {\n continue;\n }\n result = false;\n break;\n }\n // Recursively compare arrays (susceptible to call stack limits).\n if (seen) {\n if (!arraySome(other, function(othValue, othIndex) {\n if (!cacheHas(seen, othIndex) &&\n (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n return seen.push(othIndex);\n }\n })) {\n result = false;\n break;\n }\n } else if (!(\n arrValue === othValue ||\n equalFunc(arrValue, othValue, bitmask, customizer, stack)\n )) {\n result = false;\n break;\n }\n }\n stack['delete'](array);\n stack['delete'](other);\n return result;\n}\n\nexport default equalArrays;\n","/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\nexport default mapToArray;\n","/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\nexport default setToArray;\n","import Symbol from './_Symbol.js';\nimport Uint8Array from './_Uint8Array.js';\nimport eq from './eq.js';\nimport equalArrays from './_equalArrays.js';\nimport mapToArray from './_mapToArray.js';\nimport setToArray from './_setToArray.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * A specialized version of `baseIsEqualDeep` for comparing objects of\n * the same `toStringTag`.\n *\n * **Note:** This function only supports comparing values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The `toStringTag` of the objects to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n switch (tag) {\n case dataViewTag:\n if ((object.byteLength != other.byteLength) ||\n (object.byteOffset != other.byteOffset)) {\n return false;\n }\n object = object.buffer;\n other = other.buffer;\n\n case arrayBufferTag:\n if ((object.byteLength != other.byteLength) ||\n !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n return false;\n }\n return true;\n\n case boolTag:\n case dateTag:\n case numberTag:\n // Coerce booleans to `1` or `0` and dates to milliseconds.\n // Invalid dates are coerced to `NaN`.\n return eq(+object, +other);\n\n case errorTag:\n return object.name == other.name && object.message == other.message;\n\n case regexpTag:\n case stringTag:\n // Coerce regexes to strings and treat strings, primitives and objects,\n // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n // for more details.\n return object == (other + '');\n\n case mapTag:\n var convert = mapToArray;\n\n case setTag:\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n convert || (convert = setToArray);\n\n if (object.size != other.size && !isPartial) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked) {\n return stacked == other;\n }\n bitmask |= COMPARE_UNORDERED_FLAG;\n\n // Recursively compare objects (susceptible to call stack limits).\n stack.set(object, other);\n var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n stack['delete'](object);\n return result;\n\n case symbolTag:\n if (symbolValueOf) {\n return symbolValueOf.call(object) == symbolValueOf.call(other);\n }\n }\n return false;\n}\n\nexport default equalByTag;\n","import getAllKeys from './_getAllKeys.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqualDeep` for objects with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n objProps = getAllKeys(object),\n objLength = objProps.length,\n othProps = getAllKeys(other),\n othLength = othProps.length;\n\n if (objLength != othLength && !isPartial) {\n return false;\n }\n var index = objLength;\n while (index--) {\n var key = objProps[index];\n if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n return false;\n }\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked && stack.get(other)) {\n return stacked == other;\n }\n var result = true;\n stack.set(object, other);\n stack.set(other, object);\n\n var skipCtor = isPartial;\n while (++index < objLength) {\n key = objProps[index];\n var objValue = object[key],\n othValue = other[key];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, objValue, key, other, object, stack)\n : customizer(objValue, othValue, key, object, other, stack);\n }\n // Recursively compare objects (susceptible to call stack limits).\n if (!(compared === undefined\n ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n : compared\n )) {\n result = false;\n break;\n }\n skipCtor || (skipCtor = key == 'constructor');\n }\n if (result && !skipCtor) {\n var objCtor = object.constructor,\n othCtor = other.constructor;\n\n // Non `Object` object instances with different constructors are not equal.\n if (objCtor != othCtor &&\n ('constructor' in object && 'constructor' in other) &&\n !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n result = false;\n }\n }\n stack['delete'](object);\n stack['delete'](other);\n return result;\n}\n\nexport default equalObjects;\n","import Stack from './_Stack.js';\nimport equalArrays from './_equalArrays.js';\nimport equalByTag from './_equalByTag.js';\nimport equalObjects from './_equalObjects.js';\nimport getTag from './_getTag.js';\nimport isArray from './isArray.js';\nimport isBuffer from './isBuffer.js';\nimport isTypedArray from './isTypedArray.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqual` for arrays and objects which performs\n * deep comparisons and tracks traversed objects enabling objects with circular\n * references to be compared.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n var objIsArr = isArray(object),\n othIsArr = isArray(other),\n objTag = objIsArr ? arrayTag : getTag(object),\n othTag = othIsArr ? arrayTag : getTag(other);\n\n objTag = objTag == argsTag ? objectTag : objTag;\n othTag = othTag == argsTag ? objectTag : othTag;\n\n var objIsObj = objTag == objectTag,\n othIsObj = othTag == objectTag,\n isSameTag = objTag == othTag;\n\n if (isSameTag && isBuffer(object)) {\n if (!isBuffer(other)) {\n return false;\n }\n objIsArr = true;\n objIsObj = false;\n }\n if (isSameTag && !objIsObj) {\n stack || (stack = new Stack);\n return (objIsArr || isTypedArray(object))\n ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n }\n if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n if (objIsWrapped || othIsWrapped) {\n var objUnwrapped = objIsWrapped ? object.value() : object,\n othUnwrapped = othIsWrapped ? other.value() : other;\n\n stack || (stack = new Stack);\n return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n }\n }\n if (!isSameTag) {\n return false;\n }\n stack || (stack = new Stack);\n return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n}\n\nexport default baseIsEqualDeep;\n","import baseIsEqualDeep from './_baseIsEqualDeep.js';\nimport isObjectLike from './isObjectLike.js';\n\n/**\n * The base implementation of `_.isEqual` which supports partial comparisons\n * and tracks traversed objects.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Unordered comparison\n * 2 - Partial comparison\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n */\nfunction baseIsEqual(value, other, bitmask, customizer, stack) {\n if (value === other) {\n return true;\n }\n if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n return value !== value && other !== other;\n }\n return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n}\n\nexport default baseIsEqual;\n","import baseIsEqual from './_baseIsEqual.js';\n\n/**\n * This method is like `_.isEqual` except that it accepts `customizer` which\n * is invoked to compare values. If `customizer` returns `undefined`, comparisons\n * are handled by the method instead. The `customizer` is invoked with up to\n * six arguments: (objValue, othValue [, index|key, object, other, stack]).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * function isGreeting(value) {\n * return /^h(?:i|ello)$/.test(value);\n * }\n *\n * function customizer(objValue, othValue) {\n * if (isGreeting(objValue) && isGreeting(othValue)) {\n * return true;\n * }\n * }\n *\n * var array = ['hello', 'goodbye'];\n * var other = ['hi', 'goodbye'];\n *\n * _.isEqualWith(array, other, customizer);\n * // => true\n */\nfunction isEqualWith(value, other, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n var result = customizer ? customizer(value, other) : undefined;\n return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;\n}\n\nexport default isEqualWith;\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/mutationobserver\n */\n\n/* globals window */\n\nimport Observer from './observer';\nimport ViewSelection from '../selection';\nimport { startsWithFiller, getDataWithoutFiller } from '../filler';\nimport { isEqualWith } from 'lodash-es';\n\n/**\n * Mutation observer class observes changes in the DOM, fires {@link module:engine/view/document~Document#event:mutations} event, mark view\n * elements as changed and call {@link module:engine/view/renderer~Renderer#render}.\n * Because all mutated nodes are marked as \"to be rendered\" and the\n * {@link module:engine/view/renderer~Renderer#render} is called, all changes will be reverted, unless the mutation will be handled by the\n * {@link module:engine/view/document~Document#event:mutations} event listener. It means user will see only handled changes, and the editor\n * will block all changes which are not handled.\n *\n * Mutation Observer also take care of reducing number of mutations which are fired. It removes duplicates and\n * mutations on elements which do not have corresponding view elements. Also\n * {@link module:engine/view/observer/mutationobserver~MutatedText text mutation} is fired only if parent element do not change child list.\n *\n * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.\n *\n * @extends module:engine/view/observer/observer~Observer\n */\nexport default class MutationObserver extends Observer {\n\tconstructor( view ) {\n\t\tsuper( view );\n\n\t\t/**\n\t\t * Native mutation observer config.\n\t\t *\n\t\t * @private\n\t\t * @member {Object}\n\t\t */\n\t\tthis._config = {\n\t\t\tchildList: true,\n\t\t\tcharacterData: true,\n\t\t\tcharacterDataOldValue: true,\n\t\t\tsubtree: true\n\t\t};\n\n\t\t/**\n\t\t * Reference to the {@link module:engine/view/view~View#domConverter}.\n\t\t *\n\t\t * @member {module:engine/view/domconverter~DomConverter}\n\t\t */\n\t\tthis.domConverter = view.domConverter;\n\n\t\t/**\n\t\t * Reference to the {@link module:engine/view/view~View#_renderer}.\n\t\t *\n\t\t * @member {module:engine/view/renderer~Renderer}\n\t\t */\n\t\tthis.renderer = view._renderer;\n\n\t\t/**\n\t\t * Observed DOM elements.\n\t\t *\n\t\t * @private\n\t\t * @member {Array.<HTMLElement>}\n\t\t */\n\t\tthis._domElements = [];\n\n\t\t/**\n\t\t * Native mutation observer.\n\t\t *\n\t\t * @private\n\t\t * @member {MutationObserver}\n\t\t */\n\t\tthis._mutationObserver = new window.MutationObserver( this._onMutations.bind( this ) );\n\t}\n\n\t/**\n\t * Synchronously fires {@link module:engine/view/document~Document#event:mutations} event with all mutations in record queue.\n\t * At the same time empties the queue so mutations will not be fired twice.\n\t */\n\tflush() {\n\t\tthis._onMutations( this._mutationObserver.takeRecords() );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tobserve( domElement ) {\n\t\tthis._domElements.push( domElement );\n\n\t\tif ( this.isEnabled ) {\n\t\t\tthis._mutationObserver.observe( domElement, this._config );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tenable() {\n\t\tsuper.enable();\n\n\t\tfor ( const domElement of this._domElements ) {\n\t\t\tthis._mutationObserver.observe( domElement, this._config );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdisable() {\n\t\tsuper.disable();\n\n\t\tthis._mutationObserver.disconnect();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tsuper.destroy();\n\n\t\tthis._mutationObserver.disconnect();\n\t}\n\n\t/**\n\t * Handles mutations. Deduplicates, mark view elements to sync, fire event and call render.\n\t *\n\t * @private\n\t * @param {Array.<Object>} domMutations Array of native mutations.\n\t */\n\t_onMutations( domMutations ) {\n\t\t// As a result of this.flush() we can have an empty collection.\n\t\tif ( domMutations.length === 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst domConverter = this.domConverter;\n\n\t\t// Use map and set for deduplication.\n\t\tconst mutatedTexts = new Map();\n\t\tconst mutatedElements = new Set();\n\n\t\t// Handle `childList` mutations first, so we will be able to check if the `characterData` mutation is in the\n\t\t// element with changed structure anyway.\n\t\tfor ( const mutation of domMutations ) {\n\t\t\tif ( mutation.type === 'childList' ) {\n\t\t\t\tconst element = domConverter.mapDomToView( mutation.target );\n\n\t\t\t\t// Do not collect mutations from UIElements.\n\t\t\t\tif ( element && element.is( 'uiElement' ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif ( element && !this._isBogusBrMutation( mutation ) ) {\n\t\t\t\t\tmutatedElements.add( element );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Handle `characterData` mutations later, when we have the full list of nodes which changed structure.\n\t\tfor ( const mutation of domMutations ) {\n\t\t\tconst element = domConverter.mapDomToView( mutation.target );\n\n\t\t\t// Do not collect mutations from UIElements.\n\t\t\tif ( element && element.is( 'uiElement' ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( mutation.type === 'characterData' ) {\n\t\t\t\tconst text = domConverter.findCorrespondingViewText( mutation.target );\n\n\t\t\t\tif ( text && !mutatedElements.has( text.parent ) ) {\n\t\t\t\t\t// Use text as a key, for deduplication. If there will be another mutation on the same text element\n\t\t\t\t\t// we will have only one in the map.\n\t\t\t\t\tmutatedTexts.set( text, {\n\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\toldText: text.data,\n\t\t\t\t\t\tnewText: getDataWithoutFiller( mutation.target ),\n\t\t\t\t\t\tnode: text\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t\t// When we added first letter to the text node which had only inline filler, for the DOM it is mutation\n\t\t\t\t// on text, but for the view, where filler text node did not existed, new text node was created, so we\n\t\t\t\t// need to fire 'children' mutation instead of 'text'.\n\t\t\t\telse if ( !text && startsWithFiller( mutation.target ) ) {\n\t\t\t\t\tmutatedElements.add( domConverter.mapDomToView( mutation.target.parentNode ) );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Now we build the list of mutations to fire and mark elements. We did not do it earlier to avoid marking the\n\t\t// same node multiple times in case of duplication.\n\n\t\t// List of mutations we will fire.\n\t\tconst viewMutations = [];\n\n\t\tfor ( const mutatedText of mutatedTexts.values() ) {\n\t\t\tthis.renderer.markToSync( 'text', mutatedText.node );\n\t\t\tviewMutations.push( mutatedText );\n\t\t}\n\n\t\tfor ( const viewElement of mutatedElements ) {\n\t\t\tconst domElement = domConverter.mapViewToDom( viewElement );\n\t\t\tconst viewChildren = Array.from( viewElement.getChildren() );\n\t\t\tconst newViewChildren = Array.from( domConverter.domChildrenToView( domElement, { withChildren: false } ) );\n\n\t\t\t// It may happen that as a result of many changes (sth was inserted and then removed),\n\t\t\t// both elements haven't really changed. #1031\n\t\t\tif ( !isEqualWith( viewChildren, newViewChildren, sameNodes ) ) {\n\t\t\t\tthis.renderer.markToSync( 'children', viewElement );\n\n\t\t\t\tviewMutations.push( {\n\t\t\t\t\ttype: 'children',\n\t\t\t\t\toldChildren: viewChildren,\n\t\t\t\t\tnewChildren: newViewChildren,\n\t\t\t\t\tnode: viewElement\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\n\t\t// Retrieve `domSelection` using `ownerDocument` of one of mutated nodes.\n\t\t// There should not be simultaneous mutation in multiple documents, so it's fine.\n\t\tconst domSelection = domMutations[ 0 ].target.ownerDocument.getSelection();\n\n\t\tlet viewSelection = null;\n\n\t\tif ( domSelection && domSelection.anchorNode ) {\n\t\t\t// If `domSelection` is inside a dom node that is already bound to a view node from view tree, get\n\t\t\t// corresponding selection in the view and pass it together with `viewMutations`. The `viewSelection` may\n\t\t\t// be used by features handling mutations.\n\t\t\t// Only one range is supported.\n\n\t\t\tconst viewSelectionAnchor = domConverter.domPositionToView( domSelection.anchorNode, domSelection.anchorOffset );\n\t\t\tconst viewSelectionFocus = domConverter.domPositionToView( domSelection.focusNode, domSelection.focusOffset );\n\n\t\t\t// Anchor and focus has to be properly mapped to view.\n\t\t\tif ( viewSelectionAnchor && viewSelectionFocus ) {\n\t\t\t\tviewSelection = new ViewSelection( viewSelectionAnchor );\n\t\t\t\tviewSelection.setFocus( viewSelectionFocus );\n\t\t\t}\n\t\t}\n\n\t\tthis.document.fire( 'mutations', viewMutations, viewSelection );\n\n\t\t// If nothing changes on `mutations` event, at this point we have \"dirty DOM\" (changed) and de-synched\n\t\t// view (which has not been changed). In order to \"reset DOM\" we render the view again.\n\t\tthis.view.forceRender();\n\n\t\tfunction sameNodes( child1, child2 ) {\n\t\t\t// First level of comparison (array of children vs array of children) – use the Lodash's default behavior.\n\t\t\tif ( Array.isArray( child1 ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Elements.\n\t\t\tif ( child1 === child2 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\t// Texts.\n\t\t\telse if ( child1.is( 'text' ) && child2.is( 'text' ) ) {\n\t\t\t\treturn child1.data === child2.data;\n\t\t\t}\n\n\t\t\t// Not matching types.\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Checks if mutation was generated by the browser inserting bogus br on the end of the block element.\n\t * Such mutations are generated while pressing space or performing native spellchecker correction\n\t * on the end of the block element in Firefox browser.\n\t *\n\t * @private\n\t * @param {Object} mutation Native mutation object.\n\t * @returns {Boolean}\n\t */\n\t_isBogusBrMutation( mutation ) {\n\t\tlet addedNode = null;\n\n\t\t// Check if mutation added only one node on the end of its parent.\n\t\tif ( mutation.nextSibling === null && mutation.removedNodes.length === 0 && mutation.addedNodes.length == 1 ) {\n\t\t\taddedNode = this.domConverter.domToView( mutation.addedNodes[ 0 ], {\n\t\t\t\twithChildren: false\n\t\t\t} );\n\t\t}\n\n\t\treturn addedNode && addedNode.is( 'element', 'br' );\n\t}\n}\n\n/**\n * Fired when mutation occurred. If tree view is not changed on this event, DOM will be reverted to the state before\n * mutation, so all changes which should be applied, should be handled on this event.\n *\n * Introduced by {@link module:engine/view/observer/mutationobserver~MutationObserver}.\n *\n * Note that because {@link module:engine/view/observer/mutationobserver~MutationObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/mutationobserver~MutationObserver\n * @event module:engine/view/document~Document#event:mutations\n * @param {Array.<module:engine/view/observer/mutationobserver~MutatedText|module:engine/view/observer/mutationobserver~MutatedChildren>}\n * viewMutations Array of mutations.\n * For mutated texts it will be {@link module:engine/view/observer/mutationobserver~MutatedText} and for mutated elements it will be\n * {@link module:engine/view/observer/mutationobserver~MutatedChildren}. You can recognize the type based on the `type` property.\n * @param {module:engine/view/selection~Selection|null} viewSelection View selection that is a result of converting DOM selection to view.\n * Keep in\n * mind that the DOM selection is already \"updated\", meaning that it already acknowledges changes done in mutation.\n */\n\n/**\n * Mutation item for text.\n *\n * @see module:engine/view/document~Document#event:mutations\n * @see module:engine/view/observer/mutationobserver~MutatedChildren\n *\n * @typedef {Object} module:engine/view/observer/mutationobserver~MutatedText\n *\n * @property {String} type For text mutations it is always 'text'.\n * @property {module:engine/view/text~Text} node Mutated text node.\n * @property {String} oldText Old text.\n * @property {String} newText New text.\n */\n\n/**\n * Mutation item for child nodes.\n *\n * @see module:engine/view/document~Document#event:mutations\n * @see module:engine/view/observer/mutationobserver~MutatedText\n *\n * @typedef {Object} module:engine/view/observer/mutationobserver~MutatedChildren\n *\n * @property {String} type For child nodes mutations it is always 'children'.\n * @property {module:engine/view/element~Element} node Parent of the mutated children.\n * @property {Array.<module:engine/view/node~Node>} oldChildren Old child nodes.\n * @property {Array.<module:engine/view/node~Node>} newChildren New child nodes.\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/domeventdata\n */\n\nimport { extend } from 'lodash-es';\n\n/**\n * Information about a DOM event in context of the {@link module:engine/view/document~Document}.\n * It wraps the native event, which usually should not be used as the wrapper contains\n * additional data (like key code for keyboard events).\n */\nexport default class DomEventData {\n\t/**\n\t * @param {module:engine/view/view~View} view The instance of the view controller.\n\t * @param {Event} domEvent The DOM event.\n\t * @param {Object} [additionalData] Additional properties that the instance should contain.\n\t */\n\tconstructor( view, domEvent, additionalData ) {\n\t\t/**\n\t\t * Instance of the view controller.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/view~View} module:engine/view/observer/observer~Observer.DomEvent#view\n\t\t */\n\t\tthis.view = view;\n\n\t\t/**\n\t\t * The instance of the document.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/document~Document} module:engine/view/observer/observer~Observer.DomEvent#document\n\t\t */\n\t\tthis.document = view.document;\n\n\t\t/**\n\t\t * The DOM event.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Event} module:engine/view/observer/observer~Observer.DomEvent#domEvent\n\t\t */\n\t\tthis.domEvent = domEvent;\n\n\t\t/**\n\t\t * The DOM target.\n\t\t *\n\t\t * @readonly\n\t\t * @member {HTMLElement} module:engine/view/observer/observer~Observer.DomEvent#target\n\t\t */\n\t\tthis.domTarget = domEvent.target;\n\n\t\textend( this, additionalData );\n\t}\n\n\t/**\n\t * The tree view element representing the target.\n\t *\n\t * @readonly\n\t * @type module:engine/view/element~Element\n\t */\n\tget target() {\n\t\treturn this.view.domConverter.mapDomToView( this.domTarget );\n\t}\n\n\t/**\n\t * Prevents the native's event default action.\n\t */\n\tpreventDefault() {\n\t\tthis.domEvent.preventDefault();\n\t}\n\n\t/**\n\t * Stops native event propagation.\n\t */\n\tstopPropagation() {\n\t\tthis.domEvent.stopPropagation();\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/domeventobserver\n */\n\nimport Observer from './observer';\nimport DomEventData from './domeventdata';\n\n/**\n * Base class for DOM event observers. This class handles\n * {@link module:engine/view/observer/observer~Observer#observe adding} listeners to DOM elements,\n * {@link module:engine/view/observer/observer~Observer#disable disabling} and\n * {@link module:engine/view/observer/observer~Observer#enable re-enabling} events.\n * Child class needs to define\n * {@link module:engine/view/observer/domeventobserver~DomEventObserver#domEventType DOM event type} and\n * {@link module:engine/view/observer/domeventobserver~DomEventObserver#onDomEvent callback}.\n *\n * For instance:\n *\n *\t\tclass ClickObserver extends DomEventObserver {\n *\t\t\t// It can also be defined as a normal property in the constructor.\n *\t\t\tget domEventType() {\n *\t\t\t\treturn 'click';\n *\t\t\t}\n *\n *\t\t\tonDomEvent( domEvent ) {\n *\t\t\t\tthis.fire( 'click', domEvent );\n *\t\t\t}\n *\t\t}\n *\n * @extends module:engine/view/observer/observer~Observer\n */\nexport default class DomEventObserver extends Observer {\n\t/**\n\t * Type of the DOM event the observer should listen on. Array of types can be defined\n\t * if the obsever should listen to multiple DOM events.\n\t *\n\t * @readonly\n\t * @member {String|Array.<String>} #domEventType\n\t */\n\n\t/**\n\t * Callback which should be called when the DOM event occurred. Note that the callback will not be called if\n\t * observer {@link #isEnabled is not enabled}.\n\t *\n\t * @see #domEventType\n\t * @abstract\n\t * @method #onDomEvent\n\t */\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( view ) {\n\t\tsuper( view );\n\n\t\t/**\n\t\t * If set to `true` DOM events will be listened on the capturing phase.\n\t\t * Default value is `false`.\n\t\t *\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis.useCapture = false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tobserve( domElement ) {\n\t\tconst types = typeof this.domEventType == 'string' ? [ this.domEventType ] : this.domEventType;\n\n\t\ttypes.forEach( type => {\n\t\t\tthis.listenTo( domElement, type, ( eventInfo, domEvent ) => {\n\t\t\t\tif ( this.isEnabled ) {\n\t\t\t\t\tthis.onDomEvent( domEvent );\n\t\t\t\t}\n\t\t\t}, { useCapture: this.useCapture } );\n\t\t} );\n\t}\n\n\t/**\n\t * Calls `Document#fire()` if observer {@link #isEnabled is enabled}.\n\t *\n\t * @see module:utils/emittermixin~EmitterMixin#fire\n\t * @param {String} eventType The event type (name).\n\t * @param {Event} domEvent The DOM event.\n\t * @param {Object} [additionalData] The additional data which should extend the\n\t * {@link module:engine/view/observer/domeventdata~DomEventData event data} object.\n\t */\n\tfire( eventType, domEvent, additionalData ) {\n\t\tif ( this.isEnabled ) {\n\t\t\tthis.document.fire( eventType, new DomEventData( this.view, domEvent, additionalData ) );\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/keyobserver\n */\n\nimport DomEventObserver from './domeventobserver';\nimport { getCode } from '@ckeditor/ckeditor5-utils/src/keyboard';\n\n/**\n * {@link module:engine/view/document~Document#event:keydown Key down} event observer.\n *\n * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.\n *\n * @extends module:engine/view/observer/domeventobserver~DomEventObserver\n */\nexport default class KeyObserver extends DomEventObserver {\n\tconstructor( view ) {\n\t\tsuper( view );\n\n\t\tthis.domEventType = [ 'keydown', 'keyup' ];\n\t}\n\n\tonDomEvent( domEvt ) {\n\t\tthis.fire( domEvt.type, domEvt, {\n\t\t\tkeyCode: domEvt.keyCode,\n\n\t\t\taltKey: domEvt.altKey,\n\t\t\tctrlKey: domEvt.ctrlKey || domEvt.metaKey,\n\t\t\tshiftKey: domEvt.shiftKey,\n\n\t\t\tget keystroke() {\n\t\t\t\treturn getCode( this );\n\t\t\t}\n\t\t} );\n\t}\n}\n\n/**\n * Fired when a key has been pressed.\n *\n * Introduced by {@link module:engine/view/observer/keyobserver~KeyObserver}.\n *\n * Note that because {@link module:engine/view/observer/keyobserver~KeyObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/keyobserver~KeyObserver\n * @event module:engine/view/document~Document#event:keydown\n * @param {module:engine/view/observer/keyobserver~KeyEventData} keyEventData\n */\n\n/**\n * Fired when a key has been released.\n *\n * Introduced by {@link module:engine/view/observer/keyobserver~KeyObserver}.\n *\n * Note that because {@link module:engine/view/observer/keyobserver~KeyObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/keyobserver~KeyObserver\n * @event module:engine/view/document~Document#event:keyup\n * @param {module:engine/view/observer/keyobserver~KeyEventData} keyEventData\n */\n\n/**\n * The value of both events - {@link module:engine/view/document~Document#event:keydown} and\n * {@link module:engine/view/document~Document#event:keyup}.\n *\n * @class module:engine/view/observer/keyobserver~KeyEventData\n * @extends module:engine/view/observer/domeventdata~DomEventData\n * @implements module:utils/keyboard~KeystrokeInfo\n */\n\n/**\n * Code of the whole keystroke. See {@link module:utils/keyboard~getCode}.\n *\n * @readonly\n * @member {Number} module:engine/view/observer/keyobserver~KeyEventData#keystroke\n */\n","import root from './_root.js';\n\n/**\n * Gets the timestamp of the number of milliseconds that have elapsed since\n * the Unix epoch (1 January 1970 00:00:00 UTC).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Date\n * @returns {number} Returns the timestamp.\n * @example\n *\n * _.defer(function(stamp) {\n * console.log(_.now() - stamp);\n * }, _.now());\n * // => Logs the number of milliseconds it took for the deferred invocation.\n */\nvar now = function() {\n return root.Date.now();\n};\n\nexport default now;\n","import baseGetTag from './_baseGetTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nexport default isSymbol;\n","import isObject from './isObject.js';\nimport isSymbol from './isSymbol.js';\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = value.replace(reTrim, '');\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nexport default toNumber;\n","import isObject from './isObject.js';\nimport now from './now.js';\nimport toNumber from './toNumber.js';\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max,\n nativeMin = Math.min;\n\n/**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked. The debounced function comes with a `cancel` method to cancel\n * delayed `func` invocations and a `flush` method to immediately invoke them.\n * Provide `options` to indicate whether `func` should be invoked on the\n * leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n * with the last arguments provided to the debounced function. Subsequent\n * calls to the debounced function return the result of the last `func`\n * invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the debounced function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.debounce` and `_.throttle`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n * Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n * The maximum time `func` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', _.debounce(sendMail, 300, {\n * 'leading': true,\n * 'trailing': false\n * }));\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n * var source = new EventSource('/stream');\n * jQuery(source).on('message', debounced);\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel);\n */\nfunction debounce(func, wait, options) {\n var lastArgs,\n lastThis,\n maxWait,\n result,\n timerId,\n lastCallTime,\n lastInvokeTime = 0,\n leading = false,\n maxing = false,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n wait = toNumber(wait) || 0;\n if (isObject(options)) {\n leading = !!options.leading;\n maxing = 'maxWait' in options;\n maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n\n function invokeFunc(time) {\n var args = lastArgs,\n thisArg = lastThis;\n\n lastArgs = lastThis = undefined;\n lastInvokeTime = time;\n result = func.apply(thisArg, args);\n return result;\n }\n\n function leadingEdge(time) {\n // Reset any `maxWait` timer.\n lastInvokeTime = time;\n // Start the timer for the trailing edge.\n timerId = setTimeout(timerExpired, wait);\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result;\n }\n\n function remainingWait(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime,\n timeWaiting = wait - timeSinceLastCall;\n\n return maxing\n ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)\n : timeWaiting;\n }\n\n function shouldInvoke(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the `maxWait` limit.\n return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||\n (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n }\n\n function timerExpired() {\n var time = now();\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // Restart the timer.\n timerId = setTimeout(timerExpired, remainingWait(time));\n }\n\n function trailingEdge(time) {\n timerId = undefined;\n\n // Only invoke if we have `lastArgs` which means `func` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time);\n }\n lastArgs = lastThis = undefined;\n return result;\n }\n\n function cancel() {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n lastInvokeTime = 0;\n lastArgs = lastCallTime = lastThis = timerId = undefined;\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(now());\n }\n\n function debounced() {\n var time = now(),\n isInvoking = shouldInvoke(time);\n\n lastArgs = arguments;\n lastThis = this;\n lastCallTime = time;\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime);\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n timerId = setTimeout(timerExpired, wait);\n return invokeFunc(lastCallTime);\n }\n }\n if (timerId === undefined) {\n timerId = setTimeout(timerExpired, wait);\n }\n return result;\n }\n debounced.cancel = cancel;\n debounced.flush = flush;\n return debounced;\n}\n\nexport default debounce;\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/fakeselectionobserver\n */\n\nimport Observer from './observer';\nimport ViewSelection from '../selection';\nimport { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';\nimport { debounce } from 'lodash-es';\n\n/**\n * Fake selection observer class. If view selection is fake it is placed in dummy DOM container. This observer listens\n * on {@link module:engine/view/document~Document#event:keydown keydown} events and handles moving fake view selection to the correct place\n * if arrow keys are pressed.\n * Fires {@link module:engine/view/document~Document#event:selectionChange selectionChange event} simulating natural behaviour of\n * {@link module:engine/view/observer/selectionobserver~SelectionObserver SelectionObserver}.\n *\n * @extends module:engine/view/observer/observer~Observer.Observer\n */\nexport default class FakeSelectionObserver extends Observer {\n\t/**\n\t * Creates new FakeSelectionObserver instance.\n\t *\n\t * @param {module:engine/view/view~View} view\n\t */\n\tconstructor( view ) {\n\t\tsuper( view );\n\n\t\t/**\n\t\t * Fires debounced event `selectionChangeDone`. It uses `lodash#debounce` method to delay function call.\n\t\t *\n\t\t * @private\n\t\t * @param {Object} data Selection change data.\n\t\t * @method #_fireSelectionChangeDoneDebounced\n\t\t */\n\t\tthis._fireSelectionChangeDoneDebounced = debounce( data => this.document.fire( 'selectionChangeDone', data ), 200 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tobserve() {\n\t\tconst document = this.document;\n\n\t\tdocument.on( 'keydown', ( eventInfo, data ) => {\n\t\t\tconst selection = document.selection;\n\n\t\t\tif ( selection.isFake && _isArrowKeyCode( data.keyCode ) && this.isEnabled ) {\n\t\t\t\t// Prevents default key down handling - no selection change will occur.\n\t\t\t\tdata.preventDefault();\n\n\t\t\t\tthis._handleSelectionMove( data.keyCode );\n\t\t\t}\n\t\t}, { priority: 'lowest' } );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tsuper.destroy();\n\n\t\tthis._fireSelectionChangeDoneDebounced.cancel();\n\t}\n\n\t/**\n\t * Handles collapsing view selection according to given key code. If left or up key is provided - new selection will be\n\t * collapsed to left. If right or down key is pressed - new selection will be collapsed to right.\n\t *\n\t * This method fires {@link module:engine/view/document~Document#event:selectionChange} and\n\t * {@link module:engine/view/document~Document#event:selectionChangeDone} events imitating behaviour of\n\t * {@link module:engine/view/observer/selectionobserver~SelectionObserver}.\n\t *\n\t * @private\n\t * @param {Number} keyCode\n\t * @fires module:engine/view/document~Document#event:selectionChange\n\t * @fires module:engine/view/document~Document#event:selectionChangeDone\n\t */\n\t_handleSelectionMove( keyCode ) {\n\t\tconst selection = this.document.selection;\n\t\tconst newSelection = new ViewSelection( selection.getRanges(), { backward: selection.isBackward, fake: false } );\n\n\t\t// Left or up arrow pressed - move selection to start.\n\t\tif ( keyCode == keyCodes.arrowleft || keyCode == keyCodes.arrowup ) {\n\t\t\tnewSelection.setTo( newSelection.getFirstPosition() );\n\t\t}\n\n\t\t// Right or down arrow pressed - move selection to end.\n\t\tif ( keyCode == keyCodes.arrowright || keyCode == keyCodes.arrowdown ) {\n\t\t\tnewSelection.setTo( newSelection.getLastPosition() );\n\t\t}\n\n\t\tconst data = {\n\t\t\toldSelection: selection,\n\t\t\tnewSelection,\n\t\t\tdomSelection: null\n\t\t};\n\n\t\t// Fire dummy selection change event.\n\t\tthis.document.fire( 'selectionChange', data );\n\n\t\t// Call` #_fireSelectionChangeDoneDebounced` every time when `selectionChange` event is fired.\n\t\t// This function is debounced what means that `selectionChangeDone` event will be fired only when\n\t\t// defined int the function time will elapse since the last time the function was called.\n\t\t// So `selectionChangeDone` will be fired when selection will stop changing.\n\t\tthis._fireSelectionChangeDoneDebounced( data );\n\t}\n}\n\n// Checks if one of the arrow keys is pressed.\n//\n// @private\n// @param {Number} keyCode\n// @returns {Boolean}\nfunction _isArrowKeyCode( keyCode ) {\n\treturn keyCode == keyCodes.arrowright ||\n\t\tkeyCode == keyCodes.arrowleft ||\n\t\tkeyCode == keyCodes.arrowup ||\n\t\tkeyCode == keyCodes.arrowdown;\n}\n\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/selectionobserver\n */\n\n/* global setInterval, clearInterval */\n\nimport Observer from './observer';\nimport MutationObserver from './mutationobserver';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\nimport { debounce } from 'lodash-es';\n\n/**\n * Selection observer class observes selection changes in the document. If selection changes on the document this\n * observer checks if there are any mutations and if DOM selection is different than the\n * {@link module:engine/view/document~Document#selection view selection}. Selection observer fires\n * {@link module:engine/view/document~Document#event:selectionChange} event only if selection change was the only change in the document\n * and DOM selection is different then the view selection.\n *\n * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.\n *\n * @see module:engine/view/observer/mutationobserver~MutationObserver\n * @extends module:engine/view/observer/observer~Observer\n */\nexport default class SelectionObserver extends Observer {\n\tconstructor( view ) {\n\t\tsuper( view );\n\n\t\t/**\n\t\t * Instance of the mutation observer. Selection observer calls\n\t\t * {@link module:engine/view/observer/mutationobserver~MutationObserver#flush} to ensure that the mutations will be handled\n\t\t * before the {@link module:engine/view/document~Document#event:selectionChange} event is fired.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/observer/mutationobserver~MutationObserver}\n\t\t * module:engine/view/observer/selectionobserver~SelectionObserver#mutationObserver\n\t\t */\n\t\tthis.mutationObserver = view.getObserver( MutationObserver );\n\n\t\t/**\n\t\t * Reference to the view {@link module:engine/view/documentselection~DocumentSelection} object used to compare\n\t\t * new selection with it.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/documentselection~DocumentSelection}\n\t\t * module:engine/view/observer/selectionobserver~SelectionObserver#selection\n\t\t */\n\t\tthis.selection = this.document.selection;\n\n\t\t/* eslint-disable max-len */\n\t\t/**\n\t\t * Reference to the {@link module:engine/view/view~View#domConverter}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/domconverter~DomConverter} module:engine/view/observer/selectionobserver~SelectionObserver#domConverter\n\t\t */\n\t\t/* eslint-enable max-len */\n\t\tthis.domConverter = view.domConverter;\n\n\t\t/**\n\t\t * Set of documents which have added \"selectionchange\" listener to avoid adding listener twice to the same\n\t\t * document.\n\t\t *\n\t\t * @private\n\t\t * @member {WeakSet.<Document>} module:engine/view/observer/selectionobserver~SelectionObserver#_documents\n\t\t */\n\t\tthis._documents = new WeakSet();\n\n\t\t/**\n\t\t * Fires debounced event `selectionChangeDone`. It uses `lodash#debounce` method to delay function call.\n\t\t *\n\t\t * @private\n\t\t * @param {Object} data Selection change data.\n\t\t * @method #_fireSelectionChangeDoneDebounced\n\t\t */\n\t\tthis._fireSelectionChangeDoneDebounced = debounce( data => this.document.fire( 'selectionChangeDone', data ), 200 );\n\n\t\tthis._clearInfiniteLoopInterval = setInterval( () => this._clearInfiniteLoop(), 1000 );\n\n\t\t/**\n\t\t * Private property to check if the code does not enter infinite loop.\n\t\t *\n\t\t * @private\n\t\t * @member {Number} module:engine/view/observer/selectionobserver~SelectionObserver#_loopbackCounter\n\t\t */\n\t\tthis._loopbackCounter = 0;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tobserve( domElement ) {\n\t\tconst domDocument = domElement.ownerDocument;\n\n\t\t// Add listener once per each document.\n\t\tif ( this._documents.has( domDocument ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.listenTo( domDocument, 'selectionchange', () => {\n\t\t\tthis._handleSelectionChange( domDocument );\n\t\t} );\n\n\t\tthis._documents.add( domDocument );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tsuper.destroy();\n\n\t\tclearInterval( this._clearInfiniteLoopInterval );\n\t\tthis._fireSelectionChangeDoneDebounced.cancel();\n\t}\n\n\t/**\n\t * Selection change listener. {@link module:engine/view/observer/mutationobserver~MutationObserver#flush Flush} mutations, check if\n\t * selection changes and fires {@link module:engine/view/document~Document#event:selectionChange} event on every change\n\t * and {@link module:engine/view/document~Document#event:selectionChangeDone} when selection stop changing.\n\t *\n\t * @private\n\t * @param {Document} domDocument DOM document.\n\t */\n\t_handleSelectionChange( domDocument ) {\n\t\t// Selection is handled when document is not focused but is read-only. This is because in read-only\n\t\t// mode contenteditable is set as false and editor won't receive focus but we still need to know\n\t\t// selection position.\n\t\tif ( !this.isEnabled || ( !this.document.isFocused && !this.document.isReadOnly ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Ensure the mutation event will be before selection event on all browsers.\n\t\tthis.mutationObserver.flush();\n\n\t\t// If there were mutations then the view will be re-rendered by the mutation observer and selection\n\t\t// will be updated, so selections will equal and event will not be fired, as expected.\n\t\tconst domSelection = domDocument.defaultView.getSelection();\n\t\tconst newViewSelection = this.domConverter.domSelectionToView( domSelection );\n\n\t\tif ( this.selection.isEqual( newViewSelection ) && this.domConverter.isDomSelectionCorrect( domSelection ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Ensure we are not in the infinite loop (#400).\n\t\t// This counter is reset each second. 60 selection changes in 1 second is enough high number\n\t\t// to be very difficult (impossible) to achieve using just keyboard keys (during normal editor use).\n\t\tif ( ++this._loopbackCounter > 60 ) {\n\t\t\t/**\n\t\t\t * Selection change observer detected an infinite rendering loop.\n\t\t\t * Most probably you try to put the selection in the position which is not allowed\n\t\t\t * by the browser and browser fixes it automatically what causes `selectionchange` event on\n\t\t\t * which a loopback through a model tries to re-render the wrong selection and again.\n\t\t\t *\n\t\t\t * @error selectionchange-infinite-loop\n\t\t\t */\n\t\t\tlog.warn( 'selectionchange-infinite-loop: Selection change observer detected an infinite rendering loop.' );\n\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this.selection.isSimilar( newViewSelection ) ) {\n\t\t\t// If selection was equal and we are at this point of algorithm, it means that it was incorrect.\n\t\t\t// Just re-render it, no need to fire any events, etc.\n\t\t\tthis.view.forceRender();\n\t\t} else {\n\t\t\tconst data = {\n\t\t\t\toldSelection: this.selection,\n\t\t\t\tnewSelection: newViewSelection,\n\t\t\t\tdomSelection\n\t\t\t};\n\n\t\t\t// Prepare data for new selection and fire appropriate events.\n\t\t\tthis.document.fire( 'selectionChange', data );\n\n\t\t\t// Call` #_fireSelectionChangeDoneDebounced` every time when `selectionChange` event is fired.\n\t\t\t// This function is debounced what means that `selectionChangeDone` event will be fired only when\n\t\t\t// defined int the function time will elapse since the last time the function was called.\n\t\t\t// So `selectionChangeDone` will be fired when selection will stop changing.\n\t\t\tthis._fireSelectionChangeDoneDebounced( data );\n\t\t}\n\t}\n\n\t/**\n\t * Clears `SelectionObserver` internal properties connected with preventing infinite loop.\n\t *\n\t * @protected\n\t */\n\t_clearInfiniteLoop() {\n\t\tthis._loopbackCounter = 0;\n\t}\n}\n\n/**\n * Fired when selection has changed. This event is fired only when the selection change was the only change that happened\n * in the document, and old selection is different then the new selection.\n *\n * Introduced by {@link module:engine/view/observer/selectionobserver~SelectionObserver}.\n *\n * Note that because {@link module:engine/view/observer/selectionobserver~SelectionObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/selectionobserver~SelectionObserver\n * @event module:engine/view/document~Document#event:selectionChange\n * @param {Object} data\n * @param {module:engine/view/documentselection~DocumentSelection} data.oldSelection Old View selection which is\n * {@link module:engine/view/document~Document#selection}.\n * @param {module:engine/view/selection~Selection} data.newSelection New View selection which is converted DOM selection.\n * @param {Selection} data.domSelection Native DOM selection.\n */\n\n/**\n * Fired when selection stops changing.\n *\n * Introduced by {@link module:engine/view/observer/selectionobserver~SelectionObserver}.\n *\n * Note that because {@link module:engine/view/observer/selectionobserver~SelectionObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/selectionobserver~SelectionObserver\n * @event module:engine/view/document~Document#event:selectionChangeDone\n * @param {Object} data\n * @param {module:engine/view/documentselection~DocumentSelection} data.oldSelection Old View selection which is\n * {@link module:engine/view/document~Document#selection}.\n * @param {module:engine/view/selection~Selection} data.newSelection New View selection which is converted DOM selection.\n * @param {Selection} data.domSelection Native DOM selection.\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/focusobserver\n */\n\n/* globals setTimeout, clearTimeout */\n\nimport DomEventObserver from './domeventobserver';\n\n/**\n * {@link module:engine/view/document~Document#event:focus Focus}\n * and {@link module:engine/view/document~Document#event:blur blur} events observer.\n * Focus observer handle also {@link module:engine/view/rooteditableelement~RootEditableElement#isFocused isFocused} property of the\n * {@link module:engine/view/rooteditableelement~RootEditableElement root elements}.\n *\n * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.\n *\n * @extends module:engine/view/observer/domeventobserver~DomEventObserver\n */\nexport default class FocusObserver extends DomEventObserver {\n\tconstructor( view ) {\n\t\tsuper( view );\n\n\t\tthis.domEventType = [ 'focus', 'blur' ];\n\t\tthis.useCapture = true;\n\t\tconst document = this.document;\n\n\t\tdocument.on( 'focus', () => {\n\t\t\tdocument.isFocused = true;\n\n\t\t\t// Unfortunately native `selectionchange` event is fired asynchronously.\n\t\t\t// We need to wait until `SelectionObserver` handle the event and then render. Otherwise rendering will\n\t\t\t// overwrite new DOM selection with selection from the view.\n\t\t\t// See https://github.com/ckeditor/ckeditor5-engine/issues/795 for more details.\n\t\t\t// Long timeout is needed to solve #676 and https://github.com/ckeditor/ckeditor5-engine/issues/1157 issues.\n\t\t\tthis._renderTimeoutId = setTimeout( () => view.forceRender(), 50 );\n\t\t} );\n\n\t\tdocument.on( 'blur', ( evt, data ) => {\n\t\t\tconst selectedEditable = document.selection.editableElement;\n\n\t\t\tif ( selectedEditable === null || selectedEditable === data.target ) {\n\t\t\t\tdocument.isFocused = false;\n\n\t\t\t\t// Re-render the document to update view elements.\n\t\t\t\tview.forceRender();\n\t\t\t}\n\t\t} );\n\n\t\t/**\n\t\t * Identifier of the timeout currently used by focus listener to delay rendering execution.\n\t\t *\n\t\t * @private\n\t\t * @member {Number} #_renderTimeoutId\n\t\t */\n\t}\n\n\tonDomEvent( domEvent ) {\n\t\tthis.fire( domEvent.type, domEvent );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tif ( this._renderTimeoutId ) {\n\t\t\tclearTimeout( this._renderTimeoutId );\n\t\t}\n\n\t\tsuper.destroy();\n\t}\n}\n\n/**\n * Fired when one of the editables gets focus.\n *\n * Introduced by {@link module:engine/view/observer/focusobserver~FocusObserver}.\n *\n * Note that because {@link module:engine/view/observer/focusobserver~FocusObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/focusobserver~FocusObserver\n * @event module:engine/view/document~Document#event:focus\n * @param {module:engine/view/observer/domeventdata~DomEventData} data Event data.\n */\n\n/**\n * Fired when one of the editables loses focus.\n *\n * Introduced by {@link module:engine/view/observer/focusobserver~FocusObserver}.\n *\n * Note that because {@link module:engine/view/observer/focusobserver~FocusObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/focusobserver~FocusObserver\n * @event module:engine/view/document~Document#event:blur\n * @param {module:engine/view/observer/domeventdata~DomEventData} data Event data.\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/compositionobserver\n */\n\nimport DomEventObserver from './domeventobserver';\n\n/**\n * {@link module:engine/view/document~Document#event:compositionstart Compositionstart},\n * {@link module:engine/view/document~Document#event:compositionupdate compositionupdate} and\n * {@link module:engine/view/document~Document#event:compositionend compositionend} events observer.\n *\n * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.\n *\n * @extends module:engine/view/observer/domeventobserver~DomEventObserver\n */\nexport default class CompositionObserver extends DomEventObserver {\n\tconstructor( view ) {\n\t\tsuper( view );\n\n\t\tthis.domEventType = [ 'compositionstart', 'compositionupdate', 'compositionend' ];\n\t\tconst document = this.document;\n\n\t\tdocument.on( 'compositionstart', () => {\n\t\t\tdocument.isComposing = true;\n\t\t} );\n\n\t\tdocument.on( 'compositionend', () => {\n\t\t\tdocument.isComposing = false;\n\t\t} );\n\t}\n\n\tonDomEvent( domEvent ) {\n\t\tthis.fire( domEvent.type, domEvent );\n\t}\n}\n\n/**\n * Fired when composition starts inside one of the editables.\n *\n * Introduced by {@link module:engine/view/observer/compositionobserver~CompositionObserver}.\n *\n * Note that because {@link module:engine/view/observer/compositionobserver~CompositionObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/compositionobserver~CompositionObserver\n * @event module:engine/view/document~Document#event:compositionstart\n * @param {module:engine/view/observer/domeventdata~DomEventData} data Event data.\n */\n\n/**\n * Fired when composition is updated inside one of the editables.\n *\n * Introduced by {@link module:engine/view/observer/compositionobserver~CompositionObserver}.\n *\n * Note that because {@link module:engine/view/observer/compositionobserver~CompositionObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/compositionobserver~CompositionObserver\n * @event module:engine/view/document~Document#event:compositionupdate\n * @param {module:engine/view/observer/domeventdata~DomEventData} data Event data.\n */\n\n/**\n * Fired when composition ends inside one of the editables.\n *\n * Introduced by {@link module:engine/view/observer/compositionobserver~CompositionObserver}.\n *\n * Note that because {@link module:engine/view/observer/compositionobserver~CompositionObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/compositionobserver~CompositionObserver\n * @event module:engine/view/document~Document#event:compositionend\n * @param {module:engine/view/observer/domeventdata~DomEventData} data Event data.\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/isrange\n */\n\n/**\n * Checks if the object is a native DOM Range.\n *\n * @param {*} obj\n * @returns {Boolean}\n */\nexport default function isRange( obj ) {\n\treturn Object.prototype.toString.apply( obj ) == '[object Range]';\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/getborderwidths\n */\n\n/**\n * Returns an object containing CSS border widths of a specified HTML element.\n *\n * @param {HTMLElement} element An element which has CSS borders.\n * @returns {Object} An object containing `top`, `left`, `right` and `bottom` properties\n * with numerical values of the `border-[top,left,right,bottom]-width` CSS styles.\n */\nexport default function getBorderWidths( element ) {\n\t// Call getComputedStyle on the window the element document belongs to.\n\tconst style = element.ownerDocument.defaultView.getComputedStyle( element );\n\n\treturn {\n\t\ttop: parseInt( style.borderTopWidth, 10 ),\n\t\tright: parseInt( style.borderRightWidth, 10 ),\n\t\tbottom: parseInt( style.borderBottomWidth, 10 ),\n\t\tleft: parseInt( style.borderLeftWidth, 10 )\n\t};\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/rect\n */\n\nimport isRange from './isrange';\nimport isWindow from './iswindow';\nimport getBorderWidths from './getborderwidths';\nimport log from '../log';\nimport isText from './istext';\nimport { isElement } from 'lodash-es';\n\nconst rectProperties = [ 'top', 'right', 'bottom', 'left', 'width', 'height' ];\n\n/**\n * A helper class representing a `ClientRect` object, e.g. value returned by\n * the native `object.getBoundingClientRect()` method. Provides a set of methods\n * to manipulate the rect and compare it against other rect instances.\n */\nexport default class Rect {\n\t/**\n\t * Creates an instance of rect.\n\t *\n\t *\t\t// Rect of an HTMLElement.\n\t *\t\tconst rectA = new Rect( document.body );\n\t *\n\t *\t\t// Rect of a DOM Range.\n\t *\t\tconst rectB = new Rect( document.getSelection().getRangeAt( 0 ) );\n\t *\n\t *\t\t// Rect of a window (web browser viewport).\n\t *\t\tconst rectC = new Rect( window );\n\t *\n\t *\t\t// Rect out of an object.\n\t *\t\tconst rectD = new Rect( { top: 0, right: 10, bottom: 10, left: 0, width: 10, height: 10 } );\n\t *\n\t *\t\t// Rect out of another Rect instance.\n\t *\t\tconst rectE = new Rect( rectD );\n\t *\n\t *\t\t// Rect out of a ClientRect.\n\t *\t\tconst rectF = new Rect( document.body.getClientRects().item( 0 ) );\n\t *\n\t * **Note**: By default a rect of an HTML element includes its CSS borders and scrollbars (if any)\n\t * ant the rect of a `window` includes scrollbars too. Use {@link #excludeScrollbarsAndBorders}\n\t * to get the inner part of the rect.\n\t *\n\t * @param {HTMLElement|Range|Window|ClientRect|module:utils/dom/rect~Rect|Object} source A source object to create the rect.\n\t */\n\tconstructor( source ) {\n\t\tconst isSourceRange = isRange( source );\n\n\t\t/**\n\t\t * The object this rect is for.\n\t\t *\n\t\t * @protected\n\t\t * @readonly\n\t\t * @member {HTMLElement|Range|ClientRect|module:utils/dom/rect~Rect|Object} #_source\n\t\t */\n\t\tObject.defineProperty( this, '_source', {\n\t\t\t// If the source is a Rect instance, copy it's #_source.\n\t\t\tvalue: source._source || source,\n\t\t\twritable: true,\n\t\t\tenumerable: false\n\t\t} );\n\n\t\tif ( isElement( source ) || isSourceRange ) {\n\t\t\tconst sourceNode = isSourceRange ? source.startContainer : source;\n\n\t\t\tif ( !sourceNode.ownerDocument || !sourceNode.ownerDocument.body.contains( sourceNode ) ) {\n\t\t\t\t/**\n\t\t\t\t * The `Rect` class depends on `getBoundingClientRect` and `getClientRects` DOM methods.\n\t\t\t\t * If the {@link #constructor source} of a rect in an HTML element or a DOM range but it does\n\t\t\t\t * not belong to any rendered DOM tree, these methods will fail to obtain the geometry and\n\t\t\t\t * the rect instance makes little sense to the features using it.\n\t\t\t\t *\n\t\t\t\t * To get rid of this warning make sure the source passed to the constructor\n\t\t\t\t * is a descendant of `window.document.body`.\n\t\t\t\t *\n\t\t\t\t * @error rect-source-not-in-dom\n\t\t\t\t * @param {String} source The source of the Rect instance.\n\t\t\t\t */\n\t\t\t\tlog.warn(\n\t\t\t\t\t'rect-source-not-in-dom: The source of this rect does not belong to any rendered DOM tree.',\n\t\t\t\t\t{ source }\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif ( isSourceRange ) {\n\t\t\t\tcopyRectProperties( this, Rect.getDomRangeRects( source )[ 0 ] );\n\t\t\t} else {\n\t\t\t\tcopyRectProperties( this, source.getBoundingClientRect() );\n\t\t\t}\n\t\t} else if ( isWindow( source ) ) {\n\t\t\tconst { innerWidth, innerHeight } = source;\n\n\t\t\tcopyRectProperties( this, {\n\t\t\t\ttop: 0,\n\t\t\t\tright: innerWidth,\n\t\t\t\tbottom: innerHeight,\n\t\t\t\tleft: 0,\n\t\t\t\twidth: innerWidth,\n\t\t\t\theight: innerHeight\n\t\t\t} );\n\t\t} else {\n\t\t\tcopyRectProperties( this, source );\n\t\t}\n\n\t\t/**\n\t\t * The \"top\" value of the rect.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} #top\n\t\t */\n\n\t\t/**\n\t\t * The \"right\" value of the rect.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} #right\n\t\t */\n\n\t\t/**\n\t\t * The \"bottom\" value of the rect.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} #bottom\n\t\t */\n\n\t\t/**\n\t\t * The \"left\" value of the rect.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} #left\n\t\t */\n\n\t\t/**\n\t\t * The \"width\" value of the rect.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} #width\n\t\t */\n\n\t\t/**\n\t\t * The \"height\" value of the rect.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} #height\n\t\t */\n\t}\n\n\t/**\n\t * Returns a clone of the rect.\n\t *\n\t * @returns {module:utils/dom/rect~Rect} A cloned rect.\n\t */\n\tclone() {\n\t\treturn new Rect( this );\n\t}\n\n\t/**\n\t * Moves the rect so that its upper–left corner lands in desired `[ x, y ]` location.\n\t *\n\t * @param {Number} x Desired horizontal location.\n\t * @param {Number} y Desired vertical location.\n\t * @returns {module:utils/dom/rect~Rect} A rect which has been moved.\n\t */\n\tmoveTo( x, y ) {\n\t\tthis.top = y;\n\t\tthis.right = x + this.width;\n\t\tthis.bottom = y + this.height;\n\t\tthis.left = x;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Moves the rect in–place by a dedicated offset.\n\t *\n\t * @param {Number} x A horizontal offset.\n\t * @param {Number} y A vertical offset\n\t * @returns {module:utils/dom/rect~Rect} A rect which has been moved.\n\t */\n\tmoveBy( x, y ) {\n\t\tthis.top += y;\n\t\tthis.right += x;\n\t\tthis.left += x;\n\t\tthis.bottom += y;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns a new rect a a result of intersection with another rect.\n\t *\n\t * @param {module:utils/dom/rect~Rect} anotherRect\n\t * @returns {module:utils/dom/rect~Rect}\n\t */\n\tgetIntersection( anotherRect ) {\n\t\tconst rect = {\n\t\t\ttop: Math.max( this.top, anotherRect.top ),\n\t\t\tright: Math.min( this.right, anotherRect.right ),\n\t\t\tbottom: Math.min( this.bottom, anotherRect.bottom ),\n\t\t\tleft: Math.max( this.left, anotherRect.left )\n\t\t};\n\n\t\trect.width = rect.right - rect.left;\n\t\trect.height = rect.bottom - rect.top;\n\n\t\tif ( rect.width < 0 || rect.height < 0 ) {\n\t\t\treturn null;\n\t\t} else {\n\t\t\treturn new Rect( rect );\n\t\t}\n\t}\n\n\t/**\n\t * Returns the area of intersection with another rect.\n\t *\n\t * @param {module:utils/dom/rect~Rect} anotherRect [description]\n\t * @returns {Number} Area of intersection.\n\t */\n\tgetIntersectionArea( anotherRect ) {\n\t\tconst rect = this.getIntersection( anotherRect );\n\n\t\tif ( rect ) {\n\t\t\treturn rect.getArea();\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/**\n\t * Returns the area of the rect.\n\t *\n\t * @returns {Number}\n\t */\n\tgetArea() {\n\t\treturn this.width * this.height;\n\t}\n\n\t/**\n\t * Returns a new rect, a part of the original rect, which is actually visible to the user,\n\t * e.g. an original rect cropped by parent element rects which have `overflow` set in CSS\n\t * other than `\"visible\"`.\n\t *\n\t * If there's no such visible rect, which is when the rect is limited by one or many of\n\t * the ancestors, `null` is returned.\n\t *\n\t * @returns {module:utils/dom/rect~Rect|null} A visible rect instance or `null`, if there's none.\n\t */\n\tgetVisible() {\n\t\tconst source = this._source;\n\t\tlet visibleRect = this.clone();\n\n\t\t// There's no ancestor to crop <body> with the overflow.\n\t\tif ( !isBody( source ) ) {\n\t\t\tlet parent = source.parentNode || source.commonAncestorContainer;\n\n\t\t\t// Check the ancestors all the way up to the <body>.\n\t\t\twhile ( parent && !isBody( parent ) ) {\n\t\t\t\tconst parentRect = new Rect( parent );\n\t\t\t\tconst intersectionRect = visibleRect.getIntersection( parentRect );\n\n\t\t\t\tif ( intersectionRect ) {\n\t\t\t\t\tif ( intersectionRect.getArea() < visibleRect.getArea() ) {\n\t\t\t\t\t\t// Reduce the visible rect to the intersection.\n\t\t\t\t\t\tvisibleRect = intersectionRect;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// There's no intersection, the rect is completely invisible.\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tparent = parent.parentNode;\n\t\t\t}\n\t\t}\n\n\t\treturn visibleRect;\n\t}\n\n\t/**\n\t * Checks if all property values ({@link #top}, {@link #left}, {@link #right},\n\t * {@link #bottom}, {@link #width} and {@link #height}) are the equal in both rect\n\t * instances.\n\t *\n\t * @param {module:utils/dom/rect~Rect} rect A rect instance to compare with.\n\t * @returns {Boolean} `true` when Rects are equal. `false` otherwise.\n\t */\n\tisEqual( anotherRect ) {\n\t\tfor ( const prop of rectProperties ) {\n\t\t\tif ( this[ prop ] !== anotherRect[ prop ] ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Checks whether a rect fully contains another rect instance.\n\t *\n\t * @param {module:utils/dom/rect~Rect} anotherRect\n\t * @returns {Boolean} `true` if contains, `false` otherwise.\n\t */\n\tcontains( anotherRect ) {\n\t\tconst intersectRect = this.getIntersection( anotherRect );\n\n\t\treturn !!( intersectRect && intersectRect.isEqual( anotherRect ) );\n\t}\n\n\t/**\n\t * Excludes scrollbars and CSS borders from the rect.\n\t *\n\t * * Borders are removed when {@link #_source} is an HTML element.\n\t * * Scrollbars are excluded from HTML elements and the `window`.\n\t *\n\t * @returns {module:utils/dom/rect~Rect} A rect which has been updated.\n\t */\n\texcludeScrollbarsAndBorders() {\n\t\tconst source = this._source;\n\t\tlet scrollBarWidth, scrollBarHeight;\n\n\t\tif ( isWindow( source ) ) {\n\t\t\tscrollBarWidth = source.innerWidth - source.document.documentElement.clientWidth;\n\t\t\tscrollBarHeight = source.innerHeight - source.document.documentElement.clientHeight;\n\t\t} else {\n\t\t\tconst borderWidths = getBorderWidths( this._source );\n\n\t\t\tscrollBarWidth = source.offsetWidth - source.clientWidth;\n\t\t\tscrollBarHeight = source.offsetHeight - source.clientHeight;\n\n\t\t\tthis.moveBy( borderWidths.left, borderWidths.top );\n\t\t}\n\n\t\t// Assuming LTR scrollbars. TODO: RTL.\n\t\tthis.width -= scrollBarWidth;\n\t\tthis.right -= scrollBarWidth;\n\n\t\tthis.height -= scrollBarHeight;\n\t\tthis.bottom -= scrollBarHeight;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns an array of rects of the given native DOM Range.\n\t *\n\t * @param {Range} range A native DOM range.\n\t * @returns {Array.<module:utils/dom/rect~Rect>} DOM Range rects.\n\t */\n\tstatic getDomRangeRects( range ) {\n\t\tconst rects = [];\n\t\t// Safari does not iterate over ClientRectList using for...of loop.\n\t\tconst clientRects = Array.from( range.getClientRects() );\n\n\t\tif ( clientRects.length ) {\n\t\t\tfor ( const rect of clientRects ) {\n\t\t\t\trects.push( new Rect( rect ) );\n\t\t\t}\n\t\t}\n\t\t// If there's no client rects for the Range, use parent container's bounding rect\n\t\t// instead and adjust rect's width to simulate the actual geometry of such range.\n\t\t// https://github.com/ckeditor/ckeditor5-utils/issues/153\n\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/317\n\t\telse {\n\t\t\tlet startContainer = range.startContainer;\n\n\t\t\tif ( isText( startContainer ) ) {\n\t\t\t\tstartContainer = startContainer.parentNode;\n\t\t\t}\n\n\t\t\tconst rect = new Rect( startContainer.getBoundingClientRect() );\n\t\t\trect.right = rect.left;\n\t\t\trect.width = 0;\n\n\t\t\trects.push( rect );\n\t\t}\n\n\t\treturn rects;\n\t}\n}\n\n// Acquires all the rect properties from the passed source.\n//\n// @private\n// @param {module:utils/dom/rect~Rect} rect\n// @param {ClientRect|module:utils/dom/rect~Rect|Object} source\nfunction copyRectProperties( rect, source ) {\n\tfor ( const p of rectProperties ) {\n\t\trect[ p ] = source[ p ];\n\t}\n}\n\n// Checks if provided object is a <body> HTML element.\n//\n// @private\n// @param {HTMLElement|Range} elementOrRange\n// @returns {Boolean}\nfunction isBody( elementOrRange ) {\n\tif ( !isElement( elementOrRange ) ) {\n\t\treturn false;\n\t}\n\n\treturn elementOrRange === elementOrRange.ownerDocument.body;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/scroll\n */\n\nimport isRange from './isrange';\nimport Rect from './rect';\nimport isText from './istext';\n\nconst utils = {};\n\n/**\n * Makes any page `HTMLElement` or `Range` (`target`) visible inside the browser viewport.\n * This helper will scroll all `target` ancestors and the web browser viewport to reveal the target to\n * the user. If the `target` is already visible, nothing will happen.\n *\n * @param {HTMLElement|Range} options.target A target, which supposed to become visible to the user.\n * @param {Number} [options.viewportOffset] An offset from the edge of the viewport (in pixels)\n * the `target` will be moved by when the viewport is scrolled. It enhances the user experience\n * by keeping the `target` some distance from the edge of the viewport and thus making it easier to\n * read or edit by the user.\n */\nexport function scrollViewportToShowTarget( { target, viewportOffset = 0 } ) {\n\tconst targetWindow = getWindow( target );\n\tlet currentWindow = targetWindow;\n\tlet currentFrame = null;\n\n\t// Iterate over all windows, starting from target's parent window up to window#top.\n\twhile ( currentWindow ) {\n\t\tlet firstAncestorToScroll;\n\n\t\t// Let's scroll target's ancestors first to reveal it. Then, once the ancestor scrolls\n\t\t// settled down, the algorithm can eventually scroll the viewport of the current window.\n\t\t//\n\t\t// Note: If the current window is target's **original** window (e.g. the first one),\n\t\t// start scrolling the closest parent of the target. If not, scroll the closest parent\n\t\t// of an iframe that resides in the current window.\n\t\tif ( currentWindow == targetWindow ) {\n\t\t\tfirstAncestorToScroll = getParentElement( target );\n\t\t} else {\n\t\t\tfirstAncestorToScroll = getParentElement( currentFrame );\n\t\t}\n\n\t\t// Scroll the target's ancestors first. Once done, scrolling the viewport is easy.\n\t\tscrollAncestorsToShowRect( firstAncestorToScroll, () => {\n\t\t\t// Note: If the target does not belong to the current window **directly**,\n\t\t\t// i.e. it resides in an iframe belonging to the window, obtain the target's rect\n\t\t\t// in the coordinates of the current window. By default, a Rect returns geometry\n\t\t\t// relative to the current window's viewport. To make it work in a parent window,\n\t\t\t// it must be shifted.\n\t\t\treturn getRectRelativeToWindow( target, currentWindow );\n\t\t} );\n\n\t\t// Obtain the rect of the target after it has been scrolled within its ancestors.\n\t\t// It's time to scroll the viewport.\n\t\tconst targetRect = getRectRelativeToWindow( target, currentWindow );\n\n\t\tscrollWindowToShowRect( currentWindow, targetRect, viewportOffset );\n\n\t\tif ( currentWindow.parent != currentWindow ) {\n\t\t\t// Keep the reference to the <iframe> element the \"previous current window\" was\n\t\t\t// rendered within. It will be useful to re–calculate the rect of the target\n\t\t\t// in the parent window's relative geometry. The target's rect must be shifted\n\t\t\t// by it's iframe's position.\n\t\t\tcurrentFrame = currentWindow.frameElement;\n\t\t\tcurrentWindow = currentWindow.parent;\n\n\t\t\t// If the current window has some parent but frameElement is inaccessible, then they have\n\t\t\t// different domains/ports and, due to security reasons, accessing and scrolling\n\t\t\t// the parent window won't be possible.\n\t\t\t// See https://github.com/ckeditor/ckeditor5/issues/930.\n\t\t\tif ( !currentFrame ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tcurrentWindow = null;\n\t\t}\n\t}\n}\n\n/**\n * Makes any page `HTMLElement` or `Range` (target) visible within its scrollable ancestors,\n * e.g. if they have `overflow: scroll` CSS style.\n *\n * @param {HTMLElement|Range} target A target, which supposed to become visible to the user.\n */\nexport function scrollAncestorsToShowTarget( target ) {\n\tconst targetParent = getParentElement( target );\n\n\tscrollAncestorsToShowRect( targetParent, () => {\n\t\treturn new Rect( target );\n\t} );\n}\n\n// TODO: Using a property value shorthand in the top of the file\n// causes JSDoc to throw errors. See https://github.com/cksource/docs-builder/issues/75.\nObject.assign( utils, {\n\tscrollViewportToShowTarget,\n\tscrollAncestorsToShowTarget\n} );\n\n// Makes a given rect visible within its parent window.\n//\n// Note: Avoid the situation where the caret is still in the viewport, but totally\n// at the edge of it. In such situation, if it moved beyond the viewport in the next\n// action e.g. after paste, the scrolling would move it to the viewportOffset level\n// and it all would look like the caret visually moved up/down:\n//\n// 1.\n//\t\t| foo[]\n//\t\t| <--- N px of space below the caret\n//\t\t+---------------------------------...\n//\n// 2. *paste*\n// 3.\n//\t\t|\n//\t\t|\n//\t\t+-foo-----------------------------...\n//\t\t bar[] <--- caret below viewport, scrolling...\n//\n// 4. *scrolling*\n// 5.\n//\t\t|\n//\t\t| foo\n//\t\t| bar[] <--- caret precisely at the edge\n//\t\t+---------------------------------...\n//\n// To prevent this, this method checks the rects moved by the viewportOffset to cover\n// the upper/lower edge of the viewport. It makes sure if the action repeats, there's\n// no twitching – it's a purely visual improvement:\n//\n// 5. (after fix)\n//\t\t|\n//\t\t| foo\n//\t\t| bar[]\n//\t\t| <--- N px of space below the caret\n//\t\t+---------------------------------...\n//\n// @private\n// @param {Window} window A window which is scrolled to reveal the rect.\n// @param {module:utils/dom/rect~Rect} rect A rect which is to be revealed.\n// @param {Number} viewportOffset See scrollViewportToShowTarget.\nfunction scrollWindowToShowRect( window, rect, viewportOffset ) {\n\tconst targetShiftedDownRect = rect.clone().moveBy( 0, viewportOffset );\n\tconst targetShiftedUpRect = rect.clone().moveBy( 0, -viewportOffset );\n\tconst viewportRect = new Rect( window ).excludeScrollbarsAndBorders();\n\n\tconst rects = [ targetShiftedUpRect, targetShiftedDownRect ];\n\n\tif ( !rects.every( rect => viewportRect.contains( rect ) ) ) {\n\t\tlet { scrollX, scrollY } = window;\n\n\t\tif ( isAbove( targetShiftedUpRect, viewportRect ) ) {\n\t\t\tscrollY -= viewportRect.top - rect.top + viewportOffset;\n\t\t} else if ( isBelow( targetShiftedDownRect, viewportRect ) ) {\n\t\t\tscrollY += rect.bottom - viewportRect.bottom + viewportOffset;\n\t\t}\n\n\t\t// TODO: Web browsers scroll natively to place the target in the middle\n\t\t// of the viewport. It's not a very popular case, though.\n\t\tif ( isLeftOf( rect, viewportRect ) ) {\n\t\t\tscrollX -= viewportRect.left - rect.left + viewportOffset;\n\t\t} else if ( isRightOf( rect, viewportRect ) ) {\n\t\t\tscrollX += rect.right - viewportRect.right + viewportOffset;\n\t\t}\n\n\t\twindow.scrollTo( scrollX, scrollY );\n\t}\n}\n\n// Recursively scrolls element ancestors to visually reveal a rect.\n//\n// @private\n// @param {HTMLElement} A parent The first ancestors to start scrolling.\n// @param {Function} getRect A function which returns the Rect, which is to be revealed.\nfunction scrollAncestorsToShowRect( parent, getRect ) {\n\tconst parentWindow = getWindow( parent );\n\tlet parentRect, targetRect;\n\n\twhile ( parent != parentWindow.document.body ) {\n\t\ttargetRect = getRect();\n\t\tparentRect = new Rect( parent ).excludeScrollbarsAndBorders();\n\n\t\tif ( !parentRect.contains( targetRect ) ) {\n\t\t\tif ( isAbove( targetRect, parentRect ) ) {\n\t\t\t\tparent.scrollTop -= parentRect.top - targetRect.top;\n\t\t\t} else if ( isBelow( targetRect, parentRect ) ) {\n\t\t\t\tparent.scrollTop += targetRect.bottom - parentRect.bottom;\n\t\t\t}\n\n\t\t\tif ( isLeftOf( targetRect, parentRect ) ) {\n\t\t\t\tparent.scrollLeft -= parentRect.left - targetRect.left;\n\t\t\t} else if ( isRightOf( targetRect, parentRect ) ) {\n\t\t\t\tparent.scrollLeft += targetRect.right - parentRect.right;\n\t\t\t}\n\t\t}\n\n\t\tparent = parent.parentNode;\n\t}\n}\n\n// Determines if a given `Rect` extends beyond the bottom edge of the second `Rect`.\n//\n// @private\n// @param {module:utils/dom/rect~Rect} firstRect\n// @param {module:utils/dom/rect~Rect} secondRect\nfunction isBelow( firstRect, secondRect ) {\n\treturn firstRect.bottom > secondRect.bottom;\n}\n\n// Determines if a given `Rect` extends beyond the top edge of the second `Rect`.\n//\n// @private\n// @param {module:utils/dom/rect~Rect} firstRect\n// @param {module:utils/dom/rect~Rect} secondRect\nfunction isAbove( firstRect, secondRect ) {\n\treturn firstRect.top < secondRect.top;\n}\n\n// Determines if a given `Rect` extends beyond the left edge of the second `Rect`.\n//\n// @private\n// @param {module:utils/dom/rect~Rect} firstRect\n// @param {module:utils/dom/rect~Rect} secondRect\nfunction isLeftOf( firstRect, secondRect ) {\n\treturn firstRect.left < secondRect.left;\n}\n\n// Determines if a given `Rect` extends beyond the right edge of the second `Rect`.\n//\n// @private\n// @param {module:utils/dom/rect~Rect} firstRect\n// @param {module:utils/dom/rect~Rect} secondRect\nfunction isRightOf( firstRect, secondRect ) {\n\treturn firstRect.right > secondRect.right;\n}\n\n// Returns the closest window of an element or range.\n//\n// @private\n// @param {HTMLElement|Range} firstRect\n// @returns {Window}\nfunction getWindow( elementOrRange ) {\n\tif ( isRange( elementOrRange ) ) {\n\t\treturn elementOrRange.startContainer.ownerDocument.defaultView;\n\t} else {\n\t\treturn elementOrRange.ownerDocument.defaultView;\n\t}\n}\n\n// Returns the closest parent of an element or DOM range.\n//\n// @private\n// @param {HTMLElement|Range} firstRect\n// @returns {HTMLelement}\nfunction getParentElement( elementOrRange ) {\n\tif ( isRange( elementOrRange ) ) {\n\t\tlet parent = elementOrRange.commonAncestorContainer;\n\n\t\t// If a Range is attached to the Text, use the closest element ancestor.\n\t\tif ( isText( parent ) ) {\n\t\t\tparent = parent.parentNode;\n\t\t}\n\n\t\treturn parent;\n\t} else {\n\t\treturn elementOrRange.parentNode;\n\t}\n}\n\n// Returns the rect of an element or range residing in an iframe.\n// The result rect is relative to the geometry of the passed window instance.\n//\n// @private\n// @param {HTMLElement|Range} target Element or range which rect should be returned.\n// @param {Window} relativeWindow A window the rect should be relative to.\n// @returns {module:utils/dom/rect~Rect}\nfunction getRectRelativeToWindow( target, relativeWindow ) {\n\tconst targetWindow = getWindow( target );\n\tconst rect = new Rect( target );\n\n\tif ( targetWindow === relativeWindow ) {\n\t\treturn rect;\n\t} else {\n\t\tlet currentWindow = targetWindow;\n\n\t\twhile ( currentWindow != relativeWindow ) {\n\t\t\tconst frame = currentWindow.frameElement;\n\t\t\tconst frameRect = new Rect( frame ).excludeScrollbarsAndBorders();\n\n\t\t\trect.moveBy( frameRect.left, frameRect.top );\n\n\t\t\tcurrentWindow = currentWindow.parent;\n\t\t}\n\t}\n\n\treturn rect;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/view\n */\n\nimport Document from './document';\nimport DowncastWriter from './downcastwriter';\nimport Renderer from './renderer';\nimport DomConverter from './domconverter';\nimport Position from './position';\nimport Range from './range';\nimport Selection from './selection';\n\nimport MutationObserver from './observer/mutationobserver';\nimport KeyObserver from './observer/keyobserver';\nimport FakeSelectionObserver from './observer/fakeselectionobserver';\nimport SelectionObserver from './observer/selectionobserver';\nimport FocusObserver from './observer/focusobserver';\nimport CompositionObserver from './observer/compositionobserver';\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport { scrollViewportToShowTarget } from '@ckeditor/ckeditor5-utils/src/dom/scroll';\nimport { injectUiElementHandling } from './uielement';\nimport { injectQuirksHandling } from './filler';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Editor's view controller class. Its main responsibility is DOM - View management for editing purposes, to provide\n * abstraction over the DOM structure and events and hide all browsers quirks.\n *\n * View controller renders view document to DOM whenever view structure changes. To determine when view can be rendered,\n * all changes need to be done using the {@link module:engine/view/view~View#change} method, using\n * {@link module:engine/view/downcastwriter~DowncastWriter}:\n *\n *\t\tview.change( writer => {\n *\t\t\twriter.insert( position, writer.createText( 'foo' ) );\n *\t\t} );\n *\n * View controller also register {@link module:engine/view/observer/observer~Observer observers} which observes changes\n * on DOM and fire events on the {@link module:engine/view/document~Document Document}.\n * Note that the following observers are added by the class constructor and are always available:\n *\n * * {@link module:engine/view/observer/mutationobserver~MutationObserver},\n * * {@link module:engine/view/observer/selectionobserver~SelectionObserver},\n * * {@link module:engine/view/observer/focusobserver~FocusObserver},\n * * {@link module:engine/view/observer/keyobserver~KeyObserver},\n * * {@link module:engine/view/observer/fakeselectionobserver~FakeSelectionObserver}.\n * * {@link module:engine/view/observer/compositionobserver~CompositionObserver}.\n *\n * This class also {@link module:engine/view/view~View#attachDomRoot binds the DOM and the view elements}.\n *\n * If you do not need full a DOM - view management, and only want to transform a tree of view elements to a tree of DOM\n * elements you do not need this controller. You can use the {@link module:engine/view/domconverter~DomConverter DomConverter} instead.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class View {\n\tconstructor() {\n\t\t/**\n\t\t * Instance of the {@link module:engine/view/document~Document} associated with this view controller.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:engine/view/document~Document}\n\t\t */\n\t\tthis.document = new Document();\n\n\t\t/**\n\t\t * Instance of the {@link module:engine/view/domconverter~DomConverter domConverter} used by\n\t\t * {@link module:engine/view/view~View#_renderer renderer}\n\t\t * and {@link module:engine/view/observer/observer~Observer observers}.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:engine/view/domconverter~DomConverter}\n\t\t */\n\t\tthis.domConverter = new DomConverter();\n\n\t\t/**\n\t\t * Roots of the DOM tree. Map on the `HTMLElement`s with roots names as keys.\n\t\t *\n\t\t * @readonly\n\t\t * @type {Map.<String, HTMLElement>}\n\t\t */\n\t\tthis.domRoots = new Map();\n\n\t\t/**\n\t\t * Used to prevent calling {@link #forceRender} and {@link #change} during rendering view to the DOM.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} #isRenderingInProgress\n\t\t */\n\t\tthis.set( 'isRenderingInProgress', false );\n\n\t\t/**\n\t\t * Instance of the {@link module:engine/view/renderer~Renderer renderer}.\n\t\t *\n\t\t * @protected\n\t\t * @type {module:engine/view/renderer~Renderer}\n\t\t */\n\t\tthis._renderer = new Renderer( this.domConverter, this.document.selection );\n\t\tthis._renderer.bind( 'isFocused' ).to( this.document );\n\n\t\t/**\n\t\t * A DOM root attributes cache. It saves the initial values of DOM root attributes before the DOM element\n\t\t * is {@link module:engine/view/view~View#attachDomRoot attached} to the view so later on, when\n\t\t * the view is destroyed ({@link module:engine/view/view~View#detachDomRoot}), they can be easily restored.\n\t\t * This way, the DOM element can go back to the (clean) state as if the editing view never used it.\n\t\t *\n\t\t * @private\n\t\t * @member {WeakMap.<HTMLElement,Object>}\n\t\t */\n\t\tthis._initialDomRootAttributes = new WeakMap();\n\n\t\t/**\n\t\t * Map of registered {@link module:engine/view/observer/observer~Observer observers}.\n\t\t *\n\t\t * @private\n\t\t * @type {Map.<Function, module:engine/view/observer/observer~Observer>}\n\t\t */\n\t\tthis._observers = new Map();\n\n\t\t/**\n\t\t * Is set to `true` when {@link #change view changes} are currently in progress.\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._ongoingChange = false;\n\n\t\t/**\n\t\t * Used to prevent calling {@link #forceRender} and {@link #change} during rendering view to the DOM.\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._postFixersInProgress = false;\n\n\t\t/**\n\t\t * Internal flag to temporary disable rendering. See the usage in the {@link #_disableRendering}.\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._renderingDisabled = false;\n\n\t\t/**\n\t\t * Internal flag that disables rendering when there are no changes since the last rendering.\n\t\t * It stores information about changed selection and changed elements from attached document roots.\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._hasChangedSinceTheLastRendering = false;\n\n\t\t/**\n\t\t * DowncastWriter instance used in {@link #change change method} callbacks.\n\t\t *\n\t\t * @private\n\t\t * @type {module:engine/view/downcastwriter~DowncastWriter}\n\t\t */\n\t\tthis._writer = new DowncastWriter( this.document );\n\n\t\t// Add default observers.\n\t\tthis.addObserver( MutationObserver );\n\t\tthis.addObserver( SelectionObserver );\n\t\tthis.addObserver( FocusObserver );\n\t\tthis.addObserver( KeyObserver );\n\t\tthis.addObserver( FakeSelectionObserver );\n\t\tthis.addObserver( CompositionObserver );\n\n\t\t// Inject quirks handlers.\n\t\tinjectQuirksHandling( this );\n\t\tinjectUiElementHandling( this );\n\n\t\t// Use 'normal' priority so that rendering is performed as first when using that priority.\n\t\tthis.on( 'render', () => {\n\t\t\tthis._render();\n\n\t\t\t// Informs that layout has changed after render.\n\t\t\tthis.document.fire( 'layoutChanged' );\n\n\t\t\t// Reset the `_hasChangedSinceTheLastRendering` flag after rendering.\n\t\t\tthis._hasChangedSinceTheLastRendering = false;\n\t\t} );\n\n\t\t// Listen to the document selection changes directly.\n\t\tthis.listenTo( this.document.selection, 'change', () => {\n\t\t\tthis._hasChangedSinceTheLastRendering = true;\n\t\t} );\n\t}\n\n\t/**\n\t * Attaches a DOM root element to the view element and enable all observers on that element.\n\t * Also {@link module:engine/view/renderer~Renderer#markToSync mark element} to be synchronized\n\t * with the view what means that all child nodes will be removed and replaced with content of the view root.\n\t *\n\t * This method also will change view element name as the same as tag name of given dom root.\n\t * Name is always transformed to lower case.\n\t *\n\t * **Note:** Use {@link #detachDomRoot `detachDomRoot()`} to revert this action.\n\t *\n\t * @param {Element} domRoot DOM root element.\n\t * @param {String} [name='main'] Name of the root.\n\t */\n\tattachDomRoot( domRoot, name = 'main' ) {\n\t\tconst viewRoot = this.document.getRoot( name );\n\n\t\t// Set view root name the same as DOM root tag name.\n\t\tviewRoot._name = domRoot.tagName.toLowerCase();\n\n\t\tconst initialDomRootAttributes = {};\n\n\t\t// 1. Copy and cache the attributes to remember the state of the element before attaching.\n\t\t// The cached attributes will be restored in detachDomRoot() so the element goes to the\n\t\t// clean state as if the editing view never used it.\n\t\t// 2. Apply the attributes using the view writer, so they all go under the control of the engine.\n\t\t// The editing view takes over the attribute management completely because various\n\t\t// features (e.g. addPlaceholder()) require dynamic changes of those attributes and they\n\t\t// cannot be managed by the engine and the UI library at the same time.\n\t\tfor ( const { name, value } of Array.from( domRoot.attributes ) ) {\n\t\t\tinitialDomRootAttributes[ name ] = value;\n\n\t\t\t// Do not use writer.setAttribute() for the class attribute. The EditableUIView class\n\t\t\t// and its descendants could have already set some using the writer.addClass() on the view\n\t\t\t// document root. They haven't been rendered yet so they are not present in the DOM root.\n\t\t\t// Using writer.setAttribute( 'class', ... ) would override them completely.\n\t\t\tif ( name === 'class' ) {\n\t\t\t\tthis._writer.addClass( value.split( ' ' ), viewRoot );\n\t\t\t} else {\n\t\t\t\tthis._writer.setAttribute( name, value, viewRoot );\n\t\t\t}\n\t\t}\n\n\t\tthis._initialDomRootAttributes.set( domRoot, initialDomRootAttributes );\n\n\t\tconst updateContenteditableAttribute = () => {\n\t\t\tthis._writer.setAttribute( 'contenteditable', !viewRoot.isReadOnly, viewRoot );\n\n\t\t\tif ( viewRoot.isReadOnly ) {\n\t\t\t\tthis._writer.addClass( 'ck-read-only', viewRoot );\n\t\t\t} else {\n\t\t\t\tthis._writer.removeClass( 'ck-read-only', viewRoot );\n\t\t\t}\n\t\t};\n\n\t\t// Set initial value.\n\t\tupdateContenteditableAttribute();\n\n\t\tthis.domRoots.set( name, domRoot );\n\t\tthis.domConverter.bindElements( domRoot, viewRoot );\n\t\tthis._renderer.markToSync( 'children', viewRoot );\n\t\tthis._renderer.markToSync( 'attributes', viewRoot );\n\t\tthis._renderer.domDocuments.add( domRoot.ownerDocument );\n\n\t\tviewRoot.on( 'change:children', ( evt, node ) => this._renderer.markToSync( 'children', node ) );\n\t\tviewRoot.on( 'change:attributes', ( evt, node ) => this._renderer.markToSync( 'attributes', node ) );\n\t\tviewRoot.on( 'change:text', ( evt, node ) => this._renderer.markToSync( 'text', node ) );\n\t\tviewRoot.on( 'change:isReadOnly', () => this.change( updateContenteditableAttribute ) );\n\n\t\tviewRoot.on( 'change', () => {\n\t\t\tthis._hasChangedSinceTheLastRendering = true;\n\t\t} );\n\n\t\tfor ( const observer of this._observers.values() ) {\n\t\t\tobserver.observe( domRoot, name );\n\t\t}\n\t}\n\n\t/**\n\t * Detaches a DOM root element from the view element and restores its attributes to the state before\n\t * {@link #attachDomRoot `attachDomRoot()`}.\n\t *\n\t * @param {String} name Name of the root to detach.\n\t */\n\tdetachDomRoot( name ) {\n\t\tconst domRoot = this.domRoots.get( name );\n\n\t\t// Remove all root attributes so the DOM element is \"bare\".\n\t\tArray.from( domRoot.attributes ).forEach( ( { name } ) => domRoot.removeAttribute( name ) );\n\n\t\tconst initialDomRootAttributes = this._initialDomRootAttributes.get( domRoot );\n\n\t\t// Revert all view root attributes back to the state before attachDomRoot was called.\n\t\tfor ( const attribute in initialDomRootAttributes ) {\n\t\t\tdomRoot.setAttribute( attribute, initialDomRootAttributes[ attribute ] );\n\t\t}\n\n\t\tthis.domRoots.delete( name );\n\t\tthis.domConverter.unbindDomElement( domRoot );\n\t}\n\n\t/**\n\t * Gets DOM root element.\n\t *\n\t * @param {String} [name='main'] Name of the root.\n\t * @returns {Element} DOM root element instance.\n\t */\n\tgetDomRoot( name = 'main' ) {\n\t\treturn this.domRoots.get( name );\n\t}\n\n\t/**\n\t * Creates observer of the given type if not yet created, {@link module:engine/view/observer/observer~Observer#enable enables} it\n\t * and {@link module:engine/view/observer/observer~Observer#observe attaches} to all existing and future\n\t * {@link #domRoots DOM roots}.\n\t *\n\t * Note: Observers are recognized by their constructor (classes). A single observer will be instantiated and used only\n\t * when registered for the first time. This means that features and other components can register a single observer\n\t * multiple times without caring whether it has been already added or not.\n\t *\n\t * @param {Function} Observer The constructor of an observer to add.\n\t * Should create an instance inheriting from {@link module:engine/view/observer/observer~Observer}.\n\t * @returns {module:engine/view/observer/observer~Observer} Added observer instance.\n\t */\n\taddObserver( Observer ) {\n\t\tlet observer = this._observers.get( Observer );\n\n\t\tif ( observer ) {\n\t\t\treturn observer;\n\t\t}\n\n\t\tobserver = new Observer( this );\n\n\t\tthis._observers.set( Observer, observer );\n\n\t\tfor ( const [ name, domElement ] of this.domRoots ) {\n\t\t\tobserver.observe( domElement, name );\n\t\t}\n\n\t\tobserver.enable();\n\n\t\treturn observer;\n\t}\n\n\t/**\n\t * Returns observer of the given type or `undefined` if such observer has not been added yet.\n\t *\n\t * @param {Function} Observer The constructor of an observer to get.\n\t * @returns {module:engine/view/observer/observer~Observer|undefined} Observer instance or undefined.\n\t */\n\tgetObserver( Observer ) {\n\t\treturn this._observers.get( Observer );\n\t}\n\n\t/**\n\t * Disables all added observers.\n\t */\n\tdisableObservers() {\n\t\tfor ( const observer of this._observers.values() ) {\n\t\t\tobserver.disable();\n\t\t}\n\t}\n\n\t/**\n\t * Enables all added observers.\n\t */\n\tenableObservers() {\n\t\tfor ( const observer of this._observers.values() ) {\n\t\t\tobserver.enable();\n\t\t}\n\t}\n\n\t/**\n\t * Scrolls the page viewport and {@link #domRoots} with their ancestors to reveal the\n\t * caret, if not already visible to the user.\n\t */\n\tscrollToTheSelection() {\n\t\tconst range = this.document.selection.getFirstRange();\n\n\t\tif ( range ) {\n\t\t\tscrollViewportToShowTarget( {\n\t\t\t\ttarget: this.domConverter.viewRangeToDom( range ),\n\t\t\t\tviewportOffset: 20\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * It will focus DOM element representing {@link module:engine/view/editableelement~EditableElement EditableElement}\n\t * that is currently having selection inside.\n\t */\n\tfocus() {\n\t\tif ( !this.document.isFocused ) {\n\t\t\tconst editable = this.document.selection.editableElement;\n\n\t\t\tif ( editable ) {\n\t\t\t\tthis.domConverter.focus( editable );\n\t\t\t\tthis.forceRender();\n\t\t\t} else {\n\t\t\t\t/**\n\t\t\t\t * Before focusing view document, selection should be placed inside one of the view's editables.\n\t\t\t\t * Normally its selection will be converted from model document (which have default selection), but\n\t\t\t\t * when using view document on its own, we need to manually place selection before focusing it.\n\t\t\t\t *\n\t\t\t\t * @error view-focus-no-selection\n\t\t\t\t */\n\t\t\t\tlog.warn( 'view-focus-no-selection: There is no selection in any editable to focus.' );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * The `change()` method is the primary way of changing the view. You should use it to modify any node in the view tree.\n\t * It makes sure that after all changes are made the view is rendered to the DOM (assuming that the view will be changed\n\t * inside the callback). It prevents situations when the DOM is updated when the view state is not yet correct. It allows\n\t * to nest calls one inside another and still performs a single rendering after all those changes are made.\n\t * It also returns the return value of its callback.\n\t *\n\t *\t\tconst text = view.change( writer => {\n\t *\t\t\tconst newText = writer.createText( 'foo' );\n\t *\t\t\twriter.insert( position1, newText );\n\t *\n\t *\t\t\tview.change( writer => {\n\t *\t\t\t\twriter.insert( position2, writer.createText( 'bar' ) );\n\t *\t\t\t} );\n\t *\n\t * \t\t\twriter.remove( range );\n\t *\n\t * \t\t\treturn newText;\n\t *\t\t} );\n\t *\n\t * When the outermost change block is done and rendering to the DOM is over the\n\t * {@link module:engine/view/view~View#event:render `View#render`} event is fired.\n\t *\n\t * This method throws a `applying-view-changes-on-rendering` error when\n\t * the change block is used after rendering to the DOM has started.\n\t *\n\t * @param {Function} callback Callback function which may modify the view.\n\t * @returns {*} Value returned by the callback.\n\t */\n\tchange( callback ) {\n\t\tif ( this.isRenderingInProgress || this._postFixersInProgress ) {\n\t\t\t/**\n\t\t\t * Thrown when there is an attempt to make changes to the view tree when it is in incorrect state. This may\n\t\t\t * cause some unexpected behaviour and inconsistency between the DOM and the view.\n\t\t\t * This may be caused by:\n\t\t\t *\n\t\t\t * * calling {@link #change} or {@link #forceRender} during rendering process,\n\t\t\t * * calling {@link #change} or {@link #forceRender} inside of\n\t\t\t * {@link module:engine/view/document~Document#registerPostFixer post-fixer function}.\n\t\t\t *\n\t\t\t * @error cannot-change-view-tree\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'cannot-change-view-tree: ' +\n\t\t\t\t'Attempting to make changes to the view when it is in an incorrect state: rendering or post-fixers are in progress. ' +\n\t\t\t\t'This may cause some unexpected behavior and inconsistency between the DOM and the view.'\n\t\t\t);\n\t\t}\n\n\t\t// Recursive call to view.change() method - execute listener immediately.\n\t\tif ( this._ongoingChange ) {\n\t\t\treturn callback( this._writer );\n\t\t}\n\n\t\t// This lock will assure that all recursive calls to view.change() will end up in same block - one \"render\"\n\t\t// event for all nested calls.\n\t\tthis._ongoingChange = true;\n\t\tconst callbackResult = callback( this._writer );\n\t\tthis._ongoingChange = false;\n\n\t\t// This lock is used by editing controller to render changes from outer most model.change() once. As plugins might call\n\t\t// view.change() inside model.change() block - this will ensures that postfixers and rendering are called once after all changes.\n\t\t// Also, we don't need to render anything if there're no changes since last rendering.\n\t\tif ( !this._renderingDisabled && this._hasChangedSinceTheLastRendering ) {\n\t\t\tthis._postFixersInProgress = true;\n\t\t\tthis.document._callPostFixers( this._writer );\n\t\t\tthis._postFixersInProgress = false;\n\n\t\t\tthis.fire( 'render' );\n\t\t}\n\n\t\treturn callbackResult;\n\t}\n\n\t/**\n\t * Forces rendering {@link module:engine/view/document~Document view document} to DOM. If any view changes are\n\t * currently in progress, rendering will start after all {@link #change change blocks} are processed.\n\t *\n\t * Note that this method is dedicated for special cases. All view changes should be wrapped in the {@link #change}\n\t * block and the view will automatically check whether it needs to render DOM or not.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `applying-view-changes-on-rendering` when\n\t * trying to re-render when rendering to DOM has already started.\n\t */\n\tforceRender() {\n\t\tthis._hasChangedSinceTheLastRendering = true;\n\t\tthis.change( () => {} );\n\t}\n\n\t/**\n\t * Destroys this instance. Makes sure that all observers are destroyed and listeners removed.\n\t */\n\tdestroy() {\n\t\tfor ( const observer of this._observers.values() ) {\n\t\t\tobserver.destroy();\n\t\t}\n\n\t\tthis.document.destroy();\n\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/view/position~Position position},\n\t * * parent element and offset (offset defaults to `0`),\n\t * * parent element and `'end'` (sets position at the end of that element),\n\t * * {@link module:engine/view/item~Item view item} and `'before'` or `'after'` (sets position before or after given view item).\n\t *\n\t * This method is a shortcut to other constructors such as:\n\t *\n\t * * {@link #createPositionBefore},\n\t * * {@link #createPositionAfter},\n\t *\n\t * @param {module:engine/view/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tcreatePositionAt( itemOrPosition, offset ) {\n\t\treturn Position._createAt( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Creates a new position after given view item.\n\t *\n\t * @param {module:engine/view/item~Item} item View item after which the position should be located.\n\t * @returns {module:engine/view/position~Position}\n\t */\n\tcreatePositionAfter( item ) {\n\t\treturn Position._createAfter( item );\n\t}\n\n\t/**\n\t * Creates a new position before given view item.\n\t *\n\t * @param {module:engine/view/item~Item} item View item before which the position should be located.\n\t * @returns {module:engine/view/position~Position}\n\t */\n\tcreatePositionBefore( item ) {\n\t\treturn Position._createBefore( item );\n\t}\n\n\t/**\n\t * Creates a range spanning from `start` position to `end` position.\n\t *\n\t * **Note:** This factory method creates it's own {@link module:engine/view/position~Position} instances basing on passed values.\n\t *\n\t * @param {module:engine/view/position~Position} start Start position.\n\t * @param {module:engine/view/position~Position} [end] End position. If not set, range will be collapsed at `start` position.\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tcreateRange( start, end ) {\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Creates a range that starts before given {@link module:engine/view/item~Item view item} and ends after it.\n\t *\n\t * @param {module:engine/view/item~Item} item\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tcreateRangeOn( item ) {\n\t\treturn Range._createOn( item );\n\t}\n\n\t/**\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * @param {module:engine/view/element~Element} element Element which is a parent for the range.\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tcreateRangeIn( element ) {\n\t\treturn Range._createIn( element );\n\t}\n\n\t/**\n\t Creates new {@link module:engine/view/selection~Selection} instance.\n\t *\n\t * \t\t// Creates empty selection without ranges.\n\t *\t\tconst selection = view.createSelection();\n\t *\n\t *\t\t// Creates selection at the given range.\n\t *\t\tconst range = view.createRange( start, end );\n\t *\t\tconst selection = view.createSelection( range );\n\t *\n\t *\t\t// Creates selection at the given ranges\n\t * \t\tconst ranges = [ view.createRange( start1, end2 ), view.createRange( star2, end2 ) ];\n\t *\t\tconst selection = view.createSelection( ranges );\n\t *\n\t *\t\t// Creates selection from the other selection.\n\t *\t\tconst otherSelection = view.createSelection();\n\t *\t\tconst selection = view.createSelection( otherSelection );\n\t *\n\t *\t\t// Creates selection from the document selection.\n\t *\t\tconst selection = view.createSelection( editor.editing.view.document.selection );\n\t *\n\t * \t\t// Creates selection at the given position.\n\t *\t\tconst position = view.createPositionFromPath( root, path );\n\t *\t\tconst selection = view.createSelection( position );\n\t *\n\t *\t\t// Creates collapsed selection at the position of given item and offset.\n\t *\t\tconst paragraph = view.createContainerElement( 'paragraph' );\n\t *\t\tconst selection = view.createSelection( paragraph, offset );\n\t *\n\t *\t\t// Creates a range inside an {@link module:engine/view/element~Element element} which starts before the\n\t *\t\t// first child of that element and ends after the last child of that element.\n\t *\t\tconst selection = view.createSelection( paragraph, 'in' );\n\t *\n\t *\t\t// Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends\n\t *\t\t// just after the item.\n\t *\t\tconst selection = view.createSelection( paragraph, 'on' );\n\t *\n\t * `Selection`'s factory method allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t *\t\t// Creates backward selection.\n\t *\t\tconst selection = view.createSelection( range, { backward: true } );\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be properly handled by screen readers).\n\t *\n\t *\t\t// Creates fake selection with label.\n\t *\t\tconst selection = view.createSelection( range, { fake: true, label: 'foo' } );\n\t *\n\t * @param {module:engine/view/selection~Selectable} [selectable=null]\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Offset or place when selectable is an `Item`.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.backward] Sets this selection instance to be backward.\n\t * @param {Boolean} [options.fake] Sets this selection instance to be marked as `fake`.\n\t * @param {String} [options.label] Label for the fake selection.\n\t * @returns {module:engine/view/selection~Selection}\n\t */\n\tcreateSelection( selectable, placeOrOffset, options ) {\n\t\treturn new Selection( selectable, placeOrOffset, options );\n\t}\n\n\t/**\n\t * Disables or enables rendering. If the flag is set to `true` then the rendering will be disabled.\n\t * If the flag is set to `false` and if there was some change in the meantime, then the rendering action will be performed.\n\t *\n\t * @protected\n\t * @param {Boolean} flag A flag indicates whether the rendering should be disabled.\n\t */\n\t_disableRendering( flag ) {\n\t\tthis._renderingDisabled = flag;\n\n\t\tif ( flag == false ) {\n\t\t\t// Render when you stop blocking rendering.\n\t\t\tthis.change( () => {} );\n\t\t}\n\t}\n\n\t/**\n\t * Renders all changes. In order to avoid triggering the observers (e.g. mutations) all observers are disabled\n\t * before rendering and re-enabled after that.\n\t *\n\t * @private\n\t */\n\t_render() {\n\t\tthis.isRenderingInProgress = true;\n\t\tthis.disableObservers();\n\t\tthis._renderer.render();\n\t\tthis.enableObservers();\n\t\tthis.isRenderingInProgress = false;\n\t}\n\n\t/**\n\t * Fired after a topmost {@link module:engine/view/view~View#change change block} and all\n\t * {@link module:engine/view/document~Document#registerPostFixer post-fixers} are executed.\n\t *\n\t * Actual rendering is performed as a first listener on 'normal' priority.\n\t *\n\t *\t\tview.on( 'render', () => {\n\t *\t\t\t// Rendering to the DOM is complete.\n\t *\t\t} );\n\t *\n\t * This event is useful when you want to update interface elements after the rendering, e.g. position of the\n\t * balloon panel. If you wants to change view structure use\n\t * {@link module:engine/view/document~Document#registerPostFixer post-fixers}.\n\t *\n\t * @event module:engine/view/view~View#event:render\n\t */\n}\n\nmix( View, ObservableMixin );\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/tomap\n */\n\nimport objectToMap from './objecttomap';\nimport { isPlainObject } from 'lodash-es';\n\n/**\n * Transforms object or iterable to map. Iterable needs to be in the format acceptable by the `Map` constructor.\n *\n *\t\tmap = toMap( { 'foo': 1, 'bar': 2 } );\n *\t\tmap = toMap( [ [ 'foo', 1 ], [ 'bar', 2 ] ] );\n *\t\tmap = toMap( anotherMap );\n *\n * @param {Object|Iterable} data Object or iterable to transform.\n * @returns {Map} Map created from data.\n */\nexport default function toMap( data ) {\n\tif ( isPlainObject( data ) ) {\n\t\treturn objectToMap( data );\n\t} else {\n\t\treturn new Map( data );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/node\n */\n\nimport toMap from '@ckeditor/ckeditor5-utils/src/tomap';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport compareArrays from '@ckeditor/ckeditor5-utils/src/comparearrays';\n\n// To check if component is loaded more than once.\nimport '@ckeditor/ckeditor5-utils/src/version';\n\n/**\n * Model node. Most basic structure of model tree.\n *\n * This is an abstract class that is a base for other classes representing different nodes in model.\n *\n * **Note:** If a node is detached from the model tree, you can manipulate it using it's API.\n * However, it is **very important** that nodes already attached to model tree should be only changed through\n * {@link module:engine/model/writer~Writer Writer API}.\n *\n * Changes done by `Node` methods, like {@link module:engine/model/element~Element#_insertChild _insertChild} or\n * {@link module:engine/model/node~Node#_setAttribute _setAttribute}\n * do not generate {@link module:engine/model/operation/operation~Operation operations}\n * which are essential for correct editor work if you modify nodes in {@link module:engine/model/document~Document document} root.\n *\n * The flow of working on `Node` (and classes that inherits from it) is as such:\n * 1. You can create a `Node` instance, modify it using it's API.\n * 2. Add `Node` to the model using `Batch` API.\n * 3. Change `Node` that was already added to the model using `Batch` API.\n *\n * Similarly, you cannot use `Batch` API on a node that has not been added to the model tree, with the exception\n * of {@link module:engine/model/writer~Writer#insert inserting} that node to the model tree.\n *\n * Be aware that using {@link module:engine/model/writer~Writer#remove remove from Batch API} does not allow to use `Node` API because\n * the information about `Node` is still kept in model document.\n *\n * In case of {@link module:engine/model/element~Element element node}, adding and removing children also counts as changing a node and\n * follows same rules.\n */\nexport default class Node {\n\t/**\n\t * Creates a model node.\n\t *\n\t * This is an abstract class, so this constructor should not be used directly.\n\t *\n\t * @abstract\n\t * @param {Object} [attrs] Node's attributes. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t */\n\tconstructor( attrs ) {\n\t\t/**\n\t\t * Parent of this node. It could be {@link module:engine/model/element~Element}\n\t\t * or {@link module:engine/model/documentfragment~DocumentFragment}.\n\t\t * Equals to `null` if the node has no parent.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment|null}\n\t\t */\n\t\tthis.parent = null;\n\n\t\t/**\n\t\t * Attributes set on this node.\n\t\t *\n\t\t * @private\n\t\t * @member {Map} module:engine/model/node~Node#_attrs\n\t\t */\n\t\tthis._attrs = toMap( attrs );\n\t}\n\n\t/**\n\t * Index of this node in it's parent or `null` if the node has no parent.\n\t *\n\t * Accessing this property throws an error if this node's parent element does not contain it.\n\t * This means that model tree got broken.\n\t *\n\t * @readonly\n\t * @type {Number|null}\n\t */\n\tget index() {\n\t\tlet pos;\n\n\t\tif ( !this.parent ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( ( pos = this.parent.getChildIndex( this ) ) === null ) {\n\t\t\tthrow new CKEditorError( 'model-node-not-found-in-parent: The node\\'s parent does not contain this node.' );\n\t\t}\n\n\t\treturn pos;\n\t}\n\n\t/**\n\t * Offset at which this node starts in it's parent. It is equal to the sum of {@link #offsetSize offsetSize}\n\t * of all it's previous siblings. Equals to `null` if node has no parent.\n\t *\n\t * Accessing this property throws an error if this node's parent element does not contain it.\n\t * This means that model tree got broken.\n\t *\n\t * @readonly\n\t * @type {Number|null}\n\t */\n\tget startOffset() {\n\t\tlet pos;\n\n\t\tif ( !this.parent ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( ( pos = this.parent.getChildStartOffset( this ) ) === null ) {\n\t\t\tthrow new CKEditorError( 'model-node-not-found-in-parent: The node\\'s parent does not contain this node.' );\n\t\t}\n\n\t\treturn pos;\n\t}\n\n\t/**\n\t * Offset size of this node. Represents how much \"offset space\" is occupied by the node in it's parent.\n\t * It is important for {@link module:engine/model/position~Position position}. When node has `offsetSize` greater than `1`, position\n\t * can be placed between that node start and end. `offsetSize` greater than `1` is for nodes that represents more\n\t * than one entity, i.e. {@link module:engine/model/text~Text text node}.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget offsetSize() {\n\t\treturn 1;\n\t}\n\n\t/**\n\t * Offset at which this node ends in it's parent. It is equal to the sum of this node's\n\t * {@link module:engine/model/node~Node#startOffset start offset} and {@link #offsetSize offset size}.\n\t * Equals to `null` if the node has no parent.\n\t *\n\t * @readonly\n\t * @type {Number|null}\n\t */\n\tget endOffset() {\n\t\tif ( !this.parent ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.startOffset + this.offsetSize;\n\t}\n\n\t/**\n\t * Node's next sibling or `null` if the node is a last child of it's parent or if the node has no parent.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/node~Node|null}\n\t */\n\tget nextSibling() {\n\t\tconst index = this.index;\n\n\t\treturn ( index !== null && this.parent.getChild( index + 1 ) ) || null;\n\t}\n\n\t/**\n\t * Node's previous sibling or `null` if the node is a first child of it's parent or if the node has no parent.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/node~Node|null}\n\t */\n\tget previousSibling() {\n\t\tconst index = this.index;\n\n\t\treturn ( index !== null && this.parent.getChild( index - 1 ) ) || null;\n\t}\n\n\t/**\n\t * The top-most ancestor of the node. If node has no parent it is the root itself. If the node is a part\n\t * of {@link module:engine/model/documentfragment~DocumentFragment}, it's `root` is equal to that `DocumentFragment`.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/node~Node|module:engine/model/documentfragment~DocumentFragment}\n\t */\n\tget root() {\n\t\tlet root = this; // eslint-disable-line consistent-this\n\n\t\twhile ( root.parent ) {\n\t\t\troot = root.parent;\n\t\t}\n\n\t\treturn root;\n\t}\n\n\t/**\n\t * {@link module:engine/model/document~Document Document} that owns this node or `null` if the node has no parent or is inside\n\t * a {@link module:engine/model/documentfragment~DocumentFragment DocumentFragment}.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/document~Document|null}\n\t */\n\tget document() {\n\t\t// This is a top element of a sub-tree.\n\t\tif ( this.root == this ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Root may be `DocumentFragment` which does not have document property.\n\t\treturn this.root.document || null;\n\t}\n\n\t/**\n\t * Gets path to the node. The path is an array containing starting offsets of consecutive ancestors of this node,\n\t * beginning from {@link module:engine/model/node~Node#root root}, down to this node's starting offset. The path can be used to\n\t * create {@link module:engine/model/position~Position Position} instance.\n\t *\n\t *\t\tconst abc = new Text( 'abc' );\n\t *\t\tconst foo = new Text( 'foo' );\n\t *\t\tconst h1 = new Element( 'h1', null, new Text( 'header' ) );\n\t *\t\tconst p = new Element( 'p', null, [ abc, foo ] );\n\t *\t\tconst div = new Element( 'div', null, [ h1, p ] );\n\t *\t\tfoo.getPath(); // Returns [ 1, 3 ]. `foo` is in `p` which is in `div`. `p` starts at offset 1, while `foo` at 3.\n\t *\t\th1.getPath(); // Returns [ 0 ].\n\t *\t\tdiv.getPath(); // Returns [].\n\t *\n\t * @returns {Array.<Number>} The path.\n\t */\n\tgetPath() {\n\t\tconst path = [];\n\t\tlet node = this; // eslint-disable-line consistent-this\n\n\t\twhile ( node.parent ) {\n\t\t\tpath.unshift( node.startOffset );\n\t\t\tnode = node.parent;\n\t\t}\n\n\t\treturn path;\n\t}\n\n\t/**\n\t * Returns ancestors array of this node.\n\t *\n\t * @param {Object} options Options object.\n\t * @param {Boolean} [options.includeSelf=false] When set to `true` this node will be also included in parent's array.\n\t * @param {Boolean} [options.parentFirst=false] When set to `true`, array will be sorted from node's parent to root element,\n\t * otherwise root element will be the first item in the array.\n\t * @returns {Array} Array with ancestors.\n\t */\n\tgetAncestors( options = { includeSelf: false, parentFirst: false } ) {\n\t\tconst ancestors = [];\n\t\tlet parent = options.includeSelf ? this : this.parent;\n\n\t\twhile ( parent ) {\n\t\t\tancestors[ options.parentFirst ? 'push' : 'unshift' ]( parent );\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn ancestors;\n\t}\n\n\t/**\n\t * Returns a {@link module:engine/model/element~Element} or {@link module:engine/model/documentfragment~DocumentFragment}\n\t * which is a common ancestor of both nodes.\n\t *\n\t * @param {module:engine/model/node~Node} node The second node.\n\t * @param {Object} options Options object.\n\t * @param {Boolean} [options.includeSelf=false] When set to `true` both nodes will be considered \"ancestors\" too.\n\t * Which means that if e.g. node A is inside B, then their common ancestor will be B.\n\t * @returns {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment|null}\n\t */\n\tgetCommonAncestor( node, options = {} ) {\n\t\tconst ancestorsA = this.getAncestors( options );\n\t\tconst ancestorsB = node.getAncestors( options );\n\n\t\tlet i = 0;\n\n\t\twhile ( ancestorsA[ i ] == ancestorsB[ i ] && ancestorsA[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i === 0 ? null : ancestorsA[ i - 1 ];\n\t}\n\n\t/**\n\t * Returns whether this node is before given node. `false` is returned if nodes are in different trees (for example,\n\t * in different {@link module:engine/model/documentfragment~DocumentFragment}s).\n\t *\n\t * @param {module:engine/model/node~Node} node Node to compare with.\n\t * @returns {Boolean}\n\t */\n\tisBefore( node ) {\n\t\t// Given node is not before this node if they are same.\n\t\tif ( this == node ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Return `false` if it is impossible to compare nodes.\n\t\tif ( this.root !== node.root ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst thisPath = this.getPath();\n\t\tconst nodePath = node.getPath();\n\n\t\tconst result = compareArrays( thisPath, nodePath );\n\n\t\tswitch ( result ) {\n\t\t\tcase 'prefix':\n\t\t\t\treturn true;\n\n\t\t\tcase 'extension':\n\t\t\t\treturn false;\n\n\t\t\tdefault:\n\t\t\t\treturn thisPath[ result ] < nodePath[ result ];\n\t\t}\n\t}\n\n\t/**\n\t * Returns whether this node is after given node. `false` is returned if nodes are in different trees (for example,\n\t * in different {@link module:engine/model/documentfragment~DocumentFragment}s).\n\t *\n\t * @param {module:engine/model/node~Node} node Node to compare with.\n\t * @returns {Boolean}\n\t */\n\tisAfter( node ) {\n\t\t// Given node is not before this node if they are same.\n\t\tif ( this == node ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Return `false` if it is impossible to compare nodes.\n\t\tif ( this.root !== node.root ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// In other cases, just check if the `node` is before, and return the opposite.\n\t\treturn !this.isBefore( node );\n\t}\n\n\t/**\n\t * Checks if the node has an attribute with given key.\n\t *\n\t * @param {String} key Key of attribute to check.\n\t * @returns {Boolean} `true` if attribute with given key is set on node, `false` otherwise.\n\t */\n\thasAttribute( key ) {\n\t\treturn this._attrs.has( key );\n\t}\n\n\t/**\n\t * Gets an attribute value for given key or `undefined` if that attribute is not set on node.\n\t *\n\t * @param {String} key Key of attribute to look for.\n\t * @returns {*} Attribute value or `undefined`.\n\t */\n\tgetAttribute( key ) {\n\t\treturn this._attrs.get( key );\n\t}\n\n\t/**\n\t * Returns iterator that iterates over this node's attributes.\n\t *\n\t * Attributes are returned as arrays containing two items. First one is attribute key and second is attribute value.\n\t * This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t *\n\t * @returns {Iterable.<*>}\n\t */\n\tgetAttributes() {\n\t\treturn this._attrs.entries();\n\t}\n\n\t/**\n\t * Returns iterator that iterates over this node's attribute keys.\n\t *\n\t * @returns {Iterable.<String>}\n\t */\n\tgetAttributeKeys() {\n\t\treturn this._attrs.keys();\n\t}\n\n\t/**\n\t * Converts `Node` to plain object and returns it.\n\t *\n\t * @returns {Object} `Node` converted to plain object.\n\t */\n\ttoJSON() {\n\t\tconst json = {};\n\n\t\t// Serializes attributes to the object.\n\t\t// attributes = { a: 'foo', b: 1, c: true }.\n\t\tif ( this._attrs.size ) {\n\t\t\tjson.attributes = Array.from( this._attrs ).reduce( ( result, attr ) => {\n\t\t\t\tresult[ attr[ 0 ] ] = attr[ 1 ];\n\n\t\t\t\treturn result;\n\t\t\t}, {} );\n\t\t}\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Creates a copy of this node, that is a node with exactly same attributes, and returns it.\n\t *\n\t * @protected\n\t * @returns {module:engine/model/node~Node} Node with same attributes as this node.\n\t */\n\t_clone() {\n\t\treturn new Node( this._attrs );\n\t}\n\n\t/**\n\t * Removes this node from it's parent.\n\t *\n\t * @see module:engine/model/writer~Writer#remove\n\t * @protected\n\t */\n\t_remove() {\n\t\tthis.parent._removeChildren( this.index );\n\t}\n\n\t/**\n\t * Sets attribute on the node. If attribute with the same key already is set, it's value is overwritten.\n\t *\n\t * @see module:engine/model/writer~Writer#setAttribute\n\t * @protected\n\t * @param {String} key Key of attribute to set.\n\t * @param {*} value Attribute value.\n\t */\n\t_setAttribute( key, value ) {\n\t\tthis._attrs.set( key, value );\n\t}\n\n\t/**\n\t * Removes all attributes from the node and sets given attributes.\n\t *\n\t * @see module:engine/model/writer~Writer#setAttributes\n\t * @protected\n\t * @param {Object} [attrs] Attributes to set. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t */\n\t_setAttributesTo( attrs ) {\n\t\tthis._attrs = toMap( attrs );\n\t}\n\n\t/**\n\t * Removes an attribute with given key from the node.\n\t *\n\t * @see module:engine/model/writer~Writer#removeAttribute\n\t * @protected\n\t * @param {String} key Key of attribute to remove.\n\t * @returns {Boolean} `true` if the attribute was set on the element, `false` otherwise.\n\t */\n\t_removeAttribute( key ) {\n\t\treturn this._attrs.delete( key );\n\t}\n\n\t/**\n\t * Removes all attributes from the node.\n\t *\n\t * @see module:engine/model/writer~Writer#clearAttributes\n\t * @protected\n\t */\n\t_clearAttributes() {\n\t\tthis._attrs.clear();\n\t}\n\n\t/**\n\t * Checks whether given model tree object is of given type.\n\t *\n\t * This method is useful when processing model tree objects that are of unknown type. For example, a function\n\t * may return {@link module:engine/model/documentfragment~DocumentFragment} or {@link module:engine/model/node~Node}\n\t * that can be either text node or element. This method can be used to check what kind of object is returned.\n\t *\n\t *\t\tobj.is( 'node' ); // true for any node, false for document fragment and text fragment\n\t *\t\tobj.is( 'documentFragment' ); // true for document fragment, false for any node\n\t *\t\tobj.is( 'element' ); // true for any element, false for text node or document fragment\n\t *\t\tobj.is( 'element', 'paragraph' ); // true only for element which name is 'paragraph'\n\t *\t\tobj.is( 'paragraph' ); // shortcut for obj.is( 'element', 'paragraph' )\n\t *\t\tobj.is( 'text' ); // true for text node, false for element and document fragment\n\t *\t\tobj.is( 'textProxy' ); // true for text proxy object\n\t *\n\t * @method #is\n\t * @param {'element'|'rootElement'|'text'|'textProxy'|'documentFragment'} type\n\t * @returns {Boolean}\n\t */\n\tis( type ) {\n\t\treturn type == 'node';\n\t}\n}\n\n/**\n * The node's parent does not contain this node.\n *\n * This error may be thrown from corrupted trees.\n *\n * @error model-node-not-found-in-parent\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/text\n */\n\nimport Node from './node';\n\n/**\n * Model text node. Type of {@link module:engine/model/node~Node node} that contains {@link module:engine/model/text~Text#data text data}.\n *\n * **Important:** see {@link module:engine/model/node~Node} to read about restrictions using `Text` and `Node` API.\n *\n * **Note:** keep in mind that `Text` instances might indirectly got removed from model tree when model is changed.\n * This happens when {@link module:engine/model/writer~Writer model writer} is used to change model and the text node is merged with\n * another text node. Then, both text nodes are removed and a new text node is inserted into the model. Because of\n * this behavior, keeping references to `Text` is not recommended. Instead, consider creating\n * {@link module:engine/model/liveposition~LivePosition live position} placed before the text node.\n *\n * @extends {module:engine/model/node~Node}\n */\nexport default class Text extends Node {\n\t/**\n\t * Creates a text node.\n\t *\n\t * **Note:** Constructor of this class shouldn't be used directly in the code.\n\t * Use the {@link module:engine/model/writer~Writer#createText} method instead.\n\t *\n\t * @protected\n\t * @param {String} data Node's text.\n\t * @param {Object} [attrs] Node's attributes. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t */\n\tconstructor( data, attrs ) {\n\t\tsuper( attrs );\n\n\t\t/**\n\t\t * Text data contained in this text node.\n\t\t *\n\t\t * @protected\n\t\t * @type {String}\n\t\t */\n\t\tthis._data = data || '';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget offsetSize() {\n\t\treturn this.data.length;\n\t}\n\n\t/**\n\t * Returns a text data contained in the node.\n\t *\n\t * @readonly\n\t * @type {String}\n\t */\n\tget data() {\n\t\treturn this._data;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tis( type ) {\n\t\treturn type == 'text' || super.is( type );\n\t}\n\n\t/**\n\t * Converts `Text` instance to plain object and returns it.\n\t *\n\t * @returns {Object} `Text` instance converted to plain object.\n\t */\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\n\t\tjson.data = this.data;\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Creates a copy of this text node and returns it. Created text node has same text data and attributes as original text node.\n\t *\n\t * @protected\n\t * @returns {module:engine/model/text~Text} `Text` instance created using given plain object.\n\t */\n\t_clone() {\n\t\treturn new Text( this.data, this.getAttributes() );\n\t}\n\n\t/**\n\t * Creates a `Text` instance from given plain object (i.e. parsed JSON string).\n\t *\n\t * @param {Object} json Plain object to be converted to `Text`.\n\t * @returns {module:engine/model/text~Text} `Text` instance created using given plain object.\n\t */\n\tstatic fromJSON( json ) {\n\t\treturn new Text( json.data, json.attributes );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/textproxy\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * `TextProxy` represents a part of {@link module:engine/model/text~Text text node}.\n *\n * Since {@link module:engine/model/position~Position positions} can be placed between characters of a text node,\n * {@link module:engine/model/range~Range ranges} may contain only parts of text nodes. When {@link module:engine/model/range~Range#getItems\n * getting items}\n * contained in such range, we need to represent a part of that text node, since returning the whole text node would be incorrect.\n * `TextProxy` solves this issue.\n *\n * `TextProxy` has an API similar to {@link module:engine/model/text~Text Text} and allows to do most of the common tasks performed\n * on model nodes.\n *\n * **Note:** Some `TextProxy` instances may represent whole text node, not just a part of it.\n * See {@link module:engine/model/textproxy~TextProxy#isPartial}.\n *\n * **Note:** `TextProxy` is not an instance of {@link module:engine/model/node~Node node}. Keep this in mind when using it as a\n * parameter of methods.\n *\n * **Note:** `TextProxy` is a readonly interface. If you want to perform changes on model data represented by a `TextProxy`\n * use {@link module:engine/model/writer~Writer model writer API}.\n *\n * **Note:** `TextProxy` instances are created on the fly, basing on the current state of model. Because of this, it is\n * highly unrecommended to store references to `TextProxy` instances. `TextProxy` instances are not refreshed when\n * model changes, so they might get invalidated. Instead, consider creating {@link module:engine/model/liveposition~LivePosition live\n * position}.\n *\n * `TextProxy` instances are created by {@link module:engine/model/treewalker~TreeWalker model tree walker}. You should not need to create\n * an instance of this class by your own.\n */\nexport default class TextProxy {\n\t/**\n\t * Creates a text proxy.\n\t *\n\t * @protected\n\t * @param {module:engine/model/text~Text} textNode Text node which part is represented by this text proxy.\n\t * @param {Number} offsetInText Offset in {@link module:engine/model/textproxy~TextProxy#textNode text node} from which the text proxy\n\t * starts.\n\t * @param {Number} length Text proxy length, that is how many text node's characters, starting from `offsetInText` it represents.\n\t * @constructor\n\t */\n\tconstructor( textNode, offsetInText, length ) {\n\t\t/**\n\t\t * Text node which part is represented by this text proxy.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/text~Text}\n\t\t */\n\t\tthis.textNode = textNode;\n\n\t\tif ( offsetInText < 0 || offsetInText > textNode.offsetSize ) {\n\t\t\t/**\n\t\t\t * Given `offsetInText` value is incorrect.\n\t\t\t *\n\t\t\t * @error model-textproxy-wrong-offsetintext\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-textproxy-wrong-offsetintext: Given offsetInText value is incorrect.' );\n\t\t}\n\n\t\tif ( length < 0 || offsetInText + length > textNode.offsetSize ) {\n\t\t\t/**\n\t\t\t * Given `length` value is incorrect.\n\t\t\t *\n\t\t\t * @error model-textproxy-wrong-length\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-textproxy-wrong-length: Given length value is incorrect.' );\n\t\t}\n\n\t\t/**\n\t\t * Text data represented by this text proxy.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.data = textNode.data.substring( offsetInText, offsetInText + length );\n\n\t\t/**\n\t\t * Offset in {@link module:engine/model/textproxy~TextProxy#textNode text node} from which the text proxy starts.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t */\n\t\tthis.offsetInText = offsetInText;\n\t}\n\n\t/**\n\t * Offset at which this text proxy starts in it's parent.\n\t *\n\t * @see module:engine/model/node~Node#startOffset\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget startOffset() {\n\t\treturn this.textNode.startOffset !== null ? this.textNode.startOffset + this.offsetInText : null;\n\t}\n\n\t/**\n\t * Offset size of this text proxy. Equal to the number of characters represented by the text proxy.\n\t *\n\t * @see module:engine/model/node~Node#offsetSize\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget offsetSize() {\n\t\treturn this.data.length;\n\t}\n\n\t/**\n\t * Offset at which this text proxy ends in it's parent.\n\t *\n\t * @see module:engine/model/node~Node#endOffset\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget endOffset() {\n\t\treturn this.startOffset !== null ? this.startOffset + this.offsetSize : null;\n\t}\n\n\t/**\n\t * Flag indicating whether `TextProxy` instance covers only part of the original {@link module:engine/model/text~Text text node}\n\t * (`true`) or the whole text node (`false`).\n\t *\n\t * This is `false` when text proxy starts at the very beginning of {@link module:engine/model/textproxy~TextProxy#textNode textNode}\n\t * ({@link module:engine/model/textproxy~TextProxy#offsetInText offsetInText} equals `0`) and text proxy sizes is equal to\n\t * text node size.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isPartial() {\n\t\treturn this.offsetSize !== this.textNode.offsetSize;\n\t}\n\n\t/**\n\t * Parent of this text proxy, which is same as parent of text node represented by this text proxy.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment|null}\n\t */\n\tget parent() {\n\t\treturn this.textNode.parent;\n\t}\n\n\t/**\n\t * Root of this text proxy, which is same as root of text node represented by this text proxy.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/node~Node|module:engine/model/documentfragment~DocumentFragment}\n\t */\n\tget root() {\n\t\treturn this.textNode.root;\n\t}\n\n\t/**\n\t * {@link module:engine/model/document~Document Document} that owns text node represented by this text proxy or `null` if the text node\n\t * has no parent or is inside a {@link module:engine/model/documentfragment~DocumentFragment DocumentFragment}.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/document~Document|null}\n\t */\n\tget document() {\n\t\treturn this.textNode.document;\n\t}\n\n\t/**\n\t * Checks whether given model tree object is of given type.\n\t *\n\t * Read more in {@link module:engine/model/node~Node#is}.\n\t *\n\t * @param {String} type\n\t * @returns {Boolean}\n\t */\n\tis( type ) {\n\t\treturn type == 'textProxy';\n\t}\n\n\t/**\n\t * Gets path to this text proxy.\n\t *\n\t * @see module:engine/model/node~Node#getPath\n\t * @returns {Array.<Number>}\n\t */\n\tgetPath() {\n\t\tconst path = this.textNode.getPath();\n\n\t\tif ( path.length > 0 ) {\n\t\t\tpath[ path.length - 1 ] += this.offsetInText;\n\t\t}\n\n\t\treturn path;\n\t}\n\n\t/**\n\t * Returns ancestors array of this text proxy.\n\t *\n\t * @param {Object} options Options object.\n\t * @param {Boolean} [options.includeSelf=false] When set to `true` this text proxy will be also included in parent's array.\n\t * @param {Boolean} [options.parentFirst=false] When set to `true`, array will be sorted from text proxy parent to root element,\n\t * otherwise root element will be the first item in the array.\n\t * @returns {Array} Array with ancestors.\n\t */\n\tgetAncestors( options = { includeSelf: false, parentFirst: false } ) {\n\t\tconst ancestors = [];\n\t\tlet parent = options.includeSelf ? this : this.parent;\n\n\t\twhile ( parent ) {\n\t\t\tancestors[ options.parentFirst ? 'push' : 'unshift' ]( parent );\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn ancestors;\n\t}\n\n\t/**\n\t * Checks if this text proxy has an attribute for given key.\n\t *\n\t * @param {String} key Key of attribute to check.\n\t * @returns {Boolean} `true` if attribute with given key is set on text proxy, `false` otherwise.\n\t */\n\thasAttribute( key ) {\n\t\treturn this.textNode.hasAttribute( key );\n\t}\n\n\t/**\n\t * Gets an attribute value for given key or `undefined` if that attribute is not set on text proxy.\n\t *\n\t * @param {String} key Key of attribute to look for.\n\t * @returns {*} Attribute value or `undefined`.\n\t */\n\tgetAttribute( key ) {\n\t\treturn this.textNode.getAttribute( key );\n\t}\n\n\t/**\n\t * Returns iterator that iterates over this node's attributes. Attributes are returned as arrays containing two\n\t * items. First one is attribute key and second is attribute value.\n\t *\n\t * This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t *\n\t * @returns {Iterable.<*>}\n\t */\n\tgetAttributes() {\n\t\treturn this.textNode.getAttributes();\n\t}\n\n\t/**\n\t * Returns iterator that iterates over this node's attribute keys.\n\t *\n\t * @returns {Iterable.<String>}\n\t */\n\tgetAttributeKeys() {\n\t\treturn this.textNode.getAttributeKeys();\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/nodelist\n */\n\nimport Node from './node';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Provides an interface to operate on a list of {@link module:engine/model/node~Node nodes}. `NodeList` is used internally\n * in classes like {@link module:engine/model/element~Element Element}\n * or {@link module:engine/model/documentfragment~DocumentFragment DocumentFragment}.\n */\nexport default class NodeList {\n\t/**\n\t * Creates an empty node list.\n\t *\n\t * @protected\n\t * @param {Iterable.<module:engine/model/node~Node>} nodes Nodes contained in this node list.\n\t */\n\tconstructor( nodes ) {\n\t\t/**\n\t\t * Nodes contained in this node list.\n\t\t *\n\t\t * @private\n\t\t * @member {Array.<module:engine/model/node~Node>}\n\t\t */\n\t\tthis._nodes = [];\n\n\t\tif ( nodes ) {\n\t\t\tthis._insertNodes( 0, nodes );\n\t\t}\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * Iterates over all nodes contained inside this node list.\n\t *\n\t * @returns {Iterable.<module:engine/model/node~Node>}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this._nodes[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Number of nodes contained inside this node list.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget length() {\n\t\treturn this._nodes.length;\n\t}\n\n\t/**\n\t * Sum of {@link module:engine/model/node~Node#offsetSize offset sizes} of all nodes contained inside this node list.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget maxOffset() {\n\t\treturn this._nodes.reduce( ( sum, node ) => sum + node.offsetSize, 0 );\n\t}\n\n\t/**\n\t * Gets the node at the given index. Returns `null` if incorrect index was passed.\n\t *\n\t * @param {Number} index Index of node.\n\t * @returns {module:engine/model/node~Node|null} Node at given index.\n\t */\n\tgetNode( index ) {\n\t\treturn this._nodes[ index ] || null;\n\t}\n\n\t/**\n\t * Returns an index of the given node. Returns `null` if given node is not inside this node list.\n\t *\n\t * @param {module:engine/model/node~Node} node Child node to look for.\n\t * @returns {Number|null} Child node's index.\n\t */\n\tgetNodeIndex( node ) {\n\t\tconst index = this._nodes.indexOf( node );\n\n\t\treturn index == -1 ? null : index;\n\t}\n\n\t/**\n\t * Returns the starting offset of given node. Starting offset is equal to the sum of\n\t * {@link module:engine/model/node~Node#offsetSize offset sizes} of all nodes that are before this node in this node list.\n\t *\n\t * @param {module:engine/model/node~Node} node Node to look for.\n\t * @returns {Number|null} Node's starting offset.\n\t */\n\tgetNodeStartOffset( node ) {\n\t\tconst index = this.getNodeIndex( node );\n\n\t\treturn index === null ? null : this._nodes.slice( 0, index ).reduce( ( sum, node ) => sum + node.offsetSize, 0 );\n\t}\n\n\t/**\n\t * Converts index to offset in node list.\n\t *\n\t * Returns starting offset of a node that is at given index. Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError}\n\t * `model-nodelist-index-out-of-bounds` if given index is less than `0` or more than {@link #length}.\n\t *\n\t * @param {Number} index Node's index.\n\t * @returns {Number} Node's starting offset.\n\t */\n\tindexToOffset( index ) {\n\t\tif ( index == this._nodes.length ) {\n\t\t\treturn this.maxOffset;\n\t\t}\n\n\t\tconst node = this._nodes[ index ];\n\n\t\tif ( !node ) {\n\t\t\t/**\n\t\t\t * Given index cannot be found in the node list.\n\t\t\t *\n\t\t\t * @error nodelist-index-out-of-bounds\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-nodelist-index-out-of-bounds: Given index cannot be found in the node list.' );\n\t\t}\n\n\t\treturn this.getNodeStartOffset( node );\n\t}\n\n\t/**\n\t * Converts offset in node list to index.\n\t *\n\t * Returns index of a node that occupies given offset. Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError}\n\t * `model-nodelist-offset-out-of-bounds` if given offset is less than `0` or more than {@link #maxOffset}.\n\t *\n\t * @param {Number} offset Offset to look for.\n\t * @returns {Number} Index of a node that occupies given offset.\n\t */\n\toffsetToIndex( offset ) {\n\t\tlet totalOffset = 0;\n\n\t\tfor ( const node of this._nodes ) {\n\t\t\tif ( offset >= totalOffset && offset < totalOffset + node.offsetSize ) {\n\t\t\t\treturn this.getNodeIndex( node );\n\t\t\t}\n\n\t\t\ttotalOffset += node.offsetSize;\n\t\t}\n\n\t\tif ( totalOffset != offset ) {\n\t\t\t/**\n\t\t\t * Given offset cannot be found in the node list.\n\t\t\t *\n\t\t\t * @error model-nodelist-offset-out-of-bounds\n\t\t\t * @param {Number} offset\n\t\t\t * @param {module:engine/model/nodelist~NodeList} nodeList Stringified node list.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-nodelist-offset-out-of-bounds: Given offset cannot be found in the node list.', {\n\t\t\t\toffset,\n\t\t\t\tnodeList: this\n\t\t\t} );\n\t\t}\n\n\t\treturn this.length;\n\t}\n\n\t/**\n\t * Inserts given nodes at given index.\n\t *\n\t * @protected\n\t * @param {Number} index Index at which nodes should be inserted.\n\t * @param {Iterable.<module:engine/model/node~Node>} nodes Nodes to be inserted.\n\t */\n\t_insertNodes( index, nodes ) {\n\t\t// Validation.\n\t\tfor ( const node of nodes ) {\n\t\t\tif ( !( node instanceof Node ) ) {\n\t\t\t\t/**\n\t\t\t\t * Trying to insert an object which is not a Node instance.\n\t\t\t\t *\n\t\t\t\t * @error nodelist-insertNodes-not-node\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'model-nodelist-insertNodes-not-node: Trying to insert an object which is not a Node instance.' );\n\t\t\t}\n\t\t}\n\n\t\tthis._nodes.splice( index, 0, ...nodes );\n\t}\n\n\t/**\n\t * Removes one or more nodes starting at the given index.\n\t *\n\t * @protected\n\t * @param {Number} indexStart Index of the first node to remove.\n\t * @param {Number} [howMany=1] Number of nodes to remove.\n\t * @returns {Array.<module:engine/model/node~Node>} Array containing removed nodes.\n\t */\n\t_removeNodes( indexStart, howMany = 1 ) {\n\t\treturn this._nodes.splice( indexStart, howMany );\n\t}\n\n\t/**\n\t * Converts `NodeList` instance to an array containing nodes that were inserted in the node list. Nodes\n\t * are also converted to their plain object representation.\n\t *\n\t * @returns {Array.<module:engine/model/node~Node>} `NodeList` instance converted to `Array`.\n\t */\n\ttoJSON() {\n\t\treturn this._nodes.map( node => node.toJSON() );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/element\n */\n\nimport Node from './node';\nimport NodeList from './nodelist';\nimport Text from './text';\nimport TextProxy from './textproxy';\nimport isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';\n\n/**\n * Model element. Type of {@link module:engine/model/node~Node node} that has a {@link module:engine/model/element~Element#name name} and\n * {@link module:engine/model/element~Element#getChildren child nodes}.\n *\n * **Important**: see {@link module:engine/model/node~Node} to read about restrictions using `Element` and `Node` API.\n *\n * @extends {module:engine/model/node~Node}\n */\nexport default class Element extends Node {\n\t/**\n\t * Creates a model element.\n\t *\n\t * **Note:** Constructor of this class shouldn't be used directly in the code.\n\t * Use the {@link module:engine/model/writer~Writer#createElement} method instead.\n\t *\n\t * @protected\n\t * @param {String} name Element's name.\n\t * @param {Object} [attrs] Element's attributes. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t * @param {module:engine/model/node~Node|Iterable.<module:engine/model/node~Node>} [children]\n\t * One or more nodes to be inserted as children of created element.\n\t */\n\tconstructor( name, attrs, children ) {\n\t\tsuper( attrs );\n\n\t\t/**\n\t\t * Element name.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String} module:engine/model/element~Element#name\n\t\t */\n\t\tthis.name = name;\n\n\t\t/**\n\t\t * List of children nodes.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/nodelist~NodeList} module:engine/model/element~Element#_children\n\t\t */\n\t\tthis._children = new NodeList();\n\n\t\tif ( children ) {\n\t\t\tthis._insertChild( 0, children );\n\t\t}\n\t}\n\n\t/**\n\t * Number of this element's children.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget childCount() {\n\t\treturn this._children.length;\n\t}\n\n\t/**\n\t * Sum of {@link module:engine/model/node~Node#offsetSize offset sizes} of all of this element's children.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget maxOffset() {\n\t\treturn this._children.maxOffset;\n\t}\n\n\t/**\n\t * Is `true` if there are no nodes inside this element, `false` otherwise.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isEmpty() {\n\t\treturn this.childCount === 0;\n\t}\n\n\t/**\n\t * Checks whether this model object is of the given type.\n\t *\n\t *\t\tobj.name; // 'listItem'\n\t *\t\tobj instanceof Element; // true\n\t *\n\t *\t\tobj.is( 'element' ); // true\n\t *\t\tobj.is( 'listItem' ); // true\n\t *\t\tobj.is( 'element', 'listItem' ); // true\n\t *\t\tobj.is( 'text' ); // false\n\t *\t\tobj.is( 'element', 'image' ); // false\n\t *\n\t * Read more in {@link module:engine/model/node~Node#is `Node#is()`}.\n\t *\n\t * @param {String} type Type to check when `name` parameter is present.\n\t * Otherwise, it acts like the `name` parameter.\n\t * @param {String} [name] Element name.\n\t * @returns {Boolean}\n\t */\n\tis( type, name = null ) {\n\t\tif ( !name ) {\n\t\t\treturn type == 'element' || type == this.name || super.is( type );\n\t\t} else {\n\t\t\treturn type == 'element' && name == this.name;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the child at the given index.\n\t *\n\t * @param {Number} index Index of child.\n\t * @returns {module:engine/model/node~Node} Child node.\n\t */\n\tgetChild( index ) {\n\t\treturn this._children.getNode( index );\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all of this element's children.\n\t *\n\t * @returns {Iterable.<module:engine/model/node~Node>}\n\t */\n\tgetChildren() {\n\t\treturn this._children[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Returns an index of the given child node. Returns `null` if given node is not a child of this element.\n\t *\n\t * @param {module:engine/model/node~Node} node Child node to look for.\n\t * @returns {Number} Child node's index in this element.\n\t */\n\tgetChildIndex( node ) {\n\t\treturn this._children.getNodeIndex( node );\n\t}\n\n\t/**\n\t * Returns the starting offset of given child. Starting offset is equal to the sum of\n\t * {@link module:engine/model/node~Node#offsetSize offset sizes} of all node's siblings that are before it. Returns `null` if\n\t * given node is not a child of this element.\n\t *\n\t * @param {module:engine/model/node~Node} node Child node to look for.\n\t * @returns {Number} Child node's starting offset.\n\t */\n\tgetChildStartOffset( node ) {\n\t\treturn this._children.getNodeStartOffset( node );\n\t}\n\n\t/**\n\t * Returns index of a node that occupies given offset. If given offset is too low, returns `0`. If given offset is\n\t * too high, returns {@link module:engine/model/element~Element#getChildIndex index after last child}.\n\t *\n\t *\t\tconst textNode = new Text( 'foo' );\n\t *\t\tconst pElement = new Element( 'p' );\n\t *\t\tconst divElement = new Element( [ textNode, pElement ] );\n\t *\t\tdivElement.offsetToIndex( -1 ); // Returns 0, because offset is too low.\n\t *\t\tdivElement.offsetToIndex( 0 ); // Returns 0, because offset 0 is taken by `textNode` which is at index 0.\n\t *\t\tdivElement.offsetToIndex( 1 ); // Returns 0, because `textNode` has `offsetSize` equal to 3, so it occupies offset 1 too.\n\t *\t\tdivElement.offsetToIndex( 2 ); // Returns 0.\n\t *\t\tdivElement.offsetToIndex( 3 ); // Returns 1.\n\t *\t\tdivElement.offsetToIndex( 4 ); // Returns 2. There are no nodes at offset 4, so last available index is returned.\n\t *\n\t * @param {Number} offset Offset to look for.\n\t * @returns {Number}\n\t */\n\toffsetToIndex( offset ) {\n\t\treturn this._children.offsetToIndex( offset );\n\t}\n\n\t/**\n\t * Returns a descendant node by its path relative to this element.\n\t *\n\t *\t\t// <this>a<b>c</b></this>\n\t *\t\tthis.getNodeByPath( [ 0 ] ); // -> \"a\"\n\t *\t\tthis.getNodeByPath( [ 1 ] ); // -> <b>\n\t *\t\tthis.getNodeByPath( [ 1, 0 ] ); // -> \"c\"\n\t *\n\t * @param {Array.<Number>} relativePath Path of the node to find, relative to this element.\n\t * @returns {module:engine/model/node~Node}\n\t */\n\tgetNodeByPath( relativePath ) {\n\t\tlet node = this; // eslint-disable-line consistent-this\n\n\t\tfor ( const index of relativePath ) {\n\t\t\tnode = node.getChild( node.offsetToIndex( index ) );\n\t\t}\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Converts `Element` instance to plain object and returns it. Takes care of converting all of this element's children.\n\t *\n\t * @returns {Object} `Element` instance converted to plain object.\n\t */\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\n\t\tjson.name = this.name;\n\n\t\tif ( this._children.length > 0 ) {\n\t\t\tjson.children = [];\n\n\t\t\tfor ( const node of this._children ) {\n\t\t\t\tjson.children.push( node.toJSON() );\n\t\t\t}\n\t\t}\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Creates a copy of this element and returns it. Created element has the same name and attributes as the original element.\n\t * If clone is deep, the original element's children are also cloned. If not, then empty element is removed.\n\t *\n\t * @protected\n\t * @param {Boolean} [deep=false] If set to `true` clones element and all its children recursively. When set to `false`,\n\t * element will be cloned without any child.\n\t */\n\t_clone( deep = false ) {\n\t\tconst children = deep ? Array.from( this._children ).map( node => node._clone( true ) ) : null;\n\n\t\treturn new Element( this.name, this.getAttributes(), children );\n\t}\n\n\t/**\n\t * {@link module:engine/model/element~Element#_insertChild Inserts} one or more nodes at the end of this element.\n\t *\n\t * @see module:engine/model/writer~Writer#append\n\t * @protected\n\t * @param {module:engine/model/item~Item|Iterable.<module:engine/model/item~Item>} nodes Nodes to be inserted.\n\t */\n\t_appendChild( nodes ) {\n\t\tthis._insertChild( this.childCount, nodes );\n\t}\n\n\t/**\n\t * Inserts one or more nodes at the given index and sets {@link module:engine/model/node~Node#parent parent} of these nodes\n\t * to this element.\n\t *\n\t * @see module:engine/model/writer~Writer#insert\n\t * @protected\n\t * @param {Number} index Index at which nodes should be inserted.\n\t * @param {module:engine/model/item~Item|Iterable.<module:engine/model/item~Item>} items Items to be inserted.\n\t */\n\t_insertChild( index, items ) {\n\t\tconst nodes = normalize( items );\n\n\t\tfor ( const node of nodes ) {\n\t\t\t// If node that is being added to this element is already inside another element, first remove it from the old parent.\n\t\t\tif ( node.parent !== null ) {\n\t\t\t\tnode._remove();\n\t\t\t}\n\n\t\t\tnode.parent = this;\n\t\t}\n\n\t\tthis._children._insertNodes( index, nodes );\n\t}\n\n\t/**\n\t * Removes one or more nodes starting at the given index and sets\n\t * {@link module:engine/model/node~Node#parent parent} of these nodes to `null`.\n\t *\n\t * @see module:engine/model/writer~Writer#remove\n\t * @protected\n\t * @param {Number} index Index of the first node to remove.\n\t * @param {Number} [howMany=1] Number of nodes to remove.\n\t * @returns {Array.<module:engine/model/node~Node>} Array containing removed nodes.\n\t */\n\t_removeChildren( index, howMany = 1 ) {\n\t\tconst nodes = this._children._removeNodes( index, howMany );\n\n\t\tfor ( const node of nodes ) {\n\t\t\tnode.parent = null;\n\t\t}\n\n\t\treturn nodes;\n\t}\n\n\t/**\n\t * Creates an `Element` instance from given plain object (i.e. parsed JSON string).\n\t * Converts `Element` children to proper nodes.\n\t *\n\t * @param {Object} json Plain object to be converted to `Element`.\n\t * @returns {module:engine/model/element~Element} `Element` instance created using given plain object.\n\t */\n\tstatic fromJSON( json ) {\n\t\tlet children = null;\n\n\t\tif ( json.children ) {\n\t\t\tchildren = [];\n\n\t\t\tfor ( const child of json.children ) {\n\t\t\t\tif ( child.name ) {\n\t\t\t\t\t// If child has name property, it is an Element.\n\t\t\t\t\tchildren.push( Element.fromJSON( child ) );\n\t\t\t\t} else {\n\t\t\t\t\t// Otherwise, it is a Text node.\n\t\t\t\t\tchildren.push( Text.fromJSON( child ) );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn new Element( json.name, json.attributes, children );\n\t}\n}\n\n// Converts strings to Text and non-iterables to arrays.\n//\n// @param {String|module:engine/model/item~Item|Iterable.<String|module:engine/model/item~Item>}\n// @returns {Iterable.<module:engine/model/node~Node>}\nfunction normalize( nodes ) {\n\t// Separate condition because string is iterable.\n\tif ( typeof nodes == 'string' ) {\n\t\treturn [ new Text( nodes ) ];\n\t}\n\n\tif ( !isIterable( nodes ) ) {\n\t\tnodes = [ nodes ];\n\t}\n\n\t// Array.from to enable .map() on non-arrays.\n\treturn Array.from( nodes )\n\t\t.map( node => {\n\t\t\tif ( typeof node == 'string' ) {\n\t\t\t\treturn new Text( node );\n\t\t\t}\n\n\t\t\tif ( node instanceof TextProxy ) {\n\t\t\t\treturn new Text( node.data, node.getAttributes() );\n\t\t\t}\n\n\t\t\treturn node;\n\t\t} );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/treewalker\n */\n\nimport Text from './text';\nimport TextProxy from './textproxy';\nimport Element from './element';\nimport Position from './position';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Position iterator class. It allows to iterate forward and backward over the document.\n */\nexport default class TreeWalker {\n\t/**\n\t * Creates a range iterator. All parameters are optional, but you have to specify either `boundaries` or `startPosition`.\n\t *\n\t * @constructor\n\t * @param {Object} [options={}] Object with configuration.\n\t * @param {'forward'|'backward'} [options.direction='forward'] Walking direction.\n\t * @param {module:engine/model/range~Range} [options.boundaries=null] Range to define boundaries of the iterator.\n\t * @param {module:engine/model/position~Position} [options.startPosition] Starting position.\n\t * @param {Boolean} [options.singleCharacters=false] Flag indicating whether all consecutive characters with the same attributes\n\t * should be returned one by one as multiple {@link module:engine/model/textproxy~TextProxy} (`true`) objects or as one\n\t * {@link module:engine/model/textproxy~TextProxy} (`false`).\n\t * @param {Boolean} [options.shallow=false] Flag indicating whether iterator should enter elements or not. If the\n\t * iterator is shallow child nodes of any iterated node will not be returned along with `elementEnd` tag.\n\t * @param {Boolean} [options.ignoreElementEnd=false] Flag indicating whether iterator should ignore `elementEnd`\n\t * tags. If the option is true walker will not return a parent node of start position. If this option is `true`\n\t * each {@link module:engine/model/element~Element} will be returned once, while if the option is `false` they might be returned\n\t * twice: for `'elementStart'` and `'elementEnd'`.\n\t */\n\tconstructor( options = {} ) {\n\t\tif ( !options.boundaries && !options.startPosition ) {\n\t\t\t/**\n\t\t\t * Neither boundaries nor starting position of a `TreeWalker` have been defined.\n\t\t\t *\n\t\t\t * @error model-tree-walker-no-start-position\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-tree-walker-no-start-position: Neither boundaries nor starting position have been defined.' );\n\t\t}\n\n\t\tconst direction = options.direction || 'forward';\n\n\t\tif ( direction != 'forward' && direction != 'backward' ) {\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'model-tree-walker-unknown-direction: Only `backward` and `forward` direction allowed.',\n\t\t\t\t{ direction }\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Walking direction. Defaults `'forward'`.\n\t\t *\n\t\t * @readonly\n\t\t * @member {'backward'|'forward'} module:engine/model/treewalker~TreeWalker#direction\n\t\t */\n\t\tthis.direction = direction;\n\n\t\t/**\n\t\t * Iterator boundaries.\n\t\t *\n\t\t * When the iterator is walking `'forward'` on the end of boundary or is walking `'backward'`\n\t\t * on the start of boundary, then `{ done: true }` is returned.\n\t\t *\n\t\t * If boundaries are not defined they are set before first and after last child of the root node.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/range~Range} module:engine/model/treewalker~TreeWalker#boundaries\n\t\t */\n\t\tthis.boundaries = options.boundaries || null;\n\n\t\t/**\n\t\t * Iterator position. This is always static position, even if the initial position was a\n\t\t * {@link module:engine/model/liveposition~LivePosition live position}. If start position is not defined then position depends\n\t\t * on {@link #direction}. If direction is `'forward'` position starts form the beginning, when direction\n\t\t * is `'backward'` position starts from the end.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/position~Position} module:engine/model/treewalker~TreeWalker#position\n\t\t */\n\t\tif ( options.startPosition ) {\n\t\t\tthis.position = options.startPosition.clone();\n\t\t} else {\n\t\t\tthis.position = Position._createAt( this.boundaries[ this.direction == 'backward' ? 'end' : 'start' ] );\n\t\t}\n\n\t\t// Reset position stickiness in case it was set to other value, as the stickiness is kept after cloning.\n\t\tthis.position.stickiness = 'toNone';\n\n\t\t/**\n\t\t * Flag indicating whether all consecutive characters with the same attributes should be\n\t\t * returned as one {@link module:engine/model/textproxy~TextProxy} (`true`) or one by one (`false`).\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} module:engine/model/treewalker~TreeWalker#singleCharacters\n\t\t */\n\t\tthis.singleCharacters = !!options.singleCharacters;\n\n\t\t/**\n\t\t * Flag indicating whether iterator should enter elements or not. If the iterator is shallow child nodes of any\n\t\t * iterated node will not be returned along with `elementEnd` tag.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} module:engine/model/treewalker~TreeWalker#shallow\n\t\t */\n\t\tthis.shallow = !!options.shallow;\n\n\t\t/**\n\t\t * Flag indicating whether iterator should ignore `elementEnd` tags. If the option is true walker will not\n\t\t * return a parent node of the start position. If this option is `true` each {@link module:engine/model/element~Element} will\n\t\t * be returned once, while if the option is `false` they might be returned twice:\n\t\t * for `'elementStart'` and `'elementEnd'`.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} module:engine/model/treewalker~TreeWalker#ignoreElementEnd\n\t\t */\n\t\tthis.ignoreElementEnd = !!options.ignoreElementEnd;\n\n\t\t/**\n\t\t * Start boundary cached for optimization purposes.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/element~Element} module:engine/model/treewalker~TreeWalker#_boundaryStartParent\n\t\t */\n\t\tthis._boundaryStartParent = this.boundaries ? this.boundaries.start.parent : null;\n\n\t\t/**\n\t\t * End boundary cached for optimization purposes.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/element~Element} module:engine/model/treewalker~TreeWalker#_boundaryEndParent\n\t\t */\n\t\tthis._boundaryEndParent = this.boundaries ? this.boundaries.end.parent : null;\n\n\t\t/**\n\t\t * Parent of the most recently visited node. Cached for optimization purposes.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment}\n\t\t * module:engine/model/treewalker~TreeWalker#_visitedParent\n\t\t */\n\t\tthis._visitedParent = this.position.parent;\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * @returns {Iterable.<module:engine/model/treewalker~TreeWalkerValue>}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Moves {@link #position} in the {@link #direction} skipping values as long as the callback function returns `true`.\n\t *\n\t * For example:\n\t *\n\t * \t\twalker.skip( value => value.type == 'text' ); // <paragraph>[]foo</paragraph> -> <paragraph>foo[]</paragraph>\n\t * \t\twalker.skip( () => true ); // Move the position to the end: <paragraph>[]foo</paragraph> -> <paragraph>foo</paragraph>[]\n\t * \t\twalker.skip( () => false ); // Do not move the position.\n\t *\n\t * @param {Function} skip Callback function. Gets {@link module:engine/model/treewalker~TreeWalkerValue} and should\n\t * return `true` if the value should be skipped or `false` if not.\n\t */\n\tskip( skip ) {\n\t\tlet done, value, prevPosition, prevVisitedParent;\n\n\t\tdo {\n\t\t\tprevPosition = this.position;\n\t\t\tprevVisitedParent = this._visitedParent;\n\n\t\t\t( { done, value } = this.next() );\n\t\t} while ( !done && skip( value ) );\n\n\t\tif ( !done ) {\n\t\t\tthis.position = prevPosition;\n\t\t\tthis._visitedParent = prevVisitedParent;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the next tree walker's value.\n\t *\n\t * @returns {module:engine/model/treewalker~TreeWalkerValue} Next tree walker's value.\n\t */\n\tnext() {\n\t\tif ( this.direction == 'forward' ) {\n\t\t\treturn this._next();\n\t\t} else {\n\t\t\treturn this._previous();\n\t\t}\n\t}\n\n\t/**\n\t * Makes a step forward in model. Moves the {@link #position} to the next position and returns the encountered value.\n\t *\n\t * @private\n\t * @returns {Object}\n\t * @returns {Boolean} return.done True if iterator is done.\n\t * @returns {module:engine/model/treewalker~TreeWalkerValue} return.value Information about taken step.\n\t */\n\t_next() {\n\t\tconst previousPosition = this.position;\n\t\tconst position = this.position.clone();\n\t\tconst parent = this._visitedParent;\n\n\t\t// We are at the end of the root.\n\t\tif ( parent.parent === null && position.offset === parent.maxOffset ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// We reached the walker boundary.\n\t\tif ( parent === this._boundaryEndParent && position.offset == this.boundaries.end.offset ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\tconst node = position.textNode ? position.textNode : position.nodeAfter;\n\n\t\tif ( node instanceof Element ) {\n\t\t\tif ( !this.shallow ) {\n\t\t\t\t// Manual operations on path internals for optimization purposes. Here and in the rest of the method.\n\t\t\t\tposition.path.push( 0 );\n\t\t\t\tthis._visitedParent = node;\n\t\t\t} else {\n\t\t\t\tposition.offset++;\n\t\t\t}\n\n\t\t\tthis.position = position;\n\n\t\t\treturn formatReturnValue( 'elementStart', node, previousPosition, position, 1 );\n\t\t} else if ( node instanceof Text ) {\n\t\t\tlet charactersCount;\n\n\t\t\tif ( this.singleCharacters ) {\n\t\t\t\tcharactersCount = 1;\n\t\t\t} else {\n\t\t\t\tlet offset = node.endOffset;\n\n\t\t\t\tif ( this._boundaryEndParent == parent && this.boundaries.end.offset < offset ) {\n\t\t\t\t\toffset = this.boundaries.end.offset;\n\t\t\t\t}\n\n\t\t\t\tcharactersCount = offset - position.offset;\n\t\t\t}\n\n\t\t\tconst offsetInTextNode = position.offset - node.startOffset;\n\t\t\tconst item = new TextProxy( node, offsetInTextNode, charactersCount );\n\n\t\t\tposition.offset += charactersCount;\n\t\t\tthis.position = position;\n\n\t\t\treturn formatReturnValue( 'text', item, previousPosition, position, charactersCount );\n\t\t} else {\n\t\t\t// `node` is not set, we reached the end of current `parent`.\n\t\t\tposition.path.pop();\n\t\t\tposition.offset++;\n\t\t\tthis.position = position;\n\t\t\tthis._visitedParent = parent.parent;\n\n\t\t\tif ( this.ignoreElementEnd ) {\n\t\t\t\treturn this._next();\n\t\t\t} else {\n\t\t\t\treturn formatReturnValue( 'elementEnd', parent, previousPosition, position );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Makes a step backward in model. Moves the {@link #position} to the previous position and returns the encountered value.\n\t *\n\t * @private\n\t * @returns {Object}\n\t * @returns {Boolean} return.done True if iterator is done.\n\t * @returns {module:engine/model/treewalker~TreeWalkerValue} return.value Information about taken step.\n\t */\n\t_previous() {\n\t\tconst previousPosition = this.position;\n\t\tconst position = this.position.clone();\n\t\tconst parent = this._visitedParent;\n\n\t\t// We are at the beginning of the root.\n\t\tif ( parent.parent === null && position.offset === 0 ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// We reached the walker boundary.\n\t\tif ( parent == this._boundaryStartParent && position.offset == this.boundaries.start.offset ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// Get node just before current position\n\t\tconst node = position.textNode ? position.textNode : position.nodeBefore;\n\n\t\tif ( node instanceof Element ) {\n\t\t\tposition.offset--;\n\n\t\t\tif ( !this.shallow ) {\n\t\t\t\tposition.path.push( node.maxOffset );\n\t\t\t\tthis.position = position;\n\t\t\t\tthis._visitedParent = node;\n\n\t\t\t\tif ( this.ignoreElementEnd ) {\n\t\t\t\t\treturn this._previous();\n\t\t\t\t} else {\n\t\t\t\t\treturn formatReturnValue( 'elementEnd', node, previousPosition, position );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.position = position;\n\n\t\t\t\treturn formatReturnValue( 'elementStart', node, previousPosition, position, 1 );\n\t\t\t}\n\t\t} else if ( node instanceof Text ) {\n\t\t\tlet charactersCount;\n\n\t\t\tif ( this.singleCharacters ) {\n\t\t\t\tcharactersCount = 1;\n\t\t\t} else {\n\t\t\t\tlet offset = node.startOffset;\n\n\t\t\t\tif ( this._boundaryStartParent == parent && this.boundaries.start.offset > offset ) {\n\t\t\t\t\toffset = this.boundaries.start.offset;\n\t\t\t\t}\n\n\t\t\t\tcharactersCount = position.offset - offset;\n\t\t\t}\n\n\t\t\tconst offsetInTextNode = position.offset - node.startOffset;\n\t\t\tconst item = new TextProxy( node, offsetInTextNode - charactersCount, charactersCount );\n\n\t\t\tposition.offset -= charactersCount;\n\t\t\tthis.position = position;\n\n\t\t\treturn formatReturnValue( 'text', item, previousPosition, position, charactersCount );\n\t\t} else {\n\t\t\t// `node` is not set, we reached the beginning of current `parent`.\n\t\t\tposition.path.pop();\n\t\t\tthis.position = position;\n\t\t\tthis._visitedParent = parent.parent;\n\n\t\t\treturn formatReturnValue( 'elementStart', parent, previousPosition, position, 1 );\n\t\t}\n\t}\n}\n\nfunction formatReturnValue( type, item, previousPosition, nextPosition, length ) {\n\treturn {\n\t\tdone: false,\n\t\tvalue: {\n\t\t\ttype,\n\t\t\titem,\n\t\t\tpreviousPosition,\n\t\t\tnextPosition,\n\t\t\tlength\n\t\t}\n\t};\n}\n\n/**\n * Type of the step made by {@link module:engine/model/treewalker~TreeWalker}.\n * Possible values: `'elementStart'` if walker is at the beginning of a node, `'elementEnd'` if walker is at the end of node,\n * `'character'` if walker traversed over a character, or `'text'` if walker traversed over multiple characters (available in\n * character merging mode, see {@link module:engine/model/treewalker~TreeWalker#constructor}).\n *\n * @typedef {'elementStart'|'elementEnd'|'character'|'text'} module:engine/model/treewalker~TreeWalkerValueType\n */\n\n/**\n * Object returned by {@link module:engine/model/treewalker~TreeWalker} when traversing tree model.\n *\n * @typedef {Object} module:engine/model/treewalker~TreeWalkerValue\n * @property {module:engine/model/treewalker~TreeWalkerValueType} type\n * @property {module:engine/model/item~Item} item Item between old and new positions of {@link module:engine/model/treewalker~TreeWalker}.\n * @property {module:engine/model/position~Position} previousPosition Previous position of the iterator.\n * * Forward iteration: For `'elementEnd'` it is the last position inside the element. For all other types it is the\n * position before the item.\n * * Backward iteration: For `'elementStart'` it is the first position inside the element. For all other types it is\n * the position after item.\n * @property {module:engine/model/position~Position} nextPosition Next position of the iterator.\n * * Forward iteration: For `'elementStart'` it is the first position inside the element. For all other types it is\n * the position after the item.\n * * Backward iteration: For `'elementEnd'` it is last position inside element. For all other types it is the position\n * before the item.\n * @property {Number} [length] Length of the item. For `'elementStart'` and `'character'` it is 1. For `'text'` it is\n * the length of the text. For `'elementEnd'` it is `undefined`.\n */\n\n/**\n * Tree walking directions.\n *\n * @typedef {'forward'|'backward'} module:engine/view/treewalker~TreeWalkerDirection\n */\n","/**\n * Gets the last element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {*} Returns the last element of `array`.\n * @example\n *\n * _.last([1, 2, 3]);\n * // => 3\n */\nfunction last(array) {\n var length = array == null ? 0 : array.length;\n return length ? array[length - 1] : undefined;\n}\n\nexport default last;\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/position\n */\n\nimport TreeWalker from './treewalker';\nimport compareArrays from '@ckeditor/ckeditor5-utils/src/comparearrays';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport Text from './text';\nimport { last } from 'lodash-es';\n\n// To check if component is loaded more than once.\nimport '@ckeditor/ckeditor5-utils/src/version';\n\n/**\n * Represents a position in the model tree.\n *\n * A position is represented by its {@link module:engine/model/position~Position#root} and\n * a {@link module:engine/model/position~Position#path} in that root.\n *\n * You can create position instances via its constructor or the `createPosition*()` factory methods of\n * {@link module:engine/model/model~Model} and {@link module:engine/model/writer~Writer}.\n *\n * **Note:** Position is based on offsets, not indexes. This means that a position between two text nodes\n * `foo` and `bar` has offset `3`, not `1`. See {@link module:engine/model/position~Position#path} for more information.\n *\n * Since a position in the model is represented by a {@link module:engine/model/position~Position#root position root} and\n * {@link module:engine/model/position~Position#path position path} it is possible to create positions placed in non-existing places.\n * This requirement is important for operational transformation algorithms.\n *\n * Also, {@link module:engine/model/operation/operation~Operation operations}\n * kept in the {@link module:engine/model/document~Document#history document history}\n * are storing positions (and ranges) which were correct when those operations were applied, but may not be correct\n * after the document has changed.\n *\n * When changes are applied to the model, it may also happen that {@link module:engine/model/position~Position#parent position parent}\n * will change even if position path has not changed. Keep in mind, that if a position leads to non-existing element,\n * {@link module:engine/model/position~Position#parent} and some other properties and methods will throw errors.\n *\n * In most cases, position with wrong path is caused by an error in code, but it is sometimes needed, as described above.\n */\nexport default class Position {\n\t/**\n\t * Creates a position.\n\t *\n\t * @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} root Root of the position.\n\t * @param {Array.<Number>} path Position path. See {@link module:engine/model/position~Position#path}.\n\t * @param {module:engine/model/position~PositionStickiness} [stickiness='toNone'] Position stickiness.\n\t * See {@link module:engine/model/position~PositionStickiness}.\n\t */\n\tconstructor( root, path, stickiness = 'toNone' ) {\n\t\tif ( !root.is( 'element' ) && !root.is( 'documentFragment' ) ) {\n\t\t\t/**\n\t\t\t * Position root is invalid.\n\t\t\t *\n\t\t\t * Positions can only be anchored in elements or document fragments.\n\t\t\t *\n\t\t\t * @error model-position-root-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-position-root-invalid: Position root invalid.' );\n\t\t}\n\n\t\tif ( !( path instanceof Array ) || path.length === 0 ) {\n\t\t\t/**\n\t\t\t * Position path must be an array with at least one item.\n\t\t\t *\n\t\t\t * @error model-position-path-incorrect\n\t\t\t * @param path\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-position-path-incorrect: Position path must be an array with at least one item.', { path } );\n\t\t}\n\n\t\t// Normalize the root and path (if element was passed).\n\t\tpath = root.getPath().concat( path );\n\t\troot = root.root;\n\n\t\t/**\n\t\t * Root of the position path.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment}\n\t\t * module:engine/model/position~Position#root\n\t\t */\n\t\tthis.root = root;\n\n\t\t/**\n\t\t * Position of the node in the tree. **Path contains offsets, not indexes.**\n\t\t *\n\t\t * Position can be placed before, after or in a {@link module:engine/model/node~Node node} if that node has\n\t\t * {@link module:engine/model/node~Node#offsetSize} greater than `1`. Items in position path are\n\t\t * {@link module:engine/model/node~Node#startOffset starting offsets} of position ancestors, starting from direct root children,\n\t\t * down to the position offset in it's parent.\n\t\t *\n\t\t *\t\t ROOT\n\t\t *\t\t |- P before: [ 0 ] after: [ 1 ]\n\t\t *\t\t |- UL before: [ 1 ] after: [ 2 ]\n\t\t *\t\t |- LI before: [ 1, 0 ] after: [ 1, 1 ]\n\t\t *\t\t | |- foo before: [ 1, 0, 0 ] after: [ 1, 0, 3 ]\n\t\t *\t\t |- LI before: [ 1, 1 ] after: [ 1, 2 ]\n\t\t *\t\t |- bar before: [ 1, 1, 0 ] after: [ 1, 1, 3 ]\n\t\t *\n\t\t * `foo` and `bar` are representing {@link module:engine/model/text~Text text nodes}. Since text nodes has offset size\n\t\t * greater than `1` you can place position offset between their start and end:\n\t\t *\n\t\t *\t\t ROOT\n\t\t *\t\t |- P\n\t\t *\t\t |- UL\n\t\t *\t\t |- LI\n\t\t *\t\t | |- f^o|o ^ has path: [ 1, 0, 1 ] | has path: [ 1, 0, 2 ]\n\t\t *\t\t |- LI\n\t\t *\t\t |- b^a|r ^ has path: [ 1, 1, 1 ] | has path: [ 1, 1, 2 ]\n\t\t *\n\t\t * @readonly\n\t\t * @member {Array.<Number>} module:engine/model/position~Position#path\n\t\t */\n\t\tthis.path = path;\n\n\t\t/**\n\t\t * Position stickiness. See {@link module:engine/model/position~PositionStickiness}.\n\t\t *\n\t\t * @member {module:engine/model/position~PositionStickiness} module:engine/model/position~Position#stickiness\n\t\t */\n\t\tthis.stickiness = stickiness;\n\t}\n\n\t/**\n\t * Offset at which this position is located in its {@link module:engine/model/position~Position#parent parent}. It is equal\n\t * to the last item in position {@link module:engine/model/position~Position#path path}.\n\t *\n\t * @type {Number}\n\t */\n\tget offset() {\n\t\treturn last( this.path );\n\t}\n\n\t/**\n\t * @param {Number} newOffset\n\t */\n\tset offset( newOffset ) {\n\t\tthis.path[ this.path.length - 1 ] = newOffset;\n\t}\n\n\t/**\n\t * Parent element of this position.\n\t *\n\t * Keep in mind that `parent` value is calculated when the property is accessed.\n\t * If {@link module:engine/model/position~Position#path position path}\n\t * leads to a non-existing element, `parent` property will throw error.\n\t *\n\t * Also it is a good idea to cache `parent` property if it is used frequently in an algorithm (i.e. in a long loop).\n\t *\n\t * @readonly\n\t * @type {module:engine/model/element~Element}\n\t */\n\tget parent() {\n\t\tlet parent = this.root;\n\n\t\tfor ( let i = 0; i < this.path.length - 1; i++ ) {\n\t\t\tparent = parent.getChild( parent.offsetToIndex( this.path[ i ] ) );\n\t\t}\n\n\t\treturn parent;\n\t}\n\n\t/**\n\t * Position {@link module:engine/model/position~Position#offset offset} converted to an index in position's parent node. It is\n\t * equal to the {@link module:engine/model/node~Node#index index} of a node after this position. If position is placed\n\t * in text node, position index is equal to the index of that text node.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget index() {\n\t\treturn this.parent.offsetToIndex( this.offset );\n\t}\n\n\t/**\n\t * Returns {@link module:engine/model/text~Text text node} instance in which this position is placed or `null` if this\n\t * position is not in a text node.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/text~Text|null}\n\t */\n\tget textNode() {\n\t\tconst node = this.parent.getChild( this.index );\n\n\t\treturn ( node instanceof Text && node.startOffset < this.offset ) ? node : null;\n\t}\n\n\t/**\n\t * Node directly after this position or `null` if this position is in text node.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/node~Node|null}\n\t */\n\tget nodeAfter() {\n\t\treturn this.textNode === null ? this.parent.getChild( this.index ) : null;\n\t}\n\n\t/**\n\t * Node directly before this position or `null` if this position is in text node.\n\t *\n\t * @readonly\n\t * @type {Node}\n\t */\n\tget nodeBefore() {\n\t\treturn this.textNode === null ? this.parent.getChild( this.index - 1 ) : null;\n\t}\n\n\t/**\n\t * Is `true` if position is at the beginning of its {@link module:engine/model/position~Position#parent parent}, `false` otherwise.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isAtStart() {\n\t\treturn this.offset === 0;\n\t}\n\n\t/**\n\t * Is `true` if position is at the end of its {@link module:engine/model/position~Position#parent parent}, `false` otherwise.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isAtEnd() {\n\t\treturn this.offset == this.parent.maxOffset;\n\t}\n\n\t/**\n\t * Checks whether this position is before or after given position.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param {module:engine/model/position~Position} otherPosition Position to compare with.\n\t * @returns {module:engine/model/position~PositionRelation}\n\t */\n\tcompareWith( otherPosition ) {\n\t\tif ( this.root != otherPosition.root ) {\n\t\t\treturn 'different';\n\t\t}\n\n\t\tconst result = compareArrays( this.path, otherPosition.path );\n\n\t\tswitch ( result ) {\n\t\t\tcase 'same':\n\t\t\t\treturn 'same';\n\n\t\t\tcase 'prefix':\n\t\t\t\treturn 'before';\n\n\t\t\tcase 'extension':\n\t\t\t\treturn 'after';\n\n\t\t\tdefault:\n\t\t\t\treturn this.path[ result ] < otherPosition.path[ result ] ? 'before' : 'after';\n\t\t}\n\t}\n\n\t/**\n\t * Gets the farthest position which matches the callback using\n\t * {@link module:engine/model/treewalker~TreeWalker TreeWalker}.\n\t *\n\t * For example:\n\t *\n\t * \t\tgetLastMatchingPosition( value => value.type == 'text' );\n\t * \t\t// <paragraph>[]foo</paragraph> -> <paragraph>foo[]</paragraph>\n\t *\n\t * \t\tgetLastMatchingPosition( value => value.type == 'text', { direction: 'backward' } );\n\t * \t\t// <paragraph>foo[]</paragraph> -> <paragraph>[]foo</paragraph>\n\t *\n\t * \t\tgetLastMatchingPosition( value => false );\n\t * \t\t// Do not move the position.\n\t *\n\t * @param {Function} skip Callback function. Gets {@link module:engine/model/treewalker~TreeWalkerValue} and should\n\t * return `true` if the value should be skipped or `false` if not.\n\t * @param {Object} options Object with configuration options. See {@link module:engine/model/treewalker~TreeWalker}.\n\t *\n\t * @returns {module:engine/model/position~Position} The position after the last item which matches the `skip` callback test.\n\t */\n\tgetLastMatchingPosition( skip, options = {} ) {\n\t\toptions.startPosition = this;\n\n\t\tconst treeWalker = new TreeWalker( options );\n\t\ttreeWalker.skip( skip );\n\n\t\treturn treeWalker.position;\n\t}\n\n\t/**\n\t * Returns a path to this position's parent. Parent path is equal to position {@link module:engine/model/position~Position#path path}\n\t * but without the last item.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @returns {Array.<Number>} Path to the parent.\n\t */\n\tgetParentPath() {\n\t\treturn this.path.slice( 0, -1 );\n\t}\n\n\t/**\n\t * Returns ancestors array of this position, that is this position's parent and its ancestors.\n\t *\n\t * @returns {Array.<module:engine/model/item~Item>} Array with ancestors.\n\t */\n\tgetAncestors() {\n\t\tif ( this.parent.is( 'documentFragment' ) ) {\n\t\t\treturn [ this.parent ];\n\t\t} else {\n\t\t\treturn this.parent.getAncestors( { includeSelf: true } );\n\t\t}\n\t}\n\n\t/**\n\t * Returns the slice of two position {@link #path paths} which is identical. The {@link #root roots}\n\t * of these two paths must be identical.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param {module:engine/model/position~Position} position The second position.\n\t * @returns {Array.<Number>} The common path.\n\t */\n\tgetCommonPath( position ) {\n\t\tif ( this.root != position.root ) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// We find on which tree-level start and end have the lowest common ancestor\n\t\tconst cmp = compareArrays( this.path, position.path );\n\t\t// If comparison returned string it means that arrays are same.\n\t\tconst diffAt = ( typeof cmp == 'string' ) ? Math.min( this.path.length, position.path.length ) : cmp;\n\n\t\treturn this.path.slice( 0, diffAt );\n\t}\n\n\t/**\n\t * Returns an {@link module:engine/model/element~Element} or {@link module:engine/model/documentfragment~DocumentFragment}\n\t * which is a common ancestor of both positions. The {@link #root roots} of these two positions must be identical.\n\t *\n\t * @param {module:engine/model/position~Position} position The second position.\n\t * @returns {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment|null}\n\t */\n\tgetCommonAncestor( position ) {\n\t\tconst ancestorsA = this.getAncestors();\n\t\tconst ancestorsB = position.getAncestors();\n\n\t\tlet i = 0;\n\n\t\twhile ( ancestorsA[ i ] == ancestorsB[ i ] && ancestorsA[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i === 0 ? null : ancestorsA[ i - 1 ];\n\t}\n\n\t/**\n\t * Returns a new instance of `Position`, that has same {@link #parent parent} but it's offset\n\t * is shifted by `shift` value (can be a negative value).\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param {Number} shift Offset shift. Can be a negative value.\n\t * @returns {module:engine/model/position~Position} Shifted position.\n\t */\n\tgetShiftedBy( shift ) {\n\t\tconst shifted = this.clone();\n\n\t\tconst offset = shifted.offset + shift;\n\t\tshifted.offset = offset < 0 ? 0 : offset;\n\n\t\treturn shifted;\n\t}\n\n\t/**\n\t * Checks whether this position is after given position.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @see module:engine/model/position~Position#isBefore\n\t * @param {module:engine/model/position~Position} otherPosition Position to compare with.\n\t * @returns {Boolean} True if this position is after given position.\n\t */\n\tisAfter( otherPosition ) {\n\t\treturn this.compareWith( otherPosition ) == 'after';\n\t}\n\n\t/**\n\t * Checks whether this position is before given position.\n\t *\n\t * **Note:** watch out when using negation of the value returned by this method, because the negation will also\n\t * be `true` if positions are in different roots and you might not expect this. You should probably use\n\t * `a.isAfter( b ) || a.isEqual( b )` or `!a.isBefore( p ) && a.root == b.root` in most scenarios. If your\n\t * condition uses multiple `isAfter` and `isBefore` checks, build them so they do not use negated values, i.e.:\n\t *\n\t *\t\tif ( a.isBefore( b ) && c.isAfter( d ) ) {\n\t *\t\t\t// do A.\n\t *\t\t} else {\n\t *\t\t\t// do B.\n\t *\t\t}\n\t *\n\t * or, if you have only one if-branch:\n\t *\n\t *\t\tif ( !( a.isBefore( b ) && c.isAfter( d ) ) {\n\t *\t\t\t// do B.\n\t *\t\t}\n\t *\n\t * rather than:\n\t *\n\t *\t\tif ( !a.isBefore( b ) || && !c.isAfter( d ) ) {\n\t *\t\t\t// do B.\n\t *\t\t} else {\n\t *\t\t\t// do A.\n\t *\t\t}\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param {module:engine/model/position~Position} otherPosition Position to compare with.\n\t * @returns {Boolean} True if this position is before given position.\n\t */\n\tisBefore( otherPosition ) {\n\t\treturn this.compareWith( otherPosition ) == 'before';\n\t}\n\n\t/**\n\t * Checks whether this position is equal to given position.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param {module:engine/model/position~Position} otherPosition Position to compare with.\n\t * @returns {Boolean} True if positions are same.\n\t */\n\tisEqual( otherPosition ) {\n\t\treturn this.compareWith( otherPosition ) == 'same';\n\t}\n\n\t/**\n\t * Checks whether this position is touching given position. Positions touch when there are no text nodes\n\t * or empty nodes in a range between them. Technically, those positions are not equal but in many cases\n\t * they are very similar or even indistinguishable.\n\t *\n\t * @param {module:engine/model/position~Position} otherPosition Position to compare with.\n\t * @returns {Boolean} True if positions touch.\n\t */\n\tisTouching( otherPosition ) {\n\t\tlet left = null;\n\t\tlet right = null;\n\t\tconst compare = this.compareWith( otherPosition );\n\n\t\tswitch ( compare ) {\n\t\t\tcase 'same':\n\t\t\t\treturn true;\n\n\t\t\tcase 'before':\n\t\t\t\tleft = Position._createAt( this );\n\t\t\t\tright = Position._createAt( otherPosition );\n\t\t\t\tbreak;\n\n\t\t\tcase 'after':\n\t\t\t\tleft = Position._createAt( otherPosition );\n\t\t\t\tright = Position._createAt( this );\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\treturn false;\n\t\t}\n\n\t\t// Cached for optimization purposes.\n\t\tlet leftParent = left.parent;\n\n\t\twhile ( left.path.length + right.path.length ) {\n\t\t\tif ( left.isEqual( right ) ) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif ( left.path.length > right.path.length ) {\n\t\t\t\tif ( left.offset !== leftParent.maxOffset ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tleft.path = left.path.slice( 0, -1 );\n\t\t\t\tleftParent = leftParent.parent;\n\t\t\t\tleft.offset++;\n\t\t\t} else {\n\t\t\t\tif ( right.offset !== 0 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tright.path = right.path.slice( 0, -1 );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if two positions are in the same parent.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param {module:engine/model/position~Position} position Position to compare with.\n\t * @returns {Boolean} `true` if positions have the same parent, `false` otherwise.\n\t */\n\thasSameParentAs( position ) {\n\t\tif ( this.root !== position.root ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst thisParentPath = this.getParentPath();\n\t\tconst posParentPath = position.getParentPath();\n\n\t\treturn compareArrays( thisParentPath, posParentPath ) == 'same';\n\t}\n\n\t/**\n\t * Returns a copy of this position that is transformed by given `operation`.\n\t *\n\t * The new position's parameters are updated accordingly to the effect of the `operation`.\n\t *\n\t * For example, if `n` nodes are inserted before the position, the returned position {@link ~Position#offset} will be\n\t * increased by `n`. If the position was in a merged element, it will be accordingly moved to the new element, etc.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param {module:engine/model/operation/operation~Operation} operation Operation to transform by.\n\t * @returns {module:engine/model/position~Position} Transformed position.\n\t */\n\tgetTransformedByOperation( operation ) {\n\t\tlet result;\n\n\t\tswitch ( operation.type ) {\n\t\t\tcase 'insert':\n\t\t\t\tresult = this._getTransformedByInsertOperation( operation );\n\t\t\t\tbreak;\n\t\t\tcase 'move':\n\t\t\tcase 'remove':\n\t\t\tcase 'reinsert':\n\t\t\t\tresult = this._getTransformedByMoveOperation( operation );\n\t\t\t\tbreak;\n\t\t\tcase 'split':\n\t\t\t\tresult = this._getTransformedBySplitOperation( operation );\n\t\t\t\tbreak;\n\t\t\tcase 'merge':\n\t\t\t\tresult = this._getTransformedByMergeOperation( operation );\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tresult = Position._createAt( this );\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Returns a copy of this position transformed by an insert operation.\n\t *\n\t * @protected\n\t * @param {module:engine/model/operation/insertoperation~InsertOperation} operation\n\t * @returns {module:engine/model/position~Position}\n\t */\n\t_getTransformedByInsertOperation( operation ) {\n\t\treturn this._getTransformedByInsertion( operation.position, operation.howMany );\n\t}\n\n\t/**\n\t * Returns a copy of this position transformed by a move operation.\n\t *\n\t * @protected\n\t * @param {module:engine/model/operation/moveoperation~MoveOperation} operation\n\t * @returns {module:engine/model/position~Position}\n\t */\n\t_getTransformedByMoveOperation( operation ) {\n\t\treturn this._getTransformedByMove( operation.sourcePosition, operation.targetPosition, operation.howMany );\n\t}\n\n\t/**\n\t * Returns a copy of this position transformed by a split operation.\n\t *\n\t * @protected\n\t * @param {module:engine/model/operation/splitoperation~SplitOperation} operation\n\t * @returns {module:engine/model/position~Position}\n\t */\n\t_getTransformedBySplitOperation( operation ) {\n\t\tconst movedRange = operation.movedRange;\n\n\t\tconst isContained = movedRange.containsPosition( this ) ||\n\t\t\t( movedRange.start.isEqual( this ) && this.stickiness == 'toNext' );\n\n\t\tif ( isContained ) {\n\t\t\treturn this._getCombined( operation.splitPosition, operation.moveTargetPosition );\n\t\t} else {\n\t\t\tif ( operation.graveyardPosition ) {\n\t\t\t\treturn this._getTransformedByMove( operation.graveyardPosition, operation.insertionPosition, 1 );\n\t\t\t} else {\n\t\t\t\treturn this._getTransformedByInsertion( operation.insertionPosition, 1 );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns a copy of this position transformed by merge operation.\n\t *\n\t * @protected\n\t * @param {module:engine/model/operation/mergeoperation~MergeOperation} operation\n\t * @returns {module:engine/model/position~Position}\n\t */\n\t_getTransformedByMergeOperation( operation ) {\n\t\tconst movedRange = operation.movedRange;\n\t\tconst isContained = movedRange.containsPosition( this ) || movedRange.start.isEqual( this );\n\n\t\tlet pos;\n\n\t\tif ( isContained ) {\n\t\t\tpos = this._getCombined( operation.sourcePosition, operation.targetPosition );\n\n\t\t\tif ( operation.sourcePosition.isBefore( operation.targetPosition ) ) {\n\t\t\t\t// Above happens during OT when the merged element is moved before the merged-to element.\n\t\t\t\tpos = pos._getTransformedByDeletion( operation.deletionPosition, 1 );\n\t\t\t}\n\t\t} else if ( this.isEqual( operation.deletionPosition ) ) {\n\t\t\tpos = Position._createAt( operation.deletionPosition );\n\t\t} else {\n\t\t\tpos = this._getTransformedByMove( operation.deletionPosition, operation.graveyardPosition, 1 );\n\t\t}\n\n\t\treturn pos;\n\t}\n\n\t/**\n\t * Returns a copy of this position that is updated by removing `howMany` nodes starting from `deletePosition`.\n\t * It may happen that this position is in a removed node. If that is the case, `null` is returned instead.\n\t *\n\t * @protected\n\t * @param {module:engine/model/position~Position} deletePosition Position before the first removed node.\n\t * @param {Number} howMany How many nodes are removed.\n\t * @returns {module:engine/model/position~Position|null} Transformed position or `null`.\n\t */\n\t_getTransformedByDeletion( deletePosition, howMany ) {\n\t\tconst transformed = Position._createAt( this );\n\n\t\t// This position can't be affected if deletion was in a different root.\n\t\tif ( this.root != deletePosition.root ) {\n\t\t\treturn transformed;\n\t\t}\n\n\t\tif ( compareArrays( deletePosition.getParentPath(), this.getParentPath() ) == 'same' ) {\n\t\t\t// If nodes are removed from the node that is pointed by this position...\n\t\t\tif ( deletePosition.offset < this.offset ) {\n\t\t\t\t// And are removed from before an offset of that position...\n\t\t\t\tif ( deletePosition.offset + howMany > this.offset ) {\n\t\t\t\t\t// Position is in removed range, it's no longer in the tree.\n\t\t\t\t\treturn null;\n\t\t\t\t} else {\n\t\t\t\t\t// Decrement the offset accordingly.\n\t\t\t\t\ttransformed.offset -= howMany;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if ( compareArrays( deletePosition.getParentPath(), this.getParentPath() ) == 'prefix' ) {\n\t\t\t// If nodes are removed from a node that is on a path to this position...\n\t\t\tconst i = deletePosition.path.length - 1;\n\n\t\t\tif ( deletePosition.offset <= this.path[ i ] ) {\n\t\t\t\t// And are removed from before next node of that path...\n\t\t\t\tif ( deletePosition.offset + howMany > this.path[ i ] ) {\n\t\t\t\t\t// If the next node of that path is removed return null\n\t\t\t\t\t// because the node containing this position got removed.\n\t\t\t\t\treturn null;\n\t\t\t\t} else {\n\t\t\t\t\t// Otherwise, decrement index on that path.\n\t\t\t\t\ttransformed.path[ i ] -= howMany;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn transformed;\n\t}\n\n\t/**\n\t * Returns a copy of this position that is updated by inserting `howMany` nodes at `insertPosition`.\n\t *\n\t * @protected\n\t * @param {module:engine/model/position~Position} insertPosition Position where nodes are inserted.\n\t * @param {Number} howMany How many nodes are inserted.\n\t * @returns {module:engine/model/position~Position} Transformed position.\n\t */\n\t_getTransformedByInsertion( insertPosition, howMany ) {\n\t\tconst transformed = Position._createAt( this );\n\n\t\t// This position can't be affected if insertion was in a different root.\n\t\tif ( this.root != insertPosition.root ) {\n\t\t\treturn transformed;\n\t\t}\n\n\t\tif ( compareArrays( insertPosition.getParentPath(), this.getParentPath() ) == 'same' ) {\n\t\t\t// If nodes are inserted in the node that is pointed by this position...\n\t\t\tif ( insertPosition.offset < this.offset || ( insertPosition.offset == this.offset && this.stickiness != 'toPrevious' ) ) {\n\t\t\t\t// And are inserted before an offset of that position...\n\t\t\t\t// \"Push\" this positions offset.\n\t\t\t\ttransformed.offset += howMany;\n\t\t\t}\n\t\t} else if ( compareArrays( insertPosition.getParentPath(), this.getParentPath() ) == 'prefix' ) {\n\t\t\t// If nodes are inserted in a node that is on a path to this position...\n\t\t\tconst i = insertPosition.path.length - 1;\n\n\t\t\tif ( insertPosition.offset <= this.path[ i ] ) {\n\t\t\t\t// And are inserted before next node of that path...\n\t\t\t\t// \"Push\" the index on that path.\n\t\t\t\ttransformed.path[ i ] += howMany;\n\t\t\t}\n\t\t}\n\n\t\treturn transformed;\n\t}\n\n\t/**\n\t * Returns a copy of this position that is updated by moving `howMany` nodes from `sourcePosition` to `targetPosition`.\n\t *\n\t * @protected\n\t * @param {module:engine/model/position~Position} sourcePosition Position before the first element to move.\n\t * @param {module:engine/model/position~Position} targetPosition Position where moved elements will be inserted.\n\t * @param {Number} howMany How many consecutive nodes to move, starting from `sourcePosition`.\n\t * @returns {module:engine/model/position~Position} Transformed position.\n\t */\n\t_getTransformedByMove( sourcePosition, targetPosition, howMany ) {\n\t\t// Update target position, as it could be affected by nodes removal.\n\t\ttargetPosition = targetPosition._getTransformedByDeletion( sourcePosition, howMany );\n\n\t\tif ( sourcePosition.isEqual( targetPosition ) ) {\n\t\t\t// If `targetPosition` is equal to `sourcePosition` this isn't really any move. Just return position as it is.\n\t\t\treturn Position._createAt( this );\n\t\t}\n\n\t\t// Moving a range removes nodes from their original position. We acknowledge this by proper transformation.\n\t\tconst transformed = this._getTransformedByDeletion( sourcePosition, howMany );\n\n\t\tconst isMoved = transformed === null ||\n\t\t\t( sourcePosition.isEqual( this ) && this.stickiness == 'toNext' ) ||\n\t\t\t( sourcePosition.getShiftedBy( howMany ).isEqual( this ) && this.stickiness == 'toPrevious' );\n\n\t\tif ( isMoved ) {\n\t\t\t// This position is inside moved range (or sticks to it).\n\t\t\t// In this case, we calculate a combination of this position, move source position and target position.\n\t\t\treturn this._getCombined( sourcePosition, targetPosition );\n\t\t} else {\n\t\t\t// This position is not inside a removed range.\n\t\t\t//\n\t\t\t// In next step, we simply reflect inserting `howMany` nodes, which might further affect the position.\n\t\t\treturn transformed._getTransformedByInsertion( targetPosition, howMany );\n\t\t}\n\t}\n\n\t/**\n\t * Returns a new position that is a combination of this position and given positions.\n\t *\n\t * The combined position is a copy of this position transformed by moving a range starting at `source` position\n\t * to the `target` position. It is expected that this position is inside the moved range.\n\t *\n\t * Example:\n\t *\n\t *\t\tlet original = model.createPositionFromPath( root, [ 2, 3, 1 ] );\n\t *\t\tlet source = model.createPositionFromPath( root, [ 2, 2 ] );\n\t *\t\tlet target = model.createPositionFromPath( otherRoot, [ 1, 1, 3 ] );\n\t *\t\toriginal._getCombined( source, target ); // path is [ 1, 1, 4, 1 ], root is `otherRoot`\n\t *\n\t * Explanation:\n\t *\n\t * We have a position `[ 2, 3, 1 ]` and move some nodes from `[ 2, 2 ]` to `[ 1, 1, 3 ]`. The original position\n\t * was inside moved nodes and now should point to the new place. The moved nodes will be after\n\t * positions `[ 1, 1, 3 ]`, `[ 1, 1, 4 ]`, `[ 1, 1, 5 ]`. Since our position was in the second moved node,\n\t * the transformed position will be in a sub-tree of a node at `[ 1, 1, 4 ]`. Looking at original path, we\n\t * took care of `[ 2, 3 ]` part of it. Now we have to add the rest of the original path to the transformed path.\n\t * Finally, the transformed position will point to `[ 1, 1, 4, 1 ]`.\n\t *\n\t * @protected\n\t * @param {module:engine/model/position~Position} source Beginning of the moved range.\n\t * @param {module:engine/model/position~Position} target Position where the range is moved.\n\t * @returns {module:engine/model/position~Position} Combined position.\n\t */\n\t_getCombined( source, target ) {\n\t\tconst i = source.path.length - 1;\n\n\t\t// The first part of a path to combined position is a path to the place where nodes were moved.\n\t\tconst combined = Position._createAt( target );\n\t\tcombined.stickiness = this.stickiness;\n\n\t\t// Then we have to update the rest of the path.\n\n\t\t// Fix the offset because this position might be after `from` position and we have to reflect that.\n\t\tcombined.offset = combined.offset + this.path[ i ] - source.offset;\n\n\t\t// Then, add the rest of the path.\n\t\t// If this position is at the same level as `from` position nothing will get added.\n\t\tcombined.path = combined.path.concat( this.path.slice( i + 1 ) );\n\n\t\treturn combined;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\ttoJSON() {\n\t\treturn {\n\t\t\troot: this.root.toJSON(),\n\t\t\tpath: Array.from( this.path ),\n\t\t\tstickiness: this.stickiness\n\t\t};\n\t}\n\n\t/**\n\t * Returns a new position that is equal to current position.\n\t *\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tclone() {\n\t\treturn new this.constructor( this.root, this.path, this.stickiness );\n\t}\n\n\t/**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/model/position~Position position},\n\t * * parent element and offset (offset defaults to `0`),\n\t * * parent element and `'end'` (sets position at the end of that element),\n\t * * {@link module:engine/model/item~Item model item} and `'before'` or `'after'` (sets position before or after given model item).\n\t *\n\t * This method is a shortcut to other factory methods such as:\n\t *\n\t * * {@link module:engine/model/position~Position._createBefore},\n\t * * {@link module:engine/model/position~Position._createAfter}.\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when the\n\t * first parameter is a {@link module:engine/model/item~Item model item}.\n\t * @param {module:engine/model/position~PositionStickiness} [stickiness='toNone'] Position stickiness. Used only when the\n\t * first parameter is a {@link module:engine/model/item~Item model item}.\n\t * @protected\n\t */\n\tstatic _createAt( itemOrPosition, offset, stickiness = 'toNone' ) {\n\t\tif ( itemOrPosition instanceof Position ) {\n\t\t\treturn new Position( itemOrPosition.root, itemOrPosition.path, itemOrPosition.stickiness );\n\t\t} else {\n\t\t\tconst node = itemOrPosition;\n\n\t\t\tif ( offset == 'end' ) {\n\t\t\t\toffset = node.maxOffset;\n\t\t\t} else if ( offset == 'before' ) {\n\t\t\t\treturn this._createBefore( node, stickiness );\n\t\t\t} else if ( offset == 'after' ) {\n\t\t\t\treturn this._createAfter( node, stickiness );\n\t\t\t} else if ( offset !== 0 && !offset ) {\n\t\t\t\t/**\n\t\t\t\t * {@link module:engine/model/model~Model#createPositionAt `Model#createPositionAt()`}\n\t\t\t\t * requires the offset to be specified when the first parameter is a model item.\n\t\t\t\t *\n\t\t\t\t * @error model-createPositionAt-offset-required\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'model-createPositionAt-offset-required: ' +\n\t\t\t\t\t'Model#createPositionAt() requires the offset when the first parameter is a model item.' );\n\t\t\t}\n\n\t\t\tif ( !node.is( 'element' ) && !node.is( 'documentFragment' ) ) {\n\t\t\t\t/**\n\t\t\t\t * Position parent have to be a model element or model document fragment.\n\t\t\t\t *\n\t\t\t\t * @error model-position-parent-incorrect\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'model-position-parent-incorrect: Position parent have to be a element or document fragment.' );\n\t\t\t}\n\n\t\t\tconst path = node.getPath();\n\n\t\t\tpath.push( offset );\n\n\t\t\treturn new this( node.root, path, stickiness );\n\t\t}\n\t}\n\n\t/**\n\t * Creates a new position, after given {@link module:engine/model/item~Item model item}.\n\t *\n\t * @param {module:engine/model/item~Item} item Item after which the position should be placed.\n\t * @param {module:engine/model/position~PositionStickiness} [stickiness='toNone'] Position stickiness.\n\t * @returns {module:engine/model/position~Position}\n\t * @protected\n\t */\n\tstatic _createAfter( item, stickiness ) {\n\t\tif ( !item.parent ) {\n\t\t\t/**\n\t\t\t * You can not make a position after a root element.\n\t\t\t *\n\t\t\t * @error model-position-after-root\n\t\t\t * @param {module:engine/model/item~Item} root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-position-after-root: You cannot make a position after root.', { root: item } );\n\t\t}\n\n\t\treturn this._createAt( item.parent, item.endOffset, stickiness );\n\t}\n\n\t/**\n\t * Creates a new position, before the given {@link module:engine/model/item~Item model item}.\n\t *\n\t * @param {module:engine/model/item~Item} item Item before which the position should be placed.\n\t * @param {module:engine/model/position~PositionStickiness} [stickiness='toNone'] Position stickiness.\n\t * @returns {module:engine/model/position~Position}\n\t * @protected\n\t */\n\tstatic _createBefore( item, stickiness ) {\n\t\tif ( !item.parent ) {\n\t\t\t/**\n\t\t\t * You can not make a position before a root element.\n\t\t\t *\n\t\t\t * @error model-position-before-root\n\t\t\t * @param {module:engine/model/item~Item} root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-position-before-root: You cannot make a position before root.', { root: item } );\n\t\t}\n\n\t\treturn this._createAt( item.parent, item.startOffset, stickiness );\n\t}\n\n\t/**\n\t * Creates a `Position` instance from given plain object (i.e. parsed JSON string).\n\t *\n\t * @param {Object} json Plain object to be converted to `Position`.\n\t * @param {module:engine/model/document~Document} doc Document object that will be position owner.\n\t * @returns {module:engine/model/position~Position} `Position` instance created using given plain object.\n\t */\n\tstatic fromJSON( json, doc ) {\n\t\tif ( json.root === '$graveyard' ) {\n\t\t\tconst pos = new Position( doc.graveyard, json.path );\n\t\t\tpos.stickiness = json.stickiness;\n\n\t\t\treturn pos;\n\t\t}\n\n\t\tif ( !doc.getRoot( json.root ) ) {\n\t\t\t/**\n\t\t\t * Cannot create position for document. Root with specified name does not exist.\n\t\t\t *\n\t\t\t * @error model-position-fromjson-no-root\n\t\t\t * @param {String} rootName\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'model-position-fromjson-no-root: Cannot create position for document. Root with specified name does not exist.',\n\t\t\t\t{ rootName: json.root }\n\t\t\t);\n\t\t}\n\n\t\treturn new Position( doc.getRoot( json.root ), json.path, json.stickiness );\n\t}\n}\n\n/**\n * A flag indicating whether this position is `'before'` or `'after'` or `'same'` as given position.\n * If positions are in different roots `'different'` flag is returned.\n *\n * @typedef {String} module:engine/model/position~PositionRelation\n */\n\n/**\n * Represents how position is \"sticking\" with neighbour nodes. Used to define how position should be transformed (moved)\n * in edge cases. Possible values: `'toNone'`, `'toNext'`, `'toPrevious'`.\n *\n * Examples:\n *\n *\t\tInsert. Position is at | and nodes are inserted at the same position, marked as ^:\n *\n *\t\t- sticks to none: <p>f^|oo</p> -> <p>fbar|oo</p>\n *\t\t- sticks to next node: <p>f^|oo</p> -> <p>fbar|oo</p>\n *\t\t- sticks to previous node: <p>f|^oo</p> -> <p>f|baroo</p>\n *\n *\n *\t\tMove. Position is at | and range [oo] is moved to position ^:\n *\n *\t\t- sticks to none: <p>f|[oo]</p><p>b^ar</p> -> <p>f|</p><p>booar</p>\n *\t\t- sticks to none: <p>f[oo]|</p><p>b^ar</p> -> <p>f|</p><p>booar</p>\n *\n *\t\t- sticks to next node: <p>f|[oo]</p><p>b^ar</p> -> <p>f</p><p>b|ooar</p>\n *\t\t- sticks to next node: <p>f[oo]|</p><p>b^ar</p> -> <p>f|</p><p>booar</p>\n *\n *\t\t- sticks to previous node: <p>f|[oo]</p><p>b^ar</p> -> <p>f|</p><p>booar</p>\n *\t\t- sticks to previous node: <p>f[oo]|</p><p>b^ar</p> -> <p>f</p><p>boo|ar</p>\n *\n * @typedef {String} module:engine/model/position~PositionStickiness\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/range\n */\n\nimport Position from './position';\nimport TreeWalker from './treewalker';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport compareArrays from '@ckeditor/ckeditor5-utils/src/comparearrays';\n\n/**\n * Represents a range in the model tree.\n *\n * A range is defined by its {@link module:engine/model/range~Range#start} and {@link module:engine/model/range~Range#end}\n * positions.\n *\n * You can create range instances via its constructor or the `createRange*()` factory methods of\n * {@link module:engine/model/model~Model} and {@link module:engine/model/writer~Writer}.\n */\nexport default class Range {\n\t/**\n\t * Creates a range spanning from `start` position to `end` position.\n\t *\n\t * @param {module:engine/model/position~Position} start Start position.\n\t * @param {module:engine/model/position~Position} [end] End position. If not set, range will be collapsed at `start` position.\n\t */\n\tconstructor( start, end = null ) {\n\t\t/**\n\t\t * Start position.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/position~Position}\n\t\t */\n\t\tthis.start = Position._createAt( start );\n\n\t\t/**\n\t\t * End position.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/position~Position}\n\t\t */\n\t\tthis.end = end ? Position._createAt( end ) : Position._createAt( start );\n\n\t\t// If the range is collapsed, treat in a similar way as a position and set its boundaries stickiness to 'toNone'.\n\t\t// In other case, make the boundaries stick to the \"inside\" of the range.\n\t\tthis.start.stickiness = this.isCollapsed ? 'toNone' : 'toNext';\n\t\tthis.end.stickiness = this.isCollapsed ? 'toNone' : 'toPrevious';\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * Iterates over all {@link module:engine/model/item~Item items} that are in this range and returns\n\t * them together with additional information like length or {@link module:engine/model/position~Position positions},\n\t * grouped as {@link module:engine/model/treewalker~TreeWalkerValue}.\n\t * It iterates over all {@link module:engine/model/textproxy~TextProxy text contents} that are inside the range\n\t * and all the {@link module:engine/model/element~Element}s that are entered into when iterating over this range.\n\t *\n\t * This iterator uses {@link module:engine/model/treewalker~TreeWalker} with `boundaries` set to this range\n\t * and `ignoreElementEnd` option set to `true`.\n\t *\n\t * @returns {Iterable.<module:engine/model/treewalker~TreeWalkerValue>}\n\t */\n\t* [ Symbol.iterator ]() {\n\t\tyield* new TreeWalker( { boundaries: this, ignoreElementEnd: true } );\n\t}\n\n\t/**\n\t * Returns whether the range is collapsed, that is if {@link #start} and\n\t * {@link #end} positions are equal.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isCollapsed() {\n\t\treturn this.start.isEqual( this.end );\n\t}\n\n\t/**\n\t * Returns whether this range is flat, that is if {@link #start} position and\n\t * {@link #end} position are in the same {@link module:engine/model/position~Position#parent}.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isFlat() {\n\t\tconst startParentPath = this.start.getParentPath();\n\t\tconst endParentPath = this.end.getParentPath();\n\n\t\treturn compareArrays( startParentPath, endParentPath ) == 'same';\n\t}\n\n\t/**\n\t * Range root element.\n\t *\n\t * @type {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment}\n\t */\n\tget root() {\n\t\treturn this.start.root;\n\t}\n\n\t/**\n\t * Checks whether this range contains given {@link module:engine/model/position~Position position}.\n\t *\n\t * @param {module:engine/model/position~Position} position Position to check.\n\t * @returns {Boolean} `true` if given {@link module:engine/model/position~Position position} is contained\n\t * in this range,`false` otherwise.\n\t */\n\tcontainsPosition( position ) {\n\t\treturn position.isAfter( this.start ) && position.isBefore( this.end );\n\t}\n\n\t/**\n\t * Checks whether this range contains given {@link ~Range range}.\n\t *\n\t * @param {module:engine/model/range~Range} otherRange Range to check.\n\t * @param {Boolean} [loose=false] Whether the check is loose or strict. If the check is strict (`false`), compared range cannot\n\t * start or end at the same position as this range boundaries. If the check is loose (`true`), compared range can start, end or\n\t * even be equal to this range. Note that collapsed ranges are always compared in strict mode.\n\t * @returns {Boolean} `true` if given {@link ~Range range} boundaries are contained by this range, `false` otherwise.\n\t */\n\tcontainsRange( otherRange, loose = false ) {\n\t\tif ( otherRange.isCollapsed ) {\n\t\t\tloose = false;\n\t\t}\n\n\t\tconst containsStart = this.containsPosition( otherRange.start ) || ( loose && this.start.isEqual( otherRange.start ) );\n\t\tconst containsEnd = this.containsPosition( otherRange.end ) || ( loose && this.end.isEqual( otherRange.end ) );\n\n\t\treturn containsStart && containsEnd;\n\t}\n\n\t/**\n\t * Checks whether given {@link module:engine/model/item~Item} is inside this range.\n\t *\n\t * @param {module:engine/model/item~Item} item Model item to check.\n\t */\n\tcontainsItem( item ) {\n\t\tconst pos = Position._createBefore( item );\n\n\t\treturn this.containsPosition( pos ) || this.start.isEqual( pos );\n\t}\n\n\t/**\n\t * Two ranges are equal if their {@link #start} and {@link #end} positions are equal.\n\t *\n\t * @param {module:engine/model/range~Range} otherRange Range to compare with.\n\t * @returns {Boolean} `true` if ranges are equal, `false` otherwise.\n\t */\n\tisEqual( otherRange ) {\n\t\treturn this.start.isEqual( otherRange.start ) && this.end.isEqual( otherRange.end );\n\t}\n\n\t/**\n\t * Checks and returns whether this range intersects with given range.\n\t *\n\t * @param {module:engine/model/range~Range} otherRange Range to compare with.\n\t * @returns {Boolean} `true` if ranges intersect, `false` otherwise.\n\t */\n\tisIntersecting( otherRange ) {\n\t\treturn this.start.isBefore( otherRange.end ) && this.end.isAfter( otherRange.start );\n\t}\n\n\t/**\n\t * Computes which part(s) of this {@link ~Range range} is not a part of given {@link ~Range range}.\n\t * Returned array contains zero, one or two {@link ~Range ranges}.\n\t *\n\t * Examples:\n\t *\n\t *\t\tlet range = model.createRange(\n\t *\t\t\tmodel.createPositionFromPath( root, [ 2, 7 ] ),\n\t *\t\t\tmodel.createPositionFromPath( root, [ 4, 0, 1 ] )\n\t *\t\t);\n\t *\t\tlet otherRange = model.createRange( model.createPositionFromPath( root, [ 1 ] ), model.createPositionFromPath( root, [ 5 ] ) );\n\t *\t\tlet transformed = range.getDifference( otherRange );\n\t *\t\t// transformed array has no ranges because `otherRange` contains `range`\n\t *\n\t *\t\totherRange = model.createRange( model.createPositionFromPath( root, [ 1 ] ), model.createPositionFromPath( root, [ 3 ] ) );\n\t *\t\ttransformed = range.getDifference( otherRange );\n\t *\t\t// transformed array has one range: from [ 3 ] to [ 4, 0, 1 ]\n\t *\n\t *\t\totherRange = model.createRange( model.createPositionFromPath( root, [ 3 ] ), model.createPositionFromPath( root, [ 4 ] ) );\n\t *\t\ttransformed = range.getDifference( otherRange );\n\t *\t\t// transformed array has two ranges: from [ 2, 7 ] to [ 3 ] and from [ 4 ] to [ 4, 0, 1 ]\n\t *\n\t * @param {module:engine/model/range~Range} otherRange Range to differentiate against.\n\t * @returns {Array.<module:engine/model/range~Range>} The difference between ranges.\n\t */\n\tgetDifference( otherRange ) {\n\t\tconst ranges = [];\n\n\t\tif ( this.isIntersecting( otherRange ) ) {\n\t\t\t// Ranges intersect.\n\n\t\t\tif ( this.containsPosition( otherRange.start ) ) {\n\t\t\t\t// Given range start is inside this range. This means that we have to\n\t\t\t\t// add shrunken range - from the start to the middle of this range.\n\t\t\t\tranges.push( new Range( this.start, otherRange.start ) );\n\t\t\t}\n\n\t\t\tif ( this.containsPosition( otherRange.end ) ) {\n\t\t\t\t// Given range end is inside this range. This means that we have to\n\t\t\t\t// add shrunken range - from the middle of this range to the end.\n\t\t\t\tranges.push( new Range( otherRange.end, this.end ) );\n\t\t\t}\n\t\t} else {\n\t\t\t// Ranges do not intersect, return the original range.\n\t\t\tranges.push( new Range( this.start, this.end ) );\n\t\t}\n\n\t\treturn ranges;\n\t}\n\n\t/**\n\t * Returns an intersection of this {@link ~Range range} and given {@link ~Range range}.\n\t * Intersection is a common part of both of those ranges. If ranges has no common part, returns `null`.\n\t *\n\t * Examples:\n\t *\n\t *\t\tlet range = model.createRange(\n\t *\t\t\tmodel.createPositionFromPath( root, [ 2, 7 ] ),\n\t *\t\t\tmodel.createPositionFromPath( root, [ 4, 0, 1 ] )\n\t *\t\t);\n\t *\t\tlet otherRange = model.createRange( model.createPositionFromPath( root, [ 1 ] ), model.createPositionFromPath( root, [ 2 ] ) );\n\t *\t\tlet transformed = range.getIntersection( otherRange ); // null - ranges have no common part\n\t *\n\t *\t\totherRange = model.createRange( model.createPositionFromPath( root, [ 3 ] ), model.createPositionFromPath( root, [ 5 ] ) );\n\t *\t\ttransformed = range.getIntersection( otherRange ); // range from [ 3 ] to [ 4, 0, 1 ]\n\t *\n\t * @param {module:engine/model/range~Range} otherRange Range to check for intersection.\n\t * @returns {module:engine/model/range~Range|null} A common part of given ranges or `null` if ranges have no common part.\n\t */\n\tgetIntersection( otherRange ) {\n\t\tif ( this.isIntersecting( otherRange ) ) {\n\t\t\t// Ranges intersect, so a common range will be returned.\n\t\t\t// At most, it will be same as this range.\n\t\t\tlet commonRangeStart = this.start;\n\t\t\tlet commonRangeEnd = this.end;\n\n\t\t\tif ( this.containsPosition( otherRange.start ) ) {\n\t\t\t\t// Given range start is inside this range. This means thaNt we have to\n\t\t\t\t// shrink common range to the given range start.\n\t\t\t\tcommonRangeStart = otherRange.start;\n\t\t\t}\n\n\t\t\tif ( this.containsPosition( otherRange.end ) ) {\n\t\t\t\t// Given range end is inside this range. This means that we have to\n\t\t\t\t// shrink common range to the given range end.\n\t\t\t\tcommonRangeEnd = otherRange.end;\n\t\t\t}\n\n\t\t\treturn new Range( commonRangeStart, commonRangeEnd );\n\t\t}\n\n\t\t// Ranges do not intersect, so they do not have common part.\n\t\treturn null;\n\t}\n\n\t/**\n\t * Computes and returns the smallest set of {@link #isFlat flat} ranges, that covers this range in whole.\n\t *\n\t * See an example of a model structure (`[` and `]` are range boundaries):\n\t *\n\t *\t\troot root\n\t *\t\t |- element DIV DIV P2 P3 DIV\n\t *\t\t | |- element H H P1 f o o b a r H P4\n\t *\t\t | | |- \"fir[st\" fir[st lorem se]cond ipsum\n\t *\t\t | |- element P1\n\t *\t\t | | |- \"lorem\" ||\n\t *\t\t |- element P2 ||\n\t *\t\t | |- \"foo\" VV\n\t *\t\t |- element P3\n\t *\t\t | |- \"bar\" root\n\t *\t\t |- element DIV DIV [P2 P3] DIV\n\t *\t\t | |- element H H [P1] f o o b a r H P4\n\t *\t\t | | |- \"se]cond\" fir[st] lorem [se]cond ipsum\n\t *\t\t | |- element P4\n\t *\t\t | | |- \"ipsum\"\n\t *\n\t * As it can be seen, letters contained in the range are: `stloremfoobarse`, spread across different parents.\n\t * We are looking for minimal set of flat ranges that contains the same nodes.\n\t *\n\t * Minimal flat ranges for above range `( [ 0, 0, 3 ], [ 3, 0, 2 ] )` will be:\n\t *\n\t *\t\t( [ 0, 0, 3 ], [ 0, 0, 5 ] ) = \"st\"\n\t *\t\t( [ 0, 1 ], [ 0, 2 ] ) = element P1 (\"lorem\")\n\t *\t\t( [ 1 ], [ 3 ] ) = element P2, element P3 (\"foobar\")\n\t *\t\t( [ 3, 0, 0 ], [ 3, 0, 2 ] ) = \"se\"\n\t *\n\t * **Note:** if an {@link module:engine/model/element~Element element} is not wholly contained in this range, it won't be returned\n\t * in any of the returned flat ranges. See in the example how `H` elements at the beginning and at the end of the range\n\t * were omitted. Only their parts that were wholly in the range were returned.\n\t *\n\t * **Note:** this method is not returning flat ranges that contain no nodes.\n\t *\n\t * @returns {Array.<module:engine/model/range~Range>} Array of flat ranges covering this range.\n\t */\n\tgetMinimalFlatRanges() {\n\t\tconst ranges = [];\n\t\tconst diffAt = this.start.getCommonPath( this.end ).length;\n\n\t\tconst pos = Position._createAt( this.start );\n\t\tlet posParent = pos.parent;\n\n\t\t// Go up.\n\t\twhile ( pos.path.length > diffAt + 1 ) {\n\t\t\tconst howMany = posParent.maxOffset - pos.offset;\n\n\t\t\tif ( howMany !== 0 ) {\n\t\t\t\tranges.push( new Range( pos, pos.getShiftedBy( howMany ) ) );\n\t\t\t}\n\n\t\t\tpos.path = pos.path.slice( 0, -1 );\n\t\t\tpos.offset++;\n\t\t\tposParent = posParent.parent;\n\t\t}\n\n\t\t// Go down.\n\t\twhile ( pos.path.length <= this.end.path.length ) {\n\t\t\tconst offset = this.end.path[ pos.path.length - 1 ];\n\t\t\tconst howMany = offset - pos.offset;\n\n\t\t\tif ( howMany !== 0 ) {\n\t\t\t\tranges.push( new Range( pos, pos.getShiftedBy( howMany ) ) );\n\t\t\t}\n\n\t\t\tpos.offset = offset;\n\t\t\tpos.path.push( 0 );\n\t\t}\n\n\t\treturn ranges;\n\t}\n\n\t/**\n\t * Creates a {@link module:engine/model/treewalker~TreeWalker TreeWalker} instance with this range as a boundary.\n\t *\n\t * For example, to iterate over all items in the entire document root:\n\t *\n\t *\t\t// Create a range spanning over the entire root content:\n\t *\t\tconst range = editor.model.createRangeIn( editor.model.document.getRoot() );\n\t *\n\t *\t\t// Iterate over all items in this range:\n\t *\t\tfor ( const value of range.getWalker() ) {\n\t *\t\t\tconsole.log( value.item );\n\t *\t\t}\n\t *\n\t * @param {Object} options Object with configuration options. See {@link module:engine/model/treewalker~TreeWalker}.\n\t * @param {module:engine/model/position~Position} [options.startPosition]\n\t * @param {Boolean} [options.singleCharacters=false]\n\t * @param {Boolean} [options.shallow=false]\n\t * @param {Boolean} [options.ignoreElementEnd=false]\n\t */\n\tgetWalker( options = {} ) {\n\t\toptions.boundaries = this;\n\n\t\treturn new TreeWalker( options );\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all {@link module:engine/model/item~Item items} that are in this range and returns\n\t * them.\n\t *\n\t * This method uses {@link module:engine/model/treewalker~TreeWalker} with `boundaries` set to this range and `ignoreElementEnd` option\n\t * set to `true`. However it returns only {@link module:engine/model/item~Item model items},\n\t * not {@link module:engine/model/treewalker~TreeWalkerValue}.\n\t *\n\t * You may specify additional options for the tree walker. See {@link module:engine/model/treewalker~TreeWalker} for\n\t * a full list of available options.\n\t *\n\t * @method getItems\n\t * @param {Object} options Object with configuration options. See {@link module:engine/model/treewalker~TreeWalker}.\n\t * @returns {Iterable.<module:engine/model/item~Item>}\n\t */\n\t* getItems( options = {} ) {\n\t\toptions.boundaries = this;\n\t\toptions.ignoreElementEnd = true;\n\n\t\tconst treeWalker = new TreeWalker( options );\n\n\t\tfor ( const value of treeWalker ) {\n\t\t\tyield value.item;\n\t\t}\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all {@link module:engine/model/position~Position positions} that are boundaries or\n\t * contained in this range.\n\t *\n\t * This method uses {@link module:engine/model/treewalker~TreeWalker} with `boundaries` set to this range. However it returns only\n\t * {@link module:engine/model/position~Position positions}, not {@link module:engine/model/treewalker~TreeWalkerValue}.\n\t *\n\t * You may specify additional options for the tree walker. See {@link module:engine/model/treewalker~TreeWalker} for\n\t * a full list of available options.\n\t *\n\t * @param {Object} options Object with configuration options. See {@link module:engine/model/treewalker~TreeWalker}.\n\t * @returns {Iterable.<module:engine/model/position~Position>}\n\t */\n\t* getPositions( options = {} ) {\n\t\toptions.boundaries = this;\n\n\t\tconst treeWalker = new TreeWalker( options );\n\n\t\tyield treeWalker.position;\n\n\t\tfor ( const value of treeWalker ) {\n\t\t\tyield value.nextPosition;\n\t\t}\n\t}\n\n\t/**\n\t * Returns a range that is a result of transforming this range by given `operation`.\n\t *\n\t * **Note:** transformation may break one range into multiple ranges (for example, when a part of the range is\n\t * moved to a different part of document tree). For this reason, an array is returned by this method and it\n\t * may contain one or more `Range` instances.\n\t *\n\t * @param {module:engine/model/operation/operation~Operation} operation Operation to transform range by.\n\t * @returns {Array.<module:engine/model/range~Range>} Range which is the result of transformation.\n\t */\n\tgetTransformedByOperation( operation ) {\n\t\tswitch ( operation.type ) {\n\t\t\tcase 'insert':\n\t\t\t\treturn this._getTransformedByInsertOperation( operation );\n\t\t\tcase 'move':\n\t\t\tcase 'remove':\n\t\t\tcase 'reinsert':\n\t\t\t\treturn this._getTransformedByMoveOperation( operation );\n\t\t\tcase 'split':\n\t\t\t\treturn [ this._getTransformedBySplitOperation( operation ) ];\n\t\t\tcase 'merge':\n\t\t\t\treturn [ this._getTransformedByMergeOperation( operation ) ];\n\t\t}\n\n\t\treturn [ new Range( this.start, this.end ) ];\n\t}\n\n\t/**\n\t * Returns a range that is a result of transforming this range by multiple `operations`.\n\t *\n\t * @see ~Range#getTransformedByOperation\n\t * @param {Iterable.<module:engine/model/operation/operation~Operation>} operations Operations to transform the range by.\n\t * @returns {Array.<module:engine/model/range~Range>} Range which is the result of transformation.\n\t */\n\tgetTransformedByOperations( operations ) {\n\t\tconst ranges = [ new Range( this.start, this.end ) ];\n\n\t\tfor ( const operation of operations ) {\n\t\t\tfor ( let i = 0; i < ranges.length; i++ ) {\n\t\t\t\tconst result = ranges[ i ].getTransformedByOperation( operation );\n\n\t\t\t\tranges.splice( i, 1, ...result );\n\t\t\t\ti += result.length - 1;\n\t\t\t}\n\t\t}\n\n\t\t// It may happen that a range is split into two, and then the part of second \"piece\" is moved into first\n\t\t// \"piece\". In this case we will have incorrect third range, which should not be included in the result --\n\t\t// because it is already included in the first \"piece\". In this loop we are looking for all such ranges that\n\t\t// are inside other ranges and we simply remove them.\n\t\tfor ( let i = 0; i < ranges.length; i++ ) {\n\t\t\tconst range = ranges[ i ];\n\n\t\t\tfor ( let j = i + 1; j < ranges.length; j++ ) {\n\t\t\t\tconst next = ranges[ j ];\n\n\t\t\t\tif ( range.containsRange( next ) || next.containsRange( range ) || range.isEqual( next ) ) {\n\t\t\t\t\tranges.splice( j, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn ranges;\n\t}\n\n\t/**\n\t * Returns an {@link module:engine/model/element~Element} or {@link module:engine/model/documentfragment~DocumentFragment}\n\t * which is a common ancestor of the range's both ends (in which the entire range is contained).\n\t *\n\t * @returns {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment|null}\n\t */\n\tgetCommonAncestor() {\n\t\treturn this.start.getCommonAncestor( this.end );\n\t}\n\n\t/**\n\t * Converts `Range` to plain object and returns it.\n\t *\n\t * @returns {Object} `Node` converted to plain object.\n\t */\n\ttoJSON() {\n\t\treturn {\n\t\t\tstart: this.start.toJSON(),\n\t\t\tend: this.end.toJSON()\n\t\t};\n\t}\n\n\t/**\n\t * Returns a new range that is equal to current range.\n\t *\n\t * @returns {module:engine/model/range~Range}\n\t */\n\tclone() {\n\t\treturn new this.constructor( this.start, this.end );\n\t}\n\n\t/**\n\t * Returns a result of transforming a copy of this range by insert operation.\n\t *\n\t * One or more ranges may be returned as a result of this transformation.\n\t *\n\t * @protected\n\t * @param {module:engine/model/operation/insertoperation~InsertOperation} operation\n\t * @returns {Array.<module:engine/model/range~Range>}\n\t */\n\t_getTransformedByInsertOperation( operation, spread = false ) {\n\t\treturn this._getTransformedByInsertion( operation.position, operation.howMany, spread );\n\t}\n\n\t/**\n\t * Returns a result of transforming a copy of this range by move operation.\n\t *\n\t * One or more ranges may be returned as a result of this transformation.\n\t *\n\t * @protected\n\t * @param {module:engine/model/operation/moveoperation~MoveOperation} operation\n\t * @returns {Array.<module:engine/model/range~Range>}\n\t */\n\t_getTransformedByMoveOperation( operation, spread = false ) {\n\t\tconst sourcePosition = operation.sourcePosition;\n\t\tconst howMany = operation.howMany;\n\t\tconst targetPosition = operation.targetPosition;\n\n\t\treturn this._getTransformedByMove( sourcePosition, targetPosition, howMany, spread );\n\t}\n\n\t/**\n\t * Returns a result of transforming a copy of this range by split operation.\n\t *\n\t * Always one range is returned. The transformation is done in a way to not break the range.\n\t *\n\t * @protected\n\t * @param {module:engine/model/operation/splitoperation~SplitOperation} operation\n\t * @returns {module:engine/model/range~Range}\n\t */\n\t_getTransformedBySplitOperation( operation ) {\n\t\tconst start = this.start._getTransformedBySplitOperation( operation );\n\t\tlet end = this.end._getTransformedBySplitOperation( operation );\n\n\t\tif ( this.end.isEqual( operation.insertionPosition ) ) {\n\t\t\tend = this.end.getShiftedBy( 1 );\n\t\t}\n\n\t\t// Below may happen when range contains graveyard element used by split operation.\n\t\tif ( start.root != end.root ) {\n\t\t\t// End position was next to the moved graveyard element and was moved with it.\n\t\t\t// Fix it by using old `end` which has proper `root`.\n\t\t\tend = this.end.getShiftedBy( -1 );\n\t\t}\n\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Returns a result of transforming a copy of this range by merge operation.\n\t *\n\t * Always one range is returned. The transformation is done in a way to not break the range.\n\t *\n\t * @protected\n\t * @param {module:engine/model/operation/mergeoperation~MergeOperation} operation\n\t * @returns {module:engine/model/range~Range}\n\t */\n\t_getTransformedByMergeOperation( operation ) {\n\t\t// Special case when the marker is set on \"the closing tag\" of an element. Marker can be set like that during\n\t\t// transformations, especially when a content of a few block elements were removed. For example:\n\t\t//\n\t\t// {} is the transformed range, [] is the removed range.\n\t\t// <p>F[o{o</p><p>B}ar</p><p>Xy]z</p>\n\t\t//\n\t\t// <p>Fo{o</p><p>B}ar</p><p>z</p>\n\t\t// <p>F{</p><p>B}ar</p><p>z</p>\n\t\t// <p>F{</p>}<p>z</p>\n\t\t// <p>F{}z</p>\n\t\t//\n\t\tif ( this.start.isEqual( operation.targetPosition ) && this.end.isEqual( operation.deletionPosition ) ) {\n\t\t\treturn new Range( this.start );\n\t\t}\n\n\t\tlet start = this.start._getTransformedByMergeOperation( operation );\n\t\tlet end = this.end._getTransformedByMergeOperation( operation );\n\n\t\tif ( start.root != end.root ) {\n\t\t\t// This happens when the end position was next to the merged (deleted) element.\n\t\t\t// Then, the end position was moved to the graveyard root. In this case we need to fix\n\t\t\t// the range cause its boundaries would be in different roots.\n\t\t\tend = this.end.getShiftedBy( -1 );\n\t\t}\n\n\t\tif ( start.isAfter( end ) ) {\n\t\t\t// This happens in three following cases:\n\t\t\t//\n\t\t\t// Case 1: Merge operation source position is before the target position (due to some transformations, OT, etc.)\n\t\t\t// This means that start can be moved before the end of the range.\n\t\t\t//\n\t\t\t// Before: <p>a{a</p><p>b}b</p><p>cc</p>\n\t\t\t// Merge: <p>b}b</p><p>cca{a</p>\n\t\t\t// Fix: <p>{b}b</p><p>ccaa</p>\n\t\t\t//\n\t\t\t// Case 2: Range start is before merged node but not directly.\n\t\t\t// Result should include all nodes that were in the original range.\n\t\t\t//\n\t\t\t// Before: <p>aa</p>{<p>cc</p><p>b}b</p>\n\t\t\t// Merge: <p>aab}b</p>{<p>cc</p>\n\t\t\t// Fix: <p>aa{bb</p><p>cc</p>}\n\t\t\t//\n\t\t\t// The range is expanded by an additional `b` letter but it is better than dropping the whole `cc` paragraph.\n\t\t\t//\n\t\t\t// Case 3: Range start is directly before merged node.\n\t\t\t// Resulting range should include only nodes from the merged element:\n\t\t\t//\n\t\t\t// Before: <p>aa</p>{<p>b}b</p><p>cc</p>\n\t\t\t// Merge: <p>aab}b</p>{<p>cc</p>\n\t\t\t// Fix: <p>aa{b}b</p><p>cc</p>\n\t\t\t//\n\n\t\t\tif ( operation.sourcePosition.isBefore( operation.targetPosition ) ) {\n\t\t\t\t// Case 1.\n\t\t\t\tstart = Position._createAt( end );\n\t\t\t\tstart.offset = 0;\n\t\t\t} else {\n\t\t\t\tif ( !operation.deletionPosition.isEqual( start ) ) {\n\t\t\t\t\t// Case 2.\n\t\t\t\t\tend = operation.deletionPosition;\n\t\t\t\t}\n\n\t\t\t\t// In both case 2 and 3 start is at the end of the merge-to element.\n\t\t\t\tstart = operation.targetPosition;\n\t\t\t}\n\n\t\t\treturn new Range( start, end );\n\t\t}\n\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Returns an array containing one or two {@link ~Range ranges} that are a result of transforming this\n\t * {@link ~Range range} by inserting `howMany` nodes at `insertPosition`. Two {@link ~Range ranges} are\n\t * returned if the insertion was inside this {@link ~Range range} and `spread` is set to `true`.\n\t *\n\t * Examples:\n\t *\n\t *\t\tlet range = model.createRange(\n\t *\t\t\tmodel.createPositionFromPath( root, [ 2, 7 ] ),\n\t *\t\t\tmodel.createPositionFromPath( root, [ 4, 0, 1 ] )\n\t *\t\t);\n\t *\t\tlet transformed = range._getTransformedByInsertion( model.createPositionFromPath( root, [ 1 ] ), 2 );\n\t *\t\t// transformed array has one range from [ 4, 7 ] to [ 6, 0, 1 ]\n\t *\n\t *\t\ttransformed = range._getTransformedByInsertion( model.createPositionFromPath( root, [ 4, 0, 0 ] ), 4 );\n\t *\t\t// transformed array has one range from [ 2, 7 ] to [ 4, 0, 5 ]\n\t *\n\t *\t\ttransformed = range._getTransformedByInsertion( model.createPositionFromPath( root, [ 3, 2 ] ), 4 );\n\t *\t\t// transformed array has one range, which is equal to original range\n\t *\n\t *\t\ttransformed = range._getTransformedByInsertion( model.createPositionFromPath( root, [ 3, 2 ] ), 4, true );\n\t *\t\t// transformed array has two ranges: from [ 2, 7 ] to [ 3, 2 ] and from [ 3, 6 ] to [ 4, 0, 1 ]\n\t *\n\t * @protected\n\t * @param {module:engine/model/position~Position} insertPosition Position where nodes are inserted.\n\t * @param {Number} howMany How many nodes are inserted.\n\t * @param {Boolean} [spread] Flag indicating whether this {~Range range} should be spread if insertion\n\t * was inside the range. Defaults to `false`.\n\t * @returns {Array.<module:engine/model/range~Range>} Result of the transformation.\n\t */\n\t_getTransformedByInsertion( insertPosition, howMany, spread = false ) {\n\t\tif ( spread && this.containsPosition( insertPosition ) ) {\n\t\t\t// Range has to be spread. The first part is from original start to the spread point.\n\t\t\t// The other part is from spread point to the original end, but transformed by\n\t\t\t// insertion to reflect insertion changes.\n\n\t\t\treturn [\n\t\t\t\tnew Range( this.start, insertPosition ),\n\t\t\t\tnew Range(\n\t\t\t\t\tinsertPosition.getShiftedBy( howMany ),\n\t\t\t\t\tthis.end._getTransformedByInsertion( insertPosition, howMany )\n\t\t\t\t)\n\t\t\t];\n\t\t} else {\n\t\t\tconst range = new Range( this.start, this.end );\n\n\t\t\trange.start = range.start._getTransformedByInsertion( insertPosition, howMany );\n\t\t\trange.end = range.end._getTransformedByInsertion( insertPosition, howMany );\n\n\t\t\treturn [ range ];\n\t\t}\n\t}\n\n\t/**\n\t * Returns an array containing {@link ~Range ranges} that are a result of transforming this\n\t * {@link ~Range range} by moving `howMany` nodes from `sourcePosition` to `targetPosition`.\n\t *\n\t * @protected\n\t * @param {module:engine/model/position~Position} sourcePosition Position from which nodes are moved.\n\t * @param {module:engine/model/position~Position} targetPosition Position to where nodes are moved.\n\t * @param {Number} howMany How many nodes are moved.\n\t * @param {Boolean} [spread=false] Whether the range should be spread if the move points inside the range.\n\t * @returns {Array.<module:engine/model/range~Range>} Result of the transformation.\n\t */\n\t_getTransformedByMove( sourcePosition, targetPosition, howMany, spread = false ) {\n\t\t// Special case for transforming a collapsed range. Just transform it like a position.\n\t\tif ( this.isCollapsed ) {\n\t\t\tconst newPos = this.start._getTransformedByMove( sourcePosition, targetPosition, howMany );\n\n\t\t\treturn [ new Range( newPos ) ];\n\t\t}\n\n\t\t// Special case for transformation when a part of the range is moved towards the range.\n\t\t//\n\t\t// Examples:\n\t\t//\n\t\t// <div><p>ab</p><p>c[d</p></div><p>e]f</p> --> <div><p>ab</p></div><p>c[d</p><p>e]f</p>\n\t\t// <p>e[f</p><div><p>a]b</p><p>cd</p></div> --> <p>e[f</p><p>a]b</p><div><p>cd</p></div>\n\t\t//\n\t\t// Without this special condition, the default algorithm leaves an \"artifact\" range from one of `differenceSet` parts:\n\t\t//\n\t\t// <div><p>ab</p><p>c[d</p></div><p>e]f</p> --> <div><p>ab</p>{</div>}<p>c[d</p><p>e]f</p>\n\t\t//\n\t\t// This special case is applied only if the range is to be kept together (not spread).\n\t\tconst moveRange = Range._createFromPositionAndShift( sourcePosition, howMany );\n\t\tconst insertPosition = targetPosition._getTransformedByDeletion( sourcePosition, howMany );\n\n\t\tif ( this.containsPosition( targetPosition ) && !spread ) {\n\t\t\tif ( moveRange.containsPosition( this.start ) || moveRange.containsPosition( this.end ) ) {\n\t\t\t\tconst start = this.start._getTransformedByMove( sourcePosition, targetPosition, howMany );\n\t\t\t\tconst end = this.end._getTransformedByMove( sourcePosition, targetPosition, howMany );\n\n\t\t\t\treturn [ new Range( start, end ) ];\n\t\t\t}\n\t\t}\n\n\t\t// Default algorithm.\n\t\tlet result;\n\n\t\tconst differenceSet = this.getDifference( moveRange );\n\t\tlet difference = null;\n\n\t\tconst common = this.getIntersection( moveRange );\n\n\t\tif ( differenceSet.length == 1 ) {\n\t\t\t// `moveRange` and this range may intersect but may be separate.\n\t\t\tdifference = new Range(\n\t\t\t\tdifferenceSet[ 0 ].start._getTransformedByDeletion( sourcePosition, howMany ),\n\t\t\t\tdifferenceSet[ 0 ].end._getTransformedByDeletion( sourcePosition, howMany )\n\t\t\t);\n\t\t} else if ( differenceSet.length == 2 ) {\n\t\t\t// `moveRange` is inside this range.\n\t\t\tdifference = new Range(\n\t\t\t\tthis.start,\n\t\t\t\tthis.end._getTransformedByDeletion( sourcePosition, howMany )\n\t\t\t);\n\t\t} // else, `moveRange` contains this range.\n\n\t\tif ( difference ) {\n\t\t\tresult = difference._getTransformedByInsertion( insertPosition, howMany, common !== null || spread );\n\t\t} else {\n\t\t\tresult = [];\n\t\t}\n\n\t\tif ( common ) {\n\t\t\tconst transformedCommon = new Range(\n\t\t\t\tcommon.start._getCombined( moveRange.start, insertPosition ),\n\t\t\t\tcommon.end._getCombined( moveRange.start, insertPosition )\n\t\t\t);\n\n\t\t\tif ( result.length == 2 ) {\n\t\t\t\tresult.splice( 1, 0, transformedCommon );\n\t\t\t} else {\n\t\t\t\tresult.push( transformedCommon );\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Returns a copy of this range that is transformed by deletion of `howMany` nodes from `deletePosition`.\n\t *\n\t * If the deleted range is intersecting with the transformed range, the transformed range will be shrank.\n\t *\n\t * If the deleted range contains transformed range, `null` will be returned.\n\t *\n\t * @protected\n\t * @param {module:engine/model/position~Position} deletionPosition Position from which nodes are removed.\n\t * @param {Number} howMany How many nodes are removed.\n\t * @returns {module:engine/model/range~Range|null} Result of the transformation.\n\t */\n\t_getTransformedByDeletion( deletePosition, howMany ) {\n\t\tlet newStart = this.start._getTransformedByDeletion( deletePosition, howMany );\n\t\tlet newEnd = this.end._getTransformedByDeletion( deletePosition, howMany );\n\n\t\tif ( newStart == null && newEnd == null ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( newStart == null ) {\n\t\t\tnewStart = deletePosition;\n\t\t}\n\n\t\tif ( newEnd == null ) {\n\t\t\tnewEnd = deletePosition;\n\t\t}\n\n\t\treturn new Range( newStart, newEnd );\n\t}\n\n\t/**\n\t * Creates a new range, spreading from specified {@link module:engine/model/position~Position position} to a position moved by\n\t * given `shift`. If `shift` is a negative value, shifted position is treated as the beginning of the range.\n\t *\n\t * @protected\n\t * @param {module:engine/model/position~Position} position Beginning of the range.\n\t * @param {Number} shift How long the range should be.\n\t * @returns {module:engine/model/range~Range}\n\t */\n\tstatic _createFromPositionAndShift( position, shift ) {\n\t\tconst start = position;\n\t\tconst end = position.getShiftedBy( shift );\n\n\t\treturn shift > 0 ? new this( start, end ) : new this( end, start );\n\t}\n\n\t/**\n\t * Creates a range inside an {@link module:engine/model/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * @protected\n\t * @param {module:engine/model/element~Element} element Element which is a parent for the range.\n\t * @returns {module:engine/model/range~Range}\n\t */\n\tstatic _createIn( element ) {\n\t\treturn new this( Position._createAt( element, 0 ), Position._createAt( element, element.maxOffset ) );\n\t}\n\n\t/**\n\t * Creates a range that starts before given {@link module:engine/model/item~Item model item} and ends after it.\n\t *\n\t * @protected\n\t * @param {module:engine/model/item~Item} item\n\t * @returns {module:engine/model/range~Range}\n\t */\n\tstatic _createOn( item ) {\n\t\treturn this._createFromPositionAndShift( Position._createBefore( item ), item.offsetSize );\n\t}\n\n\t/**\n\t * Combines all ranges from the passed array into a one range. At least one range has to be passed.\n\t * Passed ranges must not have common parts.\n\t *\n\t * The first range from the array is a reference range. If other ranges start or end on the exactly same position where\n\t * the reference range, they get combined into one range.\n\t *\n\t *\t\t[ ][] [ ][ ][ ][ ][] [ ] // Passed ranges, shown sorted\n\t *\t\t[ ] // The result of the function if the first range was a reference range.\n\t *\t [ ] // The result of the function if the third-to-seventh range was a reference range.\n\t *\t [ ] // The result of the function if the last range was a reference range.\n\t *\n\t * @param {Array.<module:engine/model/range~Range>} ranges Ranges to combine.\n\t * @returns {module:engine/model/range~Range} Combined range.\n\t */\n\tstatic _createFromRanges( ranges ) {\n\t\tif ( ranges.length === 0 ) {\n\t\t\t/**\n\t\t\t * At least one range has to be passed to\n\t\t\t * {@link module:engine/model/range~Range._createFromRanges `Range._createFromRanges()`}.\n\t\t\t *\n\t\t\t * @error range-create-from-ranges-empty-array\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'range-create-from-ranges-empty-array: At least one range has to be passed.' );\n\t\t} else if ( ranges.length == 1 ) {\n\t\t\treturn ranges[ 0 ].clone();\n\t\t}\n\n\t\t// 1. Set the first range in `ranges` array as a reference range.\n\t\t// If we are going to return just a one range, one of the ranges need to be the reference one.\n\t\t// Other ranges will be stuck to that range, if possible.\n\t\tconst ref = ranges[ 0 ];\n\n\t\t// 2. Sort all the ranges so it's easier to process them.\n\t\tranges.sort( ( a, b ) => {\n\t\t\treturn a.start.isAfter( b.start ) ? 1 : -1;\n\t\t} );\n\n\t\t// 3. Check at which index the reference range is now.\n\t\tconst refIndex = ranges.indexOf( ref );\n\n\t\t// 4. At this moment we don't need the original range.\n\t\t// We are going to modify the result and we need to return a new instance of Range.\n\t\t// We have to create a copy of the reference range.\n\t\tconst result = new this( ref.start, ref.end );\n\n\t\t// 5. Ranges should be checked and glued starting from the range that is closest to the reference range.\n\t\t// Since ranges are sorted, start with the range with index that is closest to reference range index.\n\t\tif ( refIndex > 0 ) {\n\t\t\tfor ( let i = refIndex - 1; true; i++ ) {\n\t\t\t\tif ( ranges[ i ].end.isEqual( result.start ) ) {\n\t\t\t\t\tresult.start = Position._createAt( ranges[ i ].start );\n\t\t\t\t} else {\n\t\t\t\t\t// If ranges are not starting/ending at the same position there is no point in looking further.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// 6. Ranges should be checked and glued starting from the range that is closest to the reference range.\n\t\t// Since ranges are sorted, start with the range with index that is closest to reference range index.\n\t\tfor ( let i = refIndex + 1; i < ranges.length; i++ ) {\n\t\t\tif ( ranges[ i ].start.isEqual( result.end ) ) {\n\t\t\t\tresult.end = Position._createAt( ranges[ i ].end );\n\t\t\t} else {\n\t\t\t\t// If ranges are not starting/ending at the same position there is no point in looking further.\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Creates a `Range` instance from given plain object (i.e. parsed JSON string).\n\t *\n\t * @param {Object} json Plain object to be converted to `Range`.\n\t * @param {module:engine/model/document~Document} doc Document object that will be range owner.\n\t * @returns {module:engine/model/element~Element} `Range` instance created using given plain object.\n\t */\n\tstatic fromJSON( json, doc ) {\n\t\treturn new this( Position.fromJSON( json.start, doc ), Position.fromJSON( json.end, doc ) );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/conversion/mapper\n */\n\nimport ModelPosition from '../model/position';\nimport ModelRange from '../model/range';\n\nimport ViewPosition from '../view/position';\nimport ViewRange from '../view/range';\nimport ViewText from '../view/text';\n\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * Maps elements, positions and markers between {@link module:engine/view/document~Document the view} and\n * {@link module:engine/model/model the model}.\n *\n * Mapper use bound elements to find corresponding elements and positions, so, to get proper results,\n * all model elements should be {@link module:engine/conversion/mapper~Mapper#bindElements bound}.\n *\n * To map complex model to/from view relations, you may provide custom callbacks for\n * {@link module:engine/conversion/mapper~Mapper#event:modelToViewPosition modelToViewPosition event} and\n * {@link module:engine/conversion/mapper~Mapper#event:viewToModelPosition viewToModelPosition event} that are fired whenever\n * a position mapping request occurs.\n * Those events are fired by {@link module:engine/conversion/mapper~Mapper#toViewPosition toViewPosition}\n * and {@link module:engine/conversion/mapper~Mapper#toModelPosition toModelPosition} methods. `Mapper` adds it's own default callbacks\n * with `'lowest'` priority. To override default `Mapper` mapping, add custom callback with higher priority and\n * stop the event.\n */\nexport default class Mapper {\n\t/**\n\t * Creates an instance of the mapper.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Model element to view element mapping.\n\t\t *\n\t\t * @private\n\t\t * @member {WeakMap}\n\t\t */\n\t\tthis._modelToViewMapping = new WeakMap();\n\n\t\t/**\n\t\t * View element to model element mapping.\n\t\t *\n\t\t * @private\n\t\t * @member {WeakMap}\n\t\t */\n\t\tthis._viewToModelMapping = new WeakMap();\n\n\t\t/**\n\t\t * A map containing callbacks between view element names and functions evaluating length of view elements\n\t\t * in model.\n\t\t *\n\t\t * @private\n\t\t * @member {Map}\n\t\t */\n\t\tthis._viewToModelLengthCallbacks = new Map();\n\n\t\t/**\n\t\t * Model marker name to view elements mapping.\n\t\t *\n\t\t * Keys are `String`s while values are `Set`s with {@link module:engine/view/element~Element view elements}.\n\t\t * One marker (name) can be mapped to multiple elements.\n\t\t *\n\t\t * @private\n\t\t * @member {Map}\n\t\t */\n\t\tthis._markerNameToElements = new Map();\n\n\t\t// Default mapper algorithm for mapping model position to view position.\n\t\tthis.on( 'modelToViewPosition', ( evt, data ) => {\n\t\t\tif ( data.viewPosition ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst viewContainer = this._modelToViewMapping.get( data.modelPosition.parent );\n\n\t\t\tdata.viewPosition = this._findPositionIn( viewContainer, data.modelPosition.offset );\n\t\t}, { priority: 'low' } );\n\n\t\t// Default mapper algorithm for mapping view position to model position.\n\t\tthis.on( 'viewToModelPosition', ( evt, data ) => {\n\t\t\tif ( data.modelPosition ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst viewBlock = this.findMappedViewAncestor( data.viewPosition );\n\t\t\tconst modelParent = this._viewToModelMapping.get( viewBlock );\n\t\t\tconst modelOffset = this._toModelOffset( data.viewPosition.parent, data.viewPosition.offset, viewBlock );\n\n\t\t\tdata.modelPosition = ModelPosition._createAt( modelParent, modelOffset );\n\t\t}, { priority: 'low' } );\n\t}\n\n\t/**\n\t * Marks model and view elements as corresponding. Corresponding elements can be retrieved by using\n\t * the {@link module:engine/conversion/mapper~Mapper#toModelElement toModelElement} and\n\t * {@link module:engine/conversion/mapper~Mapper#toViewElement toViewElement} methods.\n\t * The information that elements are bound is also used to translate positions.\n\t *\n\t * @param {module:engine/model/element~Element} modelElement Model element.\n\t * @param {module:engine/view/element~Element} viewElement View element.\n\t */\n\tbindElements( modelElement, viewElement ) {\n\t\tthis._modelToViewMapping.set( modelElement, viewElement );\n\t\tthis._viewToModelMapping.set( viewElement, modelElement );\n\t}\n\n\t/**\n\t * Unbinds given {@link module:engine/view/element~Element view element} from the map.\n\t *\n\t * **Note:** view-to-model binding will be removed, if it existed. However, corresponding model-to-view binding\n\t * will be removed only if model element is still bound to passed `viewElement`.\n\t *\n\t * This behavior lets for re-binding model element to another view element without fear of losing the new binding\n\t * when the previously bound view element is unbound.\n\t *\n\t * @param {module:engine/view/element~Element} viewElement View element to unbind.\n\t */\n\tunbindViewElement( viewElement ) {\n\t\tconst modelElement = this.toModelElement( viewElement );\n\n\t\tthis._viewToModelMapping.delete( viewElement );\n\n\t\tif ( this._modelToViewMapping.get( modelElement ) == viewElement ) {\n\t\t\tthis._modelToViewMapping.delete( modelElement );\n\t\t}\n\t}\n\n\t/**\n\t * Unbinds given {@link module:engine/model/element~Element model element} from the map.\n\t *\n\t * **Note:** model-to-view binding will be removed, if it existed. However, corresponding view-to-model binding\n\t * will be removed only if view element is still bound to passed `modelElement`.\n\t *\n\t * This behavior lets for re-binding view element to another model element without fear of losing the new binding\n\t * when the previously bound model element is unbound.\n\t *\n\t * @param {module:engine/model/element~Element} modelElement Model element to unbind.\n\t */\n\tunbindModelElement( modelElement ) {\n\t\tconst viewElement = this.toViewElement( modelElement );\n\n\t\tthis._modelToViewMapping.delete( modelElement );\n\n\t\tif ( this._viewToModelMapping.get( viewElement ) == modelElement ) {\n\t\t\tthis._viewToModelMapping.delete( viewElement );\n\t\t}\n\t}\n\n\t/**\n\t * Binds given marker name with given {@link module:engine/view/element~Element view element}. The element\n\t * will be added to the current set of elements bound with given marker name.\n\t *\n\t * @param {module:engine/view/element~Element} element Element to bind.\n\t * @param {String} name Marker name.\n\t */\n\tbindElementToMarker( element, name ) {\n\t\tconst elements = this._markerNameToElements.get( name ) || new Set();\n\n\t\telements.add( element );\n\n\t\tthis._markerNameToElements.set( name, elements );\n\t}\n\n\t/**\n\t * Unbinds all elements from given marker name.\n\t *\n\t * @param {String} name Marker name.\n\t */\n\tunbindElementsFromMarkerName( name ) {\n\t\tthis._markerNameToElements.delete( name );\n\t}\n\n\t/**\n\t * Removes all model to view and view to model bindings.\n\t */\n\tclearBindings() {\n\t\tthis._modelToViewMapping = new WeakMap();\n\t\tthis._viewToModelMapping = new WeakMap();\n\t\tthis._markerNameToElements = new Map();\n\t}\n\n\t/**\n\t * Gets the corresponding model element.\n\t *\n\t * **Note:** {@link module:engine/view/uielement~UIElement} does not have corresponding element in model.\n\t *\n\t * @param {module:engine/view/element~Element} viewElement View element.\n\t * @returns {module:engine/model/element~Element|undefined} Corresponding model element or `undefined` if not found.\n\t */\n\ttoModelElement( viewElement ) {\n\t\treturn this._viewToModelMapping.get( viewElement );\n\t}\n\n\t/**\n\t * Gets the corresponding view element.\n\t *\n\t * @param {module:engine/model/element~Element} modelElement Model element.\n\t * @returns {module:engine/view/element~Element|undefined} Corresponding view element or `undefined` if not found.\n\t */\n\ttoViewElement( modelElement ) {\n\t\treturn this._modelToViewMapping.get( modelElement );\n\t}\n\n\t/**\n\t * Gets the corresponding model range.\n\t *\n\t * @param {module:engine/view/range~Range} viewRange View range.\n\t * @returns {module:engine/model/range~Range} Corresponding model range.\n\t */\n\ttoModelRange( viewRange ) {\n\t\treturn new ModelRange( this.toModelPosition( viewRange.start ), this.toModelPosition( viewRange.end ) );\n\t}\n\n\t/**\n\t * Gets the corresponding view range.\n\t *\n\t * @param {module:engine/model/range~Range} modelRange Model range.\n\t * @returns {module:engine/view/range~Range} Corresponding view range.\n\t */\n\ttoViewRange( modelRange ) {\n\t\treturn new ViewRange( this.toViewPosition( modelRange.start ), this.toViewPosition( modelRange.end ) );\n\t}\n\n\t/**\n\t * Gets the corresponding model position.\n\t *\n\t * @fires viewToModelPosition\n\t * @param {module:engine/view/position~Position} viewPosition View position.\n\t * @returns {module:engine/model/position~Position} Corresponding model position.\n\t */\n\ttoModelPosition( viewPosition ) {\n\t\tconst data = {\n\t\t\tviewPosition,\n\t\t\tmapper: this\n\t\t};\n\n\t\tthis.fire( 'viewToModelPosition', data );\n\n\t\treturn data.modelPosition;\n\t}\n\n\t/**\n\t * Gets the corresponding view position.\n\t *\n\t * @fires modelToViewPosition\n\t * @param {module:engine/model/position~Position} modelPosition Model position.\n\t * @param {Object} [options] Additional options for position mapping process.\n\t * @param {Boolean} [options.isPhantom=false] Should be set to `true` if the model position to map is pointing to a place\n\t * in model tree which no longer exists. For example, it could be an end of a removed model range.\n\t * @returns {module:engine/view/position~Position} Corresponding view position.\n\t */\n\ttoViewPosition( modelPosition, options = { isPhantom: false } ) {\n\t\tconst data = {\n\t\t\tmodelPosition,\n\t\t\tmapper: this,\n\t\t\tisPhantom: options.isPhantom\n\t\t};\n\n\t\tthis.fire( 'modelToViewPosition', data );\n\n\t\treturn data.viewPosition;\n\t}\n\n\t/**\n\t * Gets all view elements bound to the given marker name.\n\t *\n\t * @param {String} name Marker name.\n\t * @returns {Set.<module:engine/view/element~Element>|null} View elements bound with given marker name or `null`\n\t * if no elements are bound to given marker name.\n\t */\n\tmarkerNameToElements( name ) {\n\t\tconst boundElements = this._markerNameToElements.get( name );\n\n\t\tif ( !boundElements ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst elements = new Set();\n\n\t\tfor ( const element of boundElements ) {\n\t\t\tif ( element.is( 'attributeElement' ) ) {\n\t\t\t\tfor ( const clone of element.getElementsWithSameId() ) {\n\t\t\t\t\telements.add( clone );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\telements.add( element );\n\t\t\t}\n\t\t}\n\n\t\treturn elements;\n\t}\n\n\t/**\n\t * Registers a callback that evaluates the length in the model of a view element with given name.\n\t *\n\t * The callback is fired with one argument, which is a view element instance. The callback is expected to return\n\t * a number representing the length of view element in model.\n\t *\n\t *\t\t// List item in view may contain nested list, which have other list items. In model though,\n\t *\t\t// the lists are represented by flat structure. Because of those differences, length of list view element\n\t *\t\t// may be greater than one. In the callback it's checked how many nested list items are in evaluated list item.\n\t *\n\t *\t\tfunction getViewListItemLength( element ) {\n\t *\t\t\tlet length = 1;\n\t *\n\t *\t\t\tfor ( let child of element.getChildren() ) {\n\t *\t\t\t\tif ( child.name == 'ul' || child.name == 'ol' ) {\n\t *\t\t\t\t\tfor ( let item of child.getChildren() ) {\n\t *\t\t\t\t\t\tlength += getViewListItemLength( item );\n\t *\t\t\t\t\t}\n\t *\t\t\t\t}\n\t *\t\t\t}\n\t *\n\t *\t\t\treturn length;\n\t *\t\t}\n\t *\n\t *\t\tmapper.registerViewToModelLength( 'li', getViewListItemLength );\n\t *\n\t * @param {String} viewElementName Name of view element for which callback is registered.\n\t * @param {Function} lengthCallback Function return a length of view element instance in model.\n\t */\n\tregisterViewToModelLength( viewElementName, lengthCallback ) {\n\t\tthis._viewToModelLengthCallbacks.set( viewElementName, lengthCallback );\n\t}\n\n\t/**\n\t * For given `viewPosition`, finds and returns the closest ancestor of this position that has a mapping to\n\t * the model.\n\t *\n\t * @param {module:engine/view/position~Position} viewPosition Position for which mapped ancestor should be found.\n\t * @returns {module:engine/view/element~Element}\n\t */\n\tfindMappedViewAncestor( viewPosition ) {\n\t\tlet parent = viewPosition.parent;\n\n\t\twhile ( !this._viewToModelMapping.has( parent ) ) {\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn parent;\n\t}\n\n\t/**\n\t * Calculates model offset based on the view position and the block element.\n\t *\n\t * Example:\n\t *\n\t *\t\t<p>foo<b>ba|r</b></p> // _toModelOffset( b, 2, p ) -> 5\n\t *\n\t * Is a sum of:\n\t *\n\t *\t\t<p>foo|<b>bar</b></p> // _toModelOffset( p, 3, p ) -> 3\n\t *\t\t<p>foo<b>ba|r</b></p> // _toModelOffset( b, 2, b ) -> 2\n\t *\n\t * @private\n\t * @param {module:engine/view/element~Element} viewParent Position parent.\n\t * @param {Number} viewOffset Position offset.\n\t * @param {module:engine/view/element~Element} viewBlock Block used as a base to calculate offset.\n\t * @returns {Number} Offset in the model.\n\t */\n\t_toModelOffset( viewParent, viewOffset, viewBlock ) {\n\t\tif ( viewBlock != viewParent ) {\n\t\t\t// See example.\n\t\t\tconst offsetToParentStart = this._toModelOffset( viewParent.parent, viewParent.index, viewBlock );\n\t\t\tconst offsetInParent = this._toModelOffset( viewParent, viewOffset, viewParent );\n\n\t\t\treturn offsetToParentStart + offsetInParent;\n\t\t}\n\n\t\t// viewBlock == viewParent, so we need to calculate the offset in the parent element.\n\n\t\t// If the position is a text it is simple (\"ba|r\" -> 2).\n\t\tif ( viewParent.is( 'text' ) ) {\n\t\t\treturn viewOffset;\n\t\t}\n\n\t\t// If the position is in an element we need to sum lengths of siblings ( <b> bar </b> foo | -> 3 + 3 = 6 ).\n\t\tlet modelOffset = 0;\n\n\t\tfor ( let i = 0; i < viewOffset; i++ ) {\n\t\t\tmodelOffset += this.getModelLength( viewParent.getChild( i ) );\n\t\t}\n\n\t\treturn modelOffset;\n\t}\n\n\t/**\n\t * Gets the length of the view element in the model.\n\t *\n\t * The length is calculated as follows:\n\t * * if {@link #registerViewToModelLength length mapping callback} is provided for given `viewNode` it is used to\n\t * evaluate model length (`viewNode` is used as first and only parameter passed to the callback),\n\t * * length of a {@link module:engine/view/text~Text text node} is equal to the length of it's\n\t * {@link module:engine/view/text~Text#data data},\n\t * * length of a {@link module:engine/view/uielement~UIElement ui element} is equal to 0,\n\t * * length of a mapped {@link module:engine/view/element~Element element} is equal to 1,\n\t * * length of a not-mapped {@link module:engine/view/element~Element element} is equal to the length of it's children.\n\t *\n\t * Examples:\n\t *\n\t *\t\tfoo -> 3 // Text length is equal to it's data length.\n\t *\t\t<p>foo</p> -> 1 // Length of an element which is mapped is by default equal to 1.\n\t *\t\t<b>foo</b> -> 3 // Length of an element which is not mapped is a length of its children.\n\t *\t\t<div><p>x</p><p>y</p></div> -> 2 // Assuming that <div> is not mapped and <p> are mapped.\n\t *\n\t * @param {module:engine/view/element~Element} viewNode View node.\n\t * @returns {Number} Length of the node in the tree model.\n\t */\n\tgetModelLength( viewNode ) {\n\t\tif ( this._viewToModelLengthCallbacks.get( viewNode.name ) ) {\n\t\t\tconst callback = this._viewToModelLengthCallbacks.get( viewNode.name );\n\n\t\t\treturn callback( viewNode );\n\t\t} else if ( this._viewToModelMapping.has( viewNode ) ) {\n\t\t\treturn 1;\n\t\t} else if ( viewNode.is( 'text' ) ) {\n\t\t\treturn viewNode.data.length;\n\t\t} else if ( viewNode.is( 'uiElement' ) ) {\n\t\t\treturn 0;\n\t\t} else {\n\t\t\tlet len = 0;\n\n\t\t\tfor ( const child of viewNode.getChildren() ) {\n\t\t\t\tlen += this.getModelLength( child );\n\t\t\t}\n\n\t\t\treturn len;\n\t\t}\n\t}\n\n\t/**\n\t * Finds the position in the view node (or its children) with the expected model offset.\n\t *\n\t * Example:\n\t *\n\t *\t\t<p>fo<b>bar</b>bom</p> -> expected offset: 4\n\t *\n\t *\t\t_findPositionIn( p, 4 ):\n\t *\t\t<p>|fo<b>bar</b>bom</p> -> expected offset: 4, actual offset: 0\n\t *\t\t<p>fo|<b>bar</b>bom</p> -> expected offset: 4, actual offset: 2\n\t *\t\t<p>fo<b>bar</b>|bom</p> -> expected offset: 4, actual offset: 5 -> we are too far\n\t *\n\t *\t\t_findPositionIn( b, 4 - ( 5 - 3 ) ):\n\t *\t\t<p>fo<b>|bar</b>bom</p> -> expected offset: 2, actual offset: 0\n\t *\t\t<p>fo<b>bar|</b>bom</p> -> expected offset: 2, actual offset: 3 -> we are too far\n\t *\n\t *\t\t_findPositionIn( bar, 2 - ( 3 - 3 ) ):\n\t *\t\tWe are in the text node so we can simple find the offset.\n\t *\t\t<p>fo<b>ba|r</b>bom</p> -> expected offset: 2, actual offset: 2 -> position found\n\t *\n\t * @private\n\t * @param {module:engine/view/element~Element} viewParent Tree view element in which we are looking for the position.\n\t * @param {Number} expectedOffset Expected offset.\n\t * @returns {module:engine/view/position~Position} Found position.\n\t */\n\t_findPositionIn( viewParent, expectedOffset ) {\n\t\t// Last scanned view node.\n\t\tlet viewNode;\n\t\t// Length of the last scanned view node.\n\t\tlet lastLength = 0;\n\n\t\tlet modelOffset = 0;\n\t\tlet viewOffset = 0;\n\n\t\t// In the text node it is simple: offset in the model equals offset in the text.\n\t\tif ( viewParent.is( 'text' ) ) {\n\t\t\treturn new ViewPosition( viewParent, expectedOffset );\n\t\t}\n\n\t\t// In other cases we add lengths of child nodes to find the proper offset.\n\n\t\t// If it is smaller we add the length.\n\t\twhile ( modelOffset < expectedOffset ) {\n\t\t\tviewNode = viewParent.getChild( viewOffset );\n\t\t\tlastLength = this.getModelLength( viewNode );\n\t\t\tmodelOffset += lastLength;\n\t\t\tviewOffset++;\n\t\t}\n\n\t\t// If it equals we found the position.\n\t\tif ( modelOffset == expectedOffset ) {\n\t\t\treturn this._moveViewPositionToTextNode( new ViewPosition( viewParent, viewOffset ) );\n\t\t}\n\t\t// If it is higher we need to enter last child.\n\t\telse {\n\t\t\t// ( modelOffset - lastLength ) is the offset to the child we enter,\n\t\t\t// so we subtract it from the expected offset to fine the offset in the child.\n\t\t\treturn this._findPositionIn( viewNode, expectedOffset - ( modelOffset - lastLength ) );\n\t\t}\n\t}\n\n\t/**\n\t * Because we prefer positions in text nodes over positions next to text node moves view position to the text node\n\t * if it was next to it.\n\t *\n\t *\t\t<p>[]<b>foo</b></p> -> <p>[]<b>foo</b></p> // do not touch if position is not directly next to text\n\t *\t\t<p>foo[]<b>foo</b></p> -> <p>foo{}<b>foo</b></p> // move to text node\n\t *\t\t<p><b>[]foo</b></p> -> <p><b>{}foo</b></p> // move to text node\n\t *\n\t * @private\n\t * @param {module:engine/view/position~Position} viewPosition Position potentially next to text node.\n\t * @returns {module:engine/view/position~Position} Position in text node if possible.\n\t */\n\t_moveViewPositionToTextNode( viewPosition ) {\n\t\t// If the position is just after text node, put it at the end of that text node.\n\t\t// If the position is just before text node, put it at the beginning of that text node.\n\t\tconst nodeBefore = viewPosition.nodeBefore;\n\t\tconst nodeAfter = viewPosition.nodeAfter;\n\n\t\tif ( nodeBefore instanceof ViewText ) {\n\t\t\treturn new ViewPosition( nodeBefore, nodeBefore.data.length );\n\t\t} else if ( nodeAfter instanceof ViewText ) {\n\t\t\treturn new ViewPosition( nodeAfter, 0 );\n\t\t}\n\n\t\t// Otherwise, just return the given position.\n\t\treturn viewPosition;\n\t}\n\n\t/**\n\t * Fired for each model-to-view position mapping request. The purpose of this event is to enable custom model-to-view position\n\t * mapping. Callbacks added to this event take {@link module:engine/model/position~Position model position} and are expected to\n\t * calculate {@link module:engine/view/position~Position view position}. Calculated view position should be added as `viewPosition`\n\t * value in `data` object that is passed as one of parameters to the event callback.\n\t *\n\t * \t\t// Assume that \"captionedImage\" model element is converted to <img> and following <span> elements in view,\n\t * \t\t// and the model element is bound to <img> element. Force mapping model positions inside \"captionedImage\" to that\n\t * \t\t// <span> element.\n\t *\t\tmapper.on( 'modelToViewPosition', ( evt, data ) => {\n\t *\t\t\tconst positionParent = modelPosition.parent;\n\t *\n\t *\t\t\tif ( positionParent.name == 'captionedImage' ) {\n\t *\t\t\t\tconst viewImg = data.mapper.toViewElement( positionParent );\n\t *\t\t\t\tconst viewCaption = viewImg.nextSibling; // The <span> element.\n\t *\n\t *\t\t\t\tdata.viewPosition = new ViewPosition( viewCaption, modelPosition.offset );\n\t *\n\t *\t\t\t\t// Stop the event if other callbacks should not modify calculated value.\n\t *\t\t\t\tevt.stop();\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * **Note:** keep in mind that sometimes a \"phantom\" model position is being converted. \"Phantom\" model position is\n\t * a position that points to a non-existing place in model. Such position might still be valid for conversion, though\n\t * (it would point to a correct place in view when converted). One example of such situation is when a range is\n\t * removed from model, there may be a need to map the range's end (which is no longer valid model position). To\n\t * handle such situation, check `data.isPhantom` flag:\n\t *\n\t * \t\t// Assume that there is \"customElement\" model element and whenever position is before it, we want to move it\n\t * \t\t// to the inside of the view element bound to \"customElement\".\n\t *\t\tmapper.on( 'modelToViewPosition', ( evt, data ) => {\n\t *\t\t\tif ( data.isPhantom ) {\n\t *\t\t\t\treturn;\n\t *\t\t\t}\n\t *\n\t *\t\t\t// Below line might crash for phantom position that does not exist in model.\n\t *\t\t\tconst sibling = data.modelPosition.nodeBefore;\n\t *\n\t *\t\t\t// Check if this is the element we are interested in.\n\t *\t\t\tif ( !sibling.is( 'customElement' ) ) {\n\t *\t\t\t\treturn;\n\t *\t\t\t}\n\t *\n\t *\t\t\tconst viewElement = data.mapper.toViewElement( sibling );\n\t *\n\t *\t\t\tdata.viewPosition = new ViewPosition( sibling, 0 );\n\t *\n\t *\t\t\tevt.stop();\n\t *\t\t} );\n\t *\n\t * **Note:** default mapping callback is provided with `low` priority setting and does not cancel the event, so it is possible to\n\t * attach a custom callback after default callback and also use `data.viewPosition` calculated by default callback\n\t * (for example to fix it).\n\t *\n\t * **Note:** default mapping callback will not fire if `data.viewPosition` is already set.\n\t *\n\t * **Note:** these callbacks are called **very often**. For efficiency reasons, it is advised to use them only when position\n\t * mapping between given model and view elements is unsolvable using just elements mapping and default algorithm. Also,\n\t * the condition that checks if special case scenario happened should be as simple as possible.\n\t *\n\t * @event modelToViewPosition\n\t * @param {Object} data Data pipeline object that can store and pass data between callbacks. The callback should add\n\t * `viewPosition` value to that object with calculated {@link module:engine/view/position~Position view position}.\n\t * @param {module:engine/conversion/mapper~Mapper} data.mapper Mapper instance that fired the event.\n\t */\n\n\t/**\n\t * Fired for each view-to-model position mapping request. See {@link module:engine/conversion/mapper~Mapper#event:modelToViewPosition}.\n\t *\n\t * \t\t// See example in `modelToViewPosition` event description.\n\t * \t\t// This custom mapping will map positions from <span> element next to <img> to the \"captionedImage\" element.\n\t *\t\tmapper.on( 'viewToModelPosition', ( evt, data ) => {\n\t *\t\t\tconst positionParent = viewPosition.parent;\n\t *\n\t *\t\t\tif ( positionParent.hasClass( 'image-caption' ) ) {\n\t *\t\t\t\tconst viewImg = positionParent.previousSibling;\n\t *\t\t\t\tconst modelImg = data.mapper.toModelElement( viewImg );\n\t *\n\t *\t\t\t\tdata.modelPosition = new ModelPosition( modelImg, viewPosition.offset );\n\t *\t\t\t\tevt.stop();\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * **Note:** default mapping callback is provided with `low` priority setting and does not cancel the event, so it is possible to\n\t * attach a custom callback after default callback and also use `data.modelPosition` calculated by default callback\n\t * (for example to fix it).\n\t *\n\t * **Note:** default mapping callback will not fire if `data.modelPosition` is already set.\n\t *\n\t * **Note:** these callbacks are called **very often**. For efficiency reasons, it is advised to use them only when position\n\t * mapping between given model and view elements is unsolvable using just elements mapping and default algorithm. Also,\n\t * the condition that checks if special case scenario happened should be as simple as possible.\n\t *\n\t * @event viewToModelPosition\n\t * @param {Object} data Data pipeline object that can store and pass data between callbacks. The callback should add\n\t * `modelPosition` value to that object with calculated {@link module:engine/model/position~Position model position}.\n\t * @param {module:engine/conversion/mapper~Mapper} data.mapper Mapper instance that fired the event.\n\t */\n}\n\nmix( Mapper, EmitterMixin );\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/conversion/modelconsumable\n */\n\nimport TextProxy from '../model/textproxy';\n\n/**\n * Manages a list of consumable values for {@link module:engine/model/item~Item model items}.\n *\n * Consumables are various aspects of the model. A model item can be broken down into singular properties that might be\n * taken into consideration when converting that item.\n *\n * `ModelConsumable` is used by {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} while analyzing changed\n * parts of {@link module:engine/model/document~Document the document}. The added / changed / removed model items are broken down\n * into singular properties (the item itself and it's attributes). All those parts are saved in `ModelConsumable`. Then,\n * during conversion, when given part of model item is converted (i.e. the view element has been inserted into the view,\n * but without attributes), consumable value is removed from `ModelConsumable`.\n *\n * For model items, `ModelConsumable` stores consumable values of one of following types: `insert`, `addattribute:<attributeKey>`,\n * `changeattributes:<attributeKey>`, `removeattributes:<attributeKey>`.\n *\n * In most cases, it is enough to let {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}\n * gather consumable values, so there is no need to use\n * {@link module:engine/conversion/modelconsumable~ModelConsumable#add add method} directly.\n * However, it is important to understand how consumable values can be\n * {@link module:engine/conversion/modelconsumable~ModelConsumable#consume consumed}.\n * See {@link module:engine/conversion/downcasthelpers default downcast converters} for more information.\n *\n * Keep in mind, that one conversion event may have multiple callbacks (converters) attached to it. Each of those is\n * able to convert one or more parts of the model. However, when one of those callbacks actually converts\n * something, other should not, because they would duplicate the results. Using `ModelConsumable` helps avoiding\n * this situation, because callbacks should only convert those values, which were not yet consumed from `ModelConsumable`.\n *\n * Consuming multiple values in a single callback:\n *\n *\t\t// Converter for custom `image` element that might have a `caption` element inside which changes\n *\t\t// how the image is displayed in the view:\n *\t\t//\n *\t\t// Model:\n *\t\t//\n *\t\t// [image]\n *\t\t// └─ [caption]\n *\t\t// └─ foo\n *\t\t//\n *\t\t// View:\n *\t\t//\n *\t\t// <figure>\n *\t\t// ├─ <img />\n *\t\t// └─ <caption>\n *\t\t// └─ foo\n *\t\tmodelConversionDispatcher.on( 'insert:image', ( evt, data, conversionApi ) => {\n *\t\t\t// First, consume the `image` element.\n *\t\t\tconversionApi.consumable.consume( data.item, 'insert' );\n *\n *\t\t\t// Just create normal image element for the view.\n *\t\t\t// Maybe it will be \"decorated\" later.\n *\t\t\tconst viewImage = new ViewElement( 'img' );\n *\t\t\tconst insertPosition = conversionApi.mapper.toViewPosition( data.range.start );\n *\t\t\tconst viewWriter = conversionApi.writer;\n *\n *\t\t\t// Check if the `image` element has children.\n *\t\t\tif ( data.item.childCount > 0 ) {\n *\t\t\t\tconst modelCaption = data.item.getChild( 0 );\n *\n *\t\t\t\t// `modelCaption` insertion change is consumed from consumable values.\n *\t\t\t\t// It will not be converted by other converters, but it's children (probably some text) will be.\n *\t\t\t\t// Through mapping, converters for text will know where to insert contents of `modelCaption`.\n *\t\t\t\tif ( conversionApi.consumable.consume( modelCaption, 'insert' ) ) {\n *\t\t\t\t\tconst viewCaption = new ViewElement( 'figcaption' );\n *\n *\t\t\t\t\tconst viewImageHolder = new ViewElement( 'figure', null, [ viewImage, viewCaption ] );\n *\n *\t\t\t\t\tconversionApi.mapper.bindElements( modelCaption, viewCaption );\n *\t\t\t\t\tconversionApi.mapper.bindElements( data.item, viewImageHolder );\n *\t\t\t\t\tviewWriter.insert( insertPosition, viewImageHolder );\n *\t\t\t\t}\n *\t\t\t} else {\n *\t\t\t\tconversionApi.mapper.bindElements( data.item, viewImage );\n *\t\t\t\tviewWriter.insert( insertPosition, viewImage );\n *\t\t\t}\n *\n *\t\t\tevt.stop();\n *\t\t} );\n */\nexport default class ModelConsumable {\n\t/**\n\t * Creates an empty consumables list.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Contains list of consumable values.\n\t\t *\n\t\t * @private\n\t\t * @member {Map} module:engine/conversion/modelconsumable~ModelConsumable#_consumable\n\t\t */\n\t\tthis._consumable = new Map();\n\n\t\t/**\n\t\t * For each {@link module:engine/model/textproxy~TextProxy} added to `ModelConsumable`, this registry holds parent\n\t\t * of that `TextProxy` and start and end indices of that `TextProxy`. This allows identification of `TextProxy`\n\t\t * instances that points to the same part of the model but are different instances. Each distinct `TextProxy`\n\t\t * is given unique `Symbol` which is then registered as consumable. This process is transparent for `ModelConsumable`\n\t\t * API user because whenever `TextProxy` is added, tested, consumed or reverted, internal mechanisms of\n\t\t * `ModelConsumable` translates `TextProxy` to that unique `Symbol`.\n\t\t *\n\t\t * @private\n\t\t * @member {Map} module:engine/conversion/modelconsumable~ModelConsumable#_textProxyRegistry\n\t\t */\n\t\tthis._textProxyRegistry = new Map();\n\t}\n\n\t/**\n\t * Adds a consumable value to the consumables list and links it with given model item.\n\t *\n\t *\t\tmodelConsumable.add( modelElement, 'insert' ); // Add `modelElement` insertion change to consumable values.\n\t *\t\tmodelConsumable.add( modelElement, 'addAttribute:bold' ); // Add `bold` attribute insertion on `modelElement` change.\n\t *\t\tmodelConsumable.add( modelElement, 'removeAttribute:bold' ); // Add `bold` attribute removal on `modelElement` change.\n\t *\t\tmodelConsumable.add( modelSelection, 'selection' ); // Add `modelSelection` to consumable values.\n\t *\t\tmodelConsumable.add( modelRange, 'range' ); // Add `modelRange` to consumable values.\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/selection~Selection|module:engine/model/range~Range} item\n\t * Model item, range or selection that has the consumable.\n\t * @param {String} type Consumable type. Will be normalized to a proper form, that is either `<word>` or `<part>:<part>`.\n\t * Second colon and everything after will be cut. Passing event name is a safe and good practice.\n\t */\n\tadd( item, type ) {\n\t\ttype = _normalizeConsumableType( type );\n\n\t\tif ( item instanceof TextProxy ) {\n\t\t\titem = this._getSymbolForTextProxy( item );\n\t\t}\n\n\t\tif ( !this._consumable.has( item ) ) {\n\t\t\tthis._consumable.set( item, new Map() );\n\t\t}\n\n\t\tthis._consumable.get( item ).set( type, true );\n\t}\n\n\t/**\n\t * Removes given consumable value from given model item.\n\t *\n\t *\t\tmodelConsumable.consume( modelElement, 'insert' ); // Remove `modelElement` insertion change from consumable values.\n\t *\t\tmodelConsumable.consume( modelElement, 'addAttribute:bold' ); // Remove `bold` attribute insertion on `modelElement` change.\n\t *\t\tmodelConsumable.consume( modelElement, 'removeAttribute:bold' ); // Remove `bold` attribute removal on `modelElement` change.\n\t *\t\tmodelConsumable.consume( modelSelection, 'selection' ); // Remove `modelSelection` from consumable values.\n\t *\t\tmodelConsumable.consume( modelRange, 'range' ); // Remove 'modelRange' from consumable values.\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/selection~Selection|module:engine/model/range~Range} item\n\t * Model item, range or selection from which consumable will be consumed.\n\t * @param {String} type Consumable type. Will be normalized to a proper form, that is either `<word>` or `<part>:<part>`.\n\t * Second colon and everything after will be cut. Passing event name is a safe and good practice.\n\t * @returns {Boolean} `true` if consumable value was available and was consumed, `false` otherwise.\n\t */\n\tconsume( item, type ) {\n\t\ttype = _normalizeConsumableType( type );\n\n\t\tif ( item instanceof TextProxy ) {\n\t\t\titem = this._getSymbolForTextProxy( item );\n\t\t}\n\n\t\tif ( this.test( item, type ) ) {\n\t\t\tthis._consumable.get( item ).set( type, false );\n\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Tests whether there is a consumable value of given type connected with given model item.\n\t *\n\t *\t\tmodelConsumable.test( modelElement, 'insert' ); // Check for `modelElement` insertion change.\n\t *\t\tmodelConsumable.test( modelElement, 'addAttribute:bold' ); // Check for `bold` attribute insertion on `modelElement` change.\n\t *\t\tmodelConsumable.test( modelElement, 'removeAttribute:bold' ); // Check for `bold` attribute removal on `modelElement` change.\n\t *\t\tmodelConsumable.test( modelSelection, 'selection' ); // Check if `modelSelection` is consumable.\n\t *\t\tmodelConsumable.test( modelRange, 'range' ); // Check if `modelRange` is consumable.\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/selection~Selection|module:engine/model/range~Range} item\n\t * Model item, range or selection to be tested.\n\t * @param {String} type Consumable type. Will be normalized to a proper form, that is either `<word>` or `<part>:<part>`.\n\t * Second colon and everything after will be cut. Passing event name is a safe and good practice.\n\t * @returns {null|Boolean} `null` if such consumable was never added, `false` if the consumable values was\n\t * already consumed or `true` if it was added and not consumed yet.\n\t */\n\ttest( item, type ) {\n\t\ttype = _normalizeConsumableType( type );\n\n\t\tif ( item instanceof TextProxy ) {\n\t\t\titem = this._getSymbolForTextProxy( item );\n\t\t}\n\n\t\tconst itemConsumables = this._consumable.get( item );\n\n\t\tif ( itemConsumables === undefined ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst value = itemConsumables.get( type );\n\n\t\tif ( value === undefined ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn value;\n\t}\n\n\t/**\n\t * Reverts consuming of consumable value.\n\t *\n\t *\t\tmodelConsumable.revert( modelElement, 'insert' ); // Revert consuming `modelElement` insertion change.\n\t *\t\tmodelConsumable.revert( modelElement, 'addAttribute:bold' ); // Revert consuming `bold` attribute insert from `modelElement`.\n\t *\t\tmodelConsumable.revert( modelElement, 'removeAttribute:bold' ); // Revert consuming `bold` attribute remove from `modelElement`.\n\t *\t\tmodelConsumable.revert( modelSelection, 'selection' ); // Revert consuming `modelSelection`.\n\t *\t\tmodelConsumable.revert( modelRange, 'range' ); // Revert consuming `modelRange`.\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/selection~Selection|module:engine/model/range~Range} item\n\t * Model item, range or selection to be reverted.\n\t * @param {String} type Consumable type.\n\t * @returns {null|Boolean} `true` if consumable has been reversed, `false` otherwise. `null` if the consumable has\n\t * never been added.\n\t */\n\trevert( item, type ) {\n\t\ttype = _normalizeConsumableType( type );\n\n\t\tif ( item instanceof TextProxy ) {\n\t\t\titem = this._getSymbolForTextProxy( item );\n\t\t}\n\n\t\tconst test = this.test( item, type );\n\n\t\tif ( test === false ) {\n\t\t\tthis._consumable.get( item ).set( type, true );\n\n\t\t\treturn true;\n\t\t} else if ( test === true ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Gets a unique symbol for passed {@link module:engine/model/textproxy~TextProxy} instance. All `TextProxy` instances that\n\t * have same parent, same start index and same end index will get the same symbol.\n\t *\n\t * Used internally to correctly consume `TextProxy` instances.\n\t *\n\t * @private\n\t * @param {module:engine/model/textproxy~TextProxy} textProxy `TextProxy` instance to get a symbol for.\n\t * @returns {Symbol} Symbol representing all equal instances of `TextProxy`.\n\t */\n\t_getSymbolForTextProxy( textProxy ) {\n\t\tlet symbol = null;\n\n\t\tconst startMap = this._textProxyRegistry.get( textProxy.startOffset );\n\n\t\tif ( startMap ) {\n\t\t\tconst endMap = startMap.get( textProxy.endOffset );\n\n\t\t\tif ( endMap ) {\n\t\t\t\tsymbol = endMap.get( textProxy.parent );\n\t\t\t}\n\t\t}\n\n\t\tif ( !symbol ) {\n\t\t\tsymbol = this._addSymbolForTextProxy( textProxy.startOffset, textProxy.endOffset, textProxy.parent );\n\t\t}\n\n\t\treturn symbol;\n\t}\n\n\t/**\n\t * Adds a symbol for given properties that characterizes a {@link module:engine/model/textproxy~TextProxy} instance.\n\t *\n\t * Used internally to correctly consume `TextProxy` instances.\n\t *\n\t * @private\n\t * @param {Number} startIndex Text proxy start index in it's parent.\n\t * @param {Number} endIndex Text proxy end index in it's parent.\n\t * @param {module:engine/model/element~Element} parent Text proxy parent.\n\t * @returns {Symbol} Symbol generated for given properties.\n\t */\n\t_addSymbolForTextProxy( start, end, parent ) {\n\t\tconst symbol = Symbol( 'textProxySymbol' );\n\t\tlet startMap, endMap;\n\n\t\tstartMap = this._textProxyRegistry.get( start );\n\n\t\tif ( !startMap ) {\n\t\t\tstartMap = new Map();\n\t\t\tthis._textProxyRegistry.set( start, startMap );\n\t\t}\n\n\t\tendMap = startMap.get( end );\n\n\t\tif ( !endMap ) {\n\t\t\tendMap = new Map();\n\t\t\tstartMap.set( end, endMap );\n\t\t}\n\n\t\tendMap.set( parent, symbol );\n\n\t\treturn symbol;\n\t}\n}\n\n// Returns a normalized consumable type name from given string. A normalized consumable type name is a string that has\n// at most one colon, for example: `insert` or `addMarker:highlight`. If string to normalize has more \"parts\" (more colons),\n// the other parts are dropped, for example: `addattribute:bold:$text` -> `addattributes:bold`.\n//\n// @param {String} type Consumable type.\n// @returns {String} Normalized consumable type.\nfunction _normalizeConsumableType( type ) {\n\tconst parts = type.split( ':' );\n\n\treturn parts.length > 1 ? parts[ 0 ] + ':' + parts[ 1 ] : parts[ 0 ];\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/conversion/downcastdispatcher\n */\n\nimport Consumable from './modelconsumable';\nimport Range from '../model/range';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport { extend } from 'lodash-es';\n\n/**\n * `DowncastDispatcher` is a central point of downcasting (conversion from model to view), which is a process of reacting to changes\n * in the model and firing a set of events. Callbacks listening to those events are called converters. Those\n * converters role is to convert the model changes to changes in view (for example, adding view nodes or\n * changing attributes on view elements).\n *\n * During conversion process, `DowncastDispatcher` fires events, basing on state of the model and prepares\n * data for those events. It is important to understand that those events are connected with changes done on model,\n * for example: \"node has been inserted\" or \"attribute has changed\". This is in a contrary to upcasting (view to model conversion),\n * where we convert view state (view nodes) to a model tree.\n *\n * The events are prepared basing on a diff created by {@link module:engine/model/differ~Differ Differ}, which buffers them\n * and then passes to `DowncastDispatcher` as a diff between old model state and new model state.\n *\n * Note, that because changes are converted there is a need to have a mapping between model structure and view structure.\n * To map positions and elements during downcast (model to view conversion) use {@link module:engine/conversion/mapper~Mapper}.\n *\n * `DowncastDispatcher` fires following events for model tree changes:\n *\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert insert}\n * if a range of nodes has been inserted to the model tree,\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:remove remove}\n * if a range of nodes has been removed from the model tree,\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute attribute}\n * if attribute has been added, changed or removed from a model node.\n *\n * For {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert insert}\n * and {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute attribute},\n * `DowncastDispatcher` generates {@link module:engine/conversion/modelconsumable~ModelConsumable consumables}.\n * These are used to have a control over which changes has been already consumed. It is useful when some converters\n * overwrite other or converts multiple changes (for example converts insertion of an element and also converts that\n * element's attributes during insertion).\n *\n * Additionally, `DowncastDispatcher` fires events for {@link module:engine/model/markercollection~Marker marker} changes:\n *\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker} if a marker has been added,\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:removeMarker} if a marker has been removed.\n *\n * Note, that changing a marker is done through removing the marker from the old range, and adding on the new range,\n * so both those events are fired.\n *\n * Finally, `DowncastDispatcher` also handles firing events for {@link module:engine/model/selection model selection}\n * conversion:\n *\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:selection}\n * which converts selection from model to view,\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute}\n * which is fired for every selection attribute,\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker}\n * which is fired for every marker which contains selection.\n *\n * Unlike model tree and markers, events for selection are not fired for changes but for selection state.\n *\n * When providing custom listeners for `DowncastDispatcher` remember to check whether given change has not been\n * {@link module:engine/conversion/modelconsumable~ModelConsumable#consume consumed} yet.\n *\n * When providing custom listeners for `DowncastDispatcher` keep in mind that any callback that had\n * {@link module:engine/conversion/modelconsumable~ModelConsumable#consume consumed} a value from a consumable and\n * converted the change should also stop the event (for efficiency purposes).\n *\n * When providing custom listeners for `DowncastDispatcher` remember to use provided\n * {@link module:engine/view/downcastwriter~DowncastWriter view downcast writer} to apply changes to the view document.\n *\n * Example of a custom converter for `DowncastDispatcher`:\n *\n *\t\t// We will convert inserting \"paragraph\" model element into the model.\n *\t\tdowncastDispatcher.on( 'insert:paragraph', ( evt, data, conversionApi ) => {\n *\t\t\t// Remember to check whether the change has not been consumed yet and consume it.\n *\t\t\tif ( conversionApi.consumable.consume( data.item, 'insert' ) ) {\n *\t\t\t\treturn;\n *\t\t\t}\n *\n *\t\t\t// Translate position in model to position in view.\n *\t\t\tconst viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n *\n *\t\t\t// Create <p> element that will be inserted in view at `viewPosition`.\n *\t\t\tconst viewElement = conversionApi.writer.createContainerElement( 'p' );\n *\n *\t\t\t// Bind the newly created view element to model element so positions will map accordingly in future.\n *\t\t\tconversionApi.mapper.bindElements( data.item, viewElement );\n *\n *\t\t\t// Add the newly created view element to the view.\n *\t\t\tconversionApi.writer.insert( viewPosition, viewElement );\n *\n *\t\t\t// Remember to stop the event propagation.\n *\t\t\tevt.stop();\n *\t\t} );\n */\nexport default class DowncastDispatcher {\n\t/**\n\t * Creates a `DowncastDispatcher` instance.\n\t *\n\t * @see module:engine/conversion/downcastdispatcher~DowncastConversionApi\n\t * @param {Object} [conversionApi] Additional properties for interface that will be passed to events fired\n\t * by `DowncastDispatcher`.\n\t */\n\tconstructor( conversionApi = {} ) {\n\t\t/**\n\t\t * Interface passed by dispatcher to the events callbacks.\n\t\t *\n\t\t * @member {module:engine/conversion/downcastdispatcher~DowncastConversionApi}\n\t\t */\n\t\tthis.conversionApi = extend( { dispatcher: this }, conversionApi );\n\t}\n\n\t/**\n\t * Takes {@link module:engine/model/differ~Differ model differ} object with buffered changes and fires conversion basing on it.\n\t *\n\t * @param {module:engine/model/differ~Differ} differ Differ object with buffered changes.\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer View writer that should be used to modify view document.\n\t */\n\tconvertChanges( differ, writer ) {\n\t\t// Before the view is updated, remove markers which have changed.\n\t\tfor ( const change of differ.getMarkersToRemove() ) {\n\t\t\tthis.convertMarkerRemove( change.name, change.range, writer );\n\t\t}\n\n\t\t// Convert changes that happened on model tree.\n\t\tfor ( const entry of differ.getChanges() ) {\n\t\t\tif ( entry.type == 'insert' ) {\n\t\t\t\tthis.convertInsert( Range._createFromPositionAndShift( entry.position, entry.length ), writer );\n\t\t\t} else if ( entry.type == 'remove' ) {\n\t\t\t\tthis.convertRemove( entry.position, entry.length, entry.name, writer );\n\t\t\t} else {\n\t\t\t\t// entry.type == 'attribute'.\n\t\t\t\tthis.convertAttribute( entry.range, entry.attributeKey, entry.attributeOldValue, entry.attributeNewValue, writer );\n\t\t\t}\n\t\t}\n\n\t\t// After the view is updated, convert markers which have changed.\n\t\tfor ( const change of differ.getMarkersToAdd() ) {\n\t\t\tthis.convertMarkerAdd( change.name, change.range, writer );\n\t\t}\n\t}\n\n\t/**\n\t * Starts conversion of a range insertion.\n\t *\n\t * For each node in the range, {@link #event:insert insert event is fired}. For each attribute on each node,\n\t * {@link #event:attribute attribute event is fired}.\n\t *\n\t * @fires insert\n\t * @fires attribute\n\t * @param {module:engine/model/range~Range} range Inserted range.\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer View writer that should be used to modify view document.\n\t */\n\tconvertInsert( range, writer ) {\n\t\tthis.conversionApi.writer = writer;\n\n\t\t// Create a list of things that can be consumed, consisting of nodes and their attributes.\n\t\tthis.conversionApi.consumable = this._createInsertConsumable( range );\n\n\t\t// Fire a separate insert event for each node and text fragment contained in the range.\n\t\tfor ( const value of range ) {\n\t\t\tconst item = value.item;\n\t\t\tconst itemRange = Range._createFromPositionAndShift( value.previousPosition, value.length );\n\t\t\tconst data = {\n\t\t\t\titem,\n\t\t\t\trange: itemRange\n\t\t\t};\n\n\t\t\tthis._testAndFire( 'insert', data );\n\n\t\t\t// Fire a separate addAttribute event for each attribute that was set on inserted items.\n\t\t\t// This is important because most attributes converters will listen only to add/change/removeAttribute events.\n\t\t\t// If we would not add this part, attributes on inserted nodes would not be converted.\n\t\t\tfor ( const key of item.getAttributeKeys() ) {\n\t\t\t\tdata.attributeKey = key;\n\t\t\t\tdata.attributeOldValue = null;\n\t\t\t\tdata.attributeNewValue = item.getAttribute( key );\n\n\t\t\t\tthis._testAndFire( `attribute:${ key }`, data );\n\t\t\t}\n\t\t}\n\n\t\tthis._clearConversionApi();\n\t}\n\n\t/**\n\t * Fires conversion of a single node removal. Fires {@link #event:remove remove event} with provided data.\n\t *\n\t * @param {module:engine/model/position~Position} position Position from which node was removed.\n\t * @param {Number} length Offset size of removed node.\n\t * @param {String} name Name of removed node.\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer View writer that should be used to modify view document.\n\t */\n\tconvertRemove( position, length, name, writer ) {\n\t\tthis.conversionApi.writer = writer;\n\n\t\tthis.fire( 'remove:' + name, { position, length }, this.conversionApi );\n\n\t\tthis._clearConversionApi();\n\t}\n\n\t/**\n\t * Starts conversion of attribute change on given `range`.\n\t *\n\t * For each node in the given `range`, {@link #event:attribute attribute event} is fired with the passed data.\n\t *\n\t * @fires attribute\n\t * @param {module:engine/model/range~Range} range Changed range.\n\t * @param {String} key Key of the attribute that has changed.\n\t * @param {*} oldValue Attribute value before the change or `null` if the attribute has not been set before.\n\t * @param {*} newValue New attribute value or `null` if the attribute has been removed.\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer View writer that should be used to modify view document.\n\t */\n\tconvertAttribute( range, key, oldValue, newValue, writer ) {\n\t\tthis.conversionApi.writer = writer;\n\n\t\t// Create a list with attributes to consume.\n\t\tthis.conversionApi.consumable = this._createConsumableForRange( range, `attribute:${ key }` );\n\n\t\t// Create a separate attribute event for each node in the range.\n\t\tfor ( const value of range ) {\n\t\t\tconst item = value.item;\n\t\t\tconst itemRange = Range._createFromPositionAndShift( value.previousPosition, value.length );\n\t\t\tconst data = {\n\t\t\t\titem,\n\t\t\t\trange: itemRange,\n\t\t\t\tattributeKey: key,\n\t\t\t\tattributeOldValue: oldValue,\n\t\t\t\tattributeNewValue: newValue\n\t\t\t};\n\n\t\t\tthis._testAndFire( `attribute:${ key }`, data );\n\t\t}\n\n\t\tthis._clearConversionApi();\n\t}\n\n\t/**\n\t * Starts model selection conversion.\n\t *\n\t * Fires events for given {@link module:engine/model/selection~Selection selection} to start selection conversion.\n\t *\n\t * @fires selection\n\t * @fires addMarker\n\t * @fires attribute\n\t * @param {module:engine/model/selection~Selection} selection Selection to convert.\n\t * @param {Array.<module:engine/model/markercollection~Marker>} markers Array of markers containing model markers.\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer View writer that should be used to modify view document.\n\t */\n\tconvertSelection( selection, markers, writer ) {\n\t\tconst markersAtSelection = Array.from( markers.getMarkersAtPosition( selection.getFirstPosition() ) );\n\n\t\tthis.conversionApi.writer = writer;\n\t\tthis.conversionApi.consumable = this._createSelectionConsumable( selection, markersAtSelection );\n\n\t\tthis.fire( 'selection', { selection }, this.conversionApi );\n\n\t\tif ( !selection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor ( const marker of markersAtSelection ) {\n\t\t\tconst markerRange = marker.getRange();\n\n\t\t\tif ( !shouldMarkerChangeBeConverted( selection.getFirstPosition(), marker, this.conversionApi.mapper ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst data = {\n\t\t\t\titem: selection,\n\t\t\t\tmarkerName: marker.name,\n\t\t\t\tmarkerRange\n\t\t\t};\n\n\t\t\tif ( this.conversionApi.consumable.test( selection, 'addMarker:' + marker.name ) ) {\n\t\t\t\tthis.fire( 'addMarker:' + marker.name, data, this.conversionApi );\n\t\t\t}\n\t\t}\n\n\t\tfor ( const key of selection.getAttributeKeys() ) {\n\t\t\tconst data = {\n\t\t\t\titem: selection,\n\t\t\t\trange: selection.getFirstRange(),\n\t\t\t\tattributeKey: key,\n\t\t\t\tattributeOldValue: null,\n\t\t\t\tattributeNewValue: selection.getAttribute( key )\n\t\t\t};\n\n\t\t\t// Do not fire event if the attribute has been consumed.\n\t\t\tif ( this.conversionApi.consumable.test( selection, 'attribute:' + data.attributeKey ) ) {\n\t\t\t\tthis.fire( 'attribute:' + data.attributeKey + ':$text', data, this.conversionApi );\n\t\t\t}\n\t\t}\n\n\t\tthis._clearConversionApi();\n\t}\n\n\t/**\n\t * Converts added marker. Fires {@link #event:addMarker addMarker} event for each item\n\t * in marker's range. If range is collapsed single event is dispatched. See event description for more details.\n\t *\n\t * @fires addMarker\n\t * @param {String} markerName Marker name.\n\t * @param {module:engine/model/range~Range} markerRange Marker range.\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer View writer that should be used to modify view document.\n\t */\n\tconvertMarkerAdd( markerName, markerRange, writer ) {\n\t\t// Do not convert if range is in graveyard or not in the document (e.g. in DocumentFragment).\n\t\tif ( !markerRange.root.document || markerRange.root.rootName == '$graveyard' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.conversionApi.writer = writer;\n\n\t\t// In markers' case, event name == consumable name.\n\t\tconst eventName = 'addMarker:' + markerName;\n\n\t\t//\n\t\t// First, fire an event for the whole marker.\n\t\t//\n\t\tconst consumable = new Consumable();\n\t\tconsumable.add( markerRange, eventName );\n\n\t\tthis.conversionApi.consumable = consumable;\n\n\t\tthis.fire( eventName, { markerName, markerRange }, this.conversionApi );\n\n\t\t//\n\t\t// Do not fire events for each item inside the range if the range got consumed.\n\t\t//\n\t\tif ( !consumable.test( markerRange, eventName ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t//\n\t\t// Then, fire an event for each item inside the marker range.\n\t\t//\n\t\tthis.conversionApi.consumable = this._createConsumableForRange( markerRange, eventName );\n\n\t\tfor ( const item of markerRange.getItems() ) {\n\t\t\t// Do not fire event for already consumed items.\n\t\t\tif ( !this.conversionApi.consumable.test( item, eventName ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst data = { item, range: Range._createOn( item ), markerName, markerRange };\n\n\t\t\tthis.fire( eventName, data, this.conversionApi );\n\t\t}\n\n\t\tthis._clearConversionApi();\n\t}\n\n\t/**\n\t * Fires conversion of marker removal. Fires {@link #event:removeMarker removeMarker} event with provided data.\n\t *\n\t * @fires removeMarker\n\t * @param {String} markerName Marker name.\n\t * @param {module:engine/model/range~Range} markerRange Marker range.\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer View writer that should be used to modify view document.\n\t */\n\tconvertMarkerRemove( markerName, markerRange, writer ) {\n\t\t// Do not convert if range is in graveyard or not in the document (e.g. in DocumentFragment).\n\t\tif ( !markerRange.root.document || markerRange.root.rootName == '$graveyard' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.conversionApi.writer = writer;\n\n\t\tthis.fire( 'removeMarker:' + markerName, { markerName, markerRange }, this.conversionApi );\n\n\t\tthis._clearConversionApi();\n\t}\n\n\t/**\n\t * Creates {@link module:engine/conversion/modelconsumable~ModelConsumable} with values to consume from given range,\n\t * assuming that the range has just been inserted to the model.\n\t *\n\t * @private\n\t * @param {module:engine/model/range~Range} range Inserted range.\n\t * @returns {module:engine/conversion/modelconsumable~ModelConsumable} Values to consume.\n\t */\n\t_createInsertConsumable( range ) {\n\t\tconst consumable = new Consumable();\n\n\t\tfor ( const value of range ) {\n\t\t\tconst item = value.item;\n\n\t\t\tconsumable.add( item, 'insert' );\n\n\t\t\tfor ( const key of item.getAttributeKeys() ) {\n\t\t\t\tconsumable.add( item, 'attribute:' + key );\n\t\t\t}\n\t\t}\n\n\t\treturn consumable;\n\t}\n\n\t/**\n\t * Creates {@link module:engine/conversion/modelconsumable~ModelConsumable} with values to consume for given range.\n\t *\n\t * @private\n\t * @param {module:engine/model/range~Range} range Affected range.\n\t * @param {String} type Consumable type.\n\t * @returns {module:engine/conversion/modelconsumable~ModelConsumable} Values to consume.\n\t */\n\t_createConsumableForRange( range, type ) {\n\t\tconst consumable = new Consumable();\n\n\t\tfor ( const item of range.getItems() ) {\n\t\t\tconsumable.add( item, type );\n\t\t}\n\n\t\treturn consumable;\n\t}\n\n\t/**\n\t * Creates {@link module:engine/conversion/modelconsumable~ModelConsumable} with selection consumable values.\n\t *\n\t * @private\n\t * @param {module:engine/model/selection~Selection} selection Selection to create consumable from.\n\t * @param {Iterable.<module:engine/model/markercollection~Marker>} markers Markers which contains selection.\n\t * @returns {module:engine/conversion/modelconsumable~ModelConsumable} Values to consume.\n\t */\n\t_createSelectionConsumable( selection, markers ) {\n\t\tconst consumable = new Consumable();\n\n\t\tconsumable.add( selection, 'selection' );\n\n\t\tfor ( const marker of markers ) {\n\t\t\tconsumable.add( selection, 'addMarker:' + marker.name );\n\t\t}\n\n\t\tfor ( const key of selection.getAttributeKeys() ) {\n\t\t\tconsumable.add( selection, 'attribute:' + key );\n\t\t}\n\n\t\treturn consumable;\n\t}\n\n\t/**\n\t * Tests passed `consumable` to check whether given event can be fired and if so, fires it.\n\t *\n\t * @private\n\t * @fires insert\n\t * @fires attribute\n\t * @param {String} type Event type.\n\t * @param {Object} data Event data.\n\t */\n\t_testAndFire( type, data ) {\n\t\tif ( !this.conversionApi.consumable.test( data.item, type ) ) {\n\t\t\t// Do not fire event if the item was consumed.\n\t\t\treturn;\n\t\t}\n\n\t\tconst name = data.item.name || '$text';\n\n\t\tthis.fire( type + ':' + name, data, this.conversionApi );\n\t}\n\n\t/**\n\t * Clears conversion API object.\n\t *\n\t * @private\n\t */\n\t_clearConversionApi() {\n\t\tdelete this.conversionApi.writer;\n\t\tdelete this.conversionApi.consumable;\n\t}\n\n\t/**\n\t * Fired for inserted nodes.\n\t *\n\t * `insert` is a namespace for a class of events. Names of actually called events follow this pattern:\n\t * `insert:name`. `name` is either `'$text'`, when {@link module:engine/model/text~Text a text node} has been inserted,\n\t * or {@link module:engine/model/element~Element#name name} of inserted element.\n\t *\n\t * This way listeners can either listen to a general `insert` event or specific event (for example `insert:paragraph`).\n\t *\n\t * @event insert\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/item~Item} data.item Inserted item.\n\t * @param {module:engine/model/range~Range} data.range Range spanning over inserted item.\n\t * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n\t * to be used by callback, passed in `DowncastDispatcher` constructor.\n\t */\n\n\t/**\n\t * Fired for removed nodes.\n\t *\n\t * `remove` is a namespace for a class of events. Names of actually called events follow this pattern:\n\t * `remove:name`. `name` is either `'$text'`, when {@link module:engine/model/text~Text a text node} has been removed,\n\t * or the {@link module:engine/model/element~Element#name name} of removed element.\n\t *\n\t * This way listeners can either listen to a general `remove` event or specific event (for example `remove:paragraph`).\n\t *\n\t * @event remove\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/position~Position} data.position Position from which the node has been removed.\n\t * @param {Number} data.length Offset size of the removed node.\n\t * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n\t * to be used by callback, passed in `DowncastDispatcher` constructor.\n\t */\n\n\t/**\n\t * Fired in the following cases:\n\t *\n\t * * when an attribute has been added, changed, or removed from a node,\n\t * * when a node with an attribute is inserted,\n\t * * when collapsed model selection attribute is converted.\n\t *\n\t * `attribute` is a namespace for a class of events. Names of actually called events follow this pattern:\n\t * `attribute:attributeKey:name`. `attributeKey` is the key of added/changed/removed attribute.\n\t * `name` is either `'$text'` if change was on {@link module:engine/model/text~Text a text node},\n\t * or the {@link module:engine/model/element~Element#name name} of element which attribute has changed.\n\t *\n\t * This way listeners can either listen to a general `attribute:bold` event or specific event (for example `attribute:src:image`).\n\t *\n\t * @event attribute\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/item~Item|module:engine/model/documentselection~DocumentSelection} data.item Changed item\n\t * or converted selection.\n\t * @param {module:engine/model/range~Range} data.range Range spanning over changed item or selection range.\n\t * @param {String} data.attributeKey Attribute key.\n\t * @param {*} data.attributeOldValue Attribute value before the change. This is `null` when selection attribute is converted.\n\t * @param {*} data.attributeNewValue New attribute value.\n\t * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.\n\t * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n\t * to be used by callback, passed in `DowncastDispatcher` constructor.\n\t */\n\n\t/**\n\t * Fired for {@link module:engine/model/selection~Selection selection} changes.\n\t *\n\t * @event selection\n\t * @param {module:engine/model/selection~Selection} selection Selection that is converted.\n\t * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.\n\t * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n\t * to be used by callback, passed in `DowncastDispatcher` constructor.\n\t */\n\n\t/**\n\t * Fired when a new marker is added to the model. Also fired when collapsed model selection that is inside marker is converted.\n\t *\n\t * `addMarker` is a namespace for a class of events. Names of actually called events follow this pattern:\n\t * `addMarker:markerName`. By specifying certain marker names, you can make the events even more gradual. For example,\n\t * if markers are named `foo:abc`, `foo:bar`, then it is possible to listen to `addMarker:foo` or `addMarker:foo:abc` and\n\t * `addMarker:foo:bar` events.\n\t *\n\t * If the marker range is not collapsed:\n\t *\n\t * * the event is fired for each item in the marker range one by one,\n\t * * consumables object includes each item of the marker range and the consumable value is same as event name.\n\t *\n\t * If the marker range is collapsed:\n\t *\n\t * * there is only one event,\n\t * * consumables object includes marker range with event name.\n\t *\n\t * If selection inside a marker is converted:\n\t *\n\t * * there is only one event,\n\t * * consumables object includes selection instance with event name.\n\t *\n\t * @event addMarker\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/item~Item|module:engine/model/selection~Selection} data.item Item inside the new marker or\n\t * the selection that is being converted.\n\t * @param {module:engine/model/range~Range} [data.range] Range spanning over converted item. Available only in marker conversion, if\n\t * the marker range was not collapsed.\n\t * @param {module:engine/model/range~Range} data.markerRange Marker range.\n\t * @param {String} data.markerName Marker name.\n\t * @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.\n\t * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n\t * to be used by callback, passed in `DowncastDispatcher` constructor.\n\t */\n\n\t/**\n\t * Fired when marker is removed from the model.\n\t *\n\t * `removeMarker` is a namespace for a class of events. Names of actually called events follow this pattern:\n\t * `removeMarker:markerName`. By specifying certain marker names, you can make the events even more gradual. For example,\n\t * if markers are named `foo:abc`, `foo:bar`, then it is possible to listen to `removeMarker:foo` or `removeMarker:foo:abc` and\n\t * `removeMarker:foo:bar` events.\n\t *\n\t * @event removeMarker\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/range~Range} data.markerRange Marker range.\n\t * @param {String} data.markerName Marker name.\n\t * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n\t * to be used by callback, passed in `DowncastDispatcher` constructor.\n\t */\n}\n\nmix( DowncastDispatcher, EmitterMixin );\n\n// Helper function, checks whether change of `marker` at `modelPosition` should be converted. Marker changes are not\n// converted if they happen inside an element with custom conversion method.\n//\n// @param {module:engine/model/position~Position} modelPosition\n// @param {module:engine/model/markercollection~Marker} marker\n// @param {module:engine/conversion/mapper~Mapper} mapper\n// @returns {Boolean}\nfunction shouldMarkerChangeBeConverted( modelPosition, marker, mapper ) {\n\tconst range = marker.getRange();\n\tconst ancestors = Array.from( modelPosition.getAncestors() );\n\tancestors.shift(); // Remove root element. It cannot be passed to `model.Range#containsItem`.\n\tancestors.reverse();\n\n\tconst hasCustomHandling = ancestors.some( element => {\n\t\tif ( range.containsItem( element ) ) {\n\t\t\tconst viewElement = mapper.toViewElement( element );\n\n\t\t\treturn !!viewElement.getCustomProperty( 'addHighlight' );\n\t\t}\n\t} );\n\n\treturn !hasCustomHandling;\n}\n\n/**\n * Conversion interface that is registered for given {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}\n * and is passed as one of parameters when {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher dispatcher}\n * fires it's events.\n *\n * @interface module:engine/conversion/downcastdispatcher~DowncastConversionApi\n */\n\n/**\n * The {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} instance.\n *\n * @member {module:engine/conversion/downcastdispatcher~DowncastDispatcher} #dispatcher\n */\n\n/**\n * Stores information about what parts of processed model item are still waiting to be handled. After a piece of model item\n * was converted, appropriate consumable value should be {@link module:engine/conversion/modelconsumable~ModelConsumable#consume consumed}.\n *\n * @member {module:engine/conversion/modelconsumable~ModelConsumable} #consumable\n */\n\n/**\n * The {@link module:engine/conversion/mapper~Mapper} instance.\n *\n * @member {module:engine/conversion/mapper~Mapper} #mapper\n */\n\n/**\n * The {@link module:engine/view/downcastwriter~DowncastWriter} instance used to manipulate data during conversion.\n *\n * @member {module:engine/view/downcastwriter~DowncastWriter} #writer\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/selection\n */\n\nimport Position from './position';\nimport Element from './element';\nimport Node from './node';\nimport Range from './range';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';\n\n/**\n * Selection is a set of {@link module:engine/model/range~Range ranges}. It has a direction specified by its\n * {@link module:engine/model/selection~Selection#anchor anchor} and {@link module:engine/model/selection~Selection#focus focus}\n * (it can be {@link module:engine/model/selection~Selection#isBackward forward or backward}).\n * Additionally, selection may have its own attributes (think – whether text typed in in this selection\n * should have those attributes – e.g. whether you type a bolded text).\n *\n * @mixes module:utils/emittermixin~EmitterMixin\n */\nexport default class Selection {\n\t/**\n\t * Creates a new selection instance based on the given {@link module:engine/model/selection~Selectable selectable}\n\t * or creates an empty selection if no arguments were passed.\n\t *\n\t *\t\t// Creates empty selection without ranges.\n\t *\t\tconst selection = writer.createSelection();\n\t *\n\t *\t\t// Creates selection at the given range.\n\t *\t\tconst range = writer.createRange( start, end );\n\t *\t\tconst selection = writer.createSelection( range );\n\t *\n\t *\t\t// Creates selection at the given ranges\n\t *\t\tconst ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t *\t\tconst selection = writer.createSelection( ranges );\n\t *\n\t *\t\t// Creates selection from the other selection.\n\t *\t\t// Note: It doesn't copies selection attributes.\n\t *\t\tconst otherSelection = writer.createSelection();\n\t *\t\tconst selection = writer.createSelection( otherSelection );\n\t *\n\t *\t\t// Creates selection from the given document selection.\n\t *\t\t// Note: It doesn't copies selection attributes.\n\t *\t\tconst documentSelection = model.document.selection;\n\t *\t\tconst selection = writer.createSelection( documentSelection );\n\t *\n\t *\t\t// Creates selection at the given position.\n\t *\t\tconst position = writer.createPositionFromPath( root, path );\n\t *\t\tconst selection = writer.createSelection( position );\n\t *\n\t *\t\t// Creates selection at the given offset in the given element.\n\t *\t\tconst paragraph = writer.createElement( 'paragraph' );\n\t *\t\tconst selection = writer.createSelection( paragraph, offset );\n\t *\n\t *\t\t// Creates a range inside an {@link module:engine/model/element~Element element} which starts before the\n\t *\t\t// first child of that element and ends after the last child of that element.\n\t *\t\tconst selection = writer.createSelection( paragraph, 'in' );\n\t *\n\t *\t\t// Creates a range on an {@link module:engine/model/item~Item item} which starts before the item and ends\n\t *\t\t// just after the item.\n\t *\t\tconst selection = writer.createSelection( paragraph, 'on' );\n\t *\n\t * Selection's constructor allow passing additional options (`'backward'`) as the last argument.\n\t *\n\t *\t\t// Creates backward selection.\n\t *\t\tconst selection = writer.createSelection( range, { backward: true } );\n\t *\n\t * @param {module:engine/model/selection~Selectable} selectable\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Sets place or offset of the selection.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.backward] Sets this selection instance to be backward.\n\t */\n\tconstructor( selectable, placeOrOffset, options ) {\n\t\t/**\n\t\t * Specifies whether the last added range was added as a backward or forward range.\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._lastRangeBackward = false;\n\n\t\t/**\n\t\t * Stores selection ranges.\n\t\t *\n\t\t * @protected\n\t\t * @type {Array.<module:engine/model/range~Range>}\n\t\t */\n\t\tthis._ranges = [];\n\n\t\t/**\n\t\t * List of attributes set on current selection.\n\t\t *\n\t\t * @protected\n\t\t * @type {Map.<String,*>}\n\t\t */\n\t\tthis._attrs = new Map();\n\n\t\tif ( selectable ) {\n\t\t\tthis.setTo( selectable, placeOrOffset, options );\n\t\t}\n\t}\n\n\t/**\n\t * Selection anchor. Anchor is the position from which the selection was started. If a user is making a selection\n\t * by dragging the mouse, the anchor is where the user pressed the mouse button (the beggining of the selection).\n\t *\n\t * Anchor and {@link #focus} define the direction of the selection, which is important\n\t * when expanding/shrinking selection. The focus moves, while the anchor should remain in the same place.\n\t *\n\t * Anchor is always set to the {@link module:engine/model/range~Range#start start} or\n\t * {@link module:engine/model/range~Range#end end} position of the last of selection's ranges. Whether it is\n\t * the `start` or `end` depends on the specified `options.backward`. See the {@link #setTo `setTo()`} method.\n\t *\n\t * May be set to `null` if there are no ranges in the selection.\n\t *\n\t * @see #focus\n\t * @readonly\n\t * @type {module:engine/model/position~Position|null}\n\t */\n\tget anchor() {\n\t\tif ( this._ranges.length > 0 ) {\n\t\t\tconst range = this._ranges[ this._ranges.length - 1 ];\n\n\t\t\treturn this._lastRangeBackward ? range.end : range.start;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Selection focus. Focus is the position where the selection ends. If a user is making a selection\n\t * by dragging the mouse, the focus is where the mouse cursor is.\n\t *\n\t * May be set to `null` if there are no ranges in the selection.\n\t *\n\t * @see #anchor\n\t * @readonly\n\t * @type {module:engine/model/position~Position|null}\n\t */\n\tget focus() {\n\t\tif ( this._ranges.length > 0 ) {\n\t\t\tconst range = this._ranges[ this._ranges.length - 1 ];\n\n\t\t\treturn this._lastRangeBackward ? range.start : range.end;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Whether the selection is collapsed. Selection is collapsed when there is exactly one range in it\n\t * and it is collapsed.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isCollapsed() {\n\t\tconst length = this._ranges.length;\n\n\t\tif ( length === 1 ) {\n\t\t\treturn this._ranges[ 0 ].isCollapsed;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Returns the number of ranges in the selection.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget rangeCount() {\n\t\treturn this._ranges.length;\n\t}\n\n\t/**\n\t * Specifies whether the selection's {@link #focus} precedes the selection's {@link #anchor}.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isBackward() {\n\t\treturn !this.isCollapsed && this._lastRangeBackward;\n\t}\n\n\t/**\n\t * Checks whether this selection is equal to the given selection. Selections are equal if they have the same directions,\n\t * the same number of ranges and all ranges from one selection equal to ranges from the another selection.\n\t *\n\t * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} otherSelection\n\t * Selection to compare with.\n\t * @returns {Boolean} `true` if selections are equal, `false` otherwise.\n\t */\n\tisEqual( otherSelection ) {\n\t\tif ( this.rangeCount != otherSelection.rangeCount ) {\n\t\t\treturn false;\n\t\t} else if ( this.rangeCount === 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( !this.anchor.isEqual( otherSelection.anchor ) || !this.focus.isEqual( otherSelection.focus ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor ( const thisRange of this._ranges ) {\n\t\t\tlet found = false;\n\n\t\t\tfor ( const otherRange of otherSelection._ranges ) {\n\t\t\t\tif ( thisRange.isEqual( otherRange ) ) {\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( !found ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns an iterable object that iterates over copies of selection ranges.\n\t *\n\t * @returns {Iterable.<module:engine/model/range~Range>}\n\t */\n\t* getRanges() {\n\t\tfor ( const range of this._ranges ) {\n\t\t\tyield new Range( range.start, range.end );\n\t\t}\n\t}\n\n\t/**\n\t * Returns a copy of the first range in the selection.\n\t * First range is the one which {@link module:engine/model/range~Range#start start} position\n\t * {@link module:engine/model/position~Position#isBefore is before} start position of all other ranges\n\t * (not to confuse with the first range added to the selection).\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t *\n\t * @returns {module:engine/model/range~Range|null}\n\t */\n\tgetFirstRange() {\n\t\tlet first = null;\n\n\t\tfor ( const range of this._ranges ) {\n\t\t\tif ( !first || range.start.isBefore( first.start ) ) {\n\t\t\t\tfirst = range;\n\t\t\t}\n\t\t}\n\n\t\treturn first ? new Range( first.start, first.end ) : null;\n\t}\n\n\t/**\n\t * Returns a copy of the last range in the selection.\n\t * Last range is the one which {@link module:engine/model/range~Range#end end} position\n\t * {@link module:engine/model/position~Position#isAfter is after} end position of all other ranges (not to confuse with the range most\n\t * recently added to the selection).\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t *\n\t * @returns {module:engine/model/range~Range|null}\n\t */\n\tgetLastRange() {\n\t\tlet last = null;\n\n\t\tfor ( const range of this._ranges ) {\n\t\t\tif ( !last || range.end.isAfter( last.end ) ) {\n\t\t\t\tlast = range;\n\t\t\t}\n\t\t}\n\n\t\treturn last ? new Range( last.start, last.end ) : null;\n\t}\n\n\t/**\n\t * Returns the first position in the selection.\n\t * First position is the position that {@link module:engine/model/position~Position#isBefore is before}\n\t * any other position in the selection.\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t *\n\t * @returns {module:engine/model/position~Position|null}\n\t */\n\tgetFirstPosition() {\n\t\tconst first = this.getFirstRange();\n\n\t\treturn first ? first.start.clone() : null;\n\t}\n\n\t/**\n\t * Returns the last position in the selection.\n\t * Last position is the position that {@link module:engine/model/position~Position#isAfter is after}\n\t * any other position in the selection.\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t *\n\t * @returns {module:engine/model/position~Position|null}\n\t */\n\tgetLastPosition() {\n\t\tconst lastRange = this.getLastRange();\n\n\t\treturn lastRange ? lastRange.end.clone() : null;\n\t}\n\n\t/**\n\t * Sets this selection's ranges and direction to the specified location based on the given\n\t * {@link module:engine/model/selection~Selectable selectable}.\n\t *\n\t *\t\t// Removes all selection's ranges.\n\t *\t\tselection.setTo( null );\n\t *\n\t *\t\t// Sets selection to the given range.\n\t *\t\tconst range = writer.createRange( start, end );\n\t *\t\tselection.setTo( range );\n\t *\n\t *\t\t// Sets selection to given ranges.\n\t *\t\tconst ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t *\t\tselection.setTo( ranges );\n\t *\n\t *\t\t// Sets selection to other selection.\n\t *\t\t// Note: It doesn't copies selection attributes.\n\t *\t\tconst otherSelection = writer.createSelection();\n\t *\t\tselection.setTo( otherSelection );\n\t *\n\t *\t\t// Sets selection to the given document selection.\n\t *\t\t// Note: It doesn't copies selection attributes.\n\t *\t\tconst documentSelection = new DocumentSelection( doc );\n\t *\t\tselection.setTo( documentSelection );\n\t *\n\t *\t\t// Sets collapsed selection at the given position.\n\t *\t\tconst position = writer.createPositionFromPath( root, path );\n\t *\t\tselection.setTo( position );\n\t *\n\t *\t\t// Sets collapsed selection at the position of the given node and an offset.\n\t *\t\tselection.setTo( paragraph, offset );\n\t *\n\t * Creates a range inside an {@link module:engine/model/element~Element element} which starts before the first child of\n \t * that element and ends after the last child of that element.\n\t *\n\t *\t\tselection.setTo( paragraph, 'in' );\n\t *\n\t * Creates a range on an {@link module:engine/model/item~Item item} which starts before the item and ends just after the item.\n\t *\n\t *\t\tselection.setTo( paragraph, 'on' );\n\t *\n\t * `Selection#setTo()`' method allow passing additional options (`backward`) as the last argument.\n\t *\n\t *\t\t// Sets backward selection.\n\t *\t\tconst selection = writer.createSelection( range, { backward: true } );\n\t *\n\t * @param {module:engine/model/selection~Selectable} selectable\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Sets place or offset of the selection.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.backward] Sets this selection instance to be backward.\n\t */\n\tsetTo( selectable, placeOrOffset, options ) {\n\t\tif ( selectable === null ) {\n\t\t\tthis._setRanges( [] );\n\t\t} else if ( selectable instanceof Selection ) {\n\t\t\tthis._setRanges( selectable.getRanges(), selectable.isBackward );\n\t\t} else if ( selectable && typeof selectable.getRanges == 'function' ) {\n\t\t\t// We assume that the selectable is a DocumentSelection.\n\t\t\t// It can't be imported here, because it would lead to circular imports.\n\t\t\tthis._setRanges( selectable.getRanges(), selectable.isBackward );\n\t\t} else if ( selectable instanceof Range ) {\n\t\t\tthis._setRanges( [ selectable ], !!placeOrOffset && !!placeOrOffset.backward );\n\t\t} else if ( selectable instanceof Position ) {\n\t\t\tthis._setRanges( [ new Range( selectable ) ] );\n\t\t} else if ( selectable instanceof Node ) {\n\t\t\tconst backward = !!options && !!options.backward;\n\t\t\tlet range;\n\n\t\t\tif ( placeOrOffset == 'in' ) {\n\t\t\t\trange = Range._createIn( selectable );\n\t\t\t} else if ( placeOrOffset == 'on' ) {\n\t\t\t\trange = Range._createOn( selectable );\n\t\t\t} else if ( placeOrOffset !== undefined ) {\n\t\t\t\trange = new Range( Position._createAt( selectable, placeOrOffset ) );\n\t\t\t} else {\n\t\t\t\t/**\n\t\t\t\t * selection.setTo requires the second parameter when the first parameter is a node.\n\t\t\t\t *\n\t\t\t\t * @error model-selection-setTo-required-second-parameter\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'model-selection-setTo-required-second-parameter: ' +\n\t\t\t\t\t'selection.setTo requires the second parameter when the first parameter is a node.' );\n\t\t\t}\n\n\t\t\tthis._setRanges( [ range ], backward );\n\t\t} else if ( isIterable( selectable ) ) {\n\t\t\t// We assume that the selectable is an iterable of ranges.\n\t\t\tthis._setRanges( selectable, placeOrOffset && !!placeOrOffset.backward );\n\t\t} else {\n\t\t\t/**\n\t\t\t * Cannot set the selection to the given place.\n\t\t\t *\n\t\t\t * Invalid parameters were specified when setting the selection. Common issues:\n\t\t\t *\n\t\t\t * * A {@link module:engine/model/textproxy~TextProxy} instance was passed instead of\n\t\t\t * a real {@link module:engine/model/text~Text}.\n\t\t\t * * View nodes were passed instead of model nodes.\n\t\t\t * * `null`/`undefined` was passed.\n\t\t\t *\n\t\t\t * @error model-selection-setTo-not-selectable\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-selection-setTo-not-selectable: Cannot set the selection to the given place.' );\n\t\t}\n\t}\n\n\t/**\n\t * Replaces all ranges that were added to the selection with given array of ranges. Last range of the array\n\t * is treated like the last added range and is used to set {@link module:engine/model/selection~Selection#anchor} and\n\t * {@link module:engine/model/selection~Selection#focus}. Accepts a flag describing in which direction the selection is made.\n\t *\n\t * @protected\n\t * @fires change:range\n\t * @param {Iterable.<module:engine/model/range~Range>} newRanges Ranges to set.\n\t * @param {Boolean} [isLastBackward=false] Flag describing if last added range was selected forward - from start to end (`false`)\n\t * or backward - from end to start (`true`).\n\t */\n\t_setRanges( newRanges, isLastBackward = false ) {\n\t\tnewRanges = Array.from( newRanges );\n\n\t\t// Check whether there is any range in new ranges set that is different than all already added ranges.\n\t\tconst anyNewRange = newRanges.some( newRange => {\n\t\t\tif ( !( newRange instanceof Range ) ) {\n\t\t\t\t/**\n\t\t\t\t * Selection range set to an object that is not an instance of {@link module:engine/model/range~Range}.\n\t\t\t\t *\n\t\t\t\t * Only {@link module:engine/model/range~Range} instances can be used to set a selection.\n\t\t\t\t * Common mistakes leading to this error are:\n\t\t\t\t *\n\t\t\t\t * * using DOM `Range` object,\n\t\t\t\t * * incorrect CKEditor 5 installation with multiple `ckeditor5-engine` packages having different versions.\n\t\t\t\t *\n\t\t\t\t * @error model-selection-set-ranges-not-range\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'model-selection-set-ranges-not-range: ' +\n\t\t\t\t\t'Selection range set to an object that is not an instance of model.Range.'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn this._ranges.every( oldRange => {\n\t\t\t\treturn !oldRange.isEqual( newRange );\n\t\t\t} );\n\t\t} );\n\n\t\t// Don't do anything if nothing changed.\n\t\tif ( newRanges.length === this._ranges.length && !anyNewRange ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._removeAllRanges();\n\n\t\tfor ( const range of newRanges ) {\n\t\t\tthis._pushRange( range );\n\t\t}\n\n\t\tthis._lastRangeBackward = !!isLastBackward;\n\n\t\tthis.fire( 'change:range', { directChange: true } );\n\t}\n\n\t/**\n\t * Moves {@link module:engine/model/selection~Selection#focus} to the specified location.\n\t *\n\t * The location can be specified in the same form as\n\t * {@link module:engine/model/writer~Writer#createPositionAt writer.createPositionAt()} parameters.\n\t *\n\t * @fires change:range\n\t * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tsetFocus( itemOrPosition, offset ) {\n\t\tif ( this.anchor === null ) {\n\t\t\t/**\n\t\t\t * Cannot set selection focus if there are no ranges in selection.\n\t\t\t *\n\t\t\t * @error model-selection-setFocus-no-ranges\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'model-selection-setFocus-no-ranges: Cannot set selection focus if there are no ranges in selection.'\n\t\t\t);\n\t\t}\n\n\t\tconst newFocus = Position._createAt( itemOrPosition, offset );\n\n\t\tif ( newFocus.compareWith( this.focus ) == 'same' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst anchor = this.anchor;\n\n\t\tif ( this._ranges.length ) {\n\t\t\tthis._popRange();\n\t\t}\n\n\t\tif ( newFocus.compareWith( anchor ) == 'before' ) {\n\t\t\tthis._pushRange( new Range( newFocus, anchor ) );\n\t\t\tthis._lastRangeBackward = true;\n\t\t} else {\n\t\t\tthis._pushRange( new Range( anchor, newFocus ) );\n\t\t\tthis._lastRangeBackward = false;\n\t\t}\n\n\t\tthis.fire( 'change:range', { directChange: true } );\n\t}\n\n\t/**\n\t * Gets an attribute value for given key or `undefined` if that attribute is not set on the selection.\n\t *\n\t * @param {String} key Key of attribute to look for.\n\t * @returns {*} Attribute value or `undefined`.\n\t */\n\tgetAttribute( key ) {\n\t\treturn this._attrs.get( key );\n\t}\n\n\t/**\n\t * Returns iterable that iterates over this selection's attributes.\n\t *\n\t * Attributes are returned as arrays containing two items. First one is attribute key and second is attribute value.\n\t * This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t *\n\t * @returns {Iterable.<*>}\n\t */\n\tgetAttributes() {\n\t\treturn this._attrs.entries();\n\t}\n\n\t/**\n\t * Returns iterable that iterates over this selection's attribute keys.\n\t *\n\t * @returns {Iterable.<String>}\n\t */\n\tgetAttributeKeys() {\n\t\treturn this._attrs.keys();\n\t}\n\n\t/**\n\t * Checks if the selection has an attribute for given key.\n\t *\n\t * @param {String} key Key of attribute to check.\n\t * @returns {Boolean} `true` if attribute with given key is set on selection, `false` otherwise.\n\t */\n\thasAttribute( key ) {\n\t\treturn this._attrs.has( key );\n\t}\n\n\t/**\n\t * Removes an attribute with given key from the selection.\n\t *\n\t * If given attribute was set on the selection, fires the {@link #event:change:range} event with\n\t * removed attribute key.\n\t *\n\t * @fires change:attribute\n\t * @param {String} key Key of attribute to remove.\n\t */\n\tremoveAttribute( key ) {\n\t\tif ( this.hasAttribute( key ) ) {\n\t\t\tthis._attrs.delete( key );\n\n\t\t\tthis.fire( 'change:attribute', { attributeKeys: [ key ], directChange: true } );\n\t\t}\n\t}\n\n\t/**\n\t * Sets attribute on the selection. If attribute with the same key already is set, it's value is overwritten.\n\t *\n\t * If the attribute value has changed, fires the {@link #event:change:range} event with\n\t * the attribute key.\n\t *\n\t * @fires change:attribute\n\t * @param {String} key Key of attribute to set.\n\t * @param {*} value Attribute value.\n\t */\n\tsetAttribute( key, value ) {\n\t\tif ( this.getAttribute( key ) !== value ) {\n\t\t\tthis._attrs.set( key, value );\n\n\t\t\tthis.fire( 'change:attribute', { attributeKeys: [ key ], directChange: true } );\n\t\t}\n\t}\n\n\t/**\n\t * Returns the selected element. {@link module:engine/model/element~Element Element} is considered as selected if there is only\n\t * one range in the selection, and that range contains exactly one element.\n\t * Returns `null` if there is no selected element.\n\t *\n\t * @returns {module:engine/model/element~Element|null}\n\t */\n\tgetSelectedElement() {\n\t\tif ( this.rangeCount !== 1 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst range = this.getFirstRange();\n\t\tconst nodeAfterStart = range.start.nodeAfter;\n\t\tconst nodeBeforeEnd = range.end.nodeBefore;\n\n\t\treturn ( nodeAfterStart instanceof Element && nodeAfterStart == nodeBeforeEnd ) ? nodeAfterStart : null;\n\t}\n\n\t/**\n\t * Checks whether object is of given type following the convention set by\n\t * {@link module:engine/model/node~Node#is `Node#is()`}.\n\t *\n\t *\t\tconst selection = new Selection( ... );\n\t *\n\t *\t\tselection.is( 'selection' ); // true\n\t *\t\tselection.is( 'node' ); // false\n\t *\t\tselection.is( 'element' ); // false\n\t *\n\t * @param {String} type\n\t * @returns {Boolean}\n\t */\n\tis( type ) {\n\t\treturn type == 'selection';\n\t}\n\n\t/**\n\t * Gets elements of type \"block\" touched by the selection.\n\t *\n\t * This method's result can be used for example to apply block styling to all blocks covered by this selection.\n\t *\n\t * **Note:** `getSelectedBlocks()` always returns the deepest block.\n\t *\n\t * In this case the function will return exactly all 3 paragraphs:\n\t *\n\t *\t\t<paragraph>[a</paragraph>\n\t *\t\t<quote>\n\t *\t\t\t<paragraph>b</paragraph>\n\t *\t\t</quote>\n\t *\t\t<paragraph>c]d</paragraph>\n\t *\n\t * In this case the paragraph will also be returned, despite the collapsed selection:\n\t *\n\t *\t\t<paragraph>[]a</paragraph>\n\t *\n\t * **Special case**: If a selection ends at the beginning of a block, that block is not returned as from user perspective\n\t * this block wasn't selected. See [#984](https://github.com/ckeditor/ckeditor5-engine/issues/984) for more details.\n\t *\n\t *\t\t<paragraph>[a</paragraph>\n\t *\t\t<paragraph>b</paragraph>\n\t *\t\t<paragraph>]c</paragraph> // this block will not be returned\n\t *\n\t * @returns {Iterable.<module:engine/model/element~Element>}\n\t */\n\t* getSelectedBlocks() {\n\t\tconst visited = new WeakSet();\n\n\t\tfor ( const range of this.getRanges() ) {\n\t\t\tconst startBlock = getParentBlock( range.start, visited );\n\n\t\t\tif ( startBlock ) {\n\t\t\t\tyield startBlock;\n\t\t\t}\n\n\t\t\tfor ( const value of range.getWalker() ) {\n\t\t\t\tif ( value.type == 'elementEnd' && isUnvisitedBlockContainer( value.item, visited ) ) {\n\t\t\t\t\tyield value.item;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst endBlock = getParentBlock( range.end, visited );\n\n\t\t\t// #984. Don't return the end block if the range ends right at its beginning.\n\t\t\tif ( endBlock && !range.end.isTouching( Position._createAt( endBlock, 0 ) ) ) {\n\t\t\t\tyield endBlock;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns blocks that aren't nested in other selected blocks.\n\t *\n\t * In this case the method will return blocks A, B and E because C & D are children of block B:\n\t *\n\t *\t\t[<blockA></blockA>\n\t *\t\t<blockB>\n\t *\t\t\t<blockC></blockC>\n\t *\t\t\t<blockD></blockD>\n\t *\t\t</blockB>\n\t *\t\t<blockE></blockE>]\n\t *\n\t * **Note:** To get all selected blocks use {@link #getSelectedBlocks `getSelectedBlocks()`}.\n\t *\n\t * @returns {Iterable.<module:engine/model/element~Element>}\n\t */\n\t* getTopMostBlocks() {\n\t\tconst selected = Array.from( this.getSelectedBlocks() );\n\n\t\tfor ( const block of selected ) {\n\t\t\tconst parentBlock = findAncestorBlock( block );\n\n\t\t\t// Filter out blocks that are nested in other selected blocks (like paragraphs in tables).\n\t\t\tif ( !parentBlock || !selected.includes( parentBlock ) ) {\n\t\t\t\tyield block;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks whether the selection contains the entire content of the given element. This means that selection must start\n\t * at a position {@link module:engine/model/position~Position#isTouching touching} the element's start and ends at position\n\t * touching the element's end.\n\t *\n\t * By default, this method will check whether the entire content of the selection's current root is selected.\n\t * Useful to check if e.g. the user has just pressed <kbd>Ctrl</kbd> + <kbd>A</kbd>.\n\t *\n\t * @param {module:engine/model/element~Element} [element=this.anchor.root]\n\t * @returns {Boolean}\n\t */\n\tcontainsEntireContent( element = this.anchor.root ) {\n\t\tconst limitStartPosition = Position._createAt( element, 0 );\n\t\tconst limitEndPosition = Position._createAt( element, 'end' );\n\n\t\treturn limitStartPosition.isTouching( this.getFirstPosition() ) &&\n\t\t\tlimitEndPosition.isTouching( this.getLastPosition() );\n\t}\n\n\t/**\n\t * Adds given range to internal {@link #_ranges ranges array}. Throws an error\n\t * if given range is intersecting with any range that is already stored in this selection.\n\t *\n\t * @protected\n\t * @param {module:engine/model/range~Range} range Range to add.\n\t */\n\t_pushRange( range ) {\n\t\tthis._checkRange( range );\n\t\tthis._ranges.push( new Range( range.start, range.end ) );\n\t}\n\n\t/**\n\t * Checks if given range intersects with ranges that are already in the selection. Throws an error if it does.\n\t *\n\t * @protected\n\t * @param {module:engine/model/range~Range} range Range to check.\n\t */\n\t_checkRange( range ) {\n\t\tfor ( let i = 0; i < this._ranges.length; i++ ) {\n\t\t\tif ( range.isIntersecting( this._ranges[ i ] ) ) {\n\t\t\t\t/**\n\t\t\t\t * Trying to add a range that intersects with another range in the selection.\n\t\t\t\t *\n\t\t\t\t * @error model-selection-range-intersects\n\t\t\t\t * @param {module:engine/model/range~Range} addedRange Range that was added to the selection.\n\t\t\t\t * @param {module:engine/model/range~Range} intersectingRange Range in the selection that intersects with `addedRange`.\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'model-selection-range-intersects: Trying to add a range that intersects with another range in the selection.',\n\t\t\t\t\t{ addedRange: range, intersectingRange: this._ranges[ i ] }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Deletes ranges from internal range array. Uses {@link #_popRange _popRange} to\n\t * ensure proper ranges removal.\n\t *\n\t * @protected\n\t */\n\t_removeAllRanges() {\n\t\twhile ( this._ranges.length > 0 ) {\n\t\t\tthis._popRange();\n\t\t}\n\t}\n\n\t/**\n\t * Removes most recently added range from the selection.\n\t *\n\t * @protected\n\t */\n\t_popRange() {\n\t\tthis._ranges.pop();\n\t}\n\n\t/**\n\t * Fired when selection range(s) changed.\n\t *\n\t * @event change:range\n\t * @param {Boolean} directChange In case of {@link module:engine/model/selection~Selection} class it is always set\n\t * to `true` which indicates that the selection change was caused by a direct use of selection's API.\n\t * The {@link module:engine/model/documentselection~DocumentSelection}, however, may change because its position\n\t * was directly changed through the {@link module:engine/model/writer~Writer writer} or because its position was\n\t * changed because the structure of the model has been changed (which means an indirect change).\n\t * The indirect change does not occur in case of normal (detached) selections because they are \"static\" (as \"not live\")\n\t * which mean that they are not updated once the document changes.\n\t */\n\n\t/**\n\t * Fired when selection attribute changed.\n\t *\n\t * @event change:attribute\n\t * @param {Boolean} directChange In case of {@link module:engine/model/selection~Selection} class it is always set\n\t * to `true` which indicates that the selection change was caused by a direct use of selection's API.\n\t * The {@link module:engine/model/documentselection~DocumentSelection}, however, may change because its attributes\n\t * were directly changed through the {@link module:engine/model/writer~Writer writer} or because its position was\n\t * changed in the model and its attributes were refreshed (which means an indirect change).\n\t * The indirect change does not occur in case of normal (detached) selections because they are \"static\" (as \"not live\")\n\t * which mean that they are not updated once the document changes.\n\t * @param {Array.<String>} attributeKeys Array containing keys of attributes that changed.\n\t */\n}\n\nmix( Selection, EmitterMixin );\n\n// Checks whether the given element extends $block in the schema and has a parent (is not a root).\n// Marks it as already visited.\nfunction isUnvisitedBlockContainer( element, visited ) {\n\tif ( visited.has( element ) ) {\n\t\treturn false;\n\t}\n\n\tvisited.add( element );\n\n\treturn element.document.model.schema.isBlock( element ) && element.parent;\n}\n\n// Finds the lowest element in position's ancestors which is a block.\n// It will search until first ancestor that is a limit element.\n// Marks all ancestors as already visited to not include any of them later on.\nfunction getParentBlock( position, visited ) {\n\tconst schema = position.parent.document.model.schema;\n\n\tconst ancestors = position.parent.getAncestors( { parentFirst: true, includeSelf: true } );\n\n\tlet hasParentLimit = false;\n\n\tconst block = ancestors.find( element => {\n\t\t// Stop searching after first parent node that is limit element.\n\t\tif ( hasParentLimit ) {\n\t\t\treturn false;\n\t\t}\n\n\t\thasParentLimit = schema.isLimit( element );\n\n\t\treturn !hasParentLimit && isUnvisitedBlockContainer( element, visited );\n\t} );\n\n\t// Mark all ancestors of this position's parent, because find() might've stopped early and\n\t// the found block may be a child of another block.\n\tancestors.forEach( element => visited.add( element ) );\n\n\treturn block;\n}\n\n// Returns first ancestor block of a node.\n//\n// @param {module:engine/model/node~Node} node\n// @returns {module:engine/model/node~Node|undefined}\nfunction findAncestorBlock( node ) {\n\tconst schema = node.document.model.schema;\n\n\tlet parent = node.parent;\n\n\twhile ( parent ) {\n\t\tif ( schema.isBlock( parent ) ) {\n\t\t\treturn parent;\n\t\t}\n\n\t\tparent = parent.parent;\n\t}\n}\n\n/**\n * An entity that is used to set selection.\n *\n * See also {@link module:engine/model/selection~Selection#setTo}\n *\n * @typedef {\n * module:engine/model/selection~Selection|\n * module:engine/model/documentselection~DocumentSelection|\n * module:engine/model/position~Position|\n * module:engine/model/range~Range|\n * module:engine/model/node~Node|\n * Iterable.<module:engine/model/range~Range>|\n * null\n * } module:engine/model/selection~Selectable\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/liverange\n */\n\nimport Range from './range';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * `LiveRange` is a type of {@link module:engine/model/range~Range Range}\n * that updates itself as {@link module:engine/model/document~Document document}\n * is changed through operations. It may be used as a bookmark.\n *\n * **Note:** Be very careful when dealing with `LiveRange`. Each `LiveRange` instance bind events that might\n * have to be unbound. Use {@link module:engine/model/liverange~LiveRange#detach detach} whenever you don't need `LiveRange` anymore.\n */\nexport default class LiveRange extends Range {\n\t/**\n\t * Creates a live range.\n\t *\n\t * @see module:engine/model/range~Range\n\t */\n\tconstructor( start, end ) {\n\t\tsuper( start, end );\n\n\t\tbindWithDocument.call( this );\n\t}\n\n\t/**\n\t * Unbinds all events previously bound by `LiveRange`. Use it whenever you don't need `LiveRange` instance\n\t * anymore (i.e. when leaving scope in which it was declared or before re-assigning variable that was\n\t * referring to it).\n\t */\n\tdetach() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Creates a {@link module:engine/model/range~Range range instance} that is equal to this live range.\n\t *\n\t * @returns {module:engine/model/range~Range}\n\t */\n\ttoRange() {\n\t\treturn new Range( this.start, this.end );\n\t}\n\n\t/**\n\t * Creates a `LiveRange` instance that is equal to the given range.\n\t *\n\t * @param {module:engine/model/range~Range} range\n\t * @returns {module:engine/model/liverange~LiveRange}\n\t */\n\tstatic fromRange( range ) {\n\t\treturn new LiveRange( range.start, range.end );\n\t}\n\n\t/**\n\t * @see module:engine/model/range~Range._createIn\n\t * @static\n\t * @protected\n\t * @method module:engine/model/liverange~LiveRange._createIn\n\t * @param {module:engine/model/element~Element} element\n\t * @returns {module:engine/model/liverange~LiveRange}\n\t */\n\n\t/**\n\t * @see module:engine/model/range~Range._createOn\n\t * @static\n\t * @protected\n\t * @method module:engine/model/liverange~LiveRange._createOn\n\t * @param {module:engine/model/element~Element} element\n\t * @returns {module:engine/model/liverange~LiveRange}\n\t */\n\n\t/**\n\t * @see module:engine/model/range~Range._createFromPositionAndShift\n\t * @static\n\t * @protected\n\t * @method module:engine/model/liverange~LiveRange._createFromPositionAndShift\n\t * @param {module:engine/model/position~Position} position\n\t * @param {Number} shift\n\t * @returns {module:engine/model/liverange~LiveRange}\n\t */\n\n\t/**\n\t * Fired when `LiveRange` instance boundaries have changed due to changes in the\n\t * {@link module:engine/model/document~Document document}.\n\t *\n\t * @event change:range\n\t * @param {module:engine/model/range~Range} oldRange Range with start and end position equal to start and end position of this live\n\t * range before it got changed.\n\t * @param {Object} data Object with additional information about the change.\n\t * @param {module:engine/model/position~Position|null} data.deletionPosition Source position for remove and merge changes.\n\t * Available if the range was moved to the graveyard root, `null` otherwise.\n\t */\n\n\t/**\n\t * Fired when `LiveRange` instance boundaries have not changed after a change in {@link module:engine/model/document~Document document}\n\t * but the change took place inside the range, effectively changing its content.\n\t *\n\t * @event change:content\n\t * @param {module:engine/model/range~Range} range Range with start and end position equal to start and end position of\n\t * change range.\n\t * @param {Object} data Object with additional information about the change.\n\t * @param {null} data.deletionPosition Due to the nature of this event, this property is always set to `null`. It is passed\n\t * for compatibility with the {@link module:engine/model/liverange~LiveRange#event:change:range} event.\n\t */\n}\n\n// Binds this `LiveRange` to the {@link module:engine/model/document~Document document}\n// that owns this range's {@link module:engine/model/range~Range#root root}.\n//\n// @private\nfunction bindWithDocument() {\n\tthis.listenTo(\n\t\tthis.root.document.model,\n\t\t'applyOperation',\n\t\t( event, args ) => {\n\t\t\tconst operation = args[ 0 ];\n\n\t\t\tif ( !operation.isDocumentOperation ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttransform.call( this, operation );\n\t\t},\n\t\t{ priority: 'low' }\n\t);\n}\n\n// Updates this range accordingly to the updates applied to the model. Bases on change events.\n//\n// @private\n// @param {module:engine/model/operation/operation~Operation} operation Executed operation.\nfunction transform( operation ) {\n\t// Transform the range by the operation. Join the result ranges if needed.\n\tconst ranges = this.getTransformedByOperation( operation );\n\tconst result = Range._createFromRanges( ranges );\n\n\tconst boundariesChanged = !result.isEqual( this );\n\tconst contentChanged = doesOperationChangeRangeContent( this, operation );\n\n\tlet deletionPosition = null;\n\n\tif ( boundariesChanged ) {\n\t\t// If range boundaries have changed, fire `change:range` event.\n\t\t//\n\t\tif ( result.root.rootName == '$graveyard' ) {\n\t\t\t// If the range was moved to the graveyard root, set `deletionPosition`.\n\t\t\tif ( operation.type == 'remove' ) {\n\t\t\t\tdeletionPosition = operation.sourcePosition;\n\t\t\t} else {\n\t\t\t\t// Merge operation.\n\t\t\t\tdeletionPosition = operation.deletionPosition;\n\t\t\t}\n\t\t}\n\n\t\tconst oldRange = this.toRange();\n\n\t\tthis.start = result.start;\n\t\tthis.end = result.end;\n\n\t\tthis.fire( 'change:range', oldRange, { deletionPosition } );\n\t} else if ( contentChanged ) {\n\t\t// If range boundaries have not changed, but there was change inside the range, fire `change:content` event.\n\t\tthis.fire( 'change:content', this.toRange(), { deletionPosition } );\n\t}\n}\n\n// Checks whether given operation changes something inside the range (even if it does not change boundaries).\n//\n// @private\n// @param {module:engine/model/range~Range} range Range to check.\n// @param {module:engine/model/operation/operation~Operation} operation Executed operation.\n// @returns {Boolean}\nfunction doesOperationChangeRangeContent( range, operation ) {\n\tswitch ( operation.type ) {\n\t\tcase 'insert':\n\t\t\treturn range.containsPosition( operation.position );\n\t\tcase 'move':\n\t\tcase 'remove':\n\t\tcase 'reinsert':\n\t\tcase 'merge':\n\t\t\treturn range.containsPosition( operation.sourcePosition ) ||\n\t\t\t\trange.start.isEqual( operation.sourcePosition ) ||\n\t\t\t\trange.containsPosition( operation.targetPosition );\n\t\tcase 'split':\n\t\t\treturn range.containsPosition( operation.splitPosition ) || range.containsPosition( operation.insertionPosition );\n\t}\n\n\treturn false;\n}\n\nmix( LiveRange, EmitterMixin );\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/documentselection\n */\n\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\n\nimport Selection from './selection';\nimport LiveRange from './liverange';\nimport Text from './text';\nimport TextProxy from './textproxy';\nimport toMap from '@ckeditor/ckeditor5-utils/src/tomap';\nimport Collection from '@ckeditor/ckeditor5-utils/src/collection';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\nimport uid from '@ckeditor/ckeditor5-utils/src/uid';\n\nconst storePrefix = 'selection:';\n\n/**\n * `DocumentSelection` is a special selection which is used as the\n * {@link module:engine/model/document~Document#selection document's selection}.\n * There can be only one instance of `DocumentSelection` per document.\n *\n * Document selection can only be changed by using the {@link module:engine/model/writer~Writer} instance\n * inside the {@link module:engine/model/model~Model#change `change()`} block, as it provides a secure way to modify model.\n *\n * `DocumentSelection` is automatically updated upon changes in the {@link module:engine/model/document~Document document}\n * to always contain valid ranges. Its attributes are inherited from the text unless set explicitly.\n *\n * Differences between {@link module:engine/model/selection~Selection} and `DocumentSelection` are:\n * * there is always a range in `DocumentSelection` - even if no ranges were added there is a \"default range\"\n * present in the selection,\n * * ranges added to this selection updates automatically when the document changes,\n * * attributes of `DocumentSelection` are updated automatically according to selection ranges.\n *\n * Since `DocumentSelection` uses {@link module:engine/model/liverange~LiveRange live ranges}\n * and is updated when {@link module:engine/model/document~Document document}\n * changes, it cannot be set on {@link module:engine/model/node~Node nodes}\n * that are inside {@link module:engine/model/documentfragment~DocumentFragment document fragment}.\n * If you need to represent a selection in document fragment,\n * use {@link module:engine/model/selection~Selection Selection class} instead.\n *\n * @mixes module:utils/emittermixin~EmitterMixin\n */\nexport default class DocumentSelection {\n\t/**\n\t * Creates an empty live selection for given {@link module:engine/model/document~Document}.\n\t *\n\t * @param {module:engine/model/document~Document} doc Document which owns this selection.\n\t */\n\tconstructor( doc ) {\n\t\t/**\n\t\t * Selection used internally by that class (`DocumentSelection` is a proxy to that selection).\n\t\t *\n\t\t * @protected\n\t\t */\n\t\tthis._selection = new LiveSelection( doc );\n\n\t\tthis._selection.delegate( 'change:range' ).to( this );\n\t\tthis._selection.delegate( 'change:attribute' ).to( this );\n\t}\n\n\t/**\n\t * Returns whether the selection is collapsed. Selection is collapsed when there is exactly one range which is\n\t * collapsed.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isCollapsed() {\n\t\treturn this._selection.isCollapsed;\n\t}\n\n\t/**\n\t * Selection anchor. Anchor may be described as a position where the most recent part of the selection starts.\n\t * Together with {@link #focus} they define the direction of selection, which is important\n\t * when expanding/shrinking selection. Anchor is always {@link module:engine/model/range~Range#start start} or\n\t * {@link module:engine/model/range~Range#end end} position of the most recently added range.\n\t *\n\t * Is set to `null` if there are no ranges in selection.\n\t *\n\t * @see #focus\n\t * @readonly\n\t * @type {module:engine/model/position~Position|null}\n\t */\n\tget anchor() {\n\t\treturn this._selection.anchor;\n\t}\n\n\t/**\n\t * Selection focus. Focus is a position where the selection ends.\n\t *\n\t * Is set to `null` if there are no ranges in selection.\n\t *\n\t * @see #anchor\n\t * @readonly\n\t * @type {module:engine/model/position~Position|null}\n\t */\n\tget focus() {\n\t\treturn this._selection.focus;\n\t}\n\n\t/**\n\t * Returns number of ranges in selection.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget rangeCount() {\n\t\treturn this._selection.rangeCount;\n\t}\n\n\t/**\n\t * Describes whether `Documentselection` has own range(s) set, or if it is defaulted to\n\t * {@link module:engine/model/document~Document#_getDefaultRange document's default range}.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget hasOwnRange() {\n\t\treturn this._selection.hasOwnRange;\n\t}\n\n\t/**\n\t * Specifies whether the {@link #focus}\n\t * precedes {@link #anchor}.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isBackward() {\n\t\treturn this._selection.isBackward;\n\t}\n\n\t/**\n\t * Describes whether the gravity is overridden (using {@link module:engine/model/writer~Writer#overrideSelectionGravity}) or not.\n\t *\n\t * Note that the gravity remains overridden as long as will not be restored the same number of times as it was overridden.\n\t *\n\t * @readonly\n\t * @returns {Boolean}\n\t */\n\tget isGravityOverridden() {\n\t\treturn this._selection.isGravityOverridden;\n\t}\n\n\t/**\n\t * A collection of selection markers.\n\t * Marker is a selection marker when selection range is inside the marker range.\n\t *\n\t * @readonly\n\t * @type {module:utils/collection~Collection.<module:engine/model/markercollection~Marker>}\n\t */\n\tget markers() {\n\t\treturn this._selection.markers;\n\t}\n\n\t/**\n\t * Used for the compatibility with the {@link module:engine/model/selection~Selection#isEqual} method.\n\t *\n\t * @protected\n\t */\n\tget _ranges() {\n\t\treturn this._selection._ranges;\n\t}\n\n\t/**\n\t * Returns an iterable that iterates over copies of selection ranges.\n\t *\n\t * @returns {Iterable.<module:engine/model/range~Range>}\n\t */\n\tgetRanges() {\n\t\treturn this._selection.getRanges();\n\t}\n\n\t/**\n\t * Returns the first position in the selection.\n\t * First position is the position that {@link module:engine/model/position~Position#isBefore is before}\n\t * any other position in the selection.\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t *\n\t * @returns {module:engine/model/position~Position|null}\n\t */\n\tgetFirstPosition() {\n\t\treturn this._selection.getFirstPosition();\n\t}\n\n\t/**\n\t * Returns the last position in the selection.\n\t * Last position is the position that {@link module:engine/model/position~Position#isAfter is after}\n\t * any other position in the selection.\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t *\n\t * @returns {module:engine/model/position~Position|null}\n\t */\n\tgetLastPosition() {\n\t\treturn this._selection.getLastPosition();\n\t}\n\n\t/**\n\t * Returns a copy of the first range in the selection.\n\t * First range is the one which {@link module:engine/model/range~Range#start start} position\n\t * {@link module:engine/model/position~Position#isBefore is before} start position of all other ranges\n\t * (not to confuse with the first range added to the selection).\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t *\n\t * @returns {module:engine/model/range~Range|null}\n\t */\n\tgetFirstRange() {\n\t\treturn this._selection.getFirstRange();\n\t}\n\n\t/**\n\t * Returns a copy of the last range in the selection.\n\t * Last range is the one which {@link module:engine/model/range~Range#end end} position\n\t * {@link module:engine/model/position~Position#isAfter is after} end position of all other ranges (not to confuse with the range most\n\t * recently added to the selection).\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t *\n\t * @returns {module:engine/model/range~Range|null}\n\t */\n\tgetLastRange() {\n\t\treturn this._selection.getLastRange();\n\t}\n\n\t/**\n\t * Gets elements of type \"block\" touched by the selection.\n\t *\n\t * This method's result can be used for example to apply block styling to all blocks covered by this selection.\n\t *\n\t * **Note:** `getSelectedBlocks()` always returns the deepest block.\n\t *\n\t * In this case the function will return exactly all 3 paragraphs:\n\t *\n\t *\t\t<paragraph>[a</paragraph>\n\t *\t\t<quote>\n\t *\t\t\t<paragraph>b</paragraph>\n\t *\t\t</quote>\n\t *\t\t<paragraph>c]d</paragraph>\n\t *\n\t * In this case the paragraph will also be returned, despite the collapsed selection:\n\t *\n\t *\t\t<paragraph>[]a</paragraph>\n\t *\n\t * **Special case**: If a selection ends at the beginning of a block, that block is not returned as from user perspective\n\t * this block wasn't selected. See [#984](https://github.com/ckeditor/ckeditor5-engine/issues/984) for more details.\n\t *\n\t *\t\t<paragraph>[a</paragraph>\n\t *\t\t<paragraph>b</paragraph>\n\t *\t\t<paragraph>]c</paragraph> // this block will not be returned\n\t *\n\t * @returns {Iterable.<module:engine/model/element~Element>}\n\t */\n\tgetSelectedBlocks() {\n\t\treturn this._selection.getSelectedBlocks();\n\t}\n\n\t/**\n\t * Returns blocks that aren't nested in other selected blocks.\n\t *\n\t * In this case the method will return blocks A, B and E because C & D are children of block B:\n\t *\n\t *\t\t[<blockA></blockA>\n\t *\t\t<blockB>\n\t *\t\t\t<blockC></blockC>\n\t *\t\t\t<blockD></blockD>\n\t *\t\t</blockB>\n\t *\t\t<blockE></blockE>]\n\t *\n\t * **Note:** To get all selected blocks use {@link #getSelectedBlocks `getSelectedBlocks()`}.\n\t *\n\t * @returns {Iterable.<module:engine/model/element~Element>}\n\t */\n\tgetTopMostBlocks() {\n\t\treturn this._selection.getTopMostBlocks();\n\t}\n\n\t/**\n\t * Returns the selected element. {@link module:engine/model/element~Element Element} is considered as selected if there is only\n\t * one range in the selection, and that range contains exactly one element.\n\t * Returns `null` if there is no selected element.\n\t *\n\t * @returns {module:engine/model/element~Element|null}\n\t */\n\tgetSelectedElement() {\n\t\treturn this._selection.getSelectedElement();\n\t}\n\n\t/**\n\t * Checks whether the selection contains the entire content of the given element. This means that selection must start\n\t * at a position {@link module:engine/model/position~Position#isTouching touching} the element's start and ends at position\n\t * touching the element's end.\n\t *\n\t * By default, this method will check whether the entire content of the selection's current root is selected.\n\t * Useful to check if e.g. the user has just pressed <kbd>Ctrl</kbd> + <kbd>A</kbd>.\n\t *\n\t * @param {module:engine/model/element~Element} [element=this.anchor.root]\n\t * @returns {Boolean}\n\t */\n\tcontainsEntireContent( element ) {\n\t\treturn this._selection.containsEntireContent( element );\n\t}\n\n\t/**\n\t * Unbinds all events previously bound by document selection.\n\t */\n\tdestroy() {\n\t\tthis._selection.destroy();\n\t}\n\n\t/**\n\t * Returns iterable that iterates over this selection's attribute keys.\n\t *\n\t * @returns {Iterable.<String>}\n\t */\n\tgetAttributeKeys() {\n\t\treturn this._selection.getAttributeKeys();\n\t}\n\n\t/**\n\t * Returns iterable that iterates over this selection's attributes.\n\t *\n\t * Attributes are returned as arrays containing two items. First one is attribute key and second is attribute value.\n\t * This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t *\n\t * @returns {Iterable.<*>}\n\t */\n\tgetAttributes() {\n\t\treturn this._selection.getAttributes();\n\t}\n\n\t/**\n\t * Gets an attribute value for given key or `undefined` if that attribute is not set on the selection.\n\t *\n\t * @param {String} key Key of attribute to look for.\n\t * @returns {*} Attribute value or `undefined`.\n\t */\n\tgetAttribute( key ) {\n\t\treturn this._selection.getAttribute( key );\n\t}\n\n\t/**\n\t * Checks if the selection has an attribute for given key.\n\t *\n\t * @param {String} key Key of attribute to check.\n\t * @returns {Boolean} `true` if attribute with given key is set on selection, `false` otherwise.\n\t */\n\thasAttribute( key ) {\n\t\treturn this._selection.hasAttribute( key );\n\t}\n\n\t/**\n\t * Checks whether object is of given type following the convention set by\n\t * {@link module:engine/model/node~Node#is `Node#is()`}.\n\t *\n\t *\t\tconst selection = new DocumentSelection( ... );\n\t *\n\t *\t\tselection.is( 'selection' ); // true\n\t *\t\tselection.is( 'documentSelection' ); // true\n\t *\t\tselection.is( 'node' ); // false\n\t *\t\tselection.is( 'element' ); // false\n\t *\n\t * @param {String} type\n\t * @returns {Boolean}\n\t */\n\tis( type ) {\n\t\treturn type == 'selection' || type == 'documentSelection';\n\t}\n\n\t/**\n\t * Moves {@link module:engine/model/documentselection~DocumentSelection#focus} to the specified location.\n\t * Should be used only within the {@link module:engine/model/writer~Writer#setSelectionFocus} method.\n\t *\n\t * The location can be specified in the same form as\n\t * {@link module:engine/model/writer~Writer#createPositionAt writer.createPositionAt()} parameters.\n\t *\n\t * @see module:engine/model/writer~Writer#setSelectionFocus\n\t * @protected\n\t * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\t_setFocus( itemOrPosition, offset ) {\n\t\tthis._selection.setFocus( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Sets this selection's ranges and direction to the specified location based on the given\n\t * {@link module:engine/model/selection~Selectable selectable}.\n\t * Should be used only within the {@link module:engine/model/writer~Writer#setSelection} method.\n\t *\n\t * @see module:engine/model/writer~Writer#setSelection\n\t * @protected\n\t * @param {module:engine/model/selection~Selectable} selectable\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Sets place or offset of the selection.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.backward] Sets this selection instance to be backward.\n\t */\n\t_setTo( selectable, placeOrOffset, options ) {\n\t\tthis._selection.setTo( selectable, placeOrOffset, options );\n\t}\n\n\t/**\n\t * Sets attribute on the selection. If attribute with the same key already is set, it's value is overwritten.\n\t * Should be used only within the {@link module:engine/model/writer~Writer#setSelectionAttribute} method.\n\t *\n\t * @see module:engine/model/writer~Writer#setSelectionAttribute\n\t * @protected\n\t * @param {String} key Key of the attribute to set.\n\t * @param {*} value Attribute value.\n\t */\n\t_setAttribute( key, value ) {\n\t\tthis._selection.setAttribute( key, value );\n\t}\n\n\t/**\n\t * Removes an attribute with given key from the selection.\n\t * If the given attribute was set on the selection, fires the {@link module:engine/model/selection~Selection#event:change:range}\n\t * event with removed attribute key.\n\t * Should be used only within the {@link module:engine/model/writer~Writer#removeSelectionAttribute} method.\n\t *\n\t * @see module:engine/model/writer~Writer#removeSelectionAttribute\n\t * @protected\n\t * @param {String} key Key of the attribute to remove.\n\t */\n\t_removeAttribute( key ) {\n\t\tthis._selection.removeAttribute( key );\n\t}\n\n\t/**\n\t * Returns an iterable that iterates through all selection attributes stored in current selection's parent.\n\t *\n\t * @protected\n\t * @returns {Iterable.<*>}\n\t */\n\t_getStoredAttributes() {\n\t\treturn this._selection._getStoredAttributes();\n\t}\n\n\t/**\n\t * Temporarily changes the gravity of the selection from the left to the right.\n\t *\n\t * The gravity defines from which direction the selection inherits its attributes. If it's the default left\n\t * gravity, the selection (after being moved by the the user) inherits attributes from its left hand side.\n\t * This method allows to temporarily override this behavior by forcing the gravity to the right.\n\t *\n\t * It returns an unique identifier which is required to restore the gravity. It guarantees the symmetry\n\t * of the process.\n\t *\n\t * @see module:engine/model/writer~Writer#overrideSelectionGravity\n\t * @protected\n\t * @returns {String} The unique id which allows restoring the gravity.\n\t */\n\t_overrideGravity() {\n\t\treturn this._selection.overrideGravity();\n\t}\n\n\t/**\n\t * Restores the {@link ~DocumentSelection#_overrideGravity overridden gravity}.\n\t *\n\t * Restoring the gravity is only possible using the unique identifier returned by\n\t * {@link ~DocumentSelection#_overrideGravity}. Note that the gravity remains overridden as long as won't be restored\n\t * the same number of times it was overridden.\n\t *\n\t * @see module:engine/model/writer~Writer#restoreSelectionGravity\n\t * @protected\n\t * @param {String} uid The unique id returned by {@link #_overrideGravity}.\n\t */\n\t_restoreGravity( uid ) {\n\t\tthis._selection.restoreGravity( uid );\n\t}\n\n\t/**\n\t * Generates and returns an attribute key for selection attributes store, basing on original attribute key.\n\t *\n\t * @protected\n\t * @param {String} key Attribute key to convert.\n\t * @returns {String} Converted attribute key, applicable for selection store.\n\t */\n\tstatic _getStoreAttributeKey( key ) {\n\t\treturn storePrefix + key;\n\t}\n\n\t/**\n\t * Checks whether the given attribute key is an attribute stored on an element.\n\t *\n\t * @protected\n\t * @param {String} key\n\t * @returns {Boolean}\n\t */\n\tstatic _isStoreAttributeKey( key ) {\n\t\treturn key.startsWith( storePrefix );\n\t}\n}\n\nmix( DocumentSelection, EmitterMixin );\n\n/**\n * Fired when selection range(s) changed.\n *\n * @event change:range\n * @param {Boolean} directChange In case of {@link module:engine/model/selection~Selection} class it is always set\n * to `true` which indicates that the selection change was caused by a direct use of selection's API.\n * The {@link module:engine/model/documentselection~DocumentSelection}, however, may change because its position\n * was directly changed through the {@link module:engine/model/writer~Writer writer} or because its position was\n * changed because the structure of the model has been changed (which means an indirect change).\n * The indirect change does not occur in case of normal (detached) selections because they are \"static\" (as \"not live\")\n * which mean that they are not updated once the document changes.\n */\n\n/**\n * Fired when selection attribute changed.\n *\n * @event change:attribute\n * @param {Boolean} directChange In case of {@link module:engine/model/selection~Selection} class it is always set\n * to `true` which indicates that the selection change was caused by a direct use of selection's API.\n * The {@link module:engine/model/documentselection~DocumentSelection}, however, may change because its attributes\n * were directly changed through the {@link module:engine/model/writer~Writer writer} or because its position was\n * changed in the model and its attributes were refreshed (which means an indirect change).\n * The indirect change does not occur in case of normal (detached) selections because they are \"static\" (as \"not live\")\n * which mean that they are not updated once the document changes.\n * @param {Array.<String>} attributeKeys Array containing keys of attributes that changed.\n */\n\n// `LiveSelection` is used internally by {@link module:engine/model/documentselection~DocumentSelection} and shouldn't be used directly.\n//\n// LiveSelection` is automatically updated upon changes in the {@link module:engine/model/document~Document document}\n// to always contain valid ranges. Its attributes are inherited from the text unless set explicitly.\n//\n// Differences between {@link module:engine/model/selection~Selection} and `LiveSelection` are:\n// * there is always a range in `LiveSelection` - even if no ranges were added there is a \"default range\"\n// present in the selection,\n// * ranges added to this selection updates automatically when the document changes,\n// * attributes of `LiveSelection` are updated automatically according to selection ranges.\n//\n// @extends module:engine/model/selection~Selection\n//\n\nclass LiveSelection extends Selection {\n\t// Creates an empty live selection for given {@link module:engine/model/document~Document}.\n\t// @param {module:engine/model/document~Document} doc Document which owns this selection.\n\tconstructor( doc ) {\n\t\tsuper();\n\n\t\t// List of selection markers.\n\t\t// Marker is a selection marker when selection range is inside the marker range.\n\t\t//\n\t\t// @type {module:utils/collection~Collection}\n\t\tthis.markers = new Collection( { idProperty: 'name' } );\n\n\t\t// Document which owns this selection.\n\t\t//\n\t\t// @protected\n\t\t// @member {module:engine/model/model~Model}\n\t\tthis._model = doc.model;\n\n\t\t// Document which owns this selection.\n\t\t//\n\t\t// @protected\n\t\t// @member {module:engine/model/document~Document}\n\t\tthis._document = doc;\n\n\t\t// Keeps mapping of attribute name to priority with which the attribute got modified (added/changed/removed)\n\t\t// last time. Possible values of priority are: `'low'` and `'normal'`.\n\t\t//\n\t\t// Priorities are used by internal `LiveSelection` mechanisms. All attributes set using `LiveSelection`\n\t\t// attributes API are set with `'normal'` priority.\n\t\t//\n\t\t// @private\n\t\t// @member {Map} module:engine/model/liveselection~LiveSelection#_attributePriority\n\t\tthis._attributePriority = new Map();\n\n\t\t// Contains data required to fix ranges which have been moved to the graveyard.\n\t\t// @private\n\t\t// @member {Array} module:engine/model/liveselection~LiveSelection#_fixGraveyardRangesData\n\t\tthis._fixGraveyardRangesData = [];\n\n\t\t// Flag that informs whether the selection ranges have changed. It is changed on true when `LiveRange#change:range` event is fired.\n\t\t// @private\n\t\t// @member {Array} module:engine/model/liveselection~LiveSelection#_hasChangedRange\n\t\tthis._hasChangedRange = false;\n\n\t\t// Each overriding gravity adds an UID to the set and each removal removes it.\n\t\t// Gravity is overridden when there's at least one UID in the set.\n\t\t// Gravity is restored when the set is empty.\n\t\t// This is to prevent conflicts when gravity is overridden by more than one feature at the same time.\n\t\t// @private\n\t\t// @type {Set}\n\t\tthis._overriddenGravityRegister = new Set();\n\n\t\t// Ensure selection is correct and up to date after each range change.\n\t\tthis.on( 'change:range', () => {\n\t\t\tfor ( const range of this.getRanges() ) {\n\t\t\t\tif ( !this._document._validateSelectionRange( range ) ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * Range from {@link module:engine/model/documentselection~DocumentSelection document selection}\n\t\t\t\t\t * starts or ends at incorrect position.\n\t\t\t\t\t *\n\t\t\t\t\t * @error document-selection-wrong-position\n\t\t\t\t\t * @param {module:engine/model/range~Range} range\n\t\t\t\t\t */\n\t\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t\t'document-selection-wrong-position: Range from document selection starts or ends at incorrect position.',\n\t\t\t\t\t\t{ range }\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._updateMarkers();\n\t\t\tthis._updateAttributes( false );\n\t\t} );\n\n\t\t// Update markers data stored by the selection after each marker change.\n\t\tthis.listenTo( this._model.markers, 'update', () => this._updateMarkers() );\n\n\t\t// Ensure selection is correct and up to date after each operation.\n\t\tthis.listenTo( this._model, 'applyOperation', ( evt, args ) => {\n\t\t\tconst operation = args[ 0 ];\n\n\t\t\tif ( !operation.isDocumentOperation || operation.type == 'marker' || operation.type == 'rename' || operation.type == 'noop' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\twhile ( this._fixGraveyardRangesData.length ) {\n\t\t\t\tconst { liveRange, sourcePosition } = this._fixGraveyardRangesData.shift();\n\n\t\t\t\tthis._fixGraveyardSelection( liveRange, sourcePosition );\n\t\t\t}\n\n\t\t\tif ( this._hasChangedRange ) {\n\t\t\t\tthis._hasChangedRange = false;\n\t\t\t\tthis.fire( 'change:range', { directChange: false } );\n\t\t\t}\n\n\t\t\tthis._updateMarkers();\n\t\t\tthis._updateAttributes( false );\n\t\t}, { priority: 'lowest' } );\n\n\t\t// Clear selection attributes from element if no longer empty.\n\t\tthis.listenTo( this._document, 'change', ( evt, batch ) => {\n\t\t\tclearAttributesStoredInElement( this._model, batch );\n\t\t} );\n\t}\n\n\tget isCollapsed() {\n\t\tconst length = this._ranges.length;\n\n\t\treturn length === 0 ? this._document._getDefaultRange().isCollapsed : super.isCollapsed;\n\t}\n\n\tget anchor() {\n\t\treturn super.anchor || this._document._getDefaultRange().start;\n\t}\n\n\tget focus() {\n\t\treturn super.focus || this._document._getDefaultRange().end;\n\t}\n\n\tget rangeCount() {\n\t\treturn this._ranges.length ? this._ranges.length : 1;\n\t}\n\n\t// Describes whether `LiveSelection` has own range(s) set, or if it is defaulted to\n\t// {@link module:engine/model/document~Document#_getDefaultRange document's default range}.\n\t//\n\t// @readonly\n\t// @type {Boolean}\n\tget hasOwnRange() {\n\t\treturn this._ranges.length > 0;\n\t}\n\n\t// When set to `true` then selection attributes on node before the caret won't be taken\n\t// into consideration while updating selection attributes.\n\t//\n\t// @protected\n\t// @type {Boolean}\n\tget isGravityOverridden() {\n\t\treturn !!this._overriddenGravityRegister.size;\n\t}\n\n\t// Unbinds all events previously bound by live selection.\n\tdestroy() {\n\t\tfor ( let i = 0; i < this._ranges.length; i++ ) {\n\t\t\tthis._ranges[ i ].detach();\n\t\t}\n\n\t\tthis.stopListening();\n\t}\n\n\t* getRanges() {\n\t\tif ( this._ranges.length ) {\n\t\t\tyield* super.getRanges();\n\t\t} else {\n\t\t\tyield this._document._getDefaultRange();\n\t\t}\n\t}\n\n\tgetFirstRange() {\n\t\treturn super.getFirstRange() || this._document._getDefaultRange();\n\t}\n\n\tgetLastRange() {\n\t\treturn super.getLastRange() || this._document._getDefaultRange();\n\t}\n\n\tsetTo( selectable, optionsOrPlaceOrOffset, options ) {\n\t\tsuper.setTo( selectable, optionsOrPlaceOrOffset, options );\n\t\tthis._refreshAttributes();\n\t}\n\n\tsetFocus( itemOrPosition, offset ) {\n\t\tsuper.setFocus( itemOrPosition, offset );\n\t\tthis._refreshAttributes();\n\t}\n\n\tsetAttribute( key, value ) {\n\t\tif ( this._setAttribute( key, value ) ) {\n\t\t\t// Fire event with exact data.\n\t\t\tconst attributeKeys = [ key ];\n\t\t\tthis.fire( 'change:attribute', { attributeKeys, directChange: true } );\n\t\t}\n\t}\n\n\tremoveAttribute( key ) {\n\t\tif ( this._removeAttribute( key ) ) {\n\t\t\t// Fire event with exact data.\n\t\t\tconst attributeKeys = [ key ];\n\t\t\tthis.fire( 'change:attribute', { attributeKeys, directChange: true } );\n\t\t}\n\t}\n\n\toverrideGravity() {\n\t\tconst overrideUid = uid();\n\n\t\t// Remember that another overriding has been requested. It will need to be removed\n\t\t// before the gravity is to be restored.\n\t\tthis._overriddenGravityRegister.add( overrideUid );\n\n\t\tif ( this._overriddenGravityRegister.size === 1 ) {\n\t\t\tthis._refreshAttributes();\n\t\t}\n\n\t\treturn overrideUid;\n\t}\n\n\trestoreGravity( uid ) {\n\t\tif ( !this._overriddenGravityRegister.has( uid ) ) {\n\t\t\t/**\n\t\t\t * Restoring gravity for an unknown UID is not possible. Make sure you are using a correct\n\t\t\t * UID obtained from the {@link module:engine/model/writer~Writer#overrideSelectionGravity} to restore.\n\t\t\t *\n\t\t\t * @error document-selection-gravity-wrong-restore\n\t\t\t * @param {String} uid The unique identifier returned by\n\t\t\t * {@link module:engine/model/documentselection~DocumentSelection#_overrideGravity}.\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'document-selection-gravity-wrong-restore: Attempting to restore the selection gravity for an unknown UID.',\n\t\t\t\t{ uid }\n\t\t\t);\n\t\t}\n\n\t\tthis._overriddenGravityRegister.delete( uid );\n\n\t\t// Restore gravity only when all overriding have been restored.\n\t\tif ( !this.isGravityOverridden ) {\n\t\t\tthis._refreshAttributes();\n\t\t}\n\t}\n\n\t// Removes all attributes from the selection and sets attributes according to the surrounding nodes.\n\t_refreshAttributes() {\n\t\tthis._updateAttributes( true );\n\t}\n\n\t_popRange() {\n\t\tthis._ranges.pop().detach();\n\t}\n\n\t_pushRange( range ) {\n\t\tconst liveRange = this._prepareRange( range );\n\n\t\t// `undefined` is returned when given `range` is in graveyard root.\n\t\tif ( liveRange ) {\n\t\t\tthis._ranges.push( liveRange );\n\t\t}\n\t}\n\n\t// Prepares given range to be added to selection. Checks if it is correct,\n\t// converts it to {@link module:engine/model/liverange~LiveRange LiveRange}\n\t// and sets listeners listening to the range's change event.\n\t//\n\t// @private\n\t// @param {module:engine/model/range~Range} range\n\t_prepareRange( range ) {\n\t\tthis._checkRange( range );\n\n\t\tif ( range.root == this._document.graveyard ) {\n\t\t\t/**\n\t\t\t * Trying to add a Range that is in the graveyard root. Range rejected.\n\t\t\t *\n\t\t\t * @warning model-selection-range-in-graveyard\n\t\t\t */\n\t\t\tlog.warn( 'model-selection-range-in-graveyard: Trying to add a Range that is in the graveyard root. Range rejected.' );\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst liveRange = LiveRange.fromRange( range );\n\n\t\tliveRange.on( 'change:range', ( evt, oldRange, data ) => {\n\t\t\tthis._hasChangedRange = true;\n\n\t\t\t// If `LiveRange` is in whole moved to the graveyard, save necessary data. It will be fixed on `Model#applyOperation` event.\n\t\t\tif ( liveRange.root == this._document.graveyard ) {\n\t\t\t\tthis._fixGraveyardRangesData.push( {\n\t\t\t\t\tliveRange,\n\t\t\t\t\tsourcePosition: data.deletionPosition\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\n\t\treturn liveRange;\n\t}\n\n\t_updateMarkers() {\n\t\tconst markers = [];\n\n\t\tfor ( const marker of this._model.markers ) {\n\t\t\tconst markerRange = marker.getRange();\n\n\t\t\tfor ( const selectionRange of this.getRanges() ) {\n\t\t\t\tif ( markerRange.containsRange( selectionRange, !selectionRange.isCollapsed ) ) {\n\t\t\t\t\tmarkers.push( marker );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor ( const marker of markers ) {\n\t\t\tif ( !this.markers.has( marker ) ) {\n\t\t\t\tthis.markers.add( marker );\n\t\t\t}\n\t\t}\n\n\t\tfor ( const marker of Array.from( this.markers ) ) {\n\t\t\tif ( !markers.includes( marker ) ) {\n\t\t\t\tthis.markers.remove( marker );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Updates this selection attributes according to its ranges and the {@link module:engine/model/document~Document model document}.\n\t//\n\t// @protected\n\t// @param {Boolean} clearAll\n\t// @fires change:attribute\n\t_updateAttributes( clearAll ) {\n\t\tconst newAttributes = toMap( this._getSurroundingAttributes() );\n\t\tconst oldAttributes = toMap( this.getAttributes() );\n\n\t\tif ( clearAll ) {\n\t\t\t// If `clearAll` remove all attributes and reset priorities.\n\t\t\tthis._attributePriority = new Map();\n\t\t\tthis._attrs = new Map();\n\t\t} else {\n\t\t\t// If not, remove only attributes added with `low` priority.\n\t\t\tfor ( const [ key, priority ] of this._attributePriority ) {\n\t\t\t\tif ( priority == 'low' ) {\n\t\t\t\t\tthis._attrs.delete( key );\n\t\t\t\t\tthis._attributePriority.delete( key );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis._setAttributesTo( newAttributes );\n\n\t\t// Let's evaluate which attributes really changed.\n\t\tconst changed = [];\n\n\t\t// First, loop through all attributes that are set on selection right now.\n\t\t// Check which of them are different than old attributes.\n\t\tfor ( const [ newKey, newValue ] of this.getAttributes() ) {\n\t\t\tif ( !oldAttributes.has( newKey ) || oldAttributes.get( newKey ) !== newValue ) {\n\t\t\t\tchanged.push( newKey );\n\t\t\t}\n\t\t}\n\n\t\t// Then, check which of old attributes got removed.\n\t\tfor ( const [ oldKey ] of oldAttributes ) {\n\t\t\tif ( !this.hasAttribute( oldKey ) ) {\n\t\t\t\tchanged.push( oldKey );\n\t\t\t}\n\t\t}\n\n\t\t// Fire event with exact data (fire only if anything changed).\n\t\tif ( changed.length > 0 ) {\n\t\t\tthis.fire( 'change:attribute', { attributeKeys: changed, directChange: false } );\n\t\t}\n\t}\n\n\t// Internal method for setting `LiveSelection` attribute. Supports attribute priorities (through `directChange`\n\t// parameter).\n\t//\n\t// @private\n\t// @param {String} key Attribute key.\n\t// @param {*} value Attribute value.\n\t// @param {Boolean} [directChange=true] `true` if the change is caused by `Selection` API, `false` if change\n\t// is caused by `Batch` API.\n\t// @returns {Boolean} Whether value has changed.\n\t_setAttribute( key, value, directChange = true ) {\n\t\tconst priority = directChange ? 'normal' : 'low';\n\n\t\tif ( priority == 'low' && this._attributePriority.get( key ) == 'normal' ) {\n\t\t\t// Priority too low.\n\t\t\treturn false;\n\t\t}\n\n\t\tconst oldValue = super.getAttribute( key );\n\n\t\t// Don't do anything if value has not changed.\n\t\tif ( oldValue === value ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis._attrs.set( key, value );\n\n\t\t// Update priorities map.\n\t\tthis._attributePriority.set( key, priority );\n\n\t\treturn true;\n\t}\n\n\t// Internal method for removing `LiveSelection` attribute. Supports attribute priorities (through `directChange`\n\t// parameter).\n\t//\n\t// NOTE: Even if attribute is not present in the selection but is provided to this method, it's priority will\n\t// be changed according to `directChange` parameter.\n\t//\n\t// @private\n\t// @param {String} key Attribute key.\n\t// @param {Boolean} [directChange=true] `true` if the change is caused by `Selection` API, `false` if change\n\t// is caused by `Batch` API.\n\t// @returns {Boolean} Whether attribute was removed. May not be true if such attributes didn't exist or the\n\t// existing attribute had higher priority.\n\t_removeAttribute( key, directChange = true ) {\n\t\tconst priority = directChange ? 'normal' : 'low';\n\n\t\tif ( priority == 'low' && this._attributePriority.get( key ) == 'normal' ) {\n\t\t\t// Priority too low.\n\t\t\treturn false;\n\t\t}\n\n\t\t// Update priorities map.\n\t\tthis._attributePriority.set( key, priority );\n\n\t\t// Don't do anything if value has not changed.\n\t\tif ( !super.hasAttribute( key ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis._attrs.delete( key );\n\n\t\treturn true;\n\t}\n\n\t// Internal method for setting multiple `LiveSelection` attributes. Supports attribute priorities (through\n\t// `directChange` parameter).\n\t//\n\t// @private\n\t// @param {Map.<String,*>} attrs Iterable object containing attributes to be set.\n\t// @returns {Set.<String>} Changed attribute keys.\n\t_setAttributesTo( attrs ) {\n\t\tconst changed = new Set();\n\n\t\tfor ( const [ oldKey, oldValue ] of this.getAttributes() ) {\n\t\t\t// Do not remove attribute if attribute with same key and value is about to be set.\n\t\t\tif ( attrs.get( oldKey ) === oldValue ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// All rest attributes will be removed so changed attributes won't change .\n\t\t\tthis._removeAttribute( oldKey, false );\n\t\t}\n\n\t\tfor ( const [ key, value ] of attrs ) {\n\t\t\t// Attribute may not be set because of attributes or because same key/value is already added.\n\t\t\tconst gotAdded = this._setAttribute( key, value, false );\n\n\t\t\tif ( gotAdded ) {\n\t\t\t\tchanged.add( key );\n\t\t\t}\n\t\t}\n\n\t\treturn changed;\n\t}\n\n\t// Returns an iterable that iterates through all selection attributes stored in current selection's parent.\n\t//\n\t// @protected\n\t// @returns {Iterable.<*>}\n\t* _getStoredAttributes() {\n\t\tconst selectionParent = this.getFirstPosition().parent;\n\n\t\tif ( this.isCollapsed && selectionParent.isEmpty ) {\n\t\t\tfor ( const key of selectionParent.getAttributeKeys() ) {\n\t\t\t\tif ( key.startsWith( storePrefix ) ) {\n\t\t\t\t\tconst realKey = key.substr( storePrefix.length );\n\n\t\t\t\t\tyield [ realKey, selectionParent.getAttribute( key ) ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Checks model text nodes that are closest to the selection's first position and returns attributes of first\n\t// found element. If there are no text nodes in selection's first position parent, it returns selection\n\t// attributes stored in that parent.\n\t//\n\t// @private\n\t// @returns {Iterable.<*>} Collection of attributes.\n\t_getSurroundingAttributes() {\n\t\tconst position = this.getFirstPosition();\n\t\tconst schema = this._model.schema;\n\n\t\tlet attrs = null;\n\n\t\tif ( !this.isCollapsed ) {\n\t\t\t// 1. If selection is a range...\n\t\t\tconst range = this.getFirstRange();\n\n\t\t\t// ...look for a first character node in that range and take attributes from it.\n\t\t\tfor ( const value of range ) {\n\t\t\t\t// If the item is an object, we don't want to get attributes from its children.\n\t\t\t\tif ( value.item.is( 'element' ) && schema.isObject( value.item ) ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( value.type == 'text' ) {\n\t\t\t\t\tattrs = value.item.getAttributes();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// 2. If the selection is a caret or the range does not contain a character node...\n\n\t\t\tconst nodeBefore = position.textNode ? position.textNode : position.nodeBefore;\n\t\t\tconst nodeAfter = position.textNode ? position.textNode : position.nodeAfter;\n\n\t\t\t// When gravity is overridden then don't take node before into consideration.\n\t\t\tif ( !this.isGravityOverridden ) {\n\t\t\t\t// ...look at the node before caret and take attributes from it if it is a character node.\n\t\t\t\tattrs = getAttrsIfCharacter( nodeBefore );\n\t\t\t}\n\n\t\t\t// 3. If not, look at the node after caret...\n\t\t\tif ( !attrs ) {\n\t\t\t\tattrs = getAttrsIfCharacter( nodeAfter );\n\t\t\t}\n\n\t\t\t// 4. If not, try to find the first character on the left, that is in the same node.\n\t\t\t// When gravity is overridden then don't take node before into consideration.\n\t\t\tif ( !this.isGravityOverridden && !attrs ) {\n\t\t\t\tlet node = nodeBefore;\n\n\t\t\t\twhile ( node && !attrs ) {\n\t\t\t\t\tnode = node.previousSibling;\n\t\t\t\t\tattrs = getAttrsIfCharacter( node );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 5. If not found, try to find the first character on the right, that is in the same node.\n\t\t\tif ( !attrs ) {\n\t\t\t\tlet node = nodeAfter;\n\n\t\t\t\twhile ( node && !attrs ) {\n\t\t\t\t\tnode = node.nextSibling;\n\t\t\t\t\tattrs = getAttrsIfCharacter( node );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 6. If not found, selection should retrieve attributes from parent.\n\t\t\tif ( !attrs ) {\n\t\t\t\tattrs = this._getStoredAttributes();\n\t\t\t}\n\t\t}\n\n\t\treturn attrs;\n\t}\n\n\t// Fixes a selection range after it ends up in graveyard root.\n\t//\n\t// @private\n\t// @param {module:engine/model/liverange~LiveRange} liveRange The range from selection, that ended up in the graveyard root.\n\t// @param {module:engine/model/position~Position} removedRangeStart Start position of a range which was removed.\n\t_fixGraveyardSelection( liveRange, removedRangeStart ) {\n\t\t// The start of the removed range is the closest position to the `liveRange` - the original selection range.\n\t\t// This is a good candidate for a fixed selection range.\n\t\tconst positionCandidate = removedRangeStart.clone();\n\n\t\t// Find a range that is a correct selection range and is closest to the start of removed range.\n\t\tconst selectionRange = this._model.schema.getNearestSelectionRange( positionCandidate );\n\n\t\t// Remove the old selection range before preparing and adding new selection range. This order is important,\n\t\t// because new range, in some cases, may intersect with old range (it depends on `getNearestSelectionRange()` result).\n\t\tconst index = this._ranges.indexOf( liveRange );\n\t\tthis._ranges.splice( index, 1 );\n\t\tliveRange.detach();\n\n\t\t// If nearest valid selection range has been found - add it in the place of old range.\n\t\tif ( selectionRange ) {\n\t\t\t// Check the range, convert it to live range, bind events, etc.\n\t\t\tconst newRange = this._prepareRange( selectionRange );\n\n\t\t\t// Add new range in the place of old range.\n\t\t\tthis._ranges.splice( index, 0, newRange );\n\t\t}\n\t\t// If nearest valid selection range cannot be found - just removing the old range is fine.\n\t}\n}\n\n// Helper function for {@link module:engine/model/liveselection~LiveSelection#_updateAttributes}.\n//\n// It takes model item, checks whether it is a text node (or text proxy) and, if so, returns it's attributes. If not, returns `null`.\n//\n// @param {module:engine/model/item~Item|null} node\n// @returns {Boolean}\nfunction getAttrsIfCharacter( node ) {\n\tif ( node instanceof TextProxy || node instanceof Text ) {\n\t\treturn node.getAttributes();\n\t}\n\n\treturn null;\n}\n\n// Removes selection attributes from element which is not empty anymore.\n//\n// @private\n// @param {module:engine/model/model~Model} model\n// @param {module:engine/model/batch~Batch} batch\nfunction clearAttributesStoredInElement( model, batch ) {\n\tconst differ = model.document.differ;\n\n\tfor ( const entry of differ.getChanges() ) {\n\t\tif ( entry.type != 'insert' ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst changeParent = entry.position.parent;\n\t\tconst isNoLongerEmpty = entry.length === changeParent.maxOffset;\n\n\t\tif ( isNoLongerEmpty ) {\n\t\t\tmodel.enqueueChange( batch, writer => {\n\t\t\t\tconst storedAttributes = Array.from( changeParent.getAttributeKeys() )\n\t\t\t\t\t.filter( key => key.startsWith( storePrefix ) );\n\n\t\t\t\tfor ( const key of storedAttributes ) {\n\t\t\t\t\twriter.removeAttribute( key, changeParent );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/conversion/conversionhelpers\n */\n\n/**\n * Base class for conversion helpers.\n */\nexport default class ConversionHelpers {\n\t/**\n\t * Creates a conversion helpers instance.\n\t *\n\t * @param {Array.<module:engine/conversion/downcastdispatcher~DowncastDispatcher|\n\t * module:engine/conversion/upcastdispatcher~UpcastDispatcher>} dispatchers\n\t */\n\tconstructor( dispatchers ) {\n\t\tthis._dispatchers = dispatchers;\n\t}\n\n\t/**\n\t * Registers a conversion helper.\n\t *\n\t * **Note**: See full usage example in the `{@link module:engine/conversion/conversion~Conversion#for conversion.for()}`\n\t * method description.\n\t *\n\t * @param {Function} conversionHelper The function to be called on event.\n\t * @returns {module:engine/conversion/downcasthelpers~DowncastHelpers|module:engine/conversion/upcasthelpers~UpcastHelpers}\n\t */\n\tadd( conversionHelper ) {\n\t\tfor ( const dispatcher of this._dispatchers ) {\n\t\t\tconversionHelper( dispatcher );\n\t\t}\n\n\t\treturn this;\n\t}\n}\n","import baseClone from './_baseClone.js';\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_DEEP_FLAG = 1,\n CLONE_SYMBOLS_FLAG = 4;\n\n/**\n * This method is like `_.clone` except that it recursively clones `value`.\n *\n * @static\n * @memberOf _\n * @since 1.0.0\n * @category Lang\n * @param {*} value The value to recursively clone.\n * @returns {*} Returns the deep cloned value.\n * @see _.clone\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var deep = _.cloneDeep(objects);\n * console.log(deep[0] === objects[0]);\n * // => false\n */\nfunction cloneDeep(value) {\n return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);\n}\n\nexport default cloneDeep;\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\nimport ModelRange from '../model/range';\nimport ModelSelection from '../model/selection';\nimport ModelElement from '../model/element';\n\nimport ViewAttributeElement from '../view/attributeelement';\nimport DocumentSelection from '../model/documentselection';\nimport ConversionHelpers from './conversionhelpers';\n\nimport log from '@ckeditor/ckeditor5-utils/src/log';\nimport { cloneDeep } from 'lodash-es';\n\n/**\n * Contains downcast (model-to-view) converters for {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}.\n *\n * @module engine/conversion/downcasthelpers\n */\n\n/**\n * Downcast conversion helper functions.\n *\n * @extends module:engine/conversion/conversionhelpers~ConversionHelpers\n */\nexport default class DowncastHelpers extends ConversionHelpers {\n\t/**\n\t * Model element to view element conversion helper.\n\t *\n\t * This conversion results in creating a view element. For example, model `<paragraph>Foo</paragraph>` becomes `<p>Foo</p>` in the view.\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).elementToElement( {\n\t *\t\t\tmodel: 'paragraph',\n\t *\t\t\tview: 'p'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).elementToElement( {\n\t *\t\t\tmodel: 'paragraph',\n\t *\t\t\tview: 'div',\n\t *\t\t\tconverterPriority: 'high'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).elementToElement( {\n\t *\t\t\tmodel: 'fancyParagraph',\n\t *\t\t\tview: {\n\t *\t\t\t\tname: 'p',\n\t *\t\t\t\tclasses: 'fancy'\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).elementToElement( {\n\t *\t\t\tmodel: 'heading',\n\t *\t\t\tview: ( modelElement, viewWriter ) => {\n\t *\t\t\t\treturn viewWriter.createContainerElement( 'h' + modelElement.getAttribute( 'level' ) )\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @method #elementToElement\n\t * @param {Object} config Conversion configuration.\n\t * @param {String} config.model The name of the model element to convert.\n\t * @param {module:engine/view/elementdefinition~ElementDefinition|Function} config.view A view element definition or a function\n\t * that takes the model element and {@link module:engine/view/downcastwriter~DowncastWriter view downcast writer}\n\t * as parameters and returns a view container element.\n\t * @returns {module:engine/conversion/downcasthelpers~DowncastHelpers}\n\t */\n\telementToElement( config ) {\n\t\treturn this.add( downcastElementToElement( config ) );\n\t}\n\n\t/**\n\t * Model attribute to view element conversion helper.\n\t *\n\t * This conversion results in wrapping view nodes with a view attribute element. For example, a model text node with\n\t * `\"Foo\"` as data and the `bold` attribute becomes `<strong>Foo</strong>` in the view.\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).attributeToElement( {\n\t *\t\t\tmodel: 'bold',\n\t *\t\t\tview: 'strong'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).attributeToElement( {\n\t *\t\t\tmodel: 'bold',\n\t *\t\t\tview: 'b',\n\t *\t\t\tconverterPriority: 'high'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).attributeToElement( {\n\t *\t\t\tmodel: 'invert',\n\t *\t\t\tview: {\n\t *\t\t\t\tname: 'span',\n\t *\t\t\t\tclasses: [ 'font-light', 'bg-dark' ]\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).attributeToElement( {\n\t *\t\t\tmodel: {\n\t *\t\t\t\tkey: 'fontSize',\n\t *\t\t\t\tvalues: [ 'big', 'small' ]\n\t *\t\t\t},\n\t *\t\t\tview: {\n\t *\t\t\t\tbig: {\n\t *\t\t\t\t\tname: 'span',\n\t *\t\t\t\t\tstyles: {\n\t *\t\t\t\t\t\t'font-size': '1.2em'\n\t *\t\t\t\t\t}\n\t *\t\t\t\t},\n\t *\t\t\t\tsmall: {\n\t *\t\t\t\t\tname: 'span',\n\t *\t\t\t\t\tstyles: {\n\t *\t\t\t\t\t\t'font-size': '0.8em'\n\t *\t\t\t\t\t}\n\t *\t\t\t\t}\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).attributeToElement( {\n\t *\t\t\tmodel: 'bold',\n\t *\t\t\tview: ( modelAttributeValue, viewWriter ) => {\n\t *\t\t\t\treturn viewWriter.createAttributeElement( 'span', {\n\t *\t\t\t\t\tstyle: 'font-weight:' + modelAttributeValue\n\t *\t\t\t\t} );\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).attributeToElement( {\n\t *\t\t\tmodel: {\n\t *\t\t\t\tkey: 'color',\n\t *\t\t\t\tname: '$text'\n\t *\t\t\t},\n\t *\t\t\tview: ( modelAttributeValue, viewWriter ) => {\n\t *\t\t\t\treturn viewWriter.createAttributeElement( 'span', {\n\t *\t\t\t\t\tstyle: 'color:' + modelAttributeValue\n\t *\t\t\t\t} );\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @method #attributeToElement\n\t * @param {Object} config Conversion configuration.\n\t * @param {String|Object} config.model The key of the attribute to convert from or a `{ key, values }` object. `values` is an array\n\t * of `String`s with possible values if the model attribute is an enumerable.\n\t * @param {module:engine/view/elementdefinition~ElementDefinition|Function|Object} config.view A view element definition or a function\n\t * that takes the model attribute value and {@link module:engine/view/downcastwriter~DowncastWriter view downcast writer}\n\t * as parameters and returns a view attribute element. If `config.model.values` is\n\t * given, `config.view` should be an object assigning values from `config.model.values` to view element definitions or functions.\n\t * @param {module:utils/priorities~PriorityString} [config.converterPriority='normal'] Converter priority.\n\t * @returns {module:engine/conversion/downcasthelpers~DowncastHelpers}\n\t */\n\tattributeToElement( config ) {\n\t\treturn this.add( downcastAttributeToElement( config ) );\n\t}\n\n\t/**\n\t * Model attribute to view attribute conversion helper.\n\t *\n\t * This conversion results in adding an attribute to a view node, basing on an attribute from a model node. For example,\n\t * `<image src='foo.jpg'></image>` is converted to `<img src='foo.jpg'></img>`.\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t *\t\t\tmodel: 'source',\n\t *\t\t\tview: 'src'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t *\t\t\tmodel: 'source',\n\t *\t\t\tview: 'href',\n\t *\t\t\tconverterPriority: 'high'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t *\t\t\tmodel: {\n\t *\t\t\t\tname: 'image',\n\t *\t\t\t\tkey: 'source'\n\t *\t\t\t},\n\t *\t\t\tview: 'src'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t *\t\t\tmodel: {\n\t *\t\t\t\tname: 'styled',\n\t *\t\t\t\tvalues: [ 'dark', 'light' ]\n\t *\t\t\t},\n\t *\t\t\tview: {\n\t *\t\t\t\tdark: {\n\t *\t\t\t\t\tkey: 'class',\n\t *\t\t\t\t\tvalue: [ 'styled', 'styled-dark' ]\n\t *\t\t\t\t},\n\t *\t\t\t\tlight: {\n\t *\t\t\t\t\tkey: 'class',\n\t *\t\t\t\t\tvalue: [ 'styled', 'styled-light' ]\n\t *\t\t\t\t}\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t *\t\t\tmodel: 'styled',\n\t *\t\t\tview: modelAttributeValue => ( { key: 'class', value: 'styled-' + modelAttributeValue } )\n\t *\t\t} );\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @method #attributeToAttribute\n\t * @param {Object} config Conversion configuration.\n\t * @param {String|Object} config.model The key of the attribute to convert from or a `{ key, values, [ name ] }` object describing\n\t * the attribute key, possible values and, optionally, an element name to convert from.\n\t * @param {String|Object|Function} config.view A view attribute key, or a `{ key, value }` object or a function that takes\n\t * the model attribute value and returns a `{ key, value }` object. If `key` is `'class'`, `value` can be a `String` or an\n\t * array of `String`s. If `key` is `'style'`, `value` is an object with key-value pairs. In other cases, `value` is a `String`.\n\t * If `config.model.values` is set, `config.view` should be an object assigning values from `config.model.values` to\n\t * `{ key, value }` objects or a functions.\n\t * @param {module:utils/priorities~PriorityString} [config.converterPriority='normal'] Converter priority.\n\t * @returns {module:engine/conversion/downcasthelpers~DowncastHelpers}\n\t */\n\tattributeToAttribute( config ) {\n\t\treturn this.add( downcastAttributeToAttribute( config ) );\n\t}\n\n\t/**\n\t * Model marker to view element conversion helper.\n\t *\n\t * This conversion results in creating a view element on the boundaries of the converted marker. If the converted marker\n\t * is collapsed, only one element is created. For example, model marker set like this: `<paragraph>F[oo b]ar</paragraph>`\n\t * becomes `<p>F<span data-marker=\"search\"></span>oo b<span data-marker=\"search\"></span>ar</p>` in the view.\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).markerToElement( {\n\t *\t\t\tmodel: 'search',\n\t *\t\t\tview: 'marker-search'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).markerToElement( {\n\t *\t\t\tmodel: 'search',\n\t *\t\t\tview: 'search-result',\n\t *\t\t\tconverterPriority: 'high'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).markerToElement( {\n\t *\t\t\tmodel: 'search',\n\t *\t\t\tview: {\n\t *\t\t\t\tname: 'span',\n\t *\t\t\t\tattributes: {\n\t *\t\t\t\t\t'data-marker': 'search'\n\t *\t\t\t\t}\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).markerToElement( {\n\t *\t\t\tmodel: 'search',\n\t *\t\t\tview: ( markerData, viewWriter ) => {\n\t *\t\t\t\treturn viewWriter.createUIElement( 'span', {\n\t *\t\t\t\t\t'data-marker': 'search',\n\t *\t\t\t\t\t'data-start': markerData.isOpening\n\t *\t\t\t\t} );\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * If a function is passed as the `config.view` parameter, it will be used to generate both boundary elements. The function\n\t * receives the `data` object as a parameter and should return an instance of the\n\t * {@link module:engine/view/uielement~UIElement view UI element}. The `data` object and\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi `conversionApi`} are passed from\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker}. Additionally,\n\t * the `data.isOpening` parameter is passed, which is set to `true` for the marker start boundary element, and `false` to\n\t * the marker end boundary element.\n\t *\n\t * This kind of conversion is useful for saving data into the database, so it should be used in the data conversion pipeline.\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @method #markerToElement\n\t * @param {Object} config Conversion configuration.\n\t * @param {String} config.model The name of the model marker (or model marker group) to convert.\n\t * @param {module:engine/view/elementdefinition~ElementDefinition|Function} config.view A view element definition or a function\n\t * that takes the model marker data as a parameter and returns a view UI element.\n\t * @param {module:utils/priorities~PriorityString} [config.converterPriority='normal'] Converter priority.\n\t * @returns {module:engine/conversion/downcasthelpers~DowncastHelpers}\n\t */\n\tmarkerToElement( config ) {\n\t\treturn this.add( downcastMarkerToElement( config ) );\n\t}\n\n\t/**\n\t * Model marker to highlight conversion helper.\n\t *\n\t * This conversion results in creating a highlight on view nodes. For this kind of conversion,\n\t * {@link module:engine/conversion/downcasthelpers~HighlightDescriptor} should be provided.\n\t *\n\t * For text nodes, a `<span>` {@link module:engine/view/attributeelement~AttributeElement} is created and it wraps all text nodes\n\t * in the converted marker range. For example, a model marker set like this: `<paragraph>F[oo b]ar</paragraph>` becomes\n\t * `<p>F<span class=\"comment\">oo b</span>ar</p>` in the view.\n\t *\n\t * {@link module:engine/view/containerelement~ContainerElement} may provide a custom way of handling highlight. Most often,\n\t * the element itself is given classes and attributes described in the highlight descriptor (instead of being wrapped in `<span>`).\n\t * For example, a model marker set like this: `[<image src=\"foo.jpg\"></image>]` becomes `<img src=\"foo.jpg\" class=\"comment\"></img>`\n\t * in the view.\n\t *\n\t * For container elements, the conversion is two-step. While the converter processes the highlight descriptor and passes it\n\t * to a container element, it is the container element instance itself that applies values from the highlight descriptor.\n\t * So, in a sense, the converter takes care of stating what should be applied on what, while the element decides how to apply that.\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).markerToHighlight( { model: 'comment', view: { classes: 'comment' } } );\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).markerToHighlight( {\n\t *\t\t\tmodel: 'comment',\n\t *\t\t\tview: { classes: 'new-comment' },\n\t *\t\t\tconverterPriority: 'high'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'downcast' ).markerToHighlight( {\n\t *\t\t\tmodel: 'comment',\n\t *\t\t\tview: data => {\n\t *\t\t\t\t// Assuming that the marker name is in a form of comment:commentType.\n\t *\t\t\t\tconst commentType = data.markerName.split( ':' )[ 1 ];\n\t *\n\t *\t\t\t\treturn {\n\t *\t\t\t\t\tclasses: [ 'comment', 'comment-' + commentType ]\n\t *\t\t\t\t};\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * If a function is passed as the `config.view` parameter, it will be used to generate the highlight descriptor. The function\n\t * receives the `data` object as a parameter and should return a\n\t * {@link module:engine/conversion/downcasthelpers~HighlightDescriptor highlight descriptor}.\n\t * The `data` object properties are passed from {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker}.\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @method #markerToHighlight\n\t * @param {Object} config Conversion configuration.\n\t * @param {String} config.model The name of the model marker (or model marker group) to convert.\n\t * @param {module:engine/conversion/downcasthelpers~HighlightDescriptor|Function} config.view A highlight descriptor\n\t * that will be used for highlighting or a function that takes the model marker data as a parameter and returns a highlight descriptor.\n\t * @param {module:utils/priorities~PriorityString} [config.converterPriority='normal'] Converter priority.\n\t * @returns {module:engine/conversion/downcasthelpers~DowncastHelpers}\n\t */\n\tmarkerToHighlight( config ) {\n\t\treturn this.add( downcastMarkerToHighlight( config ) );\n\t}\n}\n\n/**\n * Function factory that creates a default downcast converter for text insertion changes.\n *\n * The converter automatically consumes the corresponding value from the consumables list and stops the event (see\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}).\n *\n *\t\tmodelDispatcher.on( 'insert:$text', insertText() );\n *\n * @returns {Function} Insert text event converter.\n */\nexport function insertText() {\n\treturn ( evt, data, conversionApi ) => {\n\t\tif ( !conversionApi.consumable.consume( data.item, 'insert' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n\t\tconst viewText = viewWriter.createText( data.item.data );\n\n\t\tviewWriter.insert( viewPosition, viewText );\n\t};\n}\n\n/**\n * Function factory that creates a default downcast converter for node remove changes.\n *\n *\t\tmodelDispatcher.on( 'remove', remove() );\n *\n * @returns {Function} Remove event converter.\n */\nexport function remove() {\n\treturn ( evt, data, conversionApi ) => {\n\t\t// Find view range start position by mapping model position at which the remove happened.\n\t\tconst viewStart = conversionApi.mapper.toViewPosition( data.position );\n\n\t\tconst modelEnd = data.position.getShiftedBy( data.length );\n\t\tconst viewEnd = conversionApi.mapper.toViewPosition( modelEnd, { isPhantom: true } );\n\n\t\tconst viewRange = conversionApi.writer.createRange( viewStart, viewEnd );\n\n\t\t// Trim the range to remove in case some UI elements are on the view range boundaries.\n\t\tconst removed = conversionApi.writer.remove( viewRange.getTrimmed() );\n\n\t\t// After the range is removed, unbind all view elements from the model.\n\t\t// Range inside view document fragment is used to unbind deeply.\n\t\tfor ( const child of conversionApi.writer.createRangeIn( removed ).getItems() ) {\n\t\t\tconversionApi.mapper.unbindViewElement( child );\n\t\t}\n\t};\n}\n\n/**\n * Creates a `<span>` {@link module:engine/view/attributeelement~AttributeElement view attribute element} from the information\n * provided by the {@link module:engine/conversion/downcasthelpers~HighlightDescriptor highlight descriptor} object. If a priority\n * is not provided in the descriptor, the default priority will be used.\n *\n * @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} descriptor\n * @returns {module:engine/view/attributeelement~AttributeElement}\n */\nexport function createViewElementFromHighlightDescriptor( descriptor ) {\n\tconst viewElement = new ViewAttributeElement( 'span', descriptor.attributes );\n\n\tif ( descriptor.classes ) {\n\t\tviewElement._addClass( descriptor.classes );\n\t}\n\n\tif ( descriptor.priority ) {\n\t\tviewElement._priority = descriptor.priority;\n\t}\n\n\tviewElement._id = descriptor.id;\n\n\treturn viewElement;\n}\n\n/**\n * Function factory that creates a converter which converts a non-collapsed {@link module:engine/model/selection~Selection model selection}\n * to a {@link module:engine/view/documentselection~DocumentSelection view selection}. The converter consumes appropriate\n * value from the `consumable` object and maps model positions from the selection to view positions.\n *\n *\t\tmodelDispatcher.on( 'selection', convertRangeSelection() );\n *\n * @returns {Function} Selection converter.\n */\nexport function convertRangeSelection() {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst selection = data.selection;\n\n\t\tif ( selection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !conversionApi.consumable.consume( selection, 'selection' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewRanges = [];\n\n\t\tfor ( const range of selection.getRanges() ) {\n\t\t\tconst viewRange = conversionApi.mapper.toViewRange( range );\n\t\t\tviewRanges.push( viewRange );\n\t\t}\n\n\t\tconversionApi.writer.setSelection( viewRanges, { backward: selection.isBackward } );\n\t};\n}\n\n/**\n * Function factory that creates a converter which converts a collapsed {@link module:engine/model/selection~Selection model selection} to\n * a {@link module:engine/view/documentselection~DocumentSelection view selection}. The converter consumes appropriate\n * value from the `consumable` object, maps the model selection position to the view position and breaks\n * {@link module:engine/view/attributeelement~AttributeElement attribute elements} at the selection position.\n *\n *\t\tmodelDispatcher.on( 'selection', convertCollapsedSelection() );\n *\n * An example of the view state before and after converting the collapsed selection:\n *\n *\t\t <p><strong>f^oo<strong>bar</p>\n *\t\t-> <p><strong>f</strong>^<strong>oo</strong>bar</p>\n *\n * By breaking attribute elements like `<strong>`, the selection is in a correct element. Then, when the selection attribute is\n * converted, broken attributes might be merged again, or the position where the selection is may be wrapped\n * with different, appropriate attribute elements.\n *\n * See also {@link module:engine/conversion/downcasthelpers~clearAttributes} which does a clean-up\n * by merging attributes.\n *\n * @returns {Function} Selection converter.\n */\nexport function convertCollapsedSelection() {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst selection = data.selection;\n\n\t\tif ( !selection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !conversionApi.consumable.consume( selection, 'selection' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst modelPosition = selection.getFirstPosition();\n\t\tconst viewPosition = conversionApi.mapper.toViewPosition( modelPosition );\n\t\tconst brokenPosition = viewWriter.breakAttributes( viewPosition );\n\n\t\tviewWriter.setSelection( brokenPosition );\n\t};\n}\n\n/**\n * Function factory that creates a converter which clears artifacts after the previous\n * {@link module:engine/model/selection~Selection model selection} conversion. It removes all empty\n * {@link module:engine/view/attributeelement~AttributeElement view attribute elements} and merges sibling attributes at all start and end\n * positions of all ranges.\n *\n *\t\t <p><strong>^</strong></p>\n *\t\t-> <p>^</p>\n *\n *\t\t <p><strong>foo</strong>^<strong>bar</strong>bar</p>\n *\t\t-> <p><strong>foo^bar<strong>bar</p>\n *\n *\t\t <p><strong>foo</strong><em>^</em><strong>bar</strong>bar</p>\n *\t\t-> <p><strong>foo^bar<strong>bar</p>\n *\n * This listener should be assigned before any converter for the new selection:\n *\n *\t\tmodelDispatcher.on( 'selection', clearAttributes() );\n *\n * See {@link module:engine/conversion/downcasthelpers~convertCollapsedSelection}\n * which does the opposite by breaking attributes in the selection position.\n *\n * @returns {Function} Selection converter.\n */\nexport function clearAttributes() {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewSelection = viewWriter.document.selection;\n\n\t\tfor ( const range of viewSelection.getRanges() ) {\n\t\t\t// Not collapsed selection should not have artifacts.\n\t\t\tif ( range.isCollapsed ) {\n\t\t\t\t// Position might be in the node removed by the view writer.\n\t\t\t\tif ( range.end.parent.document ) {\n\t\t\t\t\tconversionApi.writer.mergeAttributes( range.start );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tviewWriter.setSelection( null );\n\t};\n}\n\n/**\n * Function factory that creates a converter which converts set/change/remove attribute changes from the model to the view.\n * It can also be used to convert selection attributes. In that case, an empty attribute element will be created and the\n * selection will be put inside it.\n *\n * Attributes from the model are converted to a view element that will be wrapping these view nodes that are bound to\n * model elements having the given attribute. This is useful for attributes like `bold` that may be set on text nodes in the model\n * but are represented as an element in the view:\n *\n *\t\t[paragraph] MODEL ====> VIEW <p>\n *\t\t\t|- a {bold: true} |- <b>\n *\t\t\t|- b {bold: true} | |- ab\n *\t\t\t|- c |- c\n *\n * Passed `Function` will be provided with the attribute value and then all the parameters of the\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute `attribute` event}.\n * It is expected that the function returns an {@link module:engine/view/element~Element}.\n * The result of the function will be the wrapping element.\n * When the provided `Function` does not return any element, no conversion will take place.\n *\n * The converter automatically consumes the corresponding value from the consumables list and stops the event (see\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}).\n *\n *\t\tmodelDispatcher.on( 'attribute:bold', wrap( ( modelAttributeValue, viewWriter ) => {\n *\t\t\treturn viewWriter.createAttributeElement( 'strong' );\n *\t\t} );\n *\n * @protected\n * @param {Function} elementCreator Function returning a view element that will be used for wrapping.\n * @returns {Function} Set/change attribute converter.\n */\nexport function wrap( elementCreator ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\t// Recreate current wrapping node. It will be used to unwrap view range if the attribute value has changed\n\t\t// or the attribute was removed.\n\t\tconst oldViewElement = elementCreator( data.attributeOldValue, conversionApi.writer );\n\n\t\t// Create node to wrap with.\n\t\tconst newViewElement = elementCreator( data.attributeNewValue, conversionApi.writer );\n\n\t\tif ( !oldViewElement && !newViewElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewSelection = viewWriter.document.selection;\n\n\t\tif ( data.item instanceof ModelSelection || data.item instanceof DocumentSelection ) {\n\t\t\t// Selection attribute conversion.\n\t\t\tviewWriter.wrap( viewSelection.getFirstRange(), newViewElement );\n\t\t} else {\n\t\t\t// Node attribute conversion.\n\t\t\tlet viewRange = conversionApi.mapper.toViewRange( data.range );\n\n\t\t\t// First, unwrap the range from current wrapper.\n\t\t\tif ( data.attributeOldValue !== null && oldViewElement ) {\n\t\t\t\tviewRange = viewWriter.unwrap( viewRange, oldViewElement );\n\t\t\t}\n\n\t\t\tif ( data.attributeNewValue !== null && newViewElement ) {\n\t\t\t\tviewWriter.wrap( viewRange, newViewElement );\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Function factory that creates a converter which converts node insertion changes from the model to the view.\n * The function passed will be provided with all the parameters of the dispatcher's\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert `insert` event}.\n * It is expected that the function returns an {@link module:engine/view/element~Element}.\n * The result of the function will be inserted into the view.\n *\n * The converter automatically consumes the corresponding value from the consumables list, stops the event (see\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}) and binds the model and view elements.\n *\n *\t\tdowncastDispatcher.on(\n *\t\t\t'insert:myElem',\n *\t\t\tinsertElement( ( modelItem, viewWriter ) => {\n *\t\t\t\tconst text = viewWriter.createText( 'myText' );\n *\t\t\t\tconst myElem = viewWriter.createElement( 'myElem', { myAttr: 'my-' + modelItem.getAttribute( 'myAttr' ) }, text );\n *\n *\t\t\t\t// Do something fancy with `myElem` using `modelItem` or other parameters.\n *\n *\t\t\t\treturn myElem;\n *\t\t\t}\n *\t\t) );\n *\n * @protected\n * @param {Function} elementCreator Function returning a view element, which will be inserted.\n * @returns {Function} Insert element event converter.\n */\nexport function insertElement( elementCreator ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst viewElement = elementCreator( data.item, conversionApi.writer );\n\n\t\tif ( !viewElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !conversionApi.consumable.consume( data.item, 'insert' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n\n\t\tconversionApi.mapper.bindElements( data.item, viewElement );\n\t\tconversionApi.writer.insert( viewPosition, viewElement );\n\t};\n}\n\n/**\n * Function factory that creates a converter which converts marker adding change to the\n * {@link module:engine/view/uielement~UIElement view UI element}.\n *\n * The view UI element that will be added to the view depends on the passed parameter. See {@link ~insertElement}.\n * In case of a non-collapsed range, the UI element will not wrap nodes but separate elements will be placed at the beginning\n * and at the end of the range.\n *\n * This converter binds created UI elements with the marker name using {@link module:engine/conversion/mapper~Mapper#bindElementToMarker}.\n *\n * @protected\n * @param {module:engine/view/uielement~UIElement|Function} elementCreator A view UI element or a function returning the view element\n * that will be inserted.\n * @returns {Function} Insert element event converter.\n */\nexport function insertUIElement( elementCreator ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\t// Create two view elements. One will be inserted at the beginning of marker, one at the end.\n\t\t// If marker is collapsed, only \"opening\" element will be inserted.\n\t\tdata.isOpening = true;\n\t\tconst viewStartElement = elementCreator( data, conversionApi.writer );\n\n\t\tdata.isOpening = false;\n\t\tconst viewEndElement = elementCreator( data, conversionApi.writer );\n\n\t\tif ( !viewStartElement || !viewEndElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst markerRange = data.markerRange;\n\n\t\t// Marker that is collapsed has consumable build differently that non-collapsed one.\n\t\t// For more information see `addMarker` event description.\n\t\t// If marker's range is collapsed - check if it can be consumed.\n\t\tif ( markerRange.isCollapsed && !conversionApi.consumable.consume( markerRange, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If marker's range is not collapsed - consume all items inside.\n\t\tfor ( const value of markerRange ) {\n\t\t\tif ( !conversionApi.consumable.consume( value.item, evt.name ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tconst mapper = conversionApi.mapper;\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\t// Add \"opening\" element.\n\t\tviewWriter.insert( mapper.toViewPosition( markerRange.start ), viewStartElement );\n\t\tconversionApi.mapper.bindElementToMarker( viewStartElement, data.markerName );\n\n\t\t// Add \"closing\" element only if range is not collapsed.\n\t\tif ( !markerRange.isCollapsed ) {\n\t\t\tviewWriter.insert( mapper.toViewPosition( markerRange.end ), viewEndElement );\n\t\t\tconversionApi.mapper.bindElementToMarker( viewEndElement, data.markerName );\n\t\t}\n\n\t\tevt.stop();\n\t};\n}\n\n// Function factory that returns a default downcast converter for removing a {@link module:engine/view/uielement~UIElement UI element}\n// basing on marker remove change.\n//\n// This converter unbinds elements from the marker name.\n//\n// @returns {Function} Removed UI element converter.\nfunction removeUIElement() {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst elements = conversionApi.mapper.markerNameToElements( data.markerName );\n\n\t\tif ( !elements ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconversionApi.mapper.unbindElementsFromMarkerName( data.markerName );\n\n\t\tfor ( const element of elements ) {\n\t\t\tconversionApi.writer.clear( conversionApi.writer.createRangeOn( element ), element );\n\t\t}\n\n\t\tconversionApi.writer.clearClonedElementsGroup( data.markerName );\n\n\t\tevt.stop();\n\t};\n}\n\n// Function factory that creates a converter which converts set/change/remove attribute changes from the model to the view.\n//\n// Attributes from the model are converted to the view element attributes in the view. You may provide a custom function to generate\n// a key-value attribute pair to add/change/remove. If not provided, model attributes will be converted to view element\n// attributes on a one-to-one basis.\n//\n// *Note:** The provided attribute creator should always return the same `key` for a given attribute from the model.\n//\n// The converter automatically consumes the corresponding value from the consumables list and stops the event (see\n// {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}).\n//\n//\t\tmodelDispatcher.on( 'attribute:customAttr:myElem', changeAttribute( ( value, data ) => {\n//\t\t\t// Change attribute key from `customAttr` to `class` in the view.\n//\t\t\tconst key = 'class';\n//\t\t\tlet value = data.attributeNewValue;\n//\n//\t\t\t// Force attribute value to 'empty' if the model element is empty.\n//\t\t\tif ( data.item.childCount === 0 ) {\n//\t\t\t\tvalue = 'empty';\n//\t\t\t}\n//\n//\t\t\t// Return the key-value pair.\n//\t\t\treturn { key, value };\n//\t\t} ) );\n//\n// @param {Function} [attributeCreator] Function returning an object with two properties: `key` and `value`, which\n// represent the attribute key and attribute value to be set on a {@link module:engine/view/element~Element view element}.\n// The function is passed the model attribute value as the first parameter and additional data about the change as the second parameter.\n// @returns {Function} Set/change attribute converter.\nfunction changeAttribute( attributeCreator ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst oldAttribute = attributeCreator( data.attributeOldValue, data );\n\t\tconst newAttribute = attributeCreator( data.attributeNewValue, data );\n\n\t\tif ( !oldAttribute && !newAttribute ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewElement = conversionApi.mapper.toViewElement( data.item );\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\t// If model item cannot be mapped to a view element, it means item is not an `Element` instance but a `TextProxy` node.\n\t\t// Only elements can have attributes in a view so do not proceed for anything else (#1587).\n\t\tif ( !viewElement ) {\n\t\t\t/**\n\t\t\t * This error occurs when a {@link module:engine/model/textproxy~TextProxy text node's} attribute is to be downcasted\n\t\t\t * by {@link module:engine/conversion/conversion~Conversion#attributeToAttribute `Attribute to Attribute converter`}.\n\t\t\t * In most cases it is caused by converters misconfiguration when only \"generic\" converter is defined:\n\t\t\t *\n\t\t\t *\t\teditor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t\t\t *\t\t\tmodel: 'attribute-name',\n\t\t\t *\t\t\tview: 'attribute-name'\n\t\t\t *\t\t} ) );\n\t\t\t *\n\t\t\t * and given attribute is used on text node, for example:\n\t\t\t *\n\t\t\t *\t\tmodel.change( writer => {\n\t\t\t *\t\t\twriter.insertText( 'Foo', { 'attribute-name': 'bar' }, parent, 0 );\n\t\t\t *\t\t} );\n\t\t\t *\n\t\t\t * In such cases, to convert the same attribute for both {@link module:engine/model/element~Element}\n\t\t\t * and {@link module:engine/model/textproxy~TextProxy `Text`} nodes, text specific\n\t\t\t * {@link module:engine/conversion/conversion~Conversion#attributeToElement `Attribute to Element converter`}\n\t\t\t * with higher {@link module:utils/priorities~PriorityString priority} must also be defined:\n\t\t\t *\n\t\t\t *\t\teditor.conversion.for( 'downcast' ).attributeToElement( {\n\t\t\t *\t\t\tmodel: {\n\t\t\t *\t\t\t\tkey: 'attribute-name',\n\t\t\t *\t\t\t\tname: '$text'\n\t\t\t *\t\t\t},\n\t\t\t *\t\t\tview: ( value, writer ) => {\n\t\t\t *\t\t\t\treturn writer.createAttributeElement( 'span', { 'attribute-name': value } );\n\t\t\t *\t\t\t},\n\t\t\t *\t\t\tconverterPriority: 'high'\n\t\t\t *\t\t} ) );\n\t\t\t *\n\t\t\t * @error conversion-attribute-to-attribute-on-text\n\t\t\t */\n\t\t\tlog.warn( 'conversion-attribute-to-attribute-on-text: ' +\n\t\t\t\t'Trying to convert text node\\'s attribute with attribute-to-attribute converter.' );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// First remove the old attribute if there was one.\n\t\tif ( data.attributeOldValue !== null && oldAttribute ) {\n\t\t\tif ( oldAttribute.key == 'class' ) {\n\t\t\t\tconst classes = Array.isArray( oldAttribute.value ) ? oldAttribute.value : [ oldAttribute.value ];\n\n\t\t\t\tfor ( const className of classes ) {\n\t\t\t\t\tviewWriter.removeClass( className, viewElement );\n\t\t\t\t}\n\t\t\t} else if ( oldAttribute.key == 'style' ) {\n\t\t\t\tconst keys = Object.keys( oldAttribute.value );\n\n\t\t\t\tfor ( const key of keys ) {\n\t\t\t\t\tviewWriter.removeStyle( key, viewElement );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tviewWriter.removeAttribute( oldAttribute.key, viewElement );\n\t\t\t}\n\t\t}\n\n\t\t// Then set the new attribute.\n\t\tif ( data.attributeNewValue !== null && newAttribute ) {\n\t\t\tif ( newAttribute.key == 'class' ) {\n\t\t\t\tconst classes = Array.isArray( newAttribute.value ) ? newAttribute.value : [ newAttribute.value ];\n\n\t\t\t\tfor ( const className of classes ) {\n\t\t\t\t\tviewWriter.addClass( className, viewElement );\n\t\t\t\t}\n\t\t\t} else if ( newAttribute.key == 'style' ) {\n\t\t\t\tconst keys = Object.keys( newAttribute.value );\n\n\t\t\t\tfor ( const key of keys ) {\n\t\t\t\t\tviewWriter.setStyle( key, newAttribute.value[ key ], viewElement );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tviewWriter.setAttribute( newAttribute.key, newAttribute.value, viewElement );\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Function factory that creates a converter which converts the text inside marker's range. The converter wraps the text with\n// {@link module:engine/view/attributeelement~AttributeElement} created from the provided descriptor.\n// See {link module:engine/conversion/downcasthelpers~createViewElementFromHighlightDescriptor}.\n//\n// It can also be used to convert the selection that is inside a marker. In that case, an empty attribute element will be\n// created and the selection will be put inside it.\n//\n// If the highlight descriptor does not provide the `priority` property, `10` will be used.\n//\n// If the highlight descriptor does not provide the `id` property, the name of the marker will be used.\n//\n// This converter binds the created {@link module:engine/view/attributeelement~AttributeElement attribute elemens} with the marker name\n// using the {@link module:engine/conversion/mapper~Mapper#bindElementToMarker} method.\n//\n// @param {module:engine/conversion/downcasthelpers~HighlightDescriptor|Function} highlightDescriptor\n// @returns {Function}\nfunction highlightText( highlightDescriptor ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tif ( !data.item ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !( data.item instanceof ModelSelection || data.item instanceof DocumentSelection ) && !data.item.is( 'textProxy' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst descriptor = prepareDescriptor( highlightDescriptor, data, conversionApi );\n\n\t\tif ( !descriptor ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewElement = createViewElementFromHighlightDescriptor( descriptor );\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewSelection = viewWriter.document.selection;\n\n\t\tif ( data.item instanceof ModelSelection || data.item instanceof DocumentSelection ) {\n\t\t\tviewWriter.wrap( viewSelection.getFirstRange(), viewElement, viewSelection );\n\t\t} else {\n\t\t\tconst viewRange = conversionApi.mapper.toViewRange( data.range );\n\t\t\tconst rangeAfterWrap = viewWriter.wrap( viewRange, viewElement );\n\n\t\t\tfor ( const element of rangeAfterWrap.getItems() ) {\n\t\t\t\tif ( element.is( 'attributeElement' ) && element.isSimilar( viewElement ) ) {\n\t\t\t\t\tconversionApi.mapper.bindElementToMarker( element, data.markerName );\n\n\t\t\t\t\t// One attribute element is enough, because all of them are bound together by the view writer.\n\t\t\t\t\t// Mapper uses this binding to get all the elements no matter how many of them are registered in the mapper.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Converter function factory. It creates a function which applies the marker's highlight to an element inside the marker's range.\n//\n// The converter checks if an element has the `addHighlight` function stored as a\n// {@link module:engine/view/element~Element#_setCustomProperty custom property} and, if so, uses it to apply the highlight.\n// In such case the converter will consume all element's children, assuming that they were handled by the element itself.\n//\n// When the `addHighlight` custom property is not present, the element is not converted in any special way.\n// This means that converters will proceed to convert the element's child nodes.\n//\n// If the highlight descriptor does not provide the `priority` property, `10` will be used.\n//\n// If the highlight descriptor does not provide the `id` property, the name of the marker will be used.\n//\n// This converter binds altered {@link module:engine/view/containerelement~ContainerElement container elements} with the marker name using\n// the {@link module:engine/conversion/mapper~Mapper#bindElementToMarker} method.\n//\n// @param {module:engine/conversion/downcasthelpers~HighlightDescriptor|Function} highlightDescriptor\n// @returns {Function}\nfunction highlightElement( highlightDescriptor ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tif ( !data.item ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !( data.item instanceof ModelElement ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst descriptor = prepareDescriptor( highlightDescriptor, data, conversionApi );\n\n\t\tif ( !descriptor ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !conversionApi.consumable.test( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewElement = conversionApi.mapper.toViewElement( data.item );\n\n\t\tif ( viewElement && viewElement.getCustomProperty( 'addHighlight' ) ) {\n\t\t\t// Consume element itself.\n\t\t\tconversionApi.consumable.consume( data.item, evt.name );\n\n\t\t\t// Consume all children nodes.\n\t\t\tfor ( const value of ModelRange._createIn( data.item ) ) {\n\t\t\t\tconversionApi.consumable.consume( value.item, evt.name );\n\t\t\t}\n\n\t\t\tviewElement.getCustomProperty( 'addHighlight' )( viewElement, descriptor, conversionApi.writer );\n\n\t\t\tconversionApi.mapper.bindElementToMarker( viewElement, data.markerName );\n\t\t}\n\t};\n}\n\n// Function factory that creates a converter which converts the removing model marker to the view.\n//\n// Both text nodes and elements are handled by this converter but they are handled a bit differently.\n//\n// Text nodes are unwrapped using the {@link module:engine/view/attributeelement~AttributeElement attribute element} created from the\n// provided highlight descriptor. See {link module:engine/conversion/downcasthelpers~HighlightDescriptor}.\n//\n// For elements, the converter checks if an element has the `removeHighlight` function stored as a\n// {@link module:engine/view/element~Element#_setCustomProperty custom property}. If so, it uses it to remove the highlight.\n// In such case, the children of that element will not be converted.\n//\n// When `removeHighlight` is not present, the element is not converted in any special way.\n// The converter will proceed to convert the element's child nodes instead.\n//\n// If the highlight descriptor does not provide the `priority` property, `10` will be used.\n//\n// If the highlight descriptor does not provide the `id` property, the name of the marker will be used.\n//\n// This converter unbinds elements from the marker name.\n//\n// @param {module:engine/conversion/downcasthelpers~HighlightDescriptor|Function} highlightDescriptor\n// @returns {Function}\nfunction removeHighlight( highlightDescriptor ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\t// This conversion makes sense only for non-collapsed range.\n\t\tif ( data.markerRange.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst descriptor = prepareDescriptor( highlightDescriptor, data, conversionApi );\n\n\t\tif ( !descriptor ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// View element that will be used to unwrap `AttributeElement`s.\n\t\tconst viewHighlightElement = createViewElementFromHighlightDescriptor( descriptor );\n\n\t\t// Get all elements bound with given marker name.\n\t\tconst elements = conversionApi.mapper.markerNameToElements( data.markerName );\n\n\t\tif ( !elements ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconversionApi.mapper.unbindElementsFromMarkerName( data.markerName );\n\n\t\tfor ( const element of elements ) {\n\t\t\tif ( element.is( 'attributeElement' ) ) {\n\t\t\t\tconversionApi.writer.unwrap( conversionApi.writer.createRangeOn( element ), viewHighlightElement );\n\t\t\t} else {\n\t\t\t\t// if element.is( 'containerElement' ).\n\t\t\t\telement.getCustomProperty( 'removeHighlight' )( element, descriptor.id, conversionApi.writer );\n\t\t\t}\n\t\t}\n\n\t\tconversionApi.writer.clearClonedElementsGroup( data.markerName );\n\n\t\tevt.stop();\n\t};\n}\n\n// Model element to view element conversion helper.\n//\n// See {@link ~DowncastHelpers#elementToElement `.elementToElement()` downcast helper} for examples.\n//\n// @param {Object} config Conversion configuration.\n// @param {String} config.model The name of the model element to convert.\n// @param {module:engine/view/elementdefinition~ElementDefinition|Function} config.view A view element definition or a function\n// that takes the model element and {@link module:engine/view/downcastwriter~DowncastWriter view downcast writer}\n// as parameters and returns a view container element.\n// @returns {Function} Conversion helper.\nfunction downcastElementToElement( config ) {\n\tconfig = cloneDeep( config );\n\n\tconfig.view = normalizeToElementConfig( config.view, 'container' );\n\n\treturn dispatcher => {\n\t\tdispatcher.on( 'insert:' + config.model, insertElement( config.view ), { priority: config.converterPriority || 'normal' } );\n\t};\n}\n\n// Model attribute to view element conversion helper.\n//\n// See {@link ~DowncastHelpers#attributeToElement `.attributeToElement()` downcast helper} for examples.\n//\n// @param {Object} config Conversion configuration.\n// @param {String|Object} config.model The key of the attribute to convert from or a `{ key, values }` object. `values` is an array\n// of `String`s with possible values if the model attribute is an enumerable.\n// @param {module:engine/view/elementdefinition~ElementDefinition|Function|Object} config.view A view element definition or a function\n// that takes the model attribute value and {@link module:engine/view/downcastwriter~DowncastWriter view downcast writer}\n// as parameters and returns a view attribute element. If `config.model.values` is\n// given, `config.view` should be an object assigning values from `config.model.values` to view element definitions or functions.\n// @param {module:utils/priorities~PriorityString} [config.converterPriority='normal'] Converter priority.\n// @returns {Function} Conversion helper.\nfunction downcastAttributeToElement( config ) {\n\tconfig = cloneDeep( config );\n\n\tconst modelKey = config.model.key ? config.model.key : config.model;\n\tlet eventName = 'attribute:' + modelKey;\n\n\tif ( config.model.name ) {\n\t\teventName += ':' + config.model.name;\n\t}\n\n\tif ( config.model.values ) {\n\t\tfor ( const modelValue of config.model.values ) {\n\t\t\tconfig.view[ modelValue ] = normalizeToElementConfig( config.view[ modelValue ], 'attribute' );\n\t\t}\n\t} else {\n\t\tconfig.view = normalizeToElementConfig( config.view, 'attribute' );\n\t}\n\n\tconst elementCreator = getFromAttributeCreator( config );\n\n\treturn dispatcher => {\n\t\tdispatcher.on( eventName, wrap( elementCreator ), { priority: config.converterPriority || 'normal' } );\n\t};\n}\n\n// Model attribute to view attribute conversion helper.\n//\n// See {@link ~DowncastHelpers#attributeToAttribute `.attributeToAttribute()` downcast helper} for examples.\n//\n// @param {Object} config Conversion configuration.\n// @param {String|Object} config.model The key of the attribute to convert from or a `{ key, values, [ name ] }` object describing\n// the attribute key, possible values and, optionally, an element name to convert from.\n// @param {String|Object|Function} config.view A view attribute key, or a `{ key, value }` object or a function that takes\n// the model attribute value and returns a `{ key, value }` object. If `key` is `'class'`, `value` can be a `String` or an\n// array of `String`s. If `key` is `'style'`, `value` is an object with key-value pairs. In other cases, `value` is a `String`.\n// If `config.model.values` is set, `config.view` should be an object assigning values from `config.model.values` to\n// `{ key, value }` objects or a functions.\n// @param {module:utils/priorities~PriorityString} [config.converterPriority='normal'] Converter priority.\n// @returns {Function} Conversion helper.\nfunction downcastAttributeToAttribute( config ) {\n\tconfig = cloneDeep( config );\n\n\tconst modelKey = config.model.key ? config.model.key : config.model;\n\tlet eventName = 'attribute:' + modelKey;\n\n\tif ( config.model.name ) {\n\t\teventName += ':' + config.model.name;\n\t}\n\n\tif ( config.model.values ) {\n\t\tfor ( const modelValue of config.model.values ) {\n\t\t\tconfig.view[ modelValue ] = normalizeToAttributeConfig( config.view[ modelValue ] );\n\t\t}\n\t} else {\n\t\tconfig.view = normalizeToAttributeConfig( config.view );\n\t}\n\n\tconst elementCreator = getFromAttributeCreator( config );\n\n\treturn dispatcher => {\n\t\tdispatcher.on( eventName, changeAttribute( elementCreator ), { priority: config.converterPriority || 'normal' } );\n\t};\n}\n\n// Model marker to view element conversion helper.\n//\n// See {@link ~DowncastHelpers#markerToElement `.markerToElement()` downcast helper} for examples.\n//\n// @param {Object} config Conversion configuration.\n// @param {String} config.model The name of the model marker (or model marker group) to convert.\n// @param {module:engine/view/elementdefinition~ElementDefinition|Function} config.view A view element definition or a function\n// that takes the model marker data as a parameter and returns a view UI element.\n// @param {module:utils/priorities~PriorityString} [config.converterPriority='normal'] Converter priority.\n// @returns {Function} Conversion helper.\nfunction downcastMarkerToElement( config ) {\n\tconfig = cloneDeep( config );\n\n\tconfig.view = normalizeToElementConfig( config.view, 'ui' );\n\n\treturn dispatcher => {\n\t\tdispatcher.on( 'addMarker:' + config.model, insertUIElement( config.view ), { priority: config.converterPriority || 'normal' } );\n\t\tdispatcher.on( 'removeMarker:' + config.model, removeUIElement( config.view ), { priority: config.converterPriority || 'normal' } );\n\t};\n}\n\n// Model marker to highlight conversion helper.\n//\n// See {@link ~DowncastHelpers#markerToElement `.markerToElement()` downcast helper} for examples.\n//\n// @param {Object} config Conversion configuration.\n// @param {String} config.model The name of the model marker (or model marker group) to convert.\n// @param {module:engine/conversion/downcasthelpers~HighlightDescriptor|Function} config.view A highlight descriptor\n// that will be used for highlighting or a function that takes the model marker data as a parameter and returns a highlight descriptor.\n// @param {module:utils/priorities~PriorityString} [config.converterPriority='normal'] Converter priority.\n// @returns {Function} Conversion helper.\nfunction downcastMarkerToHighlight( config ) {\n\treturn dispatcher => {\n\t\tdispatcher.on( 'addMarker:' + config.model, highlightText( config.view ), { priority: config.converterPriority || 'normal' } );\n\t\tdispatcher.on( 'addMarker:' + config.model, highlightElement( config.view ), { priority: config.converterPriority || 'normal' } );\n\t\tdispatcher.on( 'removeMarker:' + config.model, removeHighlight( config.view ), { priority: config.converterPriority || 'normal' } );\n\t};\n}\n\n// Takes `config.view`, and if it is an {@link module:engine/view/elementdefinition~ElementDefinition}, converts it\n// to a function (because lower level converters accept only element creator functions).\n//\n// @param {module:engine/view/elementdefinition~ElementDefinition|Function} view View configuration.\n// @param {'container'|'attribute'|'ui'} viewElementType View element type to create.\n// @returns {Function} Element creator function to use in lower level converters.\nfunction normalizeToElementConfig( view, viewElementType ) {\n\tif ( typeof view == 'function' ) {\n\t\t// If `view` is already a function, don't do anything.\n\t\treturn view;\n\t}\n\n\treturn ( modelData, viewWriter ) => createViewElementFromDefinition( view, viewWriter, viewElementType );\n}\n\n// Creates a view element instance from the provided {@link module:engine/view/elementdefinition~ElementDefinition} and class.\n//\n// @param {module:engine/view/elementdefinition~ElementDefinition} viewElementDefinition\n// @param {module:engine/view/downcastwriter~DowncastWriter} viewWriter\n// @param {'container'|'attribute'|'ui'} viewElementType\n// @returns {module:engine/view/element~Element}\nfunction createViewElementFromDefinition( viewElementDefinition, viewWriter, viewElementType ) {\n\tif ( typeof viewElementDefinition == 'string' ) {\n\t\t// If `viewElementDefinition` is given as a `String`, normalize it to an object with `name` property.\n\t\tviewElementDefinition = { name: viewElementDefinition };\n\t}\n\n\tlet element;\n\tconst attributes = Object.assign( {}, viewElementDefinition.attributes );\n\n\tif ( viewElementType == 'container' ) {\n\t\telement = viewWriter.createContainerElement( viewElementDefinition.name, attributes );\n\t} else if ( viewElementType == 'attribute' ) {\n\t\tconst options = {\n\t\t\tpriority: viewElementDefinition.priority || ViewAttributeElement.DEFAULT_PRIORITY\n\t\t};\n\n\t\telement = viewWriter.createAttributeElement( viewElementDefinition.name, attributes, options );\n\t} else {\n\t\t// 'ui'.\n\t\telement = viewWriter.createUIElement( viewElementDefinition.name, attributes );\n\t}\n\n\tif ( viewElementDefinition.styles ) {\n\t\tconst keys = Object.keys( viewElementDefinition.styles );\n\n\t\tfor ( const key of keys ) {\n\t\t\tviewWriter.setStyle( key, viewElementDefinition.styles[ key ], element );\n\t\t}\n\t}\n\n\tif ( viewElementDefinition.classes ) {\n\t\tconst classes = viewElementDefinition.classes;\n\n\t\tif ( typeof classes == 'string' ) {\n\t\t\tviewWriter.addClass( classes, element );\n\t\t} else {\n\t\t\tfor ( const className of classes ) {\n\t\t\t\tviewWriter.addClass( className, element );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn element;\n}\n\nfunction getFromAttributeCreator( config ) {\n\tif ( config.model.values ) {\n\t\treturn ( modelAttributeValue, viewWriter ) => {\n\t\t\tconst view = config.view[ modelAttributeValue ];\n\n\t\t\tif ( view ) {\n\t\t\t\treturn view( modelAttributeValue, viewWriter );\n\t\t\t}\n\n\t\t\treturn null;\n\t\t};\n\t} else {\n\t\treturn config.view;\n\t}\n}\n\n// Takes the configuration, adds default parameters if they do not exist and normalizes other parameters to be used in downcast converters\n// for generating a view attribute.\n//\n// @param {Object} view View configuration.\nfunction normalizeToAttributeConfig( view ) {\n\tif ( typeof view == 'string' ) {\n\t\treturn modelAttributeValue => ( { key: view, value: modelAttributeValue } );\n\t} else if ( typeof view == 'object' ) {\n\t\t// { key, value, ... }\n\t\tif ( view.value ) {\n\t\t\treturn () => view;\n\t\t}\n\t\t// { key, ... }\n\t\telse {\n\t\t\treturn modelAttributeValue => ( { key: view.key, value: modelAttributeValue } );\n\t\t}\n\t} else {\n\t\t// function.\n\t\treturn view;\n\t}\n}\n\n// Helper function for `highlight`. Prepares the actual descriptor object using value passed to the converter.\nfunction prepareDescriptor( highlightDescriptor, data, conversionApi ) {\n\t// If passed descriptor is a creator function, call it. If not, just use passed value.\n\tconst descriptor = typeof highlightDescriptor == 'function' ?\n\t\thighlightDescriptor( data, conversionApi ) :\n\t\thighlightDescriptor;\n\n\tif ( !descriptor ) {\n\t\treturn null;\n\t}\n\n\t// Apply default descriptor priority.\n\tif ( !descriptor.priority ) {\n\t\tdescriptor.priority = 10;\n\t}\n\n\t// Default descriptor id is marker name.\n\tif ( !descriptor.id ) {\n\t\tdescriptor.id = data.markerName;\n\t}\n\n\treturn descriptor;\n}\n\n/**\n * An object describing how the marker highlight should be represented in the view.\n *\n * Each text node contained in a highlighted range will be wrapped in a `<span>`\n * {@link module:engine/view/attributeelement~AttributeElement view attribute element} with CSS class(es), attributes and a priority\n * described by this object.\n *\n * Additionally, each {@link module:engine/view/containerelement~ContainerElement container element} can handle displaying the highlight\n * separately by providing the `addHighlight` and `removeHighlight` custom properties. In this case:\n *\n * * The `HighlightDescriptor` object is passed to the `addHighlight` function upon conversion and should be used to apply the highlight to\n * the element.\n * * The descriptor `id` is passed to the `removeHighlight` function upon conversion and should be used to remove the highlight with the\n * given ID from the element.\n *\n * @typedef {Object} module:engine/conversion/downcasthelpers~HighlightDescriptor\n *\n * @property {String|Array.<String>} classes A CSS class or an array of classes to set. If the descriptor is used to\n * create an {@link module:engine/view/attributeelement~AttributeElement attribute element} over text nodes, these classes will be set\n * on that attribute element. If the descriptor is applied to an element, usually these classes will be set on that element, however,\n * this depends on how the element converts the descriptor.\n *\n * @property {String} [id] Descriptor identifier. If not provided, it defaults to the converted marker's name.\n *\n * @property {Number} [priority] Descriptor priority. If not provided, it defaults to `10`. If the descriptor is used to create\n * an {@link module:engine/view/attributeelement~AttributeElement attribute element}, it will be that element's\n * {@link module:engine/view/attributeelement~AttributeElement#priority priority}. If the descriptor is applied to an element,\n * the priority will be used to determine which descriptor is more important.\n *\n * @property {Object} [attributes] Attributes to set. If the descriptor is used to create\n * an {@link module:engine/view/attributeelement~AttributeElement attribute element} over text nodes, these attributes will be set on that\n * attribute element. If the descriptor is applied to an element, usually these attributes will be set on that element, however,\n * this depends on how the element converts the descriptor.\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\nimport Matcher from '../view/matcher';\nimport ModelRange from '../model/range';\nimport ConversionHelpers from './conversionhelpers';\n\nimport { cloneDeep } from 'lodash-es';\nimport ModelSelection from '../model/selection';\n\n/**\n * Contains {@link module:engine/view/view view} to {@link module:engine/model/model model} converters for\n * {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher}.\n *\n * @module engine/conversion/upcasthelpers\n */\n\n/**\n * Upcast conversion helper functions.\n *\n * @extends module:engine/conversion/conversionhelpers~ConversionHelpers\n */\nexport default class UpcastHelpers extends ConversionHelpers {\n\t/**\n\t * View element to model element conversion helper.\n\t *\n\t * This conversion results in creating a model element. For example,\n\t * view `<p>Foo</p>` becomes `<paragraph>Foo</paragraph>` in the model.\n\t *\n\t * Keep in mind that the element will be inserted only if it is allowed\n\t * by {@link module:engine/model/schema~Schema schema} configuration.\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).elementToElement( {\n\t *\t\t\tview: 'p',\n\t *\t\t\tmodel: 'paragraph'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).elementToElement( {\n\t *\t\t\tview: 'p',\n\t *\t\t\tmodel: 'paragraph',\n\t *\t\t\tconverterPriority: 'high'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).elementToElement( {\n\t *\t\t\tview: {\n\t *\t\t\t\tname: 'p',\n\t *\t\t\t\tclasses: 'fancy'\n\t *\t\t\t},\n\t *\t\t\tmodel: 'fancyParagraph'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).elementToElement( {\n\t * \t\t\tview: {\n\t *\t\t\t\tname: 'p',\n\t *\t\t\t\tclasses: 'heading'\n\t * \t\t\t},\n\t * \t\t\tmodel: ( viewElement, modelWriter ) => {\n\t * \t\t\t\treturn modelWriter.createElement( 'heading', { level: viewElement.getAttribute( 'data-level' ) } );\n\t * \t\t\t}\n\t * \t\t} );\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @method #elementToElement\n\t * @param {Object} config Conversion configuration.\n\t * @param {module:engine/view/matcher~MatcherPattern} [config.view] Pattern matching all view elements which should be converted. If not\n\t * set, the converter will fire for every view element.\n\t * @param {String|module:engine/model/element~Element|Function} config.model Name of the model element, a model element\n\t * instance or a function that takes a view element and returns a model element. The model element will be inserted in the model.\n\t * @param {module:utils/priorities~PriorityString} [config.converterPriority='normal'] Converter priority.\n\t * @returns {module:engine/conversion/upcasthelpers~UpcastHelpers}\n\t */\n\telementToElement( config ) {\n\t\treturn this.add( upcastElementToElement( config ) );\n\t}\n\n\t/**\n\t * View element to model attribute conversion helper.\n\t *\n\t * This conversion results in setting an attribute on a model node. For example, view `<strong>Foo</strong>` becomes\n\t * `Foo` {@link module:engine/model/text~Text model text node} with `bold` attribute set to `true`.\n\t *\n\t * This helper is meant to set a model attribute on all the elements that are inside the converted element:\n\t *\n\t *\t\t<strong>Foo</strong> --> <strong><p>Foo</p></strong> --> <paragraph><$text bold=\"true\">Foo</$text></paragraph>\n\t *\n\t * Above is a sample of HTML code, that goes through autoparagraphing (first step) and then is converted (second step).\n\t * Even though `<strong>` is over `<p>` element, `bold=\"true\"` was added to the text. See\n\t * {@link module:engine/conversion/upcasthelpers~UpcastHelpers#attributeToAttribute} for comparison.\n\t *\n\t * Keep in mind that the attribute will be set only if it is allowed by {@link module:engine/model/schema~Schema schema} configuration.\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).elementToAttribute( {\n\t *\t\t\tview: 'strong',\n\t *\t\t\tmodel: 'bold'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).elementToAttribute( {\n\t *\t\t\tview: 'strong',\n\t *\t\t\tmodel: 'bold',\n\t *\t\t\tconverterPriority: 'high'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).elementToAttribute( {\n\t *\t\t\tview: {\n\t *\t\t\t\tname: 'span',\n\t *\t\t\t\tclasses: 'bold'\n\t *\t\t\t},\n\t *\t\t\tmodel: 'bold'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).elementToAttribute( {\n\t *\t\t\tview: {\n\t *\t\t\t\tname: 'span',\n\t *\t\t\t\tclasses: [ 'styled', 'styled-dark' ]\n\t *\t\t\t},\n\t *\t\t\tmodel: {\n\t *\t\t\t\tkey: 'styled',\n\t *\t\t\t\tvalue: 'dark'\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * \t\teditor.conversion.for( 'upcast' ).elementToAttribute( {\n\t *\t\t\tview: {\n\t *\t\t\t\tname: 'span',\n\t *\t\t\t\tstyles: {\n\t *\t\t\t\t\t'font-size': /[\\s\\S]+/\n\t *\t\t\t\t}\n\t *\t\t\t},\n\t *\t\t\tmodel: {\n\t *\t\t\t\tkey: 'fontSize',\n\t *\t\t\t\tvalue: viewElement => {\n\t *\t\t\t\t\tconst fontSize = viewElement.getStyle( 'font-size' );\n\t *\t\t\t\t\tconst value = fontSize.substr( 0, fontSize.length - 2 );\n\t *\n\t *\t\t\t\t\tif ( value <= 10 ) {\n\t *\t\t\t\t\t\treturn 'small';\n\t *\t\t\t\t\t} else if ( value > 12 ) {\n\t *\t\t\t\t\t\treturn 'big';\n\t *\t\t\t\t\t}\n\t *\n\t *\t\t\t\t\treturn null;\n\t *\t\t\t\t}\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @method #elementToAttribute\n\t * @param {Object} config Conversion configuration.\n\t * @param {module:engine/view/matcher~MatcherPattern} config.view Pattern matching all view elements which should be converted.\n\t * @param {String|Object} config.model Model attribute key or an object with `key` and `value` properties, describing\n\t * the model attribute. `value` property may be set as a function that takes a view element and returns the value.\n\t * If `String` is given, the model attribute value will be set to `true`.\n\t * @param {module:utils/priorities~PriorityString} [config.converterPriority='normal'] Converter priority.\n\t * @returns {module:engine/conversion/upcasthelpers~UpcastHelpers}\n\t */\n\telementToAttribute( config ) {\n\t\treturn this.add( upcastElementToAttribute( config ) );\n\t}\n\n\t/**\n\t * View attribute to model attribute conversion helper.\n\t *\n\t * This conversion results in setting an attribute on a model node. For example, view `<img src=\"foo.jpg\"></img>` becomes\n\t * `<image source=\"foo.jpg\"></image>` in the model.\n\t *\n\t * This helper is meant to convert view attributes from view elements which got converted to the model, so the view attribute\n\t * is set only on the corresponding model node:\n\t *\n\t *\t\t<div class=\"dark\"><div>foo</div></div> --> <div dark=\"true\"><div>foo</div></div>\n\t *\n\t * Above, `class=\"dark\"` attribute is added only to the `<div>` elements that has it. This is in contrary to\n\t * {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToAttribute} which sets attributes for\n\t * all the children in the model:\n\t *\n\t *\t\t<strong>Foo</strong> --> <strong><p>Foo</p></strong> --> <paragraph><$text bold=\"true\">Foo</$text></paragraph>\n\t *\n\t * Above is a sample of HTML code, that goes through autoparagraphing (first step) and then is converted (second step).\n\t * Even though `<strong>` is over `<p>` element, `bold=\"true\"` was added to the text.\n\t *\n\t * Keep in mind that the attribute will be set only if it is allowed by {@link module:engine/model/schema~Schema schema} configuration.\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t *\t\t\tview: 'src',\n\t *\t\t\tmodel: 'source'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t *\t\t\tview: { key: 'src' },\n\t *\t\t\tmodel: 'source'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t *\t\t\tview: { key: 'src' },\n\t *\t\t\tmodel: 'source',\n\t *\t\t\tconverterPriority: 'normal'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t *\t\t\tview: {\n\t *\t\t\t\tkey: 'data-style',\n\t *\t\t\t\tvalue: /[\\s\\S]+/\n\t *\t\t\t},\n\t *\t\t\tmodel: 'styled'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t *\t\t\tview: {\n\t *\t\t\t\tname: 'img',\n\t *\t\t\t\tkey: 'class',\n\t *\t\t\t\tvalue: 'styled-dark'\n\t *\t\t\t},\n\t *\t\t\tmodel: {\n\t *\t\t\t\tkey: 'styled',\n\t *\t\t\t\tvalue: 'dark'\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t *\t\t\tview: {\n\t *\t\t\t\tkey: 'class',\n\t *\t\t\t\tvalue: /styled-[\\S]+/\n\t *\t\t\t},\n\t *\t\t\tmodel: {\n\t *\t\t\t\tkey: 'styled'\n\t *\t\t\t\tvalue: viewElement => {\n\t *\t\t\t\t\tconst regexp = /styled-([\\S]+)/;\n\t *\t\t\t\t\tconst match = viewElement.getAttribute( 'class' ).match( regexp );\n\t *\n\t *\t\t\t\t\treturn match[ 1 ];\n\t *\t\t\t\t}\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @method #attributeToAttribute\n\t * @param {Object} config Conversion configuration.\n\t * @param {String|Object} config.view Specifies which view attribute will be converted. If a `String` is passed,\n\t * attributes with given key will be converted. If an `Object` is passed, it must have a required `key` property,\n\t * specifying view attribute key, and may have an optional `value` property, specifying view attribute value and optional `name`\n\t * property specifying a view element name from/on which the attribute should be converted. `value` can be given as a `String`,\n\t * a `RegExp` or a function callback, that takes view attribute value as the only parameter and returns `Boolean`.\n\t * @param {String|Object} config.model Model attribute key or an object with `key` and `value` properties, describing\n\t * the model attribute. `value` property may be set as a function that takes a view element and returns the value.\n\t * If `String` is given, the model attribute value will be same as view attribute value.\n\t * @param {module:utils/priorities~PriorityString} [config.converterPriority='low'] Converter priority.\n\t * @returns {module:engine/conversion/upcasthelpers~UpcastHelpers}\n\t */\n\tattributeToAttribute( config ) {\n\t\treturn this.add( upcastAttributeToAttribute( config ) );\n\t}\n\n\t/**\n\t * View element to model marker conversion helper.\n\t *\n\t * This conversion results in creating a model marker. For example, if the marker was stored in a view as an element:\n\t * `<p>Fo<span data-marker=\"comment\" data-comment-id=\"7\"></span>o</p><p>B<span data-marker=\"comment\" data-comment-id=\"7\"></span>ar</p>`,\n\t * after the conversion is done, the marker will be available in\n\t * {@link module:engine/model/model~Model#markers model document markers}.\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).elementToMarker( {\n\t *\t\t\tview: 'marker-search',\n\t *\t\t\tmodel: 'search'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).elementToMarker( {\n\t *\t\t\tview: 'marker-search',\n\t *\t\t\tmodel: 'search',\n\t *\t\t\tconverterPriority: 'high'\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).elementToMarker( {\n\t *\t\t\tview: 'marker-search',\n\t *\t\t\tmodel: viewElement => 'comment:' + viewElement.getAttribute( 'data-comment-id' )\n\t *\t\t} );\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).elementToMarker( {\n\t *\t\t\tview: {\n\t *\t\t\t\tname: 'span',\n\t *\t\t\t\tattributes: {\n\t *\t\t\t\t\t'data-marker': 'search'\n\t *\t\t\t\t}\n\t *\t\t\t},\n\t *\t\t\tmodel: 'search'\n\t *\t\t} );\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @method #elementToMarker\n\t * @param {Object} config Conversion configuration.\n\t * @param {module:engine/view/matcher~MatcherPattern} config.view Pattern matching all view elements which should be converted.\n\t * @param {String|Function} config.model Name of the model marker, or a function that takes a view element and returns\n\t * a model marker name.\n\t * @param {module:utils/priorities~PriorityString} [config.converterPriority='normal'] Converter priority.\n\t * @returns {module:engine/conversion/upcasthelpers~UpcastHelpers}\n\t */\n\telementToMarker( config ) {\n\t\treturn this.add( upcastElementToMarker( config ) );\n\t}\n}\n\n/**\n * Function factory, creates a converter that converts {@link module:engine/view/documentfragment~DocumentFragment view document fragment}\n * or all children of {@link module:engine/view/element~Element} into\n * {@link module:engine/model/documentfragment~DocumentFragment model document fragment}.\n * This is the \"entry-point\" converter for upcast (view to model conversion). This converter starts the conversion of all children\n * of passed view document fragment. Those children {@link module:engine/view/node~Node view nodes} are then handled by other converters.\n *\n * This also a \"default\", last resort converter for all view elements that has not been converted by other converters.\n * When a view element is being converted to the model but it does not have converter specified, that view element\n * will be converted to {@link module:engine/model/documentfragment~DocumentFragment model document fragment} and returned.\n *\n * @returns {Function} Universal converter for view {@link module:engine/view/documentfragment~DocumentFragment fragments} and\n * {@link module:engine/view/element~Element elements} that returns\n * {@link module:engine/model/documentfragment~DocumentFragment model fragment} with children of converted view item.\n */\nexport function convertToModelFragment() {\n\treturn ( evt, data, conversionApi ) => {\n\t\t// Second argument in `consumable.consume` is discarded for ViewDocumentFragment but is needed for ViewElement.\n\t\tif ( !data.modelRange && conversionApi.consumable.consume( data.viewItem, { name: true } ) ) {\n\t\t\tconst { modelRange, modelCursor } = conversionApi.convertChildren( data.viewItem, data.modelCursor );\n\n\t\t\tdata.modelRange = modelRange;\n\t\t\tdata.modelCursor = modelCursor;\n\t\t}\n\t};\n}\n\n/**\n * Function factory, creates a converter that converts {@link module:engine/view/text~Text} to {@link module:engine/model/text~Text}.\n *\n * @returns {Function} {@link module:engine/view/text~Text View text} converter.\n */\nexport function convertText() {\n\treturn ( evt, data, conversionApi ) => {\n\t\tif ( conversionApi.schema.checkChild( data.modelCursor, '$text' ) ) {\n\t\t\tif ( conversionApi.consumable.consume( data.viewItem ) ) {\n\t\t\t\tconst text = conversionApi.writer.createText( data.viewItem.data );\n\n\t\t\t\tconversionApi.writer.insert( text, data.modelCursor );\n\n\t\t\t\tdata.modelRange = ModelRange._createFromPositionAndShift( data.modelCursor, text.offsetSize );\n\t\t\t\tdata.modelCursor = data.modelRange.end;\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Function factory, creates a callback function which converts a {@link module:engine/view/selection~Selection\n * view selection} taken from the {@link module:engine/view/document~Document#event:selectionChange} event\n * and sets in on the {@link module:engine/model/document~Document#selection model}.\n *\n * **Note**: because there is no view selection change dispatcher nor any other advanced view selection to model\n * conversion mechanism, the callback should be set directly on view document.\n *\n *\t\tview.document.on( 'selectionChange', convertSelectionChange( modelDocument, mapper ) );\n *\n * @param {module:engine/model/model~Model} model Data model.\n * @param {module:engine/conversion/mapper~Mapper} mapper Conversion mapper.\n * @returns {Function} {@link module:engine/view/document~Document#event:selectionChange} callback function.\n */\nexport function convertSelectionChange( model, mapper ) {\n\treturn ( evt, data ) => {\n\t\tconst viewSelection = data.newSelection;\n\t\tconst modelSelection = new ModelSelection();\n\n\t\tconst ranges = [];\n\n\t\tfor ( const viewRange of viewSelection.getRanges() ) {\n\t\t\tranges.push( mapper.toModelRange( viewRange ) );\n\t\t}\n\n\t\tmodelSelection.setTo( ranges, { backward: viewSelection.isBackward } );\n\n\t\tif ( !modelSelection.isEqual( model.document.selection ) ) {\n\t\t\tmodel.change( writer => {\n\t\t\t\twriter.setSelection( modelSelection );\n\t\t\t} );\n\t\t}\n\t};\n}\n\n// View element to model element conversion helper.\n//\n// See {@link ~UpcastHelpers#elementToElement `.elementToElement()` upcast helper} for examples.\n//\n// @param {Object} config Conversion configuration.\n// @param {module:engine/view/matcher~MatcherPattern} [config.view] Pattern matching all view elements which should be converted. If not\n// set, the converter will fire for every view element.\n// @param {String|module:engine/model/element~Element|Function} config.model Name of the model element, a model element\n// instance or a function that takes a view element and returns a model element. The model element will be inserted in the model.\n// @param {module:utils/priorities~PriorityString} [config.converterPriority='normal'] Converter priority.\n// @returns {Function} Conversion helper.\nfunction upcastElementToElement( config ) {\n\tconfig = cloneDeep( config );\n\n\tconst converter = prepareToElementConverter( config );\n\n\tconst elementName = getViewElementNameFromConfig( config );\n\tconst eventName = elementName ? 'element:' + elementName : 'element';\n\n\treturn dispatcher => {\n\t\tdispatcher.on( eventName, converter, { priority: config.converterPriority || 'normal' } );\n\t};\n}\n\n// View element to model attribute conversion helper.\n//\n// See {@link ~UpcastHelpers#elementToAttribute `.elementToAttribute()` upcast helper} for examples.\n//\n// @param {Object} config Conversion configuration.\n// @param {module:engine/view/matcher~MatcherPattern} config.view Pattern matching all view elements which should be converted.\n// @param {String|Object} config.model Model attribute key or an object with `key` and `value` properties, describing\n// the model attribute. `value` property may be set as a function that takes a view element and returns the value.\n// If `String` is given, the model attribute value will be set to `true`.\n// @param {module:utils/priorities~PriorityString} [config.converterPriority='normal'] Converter priority.\n// @returns {Function} Conversion helper.\nfunction upcastElementToAttribute( config ) {\n\tconfig = cloneDeep( config );\n\n\tnormalizeModelAttributeConfig( config );\n\n\tconst converter = prepareToAttributeConverter( config, false );\n\n\tconst elementName = getViewElementNameFromConfig( config );\n\tconst eventName = elementName ? 'element:' + elementName : 'element';\n\n\treturn dispatcher => {\n\t\tdispatcher.on( eventName, converter, { priority: config.converterPriority || 'low' } );\n\t};\n}\n\n// View attribute to model attribute conversion helper.\n//\n// See {@link ~UpcastHelpers#attributeToAttribute `.attributeToAttribute()` upcast helper} for examples.\n//\n// @param {Object} config Conversion configuration.\n// @param {String|Object} config.view Specifies which view attribute will be converted. If a `String` is passed,\n// attributes with given key will be converted. If an `Object` is passed, it must have a required `key` property,\n// specifying view attribute key, and may have an optional `value` property, specifying view attribute value and optional `name`\n// property specifying a view element name from/on which the attribute should be converted. `value` can be given as a `String`,\n// a `RegExp` or a function callback, that takes view attribute value as the only parameter and returns `Boolean`.\n// @param {String|Object} config.model Model attribute key or an object with `key` and `value` properties, describing\n// the model attribute. `value` property may be set as a function that takes a view element and returns the value.\n// If `String` is given, the model attribute value will be same as view attribute value.\n// @param {module:utils/priorities~PriorityString} [config.converterPriority='low'] Converter priority.\n// @returns {Function} Conversion helper.\nfunction upcastAttributeToAttribute( config ) {\n\tconfig = cloneDeep( config );\n\n\tlet viewKey = null;\n\n\tif ( typeof config.view == 'string' || config.view.key ) {\n\t\tviewKey = normalizeViewAttributeKeyValueConfig( config );\n\t}\n\n\tnormalizeModelAttributeConfig( config, viewKey );\n\n\tconst converter = prepareToAttributeConverter( config, true );\n\n\treturn dispatcher => {\n\t\tdispatcher.on( 'element', converter, { priority: config.converterPriority || 'low' } );\n\t};\n}\n\n// View element to model marker conversion helper.\n//\n// See {@link ~UpcastHelpers#elementToMarker `.elementToMarker()` upcast helper} for examples.\n//\n// @param {Object} config Conversion configuration.\n// @param {module:engine/view/matcher~MatcherPattern} config.view Pattern matching all view elements which should be converted.\n// @param {String|Function} config.model Name of the model marker, or a function that takes a view element and returns\n// a model marker name.\n// @param {module:utils/priorities~PriorityString} [config.converterPriority='normal'] Converter priority.\n// @returns {Function} Conversion helper.\nfunction upcastElementToMarker( config ) {\n\tconfig = cloneDeep( config );\n\n\tnormalizeToMarkerConfig( config );\n\n\treturn upcastElementToElement( config );\n}\n\n// Helper function for from-view-element conversion. Checks if `config.view` directly specifies converted view element's name\n// and if so, returns it.\n//\n// @param {Object} config Conversion config.\n// @returns {String|null} View element name or `null` if name is not directly set.\nfunction getViewElementNameFromConfig( config ) {\n\tif ( typeof config.view == 'string' ) {\n\t\treturn config.view;\n\t}\n\n\tif ( typeof config.view == 'object' && typeof config.view.name == 'string' ) {\n\t\treturn config.view.name;\n\t}\n\n\treturn null;\n}\n\n// Helper for to-model-element conversion. Takes a config object and returns a proper converter function.\n//\n// @param {Object} config Conversion configuration.\n// @returns {Function} View to model converter.\nfunction prepareToElementConverter( config ) {\n\tconst matcher = config.view ? new Matcher( config.view ) : null;\n\n\treturn ( evt, data, conversionApi ) => {\n\t\tlet match = {};\n\n\t\t// If `config.view` has not been passed do not try matching. In this case, the converter should fire for all elements.\n\t\tif ( matcher ) {\n\t\t\t// This will be usually just one pattern but we support matchers with many patterns too.\n\t\t\tconst matcherResult = matcher.match( data.viewItem );\n\n\t\t\t// If there is no match, this callback should not do anything.\n\t\t\tif ( !matcherResult ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmatch = matcherResult.match;\n\t\t}\n\n\t\t// Force consuming element's name.\n\t\tmatch.name = true;\n\n\t\t// Create model element basing on config.\n\t\tconst modelElement = getModelElement( config.model, data.viewItem, conversionApi.writer );\n\n\t\t// Do not convert if element building function returned falsy value.\n\t\tif ( !modelElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// When element was already consumed then skip it.\n\t\tif ( !conversionApi.consumable.test( data.viewItem, match ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Find allowed parent for element that we are going to insert.\n\t\t// If current parent does not allow to insert element but one of the ancestors does\n\t\t// then split nodes to allowed parent.\n\t\tconst splitResult = conversionApi.splitToAllowedParent( modelElement, data.modelCursor );\n\n\t\t// When there is no split result it means that we can't insert element to model tree, so let's skip it.\n\t\tif ( !splitResult ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Insert element on allowed position.\n\t\tconversionApi.writer.insert( modelElement, splitResult.position );\n\n\t\t// Convert children and insert to element.\n\t\tconversionApi.convertChildren( data.viewItem, conversionApi.writer.createPositionAt( modelElement, 0 ) );\n\n\t\t// Consume appropriate value from consumable values list.\n\t\tconversionApi.consumable.consume( data.viewItem, match );\n\n\t\tconst parts = conversionApi.getSplitParts( modelElement );\n\n\t\t// Set conversion result range.\n\t\tdata.modelRange = new ModelRange(\n\t\t\tconversionApi.writer.createPositionBefore( modelElement ),\n\t\t\tconversionApi.writer.createPositionAfter( parts[ parts.length - 1 ] )\n\t\t);\n\n\t\t// Now we need to check where the `modelCursor` should be.\n\t\tif ( splitResult.cursorParent ) {\n\t\t\t// If we split parent to insert our element then we want to continue conversion in the new part of the split parent.\n\t\t\t//\n\t\t\t// before: <allowed><notAllowed>foo[]</notAllowed></allowed>\n\t\t\t// after: <allowed><notAllowed>foo</notAllowed><converted></converted><notAllowed>[]</notAllowed></allowed>\n\n\t\t\tdata.modelCursor = conversionApi.writer.createPositionAt( splitResult.cursorParent, 0 );\n\t\t} else {\n\t\t\t// Otherwise just continue after inserted element.\n\n\t\t\tdata.modelCursor = data.modelRange.end;\n\t\t}\n\t};\n}\n\n// Helper function for upcasting-to-element converter. Takes the model configuration, the converted view element\n// and a writer instance and returns a model element instance to be inserted in the model.\n//\n// @param {String|Function|module:engine/model/element~Element} model Model conversion configuration.\n// @param {module:engine/view/node~Node} input The converted view node.\n// @param {module:engine/model/writer~Writer} writer A writer instance to use to create the model element.\nfunction getModelElement( model, input, writer ) {\n\tif ( model instanceof Function ) {\n\t\treturn model( input, writer );\n\t} else {\n\t\treturn writer.createElement( model );\n\t}\n}\n\n// Helper function view-attribute-to-model-attribute helper. Normalizes `config.view` which was set as `String` or\n// as an `Object` with `key`, `value` and `name` properties. Normalized `config.view` has is compatible with\n// {@link module:engine/view/matcher~MatcherPattern}.\n//\n// @param {Object} config Conversion config.\n// @returns {String} Key of the converted view attribute.\nfunction normalizeViewAttributeKeyValueConfig( config ) {\n\tif ( typeof config.view == 'string' ) {\n\t\tconfig.view = { key: config.view };\n\t}\n\n\tconst key = config.view.key;\n\tlet normalized;\n\n\tif ( key == 'class' || key == 'style' ) {\n\t\tconst keyName = key == 'class' ? 'classes' : 'styles';\n\n\t\tnormalized = {\n\t\t\t[ keyName ]: config.view.value\n\t\t};\n\t} else {\n\t\tconst value = typeof config.view.value == 'undefined' ? /[\\s\\S]*/ : config.view.value;\n\n\t\tnormalized = {\n\t\t\tattributes: {\n\t\t\t\t[ key ]: value\n\t\t\t}\n\t\t};\n\t}\n\n\tif ( config.view.name ) {\n\t\tnormalized.name = config.view.name;\n\t}\n\n\tconfig.view = normalized;\n\n\treturn key;\n}\n\n// Helper function that normalizes `config.model` in from-model-attribute conversion. `config.model` can be set\n// as a `String`, an `Object` with only `key` property or an `Object` with `key` and `value` properties. Normalized\n// `config.model` is an `Object` with `key` and `value` properties.\n//\n// @param {Object} config Conversion config.\n// @param {String} viewAttributeKeyToCopy Key of the converted view attribute. If it is set, model attribute value\n// will be equal to view attribute value.\nfunction normalizeModelAttributeConfig( config, viewAttributeKeyToCopy = null ) {\n\tconst defaultModelValue = viewAttributeKeyToCopy === null ? true : viewElement => viewElement.getAttribute( viewAttributeKeyToCopy );\n\n\tconst key = typeof config.model != 'object' ? config.model : config.model.key;\n\tconst value = typeof config.model != 'object' || typeof config.model.value == 'undefined' ? defaultModelValue : config.model.value;\n\n\tconfig.model = { key, value };\n}\n\n// Helper for to-model-attribute conversion. Takes the model attribute name and conversion configuration and returns\n// a proper converter function.\n//\n// @param {String} modelAttributeKey The key of the model attribute to set on a model node.\n// @param {Object|Array.<Object>} config Conversion configuration. It is possible to provide multiple configurations in an array.\n// @param {Boolean} shallow If set to `true` the attribute will be set only on top-level nodes. Otherwise, it will be set\n// on all elements in the range.\nfunction prepareToAttributeConverter( config, shallow ) {\n\tconst matcher = new Matcher( config.view );\n\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst match = matcher.match( data.viewItem );\n\n\t\t// If there is no match, this callback should not do anything.\n\t\tif ( !match ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelKey = config.model.key;\n\t\tconst modelValue = typeof config.model.value == 'function' ? config.model.value( data.viewItem ) : config.model.value;\n\n\t\t// Do not convert if attribute building function returned falsy value.\n\t\tif ( modelValue === null ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( onlyViewNameIsDefined( config ) ) {\n\t\t\tmatch.match.name = true;\n\t\t} else {\n\t\t\t// Do not test or consume `name` consumable.\n\t\t\tdelete match.match.name;\n\t\t}\n\n\t\t// Try to consume appropriate values from consumable values list.\n\t\tif ( !conversionApi.consumable.test( data.viewItem, match.match ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Since we are converting to attribute we need an range on which we will set the attribute.\n\t\t// If the range is not created yet, we will create it.\n\t\tif ( !data.modelRange ) {\n\t\t\t// Convert children and set conversion result as a current data.\n\t\t\tdata = Object.assign( data, conversionApi.convertChildren( data.viewItem, data.modelCursor ) );\n\t\t}\n\n\t\t// Set attribute on current `output`. `Schema` is checked inside this helper function.\n\t\tconst attributeWasSet = setAttributeOn( data.modelRange, { key: modelKey, value: modelValue }, shallow, conversionApi );\n\n\t\tif ( attributeWasSet ) {\n\t\t\tconversionApi.consumable.consume( data.viewItem, match.match );\n\t\t}\n\t};\n}\n\n// Helper function that checks if element name should be consumed in attribute converters.\n//\n// @param {Object} config Conversion config.\n// @returns {Boolean}\nfunction onlyViewNameIsDefined( config ) {\n\tif ( typeof config.view == 'object' && !getViewElementNameFromConfig( config ) ) {\n\t\treturn false;\n\t}\n\n\treturn !config.view.classes && !config.view.attributes && !config.view.styles;\n}\n\n// Helper function for to-model-attribute converter. Sets model attribute on given range. Checks {@link module:engine/model/schema~Schema}\n// to ensure proper model structure.\n//\n// @param {module:engine/model/range~Range} modelRange Model range on which attribute should be set.\n// @param {Object} modelAttribute Model attribute to set.\n// @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion API.\n// @param {Boolean} shallow If set to `true` the attribute will be set only on top-level nodes. Otherwise, it will be set\n// on all elements in the range.\n// @returns {Boolean} `true` if attribute was set on at least one node from given `modelRange`.\nfunction setAttributeOn( modelRange, modelAttribute, shallow, conversionApi ) {\n\tlet result = false;\n\n\t// Set attribute on each item in range according to Schema.\n\tfor ( const node of Array.from( modelRange.getItems( { shallow } ) ) ) {\n\t\tif ( conversionApi.schema.checkAttribute( node, modelAttribute.key ) ) {\n\t\t\tconversionApi.writer.setAttribute( modelAttribute.key, modelAttribute.value, node );\n\n\t\t\tresult = true;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n// Helper function for upcasting-to-marker conversion. Takes the config in a format requested by `upcastElementToMarker()`\n// function and converts it to a format that is supported by `_upcastElementToElement()` function.\n//\n// @param {Object} config Conversion configuration.\nfunction normalizeToMarkerConfig( config ) {\n\tconst oldModel = config.model;\n\n\tconfig.model = ( viewElement, modelWriter ) => {\n\t\tconst markerName = typeof oldModel == 'string' ? oldModel : oldModel( viewElement );\n\n\t\treturn modelWriter.createElement( '$marker', { 'data-name': markerName } );\n\t};\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/controller/editingcontroller\n */\n\nimport RootEditableElement from '../view/rooteditableelement';\nimport View from '../view/view';\nimport Mapper from '../conversion/mapper';\nimport DowncastDispatcher from '../conversion/downcastdispatcher';\nimport { clearAttributes, convertCollapsedSelection, convertRangeSelection, insertText, remove } from '../conversion/downcasthelpers';\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport { convertSelectionChange } from '../conversion/upcasthelpers';\n\n/**\n * Controller for the editing pipeline. The editing pipeline controls {@link ~EditingController#model model} rendering,\n * including selection handling. It also creates the {@link ~EditingController#view view} which builds a\n * browser-independent virtualization over the DOM elements. The editing controller also attaches default converters.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class EditingController {\n\t/**\n\t * Creates an editing controller instance.\n\t *\n\t * @param {module:engine/model/model~Model} model Editing model.\n\t */\n\tconstructor( model ) {\n\t\t/**\n\t\t * Editor model.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/model~Model}\n\t\t */\n\t\tthis.model = model;\n\n\t\t/**\n\t\t * Editing view controller.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/view~View}\n\t\t */\n\t\tthis.view = new View();\n\n\t\t/**\n\t\t * Mapper which describes the model-view binding.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/conversion/mapper~Mapper}\n\t\t */\n\t\tthis.mapper = new Mapper();\n\n\t\t/**\n\t\t * Downcast dispatcher that converts changes from the model to {@link #view the editing view}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/conversion/downcastdispatcher~DowncastDispatcher} #downcastDispatcher\n\t\t */\n\t\tthis.downcastDispatcher = new DowncastDispatcher( {\n\t\t\tmapper: this.mapper\n\t\t} );\n\n\t\tconst doc = this.model.document;\n\t\tconst selection = doc.selection;\n\t\tconst markers = this.model.markers;\n\n\t\t// When plugins listen on model changes (on selection change, post fixers, etc) and change the view as a result of\n\t\t// model's change, they might trigger view rendering before the conversion is completed (e.g. before the selection\n\t\t// is converted). We disable rendering for the length of the outermost model change() block to prevent that.\n\t\t//\n\t\t// See https://github.com/ckeditor/ckeditor5-engine/issues/1528\n\t\tthis.listenTo( this.model, '_beforeChanges', () => {\n\t\t\tthis.view._disableRendering( true );\n\t\t}, { priority: 'highest' } );\n\n\t\tthis.listenTo( this.model, '_afterChanges', () => {\n\t\t\tthis.view._disableRendering( false );\n\t\t}, { priority: 'lowest' } );\n\n\t\t// Whenever model document is changed, convert those changes to the view (using model.Document#differ).\n\t\t// Do it on 'low' priority, so changes are converted after other listeners did their job.\n\t\t// Also convert model selection.\n\t\tthis.listenTo( doc, 'change', () => {\n\t\t\tthis.view.change( writer => {\n\t\t\t\tthis.downcastDispatcher.convertChanges( doc.differ, writer );\n\t\t\t\tthis.downcastDispatcher.convertSelection( selection, markers, writer );\n\t\t\t} );\n\t\t}, { priority: 'low' } );\n\n\t\t// Convert selection from the view to the model when it changes in the view.\n\t\tthis.listenTo( this.view.document, 'selectionChange', convertSelectionChange( this.model, this.mapper ) );\n\n\t\t// Attach default model converters.\n\t\tthis.downcastDispatcher.on( 'insert:$text', insertText(), { priority: 'lowest' } );\n\t\tthis.downcastDispatcher.on( 'remove', remove(), { priority: 'low' } );\n\n\t\t// Attach default model selection converters.\n\t\tthis.downcastDispatcher.on( 'selection', clearAttributes(), { priority: 'low' } );\n\t\tthis.downcastDispatcher.on( 'selection', convertRangeSelection(), { priority: 'low' } );\n\t\tthis.downcastDispatcher.on( 'selection', convertCollapsedSelection(), { priority: 'low' } );\n\n\t\t// Binds {@link module:engine/view/document~Document#roots view roots collection} to\n\t\t// {@link module:engine/model/document~Document#roots model roots collection} so creating\n\t\t// model root automatically creates corresponding view root.\n\t\tthis.view.document.roots.bindTo( this.model.document.roots ).using( root => {\n\t\t\t// $graveyard is a special root that has no reflection in the view.\n\t\t\tif ( root.rootName == '$graveyard' ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst viewRoot = new RootEditableElement( root.name );\n\n\t\t\tviewRoot.rootName = root.rootName;\n\t\t\tviewRoot._document = this.view.document;\n\t\t\tthis.mapper.bindElements( root, viewRoot );\n\n\t\t\treturn viewRoot;\n\t\t} );\n\t}\n\n\t/**\n\t * Removes all event listeners attached to the `EditingController`. Destroys all objects created\n\t * by `EditingController` that need to be destroyed.\n\t */\n\tdestroy() {\n\t\tthis.view.destroy();\n\t\tthis.stopListening();\n\t}\n}\n\nmix( EditingController, ObservableMixin );\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugincollection\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\n\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * Manages a list of CKEditor plugins, including loading, resolving dependencies and initialization.\n *\n * @mixes module:utils/emittermixin~EmitterMixin\n */\nexport default class PluginCollection {\n\t/**\n\t * Creates an instance of the PluginCollection class.\n\t * Allows loading and initializing plugins and their dependencies.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor\n\t * @param {Array.<Function>} [availablePlugins] Plugins (constructors) which the collection will be able to use\n\t * when {@link module:core/plugincollection~PluginCollection#init} is used with plugin names (strings, instead of constructors).\n\t * Usually, the editor will pass its built-in plugins to the collection so they can later be\n\t * used in `config.plugins` or `config.removePlugins` by names.\n\t */\n\tconstructor( editor, availablePlugins = [] ) {\n\t\t/**\n\t\t * @protected\n\t\t * @member {module:core/editor/editor~Editor} module:core/plugin~PluginCollection#_editor\n\t\t */\n\t\tthis._editor = editor;\n\n\t\t/**\n\t\t * Map of plugin constructors which can be retrieved by their names.\n\t\t *\n\t\t * @protected\n\t\t * @member {Map.<String|Function,Function>} module:core/plugin~PluginCollection#_availablePlugins\n\t\t */\n\t\tthis._availablePlugins = new Map();\n\n\t\t/**\n\t\t * @protected\n\t\t * @member {Map} module:core/plugin~PluginCollection#_plugins\n\t\t */\n\t\tthis._plugins = new Map();\n\n\t\tfor ( const PluginConstructor of availablePlugins ) {\n\t\t\tthis._availablePlugins.set( PluginConstructor, PluginConstructor );\n\n\t\t\tif ( PluginConstructor.pluginName ) {\n\t\t\t\tthis._availablePlugins.set( PluginConstructor.pluginName, PluginConstructor );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * Returns `[ PluginConstructor, pluginInstance ]` pairs.\n\t *\n\t * @returns {Iterable.<Array>}\n\t */\n\t* [ Symbol.iterator ]() {\n\t\tfor ( const entry of this._plugins ) {\n\t\t\tif ( typeof entry[ 0 ] == 'function' ) {\n\t\t\t\tyield entry;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets the plugin instance by its constructor or name.\n\t *\n\t *\t\t// Check if 'Clipboard' plugin was loaded.\n\t *\t\tif ( editor.plugins.has( 'Clipboard' ) ) {\n\t *\t\t\t// Get clipboard plugin instance\n\t *\t\t\tconst clipboard = editor.plugins.get( 'Clipboard' );\n\t *\n\t *\t\t\tthis.listenTo( clipboard, 'inputTransformation', ( evt, data ) => {\n\t *\t\t\t\t// Do something on clipboard input.\n\t *\t\t\t} );\n\t *\t\t}\n\t *\n\t * **Note**: This method will throw error if plugin is not loaded. Use `{@link #has editor.plugins.has()}`\n\t * to check if plugin is available.\n\t *\n\t * @param {Function|String} key The plugin constructor or {@link module:core/plugin~PluginInterface.pluginName name}.\n\t * @returns {module:core/plugin~PluginInterface}\n\t */\n\tget( key ) {\n\t\tconst plugin = this._plugins.get( key );\n\n\t\tif ( !plugin ) {\n\t\t\t/**\n\t\t\t * The plugin is not loaded and could not be obtained.\n\t\t\t *\n\t\t\t * Plugin classes (constructors) need to be provided to the editor and must be loaded before they can be obtained from\n\t\t\t * the plugin collection.\n\t\t\t * This is usually done in CKEditor 5 builds by setting the {@link module:core/editor/editor~Editor.builtinPlugins}\n\t\t\t * property.\n\t\t\t *\n\t\t\t * **Note**: You can use `{@link module:core/plugincollection~PluginCollection#has editor.plugins.has()}`\n\t\t\t * to check if plugin was loaded.\n\t\t\t *\n\t\t\t * @error plugincollection-plugin-not-loaded\n\t\t\t * @param {String} plugin The name of the plugin which is not loaded.\n\t\t\t */\n\t\t\tconst errorMsg = 'plugincollection-plugin-not-loaded: The requested plugin is not loaded.';\n\n\t\t\tlet pluginName = key;\n\n\t\t\tif ( typeof key == 'function' ) {\n\t\t\t\tpluginName = key.pluginName || key.name;\n\t\t\t}\n\n\t\t\tthrow new CKEditorError( errorMsg, { plugin: pluginName } );\n\t\t}\n\n\t\treturn plugin;\n\t}\n\n\t/**\n\t * Checks if plugin is loaded.\n\t *\n\t *\t\t// Check if 'Clipboard' plugin was loaded.\n\t *\t\tif ( editor.plugins.has( 'Clipboard' ) ) {\n\t *\t\t\t// Now use clipboard plugin instance:\n\t *\t\t\tconst clipboard = editor.plugins.get( 'Clipboard' );\n\t *\n\t *\t\t\t// ...\n\t *\t\t}\n\t *\n\t * @param {Function|String} key The plugin constructor or {@link module:core/plugin~PluginInterface.pluginName name}.\n\t * @returns {Boolean}\n\t */\n\thas( key ) {\n\t\treturn this._plugins.has( key );\n\t}\n\n\t/**\n\t * Initializes a set of plugins and adds them to the collection.\n\t *\n\t * @param {Array.<Function|String>} plugins An array of {@link module:core/plugin~PluginInterface plugin constructors}\n\t * or {@link module:core/plugin~PluginInterface.pluginName plugin names}. The second option (names) works only if\n\t * `availablePlugins` were passed to the {@link #constructor}.\n\t * @param {Array.<String|Function>} [removePlugins] Names of plugins or plugin constructors\n\t * that should not be loaded (despite being specified in the `plugins` array).\n\t * @returns {Promise.<module:core/plugin~LoadedPlugins>} A promise which gets resolved once all plugins are loaded\n\t * and available in the collection.\n\t */\n\tinit( plugins, removePlugins = [] ) {\n\t\tconst that = this;\n\t\tconst editor = this._editor;\n\t\tconst loading = new Set();\n\t\tconst loaded = [];\n\n\t\tconst pluginConstructors = mapToAvailableConstructors( plugins );\n\t\tconst removePluginConstructors = mapToAvailableConstructors( removePlugins );\n\t\tconst missingPlugins = getMissingPluginNames( plugins );\n\n\t\tif ( missingPlugins ) {\n\t\t\t/**\n\t\t\t * Some plugins are not available and could not be loaded.\n\t\t\t *\n\t\t\t * Plugin classes (constructors) need to be provided to the editor before they can be loaded by name.\n\t\t\t * This is usually done in CKEditor 5 builds by setting the {@link module:core/editor/editor~Editor.builtinPlugins}\n\t\t\t * property.\n\t\t\t *\n\t\t\t * **If you see this warning when using one of the {@glink builds/index CKEditor 5 Builds}**, it means\n\t\t\t * that you try to enable a plugin which was not included in that build. This may be due to a typo\n\t\t\t * in the plugin name or simply because that plugin is not a part of this build. In the latter scenario,\n\t\t\t * read more about {@glink builds/guides/development/custom-builds custom builds}.\n\t\t\t *\n\t\t\t * **If you see this warning when using one of the editor creators directly** (not a build), then it means\n\t\t\t * that you tried loading plugins by name. However, unlike CKEditor 4, CKEditor 5 does not implement a \"plugin loader\".\n\t\t\t * This means that CKEditor 5 does not know where to load the plugin modules from. Therefore, you need to\n\t\t\t * provide each plugin through reference (as a constructor function). Check out the examples in\n\t\t\t * {@glink builds/guides/integration/advanced-setup#scenario-2-building-from-source \"Building from source\"}.\n\t\t\t *\n\t\t\t * @error plugincollection-plugin-not-found\n\t\t\t * @param {Array.<String>} plugins The name of the plugins which could not be loaded.\n\t\t\t */\n\t\t\tconst errorMsg = 'plugincollection-plugin-not-found: Some plugins are not available and could not be loaded.';\n\n\t\t\t// Log the error so it's more visible on the console. Hopefully, for better DX.\n\t\t\tlog.error( errorMsg, { plugins: missingPlugins } );\n\n\t\t\treturn Promise.reject( new CKEditorError( errorMsg, { plugins: missingPlugins } ) );\n\t\t}\n\n\t\treturn Promise.all( pluginConstructors.map( loadPlugin ) )\n\t\t\t.then( () => initPlugins( loaded, 'init' ) )\n\t\t\t.then( () => initPlugins( loaded, 'afterInit' ) )\n\t\t\t.then( () => loaded );\n\n\t\tfunction loadPlugin( PluginConstructor ) {\n\t\t\tif ( removePluginConstructors.includes( PluginConstructor ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// The plugin is already loaded or being loaded - do nothing.\n\t\t\tif ( that._plugins.has( PluginConstructor ) || loading.has( PluginConstructor ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\treturn instantiatePlugin( PluginConstructor )\n\t\t\t\t.catch( err => {\n\t\t\t\t\t/**\n\t\t\t\t\t * It was not possible to load the plugin.\n\t\t\t\t\t *\n\t\t\t\t\t * This is a generic error logged to the console when a JavaSript error is thrown during the initialization\n\t\t\t\t\t * of one of the plugins.\n\t\t\t\t\t *\n\t\t\t\t\t * If you correctly handled the promise returned by the editor's `create()` method (like shown below)\n\t\t\t\t\t * you will find the original error logged to the console, too:\n\t\t\t\t\t *\n\t\t\t\t\t *\t\tClassicEditor.create( document.getElementById( 'editor' ) )\n\t\t\t\t\t *\t\t\t.then( editor => {\n\t\t\t\t\t *\t\t\t\t// ...\n\t\t\t\t\t * \t\t\t} )\n\t\t\t\t\t *\t\t\t.catch( error => {\n\t\t\t\t\t *\t\t\t\tconsole.error( error );\n\t\t\t\t\t *\t\t\t} );\n\t\t\t\t\t *\n\t\t\t\t\t * @error plugincollection-load\n\t\t\t\t\t * @param {String} plugin The name of the plugin that could not be loaded.\n\t\t\t\t\t */\n\t\t\t\t\tlog.error( 'plugincollection-load: It was not possible to load the plugin.', { plugin: PluginConstructor } );\n\n\t\t\t\t\tthrow err;\n\t\t\t\t} );\n\t\t}\n\n\t\tfunction initPlugins( loadedPlugins, method ) {\n\t\t\treturn loadedPlugins.reduce( ( promise, plugin ) => {\n\t\t\t\tif ( !plugin[ method ] ) {\n\t\t\t\t\treturn promise;\n\t\t\t\t}\n\n\t\t\t\treturn promise.then( plugin[ method ].bind( plugin ) );\n\t\t\t}, Promise.resolve() );\n\t\t}\n\n\t\tfunction instantiatePlugin( PluginConstructor ) {\n\t\t\treturn new Promise( resolve => {\n\t\t\t\tloading.add( PluginConstructor );\n\n\t\t\t\tif ( PluginConstructor.requires ) {\n\t\t\t\t\tPluginConstructor.requires.forEach( RequiredPluginConstructorOrName => {\n\t\t\t\t\t\tconst RequiredPluginConstructor = getPluginConstructor( RequiredPluginConstructorOrName );\n\n\t\t\t\t\t\tif ( removePlugins.includes( RequiredPluginConstructor ) ) {\n\t\t\t\t\t\t\t/**\n\t\t\t\t\t\t\t * Cannot load a plugin because one of its dependencies is listed in the `removePlugins` option.\n\t\t\t\t\t\t\t *\n\t\t\t\t\t\t\t * @error plugincollection-required\n\t\t\t\t\t\t\t * @param {Function} plugin The required plugin.\n\t\t\t\t\t\t\t * @param {Function} requiredBy The parent plugin.\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t\t\t\t'plugincollection-required: Cannot load a plugin because one of its dependencies is listed in' +\n\t\t\t\t\t\t\t\t'the `removePlugins` option.',\n\t\t\t\t\t\t\t\t{ plugin: RequiredPluginConstructor, requiredBy: PluginConstructor }\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tloadPlugin( RequiredPluginConstructor );\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\tconst plugin = new PluginConstructor( editor );\n\t\t\t\tthat._add( PluginConstructor, plugin );\n\t\t\t\tloaded.push( plugin );\n\n\t\t\t\tresolve();\n\t\t\t} );\n\t\t}\n\n\t\tfunction getPluginConstructor( PluginConstructorOrName ) {\n\t\t\tif ( typeof PluginConstructorOrName == 'function' ) {\n\t\t\t\treturn PluginConstructorOrName;\n\t\t\t}\n\n\t\t\treturn that._availablePlugins.get( PluginConstructorOrName );\n\t\t}\n\n\t\tfunction getMissingPluginNames( plugins ) {\n\t\t\tconst missingPlugins = [];\n\n\t\t\tfor ( const pluginNameOrConstructor of plugins ) {\n\t\t\t\tif ( !getPluginConstructor( pluginNameOrConstructor ) ) {\n\t\t\t\t\tmissingPlugins.push( pluginNameOrConstructor );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn missingPlugins.length ? missingPlugins : null;\n\t\t}\n\n\t\tfunction mapToAvailableConstructors( plugins ) {\n\t\t\treturn plugins\n\t\t\t\t.map( pluginNameOrConstructor => getPluginConstructor( pluginNameOrConstructor ) )\n\t\t\t\t.filter( PluginConstructor => !!PluginConstructor );\n\t\t}\n\t}\n\n\t/**\n\t * Destroys all loaded plugins.\n\t *\n\t * @returns {Promise}\n\t */\n\tdestroy() {\n\t\tconst promises = Array.from( this )\n\t\t\t.map( ( [ , pluginInstance ] ) => pluginInstance )\n\t\t\t.filter( pluginInstance => typeof pluginInstance.destroy == 'function' )\n\t\t\t.map( pluginInstance => pluginInstance.destroy() );\n\n\t\treturn Promise.all( promises );\n\t}\n\n\t/**\n\t * Adds the plugin to the collection. Exposed mainly for testing purposes.\n\t *\n\t * @protected\n\t * @param {Function} PluginConstructor The plugin constructor.\n\t * @param {module:core/plugin~PluginInterface} plugin The instance of the plugin.\n\t */\n\t_add( PluginConstructor, plugin ) {\n\t\tthis._plugins.set( PluginConstructor, plugin );\n\n\t\tconst pluginName = PluginConstructor.pluginName;\n\n\t\tif ( !pluginName ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this._plugins.has( pluginName ) ) {\n\t\t\t/**\n\t\t\t * Two plugins with the same {@link module:core/plugin~PluginInterface.pluginName} were loaded.\n\t\t\t * This will lead to runtime conflicts between these plugins.\n\t\t\t *\n\t\t\t * In practice, this warning usually means that new plugins were added to an existing CKEditor 5 build.\n\t\t\t * Plugins should always be added to a source version of the editor (`@ckeditor/ckeditor5-editor-*`),\n\t\t\t * not to an editor imported from one of the `@ckeditor/ckeditor5-build-*` packages.\n\t\t\t *\n\t\t\t * Check your import paths and the list of plugins passed to\n\t\t\t * {@link module:core/editor/editor~Editor.create `Editor.create()`}\n\t\t\t * or specified in {@link module:core/editor/editor~Editor.builtinPlugins `Editor.builtinPlugins`}.\n\t\t\t *\n\t\t\t * The second option is that your `node_modules/` directory contains duplicated versions of the same\n\t\t\t * CKEditor 5 packages. Normally, on clean installations, npm deduplicates packages in `node_modules/`, so\n\t\t\t * it may be enough to call `rm -rf node_modules && npm i`. However, if you installed conflicting versions\n\t\t\t * of packages, their dependencies may need to be installed in more than one version which may lead to this\n\t\t\t * warning.\n\t\t\t *\n\t\t\t * Technically speaking, this error occurs because after adding a plugin to an existing editor build\n\t\t\t * dependencies of this plugin are being duplicated.\n\t\t\t * They are already built into that editor build and now get added for the second time as dependencies\n\t\t\t * of the plugin you are installing.\n\t\t\t *\n\t\t\t * Read more about {@glink builds/guides/integration/installing-plugins installing plugins}.\n\t\t\t *\n\t\t\t * @error plugincollection-plugin-name-conflict\n\t\t\t * @param {String} pluginName The duplicated plugin name.\n\t\t\t * @param {Function} plugin1 The first plugin constructor.\n\t\t\t * @param {Function} plugin2 The second plugin constructor.\n\t\t\t */\n\t\t\tlog.warn(\n\t\t\t\t'plugincollection-plugin-name-conflict: Two plugins with the same name were loaded.',\n\t\t\t\t{ pluginName, plugin1: this._plugins.get( pluginName ).constructor, plugin2: PluginConstructor }\n\t\t\t);\n\t\t} else {\n\t\t\tthis._plugins.set( pluginName, plugin );\n\t\t}\n\t}\n}\n\nmix( PluginCollection, EmitterMixin );\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/commandcollection\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Collection of commands. Its instance is available in {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n */\nexport default class CommandCollection {\n\t/**\n\t * Creates collection instance.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Command map.\n\t\t *\n\t\t * @private\n\t\t * @member {Map}\n\t\t */\n\t\tthis._commands = new Map();\n\t}\n\n\t/**\n\t * Registers a new command.\n\t *\n\t * @param {String} commandName The name of the command.\n\t * @param {module:core/command~Command} command\n\t */\n\tadd( commandName, command ) {\n\t\tthis._commands.set( commandName, command );\n\t}\n\n\t/**\n\t * Retrieves a command from the collection.\n\t *\n\t * @param {String} commandName The name of the command.\n\t * @returns {module:core/command~Command}\n\t */\n\tget( commandName ) {\n\t\treturn this._commands.get( commandName );\n\t}\n\n\t/**\n\t * Executes a command.\n\t *\n\t * @param {String} commandName The name of the command.\n\t * @param {*} [...commandParams] Command parameters.\n\t */\n\texecute( commandName, ...args ) {\n\t\tconst command = this.get( commandName );\n\n\t\tif ( !command ) {\n\t\t\t/**\n\t\t\t * Command does not exist.\n\t\t\t *\n\t\t\t * @error commandcollection-command-not-found\n\t\t\t * @param {String} commandName Name of the command.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'commandcollection-command-not-found: Command does not exist.', { commandName } );\n\t\t}\n\n\t\tcommand.execute( ...args );\n\t}\n\n\t/**\n\t * Returns iterator of command names.\n\t *\n\t * @returns {Iterable.<String>}\n\t */\n\t* names() {\n\t\tyield* this._commands.keys();\n\t}\n\n\t/**\n\t * Returns iterator of command instances.\n\t *\n\t * @returns {Iterable.<module:core/command~Command>}\n\t */\n\t* commands() {\n\t\tyield* this._commands.values();\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * Returns `[ commandName, commandInstance ]` pairs.\n\t *\n\t * @returns {Iterable.<Array>}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this._commands[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Destroys all collection commands.\n\t */\n\tdestroy() {\n\t\tfor ( const command of this.commands() ) {\n\t\t\tcommand.destroy();\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* globals window */\n\n/**\n * @module utils/translation-service\n */\n\n/* istanbul ignore else */\nif ( !window.CKEDITOR_TRANSLATIONS ) {\n\twindow.CKEDITOR_TRANSLATIONS = {};\n}\n\n/**\n * Adds translations to existing ones.\n * These translations will later be available for the {@link module:utils/translation-service~translate `translate()`} function.\n *\n *\t\tadd( 'pl', {\n *\t\t\t'OK': 'OK',\n *\t\t\t'Cancel [context: reject]': 'Anuluj'\n *\t\t} );\n *\n * If you cannot import this function from this module (e.g. because you use a CKEditor 5 build), then you can\n * still add translations by extending the global `window.CKEDITOR_TRANSLATIONS` object by using a function like\n * the one below:\n *\n *\t\tfunction addTranslations( language, translations ) {\n *\t\t\tif ( !window.CKEDITOR_TRANSLATIONS ) {\n *\t\t\t\twindow.CKEDITOR_TRANSLATIONS = {};\n *\t\t\t}\n *\n *\t\t\tconst dictionary = window.CKEDITOR_TRANSLATIONS[ language ] || ( window.CKEDITOR_TRANSLATIONS[ language ] = {} );\n *\n *\t\t\t// Extend the dictionary for the given language.\n *\t\t\tObject.assign( dictionary, translations );\n *\t\t}\n *\n * @param {String} language Target language.\n * @param {Object.<String, String>} translations Translations which will be added to the dictionary.\n */\nexport function add( language, translations ) {\n\tconst dictionary = window.CKEDITOR_TRANSLATIONS[ language ] || ( window.CKEDITOR_TRANSLATIONS[ language ] = {} );\n\n\tObject.assign( dictionary, translations );\n}\n\n/**\n * Translates string if the translation of the string was previously added to the dictionary.\n * See {@link module:utils/translation-service Translation Service}.\n * This happens in a multi-language mode were translation modules are created by the bundler.\n *\n * When no translation is defined in the dictionary or the dictionary doesn't exist this function returns\n * the original string without the `'[context: ]'` (happens in development and single-language modes).\n *\n * In a single-language mode (when values passed to `t()` were replaced with target language strings) the dictionary\n * is left empty, so this function will return the original strings always.\n *\n *\t\ttranslate( 'pl', 'Cancel [context: reject]' );\n *\n * @param {String} language Target language.\n * @param {String} translationKey String that will be translated.\n * @returns {String} Translated sentence.\n */\nexport function translate( language, translationKey ) {\n\tconst numberOfLanguages = getNumberOfLanguages();\n\n\tif ( numberOfLanguages === 1 ) {\n\t\t// Override the language to the only supported one.\n\t\t// This can't be done in the `Locale` class, because the translations comes after the `Locale` class initialization.\n\t\tlanguage = Object.keys( window.CKEDITOR_TRANSLATIONS )[ 0 ];\n\t}\n\n\tif ( numberOfLanguages === 0 || !hasTranslation( language, translationKey ) ) {\n\t\treturn translationKey.replace( / \\[context: [^\\]]+\\]$/, '' );\n\t}\n\n\tconst dictionary = window.CKEDITOR_TRANSLATIONS[ language ];\n\n\t// In case of missing translations we still need to cut off the `[context: ]` parts.\n\treturn dictionary[ translationKey ].replace( / \\[context: [^\\]]+\\]$/, '' );\n}\n\n/**\n * Clears dictionaries for test purposes.\n *\n * @protected\n */\nexport function _clear() {\n\twindow.CKEDITOR_TRANSLATIONS = {};\n}\n\n// Checks whether the dictionary exists and translation in that dictionary exists.\nfunction hasTranslation( language, translationKey ) {\n\treturn (\n\t\t( language in window.CKEDITOR_TRANSLATIONS ) &&\n\t\t( translationKey in window.CKEDITOR_TRANSLATIONS[ language ] )\n\t);\n}\n\nfunction getNumberOfLanguages() {\n\treturn Object.keys( window.CKEDITOR_TRANSLATIONS ).length;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/locale\n */\n\nimport { translate } from './translation-service';\n\n/**\n * Represents the localization services.\n */\nexport default class Locale {\n\t/**\n\t * Creates a new instance of the Locale class.\n\t *\n\t * @param {String} [language='en'] The language code in [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format.\n\t */\n\tconstructor( language ) {\n\t\t/**\n\t\t * The language code in [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.language = language || 'en';\n\n\t\t/**\n\t\t * Translates the given string to the {@link #language}. This method is also available in {@link module:core/editor/editor~Editor#t}\n\t\t * and {@link module:ui/view~View#t}.\n\t\t *\n\t\t * The strings may contain placeholders (`%<index>`) for values which are passed as the second argument.\n\t\t * `<index>` is the index in the `values` array.\n\t\t *\n\t\t *\t\teditor.t( 'Created file \"%0\" in %1ms.', [ fileName, timeTaken ] );\n\t\t *\n\t\t * This method's context is statically bound to Locale instance,\n\t\t * so it can be called as a function:\n\t\t *\n\t\t *\t\tconst t = this.t;\n\t\t *\t\tt( 'Label' );\n\t\t *\n\t\t * @method #t\n\t\t * @param {String} str The string to translate.\n\t\t * @param {String[]} [values] Values that should be used to interpolate the string.\n\t\t */\n\t\tthis.t = ( ...args ) => this._t( ...args );\n\t}\n\n\t/**\n\t * Base for the {@link #t} method.\n\t *\n\t * @private\n\t */\n\t_t( str, values ) {\n\t\tlet translatedString = translate( this.language, str );\n\n\t\tif ( values ) {\n\t\t\ttranslatedString = translatedString.replace( /%(\\d+)/g, ( match, index ) => {\n\t\t\t\treturn ( index < values.length ) ? values[ index ] : match;\n\t\t\t} );\n\t\t}\n\n\t\treturn translatedString;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/conversion/viewconsumable\n */\n\nimport { isArray } from 'lodash-es';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Class used for handling consumption of view {@link module:engine/view/element~Element elements},\n * {@link module:engine/view/text~Text text nodes} and {@link module:engine/view/documentfragment~DocumentFragment document fragments}.\n * Element's name and its parts (attributes, classes and styles) can be consumed separately. Consuming an element's name\n * does not consume its attributes, classes and styles.\n * To add items for consumption use {@link module:engine/conversion/viewconsumable~ViewConsumable#add add method}.\n * To test items use {@link module:engine/conversion/viewconsumable~ViewConsumable#test test method}.\n * To consume items use {@link module:engine/conversion/viewconsumable~ViewConsumable#consume consume method}.\n * To revert already consumed items use {@link module:engine/conversion/viewconsumable~ViewConsumable#revert revert method}.\n *\n *\t\tviewConsumable.add( element, { name: true } ); // Adds element's name as ready to be consumed.\n *\t\tviewConsumable.add( textNode ); // Adds text node for consumption.\n *\t\tviewConsumable.add( docFragment ); // Adds document fragment for consumption.\n *\t\tviewConsumable.test( element, { name: true } ); // Tests if element's name can be consumed.\n *\t\tviewConsumable.test( textNode ); // Tests if text node can be consumed.\n *\t\tviewConsumable.test( docFragment ); // Tests if document fragment can be consumed.\n *\t\tviewConsumable.consume( element, { name: true } ); // Consume element's name.\n *\t\tviewConsumable.consume( textNode ); // Consume text node.\n *\t\tviewConsumable.consume( docFragment ); // Consume document fragment.\n *\t\tviewConsumable.revert( element, { name: true } ); // Revert already consumed element's name.\n *\t\tviewConsumable.revert( textNode ); // Revert already consumed text node.\n *\t\tviewConsumable.revert( docFragment ); // Revert already consumed document fragment.\n */\nexport default class ViewConsumable {\n\t/**\n\t * Creates new ViewConsumable.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Map of consumable elements. If {@link module:engine/view/element~Element element} is used as a key,\n\t\t * {@link module:engine/conversion/viewconsumable~ViewElementConsumables ViewElementConsumables} instance is stored as value.\n\t\t * For {@link module:engine/view/text~Text text nodes} and\n\t\t * {@link module:engine/view/documentfragment~DocumentFragment document fragments} boolean value is stored as value.\n\t\t *\n\t\t * @protected\n\t\t * @member {Map.<module:engine/conversion/viewconsumable~ViewElementConsumables|Boolean>}\n\t\t*/\n\t\tthis._consumables = new Map();\n\t}\n\n\t/**\n\t * Adds {@link module:engine/view/element~Element view element}, {@link module:engine/view/text~Text text node} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragment} as ready to be consumed.\n\t *\n\t *\t\tviewConsumable.add( p, { name: true } ); // Adds element's name to consume.\n\t *\t\tviewConsumable.add( p, { attributes: 'name' } ); // Adds element's attribute.\n\t *\t\tviewConsumable.add( p, { classes: 'foobar' } ); // Adds element's class.\n\t *\t\tviewConsumable.add( p, { styles: 'color' } ); // Adds element's style\n\t *\t\tviewConsumable.add( p, { attributes: 'name', styles: 'color' } ); // Adds attribute and style.\n\t *\t\tviewConsumable.add( p, { classes: [ 'baz', 'bar' ] } ); // Multiple consumables can be provided.\n\t *\t\tviewConsumable.add( textNode ); // Adds text node to consume.\n\t *\t\tviewConsumable.add( docFragment ); // Adds document fragment to consume.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `viewconsumable-invalid-attribute` when `class` or `style`\n\t * attribute is provided - it should be handled separately by providing actual style/class.\n\t *\n\t *\t\tviewConsumable.add( p, { attributes: 'style' } ); // This call will throw an exception.\n\t *\t\tviewConsumable.add( p, { styles: 'color' } ); // This is properly handled style.\n\t *\n\t * @param {module:engine/view/element~Element|module:engine/view/text~Text|module:engine/view/documentfragment~DocumentFragment} element\n\t * @param {Object} [consumables] Used only if first parameter is {@link module:engine/view/element~Element view element} instance.\n\t * @param {Boolean} consumables.name If set to true element's name will be included.\n\t * @param {String|Array.<String>} consumables.attributes Attribute name or array of attribute names.\n\t * @param {String|Array.<String>} consumables.classes Class name or array of class names.\n\t * @param {String|Array.<String>} consumables.styles Style name or array of style names.\n\t */\n\tadd( element, consumables ) {\n\t\tlet elementConsumables;\n\n\t\t// For text nodes and document fragments just mark them as consumable.\n\t\tif ( element.is( 'text' ) || element.is( 'documentFragment' ) ) {\n\t\t\tthis._consumables.set( element, true );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// For elements create new ViewElementConsumables or update already existing one.\n\t\tif ( !this._consumables.has( element ) ) {\n\t\t\telementConsumables = new ViewElementConsumables();\n\t\t\tthis._consumables.set( element, elementConsumables );\n\t\t} else {\n\t\t\telementConsumables = this._consumables.get( element );\n\t\t}\n\n\t\telementConsumables.add( consumables );\n\t}\n\n\t/**\n\t * Tests if {@link module:engine/view/element~Element view element}, {@link module:engine/view/text~Text text node} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragment} can be consumed.\n\t * It returns `true` when all items included in method's call can be consumed. Returns `false` when\n\t * first already consumed item is found and `null` when first non-consumable item is found.\n\t *\n\t *\t\tviewConsumable.test( p, { name: true } ); // Tests element's name.\n\t *\t\tviewConsumable.test( p, { attributes: 'name' } ); // Tests attribute.\n\t *\t\tviewConsumable.test( p, { classes: 'foobar' } ); // Tests class.\n\t *\t\tviewConsumable.test( p, { styles: 'color' } ); // Tests style.\n\t *\t\tviewConsumable.test( p, { attributes: 'name', styles: 'color' } ); // Tests attribute and style.\n\t *\t\tviewConsumable.test( p, { classes: [ 'baz', 'bar' ] } ); // Multiple consumables can be tested.\n\t *\t\tviewConsumable.test( textNode ); // Tests text node.\n\t *\t\tviewConsumable.test( docFragment ); // Tests document fragment.\n\t *\n\t * Testing classes and styles as attribute will test if all added classes/styles can be consumed.\n\t *\n\t *\t\tviewConsumable.test( p, { attributes: 'class' } ); // Tests if all added classes can be consumed.\n\t *\t\tviewConsumable.test( p, { attributes: 'style' } ); // Tests if all added styles can be consumed.\n\t *\n\t * @param {module:engine/view/element~Element|module:engine/view/text~Text|module:engine/view/documentfragment~DocumentFragment} element\n\t * @param {Object} [consumables] Used only if first parameter is {@link module:engine/view/element~Element view element} instance.\n\t * @param {Boolean} consumables.name If set to true element's name will be included.\n\t * @param {String|Array.<String>} consumables.attributes Attribute name or array of attribute names.\n\t * @param {String|Array.<String>} consumables.classes Class name or array of class names.\n\t * @param {String|Array.<String>} consumables.styles Style name or array of style names.\n\t * @returns {Boolean|null} Returns `true` when all items included in method's call can be consumed. Returns `false`\n\t * when first already consumed item is found and `null` when first non-consumable item is found.\n\t */\n\ttest( element, consumables ) {\n\t\tconst elementConsumables = this._consumables.get( element );\n\n\t\tif ( elementConsumables === undefined ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// For text nodes and document fragments return stored boolean value.\n\t\tif ( element.is( 'text' ) || element.is( 'documentFragment' ) ) {\n\t\t\treturn elementConsumables;\n\t\t}\n\n\t\t// For elements test consumables object.\n\t\treturn elementConsumables.test( consumables );\n\t}\n\n\t/**\n\t * Consumes {@link module:engine/view/element~Element view element}, {@link module:engine/view/text~Text text node} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragment}.\n\t * It returns `true` when all items included in method's call can be consumed, otherwise returns `false`.\n\t *\n\t *\t\tviewConsumable.consume( p, { name: true } ); // Consumes element's name.\n\t *\t\tviewConsumable.consume( p, { attributes: 'name' } ); // Consumes element's attribute.\n\t *\t\tviewConsumable.consume( p, { classes: 'foobar' } ); // Consumes element's class.\n\t *\t\tviewConsumable.consume( p, { styles: 'color' } ); // Consumes element's style.\n\t *\t\tviewConsumable.consume( p, { attributes: 'name', styles: 'color' } ); // Consumes attribute and style.\n\t *\t\tviewConsumable.consume( p, { classes: [ 'baz', 'bar' ] } ); // Multiple consumables can be consumed.\n\t *\t\tviewConsumable.consume( textNode ); // Consumes text node.\n\t *\t\tviewConsumable.consume( docFragment ); // Consumes document fragment.\n\t *\n\t * Consuming classes and styles as attribute will test if all added classes/styles can be consumed.\n\t *\n\t *\t\tviewConsumable.consume( p, { attributes: 'class' } ); // Consume only if all added classes can be consumed.\n\t *\t\tviewConsumable.consume( p, { attributes: 'style' } ); // Consume only if all added styles can be consumed.\n\t *\n\t * @param {module:engine/view/element~Element|module:engine/view/text~Text|module:engine/view/documentfragment~DocumentFragment} element\n\t * @param {Object} [consumables] Used only if first parameter is {@link module:engine/view/element~Element view element} instance.\n\t * @param {Boolean} consumables.name If set to true element's name will be included.\n\t * @param {String|Array.<String>} consumables.attributes Attribute name or array of attribute names.\n\t * @param {String|Array.<String>} consumables.classes Class name or array of class names.\n\t * @param {String|Array.<String>} consumables.styles Style name or array of style names.\n\t * @returns {Boolean} Returns `true` when all items included in method's call can be consumed,\n\t * otherwise returns `false`.\n\t */\n\tconsume( element, consumables ) {\n\t\tif ( this.test( element, consumables ) ) {\n\t\t\tif ( element.is( 'text' ) || element.is( 'documentFragment' ) ) {\n\t\t\t\t// For text nodes and document fragments set value to false.\n\t\t\t\tthis._consumables.set( element, false );\n\t\t\t} else {\n\t\t\t\t// For elements - consume consumables object.\n\t\t\t\tthis._consumables.get( element ).consume( consumables );\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Reverts {@link module:engine/view/element~Element view element}, {@link module:engine/view/text~Text text node} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragment} so they can be consumed once again.\n\t * Method does not revert items that were never previously added for consumption, even if they are included in\n\t * method's call.\n\t *\n\t *\t\tviewConsumable.revert( p, { name: true } ); // Reverts element's name.\n\t *\t\tviewConsumable.revert( p, { attributes: 'name' } ); // Reverts element's attribute.\n\t *\t\tviewConsumable.revert( p, { classes: 'foobar' } ); // Reverts element's class.\n\t *\t\tviewConsumable.revert( p, { styles: 'color' } ); // Reverts element's style.\n\t *\t\tviewConsumable.revert( p, { attributes: 'name', styles: 'color' } ); // Reverts attribute and style.\n\t *\t\tviewConsumable.revert( p, { classes: [ 'baz', 'bar' ] } ); // Multiple names can be reverted.\n\t *\t\tviewConsumable.revert( textNode ); // Reverts text node.\n\t *\t\tviewConsumable.revert( docFragment ); // Reverts document fragment.\n\t *\n\t * Reverting classes and styles as attribute will revert all classes/styles that were previously added for\n\t * consumption.\n\t *\n\t *\t\tviewConsumable.revert( p, { attributes: 'class' } ); // Reverts all classes added for consumption.\n\t *\t\tviewConsumable.revert( p, { attributes: 'style' } ); // Reverts all styles added for consumption.\n\t *\n\t * @param {module:engine/view/element~Element|module:engine/view/text~Text|module:engine/view/documentfragment~DocumentFragment} element\n\t * @param {Object} [consumables] Used only if first parameter is {@link module:engine/view/element~Element view element} instance.\n\t * @param {Boolean} consumables.name If set to true element's name will be included.\n\t * @param {String|Array.<String>} consumables.attributes Attribute name or array of attribute names.\n\t * @param {String|Array.<String>} consumables.classes Class name or array of class names.\n\t * @param {String|Array.<String>} consumables.styles Style name or array of style names.\n\t */\n\trevert( element, consumables ) {\n\t\tconst elementConsumables = this._consumables.get( element );\n\n\t\tif ( elementConsumables !== undefined ) {\n\t\t\tif ( element.is( 'text' ) || element.is( 'documentFragment' ) ) {\n\t\t\t\t// For text nodes and document fragments - set consumable to true.\n\t\t\t\tthis._consumables.set( element, true );\n\t\t\t} else {\n\t\t\t\t// For elements - revert items from consumables object.\n\t\t\t\telementConsumables.revert( consumables );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Creates consumable object from {@link module:engine/view/element~Element view element}. Consumable object will include\n\t * element's name and all its attributes, classes and styles.\n\t *\n\t * @static\n\t * @param {module:engine/view/element~Element} element\n\t * @returns {Object} consumables\n\t */\n\tstatic consumablesFromElement( element ) {\n\t\tconst consumables = {\n\t\t\tname: true,\n\t\t\tattributes: [],\n\t\t\tclasses: [],\n\t\t\tstyles: []\n\t\t};\n\n\t\tconst attributes = element.getAttributeKeys();\n\n\t\tfor ( const attribute of attributes ) {\n\t\t\t// Skip classes and styles - will be added separately.\n\t\t\tif ( attribute == 'style' || attribute == 'class' ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconsumables.attributes.push( attribute );\n\t\t}\n\n\t\tconst classes = element.getClassNames();\n\n\t\tfor ( const className of classes ) {\n\t\t\tconsumables.classes.push( className );\n\t\t}\n\n\t\tconst styles = element.getStyleNames();\n\n\t\tfor ( const style of styles ) {\n\t\t\tconsumables.styles.push( style );\n\t\t}\n\n\t\treturn consumables;\n\t}\n\n\t/**\n\t * Creates {@link module:engine/conversion/viewconsumable~ViewConsumable ViewConsumable} instance from\n\t * {@link module:engine/view/node~Node node} or {@link module:engine/view/documentfragment~DocumentFragment document fragment}.\n\t * Instance will contain all elements, child nodes, attributes, styles and classes added for consumption.\n\t *\n\t * @static\n\t * @param {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment} from View node or document fragment\n\t * from which `ViewConsumable` will be created.\n\t * @param {module:engine/conversion/viewconsumable~ViewConsumable} [instance] If provided, given `ViewConsumable` instance will be used\n\t * to add all consumables. It will be returned instead of a new instance.\n\t */\n\tstatic createFrom( from, instance ) {\n\t\tif ( !instance ) {\n\t\t\tinstance = new ViewConsumable();\n\t\t}\n\n\t\tif ( from.is( 'text' ) ) {\n\t\t\tinstance.add( from );\n\n\t\t\treturn instance;\n\t\t}\n\n\t\t// Add `from` itself, if it is an element.\n\t\tif ( from.is( 'element' ) ) {\n\t\t\tinstance.add( from, ViewConsumable.consumablesFromElement( from ) );\n\t\t}\n\n\t\tif ( from.is( 'documentFragment' ) ) {\n\t\t\tinstance.add( from );\n\t\t}\n\n\t\tfor ( const child of from.getChildren() ) {\n\t\t\tinstance = ViewConsumable.createFrom( child, instance );\n\t\t}\n\n\t\treturn instance;\n\t}\n}\n\n/**\n * This is a private helper-class for {@link module:engine/conversion/viewconsumable~ViewConsumable}.\n * It represents and manipulates consumable parts of a single {@link module:engine/view/element~Element}.\n *\n * @private\n */\nclass ViewElementConsumables {\n\t/**\n\t * Creates ViewElementConsumables instance.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Flag indicating if name of the element can be consumed.\n\t\t *\n\t\t * @private\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis._canConsumeName = null;\n\n\t\t/**\n\t\t * Contains maps of element's consumables: attributes, classes and styles.\n\t\t *\n\t\t * @private\n\t\t * @member {Object}\n\t\t */\n\t\tthis._consumables = {\n\t\t\tattributes: new Map(),\n\t\t\tstyles: new Map(),\n\t\t\tclasses: new Map()\n\t\t};\n\t}\n\n\t/**\n\t * Adds consumable parts of the {@link module:engine/view/element~Element view element}.\n\t * Element's name itself can be marked to be consumed (when element's name is consumed its attributes, classes and\n\t * styles still could be consumed):\n\t *\n\t *\t\tconsumables.add( { name: true } );\n\t *\n\t * Attributes classes and styles:\n\t *\n\t *\t\tconsumables.add( { attributes: 'title', classes: 'foo', styles: 'color' } );\n\t *\t\tconsumables.add( { attributes: [ 'title', 'name' ], classes: [ 'foo', 'bar' ] );\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `viewconsumable-invalid-attribute` when `class` or `style`\n\t * attribute is provided - it should be handled separately by providing `style` and `class` in consumables object.\n\t *\n\t * @param {Object} consumables Object describing which parts of the element can be consumed.\n\t * @param {Boolean} consumables.name If set to `true` element's name will be added as consumable.\n\t * @param {String|Array.<String>} consumables.attributes Attribute name or array of attribute names to add as consumable.\n\t * @param {String|Array.<String>} consumables.classes Class name or array of class names to add as consumable.\n\t * @param {String|Array.<String>} consumables.styles Style name or array of style names to add as consumable.\n\t */\n\tadd( consumables ) {\n\t\tif ( consumables.name ) {\n\t\t\tthis._canConsumeName = true;\n\t\t}\n\n\t\tfor ( const type in this._consumables ) {\n\t\t\tif ( type in consumables ) {\n\t\t\t\tthis._add( type, consumables[ type ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Tests if parts of the {@link module:engine/view/node~Node view node} can be consumed.\n\t *\n\t * Element's name can be tested:\n\t *\n\t *\t\tconsumables.test( { name: true } );\n\t *\n\t * Attributes classes and styles:\n\t *\n\t *\t\tconsumables.test( { attributes: 'title', classes: 'foo', styles: 'color' } );\n\t *\t\tconsumables.test( { attributes: [ 'title', 'name' ], classes: [ 'foo', 'bar' ] );\n\t *\n\t * @param {Object} consumables Object describing which parts of the element should be tested.\n\t * @param {Boolean} consumables.name If set to `true` element's name will be tested.\n\t * @param {String|Array.<String>} consumables.attributes Attribute name or array of attribute names to test.\n\t * @param {String|Array.<String>} consumables.classes Class name or array of class names to test.\n\t * @param {String|Array.<String>} consumables.styles Style name or array of style names to test.\n\t * @returns {Boolean|null} `true` when all tested items can be consumed, `null` when even one of the items\n\t * was never marked for consumption and `false` when even one of the items was already consumed.\n\t */\n\ttest( consumables ) {\n\t\t// Check if name can be consumed.\n\t\tif ( consumables.name && !this._canConsumeName ) {\n\t\t\treturn this._canConsumeName;\n\t\t}\n\n\t\tfor ( const type in this._consumables ) {\n\t\t\tif ( type in consumables ) {\n\t\t\t\tconst value = this._test( type, consumables[ type ] );\n\n\t\t\t\tif ( value !== true ) {\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return true only if all can be consumed.\n\t\treturn true;\n\t}\n\n\t/**\n\t * Consumes parts of {@link module:engine/view/element~Element view element}. This function does not check if consumable item\n\t * is already consumed - it consumes all consumable items provided.\n\t * Element's name can be consumed:\n\t *\n\t *\t\tconsumables.consume( { name: true } );\n\t *\n\t * Attributes classes and styles:\n\t *\n\t *\t\tconsumables.consume( { attributes: 'title', classes: 'foo', styles: 'color' } );\n\t *\t\tconsumables.consume( { attributes: [ 'title', 'name' ], classes: [ 'foo', 'bar' ] );\n\t *\n\t * @param {Object} consumables Object describing which parts of the element should be consumed.\n\t * @param {Boolean} consumables.name If set to `true` element's name will be consumed.\n\t * @param {String|Array.<String>} consumables.attributes Attribute name or array of attribute names to consume.\n\t * @param {String|Array.<String>} consumables.classes Class name or array of class names to consume.\n\t * @param {String|Array.<String>} consumables.styles Style name or array of style names to consume.\n\t */\n\tconsume( consumables ) {\n\t\tif ( consumables.name ) {\n\t\t\tthis._canConsumeName = false;\n\t\t}\n\n\t\tfor ( const type in this._consumables ) {\n\t\t\tif ( type in consumables ) {\n\t\t\t\tthis._consume( type, consumables[ type ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Revert already consumed parts of {@link module:engine/view/element~Element view Element}, so they can be consumed once again.\n\t * Element's name can be reverted:\n\t *\n\t *\t\tconsumables.revert( { name: true } );\n\t *\n\t * Attributes classes and styles:\n\t *\n\t *\t\tconsumables.revert( { attributes: 'title', classes: 'foo', styles: 'color' } );\n\t *\t\tconsumables.revert( { attributes: [ 'title', 'name' ], classes: [ 'foo', 'bar' ] );\n\t *\n\t * @param {Object} consumables Object describing which parts of the element should be reverted.\n\t * @param {Boolean} consumables.name If set to `true` element's name will be reverted.\n\t * @param {String|Array.<String>} consumables.attributes Attribute name or array of attribute names to revert.\n\t * @param {String|Array.<String>} consumables.classes Class name or array of class names to revert.\n\t * @param {String|Array.<String>} consumables.styles Style name or array of style names to revert.\n\t */\n\trevert( consumables ) {\n\t\tif ( consumables.name ) {\n\t\t\tthis._canConsumeName = true;\n\t\t}\n\n\t\tfor ( const type in this._consumables ) {\n\t\t\tif ( type in consumables ) {\n\t\t\t\tthis._revert( type, consumables[ type ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Helper method that adds consumables of a given type: attribute, class or style.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `viewconsumable-invalid-attribute` when `class` or `style`\n\t * type is provided - it should be handled separately by providing actual style/class type.\n\t *\n\t * @private\n\t * @param {String} type Type of the consumable item: `attributes`, `classes` or `styles`.\n\t * @param {String|Array.<String>} item Consumable item or array of items.\n\t */\n\t_add( type, item ) {\n\t\tconst items = isArray( item ) ? item : [ item ];\n\t\tconst consumables = this._consumables[ type ];\n\n\t\tfor ( const name of items ) {\n\t\t\tif ( type === 'attributes' && ( name === 'class' || name === 'style' ) ) {\n\t\t\t\t/**\n\t\t\t\t * Class and style attributes should be handled separately in\n\t\t\t\t * {@link module:engine/conversion/viewconsumable~ViewConsumable#add `ViewConsumable#add()`}.\n\t\t\t\t *\n\t\t\t\t * What you have done is trying to use:\n\t\t\t\t *\n\t\t\t\t *\t\tconsumables.add( { attributes: [ 'class', 'style' ] } );\n\t\t\t\t *\n\t\t\t\t * While each class and style should be registered separately:\n\t\t\t\t *\n\t\t\t\t *\t\tconsumables.add( { classes: 'some-class', styles: 'font-weight' } );\n\t\t\t\t *\n\t\t\t\t * @error viewconsumable-invalid-attribute\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'viewconsumable-invalid-attribute: Classes and styles should be handled separately.' );\n\t\t\t}\n\n\t\t\tconsumables.set( name, true );\n\t\t}\n\t}\n\n\t/**\n\t * Helper method that tests consumables of a given type: attribute, class or style.\n\t *\n\t * @private\n\t * @param {String} type Type of the consumable item: `attributes`, `classes` or `styles`.\n\t * @param {String|Array.<String>} item Consumable item or array of items.\n\t * @returns {Boolean|null} Returns `true` if all items can be consumed, `null` when one of the items cannot be\n\t * consumed and `false` when one of the items is already consumed.\n\t */\n\t_test( type, item ) {\n\t\tconst items = isArray( item ) ? item : [ item ];\n\t\tconst consumables = this._consumables[ type ];\n\n\t\tfor ( const name of items ) {\n\t\t\tif ( type === 'attributes' && ( name === 'class' || name === 'style' ) ) {\n\t\t\t\tconst consumableName = name == 'class' ? 'classes' : 'styles';\n\n\t\t\t\t// Check all classes/styles if class/style attribute is tested.\n\t\t\t\tconst value = this._test( consumableName, [ ...this._consumables[ consumableName ].keys() ] );\n\n\t\t\t\tif ( value !== true ) {\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst value = consumables.get( name );\n\t\t\t\t// Return null if attribute is not found.\n\t\t\t\tif ( value === undefined ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tif ( !value ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Helper method that consumes items of a given type: attribute, class or style.\n\t *\n\t * @private\n\t * @param {String} type Type of the consumable item: `attributes`, `classes` or `styles`.\n\t * @param {String|Array.<String>} item Consumable item or array of items.\n\t */\n\t_consume( type, item ) {\n\t\tconst items = isArray( item ) ? item : [ item ];\n\t\tconst consumables = this._consumables[ type ];\n\n\t\tfor ( const name of items ) {\n\t\t\tif ( type === 'attributes' && ( name === 'class' || name === 'style' ) ) {\n\t\t\t\tconst consumableName = name == 'class' ? 'classes' : 'styles';\n\n\t\t\t\t// If class or style is provided for consumption - consume them all.\n\t\t\t\tthis._consume( consumableName, [ ...this._consumables[ consumableName ].keys() ] );\n\t\t\t} else {\n\t\t\t\tconsumables.set( name, false );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Helper method that reverts items of a given type: attribute, class or style.\n\t *\n\t * @private\n\t * @param {String} type Type of the consumable item: `attributes`, `classes` or , `styles`.\n\t * @param {String|Array.<String>} item Consumable item or array of items.\n\t */\n\t_revert( type, item ) {\n\t\tconst items = isArray( item ) ? item : [ item ];\n\t\tconst consumables = this._consumables[ type ];\n\n\t\tfor ( const name of items ) {\n\t\t\tif ( type === 'attributes' && ( name === 'class' || name === 'style' ) ) {\n\t\t\t\tconst consumableName = name == 'class' ? 'classes' : 'styles';\n\n\t\t\t\t// If class or style is provided for reverting - revert them all.\n\t\t\t\tthis._revert( consumableName, [ ...this._consumables[ consumableName ].keys() ] );\n\t\t\t} else {\n\t\t\t\tconst value = consumables.get( name );\n\n\t\t\t\tif ( value === false ) {\n\t\t\t\t\tconsumables.set( name, true );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/schema\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\nimport Range from './range';\nimport Position from './position';\nimport Element from './element';\nimport Text from './text';\nimport TreeWalker from './treewalker';\n\n/**\n * The model's schema. It defines allowed and disallowed structures of nodes as well as nodes' attributes.\n * The schema is usually defined by features and based on them the editing framework and features\n * make decisions how to change and process the model.\n *\n * The instance of schema is available in {@link module:engine/model/model~Model#schema `editor.model.schema`}.\n *\n * Read more about the schema in:\n *\n * * {@glink framework/guides/architecture/editing-engine#schema \"Schema\"} section of the\n * {@glink framework/guides/architecture/editing-engine Introduction to the \"Editing engine architecture\"}.\n * * {@glink framework/guides/deep-dive/schema \"Schema\" deep dive} guide.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Schema {\n\t/**\n\t * Creates schema instance.\n\t */\n\tconstructor() {\n\t\tthis._sourceDefinitions = {};\n\n\t\t/**\n\t\t * A dictionary containing attribute properties.\n\t\t *\n\t\t * @private\n\t\t * @member {Object.<String,String>}\n\t\t */\n\t\tthis._attributeProperties = {};\n\n\t\tthis.decorate( 'checkChild' );\n\t\tthis.decorate( 'checkAttribute' );\n\n\t\tthis.on( 'checkAttribute', ( evt, args ) => {\n\t\t\targs[ 0 ] = new SchemaContext( args[ 0 ] );\n\t\t}, { priority: 'highest' } );\n\n\t\tthis.on( 'checkChild', ( evt, args ) => {\n\t\t\targs[ 0 ] = new SchemaContext( args[ 0 ] );\n\t\t\targs[ 1 ] = this.getDefinition( args[ 1 ] );\n\t\t}, { priority: 'highest' } );\n\t}\n\n\t/**\n\t * Registers schema item. Can only be called once for every item name.\n\t *\n\t *\t\tschema.register( 'paragraph', {\n\t *\t\t\tinheritAllFrom: '$block'\n\t *\t\t} );\n\t *\n\t * @param {String} itemName\n\t * @param {module:engine/model/schema~SchemaItemDefinition} definition\n\t */\n\tregister( itemName, definition ) {\n\t\tif ( this._sourceDefinitions[ itemName ] ) {\n\t\t\t/**\n\t\t\t * A single item cannot be registered twice in the schema.\n\t\t\t *\n\t\t\t * This situation may happen when:\n\t\t\t *\n\t\t\t * * Two or more plugins called {@link #register `register()`} with the same name. This will usually mean that\n\t\t\t * there is a collision between plugins which try to use the same element in the model. Unfortunately,\n\t\t\t * the only way to solve this is by modifying one of these plugins to use a unique model element name.\n\t\t\t * * A single plugin was loaded twice. This happens when it is installed by npm/yarn in two versions\n\t\t\t * and usually means one or more of the following issues:\n\t\t\t * * a version mismatch (two of your dependencies require two different versions of this plugin),\n\t\t\t * * incorrect imports (this plugin is somehow imported twice in a way which confuses webpack),\n\t\t\t * * mess in `node_modules/` (`rm -rf node_modules/` may help).\n\t\t\t *\n\t\t\t * **Note:** Check the logged `itemName` to better understand which plugin was duplicated/conflicting.\n\t\t\t *\n\t\t\t * @param itemName The name of the model element that is being registered twice.\n\t\t\t * @error schema-cannot-register-item-twice\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'schema-cannot-register-item-twice: A single item cannot be registered twice in the schema.', {\n\t\t\t\titemName\n\t\t\t} );\n\t\t}\n\n\t\tthis._sourceDefinitions[ itemName ] = [\n\t\t\tObject.assign( {}, definition )\n\t\t];\n\n\t\tthis._clearCache();\n\t}\n\n\t/**\n\t * Extends a {@link #register registered} item's definition.\n\t *\n\t * Extending properties such as `allowIn` will add more items to the existing properties,\n\t * while redefining properties such as `isBlock` will override the previously defined ones.\n\t *\n\t *\t\tschema.register( 'foo', {\n\t *\t\t\tallowIn: '$root',\n\t *\t\t\tisBlock: true;\n\t *\t\t} );\n\t *\t\tschema.extend( 'foo', {\n\t *\t\t\tallowIn: 'blockQuote',\n\t *\t\t\tisBlock: false\n\t *\t\t} );\n\t *\n\t *\t\tschema.getDefinition( 'foo' );\n\t *\t\t//\t{\n\t *\t\t//\t\tallowIn: [ '$root', 'blockQuote' ],\n\t *\t\t// \t\tisBlock: false\n\t *\t\t//\t}\n\t *\n\t * @param {String} itemName\n\t * @param {module:engine/model/schema~SchemaItemDefinition} definition\n\t */\n\textend( itemName, definition ) {\n\t\tif ( !this._sourceDefinitions[ itemName ] ) {\n\t\t\t/**\n\t\t\t * Cannot extend an item which was not registered yet.\n\t\t\t *\n\t\t\t * This error happens when a plugin tries to extend the schema definition of an item which was not\n\t\t\t * {@link #register registered} yet.\n\t\t\t *\n\t\t\t * @param itemName The name of the model element which is being extended.\n\t\t\t * @error schema-cannot-register-item-twice\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'schema-cannot-extend-missing-item: Cannot extend an item which was not registered yet.', {\n\t\t\t\titemName\n\t\t\t} );\n\t\t}\n\n\t\tthis._sourceDefinitions[ itemName ].push( Object.assign( {}, definition ) );\n\n\t\tthis._clearCache();\n\t}\n\n\t/**\n\t * Returns all registered items.\n\t *\n\t * @returns {Object.<String,module:engine/model/schema~SchemaCompiledItemDefinition>}\n\t */\n\tgetDefinitions() {\n\t\tif ( !this._compiledDefinitions ) {\n\t\t\tthis._compile();\n\t\t}\n\n\t\treturn this._compiledDefinitions;\n\t}\n\n\t/**\n\t * Returns a definition of the given item or `undefined` if item is not registered.\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/schema~SchemaContextItem|String} item\n\t * @returns {module:engine/model/schema~SchemaCompiledItemDefinition}\n\t */\n\tgetDefinition( item ) {\n\t\tlet itemName;\n\n\t\tif ( typeof item == 'string' ) {\n\t\t\titemName = item;\n\t\t} else if ( item.is && ( item.is( 'text' ) || item.is( 'textProxy' ) ) ) {\n\t\t\titemName = '$text';\n\t\t}\n\t\t// Element or module:engine/model/schema~SchemaContextItem.\n\t\telse {\n\t\t\titemName = item.name;\n\t\t}\n\n\t\treturn this.getDefinitions()[ itemName ];\n\t}\n\n\t/**\n\t * Returns `true` if the given item is registered in the schema.\n\t *\n\t *\t\tschema.isRegistered( 'paragraph' ); // -> true\n\t *\t\tschema.isRegistered( editor.model.document.getRoot() ); // -> true\n\t *\t\tschema.isRegistered( 'foo' ); // -> false\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/schema~SchemaContextItem|String} item\n\t */\n\tisRegistered( item ) {\n\t\treturn !!this.getDefinition( item );\n\t}\n\n\t/**\n\t * Returns `true` if the given item is defined to be\n\t * a block by {@link module:engine/model/schema~SchemaItemDefinition}'s `isBlock` property.\n\t *\n\t *\t\tschema.isBlock( 'paragraph' ); // -> true\n\t *\t\tschema.isBlock( '$root' ); // -> false\n\t *\n\t *\t\tconst paragraphElement = writer.createElement( 'paragraph' );\n\t *\t\tschema.isBlock( paragraphElement ); // -> true\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/schema~SchemaContextItem|String} item\n\t */\n\tisBlock( item ) {\n\t\tconst def = this.getDefinition( item );\n\n\t\treturn !!( def && def.isBlock );\n\t}\n\n\t/**\n\t * Returns `true` if the given item is defined to be\n\t * a limit element by {@link module:engine/model/schema~SchemaItemDefinition}'s `isLimit` or `isObject` property\n\t * (all objects are also limits).\n\t *\n\t *\t\tschema.isLimit( 'paragraph' ); // -> false\n\t *\t\tschema.isLimit( '$root' ); // -> true\n\t *\t\tschema.isLimit( editor.model.document.getRoot() ); // -> true\n\t *\t\tschema.isLimit( 'image' ); // -> true\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/schema~SchemaContextItem|String} item\n\t */\n\tisLimit( item ) {\n\t\tconst def = this.getDefinition( item );\n\n\t\tif ( !def ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn !!( def.isLimit || def.isObject );\n\t}\n\n\t/**\n\t * Returns `true` if the given item is defined to be\n\t * an object element by {@link module:engine/model/schema~SchemaItemDefinition}'s `isObject` property.\n\t *\n\t *\t\tschema.isObject( 'paragraph' ); // -> false\n\t *\t\tschema.isObject( 'image' ); // -> true\n\t *\n\t *\t\tconst imageElement = writer.createElement( 'image' );\n\t *\t\tschema.isObject( imageElement ); // -> true\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/schema~SchemaContextItem|String} item\n\t */\n\tisObject( item ) {\n\t\tconst def = this.getDefinition( item );\n\n\t\treturn !!( def && def.isObject );\n\t}\n\n\t/**\n\t * Returns `true` if the given item is defined to be\n\t * an inline element by {@link module:engine/model/schema~SchemaItemDefinition}'s `isInline` property.\n\t *\n\t *\t\tschema.isInline( 'paragraph' ); // -> false\n\t *\t\tschema.isInline( 'softBreak' ); // -> true\n\t *\n\t *\t\tconst text = writer.createText('foo' );\n\t *\t\tschema.isInline( text ); // -> true\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/schema~SchemaContextItem|String} item\n\t */\n\tisInline( item ) {\n\t\tconst def = this.getDefinition( item );\n\n\t\treturn !!( def && def.isInline );\n\t}\n\n\t/**\n\t * Checks whether the given node (`child`) can be a child of the given context.\n\t *\n\t *\t\tschema.checkChild( model.document.getRoot(), paragraph ); // -> false\n\t *\n\t *\t\tschema.register( 'paragraph', {\n\t *\t\t\tallowIn: '$root'\n\t *\t\t} );\n\t *\t\tschema.checkChild( model.document.getRoot(), paragraph ); // -> true\n\t *\n\t * Note: When verifying whether the given node can be a child of the given context, the\n\t * schema also verifies the entire context &mdash; from its root to its last element. Therefore, it is possible\n\t * for `checkChild()` to return `false` even though the context's last element can contain the checked child.\n\t * It happens if one of the context's elements does not allow its child.\n\t *\n\t * @fires checkChild\n\t * @param {module:engine/model/schema~SchemaContextDefinition} context The context in which the child will be checked.\n\t * @param {module:engine/model/node~Node|String} def The child to check.\n\t */\n\tcheckChild( context, def ) {\n\t\t// Note: context and child are already normalized here to a SchemaContext and SchemaCompiledItemDefinition.\n\t\tif ( !def ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn this._checkContextMatch( def, context );\n\t}\n\n\t/**\n\t * Checks whether the given attribute can be applied in the given context (on the last\n\t * item of the context).\n\t *\n\t *\t\tschema.checkAttribute( textNode, 'bold' ); // -> false\n\t *\n\t *\t\tschema.extend( '$text', {\n\t *\t\t\tallowAttributes: 'bold'\n\t *\t\t} );\n\t *\t\tschema.checkAttribute( textNode, 'bold' ); // -> true\n\t *\n\t * @fires checkAttribute\n\t * @param {module:engine/model/schema~SchemaContextDefinition} context The context in which the attribute will be checked.\n\t * @param {String} attributeName\n\t */\n\tcheckAttribute( context, attributeName ) {\n\t\tconst def = this.getDefinition( context.last );\n\n\t\tif ( !def ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn def.allowAttributes.includes( attributeName );\n\t}\n\n\t/**\n\t * Checks whether the given element (`elementToMerge`) can be merged with the specified base element (`positionOrBaseElement`).\n\t *\n\t * In other words &mdash; whether `elementToMerge`'s children {@link #checkChild are allowed} in the `positionOrBaseElement`.\n\t *\n\t * This check ensures that elements merged with {@link module:engine/model/writer~Writer#merge `Writer#merge()`}\n\t * will be valid.\n\t *\n\t * Instead of elements, you can pass the instance of the {@link module:engine/model/position~Position} class as the\n\t * `positionOrBaseElement`. It means that the elements before and after the position will be checked whether they can be merged.\n\t *\n\t * @param {module:engine/model/position~Position|module:engine/model/element~Element} positionOrBaseElement The position or base\n\t * element to which the `elementToMerge` will be merged.\n\t * @param {module:engine/model/element~Element} elementToMerge The element to merge. Required if `positionOrBaseElement` is an element.\n\t * @returns {Boolean}\n\t */\n\tcheckMerge( positionOrBaseElement, elementToMerge = null ) {\n\t\tif ( positionOrBaseElement instanceof Position ) {\n\t\t\tconst nodeBefore = positionOrBaseElement.nodeBefore;\n\t\t\tconst nodeAfter = positionOrBaseElement.nodeAfter;\n\n\t\t\tif ( !( nodeBefore instanceof Element ) ) {\n\t\t\t\t/**\n\t\t\t\t * The node before the merge position must be an element.\n\t\t\t\t *\n\t\t\t\t * @error schema-check-merge-no-element-before\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'schema-check-merge-no-element-before: The node before the merge position must be an element.' );\n\t\t\t}\n\n\t\t\tif ( !( nodeAfter instanceof Element ) ) {\n\t\t\t\t/**\n\t\t\t\t * The node after the merge position must be an element.\n\t\t\t\t *\n\t\t\t\t * @error schema-check-merge-no-element-after\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'schema-check-merge-no-element-after: The node after the merge position must be an element.' );\n\t\t\t}\n\n\t\t\treturn this.checkMerge( nodeBefore, nodeAfter );\n\t\t}\n\n\t\tfor ( const child of elementToMerge.getChildren() ) {\n\t\t\tif ( !this.checkChild( positionOrBaseElement, child ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Allows registering a callback to the {@link #checkChild} method calls.\n\t *\n\t * Callbacks allow you to implement rules which are not otherwise possible to achieve\n\t * by using the declarative API of {@link module:engine/model/schema~SchemaItemDefinition}.\n\t * For example, by using this method you can disallow elements in specific contexts.\n\t *\n\t * This method is a shorthand for using the {@link #event:checkChild} event. For even better control,\n\t * you can use that event instead.\n\t *\n\t * Example:\n\t *\n\t *\t\t// Disallow heading1 directly inside a blockQuote.\n\t *\t\tschema.addChildCheck( ( context, childDefinition ) => {\n\t *\t\t\tif ( context.endsWith( 'blockQuote' ) && childDefinition.name == 'heading1' ) {\n\t *\t\t\t\treturn false;\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * Which translates to:\n\t *\n\t *\t\tschema.on( 'checkChild', ( evt, args ) => {\n\t *\t\t\tconst context = args[ 0 ];\n\t *\t\t\tconst childDefinition = args[ 1 ];\n\t *\n\t *\t\t\tif ( context.endsWith( 'blockQuote' ) && childDefinition && childDefinition.name == 'heading1' ) {\n\t *\t\t\t\t// Prevent next listeners from being called.\n\t *\t\t\t\tevt.stop();\n\t *\t\t\t\t// Set the checkChild()'s return value.\n\t *\t\t\t\tevt.return = false;\n\t *\t\t\t}\n\t *\t\t}, { priority: 'high' } );\n\t *\n\t * @param {Function} callback The callback to be called. It is called with two parameters:\n\t * {@link module:engine/model/schema~SchemaContext} (context) instance and\n\t * {@link module:engine/model/schema~SchemaCompiledItemDefinition} (child-to-check definition).\n\t * The callback may return `true/false` to override `checkChild()`'s return value. If it does not return\n\t * a boolean value, the default algorithm (or other callbacks) will define `checkChild()`'s return value.\n\t */\n\taddChildCheck( callback ) {\n\t\tthis.on( 'checkChild', ( evt, [ ctx, childDef ] ) => {\n\t\t\t// checkChild() was called with a non-registered child.\n\t\t\t// In 99% cases such check should return false, so not to overcomplicate all callbacks\n\t\t\t// don't even execute them.\n\t\t\tif ( !childDef ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst retValue = callback( ctx, childDef );\n\n\t\t\tif ( typeof retValue == 'boolean' ) {\n\t\t\t\tevt.stop();\n\t\t\t\tevt.return = retValue;\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\t}\n\n\t/**\n\t * Allows registering a callback to the {@link #checkAttribute} method calls.\n\t *\n\t * Callbacks allow you to implement rules which are not otherwise possible to achieve\n\t * by using the declarative API of {@link module:engine/model/schema~SchemaItemDefinition}.\n\t * For example, by using this method you can disallow attribute if node to which it is applied\n\t * is contained within some other element (e.g. you want to disallow `bold` on `$text` within `heading1`).\n\t *\n\t * This method is a shorthand for using the {@link #event:checkAttribute} event. For even better control,\n\t * you can use that event instead.\n\t *\n\t * Example:\n\t *\n\t *\t\t// Disallow bold on $text inside heading1.\n\t *\t\tschema.addAttributeCheck( ( context, attributeName ) => {\n\t *\t\t\tif ( context.endsWith( 'heading1 $text' ) && attributeName == 'bold' ) {\n\t *\t\t\t\treturn false;\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * Which translates to:\n\t *\n\t *\t\tschema.on( 'checkAttribute', ( evt, args ) => {\n\t *\t\t\tconst context = args[ 0 ];\n\t *\t\t\tconst attributeName = args[ 1 ];\n\t *\n\t *\t\t\tif ( context.endsWith( 'heading1 $text' ) && attributeName == 'bold' ) {\n\t *\t\t\t\t// Prevent next listeners from being called.\n\t *\t\t\t\tevt.stop();\n\t *\t\t\t\t// Set the checkAttribute()'s return value.\n\t *\t\t\t\tevt.return = false;\n\t *\t\t\t}\n\t *\t\t}, { priority: 'high' } );\n\t *\n\t * @param {Function} callback The callback to be called. It is called with two parameters:\n\t * {@link module:engine/model/schema~SchemaContext} (context) instance and attribute name.\n\t * The callback may return `true/false` to override `checkAttribute()`'s return value. If it does not return\n\t * a boolean value, the default algorithm (or other callbacks) will define `checkAttribute()`'s return value.\n\t */\n\taddAttributeCheck( callback ) {\n\t\tthis.on( 'checkAttribute', ( evt, [ ctx, attributeName ] ) => {\n\t\t\tconst retValue = callback( ctx, attributeName );\n\n\t\t\tif ( typeof retValue == 'boolean' ) {\n\t\t\t\tevt.stop();\n\t\t\t\tevt.return = retValue;\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\t}\n\n\t/**\n\t * This method allows assigning additional metadata to the model attributes. For example,\n\t * {@link module:engine/model/schema~AttributeProperties `AttributeProperties#isFormatting` property} is\n\t * used to mark formatting attributes (like `bold` or `italic`).\n\t *\n\t *\t\t// Mark bold as a formatting attribute.\n\t *\t\tschema.setAttributeProperties( 'bold', {\n\t *\t\t\tisFormatting: true\n\t *\t\t} );\n\t *\n\t *\t\t// Override code not to be considered a formatting markup.\n\t *\t\tschema.setAttributeProperties( 'code', {\n\t *\t\t\tisFormatting: false\n\t *\t\t} );\n\t *\n\t * Properties are not limited to members defined in the\n\t * {@link module:engine/model/schema~AttributeProperties `AttributeProperties` type} and you can also use custom properties:\n\t *\n\t *\t\tschema.setAttributeProperties( 'blockQuote', {\n\t *\t\t\tcustomProperty: 'value'\n\t *\t\t} );\n\t *\n\t * Subsequent calls with the same attribute will extend its custom properties:\n\t *\n\t *\t\tschema.setAttributeProperties( 'blockQuote', {\n\t *\t\t\tone: 1\n\t *\t\t} );\n\t *\n\t *\t\tschema.setAttributeProperties( 'blockQuote', {\n\t *\t\t\ttwo: 2\n\t *\t\t} );\n\t *\n\t *\t\tconsole.log( schema.getAttributeProperties( 'blockQuote' ) );\n\t *\t\t// Logs: { one: 1, two: 2 }\n\t *\n\t * @param {String} attributeName A name of the attribute to receive the properties.\n\t * @param {module:engine/model/schema~AttributeProperties} properties A dictionary of properties.\n\t */\n\tsetAttributeProperties( attributeName, properties ) {\n\t\tthis._attributeProperties[ attributeName ] = Object.assign( this.getAttributeProperties( attributeName ), properties );\n\t}\n\n\t/**\n\t * Returns properties associated with a given model attribute. See {@link #setAttributeProperties `setAttributeProperties()`}.\n\t *\n\t * @param {String} attributeName A name of the attribute.\n\t * @returns {module:engine/model/schema~AttributeProperties}\n\t */\n\tgetAttributeProperties( attributeName ) {\n\t\treturn this._attributeProperties[ attributeName ] || {};\n\t}\n\n\t/**\n\t * Returns the lowest {@link module:engine/model/schema~Schema#isLimit limit element} containing the entire\n\t * selection/range/position or the root otherwise.\n\t *\n\t * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection|\n\t * module:engine/model/range~Range|module:engine/model/position~Position} selectionOrRangeOrPosition\n\t * The selection/range/position to check.\n\t * @returns {module:engine/model/element~Element} The lowest limit element containing\n\t * the entire `selectionOrRangeOrPosition`.\n\t */\n\tgetLimitElement( selectionOrRangeOrPosition ) {\n\t\tlet element;\n\n\t\tif ( selectionOrRangeOrPosition instanceof Position ) {\n\t\t\telement = selectionOrRangeOrPosition.parent;\n\t\t} else {\n\t\t\tconst ranges = selectionOrRangeOrPosition instanceof Range ?\n\t\t\t\t[ selectionOrRangeOrPosition ] :\n\t\t\t\tArray.from( selectionOrRangeOrPosition.getRanges() );\n\n\t\t\t// Find the common ancestor for all selection's ranges.\n\t\t\telement = ranges\n\t\t\t\t.reduce( ( element, range ) => {\n\t\t\t\t\tconst rangeCommonAncestor = range.getCommonAncestor();\n\n\t\t\t\t\tif ( !element ) {\n\t\t\t\t\t\treturn rangeCommonAncestor;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn element.getCommonAncestor( rangeCommonAncestor, { includeSelf: true } );\n\t\t\t\t}, null );\n\t\t}\n\n\t\twhile ( !this.isLimit( element ) ) {\n\t\t\tif ( element.parent ) {\n\t\t\t\telement = element.parent;\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn element;\n\t}\n\n\t/**\n\t * Checks whether the attribute is allowed in selection:\n\t *\n\t * * if the selection is not collapsed, then checks if the attribute is allowed on any of nodes in that range,\n\t * * if the selection is collapsed, then checks if on the selection position there's a text with the\n\t * specified attribute allowed.\n\t *\n\t * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection\n\t * Selection which will be checked.\n\t * @param {String} attribute The name of the attribute to check.\n\t * @returns {Boolean}\n\t */\n\tcheckAttributeInSelection( selection, attribute ) {\n\t\tif ( selection.isCollapsed ) {\n\t\t\tconst firstPosition = selection.getFirstPosition();\n\t\t\tconst context = [\n\t\t\t\t...firstPosition.getAncestors(),\n\t\t\t\tnew Text( '', selection.getAttributes() )\n\t\t\t];\n\n\t\t\t// Check whether schema allows for a text with the attribute in the selection.\n\t\t\treturn this.checkAttribute( context, attribute );\n\t\t} else {\n\t\t\tconst ranges = selection.getRanges();\n\n\t\t\t// For all ranges, check nodes in them until you find a node that is allowed to have the attribute.\n\t\t\tfor ( const range of ranges ) {\n\t\t\t\tfor ( const value of range ) {\n\t\t\t\t\tif ( this.checkAttribute( value.item, attribute ) ) {\n\t\t\t\t\t\t// If we found a node that is allowed to have the attribute, return true.\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we haven't found such node, return false.\n\t\treturn false;\n\t}\n\n\t/**\n\t * Transforms the given set of ranges into a set of ranges where the given attribute is allowed (and can be applied).\n\t *\n\t * @param {Array.<module:engine/model/range~Range>} ranges Ranges to be validated.\n\t * @param {String} attribute The name of the attribute to check.\n\t * @returns {Iterable.<module:engine/model/range~Range>} Ranges in which the attribute is allowed.\n\t */\n\t* getValidRanges( ranges, attribute ) {\n\t\tranges = convertToMinimalFlatRanges( ranges );\n\n\t\tfor ( const range of ranges ) {\n\t\t\tyield* this._getValidRangesForRange( range, attribute );\n\t\t}\n\t}\n\n\t/**\n\t * Basing on given `position`, finds and returns a {@link module:engine/model/range~Range range} which is\n\t * nearest to that `position` and is a correct range for selection.\n\t *\n\t * The correct selection range might be collapsed when it is located in a position where the text node can be placed.\n\t * Non-collapsed range is returned when selection can be placed around element marked as an \"object\" in\n\t * the {@link module:engine/model/schema~Schema schema}.\n\t *\n\t * Direction of searching for the nearest correct selection range can be specified as:\n\t *\n\t * * `both` - searching will be performed in both ways,\n\t * * `forward` - searching will be performed only forward,\n\t * * `backward` - searching will be performed only backward.\n\t *\n\t * When valid selection range cannot be found, `null` is returned.\n\t *\n\t * @param {module:engine/model/position~Position} position Reference position where new selection range should be looked for.\n\t * @param {'both'|'forward'|'backward'} [direction='both'] Search direction.\n\t * @returns {module:engine/model/range~Range|null} Nearest selection range or `null` if one cannot be found.\n\t */\n\tgetNearestSelectionRange( position, direction = 'both' ) {\n\t\t// Return collapsed range if provided position is valid.\n\t\tif ( this.checkChild( position, '$text' ) ) {\n\t\t\treturn new Range( position );\n\t\t}\n\n\t\tlet backwardWalker, forwardWalker;\n\n\t\tif ( direction == 'both' || direction == 'backward' ) {\n\t\t\tbackwardWalker = new TreeWalker( { startPosition: position, direction: 'backward' } );\n\t\t}\n\n\t\tif ( direction == 'both' || direction == 'forward' ) {\n\t\t\tforwardWalker = new TreeWalker( { startPosition: position } );\n\t\t}\n\n\t\tfor ( const data of combineWalkers( backwardWalker, forwardWalker ) ) {\n\t\t\tconst type = ( data.walker == backwardWalker ? 'elementEnd' : 'elementStart' );\n\t\t\tconst value = data.value;\n\n\t\t\tif ( value.type == type && this.isObject( value.item ) ) {\n\t\t\t\treturn Range._createOn( value.item );\n\t\t\t}\n\n\t\t\tif ( this.checkChild( value.nextPosition, '$text' ) ) {\n\t\t\t\treturn new Range( value.nextPosition );\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Tries to find position ancestors that allows to insert given node.\n\t * It starts searching from the given position and goes node by node to the top of the model tree\n\t * as long as {@link module:engine/model/schema~Schema#isLimit limit element},\n\t * {@link module:engine/model/schema~Schema#isObject object element} or top-most ancestor won't be reached.\n\t *\n\t * @params {module:engine/model/position~Position} position Position from searching will start.\n\t * @params {module:engine/model/node~Node|String} node Node for which allowed parent should be found or its name.\n\t * @returns {module:engine/model/element~Element|null} element Allowed parent or null if nothing was found.\n\t */\n\tfindAllowedParent( position, node ) {\n\t\tlet parent = position.parent;\n\n\t\twhile ( parent ) {\n\t\t\tif ( this.checkChild( parent, node ) ) {\n\t\t\t\treturn parent;\n\t\t\t}\n\n\t\t\t// Do not split limit elements.\n\t\t\tif ( this.isLimit( parent ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Removes attributes disallowed by the schema.\n\t *\n\t * @param {Iterable.<module:engine/model/node~Node>} nodes Nodes that will be filtered.\n\t * @param {module:engine/model/writer~Writer} writer\n\t */\n\tremoveDisallowedAttributes( nodes, writer ) {\n\t\tfor ( const node of nodes ) {\n\t\t\tfor ( const attribute of node.getAttributeKeys() ) {\n\t\t\t\tif ( !this.checkAttribute( node, attribute ) ) {\n\t\t\t\t\twriter.removeAttribute( attribute, node );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( node.is( 'element' ) ) {\n\t\t\t\tthis.removeDisallowedAttributes( node.getChildren(), writer );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Creates an instance of the schema context.\n\t *\n\t * @param {module:engine/model/schema~SchemaContextDefinition} context\n\t * @returns {module:engine/model/schema~SchemaContext}\n\t */\n\tcreateContext( context ) {\n\t\treturn new SchemaContext( context );\n\t}\n\n\t/**\n\t * @private\n\t */\n\t_clearCache() {\n\t\tthis._compiledDefinitions = null;\n\t}\n\n\t/**\n\t * @private\n\t */\n\t_compile() {\n\t\tconst compiledDefinitions = {};\n\t\tconst sourceRules = this._sourceDefinitions;\n\t\tconst itemNames = Object.keys( sourceRules );\n\n\t\tfor ( const itemName of itemNames ) {\n\t\t\tcompiledDefinitions[ itemName ] = compileBaseItemRule( sourceRules[ itemName ], itemName );\n\t\t}\n\n\t\tfor ( const itemName of itemNames ) {\n\t\t\tcompileAllowContentOf( compiledDefinitions, itemName );\n\t\t}\n\n\t\tfor ( const itemName of itemNames ) {\n\t\t\tcompileAllowWhere( compiledDefinitions, itemName );\n\t\t}\n\n\t\tfor ( const itemName of itemNames ) {\n\t\t\tcompileAllowAttributesOf( compiledDefinitions, itemName );\n\t\t\tcompileInheritPropertiesFrom( compiledDefinitions, itemName );\n\t\t}\n\n\t\tfor ( const itemName of itemNames ) {\n\t\t\tcleanUpAllowIn( compiledDefinitions, itemName );\n\t\t\tcleanUpAllowAttributes( compiledDefinitions, itemName );\n\t\t}\n\n\t\tthis._compiledDefinitions = compiledDefinitions;\n\t}\n\n\t/**\n\t * @private\n\t * @param {module:engine/model/schema~SchemaCompiledItemDefinition} def\n\t * @param {module:engine/model/schema~SchemaContext} context\n\t * @param {Number} contextItemIndex\n\t */\n\t_checkContextMatch( def, context, contextItemIndex = context.length - 1 ) {\n\t\tconst contextItem = context.getItem( contextItemIndex );\n\n\t\tif ( def.allowIn.includes( contextItem.name ) ) {\n\t\t\tif ( contextItemIndex == 0 ) {\n\t\t\t\treturn true;\n\t\t\t} else {\n\t\t\t\tconst parentRule = this.getDefinition( contextItem );\n\n\t\t\t\treturn this._checkContextMatch( parentRule, context, contextItemIndex - 1 );\n\t\t\t}\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Takes a flat range and an attribute name. Traverses the range recursively and deeply to find and return all ranges\n\t * inside the given range on which the attribute can be applied.\n\t *\n\t * This is a helper function for {@link ~Schema#getValidRanges}.\n\t *\n\t * @private\n\t * @param {module:engine/model/range~Range} range Range to process.\n\t * @param {String} attribute The name of the attribute to check.\n\t * @returns {Iterable.<module:engine/model/range~Range>} Ranges in which the attribute is allowed.\n\t */\n\t* _getValidRangesForRange( range, attribute ) {\n\t\tlet start = range.start;\n\t\tlet end = range.start;\n\n\t\tfor ( const item of range.getItems( { shallow: true } ) ) {\n\t\t\tif ( item.is( 'element' ) ) {\n\t\t\t\tyield* this._getValidRangesForRange( Range._createIn( item ), attribute );\n\t\t\t}\n\n\t\t\tif ( !this.checkAttribute( item, attribute ) ) {\n\t\t\t\tif ( !start.isEqual( end ) ) {\n\t\t\t\t\tyield new Range( start, end );\n\t\t\t\t}\n\n\t\t\t\tstart = Position._createAfter( item );\n\t\t\t}\n\n\t\t\tend = Position._createAfter( item );\n\t\t}\n\n\t\tif ( !start.isEqual( end ) ) {\n\t\t\tyield new Range( start, end );\n\t\t}\n\t}\n}\n\nmix( Schema, ObservableMixin );\n\n/**\n * Event fired when the {@link #checkChild} method is called. It allows plugging in\n * additional behavior – e.g. implementing rules which cannot be defined using the declarative\n * {@link module:engine/model/schema~SchemaItemDefinition} interface.\n *\n * **Note:** The {@link #addChildCheck} method is a more handy way to register callbacks. Internally,\n * it registers a listener to this event but comes with a simpler API and it is the recommended choice\n * in most of the cases.\n *\n * The {@link #checkChild} method fires an event because it is\n * {@link module:utils/observablemixin~ObservableMixin#decorate decorated} with it. Thanks to that you can\n * use this event in a various way, but the most important use case is overriding standard behaviour of the\n * `checkChild()` method. Let's see a typical listener template:\n *\n *\t\tschema.on( 'checkChild', ( evt, args ) => {\n *\t\t\tconst context = args[ 0 ];\n *\t\t\tconst childDefinition = args[ 1 ];\n *\t\t}, { priority: 'high' } );\n *\n * The listener is added with a `high` priority to be executed before the default method is really called. The `args` callback\n * parameter contains arguments passed to `checkChild( context, child )`. However, the `context` parameter is already\n * normalized to a {@link module:engine/model/schema~SchemaContext} instance and `child` to a\n * {@link module:engine/model/schema~SchemaCompiledItemDefinition} instance, so you don't have to worry about\n * the various ways how `context` and `child` may be passed to `checkChild()`.\n *\n * **Note:** `childDefinition` may be `undefined` if `checkChild()` was called with a non-registered element.\n *\n * So, in order to implement a rule \"disallow `heading1` in `blockQuote`\" you can add such a listener:\n *\n *\t\tschema.on( 'checkChild', ( evt, args ) => {\n *\t\t\tconst context = args[ 0 ];\n *\t\t\tconst childDefinition = args[ 1 ];\n *\n *\t\t\tif ( context.endsWith( 'blockQuote' ) && childDefinition && childDefinition.name == 'heading1' ) {\n *\t\t\t\t// Prevent next listeners from being called.\n *\t\t\t\tevt.stop();\n *\t\t\t\t// Set the checkChild()'s return value.\n *\t\t\t\tevt.return = false;\n *\t\t\t}\n *\t\t}, { priority: 'high' } );\n *\n * Allowing elements in specific contexts will be a far less common use case, because it's normally handled by\n * `allowIn` rule from {@link module:engine/model/schema~SchemaItemDefinition} but if you have a complex scenario\n * where `listItem` should be allowed only in element `foo` which must be in element `bar`, then this would be the way:\n *\n *\t\tschema.on( 'checkChild', ( evt, args ) => {\n *\t\t\tconst context = args[ 0 ];\n *\t\t\tconst childDefinition = args[ 1 ];\n *\n *\t\t\tif ( context.endsWith( 'bar foo' ) && childDefinition.name == 'listItem' ) {\n *\t\t\t\t// Prevent next listeners from being called.\n *\t\t\t\tevt.stop();\n *\t\t\t\t// Set the checkChild()'s return value.\n *\t\t\t\tevt.return = true;\n *\t\t\t}\n *\t\t}, { priority: 'high' } );\n *\n * @event checkChild\n * @param {Array} args The `checkChild()`'s arguments.\n */\n\n/**\n * Event fired when the {@link #checkAttribute} method is called. It allows plugging in\n * additional behavior – e.g. implementing rules which cannot be defined using the declarative\n * {@link module:engine/model/schema~SchemaItemDefinition} interface.\n *\n * **Note:** The {@link #addAttributeCheck} method is a more handy way to register callbacks. Internally,\n * it registers a listener to this event but comes with a simpler API and it is the recommended choice\n * in most of the cases.\n *\n * The {@link #checkAttribute} method fires an event because it's\n * {@link module:utils/observablemixin~ObservableMixin#decorate decorated} with it. Thanks to that you can\n * use this event in a various way, but the most important use case is overriding standard behaviour of the\n * `checkAttribute()` method. Let's see a typical listener template:\n *\n *\t\tschema.on( 'checkAttribute', ( evt, args ) => {\n *\t\t\tconst context = args[ 0 ];\n *\t\t\tconst attributeName = args[ 1 ];\n *\t\t}, { priority: 'high' } );\n *\n * The listener is added with a `high` priority to be executed before the default method is really called. The `args` callback\n * parameter contains arguments passed to `checkAttribute( context, attributeName )`. However, the `context` parameter is already\n * normalized to a {@link module:engine/model/schema~SchemaContext} instance, so you don't have to worry about\n * the various ways how `context` may be passed to `checkAttribute()`.\n *\n * So, in order to implement a rule \"disallow `bold` in a text which is in a `heading1` you can add such a listener:\n *\n *\t\tschema.on( 'checkAttribute', ( evt, args ) => {\n *\t\t\tconst context = args[ 0 ];\n *\t\t\tconst atributeName = args[ 1 ];\n *\n *\t\t\tif ( context.endsWith( 'heading1 $text' ) && attributeName == 'bold' ) {\n *\t\t\t\t// Prevent next listeners from being called.\n *\t\t\t\tevt.stop();\n *\t\t\t\t// Set the checkAttribute()'s return value.\n *\t\t\t\tevt.return = false;\n *\t\t\t}\n *\t\t}, { priority: 'high' } );\n *\n * Allowing attributes in specific contexts will be a far less common use case, because it's normally handled by\n * `allowAttributes` rule from {@link module:engine/model/schema~SchemaItemDefinition} but if you have a complex scenario\n * where `bold` should be allowed only in element `foo` which must be in element `bar`, then this would be the way:\n *\n *\t\tschema.on( 'checkAttribute', ( evt, args ) => {\n *\t\t\tconst context = args[ 0 ];\n *\t\t\tconst atributeName = args[ 1 ];\n *\n *\t\t\tif ( context.endsWith( 'bar foo $text' ) && attributeName == 'bold' ) {\n *\t\t\t\t// Prevent next listeners from being called.\n *\t\t\t\tevt.stop();\n *\t\t\t\t// Set the checkAttribute()'s return value.\n *\t\t\t\tevt.return = true;\n *\t\t\t}\n *\t\t}, { priority: 'high' } );\n *\n * @event checkAttribute\n * @param {Array} args The `checkAttribute()`'s arguments.\n */\n\n/**\n * A definition of a {@link module:engine/model/schema~Schema schema} item.\n *\n * You can define the following rules:\n *\n * * `allowIn` &ndash; A string or an array of strings. Defines in which other items this item will be allowed.\n * * `allowAttributes` &ndash; A string or an array of strings. Defines allowed attributes of the given item.\n * * `allowContentOf` &ndash; A string or an array of strings. Inherits \"allowed children\" from other items.\n * * `allowWhere` &ndash; A string or an array of strings. Inherits \"allowed in\" from other items.\n * * `allowAttributesOf` &ndash; A string or an array of strings. Inherits attributes from other items.\n * * `inheritTypesFrom` &ndash; A string or an array of strings. Inherits `is*` properties of other items.\n * * `inheritAllFrom` &ndash; A string. A shorthand for `allowContentOf`, `allowWhere`, `allowAttributesOf`, `inheritTypesFrom`.\n * * Additionally, you can define the following `is*` properties: `isBlock`, `isLimit`, `isObject`, `isInline`. Read about them below.\n *\n * # The is* properties\n *\n * There are 3 commonly used `is*` properties. Their role is to assign additional semantics to schema items.\n * You can define more properties but you will also need to implement support for them in the existing editor features.\n *\n * * `isBlock` &ndash; Whether this item is paragraph-like. Generally speaking, content is usually made out of blocks\n * like paragraphs, list items, images, headings, etc. All these elements are marked as blocks. A block\n * should not allow another block inside. Note: There is also the `$block` generic item which has `isBlock` set to `true`.\n * Most block type items will inherit from `$block` (through `inheritAllFrom`).\n * * `isLimit` &ndash; It can be understood as whether this element should not be split by <kbd>Enter</kbd>.\n * Examples of limit elements: `$root`, table cell, image caption, etc. In other words, all actions that happen inside\n * a limit element are limited to its content. **Note:** All objects (`isObject`) are treated as limit elements, too.\n * * `isObject` &ndash; Whether an item is \"self-contained\" and should be treated as a whole. Examples of object elements:\n * `image`, `table`, `video`, etc. **Note:** An object is also a limit, so\n * {@link module:engine/model/schema~Schema#isLimit `isLimit()`} returns `true` for object elements automatically.\n * * `isInline` &ndash; Whether an item is \"text-like\" and should be treated as an inline node. Examples of inline elements:\n * `$text`, `softBreak` (`<br>`), etc.\n *\n * # Generic items\n *\n * There are three basic generic items: `$root`, `$block` and `$text`.\n * They are defined as follows:\n *\n *\t\tthis.schema.register( '$root', {\n *\t\t\tisLimit: true\n *\t\t} );\n *\t\tthis.schema.register( '$block', {\n *\t\t\tallowIn: '$root',\n *\t\t\tisBlock: true\n *\t\t} );\n *\t\tthis.schema.register( '$text', {\n *\t\t\tallowIn: '$block',\n *\t\t\tisInline: true\n *\t\t} );\n *\n * They reflect typical editor content that is contained within one root, consists of several blocks\n * (paragraphs, lists items, headings, images) which, in turn, may contain text inside.\n *\n * By inheriting from the generic items you can define new items which will get extended by other editor features.\n * Read more about generic types in the {@linkTODO Defining schema} guide.\n *\n * # Example definitions\n *\n * Allow `paragraph` in roots and block quotes:\n *\n *\t\tschema.register( 'paragraph', {\n *\t\t\tallowIn: [ '$root', 'blockQuote' ],\n *\t\t\tisBlock: true\n *\t\t} );\n *\n * Allow `paragraph` everywhere where `$block` is allowed (i.e. in `$root`):\n *\n *\t\tschema.register( 'paragraph', {\n *\t\t\tallowWhere: '$block',\n *\t\t\tisBlock: true\n *\t\t} );\n *\n * Make `image` a block object, which is allowed everywhere where `$block` is.\n * Also, allow `src` and `alt` attributes in it:\n *\n *\t\tschema.register( 'image', {\n *\t\t\tallowWhere: '$block',\n *\t\t\tallowAttributes: [ 'src', 'alt' ],\n *\t\t\tisBlock: true,\n *\t\t\tisObject: true\n *\t\t} );\n *\n * Make `caption` allowed in `image` and make it allow all the content of `$block`s (usually, `$text`).\n * Also, mark it as a limit element so it cannot be split:\n *\n *\t\tschema.register( 'caption', {\n *\t\t\tallowIn: 'image',\n *\t\t\tallowContentOf: '$block',\n *\t\t\tisLimit: true\n *\t\t} );\n *\n * Make `listItem` inherit all from `$block` but also allow additional attributes:\n *\n *\t\tschema.register( 'listItem', {\n *\t\t\tinheritAllFrom: '$block',\n *\t\t\tallowAttributes: [ 'listType', 'listIndent' ]\n *\t\t} );\n *\n * Which translates to:\n *\n *\t\tschema.register( 'listItem', {\n *\t\t\tallowWhere: '$block',\n *\t\t\tallowContentOf: '$block',\n *\t\t\tallowAttributesOf: '$block',\n *\t\t\tinheritTypesFrom: '$block',\n *\t\t\tallowAttributes: [ 'listType', 'listIndent' ]\n *\t\t} );\n *\n * # Tips\n *\n * * Check schema definitions of existing features to see how they are defined.\n * * If you want to publish your feature so other developers can use it, try to use\n * generic items as much as possible.\n * * Keep your model clean. Limit it to the actual data and store information in a normalized way.\n * * Remember about definining the `is*` properties. They do not affect the allowed structures, but they can\n * affect how the editor features treat your elements.\n *\n * @typedef {Object} module:engine/model/schema~SchemaItemDefinition\n */\n\n/**\n * A simplified version of {@link module:engine/model/schema~SchemaItemDefinition} after\n * compilation by the {@link module:engine/model/schema~Schema schema}.\n * Rules fed to the schema by {@link module:engine/model/schema~Schema#register}\n * and {@link module:engine/model/schema~Schema#extend} methods are defined in the\n * {@link module:engine/model/schema~SchemaItemDefinition} format.\n * Later on, they are compiled to `SchemaCompiledItemDefition` so when you use e.g.\n * the {@link module:engine/model/schema~Schema#getDefinition} method you get the compiled version.\n *\n * The compiled version contains only the following properties:\n *\n * * The `name` property,\n * * The `is*` properties,\n * * The `allowIn` array,\n * * The `allowAttributes` array.\n *\n * @typedef {Object} module:engine/model/schema~SchemaCompiledItemDefinition\n */\n\n/**\n * A schema context &mdash; a list of ancestors of a given position in the document.\n *\n * Considering such position:\n *\n *\t\t<$root>\n *\t\t\t<blockQuote>\n *\t\t\t\t<paragraph>\n *\t\t\t\t\t^\n *\t\t\t\t</paragraph>\n *\t\t\t</blockQuote>\n *\t\t</$root>\n *\n * The context of this position is its {@link module:engine/model/position~Position#getAncestors lists of ancestors}:\n *\n *\t\t[ rootElement, blockQuoteElement, paragraphElement ]\n *\n * Contexts are used in the {@link module:engine/model/schema~Schema#event:checkChild `Schema#checkChild`} and\n * {@link module:engine/model/schema~Schema#event:checkAttribute `Schema#checkAttribute`} events as a definition\n * of a place in the document where the check occurs. The context instances are created based on the first arguments\n * of the {@link module:engine/model/schema~Schema#checkChild `Schema#checkChild()`} and\n * {@link module:engine/model/schema~Schema#checkAttribute `Schema#checkAttribute()`} methods so when\n * using these methods you need to use {@link module:engine/model/schema~SchemaContextDefinition}s.\n */\nexport class SchemaContext {\n\t/**\n\t * Creates an instance of the context.\n\t *\n\t * @param {module:engine/model/schema~SchemaContextDefinition} context\n\t */\n\tconstructor( context ) {\n\t\tif ( context instanceof SchemaContext ) {\n\t\t\treturn context;\n\t\t}\n\n\t\tif ( typeof context == 'string' ) {\n\t\t\tcontext = [ context ];\n\t\t} else if ( !Array.isArray( context ) ) {\n\t\t\t// `context` is item or position.\n\t\t\t// Position#getAncestors() doesn't accept any parameters but it works just fine here.\n\t\t\tcontext = context.getAncestors( { includeSelf: true } );\n\t\t}\n\n\t\tif ( context[ 0 ] && typeof context[ 0 ] != 'string' && context[ 0 ].is( 'documentFragment' ) ) {\n\t\t\tcontext.shift();\n\t\t}\n\n\t\tthis._items = context.map( mapContextItem );\n\t}\n\n\t/**\n\t * The number of items.\n\t *\n\t * @type {Number}\n\t */\n\tget length() {\n\t\treturn this._items.length;\n\t}\n\n\t/**\n\t * The last item (the lowest node).\n\t *\n\t * @type {module:engine/model/schema~SchemaContextItem}\n\t */\n\tget last() {\n\t\treturn this._items[ this._items.length - 1 ];\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * Iterates over all context items.\n\t *\n\t * @returns {Iterable.<module:engine/model/schema~SchemaContextItem>}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this._items[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Returns a new schema context instance with an additional item.\n\t *\n\t * Item can be added as:\n\t *\n\t * \t\tconst context = new SchemaContext( [ '$root' ] );\n\t *\n\t * \t\t// An element.\n\t * \t\tconst fooElement = writer.createElement( 'fooElement' );\n\t * \t\tconst newContext = context.push( fooElement ); // [ '$root', 'fooElement' ]\n\t *\n\t * \t\t// A text node.\n\t * \t\tconst text = writer.createText( 'foobar' );\n\t * \t\tconst newContext = context.push( text ); // [ '$root', '$text' ]\n\t *\n\t * \t\t// A string (element name).\n\t * \t\tconst newContext = context.push( 'barElement' ); // [ '$root', 'barElement' ]\n\t *\n\t * **Note** {@link module:engine/model/node~Node} that is already in the model tree will be added as the only item\n\t * (without ancestors).\n\t *\n\t * @param {String|module:engine/model/node~Node|Array<String|module:engine/model/node~Node>} item An item that will be added\n\t * to the current context.\n\t * @returns {module:engine/model/schema~SchemaContext} A new schema context instance with an additional item.\n\t */\n\tpush( item ) {\n\t\tconst ctx = new SchemaContext( [ item ] );\n\n\t\tctx._items = [ ...this._items, ...ctx._items ];\n\n\t\treturn ctx;\n\t}\n\n\t/**\n\t * Gets an item on the given index.\n\t *\n\t * @returns {module:engine/model/schema~SchemaContextItem}\n\t */\n\tgetItem( index ) {\n\t\treturn this._items[ index ];\n\t}\n\n\t/**\n\t * Returns the names of items.\n\t *\n\t * @returns {Iterable.<String>}\n\t */\n\t* getNames() {\n\t\tyield* this._items.map( item => item.name );\n\t}\n\n\t/**\n\t * Checks whether the context ends with the given nodes.\n\t *\n\t *\t\tconst ctx = new SchemaContext( [ rootElement, paragraphElement, textNode ] );\n\t *\n\t *\t\tctx.endsWith( '$text' ); // -> true\n\t *\t\tctx.endsWith( 'paragraph $text' ); // -> true\n\t *\t\tctx.endsWith( '$root' ); // -> false\n\t *\t\tctx.endsWith( 'paragraph' ); // -> false\n\t *\n\t * @param {String} query\n\t * @returns {Boolean}\n\t */\n\tendsWith( query ) {\n\t\treturn Array.from( this.getNames() ).join( ' ' ).endsWith( query );\n\t}\n}\n\n/**\n * The definition of a {@link module:engine/model/schema~SchemaContext schema context}.\n *\n * Contexts can be created in multiple ways:\n *\n * * By defining a **node** – in this cases this node and all its ancestors will be used.\n * * By defining a **position** in the document – in this case all its ancestors will be used.\n * * By defining an **array of nodes** – in this case this array defines the entire context.\n * * By defining a **name of node** - in this case node will be \"mocked\". It is not recommended because context\n * will be unrealistic (e.g. attributes of these nodes are not specified). However, at times this may be the only\n * way to define the context (e.g. when checking some hypothetical situation).\n * * By defining an **array of node names** (potentially, mixed with real nodes) – The same as **name of node**\n * but it is possible to create a path.\n * * By defining a {@link module:engine/model/schema~SchemaContext} instance - in this case the same instance as provided\n * will be return.\n *\n * Examples of context definitions passed to the {@link module:engine/model/schema~Schema#checkChild `Schema#checkChild()`}\n * method:\n *\n *\t\t// Assuming that we have a $root > blockQuote > paragraph structure, the following code\n *\t\t// will check node 'foo' in the following context:\n *\t\t// [ rootElement, blockQuoteElement, paragraphElement ]\n *\t\tconst contextDefinition = paragraphElement;\n * \t\tconst childToCheck = 'foo';\n *\t\tschema.checkChild( contextDefinition, childToCheck );\n *\n *\t\t// Also check in [ rootElement, blockQuoteElement, paragraphElement ].\n *\t\tschema.checkChild( model.createPositionAt( paragraphElement, 0 ), 'foo' );\n *\n *\t\t// Check in [ rootElement, paragraphElement ].\n *\t\tschema.checkChild( [ rootElement, paragraphElement ], 'foo' );\n *\n *\t\t// Check only fakeParagraphElement.\n *\t\tschema.checkChild( 'paragraph', 'foo' );\n *\n *\t\t// Check in [ fakeRootElement, fakeBarElement, paragraphElement ].\n *\t\tschema.checkChild( [ '$root', 'bar', paragraphElement ], 'foo' );\n *\n * All these `checkChild()` calls will fire {@link module:engine/model/schema~Schema#event:checkChild `Schema#checkChild`}\n * events in which `args[ 0 ]` is an instance of the context. Therefore, you can write a listener like this:\n *\n *\t\tschema.on( 'checkChild', ( evt, args ) => {\n *\t\t\tconst ctx = args[ 0 ];\n *\n *\t\t\tconsole.log( Array.from( ctx.getNames() ) );\n *\t\t} );\n *\n * Which will log the following:\n *\n *\t\t[ '$root', 'blockQuote', 'paragraph' ]\n *\t\t[ '$root', 'paragraph' ]\n *\t\t[ '$root', 'bar', 'paragraph' ]\n *\n * Note: When using the {@link module:engine/model/schema~Schema#checkAttribute `Schema#checkAttribute()`} method\n * you may want to check whether a text node may have an attribute. A {@link module:engine/model/text~Text} is a\n * correct way to define a context so you can do this:\n *\n *\t\tschema.checkAttribute( textNode, 'bold' );\n *\n * But sometimes you want to check whether a text at a given position might've had some attribute,\n * in which case you can create a context by mising an array of elements with a `'$text'` string:\n *\n *\t\t// Check in [ rootElement, paragraphElement, textNode ].\n *\t\tschema.checkChild( [ ...positionInParagraph.getAncestors(), '$text' ], 'bold' );\n *\n * @typedef {module:engine/model/node~Node|module:engine/model/position~Position|module:engine/model/schema~SchemaContext|\n * String|Array.<String|module:engine/model/node~Node>} module:engine/model/schema~SchemaContextDefinition\n */\n\n/**\n * An item of the {@link module:engine/model/schema~SchemaContext schema context}.\n *\n * It contains 3 properties:\n *\n * * `name` – the name of this item,\n * * `* getAttributeKeys()` – a generator of keys of item attributes,\n * * `getAttribute( keyName )` – a method to get attribute values.\n *\n * The context item interface is a highly simplified version of {@link module:engine/model/node~Node} and its role\n * is to expose only the information which schema checks are able to provide (which is the name of the node and\n * node's attributes).\n *\n *\t\tschema.on( 'checkChild', ( evt, args ) => {\n *\t\t\tconst ctx = args[ 0 ];\n *\t\t\tconst firstItem = ctx.getItem( 0 );\n *\n *\t\t\tconsole.log( firstItem.name ); // -> '$root'\n *\t\t\tconsole.log( firstItem.getAttribute( 'foo' ) ); // -> 'bar'\n *\t\t\tconsole.log( Array.from( firstItem.getAttributeKeys() ) ); // -> [ 'foo', 'faa' ]\n *\t\t} );\n *\n * @typedef {Object} module:engine/model/schema~SchemaContextItem\n */\n\n/**\n * A structure containing additional metadata describing the attribute.\n *\n * See {@link module:engine/model/schema~Schema#setAttributeProperties `Schema#setAttributeProperties()`} for usage examples.\n *\n * @typedef {Object} module:engine/model/schema~AttributeProperties\n * @property {Boolean} [isFormatting] Indicates that the attribute should be considered as a visual formatting, like `bold`, `italic` or\n * `fontSize` rather than semantic attribute (such as `src`, `listType`, etc.). For example, it is used by the \"Remove format\" feature.\n */\n\nfunction compileBaseItemRule( sourceItemRules, itemName ) {\n\tconst itemRule = {\n\t\tname: itemName,\n\n\t\tallowIn: [],\n\t\tallowContentOf: [],\n\t\tallowWhere: [],\n\n\t\tallowAttributes: [],\n\t\tallowAttributesOf: [],\n\n\t\tinheritTypesFrom: []\n\t};\n\n\tcopyTypes( sourceItemRules, itemRule );\n\n\tcopyProperty( sourceItemRules, itemRule, 'allowIn' );\n\tcopyProperty( sourceItemRules, itemRule, 'allowContentOf' );\n\tcopyProperty( sourceItemRules, itemRule, 'allowWhere' );\n\n\tcopyProperty( sourceItemRules, itemRule, 'allowAttributes' );\n\tcopyProperty( sourceItemRules, itemRule, 'allowAttributesOf' );\n\n\tcopyProperty( sourceItemRules, itemRule, 'inheritTypesFrom' );\n\n\tmakeInheritAllWork( sourceItemRules, itemRule );\n\n\treturn itemRule;\n}\n\nfunction compileAllowContentOf( compiledDefinitions, itemName ) {\n\tfor ( const allowContentOfItemName of compiledDefinitions[ itemName ].allowContentOf ) {\n\t\t// The allowContentOf property may point to an unregistered element.\n\t\tif ( compiledDefinitions[ allowContentOfItemName ] ) {\n\t\t\tconst allowedChildren = getAllowedChildren( compiledDefinitions, allowContentOfItemName );\n\n\t\t\tallowedChildren.forEach( allowedItem => {\n\t\t\t\tallowedItem.allowIn.push( itemName );\n\t\t\t} );\n\t\t}\n\t}\n\n\tdelete compiledDefinitions[ itemName ].allowContentOf;\n}\n\nfunction compileAllowWhere( compiledDefinitions, itemName ) {\n\tfor ( const allowWhereItemName of compiledDefinitions[ itemName ].allowWhere ) {\n\t\tconst inheritFrom = compiledDefinitions[ allowWhereItemName ];\n\n\t\t// The allowWhere property may point to an unregistered element.\n\t\tif ( inheritFrom ) {\n\t\t\tconst allowedIn = inheritFrom.allowIn;\n\n\t\t\tcompiledDefinitions[ itemName ].allowIn.push( ...allowedIn );\n\t\t}\n\t}\n\n\tdelete compiledDefinitions[ itemName ].allowWhere;\n}\n\nfunction compileAllowAttributesOf( compiledDefinitions, itemName ) {\n\tfor ( const allowAttributeOfItem of compiledDefinitions[ itemName ].allowAttributesOf ) {\n\t\tconst inheritFrom = compiledDefinitions[ allowAttributeOfItem ];\n\n\t\tif ( inheritFrom ) {\n\t\t\tconst inheritAttributes = inheritFrom.allowAttributes;\n\n\t\t\tcompiledDefinitions[ itemName ].allowAttributes.push( ...inheritAttributes );\n\t\t}\n\t}\n\n\tdelete compiledDefinitions[ itemName ].allowAttributesOf;\n}\n\nfunction compileInheritPropertiesFrom( compiledDefinitions, itemName ) {\n\tconst item = compiledDefinitions[ itemName ];\n\n\tfor ( const inheritPropertiesOfItem of item.inheritTypesFrom ) {\n\t\tconst inheritFrom = compiledDefinitions[ inheritPropertiesOfItem ];\n\n\t\tif ( inheritFrom ) {\n\t\t\tconst typeNames = Object.keys( inheritFrom ).filter( name => name.startsWith( 'is' ) );\n\n\t\t\tfor ( const name of typeNames ) {\n\t\t\t\tif ( !( name in item ) ) {\n\t\t\t\t\titem[ name ] = inheritFrom[ name ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tdelete item.inheritTypesFrom;\n}\n\n// Remove items which weren't registered (because it may break some checks or we'd need to complicate them).\n// Make sure allowIn doesn't contain repeated values.\nfunction cleanUpAllowIn( compiledDefinitions, itemName ) {\n\tconst itemRule = compiledDefinitions[ itemName ];\n\tconst existingItems = itemRule.allowIn.filter( itemToCheck => compiledDefinitions[ itemToCheck ] );\n\n\titemRule.allowIn = Array.from( new Set( existingItems ) );\n}\n\nfunction cleanUpAllowAttributes( compiledDefinitions, itemName ) {\n\tconst itemRule = compiledDefinitions[ itemName ];\n\n\titemRule.allowAttributes = Array.from( new Set( itemRule.allowAttributes ) );\n}\n\nfunction copyTypes( sourceItemRules, itemRule ) {\n\tfor ( const sourceItemRule of sourceItemRules ) {\n\t\tconst typeNames = Object.keys( sourceItemRule ).filter( name => name.startsWith( 'is' ) );\n\n\t\tfor ( const name of typeNames ) {\n\t\t\titemRule[ name ] = sourceItemRule[ name ];\n\t\t}\n\t}\n}\n\nfunction copyProperty( sourceItemRules, itemRule, propertyName ) {\n\tfor ( const sourceItemRule of sourceItemRules ) {\n\t\tif ( typeof sourceItemRule[ propertyName ] == 'string' ) {\n\t\t\titemRule[ propertyName ].push( sourceItemRule[ propertyName ] );\n\t\t} else if ( Array.isArray( sourceItemRule[ propertyName ] ) ) {\n\t\t\titemRule[ propertyName ].push( ...sourceItemRule[ propertyName ] );\n\t\t}\n\t}\n}\n\nfunction makeInheritAllWork( sourceItemRules, itemRule ) {\n\tfor ( const sourceItemRule of sourceItemRules ) {\n\t\tconst inheritFrom = sourceItemRule.inheritAllFrom;\n\n\t\tif ( inheritFrom ) {\n\t\t\titemRule.allowContentOf.push( inheritFrom );\n\t\t\titemRule.allowWhere.push( inheritFrom );\n\t\t\titemRule.allowAttributesOf.push( inheritFrom );\n\t\t\titemRule.inheritTypesFrom.push( inheritFrom );\n\t\t}\n\t}\n}\n\nfunction getAllowedChildren( compiledDefinitions, itemName ) {\n\tconst itemRule = compiledDefinitions[ itemName ];\n\n\treturn getValues( compiledDefinitions ).filter( def => def.allowIn.includes( itemRule.name ) );\n}\n\nfunction getValues( obj ) {\n\treturn Object.keys( obj ).map( key => obj[ key ] );\n}\n\nfunction mapContextItem( ctxItem ) {\n\tif ( typeof ctxItem == 'string' ) {\n\t\treturn {\n\t\t\tname: ctxItem,\n\n\t\t\t* getAttributeKeys() {},\n\n\t\t\tgetAttribute() {}\n\t\t};\n\t} else {\n\t\treturn {\n\t\t\t// '$text' means text nodes and text proxies.\n\t\t\tname: ctxItem.is( 'element' ) ? ctxItem.name : '$text',\n\n\t\t\t* getAttributeKeys() {\n\t\t\t\tyield* ctxItem.getAttributeKeys();\n\t\t\t},\n\n\t\t\tgetAttribute( key ) {\n\t\t\t\treturn ctxItem.getAttribute( key );\n\t\t\t}\n\t\t};\n\t}\n}\n\n// Generator function returning values from provided walkers, switching between them at each iteration. If only one walker\n// is provided it will return data only from that walker.\n//\n// @param {module:engine/module/treewalker~TreeWalker} [backward] Walker iterating in backward direction.\n// @param {module:engine/module/treewalker~TreeWalker} [forward] Walker iterating in forward direction.\n// @returns {Iterable.<Object>} Object returned at each iteration contains `value` and `walker` (informing which walker returned\n// given value) fields.\nfunction* combineWalkers( backward, forward ) {\n\tlet done = false;\n\n\twhile ( !done ) {\n\t\tdone = true;\n\n\t\tif ( backward ) {\n\t\t\tconst step = backward.next();\n\n\t\t\tif ( !step.done ) {\n\t\t\t\tdone = false;\n\t\t\t\tyield {\n\t\t\t\t\twalker: backward,\n\t\t\t\t\tvalue: step.value\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( forward ) {\n\t\t\tconst step = forward.next();\n\n\t\t\tif ( !step.done ) {\n\t\t\t\tdone = false;\n\t\t\t\tyield {\n\t\t\t\t\twalker: forward,\n\t\t\t\t\tvalue: step.value\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Takes an array of non-intersecting ranges. For each of them gets minimal flat ranges covering that range and returns\n// all those minimal flat ranges.\n//\n// @param {Array.<module:engine/model/range~Range>} ranges Ranges to process.\n// @returns {Iterable.<module:engine/model/range~Range>} Minimal flat ranges of given `ranges`.\nfunction* convertToMinimalFlatRanges( ranges ) {\n\tfor ( const range of ranges ) {\n\t\tyield* range.getMinimalFlatRanges();\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/conversion/upcastdispatcher\n */\n\nimport ViewConsumable from './viewconsumable';\nimport ModelRange from '../model/range';\nimport ModelPosition from '../model/position';\nimport { SchemaContext } from '../model/schema';\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * `UpcastDispatcher` is a central point of {@link module:engine/view/view view} conversion, which is a process of\n * converting given {@link module:engine/view/documentfragment~DocumentFragment view document fragment} or\n * {@link module:engine/view/element~Element} into another structure.\n * In default application, {@link module:engine/view/view view} is converted to {@link module:engine/model/model}.\n *\n * During conversion process, for all {@link module:engine/view/node~Node view nodes} from the converted view document fragment,\n * `UpcastDispatcher` fires corresponding events. Special callbacks called \"converters\" should listen to\n * `UpcastDispatcher` for those events.\n *\n * Each callback, as the second argument, is passed a special object `data` that has `viewItem`, `modelCursor` and\n * `modelRange` properties. `viewItem` property contains {@link module:engine/view/node~Node view node} or\n * {@link module:engine/view/documentfragment~DocumentFragment view document fragment}\n * that is converted at the moment and might be handled by the callback. `modelRange` property should be used to save the result\n * of conversion and is always a {@link module:engine/model/range~Range} when conversion result is correct.\n * `modelCursor` property is a {@link module:engine/model/position~Position position} on which conversion result will be inserted\n * and is a context according to {@link module:engine/model/schema~Schema schema} will be checked before the conversion.\n * See also {@link ~UpcastDispatcher#convert}. It is also shared by reference by all callbacks listening to given event.\n *\n * The third parameter passed to a callback is an instance of {@link ~UpcastDispatcher}\n * which provides additional tools for converters.\n *\n * Examples of providing callbacks for `UpcastDispatcher`:\n *\n *\t\t// Converter for links (<a>).\n *\t\tupcastDispatcher.on( 'element:a', ( evt, data, conversionApi ) => {\n *\t\t\tif ( conversionApi.consumable.consume( data.viewItem, { name: true, attributes: [ 'href' ] } ) ) {\n *\t\t\t\t// <a> element is inline and is represented by an attribute in the model.\n *\t\t\t\t// This is why we need to convert only children.\n *\t\t\t\tconst { modelRange } = conversionApi.convertChildren( data.viewItem, data.modelCursor );\n *\n *\t\t\t\tfor ( let item of modelRange.getItems() ) {\n *\t\t\t\t\tif ( conversionApi.schema.checkAttribute( item, 'linkHref' ) ) {\n *\t\t\t\t\t\tconversionApi.writer.setAttribute( 'linkHref', data.viewItem.getAttribute( 'href' ), item );\n *\t\t\t\t\t}\n *\t\t\t\t}\n *\t\t\t}\n *\t\t} );\n *\n *\t\t// Convert all elements which have no custom converter into paragraph (autoparagraphing).\n * \tdata.viewToModel.on( 'element', ( evt, data, conversionApi ) => {\n * \t \t// When element is already consumed by higher priority converters then do nothing.\n * \t \tif ( conversionApi.consumable.test( data.viewItem, { name: data.viewItem.name } ) ) {\n * \t \t\t\tconst paragraph = conversionApi.writer.createElement( 'paragraph' );\n *\n * \t \t\t\t// Find allowed parent for paragraph that we are going to insert. If current parent does not allow\n * \t \t\t\t// to insert paragraph but one of the ancestors does then split nodes to allowed parent.\n * \t \t\t\tconst splitResult = conversionApi.splitToAllowedParent( paragraph, data.modelCursor );\n *\n * \t \t\t\t// When there is no split result it means that we can't insert paragraph in this position.\n * \t \t\t\tif ( splitResult ) {\n * \t \t\t\t\t// Insert paragraph in allowed position.\n * \t \t\t\t\tconversionApi.writer.insert( paragraph, splitResult.position );\n *\n * \t \t\t\t\t// Convert children to paragraph.\n * \t \t\t\t\tconst { modelRange } = conversionApi.convertChildren(\n * \t \t\t\t\t\tdata.viewItem,\n * \t \t\t\t\t\tconversionApi.writer.createPositionAt( paragraph, 0 )\n * \t \t\t\t\t);\n *\n * \t\t\t\t\t\t// Set as conversion result, attribute converters may use this property.\n * \t \t\t\t\tdata.modelRange = conversionApi.writer.createRange(\n * \t \t\t\t\t\tconversionApi.writer.createPositionBefore( paragraph ),\n * \t \t\t\t\t\tmodelRange.end\n * \t \t\t\t\t);\n *\n * \t \t\t\t\t// Continue conversion inside paragraph.\n * \t \t\t\t\tdata.modelCursor = data.modelRange.end;\n * \t \t\t\t}\n * \t \t\t}\n * \t \t}\n * \t }, { priority: 'low' } );\n *\n * Before each conversion process, `UpcastDispatcher` fires {@link ~UpcastDispatcher#event:viewCleanup}\n * event which can be used to prepare tree view for conversion.\n *\n * @mixes module:utils/emittermixin~EmitterMixin\n * @fires viewCleanup\n * @fires element\n * @fires text\n * @fires documentFragment\n */\nexport default class UpcastDispatcher {\n\t/**\n\t * Creates a `UpcastDispatcher` that operates using passed API.\n\t *\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi\n\t * @param {Object} [conversionApi] Additional properties for interface that will be passed to events fired\n\t * by `UpcastDispatcher`.\n\t */\n\tconstructor( conversionApi = {} ) {\n\t\t/**\n\t\t * List of the elements that were created during splitting.\n\t\t *\n\t\t * After conversion process the list is cleared.\n\t\t *\n\t\t * @private\n\t\t * @type {Map.<module:engine/model/element~Element,Array.<module:engine/model/element~Element>>}\n\t\t */\n\t\tthis._splitParts = new Map();\n\n\t\t/**\n\t\t * Position in the temporary structure where the converted content is inserted. The structure reflect the context of\n\t\t * the target position where the content will be inserted. This property is build based on the context parameter of the\n\t\t * convert method.\n\t\t *\n\t\t * @private\n\t\t * @type {module:engine/model/position~Position|null}\n\t\t */\n\t\tthis._modelCursor = null;\n\n\t\t/**\n\t\t * Interface passed by dispatcher to the events callbacks.\n\t\t *\n\t\t * @member {module:engine/conversion/upcastdispatcher~UpcastConversionApi}\n\t\t */\n\t\tthis.conversionApi = Object.assign( {}, conversionApi );\n\n\t\t// `convertItem`, `convertChildren` and `splitToAllowedParent` are bound to this `UpcastDispatcher`\n\t\t// instance and set on `conversionApi`. This way only a part of `UpcastDispatcher` API is exposed.\n\t\tthis.conversionApi.convertItem = this._convertItem.bind( this );\n\t\tthis.conversionApi.convertChildren = this._convertChildren.bind( this );\n\t\tthis.conversionApi.splitToAllowedParent = this._splitToAllowedParent.bind( this );\n\t\tthis.conversionApi.getSplitParts = this._getSplitParts.bind( this );\n\t}\n\n\t/**\n\t * Starts the conversion process. The entry point for the conversion.\n\t *\n\t * @fires element\n\t * @fires text\n\t * @fires documentFragment\n\t * @param {module:engine/view/documentfragment~DocumentFragment|module:engine/view/element~Element} viewItem\n\t * Part of the view to be converted.\n\t * @param {module:engine/model/writer~Writer} writer Instance of model writer.\n\t * @param {module:engine/model/schema~SchemaContextDefinition} [context=['$root']] Elements will be converted according to this context.\n\t * @returns {module:engine/model/documentfragment~DocumentFragment} Model data that is a result of the conversion process\n\t * wrapped in `DocumentFragment`. Converted marker elements will be set as that document fragment's\n\t * {@link module:engine/model/documentfragment~DocumentFragment#markers static markers map}.\n\t */\n\tconvert( viewItem, writer, context = [ '$root' ] ) {\n\t\tthis.fire( 'viewCleanup', viewItem );\n\n\t\t// Create context tree and set position in the top element.\n\t\t// Items will be converted according to this position.\n\t\tthis._modelCursor = createContextTree( context, writer );\n\n\t\t// Store writer in conversion as a conversion API\n\t\t// to be sure that conversion process will use the same batch.\n\t\tthis.conversionApi.writer = writer;\n\n\t\t// Create consumable values list for conversion process.\n\t\tthis.conversionApi.consumable = ViewConsumable.createFrom( viewItem );\n\n\t\t// Custom data stored by converter for conversion process.\n\t\tthis.conversionApi.store = {};\n\n\t\t// Do the conversion.\n\t\tconst { modelRange } = this._convertItem( viewItem, this._modelCursor );\n\n\t\t// Conversion result is always a document fragment so let's create it.\n\t\tconst documentFragment = writer.createDocumentFragment();\n\n\t\t// When there is a conversion result.\n\t\tif ( modelRange ) {\n\t\t\t// Remove all empty elements that were create while splitting.\n\t\t\tthis._removeEmptyElements();\n\n\t\t\t// Move all items that were converted in context tree to the document fragment.\n\t\t\tfor ( const item of Array.from( this._modelCursor.parent.getChildren() ) ) {\n\t\t\t\twriter.append( item, documentFragment );\n\t\t\t}\n\n\t\t\t// Extract temporary markers elements from model and set as static markers collection.\n\t\t\tdocumentFragment.markers = extractMarkersFromModelFragment( documentFragment, writer );\n\t\t}\n\n\t\t// Clear context position.\n\t\tthis._modelCursor = null;\n\n\t\t// Clear split elements lists.\n\t\tthis._splitParts.clear();\n\n\t\t// Clear conversion API.\n\t\tthis.conversionApi.writer = null;\n\t\tthis.conversionApi.store = null;\n\n\t\t// Return fragment as conversion result.\n\t\treturn documentFragment;\n\t}\n\n\t/**\n\t * @private\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#convertItem\n\t */\n\t_convertItem( viewItem, modelCursor ) {\n\t\tconst data = Object.assign( { viewItem, modelCursor, modelRange: null } );\n\n\t\tif ( viewItem.is( 'element' ) ) {\n\t\t\tthis.fire( 'element:' + viewItem.name, data, this.conversionApi );\n\t\t} else if ( viewItem.is( 'text' ) ) {\n\t\t\tthis.fire( 'text', data, this.conversionApi );\n\t\t} else {\n\t\t\tthis.fire( 'documentFragment', data, this.conversionApi );\n\t\t}\n\n\t\t// Handle incorrect conversion result.\n\t\tif ( data.modelRange && !( data.modelRange instanceof ModelRange ) ) {\n\t\t\t/**\n\t\t\t * Incorrect conversion result was dropped.\n\t\t\t *\n\t\t\t * {@link module:engine/model/range~Range Model range} should be a conversion result.\n\t\t\t *\n\t\t\t * @error view-conversion-dispatcher-incorrect-result\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-conversion-dispatcher-incorrect-result: Incorrect conversion result was dropped.' );\n\t\t}\n\n\t\treturn { modelRange: data.modelRange, modelCursor: data.modelCursor };\n\t}\n\n\t/**\n\t * @private\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#convertChildren\n\t */\n\t_convertChildren( viewItem, modelCursor ) {\n\t\tconst modelRange = new ModelRange( modelCursor );\n\t\tlet nextModelCursor = modelCursor;\n\n\t\tfor ( const viewChild of Array.from( viewItem.getChildren() ) ) {\n\t\t\tconst result = this._convertItem( viewChild, nextModelCursor );\n\n\t\t\tif ( result.modelRange instanceof ModelRange ) {\n\t\t\t\tmodelRange.end = result.modelRange.end;\n\t\t\t\tnextModelCursor = result.modelCursor;\n\t\t\t}\n\t\t}\n\n\t\treturn { modelRange, modelCursor: nextModelCursor };\n\t}\n\n\t/**\n\t * @private\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#splitToAllowedParent\n\t */\n\t_splitToAllowedParent( node, modelCursor ) {\n\t\t// Try to find allowed parent.\n\t\tconst allowedParent = this.conversionApi.schema.findAllowedParent( modelCursor, node );\n\n\t\t// When there is no parent that allows to insert node then return `null`.\n\t\tif ( !allowedParent ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// When current position parent allows to insert node then return this position.\n\t\tif ( allowedParent === modelCursor.parent ) {\n\t\t\treturn { position: modelCursor };\n\t\t}\n\n\t\t// When allowed parent is in context tree.\n\t\tif ( this._modelCursor.parent.getAncestors().includes( allowedParent ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Split element to allowed parent.\n\t\tconst splitResult = this.conversionApi.writer.split( modelCursor, allowedParent );\n\n\t\t// Using the range returned by `model.Writer#split`, we will pair original elements with their split parts.\n\t\t//\n\t\t// The range returned from the writer spans \"over the split\" or, precisely saying, from the end of the original element (the one\n\t\t// that got split) to the beginning of the other part of that element:\n\t\t//\n\t\t// <limit><a><b><c>X[]Y</c></b><a></limit> ->\n\t\t// <limit><a><b><c>X[</c></b></a><a><b><c>]Y</c></b></a>\n\t\t//\n\t\t// After the split there cannot be any full node between the positions in `splitRange`. The positions are touching.\n\t\t// Also, because of how splitting works, it is easy to notice, that \"closing tags\" are in the reverse order than \"opening tags\".\n\t\t// Also, since we split all those elements, each of them has to have the other part.\n\t\t//\n\t\t// With those observations in mind, we will pair the original elements with their split parts by saving \"closing tags\" and matching\n\t\t// them with \"opening tags\" in the reverse order. For that we can use a stack.\n\t\tconst stack = [];\n\n\t\tfor ( const treeWalkerValue of splitResult.range.getWalker() ) {\n\t\t\tif ( treeWalkerValue.type == 'elementEnd' ) {\n\t\t\t\tstack.push( treeWalkerValue.item );\n\t\t\t} else {\n\t\t\t\t// There should not be any text nodes after the element is split, so the only other value is `elementStart`.\n\t\t\t\tconst originalPart = stack.pop();\n\t\t\t\tconst splitPart = treeWalkerValue.item;\n\n\t\t\t\tthis._registerSplitPair( originalPart, splitPart );\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tposition: splitResult.position,\n\t\t\tcursorParent: splitResult.range.end.parent\n\t\t};\n\t}\n\n\t/**\n\t * Registers that `splitPart` element is a split part of the `originalPart` element.\n\t *\n\t * Data set by this method is used by {@link #_getSplitParts} and {@link #_removeEmptyElements}.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} originalPart\n\t * @param {module:engine/model/element~Element} splitPart\n\t */\n\t_registerSplitPair( originalPart, splitPart ) {\n\t\tif ( !this._splitParts.has( originalPart ) ) {\n\t\t\tthis._splitParts.set( originalPart, [ originalPart ] );\n\t\t}\n\n\t\tconst list = this._splitParts.get( originalPart );\n\n\t\tthis._splitParts.set( splitPart, list );\n\t\tlist.push( splitPart );\n\t}\n\n\t/**\n\t * @private\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#getSplitParts\n\t */\n\t_getSplitParts( element ) {\n\t\tlet parts;\n\n\t\tif ( !this._splitParts.has( element ) ) {\n\t\t\tparts = [ element ];\n\t\t} else {\n\t\t\tparts = this._splitParts.get( element );\n\t\t}\n\n\t\treturn parts;\n\t}\n\n\t/**\n\t * Checks if there are any empty elements created while splitting and removes them.\n\t *\n\t * This method works recursively to re-check empty elements again after at least one element was removed in the initial call,\n\t * as some elements might have become empty after other empty elements were removed from them.\n\t *\n\t * @private\n\t */\n\t_removeEmptyElements() {\n\t\tlet anyRemoved = false;\n\n\t\tfor ( const element of this._splitParts.keys() ) {\n\t\t\tif ( element.isEmpty ) {\n\t\t\t\tthis.conversionApi.writer.remove( element );\n\t\t\t\tthis._splitParts.delete( element );\n\n\t\t\t\tanyRemoved = true;\n\t\t\t}\n\t\t}\n\n\t\tif ( anyRemoved ) {\n\t\t\tthis._removeEmptyElements();\n\t\t}\n\t}\n\n\t/**\n\t * Fired before the first conversion event, at the beginning of upcast (view to model conversion) process.\n\t *\n\t * @event viewCleanup\n\t * @param {module:engine/view/documentfragment~DocumentFragment|module:engine/view/element~Element}\n\t * viewItem Part of the view to be converted.\n\t */\n\n\t/**\n\t * Fired when {@link module:engine/view/element~Element} is converted.\n\t *\n\t * `element` is a namespace event for a class of events. Names of actually called events follow this pattern:\n\t * `element:<elementName>` where `elementName` is the name of converted element. This way listeners may listen to\n\t * all elements conversion or to conversion of specific elements.\n\t *\n\t * @event element\n\t * @param {Object} data Conversion data. Keep in mind that this object is shared by reference between all\n\t * callbacks that will be called. This means that callbacks can override values if needed, and those values will\n\t * be available in other callbacks.\n\t * @param {module:engine/view/item~Item} data.viewItem Converted item.\n\t * @param {module:engine/model/position~Position} data.modelCursor Position where a converter should start changes.\n\t * Change this value for the next converter to tell where the conversion should continue.\n\t * @param {module:engine/model/range~Range} data.modelRange The current state of conversion result. Every change to\n\t * converted element should be reflected by setting or modifying this property.\n\t * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion utilities to be used by callback.\n\t */\n\n\t/**\n\t * Fired when {@link module:engine/view/text~Text} is converted.\n\t *\n\t * @event text\n\t * @see #event:element\n\t */\n\n\t/**\n\t * Fired when {@link module:engine/view/documentfragment~DocumentFragment} is converted.\n\t *\n\t * @event documentFragment\n\t * @see #event:element\n\t */\n}\n\nmix( UpcastDispatcher, EmitterMixin );\n\n// Traverses given model item and searches elements which marks marker range. Found element is removed from\n// DocumentFragment but path of this element is stored in a Map which is then returned.\n//\n// @param {module:engine/view/documentfragment~DocumentFragment|module:engine/view/node~Node} modelItem Fragment of model.\n// @returns {Map<String, module:engine/model/range~Range>} List of static markers.\nfunction extractMarkersFromModelFragment( modelItem, writer ) {\n\tconst markerElements = new Set();\n\tconst markers = new Map();\n\n\t// Create ModelTreeWalker.\n\tconst range = ModelRange._createIn( modelItem ).getItems();\n\n\t// Walk through DocumentFragment and collect marker elements.\n\tfor ( const item of range ) {\n\t\t// Check if current element is a marker.\n\t\tif ( item.name == '$marker' ) {\n\t\t\tmarkerElements.add( item );\n\t\t}\n\t}\n\n\t// Walk through collected marker elements store its path and remove its from the DocumentFragment.\n\tfor ( const markerElement of markerElements ) {\n\t\tconst markerName = markerElement.getAttribute( 'data-name' );\n\t\tconst currentPosition = writer.createPositionBefore( markerElement );\n\n\t\t// When marker of given name is not stored it means that we have found the beginning of the range.\n\t\tif ( !markers.has( markerName ) ) {\n\t\t\tmarkers.set( markerName, new ModelRange( currentPosition.clone() ) );\n\t\t// Otherwise is means that we have found end of the marker range.\n\t\t} else {\n\t\t\tmarkers.get( markerName ).end = currentPosition.clone();\n\t\t}\n\n\t\t// Remove marker element from DocumentFragment.\n\t\twriter.remove( markerElement );\n\t}\n\n\treturn markers;\n}\n\n// Creates model fragment according to given context and returns position in the bottom (the deepest) element.\nfunction createContextTree( contextDefinition, writer ) {\n\tlet position;\n\n\tfor ( const item of new SchemaContext( contextDefinition ) ) {\n\t\tconst attributes = {};\n\n\t\tfor ( const key of item.getAttributeKeys() ) {\n\t\t\tattributes[ key ] = item.getAttribute( key );\n\t\t}\n\n\t\tconst current = writer.createElement( item.name, attributes );\n\n\t\tif ( position ) {\n\t\t\twriter.append( current, position );\n\t\t}\n\n\t\tposition = ModelPosition._createAt( current, 0 );\n\t}\n\n\treturn position;\n}\n\n/**\n * Conversion interface that is registered for given {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher}\n * and is passed as one of parameters when {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher dispatcher}\n * fires it's events.\n *\n * @interface module:engine/conversion/upcastdispatcher~UpcastConversionApi\n */\n\n/**\n * Starts conversion of given item by firing an appropriate event.\n *\n * Every fired event is passed (as first parameter) an object with `modelRange` property. Every event may set and/or\n * modify that property. When all callbacks are done, the final value of `modelRange` property is returned by this method.\n * The `modelRange` must be {@link module:engine/model/range~Range model range} or `null` (as set by default).\n *\n * @method #convertItem\n * @fires module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n * @fires module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:text\n * @fires module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:documentFragment\n * @param {module:engine/view/item~Item} viewItem Item to convert.\n * @param {module:engine/model/position~Position} modelCursor Position of conversion.\n * @returns {Object} result Conversion result.\n * @returns {module:engine/model/range~Range|null} result.modelRange Model range containing result of item conversion,\n * created and modified by callbacks attached to fired event, or `null` if the conversion result was incorrect.\n * @returns {module:engine/model/position~Position} result.modelCursor Position where conversion should be continued.\n */\n\n/**\n * Starts conversion of all children of given item by firing appropriate events for all those children.\n *\n * @method #convertChildren\n * @fires module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n * @fires module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:text\n * @fires module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:documentFragment\n * @param {module:engine/view/item~Item} viewItem Element which children should be converted.\n * @param {module:engine/model/position~Position} modelCursor Position of conversion.\n * @returns {Object} result Conversion result.\n * @returns {module:engine/model/range~Range} result.modelRange Model range containing results of conversion of all children of given item.\n * When no children was converted then range is collapsed.\n * @returns {module:engine/model/position~Position} result.modelCursor Position where conversion should be continued.\n */\n\n/**\n * Checks {@link module:engine/model/schema~Schema schema} to find allowed parent for element that we are going to insert\n * starting from given position. If current parent does not allow to insert element but one of the ancestors does then\n * split nodes to allowed parent.\n *\n * If schema allows to insert node in given position, nothing is split and object with that position is returned.\n *\n * If it was not possible to find allowed parent, `null` is returned, nothing is split.\n *\n * Otherwise, ancestors are split and object with position and the copy of the split element is returned.\n *\n * For instance, if `<image>` is not allowed in `<paragraph>` but is allowed in `$root`:\n *\n *\t\t<paragraph>foo[]bar</paragraph>\n *\n * \t-> split for `<image>` ->\n *\n * \t<paragraph>foo</paragraph>[]<paragraph>bar</paragraph>\n *\n * In the sample above position between `<paragraph>` elements will be returned as `position` and the second `paragraph`\n * as `cursorParent`.\n *\n * @method #splitToAllowedParent\n * @param {module:engine/model/position~Position} position Position on which element is going to be inserted.\n * @param {module:engine/model/node~Node} node Node to insert.\n * @returns {Object|null} Split result. If it was not possible to find allowed position `null` is returned.\n * @returns {module:engine/model/position~Position} position between split elements.\n * @returns {module:engine/model/element~Element} [cursorParent] Element inside which cursor should be placed to\n * continue conversion. When element is not defined it means that there was no split.\n */\n\n/**\n * Returns all the split parts of given `element` that were created during upcasting through using {@link #splitToAllowedParent}.\n * It enables you to easily track those elements and continue processing them after they are split during their children conversion.\n *\n *\t\t<paragraph>Foo<image />bar<image />baz</paragraph> ->\n *\t\t<paragraph>Foo</paragraph><image /><paragraph>bar</paragraph><image /><paragraph>baz</paragraph>\n *\n * For a reference to any of above paragraphs, the function will return all three paragraphs (the original element included),\n * sorted in the order of their creation (the original element is the first one).\n *\n * If given `element` was not split, an array with single element is returned.\n *\n * Example of a usage in a converter code:\n *\n *\t\tconst myElement = conversionApi.writer.createElement( 'myElement' );\n *\n *\t\t// Children conversion may split `myElement`.\n *\t\tconversionApi.convertChildren( myElement, modelCursor );\n *\n *\t\tconst splitParts = conversionApi.getSplitParts( myElement );\n *\t\tconst lastSplitPart = splitParts[ splitParts.length - 1 ];\n *\n *\t\t// Setting `data.modelRange` basing on split parts:\n *\t\tdata.modelRange = conversionApi.writer.createRange(\n *\t\t\tconversionApi.writer.createPositionBefore( myElement ),\n *\t\t\tconversionApi.writer.createPositionAfter( lastSplitPart )\n *\t\t);\n *\n *\t\t// Setting `data.modelCursor` to continue after the last split element:\n *\t\tdata.modelCursor = conversionApi.writer.createPositionAfter( lastSplitPart );\n *\n * **Tip:** if you are unable to get a reference to the original element (for example because the code is split into multiple converters\n * or even classes) but it was already converted, you might want to check first element in `data.modelRange`. This is a common situation\n * if an attribute converter is separated from an element converter.\n *\n * @method #getSplitParts\n * @param {module:engine/model/element~Element} element\n * @returns {Array.<module:engine/model/element~Element>}\n */\n\n/**\n * Stores information about what parts of processed view item are still waiting to be handled. After a piece of view item\n * was converted, appropriate consumable value should be {@link module:engine/conversion/viewconsumable~ViewConsumable#consume consumed}.\n *\n * @member {module:engine/conversion/viewconsumable~ViewConsumable} #consumable\n */\n\n/**\n * Custom data stored by converters for conversion process. Custom properties of this object can be defined and use to\n * pass parameters between converters.\n *\n * The difference between this property and `data` parameter of\n * {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element} is that `data` parameters allows you\n * to pass parameters within a single event and `store` within the whole conversion.\n *\n * @member {Object} #store\n */\n\n/**\n * The model's schema instance.\n *\n * @member {module:engine/model/schema~Schema} #schema\n */\n\n/**\n * The {@link module:engine/model/writer~Writer} instance used to manipulate data during conversion.\n *\n * @member {module:engine/model/writer~Writer} #writer\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/controller/datacontroller\n */\n\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\nimport Mapper from '../conversion/mapper';\n\nimport DowncastDispatcher from '../conversion/downcastdispatcher';\nimport { insertText } from '../conversion/downcasthelpers';\n\nimport UpcastDispatcher from '../conversion/upcastdispatcher';\nimport { convertText, convertToModelFragment } from '../conversion/upcasthelpers';\n\nimport ViewDocumentFragment from '../view/documentfragment';\nimport ViewDocument from '../view/document';\nimport ViewDowncastWriter from '../view/downcastwriter';\n\nimport ModelRange from '../model/range';\n\n/**\n * Controller for the data pipeline. The data pipeline controls how data is retrieved from the document\n * and set inside it. Hence, the controller features two methods which allow to {@link ~DataController#get get}\n * and {@link ~DataController#set set} data of the {@link ~DataController#model model}\n * using given:\n *\n * * {@link module:engine/dataprocessor/dataprocessor~DataProcessor data processor},\n * * downcast converters,\n * * upcast converters.\n *\n * An instance of the data controller is always available in the {@link module:core/editor/editor~Editor#data `editor.data`}\n * property:\n *\n *\t\teditor.data.get( { rootName: 'customRoot' } ); // -> '<p>Hello!</p>'\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class DataController {\n\t/**\n\t * Creates a data controller instance.\n\t *\n\t * @param {module:engine/model/model~Model} model Data model.\n\t * @param {module:engine/dataprocessor/dataprocessor~DataProcessor} [dataProcessor] Data processor that should be used\n\t * by the controller.\n\t */\n\tconstructor( model, dataProcessor ) {\n\t\t/**\n\t\t * Data model.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/model~Model}\n\t\t */\n\t\tthis.model = model;\n\n\t\t/**\n\t\t * Data processor used during the conversion.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/dataprocessor/dataprocessor~DataProcessor}\n\t\t */\n\t\tthis.processor = dataProcessor;\n\n\t\t/**\n\t\t * Mapper used for the conversion. It has no permanent bindings, because they are created when getting data and\n\t\t * cleared directly after the data are converted. However, the mapper is defined as a class property, because\n\t\t * it needs to be passed to the `DowncastDispatcher` as a conversion API.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/conversion/mapper~Mapper}\n\t\t */\n\t\tthis.mapper = new Mapper();\n\n\t\t/**\n\t\t * Downcast dispatcher used by the {@link #get get method}. Downcast converters should be attached to it.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/conversion/downcastdispatcher~DowncastDispatcher}\n\t\t */\n\t\tthis.downcastDispatcher = new DowncastDispatcher( {\n\t\t\tmapper: this.mapper\n\t\t} );\n\t\tthis.downcastDispatcher.on( 'insert:$text', insertText(), { priority: 'lowest' } );\n\n\t\t/**\n\t\t * Upcast dispatcher used by the {@link #set set method}. Upcast converters should be attached to it.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/conversion/upcastdispatcher~UpcastDispatcher}\n\t\t */\n\t\tthis.upcastDispatcher = new UpcastDispatcher( {\n\t\t\tschema: model.schema\n\t\t} );\n\n\t\t// Define default converters for text and elements.\n\t\t//\n\t\t// Note that if there is no default converter for the element it will be skipped, for instance `<b>foo</b>` will be\n\t\t// converted to nothing. We add `convertToModelFragment` as a last converter so it converts children of that\n\t\t// element to the document fragment so `<b>foo</b>` will be converted to `foo` if there is no converter for `<b>`.\n\t\tthis.upcastDispatcher.on( 'text', convertText(), { priority: 'lowest' } );\n\t\tthis.upcastDispatcher.on( 'element', convertToModelFragment(), { priority: 'lowest' } );\n\t\tthis.upcastDispatcher.on( 'documentFragment', convertToModelFragment(), { priority: 'lowest' } );\n\n\t\tthis.decorate( 'init' );\n\n\t\t// Fire `ready` event when initialisation has completed. Such low level listener gives possibility\n\t\t// to plug into initialisation pipeline without interrupting the initialisation flow.\n\t\tthis.on( 'init', () => {\n\t\t\tthis.fire( 'ready' );\n\t\t}, { priority: 'lowest' } );\n\t}\n\n\t/**\n\t * Returns the model's data converted by downcast dispatchers attached to {@link #downcastDispatcher} and\n\t * formatted by the {@link #processor data processor}.\n\t *\n\t * @param {Object} [options]\n\t * @param {String} [options.rootName='main'] Root name.\n\t * @param {String} [options.trim='empty'] Whether returned data should be trimmed. This option is set to `empty` by default,\n\t * which means whenever editor content is considered empty, an empty string will be returned. To turn off trimming completely\n\t * use `'none'`. In such cases exact content will be returned (for example `<p>&nbsp;</p>` for an empty editor).\n\t * @returns {String} Output data.\n\t */\n\tget( options ) {\n\t\tconst { rootName = 'main', trim = 'empty' } = options || {};\n\n\t\tif ( !this._checkIfRootsExists( [ rootName ] ) ) {\n\t\t\t/**\n\t\t\t * Cannot get data from a non-existing root. This error is thrown when {@link #get DataController#get() method}\n\t\t\t * is called with non-existent root name. For example, if there is an editor instance with only `main` root,\n\t\t\t * calling {@link #get} like:\n\t\t\t *\n\t\t\t *\t\tdata.get( { rootName: 'root2' } );\n\t\t\t *\n\t\t\t * will throw this error.\n\t\t\t *\n\t\t\t * @error datacontroller-get-non-existent-root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'datacontroller-get-non-existent-root: Attempting to get data from a non-existing root.' );\n\t\t}\n\n\t\tconst root = this.model.document.getRoot( rootName );\n\n\t\tif ( trim === 'empty' && !this.model.hasContent( root, { ignoreWhitespaces: true } ) ) {\n\t\t\treturn '';\n\t\t}\n\n\t\treturn this.stringify( root );\n\t}\n\n\t/**\n\t * Returns the content of the given {@link module:engine/model/element~Element model's element} or\n\t * {@link module:engine/model/documentfragment~DocumentFragment model document fragment} converted by the downcast converters\n\t * attached to {@link #downcastDispatcher} and formatted by the {@link #processor data processor}.\n\t *\n\t * @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} modelElementOrFragment\n\t * Element whose content will be stringified.\n\t * @returns {String} Output data.\n\t */\n\tstringify( modelElementOrFragment ) {\n\t\t// Model -> view.\n\t\tconst viewDocumentFragment = this.toView( modelElementOrFragment );\n\n\t\t// View -> data.\n\t\treturn this.processor.toData( viewDocumentFragment );\n\t}\n\n\t/**\n\t * Returns the content of the given {@link module:engine/model/element~Element model element} or\n\t * {@link module:engine/model/documentfragment~DocumentFragment model document fragment} converted by the downcast\n\t * converters attached to {@link #downcastDispatcher} to a\n\t * {@link module:engine/view/documentfragment~DocumentFragment view document fragment}.\n\t *\n\t * @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} modelElementOrFragment\n\t * Element or document fragment whose content will be converted.\n\t * @returns {module:engine/view/documentfragment~DocumentFragment} Output view DocumentFragment.\n\t */\n\ttoView( modelElementOrFragment ) {\n\t\t// Clear bindings so the call to this method gives correct results.\n\t\tthis.mapper.clearBindings();\n\n\t\t// First, convert elements.\n\t\tconst modelRange = ModelRange._createIn( modelElementOrFragment );\n\n\t\tconst viewDocumentFragment = new ViewDocumentFragment();\n\n\t\t// Create separate ViewDowncastWriter just for data conversion purposes.\n\t\t// We have no view controller and rendering do DOM in DataController so view.change() block is not used here.\n\t\tconst viewWriter = new ViewDowncastWriter( new ViewDocument() );\n\t\tthis.mapper.bindElements( modelElementOrFragment, viewDocumentFragment );\n\n\t\tthis.downcastDispatcher.convertInsert( modelRange, viewWriter );\n\n\t\tif ( !modelElementOrFragment.is( 'documentFragment' ) ) {\n\t\t\t// Then, if a document element is converted, convert markers.\n\t\t\t// From all document markers, get those, which \"intersect\" with the converter element.\n\t\t\tconst markers = _getMarkersRelativeToElement( modelElementOrFragment );\n\n\t\t\tfor ( const [ name, range ] of markers ) {\n\t\t\t\tthis.downcastDispatcher.convertMarkerAdd( name, range, viewWriter );\n\t\t\t}\n\t\t}\n\n\t\treturn viewDocumentFragment;\n\t}\n\n\t/**\n\t * Sets initial input data parsed by the {@link #processor data processor} and\n\t * converted by the {@link #upcastDispatcher view-to-model converters}.\n\t * Initial data can be set only to document that {@link module:engine/model/document~Document#version} is equal 0.\n\t *\n\t * **Note** This method is {@link module:utils/observablemixin~ObservableMixin#decorate decorated} which is\n\t * used by e.g. collaborative editing plugin that syncs remote data on init.\n\t *\n\t * When data is passed as a string it is initialized on a default `main` root:\n\t *\n\t *\t\tdataController.init( '<p>Foo</p>' ); // Initializes data on the `main` root.\n\t *\n\t * To initialize data on a different root or multiple roots at once, object containing `rootName` - `data` pairs should be passed:\n\t *\n\t *\t\tdataController.init( { main: '<p>Foo</p>', title: '<h1>Bar</h1>' } ); // Initializes data on the `main` and `title` roots.\n\t *\n\t * @fires init\n\t * @param {String|Object.<String,String>} data Input data as a string or an object containing `rootName` - `data`\n\t * pairs to initialize data on multiple roots at once.\n\t * @returns {Promise} Promise that is resolved after the data is set on the editor.\n\t */\n\tinit( data ) {\n\t\tif ( this.model.document.version ) {\n\t\t\t/**\n\t\t\t * Cannot set initial data to not empty {@link module:engine/model/document~Document}.\n\t\t\t * Initial data should be set once, during {@link module:core/editor/editor~Editor} initialization,\n\t\t\t * when the {@link module:engine/model/document~Document#version} is equal 0.\n\t\t\t *\n\t\t\t * @error datacontroller-init-document-not-empty\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'datacontroller-init-document-not-empty: Trying to set initial data to not empty document.' );\n\t\t}\n\n\t\tlet initialData = {};\n\t\tif ( typeof data === 'string' ) {\n\t\t\tinitialData.main = data; // Default root is 'main'. To initiate data on a different root, object should be passed.\n\t\t} else {\n\t\t\tinitialData = data;\n\t\t}\n\n\t\tif ( !this._checkIfRootsExists( Object.keys( initialData ) ) ) {\n\t\t\t/**\n\t\t\t * Cannot init data on a non-existing root. This error is thrown when {@link #init DataController#init() method}\n\t\t\t * is called with non-existent root name. For example, if there is an editor instance with only `main` root,\n\t\t\t * calling {@link #init} like:\n\t\t\t *\n\t\t\t * \t\tdata.init( { main: '<p>Foo</p>', root2: '<p>Bar</p>' } );\n\t\t\t *\n\t\t\t * will throw this error.\n\t\t\t *\n\t\t\t * @error datacontroller-init-non-existent-root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'datacontroller-init-non-existent-root: Attempting to init data on a non-existing root.' );\n\t\t}\n\n\t\tthis.model.enqueueChange( 'transparent', writer => {\n\t\t\tfor ( const rootName of Object.keys( initialData ) ) {\n\t\t\t\tconst modelRoot = this.model.document.getRoot( rootName );\n\t\t\t\twriter.insert( this.parse( initialData[ rootName ], modelRoot ), modelRoot, 0 );\n\t\t\t}\n\t\t} );\n\n\t\treturn Promise.resolve();\n\t}\n\n\t/**\n\t * Sets input data parsed by the {@link #processor data processor} and\n\t * converted by the {@link #upcastDispatcher view-to-model converters}.\n\t * This method can be used any time to replace existing editor data by the new one without clearing the\n\t * {@link module:engine/model/document~Document#history document history}.\n\t *\n\t * This method also creates a batch with all the changes applied. If all you need is to parse data, use\n\t * the {@link #parse} method.\n\t *\n\t * When data is passed as a string it is set on a default `main` root:\n\t *\n\t *\t\tdataController.set( '<p>Foo</p>' ); // Sets data on the `main` root.\n\t *\n\t * To set data on a different root or multiple roots at once, object containing `rootName` - `data` pairs should be passed:\n\t *\n\t *\t\tdataController.set( { main: '<p>Foo</p>', title: '<h1>Bar</h1>' } ); // Sets data on the `main` and `title` roots.\n\t *\n\t * @param {String|Object.<String,String>} data Input data as a string or an object containing `rootName` - `data`\n\t * pairs to set data on multiple roots at once.\n\t */\n\tset( data ) {\n\t\tlet newData = {};\n\t\tif ( typeof data === 'string' ) {\n\t\t\tnewData.main = data; // Default root is 'main'. To set data on a different root, object should be passed.\n\t\t} else {\n\t\t\tnewData = data;\n\t\t}\n\n\t\tif ( !this._checkIfRootsExists( Object.keys( newData ) ) ) {\n\t\t\t/**\n\t\t\t * Cannot set data on a non-existing root. This error is thrown when {@link #set DataController#set() method}\n\t\t\t * is called with non-existent root name. For example, if there is an editor instance with only `main` root,\n\t\t\t * calling {@link #set} like:\n\t\t\t *\n\t\t\t * \t\tdata.set( { main: '<p>Foo</p>', root2: '<p>Bar</p>' } );\n\t\t\t *\n\t\t\t * will throw this error.\n\t\t\t *\n\t\t\t * @error datacontroller-set-non-existent-root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'datacontroller-set-non-existent-root: Attempting to set data on a non-existing root.' );\n\t\t}\n\n\t\tthis.model.enqueueChange( 'transparent', writer => {\n\t\t\twriter.setSelection( null );\n\t\t\twriter.removeSelectionAttribute( this.model.document.selection.getAttributeKeys() );\n\n\t\t\tfor ( const rootName of Object.keys( newData ) ) {\n\t\t\t\t// Save to model.\n\t\t\t\tconst modelRoot = this.model.document.getRoot( rootName );\n\n\t\t\t\twriter.remove( writer.createRangeIn( modelRoot ) );\n\t\t\t\twriter.insert( this.parse( newData[ rootName ], modelRoot ), modelRoot, 0 );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Returns the data parsed by the {@link #processor data processor} and then converted by upcast converters\n\t * attached to the {@link #upcastDispatcher}.\n\t *\n\t * @see #set\n\t * @param {String} data Data to parse.\n\t * @param {module:engine/model/schema~SchemaContextDefinition} [context='$root'] Base context in which the view will\n\t * be converted to the model. See: {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#convert}.\n\t * @returns {module:engine/model/documentfragment~DocumentFragment} Parsed data.\n\t */\n\tparse( data, context = '$root' ) {\n\t\t// data -> view\n\t\tconst viewDocumentFragment = this.processor.toView( data );\n\n\t\t// view -> model\n\t\treturn this.toModel( viewDocumentFragment, context );\n\t}\n\n\t/**\n\t * Returns the result of the given {@link module:engine/view/element~Element view element} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment view document fragment} converted by the\n\t * {@link #upcastDispatcher view-to-model converters}, wrapped by {@link module:engine/model/documentfragment~DocumentFragment}.\n\t *\n\t * When marker elements were converted during the conversion process, it will be set as a document fragment's\n\t * {@link module:engine/model/documentfragment~DocumentFragment#markers static markers map}.\n\t *\n\t * @param {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment} viewElementOrFragment\n\t * Element or document fragment whose content will be converted.\n\t * @param {module:engine/model/schema~SchemaContextDefinition} [context='$root'] Base context in which the view will\n\t * be converted to the model. See: {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#convert}.\n\t * @returns {module:engine/model/documentfragment~DocumentFragment} Output document fragment.\n\t */\n\ttoModel( viewElementOrFragment, context = '$root' ) {\n\t\treturn this.model.change( writer => {\n\t\t\treturn this.upcastDispatcher.convert( viewElementOrFragment, writer, context );\n\t\t} );\n\t}\n\n\t/**\n\t * Removes all event listeners set by the DataController.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Checks if all provided root names are existing editor roots.\n\t *\n\t * @private\n\t * @param {Array.<String>} rootNames Root names to check.\n\t * @returns {Boolean} Whether all provided root names are existing editor roots.\n\t */\n\t_checkIfRootsExists( rootNames ) {\n\t\tfor ( const rootName of rootNames ) {\n\t\t\tif ( !this.model.document.getRootNames().includes( rootName ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Event fired once data initialisation has finished.\n\t *\n\t * @event ready\n\t */\n\n\t/**\n\t * Event fired after {@link #init init() method} has been run. It can be {@link #listenTo listened to} to adjust/modify\n\t * the initialisation flow. However, if the `init` event is stopped or prevented, the {@link #event:ready ready event}\n\t * should be fired manually.\n\t *\n\t * The `init` event is fired by decorated {@link #init} method.\n\t * See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples.\n\t *\n\t * @event init\n\t */\n}\n\nmix( DataController, ObservableMixin );\n\n// Helper function for downcast conversion.\n//\n// Takes a document element (element that is added to a model document) and checks which markers are inside it\n// and which markers are containing it. If the marker is intersecting with element, the intersection is returned.\nfunction _getMarkersRelativeToElement( element ) {\n\tconst result = [];\n\tconst doc = element.root.document;\n\n\tif ( !doc ) {\n\t\treturn [];\n\t}\n\n\tconst elementRange = ModelRange._createIn( element );\n\n\tfor ( const marker of doc.model.markers ) {\n\t\tconst intersection = elementRange.getIntersection( marker.getRange() );\n\n\t\tif ( intersection ) {\n\t\t\tresult.push( [ marker.name, intersection ] );\n\t\t}\n\t}\n\n\treturn result;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/conversion/conversion\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport UpcastHelpers from './upcasthelpers';\nimport DowncastHelpers from './downcasthelpers';\n\n/**\n * A utility class that helps add converters to upcast and downcast dispatchers.\n *\n * We recommend reading the {@glink framework/guides/architecture/editing-engine Editing engine architecture} guide first to\n * understand the core concepts of the conversion mechanisms.\n *\n * An instance of the conversion manager is available in the\n * {@link module:core/editor/editor~Editor#conversion `editor.conversion`} property\n * and by default has the following groups of dispatchers (i.e. directions of conversion):\n *\n * * `downcast` (editing and data downcasts)\n * * `editingDowncast`\n * * `dataDowncast`\n * * `upcast`\n *\n * # One-way converters\n *\n * To add a converter to a specific group, use the {@link module:engine/conversion/conversion~Conversion#for `for()`}\n * method:\n *\n *\t\t// Add a converter to editing downcast and data downcast.\n *\t\teditor.conversion.for( 'downcast' ).elementToElement( config ) );\n *\n *\t\t// Add a converter to the data pipepline only:\n *\t\teditor.conversion.for( 'dataDowncast' ).elementToElement( dataConversionConfig ) );\n *\n *\t\t// And a slightly different one for the editing pipeline:\n *\t\teditor.conversion.for( 'editingDowncast' ).elementToElement( editingConversionConfig ) );\n *\n * See {@link module:engine/conversion/conversion~Conversion#for `for()`} method documentation to learn more about\n * available conversion helpers and how to use your custom ones.\n *\n * # Two-way converters\n *\n * Besides using one-way converters via the `for()` method, you can also use other methods available in this\n * class to add two-way converters (upcast and downcast):\n *\n * * {@link module:engine/conversion/conversion~Conversion#elementToElement `elementToElement()`} &ndash;\n * Model element to view element and vice versa.\n * * {@link module:engine/conversion/conversion~Conversion#attributeToElement `attributeToElement()`} &ndash;\n * Model attribute to view element and vice versa.\n * * {@link module:engine/conversion/conversion~Conversion#attributeToAttribute `attributeToAttribute()`} &ndash;\n * Model attribute to view element and vice versa.\n */\nexport default class Conversion {\n\t/**\n\t * Creates a new conversion instance.\n\t *\n\t * @param {module:engine/conversion/downcastdispatcher~DowncastDispatcher|\n\t * Array.<module:engine/conversion/downcastdispatcher~DowncastDispatcher>} downcastDispatchers\n\t * @param {module:engine/conversion/upcastdispatcher~UpcastDispatcher|\n\t * Array.<module:engine/conversion/upcastdispatcher~UpcastDispatcher>} upcastDispatchers\n\t */\n\tconstructor( downcastDispatchers, upcastDispatchers ) {\n\t\t/**\n\t\t * Maps dispatchers group name to ConversionHelpers instances.\n\t\t *\n\t\t * @private\n\t\t * @member {Map.<String,module:engine/conversion/conversionhelpers~ConversionHelpers>}\n\t\t */\n\t\tthis._helpers = new Map();\n\n\t\t// Define default 'downcast' & 'upcast' dispatchers groups. Those groups are always available as two-way converters needs them.\n\t\tthis._downcast = Array.isArray( downcastDispatchers ) ? downcastDispatchers : [ downcastDispatchers ];\n\t\tthis._createConversionHelpers( { name: 'downcast', dispatchers: this._downcast, isDowncast: true } );\n\n\t\tthis._upcast = Array.isArray( upcastDispatchers ) ? upcastDispatchers : [ upcastDispatchers ];\n\t\tthis._createConversionHelpers( { name: 'upcast', dispatchers: this._upcast, isDowncast: false } );\n\t}\n\n\t/**\n\t * Define an alias for registered dispatcher.\n\t *\n\t *\t\tconst conversion = new Conversion(\n\t *\t\t\t[ dataDowncastDispatcher, editingDowncastDispatcher ],\n\t *\t\t\tupcastDispatcher\n\t *\t\t);\n\t *\n\t *\t\tconversion.addAlias( 'dataDowncast', dataDowncastDispatcher );\n\t *\n\t * @param {String} alias An alias of a dispatcher.\n\t * @param {module:engine/conversion/downcastdispatcher~DowncastDispatcher|\n\t * module:engine/conversion/upcastdispatcher~UpcastDispatcher} dispatcher Dispatcher which should have an alias.\n\t */\n\taddAlias( alias, dispatcher ) {\n\t\tconst isDowncast = this._downcast.includes( dispatcher );\n\t\tconst isUpcast = this._upcast.includes( dispatcher );\n\n\t\tif ( !isUpcast && !isDowncast ) {\n\t\t\t/**\n\t\t\t * Trying to register and alias for a dispatcher that nas not been registered.\n\t\t\t *\n\t\t\t * @error conversion-add-alias-dispatcher-not-registered\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'conversion-add-alias-dispatcher-not-registered: ' +\n\t\t\t\t'Trying to register and alias for a dispatcher that nas not been registered.' );\n\t\t}\n\n\t\tthis._createConversionHelpers( { name: alias, dispatchers: [ dispatcher ], isDowncast } );\n\t}\n\n\t/**\n\t * Provides a chainable API to assign converters to conversion dispatchers group.\n\t *\n\t * If the given group name has not been registered, the\n\t * {@link module:utils/ckeditorerror~CKEditorError `conversion-for-unknown-group` error} is thrown.\n\t *\n\t * You can use conversion helpers available directly in the `for()` chain or your custom ones via\n\t * the {@link module:engine/conversion/conversionhelpers~ConversionHelpers#add `add()`} method.\n\t *\n\t * # Using bulit-in conversion helpers\n\t *\n\t * The `for()` chain comes with a set of conversion helpers which you can use like this:\n\t *\n\t *\t\teditor.conversion.for( 'downcast' )\n\t *\t\t\t.elementToElement( config1 ) // Adds an element-to-element downcast converter.\n\t *\t\t\t.attributeToElement( config2 ); // Adds an attribute-to-element downcast converter.\n\t *\n\t *\t\teditor.conversion.for( 'upcast' )\n\t *\t\t\t.elementToAttribute( config3 ); // Adds an element-to-attribute upcast converter.\n\t *\n\t * Refer to the documentation of built-in conversion helpers to learn about their configuration options.\n\t *\n\t * * downcast (model-to-view) conversion helpers:\n\t *\n\t *\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`},\n\t *\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#attributeToElement `attributeToElement()`},\n\t *\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#attributeToAttribute `attributeToAttribute()`}.\n\t *\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToElement `markerToElement()`}.\n\t *\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToHighlight `markerToHighlight()`}.\n\t *\n\t * * upcast (view-to-model) conversion helpers:\n\t *\n\t *\t* {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToElement `elementToElement()`},\n\t *\t* {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToAttribute `elementToAttribute()`},\n\t *\t* {@link module:engine/conversion/upcasthelpers~UpcastHelpers#attributeToAttribute `attributeToAttribute()`}.\n\t *\t* {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToMarker `elementToMarker()`}.\n\t *\n\t * # Using custom conversion helpers\n\t *\n\t * If you need to implement a nontypical converter, you can do so by calling:\n\t *\n\t *\t\teditor.conversion.for( direction ).add( customHelper );\n\t *\n\t * The `.add()` method takes exactly one parameter, which is a function. This function should accept one parameter that\n\t * is a dispatcher instance. The function should add an actual converter to the passed dispatcher instance.\n\t *\n\t * Example:\n\t *\n\t *\t\teditor.conversion.for( 'upcast' ).add( dispatcher => {\n\t *\t\t\tdispatcher.on( 'element:a', ( evt, data, conversionApi ) => {\n\t *\t\t\t\t// Do something with a view <a> element.\n\t *\t\t\t} );\n\t *\t\t} );\n\t *\n\t * Refer to the documentation of {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher}\n\t * and {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} to learn how to write\n\t * custom converters.\n\t *\n\t * @param {String} groupName The name of dispatchers group to add the converters to.\n\t * @returns {module:engine/conversion/downcasthelpers~DowncastHelpers|module:engine/conversion/upcasthelpers~UpcastHelpers}\n\t */\n\tfor( groupName ) {\n\t\tif ( !this._helpers.has( groupName ) ) {\n\t\t\t/**\n\t\t\t * Trying to add a converter to an unknown dispatchers group.\n\t\t\t *\n\t\t\t * @error conversion-for-unknown-group\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'conversion-for-unknown-group: Trying to add a converter to an unknown dispatchers group.' );\n\t\t}\n\n\t\treturn this._helpers.get( groupName );\n\t}\n\n\t/**\n\t * Sets up converters between the model and the view that convert a model element to a view element (and vice versa).\n\t * For example, the model `<paragraph>Foo</paragraph>` is `<p>Foo</p>` in the view.\n\t *\n\t *\t\t// A simple conversion from the `paragraph` model element to the `<p>` view element (and vice versa).\n\t *\t\teditor.conversion.elementToElement( { model: 'paragraph', view: 'p' } );\n\t *\n\t *\t\t// Override other converters by specifying a converter definition with a higher priority.\n\t *\t\teditor.conversion.elementToElement( { model: 'paragraph', view: 'div', converterPriority: 'high' } );\n\t *\n\t *\t\t// View specified as an object instead of a string.\n\t *\t\teditor.conversion.elementToElement( {\n\t *\t\t\tmodel: 'fancyParagraph',\n\t *\t\t\tview: {\n\t *\t\t\t\tname: 'p',\n\t *\t\t\t\tclasses: 'fancy'\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t *\t\t// Use `upcastAlso` to define other view elements that should also be converted to a `paragraph` element.\n\t *\t\teditor.conversion.elementToElement( {\n\t *\t\t\tmodel: 'paragraph',\n\t *\t\t\tview: 'p',\n\t *\t\t\tupcastAlso: [\n\t *\t\t\t\t'div',\n\t *\t\t\t\t{\n\t *\t\t\t\t\t// Any element with the `display: block` style.\n\t *\t\t\t\t\tstyles: {\n\t *\t\t\t\t\t\tdisplay: 'block'\n\t *\t\t\t\t\t}\n\t *\t\t\t\t}\n\t *\t\t\t]\n\t *\t\t} );\n\t *\n\t *\t\t// `upcastAlso` set as callback enables a conversion of a wide range of different view elements.\n\t *\t\teditor.conversion.elementToElement( {\n\t *\t\t\tmodel: 'heading',\n\t *\t\t\tview: 'h2',\n\t *\t\t\t// Convert \"headling-like\" paragraphs to headings.\n\t *\t\t\tupcastAlso: viewElement => {\n\t *\t\t\t\tconst fontSize = viewElement.getStyle( 'font-size' );\n\t *\n\t *\t\t\t\tif ( !fontSize ) {\n\t *\t\t\t\t\treturn null;\n\t *\t\t\t\t}\n\t *\n\t *\t\t\t\tconst match = fontSize.match( /(\\d+)\\s*px/ );\n\t *\n\t *\t\t\t\tif ( !match ) {\n\t *\t\t\t\t\treturn null;\n\t *\t\t\t\t}\n\t *\n\t *\t\t\t\tconst size = Number( match[ 1 ] );\n\t *\n\t *\t\t\t\tif ( size > 26 ) {\n\t *\t\t\t\t\t// Returned value can be an object with the matched properties.\n\t *\t\t\t\t\t// These properties will be \"consumed\" during the conversion.\n\t *\t\t\t\t\t// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.\n\t *\n\t *\t\t\t\t\treturn { name: true, styles: [ 'font-size' ] };\n\t *\t\t\t\t}\n\t *\n\t *\t\t\t\treturn null;\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * `definition.model` is a `String` with a model element name to convert from or to.\n\t * See {@link module:engine/conversion/conversion~ConverterDefinition} to learn about other parameters.\n\t *\n\t * @param {module:engine/conversion/conversion~ConverterDefinition} definition The converter definition.\n\t */\n\telementToElement( definition ) {\n\t\t// Set up downcast converter.\n\t\tthis.for( 'downcast' ).elementToElement( definition );\n\n\t\t// Set up upcast converter.\n\t\tfor ( const { model, view } of _getAllUpcastDefinitions( definition ) ) {\n\t\t\tthis.for( 'upcast' )\n\t\t\t\t.elementToElement( {\n\t\t\t\t\tmodel,\n\t\t\t\t\tview,\n\t\t\t\t\tconverterPriority: definition.converterPriority\n\t\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Sets up converters between the model and the view that convert a model attribute to a view element (and vice versa).\n\t * For example, a model text node with `\"Foo\"` as data and the `bold` attribute is `<strong>Foo</strong>` in the view.\n\t *\n\t *\t\t// A simple conversion from the `bold=true` attribute to the `<strong>` view element (and vice versa).\n\t *\t\teditor.conversion.attributeToElement( { model: 'bold', view: 'strong' } );\n\t *\n\t *\t\t// Override other converters by specifying a converter definition with a higher priority.\n\t *\t\teditor.conversion.attributeToElement( { model: 'bold', view: 'b', converterPriority: 'high' } );\n\t *\n\t *\t\t// View specified as an object instead of a string.\n\t *\t\teditor.conversion.attributeToElement( {\n\t *\t\t\tmodel: 'bold',\n\t *\t\t\tview: {\n\t *\t\t\t\tname: 'span',\n\t *\t\t\t\tclasses: 'bold'\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t *\t\t// Use `config.model.name` to define the conversion only from a given node type, `$text` in this case.\n\t *\t\t// The same attribute on different elements may then be handled by a different converter.\n\t *\t\teditor.conversion.attributeToElement( {\n\t *\t\t\tmodel: {\n\t *\t\t\t\tkey: 'textDecoration',\n\t *\t\t\t\tvalues: [ 'underline', 'lineThrough' ],\n\t *\t\t\t\tname: '$text'\n\t *\t\t\t},\n\t *\t\t\tview: {\n\t *\t\t\t\tunderline: {\n\t *\t\t\t\t\tname: 'span',\n\t *\t\t\t\t\tstyles: {\n\t *\t\t\t\t\t\t'text-decoration': 'underline'\n\t *\t\t\t\t\t}\n\t *\t\t\t\t},\n\t *\t\t\t\tlineThrough: {\n\t *\t\t\t\t\tname: 'span',\n\t *\t\t\t\t\tstyles: {\n\t *\t\t\t\t\t\t'text-decoration': 'line-through'\n\t *\t\t\t\t\t}\n\t *\t\t\t\t}\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t *\t\t// Use `upcastAlso` to define other view elements that should also be converted to the `bold` attribute.\n\t *\t\teditor.conversion.attributeToElement( {\n\t *\t\t\tmodel: 'bold',\n\t *\t\t\tview: 'strong',\n\t *\t\t\tupcastAlso: [\n\t *\t\t\t\t'b',\n\t *\t\t\t\t{\n\t *\t\t\t\t\tname: 'span',\n\t *\t\t\t\t\tclasses: 'bold'\n\t *\t\t\t\t},\n\t *\t\t\t\t{\n\t *\t\t\t\t\tname: 'span',\n\t *\t\t\t\t\tstyles: {\n\t *\t\t\t\t\t\t'font-weight': 'bold'\n\t *\t\t\t\t\t}\n\t *\t\t\t\t},\n\t *\t\t\t\tviewElement => {\n\t *\t\t\t\t\tconst fontWeight = viewElement.getStyle( 'font-weight' );\n\t *\n\t *\t\t\t\t\tif ( viewElement.is( 'span' ) && fontWeight && /\\d+/.test() && Number( fontWeight ) > 500 ) {\n\t *\t\t\t\t\t\t// Returned value can be an object with the matched properties.\n\t *\t\t\t\t\t\t// These properties will be \"consumed\" during the conversion.\n\t *\t\t\t\t\t\t// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.\n\t *\n\t *\t\t\t\t\t\treturn {\n\t *\t\t\t\t\t\t\tname: true,\n\t *\t\t\t\t\t\t\tstyles: [ 'font-weight' ]\n\t *\t\t\t\t\t\t};\n\t *\t\t\t\t\t}\n\t *\t\t\t\t}\n\t *\t\t\t]\n\t *\t\t} );\n\t *\n\t *\t\t// Conversion from and to a model attribute key whose value is an enum (`fontSize=big|small`).\n\t *\t\t// `upcastAlso` set as callback enables a conversion of a wide range of different view elements.\n\t *\t\teditor.conversion.attributeToElement( {\n\t *\t\t\tmodel: {\n\t *\t\t\t\tkey: 'fontSize',\n\t *\t\t\t\tvalues: [ 'big', 'small' ]\n\t *\t\t\t},\n\t *\t\t\tview: {\n\t *\t\t\t\tbig: {\n\t *\t\t\t\t\tname: 'span',\n\t *\t\t\t\t\tstyles: {\n\t *\t\t\t\t\t\t'font-size': '1.2em'\n\t *\t\t\t\t\t}\n\t *\t\t\t\t},\n\t *\t\t\t\tsmall: {\n\t *\t\t\t\t\tname: 'span',\n\t *\t\t\t\t\tstyles: {\n\t *\t\t\t\t\t\t'font-size': '0.8em'\n\t *\t\t\t\t\t}\n\t *\t\t\t\t}\n\t *\t\t\t},\n\t *\t\t\tupcastAlso: {\n\t *\t\t\t\tbig: viewElement => {\n\t *\t\t\t\t\tconst fontSize = viewElement.getStyle( 'font-size' );\n\t *\n\t *\t\t\t\t\tif ( !fontSize ) {\n\t *\t\t\t\t\t\treturn null;\n\t *\t\t\t\t\t}\n\t *\n\t *\t\t\t\t\tconst match = fontSize.match( /(\\d+)\\s*px/ );\n\t *\n\t *\t\t\t\t\tif ( !match ) {\n\t *\t\t\t\t\t\treturn null;\n\t *\t\t\t\t\t}\n\t *\n\t *\t\t\t\t\tconst size = Number( match[ 1 ] );\n\t *\n\t *\t\t\t\t\tif ( viewElement.is( 'span' ) && size > 10 ) {\n\t *\t\t\t\t\t\t// Returned value can be an object with the matched properties.\n\t *\t\t\t\t\t\t// These properties will be \"consumed\" during the conversion.\n\t *\t\t\t\t\t\t// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.\n\t *\n\t *\t\t\t\t\t\treturn { name: true, styles: [ 'font-size' ] };\n\t *\t\t\t\t\t}\n\t *\n\t *\t\t\t\t\treturn null;\n\t *\t\t\t\t},\n\t *\t\t\t\tsmall: viewElement => {\n\t *\t\t\t\t\tconst fontSize = viewElement.getStyle( 'font-size' );\n\t *\n\t *\t\t\t\t\tif ( !fontSize ) {\n\t *\t\t\t\t\t\treturn null;\n\t *\t\t\t\t\t}\n\t *\n\t *\t\t\t\t\tconst match = fontSize.match( /(\\d+)\\s*px/ );\n\t *\n\t *\t\t\t\t\tif ( !match ) {\n\t *\t\t\t\t\t\treturn null;\n\t *\t\t\t\t\t}\n\t *\n\t *\t\t\t\t\tconst size = Number( match[ 1 ] );\n\t *\n\t *\t\t\t\t\tif ( viewElement.is( 'span' ) && size < 10 ) {\n\t *\t\t\t\t\t\t// Returned value can be an object with the matched properties.\n\t *\t\t\t\t\t\t// These properties will be \"consumed\" during the conversion.\n\t *\t\t\t\t\t\t// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.\n\t *\n\t *\t\t\t\t\t\treturn { name: true, styles: [ 'font-size' ] };\n\t *\t\t\t\t\t}\n\t *\n\t *\t\t\t\t\treturn null;\n\t *\t\t\t\t}\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * The `definition.model` parameter specifies which model attribute should be converted from or to. It can be a `{ key, value }` object\n\t * describing the attribute key and value to convert or a `String` specifying just the attribute key (then `value` is set to `true`).\n\t * See {@link module:engine/conversion/conversion~ConverterDefinition} to learn about other parameters.\n\t *\n\t * @param {module:engine/conversion/conversion~ConverterDefinition} definition The converter definition.\n\t */\n\tattributeToElement( definition ) {\n\t\t// Set up downcast converter.\n\t\tthis.for( 'downcast' ).attributeToElement( definition );\n\n\t\t// Set up upcast converter.\n\t\tfor ( const { model, view } of _getAllUpcastDefinitions( definition ) ) {\n\t\t\tthis.for( 'upcast' )\n\t\t\t\t.elementToAttribute( {\n\t\t\t\t\tview,\n\t\t\t\t\tmodel,\n\t\t\t\t\tconverterPriority: definition.converterPriority\n\t\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Sets up converters between the model and the view that convert a model attribute to a view attribute (and vice versa).\n\t * For example, `<image src='foo.jpg'></image>` is converted to `<img src='foo.jpg'></img>` (the same attribute key and value).\n\t * This type of converters is intended to be used with {@link module:engine/model/element~Element model element} nodes.\n\t * To convert text attributes {@link module:engine/conversion/conversion~Conversion#attributeToElement `attributeToElement converter`}\n\t * should be set up.\n\t *\n\t *\t\t// A simple conversion from the `source` model attribute to the `src` view attribute (and vice versa).\n\t *\t\teditor.conversion.attributeToAttribute( { model: 'source', view: 'src' } );\n\t *\n\t *\t\t// Attribute values are strictly specified.\n\t *\t\teditor.conversion.attributeToAttribute( {\n\t *\t\t\tmodel: {\n\t *\t\t\t\tname: 'image',\n\t *\t\t\t\tkey: 'aside',\n\t *\t\t\t\tvalues: [ 'aside' ]\n\t *\t\t\t},\n\t *\t\t\tview: {\n\t *\t\t\t\taside: {\n\t *\t\t\t\t\tname: 'img',\n\t *\t\t\t\t\tkey: 'class',\n\t *\t\t\t\t\tvalue: [ 'aside', 'half-size' ]\n\t *\t\t\t\t}\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t *\t\t// Set the style attribute.\n\t *\t\teditor.conversion.attributeToAttribute( {\n\t *\t\t\tmodel: {\n\t *\t\t\t\tname: 'image',\n\t *\t\t\t\tkey: 'aside',\n\t *\t\t\t\tvalues: [ 'aside' ]\n\t *\t\t\t},\n\t *\t\t\tview: {\n\t *\t\t\t\taside: {\n\t *\t\t\t\t\tname: 'img',\n\t *\t\t\t\t\tkey: 'style',\n\t *\t\t\t\t\tvalue: {\n\t *\t\t\t\t\t\tfloat: 'right',\n\t *\t\t\t\t\t\twidth: '50%',\n\t *\t\t\t\t\t\tmargin: '5px'\n\t *\t\t\t\t\t}\n\t *\t\t\t\t}\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t *\t\t// Conversion from and to a model attribute key whose value is an enum (`align=right|center`).\n\t *\t\t// Use `upcastAlso` to define other view elements that should also be converted to the `align=right` attribute.\n\t *\t\teditor.conversion.attributeToAttribute( {\n\t *\t\t\tmodel: {\n\t *\t\t\t\tkey: 'align',\n\t *\t\t\t\tvalues: [ 'right', 'center' ]\n\t *\t\t\t},\n\t *\t\t\tview: {\n\t *\t\t\t\tright: {\n\t *\t\t\t\t\tkey: 'class',\n\t *\t\t\t\t\tvalue: 'align-right'\n\t *\t\t\t\t},\n\t *\t\t\t\tcenter: {\n\t *\t\t\t\t\tkey: 'class',\n\t *\t\t\t\t\tvalue: 'align-center'\n\t *\t\t\t\t}\n\t *\t\t\t},\n\t *\t\t\tupcastAlso: {\n\t *\t\t\t\tright: {\n\t *\t\t\t\t\tstyles: {\n\t *\t\t\t\t\t\t'text-align': 'right'\n\t *\t\t\t\t\t}\n\t *\t\t\t\t},\n\t *\t\t\t\tcenter: {\n\t *\t\t\t\t\tstyles: {\n\t *\t\t\t\t\t\t'text-align': 'center'\n\t *\t\t\t\t\t}\n\t *\t\t\t\t}\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * The `definition.model` parameter specifies which model attribute should be converted from and to.\n\t * It can be a `{ key, [ values ], [ name ] }` object or a `String`, which will be treated like `{ key: definition.model }`.\n\t * The `key` property is the model attribute key to convert from and to.\n\t * The `values` are the possible model attribute values. If `values` is not set, the model attribute value will be the same as the\n\t * view attribute value.\n\t * If `name` is set, the conversion will be set up only for model elements with the given name.\n\t *\n\t * The `definition.view` parameter specifies which view attribute should be converted from and to.\n\t * It can be a `{ key, value, [ name ] }` object or a `String`, which will be treated like `{ key: definition.view }`.\n\t * The `key` property is the view attribute key to convert from and to.\n\t * The `value` is the view attribute value to convert from and to. If `definition.value` is not set, the view attribute value will be\n\t * the same as the model attribute value.\n\t * If `key` is `'class'`, `value` can be a `String` or an array of `String`s.\n\t * If `key` is `'style'`, `value` is an object with key-value pairs.\n\t * In other cases, `value` is a `String`.\n\t * If `name` is set, the conversion will be set up only for model elements with the given name.\n\t * If `definition.model.values` is set, `definition.view` is an object that assigns values from `definition.model.values`\n\t * to `{ key, value, [ name ] }` objects.\n\t *\n\t * `definition.upcastAlso` specifies which other matching view elements should also be upcast to the given model configuration.\n\t * If `definition.model.values` is set, `definition.upcastAlso` should be an object assigning values from `definition.model.values`\n\t * to {@link module:engine/view/matcher~MatcherPattern}s or arrays of {@link module:engine/view/matcher~MatcherPattern}s.\n\t *\n\t * **Note:** `definition.model` and `definition.view` form should be mirrored, so the same types of parameters should\n\t * be given in both parameters.\n\t *\n\t * @param {Object} definition The converter definition.\n\t * @param {String|Object} definition.model The model attribute to convert from and to.\n\t * @param {String|Object} definition.view The view attribute to convert from and to.\n\t * @param {module:engine/view/matcher~MatcherPattern|Array.<module:engine/view/matcher~MatcherPattern>} [definition.upcastAlso]\n\t * Any view element matching `definition.upcastAlso` will also be converted to the given model attribute. `definition.upcastAlso`\n\t * is used only if `config.model.values` is specified.\n\t */\n\tattributeToAttribute( definition ) {\n\t\t// Set up downcast converter.\n\t\tthis.for( 'downcast' ).attributeToAttribute( definition );\n\n\t\t// Set up upcast converter.\n\t\tfor ( const { model, view } of _getAllUpcastDefinitions( definition ) ) {\n\t\t\tthis.for( 'upcast' )\n\t\t\t\t.attributeToAttribute( {\n\t\t\t\t\tview,\n\t\t\t\t\tmodel\n\t\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Creates and caches conversion helpers for given dispatchers group.\n\t *\n\t * @private\n\t * @param {Object} options\n\t * @param {String} options.name Group name.\n\t * @param {Array.<module:engine/conversion/downcastdispatcher~DowncastDispatcher|\n\t * module:engine/conversion/upcastdispatcher~UpcastDispatcher>} options.dispatchers\n\t * @param {Boolean} options.isDowncast\n\t */\n\t_createConversionHelpers( { name, dispatchers, isDowncast } ) {\n\t\tif ( this._helpers.has( name ) ) {\n\t\t\t/**\n\t\t\t * Trying to register a group name that has already been registered.\n\t\t\t *\n\t\t\t * @error conversion-group-exists\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'conversion-group-exists: Trying to register a group name that has already been registered.' );\n\t\t}\n\n\t\tconst helpers = isDowncast ? new DowncastHelpers( dispatchers ) : new UpcastHelpers( dispatchers );\n\n\t\tthis._helpers.set( name, helpers );\n\t}\n}\n\n/**\n * Defines how the model should be converted from and to the view.\n *\n * @typedef {Object} module:engine/conversion/conversion~ConverterDefinition\n *\n * @property {*} [model] The model conversion definition. Describes the model element or model attribute to convert. This parameter differs\n * for different functions that accept `ConverterDefinition`. See the description of the function to learn how to set it.\n * @property {module:engine/view/elementdefinition~ElementDefinition|Object} view The definition of the view element to convert from and\n * to. If `model` describes multiple values, `view` is an object that assigns these values (`view` object keys) to view element definitions\n * (`view` object values).\n * @property {module:engine/view/matcher~MatcherPattern|Array.<module:engine/view/matcher~MatcherPattern>} [upcastAlso]\n * Any view element matching `upcastAlso` will also be converted to the model. If `model` describes multiple values, `upcastAlso`\n * is an object that assigns these values (`upcastAlso` object keys) to {@link module:engine/view/matcher~MatcherPattern}s\n * (`upcastAlso` object values).\n * @property {module:utils/priorities~PriorityString} [converterPriority] The converter priority.\n */\n\n// Helper function that creates a joint array out of an item passed in `definition.view` and items passed in\n// `definition.upcastAlso`.\n//\n// @param {module:engine/conversion/conversion~ConverterDefinition} definition\n// @returns {Array} Array containing view definitions.\nfunction* _getAllUpcastDefinitions( definition ) {\n\tif ( definition.model.values ) {\n\t\tfor ( const value of definition.model.values ) {\n\t\t\tconst model = { key: definition.model.key, value };\n\t\t\tconst view = definition.view[ value ];\n\t\t\tconst upcastAlso = definition.upcastAlso ? definition.upcastAlso[ value ] : undefined;\n\n\t\t\tyield* _getUpcastDefinition( model, view, upcastAlso );\n\t\t}\n\t} else {\n\t\tyield* _getUpcastDefinition( definition.model, definition.view, definition.upcastAlso );\n\t}\n}\n\nfunction* _getUpcastDefinition( model, view, upcastAlso ) {\n\tyield { model, view };\n\n\tif ( upcastAlso ) {\n\t\tupcastAlso = Array.isArray( upcastAlso ) ? upcastAlso : [ upcastAlso ];\n\n\t\tfor ( const upcastAlsoItem of upcastAlso ) {\n\t\t\tyield { model, view: upcastAlsoItem };\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/batch\n */\n\n/**\n * A batch instance groups model changes ({@link module:engine/model/operation/operation~Operation operations}). All operations\n * grouped in a single batch can be reverted together, so you can also think about a batch as of a single undo step. If you want\n * to extend a given undo step, you can add more changes to the batch using {@link module:engine/model/model~Model#enqueueChange}:\n *\n *\t\tmodel.enqueueChange( batch, writer => {\n *\t\t\twriter.insertText( 'foo', paragraph, 'end' );\n *\t\t} );\n *\n * @see module:engine/model/model~Model#enqueueChange\n * @see module:engine/model/model~Model#change\n */\nexport default class Batch {\n\t/**\n\t * Creates a batch instance.\n\t *\n\t * @see module:engine/model/model~Model#enqueueChange\n\t * @see module:engine/model/model~Model#change\n\t * @param {'transparent'|'default'} [type='default'] The type of the batch.\n\t */\n\tconstructor( type = 'default' ) {\n\t\t/**\n\t\t * An array of operations that compose this batch.\n\t\t *\n\t\t * @readonly\n\t\t * @type {Array.<module:engine/model/operation/operation~Operation>}\n\t\t */\n\t\tthis.operations = [];\n\n\t\t/**\n\t\t * The type of the batch.\n\t\t *\n\t\t * It can be one of the following values:\n\t\t * * `'default'` &ndash; All \"normal\" batches. This is the most commonly used type.\n\t\t * * `'transparent'` &ndash; A batch that should be ignored by other features, i.e. an initial batch or collaborative editing\n\t\t * changes.\n\t\t *\n\t\t * @readonly\n\t\t * @type {'transparent'|'default'}\n\t\t */\n\t\tthis.type = type;\n\t}\n\n\t/**\n\t * Returns the base version of this batch, which is equal to the base version of the first operation in the batch.\n\t * If there are no operations in the batch or neither operation has the base version set, it returns `null`.\n\t *\n\t * @readonly\n\t * @type {Number|null}\n\t */\n\tget baseVersion() {\n\t\tfor ( const op of this.operations ) {\n\t\t\tif ( op.baseVersion !== null ) {\n\t\t\t\treturn op.baseVersion;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Adds an operation to the batch instance.\n\t *\n\t * @param {module:engine/model/operation/operation~Operation} operation An operation to add.\n\t * @returns {module:engine/model/operation/operation~Operation} The added operation.\n\t */\n\taddOperation( operation ) {\n\t\toperation.batch = this;\n\t\tthis.operations.push( operation );\n\n\t\treturn operation;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/operation\n */\n\n/**\n * Abstract base operation class.\n *\n * @abstract\n */\nexport default class Operation {\n\t/**\n\t * Base operation constructor.\n\t *\n\t * @param {Number|null} baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */\n\tconstructor( baseVersion ) {\n\t\t/**\n\t\t * {@link module:engine/model/document~Document#version} on which operation can be applied. If you try to\n\t\t * {@link module:engine/model/model~Model#applyOperation apply} operation with different base version than the\n\t\t * {@link module:engine/model/document~Document#version document version} the\n\t\t * {@link module:utils/ckeditorerror~CKEditorError model-document-applyOperation-wrong-version} error is thrown.\n\t\t *\n\t\t * @member {Number}\n\t\t */\n\t\tthis.baseVersion = baseVersion;\n\n\t\t/**\n\t\t * Defines whether operation is executed on attached or detached {@link module:engine/model/item~Item items}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} #isDocumentOperation\n\t\t */\n\t\tthis.isDocumentOperation = this.baseVersion !== null;\n\n\t\t/**\n\t\t * {@link module:engine/model/batch~Batch Batch} to which the operation is added or `null` if the operation is not\n\t\t * added to any batch yet.\n\t\t *\n\t\t * @member {module:engine/model/batch~Batch|null} #batch\n\t\t */\n\t\tthis.batch = null;\n\n\t\t/**\n\t\t * Operation type.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String} #type\n\t\t */\n\n\t\t/**\n\t\t * Creates and returns an operation that has the same parameters as this operation.\n\t\t *\n\t\t * @method #clone\n\t\t * @returns {module:engine/model/operation/operation~Operation} Clone of this operation.\n\t\t */\n\n\t\t/**\n\t\t * Creates and returns a reverse operation. Reverse operation when executed right after\n\t\t * the original operation will bring back tree model state to the point before the original\n\t\t * operation execution. In other words, it reverses changes done by the original operation.\n\t\t *\n\t\t * Keep in mind that tree model state may change since executing the original operation,\n\t\t * so reverse operation will be \"outdated\". In that case you will need to transform it by\n\t\t * all operations that were executed after the original operation.\n\t\t *\n\t\t * @method #getReversed\n\t\t * @returns {module:engine/model/operation/operation~Operation} Reversed operation.\n\t\t */\n\n\t\t/**\n\t\t * Executes the operation - modifications described by the operation properties will be applied to the model tree.\n\t\t *\n\t\t * @protected\n\t\t * @method #_execute\n\t\t */\n\t}\n\n\t/**\n\t * Checks whether the operation's parameters are correct and the operation can be correctly executed. Throws\n\t * an error if operation is not valid.\n\t *\n\t * @protected\n\t * @method #_validate\n\t */\n\t_validate() {\n\t}\n\n\t/**\n\t * Custom toJSON method to solve child-parent circular dependencies.\n\t *\n\t * @method #toJSON\n\t * @returns {Object} Clone of this object with the operation property replaced with string.\n\t */\n\ttoJSON() {\n\t\t// This method creates only a shallow copy, all nested objects should be defined separately.\n\t\t// See https://github.com/ckeditor/ckeditor5-engine/issues/1477.\n\t\tconst json = Object.assign( {}, this );\n\n\t\tjson.__className = this.constructor.className;\n\n\t\t// Remove reference to the parent `Batch` to avoid circular dependencies.\n\t\tdelete json.batch;\n\n\t\t// Only document operations are shared with other clients so it is not necessary to keep this information.\n\t\tdelete json.isDocumentOperation;\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Name of the operation class used for serialization.\n\t *\n\t * @type {String}\n\t */\n\tstatic get className() {\n\t\treturn 'Operation';\n\t}\n\n\t/**\n\t * Creates Operation object from deserilized object, i.e. from parsed JSON string.\n\t *\n\t * @param {Object} json Deserialized JSON object.\n\t * @param {module:engine/model/document~Document} doc Document on which this operation will be applied.\n\t * @returns {module:engine/model/operation/operation~Operation}\n\t */\n\tstatic fromJSON( json ) {\n\t\treturn new this( json.baseVersion );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module module:engine/model/documentfragment\n */\n\nimport NodeList from './nodelist';\nimport Element from './element';\nimport Text from './text';\nimport TextProxy from './textproxy';\nimport isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';\n\n/**\n * DocumentFragment represents a part of model which does not have a common root but it's top-level nodes\n * can be seen as siblings. In other words, it is a detached part of model tree, without a root.\n *\n * DocumentFragment has own {@link module:engine/model/markercollection~MarkerCollection}. Markers from this collection\n * will be set to the {@link module:engine/model/model~Model#markers model markers} by a\n * {@link module:engine/model/writer~Writer#insert} function.\n */\nexport default class DocumentFragment {\n\t/**\n\t * Creates an empty `DocumentFragment`.\n\t *\n\t * **Note:** Constructor of this class shouldn't be used directly in the code.\n\t * Use the {@link module:engine/model/writer~Writer#createDocumentFragment} method instead.\n\t *\n\t * @protected\n\t * @param {module:engine/model/node~Node|Iterable.<module:engine/model/node~Node>} [children]\n\t * Nodes to be contained inside the `DocumentFragment`.\n\t */\n\tconstructor( children ) {\n\t\t/**\n\t\t * DocumentFragment static markers map. This is a list of names and {@link module:engine/model/range~Range ranges}\n\t\t * which will be set as Markers to {@link module:engine/model/model~Model#markers model markers collection}\n\t\t * when DocumentFragment will be inserted to the document.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Map<String,module:engine/model/range~Range>} module:engine/model/documentfragment~DocumentFragment#markers\n\t\t */\n\t\tthis.markers = new Map();\n\n\t\t/**\n\t\t * List of nodes contained inside the document fragment.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/nodelist~NodeList} module:engine/model/documentfragment~DocumentFragment#_children\n\t\t */\n\t\tthis._children = new NodeList();\n\n\t\tif ( children ) {\n\t\t\tthis._insertChild( 0, children );\n\t\t}\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all nodes contained inside this document fragment.\n\t *\n\t * @returns {Iterable.<module:engine/model/node~Node>}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this.getChildren();\n\t}\n\n\t/**\n\t * Number of this document fragment's children.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget childCount() {\n\t\treturn this._children.length;\n\t}\n\n\t/**\n\t * Sum of {@link module:engine/model/node~Node#offsetSize offset sizes} of all of this document fragment's children.\n\t *\n\t * @readonly\n\t * @type {Number}\n\t */\n\tget maxOffset() {\n\t\treturn this._children.maxOffset;\n\t}\n\n\t/**\n\t * Is `true` if there are no nodes inside this document fragment, `false` otherwise.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isEmpty() {\n\t\treturn this.childCount === 0;\n\t}\n\n\t/**\n\t * Artificial root of `DocumentFragment`. Returns itself. Added for compatibility reasons.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/documentfragment~DocumentFragment}\n\t */\n\tget root() {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Artificial parent of `DocumentFragment`. Returns `null`. Added for compatibility reasons.\n\t *\n\t * @readonly\n\t * @type {null}\n\t */\n\tget parent() {\n\t\treturn null;\n\t}\n\n\t/**\n\t * Checks whether given model tree object is of given type.\n\t *\n\t * Read more in {@link module:engine/model/node~Node#is}.\n\t *\n\t * @param {String} type\n\t * @returns {Boolean}\n\t */\n\tis( type ) {\n\t\treturn type == 'documentFragment';\n\t}\n\n\t/**\n\t * Gets the child at the given index. Returns `null` if incorrect index was passed.\n\t *\n\t * @param {Number} index Index of child.\n\t * @returns {module:engine/model/node~Node|null} Child node.\n\t */\n\tgetChild( index ) {\n\t\treturn this._children.getNode( index );\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all of this document fragment's children.\n\t *\n\t * @returns {Iterable.<module:engine/model/node~Node>}\n\t */\n\tgetChildren() {\n\t\treturn this._children[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Returns an index of the given child node. Returns `null` if given node is not a child of this document fragment.\n\t *\n\t * @param {module:engine/model/node~Node} node Child node to look for.\n\t * @returns {Number|null} Child node's index.\n\t */\n\tgetChildIndex( node ) {\n\t\treturn this._children.getNodeIndex( node );\n\t}\n\n\t/**\n\t * Returns the starting offset of given child. Starting offset is equal to the sum of\n\t * {@link module:engine/model/node~Node#offsetSize offset sizes} of all node's siblings that are before it. Returns `null` if\n\t * given node is not a child of this document fragment.\n\t *\n\t * @param {module:engine/model/node~Node} node Child node to look for.\n\t * @returns {Number|null} Child node's starting offset.\n\t */\n\tgetChildStartOffset( node ) {\n\t\treturn this._children.getNodeStartOffset( node );\n\t}\n\n\t/**\n\t * Returns path to a `DocumentFragment`, which is an empty array. Added for compatibility reasons.\n\t *\n\t * @returns {Array}\n\t */\n\tgetPath() {\n\t\treturn [];\n\t}\n\n\t/**\n\t * Returns a descendant node by its path relative to this element.\n\t *\n\t *\t\t// <this>a<b>c</b></this>\n\t *\t\tthis.getNodeByPath( [ 0 ] ); // -> \"a\"\n\t *\t\tthis.getNodeByPath( [ 1 ] ); // -> <b>\n\t *\t\tthis.getNodeByPath( [ 1, 0 ] ); // -> \"c\"\n\t *\n\t * @param {Array.<Number>} relativePath Path of the node to find, relative to this element.\n\t * @returns {module:engine/model/node~Node|module:engine/model/documentfragment~DocumentFragment}\n\t */\n\tgetNodeByPath( relativePath ) {\n\t\tlet node = this; // eslint-disable-line consistent-this\n\n\t\tfor ( const index of relativePath ) {\n\t\t\tnode = node.getChild( node.offsetToIndex( index ) );\n\t\t}\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Converts offset \"position\" to index \"position\".\n\t *\n\t * Returns index of a node that occupies given offset. If given offset is too low, returns `0`. If given offset is\n\t * too high, returns index after last child}.\n\t *\n\t *\t\tconst textNode = new Text( 'foo' );\n\t *\t\tconst pElement = new Element( 'p' );\n\t *\t\tconst docFrag = new DocumentFragment( [ textNode, pElement ] );\n\t *\t\tdocFrag.offsetToIndex( -1 ); // Returns 0, because offset is too low.\n\t *\t\tdocFrag.offsetToIndex( 0 ); // Returns 0, because offset 0 is taken by `textNode` which is at index 0.\n\t *\t\tdocFrag.offsetToIndex( 1 ); // Returns 0, because `textNode` has `offsetSize` equal to 3, so it occupies offset 1 too.\n\t *\t\tdocFrag.offsetToIndex( 2 ); // Returns 0.\n\t *\t\tdocFrag.offsetToIndex( 3 ); // Returns 1.\n\t *\t\tdocFrag.offsetToIndex( 4 ); // Returns 2. There are no nodes at offset 4, so last available index is returned.\n\t *\n\t * @param {Number} offset Offset to look for.\n\t * @returns {Number} Index of a node that occupies given offset.\n\t */\n\toffsetToIndex( offset ) {\n\t\treturn this._children.offsetToIndex( offset );\n\t}\n\n\t/**\n\t * Converts `DocumentFragment` instance to plain object and returns it.\n\t * Takes care of converting all of this document fragment's children.\n\t *\n\t * @returns {Object} `DocumentFragment` instance converted to plain object.\n\t */\n\ttoJSON() {\n\t\tconst json = [];\n\n\t\tfor ( const node of this._children ) {\n\t\t\tjson.push( node.toJSON() );\n\t\t}\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Creates a `DocumentFragment` instance from given plain object (i.e. parsed JSON string).\n\t * Converts `DocumentFragment` children to proper nodes.\n\t *\n\t * @param {Object} json Plain object to be converted to `DocumentFragment`.\n\t * @returns {module:engine/model/documentfragment~DocumentFragment} `DocumentFragment` instance created using given plain object.\n\t */\n\tstatic fromJSON( json ) {\n\t\tconst children = [];\n\n\t\tfor ( const child of json ) {\n\t\t\tif ( child.name ) {\n\t\t\t\t// If child has name property, it is an Element.\n\t\t\t\tchildren.push( Element.fromJSON( child ) );\n\t\t\t} else {\n\t\t\t\t// Otherwise, it is a Text node.\n\t\t\t\tchildren.push( Text.fromJSON( child ) );\n\t\t\t}\n\t\t}\n\n\t\treturn new DocumentFragment( children );\n\t}\n\n\t/**\n\t * {@link #_insertChild Inserts} one or more nodes at the end of this document fragment.\n\t *\n\t * @protected\n\t * @param {module:engine/model/item~Item|Iterable.<module:engine/model/item~Item>} items Items to be inserted.\n\t */\n\t_appendChild( items ) {\n\t\tthis._insertChild( this.childCount, items );\n\t}\n\n\t/**\n\t * Inserts one or more nodes at the given index and sets {@link module:engine/model/node~Node#parent parent} of these nodes\n\t * to this document fragment.\n\t *\n\t * @protected\n\t * @param {Number} index Index at which nodes should be inserted.\n\t * @param {module:engine/model/item~Item|Iterable.<module:engine/model/item~Item>} items Items to be inserted.\n\t */\n\t_insertChild( index, items ) {\n\t\tconst nodes = normalize( items );\n\n\t\tfor ( const node of nodes ) {\n\t\t\t// If node that is being added to this element is already inside another element, first remove it from the old parent.\n\t\t\tif ( node.parent !== null ) {\n\t\t\t\tnode._remove();\n\t\t\t}\n\n\t\t\tnode.parent = this;\n\t\t}\n\n\t\tthis._children._insertNodes( index, nodes );\n\t}\n\n\t/**\n\t * Removes one or more nodes starting at the given index\n\t * and sets {@link module:engine/model/node~Node#parent parent} of these nodes to `null`.\n\t *\n\t * @protected\n\t * @param {Number} index Index of the first node to remove.\n\t * @param {Number} [howMany=1] Number of nodes to remove.\n\t * @returns {Array.<module:engine/model/node~Node>} Array containing removed nodes.\n\t */\n\t_removeChildren( index, howMany = 1 ) {\n\t\tconst nodes = this._children._removeNodes( index, howMany );\n\n\t\tfor ( const node of nodes ) {\n\t\t\tnode.parent = null;\n\t\t}\n\n\t\treturn nodes;\n\t}\n}\n\n// Converts strings to Text and non-iterables to arrays.\n//\n// @param {String|module:engine/model/item~Item|Iterable.<module:engine/model/item~Item>}\n// @returns {Iterable.<module:engine/model/node~Node>}\nfunction normalize( nodes ) {\n\t// Separate condition because string is iterable.\n\tif ( typeof nodes == 'string' ) {\n\t\treturn [ new Text( nodes ) ];\n\t}\n\n\tif ( !isIterable( nodes ) ) {\n\t\tnodes = [ nodes ];\n\t}\n\n\t// Array.from to enable .map() on non-arrays.\n\treturn Array.from( nodes )\n\t\t.map( node => {\n\t\t\tif ( typeof node == 'string' ) {\n\t\t\t\treturn new Text( node );\n\t\t\t}\n\n\t\t\tif ( node instanceof TextProxy ) {\n\t\t\t\treturn new Text( node.data, node.getAttributes() );\n\t\t\t}\n\n\t\t\treturn node;\n\t\t} );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/utils\n */\n\nimport Node from '../node';\nimport Text from '../text';\nimport TextProxy from '../textproxy';\nimport Range from '../range';\nimport DocumentFragment from '../documentfragment';\nimport NodeList from '../nodelist';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Contains functions used for composing model tree by {@link module:engine/model/operation/operation~Operation operations}.\n * Those functions are built on top of {@link module:engine/model/node~Node node}, and it's child classes', APIs.\n *\n * @protected\n * @namespace utils\n */\n\n/**\n * Inserts given nodes at given position.\n *\n * @protected\n * @function module:engine/model/operation/utils~utils.insert\n * @param {module:engine/model/position~Position} position Position at which nodes should be inserted.\n * @param {module:engine/model/node~NodeSet} nodes Nodes to insert.\n * @returns {module:engine/model/range~Range} Range spanning over inserted elements.\n */\nexport function _insert( position, nodes ) {\n\tnodes = _normalizeNodes( nodes );\n\n\t// We have to count offset before inserting nodes because they can get merged and we would get wrong offsets.\n\tconst offset = nodes.reduce( ( sum, node ) => sum + node.offsetSize, 0 );\n\tconst parent = position.parent;\n\n\t// Insertion might be in a text node, we should split it if that's the case.\n\t_splitNodeAtPosition( position );\n\tconst index = position.index;\n\n\t// Insert nodes at given index. After splitting we have a proper index and insertion is between nodes,\n\t// using basic `Element` API.\n\tparent._insertChild( index, nodes );\n\n\t// Merge text nodes, if possible. Merging is needed only at points where inserted nodes \"touch\" \"old\" nodes.\n\t_mergeNodesAtIndex( parent, index + nodes.length );\n\t_mergeNodesAtIndex( parent, index );\n\n\treturn new Range( position, position.getShiftedBy( offset ) );\n}\n\n/**\n * Removed nodes in given range. Only {@link module:engine/model/range~Range#isFlat flat} ranges are accepted.\n *\n * @protected\n * @function module:engine/model/operation/utils~utils._remove\n * @param {module:engine/model/range~Range} range Range containing nodes to remove.\n * @returns {Array.<module:engine/model/node~Node>}\n */\nexport function _remove( range ) {\n\tif ( !range.isFlat ) {\n\t\t/**\n\t\t * Trying to remove a range which starts and ends in different element.\n\t\t *\n\t\t * @error operation-utils-remove-range-not-flat\n\t\t */\n\t\tthrow new CKEditorError( 'operation-utils-remove-range-not-flat: ' +\n\t\t\t'Trying to remove a range which starts and ends in different element.' );\n\t}\n\n\tconst parent = range.start.parent;\n\n\t// Range may be inside text nodes, we have to split them if that's the case.\n\t_splitNodeAtPosition( range.start );\n\t_splitNodeAtPosition( range.end );\n\n\t// Remove the text nodes using basic `Element` API.\n\tconst removed = parent._removeChildren( range.start.index, range.end.index - range.start.index );\n\n\t// Merge text nodes, if possible. After some nodes were removed, node before and after removed range will be\n\t// touching at the position equal to the removed range beginning. We check merging possibility there.\n\t_mergeNodesAtIndex( parent, range.start.index );\n\n\treturn removed;\n}\n\n/**\n * Moves nodes in given range to given target position. Only {@link module:engine/model/range~Range#isFlat flat} ranges are accepted.\n *\n * @protected\n * @function module:engine/model/operation/utils~utils.move\n * @param {module:engine/model/range~Range} sourceRange Range containing nodes to move.\n * @param {module:engine/model/position~Position} targetPosition Position to which nodes should be moved.\n * @returns {module:engine/model/range~Range} Range containing moved nodes.\n */\nexport function _move( sourceRange, targetPosition ) {\n\tif ( !sourceRange.isFlat ) {\n\t\t/**\n\t\t * Trying to move a range which starts and ends in different element.\n\t\t *\n\t\t * @error operation-utils-move-range-not-flat\n\t\t */\n\t\tthrow new CKEditorError( 'operation-utils-move-range-not-flat: ' +\n\t\t\t'Trying to move a range which starts and ends in different element.' );\n\t}\n\n\tconst nodes = _remove( sourceRange );\n\n\t// We have to fix `targetPosition` because model changed after nodes from `sourceRange` got removed and\n\t// that change might have an impact on `targetPosition`.\n\ttargetPosition = targetPosition._getTransformedByDeletion( sourceRange.start, sourceRange.end.offset - sourceRange.start.offset );\n\n\treturn _insert( targetPosition, nodes );\n}\n\n/**\n * Sets given attribute on nodes in given range. The attributes are only set on top-level nodes of the range, not on its children.\n *\n * @protected\n * @function module:engine/model/operation/utils~utils._setAttribute\n * @param {module:engine/model/range~Range} range Range containing nodes that should have the attribute set. Must be a flat range.\n * @param {String} key Key of attribute to set.\n * @param {*} value Attribute value.\n */\nexport function _setAttribute( range, key, value ) {\n\t// Range might start or end in text nodes, so we have to split them.\n\t_splitNodeAtPosition( range.start );\n\t_splitNodeAtPosition( range.end );\n\n\t// Iterate over all items in the range.\n\tfor ( const item of range.getItems( { shallow: true } ) ) {\n\t\t// Iterator will return `TextProxy` instances but we know that those text proxies will\n\t\t// always represent full text nodes (this is guaranteed thanks to splitting we did before).\n\t\t// So, we can operate on those text proxies' text nodes.\n\t\tconst node = item.is( 'textProxy' ) ? item.textNode : item;\n\n\t\tif ( value !== null ) {\n\t\t\tnode._setAttribute( key, value );\n\t\t} else {\n\t\t\tnode._removeAttribute( key );\n\t\t}\n\n\t\t// After attributes changing it may happen that some text nodes can be merged. Try to merge with previous node.\n\t\t_mergeNodesAtIndex( node.parent, node.index );\n\t}\n\n\t// Try to merge last changed node with it's previous sibling (not covered by the loop above).\n\t_mergeNodesAtIndex( range.end.parent, range.end.index );\n}\n\n/**\n * Normalizes given object or an array of objects to an array of {@link module:engine/model/node~Node nodes}. See\n * {@link module:engine/model/node~NodeSet NodeSet} for details on how normalization is performed.\n *\n * @protected\n * @function module:engine/model/operation/utils~utils.normalizeNodes\n * @param {module:engine/model/node~NodeSet} nodes Objects to normalize.\n * @returns {Array.<module:engine/model/node~Node>} Normalized nodes.\n */\nexport function _normalizeNodes( nodes ) {\n\tconst normalized = [];\n\n\tif ( !( nodes instanceof Array ) ) {\n\t\tnodes = [ nodes ];\n\t}\n\n\t// Convert instances of classes other than Node.\n\tfor ( let i = 0; i < nodes.length; i++ ) {\n\t\tif ( typeof nodes[ i ] == 'string' ) {\n\t\t\tnormalized.push( new Text( nodes[ i ] ) );\n\t\t} else if ( nodes[ i ] instanceof TextProxy ) {\n\t\t\tnormalized.push( new Text( nodes[ i ].data, nodes[ i ].getAttributes() ) );\n\t\t} else if ( nodes[ i ] instanceof DocumentFragment || nodes[ i ] instanceof NodeList ) {\n\t\t\tfor ( const child of nodes[ i ] ) {\n\t\t\t\tnormalized.push( child );\n\t\t\t}\n\t\t} else if ( nodes[ i ] instanceof Node ) {\n\t\t\tnormalized.push( nodes[ i ] );\n\t\t}\n\t\t// Skip unrecognized type.\n\t}\n\n\t// Merge text nodes.\n\tfor ( let i = 1; i < normalized.length; i++ ) {\n\t\tconst node = normalized[ i ];\n\t\tconst prev = normalized[ i - 1 ];\n\n\t\tif ( node instanceof Text && prev instanceof Text && _haveSameAttributes( node, prev ) ) {\n\t\t\t// Doing this instead changing `prev.data` because `data` is readonly.\n\t\t\tnormalized.splice( i - 1, 2, new Text( prev.data + node.data, prev.getAttributes() ) );\n\t\t\ti--;\n\t\t}\n\t}\n\n\treturn normalized;\n}\n\n// Checks if nodes before and after given index in given element are {@link module:engine/model/text~Text text nodes} and\n// merges them into one node if they have same attributes.\n//\n// Merging is done by removing two text nodes and inserting a new text node containing data from both merged text nodes.\n//\n// @private\n// @param {module:engine/model/element~Element} element Parent element of nodes to merge.\n// @param {Number} index Index between nodes to merge.\nfunction _mergeNodesAtIndex( element, index ) {\n\tconst nodeBefore = element.getChild( index - 1 );\n\tconst nodeAfter = element.getChild( index );\n\n\t// Check if both of those nodes are text objects with same attributes.\n\tif ( nodeBefore && nodeAfter && nodeBefore.is( 'text' ) && nodeAfter.is( 'text' ) && _haveSameAttributes( nodeBefore, nodeAfter ) ) {\n\t\t// Append text of text node after index to the before one.\n\t\tconst mergedNode = new Text( nodeBefore.data + nodeAfter.data, nodeBefore.getAttributes() );\n\n\t\t// Remove separate text nodes.\n\t\telement._removeChildren( index - 1, 2 );\n\n\t\t// Insert merged text node.\n\t\telement._insertChild( index - 1, mergedNode );\n\t}\n}\n\n// Checks if given position is in a text node, and if so, splits the text node in two text nodes, each of them\n// containing a part of original text node.\n//\n// @private\n// @param {module:engine/model/position~Position} position Position at which node should be split.\nfunction _splitNodeAtPosition( position ) {\n\tconst textNode = position.textNode;\n\tconst element = position.parent;\n\n\tif ( textNode ) {\n\t\tconst offsetDiff = position.offset - textNode.startOffset;\n\t\tconst index = textNode.index;\n\n\t\telement._removeChildren( index, 1 );\n\n\t\tconst firstPart = new Text( textNode.data.substr( 0, offsetDiff ), textNode.getAttributes() );\n\t\tconst secondPart = new Text( textNode.data.substr( offsetDiff ), textNode.getAttributes() );\n\n\t\telement._insertChild( index, [ firstPart, secondPart ] );\n\t}\n}\n\n// Checks whether two given nodes have same attributes.\n//\n// @private\n// @param {module:engine/model/node~Node} nodeA Node to check.\n// @param {module:engine/model/node~Node} nodeB Node to check.\n// @returns {Boolean} `true` if nodes have same attributes, `false` otherwise.\nfunction _haveSameAttributes( nodeA, nodeB ) {\n\tconst iteratorA = nodeA.getAttributes();\n\tconst iteratorB = nodeB.getAttributes();\n\n\tfor ( const attr of iteratorA ) {\n\t\tif ( attr[ 1 ] !== nodeB.getAttribute( attr[ 0 ] ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\titeratorB.next();\n\t}\n\n\treturn iteratorB.next().done;\n}\n\n/**\n * Value that can be normalized to an array of {@link module:engine/model/node~Node nodes}.\n *\n * Non-arrays are normalized as follows:\n * * {@link module:engine/model/node~Node Node} is left as is,\n * * {@link module:engine/model/textproxy~TextProxy TextProxy} and `String` are normalized to {@link module:engine/model/text~Text Text},\n * * {@link module:engine/model/nodelist~NodeList NodeList} is normalized to an array containing all nodes that are in that node list,\n * * {@link module:engine/model/documentfragment~DocumentFragment DocumentFragment} is normalized to an array containing all of it's\n * * children.\n *\n * Arrays are processed item by item like non-array values and flattened to one array. Normalization always results in\n * a flat array of {@link module:engine/model/node~Node nodes}. Consecutive text nodes (or items normalized to text nodes) will be\n * merged if they have same attributes.\n *\n * @typedef {module:engine/model/node~Node|module:engine/model/textproxy~TextProxy|String|\n * module:engine/model/nodelist~NodeList|module:engine/model/documentfragment~DocumentFragment|Iterable}\n * module:engine/model/node~NodeSet\n */\n","import baseIsEqual from './_baseIsEqual.js';\n\n/**\n * Performs a deep comparison between two values to determine if they are\n * equivalent.\n *\n * **Note:** This method supports comparing arrays, array buffers, booleans,\n * date objects, error objects, maps, numbers, `Object` objects, regexes,\n * sets, strings, symbols, and typed arrays. `Object` objects are compared\n * by their own, not inherited, enumerable properties. Functions and DOM\n * nodes are compared by strict equality, i.e. `===`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.isEqual(object, other);\n * // => true\n *\n * object === other;\n * // => false\n */\nfunction isEqual(value, other) {\n return baseIsEqual(value, other);\n}\n\nexport default isEqual;\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/attributeoperation\n */\n\nimport Operation from './operation';\nimport Range from '../range';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport { _setAttribute } from './utils';\nimport { isEqual } from 'lodash-es';\n\n/**\n * Operation to change nodes' attribute.\n *\n * Using this class you can add, remove or change value of the attribute.\n *\n * @extends module:engine/model/operation/operation~Operation\n */\nexport default class AttributeOperation extends Operation {\n\t/**\n\t * Creates an operation that changes, removes or adds attributes.\n\t *\n\t * If only `newValue` is set, attribute will be added on a node. Note that all nodes in operation's range must not\n\t * have an attribute with the same key as the added attribute.\n\t *\n\t * If only `oldValue` is set, then attribute with given key will be removed. Note that all nodes in operation's range\n\t * must have an attribute with that key added.\n\t *\n\t * If both `newValue` and `oldValue` are set, then the operation will change the attribute value. Note that all nodes in\n\t * operation's ranges must already have an attribute with given key and `oldValue` as value\n\t *\n\t * @param {module:engine/model/range~Range} range Range on which the operation should be applied. Must be a flat range.\n\t * @param {String} key Key of an attribute to change or remove.\n\t * @param {*} oldValue Old value of the attribute with given key or `null`, if attribute was not set before.\n\t * @param {*} newValue New value of the attribute with given key or `null`, if operation should remove attribute.\n\t * @param {Number|null} baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */\n\tconstructor( range, key, oldValue, newValue, baseVersion ) {\n\t\tsuper( baseVersion );\n\n\t\t/**\n\t\t * Range on which operation should be applied.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/range~Range}\n\t\t */\n\t\tthis.range = range.clone();\n\n\t\t/**\n\t\t * Key of an attribute to change or remove.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.key = key;\n\n\t\t/**\n\t\t * Old value of the attribute with given key or `null`, if attribute was not set before.\n\t\t *\n\t\t * @readonly\n\t\t * @member {*}\n\t\t */\n\t\tthis.oldValue = oldValue === undefined ? null : oldValue;\n\n\t\t/**\n\t\t * New value of the attribute with given key or `null`, if operation should remove attribute.\n\t\t *\n\t\t * @readonly\n\t\t * @member {*}\n\t\t */\n\t\tthis.newValue = newValue === undefined ? null : newValue;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\tif ( this.oldValue === null ) {\n\t\t\treturn 'addAttribute';\n\t\t} else if ( this.newValue === null ) {\n\t\t\treturn 'removeAttribute';\n\t\t} else {\n\t\t\treturn 'changeAttribute';\n\t\t}\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns {module:engine/model/operation/attributeoperation~AttributeOperation} Clone of this operation.\n\t */\n\tclone() {\n\t\treturn new AttributeOperation( this.range, this.key, this.oldValue, this.newValue, this.baseVersion );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t *\n\t * @returns {module:engine/model/operation/attributeoperation~AttributeOperation}\n\t */\n\tgetReversed() {\n\t\treturn new AttributeOperation( this.range, this.key, this.newValue, this.oldValue, this.baseVersion + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\n\t\tjson.range = this.range.toJSON();\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_validate() {\n\t\tif ( !this.range.isFlat ) {\n\t\t\t/**\n\t\t\t * The range to change is not flat.\n\t\t\t *\n\t\t\t * @error attribute-operation-range-not-flat\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'attribute-operation-range-not-flat: The range to change is not flat.' );\n\t\t}\n\n\t\tfor ( const item of this.range.getItems( { shallow: true } ) ) {\n\t\t\tif ( this.oldValue !== null && !isEqual( item.getAttribute( this.key ), this.oldValue ) ) {\n\t\t\t\t/**\n\t\t\t\t * Changed node has different attribute value than operation's old attribute value.\n\t\t\t\t *\n\t\t\t\t * @error attribute-operation-wrong-old-value\n\t\t\t\t * @param {module:engine/model/item~Item} item\n\t\t\t\t * @param {String} key\n\t\t\t\t * @param {*} value\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'attribute-operation-wrong-old-value: Changed node has different attribute value than operation\\'s ' +\n\t\t\t\t\t'old attribute value.',\n\t\t\t\t\t{ item, key: this.key, value: this.oldValue }\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif ( this.oldValue === null && this.newValue !== null && item.hasAttribute( this.key ) ) {\n\t\t\t\t/**\n\t\t\t\t * The attribute with given key already exists for the given node.\n\t\t\t\t *\n\t\t\t\t * @error attribute-operation-attribute-exists\n\t\t\t\t * @param {module:engine/model/node~Node} node\n\t\t\t\t * @param {String} key\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'attribute-operation-attribute-exists: The attribute with given key already exists.',\n\t\t\t\t\t{ node: item, key: this.key }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_execute() {\n\t\t// If value to set is same as old value, don't do anything.\n\t\tif ( !isEqual( this.oldValue, this.newValue ) ) {\n\t\t\t// Execution.\n\t\t\t_setAttribute( this.range, this.key, this.newValue );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'AttributeOperation';\n\t}\n\n\t/**\n\t * Creates `AttributeOperation` object from deserilized object, i.e. from parsed JSON string.\n\t *\n\t * @param {Object} json Deserialized JSON object.\n\t * @param {module:engine/model/document~Document} document Document on which this operation will be applied.\n\t * @returns {module:engine/model/operation/attributeoperation~AttributeOperation}\n\t */\n\tstatic fromJSON( json, document ) {\n\t\treturn new AttributeOperation( Range.fromJSON( json.range, document ), json.key, json.oldValue, json.newValue, json.baseVersion );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/detachoperation\n */\n\nimport Operation from './operation';\nimport Range from '../range';\nimport { _remove } from './utils';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Operation to permanently remove node from detached root.\n * Note this operation is only a local operation and won't be send to the other clients.\n *\n * @extends module:engine/model/operation/operation~Operation\n */\nexport default class DetachOperation extends Operation {\n\t/**\n\t * Creates an insert operation.\n\t *\n\t * @param {module:engine/model/position~Position} sourcePosition\n\t * Position before the first {@link module:engine/model/item~Item model item} to move.\n\t * @param {Number} howMany Offset size of moved range. Moved range will start from `sourcePosition` and end at\n\t * `sourcePosition` with offset shifted by `howMany`.\n\t */\n\tconstructor( sourcePosition, howMany ) {\n\t\tsuper( null );\n\n\t\t/**\n\t\t * Position before the first {@link module:engine/model/item~Item model item} to detach.\n\t\t *\n\t\t * @member {module:engine/model/position~Position} #sourcePosition\n\t\t */\n\t\tthis.sourcePosition = sourcePosition.clone();\n\n\t\t/**\n\t\t * Offset size of moved range.\n\t\t *\n\t\t * @member {Number} #howMany\n\t\t */\n\t\tthis.howMany = howMany;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'detach';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\n\t\tjson.sourcePosition = this.sourcePosition.toJSON();\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_validate() {\n\t\tif ( this.sourcePosition.root.document ) {\n\t\t\t/**\n\t\t\t * Cannot detach document node.\n\t\t\t *\n\t\t\t * @error detach-operation-on-document-node\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'detach-operation-on-document-node: Cannot detach document node.' );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_execute() {\n\t\t_remove( Range._createFromPositionAndShift( this.sourcePosition, this.howMany ) );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'DetachOperation';\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/moveoperation\n */\n\nimport Operation from './operation';\nimport Position from '../position';\nimport Range from '../range';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport compareArrays from '@ckeditor/ckeditor5-utils/src/comparearrays';\nimport { _move } from './utils';\n\n/**\n * Operation to move a range of {@link module:engine/model/item~Item model items}\n * to given {@link module:engine/model/position~Position target position}.\n *\n * @extends module:engine/model/operation/operation~Operation\n */\nexport default class MoveOperation extends Operation {\n\t/**\n\t * Creates a move operation.\n\t *\n\t * @param {module:engine/model/position~Position} sourcePosition\n\t * Position before the first {@link module:engine/model/item~Item model item} to move.\n\t * @param {Number} howMany Offset size of moved range. Moved range will start from `sourcePosition` and end at\n\t * `sourcePosition` with offset shifted by `howMany`.\n\t * @param {module:engine/model/position~Position} targetPosition Position at which moved nodes will be inserted.\n\t * @param {Number|null} baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */\n\tconstructor( sourcePosition, howMany, targetPosition, baseVersion ) {\n\t\tsuper( baseVersion );\n\n\t\t/**\n\t\t * Position before the first {@link module:engine/model/item~Item model item} to move.\n\t\t *\n\t\t * @member {module:engine/model/position~Position} module:engine/model/operation/moveoperation~MoveOperation#sourcePosition\n\t\t */\n\t\tthis.sourcePosition = sourcePosition.clone();\n\t\t// `'toNext'` because `sourcePosition` is a bit like a start of the moved range.\n\t\tthis.sourcePosition.stickiness = 'toNext';\n\n\t\t/**\n\t\t * Offset size of moved range.\n\t\t *\n\t\t * @member {Number} module:engine/model/operation/moveoperation~MoveOperation#howMany\n\t\t */\n\t\tthis.howMany = howMany;\n\n\t\t/**\n\t\t * Position at which moved nodes will be inserted.\n\t\t *\n\t\t * @member {module:engine/model/position~Position} module:engine/model/operation/moveoperation~MoveOperation#targetPosition\n\t\t */\n\t\tthis.targetPosition = targetPosition.clone();\n\t\tthis.targetPosition.stickiness = 'toNone';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\tif ( this.targetPosition.root.rootName == '$graveyard' ) {\n\t\t\treturn 'remove';\n\t\t} else if ( this.sourcePosition.root.rootName == '$graveyard' ) {\n\t\t\treturn 'reinsert';\n\t\t}\n\n\t\treturn 'move';\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns {module:engine/model/operation/moveoperation~MoveOperation} Clone of this operation.\n\t */\n\tclone() {\n\t\treturn new this.constructor( this.sourcePosition, this.howMany, this.targetPosition, this.baseVersion );\n\t}\n\n\t/**\n\t * Returns the start position of the moved range after it got moved. This may be different than\n\t * {@link module:engine/model/operation/moveoperation~MoveOperation#targetPosition} in some cases, i.e. when a range is moved\n\t * inside the same parent but {@link module:engine/model/operation/moveoperation~MoveOperation#targetPosition targetPosition}\n\t * is after {@link module:engine/model/operation/moveoperation~MoveOperation#sourcePosition sourcePosition}.\n\t *\n\t *\t\t vv vv\n\t *\t\tabcdefg ===> adefbcg\n\t *\t\t ^ ^\n\t *\t\t targetPos\tmovedRangeStart\n\t *\t\t offset 6\toffset 4\n\t *\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tgetMovedRangeStart() {\n\t\treturn this.targetPosition._getTransformedByDeletion( this.sourcePosition, this.howMany );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t *\n\t * @returns {module:engine/model/operation/moveoperation~MoveOperation}\n\t */\n\tgetReversed() {\n\t\tconst newTargetPosition = this.sourcePosition._getTransformedByInsertion( this.targetPosition, this.howMany );\n\n\t\treturn new this.constructor( this.getMovedRangeStart(), this.howMany, newTargetPosition, this.baseVersion + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_validate() {\n\t\tconst sourceElement = this.sourcePosition.parent;\n\t\tconst targetElement = this.targetPosition.parent;\n\t\tconst sourceOffset = this.sourcePosition.offset;\n\t\tconst targetOffset = this.targetPosition.offset;\n\n\t\t// Validate whether move operation has correct parameters.\n\t\t// Validation is pretty complex but move operation is one of the core ways to manipulate the document state.\n\t\t// We expect that many errors might be connected with one of scenarios described below.\n\t\tif ( !sourceElement || !targetElement ) {\n\t\t\t/**\n\t\t\t * Source position or target position is invalid.\n\t\t\t *\n\t\t\t * @error move-operation-position-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'move-operation-position-invalid: Source position or target position is invalid.'\n\t\t\t);\n\t\t} else if ( sourceOffset + this.howMany > sourceElement.maxOffset ) {\n\t\t\t/**\n\t\t\t * The nodes which should be moved do not exist.\n\t\t\t *\n\t\t\t * @error move-operation-nodes-do-not-exist\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'move-operation-nodes-do-not-exist: The nodes which should be moved do not exist.'\n\t\t\t);\n\t\t} else if ( sourceElement === targetElement && sourceOffset < targetOffset && targetOffset < sourceOffset + this.howMany ) {\n\t\t\t/**\n\t\t\t * Trying to move a range of nodes into the middle of that range.\n\t\t\t *\n\t\t\t * @error move-operation-range-into-itself\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'move-operation-range-into-itself: Trying to move a range of nodes to the inside of that range.'\n\t\t\t);\n\t\t} else if ( this.sourcePosition.root == this.targetPosition.root ) {\n\t\t\tif ( compareArrays( this.sourcePosition.getParentPath(), this.targetPosition.getParentPath() ) == 'prefix' ) {\n\t\t\t\tconst i = this.sourcePosition.path.length - 1;\n\n\t\t\t\tif ( this.targetPosition.path[ i ] >= sourceOffset && this.targetPosition.path[ i ] < sourceOffset + this.howMany ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * Trying to move a range of nodes into one of nodes from that range.\n\t\t\t\t\t *\n\t\t\t\t\t * @error move-operation-node-into-itself\n\t\t\t\t\t */\n\t\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t\t'move-operation-node-into-itself: Trying to move a range of nodes into one of nodes from that range.'\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_execute() {\n\t\t_move( Range._createFromPositionAndShift( this.sourcePosition, this.howMany ), this.targetPosition );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\n\t\tjson.sourcePosition = this.sourcePosition.toJSON();\n\t\tjson.targetPosition = this.targetPosition.toJSON();\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'MoveOperation';\n\t}\n\n\t/**\n\t * Creates `MoveOperation` object from deserilized object, i.e. from parsed JSON string.\n\t *\n\t * @param {Object} json Deserialized JSON object.\n\t * @param {module:engine/model/document~Document} document Document on which this operation will be applied.\n\t * @returns {module:engine/model/operation/moveoperation~MoveOperation}\n\t */\n\tstatic fromJSON( json, document ) {\n\t\tconst sourcePosition = Position.fromJSON( json.sourcePosition, document );\n\t\tconst targetPosition = Position.fromJSON( json.targetPosition, document );\n\n\t\treturn new this( sourcePosition, json.howMany, targetPosition, json.baseVersion );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/insertoperation\n */\n\nimport Operation from './operation';\nimport Position from '../position';\nimport NodeList from '../nodelist';\nimport MoveOperation from './moveoperation';\nimport { _insert, _normalizeNodes } from './utils';\nimport Text from '../text';\nimport Element from '../element';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Operation to insert one or more nodes at given position in the model.\n *\n * @extends module:engine/model/operation/operation~Operation\n */\nexport default class InsertOperation extends Operation {\n\t/**\n\t * Creates an insert operation.\n\t *\n\t * @param {module:engine/model/position~Position} position Position of insertion.\n\t * @param {module:engine/model/node~NodeSet} nodes The list of nodes to be inserted.\n\t * @param {Number|null} baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */\n\tconstructor( position, nodes, baseVersion ) {\n\t\tsuper( baseVersion );\n\n\t\t/**\n\t\t * Position of insertion.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/position~Position} module:engine/model/operation/insertoperation~InsertOperation#position\n\t\t */\n\t\tthis.position = position.clone();\n\t\tthis.position.stickiness = 'toNone';\n\n\t\t/**\n\t\t * List of nodes to insert.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/nodelist~NodeList} module:engine/model/operation/insertoperation~InsertOperation#nodeList\n\t\t */\n\t\tthis.nodes = new NodeList( _normalizeNodes( nodes ) );\n\n\t\t/**\n\t\t * Flag deciding how the operation should be transformed. If set to `true`, nodes might get additional attributes\n\t\t * during operational transformation. This happens when the operation insertion position is inside of a range\n\t\t * where attributes have changed.\n\t\t *\n\t\t * @member {Boolean} module:engine/model/operation/insertoperation~InsertOperation#shouldReceiveAttributes\n\t\t */\n\t\tthis.shouldReceiveAttributes = false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'insert';\n\t}\n\n\t/**\n\t * Total offset size of inserted nodes.\n\t *\n\t * @returns {Number}\n\t */\n\tget howMany() {\n\t\treturn this.nodes.maxOffset;\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns {module:engine/model/operation/insertoperation~InsertOperation} Clone of this operation.\n\t */\n\tclone() {\n\t\tconst nodes = new NodeList( [ ...this.nodes ].map( node => node._clone( true ) ) );\n\t\tconst insert = new InsertOperation( this.position, nodes, this.baseVersion );\n\n\t\tinsert.shouldReceiveAttributes = this.shouldReceiveAttributes;\n\n\t\treturn insert;\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t *\n\t * @returns {module:engine/model/operation/moveoperation~MoveOperation}\n\t */\n\tgetReversed() {\n\t\tconst graveyard = this.position.root.document.graveyard;\n\t\tconst gyPosition = new Position( graveyard, [ 0 ] );\n\n\t\treturn new MoveOperation( this.position, this.nodes.maxOffset, gyPosition, this.baseVersion + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_validate() {\n\t\tconst targetElement = this.position.parent;\n\n\t\tif ( !targetElement || targetElement.maxOffset < this.position.offset ) {\n\t\t\t/**\n\t\t\t * Insertion position is invalid.\n\t\t\t *\n\t\t\t * @error insert-operation-position-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'insert-operation-position-invalid: Insertion position is invalid.'\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_execute() {\n\t\t// What happens here is that we want original nodes be passed to writer because we want original nodes\n\t\t// to be inserted to the model. But in InsertOperation, we want to keep those nodes as they were added\n\t\t// to the operation, not modified. For example, text nodes can get merged or cropped while Elements can\n\t\t// get children. It is important that InsertOperation has the copy of original nodes in intact state.\n\t\tconst originalNodes = this.nodes;\n\t\tthis.nodes = new NodeList( [ ...originalNodes ].map( node => node._clone( true ) ) );\n\n\t\t_insert( this.position, originalNodes );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\n\t\tjson.position = this.position.toJSON();\n\t\tjson.nodes = this.nodes.toJSON();\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'InsertOperation';\n\t}\n\n\t/**\n\t * Creates `InsertOperation` object from deserilized object, i.e. from parsed JSON string.\n\t *\n\t * @param {Object} json Deserialized JSON object.\n\t * @param {module:engine/model/document~Document} document Document on which this operation will be applied.\n\t * @returns {module:engine/model/operation/insertoperation~InsertOperation}\n\t */\n\tstatic fromJSON( json, document ) {\n\t\tconst children = [];\n\n\t\tfor ( const child of json.nodes ) {\n\t\t\tif ( child.name ) {\n\t\t\t\t// If child has name property, it is an Element.\n\t\t\t\tchildren.push( Element.fromJSON( child ) );\n\t\t\t} else {\n\t\t\t\t// Otherwise, it is a Text node.\n\t\t\t\tchildren.push( Text.fromJSON( child ) );\n\t\t\t}\n\t\t}\n\n\t\tconst insert = new InsertOperation( Position.fromJSON( json.position, document ), children, json.baseVersion );\n\t\tinsert.shouldReceiveAttributes = json.shouldReceiveAttributes;\n\n\t\treturn insert;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/markeroperation\n */\n\nimport Operation from './operation';\nimport Range from '../range';\n\n/**\n * @extends module:engine/model/operation/operation~Operation\n */\nexport default class MarkerOperation extends Operation {\n\t/**\n\t * @param {String} name Marker name.\n\t * @param {module:engine/model/range~Range} oldRange Marker range before the change.\n\t * @param {module:engine/model/range~Range} newRange Marker range after the change.\n\t * @param {module:engine/model/markercollection~MarkerCollection} markers Marker collection on which change should be executed.\n\t * @param {Boolean} affectsData Specifies whether the marker operation affects the data produced by the data pipeline\n\t * (is persisted in the editor's data).\n\t * @param {Number|null} baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */\n\tconstructor( name, oldRange, newRange, markers, affectsData, baseVersion ) {\n\t\tsuper( baseVersion );\n\n\t\t/**\n\t\t * Marker name.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.name = name;\n\n\t\t/**\n\t\t * Marker range before the change.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/range~Range}\n\t\t */\n\t\tthis.oldRange = oldRange ? oldRange.clone() : null;\n\n\t\t/**\n\t\t * Marker range after the change.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/range~Range}\n\t\t */\n\t\tthis.newRange = newRange ? newRange.clone() : null;\n\n\t\t/**\n\t\t * Specifies whether the marker operation affects the data produced by the data pipeline\n\t\t * (is persisted in the editor's data).\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis.affectsData = affectsData;\n\n\t\t/**\n\t\t * Marker collection on which change should be executed.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/markercollection~MarkerCollection}\n\t\t */\n\t\tthis._markers = markers;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'marker';\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns {module:engine/model/operation/markeroperation~MarkerOperation} Clone of this operation.\n\t */\n\tclone() {\n\t\treturn new MarkerOperation( this.name, this.oldRange, this.newRange, this._markers, this.affectsData, this.baseVersion );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t *\n\t * @returns {module:engine/model/operation/markeroperation~MarkerOperation}\n\t */\n\tgetReversed() {\n\t\treturn new MarkerOperation( this.name, this.newRange, this.oldRange, this._markers, this.affectsData, this.baseVersion + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_execute() {\n\t\tconst type = this.newRange ? '_set' : '_remove';\n\n\t\tthis._markers[ type ]( this.name, this.newRange, true, this.affectsData );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\n\t\tif ( this.oldRange ) {\n\t\t\tjson.oldRange = this.oldRange.toJSON();\n\t\t}\n\n\t\tif ( this.newRange ) {\n\t\t\tjson.newRange = this.newRange.toJSON();\n\t\t}\n\n\t\tdelete json._markers;\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'MarkerOperation';\n\t}\n\n\t/**\n\t * Creates `MarkerOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param {Object} json Deserialized JSON object.\n\t * @param {module:engine/model/document~Document} document Document on which this operation will be applied.\n\t * @returns {module:engine/model/operation/markeroperation~MarkerOperation}\n\t */\n\tstatic fromJSON( json, document ) {\n\t\treturn new MarkerOperation(\n\t\t\tjson.name,\n\t\t\tjson.oldRange ? Range.fromJSON( json.oldRange, document ) : null,\n\t\t\tjson.newRange ? Range.fromJSON( json.newRange, document ) : null,\n\t\t\tdocument.model.markers,\n\t\t\tjson.affectsData,\n\t\t\tjson.baseVersion\n\t\t);\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/renameoperation\n */\n\nimport Operation from './operation';\nimport Element from '../element';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport Position from '../position';\n\n/**\n * Operation to change element's name.\n *\n * Using this class you can change element's name.\n *\n * @extends module:engine/model/operation/operation~Operation\n */\nexport default class RenameOperation extends Operation {\n\t/**\n\t * Creates an operation that changes element's name.\n\t *\n\t * @param {module:engine/model/position~Position} position Position before an element to change.\n\t * @param {String} oldName Current name of the element.\n\t * @param {String} newName New name for the element.\n\t * @param {Number|null} baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */\n\tconstructor( position, oldName, newName, baseVersion ) {\n\t\tsuper( baseVersion );\n\n\t\t/**\n\t\t * Position before an element to change.\n\t\t *\n\t\t * @member {module:engine/model/position~Position} module:engine/model/operation/renameoperation~RenameOperation#position\n\t\t */\n\t\tthis.position = position;\n\t\t// This position sticks to the next node because it is a position before the node that we want to change.\n\t\tthis.position.stickiness = 'toNext';\n\n\t\t/**\n\t\t * Current name of the element.\n\t\t *\n\t\t * @member {String} module:engine/model/operation/renameoperation~RenameOperation#oldName\n\t\t */\n\t\tthis.oldName = oldName;\n\n\t\t/**\n\t\t * New name for the element.\n\t\t *\n\t\t * @member {String} module:engine/model/operation/renameoperation~RenameOperation#newName\n\t\t */\n\t\tthis.newName = newName;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'rename';\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns {module:engine/model/operation/renameoperation~RenameOperation} Clone of this operation.\n\t */\n\tclone() {\n\t\treturn new RenameOperation( this.position.clone(), this.oldName, this.newName, this.baseVersion );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t *\n\t * @returns {module:engine/model/operation/renameoperation~RenameOperation}\n\t */\n\tgetReversed() {\n\t\treturn new RenameOperation( this.position.clone(), this.newName, this.oldName, this.baseVersion + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_validate() {\n\t\tconst element = this.position.nodeAfter;\n\n\t\tif ( !( element instanceof Element ) ) {\n\t\t\t/**\n\t\t\t * Given position is invalid or node after it is not instance of Element.\n\t\t\t *\n\t\t\t * @error rename-operation-wrong-position\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'rename-operation-wrong-position: Given position is invalid or node after it is not an instance of Element.'\n\t\t\t);\n\t\t} else if ( element.name !== this.oldName ) {\n\t\t\t/**\n\t\t\t * Element to change has different name than operation's old name.\n\t\t\t *\n\t\t\t * @error rename-operation-wrong-name\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'rename-operation-wrong-name: Element to change has different name than operation\\'s old name.'\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_execute() {\n\t\tconst element = this.position.nodeAfter;\n\n\t\telement.name = this.newName;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\n\t\tjson.position = this.position.toJSON();\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'RenameOperation';\n\t}\n\n\t/**\n\t * Creates `RenameOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param {Object} json Deserialized JSON object.\n\t * @param {module:engine/model/document~Document} document Document on which this operation will be applied.\n\t * @returns {module:engine/model/operation/attributeoperation~AttributeOperation}\n\t */\n\tstatic fromJSON( json, document ) {\n\t\treturn new RenameOperation( Position.fromJSON( json.position, document ), json.oldName, json.newName, json.baseVersion );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/rootattributeoperation\n */\n\nimport Operation from './operation';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Operation to change root element's attribute. Using this class you can add, remove or change value of the attribute.\n *\n * This operation is needed, because root elements can't be changed through\n * @link module:engine/model/operation/attributeoperation~AttributeOperation}.\n * It is because {@link module:engine/model/operation/attributeoperation~AttributeOperation}\n * requires a range to change and root element can't\n * be a part of range because every {@link module:engine/model/position~Position} has to be inside a root.\n * {@link module:engine/model/position~Position} can't be created before a root element.\n *\n * @extends module:engine/model/operation/operation~Operation\n */\nexport default class RootAttributeOperation extends Operation {\n\t/**\n\t * Creates an operation that changes, removes or adds attributes on root element.\n\t *\n\t * @see module:engine/model/operation/attributeoperation~AttributeOperation\n\t * @param {module:engine/model/rootelement~RootElement} root Root element to change.\n\t * @param {String} key Key of an attribute to change or remove.\n\t * @param {*} oldValue Old value of the attribute with given key or `null` if adding a new attribute.\n\t * @param {*} newValue New value to set for the attribute. If `null`, then the operation just removes the attribute.\n\t * @param {Number|null} baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */\n\tconstructor( root, key, oldValue, newValue, baseVersion ) {\n\t\tsuper( baseVersion );\n\n\t\t/**\n\t\t * Root element to change.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/rootelement~RootElement}\n\t\t */\n\t\tthis.root = root;\n\n\t\t/**\n\t\t * Key of an attribute to change or remove.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.key = key;\n\n\t\t/**\n\t\t * Old value of the attribute with given key or `null` if adding a new attribute.\n\t\t *\n\t\t * @readonly\n\t\t * @member {*}\n\t\t */\n\t\tthis.oldValue = oldValue;\n\n\t\t/**\n\t\t * New value to set for the attribute. If `null`, then the operation just removes the attribute.\n\t\t *\n\t\t * @readonly\n\t\t * @member {*}\n\t\t */\n\t\tthis.newValue = newValue;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\tif ( this.oldValue === null ) {\n\t\t\treturn 'addRootAttribute';\n\t\t} else if ( this.newValue === null ) {\n\t\t\treturn 'removeRootAttribute';\n\t\t} else {\n\t\t\treturn 'changeRootAttribute';\n\t\t}\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns {module:engine/model/operation/rootattributeoperation~RootAttributeOperation} Clone of this operation.\n\t */\n\tclone() {\n\t\treturn new RootAttributeOperation( this.root, this.key, this.oldValue, this.newValue, this.baseVersion );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t *\n\t * @returns {module:engine/model/operation/rootattributeoperation~RootAttributeOperation}\n\t */\n\tgetReversed() {\n\t\treturn new RootAttributeOperation( this.root, this.key, this.newValue, this.oldValue, this.baseVersion + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_validate() {\n\t\tif ( this.root != this.root.root || this.root.is( 'documentFragment' ) ) {\n\t\t\t/**\n\t\t\t * The element to change is not a root element.\n\t\t\t *\n\t\t\t * @error rootattribute-operation-not-a-root\n\t\t\t * @param {module:engine/model/rootelement~RootElement} root\n\t\t\t * @param {String} key\n\t\t\t * @param {*} value\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'rootattribute-operation-not-a-root: The element to change is not a root element.',\n\t\t\t\t{ root: this.root, key: this.key }\n\t\t\t);\n\t\t}\n\n\t\tif ( this.oldValue !== null && this.root.getAttribute( this.key ) !== this.oldValue ) {\n\t\t\t/**\n\t\t\t * The attribute which should be removed does not exists for the given node.\n\t\t\t *\n\t\t\t * @error rootattribute-operation-wrong-old-value\n\t\t\t * @param {module:engine/model/rootelement~RootElement} root\n\t\t\t * @param {String} key\n\t\t\t * @param {*} value\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'rootattribute-operation-wrong-old-value: Changed node has different attribute value than operation\\'s ' +\n\t\t\t\t'old attribute value.',\n\t\t\t\t{ root: this.root, key: this.key }\n\t\t\t);\n\t\t}\n\n\t\tif ( this.oldValue === null && this.newValue !== null && this.root.hasAttribute( this.key ) ) {\n\t\t\t/**\n\t\t\t * The attribute with given key already exists for the given node.\n\t\t\t *\n\t\t\t * @error rootattribute-operation-attribute-exists\n\t\t\t * @param {module:engine/model/rootelement~RootElement} root\n\t\t\t * @param {String} key\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'rootattribute-operation-attribute-exists: The attribute with given key already exists.',\n\t\t\t\t{ root: this.root, key: this.key }\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_execute() {\n\t\tif ( this.newValue !== null ) {\n\t\t\tthis.root._setAttribute( this.key, this.newValue );\n\t\t} else {\n\t\t\tthis.root._removeAttribute( this.key );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\n\t\tjson.root = this.root.toJSON();\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'RootAttributeOperation';\n\t}\n\n\t/**\n\t * Creates RootAttributeOperation object from deserilized object, i.e. from parsed JSON string.\n\t *\n\t * @param {Object} json Deserialized JSON object.\n\t * @param {module:engine/model/document~Document} document Document on which this operation will be applied.\n\t * @returns {module:engine/model/operation/rootattributeoperation~RootAttributeOperation}\n\t */\n\tstatic fromJSON( json, document ) {\n\t\tif ( !document.getRoot( json.root ) ) {\n\t\t\t/**\n\t\t\t * Cannot create RootAttributeOperation for document. Root with specified name does not exist.\n\t\t\t *\n\t\t\t * @error rootattributeoperation-fromjson-no-root\n\t\t\t * @param {String} rootName\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'rootattribute-operation-fromjson-no-root: Cannot create RootAttributeOperation. Root with specified name does not exist.',\n\t\t\t\t{ rootName: json.root }\n\t\t\t);\n\t\t}\n\n\t\treturn new RootAttributeOperation( document.getRoot( json.root ), json.key, json.oldValue, json.newValue, json.baseVersion );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/mergeoperation\n */\n\nimport Operation from './operation';\nimport SplitOperation from './splitoperation';\nimport Position from '../position';\nimport Range from '../range';\nimport { _move } from './utils';\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Operation to merge two {@link module:engine/model/element~Element elements}.\n *\n * The merged element is the parent of {@link ~MergeOperation#sourcePosition} and it is merged into the parent of\n * {@link ~MergeOperation#targetPosition}. All nodes from the merged element are moved to {@link ~MergeOperation#targetPosition}.\n *\n * The merged element is moved to the graveyard at {@link ~MergeOperation#graveyardPosition}.\n *\n * @extends module:engine/model/operation/operation~Operation\n */\nexport default class MergeOperation extends Operation {\n\t/**\n\t * Creates a merge operation.\n\t *\n\t * @param {module:engine/model/position~Position} sourcePosition Position inside the merged element. All nodes from that\n\t * element after that position will be moved to {@link ~#targetPosition}.\n\t * @param {Number} howMany Summary offset size of nodes which will be moved from the merged element to the new parent.\n\t * @param {module:engine/model/position~Position} targetPosition Position which the nodes from the merged elements will be moved to.\n\t * @param {module:engine/model/position~Position} graveyardPosition Position in graveyard to which the merged element will be moved.\n\t * @param {Number|null} baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */\n\tconstructor( sourcePosition, howMany, targetPosition, graveyardPosition, baseVersion ) {\n\t\tsuper( baseVersion );\n\n\t\t/**\n\t\t * Position inside the merged element. All nodes from that element after that position will be moved to {@link ~#targetPosition}.\n\t\t *\n\t\t * @member {module:engine/model/position~Position} module:engine/model/operation/mergeoperation~MergeOperation#sourcePosition\n\t\t */\n\t\tthis.sourcePosition = sourcePosition.clone();\n\t\t// This is, and should always remain, the first position in its parent.\n\t\tthis.sourcePosition.stickiness = 'toPrevious';\n\n\t\t/**\n\t\t * Summary offset size of nodes which will be moved from the merged element to the new parent.\n\t\t *\n\t\t * @member {Number} module:engine/model/operation/mergeoperation~MergeOperation#howMany\n\t\t */\n\t\tthis.howMany = howMany;\n\n\t\t/**\n\t\t * Position which the nodes from the merged elements will be moved to.\n\t\t *\n\t\t * @member {module:engine/model/position~Position} module:engine/model/operation/mergeoperation~MergeOperation#targetPosition\n\t\t */\n\t\tthis.targetPosition = targetPosition.clone();\n\t\t// Except of a rare scenario in `MergeOperation` x `MergeOperation` transformation,\n\t\t// this is, and should always remain, the last position in its parent.\n\t\tthis.targetPosition.stickiness = 'toNext';\n\n\t\t/**\n\t\t * Position in graveyard to which the merged element will be moved.\n\t\t *\n\t\t * @member {module:engine/model/position~Position} module:engine/model/operation/mergeoperation~MergeOperation#graveyardPosition\n\t\t */\n\t\tthis.graveyardPosition = graveyardPosition.clone();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'merge';\n\t}\n\n\t/**\n\t * Position before the merged element (which will be deleted).\n\t *\n\t * @readonly\n\t * @type {module:engine/model/position~Position}\n\t */\n\tget deletionPosition() {\n\t\treturn new Position( this.sourcePosition.root, this.sourcePosition.path.slice( 0, -1 ) );\n\t}\n\n\t/**\n\t * Artificial range that contains all the nodes from the merged element that will be moved to {@link ~MergeOperation#sourcePosition}.\n\t * The range starts at {@link ~MergeOperation#sourcePosition} and ends in the same parent, at `POSITIVE_INFINITY` offset.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/range~Range}\n\t */\n\tget movedRange() {\n\t\tconst end = this.sourcePosition.getShiftedBy( Number.POSITIVE_INFINITY );\n\n\t\treturn new Range( this.sourcePosition, end );\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns {module:engine/model/operation/mergeoperation~MergeOperation} Clone of this operation.\n\t */\n\tclone() {\n\t\treturn new this.constructor( this.sourcePosition, this.howMany, this.targetPosition, this.graveyardPosition, this.baseVersion );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t *\n\t * @returns {module:engine/model/operation/splitoperation~SplitOperation}\n\t */\n\tgetReversed() {\n\t\t// Positions in this method are transformed by this merge operation because the split operation bases on\n\t\t// the context after this merge operation happened (because split operation reverses it).\n\t\t// So we need to acknowledge that the merge operation happened and those positions changed a little.\n\t\tconst targetPosition = this.targetPosition._getTransformedByMergeOperation( this );\n\n\t\tconst path = this.sourcePosition.path.slice( 0, -1 );\n\t\tconst insertionPosition = new Position( this.sourcePosition.root, path )._getTransformedByMergeOperation( this );\n\n\t\tconst split = new SplitOperation( targetPosition, this.howMany, this.graveyardPosition, this.baseVersion + 1 );\n\t\tsplit.insertionPosition = insertionPosition;\n\n\t\treturn split;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_validate() {\n\t\tconst sourceElement = this.sourcePosition.parent;\n\t\tconst targetElement = this.targetPosition.parent;\n\n\t\t// Validate whether merge operation has correct parameters.\n\t\tif ( !sourceElement || !sourceElement.is( 'element' ) || !sourceElement.parent ) {\n\t\t\t/**\n\t\t\t * Merge source position is invalid.\n\t\t\t *\n\t\t\t * @error merge-operation-source-position-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'merge-operation-source-position-invalid: Merge source position is invalid.' );\n\t\t} else if ( !targetElement || !targetElement.is( 'element' ) || !targetElement.parent ) {\n\t\t\t/**\n\t\t\t * Merge target position is invalid.\n\t\t\t *\n\t\t\t * @error merge-operation-target-position-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'merge-operation-target-position-invalid: Merge target position is invalid.' );\n\t\t} else if ( this.howMany != sourceElement.maxOffset ) {\n\t\t\t/**\n\t\t\t * Merge operation specifies wrong number of nodes to move.\n\t\t\t *\n\t\t\t * @error merge-operation-how-many-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'merge-operation-how-many-invalid: Merge operation specifies wrong number of nodes to move.' );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_execute() {\n\t\tconst mergedElement = this.sourcePosition.parent;\n\t\tconst sourceRange = Range._createIn( mergedElement );\n\n\t\t_move( sourceRange, this.targetPosition );\n\t\t_move( Range._createOn( mergedElement ), this.graveyardPosition );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\n\t\tjson.sourcePosition = json.sourcePosition.toJSON();\n\t\tjson.targetPosition = json.targetPosition.toJSON();\n\t\tjson.graveyardPosition = json.graveyardPosition.toJSON();\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'MergeOperation';\n\t}\n\n\t/**\n\t * Creates `MergeOperation` object from deserilized object, i.e. from parsed JSON string.\n\t *\n\t * @param {Object} json Deserialized JSON object.\n\t * @param {module:engine/model/document~Document} document Document on which this operation will be applied.\n\t * @returns {module:engine/model/operation/mergeoperation~MergeOperation}\n\t */\n\tstatic fromJSON( json, document ) {\n\t\tconst sourcePosition = Position.fromJSON( json.sourcePosition, document );\n\t\tconst targetPosition = Position.fromJSON( json.targetPosition, document );\n\t\tconst graveyardPosition = Position.fromJSON( json.graveyardPosition, document );\n\n\t\treturn new this( sourcePosition, json.howMany, targetPosition, graveyardPosition, json.baseVersion );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/splitoperation\n */\n\nimport Operation from './operation';\nimport MergeOperation from './mergeoperation';\nimport Position from '../position';\nimport Range from '../range';\nimport { _insert, _move } from './utils';\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Operation to split {@link module:engine/model/element~Element an element} at given\n * {@link module:engine/model/operation/splitoperation~SplitOperation#splitPosition split position} into two elements,\n * both containing a part of the element's original content.\n *\n * @extends module:engine/model/operation/operation~Operation\n */\nexport default class SplitOperation extends Operation {\n\t/**\n\t * Creates a split operation.\n\t *\n\t * @param {module:engine/model/position~Position} splitPosition Position at which an element should be split.\n\t * @param {Number} howMany Total offset size of elements that are in the split element after `position`.\n\t * @param {module:engine/model/position~Position|null} graveyardPosition Position in the graveyard root before the element which\n\t * should be used as a parent of the nodes after `position`. If it is not set, a copy of the the `position` parent will be used.\n\t * @param {Number|null} baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */\n\tconstructor( splitPosition, howMany, graveyardPosition, baseVersion ) {\n\t\tsuper( baseVersion );\n\n\t\t/**\n\t\t * Position at which an element should be split.\n\t\t *\n\t\t * @member {module:engine/model/position~Position} module:engine/model/operation/splitoperation~SplitOperation#splitPosition\n\t\t */\n\t\tthis.splitPosition = splitPosition.clone();\n\t\t// Keep position sticking to the next node. This way any new content added at the place where the element is split\n\t\t// will be left in the original element.\n\t\tthis.splitPosition.stickiness = 'toNext';\n\n\t\t/**\n\t\t * Total offset size of elements that are in the split element after `position`.\n\t\t *\n\t\t * @member {Number} module:engine/model/operation/splitoperation~SplitOperation#howMany\n\t\t */\n\t\tthis.howMany = howMany;\n\n\t\t/**\n\t\t * Position at which the clone of split element (or element from graveyard) will be inserted.\n\t\t *\n\t\t * @member {module:engine/model/position~Position} module:engine/model/operation/splitoperation~SplitOperation#insertionPosition\n\t\t */\n\t\tthis.insertionPosition = SplitOperation.getInsertionPosition( splitPosition );\n\t\tthis.insertionPosition.stickiness = 'toNone';\n\n\t\t/**\n\t\t * Position in the graveyard root before the element which should be used as a parent of the nodes after `position`.\n\t\t * If it is not set, a copy of the the `position` parent will be used.\n\t\t *\n\t\t * The default behavior is to clone the split element. Element from graveyard is used during undo.\n\t\t *\n\t\t * @member {module:engine/model/position~Position|null} #graveyardPosition\n\t\t */\n\t\tthis.graveyardPosition = graveyardPosition ? graveyardPosition.clone() : null;\n\n\t\tif ( this.graveyardPosition ) {\n\t\t\tthis.graveyardPosition.stickiness = 'toNext';\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget type() {\n\t\treturn 'split';\n\t}\n\n\t/**\n\t * Position inside the new clone of a split element.\n\t *\n\t * This is a position where nodes that are after the split position will be moved to.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/position~Position}\n\t */\n\tget moveTargetPosition() {\n\t\tconst path = this.insertionPosition.path.slice();\n\t\tpath.push( 0 );\n\n\t\treturn new Position( this.insertionPosition.root, path );\n\t}\n\n\t/**\n\t * Artificial range that contains all the nodes from the split element that will be moved to the new element.\n\t * The range starts at {@link ~#splitPosition} and ends in the same parent, at `POSITIVE_INFINITY` offset.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/range~Range}\n\t */\n\tget movedRange() {\n\t\tconst end = this.splitPosition.getShiftedBy( Number.POSITIVE_INFINITY );\n\n\t\treturn new Range( this.splitPosition, end );\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns {module:engine/model/operation/splitoperation~SplitOperation} Clone of this operation.\n\t */\n\tclone() {\n\t\tconst split = new this.constructor( this.splitPosition, this.howMany, this.graveyardPosition, this.baseVersion );\n\t\tsplit.insertionPosition = this.insertionPosition;\n\n\t\treturn split;\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t *\n\t * @returns {module:engine/model/operation/mergeoperation~MergeOperation}\n\t */\n\tgetReversed() {\n\t\tconst graveyard = this.splitPosition.root.document.graveyard;\n\t\tconst graveyardPosition = new Position( graveyard, [ 0 ] );\n\n\t\treturn new MergeOperation( this.moveTargetPosition, this.howMany, this.splitPosition, graveyardPosition, this.baseVersion + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_validate() {\n\t\tconst element = this.splitPosition.parent;\n\t\tconst offset = this.splitPosition.offset;\n\n\t\t// Validate whether split operation has correct parameters.\n\t\tif ( !element || element.maxOffset < offset ) {\n\t\t\t/**\n\t\t\t * Split position is invalid.\n\t\t\t *\n\t\t\t * @error split-operation-position-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'split-operation-position-invalid: Split position is invalid.' );\n\t\t} else if ( !element.parent ) {\n\t\t\t/**\n\t\t\t * Cannot split root element.\n\t\t\t *\n\t\t\t * @error split-operation-split-in-root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'split-operation-split-in-root: Cannot split root element.' );\n\t\t} else if ( this.howMany != element.maxOffset - this.splitPosition.offset ) {\n\t\t\t/**\n\t\t\t * Split operation specifies wrong number of nodes to move.\n\t\t\t *\n\t\t\t * @error split-operation-how-many-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'split-operation-how-many-invalid: Split operation specifies wrong number of nodes to move.' );\n\t\t} else if ( this.graveyardPosition && !this.graveyardPosition.nodeAfter ) {\n\t\t\t/**\n\t\t\t * Graveyard position invalid.\n\t\t\t *\n\t\t\t * @error split-operation-graveyard-position-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'split-operation-graveyard-position-invalid: Graveyard position invalid.' );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_execute() {\n\t\tconst splitElement = this.splitPosition.parent;\n\n\t\tif ( this.graveyardPosition ) {\n\t\t\t_move( Range._createFromPositionAndShift( this.graveyardPosition, 1 ), this.insertionPosition );\n\t\t} else {\n\t\t\tconst newElement = splitElement._clone();\n\n\t\t\t_insert( this.insertionPosition, newElement );\n\t\t}\n\n\t\tconst sourceRange = new Range(\n\t\t\tPosition._createAt( splitElement, this.splitPosition.offset ),\n\t\t\tPosition._createAt( splitElement, splitElement.maxOffset )\n\t\t);\n\n\t\t_move( sourceRange, this.moveTargetPosition );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\ttoJSON() {\n\t\tconst json = super.toJSON();\n\n\t\tjson.splitPosition = this.splitPosition.toJSON();\n\t\tjson.insertionPosition = this.insertionPosition.toJSON();\n\n\t\tif ( this.graveyardPosition ) {\n\t\t\tjson.graveyardPosition = this.graveyardPosition.toJSON();\n\t\t}\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'SplitOperation';\n\t}\n\n\t/**\n\t * Helper function that returns a default insertion position basing on given `splitPosition`. The default insertion\n\t * position is after the split element.\n\t *\n\t * @param {module:engine/model/position~Position} splitPosition\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tstatic getInsertionPosition( splitPosition ) {\n\t\tconst path = splitPosition.path.slice( 0, -1 );\n\t\tpath[ path.length - 1 ]++;\n\n\t\treturn new Position( splitPosition.root, path );\n\t}\n\n\t/**\n\t * Creates `SplitOperation` object from deserilized object, i.e. from parsed JSON string.\n\t *\n\t * @param {Object} json Deserialized JSON object.\n\t * @param {module:engine/model/document~Document} document Document on which this operation will be applied.\n\t * @returns {module:engine/model/operation/splitoperation~SplitOperation}\n\t */\n\tstatic fromJSON( json, document ) {\n\t\tconst splitPosition = Position.fromJSON( json.splitPosition, document );\n\t\tconst insertionPosition = Position.fromJSON( json.insertionPosition, document );\n\t\tconst graveyardPosition = json.graveyardPosition ? Position.fromJSON( json.graveyardPosition, document ) : null;\n\n\t\tconst split = new this( splitPosition, json.howMany, graveyardPosition, json.baseVersion );\n\t\tsplit.insertionPosition = insertionPosition;\n\n\t\treturn split;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/rootelement\n */\n\nimport Element from './element';\n\n/**\n * Type of {@link module:engine/model/element~Element} that is a root of a model tree.\n * @extends module:engine/model/element~Element\n */\nexport default class RootElement extends Element {\n\t/**\n\t * Creates root element.\n\t *\n\t * @param {module:engine/model/document~Document} doc Document that is an owner of this root.\n\t * @param {String} name Node name.\n\t * @param {String} [rootName='main'] Unique root name used to identify this root\n\t * element by {@link module:engine/model/document~Document}.\n\t */\n\tconstructor( doc, name, rootName = 'main' ) {\n\t\tsuper( name );\n\n\t\t/**\n\t\t * Document that is an owner of this root.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/document~Document}\n\t\t */\n\t\tthis._doc = doc;\n\n\t\t/**\n\t\t * Unique root name used to identify this root element by {@link module:engine/model/document~Document}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.rootName = rootName;\n\t}\n\n\t/**\n\t * {@link module:engine/model/document~Document Document} that owns this root element.\n\t *\n\t * In contrary, to {@link module:engine/model/node~Node node}, root element always have a `document`.\n\t *\n\t * @readonly\n\t * @type {module:engine/model/document~Document|null}\n\t */\n\tget document() {\n\t\treturn this._doc;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tis( type, name ) {\n\t\tif ( !name ) {\n\t\t\treturn type == 'rootElement' || super.is( type );\n\t\t} else {\n\t\t\treturn ( type == 'rootElement' && name == this.name ) || super.is( type, name );\n\t\t}\n\t}\n\n\t/**\n\t * Converts `RootElement` instance to `String` containing it's name.\n\t *\n\t * @returns {String} `RootElement` instance converted to `String`.\n\t */\n\ttoJSON() {\n\t\treturn this.rootName;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/writer\n */\n\nimport AttributeOperation from './operation/attributeoperation';\nimport DetachOperation from './operation/detachoperation';\nimport InsertOperation from './operation/insertoperation';\nimport MarkerOperation from './operation/markeroperation';\nimport MoveOperation from './operation/moveoperation';\nimport RenameOperation from './operation/renameoperation';\nimport RootAttributeOperation from './operation/rootattributeoperation';\nimport SplitOperation from './operation/splitoperation';\nimport MergeOperation from './operation/mergeoperation';\n\nimport DocumentFragment from './documentfragment';\nimport Text from './text';\nimport Element from './element';\nimport RootElement from './rootelement';\nimport Position from './position';\nimport Range from './range.js';\nimport DocumentSelection from './documentselection';\n\nimport toMap from '@ckeditor/ckeditor5-utils/src/tomap';\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * The model can only be modified by using the writer. It should be used whenever you want to create a node, modify\n * child nodes, attributes or text, set the selection's position and its attributes.\n *\n * The instance of the writer is only available in the {@link module:engine/model/model~Model#change `change()`} or\n * {@link module:engine/model/model~Model#enqueueChange `enqueueChange()`}.\n *\n *\t\tmodel.change( writer => {\n *\t\t\twriter.insertText( 'foo', paragraph, 'end' );\n *\t\t} );\n *\n * Note that the writer should never be stored and used outside of the `change()` and\n * `enqueueChange()` blocks.\n *\n * Note that writer's methods do not check the {@link module:engine/model/schema~Schema}. It is possible\n * to create incorrect model structures by using the writer. Read more about in\n * {@glink framework/guides/deep-dive/schema#who-checks-the-schema \"Who checks the schema?\"}.\n *\n * @see module:engine/model/model~Model#change\n * @see module:engine/model/model~Model#enqueueChange\n */\nexport default class Writer {\n\t/**\n\t * Creates a writer instance.\n\t *\n\t * **Note:** It is not recommended to use it directly. Use {@link module:engine/model/model~Model#change `Model#change()`} or\n\t * {@link module:engine/model/model~Model#enqueueChange `Model#enqueueChange()`} instead.\n\t *\n\t * @protected\n\t * @param {module:engine/model/model~Model} model\n\t * @param {module:engine/model/batch~Batch} batch\n\t */\n\tconstructor( model, batch ) {\n\t\t/**\n\t\t * Instance of the model on which this writer operates.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:engine/model/model~Model}\n\t\t */\n\t\tthis.model = model;\n\n\t\t/**\n\t\t * The batch to which this writer will add changes.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:engine/model/batch~Batch}\n\t\t */\n\t\tthis.batch = batch;\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/model/text~Text text node}.\n\t *\n\t *\t\twriter.createText( 'foo' );\n\t *\t\twriter.createText( 'foo', { bold: true } );\n\t *\n\t * @param {String} data Text data.\n\t * @param {Object} [attributes] Text attributes.\n\t * @returns {module:engine/model/text~Text} Created text node.\n\t */\n\tcreateText( data, attributes ) {\n\t\treturn new Text( data, attributes );\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/model/element~Element element}.\n\t *\n\t *\t\twriter.createElement( 'paragraph' );\n\t *\t\twriter.createElement( 'paragraph', { alignment: 'center' } );\n\t *\n\t * @param {String} name Name of the element.\n\t * @param {Object} [attributes] Elements attributes.\n\t * @returns {module:engine/model/element~Element} Created element.\n\t */\n\tcreateElement( name, attributes ) {\n\t\treturn new Element( name, attributes );\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/model/documentfragment~DocumentFragment document fragment}.\n\t *\n\t * @returns {module:engine/model/documentfragment~DocumentFragment} Created document fragment.\n\t */\n\tcreateDocumentFragment() {\n\t\treturn new DocumentFragment();\n\t}\n\n\t/**\n\t * Inserts item on given position.\n\t *\n\t *\t\tconst paragraph = writer.createElement( 'paragraph' );\n\t *\t\twriter.insert( paragraph, position );\n\t *\n\t * Instead of using position you can use parent and offset:\n\t *\n\t *\t\tconst text = writer.createText( 'foo' );\n\t *\t\twriter.insert( text, paragraph, 5 );\n\t *\n\t * You can also use `end` instead of the offset to insert at the end:\n\t *\n\t *\t\tconst text = writer.createText( 'foo' );\n\t *\t\twriter.insert( text, paragraph, 'end' );\n\t *\n\t * Or insert before or after another element:\n\t *\n\t *\t\tconst paragraph = writer.createElement( 'paragraph' );\n\t *\t\twriter.insert( paragraph, anotherParagraph, 'after' );\n\t *\n\t * These parameters works the same way as {@link #createPositionAt `writer.createPositionAt()`}.\n\t *\n\t * Note that if the item already has parent it will be removed from the previous parent.\n\t *\n\t * Note that you cannot re-insert a node from a document to a different document or a document fragment. In this case,\n\t * `model-writer-insert-forbidden-move` is thrown.\n\t *\n\t * If you want to move {@link module:engine/model/range~Range range} instead of an\n\t * {@link module:engine/model/item~Item item} use {@link module:engine/model/writer~Writer#move `Writer#move()`}.\n\t *\n\t * **Note:** For a paste-like content insertion mechanism see\n\t * {@link module:engine/model/model~Model#insertContent `model.insertContent()`}.\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/documentfragment~DocumentFragment} item Item or document\n\t * fragment to insert.\n\t * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when\n\t * second parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tinsert( item, itemOrPosition, offset = 0 ) {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( item instanceof Text && item.data == '' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst position = Position._createAt( itemOrPosition, offset );\n\n\t\t// If item has a parent already.\n\t\tif ( item.parent ) {\n\t\t\t// We need to check if item is going to be inserted within the same document.\n\t\t\tif ( isSameTree( item.root, position.root ) ) {\n\t\t\t\t// If it's we just need to move it.\n\t\t\t\tthis.move( Range._createOn( item ), position );\n\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// If it isn't the same root.\n\t\t\telse {\n\t\t\t\tif ( item.root.document ) {\n\t\t\t\t\t// It is forbidden to move a node that was already in a document outside of it.\n\t\t\t\t\tthrow new Error( 'model-writer-insert-forbidden-move: Cannot move a node from a document to a different tree.' );\n\t\t\t\t} else {\n\t\t\t\t\t// Move between two different document fragments or from document fragment to a document is possible.\n\t\t\t\t\t// In that case, remove the item from it's original parent.\n\t\t\t\t\tthis.remove( item );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst version = position.root.document ? position.root.document.version : null;\n\n\t\tconst insert = new InsertOperation( position, item, version );\n\n\t\tif ( item instanceof Text ) {\n\t\t\tinsert.shouldReceiveAttributes = true;\n\t\t}\n\n\t\tthis.batch.addOperation( insert );\n\t\tthis.model.applyOperation( insert );\n\n\t\t// When element is a DocumentFragment we need to move its markers to Document#markers.\n\t\tif ( item instanceof DocumentFragment ) {\n\t\t\tfor ( const [ markerName, markerRange ] of item.markers ) {\n\t\t\t\t// We need to migrate marker range from DocumentFragment to Document.\n\t\t\t\tconst rangeRootPosition = Position._createAt( markerRange.root, 0 );\n\t\t\t\tconst range = new Range(\n\t\t\t\t\tmarkerRange.start._getCombined( rangeRootPosition, position ),\n\t\t\t\t\tmarkerRange.end._getCombined( rangeRootPosition, position )\n\t\t\t\t);\n\n\t\t\t\tthis.addMarker( markerName, { range, usingOperation: true, affectsData: true } );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Creates and inserts text on given position. You can optionally set text attributes:\n\t *\n\t *\t\twriter.insertText( 'foo', position );\n\t *\t\twriter.insertText( 'foo', { bold: true }, position );\n\t *\n\t * Instead of using position you can use parent and offset or define that text should be inserted at the end\n\t * or before or after other node:\n\t *\n\t *\t\t// Inserts 'foo' in paragraph, at offset 5:\n\t *\t\twriter.insertText( 'foo', paragraph, 5 );\n\t *\t\t// Inserts 'foo' at the end of a paragraph:\n\t *\t\twriter.insertText( 'foo', paragraph, 'end' );\n\t *\t\t// Inserts 'foo' after an image:\n\t *\t\twriter.insertText( 'foo', image, 'after' );\n\t *\n\t * These parameters work in the same way as {@link #createPositionAt `writer.createPositionAt()`}.\n\t *\n\t * @param {String} data Text data.\n\t * @param {Object} [attributes] Text attributes.\n\t * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when\n\t * third parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tinsertText( text, attributes, itemOrPosition, offset ) {\n\t\tif ( attributes instanceof DocumentFragment || attributes instanceof Element || attributes instanceof Position ) {\n\t\t\tthis.insert( this.createText( text ), attributes, itemOrPosition );\n\t\t} else {\n\t\t\tthis.insert( this.createText( text, attributes ), itemOrPosition, offset );\n\t\t}\n\t}\n\n\t/**\n\t * Creates and inserts element on given position. You can optionally set attributes:\n\t *\n\t *\t\twriter.insertElement( 'paragraph', position );\n\t *\t\twriter.insertElement( 'paragraph', { alignment: 'center' }, position );\n\t *\n\t * Instead of using position you can use parent and offset or define that text should be inserted at the end\n\t * or before or after other node:\n\t *\n\t *\t\t// Inserts paragraph in the root at offset 5:\n\t *\t\twriter.insertElement( 'paragraph', root, 5 );\n\t *\t\t// Inserts paragraph at the end of a blockquote:\n\t *\t\twriter.insertElement( 'paragraph', blockquote, 'end' );\n\t *\t\t// Inserts after an image:\n\t *\t\twriter.insertElement( 'paragraph', image, 'after' );\n\t *\n\t * These parameters works the same way as {@link #createPositionAt `writer.createPositionAt()`}.\n\t *\n\t * @param {String} name Name of the element.\n\t * @param {Object} [attributes] Elements attributes.\n\t * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when\n\t * third parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tinsertElement( name, attributes, itemOrPosition, offset ) {\n\t\tif ( attributes instanceof DocumentFragment || attributes instanceof Element || attributes instanceof Position ) {\n\t\t\tthis.insert( this.createElement( name ), attributes, itemOrPosition );\n\t\t} else {\n\t\t\tthis.insert( this.createElement( name, attributes ), itemOrPosition, offset );\n\t\t}\n\t}\n\n\t/**\n\t * Inserts item at the end of the given parent.\n\t *\n\t *\t\tconst paragraph = writer.createElement( 'paragraph' );\n\t *\t\twriter.append( paragraph, root );\n\t *\n\t * Note that if the item already has parent it will be removed from the previous parent.\n\t *\n\t * If you want to move {@link module:engine/model/range~Range range} instead of an\n\t * {@link module:engine/model/item~Item item} use {@link module:engine/model/writer~Writer#move `Writer#move()`}.\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/documentfragment~DocumentFragment}\n\t * item Item or document fragment to insert.\n\t * @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} parent\n\t */\n\tappend( item, parent ) {\n\t\tthis.insert( item, parent, 'end' );\n\t}\n\n\t/**\n\t * Creates text node and inserts it at the end of the parent. You can optionally set text attributes:\n\t *\n\t *\t\twriter.appendText( 'foo', paragraph );\n\t *\t\twriter.appendText( 'foo', { bold: true }, paragraph );\n\t *\n\t * @param {String} text Text data.\n\t * @param {Object} [attributes] Text attributes.\n\t * @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} parent\n\t */\n\tappendText( text, attributes, parent ) {\n\t\tif ( attributes instanceof DocumentFragment || attributes instanceof Element ) {\n\t\t\tthis.insert( this.createText( text ), attributes, 'end' );\n\t\t} else {\n\t\t\tthis.insert( this.createText( text, attributes ), parent, 'end' );\n\t\t}\n\t}\n\n\t/**\n\t * Creates element and inserts it at the end of the parent. You can optionally set attributes:\n\t *\n\t *\t\twriter.appendElement( 'paragraph', root );\n\t *\t\twriter.appendElement( 'paragraph', { alignment: 'center' }, root );\n\t *\n\t * @param {String} name Name of the element.\n\t * @param {Object} [attributes] Elements attributes.\n\t * @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} parent\n\t */\n\tappendElement( name, attributes, parent ) {\n\t\tif ( attributes instanceof DocumentFragment || attributes instanceof Element ) {\n\t\t\tthis.insert( this.createElement( name ), attributes, 'end' );\n\t\t} else {\n\t\t\tthis.insert( this.createElement( name, attributes ), parent, 'end' );\n\t\t}\n\t}\n\n\t/**\n\t * Sets value of the attribute with given key on a {@link module:engine/model/item~Item model item}\n\t * or on a {@link module:engine/model/range~Range range}.\n\t *\n\t * @param {String} key Attribute key.\n\t * @param {*} value Attribute new value.\n\t * @param {module:engine/model/item~Item|module:engine/model/range~Range} itemOrRange\n\t * Model item or range on which the attribute will be set.\n\t */\n\tsetAttribute( key, value, itemOrRange ) {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( itemOrRange instanceof Range ) {\n\t\t\tconst ranges = itemOrRange.getMinimalFlatRanges();\n\n\t\t\tfor ( const range of ranges ) {\n\t\t\t\tsetAttributeOnRange( this, key, value, range );\n\t\t\t}\n\t\t} else {\n\t\t\tsetAttributeOnItem( this, key, value, itemOrRange );\n\t\t}\n\t}\n\n\t/**\n\t * Sets values of attributes on a {@link module:engine/model/item~Item model item}\n\t * or on a {@link module:engine/model/range~Range range}.\n\t *\n\t *\t\twriter.setAttributes( {\n\t *\t\t\tbold: true,\n\t *\t\t\titalic: true\n\t *\t\t}, range );\n\t *\n\t * @param {Object} attributes Attributes keys and values.\n\t * @param {module:engine/model/item~Item|module:engine/model/range~Range} itemOrRange\n\t * Model item or range on which the attributes will be set.\n\t */\n\tsetAttributes( attributes, itemOrRange ) {\n\t\tfor ( const [ key, val ] of toMap( attributes ) ) {\n\t\t\tthis.setAttribute( key, val, itemOrRange );\n\t\t}\n\t}\n\n\t/**\n\t * Removes an attribute with given key from a {@link module:engine/model/item~Item model item}\n\t * or from a {@link module:engine/model/range~Range range}.\n\t *\n\t * @param {String} key Attribute key.\n\t * @param {module:engine/model/item~Item|module:engine/model/range~Range} itemOrRange\n\t * Model item or range from which the attribute will be removed.\n\t */\n\tremoveAttribute( key, itemOrRange ) {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( itemOrRange instanceof Range ) {\n\t\t\tconst ranges = itemOrRange.getMinimalFlatRanges();\n\n\t\t\tfor ( const range of ranges ) {\n\t\t\t\tsetAttributeOnRange( this, key, null, range );\n\t\t\t}\n\t\t} else {\n\t\t\tsetAttributeOnItem( this, key, null, itemOrRange );\n\t\t}\n\t}\n\n\t/**\n\t * Removes all attributes from all elements in the range or from the given item.\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/range~Range} itemOrRange\n\t * Model item or range from which all attributes will be removed.\n\t */\n\tclearAttributes( itemOrRange ) {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tconst removeAttributesFromItem = item => {\n\t\t\tfor ( const attribute of item.getAttributeKeys() ) {\n\t\t\t\tthis.removeAttribute( attribute, item );\n\t\t\t}\n\t\t};\n\n\t\tif ( !( itemOrRange instanceof Range ) ) {\n\t\t\tremoveAttributesFromItem( itemOrRange );\n\t\t} else {\n\t\t\tfor ( const item of itemOrRange.getItems() ) {\n\t\t\t\tremoveAttributesFromItem( item );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Moves all items in the source range to the target position.\n\t *\n\t *\t\twriter.move( sourceRange, targetPosition );\n\t *\n\t * Instead of the target position you can use parent and offset or define that range should be moved to the end\n\t * or before or after chosen item:\n\t *\n\t *\t\t// Moves all items in the range to the paragraph at offset 5:\n\t *\t\twriter.move( sourceRange, paragraph, 5 );\n\t *\t\t// Moves all items in the range to the end of a blockquote:\n\t *\t\twriter.move( sourceRange, blockquote, 'end' );\n\t *\t\t// Moves all items in the range to a position after an image:\n\t *\t\twriter.move( sourceRange, image, 'after' );\n\t *\n\t * These parameters works the same way as {@link #createPositionAt `writer.createPositionAt()`}.\n\t *\n\t * Note that items can be moved only within the same tree. It means that you can move items within the same root\n\t * (element or document fragment) or between {@link module:engine/model/document~Document#roots documents roots},\n\t * but you can not move items from document fragment to the document or from one detached element to another. Use\n\t * {@link module:engine/model/writer~Writer#insert} in such cases.\n\t *\n\t * @param {module:engine/model/range~Range} range Source range.\n\t * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when\n\t * second parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tmove( range, itemOrPosition, offset ) {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( !( range instanceof Range ) ) {\n\t\t\t/**\n\t\t\t * Invalid range to move.\n\t\t\t *\n\t\t\t * @error writer-move-invalid-range\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-move-invalid-range: Invalid range to move.' );\n\t\t}\n\n\t\tif ( !range.isFlat ) {\n\t\t\t/**\n\t\t\t * Range to move is not flat.\n\t\t\t *\n\t\t\t * @error writer-move-range-not-flat\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-move-range-not-flat: Range to move is not flat.' );\n\t\t}\n\n\t\tconst position = Position._createAt( itemOrPosition, offset );\n\n\t\t// Do not move anything if the move target is same as moved range start.\n\t\tif ( position.isEqual( range.start ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If part of the marker is removed, create additional marker operation for undo purposes.\n\t\tthis._addOperationForAffectedMarkers( 'move', range );\n\n\t\tif ( !isSameTree( range.root, position.root ) ) {\n\t\t\t/**\n\t\t\t * Range is going to be moved within not the same document. Please use\n\t\t\t * {@link module:engine/model/writer~Writer#insert insert} instead.\n\t\t\t *\n\t\t\t * @error writer-move-different-document\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-move-different-document: Range is going to be moved between different documents.' );\n\t\t}\n\n\t\tconst version = range.root.document ? range.root.document.version : null;\n\t\tconst operation = new MoveOperation( range.start, range.end.offset - range.start.offset, position, version );\n\n\t\tthis.batch.addOperation( operation );\n\t\tthis.model.applyOperation( operation );\n\t}\n\n\t/**\n\t * Removes given model {@link module:engine/model/item~Item item} or {@link module:engine/model/range~Range range}.\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/range~Range} itemOrRange Model item or range to remove.\n\t */\n\tremove( itemOrRange ) {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tconst rangeToRemove = itemOrRange instanceof Range ? itemOrRange : Range._createOn( itemOrRange );\n\t\tconst ranges = rangeToRemove.getMinimalFlatRanges().reverse();\n\n\t\tfor ( const flat of ranges ) {\n\t\t\t// If part of the marker is removed, create additional marker operation for undo purposes.\n\t\t\tthis._addOperationForAffectedMarkers( 'move', flat );\n\n\t\t\tapplyRemoveOperation( flat.start, flat.end.offset - flat.start.offset, this.batch, this.model );\n\t\t}\n\t}\n\n\t/**\n\t * Merges two siblings at the given position.\n\t *\n\t * Node before and after the position have to be an element. Otherwise `writer-merge-no-element-before` or\n\t * `writer-merge-no-element-after` error will be thrown.\n\t *\n\t * @param {module:engine/model/position~Position} position Position between merged elements.\n\t */\n\tmerge( position ) {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tconst nodeBefore = position.nodeBefore;\n\t\tconst nodeAfter = position.nodeAfter;\n\n\t\t// If part of the marker is removed, create additional marker operation for undo purposes.\n\t\tthis._addOperationForAffectedMarkers( 'merge', position );\n\n\t\tif ( !( nodeBefore instanceof Element ) ) {\n\t\t\t/**\n\t\t\t * Node before merge position must be an element.\n\t\t\t *\n\t\t\t * @error writer-merge-no-element-before\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-merge-no-element-before: Node before merge position must be an element.' );\n\t\t}\n\n\t\tif ( !( nodeAfter instanceof Element ) ) {\n\t\t\t/**\n\t\t\t * Node after merge position must be an element.\n\t\t\t *\n\t\t\t * @error writer-merge-no-element-after\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-merge-no-element-after: Node after merge position must be an element.' );\n\t\t}\n\n\t\tif ( !position.root.document ) {\n\t\t\tthis._mergeDetached( position );\n\t\t} else {\n\t\t\tthis._merge( position );\n\t\t}\n\t}\n\n\t/**\n\t * Shortcut for {@link module:engine/model/model~Model#createPositionFromPath `Model#createPositionFromPath()`}.\n\t *\n\t * @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} root Root of the position.\n\t * @param {Array.<Number>} path Position path. See {@link module:engine/model/position~Position#path}.\n\t * @param {module:engine/model/position~PositionStickiness} [stickiness='toNone'] Position stickiness.\n\t * See {@link module:engine/model/position~PositionStickiness}.\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tcreatePositionFromPath( root, path, stickiness ) {\n\t\treturn this.model.createPositionFromPath( root, path, stickiness );\n\t}\n\n\t/**\n\t * Shortcut for {@link module:engine/model/model~Model#createPositionAt `Model#createPositionAt()`}.\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/model/item~Item model item}.\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tcreatePositionAt( itemOrPosition, offset ) {\n\t\treturn this.model.createPositionAt( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Shortcut for {@link module:engine/model/model~Model#createPositionAfter `Model#createPositionAfter()`}.\n\t *\n\t * @param {module:engine/model/item~Item} item Item after which the position should be placed.\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tcreatePositionAfter( item ) {\n\t\treturn this.model.createPositionAfter( item );\n\t}\n\n\t/**\n\t * Shortcut for {@link module:engine/model/model~Model#createPositionBefore `Model#createPositionBefore()`}.\n\t *\n\t * @param {module:engine/model/item~Item} item Item after which the position should be placed.\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tcreatePositionBefore( item ) {\n\t\treturn this.model.createPositionBefore( item );\n\t}\n\n\t/**\n\t * Shortcut for {@link module:engine/model/model~Model#createRange `Model#createRange()`}.\n\t *\n\t * @param {module:engine/model/position~Position} start Start position.\n\t * @param {module:engine/model/position~Position} [end] End position. If not set, range will be collapsed at `start` position.\n\t * @returns {module:engine/model/range~Range}\n\t */\n\tcreateRange( start, end ) {\n\t\treturn this.model.createRange( start, end );\n\t}\n\n\t/**\n\t * Shortcut for {@link module:engine/model/model~Model#createRangeIn `Model#createRangeIn()`}.\n\t *\n\t * @param {module:engine/model/element~Element} element Element which is a parent for the range.\n\t * @returns {module:engine/model/range~Range}\n\t */\n\tcreateRangeIn( element ) {\n\t\treturn this.model.createRangeIn( element );\n\t}\n\n\t/**\n\t * Shortcut for {@link module:engine/model/model~Model#createRangeOn `Model#createRangeOn()`}.\n\t *\n\t * @param {module:engine/model/element~Element} element Element which is a parent for the range.\n\t * @returns {module:engine/model/range~Range}\n\t */\n\tcreateRangeOn( element ) {\n\t\treturn this.model.createRangeOn( element );\n\t}\n\n\t/**\n\t * Shortcut for {@link module:engine/model/model~Model#createSelection `Model#createSelection()`}.\n\t *\n\t * @param {module:engine/model/selection~Selectable} selectable\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Sets place or offset of the selection.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.backward] Sets this selection instance to be backward.\n\t * @returns {module:engine/model/selection~Selection}\n\t */\n\tcreateSelection( selectable, placeOrOffset, options ) {\n\t\treturn this.model.createSelection( selectable, placeOrOffset, options );\n\t}\n\n\t/**\n\t * Performs merge action in a detached tree.\n\t *\n\t * @private\n\t * @param {module:engine/model/position~Position} position Position between merged elements.\n\t */\n\t_mergeDetached( position ) {\n\t\tconst nodeBefore = position.nodeBefore;\n\t\tconst nodeAfter = position.nodeAfter;\n\n\t\tthis.move( Range._createIn( nodeAfter ), Position._createAt( nodeBefore, 'end' ) );\n\t\tthis.remove( nodeAfter );\n\t}\n\n\t/**\n\t * Performs merge action in a non-detached tree.\n\t *\n\t * @private\n\t * @param {module:engine/model/position~Position} position Position between merged elements.\n\t */\n\t_merge( position ) {\n\t\tconst targetPosition = Position._createAt( position.nodeBefore, 'end' );\n\t\tconst sourcePosition = Position._createAt( position.nodeAfter, 0 );\n\n\t\tconst graveyard = position.root.document.graveyard;\n\t\tconst graveyardPosition = new Position( graveyard, [ 0 ] );\n\n\t\tconst version = position.root.document.version;\n\n\t\tconst merge = new MergeOperation( sourcePosition, position.nodeAfter.maxOffset, targetPosition, graveyardPosition, version );\n\n\t\tthis.batch.addOperation( merge );\n\t\tthis.model.applyOperation( merge );\n\t}\n\n\t/**\n\t * Renames the given element.\n\t *\n\t * @param {module:engine/model/element~Element} element The element to rename.\n\t * @param {String} newName New element name.\n\t */\n\trename( element, newName ) {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( !( element instanceof Element ) ) {\n\t\t\t/**\n\t\t\t * Trying to rename an object which is not an instance of Element.\n\t\t\t *\n\t\t\t * @error writer-rename-not-element-instance\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'writer-rename-not-element-instance: Trying to rename an object which is not an instance of Element.'\n\t\t\t);\n\t\t}\n\n\t\tconst version = element.root.document ? element.root.document.version : null;\n\t\tconst renameOperation = new RenameOperation( Position._createBefore( element ), element.name, newName, version );\n\n\t\tthis.batch.addOperation( renameOperation );\n\t\tthis.model.applyOperation( renameOperation );\n\t}\n\n\t/**\n\t * Splits elements starting from the given position and going to the top of the model tree as long as given\n\t * `limitElement` is reached. When `limitElement` is not defined then only the parent of the given position will be split.\n\t *\n\t * The element needs to have a parent. It cannot be a root element nor a document fragment.\n\t * The `writer-split-element-no-parent` error will be thrown if you try to split an element with no parent.\n\t *\n\t * @param {module:engine/model/position~Position} position Position of split.\n\t * @param {module:engine/model/node~Node} [limitElement] Stop splitting when this element will be reached.\n\t * @returns {Object} result Split result.\n\t * @returns {module:engine/model/position~Position} result.position Position between split elements.\n\t * @returns {module:engine/model/range~Range} result.range Range that stars from the end of the first split element and ends\n\t * at the beginning of the first copy element.\n\t */\n\tsplit( position, limitElement ) {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tlet splitElement = position.parent;\n\n\t\tif ( !splitElement.parent ) {\n\t\t\t/**\n\t\t\t * Element with no parent can not be split.\n\t\t\t *\n\t\t\t * @error writer-split-element-no-parent\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-split-element-no-parent: Element with no parent can not be split.' );\n\t\t}\n\n\t\t// When limit element is not defined lets set splitElement parent as limit.\n\t\tif ( !limitElement ) {\n\t\t\tlimitElement = splitElement.parent;\n\t\t}\n\n\t\tif ( !position.parent.getAncestors( { includeSelf: true } ).includes( limitElement ) ) {\n\t\t\tthrow new CKEditorError( 'writer-split-invalid-limit-element: Limit element is not a position ancestor.' );\n\t\t}\n\n\t\t// We need to cache elements that will be created as a result of the first split because\n\t\t// we need to create a range from the end of the first split element to the beginning of the\n\t\t// first copy element. This should be handled by LiveRange but it doesn't work on detached nodes.\n\t\tlet firstSplitElement, firstCopyElement;\n\n\t\tdo {\n\t\t\tconst version = splitElement.root.document ? splitElement.root.document.version : null;\n\t\t\tconst howMany = splitElement.maxOffset - position.offset;\n\t\t\tconst split = new SplitOperation( position, howMany, null, version );\n\n\t\t\tthis.batch.addOperation( split );\n\t\t\tthis.model.applyOperation( split );\n\n\t\t\t// Cache result of the first split.\n\t\t\tif ( !firstSplitElement && !firstCopyElement ) {\n\t\t\t\tfirstSplitElement = splitElement;\n\t\t\t\tfirstCopyElement = position.parent.nextSibling;\n\t\t\t}\n\n\t\t\tposition = this.createPositionAfter( position.parent );\n\t\t\tsplitElement = position.parent;\n\t\t} while ( splitElement !== limitElement );\n\n\t\treturn {\n\t\t\tposition,\n\t\t\trange: new Range( Position._createAt( firstSplitElement, 'end' ), Position._createAt( firstCopyElement, 0 ) )\n\t\t};\n\t}\n\n\t/**\n\t * Wraps the given range with the given element or with a new element (if a string was passed).\n\t *\n\t * **Note:** range to wrap should be a \"flat range\" (see {@link module:engine/model/range~Range#isFlat `Range#isFlat`}).\n\t * If not, an error will be thrown.\n\t *\n\t * @param {module:engine/model/range~Range} range Range to wrap.\n\t * @param {module:engine/model/element~Element|String} elementOrString Element or name of element to wrap the range with.\n\t */\n\twrap( range, elementOrString ) {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( !range.isFlat ) {\n\t\t\t/**\n\t\t\t * Range to wrap is not flat.\n\t\t\t *\n\t\t\t * @error writer-wrap-range-not-flat\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-wrap-range-not-flat: Range to wrap is not flat.' );\n\t\t}\n\n\t\tconst element = elementOrString instanceof Element ? elementOrString : new Element( elementOrString );\n\n\t\tif ( element.childCount > 0 ) {\n\t\t\t/**\n\t\t\t * Element to wrap with is not empty.\n\t\t\t *\n\t\t\t * @error writer-wrap-element-not-empty\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-wrap-element-not-empty: Element to wrap with is not empty.' );\n\t\t}\n\n\t\tif ( element.parent !== null ) {\n\t\t\t/**\n\t\t\t * Element to wrap with is already attached to a tree model.\n\t\t\t *\n\t\t\t * @error writer-wrap-element-attached\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-wrap-element-attached: Element to wrap with is already attached to tree model.' );\n\t\t}\n\n\t\tthis.insert( element, range.start );\n\n\t\t// Shift the range-to-wrap because we just inserted an element before that range.\n\t\tconst shiftedRange = new Range( range.start.getShiftedBy( 1 ), range.end.getShiftedBy( 1 ) );\n\n\t\tthis.move( shiftedRange, Position._createAt( element, 0 ) );\n\t}\n\n\t/**\n\t * Unwraps children of the given element – all its children are moved before it and then the element is removed.\n\t * Throws error if you try to unwrap an element which does not have a parent.\n\t *\n\t * @param {module:engine/model/element~Element} element Element to unwrap.\n\t */\n\tunwrap( element ) {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( element.parent === null ) {\n\t\t\t/**\n\t\t\t * Trying to unwrap an element which has no parent.\n\t\t\t *\n\t\t\t * @error writer-unwrap-element-no-parent\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-unwrap-element-no-parent: Trying to unwrap an element which has no parent.' );\n\t\t}\n\n\t\tthis.move( Range._createIn( element ), this.createPositionAfter( element ) );\n\t\tthis.remove( element );\n\t}\n\n\t/**\n\t * Adds a {@link module:engine/model/markercollection~Marker marker}. Marker is a named range, which tracks\n\t * changes in the document and updates its range automatically, when model tree changes.\n\t *\n\t * As the first parameter you can set marker name.\n\t *\n\t * The required `options.usingOperation` parameter lets you decide if the marker should be managed by operations or not. See\n\t * {@link module:engine/model/markercollection~Marker marker class description} to learn about the difference between\n\t * markers managed by operations and not-managed by operations.\n\t *\n\t * The `options.affectsData` parameter, which defaults to `false`, allows you to define if a marker affects the data. It should be\n\t * `true` when the marker change changes the data returned by the\n\t * {@link module:core/editor/utils/dataapimixin~DataApi#getData `editor.getData()`} method.\n\t * When set to `true` it fires the {@link module:engine/model/document~Document#event:change:data `change:data`} event.\n\t * When set to `false` it fires the {@link module:engine/model/document~Document#event:change `change`} event.\n\t *\n\t * Create marker directly base on marker's name:\n\t *\n\t *\t\taddMarker( markerName, { range, usingOperation: false } );\n\t *\n\t * Create marker using operation:\n\t *\n\t *\t\taddMarker( markerName, { range, usingOperation: true } );\n\t *\n\t * Create marker that affects the editor data:\n\t *\n\t *\t\taddMarker( markerName, { range, usingOperation: false, affectsData: true } );\n\t *\n\t * Note: For efficiency reasons, it's best to create and keep as little markers as possible.\n\t *\n\t * @see module:engine/model/markercollection~Marker\n\t * @param {String} name Name of a marker to create - must be unique.\n\t * @param {Object} options\n\t * @param {Boolean} options.usingOperation Flag indicating that the marker should be added by MarkerOperation.\n\t * See {@link module:engine/model/markercollection~Marker#managedUsingOperations}.\n\t * @param {module:engine/model/range~Range} options.range Marker range.\n\t * @param {Boolean} [options.affectsData=false] Flag indicating that the marker changes the editor data.\n\t * @returns {module:engine/model/markercollection~Marker} Marker that was set.\n\t */\n\taddMarker( name, options ) {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( !options || typeof options.usingOperation != 'boolean' ) {\n\t\t\t/**\n\t\t\t * The `options.usingOperation` parameter is required when adding a new marker.\n\t\t\t *\n\t\t\t * @error writer-addMarker-no-usingOperation\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'writer-addMarker-no-usingOperation: The options.usingOperation parameter is required when adding a new marker.'\n\t\t\t);\n\t\t}\n\n\t\tconst usingOperation = options.usingOperation;\n\t\tconst range = options.range;\n\t\tconst affectsData = options.affectsData === undefined ? false : options.affectsData;\n\n\t\tif ( this.model.markers.has( name ) ) {\n\t\t\t/**\n\t\t\t * Marker with provided name already exists.\n\t\t\t *\n\t\t\t * @error writer-addMarker-marker-exists\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-addMarker-marker-exists: Marker with provided name already exists.' );\n\t\t}\n\n\t\tif ( !range ) {\n\t\t\t/**\n\t\t\t * Range parameter is required when adding a new marker.\n\t\t\t *\n\t\t\t * @error writer-addMarker-no-range\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-addMarker-no-range: Range parameter is required when adding a new marker.' );\n\t\t}\n\n\t\tif ( !usingOperation ) {\n\t\t\treturn this.model.markers._set( name, range, usingOperation, affectsData );\n\t\t}\n\n\t\tapplyMarkerOperation( this, name, null, range, affectsData );\n\n\t\treturn this.model.markers.get( name );\n\t}\n\n\t/**\n\t * Adds, updates or refreshes a {@link module:engine/model/markercollection~Marker marker}. Marker is a named range, which tracks\n\t * changes in the document and updates its range automatically, when model tree changes. Still, it is possible to change the\n\t * marker's range directly using this method.\n\t *\n\t * As the first parameter you can set marker name or instance. If none of them is provided, new marker, with a unique\n\t * name is created and returned.\n\t *\n\t * As the second parameter you can set the new marker data or leave this parameter as empty which will just refresh\n\t * the marker by triggering downcast conversion for it. Refreshing the marker is useful when you want to change\n\t * the marker {@link module:engine/view/element~Element view element} without changing any marker data.\n\t *\n\t * \t\tlet isCommentActive = false;\n\t *\n\t * \t\tmodel.conversion.markerToHighlight( {\n\t * \t\t\tmodel: 'comment',\n\t *\t\t\tview: data => {\n\t *\t\t\t\tconst classes = [ 'comment-marker' ];\n\t *\n\t *\t\t\t\tif ( isCommentActive ) {\n\t *\t\t\t\t\tclasses.push( 'comment-marker--active' );\n\t *\t\t\t\t}\n\t *\n\t *\t\t\t\treturn { classes };\n\t *\t\t\t}\n\t * \t\t} );\n\t *\n\t * \t\t// Change the property that indicates if marker is displayed as active or not.\n\t * \t\tisCommentActive = true;\n\t *\n\t * \t\t// And refresh the marker to convert it with additional class.\n\t * \t\tmodel.change( writer => writer.updateMarker( 'comment' ) );\n\t *\n\t * The `options.usingOperation` parameter lets you change if the marker should be managed by operations or not. See\n\t * {@link module:engine/model/markercollection~Marker marker class description} to learn about the difference between\n\t * markers managed by operations and not-managed by operations. It is possible to change this option for an existing marker.\n\t *\n\t * The `options.affectsData` parameter, which defaults to `false`, allows you to define if a marker affects the data. It should be\n\t * `true` when the marker change changes the data returned by\n\t * the {@link module:core/editor/utils/dataapimixin~DataApi#getData `editor.getData()`} method.\n\t * When set to `true` it fires the {@link module:engine/model/document~Document#event:change:data `change:data`} event.\n\t * When set to `false` it fires the {@link module:engine/model/document~Document#event:change `change`} event.\n\t *\n\t * Update marker directly base on marker's name:\n\t *\n\t *\t\tupdateMarker( markerName, { range } );\n\t *\n\t * Update marker using operation:\n\t *\n\t *\t\tupdateMarker( marker, { range, usingOperation: true } );\n\t *\t\tupdateMarker( markerName, { range, usingOperation: true } );\n\t *\n\t * Change marker's option (start using operations to manage it):\n\t *\n\t *\t\tupdateMarker( marker, { usingOperation: true } );\n\t *\n\t * Change marker's option (inform the engine, that the marker does not affect the data anymore):\n\t *\n\t *\t\tupdateMarker( markerName, { affectsData: false } );\n\t *\n\t * @see module:engine/model/markercollection~Marker\n\t * @param {String} markerOrName Name of a marker to update, or a marker instance.\n\t * @param {Object} [options] If options object is not defined then marker will be refreshed by triggering\n\t * downcast conversion for this marker with the same data.\n\t * @param {module:engine/model/range~Range} [options.range] Marker range to update.\n\t * @param {Boolean} [options.usingOperation] Flag indicated whether the marker should be added by MarkerOperation.\n\t * See {@link module:engine/model/markercollection~Marker#managedUsingOperations}.\n\t * @param {Boolean} [options.affectsData] Flag indicating that the marker changes the editor data.\n\t */\n\tupdateMarker( markerOrName, options ) {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tconst markerName = typeof markerOrName == 'string' ? markerOrName : markerOrName.name;\n\t\tconst currentMarker = this.model.markers.get( markerName );\n\n\t\tif ( !currentMarker ) {\n\t\t\t/**\n\t\t\t * Marker with provided name does not exists.\n\t\t\t *\n\t\t\t * @error writer-updateMarker-marker-not-exists\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-updateMarker-marker-not-exists: Marker with provided name does not exists.' );\n\t\t}\n\n\t\tif ( !options ) {\n\t\t\tthis.model.markers._refresh( currentMarker );\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst hasUsingOperationDefined = typeof options.usingOperation == 'boolean';\n\t\tconst affectsDataDefined = typeof options.affectsData == 'boolean';\n\n\t\t// Use previously defined marker's affectsData if the property is not provided.\n\t\tconst affectsData = affectsDataDefined ? options.affectsData : currentMarker.affectsData;\n\n\t\tif ( !hasUsingOperationDefined && !options.range && !affectsDataDefined ) {\n\t\t\t/**\n\t\t\t * One of the options is required - provide range, usingOperations or affectsData.\n\t\t\t *\n\t\t\t * @error writer-updateMarker-wrong-options\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'writer-updateMarker-wrong-options: One of the options is required - provide range, usingOperations or affectsData.'\n\t\t\t);\n\t\t}\n\n\t\tconst currentRange = currentMarker.getRange();\n\t\tconst updatedRange = options.range ? options.range : currentRange;\n\n\t\tif ( hasUsingOperationDefined && options.usingOperation !== currentMarker.managedUsingOperations ) {\n\t\t\t// The marker type is changed so it's necessary to create proper operations.\n\t\t\tif ( options.usingOperation ) {\n\t\t\t\t// If marker changes to a managed one treat this as synchronizing existing marker.\n\t\t\t\t// Create `MarkerOperation` with `oldRange` set to `null`, so reverse operation will remove the marker.\n\t\t\t\tapplyMarkerOperation( this, markerName, null, updatedRange, affectsData );\n\t\t\t} else {\n\t\t\t\t// If marker changes to a marker that do not use operations then we need to create additional operation\n\t\t\t\t// that removes that marker first.\n\t\t\t\tapplyMarkerOperation( this, markerName, currentRange, null, affectsData );\n\n\t\t\t\t// Although not managed the marker itself should stay in model and its range should be preserver or changed to passed range.\n\t\t\t\tthis.model.markers._set( markerName, updatedRange, undefined, affectsData );\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Marker's type doesn't change so update it accordingly.\n\t\tif ( currentMarker.managedUsingOperations ) {\n\t\t\tapplyMarkerOperation( this, markerName, currentRange, updatedRange, affectsData );\n\t\t} else {\n\t\t\tthis.model.markers._set( markerName, updatedRange, undefined, affectsData );\n\t\t}\n\t}\n\n\t/**\n\t * Removes given {@link module:engine/model/markercollection~Marker marker} or marker with given name.\n\t * The marker is removed accordingly to how it has been created, so if the marker was created using operation,\n\t * it will be destroyed using operation.\n\t *\n\t * @param {module:engine/model/markercollection~Marker|String} markerOrName Marker or marker name to remove.\n\t */\n\tremoveMarker( markerOrName ) {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tconst name = typeof markerOrName == 'string' ? markerOrName : markerOrName.name;\n\n\t\tif ( !this.model.markers.has( name ) ) {\n\t\t\t/**\n\t\t\t * Trying to remove marker which does not exist.\n\t\t\t *\n\t\t\t * @error writer-removeMarker-no-marker\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-removeMarker-no-marker: Trying to remove marker which does not exist.' );\n\t\t}\n\n\t\tconst marker = this.model.markers.get( name );\n\n\t\tif ( !marker.managedUsingOperations ) {\n\t\t\tthis.model.markers._remove( name );\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst oldRange = marker.getRange();\n\n\t\tapplyMarkerOperation( this, name, oldRange, null, marker.affectsData );\n\t}\n\n\t/**\n\t * Sets the document's selection (ranges and direction) to the specified location based on the given\n\t * {@link module:engine/model/selection~Selectable selectable} or creates an empty selection if no arguments were passed.\n\t *\n\t *\t\t// Sets selection to the given range.\n\t *\t\tconst range = writer.createRange( start, end );\n\t *\t\twriter.setSelection( range );\n\t *\n\t *\t\t// Sets selection to given ranges.\n\t *\t\tconst ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t *\t\twriter.setSelection( range );\n\t *\n\t *\t\t// Sets selection to other selection.\n\t *\t\tconst otherSelection = writer.createSelection();\n\t *\t\twriter.setSelection( otherSelection );\n\t *\n\t *\t\t// Sets selection to the given document selection.\n\t *\t\tconst documentSelection = model.document.selection;\n\t *\t\twriter.setSelection( documentSelection );\n\t *\n\t *\t\t// Sets collapsed selection at the given position.\n\t *\t\tconst position = writer.createPosition( root, path );\n\t *\t\twriter.setSelection( position );\n\t *\n\t *\t\t// Sets collapsed selection at the position of the given node and an offset.\n\t *\t\twriter.setSelection( paragraph, offset );\n\t *\n\t * Creates a range inside an {@link module:engine/model/element~Element element} which starts before the first child of\n \t * that element and ends after the last child of that element.\n\t *\n\t *\t\twriter.setSelection( paragraph, 'in' );\n\t *\n\t * Creates a range on an {@link module:engine/model/item~Item item} which starts before the item and ends just after the item.\n\t *\n\t *\t\twriter.setSelection( paragraph, 'on' );\n\t *\n\t *\t\t// Removes all selection's ranges.\n\t *\t\twriter.setSelection( null );\n\t *\n\t * `Writer#setSelection()` allow passing additional options (`backward`) as the last argument.\n\t *\n\t *\t\t// Sets selection as backward.\n\t *\t\twriter.setSelection( range, { backward: true } );\n\t *\n\t * Throws `writer-incorrect-use` error when the writer is used outside the `change()` block.\n\t *\n\t * @param {module:engine/model/selection~Selectable} selectable\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Sets place or offset of the selection.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.backward] Sets this selection instance to be backward.\n\t */\n\tsetSelection( selectable, placeOrOffset, options ) {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tthis.model.document.selection._setTo( selectable, placeOrOffset, options );\n\t}\n\n\t/**\n\t * Moves {@link module:engine/model/documentselection~DocumentSelection#focus} to the specified location.\n\t *\n\t * The location can be specified in the same form as\n\t * {@link #createPositionAt `writer.createPositionAt()`} parameters.\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tsetSelectionFocus( itemOrPosition, offset ) {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tthis.model.document.selection._setFocus( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Sets attribute(s) on the selection. If attribute with the same key already is set, it's value is overwritten.\n\t *\n\t * Using key and value pair:\n\t *\n\t * \twriter.setSelectionAttribute( 'italic', true );\n\t *\n\t * Using key-value object:\n\t *\n\t * \twriter.setSelectionAttribute( { italic: true, bold: false } );\n\t *\n\t * Using iterable object:\n\t *\n\t * \twriter.setSelectionAttribute( new Map( [ [ 'italic', true ] ] ) );\n\t *\n\t * @param {String|Object|Iterable.<*>} keyOrObjectOrIterable Key of the attribute to set\n\t * or object / iterable of key => value attribute pairs.\n\t * @param {*} [value] Attribute value.\n\t */\n\tsetSelectionAttribute( keyOrObjectOrIterable, value ) {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( typeof keyOrObjectOrIterable === 'string' ) {\n\t\t\tthis._setSelectionAttribute( keyOrObjectOrIterable, value );\n\t\t} else {\n\t\t\tfor ( const [ key, value ] of toMap( keyOrObjectOrIterable ) ) {\n\t\t\t\tthis._setSelectionAttribute( key, value );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Removes attribute(s) with given key(s) from the selection.\n\t *\n\t * Remove one attribute:\n\t *\n\t *\t\twriter.removeSelectionAttribute( 'italic' );\n\t *\n\t * Remove multiple attributes:\n\t *\n\t *\t\twriter.removeSelectionAttribute( [ 'italic', 'bold' ] );\n\t *\n\t * @param {String|Iterable.<String>} keyOrIterableOfKeys Key of the attribute to remove or an iterable of attribute keys to remove.\n\t */\n\tremoveSelectionAttribute( keyOrIterableOfKeys ) {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( typeof keyOrIterableOfKeys === 'string' ) {\n\t\t\tthis._removeSelectionAttribute( keyOrIterableOfKeys );\n\t\t} else {\n\t\t\tfor ( const key of keyOrIterableOfKeys ) {\n\t\t\t\tthis._removeSelectionAttribute( key );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Temporarily changes the {@link module:engine/model/documentselection~DocumentSelection#isGravityOverridden gravity}\n\t * of the selection from left to right.\n\t *\n\t * The gravity defines from which direction the selection inherits its attributes. If it's the default left gravity,\n\t * then the selection (after being moved by the user) inherits attributes from its left-hand side.\n\t * This method allows to temporarily override this behavior by forcing the gravity to the right.\n\t *\n\t * For the following model fragment:\n\t *\n\t *\t\t<$text bold=\"true\" linkHref=\"url\">bar[]</$text><$text bold=\"true\">biz</$text>\n\t *\n\t * * Default gravity: selection will have the `bold` and `linkHref` attributes.\n\t * * Overridden gravity: selection will have `bold` attribute.\n\t *\n\t * **Note**: It returns an unique identifier which is required to restore the gravity. It guarantees the symmetry\n\t * of the process.\n\t *\n\t * @returns {String} The unique id which allows restoring the gravity.\n\t */\n\toverrideSelectionGravity() {\n\t\treturn this.model.document.selection._overrideGravity();\n\t}\n\n\t/**\n\t * Restores {@link ~Writer#overrideSelectionGravity} gravity to default.\n\t *\n\t * Restoring the gravity is only possible using the unique identifier returned by\n\t * {@link ~Writer#overrideSelectionGravity}. Note that the gravity remains overridden as long as won't be restored\n\t * the same number of times it was overridden.\n\t *\n\t * @param {String} uid The unique id returned by {@link ~Writer#overrideSelectionGravity}.\n\t */\n\trestoreSelectionGravity( uid ) {\n\t\tthis.model.document.selection._restoreGravity( uid );\n\t}\n\n\t/**\n\t * @private\n\t * @param {String} key Key of the attribute to remove.\n\t * @param {*} value Attribute value.\n\t */\n\t_setSelectionAttribute( key, value ) {\n\t\tconst selection = this.model.document.selection;\n\n\t\t// Store attribute in parent element if the selection is collapsed in an empty node.\n\t\tif ( selection.isCollapsed && selection.anchor.parent.isEmpty ) {\n\t\t\tconst storeKey = DocumentSelection._getStoreAttributeKey( key );\n\n\t\t\tthis.setAttribute( storeKey, value, selection.anchor.parent );\n\t\t}\n\n\t\tselection._setAttribute( key, value );\n\t}\n\n\t/**\n\t * @private\n\t * @param {String} key Key of the attribute to remove.\n\t */\n\t_removeSelectionAttribute( key ) {\n\t\tconst selection = this.model.document.selection;\n\n\t\t// Remove stored attribute from parent element if the selection is collapsed in an empty node.\n\t\tif ( selection.isCollapsed && selection.anchor.parent.isEmpty ) {\n\t\t\tconst storeKey = DocumentSelection._getStoreAttributeKey( key );\n\n\t\t\tthis.removeAttribute( storeKey, selection.anchor.parent );\n\t\t}\n\n\t\tselection._removeAttribute( key );\n\t}\n\n\t/**\n\t * Throws `writer-detached-writer-tries-to-modify-model` error when the writer is used outside of the `change()` block.\n\t *\n\t * @private\n\t */\n\t_assertWriterUsedCorrectly() {\n\t\t/**\n\t\t * Trying to use a writer outside a {@link module:engine/model/model~Model#change `change()` or\n\t\t * {@link module:engine/model/model~Model#enqueueChange `enqueueChange()`} blocks.\n\t\t *\n\t\t * The writer can only be used inside these blocks which ensures that the model\n\t\t * can only be changed during such \"sessions\".\n\t\t *\n\t\t * @error writer-incorrect-use\n\t\t */\n\t\tif ( this.model._currentWriter !== this ) {\n\t\t\tthrow new CKEditorError( 'writer-incorrect-use: Trying to use a writer outside the change() block.' );\n\t\t}\n\t}\n\n\t/**\n\t * For given action `type` and `positionOrRange` where the action happens, this function finds all affected markers\n\t * and applies a marker operation with the new marker range equal to the current range. Thanks to this, the marker range\n\t * can be later correctly processed during undo.\n\t *\n\t * @private\n\t * @param {'move'|'merge'} type Writer action type.\n\t * @param {module:engine/model/position~Position|module:engine/model/range~Range} positionOrRange Position or range\n\t * where the writer action happens.\n\t */\n\t_addOperationForAffectedMarkers( type, positionOrRange ) {\n\t\tfor ( const marker of this.model.markers ) {\n\t\t\tif ( !marker.managedUsingOperations ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst markerRange = marker.getRange();\n\t\t\tlet isAffected = false;\n\n\t\t\tif ( type == 'move' ) {\n\t\t\t\tisAffected =\n\t\t\t\t\tpositionOrRange.containsPosition( markerRange.start ) ||\n\t\t\t\t\tpositionOrRange.start.isEqual( markerRange.start ) ||\n\t\t\t\t\tpositionOrRange.containsPosition( markerRange.end ) ||\n\t\t\t\t\tpositionOrRange.end.isEqual( markerRange.end );\n\t\t\t} else {\n\t\t\t\t// if type == 'merge'.\n\t\t\t\tconst elementBefore = positionOrRange.nodeBefore;\n\t\t\t\tconst elementAfter = positionOrRange.nodeAfter;\n\n\t\t\t\tconst affectedOnLeft = markerRange.start.parent == elementBefore && markerRange.start.isAtEnd;\n\t\t\t\tconst affectedOnRight = markerRange.end.parent == elementAfter && markerRange.end.offset == 0;\n\n\t\t\t\tisAffected = affectedOnLeft || affectedOnRight;\n\t\t\t}\n\n\t\t\tif ( isAffected ) {\n\t\t\t\tthis.updateMarker( marker.name, { range: markerRange } );\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Sets given attribute to each node in given range. When attribute value is null then attribute will be removed.\n//\n// Because attribute operation needs to have the same attribute value on the whole range, this function splits\n// the range into smaller parts.\n//\n// Given `range` must be flat.\n//\n// @private\n// @param {module:engine/model/writer~Writer} writer\n// @param {String} key Attribute key.\n// @param {*} value Attribute new value.\n// @param {module:engine/model/range~Range} range Model range on which the attribute will be set.\nfunction setAttributeOnRange( writer, key, value, range ) {\n\tconst model = writer.model;\n\tconst doc = model.document;\n\n\t// Position of the last split, the beginning of the new range.\n\tlet lastSplitPosition = range.start;\n\n\t// Currently position in the scanning range. Because we need value after the position, it is not a current\n\t// position of the iterator but the previous one (we need to iterate one more time to get the value after).\n\tlet position;\n\n\t// Value before the currently position.\n\tlet valueBefore;\n\n\t// Value after the currently position.\n\tlet valueAfter;\n\n\tfor ( const val of range.getWalker( { shallow: true } ) ) {\n\t\tvalueAfter = val.item.getAttribute( key );\n\n\t\t// At the first run of the iterator the position in undefined. We also do not have a valueBefore, but\n\t\t// because valueAfter may be null, valueBefore may be equal valueAfter ( undefined == null ).\n\t\tif ( position && valueBefore != valueAfter ) {\n\t\t\t// if valueBefore == value there is nothing to change, so we add operation only if these values are different.\n\t\t\tif ( valueBefore != value ) {\n\t\t\t\taddOperation();\n\t\t\t}\n\n\t\t\tlastSplitPosition = position;\n\t\t}\n\n\t\tposition = val.nextPosition;\n\t\tvalueBefore = valueAfter;\n\t}\n\n\t// Because position in the loop is not the iterator position (see let position comment), the last position in\n\t// the while loop will be last but one position in the range. We need to check the last position manually.\n\tif ( position instanceof Position && position != lastSplitPosition && valueBefore != value ) {\n\t\taddOperation();\n\t}\n\n\tfunction addOperation() {\n\t\tconst range = new Range( lastSplitPosition, position );\n\t\tconst version = range.root.document ? doc.version : null;\n\t\tconst operation = new AttributeOperation( range, key, valueBefore, value, version );\n\n\t\twriter.batch.addOperation( operation );\n\t\tmodel.applyOperation( operation );\n\t}\n}\n\n// Sets given attribute to the given node. When attribute value is null then attribute will be removed.\n//\n// @private\n// @param {module:engine/model/writer~Writer} writer\n// @param {String} key Attribute key.\n// @param {*} value Attribute new value.\n// @param {module:engine/model/item~Item} item Model item on which the attribute will be set.\nfunction setAttributeOnItem( writer, key, value, item ) {\n\tconst model = writer.model;\n\tconst doc = model.document;\n\tconst previousValue = item.getAttribute( key );\n\tlet range, operation;\n\n\tif ( previousValue != value ) {\n\t\tconst isRootChanged = item.root === item;\n\n\t\tif ( isRootChanged ) {\n\t\t\t// If we change attributes of root element, we have to use `RootAttributeOperation`.\n\t\t\tconst version = item.document ? doc.version : null;\n\n\t\t\toperation = new RootAttributeOperation( item, key, previousValue, value, version );\n\t\t} else {\n\t\t\trange = new Range( Position._createBefore( item ), writer.createPositionAfter( item ) );\n\n\t\t\tconst version = range.root.document ? doc.version : null;\n\n\t\t\toperation = new AttributeOperation( range, key, previousValue, value, version );\n\t\t}\n\n\t\twriter.batch.addOperation( operation );\n\t\tmodel.applyOperation( operation );\n\t}\n}\n\n// Creates and applies marker operation to {@link module:engine/model/operation/operation~Operation operation}.\n//\n// @private\n// @param {module:engine/model/writer~Writer} writer\n// @param {String} name Marker name.\n// @param {module:engine/model/range~Range} oldRange Marker range before the change.\n// @param {module:engine/model/range~Range} newRange Marker range after the change.\n// @param {Boolean} affectsData\nfunction applyMarkerOperation( writer, name, oldRange, newRange, affectsData ) {\n\tconst model = writer.model;\n\tconst doc = model.document;\n\n\tconst operation = new MarkerOperation( name, oldRange, newRange, model.markers, affectsData, doc.version );\n\n\twriter.batch.addOperation( operation );\n\tmodel.applyOperation( operation );\n}\n\n// Creates `MoveOperation` or `DetachOperation` that removes `howMany` nodes starting from `position`.\n// The operation will be applied on given model instance and added to given operation instance.\n//\n// @private\n// @param {module:engine/model/position~Position} position Position from which nodes are removed.\n// @param {Number} howMany Number of nodes to remove.\n// @param {Batch} batch Batch to which the operation will be added.\n// @param {module:engine/model/model~Model} model Model instance on which operation will be applied.\nfunction applyRemoveOperation( position, howMany, batch, model ) {\n\tlet operation;\n\n\tif ( position.root.document ) {\n\t\tconst doc = model.document;\n\t\tconst graveyardPosition = new Position( doc.graveyard, [ 0 ] );\n\n\t\toperation = new MoveOperation( position, howMany, graveyardPosition, doc.version );\n\t} else {\n\t\toperation = new DetachOperation( position, howMany );\n\t}\n\n\tbatch.addOperation( operation );\n\tmodel.applyOperation( operation );\n}\n\n// Returns `true` if both root elements are the same element or both are documents root elements.\n//\n// Elements in the same tree can be moved (for instance you can move element form one documents root to another, or\n// within the same document fragment), but when element supposed to be moved from document fragment to the document, or\n// to another document it should be removed and inserted to avoid problems with OT. This is because features like undo or\n// collaboration may track changes on the document but ignore changes on detached fragments and should not get\n// unexpected `move` operation.\nfunction isSameTree( rootA, rootB ) {\n\t// If it is the same root this is the same tree.\n\tif ( rootA === rootB ) {\n\t\treturn true;\n\t}\n\n\t// If both roots are documents root it is operation within the document what we still treat as the same tree.\n\tif ( rootA instanceof RootElement && rootB instanceof RootElement ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/differ\n */\n\nimport Position from './position';\nimport Range from './range';\n\n/**\n * Calculates the difference between two model states.\n *\n * Receives operations that are to be applied on the model document. Marks parts of the model document tree which\n * are changed and saves the state of these elements before the change. Then, it compares saved elements with the\n * changed elements, after all changes are applied on the model document. Calculates the diff between saved\n * elements and new ones and returns a change set.\n */\nexport default class Differ {\n\t/**\n\t * Creates a `Differ` instance.\n\t *\n\t * @param {module:engine/model/markercollection~MarkerCollection} markerCollection Model's marker collection.\n\t */\n\tconstructor( markerCollection ) {\n\t\t/**\n\t\t * Reference to the model's marker collection.\n\t\t *\n\t\t * @private\n\t\t * @type {module:engine/model/markercollection~MarkerCollection}\n\t\t */\n\t\tthis._markerCollection = markerCollection;\n\n\t\t/**\n\t\t * A map that stores changes that happened in a given element.\n\t\t *\n\t\t * The keys of the map are references to the model elements.\n\t\t * The values of the map are arrays with changes that were done on this element.\n\t\t *\n\t\t * @private\n\t\t * @type {Map}\n\t\t */\n\t\tthis._changesInElement = new Map();\n\n\t\t/**\n\t\t * A map that stores \"element's children snapshots\". A snapshot is representing children of a given element before\n\t\t * the first change was applied on that element. Snapshot items are objects with two properties: `name`,\n\t\t * containing the element name (or `'$text'` for a text node) and `attributes` which is a map of the node's attributes.\n\t\t *\n\t\t * @private\n\t\t * @type {Map}\n\t\t */\n\t\tthis._elementSnapshots = new Map();\n\n\t\t/**\n\t\t * A map that stores all changed markers.\n\t\t *\n\t\t * The keys of the map are marker names.\n\t\t * The values of the map are objects with the `oldRange` and `newRange` properties. They store the marker range\n\t\t * state before and after the change.\n\t\t *\n\t\t * @private\n\t\t * @type {Map}\n\t\t */\n\t\tthis._changedMarkers = new Map();\n\n\t\t/**\n\t\t * Stores the number of changes that were processed. Used to order the changes chronologically. It is important\n\t\t * when changes are sorted.\n\t\t *\n\t\t * @private\n\t\t * @type {Number}\n\t\t */\n\t\tthis._changeCount = 0;\n\n\t\t/**\n\t\t * For efficiency purposes, `Differ` stores the change set returned by the differ after {@link #getChanges} call.\n\t\t * Cache is reset each time a new operation is buffered. If the cache has not been reset, {@link #getChanges} will\n\t\t * return the cached value instead of calculating it again.\n\t\t *\n\t\t * This property stores those changes that did not take place in graveyard root.\n\t\t *\n\t\t * @private\n\t\t * @type {Array.<Object>|null}\n\t\t */\n\t\tthis._cachedChanges = null;\n\n\t\t/**\n\t\t * For efficiency purposes, `Differ` stores the change set returned by the differ after the {@link #getChanges} call.\n\t\t * The cache is reset each time a new operation is buffered. If the cache has not been reset, {@link #getChanges} will\n\t\t * return the cached value instead of calculating it again.\n\t\t *\n\t\t * This property stores all changes evaluated by `Differ`, including those that took place in the graveyard.\n\t\t *\n\t\t * @private\n\t\t * @type {Array.<Object>|null}\n\t\t */\n\t\tthis._cachedChangesWithGraveyard = null;\n\t}\n\n\t/**\n\t * Informs whether there are any changes buffered in `Differ`.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isEmpty() {\n\t\treturn this._changesInElement.size == 0 && this._changedMarkers.size == 0;\n\t}\n\n\t/**\n\t * Buffers the given operation. An operation has to be buffered before it is executed.\n\t *\n\t * Operation type is checked and it is checked which nodes it will affect. These nodes are then stored in `Differ`\n\t * in the state before the operation is executed.\n\t *\n\t * @param {module:engine/model/operation/operation~Operation} operation An operation to buffer.\n\t */\n\tbufferOperation( operation ) {\n\t\t// Below we take an operation, check its type, then use its parameters in marking (private) methods.\n\t\t// The general rule is to not mark elements inside inserted element. All inserted elements are re-rendered.\n\t\t// Marking changes in them would cause a \"double\" changing then.\n\t\t//\n\t\tswitch ( operation.type ) {\n\t\t\tcase 'insert': {\n\t\t\t\tif ( this._isInInsertedElement( operation.position.parent ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis._markInsert( operation.position.parent, operation.position.offset, operation.nodes.maxOffset );\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'addAttribute':\n\t\t\tcase 'removeAttribute':\n\t\t\tcase 'changeAttribute': {\n\t\t\t\tfor ( const item of operation.range.getItems() ) {\n\t\t\t\t\tif ( this._isInInsertedElement( item.parent ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis._markAttribute( item );\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'remove':\n\t\t\tcase 'move':\n\t\t\tcase 'reinsert': {\n\t\t\t\t// When range is moved to the same position then not mark it as a change.\n\t\t\t\t// See: https://github.com/ckeditor/ckeditor5-engine/issues/1664.\n\t\t\t\tif (\n\t\t\t\t\toperation.sourcePosition.isEqual( operation.targetPosition ) ||\n\t\t\t\t\toperation.sourcePosition.getShiftedBy( operation.howMany ).isEqual( operation.targetPosition )\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst sourceParentInserted = this._isInInsertedElement( operation.sourcePosition.parent );\n\t\t\t\tconst targetParentInserted = this._isInInsertedElement( operation.targetPosition.parent );\n\n\t\t\t\tif ( !sourceParentInserted ) {\n\t\t\t\t\tthis._markRemove( operation.sourcePosition.parent, operation.sourcePosition.offset, operation.howMany );\n\t\t\t\t}\n\n\t\t\t\tif ( !targetParentInserted ) {\n\t\t\t\t\tthis._markInsert( operation.targetPosition.parent, operation.getMovedRangeStart().offset, operation.howMany );\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'rename': {\n\t\t\t\tif ( this._isInInsertedElement( operation.position.parent ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis._markRemove( operation.position.parent, operation.position.offset, 1 );\n\t\t\t\tthis._markInsert( operation.position.parent, operation.position.offset, 1 );\n\n\t\t\t\tconst range = Range._createFromPositionAndShift( operation.position, 1 );\n\n\t\t\t\tfor ( const marker of this._markerCollection.getMarkersIntersectingRange( range ) ) {\n\t\t\t\t\tconst markerRange = marker.getRange();\n\n\t\t\t\t\tthis.bufferMarkerChange( marker.name, markerRange, markerRange, marker.affectsData );\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'split': {\n\t\t\t\tconst splitElement = operation.splitPosition.parent;\n\n\t\t\t\t// Mark that children of the split element were removed.\n\t\t\t\tif ( !this._isInInsertedElement( splitElement ) ) {\n\t\t\t\t\tthis._markRemove( splitElement, operation.splitPosition.offset, operation.howMany );\n\t\t\t\t}\n\n\t\t\t\t// Mark that the new element (split copy) was inserted.\n\t\t\t\tif ( !this._isInInsertedElement( operation.insertionPosition.parent ) ) {\n\t\t\t\t\tthis._markInsert( operation.insertionPosition.parent, operation.insertionPosition.offset, 1 );\n\t\t\t\t}\n\n\t\t\t\t// If the split took the element from the graveyard, mark that the element from the graveyard was removed.\n\t\t\t\tif ( operation.graveyardPosition ) {\n\t\t\t\t\tthis._markRemove( operation.graveyardPosition.parent, operation.graveyardPosition.offset, 1 );\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'merge': {\n\t\t\t\t// Mark that the merged element was removed.\n\t\t\t\tconst mergedElement = operation.sourcePosition.parent;\n\n\t\t\t\tif ( !this._isInInsertedElement( mergedElement.parent ) ) {\n\t\t\t\t\tthis._markRemove( mergedElement.parent, mergedElement.startOffset, 1 );\n\t\t\t\t}\n\n\t\t\t\t// Mark that the merged element was inserted into graveyard.\n\t\t\t\tconst graveyardParent = operation.graveyardPosition.parent;\n\n\t\t\t\tthis._markInsert( graveyardParent, operation.graveyardPosition.offset, 1 );\n\n\t\t\t\t// Mark that children of merged element were inserted at new parent.\n\t\t\t\tconst mergedIntoElement = operation.targetPosition.parent;\n\n\t\t\t\tif ( !this._isInInsertedElement( mergedIntoElement ) ) {\n\t\t\t\t\tthis._markInsert( mergedIntoElement, operation.targetPosition.offset, mergedElement.maxOffset );\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// Clear cache after each buffered operation as it is no longer valid.\n\t\tthis._cachedChanges = null;\n\t}\n\n\t/**\n\t * Buffers a marker change.\n\t *\n\t * @param {String} markerName The name of the marker that changed.\n\t * @param {module:engine/model/range~Range|null} oldRange Marker range before the change or `null` if the marker has just\n\t * been created.\n\t * @param {module:engine/model/range~Range|null} newRange Marker range after the change or `null` if the marker was removed.\n\t * @param {Boolean} affectsData Flag indicating whether marker affects the editor data.\n\t */\n\tbufferMarkerChange( markerName, oldRange, newRange, affectsData ) {\n\t\tconst buffered = this._changedMarkers.get( markerName );\n\n\t\tif ( !buffered ) {\n\t\t\tthis._changedMarkers.set( markerName, {\n\t\t\t\toldRange,\n\t\t\t\tnewRange,\n\t\t\t\taffectsData\n\t\t\t} );\n\t\t} else {\n\t\t\tbuffered.newRange = newRange;\n\t\t\tbuffered.affectsData = affectsData;\n\n\t\t\tif ( buffered.oldRange == null && buffered.newRange == null ) {\n\t\t\t\t// The marker is going to be removed (`newRange == null`) but it did not exist before the first buffered change\n\t\t\t\t// (`buffered.oldRange == null`). In this case, do not keep the marker in buffer at all.\n\t\t\t\tthis._changedMarkers.delete( markerName );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns all markers that should be removed as a result of buffered changes.\n\t *\n\t * @returns {Array.<Object>} Markers to remove. Each array item is an object containing the `name` and `range` properties.\n\t */\n\tgetMarkersToRemove() {\n\t\tconst result = [];\n\n\t\tfor ( const [ name, change ] of this._changedMarkers ) {\n\t\t\tif ( change.oldRange != null ) {\n\t\t\t\tresult.push( { name, range: change.oldRange } );\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Returns all markers which should be added as a result of buffered changes.\n\t *\n\t * @returns {Array.<Object>} Markers to add. Each array item is an object containing the `name` and `range` properties.\n\t */\n\tgetMarkersToAdd() {\n\t\tconst result = [];\n\n\t\tfor ( const [ name, change ] of this._changedMarkers ) {\n\t\t\tif ( change.newRange != null ) {\n\t\t\t\tresult.push( { name, range: change.newRange } );\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Returns all markers which changed.\n\t *\n\t * @returns {Array.<Object>}\n\t */\n\tgetChangedMarkers() {\n\t\treturn Array.from( this._changedMarkers ).map( item => (\n\t\t\t{\n\t\t\t\tname: item[ 0 ],\n\t\t\t\tdata: {\n\t\t\t\t\toldRange: item[ 1 ].oldRange,\n\t\t\t\t\tnewRange: item[ 1 ].newRange\n\t\t\t\t}\n\t\t\t}\n\t\t) );\n\t}\n\n\t/**\n\t * Checks whether some of the buffered changes affect the editor data.\n\t *\n\t * Types of changes which affect the editor data:\n\t *\n\t * * model structure changes,\n\t * * attribute changes,\n\t * * changes of markers which were defined as `affectingData`.\n\t *\n\t * @returns {Boolean}\n\t */\n\thasDataChanges() {\n\t\tfor ( const [ , change ] of this._changedMarkers ) {\n\t\t\tif ( change.affectsData ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t// If markers do not affect the data, check whether there are some changes in elements.\n\t\treturn this._changesInElement.size > 0;\n\t}\n\n\t/**\n\t * Calculates the diff between the old model tree state (the state before the first buffered operations since the last {@link #reset}\n\t * call) and the new model tree state (actual one). It should be called after all buffered operations are executed.\n\t *\n\t * The diff set is returned as an array of diff items, each describing a change done on the model. The items are sorted by\n\t * the position on which the change happened. If a position {@link module:engine/model/position~Position#isBefore is before}\n\t * another one, it will be on an earlier index in the diff set.\n\t *\n\t * Because calculating the diff is a costly operation, the result is cached. If no new operation was buffered since the\n\t * previous {@link #getChanges} call, the next call will return the cached value.\n\t *\n\t * @param {Object} options Additional options.\n\t * @param {Boolean} [options.includeChangesInGraveyard=false] If set to `true`, also changes that happened\n\t * in the graveyard root will be returned. By default, changes in the graveyard root are not returned.\n\t * @returns {Array.<Object>} Diff between the old and the new model tree state.\n\t */\n\tgetChanges( options = { includeChangesInGraveyard: false } ) {\n\t\t// If there are cached changes, just return them instead of calculating changes again.\n\t\tif ( this._cachedChanges ) {\n\t\t\tif ( options.includeChangesInGraveyard ) {\n\t\t\t\treturn this._cachedChangesWithGraveyard.slice();\n\t\t\t} else {\n\t\t\t\treturn this._cachedChanges.slice();\n\t\t\t}\n\t\t}\n\n\t\t// Will contain returned results.\n\t\tconst diffSet = [];\n\n\t\t// Check all changed elements.\n\t\tfor ( const element of this._changesInElement.keys() ) {\n\t\t\t// Get changes for this element and sort them.\n\t\t\tconst changes = this._changesInElement.get( element ).sort( ( a, b ) => {\n\t\t\t\tif ( a.offset === b.offset ) {\n\t\t\t\t\tif ( a.type != b.type ) {\n\t\t\t\t\t\t// If there are multiple changes at the same position, \"remove\" change should be first.\n\t\t\t\t\t\t// If the order is different, for example, we would first add some nodes and then removed them\n\t\t\t\t\t\t// (instead of the nodes that we should remove).\n\t\t\t\t\t\treturn a.type == 'remove' ? -1 : 1;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn a.offset < b.offset ? -1 : 1;\n\t\t\t} );\n\n\t\t\t// Get children of this element before any change was applied on it.\n\t\t\tconst snapshotChildren = this._elementSnapshots.get( element );\n\t\t\t// Get snapshot of current element's children.\n\t\t\tconst elementChildren = _getChildrenSnapshot( element.getChildren() );\n\n\t\t\t// Generate actions basing on changes done on element.\n\t\t\tconst actions = _generateActionsFromChanges( snapshotChildren.length, changes );\n\n\t\t\tlet i = 0; // Iterator in `elementChildren` array -- iterates through current children of element.\n\t\t\tlet j = 0; // Iterator in `snapshotChildren` array -- iterates through old children of element.\n\n\t\t\t// Process every action.\n\t\t\tfor ( const action of actions ) {\n\t\t\t\tif ( action === 'i' ) {\n\t\t\t\t\t// Generate diff item for this element and insert it into the diff set.\n\t\t\t\t\tdiffSet.push( this._getInsertDiff( element, i, elementChildren[ i ].name ) );\n\n\t\t\t\t\ti++;\n\t\t\t\t} else if ( action === 'r' ) {\n\t\t\t\t\t// Generate diff item for this element and insert it into the diff set.\n\t\t\t\t\tdiffSet.push( this._getRemoveDiff( element, i, snapshotChildren[ j ].name ) );\n\n\t\t\t\t\tj++;\n\t\t\t\t} else if ( action === 'a' ) {\n\t\t\t\t\t// Take attributes from saved and current children.\n\t\t\t\t\tconst elementAttributes = elementChildren[ i ].attributes;\n\t\t\t\t\tconst snapshotAttributes = snapshotChildren[ j ].attributes;\n\t\t\t\t\tlet range;\n\n\t\t\t\t\tif ( elementChildren[ i ].name == '$text' ) {\n\t\t\t\t\t\trange = new Range( Position._createAt( element, i ), Position._createAt( element, i + 1 ) );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst index = element.offsetToIndex( i );\n\t\t\t\t\t\trange = new Range( Position._createAt( element, i ), Position._createAt( element.getChild( index ), 0 ) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Generate diff items for this change (there might be multiple attributes changed and\n\t\t\t\t\t// there is a single diff for each of them) and insert them into the diff set.\n\t\t\t\t\tdiffSet.push( ...this._getAttributesDiff( range, snapshotAttributes, elementAttributes ) );\n\n\t\t\t\t\ti++;\n\t\t\t\t\tj++;\n\t\t\t\t} else {\n\t\t\t\t\t// `action` is 'equal'. Child not changed.\n\t\t\t\t\ti++;\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Then, sort the changes by the position (change at position before other changes is first).\n\t\tdiffSet.sort( ( a, b ) => {\n\t\t\t// If the change is in different root, we don't care much, but we'd like to have all changes in given\n\t\t\t// root \"together\" in the array. So let's just sort them by the root name. It does not matter which root\n\t\t\t// will be processed first.\n\t\t\tif ( a.position.root != b.position.root ) {\n\t\t\t\treturn a.position.root.rootName < b.position.root.rootName ? -1 : 1;\n\t\t\t}\n\n\t\t\t// If change happens at the same position...\n\t\t\tif ( a.position.isEqual( b.position ) ) {\n\t\t\t\t// Keep chronological order of operations.\n\t\t\t\treturn a.changeCount - b.changeCount;\n\t\t\t}\n\n\t\t\t// If positions differ, position \"on the left\" should be earlier in the result.\n\t\t\treturn a.position.isBefore( b.position ) ? -1 : 1;\n\t\t} );\n\n\t\t// Glue together multiple changes (mostly on text nodes).\n\t\tfor ( let i = 1; i < diffSet.length; i++ ) {\n\t\t\tconst prevDiff = diffSet[ i - 1 ];\n\t\t\tconst thisDiff = diffSet[ i ];\n\n\t\t\t// Glue remove changes if they happen on text on same position.\n\t\t\tconst isConsecutiveTextRemove =\n\t\t\t\tprevDiff.type == 'remove' && thisDiff.type == 'remove' &&\n\t\t\t\tprevDiff.name == '$text' && thisDiff.name == '$text' &&\n\t\t\t\tprevDiff.position.isEqual( thisDiff.position );\n\n\t\t\t// Glue insert changes if they happen on text on consecutive fragments.\n\t\t\tconst isConsecutiveTextAdd =\n\t\t\t\tprevDiff.type == 'insert' && thisDiff.type == 'insert' &&\n\t\t\t\tprevDiff.name == '$text' && thisDiff.name == '$text' &&\n\t\t\t\tprevDiff.position.parent == thisDiff.position.parent &&\n\t\t\t\tprevDiff.position.offset + prevDiff.length == thisDiff.position.offset;\n\n\t\t\t// Glue attribute changes if they happen on consecutive fragments and have same key, old value and new value.\n\t\t\tconst isConsecutiveAttributeChange =\n\t\t\t\tprevDiff.type == 'attribute' && thisDiff.type == 'attribute' &&\n\t\t\t\tprevDiff.position.parent == thisDiff.position.parent &&\n\t\t\t\tprevDiff.range.isFlat && thisDiff.range.isFlat &&\n\t\t\t\tprevDiff.position.offset + prevDiff.length == thisDiff.position.offset &&\n\t\t\t\tprevDiff.attributeKey == thisDiff.attributeKey &&\n\t\t\t\tprevDiff.attributeOldValue == thisDiff.attributeOldValue &&\n\t\t\t\tprevDiff.attributeNewValue == thisDiff.attributeNewValue;\n\n\t\t\tif ( isConsecutiveTextRemove || isConsecutiveTextAdd || isConsecutiveAttributeChange ) {\n\t\t\t\tdiffSet[ i - 1 ].length++;\n\n\t\t\t\tif ( isConsecutiveAttributeChange ) {\n\t\t\t\t\tdiffSet[ i - 1 ].range.end = diffSet[ i - 1 ].range.end.getShiftedBy( 1 );\n\t\t\t\t}\n\n\t\t\t\tdiffSet.splice( i, 1 );\n\t\t\t\ti--;\n\t\t\t}\n\t\t}\n\n\t\t// Remove `changeCount` property from diff items. It is used only for sorting and is internal thing.\n\t\tfor ( const item of diffSet ) {\n\t\t\tdelete item.changeCount;\n\n\t\t\tif ( item.type == 'attribute' ) {\n\t\t\t\tdelete item.position;\n\t\t\t\tdelete item.length;\n\t\t\t}\n\t\t}\n\n\t\tthis._changeCount = 0;\n\n\t\t// Cache changes.\n\t\tthis._cachedChangesWithGraveyard = diffSet.slice();\n\t\tthis._cachedChanges = diffSet.slice().filter( _changesInGraveyardFilter );\n\n\t\tif ( options.includeChangesInGraveyard ) {\n\t\t\treturn this._cachedChangesWithGraveyard;\n\t\t} else {\n\t\t\treturn this._cachedChanges;\n\t\t}\n\t}\n\n\t/**\n\t * Resets `Differ`. Removes all buffered changes.\n\t */\n\treset() {\n\t\tthis._changesInElement.clear();\n\t\tthis._elementSnapshots.clear();\n\t\tthis._changedMarkers.clear();\n\t\tthis._cachedChanges = null;\n\t}\n\n\t/**\n\t * Saves and handles an insert change.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} parent\n\t * @param {Number} offset\n\t * @param {Number} howMany\n\t */\n\t_markInsert( parent, offset, howMany ) {\n\t\tconst changeItem = { type: 'insert', offset, howMany, count: this._changeCount++ };\n\n\t\tthis._markChange( parent, changeItem );\n\t}\n\n\t/**\n\t * Saves and handles a remove change.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} parent\n\t * @param {Number} offset\n\t * @param {Number} howMany\n\t */\n\t_markRemove( parent, offset, howMany ) {\n\t\tconst changeItem = { type: 'remove', offset, howMany, count: this._changeCount++ };\n\n\t\tthis._markChange( parent, changeItem );\n\n\t\tthis._removeAllNestedChanges( parent, offset, howMany );\n\t}\n\n\t/**\n\t * Saves and handles an attribute change.\n\t *\n\t * @private\n\t * @param {module:engine/model/item~Item} item\n\t */\n\t_markAttribute( item ) {\n\t\tconst changeItem = { type: 'attribute', offset: item.startOffset, howMany: item.offsetSize, count: this._changeCount++ };\n\n\t\tthis._markChange( item.parent, changeItem );\n\t}\n\n\t/**\n\t * Saves and handles a model change.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} parent\n\t * @param {Object} changeItem\n\t */\n\t_markChange( parent, changeItem ) {\n\t\t// First, make a snapshot of this parent's children (it will be made only if it was not made before).\n\t\tthis._makeSnapshot( parent );\n\n\t\t// Then, get all changes that already were done on the element (empty array if this is the first change).\n\t\tconst changes = this._getChangesForElement( parent );\n\n\t\t// Then, look through all the changes, and transform them or the new change.\n\t\tthis._handleChange( changeItem, changes );\n\n\t\t// Add the new change.\n\t\tchanges.push( changeItem );\n\n\t\t// Remove incorrect changes. During transformation some change might be, for example, included in another.\n\t\t// In that case, the change will have `howMany` property set to `0` or less. We need to remove those changes.\n\t\tfor ( let i = 0; i < changes.length; i++ ) {\n\t\t\tif ( changes[ i ].howMany < 1 ) {\n\t\t\t\tchanges.splice( i, 1 );\n\n\t\t\t\ti--;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets an array of changes that have already been saved for a given element.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} element\n\t * @returns {Array.<Object>}\n\t */\n\t_getChangesForElement( element ) {\n\t\tlet changes;\n\n\t\tif ( this._changesInElement.has( element ) ) {\n\t\t\tchanges = this._changesInElement.get( element );\n\t\t} else {\n\t\t\tchanges = [];\n\n\t\t\tthis._changesInElement.set( element, changes );\n\t\t}\n\n\t\treturn changes;\n\t}\n\n\t/**\n\t * Saves a children snapshot for a given element.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} element\n\t */\n\t_makeSnapshot( element ) {\n\t\tif ( !this._elementSnapshots.has( element ) ) {\n\t\t\tthis._elementSnapshots.set( element, _getChildrenSnapshot( element.getChildren() ) );\n\t\t}\n\t}\n\n\t/**\n\t * For a given newly saved change, compares it with a change already done on the element and modifies the incoming\n\t * change and/or the old change.\n\t *\n\t * @private\n\t * @param {Object} inc Incoming (new) change.\n\t * @param {Array.<Object>} changes An array containing all the changes done on that element.\n\t */\n\t_handleChange( inc, changes ) {\n\t\t// We need a helper variable that will store how many nodes are to be still handled for this change item.\n\t\t// `nodesToHandle` (how many nodes still need to be handled) and `howMany` (how many nodes were affected)\n\t\t// needs to be differentiated.\n\t\t//\n\t\t// This comes up when there are multiple changes that are affected by `inc` change item.\n\t\t//\n\t\t// For example: assume two insert changes: `{ offset: 2, howMany: 1 }` and `{ offset: 5, howMany: 1 }`.\n\t\t// Assume that `inc` change is remove `{ offset: 2, howMany: 2, nodesToHandle: 2 }`.\n\t\t//\n\t\t// Then, we:\n\t\t// - \"forget\" about first insert change (it is \"eaten\" by remove),\n\t\t// - because of that, at the end we will want to remove only one node (`nodesToHandle = 1`),\n\t\t// - but still we have to change offset of the second insert change from `5` to `3`!\n\t\t//\n\t\t// So, `howMany` does not change throughout items transformation and keeps information about how many nodes were affected,\n\t\t// while `nodesToHandle` means how many nodes need to be handled after the change item is transformed by other changes.\n\t\tinc.nodesToHandle = inc.howMany;\n\n\t\tfor ( const old of changes ) {\n\t\t\tconst incEnd = inc.offset + inc.howMany;\n\t\t\tconst oldEnd = old.offset + old.howMany;\n\n\t\t\tif ( inc.type == 'insert' ) {\n\t\t\t\tif ( old.type == 'insert' ) {\n\t\t\t\t\tif ( inc.offset <= old.offset ) {\n\t\t\t\t\t\told.offset += inc.howMany;\n\t\t\t\t\t} else if ( inc.offset < oldEnd ) {\n\t\t\t\t\t\told.howMany += inc.nodesToHandle;\n\t\t\t\t\t\tinc.nodesToHandle = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( old.type == 'remove' ) {\n\t\t\t\t\tif ( inc.offset < old.offset ) {\n\t\t\t\t\t\told.offset += inc.howMany;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( old.type == 'attribute' ) {\n\t\t\t\t\tif ( inc.offset <= old.offset ) {\n\t\t\t\t\t\told.offset += inc.howMany;\n\t\t\t\t\t} else if ( inc.offset < oldEnd ) {\n\t\t\t\t\t\t// This case is more complicated, because attribute change has to be split into two.\n\t\t\t\t\t\t// Example (assume that uppercase and lowercase letters mean different attributes):\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// initial state:\t\tabcxyz\n\t\t\t\t\t\t// attribute change:\taBCXYz\n\t\t\t\t\t\t// incoming insert:\t\taBCfooXYz\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// Change ranges cannot intersect because each item has to be described exactly (it was either\n\t\t\t\t\t\t// not changed, inserted, removed, or its attribute was changed). That's why old attribute\n\t\t\t\t\t\t// change has to be split and both parts has to be handled separately from now on.\n\t\t\t\t\t\tconst howMany = old.howMany;\n\n\t\t\t\t\t\told.howMany = inc.offset - old.offset;\n\n\t\t\t\t\t\t// Add the second part of attribute change to the beginning of processed array so it won't\n\t\t\t\t\t\t// be processed again in this loop.\n\t\t\t\t\t\tchanges.unshift( {\n\t\t\t\t\t\t\ttype: 'attribute',\n\t\t\t\t\t\t\toffset: incEnd,\n\t\t\t\t\t\t\thowMany: howMany - old.howMany,\n\t\t\t\t\t\t\tcount: this._changeCount++\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( inc.type == 'remove' ) {\n\t\t\t\tif ( old.type == 'insert' ) {\n\t\t\t\t\tif ( incEnd <= old.offset ) {\n\t\t\t\t\t\told.offset -= inc.howMany;\n\t\t\t\t\t} else if ( incEnd <= oldEnd ) {\n\t\t\t\t\t\tif ( inc.offset < old.offset ) {\n\t\t\t\t\t\t\tconst intersectionLength = incEnd - old.offset;\n\n\t\t\t\t\t\t\told.offset = inc.offset;\n\n\t\t\t\t\t\t\told.howMany -= intersectionLength;\n\t\t\t\t\t\t\tinc.nodesToHandle -= intersectionLength;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\told.howMany -= inc.nodesToHandle;\n\t\t\t\t\t\t\tinc.nodesToHandle = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( inc.offset <= old.offset ) {\n\t\t\t\t\t\t\tinc.nodesToHandle -= old.howMany;\n\t\t\t\t\t\t\told.howMany = 0;\n\t\t\t\t\t\t} else if ( inc.offset < oldEnd ) {\n\t\t\t\t\t\t\tconst intersectionLength = oldEnd - inc.offset;\n\n\t\t\t\t\t\t\told.howMany -= intersectionLength;\n\t\t\t\t\t\t\tinc.nodesToHandle -= intersectionLength;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( old.type == 'remove' ) {\n\t\t\t\t\tif ( incEnd <= old.offset ) {\n\t\t\t\t\t\told.offset -= inc.howMany;\n\t\t\t\t\t} else if ( inc.offset < old.offset ) {\n\t\t\t\t\t\tinc.nodesToHandle += old.howMany;\n\t\t\t\t\t\told.howMany = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( old.type == 'attribute' ) {\n\t\t\t\t\tif ( incEnd <= old.offset ) {\n\t\t\t\t\t\told.offset -= inc.howMany;\n\t\t\t\t\t} else if ( inc.offset < old.offset ) {\n\t\t\t\t\t\tconst intersectionLength = incEnd - old.offset;\n\n\t\t\t\t\t\told.offset = inc.offset;\n\t\t\t\t\t\told.howMany -= intersectionLength;\n\t\t\t\t\t} else if ( inc.offset < oldEnd ) {\n\t\t\t\t\t\tif ( incEnd <= oldEnd ) {\n\t\t\t\t\t\t\t// On first sight in this case we don't need to split attribute operation into two.\n\t\t\t\t\t\t\t// However the changes set is later converted to actions (see `_generateActionsFromChanges`).\n\t\t\t\t\t\t\t// For that reason, no two changes may intersect.\n\t\t\t\t\t\t\t// So we cannot have an attribute change that \"contains\" remove change.\n\t\t\t\t\t\t\t// Attribute change needs to be split.\n\t\t\t\t\t\t\tconst howMany = old.howMany;\n\n\t\t\t\t\t\t\told.howMany = inc.offset - old.offset;\n\n\t\t\t\t\t\t\tconst howManyAfter = howMany - old.howMany - inc.nodesToHandle;\n\n\t\t\t\t\t\t\t// Add the second part of attribute change to the beginning of processed array so it won't\n\t\t\t\t\t\t\t// be processed again in this loop.\n\t\t\t\t\t\t\tchanges.unshift( {\n\t\t\t\t\t\t\t\ttype: 'attribute',\n\t\t\t\t\t\t\t\toffset: inc.offset,\n\t\t\t\t\t\t\t\thowMany: howManyAfter,\n\t\t\t\t\t\t\t\tcount: this._changeCount++\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\told.howMany -= oldEnd - inc.offset;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( inc.type == 'attribute' ) {\n\t\t\t\t// In case of attribute change, `howMany` should be kept same as `nodesToHandle`. It's not an error.\n\t\t\t\tif ( old.type == 'insert' ) {\n\t\t\t\t\tif ( inc.offset < old.offset && incEnd > old.offset ) {\n\t\t\t\t\t\tif ( incEnd > oldEnd ) {\n\t\t\t\t\t\t\t// This case is similar to a case described when incoming change was insert and old change was attribute.\n\t\t\t\t\t\t\t// See comment above.\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t// This time incoming change is attribute. We need to split incoming change in this case too.\n\t\t\t\t\t\t\t// However this time, the second part of the attribute change needs to be processed further\n\t\t\t\t\t\t\t// because there might be other changes that it collides with.\n\t\t\t\t\t\t\tconst attributePart = {\n\t\t\t\t\t\t\t\ttype: 'attribute',\n\t\t\t\t\t\t\t\toffset: oldEnd,\n\t\t\t\t\t\t\t\thowMany: incEnd - oldEnd,\n\t\t\t\t\t\t\t\tcount: this._changeCount++\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\tthis._handleChange( attributePart, changes );\n\n\t\t\t\t\t\t\tchanges.push( attributePart );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tinc.nodesToHandle = old.offset - inc.offset;\n\t\t\t\t\t\tinc.howMany = inc.nodesToHandle;\n\t\t\t\t\t} else if ( inc.offset >= old.offset && inc.offset < oldEnd ) {\n\t\t\t\t\t\tif ( incEnd > oldEnd ) {\n\t\t\t\t\t\t\tinc.nodesToHandle = incEnd - oldEnd;\n\t\t\t\t\t\t\tinc.offset = oldEnd;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tinc.nodesToHandle = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( old.type == 'remove' ) {\n\t\t\t\t\t// This is a case when attribute change \"contains\" remove change.\n\t\t\t\t\t// The attribute change needs to be split into two because changes cannot intersect.\n\t\t\t\t\tif ( inc.offset < old.offset && incEnd > old.offset ) {\n\t\t\t\t\t\tconst attributePart = {\n\t\t\t\t\t\t\ttype: 'attribute',\n\t\t\t\t\t\t\toffset: old.offset,\n\t\t\t\t\t\t\thowMany: incEnd - old.offset,\n\t\t\t\t\t\t\tcount: this._changeCount++\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tthis._handleChange( attributePart, changes );\n\n\t\t\t\t\t\tchanges.push( attributePart );\n\n\t\t\t\t\t\tinc.nodesToHandle = old.offset - inc.offset;\n\t\t\t\t\t\tinc.howMany = inc.nodesToHandle;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( old.type == 'attribute' ) {\n\t\t\t\t\t// There are only two conflicting scenarios possible here:\n\t\t\t\t\tif ( inc.offset >= old.offset && incEnd <= oldEnd ) {\n\t\t\t\t\t\t// `old` change includes `inc` change, or they are the same.\n\t\t\t\t\t\tinc.nodesToHandle = 0;\n\t\t\t\t\t\tinc.howMany = 0;\n\t\t\t\t\t\tinc.offset = 0;\n\t\t\t\t\t} else if ( inc.offset <= old.offset && incEnd >= oldEnd ) {\n\t\t\t\t\t\t// `inc` change includes `old` change.\n\t\t\t\t\t\told.howMany = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tinc.howMany = inc.nodesToHandle;\n\t\tdelete inc.nodesToHandle;\n\t}\n\n\t/**\n\t * Returns an object with a single insert change description.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} parent The element in which the change happened.\n\t * @param {Number} offset The offset at which change happened.\n\t * @param {String} name The name of the removed element or `'$text'` for a character.\n\t * @returns {Object} The diff item.\n\t */\n\t_getInsertDiff( parent, offset, name ) {\n\t\treturn {\n\t\t\ttype: 'insert',\n\t\t\tposition: Position._createAt( parent, offset ),\n\t\t\tname,\n\t\t\tlength: 1,\n\t\t\tchangeCount: this._changeCount++\n\t\t};\n\t}\n\n\t/**\n\t * Returns an object with a single remove change description.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} parent The element in which change happened.\n\t * @param {Number} offset The offset at which change happened.\n\t * @param {String} name The name of the removed element or `'$text'` for a character.\n\t * @returns {Object} The diff item.\n\t */\n\t_getRemoveDiff( parent, offset, name ) {\n\t\treturn {\n\t\t\ttype: 'remove',\n\t\t\tposition: Position._createAt( parent, offset ),\n\t\t\tname,\n\t\t\tlength: 1,\n\t\t\tchangeCount: this._changeCount++\n\t\t};\n\t}\n\n\t/**\n\t * Returns an array of objects where each one is a single attribute change description.\n\t *\n\t * @private\n\t * @param {module:engine/model/range~Range} range The range where the change happened.\n\t * @param {Map} oldAttributes A map, map iterator or compatible object that contains attributes before the change.\n\t * @param {Map} newAttributes A map, map iterator or compatible object that contains attributes after the change.\n\t * @returns {Array.<Object>} An array containing one or more diff items.\n\t */\n\t_getAttributesDiff( range, oldAttributes, newAttributes ) {\n\t\t// Results holder.\n\t\tconst diffs = [];\n\n\t\t// Clone new attributes as we will be performing changes on this object.\n\t\tnewAttributes = new Map( newAttributes );\n\n\t\t// Look through old attributes.\n\t\tfor ( const [ key, oldValue ] of oldAttributes ) {\n\t\t\t// Check what is the new value of the attribute (or if it was removed).\n\t\t\tconst newValue = newAttributes.has( key ) ? newAttributes.get( key ) : null;\n\n\t\t\t// If values are different (or attribute was removed)...\n\t\t\tif ( newValue !== oldValue ) {\n\t\t\t\t// Add diff item.\n\t\t\t\tdiffs.push( {\n\t\t\t\t\ttype: 'attribute',\n\t\t\t\t\tposition: range.start,\n\t\t\t\t\trange: range.clone(),\n\t\t\t\t\tlength: 1,\n\t\t\t\t\tattributeKey: key,\n\t\t\t\t\tattributeOldValue: oldValue,\n\t\t\t\t\tattributeNewValue: newValue,\n\t\t\t\t\tchangeCount: this._changeCount++\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// Prevent returning two diff items for the same change.\n\t\t\tnewAttributes.delete( key );\n\t\t}\n\n\t\t// Look through new attributes that weren't handled above.\n\t\tfor ( const [ key, newValue ] of newAttributes ) {\n\t\t\t// Each of them is a new attribute. Add diff item.\n\t\t\tdiffs.push( {\n\t\t\t\ttype: 'attribute',\n\t\t\t\tposition: range.start,\n\t\t\t\trange: range.clone(),\n\t\t\t\tlength: 1,\n\t\t\t\tattributeKey: key,\n\t\t\t\tattributeOldValue: null,\n\t\t\t\tattributeNewValue: newValue,\n\t\t\t\tchangeCount: this._changeCount++\n\t\t\t} );\n\t\t}\n\n\t\treturn diffs;\n\t}\n\n\t/**\n\t * Checks whether given element or any of its parents is an element that is buffered as an inserted element.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} element Element to check.\n\t * @returns {Boolean}\n\t */\n\t_isInInsertedElement( element ) {\n\t\tconst parent = element.parent;\n\n\t\tif ( !parent ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst changes = this._changesInElement.get( parent );\n\t\tconst offset = element.startOffset;\n\n\t\tif ( changes ) {\n\t\t\tfor ( const change of changes ) {\n\t\t\t\tif ( change.type == 'insert' && offset >= change.offset && offset < change.offset + change.howMany ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this._isInInsertedElement( parent );\n\t}\n\n\t/**\n\t * Removes deeply all buffered changes that are registered in elements from range specified by `parent`, `offset`\n\t * and `howMany`.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} parent\n\t * @param {Number} offset\n\t * @param {Number} howMany\n\t */\n\t_removeAllNestedChanges( parent, offset, howMany ) {\n\t\tconst range = new Range( Position._createAt( parent, offset ), Position._createAt( parent, offset + howMany ) );\n\n\t\tfor ( const item of range.getItems( { shallow: true } ) ) {\n\t\t\tif ( item.is( 'element' ) ) {\n\t\t\t\tthis._elementSnapshots.delete( item );\n\t\t\t\tthis._changesInElement.delete( item );\n\n\t\t\t\tthis._removeAllNestedChanges( item, 0, item.maxOffset );\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Returns an array that is a copy of passed child list with the exception that text nodes are split to one or more\n// objects, each representing one character and attributes set on that character.\nfunction _getChildrenSnapshot( children ) {\n\tconst snapshot = [];\n\n\tfor ( const child of children ) {\n\t\tif ( child.is( 'text' ) ) {\n\t\t\tfor ( let i = 0; i < child.data.length; i++ ) {\n\t\t\t\tsnapshot.push( {\n\t\t\t\t\tname: '$text',\n\t\t\t\t\tattributes: new Map( child.getAttributes() )\n\t\t\t\t} );\n\t\t\t}\n\t\t} else {\n\t\t\tsnapshot.push( {\n\t\t\t\tname: child.name,\n\t\t\t\tattributes: new Map( child.getAttributes() )\n\t\t\t} );\n\t\t}\n\t}\n\n\treturn snapshot;\n}\n\n// Generates array of actions for given changes set.\n// It simulates what `diff` function does.\n// Generated actions are:\n// - 'e' for 'equal' - when item at that position did not change,\n// - 'i' for 'insert' - when item at that position was inserted,\n// - 'r' for 'remove' - when item at that position was removed,\n// - 'a' for 'attribute' - when item at that position has it attributes changed.\n//\n// Example (assume that uppercase letters have bold attribute, compare with function code):\n//\n// children before:\tfooBAR\n// children after:\tfoxybAR\n//\n// changes: type: remove, offset: 1, howMany: 1\n//\t\t\ttype: insert, offset: 2, howMany: 2\n//\t\t\ttype: attribute, offset: 4, howMany: 1\n//\n// expected actions: equal (f), remove (o), equal (o), insert (x), insert (y), attribute (b), equal (A), equal (R)\n//\n// steps taken by th script:\n//\n// 1. change = \"type: remove, offset: 1, howMany: 1\"; offset = 0; oldChildrenHandled = 0\n// 1.1 between this change and the beginning is one not-changed node, fill with one equal action, one old child has been handled\n// 1.2 this change removes one node, add one remove action\n// 1.3 change last visited `offset` to 1\n// 1.4 since an old child has been removed, one more old child has been handled\n// 1.5 actions at this point are: equal, remove\n//\n// 2. change = \"type: insert, offset: 2, howMany: 2\"; offset = 1; oldChildrenHandled = 2\n// 2.1 between this change and previous change is one not-changed node, add equal action, another one old children has been handled\n// 2.2 this change inserts two nodes, add two insert actions\n// 2.3 change last visited offset to the end of the inserted range, that is 4\n// 2.4 actions at this point are: equal, remove, equal, insert, insert\n//\n// 3. change = \"type: attribute, offset: 4, howMany: 1\"; offset = 4, oldChildrenHandled = 3\n// 3.1 between this change and previous change are no not-changed nodes\n// 3.2 this change changes one node, add one attribute action\n// 3.3 change last visited `offset` to the end of change range, that is 5\n// 3.4 since an old child has been changed, one more old child has been handled\n// 3.5 actions at this point are: equal, remove, equal, insert, insert, attribute\n//\n// 4. after loop oldChildrenHandled = 4, oldChildrenLength = 6 (fooBAR is 6 characters)\n// 4.1 fill up with two equal actions\n//\n// The result actions are: equal, remove, equal, insert, insert, attribute, equal, equal.\nfunction _generateActionsFromChanges( oldChildrenLength, changes ) {\n\tconst actions = [];\n\n\tlet offset = 0;\n\tlet oldChildrenHandled = 0;\n\n\t// Go through all buffered changes.\n\tfor ( const change of changes ) {\n\t\t// First, fill \"holes\" between changes with \"equal\" actions.\n\t\tif ( change.offset > offset ) {\n\t\t\tactions.push( ...'e'.repeat( change.offset - offset ).split( '' ) );\n\n\t\t\toldChildrenHandled += change.offset - offset;\n\t\t}\n\n\t\t// Then, fill up actions accordingly to change type.\n\t\tif ( change.type == 'insert' ) {\n\t\t\tactions.push( ...'i'.repeat( change.howMany ).split( '' ) );\n\n\t\t\t// The last handled offset is after inserted range.\n\t\t\toffset = change.offset + change.howMany;\n\t\t} else if ( change.type == 'remove' ) {\n\t\t\tactions.push( ...'r'.repeat( change.howMany ).split( '' ) );\n\n\t\t\t// The last handled offset is at the position where the nodes were removed.\n\t\t\toffset = change.offset;\n\t\t\t// We removed `howMany` old nodes, update `oldChildrenHandled`.\n\t\t\toldChildrenHandled += change.howMany;\n\t\t} else {\n\t\t\tactions.push( ...'a'.repeat( change.howMany ).split( '' ) );\n\n\t\t\t// The last handled offset is at the position after the changed range.\n\t\t\toffset = change.offset + change.howMany;\n\t\t\t// We changed `howMany` old nodes, update `oldChildrenHandled`.\n\t\t\toldChildrenHandled += change.howMany;\n\t\t}\n\t}\n\n\t// Fill \"equal\" actions at the end of actions set. Use `oldChildrenHandled` to see how many children\n\t// has not been changed / removed at the end of their parent.\n\tif ( oldChildrenHandled < oldChildrenLength ) {\n\t\tactions.push( ...'e'.repeat( oldChildrenLength - oldChildrenHandled ).split( '' ) );\n\t}\n\n\treturn actions;\n}\n\n// Filter callback for Array.filter that filters out change entries that are in graveyard.\nfunction _changesInGraveyardFilter( entry ) {\n\tconst posInGy = entry.position && entry.position.root.rootName == '$graveyard';\n\tconst rangeInGy = entry.range && entry.range.root.rootName == '$graveyard';\n\n\treturn !posInGy && !rangeInGy;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/history\n */\n\n/**\n * `History` keeps the track of all the operations applied to the {@link module:engine/model/document~Document document}.\n */\nexport default class History {\n\t/**\n\t * Creates an empty History instance.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Operations added to the history.\n\t\t *\n\t\t * @protected\n\t\t * @member {Array.<module:engine/model/operation/operation~Operation>} module:engine/model/history~History#_operations\n\t\t */\n\t\tthis._operations = [];\n\n\t\t/**\n\t\t * Holds an information which {@link module:engine/model/operation/operation~Operation operation} undoes which\n\t\t * {@link module:engine/model/operation/operation~Operation operation}.\n\t\t *\n\t\t * Keys of the map are \"undoing operations\", that is operations that undone some other operations. For each key, the\n\t\t * value is an operation that has been undone by the \"undoing operation\".\n\t\t *\n\t\t * @private\n\t\t * @member {Map} module:engine/model/history~History#_undoPairs\n\t\t */\n\t\tthis._undoPairs = new Map();\n\n\t\t/**\n\t\t * Holds all undone operations.\n\t\t *\n\t\t * @private\n\t\t * @member {Set.<module:engine/model/operation/operation~Operation>} module:engine/model/history~History#_undoneOperations\n\t\t */\n\t\tthis._undoneOperations = new Set();\n\t}\n\n\t/**\n\t * Adds an operation to the history.\n\t *\n\t * @param {module:engine/model/operation/operation~Operation} operation Operation to add.\n\t */\n\taddOperation( operation ) {\n\t\tif ( this._operations.includes( operation ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._operations.push( operation );\n\t}\n\n\t/**\n\t * Returns operations added to the history.\n\t *\n\t * @param {Number} [from=0] Base version from which operations should be returned (inclusive). Defaults to `0`, which means\n\t * that operations from the first one will be returned.\n\t * @param {Number} [to=Number.POSITIVE_INFINITY] Base version up to which operations should be returned (exclusive).\n\t * Defaults to `Number.POSITIVE_INFINITY` which means that operations up to the last one will be returned.\n\t * @returns {Iterable.<module:engine/model/operation/operation~Operation>} Operations added to the history.\n\t */\n\tgetOperations( from = 0, to = Number.POSITIVE_INFINITY ) {\n\t\tif ( from < 0 ) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn this._operations.slice( from, to );\n\t}\n\n\t/**\n\t * Returns operation from the history that bases on given `baseVersion`.\n\t *\n\t * @param {Number} baseVersion Base version of the operation to get.\n\t * @returns {module:engine/model/operation/operation~Operation|null} Operation with given base version or `null` if\n\t * there is no such operation in history.\n\t */\n\tgetOperation( baseVersion ) {\n\t\treturn this._operations[ baseVersion ];\n\t}\n\n\t/**\n\t * Marks in history that one operation is an operation that is undoing the other operation. By marking operation this way,\n\t * history is keeping more context information about operations, which helps in operational transformation.\n\t *\n\t * @param {module:engine/model/operation/operation~Operation} undoneOperation Operation which is undone by `undoingOperation`.\n\t * @param {module:engine/model/operation/operation~Operation} undoingOperation Operation which undoes `undoneOperation`.\n\t */\n\tsetOperationAsUndone( undoneOperation, undoingOperation ) {\n\t\tthis._undoPairs.set( undoingOperation, undoneOperation );\n\t\tthis._undoneOperations.add( undoneOperation );\n\t}\n\n\t/**\n\t * Checks whether given `operation` is undoing any other operation.\n\t *\n\t * @param {module:engine/model/operation/operation~Operation} operation Operation to check.\n\t * @returns {Boolean} `true` if given `operation` is undoing any other operation, `false` otherwise.\n\t */\n\tisUndoingOperation( operation ) {\n\t\treturn this._undoPairs.has( operation );\n\t}\n\n\t/**\n\t * Checks whether given `operation` has been undone by any other operation.\n\t *\n\t * @param {module:engine/model/operation/operation~Operation} operation Operation to check.\n\t * @returns {Boolean} `true` if given `operation` has been undone any other operation, `false` otherwise.\n\t */\n\tisUndoneOperation( operation ) {\n\t\treturn this._undoneOperations.has( operation );\n\t}\n\n\t/**\n\t * For given `undoingOperation`, returns the operation which has been undone by it.\n\t *\n\t * @param {module:engine/model/operation/operation~Operation} undoingOperation\n\t * @returns {module:engine/model/operation/operation~Operation|undefined} Operation that has been undone by given\n\t * `undoingOperation` or `undefined` if given `undoingOperation` is not undoing any other operation.\n\t */\n\tgetUndoneOperation( undoingOperation ) {\n\t\treturn this._undoPairs.get( undoingOperation );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * Set of utils to handle unicode characters.\n *\n * @module utils/unicode\n */\n\n/**\n * Checks whether given `character` is a combining mark.\n *\n * @param {String} character Character to check.\n * @returns {Boolean}\n */\nexport function isCombiningMark( character ) {\n\treturn !!character && character.length == 1 && /[\\u0300-\\u036f\\u1ab0-\\u1aff\\u1dc0-\\u1dff\\u20d0-\\u20ff\\ufe20-\\ufe2f]/.test( character );\n}\n\n/**\n * Checks whether given `character` is a high half of surrogate pair.\n *\n * Using UTF-16 terminology, a surrogate pair denotes UTF-16 character using two UTF-8 characters. The surrogate pair\n * consist of high surrogate pair character followed by low surrogate pair character.\n *\n * @param {String} character Character to check.\n * @returns {Boolean}\n */\nexport function isHighSurrogateHalf( character ) {\n\treturn !!character && character.length == 1 && /[\\ud800-\\udbff]/.test( character );\n}\n\n/**\n * Checks whether given `character` is a low half of surrogate pair.\n *\n * Using UTF-16 terminology, a surrogate pair denotes UTF-16 character using two UTF-8 characters. The surrogate pair\n * consist of high surrogate pair character followed by low surrogate pair character.\n *\n * @param {String} character Character to check.\n * @returns {Boolean}\n */\nexport function isLowSurrogateHalf( character ) {\n\treturn !!character && character.length == 1 && /[\\udc00-\\udfff]/.test( character );\n}\n\n/**\n * Checks whether given offset in a string is inside a surrogate pair (between two surrogate halves).\n *\n * @param {String} string String to check.\n * @param {Number} offset Offset to check.\n * @returns {Boolean}\n */\nexport function isInsideSurrogatePair( string, offset ) {\n\treturn isHighSurrogateHalf( string.charAt( offset - 1 ) ) && isLowSurrogateHalf( string.charAt( offset ) );\n}\n\n/**\n * Checks whether given offset in a string is between base character and combining mark or between two combining marks.\n *\n * @param {String} string String to check.\n * @param {Number} offset Offset to check.\n * @returns {Boolean}\n */\nexport function isInsideCombinedSymbol( string, offset ) {\n\treturn isCombiningMark( string.charAt( offset ) );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/document\n */\n\nimport Differ from './differ';\nimport RootElement from './rootelement';\nimport History from './history';\nimport DocumentSelection from './documentselection';\nimport Collection from '@ckeditor/ckeditor5-utils/src/collection';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport { isInsideSurrogatePair, isInsideCombinedSymbol } from '@ckeditor/ckeditor5-utils/src/unicode';\nimport { clone } from 'lodash-es';\n\nconst graveyardName = '$graveyard';\n\n/**\n * Data model's document. It contains the model's structure, its selection and the history of changes.\n *\n * Read more about working with the model in\n * {@glink framework/guides/architecture/editing-engine#model introduction to the the editing engine's architecture}.\n *\n * Usually, the document contains just one {@link module:engine/model/document~Document#roots root element}, so\n * you can retrieve it by just calling {@link module:engine/model/document~Document#getRoot} without specifying its name:\n *\n *\t\tmodel.document.getRoot(); // -> returns the main root\n *\n * However, the document may contain multiple roots – e.g. when the editor has multiple editable areas\n * (e.g. a title and a body of a message).\n *\n * @mixes module:utils/emittermixin~EmitterMixin\n */\nexport default class Document {\n\t/**\n\t * Creates an empty document instance with no {@link #roots} (other than\n\t * the {@link #graveyard graveyard root}).\n\t */\n\tconstructor( model ) {\n\t\t/**\n\t\t * The {@link module:engine/model/model~Model model} that the document is a part of.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:engine/model/model~Model}\n\t\t */\n\t\tthis.model = model;\n\n\t\t/**\n\t\t * The document version. It starts from `0` and every operation increases the version number. It is used to ensure that\n\t\t * operations are applied on a proper document version.\n\t\t *\n\t\t * If the {@link module:engine/model/operation/operation~Operation#baseVersion base version} does not match the document version,\n\t\t * a {@link module:utils/ckeditorerror~CKEditorError model-document-applyOperation-wrong-version} error is thrown.\n\t\t *\n\t\t * @readonly\n\t\t * @type {Number}\n\t\t */\n\t\tthis.version = 0;\n\n\t\t/**\n\t\t * The document's history.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:engine/model/history~History}\n\t\t */\n\t\tthis.history = new History( this );\n\n\t\t/**\n\t\t * The selection in this document.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:engine/model/documentselection~DocumentSelection}\n\t\t */\n\t\tthis.selection = new DocumentSelection( this );\n\n\t\t/**\n\t\t * A list of roots that are owned and managed by this document. Use {@link #createRoot} and\n\t\t * {@link #getRoot} to manipulate it.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:utils/collection~Collection}\n\t\t */\n\t\tthis.roots = new Collection( { idProperty: 'rootName' } );\n\n\t\t/**\n\t\t * The model differ object. Its role is to buffer changes done on the model document and then calculate a diff of those changes.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:engine/model/differ~Differ}\n\t\t */\n\t\tthis.differ = new Differ( model.markers );\n\n\t\t/**\n\t\t * Post-fixer callbacks registered to the model document.\n\t\t *\n\t\t * @private\n\t\t * @type {Set.<Function>}\n\t\t */\n\t\tthis._postFixers = new Set();\n\n\t\t/**\n\t\t * A boolean indicates whether the selection has changed until\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._hasSelectionChangedFromTheLastChangeBlock = false;\n\n\t\t// Graveyard tree root. Document always have a graveyard root, which stores removed nodes.\n\t\tthis.createRoot( '$root', graveyardName );\n\n\t\t// First, if the operation is a document operation check if it's base version is correct.\n\t\tthis.listenTo( model, 'applyOperation', ( evt, args ) => {\n\t\t\tconst operation = args[ 0 ];\n\n\t\t\tif ( operation.isDocumentOperation && operation.baseVersion !== this.version ) {\n\t\t\t\t/**\n\t\t\t\t * Only operations with matching versions can be applied.\n\t\t\t\t *\n\t\t\t\t * @error document-applyOperation-wrong-version\n\t\t\t\t * @param {module:engine/model/operation/operation~Operation} operation\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'model-document-applyOperation-wrong-version: Only operations with matching versions can be applied.',\n\t\t\t\t\t{ operation }\n\t\t\t\t);\n\t\t\t}\n\t\t}, { priority: 'highest' } );\n\n\t\t// Then, still before an operation is applied on model, buffer the change in differ.\n\t\tthis.listenTo( model, 'applyOperation', ( evt, args ) => {\n\t\t\tconst operation = args[ 0 ];\n\n\t\t\tif ( operation.isDocumentOperation ) {\n\t\t\t\tthis.differ.bufferOperation( operation );\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// After the operation is applied, bump document's version and add the operation to the history.\n\t\tthis.listenTo( model, 'applyOperation', ( evt, args ) => {\n\t\t\tconst operation = args[ 0 ];\n\n\t\t\tif ( operation.isDocumentOperation ) {\n\t\t\t\tthis.version++;\n\t\t\t\tthis.history.addOperation( operation );\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\n\t\t// Listen to selection changes. If selection changed, mark it.\n\t\tthis.listenTo( this.selection, 'change', () => {\n\t\t\tthis._hasSelectionChangedFromTheLastChangeBlock = true;\n\t\t} );\n\n\t\t// Buffer marker changes.\n\t\t// This is not covered in buffering operations because markers may change outside of them (when they\n\t\t// are modified using `model.markers` collection, not through `MarkerOperation`).\n\t\tthis.listenTo( model.markers, 'update', ( evt, marker, oldRange, newRange ) => {\n\t\t\t// Whenever marker is updated, buffer that change.\n\t\t\tthis.differ.bufferMarkerChange( marker.name, oldRange, newRange, marker.affectsData );\n\n\t\t\tif ( oldRange === null ) {\n\t\t\t\t// If this is a new marker, add a listener that will buffer change whenever marker changes.\n\t\t\t\tmarker.on( 'change', ( evt, oldRange ) => {\n\t\t\t\t\tthis.differ.bufferMarkerChange( marker.name, oldRange, marker.getRange(), marker.affectsData );\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * The graveyard tree root. A document always has a graveyard root that stores removed nodes.\n\t *\n\t * @readonly\n\t * @member {module:engine/model/rootelement~RootElement}\n\t */\n\tget graveyard() {\n\t\treturn this.getRoot( graveyardName );\n\t}\n\n\t/**\n\t * Creates a new root.\n\t *\n\t * @param {String} [elementName='$root'] The element name. Defaults to `'$root'` which also has some basic schema defined\n\t * (`$block`s are allowed inside the `$root`). Make sure to define a proper schema if you use a different name.\n\t * @param {String} [rootName='main'] A unique root name.\n\t * @returns {module:engine/model/rootelement~RootElement} The created root.\n\t */\n\tcreateRoot( elementName = '$root', rootName = 'main' ) {\n\t\tif ( this.roots.get( rootName ) ) {\n\t\t\t/**\n\t\t\t * A root with the specified name already exists.\n\t\t\t *\n\t\t\t * @error model-document-createRoot-name-exists\n\t\t\t * @param {module:engine/model/document~Document} doc\n\t\t\t * @param {String} name\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'model-document-createRoot-name-exists: Root with specified name already exists.',\n\t\t\t\t{ name: rootName }\n\t\t\t);\n\t\t}\n\n\t\tconst root = new RootElement( this, elementName, rootName );\n\t\tthis.roots.add( root );\n\n\t\treturn root;\n\t}\n\n\t/**\n\t * Removes all event listeners set by the document instance.\n\t */\n\tdestroy() {\n\t\tthis.selection.destroy();\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Returns a root by its name.\n\t *\n\t * @param {String} [name='main'] A unique root name.\n\t * @returns {module:engine/model/rootelement~RootElement|null} The root registered under a given name or `null` when\n\t * there is no root with the given name.\n\t */\n\tgetRoot( name = 'main' ) {\n\t\treturn this.roots.get( name );\n\t}\n\n\t/**\n\t * Returns an array with names of all roots (without the {@link #graveyard}) added to the document.\n\t *\n\t * @returns {Array.<String>} Roots names.\n\t */\n\tgetRootNames() {\n\t\treturn Array.from( this.roots, root => root.rootName ).filter( name => name != graveyardName );\n\t}\n\n\t/**\n\t * Used to register a post-fixer callback. A post-fixer mechanism guarantees that the features\n\t * will operate on a correct model state.\n\t *\n\t * An execution of a feature may lead to an incorrect document tree state. The callbacks are used to fix the document tree after\n\t * it has changed. Post-fixers are fired just after all changes from the outermost change block were applied but\n\t * before the {@link module:engine/model/document~Document#event:change change event} is fired. If a post-fixer callback made\n\t * a change, it should return `true`. When this happens, all post-fixers are fired again to check if something else should\n\t * not be fixed in the new document tree state.\n\t *\n\t * As a parameter, a post-fixer callback receives a {@link module:engine/model/writer~Writer writer} instance connected with the\n\t * executed changes block. Thanks to that, all changes done by the callback will be added to the same\n\t * {@link module:engine/model/batch~Batch batch} (and undo step) as the original changes. This makes post-fixer changes transparent\n\t * for the user.\n\t *\n\t * An example of a post-fixer is a callback that checks if all the data were removed from the editor. If so, the\n\t * callback should add an empty paragraph so that the editor is never empty:\n\t *\n\t *\t\tdocument.registerPostFixer( writer => {\n\t *\t\t\tconst changes = document.differ.getChanges();\n\t *\n\t *\t\t\t// Check if the changes lead to an empty root in the editor.\n\t *\t\t\tfor ( const entry of changes ) {\n\t *\t\t\t\tif ( entry.type == 'remove' && entry.position.root.isEmpty ) {\n\t *\t\t\t\t\twriter.insertElement( 'paragraph', entry.position.root, 0 );\n\t *\n\t *\t\t\t\t\t// It is fine to return early, even if multiple roots would need to be fixed.\n\t *\t\t\t\t\t// All post-fixers will be fired again, so if there are more empty roots, those will be fixed, too.\n\t *\t\t\t\t\treturn true;\n\t *\t\t\t\t}\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * @param {Function} postFixer\n\t */\n\tregisterPostFixer( postFixer ) {\n\t\tthis._postFixers.add( postFixer );\n\t}\n\n\t/**\n\t * A custom `toJSON()` method to solve child-parent circular dependencies.\n\t *\n\t * @returns {Object} A clone of this object with the document property changed to a string.\n\t */\n\ttoJSON() {\n\t\tconst json = clone( this );\n\n\t\t// Due to circular references we need to remove parent reference.\n\t\tjson.selection = '[engine.model.DocumentSelection]';\n\t\tjson.model = '[engine.model.Model]';\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Check if there were any changes done on document, and if so, call post-fixers,\n\t * fire `change` event for features and conversion and then reset the differ.\n\t * Fire `change:data` event when at least one operation or buffered marker changes the data.\n\t *\n\t * @protected\n\t * @fires change\n\t * @fires change:data\n\t * @param {module:engine/model/writer~Writer} writer The writer on which post-fixers will be called.\n\t */\n\t_handleChangeBlock( writer ) {\n\t\tif ( this._hasDocumentChangedFromTheLastChangeBlock() ) {\n\t\t\tthis._callPostFixers( writer );\n\n\t\t\tif ( this.differ.hasDataChanges() ) {\n\t\t\t\tthis.fire( 'change:data', writer.batch );\n\t\t\t} else {\n\t\t\t\tthis.fire( 'change', writer.batch );\n\t\t\t}\n\n\t\t\tthis.differ.reset();\n\t\t}\n\n\t\tthis._hasSelectionChangedFromTheLastChangeBlock = false;\n\t}\n\n\t/**\n\t * Returns whether there is a buffered change or if the selection has changed from the last\n\t * {@link module:engine/model/model~Model#enqueueChange `enqueueChange()` block}\n\t * or {@link module:engine/model/model~Model#change `change()` block}.\n\t *\n\t * @protected\n\t * @returns {Boolean} Returns `true` if document has changed from the last `change()` or `enqueueChange()` block.\n\t */\n\t_hasDocumentChangedFromTheLastChangeBlock() {\n\t\treturn !this.differ.isEmpty || this._hasSelectionChangedFromTheLastChangeBlock;\n\t}\n\n\t/**\n\t * Returns the default root for this document which is either the first root that was added to the document using\n\t * {@link #createRoot} or the {@link #graveyard graveyard root} if no other roots were created.\n\t *\n\t * @protected\n\t * @returns {module:engine/model/rootelement~RootElement} The default root for this document.\n\t */\n\t_getDefaultRoot() {\n\t\tfor ( const root of this.roots ) {\n\t\t\tif ( root !== this.graveyard ) {\n\t\t\t\treturn root;\n\t\t\t}\n\t\t}\n\n\t\treturn this.graveyard;\n\t}\n\n\t/**\n\t * Returns the default range for this selection. The default range is a collapsed range that starts and ends\n\t * at the beginning of this selection's document {@link #_getDefaultRoot default root}.\n\t *\n\t * @protected\n\t * @returns {module:engine/model/range~Range}\n\t */\n\t_getDefaultRange() {\n\t\tconst defaultRoot = this._getDefaultRoot();\n\t\tconst model = this.model;\n\t\tconst schema = model.schema;\n\n\t\t// Find the first position where the selection can be put.\n\t\tconst position = model.createPositionFromPath( defaultRoot, [ 0 ] );\n\t\tconst nearestRange = schema.getNearestSelectionRange( position );\n\n\t\t// If valid selection range is not found - return range collapsed at the beginning of the root.\n\t\treturn nearestRange || model.createRange( position );\n\t}\n\n\t/**\n\t * Checks whether a given {@link module:engine/model/range~Range range} is a valid range for\n\t * the {@link #selection document's selection}.\n\t *\n\t * @private\n\t * @param {module:engine/model/range~Range} range A range to check.\n\t * @returns {Boolean} `true` if `range` is valid, `false` otherwise.\n\t */\n\t_validateSelectionRange( range ) {\n\t\treturn validateTextNodePosition( range.start ) && validateTextNodePosition( range.end );\n\t}\n\n\t/**\n\t * Performs post-fixer loops. Executes post-fixer callbacks as long as none of them has done any changes to the model.\n\t *\n\t * @private\n\t * @param {module:engine/model/writer~Writer} writer The writer on which post-fixer callbacks will be called.\n\t */\n\t_callPostFixers( writer ) {\n\t\tlet wasFixed = false;\n\n\t\tdo {\n\t\t\tfor ( const callback of this._postFixers ) {\n\t\t\t\twasFixed = callback( writer );\n\n\t\t\t\tif ( wasFixed ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} while ( wasFixed );\n\t}\n\n\t/**\n\t * Fired after each {@link module:engine/model/model~Model#enqueueChange `enqueueChange()` block} or the outermost\n\t * {@link module:engine/model/model~Model#change `change()` block} was executed and the document was changed\n\t * during that block's execution.\n\t *\n\t * The changes which this event will cover include:\n\t *\n\t * * document structure changes,\n\t * * selection changes,\n\t * * marker changes.\n\t *\n\t * If you want to be notified about all these changes, then simply listen to this event like this:\n\t *\n\t *\t\tmodel.document.on( 'change', () => {\n\t *\t\t\tconsole.log( 'The document has changed!' );\n\t *\t\t} );\n\t *\n\t * If, however, you only want to be notified about the data changes, then use the\n\t * {@link module:engine/model/document~Document#event:change:data change:data} event,\n\t * which is fired for document structure changes and marker changes (which affects the data).\n\t *\n\t *\t\tmodel.document.on( 'change:data', () => {\n\t *\t\t\tconsole.log( 'The data has changed!' );\n\t *\t\t} );\n\t *\n\t * @event change\n\t * @param {module:engine/model/batch~Batch} batch The batch that was used in the executed changes block.\n\t */\n\n\t/**\n\t * It is a narrower version of the {@link #event:change} event. It is fired for changes which\n\t * affect the editor data. This is:\n\t *\n\t * * document structure changes,\n\t * * marker changes (which affects the data).\n\t *\n\t * If you want to be notified about the data changes, then listen to this event:\n\t *\n\t *\t\tmodel.document.on( 'change:data', () => {\n\t *\t\t\tconsole.log( 'The data has changed!' );\n\t *\t\t} );\n\t *\n\t * If you would like to listen to all document changes, then check out the\n\t * {@link module:engine/model/document~Document#event:change change} event.\n\t *\n\t * @event change:data\n\t * @param {module:engine/model/batch~Batch} batch The batch that was used in the executed changes block.\n\t */\n}\n\nmix( Document, EmitterMixin );\n\n// Checks whether given range boundary position is valid for document selection, meaning that is not between\n// unicode surrogate pairs or base character and combining marks.\nfunction validateTextNodePosition( rangeBoundary ) {\n\tconst textNode = rangeBoundary.textNode;\n\n\tif ( textNode ) {\n\t\tconst data = textNode.data;\n\t\tconst offset = rangeBoundary.offset - textNode.startOffset;\n\n\t\treturn !isInsideSurrogatePair( data, offset ) && !isInsideCombinedSymbol( data, offset );\n\t}\n\n\treturn true;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/markercollection\n */\n\nimport LiveRange from './liverange';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The collection of all {@link module:engine/model/markercollection~Marker markers} attached to the document.\n * It lets you {@link module:engine/model/markercollection~MarkerCollection#get get} markers or track them using\n * {@link module:engine/model/markercollection~MarkerCollection#event:update} event.\n *\n * To create, change or remove makers use {@link module:engine/model/writer~Writer model writers'} methods:\n * {@link module:engine/model/writer~Writer#addMarker} or {@link module:engine/model/writer~Writer#removeMarker}. Since\n * the writer is the only proper way to change the data model it is not possible to change markers directly using this\n * collection. All markers created by the writer will be automatically added to this collection.\n *\n * By default there is one marker collection available as {@link module:engine/model/model~Model#markers model property}.\n *\n * @see module:engine/model/markercollection~Marker\n */\nexport default class MarkerCollection {\n\t/**\n\t * Creates a markers collection.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Stores {@link ~Marker markers} added to the collection.\n\t\t *\n\t\t * @private\n\t\t * @member {Map} #_markers\n\t\t */\n\t\tthis._markers = new Map();\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * Iterates over all {@link ~Marker markers} added to the collection.\n\t *\n\t * @returns {Iterable}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this._markers.values();\n\t}\n\n\t/**\n\t * Checks if marker with given `markerName` is in the collection.\n\t *\n\t * @param {String} markerName Marker name.\n\t * @returns {Boolean} `true` if marker with given `markerName` is in the collection, `false` otherwise.\n\t */\n\thas( markerName ) {\n\t\treturn this._markers.has( markerName );\n\t}\n\n\t/**\n\t * Returns {@link ~Marker marker} with given `markerName`.\n\t *\n\t * @param {String} markerName Name of marker to get.\n\t * @returns {module:engine/model/markercollection~Marker|null} Marker with given name or `null` if such marker was\n\t * not added to the collection.\n\t */\n\tget( markerName ) {\n\t\treturn this._markers.get( markerName ) || null;\n\t}\n\n\t/**\n\t * Creates and adds a {@link ~Marker marker} to the `MarkerCollection` with given name on given\n\t * {@link module:engine/model/range~Range range}.\n\t *\n\t * If `MarkerCollection` already had a marker with given name (or {@link ~Marker marker} was passed), the marker in\n\t * collection is updated and {@link module:engine/model/markercollection~MarkerCollection#event:update} event is fired\n\t * but only if there was a change (marker range or {@link module:engine/model/markercollection~Marker#managedUsingOperations}\n\t * flag has changed.\n\t *\n\t * @protected\n\t * @fires module:engine/model/markercollection~MarkerCollection#event:update\n\t * @param {String|module:engine/model/markercollection~Marker} markerOrName Name of marker to set or marker instance to update.\n\t * @param {module:engine/model/range~Range} range Marker range.\n\t * @param {Boolean} [managedUsingOperations=false] Specifies whether the marker is managed using operations.\n\t * @param {Boolean} [affectsData=false] Specifies whether the marker affects the data produced by the data pipeline\n\t * (is persisted in the editor's data).\n\t * @returns {module:engine/model/markercollection~Marker} `Marker` instance which was added or updated.\n\t */\n\t_set( markerOrName, range, managedUsingOperations = false, affectsData = false ) {\n\t\tconst markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;\n\t\tconst oldMarker = this._markers.get( markerName );\n\n\t\tif ( oldMarker ) {\n\t\t\tconst oldRange = oldMarker.getRange();\n\t\t\tlet hasChanged = false;\n\n\t\t\tif ( !oldRange.isEqual( range ) ) {\n\t\t\t\toldMarker._attachLiveRange( LiveRange.fromRange( range ) );\n\t\t\t\thasChanged = true;\n\t\t\t}\n\n\t\t\tif ( managedUsingOperations != oldMarker.managedUsingOperations ) {\n\t\t\t\toldMarker._managedUsingOperations = managedUsingOperations;\n\t\t\t\thasChanged = true;\n\t\t\t}\n\n\t\t\tif ( typeof affectsData === 'boolean' && affectsData != oldMarker.affectsData ) {\n\t\t\t\toldMarker._affectsData = affectsData;\n\t\t\t\thasChanged = true;\n\t\t\t}\n\n\t\t\tif ( hasChanged ) {\n\t\t\t\tthis.fire( 'update:' + markerName, oldMarker, oldRange, range );\n\t\t\t}\n\n\t\t\treturn oldMarker;\n\t\t}\n\n\t\tconst liveRange = LiveRange.fromRange( range );\n\t\tconst marker = new Marker( markerName, liveRange, managedUsingOperations, affectsData );\n\n\t\tthis._markers.set( markerName, marker );\n\t\tthis.fire( 'update:' + markerName, marker, null, range );\n\n\t\treturn marker;\n\t}\n\n\t/**\n\t * Removes given {@link ~Marker marker} or a marker with given name from the `MarkerCollection`.\n\t *\n\t * @protected\n\t * @fires module:engine/model/markercollection~MarkerCollection#event:update\n\t * @param {String} markerOrName Marker or name of a marker to remove.\n\t * @returns {Boolean} `true` if marker was found and removed, `false` otherwise.\n\t */\n\t_remove( markerOrName ) {\n\t\tconst markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;\n\t\tconst oldMarker = this._markers.get( markerName );\n\n\t\tif ( oldMarker ) {\n\t\t\tthis._markers.delete( markerName );\n\t\t\tthis.fire( 'update:' + markerName, oldMarker, oldMarker.getRange(), null );\n\n\t\t\tthis._destroyMarker( oldMarker );\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Fires an {@link module:engine/model/markercollection~MarkerCollection#event:update} event for the given {@link ~Marker marker}\n\t * but does not change the marker. Useful to force {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher downcast\n\t * conversion} for the marker.\n\t *\n\t * @protected\n\t * @fires module:engine/model/markercollection~MarkerCollection#event:update\n\t * @param {String} markerOrName Marker or name of a marker to refresh.\n\t */\n\t_refresh( markerOrName ) {\n\t\tconst markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;\n\t\tconst marker = this._markers.get( markerName );\n\n\t\tif ( !marker ) {\n\t\t\tthrow new CKEditorError( 'markercollection-refresh-marker-not-exists: Marker with provided name does not exists.' );\n\t\t}\n\n\t\tconst range = marker.getRange();\n\n\t\tthis.fire( 'update:' + markerName, marker, range, range, marker.managedUsingOperations, marker.affectsData );\n\t}\n\n\t/**\n\t * Returns iterator that iterates over all markers, which ranges contain given {@link module:engine/model/position~Position position}.\n\t *\n\t * @param {module:engine/model/position~Position} position\n\t * @returns {Iterable.<module:engine/model/markercollection~Marker>}\n\t */\n\t* getMarkersAtPosition( position ) {\n\t\tfor ( const marker of this ) {\n\t\t\tif ( marker.getRange().containsPosition( position ) ) {\n\t\t\t\tyield marker;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns iterator that iterates over all markers, which intersects with given {@link module:engine/model/range~Range range}.\n\t *\n\t * @param {module:engine/model/range~Range} range\n\t * @returns {Iterable.<module:engine/model/markercollection~Marker>}\n\t */\n\t* getMarkersIntersectingRange( range ) {\n\t\tfor ( const marker of this ) {\n\t\t\tif ( marker.getRange().getIntersection( range ) !== null ) {\n\t\t\t\tyield marker;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Destroys marker collection and all markers inside it.\n\t */\n\tdestroy() {\n\t\tfor ( const marker of this._markers.values() ) {\n\t\t\tthis._destroyMarker( marker );\n\t\t}\n\n\t\tthis._markers = null;\n\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Iterates over all markers that starts with given `prefix`.\n\t *\n\t *\t\tconst markerFooA = markersCollection.set( 'foo:a', rangeFooA );\n\t *\t\tconst markerFooB = markersCollection.set( 'foo:b', rangeFooB );\n\t *\t\tconst markerBarA = markersCollection.set( 'bar:a', rangeBarA );\n\t *\t\tconst markerFooBarA = markersCollection.set( 'foobar:a', rangeFooBarA );\n\t *\t\tArray.from( markersCollection.getMarkersGroup( 'foo' ) ); // [ markerFooA, markerFooB ]\n\t *\t\tArray.from( markersCollection.getMarkersGroup( 'a' ) ); // []\n\t *\n\t * @param prefix\n\t * @returns {Iterable.<module:engine/model/markercollection~Marker>}\n\t */\n\t* getMarkersGroup( prefix ) {\n\t\tfor ( const marker of this._markers.values() ) {\n\t\t\tif ( marker.name.startsWith( prefix + ':' ) ) {\n\t\t\t\tyield marker;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Destroys the marker.\n\t *\n\t * @private\n\t * @param {module:engine/model/markercollection~Marker} marker Marker to destroy.\n\t */\n\t_destroyMarker( marker ) {\n\t\tmarker.stopListening();\n\t\tmarker._detachLiveRange();\n\t}\n\n\t/**\n\t * Fired whenever marker is added, updated or removed from `MarkerCollection`.\n\t *\n\t * @event update\n\t * @param {module:engine/model/markercollection~Marker} marker Updated Marker.\n\t * @param {module:engine/model/range~Range|null} oldRange Marker range before the update. When is not defined it\n\t * means that marker is just added.\n\t * @param {module:engine/model/range~Range|null} newRange Marker range after update. When is not defined it\n\t * means that marker is just removed.\n\t */\n}\n\nmix( MarkerCollection, EmitterMixin );\n\n/**\n * `Marker` is a continuous parts of model (like a range), is named and represent some kind of information about marked\n * part of model document. In contrary to {@link module:engine/model/node~Node nodes}, which are building blocks of\n * model document tree, markers are not stored directly in document tree but in\n * {@link module:engine/model/model~Model#markers model markers' collection}. Still, they are document data, by giving\n * additional meaning to the part of a model document between marker start and marker end.\n *\n * In this sense, markers are similar to adding and converting attributes on nodes. The difference is that attribute is\n * connected with a given node (e.g. a character is bold no matter if it gets moved or content around it changes).\n * Markers on the other hand are continuous ranges and are characterized by their start and end position. This means that\n * any character in the marker is marked by the marker. For example, if a character is moved outside of marker it stops being\n * \"special\" and the marker is shrunk. Similarly, when a character is moved into the marker from other place in document\n * model, it starts being \"special\" and the marker is enlarged.\n *\n * Another upside of markers is that finding marked part of document is fast and easy. Using attributes to mark some nodes\n * and then trying to find that part of document would require traversing whole document tree. Marker gives instant access\n * to the range which it is marking at the moment.\n *\n * Markers are built from a name and a range.\n *\n * Range of the marker is updated automatically when document changes, using\n * {@link module:engine/model/liverange~LiveRange live range} mechanism.\n *\n * Name is used to group and identify markers. Names have to be unique, but markers can be grouped by\n * using common prefixes, separated with `:`, for example: `user:john` or `search:3`. That's useful in term of creating\n * namespaces for custom elements (e.g. comments, highlights). You can use this prefixes in\n * {@link module:engine/model/markercollection~MarkerCollection#event:update} listeners to listen on changes in a group of markers.\n * For instance: `model.markers.on( 'set:user', callback );` will be called whenever any `user:*` markers changes.\n *\n * There are two types of markers.\n *\n * 1. Markers managed directly, without using operations. They are added directly by {@link module:engine/model/writer~Writer}\n * to the {@link module:engine/model/markercollection~MarkerCollection} without any additional mechanism. They can be used\n * as bookmarks or visual markers. They are great for showing results of the find, or select link when the focus is in the input.\n *\n * 1. Markers managed using operations. These markers are also stored in {@link module:engine/model/markercollection~MarkerCollection}\n * but changes in these markers is managed the same way all other changes in the model structure - using operations.\n * Therefore, they are handled in the undo stack and synchronized between clients if the collaboration plugin is enabled.\n * This type of markers is useful for solutions like spell checking or comments.\n *\n * Both type of them should be added / updated by {@link module:engine/model/writer~Writer#addMarker}\n * and removed by {@link module:engine/model/writer~Writer#removeMarker} methods.\n *\n *\t\tmodel.change( ( writer ) => {\n * \t\t\tconst marker = writer.addMarker( name, { range, usingOperation: true } );\n *\n * \t\t\t// ...\n *\n * \t\t\twriter.removeMarker( marker );\n *\t\t} );\n *\n * See {@link module:engine/model/writer~Writer} to find more examples.\n *\n * Since markers need to track change in the document, for efficiency reasons, it is best to create and keep as little\n * markers as possible and remove them as soon as they are not needed anymore.\n *\n * Markers can be downcasted and upcasted.\n *\n * Markers downcast happens on {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker} and\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:removeMarker} events.\n * Use {@link module:engine/conversion/downcasthelpers downcast converters} or attach a custom converter to mentioned events.\n * For {@link module:engine/controller/datacontroller~DataController data pipeline}, marker should be downcasted to an element.\n * Then, it can be upcasted back to a marker. Again, use {@link module:engine/conversion/upcasthelpers upcast converters} or\n * attach a custom converter to {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element}.\n *\n * `Marker` instances are created and destroyed only by {@link ~MarkerCollection MarkerCollection}.\n */\nclass Marker {\n\t/**\n\t * Creates a marker instance.\n\t *\n\t * @param {String} name Marker name.\n\t * @param {module:engine/model/liverange~LiveRange} liveRange Range marked by the marker.\n\t * @param {Boolean} managedUsingOperations Specifies whether the marker is managed using operations.\n\t * @param {Boolean} affectsData Specifies whether the marker affects the data produced by the data pipeline\n\t * (is persisted in the editor's data).\n\t */\n\tconstructor( name, liveRange, managedUsingOperations, affectsData ) {\n\t\t/**\n\t\t * Marker's name.\n\t\t *\n\t\t * @readonly\n\t\t * @type {String}\n\t\t */\n\t\tthis.name = name;\n\n\t\t/**\n\t\t * Range marked by the marker.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:engine/model/liverange~LiveRange}\n\t\t */\n\t\tthis._liveRange = this._attachLiveRange( liveRange );\n\n\t\t/**\n\t\t * Flag indicates if the marker is managed using operations or not.\n\t\t *\n\t\t * @private\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis._managedUsingOperations = managedUsingOperations;\n\n\t\t/**\n\t\t * Specifies whether the marker affects the data produced by the data pipeline\n\t\t * (is persisted in the editor's data).\n\t\t *\n\t\t * @private\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis._affectsData = affectsData;\n\t}\n\n\t/**\n\t * A value indicating if the marker is managed using operations.\n\t * See {@link ~Marker marker class description} to learn more about marker types.\n\t * See {@link module:engine/model/writer~Writer#addMarker}.\n\t *\n\t * @returns {Boolean}\n\t */\n\tget managedUsingOperations() {\n\t\tif ( !this._liveRange ) {\n\t\t\tthrow new CKEditorError( 'marker-destroyed: Cannot use a destroyed marker instance.' );\n\t\t}\n\n\t\treturn this._managedUsingOperations;\n\t}\n\n\t/**\n\t * A value indicating if the marker changes the data.\n\t *\n\t * @returns {Boolean}\n\t */\n\tget affectsData() {\n\t\tif ( !this._liveRange ) {\n\t\t\tthrow new CKEditorError( 'marker-destroyed: Cannot use a destroyed marker instance.' );\n\t\t}\n\n\t\treturn this._affectsData;\n\t}\n\n\t/**\n\t * Returns current marker start position.\n\t *\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tgetStart() {\n\t\tif ( !this._liveRange ) {\n\t\t\tthrow new CKEditorError( 'marker-destroyed: Cannot use a destroyed marker instance.' );\n\t\t}\n\n\t\treturn this._liveRange.start.clone();\n\t}\n\n\t/**\n\t * Returns current marker end position.\n\t *\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tgetEnd() {\n\t\tif ( !this._liveRange ) {\n\t\t\tthrow new CKEditorError( 'marker-destroyed: Cannot use a destroyed marker instance.' );\n\t\t}\n\n\t\treturn this._liveRange.end.clone();\n\t}\n\n\t/**\n\t * Returns a range that represents the current state of the marker.\n\t *\n\t * Keep in mind that returned value is a {@link module:engine/model/range~Range Range}, not a\n\t * {@link module:engine/model/liverange~LiveRange LiveRange}. This means that it is up-to-date and relevant only\n\t * until next model document change. Do not store values returned by this method. Instead, store {@link ~Marker#name}\n\t * and get `Marker` instance from {@link module:engine/model/markercollection~MarkerCollection MarkerCollection} every\n\t * time there is a need to read marker properties. This will guarantee that the marker has not been removed and\n\t * that it's data is up-to-date.\n\t *\n\t * @returns {module:engine/model/range~Range}\n\t */\n\tgetRange() {\n\t\tif ( !this._liveRange ) {\n\t\t\tthrow new CKEditorError( 'marker-destroyed: Cannot use a destroyed marker instance.' );\n\t\t}\n\n\t\treturn this._liveRange.toRange();\n\t}\n\n\t/**\n\t * Binds new live range to the marker and detach the old one if is attached.\n\t *\n\t * @protected\n\t * @param {module:engine/model/liverange~LiveRange} liveRange Live range to attach\n\t * @returns {module:engine/model/liverange~LiveRange} Attached live range.\n\t */\n\t_attachLiveRange( liveRange ) {\n\t\tif ( this._liveRange ) {\n\t\t\tthis._detachLiveRange();\n\t\t}\n\n\t\t// Delegating does not work with namespaces. Alternatively, we could delegate all events (using `*`).\n\t\tliveRange.delegate( 'change:range' ).to( this );\n\t\tliveRange.delegate( 'change:content' ).to( this );\n\n\t\tthis._liveRange = liveRange;\n\n\t\treturn liveRange;\n\t}\n\n\t/**\n\t * Unbinds and destroys currently attached live range.\n\t *\n\t * @protected\n\t */\n\t_detachLiveRange() {\n\t\tthis._liveRange.stopDelegating( 'change:range', this );\n\t\tthis._liveRange.stopDelegating( 'change:content', this );\n\t\tthis._liveRange.detach();\n\t\tthis._liveRange = null;\n\t}\n\n\t/**\n\t * Fired whenever {@link ~Marker#_liveRange marker range} is changed due to changes on {@link module:engine/model/document~Document}.\n\t * This is a delegated {@link module:engine/model/liverange~LiveRange#event:change:range LiveRange change:range event}.\n\t *\n\t * When marker is removed from {@link module:engine/model/markercollection~MarkerCollection MarkerCollection},\n\t * all event listeners listening to it should be removed. It is best to do it on\n\t * {@link module:engine/model/markercollection~MarkerCollection#event:update MarkerCollection update event}.\n\t *\n\t * @see module:engine/model/liverange~LiveRange#event:change:range\n\t * @event change:range\n\t * @param {module:engine/model/range~Range} oldRange\n\t * @param {Object} data\n\t */\n\n\t/**\n\t * Fired whenever change on {@link module:engine/model/document~Document} is done inside {@link ~Marker#_liveRange marker range}.\n\t * This is a delegated {@link module:engine/model/liverange~LiveRange#event:change:content LiveRange change:content event}.\n\t *\n\t * When marker is removed from {@link module:engine/model/markercollection~MarkerCollection MarkerCollection},\n\t * all event listeners listening to it should be removed. It is best to do it on\n\t * {@link module:engine/model/markercollection~MarkerCollection#event:update MarkerCollection update event}.\n\t *\n\t * @see module:engine/model/liverange~LiveRange#event:change:content\n\t * @event change:content\n\t * @param {module:engine/model/range~Range} oldRange\n\t * @param {Object} data\n\t */\n}\n\nmix( Marker, EmitterMixin );\n\n/**\n * Cannot use a {@link module:engine/model/markercollection~MarkerCollection#destroy destroyed marker} instance.\n *\n * @error marker-destroyed\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/liveposition\n */\n\nimport Position from './position';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * `LivePosition` is a type of {@link module:engine/model/position~Position Position}\n * that updates itself as {@link module:engine/model/document~Document document}\n * is changed through operations. It may be used as a bookmark.\n *\n * **Note:** Contrary to {@link module:engine/model/position~Position}, `LivePosition` works only in roots that are\n * {@link module:engine/model/rootelement~RootElement}.\n * If {@link module:engine/model/documentfragment~DocumentFragment} is passed, error will be thrown.\n *\n * **Note:** Be very careful when dealing with `LivePosition`. Each `LivePosition` instance bind events that might\n * have to be unbound.\n * Use {@link module:engine/model/liveposition~LivePosition#detach} whenever you don't need `LivePosition` anymore.\n *\n * @extends module:engine/model/position~Position\n */\nexport default class LivePosition extends Position {\n\t/**\n\t * Creates a live position.\n\t *\n\t * @see module:engine/model/position~Position\n\t * @param {module:engine/model/rootelement~RootElement} root\n\t * @param {Array.<Number>} path\n\t * @param {module:engine/model/position~PositionStickiness} [stickiness]\n\t */\n\tconstructor( root, path, stickiness = 'toNone' ) {\n\t\tsuper( root, path, stickiness );\n\n\t\tif ( !this.root.is( 'rootElement' ) ) {\n\t\t\t/**\n\t\t\t * LivePosition's root has to be an instance of RootElement.\n\t\t\t *\n\t\t\t * @error liveposition-root-not-rootelement\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'model-liveposition-root-not-rootelement: LivePosition\\'s root has to be an instance of RootElement.'\n\t\t\t);\n\t\t}\n\n\t\tbindWithDocument.call( this );\n\t}\n\n\t/**\n\t * Unbinds all events previously bound by `LivePosition`. Use it whenever you don't need `LivePosition` instance\n\t * anymore (i.e. when leaving scope in which it was declared or before re-assigning variable that was\n\t * referring to it).\n\t */\n\tdetach() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Creates a {@link module:engine/model/position~Position position instance}, which is equal to this live position.\n\t *\n\t * @returns {module:engine/model/position~Position}\n\t */\n\ttoPosition() {\n\t\treturn new Position( this.root, this.path.slice(), this.stickiness );\n\t}\n\n\t/**\n\t * Creates a `LivePosition` instance that is equal to position.\n\t *\n\t * @param {module:engine/model/position~Position} position\n\t * @param {module:engine/model/position~PositionStickiness} [stickiness]\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tstatic fromPosition( position, stickiness ) {\n\t\treturn new this( position.root, position.path.slice(), stickiness ? stickiness : position.stickiness );\n\t}\n\n\t/**\n\t * @static\n\t * @protected\n\t * @method module:engine/model/liveposition~LivePosition._createAfter\n\t * @see module:engine/model/position~Position._createAfter\n\t * @param {module:engine/model/node~Node} node\n\t * @param {module:engine/model/position~PositionStickiness} [stickiness='toNone']\n\t * @returns {module:engine/model/liveposition~LivePosition}\n\t */\n\n\t/**\n\t * @static\n\t * @protected\n\t * @method module:engine/model/liveposition~LivePosition._createBefore\n\t * @see module:engine/model/position~Position._createBefore\n\t * @param {module:engine/model/node~Node} node\n\t * @param {module:engine/model/position~PositionStickiness} [stickiness='toNone']\n\t * @returns {module:engine/model/liveposition~LivePosition}\n\t */\n\n\t/**\n\t * @static\n\t * @protected\n\t * @method module:engine/model/liveposition~LivePosition._createAt\n\t * @see module:engine/model/position~Position._createAt\n\t * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset]\n\t * @param {module:engine/model/position~PositionStickiness} [stickiness='toNone']\n\t * @returns {module:engine/model/liveposition~LivePosition}\n\t */\n\n\t/**\n\t * Fired when `LivePosition` instance is changed due to changes on {@link module:engine/model/document~Document}.\n\t *\n\t * @event module:engine/model/liveposition~LivePosition#change\n\t * @param {module:engine/model/position~Position} oldPosition Position equal to this live position before it got changed.\n\t */\n}\n\n// Binds this `LivePosition` to the {@link module:engine/model/document~Document document} that owns\n// this position's {@link module:engine/model/position~Position#root root}.\n//\n// @private\nfunction bindWithDocument() {\n\tthis.listenTo(\n\t\tthis.root.document.model,\n\t\t'applyOperation',\n\t\t( event, args ) => {\n\t\t\tconst operation = args[ 0 ];\n\n\t\t\tif ( !operation.isDocumentOperation ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttransform.call( this, operation );\n\t\t},\n\t\t{ priority: 'low' }\n\t);\n}\n\n// Updates this position accordingly to the updates applied to the model. Bases on change events.\n//\n// @private\n// @param {module:engine/model/operation/operation~Operation} operation Executed operation.\nfunction transform( operation ) {\n\tconst result = this.getTransformedByOperation( operation );\n\n\tif ( !this.isEqual( result ) ) {\n\t\tconst oldPosition = this.toPosition();\n\n\t\tthis.path = result.path;\n\t\tthis.root = result.root;\n\n\t\tthis.fire( 'change', oldPosition );\n\t}\n}\n\nmix( LivePosition, EmitterMixin );\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/utils/insertcontent\n */\n\nimport Position from '../position';\nimport LivePosition from '../liveposition';\nimport Element from '../element';\nimport Range from '../range';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\nimport DocumentSelection from '../documentselection';\nimport Selection from '../selection';\n\n/**\n * Inserts content into the editor (specified selection) as one would expect the paste\n * functionality to work.\n *\n * If an instance of {@link module:engine/model/selection~Selection} is passed as `selectable` it will be modified\n * to the insertion selection (equal to a range to be selected after insertion).\n *\n * If `selectable` is not passed, the content will be inserted using the current selection of the model document.\n *\n * **Note:** Use {@link module:engine/model/model~Model#insertContent} instead of this function.\n * This function is only exposed to be reusable in algorithms which change the {@link module:engine/model/model~Model#insertContent}\n * method's behavior.\n *\n * @param {module:engine/model/model~Model} model The model in context of which the insertion\n * should be performed.\n * @param {module:engine/model/documentfragment~DocumentFragment|module:engine/model/item~Item} content The content to insert.\n * @param {module:engine/model/selection~Selectable} [selectable=model.document.selection]\n * Selection into which the content should be inserted.\n * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Sets place or offset of the selection.\n * @returns {module:engine/model/range~Range} Range which contains all the performed changes. This is a range that, if removed,\n * would return the model to the state before the insertion. If no changes were preformed by `insertContent`, returns a range collapsed\n * at the insertion position.\n */\nexport default function insertContent( model, content, selectable, placeOrOffset ) {\n\treturn model.change( writer => {\n\t\tlet selection;\n\n\t\tif ( !selectable ) {\n\t\t\tselection = model.document.selection;\n\t\t} else if ( selectable instanceof Selection || selectable instanceof DocumentSelection ) {\n\t\t\tselection = selectable;\n\t\t} else {\n\t\t\tselection = writer.createSelection( selectable, placeOrOffset );\n\t\t}\n\n\t\tconst insertionPosition = selection.getFirstPosition();\n\n\t\tif ( !selection.isCollapsed ) {\n\t\t\tmodel.deleteContent( selection, { doNotAutoparagraph: true } );\n\t\t}\n\n\t\tconst insertion = new Insertion( model, writer, insertionPosition );\n\n\t\tlet nodesToInsert;\n\n\t\tif ( content.is( 'documentFragment' ) ) {\n\t\t\tnodesToInsert = content.getChildren();\n\t\t} else {\n\t\t\tnodesToInsert = [ content ];\n\t\t}\n\n\t\tinsertion.handleNodes( nodesToInsert, {\n\t\t\t// The set of children being inserted is the only set in this context\n\t\t\t// so it's the first and last (it's a hack ;)).\n\t\t\tisFirst: true,\n\t\t\tisLast: true\n\t\t} );\n\n\t\tconst newRange = insertion.getSelectionRange();\n\n\t\t/* istanbul ignore else */\n\t\tif ( newRange ) {\n\t\t\tif ( selection instanceof DocumentSelection ) {\n\t\t\t\twriter.setSelection( newRange );\n\t\t\t} else {\n\t\t\t\tselection.setTo( newRange );\n\t\t\t}\n\t\t} else {\n\t\t\t// We are not testing else because it's a safe check for unpredictable edge cases:\n\t\t\t// an insertion without proper range to select.\n\n\t\t\t/**\n\t\t\t * Cannot determine a proper selection range after insertion.\n\t\t\t *\n\t\t\t * @warning insertcontent-no-range\n\t\t\t */\n\t\t\tlog.warn( 'insertcontent-no-range: Cannot determine a proper selection range after insertion.' );\n\t\t}\n\n\t\tconst affectedRange = insertion.getAffectedRange() || model.createRange( insertionPosition );\n\n\t\tinsertion.destroy();\n\n\t\treturn affectedRange;\n\t} );\n}\n\n/**\n * Utility class for performing content insertion.\n *\n * @private\n */\nclass Insertion {\n\tconstructor( model, writer, position ) {\n\t\t/**\n\t\t * The model in context of which the insertion should be performed.\n\t\t *\n\t\t * @member {module:engine/model~Model} #model\n\t\t */\n\t\tthis.model = model;\n\n\t\t/**\n\t\t * Batch to which operations will be added.\n\t\t *\n\t\t * @member {module:engine/controller/writer~Batch} #writer\n\t\t */\n\t\tthis.writer = writer;\n\n\t\t/**\n\t\t * The position at which (or near which) the next node will be inserted.\n\t\t *\n\t\t * @member {module:engine/model/position~Position} #position\n\t\t */\n\t\tthis.position = position;\n\n\t\t/**\n\t\t * Elements with which the inserted elements can be merged.\n\t\t *\n\t\t *\t\t<p>x^</p><p>y</p> + <p>z</p> (can merge to <p>x</p>)\n\t\t *\t\t<p>x</p><p>^y</p> + <p>z</p> (can merge to <p>y</p>)\n\t\t *\t\t<p>x^y</p> + <p>z</p> (can merge to <p>xy</p> which will be split during the action,\n\t\t *\t\t\t\t\t\t\t\tso both its pieces will be added to this set)\n\t\t *\n\t\t *\n\t\t * @member {Set} #canMergeWith\n\t\t */\n\t\tthis.canMergeWith = new Set( [ this.position.parent ] );\n\n\t\t/**\n\t\t * Schema of the model.\n\t\t *\n\t\t * @member {module:engine/model/schema~Schema} #schema\n\t\t */\n\t\tthis.schema = model.schema;\n\n\t\tthis._filterAttributesOf = [];\n\n\t\t/**\n\t\t * Beginning of the affected range. See {@link module:engine/model/utils/insertcontent~Insertion#getAffectedRange}.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/liveposition~LivePosition|null} #_affectedStart\n\t\t */\n\t\tthis._affectedStart = null;\n\n\t\t/**\n\t\t * End of the affected range. See {@link module:engine/model/utils/insertcontent~Insertion#getAffectedRange}.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/liveposition~LivePosition|null} #_affectedEnd\n\t\t */\n\t\tthis._affectedEnd = null;\n\t}\n\n\t/**\n\t * Handles insertion of a set of nodes.\n\t *\n\t * @param {Iterable.<module:engine/model/node~Node>} nodes Nodes to insert.\n\t * @param {Object} parentContext Context in which parent of these nodes was supposed to be inserted.\n\t * If the parent context is passed it means that the parent element was stripped (was not allowed).\n\t */\n\thandleNodes( nodes, parentContext ) {\n\t\tnodes = Array.from( nodes );\n\n\t\tfor ( let i = 0; i < nodes.length; i++ ) {\n\t\t\tconst node = nodes[ i ];\n\n\t\t\tthis._handleNode( node, {\n\t\t\t\tisFirst: i === 0 && parentContext.isFirst,\n\t\t\t\tisLast: ( i === ( nodes.length - 1 ) ) && parentContext.isLast\n\t\t\t} );\n\t\t}\n\n\t\t// TMP this will become a post-fixer.\n\t\tthis.schema.removeDisallowedAttributes( this._filterAttributesOf, this.writer );\n\t\tthis._filterAttributesOf = [];\n\t}\n\n\t/**\n\t * Returns range to be selected after insertion.\n\t * Returns `null` if there is no valid range to select after insertion.\n\t *\n\t * @returns {module:engine/model/range~Range|null}\n\t */\n\tgetSelectionRange() {\n\t\tif ( this.nodeToSelect ) {\n\t\t\treturn Range._createOn( this.nodeToSelect );\n\t\t}\n\n\t\treturn this.model.schema.getNearestSelectionRange( this.position );\n\t}\n\n\t/**\n\t * Returns a range which contains all the performed changes. This is a range that, if removed, would return the model to the state\n\t * before the insertion. Returns `null` if no changes were done.\n\t *\n\t * @returns {module:engine/model/range~Range|null}\n\t */\n\tgetAffectedRange() {\n\t\tif ( !this._affectedStart ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn new Range( this._affectedStart, this._affectedEnd );\n\t}\n\n\t/**\n\t * Destroys `Insertion` instance.\n\t */\n\tdestroy() {\n\t\tif ( this._affectedStart ) {\n\t\t\tthis._affectedStart.detach();\n\t\t}\n\n\t\tif ( this._affectedEnd ) {\n\t\t\tthis._affectedEnd.detach();\n\t\t}\n\t}\n\n\t/**\n\t * Handles insertion of a single node.\n\t *\n\t * @private\n\t * @param {module:engine/model/node~Node} node\n\t * @param {Object} context\n\t * @param {Boolean} context.isFirst Whether the given node is the first one in the content to be inserted.\n\t * @param {Boolean} context.isLast Whether the given node is the last one in the content to be inserted.\n\t */\n\t_handleNode( node, context ) {\n\t\t// Let's handle object in a special way.\n\t\t// * They should never be merged with other elements.\n\t\t// * If they are not allowed in any of the selection ancestors, they could be either autoparagraphed or totally removed.\n\t\tif ( this.schema.isObject( node ) ) {\n\t\t\tthis._handleObject( node, context );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Try to find a place for the given node.\n\t\t// Split the position.parent's branch up to a point where the node can be inserted.\n\t\t// If it isn't allowed in the whole branch, then of course don't split anything.\n\t\tconst isAllowed = this._checkAndSplitToAllowedPosition( node, context );\n\n\t\tif ( !isAllowed ) {\n\t\t\tthis._handleDisallowedNode( node, context );\n\n\t\t\treturn;\n\t\t}\n\n\t\tthis._insert( node );\n\n\t\t// After the node was inserted we may try to merge it with its siblings.\n\t\t// This should happen only if it was the first and/or last of the nodes (so only with boundary nodes)\n\t\t// and only if the selection was in those elements initially.\n\t\t//\n\t\t// E.g.:\n\t\t// <p>x^</p> + <p>y</p> => <p>x</p><p>y</p> => <p>xy[]</p>\n\t\t// and:\n\t\t// <p>x^y</p> + <p>z</p> => <p>x</p>^<p>y</p> + <p>z</p> => <p>x</p><p>z</p><p>y</p> => <p>xz[]y</p>\n\t\t// but:\n\t\t// <p>x</p><p>^</p><p>z</p> + <p>y</p> => <p>x</p><p>y</p><p>z</p> (no merging)\n\t\t// <p>x</p>[<img>]<p>z</p> + <p>y</p> => <p>x</p><p>y</p><p>z</p> (no merging, note: after running deleteContents\n\t\t//\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t it's exactly the same case as above)\n\t\tthis._mergeSiblingsOf( node, context );\n\t}\n\n\t/**\n\t * @private\n\t * @param {module:engine/model/element~Element} node The object element.\n\t * @param {Object} context\n\t */\n\t_handleObject( node, context ) {\n\t\t// Try finding it a place in the tree.\n\t\tif ( this._checkAndSplitToAllowedPosition( node ) ) {\n\t\t\tthis._insert( node );\n\t\t}\n\t\t// Try autoparagraphing.\n\t\telse {\n\t\t\tthis._tryAutoparagraphing( node, context );\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {module:engine/model/node~Node} node The disallowed node which needs to be handled.\n\t * @param {Object} context\n\t */\n\t_handleDisallowedNode( node, context ) {\n\t\t// If the node is an element, try inserting its children (strip the parent).\n\t\tif ( node.is( 'element' ) ) {\n\t\t\tthis.handleNodes( node.getChildren(), context );\n\t\t}\n\t\t// If text is not allowed, try autoparagraphing it.\n\t\telse {\n\t\t\tthis._tryAutoparagraphing( node, context );\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {module:engine/model/node~Node} node The node to insert.\n\t */\n\t_insert( node ) {\n\t\t/* istanbul ignore if */\n\t\tif ( !this.schema.checkChild( this.position, node ) ) {\n\t\t\t// Algorithm's correctness check. We should never end up here but it's good to know that we did.\n\t\t\t// Note that it would often be a silent issue if we insert node in a place where it's not allowed.\n\t\t\tlog.error(\n\t\t\t\t'insertcontent-wrong-position: The node cannot be inserted on the given position.',\n\t\t\t\t{ node, position: this.position }\n\t\t\t);\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst livePos = LivePosition.fromPosition( this.position, 'toNext' );\n\n\t\tthis._setAffectedBoundaries( this.position );\n\t\tthis.writer.insert( node, this.position );\n\n\t\tthis.position = livePos.toPosition();\n\t\tlivePos.detach();\n\n\t\t// The last inserted object should be selected because we can't put a collapsed selection after it.\n\t\tif ( this.schema.isObject( node ) && !this.schema.checkChild( this.position, '$text' ) ) {\n\t\t\tthis.nodeToSelect = node;\n\t\t} else {\n\t\t\tthis.nodeToSelect = null;\n\t\t}\n\n\t\tthis._filterAttributesOf.push( node );\n\t}\n\n\t/**\n\t * Sets `_affectedStart` and `_affectedEnd` to the given `position`. Should be used before a change is done during insertion process to\n\t * mark the affected range.\n\t *\n\t * This method is used before inserting a node or splitting a parent node. `_affectedStart` and `_affectedEnd` are also changed\n\t * during merging, but the logic there is more complicated so it is left out of this function.\n\t *\n\t * @private\n\t * @param {module:engine/model/position~Position} position\n\t */\n\t_setAffectedBoundaries( position ) {\n\t\t// Set affected boundaries stickiness so that those position will \"expand\" when something is inserted in between them:\n\t\t// <paragraph>Foo][bar</paragraph> -> <paragraph>Foo]xx[bar</paragraph>\n\t\t// This is why it cannot be a range but two separate positions.\n\t\tif ( !this._affectedStart ) {\n\t\t\tthis._affectedStart = LivePosition.fromPosition( position, 'toPrevious' );\n\t\t}\n\n\t\t// If `_affectedEnd` is before the new boundary position, expand `_affectedEnd`. This can happen if first inserted node was\n\t\t// inserted into the parent but the next node is moved-out of that parent:\n\t\t// (1) <paragraph>Foo][</paragraph> -> <paragraph>Foo]xx[</paragraph>\n\t\t// (2) <paragraph>Foo]xx[</paragraph> -> <paragraph>Foo]xx</paragraph><widget></widget>[\n\t\tif ( !this._affectedEnd || this._affectedEnd.isBefore( position ) ) {\n\t\t\tif ( this._affectedEnd ) {\n\t\t\t\tthis._affectedEnd.detach();\n\t\t\t}\n\n\t\t\tthis._affectedEnd = LivePosition.fromPosition( position, 'toNext' );\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {module:engine/model/node~Node} node The node which could potentially be merged.\n\t * @param {Object} context\n\t */\n\t_mergeSiblingsOf( node, context ) {\n\t\tif ( !( node instanceof Element ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst mergeLeft = this._canMergeLeft( node, context );\n\t\tconst mergeRight = this._canMergeRight( node, context );\n\t\tconst mergePosLeft = LivePosition._createBefore( node );\n\t\tmergePosLeft.stickiness = 'toNext';\n\t\tconst mergePosRight = LivePosition._createAfter( node );\n\t\tmergePosRight.stickiness = 'toNext';\n\n\t\tif ( mergeLeft ) {\n\t\t\tconst livePosition = LivePosition.fromPosition( this.position );\n\t\t\tlivePosition.stickiness = 'toNext';\n\n\t\t\t// If `_affectedStart` is sames as merge position, it means that the element \"marked\" by `_affectedStart` is going to be\n\t\t\t// removed and its contents will be moved. This won't transform `LivePosition` so `_affectedStart` needs to be moved\n\t\t\t// by hand to properly reflect affected range. (Due to `_affectedStart` and `_affectedEnd` stickiness, the \"range\" is\n\t\t\t// shown as `][`).\n\t\t\t//\n\t\t\t// Example - insert `<paragraph>Abc</paragraph><paragraph>Xyz</paragraph>` at the end of `<paragraph>Foo^</paragraph>`:\n\t\t\t//\n\t\t\t// <paragraph>Foo</paragraph><paragraph>Bar</paragraph> -->\n\t\t\t// <paragraph>Foo</paragraph>]<paragraph>Abc</paragraph><paragraph>Xyz</paragraph>[<paragraph>Bar</paragraph> -->\n\t\t\t// <paragraph>Foo]Abc</paragraph><paragraph>Xyz</paragraph>[<paragraph>Bar</paragraph>\n\t\t\t//\n\t\t\t// Note, that if we are here then something must have been inserted, so `_affectedStart` and `_affectedEnd` have to be set.\n\t\t\tif ( this._affectedStart.isEqual( mergePosLeft ) ) {\n\t\t\t\tthis._affectedStart.detach();\n\t\t\t\tthis._affectedStart = LivePosition._createAt( mergePosLeft.nodeBefore, 'end', 'toPrevious' );\n\t\t\t}\n\n\t\t\tthis.writer.merge( mergePosLeft );\n\n\t\t\t// If only one element (the merged one) is in the \"affected range\", also move the affected range end appropriately.\n\t\t\t//\n\t\t\t// Example - insert `<paragraph>Abc</paragraph>` at the of `<paragraph>Foo^</paragraph>`:\n\t\t\t//\n\t\t\t// <paragraph>Foo</paragraph><paragraph>Bar</paragraph> -->\n\t\t\t// <paragraph>Foo</paragraph>]<paragraph>Abc</paragraph>[<paragraph>Bar</paragraph> -->\n\t\t\t// <paragraph>Foo]Abc</paragraph>[<paragraph>Bar</paragraph> -->\n\t\t\t// <paragraph>Foo]Abc[</paragraph><paragraph>Bar</paragraph>\n\t\t\tif ( mergePosLeft.isEqual( this._affectedEnd ) && context.isLast ) {\n\t\t\t\tthis._affectedEnd.detach();\n\t\t\t\tthis._affectedEnd = LivePosition._createAt( mergePosLeft.nodeBefore, 'end', 'toNext' );\n\t\t\t}\n\n\t\t\tthis.position = livePosition.toPosition();\n\t\t\tlivePosition.detach();\n\t\t}\n\n\t\tif ( mergeRight ) {\n\t\t\t/* istanbul ignore if */\n\t\t\tif ( !this.position.isEqual( mergePosRight ) ) {\n\t\t\t\t// Algorithm's correctness check. We should never end up here but it's good to know that we did.\n\t\t\t\t// At this point the insertion position should be after the node we'll merge. If it isn't,\n\t\t\t\t// it should need to be secured as in the left merge case.\n\t\t\t\tlog.error( 'insertcontent-wrong-position-on-merge: The insertion position should equal the merge position' );\n\t\t\t}\n\n\t\t\t// Move the position to the previous node, so it isn't moved to the graveyard on merge.\n\t\t\t// <p>x</p>[]<p>y</p> => <p>x[]</p><p>y</p>\n\t\t\tthis.position = Position._createAt( mergePosRight.nodeBefore, 'end' );\n\n\t\t\t// OK: <p>xx[]</p> + <p>yy</p> => <p>xx[]yy</p> (when sticks to previous)\n\t\t\t// NOK: <p>xx[]</p> + <p>yy</p> => <p>xxyy[]</p> (when sticks to next)\n\t\t\tconst livePosition = LivePosition.fromPosition( this.position, 'toPrevious' );\n\n\t\t\t// See comment above on moving `_affectedStart`.\n\t\t\tif ( this._affectedEnd.isEqual( mergePosRight ) ) {\n\t\t\t\tthis._affectedEnd.detach();\n\t\t\t\tthis._affectedEnd = LivePosition._createAt( mergePosRight.nodeBefore, 'end', 'toNext' );\n\t\t\t}\n\n\t\t\tthis.writer.merge( mergePosRight );\n\n\t\t\t// See comment above on moving `_affectedStart`.\n\t\t\tif ( mergePosRight.getShiftedBy( -1 ).isEqual( this._affectedStart ) && context.isFirst ) {\n\t\t\t\tthis._affectedStart.detach();\n\t\t\t\tthis._affectedStart = LivePosition._createAt( mergePosRight.nodeBefore, 0, 'toPrevious' );\n\t\t\t}\n\n\t\t\tthis.position = livePosition.toPosition();\n\t\t\tlivePosition.detach();\n\t\t}\n\n\t\tif ( mergeLeft || mergeRight ) {\n\t\t\t// After merge elements that were marked by _insert() to be filtered might be gone so\n\t\t\t// we need to mark the new container.\n\t\t\tthis._filterAttributesOf.push( this.position.parent );\n\t\t}\n\n\t\tmergePosLeft.detach();\n\t\tmergePosRight.detach();\n\t}\n\n\t/**\n\t * Checks whether specified node can be merged with previous sibling element.\n\t *\n\t * @private\n\t * @param {module:engine/model/node~Node} node The node which could potentially be merged.\n\t * @param {Object} context\n\t * @returns {Boolean}\n\t */\n\t_canMergeLeft( node, context ) {\n\t\tconst previousSibling = node.previousSibling;\n\n\t\treturn context.isFirst &&\n\t\t\t( previousSibling instanceof Element ) &&\n\t\t\tthis.canMergeWith.has( previousSibling ) &&\n\t\t\tthis.model.schema.checkMerge( previousSibling, node );\n\t}\n\n\t/**\n\t * Checks whether specified node can be merged with next sibling element.\n\t *\n\t * @private\n\t * @param {module:engine/model/node~Node} node The node which could potentially be merged.\n\t * @param {Object} context\n\t * @returns {Boolean}\n\t */\n\t_canMergeRight( node, context ) {\n\t\tconst nextSibling = node.nextSibling;\n\n\t\treturn context.isLast &&\n\t\t\t( nextSibling instanceof Element ) &&\n\t\t\tthis.canMergeWith.has( nextSibling ) &&\n\t\t\tthis.model.schema.checkMerge( node, nextSibling );\n\t}\n\n\t/**\n\t * Tries wrapping the node in a new paragraph and inserting it this way.\n\t *\n\t * @private\n\t * @param {module:engine/model/node~Node} node The node which needs to be autoparagraphed.\n\t * @param {Object} context\n\t */\n\t_tryAutoparagraphing( node, context ) {\n\t\tconst paragraph = this.writer.createElement( 'paragraph' );\n\n\t\t// Do not autoparagraph if the paragraph won't be allowed there,\n\t\t// cause that would lead to an infinite loop. The paragraph would be rejected in\n\t\t// the next _handleNode() call and we'd be here again.\n\t\tif ( this._getAllowedIn( paragraph, this.position.parent ) && this.schema.checkChild( paragraph, node ) ) {\n\t\t\tparagraph._appendChild( node );\n\t\t\tthis._handleNode( paragraph, context );\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {module:engine/model/node~Node} node\n\t * @returns {Boolean} Whether an allowed position was found.\n\t * `false` is returned if the node isn't allowed at any position up in the tree, `true` if was.\n\t */\n\t_checkAndSplitToAllowedPosition( node ) {\n\t\tconst allowedIn = this._getAllowedIn( node, this.position.parent );\n\n\t\tif ( !allowedIn ) {\n\t\t\treturn false;\n\t\t}\n\n\t\twhile ( allowedIn != this.position.parent ) {\n\t\t\t// If a parent which we'd need to leave is a limit element, break.\n\t\t\tif ( this.schema.isLimit( this.position.parent ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif ( this.position.isAtStart ) {\n\t\t\t\t// If insertion position is at the beginning of the parent, move it out instead of splitting.\n\t\t\t\t// <p>^Foo</p> -> ^<p>Foo</p>\n\t\t\t\tconst parent = this.position.parent;\n\n\t\t\t\tthis.position = this.writer.createPositionBefore( parent );\n\n\t\t\t\t// Special case – parent is empty (<p>^</p>).\n\t\t\t\t// We can remove the element after moving insertion position out of it.\n\t\t\t\tif ( parent.isEmpty ) {\n\t\t\t\t\tthis.writer.remove( parent );\n\t\t\t\t}\n\t\t\t} else if ( this.position.isAtEnd ) {\n\t\t\t\t// If insertion position is at the end of the parent, move it out instead of splitting.\n\t\t\t\t// <p>Foo^</p> -> <p>Foo</p>^\n\t\t\t\tthis.position = this.writer.createPositionAfter( this.position.parent );\n\t\t\t} else {\n\t\t\t\tconst tempPos = this.writer.createPositionAfter( this.position.parent );\n\n\t\t\t\tthis._setAffectedBoundaries( this.position );\n\t\t\t\tthis.writer.split( this.position );\n\n\t\t\t\tthis.position = tempPos;\n\n\t\t\t\tthis.canMergeWith.add( this.position.nodeAfter );\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Gets the element in which the given node is allowed. It checks the passed element and all its ancestors.\n\t *\n\t * @private\n\t * @param {module:engine/model/node~Node} node The node to check.\n\t * @param {module:engine/model/element~Element} element The element in which the node's correctness should be checked.\n\t * @returns {module:engine/model/element~Element|null}\n\t */\n\t_getAllowedIn( node, element ) {\n\t\tif ( this.schema.checkChild( element, node ) ) {\n\t\t\treturn element;\n\t\t}\n\n\t\tif ( element.parent ) {\n\t\t\treturn this._getAllowedIn( node, element.parent );\n\t\t}\n\n\t\treturn null;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/utils/deletecontent\n */\n\nimport LivePosition from '../liveposition';\nimport Range from '../range';\nimport DocumentSelection from '../documentselection';\n\n/**\n * Deletes content of the selection and merge siblings. The resulting selection is always collapsed.\n *\n * **Note:** Use {@link module:engine/model/model~Model#deleteContent} instead of this function.\n * This function is only exposed to be reusable in algorithms\n * which change the {@link module:engine/model/model~Model#deleteContent}\n * method's behavior.\n *\n * @param {module:engine/model/model~Model} model The model in context of which the insertion\n * should be performed.\n * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection\n * Selection of which the content should be deleted.\n * @param {module:engine/model/batch~Batch} batch Batch to which the operations will be added.\n * @param {Object} [options]\n * @param {Boolean} [options.leaveUnmerged=false] Whether to merge elements after removing the content of the selection.\n *\n * For example `<heading>x[x</heading><paragraph>y]y</paragraph>` will become:\n *\n * * `<heading>x^y</heading>` with the option disabled (`leaveUnmerged == false`)\n * * `<heading>x^</heading><paragraph>y</paragraph>` with enabled (`leaveUnmerged == true`).\n *\n * Note: {@link module:engine/model/schema~Schema#isObject object} and {@link module:engine/model/schema~Schema#isLimit limit}\n * elements will not be merged.\n *\n * @param {Boolean} [options.doNotResetEntireContent=false] Whether to skip replacing the entire content with a\n * paragraph when the entire content was selected.\n *\n * For example `<heading>[x</heading><paragraph>y]</paragraph>` will become:\n *\n * * `<paragraph>^</paragraph>` with the option disabled (`doNotResetEntireContent == false`)\n * * `<heading>^</heading>` with enabled (`doNotResetEntireContent == true`).\n *\n * @param {Boolean} [options.doNotAutoparagraph=false] Whether to create a paragraph if after content deletion selection is moved\n * to a place where text cannot be inserted.\n *\n * For example `<paragraph>x</paragraph>[<image src=\"foo.jpg\"></image>]` will become:\n *\n * * `<paragraph>x</paragraph><paragraph>[]</paragraph>` with the option disabled (`doNotAutoparagraph == false`)\n * * `<paragraph>x[]</paragraph>` with the option enabled (`doNotAutoparagraph == true`).\n *\n * **Note:** if there is no valid position for the selection, the paragraph will always be created:\n *\n * `[<image src=\"foo.jpg\"></image>]` -> `<paragraph>[]</paragraph>`.\n */\nexport default function deleteContent( model, selection, options = {} ) {\n\tif ( selection.isCollapsed ) {\n\t\treturn;\n\t}\n\n\tconst selRange = selection.getFirstRange();\n\n\t// If the selection is already removed, don't do anything.\n\tif ( selRange.root.rootName == '$graveyard' ) {\n\t\treturn;\n\t}\n\n\tconst schema = model.schema;\n\n\tmodel.change( writer => {\n\t\t// 1. Replace the entire content with paragraph.\n\t\t// See: https://github.com/ckeditor/ckeditor5-engine/issues/1012#issuecomment-315017594.\n\t\tif ( !options.doNotResetEntireContent && shouldEntireContentBeReplacedWithParagraph( schema, selection ) ) {\n\t\t\treplaceEntireContentWithParagraph( writer, selection, schema );\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst startPos = selRange.start;\n\t\tconst endPos = LivePosition.fromPosition( selRange.end, 'toNext' );\n\n\t\t// 2. Remove the content if there is any.\n\t\tif ( !selRange.start.isTouching( selRange.end ) ) {\n\t\t\twriter.remove( selRange );\n\t\t}\n\n\t\t// 3. Merge elements in the right branch to the elements in the left branch.\n\t\t// The only reasonable (in terms of data and selection correctness) case in which we need to do that is:\n\t\t//\n\t\t// <heading type=1>Fo[</heading><paragraph>]ar</paragraph> => <heading type=1>Fo^ar</heading>\n\t\t//\n\t\t// However, the algorithm supports also merging deeper structures (up to the depth of the shallower branch),\n\t\t// as it's hard to imagine what should actually be the default behavior. Usually, specific features will\n\t\t// want to override that behavior anyway.\n\t\tif ( !options.leaveUnmerged ) {\n\t\t\tmergeBranches( writer, startPos, endPos );\n\n\t\t\t// TMP this will be replaced with a postfixer.\n\t\t\t// We need to check and strip disallowed attributes in all nested nodes because after merge\n\t\t\t// some attributes could end up in a path where are disallowed.\n\t\t\t//\n\t\t\t// e.g. bold is disallowed for <H1>\n\t\t\t// <h1>Fo{o</h1><p>b}a<b>r</b><p> -> <h1>Fo{}a<b>r</b><h1> -> <h1>Fo{}ar<h1>.\n\t\t\tschema.removeDisallowedAttributes( startPos.parent.getChildren(), writer );\n\t\t}\n\n\t\tcollapseSelectionAt( writer, selection, startPos );\n\n\t\t// 4. Add a paragraph to set selection in it.\n\t\t// Check if a text is allowed in the new container. If not, try to create a new paragraph (if it's allowed here).\n\t\tif ( shouldAutoparagraph( schema, startPos ) ) {\n\t\t\t// If auto-paragraphing is off, find the closest valid selection range and collapse the selection there.\n\t\t\t// If there is no valid selection range, create paragraph anyway and set selection there.\n\t\t\tconst validSelectionRange = schema.getNearestSelectionRange( startPos );\n\n\t\t\tif ( options.doNotAutoparagraph && validSelectionRange ) {\n\t\t\t\tcollapseSelectionAt( writer, selection, validSelectionRange );\n\t\t\t} else {\n\t\t\t\tinsertParagraph( writer, startPos, selection );\n\t\t\t}\n\t\t}\n\n\t\tendPos.detach();\n\t} );\n}\n\n// This function is a result of reaching the Ballmer's peak for just the right amount of time.\n// Even I had troubles documenting it after a while and after reading it again I couldn't believe that it really works.\nfunction mergeBranches( writer, startPos, endPos ) {\n\tconst startParent = startPos.parent;\n\tconst endParent = endPos.parent;\n\n\t// If both positions ended up in the same parent, then there's nothing more to merge:\n\t// <$root><p>x[]</p><p>{}y</p></$root> => <$root><p>xy</p>[]{}</$root>\n\tif ( startParent == endParent ) {\n\t\treturn;\n\t}\n\n\t// If one of the positions is a limit element, then there's nothing to merge because we don't want to cross the limit boundaries.\n\tif ( writer.model.schema.isLimit( startParent ) || writer.model.schema.isLimit( endParent ) ) {\n\t\treturn;\n\t}\n\n\t// Check if operations we'll need to do won't need to cross object or limit boundaries.\n\t// E.g., we can't merge endParent into startParent in this case:\n\t// <limit><startParent>x[]</startParent></limit><endParent>{}</endParent>\n\tif ( !checkCanBeMerged( startPos, endPos, writer.model.schema ) ) {\n\t\treturn;\n\t}\n\n\t// Remember next positions to merge. For example:\n\t// <a><b>x[]</b></a><c><d>{}y</d></c>\n\t// will become:\n\t// <a><b>xy</b>[]</a><c>{}</c>\n\tstartPos = writer.createPositionAfter( startParent );\n\tendPos = writer.createPositionBefore( endParent );\n\n\tif ( !endPos.isEqual( startPos ) ) {\n\t\t// In this case, before we merge, we need to move `endParent` to the `startPos`:\n\t\t// <a><b>x[]</b></a><c><d>{}y</d></c>\n\t\t// becomes:\n\t\t// <a><b>x</b>[]<d>y</d></a><c>{}</c>\n\t\twriter.insert( endParent, startPos );\n\t}\n\n\t// Merge two siblings:\n\t// <a>x</a>[]<b>y</b> -> <a>xy</a> (the usual case)\n\t// <a><b>x</b>[]<d>y</d></a><c></c> -> <a><b>xy</b>[]</a><c></c> (this is the \"move parent\" case shown above)\n\twriter.merge( startPos );\n\n\t// Remove empty end ancestors:\n\t// <a>fo[o</a><b><a><c>bar]</c></a></b>\n\t// becomes:\n\t// <a>fo[]</a><b><a>{}</a></b>\n\t// So we can remove <a> and <b>.\n\twhile ( endPos.parent.isEmpty ) {\n\t\tconst parentToRemove = endPos.parent;\n\n\t\tendPos = writer.createPositionBefore( parentToRemove );\n\n\t\twriter.remove( parentToRemove );\n\t}\n\n\t// Continue merging next level.\n\tmergeBranches( writer, startPos, endPos );\n}\n\nfunction shouldAutoparagraph( schema, position ) {\n\tconst isTextAllowed = schema.checkChild( position, '$text' );\n\tconst isParagraphAllowed = schema.checkChild( position, 'paragraph' );\n\n\treturn !isTextAllowed && isParagraphAllowed;\n}\n\n// Check if parents of two positions can be merged by checking if there are no limit/object\n// boundaries between those two positions.\n//\n// E.g. in <bQ><p>x[]</p></bQ><widget><caption>{}</caption></widget>\n// we'll check <p>, <bQ>, <widget> and <caption>.\n// Usually, widget and caption are marked as objects/limits in the schema, so in this case merging will be blocked.\nfunction checkCanBeMerged( leftPos, rightPos, schema ) {\n\tconst rangeToCheck = new Range( leftPos, rightPos );\n\n\tfor ( const value of rangeToCheck.getWalker() ) {\n\t\tif ( schema.isLimit( value.item ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nfunction insertParagraph( writer, position, selection ) {\n\tconst paragraph = writer.createElement( 'paragraph' );\n\n\twriter.insert( paragraph, position );\n\n\tcollapseSelectionAt( writer, selection, writer.createPositionAt( paragraph, 0 ) );\n}\n\nfunction replaceEntireContentWithParagraph( writer, selection ) {\n\tconst limitElement = writer.model.schema.getLimitElement( selection );\n\n\twriter.remove( writer.createRangeIn( limitElement ) );\n\tinsertParagraph( writer, writer.createPositionAt( limitElement, 0 ), selection );\n}\n\n// We want to replace the entire content with a paragraph when:\n// * the entire content is selected,\n// * selection contains at least two elements,\n// * whether the paragraph is allowed in schema in the common ancestor.\nfunction shouldEntireContentBeReplacedWithParagraph( schema, selection ) {\n\tconst limitElement = schema.getLimitElement( selection );\n\n\tif ( !selection.containsEntireContent( limitElement ) ) {\n\t\treturn false;\n\t}\n\n\tconst range = selection.getFirstRange();\n\n\tif ( range.start.parent == range.end.parent ) {\n\t\treturn false;\n\t}\n\n\treturn schema.checkChild( limitElement, 'paragraph' );\n}\n\n// Helper function that sets the selection. Depending whether given `selection` is a document selection or not,\n// uses a different method to set it.\nfunction collapseSelectionAt( writer, selection, positionOrRange ) {\n\tif ( selection instanceof DocumentSelection ) {\n\t\twriter.setSelection( positionOrRange );\n\t} else {\n\t\tselection.setTo( positionOrRange );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/utils/modifyselection\n */\n\nimport Position from '../position';\nimport TreeWalker from '../treewalker';\nimport Range from '../range';\nimport { isInsideSurrogatePair, isInsideCombinedSymbol } from '@ckeditor/ckeditor5-utils/src/unicode';\nimport DocumentSelection from '../documentselection';\n\nconst wordBoundaryCharacters = ' ,.?!:;\"-()';\n\n/**\n * Modifies the selection. Currently, the supported modifications are:\n *\n * * Extending. The selection focus is moved in the specified `options.direction` with a step specified in `options.unit`.\n * Possible values for `unit` are:\n * * `'character'` (default) - moves selection by one user-perceived character. In most cases this means moving by one\n * character in `String` sense. However, unicode also defines \"combing marks\". These are special symbols, that combines\n * with a symbol before it (\"base character\") to create one user-perceived character. For example, `q̣̇` is a normal\n * letter `q` with two \"combining marks\": upper dot (`Ux0307`) and lower dot (`Ux0323`). For most actions, i.e. extending\n * selection by one position, it is correct to include both \"base character\" and all of it's \"combining marks\". That is\n * why `'character'` value is most natural and common method of modifying selection.\n * * `'codePoint'` - moves selection by one unicode code point. In contrary to, `'character'` unit, this will insert\n * selection between \"base character\" and \"combining mark\", because \"combining marks\" have their own unicode code points.\n * However, for technical reasons, unicode code points with values above `UxFFFF` are represented in native `String` by\n * two characters, called \"surrogate pairs\". Halves of \"surrogate pairs\" have a meaning only when placed next to each other.\n * For example `𨭎` is represented in `String` by `\\uD862\\uDF4E`. Both `\\uD862` and `\\uDF4E` do not have any meaning\n * outside the pair (are rendered as ? when alone). Position between them would be incorrect. In this case, selection\n * extension will include whole \"surrogate pair\".\n * * `'word'` - moves selection by a whole word.\n *\n * **Note:** if you extend a forward selection in a backward direction you will in fact shrink it.\n *\n * **Note:** Use {@link module:engine/model/model~Model#modifySelection} instead of this function.\n * This function is only exposed to be reusable in algorithms\n * which change the {@link module:engine/model/model~Model#modifySelection}\n * method's behavior.\n *\n * @param {module:engine/model/model~Model} model The model in context of which\n * the selection modification should be performed.\n * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection\n * The selection to modify.\n * @param {Object} [options]\n * @param {'forward'|'backward'} [options.direction='forward'] The direction in which the selection should be modified.\n * @param {'character'|'codePoint'|'word'} [options.unit='character'] The unit by which selection should be modified.\n */\nexport default function modifySelection( model, selection, options = {} ) {\n\tconst schema = model.schema;\n\tconst isForward = options.direction != 'backward';\n\tconst unit = options.unit ? options.unit : 'character';\n\n\tconst focus = selection.focus;\n\n\tconst walker = new TreeWalker( {\n\t\tboundaries: getSearchRange( focus, isForward ),\n\t\tsingleCharacters: true,\n\t\tdirection: isForward ? 'forward' : 'backward'\n\t} );\n\n\tconst data = { walker, schema, isForward, unit };\n\n\tlet next;\n\n\twhile ( ( next = walker.next() ) ) {\n\t\tif ( next.done ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst position = tryExtendingTo( data, next.value );\n\n\t\tif ( position ) {\n\t\t\tif ( selection instanceof DocumentSelection ) {\n\t\t\t\tmodel.change( writer => {\n\t\t\t\t\twriter.setSelectionFocus( position );\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tselection.setFocus( position );\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\t}\n}\n\n// Checks whether the selection can be extended to the the walker's next value (next position).\n// @param {{ walker, unit, isForward, schema }} data\n// @param {module:engine/view/treewalker~TreeWalkerValue} value\nfunction tryExtendingTo( data, value ) {\n\t// If found text, we can certainly put the focus in it. Let's just find a correct position\n\t// based on the unit.\n\tif ( value.type == 'text' ) {\n\t\tif ( data.unit === 'word' ) {\n\t\t\treturn getCorrectWordBreakPosition( data.walker, data.isForward );\n\t\t}\n\n\t\treturn getCorrectPosition( data.walker, data.unit, data.isForward );\n\t}\n\n\t// Entering an element.\n\tif ( value.type == ( data.isForward ? 'elementStart' : 'elementEnd' ) ) {\n\t\t// If it's an object, we can select it now.\n\t\tif ( data.schema.isObject( value.item ) ) {\n\t\t\treturn Position._createAt( value.item, data.isForward ? 'after' : 'before' );\n\t\t}\n\n\t\t// If text allowed on this position, extend to this place.\n\t\tif ( data.schema.checkChild( value.nextPosition, '$text' ) ) {\n\t\t\treturn value.nextPosition;\n\t\t}\n\t}\n\t// Leaving an element.\n\telse {\n\t\t// If leaving a limit element, stop.\n\t\tif ( data.schema.isLimit( value.item ) ) {\n\t\t\t// NOTE: Fast-forward the walker until the end.\n\t\t\tdata.walker.skip( () => true );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// If text allowed on this position, extend to this place.\n\t\tif ( data.schema.checkChild( value.nextPosition, '$text' ) ) {\n\t\t\treturn value.nextPosition;\n\t\t}\n\t}\n}\n\n// Finds a correct position by walking in a text node and checking whether selection can be extended to given position\n// or should be extended further.\n//\n// @param {module:engine/model/treewalker~TreeWalker} walker\n// @param {String} unit The unit by which selection should be modified.\nfunction getCorrectPosition( walker, unit ) {\n\tconst textNode = walker.position.textNode;\n\n\tif ( textNode ) {\n\t\tconst data = textNode.data;\n\t\tlet offset = walker.position.offset - textNode.startOffset;\n\n\t\twhile ( isInsideSurrogatePair( data, offset ) || ( unit == 'character' && isInsideCombinedSymbol( data, offset ) ) ) {\n\t\t\twalker.next();\n\n\t\t\toffset = walker.position.offset - textNode.startOffset;\n\t\t}\n\t}\n\n\treturn walker.position;\n}\n\n// Finds a correct position of a word break by walking in a text node and checking whether selection can be extended to given position\n// or should be extended further.\n//\n// @param {module:engine/model/treewalker~TreeWalker} walker\n// @param {Boolean} isForward Is the direction in which the selection should be modified is forward.\nfunction getCorrectWordBreakPosition( walker, isForward ) {\n\tlet textNode = walker.position.textNode;\n\n\tif ( textNode ) {\n\t\tlet offset = walker.position.offset - textNode.startOffset;\n\n\t\twhile ( !isAtWordBoundary( textNode.data, offset, isForward ) && !isAtNodeBoundary( textNode, offset, isForward ) ) {\n\t\t\twalker.next();\n\n\t\t\t// Check of adjacent text nodes with different attributes (like BOLD).\n\t\t\t// Example : 'foofoo []bar<$text bold=\"true\">bar</$text> bazbaz'\n\t\t\t// should expand to : 'foofoo [bar<$text bold=\"true\">bar</$text>] bazbaz'.\n\t\t\tconst nextNode = isForward ? walker.position.nodeAfter : walker.position.nodeBefore;\n\n\t\t\t// Scan only text nodes. Ignore inline elements (like `<softBreak>`).\n\t\t\tif ( nextNode && nextNode.is( 'text' ) ) {\n\t\t\t\t// Check boundary char of an adjacent text node.\n\t\t\t\tconst boundaryChar = nextNode.data.charAt( isForward ? 0 : nextNode.data.length - 1 );\n\n\t\t\t\t// Go to the next node if the character at the boundary of that node belongs to the same word.\n\t\t\t\tif ( !wordBoundaryCharacters.includes( boundaryChar ) ) {\n\t\t\t\t\t// If adjacent text node belongs to the same word go to it & reset values.\n\t\t\t\t\twalker.next();\n\n\t\t\t\t\ttextNode = walker.position.textNode;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\toffset = walker.position.offset - textNode.startOffset;\n\t\t}\n\t}\n\n\treturn walker.position;\n}\n\nfunction getSearchRange( start, isForward ) {\n\tconst root = start.root;\n\tconst searchEnd = Position._createAt( root, isForward ? 'end' : 0 );\n\n\tif ( isForward ) {\n\t\treturn new Range( start, searchEnd );\n\t} else {\n\t\treturn new Range( searchEnd, start );\n\t}\n}\n\n// Checks if selection is on word boundary.\n//\n// @param {String} data The text node value to investigate.\n// @param {Number} offset Position offset.\n// @param {Boolean} isForward Is the direction in which the selection should be modified is forward.\nfunction isAtWordBoundary( data, offset, isForward ) {\n\t// The offset to check depends on direction.\n\tconst offsetToCheck = offset + ( isForward ? 0 : -1 );\n\n\treturn wordBoundaryCharacters.includes( data.charAt( offsetToCheck ) );\n}\n\n// Checks if selection is on node boundary.\n//\n// @param {module:engine/model/text~Text} textNode The text node to investigate.\n// @param {Number} offset Position offset.\n// @param {Boolean} isForward Is the direction in which the selection should be modified is forward.\nfunction isAtNodeBoundary( textNode, offset, isForward ) {\n\treturn offset === ( isForward ? textNode.endOffset : 0 );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/utils/getselectedcontent\n */\n\n/**\n * Gets a clone of the selected content.\n *\n * For example, for the following selection:\n *\n * ```html\n * <p>x</p><quote><p>y</p><h>fir[st</h></quote><p>se]cond</p><p>z</p>\n * ```\n *\n * It will return a document fragment with such a content:\n *\n * ```html\n * <quote><h>st</h></quote><p>se</p>\n * ```\n *\n * @param {module:engine/model/model~Model} model The model in context of which\n * the selection modification should be performed.\n * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection\n * The selection of which content will be returned.\n * @returns {module:engine/model/documentfragment~DocumentFragment}\n */\nexport default function getSelectedContent( model, selection ) {\n\treturn model.change( writer => {\n\t\tconst frag = writer.createDocumentFragment();\n\t\tconst range = selection.getFirstRange();\n\n\t\tif ( !range || range.isCollapsed ) {\n\t\t\treturn frag;\n\t\t}\n\n\t\tconst root = range.start.root;\n\t\tconst commonPath = range.start.getCommonPath( range.end );\n\t\tconst commonParent = root.getNodeByPath( commonPath );\n\n\t\t// ## 1st step\n\t\t//\n\t\t// First, we'll clone a fragment represented by a minimal flat range\n\t\t// containing the original range to be cloned.\n\t\t// E.g. let's consider such a range:\n\t\t//\n\t\t// <p>x</p><quote><p>y</p><h>fir[st</h></quote><p>se]cond</p><p>z</p>\n\t\t//\n\t\t// A minimal flat range containing this one is:\n\t\t//\n\t\t// <p>x</p>[<quote><p>y</p><h>first</h></quote><p>second</p>]<p>z</p>\n\t\t//\n\t\t// We can easily clone this structure, preserving e.g. the <quote> element.\n\t\tlet flatSubtreeRange;\n\n\t\tif ( range.start.parent == range.end.parent ) {\n\t\t\t// The original range is flat, so take it.\n\t\t\tflatSubtreeRange = range;\n\t\t} else {\n\t\t\tflatSubtreeRange = writer.createRange(\n\t\t\t\twriter.createPositionAt( commonParent, range.start.path[ commonPath.length ] ),\n\t\t\t\twriter.createPositionAt( commonParent, range.end.path[ commonPath.length ] + 1 )\n\t\t\t);\n\t\t}\n\n\t\tconst howMany = flatSubtreeRange.end.offset - flatSubtreeRange.start.offset;\n\n\t\t// Clone the whole contents.\n\t\tfor ( const item of flatSubtreeRange.getItems( { shallow: true } ) ) {\n\t\t\tif ( item.is( 'textProxy' ) ) {\n\t\t\t\twriter.appendText( item.data, item.getAttributes(), frag );\n\t\t\t} else {\n\t\t\t\twriter.append( item._clone( true ), frag );\n\t\t\t}\n\t\t}\n\n\t\t// ## 2nd step\n\t\t//\n\t\t// If the original range wasn't flat, then we need to remove the excess nodes from the both ends of the cloned fragment.\n\t\t//\n\t\t// For example, for the range shown in the 1st step comment, we need to remove these pieces:\n\t\t//\n\t\t// <quote>[<p>y</p>]<h>[fir]st</h></quote><p>se[cond]</p>\n\t\t//\n\t\t// So this will be the final copied content:\n\t\t//\n\t\t// <quote><h>st</h></quote><p>se</p>\n\t\t//\n\t\t// In order to do that, we remove content from these two ranges:\n\t\t//\n\t\t// [<quote><p>y</p><h>fir]st</h></quote><p>se[cond</p>]\n\t\tif ( flatSubtreeRange != range ) {\n\t\t\t// Find the position of the original range in the cloned fragment.\n\t\t\tconst newRange = range._getTransformedByMove( flatSubtreeRange.start, writer.createPositionAt( frag, 0 ), howMany )[ 0 ];\n\n\t\t\tconst leftExcessRange = writer.createRange( writer.createPositionAt( frag, 0 ), newRange.start );\n\t\t\tconst rightExcessRange = writer.createRange( newRange.end, writer.createPositionAt( frag, 'end' ) );\n\n\t\t\tremoveRangeContent( rightExcessRange, writer );\n\t\t\tremoveRangeContent( leftExcessRange, writer );\n\t\t}\n\n\t\treturn frag;\n\t} );\n}\n\n// After https://github.com/ckeditor/ckeditor5-engine/issues/690 is fixed,\n// this function will, most likely, be able to rewritten using getMinimalFlatRanges().\nfunction removeRangeContent( range, writer ) {\n\tconst parentsToCheck = [];\n\n\tArray.from( range.getItems( { direction: 'backward' } ) )\n\t\t// We should better store ranges because text proxies will lose integrity\n\t\t// with the text nodes when we'll start removing content.\n\t\t.map( item => writer.createRangeOn( item ) )\n\t\t// Filter only these items which are fully contained in the passed range.\n\t\t//\n\t\t// E.g. for the following range: [<quote><p>y</p><h>fir]st</h>\n\t\t// the walker will return the entire <h> element, when only the \"fir\" item inside it is fully contained.\n\t\t.filter( itemRange => {\n\t\t\t// We should be able to use Range.containsRange, but https://github.com/ckeditor/ckeditor5-engine/issues/691.\n\t\t\tconst contained =\n\t\t\t\t( itemRange.start.isAfter( range.start ) || itemRange.start.isEqual( range.start ) ) &&\n\t\t\t\t( itemRange.end.isBefore( range.end ) || itemRange.end.isEqual( range.end ) );\n\n\t\t\treturn contained;\n\t\t} )\n\t\t.forEach( itemRange => {\n\t\t\tparentsToCheck.push( itemRange.start.parent );\n\n\t\t\twriter.remove( itemRange );\n\t\t} );\n\n\t// Remove ancestors of the removed items if they turned to be empty now\n\t// (their whole content was contained in the range).\n\tparentsToCheck.forEach( parentToCheck => {\n\t\tlet parent = parentToCheck;\n\n\t\twhile ( parent.parent && parent.isEmpty ) {\n\t\t\tconst removeRange = writer.createRangeOn( parent );\n\n\t\t\tparent = parent.parent;\n\n\t\t\twriter.remove( removeRange );\n\t\t}\n\t} );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/utils/selection-post-fixer\n */\n\nimport Range from '../range';\nimport Position from '../position';\n\n/**\n * Injects selection post-fixer to the model.\n *\n * The role of the selection post-fixer is to ensure that the selection is in a correct place\n * after a {@link module:engine/model/model~Model#change `change()`} block was executed.\n *\n * The correct position means that:\n *\n * * All collapsed selection ranges are in a place where the {@link module:engine/model/schema~Schema}\n * allows a `$text`.\n * * None of the selection's non-collapsed ranges crosses a {@link module:engine/model/schema~Schema#isLimit limit element}\n * boundary (a range must be rooted within one limit element).\n * * Only {@link module:engine/model/schema~Schema#isObject object elements} can be selected from the outside\n * (e.g. `[<paragraph>foo</paragraph>]` is invalid). This rule applies independently to both selection ends, so this\n * selection is correct: `<paragraph>f[oo</paragraph><image></image>]`.\n *\n * If the position is not correct, the post-fixer will automatically correct it.\n *\n * ## Fixing a non-collapsed selection\n *\n * See as an example a selection that starts in a P1 element and ends inside the text of a TD element\n * (`[` and `]` are range boundaries and `(l)` denotes an element defined as `isLimit=true`):\n *\n *\t\troot\n *\t\t |- element P1\n *\t\t | |- \"foo\" root\n *\t\t |- element TABLE (l) P1 TABLE P2\n *\t\t | |- element TR (l) f o[o TR TR b a r\n *\t\t | | |- element TD (l) TD TD\n *\t\t | | |- \"aaa\" a]a a b b b\n *\t\t | |- element TR (l)\n *\t\t | | |- element TD (l) ||\n *\t\t | | |- \"bbb\" ||\n *\t\t |- element P2 VV\n *\t\t | |- \"bar\"\n *\t\t root\n *\t\t P1 TABLE] P2\n *\t\t f o[o TR TR b a r\n *\t\t TD TD\n *\t\t a a a b b b\n *\n * In the example above, the TABLE, TR and TD are defined as `isLimit=true` in the schema. The range which is not contained within\n * a single limit element must be expanded to select the outermost limit element. The range end is inside the text node of the TD element.\n * As the TD element is a child of the TR and TABLE elements, where both are defined as `isLimit=true` in the schema, the range must be\n * expanded to select the whole TABLE element.\n *\n * **Note** If the selection contains multiple ranges, the method returns a minimal set of ranges that are not intersecting after expanding\n * them to select `isLimit=true` elements.\n *\n * @param {module:engine/model/model~Model} model\n */\nexport function injectSelectionPostFixer( model ) {\n\tmodel.document.registerPostFixer( writer => selectionPostFixer( writer, model ) );\n}\n\n// The selection post-fixer.\n//\n// @param {module:engine/model/writer~Writer} writer\n// @param {module:engine/model/model~Model} model\nfunction selectionPostFixer( writer, model ) {\n\tconst selection = model.document.selection;\n\tconst schema = model.schema;\n\n\tconst ranges = [];\n\n\tlet wasFixed = false;\n\n\tfor ( const modelRange of selection.getRanges() ) {\n\t\t// Go through all ranges in selection and try fixing each of them.\n\t\t// Those ranges might overlap but will be corrected later.\n\t\tconst correctedRange = tryFixingRange( modelRange, schema );\n\n\t\tif ( correctedRange ) {\n\t\t\tranges.push( correctedRange );\n\t\t\twasFixed = true;\n\t\t} else {\n\t\t\tranges.push( modelRange );\n\t\t}\n\t}\n\n\t// If any of ranges were corrected update the selection.\n\tif ( wasFixed ) {\n\t\t// The above algorithm might create ranges that intersects each other when selection contains more then one range.\n\t\t// This is case happens mostly on Firefox which creates multiple ranges for selected table.\n\t\tlet fixedRanges = ranges;\n\n\t\t// Fixing selection with many ranges usually breaks the selection in Firefox. As only Firefox supports multiple selection ranges\n\t\t// we simply create one continuous range from fixed selection ranges (even if they are not adjacent).\n\t\tif ( ranges.length > 1 ) {\n\t\t\tconst selectionStart = ranges[ 0 ].start;\n\t\t\tconst selectionEnd = ranges[ ranges.length - 1 ].end;\n\n\t\t\tfixedRanges = [ new Range( selectionStart, selectionEnd ) ];\n\t\t}\n\n\t\twriter.setSelection( fixedRanges, { backward: selection.isBackward } );\n\t}\n}\n\n// Tries fixing a range if it's incorrect.\n//\n// @param {module:engine/model/range~Range} range\n// @param {module:engine/model/schema~Schema} schema\n// @returns {module:engine/model/range~Range|null} Returns fixed range or null if range is valid.\nfunction tryFixingRange( range, schema ) {\n\tif ( range.isCollapsed ) {\n\t\treturn tryFixingCollapsedRange( range, schema );\n\t}\n\n\treturn tryFixingNonCollapsedRage( range, schema );\n}\n\n// Tries to fix collapsed ranges.\n//\n// * Fixes situation when a range is in a place where $text is not allowed\n//\n// @param {module:engine/model/range~Range} range Collapsed range to fix.\n// @param {module:engine/model/schema~Schema} schema\n// @returns {module:engine/model/range~Range|null} Returns fixed range or null if range is valid.\nfunction tryFixingCollapsedRange( range, schema ) {\n\tconst originalPosition = range.start;\n\n\tconst nearestSelectionRange = schema.getNearestSelectionRange( originalPosition );\n\n\t// This might be null ie when editor data is empty.\n\t// In such cases there is no need to fix the selection range.\n\tif ( !nearestSelectionRange ) {\n\t\treturn null;\n\t}\n\n\tconst fixedPosition = nearestSelectionRange.start;\n\n\t// Fixed position is the same as original - no need to return corrected range.\n\tif ( originalPosition.isEqual( fixedPosition ) ) {\n\t\treturn null;\n\t}\n\n\t// Check single node selection (happens in tables).\n\tif ( fixedPosition.nodeAfter && schema.isLimit( fixedPosition.nodeAfter ) ) {\n\t\treturn new Range( fixedPosition, Position._createAfter( fixedPosition.nodeAfter ) );\n\t}\n\n\treturn new Range( fixedPosition );\n}\n\n// Tries to fix an expanded range.\n//\n// @param {module:engine/model/range~Range} range Expanded range to fix.\n// @param {module:engine/model/schema~Schema} schema\n// @returns {module:engine/model/range~Range|null} Returns fixed range or null if range is valid.\nfunction tryFixingNonCollapsedRage( range, schema ) {\n\tconst start = range.start;\n\tconst end = range.end;\n\n\tconst isTextAllowedOnStart = schema.checkChild( start, '$text' );\n\tconst isTextAllowedOnEnd = schema.checkChild( end, '$text' );\n\n\tconst startLimitElement = schema.getLimitElement( start );\n\tconst endLimitElement = schema.getLimitElement( end );\n\n\t// Ranges which both end are inside the same limit element (or root) might needs only minor fix.\n\tif ( startLimitElement === endLimitElement ) {\n\t\t// Range is valid when both position allows to place a text:\n\t\t// - <block>f[oobarba]z</block>\n\t\t// This would be \"fixed\" by a next check but as it will be the same it's better to return null so the selection stays the same.\n\t\tif ( isTextAllowedOnStart && isTextAllowedOnEnd ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Range that is on non-limit element (or is partially) must be fixed so it is placed inside the block around $text:\n\t\t// - [<block>foo</block>] -> <block>[foo]</block>\n\t\t// - [<block>foo]</block> -> <block>[foo]</block>\n\t\t// - <block>f[oo</block>] -> <block>f[oo]</block>\n\t\t// - [<block>foo</block><object></object>] -> <block>[foo</block><object></object>]\n\t\tif ( checkSelectionOnNonLimitElements( start, end, schema ) ) {\n\t\t\tconst isStartObject = start.nodeAfter && schema.isObject( start.nodeAfter );\n\t\t\tconst fixedStart = isStartObject ? null : schema.getNearestSelectionRange( start, 'forward' );\n\n\t\t\tconst isEndObject = end.nodeBefore && schema.isObject( end.nodeBefore );\n\t\t\tconst fixedEnd = isEndObject ? null : schema.getNearestSelectionRange( end, 'backward' );\n\n\t\t\t// The schema.getNearestSelectionRange might return null - if that happens use original position.\n\t\t\tconst rangeStart = fixedStart ? fixedStart.start : start;\n\t\t\tconst rangeEnd = fixedEnd ? fixedEnd.start : end;\n\n\t\t\treturn new Range( rangeStart, rangeEnd );\n\t\t}\n\t}\n\n\tconst isStartInLimit = startLimitElement && !startLimitElement.is( 'rootElement' );\n\tconst isEndInLimit = endLimitElement && !endLimitElement.is( 'rootElement' );\n\n\t// At this point we eliminated valid positions on text nodes so if one of range positions is placed inside a limit element\n\t// then the range crossed limit element boundaries and needs to be fixed.\n\tif ( isStartInLimit || isEndInLimit ) {\n\t\tconst bothInSameParent = ( start.nodeAfter && end.nodeBefore ) && start.nodeAfter.parent === end.nodeBefore.parent;\n\n\t\tconst expandStart = isStartInLimit && ( !bothInSameParent || !isInObject( start.nodeAfter, schema ) );\n\t\tconst expandEnd = isEndInLimit && ( !bothInSameParent || !isInObject( end.nodeBefore, schema ) );\n\n\t\t// Although we've already found limit element on start/end positions we must find the outer-most limit element.\n\t\t// as limit elements might be nested directly inside (ie table > tableRow > tableCell).\n\t\tlet fixedStart = start;\n\t\tlet fixedEnd = end;\n\n\t\tif ( expandStart ) {\n\t\t\tfixedStart = Position._createBefore( findOutermostLimitAncestor( startLimitElement, schema ) );\n\t\t}\n\n\t\tif ( expandEnd ) {\n\t\t\tfixedEnd = Position._createAfter( findOutermostLimitAncestor( endLimitElement, schema ) );\n\t\t}\n\n\t\treturn new Range( fixedStart, fixedEnd );\n\t}\n\n\t// Range was not fixed at this point so it is valid - ie it was placed around limit element already.\n\treturn null;\n}\n\n// Finds the outer-most ancestor.\n//\n// @param {module:engine/model/node~Node} startingNode\n// @param {module:engine/model/schema~Schema} schema\n// @param {String} expandToDirection Direction of expansion - either 'start' or 'end' of the range.\n// @returns {module:engine/model/node~Node}\nfunction findOutermostLimitAncestor( startingNode, schema ) {\n\tlet isLimitNode = startingNode;\n\tlet parent = isLimitNode;\n\n\t// Find outer most isLimit block as such blocks might be nested (ie. in tables).\n\twhile ( schema.isLimit( parent ) && parent.parent ) {\n\t\tisLimitNode = parent;\n\t\tparent = parent.parent;\n\t}\n\n\treturn isLimitNode;\n}\n\n// Checks whether any of range boundaries is placed around non-limit elements.\n//\n// @param {module:engine/model/position~Position} start\n// @param {module:engine/model/position~Position} end\n// @param {module:engine/model/schema~Schema} schema\n// @returns {Boolean}\nfunction checkSelectionOnNonLimitElements( start, end, schema ) {\n\tconst startIsOnBlock = ( start.nodeAfter && !schema.isLimit( start.nodeAfter ) ) || schema.checkChild( start, '$text' );\n\tconst endIsOnBlock = ( end.nodeBefore && !schema.isLimit( end.nodeBefore ) ) || schema.checkChild( end, '$text' );\n\n\t// We should fix such selection when one of those nodes needs fixing.\n\treturn startIsOnBlock || endIsOnBlock;\n}\n\n// Checks if node exists and if it's an object.\n//\n// @param {module:engine/model/node~Node} node\n// @param {module:engine/model/schema~Schema} schema\n// @returns {Boolean}\nfunction isInObject( node, schema ) {\n\treturn node && schema.isObject( node );\n}\n\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/model\n */\n\nimport Batch from './batch';\nimport Writer from './writer';\nimport Schema from './schema';\nimport Document from './document';\nimport MarkerCollection from './markercollection';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport ModelElement from './element';\nimport ModelRange from './range';\nimport ModelPosition from './position';\nimport ModelSelection from './selection';\n\nimport insertContent from './utils/insertcontent';\nimport deleteContent from './utils/deletecontent';\nimport modifySelection from './utils/modifyselection';\nimport getSelectedContent from './utils/getselectedcontent';\nimport { injectSelectionPostFixer } from './utils/selection-post-fixer';\n\n/**\n * Editor's data model. Read about the model in the\n * {@glink framework/guides/architecture/editing-engine engine architecture guide}.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Model {\n\tconstructor() {\n\t\t/**\n\t\t * Model's marker collection.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/markercollection~MarkerCollection}\n\t\t */\n\t\tthis.markers = new MarkerCollection();\n\n\t\t/**\n\t\t * Model's document.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/document~Document}\n\t\t */\n\t\tthis.document = new Document( this );\n\n\t\t/**\n\t\t * Model's schema.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/schema~Schema}\n\t\t */\n\t\tthis.schema = new Schema();\n\n\t\t/**\n\t\t * All callbacks added by {@link module:engine/model/model~Model#change} or\n\t\t * {@link module:engine/model/model~Model#enqueueChange} methods waiting to be executed.\n\t\t *\n\t\t * @private\n\t\t * @type {Array.<Function>}\n\t\t */\n\t\tthis._pendingChanges = [];\n\n\t\t/**\n\t\t * The last created and currently used writer instance.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/writer~Writer}\n\t\t */\n\t\tthis._currentWriter = null;\n\n\t\t[ 'insertContent', 'deleteContent', 'modifySelection', 'getSelectedContent', 'applyOperation' ]\n\t\t\t.forEach( methodName => this.decorate( methodName ) );\n\n\t\t// Adding operation validation with `highest` priority, so it is called before any other feature would like\n\t\t// to do anything with the operation. If the operation has incorrect parameters it should throw on the earliest occasion.\n\t\tthis.on( 'applyOperation', ( evt, args ) => {\n\t\t\tconst operation = args[ 0 ];\n\n\t\t\toperation._validate();\n\t\t}, { priority: 'highest' } );\n\n\t\t// Register some default abstract entities.\n\t\tthis.schema.register( '$root', {\n\t\t\tisLimit: true\n\t\t} );\n\t\tthis.schema.register( '$block', {\n\t\t\tallowIn: '$root',\n\t\t\tisBlock: true\n\t\t} );\n\t\tthis.schema.register( '$text', {\n\t\t\tallowIn: '$block',\n\t\t\tisInline: true\n\t\t} );\n\t\tthis.schema.register( '$clipboardHolder', {\n\t\t\tallowContentOf: '$root',\n\t\t\tisLimit: true\n\t\t} );\n\t\tthis.schema.extend( '$text', { allowIn: '$clipboardHolder' } );\n\n\t\t// An element needed by the `upcastElementToMarker` converter.\n\t\t// This element temporarily represents a marker boundary during the conversion process and is removed\n\t\t// at the end of the conversion. `UpcastDispatcher` or at least `Conversion` class looks like a\n\t\t// better place for this registration but both know nothing about `Schema`.\n\t\tthis.schema.register( '$marker' );\n\t\tthis.schema.addChildCheck( ( context, childDefinition ) => {\n\t\t\tif ( childDefinition.name === '$marker' ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} );\n\n\t\tinjectSelectionPostFixer( this );\n\t}\n\n\t/**\n\t * The `change()` method is the primary way of changing the model. You should use it to modify all document nodes\n\t * (including detached nodes – i.e. nodes not added to the {@link module:engine/model/model~Model#document model document}),\n\t * the {@link module:engine/model/document~Document#selection document's selection}, and\n\t * {@link module:engine/model/model~Model#markers model markers}.\n\t *\n\t *\t\tmodel.change( writer => {\n\t *\t\t\twriter.insertText( 'foo', paragraph, 'end' );\n\t *\t\t} );\n\t *\n\t * All changes inside the change block use the same {@link module:engine/model/batch~Batch} so they are combined\n\t * into a single undo step.\n\t *\n\t *\t\tmodel.change( writer => {\n\t *\t\t\twriter.insertText( 'foo', paragraph, 'end' ); // foo.\n\t *\n\t *\t\t\tmodel.change( writer => {\n\t *\t\t\t\twriter.insertText( 'bar', paragraph, 'end' ); // foobar.\n\t *\t\t\t} );\n\t *\n\t * \t\t\twriter.insertText( 'bom', paragraph, 'end' ); // foobarbom.\n\t *\t\t} );\n\t *\n\t * The callback of the `change()` block is executed synchronously.\n\t *\n\t * You can also return a value from the change block.\n\t *\n\t *\t\tconst img = model.change( writer => {\n\t *\t\t\treturn writer.createElement( 'img' );\n\t *\t\t} );\n\t *\n\t * @see #enqueueChange\n\t * @param {Function} callback Callback function which may modify the model.\n\t * @returns {*} Value returned by the callback.\n\t */\n\tchange( callback ) {\n\t\tif ( this._pendingChanges.length === 0 ) {\n\t\t\t// If this is the outermost block, create a new batch and start `_runPendingChanges` execution flow.\n\t\t\tthis._pendingChanges.push( { batch: new Batch(), callback } );\n\n\t\t\treturn this._runPendingChanges()[ 0 ];\n\t\t} else {\n\t\t\t// If this is not the outermost block, just execute the callback.\n\t\t\treturn callback( this._currentWriter );\n\t\t}\n\t}\n\n\t/**\n\t * The `enqueueChange()` method performs similar task as the {@link #change `change()` method}, with two major differences.\n\t *\n\t * First, the callback of `enqueueChange()` is executed when all other enqueued changes are done. It might be executed\n\t * immediately if it is not nested in any other change block, but if it is nested in another (enqueue)change block,\n\t * it will be delayed and executed after the outermost block.\n\t *\n\t *\t\tmodel.change( writer => {\n\t *\t\t\tconsole.log( 1 );\n\t *\n\t *\t\t\tmodel.enqueueChange( writer => {\n\t *\t\t\t\tconsole.log( 2 );\n\t *\t\t\t} );\n\t *\n\t * \t\t\tconsole.log( 3 );\n\t *\t\t} ); // Will log: 1, 3, 2.\n\t *\n\t * Second, it lets you define the {@link module:engine/model/batch~Batch} into which you want to add your changes.\n\t * By default, a new batch is created. In the sample above, `change` and `enqueueChange` blocks use a different\n\t * batch (and different {@link module:engine/model/writer~Writer} since each of them operates on the separate batch).\n\t *\n\t * When using the `enqueueChange()` block you can also add some changes to the batch you used before.\n\t *\n\t *\t\tmodel.enqueueChange( batch, writer => {\n\t *\t\t\twriter.insertText( 'foo', paragraph, 'end' );\n\t *\t\t} );\n\t *\n\t * The batch instance can be obtained from {@link module:engine/model/writer~Writer#batch the writer}.\n\t *\n\t * @param {module:engine/model/batch~Batch|'transparent'|'default'} batchOrType Batch or batch type should be used in the callback.\n\t * If not defined, a new batch will be created.\n\t * @param {Function} callback Callback function which may modify the model.\n\t */\n\tenqueueChange( batchOrType, callback ) {\n\t\tif ( typeof batchOrType === 'string' ) {\n\t\t\tbatchOrType = new Batch( batchOrType );\n\t\t} else if ( typeof batchOrType == 'function' ) {\n\t\t\tcallback = batchOrType;\n\t\t\tbatchOrType = new Batch();\n\t\t}\n\n\t\tthis._pendingChanges.push( { batch: batchOrType, callback } );\n\n\t\tif ( this._pendingChanges.length == 1 ) {\n\t\t\tthis._runPendingChanges();\n\t\t}\n\t}\n\n\t/**\n\t * {@link module:utils/observablemixin~ObservableMixin#decorate Decorated} function for applying\n\t * {@link module:engine/model/operation/operation~Operation operations} to the model.\n\t *\n\t * This is a low-level way of changing the model. It is exposed for very specific use cases (like the undo feature).\n\t * Normally, to modify the model, you will want to use {@link module:engine/model/writer~Writer `Writer`}.\n\t * See also {@glink framework/guides/architecture/editing-engine#changing-the-model Changing the model} section\n\t * of the {@glink framework/guides/architecture/editing-engine Editing architecture} guide.\n\t *\n\t * @param {module:engine/model/operation/operation~Operation} operation The operation to apply.\n\t */\n\tapplyOperation( operation ) {\n\t\toperation._execute();\n\t}\n\n\t/**\n\t * Inserts content at the position in the editor specified by the selection, as one would expect the paste\n\t * functionality to work.\n\t *\n\t * This is a high-level method. It takes the {@link #schema schema} into consideration when inserting\n\t * the content, clears the given selection's content before inserting nodes and moves the selection\n\t * to its target position at the end of the process.\n\t * It can split elements, merge them, wrap bare text nodes with paragraphs, etc. &mdash; just like the\n\t * pasting feature should do.\n\t *\n\t * For lower-level methods see {@link module:engine/model/writer~Writer `Writer`}.\n\t *\n\t * This method, unlike {@link module:engine/model/writer~Writer `Writer`}'s methods, does not have to be used\n\t * inside a {@link #change `change()` block}.\n\t *\n\t * # Conversion and schema\n\t *\n\t * Inserting elements and text nodes into the model is not enough to make CKEditor 5 render that content\n\t * to the user. CKEditor 5 implements a model-view-controller architecture and what `model.insertContent()` does\n\t * is only adding nodes to the model. Additionally, you need to define\n\t * {@glink framework/guides/architecture/editing-engine#conversion converters} between the model and view\n\t * and define those nodes in the {@glink framework/guides/architecture/editing-engine#schema schema}.\n\t *\n\t * So, while this method may seem similar to CKEditor 4 `editor.insertHtml()` (in fact, both methods\n\t * are used for paste-like content insertion), the CKEditor 5 method cannot be use to insert arbitrary HTML\n\t * unless converters are defined for all elements and attributes in that HTML.\n\t *\n\t * # Examples\n\t *\n\t * Using `insertContent()` with a manually created model structure:\n\t *\n\t *\t\t// Let's create a document fragment containing such content as:\n\t *\t\t//\n\t *\t\t// <paragrap>foo</paragraph>\n\t *\t\t// <blockQuote>\n\t *\t\t// <paragraph>bar</paragraph>\n\t *\t\t// </blockQuote>\n\t *\t\tconst docFrag = editor.model.change( writer => {\n\t *\t\t\tconst p1 = writer.createElement( 'paragraph' );\n\t *\t\t\tconst p2 = writer.createElement( 'paragraph' );\n\t *\t\t\tconst blockQuote = writer.createElement( 'blockQuote' );\n\t *\t\t\tconst docFrag = writer.createDocumentFragment();\n\t *\n\t *\t\t\twriter.append( p1, docFrag );\n\t *\t\t\twriter.append( blockQuote, docFrag );\n\t *\t\t\twriter.append( p2, blockQuote );\n\t *\t\t\twriter.insertText( 'foo', p1 );\n\t *\t\t\twriter.insertText( 'bar', p2 );\n\t *\n\t *\t\t\treturn docFrag;\n\t *\t\t} );\n\t *\n\t *\t\t// insertContent() does not have to be used in a change() block. It can, though,\n\t *\t\t// so this code could be moved to the callback defined above.\n\t *\t\teditor.model.insertContent( docFrag );\n\t *\n\t * Using `insertContent()` with an HTML string converted to a model document fragment (similar to the pasting mechanism):\n\t *\n\t *\t\t// You can create your own HtmlDataProcessor instance or use editor.data.processor\n\t *\t\t// if you have not overridden the default one (which is the HtmlDataProcessor instance).\n\t *\t\tconst htmlDP = new HtmlDataProcessor();\n\t *\n\t *\t\t// Convert an HTML string to a view document fragment:\n\t *\t\tconst viewFragment = htmlDP.toView( htmlString );\n\t *\n\t *\t\t// Convert the view document fragment to a model document fragment\n\t *\t\t// in the context of $root. This conversion takes the schema into\n\t *\t\t// account so if, for example, the view document fragment contained a bare text node,\n\t *\t\t// this text node cannot be a child of $root, so it will be automatically\n\t *\t\t// wrapped with a <paragraph>. You can define the context yourself (in the second parameter),\n\t *\t\t// and e.g. convert the content like it would happen in a <paragraph>.\n\t *\t\t// Note: The clipboard feature uses a custom context called $clipboardHolder\n\t *\t\t// which has a loosened schema.\n\t *\t\tconst modelFragment = editor.data.toModel( viewFragment );\n\t *\n\t *\t\teditor.model.insertContent( modelFragment );\n\t *\n\t * By default this method will use the document selection but it can also be used with a position, range or selection instance.\n\t *\n\t *\t\t// Insert text at the current document selection position.\n\t *\t\teditor.model.change( writer => {\n\t *\t\t\teditor.model.insertContent( writer.createText( 'x' ) );\n\t *\t\t} );\n\t *\n\t *\t\t// Insert text at a given position - the document selection will not be modified.\n\t *\t\teditor.model.change( writer => {\n\t *\t\t\teditor.model.insertContent( writer.createText( 'x' ), doc.getRoot(), 2 );\n\t *\n\t *\t\t\t// Which is a shorthand for:\n\t *\t\t\teditor.model.insertContent( writer.createText( 'x' ), writer.createPositionAt( doc.getRoot(), 2 ) );\n\t *\t\t} );\n\t *\n\t * If an instance of {@link module:engine/model/selection~Selection} is passed as `selectable`\n\t * it will be moved to the target position (where the document selection should be moved after the insertion).\n\t *\n\t *\t\teditor.model.change( writer => {\n\t *\t\t\t// Insert text replacing the given selection instance.\n\t *\t\t\tconst selection = writer.createSelection( paragraph, 'in' );\n\t *\n\t *\t\t\teditor.model.insertContent( writer.createText( 'x' ), selection );\n\t *\n\t *\t\t\t// insertContent() modifies the passed selection instance so it can be used to set the document selection.\n\t *\t\t\t// Note: This is not necessary when you passed the document selection to insertContent().\n\t *\t\t\twriter.setSelection( selection );\n\t *\t\t} );\n\t *\n\t * @fires insertContent\n\t * @param {module:engine/model/documentfragment~DocumentFragment|module:engine/model/item~Item} content The content to insert.\n\t * @param {module:engine/model/selection~Selectable} [selectable=model.document.selection]\n\t * The selection into which the content should be inserted. If not provided the current model document selection will be used.\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] To be used when a model item was passed as `selectable`.\n\t * This param defines a position in relation to that item.\n\t * @returns {module:engine/model/range~Range} Range which contains all the performed changes. This is a range that, if removed,\n\t * would return the model to the state before the insertion. If no changes were preformed by `insertContent`, returns a range collapsed\n\t * at the insertion position.\n\t */\n\tinsertContent( content, selectable, placeOrOffset ) {\n\t\treturn insertContent( this, content, selectable, placeOrOffset );\n\t}\n\n\t/**\n\t * Deletes content of the selection and merge siblings. The resulting selection is always collapsed.\n\t *\n\t * **Note:** For the sake of predictability, the resulting selection should always be collapsed.\n\t * In cases where a feature wants to modify deleting behavior so selection isn't collapsed\n\t * (e.g. a table feature may want to keep row selection after pressing <kbd>Backspace</kbd>),\n\t * then that behavior should be implemented in the view's listener. At the same time, the table feature\n\t * will need to modify this method's behavior too, e.g. to \"delete contents and then collapse\n\t * the selection inside the last selected cell\" or \"delete the row and collapse selection somewhere near\".\n\t * That needs to be done in order to ensure that other features which use `deleteContent()` will work well with tables.\n\t *\n\t * @fires deleteContent\n\t * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection\n\t * Selection of which the content should be deleted.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.leaveUnmerged=false] Whether to merge elements after removing the content of the selection.\n\t *\n\t * For example `<heading1>x[x</heading1><paragraph>y]y</paragraph>` will become:\n\t *\n\t * * `<heading1>x^y</heading1>` with the option disabled (`leaveUnmerged == false`)\n\t * * `<heading1>x^</heading1><paragraph>y</paragraph>` with enabled (`leaveUnmerged == true`).\n\t *\n\t * Note: {@link module:engine/model/schema~Schema#isObject object} and {@link module:engine/model/schema~Schema#isLimit limit}\n\t * elements will not be merged.\n\t *\n\t * @param {Boolean} [options.doNotResetEntireContent=false] Whether to skip replacing the entire content with a\n\t * paragraph when the entire content was selected.\n\t *\n\t * For example `<heading1>[x</heading1><paragraph>y]</paragraph>` will become:\n\t *\n\t * * `<paragraph>^</paragraph>` with the option disabled (`doNotResetEntireContent == false`)\n\t * * `<heading1>^</heading1>` with enabled (`doNotResetEntireContent == true`)\n\t *\n\t * @param {Boolean} [options.doNotAutoparagraph=false] Whether to create a paragraph if after content deletion selection is moved\n\t * to a place where text cannot be inserted.\n\t *\n\t * For example `<paragraph>x</paragraph>[<image src=\"foo.jpg\"></image>]` will become:\n\t *\n\t * * `<paragraph>x</paragraph><paragraph>[]</paragraph>` with the option disabled (`doNotAutoparagraph == false`)\n\t * * `<paragraph>x[]</paragraph>` with the option enabled (`doNotAutoparagraph == true`).\n\t *\n\t * **Note:** if there is no valid position for the selection, the paragraph will always be created:\n\t *\n\t * `[<image src=\"foo.jpg\"></image>]` -> `<paragraph>[]</paragraph>`.\n\t */\n\tdeleteContent( selection, options ) {\n\t\tdeleteContent( this, selection, options );\n\t}\n\n\t/**\n\t * Modifies the selection. Currently, the supported modifications are:\n\t *\n\t * * Extending. The selection focus is moved in the specified `options.direction` with a step specified in `options.unit`.\n\t * Possible values for `unit` are:\n\t * * `'character'` (default) - moves selection by one user-perceived character. In most cases this means moving by one\n\t * character in `String` sense. However, unicode also defines \"combing marks\". These are special symbols, that combines\n\t * with a symbol before it (\"base character\") to create one user-perceived character. For example, `q̣̇` is a normal\n\t * letter `q` with two \"combining marks\": upper dot (`Ux0307`) and lower dot (`Ux0323`). For most actions, i.e. extending\n\t * selection by one position, it is correct to include both \"base character\" and all of it's \"combining marks\". That is\n\t * why `'character'` value is most natural and common method of modifying selection.\n\t * * `'codePoint'` - moves selection by one unicode code point. In contrary to, `'character'` unit, this will insert\n\t * selection between \"base character\" and \"combining mark\", because \"combining marks\" have their own unicode code points.\n\t * However, for technical reasons, unicode code points with values above `UxFFFF` are represented in native `String` by\n\t * two characters, called \"surrogate pairs\". Halves of \"surrogate pairs\" have a meaning only when placed next to each other.\n\t * For example `𨭎` is represented in `String` by `\\uD862\\uDF4E`. Both `\\uD862` and `\\uDF4E` do not have any meaning\n\t * outside the pair (are rendered as ? when alone). Position between them would be incorrect. In this case, selection\n\t * extension will include whole \"surrogate pair\".\n\t * * `'word'` - moves selection by a whole word.\n\t *\n\t * **Note:** if you extend a forward selection in a backward direction you will in fact shrink it.\n\t *\n\t * @fires modifySelection\n\t * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection\n\t * The selection to modify.\n\t * @param {Object} [options]\n\t * @param {'forward'|'backward'} [options.direction='forward'] The direction in which the selection should be modified.\n\t * @param {'character'|'codePoint'|'word'} [options.unit='character'] The unit by which selection should be modified.\n\t */\n\tmodifySelection( selection, options ) {\n\t\tmodifySelection( this, selection, options );\n\t}\n\n\t/**\n\t * Gets a clone of the selected content.\n\t *\n\t * For example, for the following selection:\n\t *\n\t * ```html\n\t * <paragraph>x</paragraph>\n\t * <blockQuote>\n\t *\t<paragraph>y</paragraph>\n\t *\t<heading1>fir[st</heading1>\n\t * </blockQuote>\n\t * <paragraph>se]cond</paragraph>\n\t * <paragraph>z</paragraph>\n\t * ```\n\t *\n\t * It will return a document fragment with such a content:\n\t *\n\t * ```html\n\t * <blockQuote>\n\t *\t<heading1>st</heading1>\n\t * </blockQuote>\n\t * <paragraph>se</paragraph>\n\t * ```\n\t *\n\t * @fires getSelectedContent\n\t * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection\n\t * The selection of which content will be returned.\n\t * @returns {module:engine/model/documentfragment~DocumentFragment}\n\t */\n\tgetSelectedContent( selection ) {\n\t\treturn getSelectedContent( this, selection );\n\t}\n\n\t/**\n\t * Checks whether the given {@link module:engine/model/range~Range range} or\n\t * {@link module:engine/model/element~Element element} has any meaningful content.\n\t *\n\t * Meaningful content is:\n\t *\n\t * * any text node (`options.ignoreWhitespaces` allows controlling whether this text node must also contain\n\t * any non-whitespace characters),\n\t * * or any {@link module:engine/model/schema~Schema#isObject object element},\n\t * * or any {@link module:engine/model/markercollection~Marker marker} which\n\t * {@link module:engine/model/markercollection~Marker#_affectsData affects data}.\n\t *\n\t * This means that a range containing an empty `<paragraph></paragraph>` is not considered to have a meaningful content.\n\t * However, a range containing an `<image></image>` (which would normally be marked in the schema as an object element)\n\t * is considered non-empty.\n\t *\n\t * @param {module:engine/model/range~Range|module:engine/model/element~Element} rangeOrElement Range or element to check.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.ignoreWhitespaces] Whether text node with whitespaces only should be considered empty.\n\t * @returns {Boolean}\n\t */\n\thasContent( rangeOrElement, options ) {\n\t\tconst range = rangeOrElement instanceof ModelElement ? ModelRange._createIn( rangeOrElement ) : rangeOrElement;\n\n\t\tif ( range.isCollapsed ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check if there are any markers which affects data in this given range.\n\t\tfor ( const intersectingMarker of this.markers.getMarkersIntersectingRange( range ) ) {\n\t\t\tif ( intersectingMarker.affectsData ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tconst { ignoreWhitespaces = false } = options || {};\n\n\t\tfor ( const item of range.getItems() ) {\n\t\t\tif ( item.is( 'textProxy' ) ) {\n\t\t\t\tif ( !ignoreWhitespaces ) {\n\t\t\t\t\treturn true;\n\t\t\t\t} else if ( item.data.search( /\\S/ ) !== -1 ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} else if ( this.schema.isObject( item ) ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Creates a position from the given root and path in that root.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createPositionFromPath `Writer#createPositionFromPath()`}.\n\t *\n\t * @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} root Root of the position.\n\t * @param {Array.<Number>} path Position path. See {@link module:engine/model/position~Position#path}.\n\t * @param {module:engine/model/position~PositionStickiness} [stickiness='toNone'] Position stickiness.\n\t * See {@link module:engine/model/position~PositionStickiness}.\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tcreatePositionFromPath( root, path, stickiness ) {\n\t\treturn new ModelPosition( root, path, stickiness );\n\t}\n\n\t/**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/model/position~Position position},\n\t * * a parent element and offset in that element,\n\t * * a parent element and `'end'` (the position will be set at the end of that element),\n\t * * a {@link module:engine/model/item~Item model item} and `'before'` or `'after'`\n\t * (the position will be set before or after the given model item).\n\t *\n\t * This method is a shortcut to other factory methods such as:\n\t *\n\t * * {@link module:engine/model/model~Model#createPositionBefore `createPositionBefore()`},\n\t * * {@link module:engine/model/model~Model#createPositionAfter `createPositionAfter()`}.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createPositionAt `Writer#createPositionAt()`},\n\t *\n\t * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tcreatePositionAt( itemOrPosition, offset ) {\n\t\treturn ModelPosition._createAt( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Creates a new position after the given {@link module:engine/model/item~Item model item}.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createPositionAfter `Writer#createPositionAfter()`}.\n\t *\n\t * @param {module:engine/model/item~Item} item Item after which the position should be placed.\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tcreatePositionAfter( item ) {\n\t\treturn ModelPosition._createAfter( item );\n\t}\n\n\t/**\n\t * Creates a new position before the given {@link module:engine/model/item~Item model item}.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createPositionBefore `Writer#createPositionBefore()`}.\n\t *\n\t * @param {module:engine/model/item~Item} item Item before which the position should be placed.\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tcreatePositionBefore( item ) {\n\t\treturn ModelPosition._createBefore( item );\n\t}\n\n\t/**\n\t * Creates a range spanning from the `start` position to the `end` position.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createRange `Writer#createRange()`}:\n\t *\n\t *\t\tmodel.change( writer => {\n\t *\t\t\tconst range = writer.createRange( start, end );\n\t *\t\t} );\n\t *\n\t * @param {module:engine/model/position~Position} start Start position.\n\t * @param {module:engine/model/position~Position} [end] End position. If not set, the range will be collapsed\n\t * to the `start` position.\n\t * @returns {module:engine/model/range~Range}\n\t */\n\tcreateRange( start, end ) {\n\t\treturn new ModelRange( start, end );\n\t}\n\n\t/**\n\t * Creates a range inside the given element which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createRangeIn `Writer#createRangeIn()`}:\n\t *\n\t *\t\tmodel.change( writer => {\n\t *\t\t\tconst range = writer.createRangeIn( paragraph );\n\t *\t\t} );\n\t *\n\t * @param {module:engine/model/element~Element} element Element which is a parent for the range.\n\t * @returns {module:engine/model/range~Range}\n\t */\n\tcreateRangeIn( element ) {\n\t\treturn ModelRange._createIn( element );\n\t}\n\n\t/**\n\t * Creates a range that starts before the given {@link module:engine/model/item~Item model item} and ends after it.\n\t *\n\t * Note: This method is also available on `writer` instance as\n\t * {@link module:engine/model/writer~Writer#createRangeOn `Writer.createRangeOn()`}:\n\t *\n\t *\t\tmodel.change( writer => {\n\t *\t\t\tconst range = writer.createRangeOn( paragraph );\n\t *\t\t} );\n\t *\n\t * @param {module:engine/model/item~Item} item\n\t * @returns {module:engine/model/range~Range}\n\t */\n\tcreateRangeOn( item ) {\n\t\treturn ModelRange._createOn( item );\n\t}\n\n\t/**\n\t * Creates a new selection instance based on the given {@link module:engine/model/selection~Selectable selectable}\n\t * or creates an empty selection if no arguments were passed.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createSelection `Writer#createSelection()`}.\n\t *\n\t *\t\t// Creates empty selection without ranges.\n\t *\t\tconst selection = writer.createSelection();\n\t *\n\t *\t\t// Creates selection at the given range.\n\t *\t\tconst range = writer.createRange( start, end );\n\t *\t\tconst selection = writer.createSelection( range );\n\t *\n\t *\t\t// Creates selection at the given ranges\n\t *\t\tconst ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t *\t\tconst selection = writer.createSelection( ranges );\n\t *\n\t *\t\t// Creates selection from the other selection.\n\t *\t\t// Note: It doesn't copies selection attributes.\n\t *\t\tconst otherSelection = writer.createSelection();\n\t *\t\tconst selection = writer.createSelection( otherSelection );\n\t *\n\t *\t\t// Creates selection from the given document selection.\n\t *\t\t// Note: It doesn't copies selection attributes.\n\t *\t\tconst documentSelection = model.document.selection;\n\t *\t\tconst selection = writer.createSelection( documentSelection );\n\t *\n\t *\t\t// Creates selection at the given position.\n\t *\t\tconst position = writer.createPositionFromPath( root, path );\n\t *\t\tconst selection = writer.createSelection( position );\n\t *\n\t *\t\t// Creates selection at the given offset in the given element.\n\t *\t\tconst paragraph = writer.createElement( 'paragraph' );\n\t *\t\tconst selection = writer.createSelection( paragraph, offset );\n\t *\n\t *\t\t// Creates a range inside an {@link module:engine/model/element~Element element} which starts before the\n\t *\t\t// first child of that element and ends after the last child of that element.\n\t *\t\tconst selection = writer.createSelection( paragraph, 'in' );\n\t *\n\t *\t\t// Creates a range on an {@link module:engine/model/item~Item item} which starts before the item and ends\n\t *\t\t// just after the item.\n\t *\t\tconst selection = writer.createSelection( paragraph, 'on' );\n\t *\n\t *\t\t// Additional options (`'backward'`) can be specified as the last argument.\n\t *\n\t *\t\t// Creates backward selection.\n\t *\t\tconst selection = writer.createSelection( range, { backward: true } );\n\t *\n\t * @param {module:engine/model/selection~Selectable} selectable\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Sets place or offset of the selection.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.backward] Sets this selection instance to be backward.\n\t * @returns {module:engine/model/selection~Selection}\n\t */\n\tcreateSelection( selectable, placeOrOffset, options ) {\n\t\treturn new ModelSelection( selectable, placeOrOffset, options );\n\t}\n\n\t/**\n\t * Creates a {@link module:engine/model/batch~Batch} instance.\n\t *\n\t * **Note:** In most cases creating a batch instance is not necessary as they are created when using:\n\t *\n\t * * {@link #change `change()`},\n\t * * {@link #enqueueChange `enqueueChange()`}.\n\t *\n\t * @returns {module:engine/model/batch~Batch}\n\t */\n\tcreateBatch() {\n\t\treturn new Batch();\n\t}\n\n\t/**\n\t * Removes all events listeners set by model instance and destroys {@link module:engine/model/document~Document}.\n\t */\n\tdestroy() {\n\t\tthis.document.destroy();\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Common part of {@link module:engine/model/model~Model#change} and {@link module:engine/model/model~Model#enqueueChange}\n\t * which calls callbacks and returns array of values returned by these callbacks.\n\t *\n\t * @private\n\t * @returns {Array.<*>} Array of values returned by callbacks.\n\t */\n\t_runPendingChanges() {\n\t\tconst ret = [];\n\n\t\tthis.fire( '_beforeChanges' );\n\n\t\twhile ( this._pendingChanges.length ) {\n\t\t\t// Create a new writer using batch instance created for this chain of changes.\n\t\t\tconst currentBatch = this._pendingChanges[ 0 ].batch;\n\t\t\tthis._currentWriter = new Writer( this, currentBatch );\n\n\t\t\t// Execute changes callback and gather the returned value.\n\t\t\tconst callbackReturnValue = this._pendingChanges[ 0 ].callback( this._currentWriter );\n\t\t\tret.push( callbackReturnValue );\n\n\t\t\tthis.document._handleChangeBlock( this._currentWriter );\n\n\t\t\tthis._pendingChanges.shift();\n\t\t\tthis._currentWriter = null;\n\t\t}\n\n\t\tthis.fire( '_afterChanges' );\n\n\t\treturn ret;\n\t}\n\n\t/**\n\t * Fired when entering the outermost {@link module:engine/model/model~Model#enqueueChange} or\n\t * {@link module:engine/model/model~Model#change} block.\n\t *\n\t * @protected\n\t * @event _beforeChanges\n\t */\n\n\t/**\n\t * Fired when leaving the outermost {@link module:engine/model/model~Model#enqueueChange} or\n\t * {@link module:engine/model/model~Model#change} block.\n\t *\n\t * @protected\n\t * @event _afterChanges\n\t */\n\n\t/**\n\t * Fired every time any {@link module:engine/model/operation/operation~Operation operation} is applied on the model\n\t * using {@link #applyOperation}.\n\t *\n\t * Note that this event is suitable only for very specific use-cases. Use it if you need to listen to every single operation\n\t * applied on the document. However, in most cases {@link module:engine/model/document~Document#event:change} should\n\t * be used.\n\t *\n\t * A few callbacks are already added to this event by engine internal classes:\n\t *\n\t * * with `highest` priority operation is validated,\n\t * * with `normal` priority operation is executed,\n\t * * with `low` priority the {@link module:engine/model/document~Document} updates its version,\n\t * * with `low` priority {@link module:engine/model/liveposition~LivePosition} and {@link module:engine/model/liverange~LiveRange}\n\t * update themselves.\n\t *\n\t * @event applyOperation\n\t * @param {Array} args Arguments of the `applyOperation` which is an array with a single element - applied\n\t * {@link module:engine/model/operation/operation~Operation operation}.\n\t */\n\n\t/**\n\t * Event fired when {@link #insertContent} method is called.\n\t *\n\t * The {@link #insertContent default action of that method} is implemented as a\n\t * listener to this event so it can be fully customized by the features.\n\t *\n\t * **Note** The `selectable` parameter for the {@link #insertContent} is optional. When `undefined` value is passed the method uses\n\t * `model.document.selection`.\n\t *\n\t * @event insertContent\n\t * @param {Array} args The arguments passed to the original method.\n\t */\n\n\t/**\n\t * Event fired when {@link #deleteContent} method is called.\n\t *\n\t * The {@link #deleteContent default action of that method} is implemented as a\n\t * listener to this event so it can be fully customized by the features.\n\t *\n\t * @event deleteContent\n\t * @param {Array} args The arguments passed to the original method.\n\t */\n\n\t/**\n\t * Event fired when {@link #modifySelection} method is called.\n\t *\n\t * The {@link #modifySelection default action of that method} is implemented as a\n\t * listener to this event so it can be fully customized by the features.\n\t *\n\t * @event modifySelection\n\t * @param {Array} args The arguments passed to the original method.\n\t */\n\n\t/**\n\t * Event fired when {@link #getSelectedContent} method is called.\n\t *\n\t * The {@link #getSelectedContent default action of that method} is implemented as a\n\t * listener to this event so it can be fully customized by the features.\n\t *\n\t * @event getSelectedContent\n\t * @param {Array} args The arguments passed to the original method.\n\t */\n}\n\nmix( Model, ObservableMixin );\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/keystrokehandler\n */\n\nimport DomEmitterMixin from './dom/emittermixin';\nimport { getCode, parseKeystroke } from './keyboard';\n\n/**\n * Keystroke handler allows registering callbacks for given keystrokes.\n *\n * The most frequent use of this class is through the {@link module:core/editor/editor~Editor#keystrokes `editor.keystrokes`}\n * property. It allows listening to keystrokes executed in the editing view:\n *\n *\t\teditor.keystrokes.set( 'Ctrl+A', ( keyEvtData, cancel ) => {\n *\t\t\tconsole.log( 'Ctrl+A has been pressed' );\n *\t\t\tcancel();\n *\t\t} );\n *\n * However, this utility class can be used in various part of the UI. For instance, a certain {@link module:ui/view~View}\n * can use it like this:\n *\n *\t\tclass MyView extends View {\n *\t\t\tconstructor() {\n *\t\t\t\tthis.keystrokes = new KeystrokeHandler();\n *\n * \t\t\t\tthis.keystrokes.set( 'tab', handleTabKey );\n *\t\t\t}\n *\n *\t\t\trender() {\n *\t\t\t\tsuper.render();\n *\n *\t\t\t\tthis.keystrokes.listenTo( this.element );\n *\t\t\t}\n *\t\t}\n *\n * That keystroke handler will listen to `keydown` events fired in this view's main element.\n *\n */\nexport default class KeystrokeHandler {\n\t/**\n\t * Creates an instance of the keystroke handler.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Listener used to listen to events for easier keystroke handler destruction.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:utils/dom/emittermixin~Emitter}\n\t\t */\n\t\tthis._listener = Object.create( DomEmitterMixin );\n\t}\n\n\t/**\n\t * Starts listening for `keydown` events from a given emitter.\n\t *\n\t * @param {module:utils/emittermixin~Emitter} emitter\n\t */\n\tlistenTo( emitter ) {\n\t\t// The #_listener works here as a kind of dispatcher. It groups the events coming from the same\n\t\t// keystroke so the listeners can be attached to them with different priorities.\n\t\t//\n\t\t// E.g. all the keystrokes with the `keyCode` of 42 coming from the `emitter` are propagated\n\t\t// as a `_keydown:42` event by the `_listener`. If there's a callback created by the `set`\n\t\t// method for this 42 keystroke, it listens to the `_listener#_keydown:42` event only and interacts\n\t\t// only with other listeners of this particular event, thus making it possible to prioritize\n\t\t// the listeners and safely cancel execution, when needed. Instead of duplicating the Emitter logic,\n\t\t// the KeystrokeHandler re–uses it to do its job.\n\t\tthis._listener.listenTo( emitter, 'keydown', ( evt, keyEvtData ) => {\n\t\t\tthis._listener.fire( '_keydown:' + getCode( keyEvtData ), keyEvtData );\n\t\t} );\n\t}\n\n\t/**\n\t * Registers a handler for the specified keystroke.\n\t *\n\t * @param {String|Array.<String|Number>} keystroke Keystroke defined in a format accepted by\n\t * the {@link module:utils/keyboard~parseKeystroke} function.\n\t * @param {Function} callback A function called with the\n\t * {@link module:engine/view/observer/keyobserver~KeyEventData key event data} object and\n\t * a helper funcion to call both `preventDefault()` and `stopPropagation()` on the underlying event.\n\t * @param {Object} [options={}] Additional options.\n\t * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of the keystroke\n\t * callback. The higher the priority value the sooner the callback will be executed. Keystrokes having the same priority\n\t * are called in the order they were added.\n\t */\n\tset( keystroke, callback, options = {} ) {\n\t\tconst keyCode = parseKeystroke( keystroke );\n\t\tconst priority = options.priority;\n\n\t\t// Execute the passed callback on KeystrokeHandler#_keydown.\n\t\t// TODO: https://github.com/ckeditor/ckeditor5-utils/issues/144\n\t\tthis._listener.listenTo( this._listener, '_keydown:' + keyCode, ( evt, keyEvtData ) => {\n\t\t\tcallback( keyEvtData, () => {\n\t\t\t\t// Stop the event in the DOM: no listener in the web page\n\t\t\t\t// will be triggered by this event.\n\t\t\t\tkeyEvtData.preventDefault();\n\t\t\t\tkeyEvtData.stopPropagation();\n\n\t\t\t\t// Stop the event in the KeystrokeHandler: no more callbacks\n\t\t\t\t// will be executed for this keystroke.\n\t\t\t\tevt.stop();\n\t\t\t} );\n\n\t\t\t// Mark this keystroke as handled by the callback. See: #press.\n\t\t\tevt.return = true;\n\t\t}, { priority } );\n\t}\n\n\t/**\n\t * Triggers a keystroke handler for a specified key combination, if such a keystroke was {@link #set defined}.\n\t *\n\t * @param {module:engine/view/observer/keyobserver~KeyEventData} keyEvtData Key event data.\n\t * @returns {Boolean} Whether the keystroke was handled.\n\t */\n\tpress( keyEvtData ) {\n\t\treturn !!this._listener.fire( '_keydown:' + getCode( keyEvtData ), keyEvtData );\n\t}\n\n\t/**\n\t * Destroys the keystroke handler.\n\t */\n\tdestroy() {\n\t\tthis._listener.stopListening();\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/editingkeystrokehandler\n */\n\nimport KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';\n\n/**\n * A keystroke handler for editor editing. Its instance is available\n * in {@link module:core/editor/editor~Editor#keystrokes} so plugins\n * can register their keystrokes.\n *\n * E.g. an undo plugin would do this:\n *\n *\t\teditor.keystrokes.set( 'Ctrl+Z', 'undo' );\n *\t\teditor.keystrokes.set( 'Ctrl+Shift+Z', 'redo' );\n *\t\teditor.keystrokes.set( 'Ctrl+Y', 'redo' );\n *\n * @extends utils/keystrokehandler~KeystrokeHandler\n */\nexport default class EditingKeystrokeHandler extends KeystrokeHandler {\n\t/**\n\t * Creates an instance of the keystroke handler.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor\n\t */\n\tconstructor( editor ) {\n\t\tsuper();\n\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * Registers a handler for the specified keystroke.\n\t *\n\t * The handler can be specified as a command name or a callback.\n\t *\n\t * @param {String|Array.<String|Number>} keystroke Keystroke defined in a format accepted by\n\t * the {@link module:utils/keyboard~parseKeystroke} function.\n\t * @param {Function|String} callback If a string is passed, then the keystroke will\n\t * {@link module:core/editor/editor~Editor#execute execute a command}.\n\t * If a function, then it will be called with the\n\t * {@link module:engine/view/observer/keyobserver~KeyEventData key event data} object and\n\t * a `cancel()` helper to both `preventDefault()` and `stopPropagation()` of the event.\n\t * @param {Object} [options={}] Additional options.\n\t * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of the keystroke\n\t * callback. The higher the priority value the sooner the callback will be executed. Keystrokes having the same priority\n\t * are called in the order they were added.\n\t */\n\tset( keystroke, callback, options = {} ) {\n\t\tif ( typeof callback == 'string' ) {\n\t\t\tconst commandName = callback;\n\n\t\t\tcallback = ( evtData, cancel ) => {\n\t\t\t\tthis.editor.execute( commandName );\n\t\t\t\tcancel();\n\t\t\t};\n\t\t}\n\n\t\tsuper.set( keystroke, callback, options );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/editor/editor\n */\n\nimport Config from '@ckeditor/ckeditor5-utils/src/config';\nimport EditingController from '@ckeditor/ckeditor5-engine/src/controller/editingcontroller';\nimport PluginCollection from '../plugincollection';\nimport CommandCollection from '../commandcollection';\nimport Locale from '@ckeditor/ckeditor5-utils/src/locale';\nimport DataController from '@ckeditor/ckeditor5-engine/src/controller/datacontroller';\nimport Conversion from '@ckeditor/ckeditor5-engine/src/conversion/conversion';\nimport Model from '@ckeditor/ckeditor5-engine/src/model/model';\nimport EditingKeystrokeHandler from '../editingkeystrokehandler';\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * Class representing a basic, generic editor.\n *\n * Check out the list of its subclasses to learn about specific editor implementations.\n *\n * All editor implementations (like {@link module:editor-classic/classiceditor~ClassicEditor} or\n * {@link module:editor-inline/inlineeditor~InlineEditor}) should extend this class. They can add their\n * own methods and properties.\n *\n * When you are implementing a plugin, then this editor represents the API\n * which your plugin can expect to get when using its {@link module:core/plugin~Plugin#editor} property.\n *\n * This API should be sufficient in order to implement the \"editing\" part of your feature\n * (schema definition, conversion, commands, keystrokes, etc.).\n * It does not define the editor UI, which is available only if the\n * the specific editor implements also the {@link module:core/editor/editorwithui~EditorWithUI} interface\n * (as most editor implementations do).\n *\n * @abstract\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Editor {\n\t/**\n\t * Creates a new instance of the Editor class.\n\t *\n\t * Usually, not to be used directly. See the static {@link module:core/editor/editor~Editor.create `create()`} method.\n\t *\n\t * @param {Object} [config] The editor config.\n\t */\n\tconstructor( config ) {\n\t\tconst availablePlugins = this.constructor.builtinPlugins;\n\n\t\t/**\n\t\t * Holds all configurations specific to this editor instance.\n\t\t *\n\t\t *\t\teditor.config.get( 'image.toolbar' );\n\t\t *\t\t// -> [ 'imageStyle:full', 'imageStyle:side', '|', 'imageTextAlternative' ]\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/config~Config}\n\t\t */\n\t\tthis.config = new Config( config, this.constructor.defaultConfig );\n\n\t\tthis.config.define( 'plugins', availablePlugins );\n\n\t\t/**\n\t\t * The plugins loaded and in use by this editor instance.\n\t\t *\n\t\t *\t\teditor.plugins.get( 'Clipboard' ); // -> instance of the Clipboard plugin.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/plugincollection~PluginCollection}\n\t\t */\n\t\tthis.plugins = new PluginCollection( this, availablePlugins );\n\n\t\t/**\n\t\t * Commands registered to the editor.\n\t\t *\n\t\t * Use the shorthand {@link #execute `editor.execute()`} method to execute commands:\n\t\t *\n\t\t *\t\t// Execute the bold command:\n\t\t *\t\teditor.execute( 'bold' );\n\t\t *\n\t\t *\t\t// Check the state of the bold command:\n\t\t *\t\teditor.commands.get( 'bold' ).value;\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/commandcollection~CommandCollection}\n\t\t */\n\t\tthis.commands = new CommandCollection();\n\n\t\t/**\n\t\t * @readonly\n\t\t * @member {module:utils/locale~Locale}\n\t\t */\n\t\tthis.locale = new Locale( this.config.get( 'language' ) );\n\n\t\t/**\n\t\t * Shorthand for {@link module:utils/locale~Locale#t}.\n\t\t *\n\t\t * @see module:utils/locale~Locale#t\n\t\t * @method #t\n\t\t */\n\t\tthis.t = this.locale.t;\n\n\t\t/**\n\t\t * Indicates the editor life-cycle state.\n\t\t *\n\t\t * The editor is in one of the following states:\n\t\t *\n\t\t * * `initializing` - during the editor initialization (before {@link module:core/editor/editor~Editor.create `Editor.create()`})\n\t\t * finished its job,\n\t\t * * `ready` - after the promise returned by the {@link module:core/editor/editor~Editor.create `Editor.create()`}\n\t\t * method is resolved,\n\t\t * * `destroyed` - once the {@link #destroy `editor.destroy()`} method was called.\n\t\t *\n\t\t * @observable\n\t\t * @member {'initializing'|'ready'|'destroyed'} #state\n\t\t */\n\t\tthis.set( 'state', 'initializing' );\n\t\tthis.once( 'ready', () => ( this.state = 'ready' ), { priority: 'high' } );\n\t\tthis.once( 'destroy', () => ( this.state = 'destroyed' ), { priority: 'high' } );\n\n\t\t/**\n\t\t * Defines whether this editor is in read-only mode.\n\t\t *\n\t\t * In read-only mode the editor {@link #commands commands} are disabled so it is not possible\n\t\t * to modify the document by using them. Also, the editable element(s) become non-editable.\n\t\t *\n\t\t * In order to make the editor read-only, you can set this value directly:\n\t\t *\n\t\t *\t\teditor.isReadOnly = true;\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isReadOnly\n\t\t */\n\t\tthis.set( 'isReadOnly', false );\n\n\t\t/**\n\t\t * The editor's model.\n\t\t *\n\t\t * The central point of the editor's abstract data model.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/model~Model}\n\t\t */\n\t\tthis.model = new Model();\n\n\t\t/**\n\t\t * The {@link module:engine/controller/datacontroller~DataController data controller}.\n\t\t * Used e.g. for setting and retrieving editor data.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/controller/datacontroller~DataController}\n\t\t */\n\t\tthis.data = new DataController( this.model );\n\n\t\t/**\n\t\t * The {@link module:engine/controller/editingcontroller~EditingController editing controller}.\n\t\t * Controls user input and rendering the content for editing.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/controller/editingcontroller~EditingController}\n\t\t */\n\t\tthis.editing = new EditingController( this.model );\n\t\tthis.editing.view.document.bind( 'isReadOnly' ).to( this );\n\n\t\t/**\n\t\t * Conversion manager through which you can register model to view and view to model converters.\n\t\t *\n\t\t * See {@link module:engine/conversion/conversion~Conversion}'s documentation to learn how to add converters.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/conversion/conversion~Conversion}\n\t\t */\n\t\tthis.conversion = new Conversion( [ this.editing.downcastDispatcher, this.data.downcastDispatcher ], this.data.upcastDispatcher );\n\t\tthis.conversion.addAlias( 'dataDowncast', this.data.downcastDispatcher );\n\t\tthis.conversion.addAlias( 'editingDowncast', this.editing.downcastDispatcher );\n\n\t\t/**\n\t\t * Instance of the {@link module:core/editingkeystrokehandler~EditingKeystrokeHandler}.\n\t\t *\n\t\t * It allows setting simple keystrokes:\n\t\t *\n\t\t *\t\t// Execute the bold command on Ctrl+E:\n\t\t *\t\teditor.keystrokes.set( 'Ctrl+E', 'bold' );\n\t\t *\n\t\t *\t\t// Execute your own callback:\n\t\t *\t\teditor.keystrokes.set( 'Ctrl+E', ( data, cancel ) => {\n\t\t *\t\t\tconsole.log( data.keyCode );\n\t\t *\n\t\t *\t\t\t// Prevent default (native) action and stop the underlying keydown event\n\t\t *\t\t\t// so no other editor feature will interfere.\n\t\t *\t\t\tcancel();\n\t\t *\t\t} );\n\t\t *\n\t\t * Note: Certain, typing oriented keystrokes (like <kbd>Backspace</kbd> or <kbd>Enter</kbd>) are handled\n\t\t * by low level mechanism and trying to listen to them via the keystroke handler will not work reliably.\n\t\t * To handle those specific keystrokes see the events fired by the\n\t\t * {@link module:engine/view/document~Document editing view document} (`editor.editing.view.document`).\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editingkeystrokehandler~EditingKeystrokeHandler}\n\t\t */\n\t\tthis.keystrokes = new EditingKeystrokeHandler( this );\n\t\tthis.keystrokes.listenTo( this.editing.view.document );\n\t}\n\n\t/**\n\t * Loads and initializes plugins specified in the config.\n\t *\n\t * @returns {Promise.<module:core/plugin~LoadedPlugins>} A promise which resolves\n\t * once the initialization is completed providing an array of loaded plugins.\n\t */\n\tinitPlugins() {\n\t\tconst config = this.config;\n\t\tconst plugins = config.get( 'plugins' ) || [];\n\t\tconst removePlugins = config.get( 'removePlugins' ) || [];\n\t\tconst extraPlugins = config.get( 'extraPlugins' ) || [];\n\n\t\treturn this.plugins.init( plugins.concat( extraPlugins ), removePlugins );\n\t}\n\n\t/**\n\t * Destroys the editor instance, releasing all resources used by it.\n\t *\n\t * **Note** The editor cannot be destroyed during the initialization phase so if it is called\n\t * while the editor {@link #state is being initialized}, it will wait for the editor initialization before destroying it.\n\t *\n\t * @fires destroy\n\t * @returns {Promise} A promise that resolves once the editor instance is fully destroyed.\n\t */\n\tdestroy() {\n\t\tlet readyPromise = Promise.resolve();\n\n\t\tif ( this.state == 'initializing' ) {\n\t\t\treadyPromise = new Promise( resolve => this.once( 'ready', resolve ) );\n\t\t}\n\n\t\treturn readyPromise\n\t\t\t.then( () => {\n\t\t\t\tthis.fire( 'destroy' );\n\t\t\t\tthis.stopListening();\n\t\t\t\tthis.commands.destroy();\n\t\t\t} )\n\t\t\t.then( () => this.plugins.destroy() )\n\t\t\t.then( () => {\n\t\t\t\tthis.model.destroy();\n\t\t\t\tthis.data.destroy();\n\t\t\t\tthis.editing.destroy();\n\t\t\t\tthis.keystrokes.destroy();\n\t\t\t} );\n\t}\n\n\t/**\n\t * Executes specified command with given parameters.\n\t *\n\t * Shorthand for:\n\t *\n\t *\t\teditor.commands.get( commandName ).execute( ... );\n\t *\n\t * @param {String} commandName Name of command to execute.\n\t * @param {*} [...commandParams] Command parameters.\n\t */\n\texecute( ...args ) {\n\t\tthis.commands.execute( ...args );\n\t}\n\n\t/**\n\t * Creates and initializes a new editor instance.\n\t *\n\t * This is an abstract method. Every editor type needs to implement its own initialization logic.\n\t *\n\t * See the `create()` methods of the existing editor types to learn how to use them:\n\t *\n\t * * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`}\n\t * * {@link module:editor-balloon/ballooneditor~BalloonEditor.create `BalloonEditor.create()`}\n\t * * {@link module:editor-decoupled/decouplededitor~DecoupledEditor.create `DecoupledEditor.create()`}\n\t * * {@link module:editor-inline/inlineeditor~InlineEditor.create `InlineEditor.create()`}\n\t *\n\t * @abstract\n\t * @method module:core/editor/editor~Editor.create\n\t */\n}\n\nmix( Editor, ObservableMixin );\n\n/**\n * Fired when {@link module:engine/controller/datacontroller~DataController#event:ready data} and all additional\n * editor components are ready.\n *\n * Note: This event is most useful for plugin developers. When integrating the editor with your website or\n * application you do not have to listen to `editor#ready` because when the promise returned by the static\n * {@link module:core/editor/editor~Editor.create `Editor.create()`} event is resolved, the editor is already ready.\n * In fact, since the first moment when the editor instance is available to you is inside `then()`'s callback,\n * you cannot even add a listener to the `editor#ready` event.\n *\n * See also the {@link #state `editor.state`} property.\n *\n * @event ready\n */\n\n/**\n * Fired when this editor instance is destroyed. The editor at this point is not usable and this event should be used to\n * perform the clean-up in any plugin.\n *\n *\n * See also the {@link #state `editor.state`} property.\n *\n * @event destroy\n */\n\n/**\n * An array of plugins built into this editor class.\n * It is used in CKEditor 5 builds to provide a list of plugins which are later automatically initialized\n * during the editor initialization.\n *\n * They will be automatically initialized by the editor, unless listed in `config.removePlugins` and\n * unless `config.plugins` is passed.\n *\n *\t\t// Build some plugins into the editor class first.\n *\t\tClassicEditor.builtinPlugins = [ FooPlugin, BarPlugin ];\n *\n *\t\t// Normally, you need to define config.plugins, but since ClassicEditor.builtinPlugins was\n *\t\t// defined, now you can call create() without any configuration.\n *\t\tClassicEditor\n *\t\t\t.create( sourceElement )\n *\t\t\t.then( editor => {\n *\t\t\t\teditor.plugins.get( FooPlugin ); // -> instance of the Foo plugin\n *\t\t\t\teditor.plugins.get( BarPlugin ); // -> instance of the Bar plugin\n *\t\t\t} );\n *\n *\t\tClassicEditor\n *\t\t\t.create( sourceElement, {\n *\t\t\t\t// Don't initialize this plugins (note: it's defined by a string):\n *\t\t\t\tremovePlugins: [ 'Foo' ]\n *\t\t\t} )\n *\t\t\t.then( editor => {\n *\t\t\t\teditor.plugins.get( FooPlugin ); // -> undefined\n *\t\t\t\teditor.config.get( BarPlugin ); // -> instance of the Bar plugin\n *\t\t\t} );\n *\n *\t\tClassicEditor\n *\t\t\t.create( sourceElement, {\n *\t\t\t\t// Load only this plugin. Can also be define by a string if\n *\t\t\t\t// this plugin was built into the editor class.\n *\t\t\t\tplugins: [ FooPlugin ]\n *\t\t\t} )\n *\t\t\t.then( editor => {\n *\t\t\t\teditor.plugins.get( FooPlugin ); // -> instance of the Foo plugin\n *\t\t\t\teditor.config.get( BarPlugin ); // -> undefined\n *\t\t\t} );\n *\n * See also {@link module:core/editor/editor~Editor.defaultConfig}.\n *\n * @static\n * @member {Array.<Function>} module:core/editor/editor~Editor.builtinPlugins\n */\n\n/**\n * The default config which is built into the editor class.\n * It is used in CKEditor 5 builds to provide the default config options which are later used during editor initialization.\n *\n *\t\tClassicEditor.defaultConfig = {\n *\t\t\tfoo: 1,\n *\t\t\tbar: 2\n *\t\t};\n *\n *\t\tClassicEditor\n *\t\t\t.create( sourceElement )\n *\t\t\t.then( editor => {\n *\t\t\t\teditor.config.get( 'foo' ); // -> 1\n *\t\t\t\teditor.config.get( 'bar' ); // -> 2\n *\t\t\t} );\n *\n *\t\t// The default options can be overridden by the config passed to create().\n *\t\tClassicEditor\n *\t\t\t.create( sourceElement, { bar: 3 } )\n *\t\t\t.then( editor => {\n *\t\t\t\teditor.config.get( 'foo' ); // -> 1\n *\t\t\t\teditor.config.get( 'bar' ); // -> 3\n *\t\t\t} );\n *\n * See also {@link module:core/editor/editor~Editor.builtinPlugins}.\n *\n * @static\n * @member {Object} module:core/editor/editor~Editor.defaultConfig\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/editor/utils/dataapimixin\n */\n\n/**\n * Implementation of the {@link module:core/editor/utils/dataapimixin~DataApi}.\n *\n * @mixin DataApiMixin\n * @implements module:core/editor/utils/dataapimixin~DataApi\n */\nconst DataApiMixin = {\n\t/**\n\t * @inheritDoc\n\t */\n\tsetData( data ) {\n\t\tthis.data.set( data );\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tgetData( options ) {\n\t\treturn this.data.get( options );\n\t}\n};\n\nexport default DataApiMixin;\n\n/**\n * Interface defining editor methods for setting and getting data to and from the editor's main root element\n * using the {@link module:core/editor/editor~Editor#data data pipeline}.\n *\n * This interface is not a part of the {@link module:core/editor/editor~Editor} class because one may want to implement\n * an editor with multiple root elements, in which case the methods for setting and getting data will need to be implemented\n * differently.\n *\n * @interface DataApi\n */\n\n/**\n * Sets the data in the editor.\n *\n *\t\teditor.setData( '<p>This is editor!</p>' );\n *\n * By default the editor accepts HTML. This can be controlled by injecting a different data processor.\n * See the {@glink features/markdown Markdown output} guide for more details.\n *\n * Note: Not only is the format of the data configurable, but the type of the `setData()`'s parameter does not\n * have to be a string either. You can e.g. accept an object or a DOM `DocumentFragment` if you consider this\n * the right format for you.\n *\n * @method #setData\n * @param {String} data Input data.\n */\n\n/**\n * Gets the data from the editor.\n *\n *\t\teditor.getData(); // -> '<p>This is editor!</p>'\n *\n * By default the editor outputs HTML. This can be controlled by injecting a different data processor.\n * See the {@glink features/markdown Markdown output} guide for more details.\n *\n * Note: Not only is the format of the data configurable, but the type of the `getData()`'s return value does not\n * have to be a string either. You can e.g. return an object or a DOM `DocumentFragment` if you consider this\n * the right format for you.\n *\n * @method #getData\n * @param {Object} [options]\n * @param {String} [options.rootName='main'] Root name.\n * @param {String} [options.trim='empty'] Whether returned data should be trimmed. This option is set to `'empty'` by default,\n * which means that whenever editor content is considered empty, an empty string is returned. To turn off trimming\n * use `'none'`. In such cases exact content will be returned (for example `'<p>&nbsp;</p>'` for an empty editor).\n * @returns {String} Output data.\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport setDataInElement from '@ckeditor/ckeditor5-utils/src/dom/setdatainelement';\n\n/**\n * @module core/editor/utils/elementapimixin\n */\n\n/**\n * Implementation of the {@link module:core/editor/utils/elementapimixin~ElementApi}.\n *\n * @mixin ElementApiMixin\n * @implements module:core/editor/utils/elementapimixin~ElementApi\n */\nconst ElementApiMixin = {\n\t/**\n\t * @inheritDoc\n\t */\n\tupdateSourceElement() {\n\t\tif ( !this.sourceElement ) {\n\t\t\t/**\n\t\t\t * Cannot update the source element of a detached editor.\n\t\t\t *\n\t\t\t * The {@link ~ElementApi#updateSourceElement `updateSourceElement()`} method cannot be called if you did not\n\t\t\t * pass an element to `Editor.create()`.\n\t\t\t *\n\t\t\t * @error editor-missing-sourceelement\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'editor-missing-sourceelement: Cannot update the source element of a detached editor.' );\n\t\t}\n\n\t\tsetDataInElement( this.sourceElement, this.data.get() );\n\t}\n};\n\nexport default ElementApiMixin;\n\n/**\n * Interface describing an editor that replaced a DOM element (was \"initialized on an element\").\n *\n * Such an editor should provide a method to\n * {@link module:core/editor/utils/elementapimixin~ElementApi#updateSourceElement update the replaced element with the current data}.\n *\n * @interface ElementApi\n */\n\n/**\n * The element on which the editor has been initialized.\n *\n * @readonly\n * @member {HTMLElement} #sourceElement\n */\n\n/**\n * Updates the {@link #sourceElement editor source element}'s content with the data.\n *\n * @method #updateSourceElement\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/setdatainelement\n */\n\n/* globals HTMLTextAreaElement */\n\n/**\n * Sets data in a given element.\n *\n * @param {HTMLElement} el The element in which the data will be set.\n * @param {String} data The data string.\n */\nexport default function setDataInElement( el, data ) {\n\tif ( el instanceof HTMLTextAreaElement ) {\n\t\tel.value = data;\n\t}\n\n\tel.innerHTML = data;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/dataprocessor/basichtmlwriter\n */\n\n/* globals document */\n\n/**\n * Basic HTML writer. It uses the native `innerHTML` property for basic conversion\n * from a document fragment to an HTML string.\n *\n * @implements module:engine/dataprocessor/htmlwriter~HtmlWriter\n */\nexport default class BasicHtmlWriter {\n\t/**\n\t * Returns an HTML string created from the document fragment.\n\t *\n\t * @param {DocumentFragment} fragment\n\t * @returns {String}\n\t */\n\tgetHtml( fragment ) {\n\t\tconst doc = document.implementation.createHTMLDocument( '' );\n\t\tconst container = doc.createElement( 'div' );\n\t\tcontainer.appendChild( fragment );\n\n\t\treturn container.innerHTML;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/dataprocessor/htmldataprocessor\n */\n\n/* globals document, DOMParser */\n\nimport BasicHtmlWriter from './basichtmlwriter';\nimport DomConverter from '../view/domconverter';\nimport { NBSP_FILLER } from '../view/filler';\n\n/**\n * The HTML data processor class.\n * This data processor implementation uses HTML as input and output data.\n *\n * @implements module:engine/dataprocessor/dataprocessor~DataProcessor\n */\nexport default class HtmlDataProcessor {\n\t/**\n\t * Creates a new instance of the HTML data processor class.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * A DOM parser instance used to parse an HTML string to an HTML document.\n\t\t *\n\t\t * @private\n\t\t * @member {DOMParser}\n\t\t */\n\t\tthis._domParser = new DOMParser();\n\n\t\t/**\n\t\t * A DOM converter used to convert DOM elements to view elements.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/view/domconverter~DomConverter}\n\t\t */\n\t\tthis._domConverter = new DomConverter( { blockFiller: NBSP_FILLER } );\n\n\t\t/**\n\t\t * A basic HTML writer instance used to convert DOM elements to an HTML string.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/dataprocessor/basichtmlwriter~BasicHtmlWriter}\n\t\t */\n\t\tthis._htmlWriter = new BasicHtmlWriter();\n\t}\n\n\t/**\n\t * Converts a provided {@link module:engine/view/documentfragment~DocumentFragment document fragment}\n\t * to data format &mdash; in this case to an HTML string.\n\t *\n\t * @param {module:engine/view/documentfragment~DocumentFragment} viewFragment\n\t * @returns {String} HTML string.\n\t */\n\ttoData( viewFragment ) {\n\t\t// Convert view DocumentFragment to DOM DocumentFragment.\n\t\tconst domFragment = this._domConverter.viewToDom( viewFragment, document );\n\n\t\t// Convert DOM DocumentFragment to HTML output.\n\t\treturn this._htmlWriter.getHtml( domFragment );\n\t}\n\n\t/**\n\t * Converts the provided HTML string to a view tree.\n\t *\n\t * @param {String} data An HTML string.\n\t * @returns {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment|null} A converted view element.\n\t */\n\ttoView( data ) {\n\t\t// Convert input HTML data to DOM DocumentFragment.\n\t\tconst domFragment = this._toDom( data );\n\n\t\t// Convert DOM DocumentFragment to view DocumentFragment.\n\t\treturn this._domConverter.domToView( domFragment );\n\t}\n\n\t/**\n\t * Converts an HTML string to its DOM representation. Returns a document fragment containing nodes parsed from\n\t * the provided data.\n\t *\n\t * @private\n\t * @param {String} data\n\t * @returns {DocumentFragment}\n\t */\n\t_toDom( data ) {\n\t\tconst document = this._domParser.parseFromString( data, 'text/html' );\n\t\tconst fragment = document.createDocumentFragment();\n\t\tconst nodes = document.body.childNodes;\n\n\t\twhile ( nodes.length > 0 ) {\n\t\t\tfragment.appendChild( nodes[ 0 ] );\n\t\t}\n\n\t\treturn fragment;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/componentfactory\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * A helper class implementing the UI component ({@link module:ui/view~View view}) factory.\n *\n * It allows functions producing specific UI components to be registered under their unique names\n * in the factory. A registered component can be then instantiated by providing its name.\n * Note that names are case insensitive.\n *\n *\t\t// The editor provides localization tools for the factory.\n *\t\tconst factory = new ComponentFactory( editor );\n *\n *\t\tfactory.add( 'foo', locale => new FooView( locale ) );\n *\t\tfactory.add( 'bar', locale => new BarView( locale ) );\n *\n *\t\t// An instance of FooView.\n *\t\tconst fooInstance = factory.create( 'foo' );\n *\n *\t\t// Names are case insensitive so this is also allowed:\n *\t\tconst barInstance = factory.create( 'Bar' );\n *\n * The {@link module:core/editor/editor~Editor#locale editor locale} is passed to the factory\n * function when {@link module:ui/componentfactory~ComponentFactory#create} is called.\n */\nexport default class ComponentFactory {\n\t/**\n\t * Creates an instance of the factory.\n\t *\n\t * @constructor\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance that the factory belongs to.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * Registered component factories.\n\t\t *\n\t\t * @private\n\t\t * @member {Map}\n\t\t */\n\t\tthis._components = new Map();\n\t}\n\n\t/**\n\t * Returns an iterator of registered component names. Names are returned in lower case.\n\t *\n\t * @returns {Iterable.<String>}\n\t */\n\t* names() {\n\t\tfor ( const value of this._components.values() ) {\n\t\t\tyield value.originalName;\n\t\t}\n\t}\n\n\t/**\n\t * Registers a component factory function that will be used by the\n\t * {@link #create create} method and called with the\n\t * {@link module:core/editor/editor~Editor#locale editor locale} as an argument,\n\t * allowing localization of the {@link module:ui/view~View view}.\n\t *\n\t * @param {String} name The name of the component.\n\t * @param {Function} callback The callback that returns the component.\n\t */\n\tadd( name, callback ) {\n\t\tif ( this.has( name ) ) {\n\t\t\t/**\n\t\t\t * The item already exists in the component factory.\n\t\t\t *\n\t\t\t * @error componentfactory-item-exists\n\t\t\t * @param {String} name The name of the component.\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'componentfactory-item-exists: The item already exists in the component factory.', { name }\n\t\t\t);\n\t\t}\n\n\t\tthis._components.set( getNormalized( name ), { callback, originalName: name } );\n\t}\n\n\t/**\n\t * Creates an instance of a component registered in the factory under a specific name.\n\t *\n\t * When called, the {@link module:core/editor/editor~Editor#locale editor locale} is passed to\n\t * the previously {@link #add added} factory function, allowing localization of the\n\t * {@link module:ui/view~View view}.\n\t *\n\t * @param {String} name The name of the component.\n\t * @returns {module:ui/view~View} The instantiated component view.\n\t */\n\tcreate( name ) {\n\t\tif ( !this.has( name ) ) {\n\t\t\t/**\n\t\t\t * The required component is not registered in the component factory. Please make sure\n\t\t\t * the provided name is correct and the component has been correctly\n\t\t\t * {@link #add added} to the factory.\n\t\t\t *\n\t\t\t * @error componentfactory-item-missing\n\t\t\t * @param {String} name The name of the missing component.\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'componentfactory-item-missing: The required component is not registered in the factory.', { name }\n\t\t\t);\n\t\t}\n\n\t\treturn this._components.get( getNormalized( name ) ).callback( this.editor.locale );\n\t}\n\n\t/**\n\t * Checks if a component of a given name is registered in the factory.\n\t *\n\t * @param {String} name The name of the component.\n\t * @returns {Boolean}\n\t */\n\thas( name ) {\n\t\treturn this._components.has( getNormalized( name ) );\n\t}\n}\n\n//\n// Ensures that the component name used as the key in the internal map is in lower case.\n//\n// @private\n// @param {String} name\n// @returns {String}\nfunction getNormalized( name ) {\n\treturn String( name ).toLowerCase();\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* global setTimeout, clearTimeout */\n\n/**\n * @module utils/focustracker\n */\n\nimport DomEmitterMixin from './dom/emittermixin';\nimport ObservableMixin from './observablemixin';\nimport CKEditorError from './ckeditorerror';\nimport mix from './mix';\n\n/**\n * Allows observing a group of `HTMLElement`s whether at least one of them is focused.\n *\n * Used by the {@link module:core/editor/editor~Editor} in order to track whether the focus is still within the application,\n * or were used outside of its UI.\n *\n * **Note** `focus` and `blur` listeners use event capturing, so it is only needed to register wrapper `HTMLElement`\n * which contain other `focusable` elements. But note that this wrapper element has to be focusable too\n * (have e.g. `tabindex=\"-1\"`).\n *\n * @mixes module:utils/dom/emittermixin~EmitterMixin\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class FocusTracker {\n\tconstructor() {\n\t\t/**\n\t\t * True when one of the registered elements is focused.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Boolean} #isFocused\n\t\t */\n\t\tthis.set( 'isFocused', false );\n\n\t\t/**\n\t\t * The currently focused element.\n\t\t *\n\t\t * While {@link #isFocused `isFocused`} remains `true`, the focus can\n\t\t * move between different UI elements. This property tracks those\n\t\t * elements and tells which one is currently focused.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {HTMLElement|null}\n\t\t */\n\t\tthis.set( 'focusedElement', null );\n\n\t\t/**\n\t\t * List of registered elements.\n\t\t *\n\t\t * @private\n\t\t * @member {Set.<HTMLElement>}\n\t\t */\n\t\tthis._elements = new Set();\n\n\t\t/**\n\t\t * Event loop timeout.\n\t\t *\n\t\t * @private\n\t\t * @member {Number}\n\t\t */\n\t\tthis._nextEventLoopTimeout = null;\n\t}\n\n\t/**\n\t * Starts tracking the specified element.\n\t *\n\t * @param {HTMLElement} element\n\t */\n\tadd( element ) {\n\t\tif ( this._elements.has( element ) ) {\n\t\t\tthrow new CKEditorError( 'focusTracker-add-element-already-exist' );\n\t\t}\n\n\t\tthis.listenTo( element, 'focus', () => this._focus( element ), { useCapture: true } );\n\t\tthis.listenTo( element, 'blur', () => this._blur(), { useCapture: true } );\n\t\tthis._elements.add( element );\n\t}\n\n\t/**\n\t * Stops tracking the specified element and stops listening on this element.\n\t *\n\t * @param {HTMLElement} element\n\t */\n\tremove( element ) {\n\t\tif ( element === this.focusedElement ) {\n\t\t\tthis._blur( element );\n\t\t}\n\n\t\tif ( this._elements.has( element ) ) {\n\t\t\tthis.stopListening( element );\n\t\t\tthis._elements.delete( element );\n\t\t}\n\t}\n\n\t/**\n\t * Destroys the focus tracker by:\n\t * - Disabling all event listeners attached to tracked elements.\n\t * - Removing all tracked elements that were previously added.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Stores currently focused element and set {#isFocused} as `true`.\n\t *\n\t * @private\n\t * @param {HTMLElement} element Element which has been focused.\n\t */\n\t_focus( element ) {\n\t\tclearTimeout( this._nextEventLoopTimeout );\n\n\t\tthis.focusedElement = element;\n\t\tthis.isFocused = true;\n\t}\n\n\t/**\n\t * Clears currently focused element and set {@link #isFocused} as `false`.\n\t * This method uses `setTimeout` to change order of fires `blur` and `focus` events.\n\t *\n\t * @private\n\t * @fires blur\n\t */\n\t_blur() {\n\t\tclearTimeout( this._nextEventLoopTimeout );\n\n\t\tthis._nextEventLoopTimeout = setTimeout( () => {\n\t\t\tthis.focusedElement = null;\n\t\t\tthis.isFocused = false;\n\t\t}, 0 );\n\t}\n\n\t/**\n\t * @event focus\n\t */\n\n\t/**\n\t * @event blur\n\t */\n}\n\nmix( FocusTracker, DomEmitterMixin );\nmix( FocusTracker, ObservableMixin );\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/editor/editorui\n */\n\nimport ComponentFactory from '@ckeditor/ckeditor5-ui/src/componentfactory';\nimport FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';\n\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * A class providing the minimal interface that is required to successfully bootstrap any editor UI.\n *\n * @mixes module:utils/emittermixin~EmitterMixin\n */\nexport default class EditorUI {\n\t/**\n\t * Creates an instance of the editor UI class.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor that the UI belongs to.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * An instance of the {@link module:ui/componentfactory~ComponentFactory}, a registry used by plugins\n\t\t * to register factories of specific UI components.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/componentfactory~ComponentFactory} #componentFactory\n\t\t */\n\t\tthis.componentFactory = new ComponentFactory( editor );\n\n\t\t/**\n\t\t * Stores the information about the editor UI focus and propagates it so various plugins and components\n\t\t * are unified as a focus group.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/focustracker~FocusTracker} #focusTracker\n\t\t */\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\t/**\n\t\t * Stores all editable elements used by the editor instance.\n\t\t *\n\t\t * @protected\n\t\t * @member {Map.<String,HTMLElement>}\n\t\t */\n\t\tthis._editableElements = new Map();\n\n\t\t// Informs UI components that should be refreshed after layout change.\n\t\tthis.listenTo( editor.editing.view.document, 'layoutChanged', () => this.update() );\n\t}\n\n\t/**\n\t * The main (outermost) DOM element of the editor UI.\n\t *\n\t * For example, in {@link module:editor-classic/classiceditor~ClassicEditor} it is a `<div>` which\n\t * wraps the editable element and the toolbar. In {@link module:editor-inline/inlineeditor~InlineEditor}\n\t * it is the editable element itself (as there is no other wrapper). However, in\n\t * {@link module:editor-decoupled/decouplededitor~DecoupledEditor} it is set to `null` because this editor does not\n\t * come with a single \"main\" HTML element (its editable element and toolbar are separate).\n\t *\n\t * This property can be understood as a shorthand for retrieving the element that a specific editor integration\n\t * considers to be its main DOM element.\n\t *\n\t * @readonly\n\t * @member {HTMLElement|null} #element\n\t */\n\tget element() {\n\t\treturn null;\n\t}\n\n\t/**\n\t * Fires the {@link module:core/editor/editorui~EditorUI#event:update `update`} event.\n\t *\n\t * This method should be called when the editor UI (e.g. positions of its balloons) needs to be updated due to\n\t * some environmental change which CKEditor 5 is not aware of (e.g. resize of a container in which it is used).\n\t */\n\tupdate() {\n\t\tthis.fire( 'update' );\n\t}\n\n\t/**\n\t * Destroys the UI.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\n\t\tthis.focusTracker.destroy();\n\n\t\tthis._editableElements = new Map();\n\t}\n\n\t/**\n\t * Returns the editable editor element with the given name or null if editable does not exist.\n\t *\n\t * @param {String} [rootName=main] The editable name.\n\t * @returns {HTMLElement|undefined}\n\t */\n\tgetEditableElement( rootName = 'main' ) {\n\t\treturn this._editableElements.get( rootName );\n\t}\n\n\t/**\n\t * Returns array of names of all editor editable elements.\n\t *\n\t * @returns {Iterable.<String>}\n\t */\n\tgetEditableElementsNames() {\n\t\treturn this._editableElements.keys();\n\t}\n\n\t/**\n\t * Fired when the editor UI is ready.\n\t *\n\t * Fired before {@link module:engine/controller/datacontroller~DataController#event:ready}.\n\t *\n\t * @event ready\n\t */\n\n\t/**\n\t * Fired whenever the UI (all related components) should be refreshed.\n\t *\n\t * **Note:**: The event is fired after each {@link module:engine/view/document~Document#event:layoutChanged}.\n\t * It can also be fired manually via the {@link module:core/editor/editorui~EditorUI#update} method.\n\t *\n\t * @event update\n\t */\n}\n\nmix( EditorUI, EmitterMixin );\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/placeholder\n */\n\nimport '../../theme/placeholder.css';\n\n// Each document stores information about its placeholder elements and check functions.\nconst documentPlaceholders = new WeakMap();\n\n/**\n * A helper that enables a placeholder on the provided view element (also updates its visibility).\n * The placeholder is a CSS pseudo–element (with a text content) attached to the element.\n *\n * To change the placeholder text, simply call this method again with new options.\n *\n * To disable the placeholder, use {@link module:engine/view/placeholder~disablePlaceholder `disablePlaceholder()`} helper.\n *\n * @param {Object} [options] Configuration options of the placeholder.\n * @param {module:engine/view/view~View} options.view Editing view instance.\n * @param {module:engine/view/element~Element} options.element Element that will gain a placeholder.\n * See `options.isDirectHost` to learn more.\n * @param {String} options.text Placeholder text.\n * @param {Boolean} [options.isDirectHost=true] If set `false`, the placeholder will not be enabled directly\n * in the passed `element` but in one of its children (selected automatically, i.e. a first empty child element).\n * Useful when attaching placeholders to elements that can host other elements (not just text), for instance,\n * editable root elements.\n */\nexport function enablePlaceholder( options ) {\n\tconst { view, element, text, isDirectHost = true } = options;\n\tconst doc = view.document;\n\n\t// Use a single a single post fixer per—document to update all placeholders.\n\tif ( !documentPlaceholders.has( doc ) ) {\n\t\tdocumentPlaceholders.set( doc, new Map() );\n\n\t\t// If a post-fixer callback makes a change, it should return `true` so other post–fixers\n\t\t// can re–evaluate the document again.\n\t\tdoc.registerPostFixer( writer => updateDocumentPlaceholders( doc, writer ) );\n\t}\n\n\t// Store information about the element placeholder under its document.\n\tdocumentPlaceholders.get( doc ).set( element, {\n\t\ttext,\n\t\tisDirectHost\n\t} );\n\n\t// Update the placeholders right away.\n\tview.change( writer => updateDocumentPlaceholders( doc, writer ) );\n}\n\n/**\n * Disables the placeholder functionality from a given element.\n *\n * See {@link module:engine/view/placeholder~enablePlaceholder `enablePlaceholder()`} to learn more.\n *\n * @param {module:engine/view/view~View} view\n * @param {module:engine/view/element~Element} element\n */\nexport function disablePlaceholder( view, element ) {\n\tconst doc = element.document;\n\n\tview.change( writer => {\n\t\tif ( !documentPlaceholders.has( doc ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst placeholders = documentPlaceholders.get( doc );\n\t\tconst config = placeholders.get( element );\n\n\t\twriter.removeAttribute( 'data-placeholder', config.hostElement );\n\t\thidePlaceholder( writer, config.hostElement );\n\n\t\tplaceholders.delete( element );\n\t} );\n}\n\n/**\n * Shows a placeholder in the provided element by changing related attributes and CSS classes.\n *\n * **Note**: This helper will not update the placeholder visibility nor manage the\n * it in any way in the future. What it does is a one–time state change of an element. Use\n * {@link module:engine/view/placeholder~enablePlaceholder `enablePlaceholder()`} and\n * {@link module:engine/view/placeholder~disablePlaceholder `disablePlaceholder()`} for full\n * placeholder functionality.\n *\n * **Note**: This helper will blindly show the placeholder directly in the root editable element if\n * one is passed, which could result in a visual clash if the editable element has some children\n * (for instance, an empty paragraph). Use {@link module:engine/view/placeholder~enablePlaceholder `enablePlaceholder()`}\n * in that case or make sure the correct element is passed to the helper.\n *\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer\n * @param {module:engine/view/element~Element} element\n * @returns {Boolean} `true`, if any changes were made to the `element`.\n */\nexport function showPlaceholder( writer, element ) {\n\tif ( !element.hasClass( 'ck-placeholder' ) ) {\n\t\twriter.addClass( 'ck-placeholder', element );\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Hides a placeholder in the element by changing related attributes and CSS classes.\n *\n * **Note**: This helper will not update the placeholder visibility nor manage the\n * it in any way in the future. What it does is a one–time state change of an element. Use\n * {@link module:engine/view/placeholder~enablePlaceholder `enablePlaceholder()`} and\n * {@link module:engine/view/placeholder~disablePlaceholder `disablePlaceholder()`} for full\n * placeholder functionality.\n *\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer\n * @param {module:engine/view/element~Element} element\n * @returns {Boolean} `true`, if any changes were made to the `element`.\n */\nexport function hidePlaceholder( writer, element ) {\n\tif ( element.hasClass( 'ck-placeholder' ) ) {\n\t\twriter.removeClass( 'ck-placeholder', element );\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Checks if a placeholder should be displayed in the element.\n *\n * **Note**: This helper will blindly check the possibility of showing a placeholder directly in the\n * root editable element if one is passed, which may not be the expected result. If an element can\n * host other elements (not just text), most likely one of its children should be checked instead\n * because it will be the final host for the placeholder. Use\n * {@link module:engine/view/placeholder~enablePlaceholder `enablePlaceholder()`} in that case or make\n * sure the correct element is passed to the helper.\n *\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer\n * @param {module:engine/view/element~Element} element\n * @param {String} text\n * @returns {Boolean}\n */\nexport function needsPlaceholder( element ) {\n\tconst doc = element.document;\n\n\t// The element was removed from document.\n\tif ( !doc ) {\n\t\treturn false;\n\t}\n\n\t// The element is empty only as long as it contains nothing but uiElements.\n\tconst isEmptyish = !Array.from( element.getChildren() )\n\t\t.some( element => !element.is( 'uiElement' ) );\n\n\t// If the element is empty and the document is blurred.\n\tif ( !doc.isFocused && isEmptyish ) {\n\t\treturn true;\n\t}\n\n\tconst viewSelection = doc.selection;\n\tconst selectionAnchor = viewSelection.anchor;\n\n\t// If document is focused and the element is empty but the selection is not anchored inside it.\n\tif ( isEmptyish && selectionAnchor && selectionAnchor.parent !== element ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n// Updates all placeholders associated with a document in a post–fixer callback.\n//\n// @private\n// @param { module:engine/model/document~Document} doc\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\n// @returns {Boolean} True if any changes were made to the view document.\nfunction updateDocumentPlaceholders( doc, writer ) {\n\tconst placeholders = documentPlaceholders.get( doc );\n\tlet wasViewModified = false;\n\n\tfor ( const [ element, config ] of placeholders ) {\n\t\tif ( updatePlaceholder( writer, element, config ) ) {\n\t\t\twasViewModified = true;\n\t\t}\n\t}\n\n\treturn wasViewModified;\n}\n\n// Updates a single placeholder in a post–fixer callback.\n//\n// @private\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\n// @param {module:engine/view/element~Element} element\n// @param {Object} config Configuration of the placeholder\n// @param {String} config.text\n// @param {Boolean} config.isDirectHost\n// @returns {Boolean} True if any changes were made to the view document.\nfunction updatePlaceholder( writer, element, config ) {\n\tconst { text, isDirectHost } = config;\n\tconst hostElement = isDirectHost ? element : getChildPlaceholderHostSubstitute( element );\n\tlet wasViewModified = false;\n\n\t// When not a direct host, it could happen that there is no child element\n\t// capable of displaying a placeholder.\n\tif ( !hostElement ) {\n\t\treturn false;\n\t}\n\n\t// Cache the host element. It will be necessary for disablePlaceholder() to know\n\t// which element should have class and attribute removed because, depending on\n\t// the config.isDirectHost value, it could be the element or one of its descendants.\n\tconfig.hostElement = hostElement;\n\n\t// This may be necessary when updating the placeholder text to something else.\n\tif ( hostElement.getAttribute( 'data-placeholder' ) !== text ) {\n\t\twriter.setAttribute( 'data-placeholder', text, hostElement );\n\t\twasViewModified = true;\n\t}\n\n\tif ( needsPlaceholder( hostElement ) ) {\n\t\tif ( showPlaceholder( writer, hostElement ) ) {\n\t\t\twasViewModified = true;\n\t\t}\n\t} else if ( hidePlaceholder( writer, hostElement ) ) {\n\t\twasViewModified = true;\n\t}\n\n\treturn wasViewModified;\n}\n\n// Gets a child element capable of displaying a placeholder if a parent element can host more\n// than just text (for instance, when it is a root editable element). The child element\n// can then be used in other placeholder helpers as a substitute of its parent.\n//\n// @private\n// @param {module:engine/view/element~Element} parent\n// @returns {module:engine/view/element~Element|null}\nfunction getChildPlaceholderHostSubstitute( parent ) {\n\tif ( parent.childCount === 1 ) {\n\t\tconst firstChild = parent.getChild( 0 );\n\n\t\tif ( firstChild.is( 'element' ) && !firstChild.is( 'uiElement' ) ) {\n\t\t\treturn firstChild;\n\t\t}\n\t}\n\n\treturn null;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/elementreplacer\n */\n\n/**\n * Utility class allowing to hide existing HTML elements or replace them with given ones in a way that doesn't remove\n * the original elements from the DOM.\n */\nexport default class ElementReplacer {\n\tconstructor() {\n\t\t/**\n\t\t * The elements replaced by {@link #replace} and their replacements.\n\t\t *\n\t\t * @private\n\t\t * @member {Array.<Object>}\n\t\t */\n\t\tthis._replacedElements = [];\n\t}\n\n\t/**\n\t * Hides the `element` and, if specified, inserts the the given element next to it.\n\t *\n\t * The effect of this method can be reverted by {@link #restore}.\n\t *\n\t * @param {HTMLElement} element The element to replace.\n\t * @param {HTMLElement} [newElement] The replacement element. If not passed, then the `element` will just be hidden.\n\t */\n\treplace( element, newElement ) {\n\t\tthis._replacedElements.push( { element, newElement } );\n\n\t\telement.style.display = 'none';\n\n\t\tif ( newElement ) {\n\t\t\telement.parentNode.insertBefore( newElement, element.nextSibling );\n\t\t}\n\t}\n\n\t/**\n\t * Restores what {@link #replace} did.\n\t */\n\trestore() {\n\t\tthis._replacedElements.forEach( ( { element, newElement } ) => {\n\t\t\telement.style.display = '';\n\n\t\t\tif ( newElement ) {\n\t\t\t\tnewElement.remove();\n\t\t\t}\n\t\t} );\n\n\t\tthis._replacedElements = [];\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module editor-classic/classiceditorui\n */\n\nimport EditorUI from '@ckeditor/ckeditor5-core/src/editor/editorui';\nimport enableToolbarKeyboardFocus from '@ckeditor/ckeditor5-ui/src/toolbar/enabletoolbarkeyboardfocus';\nimport normalizeToolbarConfig from '@ckeditor/ckeditor5-ui/src/toolbar/normalizetoolbarconfig';\nimport { enablePlaceholder } from '@ckeditor/ckeditor5-engine/src/view/placeholder';\nimport ElementReplacer from '@ckeditor/ckeditor5-utils/src/elementreplacer';\n\n/**\n * The classic editor UI class.\n *\n * @extends module:core/editor/editorui~EditorUI\n */\nexport default class ClassicEditorUI extends EditorUI {\n\t/**\n\t * Creates an instance of the classic editor UI class.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {module:ui/editorui/editoruiview~EditorUIView} view The view of the UI.\n\t */\n\tconstructor( editor, view ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The main (top–most) view of the editor UI.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/editorui/editoruiview~EditorUIView} #view\n\t\t */\n\t\tthis.view = view;\n\n\t\t/**\n\t\t * A normalized `config.toolbar` object.\n\t\t *\n\t\t * @private\n\t\t * @member {Object}\n\t\t */\n\t\tthis._toolbarConfig = normalizeToolbarConfig( editor.config.get( 'toolbar' ) );\n\n\t\t/**\n\t\t * The element replacer instance used to hide the editor's source element.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:utils/elementreplacer~ElementReplacer}\n\t\t */\n\t\tthis._elementReplacer = new ElementReplacer();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tget element() {\n\t\treturn this.view.element;\n\t}\n\n\t/**\n\t * Initializes the UI.\n\t *\n\t * @param {HTMLElement|null} replacementElement The DOM element that will be the source for the created editor.\n\t */\n\tinit( replacementElement ) {\n\t\tconst editor = this.editor;\n\t\tconst view = this.view;\n\t\tconst editingView = editor.editing.view;\n\t\tconst editable = view.editable;\n\t\tconst editingRoot = editingView.document.getRoot();\n\n\t\t// The editable UI and editing root should share the same name. Then name is used\n\t\t// to recognize the particular editable, for instance in ARIA attributes.\n\t\teditable.name = editingRoot.rootName;\n\n\t\tview.render();\n\n\t\t// The editable UI element in DOM is available for sure only after the editor UI view has been rendered.\n\t\t// But it can be available earlier if a DOM element has been passed to BalloonEditor.create().\n\t\tconst editableElement = editable.element;\n\n\t\t// Register the editable UI view in the editor. A single editor instance can aggregate multiple\n\t\t// editable areas (roots) but the classic editor has only one.\n\t\tthis._editableElements.set( editable.name, editableElement );\n\n\t\t// Let the global focus tracker know that the editable UI element is focusable and\n\t\t// belongs to the editor. From now on, the focus tracker will sustain the editor focus\n\t\t// as long as the editable is focused (e.g. the user is typing).\n\t\tthis.focusTracker.add( editableElement );\n\n\t\t// Let the editable UI element respond to the changes in the global editor focus\n\t\t// tracker. It has been added to the same tracker a few lines above but, in reality, there are\n\t\t// many focusable areas in the editor, like balloons, toolbars or dropdowns and as long\n\t\t// as they have focus, the editable should act like it is focused too (although technically\n\t\t// it isn't), e.g. by setting the proper CSS class, visually announcing focus to the user.\n\t\t// Doing otherwise will result in editable focus styles disappearing, once e.g. the\n\t\t// toolbar gets focused.\n\t\tview.editable.bind( 'isFocused' ).to( this.focusTracker );\n\n\t\t// Bind the editable UI element to the editing view, making it an end– and entry–point\n\t\t// of the editor's engine. This is where the engine meets the UI.\n\t\teditingView.attachDomRoot( editableElement );\n\n\t\t// If an element containing the initial data of the editor was provided, replace it with\n\t\t// an editor instance's UI in DOM until the editor is destroyed. For instance, a <textarea>\n\t\t// can be such element.\n\t\tif ( replacementElement ) {\n\t\t\tthis._elementReplacer.replace( replacementElement, this.element );\n\t\t}\n\n\t\tthis._initPlaceholder();\n\t\tthis._initToolbar();\n\t\tthis.fire( 'ready' );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tconst view = this.view;\n\t\tconst editingView = this.editor.editing.view;\n\n\t\tthis._elementReplacer.restore();\n\t\teditingView.detachDomRoot( view.editable.name );\n\t\tview.destroy();\n\n\t\tsuper.destroy();\n\t}\n\n\t/**\n\t * Initializes the editor toolbar.\n\t *\n\t * @private\n\t */\n\t_initToolbar() {\n\t\tconst editor = this.editor;\n\t\tconst view = this.view;\n\t\tconst editingView = editor.editing.view;\n\n\t\t// Set–up the sticky panel with toolbar.\n\t\tview.stickyPanel.bind( 'isActive' ).to( this.focusTracker, 'isFocused' );\n\t\tview.stickyPanel.limiterElement = view.element;\n\n\t\tif ( this._toolbarConfig.viewportTopOffset ) {\n\t\t\tview.stickyPanel.viewportTopOffset = this._toolbarConfig.viewportTopOffset;\n\t\t}\n\n\t\tview.toolbar.fillFromConfig( this._toolbarConfig.items, this.componentFactory );\n\n\t\tenableToolbarKeyboardFocus( {\n\t\t\torigin: editingView,\n\t\t\toriginFocusTracker: this.focusTracker,\n\t\t\toriginKeystrokeHandler: editor.keystrokes,\n\t\t\ttoolbar: view.toolbar\n\t\t} );\n\t}\n\n\t/**\n\t * Enable the placeholder text on the editing root, if any was configured.\n\t *\n\t * @private\n\t */\n\t_initPlaceholder() {\n\t\tconst editor = this.editor;\n\t\tconst editingView = editor.editing.view;\n\t\tconst editingRoot = editingView.document.getRoot();\n\t\tconst sourceElement = editor.sourceElement;\n\n\t\tconst placeholderText = editor.config.get( 'placeholder' ) ||\n\t\t\tsourceElement && sourceElement.tagName.toLowerCase() === 'textarea' && sourceElement.getAttribute( 'placeholder' );\n\n\t\tif ( placeholderText ) {\n\t\t\tenablePlaceholder( {\n\t\t\t\tview: editingView,\n\t\t\t\telement: editingRoot,\n\t\t\t\ttext: placeholderText,\n\t\t\t\tisDirectHost: false\n\t\t\t} );\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/toolbar/normalizetoolbarconfig\n */\n\n/**\n * Normalizes the toolbar configuration (`config.toolbar`), which:\n *\n * * may be defined as an `Array`:\n *\n * \t\ttoolbar: [ 'heading', 'bold', 'italic', 'link', ... ]\n *\n * * or an `Object`:\n *\n *\t\ttoolbar: {\n *\t\t\titems: [ 'heading', 'bold', 'italic', 'link', ... ],\n *\t\t\t...\n *\t\t}\n *\n * * or may not be defined at all (`undefined`)\n *\n * and returns it in the object form.\n *\n * @param {Array|Object|undefined} config The value of `config.toolbar`.\n * @returns {Object} A normalized toolbar config object.\n */\nexport default function normalizeToolbarConfig( config ) {\n\tif ( Array.isArray( config ) ) {\n\t\treturn {\n\t\t\titems: config\n\t\t};\n\t}\n\n\tif ( !config ) {\n\t\treturn {\n\t\t\titems: []\n\t\t};\n\t}\n\n\treturn Object.assign( {\n\t\titems: []\n\t}, config );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/toolbar/enabletoolbarkeyboardfocus\n */\n\n/**\n * Enables focus/blur toolbar navigation using `Alt+F10` and `Esc` keystrokes.\n *\n * @param {Object} options Options of the utility.\n * @param {*} options.origin A view to which the focus will return when `Esc` is pressed and\n * `options.toolbar` is focused.\n * @param {module:utils/keystrokehandler~KeystrokeHandler} options.originKeystrokeHandler A keystroke\n * handler to register `Alt+F10` keystroke.\n * @param {module:utils/focustracker~FocusTracker} options.originFocusTracker A focus tracker\n * for `options.origin`.\n * @param {module:ui/toolbar/toolbarview~ToolbarView} options.toolbar A toolbar which is to gain\n * focus when `Alt+F10` is pressed.\n * @param {Function} [options.beforeFocus] A callback executed before the `options.toolbar` gains focus\n * upon the `Alt+F10` keystroke.\n * @param {Function} [options.afterBlur] A callback executed after `options.toolbar` loses focus upon\n * `Esc` keystroke but before the focus goes back to `options.origin`.\n */\nexport default function enableToolbarKeyboardFocus( {\n\torigin,\n\toriginKeystrokeHandler,\n\toriginFocusTracker,\n\ttoolbar,\n\tbeforeFocus,\n\tafterBlur\n} ) {\n\t// Because toolbar items can get focus, the overall state of the toolbar must\n\t// also be tracked.\n\toriginFocusTracker.add( toolbar.element );\n\n\t// Focus the toolbar on the keystroke, if not already focused.\n\toriginKeystrokeHandler.set( 'Alt+F10', ( data, cancel ) => {\n\t\tif ( originFocusTracker.isFocused && !toolbar.focusTracker.isFocused ) {\n\t\t\tif ( beforeFocus ) {\n\t\t\t\tbeforeFocus();\n\t\t\t}\n\n\t\t\ttoolbar.focus();\n\n\t\t\tcancel();\n\t\t}\n\t} );\n\n\t// Blur the toolbar and bring the focus back to origin.\n\ttoolbar.keystrokes.set( 'Esc', ( data, cancel ) => {\n\t\tif ( toolbar.focusTracker.isFocused ) {\n\t\t\torigin.focus();\n\n\t\t\tif ( afterBlur ) {\n\t\t\t\tafterBlur();\n\t\t\t}\n\n\t\t\tcancel();\n\t\t}\n\t} );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/viewcollection\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport Collection from '@ckeditor/ckeditor5-utils/src/collection';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * Collects {@link module:ui/view~View} instances.\n *\n *\t\tconst parentView = new ParentView( locale );\n *\t\tconst collection = new ViewCollection( locale );\n *\n *\t\tcollection.setParent( parentView.element );\n *\n *\t\tconst viewA = new ChildView( locale );\n *\t\tconst viewB = new ChildView( locale );\n *\n * View collection renders and manages view {@link module:ui/view~View#element elements}:\n *\n *\t\tcollection.add( viewA );\n *\t\tcollection.add( viewB );\n *\n *\t\tconsole.log( parentView.element.firsChild ); // -> viewA.element\n *\t\tconsole.log( parentView.element.lastChild ); // -> viewB.element\n *\n * It {@link module:ui/viewcollection~ViewCollection#delegate propagates} DOM events too:\n *\n *\t\t// Delegate #click and #keydown events from viewA and viewB to the parentView.\n *\t\tcollection.delegate( 'click' ).to( parentView );\n *\n *\t\tparentView.on( 'click', ( evt ) => {\n *\t\t\tconsole.log( `${ evt.source } has been clicked.` );\n *\t\t} );\n *\n *\t\t// This event will be delegated to the parentView.\n *\t\tviewB.fire( 'click' );\n *\n * **Note**: A view collection can be used directly in the {@link module:ui/template~TemplateDefinition definition}\n * of a {@link module:ui/template~Template template}.\n *\n * @extends module:utils/collection~Collection\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class ViewCollection extends Collection {\n\t/**\n\t * Creates a new instance of the {@link module:ui/viewcollection~ViewCollection}.\n\t *\n\t * @param {module:utils/locale~Locale} [locale] The {@link module:core/editor/editor~Editor editor's locale} instance.\n\t */\n\tconstructor( locale ) {\n\t\tsuper( {\n\t\t\t// An #id Number attribute should be legal and not break the `ViewCollection` instance.\n\t\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/93\n\t\t\tidProperty: 'viewUid'\n\t\t} );\n\n\t\t// Handle {@link module:ui/view~View#element} in DOM when a new view is added to the collection.\n\t\tthis.on( 'add', ( evt, view, index ) => {\n\t\t\tif ( !view.isRendered ) {\n\t\t\t\tview.render();\n\t\t\t}\n\n\t\t\tif ( view.element && this._parentElement ) {\n\t\t\t\tthis._parentElement.insertBefore( view.element, this._parentElement.children[ index ] );\n\t\t\t}\n\t\t} );\n\n\t\t// Handle {@link module:ui/view~View#element} in DOM when a view is removed from the collection.\n\t\tthis.on( 'remove', ( evt, view ) => {\n\t\t\tif ( view.element && this._parentElement ) {\n\t\t\t\tview.element.remove();\n\t\t\t}\n\t\t} );\n\n\t\t/**\n\t\t * The {@link module:core/editor/editor~Editor#locale editor's locale} instance.\n\t\t * See the view {@link module:ui/view~View#locale locale} property.\n\t\t *\n\t\t * @member {module:utils/locale~Locale}\n\t\t */\n\t\tthis.locale = locale;\n\n\t\t/**\n\t\t * A parent element within which child views are rendered and managed in DOM.\n\t\t *\n\t\t * @protected\n\t\t * @member {HTMLElement}\n\t\t */\n\t\tthis._parentElement = null;\n\t}\n\n\t/**\n\t * Destroys the view collection along with child views.\n\t * See the view {@link module:ui/view~View#destroy} method.\n\t */\n\tdestroy() {\n\t\tthis.map( view => view.destroy() );\n\t}\n\n\t/**\n\t * Sets the parent HTML element of this collection. When parent is set, {@link #add adding} and\n\t * {@link #remove removing} views in the collection synchronizes their\n\t * {@link module:ui/view~View#element elements} in the parent element.\n\t *\n\t * @param {HTMLElement} element A new parent element.\n\t */\n\tsetParent( elementOrDocFragment ) {\n\t\tthis._parentElement = elementOrDocFragment;\n\t}\n\n\t/**\n\t * Delegates selected events coming from within views in the collection to any\n\t * {@link module:utils/emittermixin~Emitter}.\n\t *\n\t * For the following views and collection:\n\t *\n\t *\t\tconst viewA = new View();\n\t *\t\tconst viewB = new View();\n\t *\t\tconst viewC = new View();\n\t *\n\t *\t\tconst views = parentView.createCollection();\n\t *\n\t *\t\tviews.delegate( 'eventX' ).to( viewB );\n\t *\t\tviews.delegate( 'eventX', 'eventY' ).to( viewC );\n\t *\n\t *\t\tviews.add( viewA );\n\t *\n\t * the `eventX` is delegated (fired by) `viewB` and `viewC` along with `customData`:\n\t *\n\t *\t\tviewA.fire( 'eventX', customData );\n\t *\n\t * and `eventY` is delegated (fired by) `viewC` along with `customData`:\n\t *\n\t *\t\tviewA.fire( 'eventY', customData );\n\t *\n\t * See {@link module:utils/emittermixin~EmitterMixin#delegate}.\n\t *\n\t * @param {...String} events {@link module:ui/view~View} event names to be delegated to another\n\t * {@link module:utils/emittermixin~Emitter}.\n\t * @returns {Object}\n\t * @returns {Function} return.to A function which accepts the destination of\n\t * {@link module:utils/emittermixin~EmitterMixin#delegate delegated} events.\n\t */\n\tdelegate( ...events ) {\n\t\tif ( !events.length || !isStringArray( events ) ) {\n\t\t\t/**\n\t\t\t * All event names must be strings.\n\t\t\t *\n\t\t\t * @error ui-viewcollection-delegate-wrong-events\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'ui-viewcollection-delegate-wrong-events: All event names must be strings.' );\n\t\t}\n\n\t\treturn {\n\t\t\t/**\n\t\t\t * Selects destination for {@link module:utils/emittermixin~EmitterMixin#delegate} events.\n\t\t\t *\n\t\t\t * @memberOf module:ui/viewcollection~ViewCollection#delegate\n\t\t\t * @function module:ui/viewcollection~ViewCollection#delegate.to\n\t\t\t * @param {module:utils/emittermixin~EmitterMixin} dest An `EmitterMixin` instance which is\n\t\t\t * the destination for delegated events.\n\t\t\t */\n\t\t\tto: dest => {\n\t\t\t\t// Activate delegating on existing views in this collection.\n\t\t\t\tfor ( const view of this ) {\n\t\t\t\t\tfor ( const evtName of events ) {\n\t\t\t\t\t\tview.delegate( evtName ).to( dest );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Activate delegating on future views in this collection.\n\t\t\t\tthis.on( 'add', ( evt, view ) => {\n\t\t\t\t\tfor ( const evtName of events ) {\n\t\t\t\t\t\tview.delegate( evtName ).to( dest );\n\t\t\t\t\t}\n\t\t\t\t} );\n\n\t\t\t\t// Deactivate delegating when view is removed from this collection.\n\t\t\t\tthis.on( 'remove', ( evt, view ) => {\n\t\t\t\t\tfor ( const evtName of events ) {\n\t\t\t\t\t\tview.stopDelegating( evtName, dest );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Removes a child view from the collection. If the {@link #setParent parent element} of the\n\t * collection has been set, the {@link module:ui/view~View#element element} of the view is also removed\n\t * in DOM, reflecting the order of the collection.\n\t *\n\t * See the {@link #add} method.\n\t *\n\t * @method #remove\n\t * @param {module:ui/view~View|Number|String} subject The view to remove, its id or index in the collection.\n\t * @returns {Object} The removed view.\n\t */\n}\n\nmix( Collection, ObservableMixin );\n\n// Check if all entries of the array are of `String` type.\n//\n// @private\n// @param {Array} arr An array to be checked.\n// @returns {Boolean}\nfunction isStringArray( arr ) {\n\treturn arr.every( a => typeof a == 'string' );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/template\n */\n\n/* global document */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport View from './view';\nimport ViewCollection from './viewcollection';\nimport isNode from '@ckeditor/ckeditor5-utils/src/dom/isnode';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\nimport { isObject, cloneDeepWith } from 'lodash-es';\n\nconst xhtmlNs = 'http://www.w3.org/1999/xhtml';\n\n/**\n * A basic Template class. It renders a DOM HTML element or text from a\n * {@link module:ui/template~TemplateDefinition definition} and supports element attributes, children,\n * bindings to {@link module:utils/observablemixin~Observable observables} and DOM event propagation.\n *\n * A simple template can look like this:\n *\n *\t\tconst bind = Template.bind( observable, emitter );\n *\n *\t\tnew Template( {\n *\t\t\ttag: 'p',\n *\t\t\tattributes: {\n *\t\t\t\tclass: 'foo',\n *\t\t\t\tstyle: {\n *\t\t\t\t\tbackgroundColor: 'yellow'\n *\t\t\t\t}\n *\t\t\t},\n *\t\t\ton: {\n *\t\t\t\tclick: bind.to( 'clicked' )\n *\t\t\t}\n *\t\t\tchildren: [\n *\t\t\t\t'A paragraph.'\n *\t\t\t]\n *\t\t} ).render();\n *\n * and it will render the following HTML element:\n *\n *\t\t<p class=\"foo\" style=\"background-color: yellow;\">A paragraph.</p>\n *\n * Additionally, the `observable` will always fire `clicked` upon clicking `<p>` in the DOM.\n *\n * See {@link module:ui/template~TemplateDefinition} to know more about templates and complex\n * template definitions.\n *\n* @mixes module:utils/emittermixin~EmitterMixin\n */\nexport default class Template {\n\t/**\n\t * Creates an instance of the {@link ~Template} class.\n\t *\n\t * @param {module:ui/template~TemplateDefinition} def The definition of the template.\n\t */\n\tconstructor( def ) {\n\t\tObject.assign( this, normalize( clone( def ) ) );\n\n\t\t/**\n\t\t * Indicates whether this particular Template instance has been\n\t\t * {@link #render rendered}.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis._isRendered = false;\n\n\t\t/**\n\t\t * The tag (`tagName`) of this template, e.g. `div`. It also indicates that the template\n\t\t * renders to an HTML element.\n\t\t *\n\t\t * @member {String} #tag\n\t\t */\n\n\t\t/**\n\t\t * The text of the template. It also indicates that the template renders to a DOM text node.\n\t\t *\n\t\t * @member {Array.<String|module:ui/template~TemplateValueSchema>} #text\n\t\t */\n\n\t\t/**\n\t\t * The attributes of the template, e.g. `{ id: [ 'ck-id' ] }`, corresponding with\n\t\t * the attributes of an HTML element.\n\t\t *\n\t\t * **Note**: This property only makes sense when {@link #tag} is defined.\n\t\t *\n\t\t * @member {Object} #attributes\n\t\t */\n\n\t\t/**\n\t\t * The children of the template. They can be either:\n\t\t * * independent instances of {@link ~Template} (sub–templates),\n\t\t * * native DOM Nodes.\n\t\t *\n\t\t * **Note**: This property only makes sense when {@link #tag} is defined.\n\t\t *\n\t\t * @member {Array.<module:ui/template~Template|Node>} #children\n\t\t */\n\n\t\t/**\n\t\t * The DOM event listeners of the template.\n\t\t *\n\t\t * @member {Object} #eventListeners\n\t\t */\n\n\t\t/**\n\t\t * The data used by the {@link #revert} method to restore a node to its original state.\n\t\t *\n\t\t * See: {@link #apply}.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/template~RenderData}\n\t\t */\n\t\tthis._revertData = null;\n\t}\n\n\t/**\n\t * Renders a DOM Node (an HTML element or text) out of the template.\n\t *\n\t *\t\tconst domNode = new Template( { ... } ).render();\n\t *\n\t * See: {@link #apply}.\n\t *\n\t * @returns {HTMLElement|Text}\n\t */\n\trender() {\n\t\tconst node = this._renderNode( {\n\t\t\tintoFragment: true\n\t\t} );\n\n\t\tthis._isRendered = true;\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Applies the template to an existing DOM Node, either HTML element or text.\n\t *\n\t * **Note:** No new DOM nodes will be created. Applying extends\n\t * {@link module:ui/template~TemplateDefinition attributes} and\n\t * {@link module:ui/template~TemplateDefinition event listeners} only.\n\t *\n\t * **Note:** Existing `class` and `style` attributes are extended when a template\n\t * is applied to an HTML element, while other attributes and `textContent` are overridden.\n\t *\n\t * **Note:** The process of applying a template can be easily reverted using the\n\t * {@link module:ui/template~Template#revert} method.\n\t *\n\t *\t\tconst element = document.createElement( 'div' );\n\t *\t\tconst bind = Template.bind( observable, emitter );\n\t *\n\t *\t\tnew Template( {\n\t *\t\t\tattrs: {\n\t *\t\t\t\tid: 'first-div',\n\t *\t\t\t\tclass: bind.to( 'divClass' )\n\t *\t\t\t},\n\t *\t\t\ton: {\n\t *\t\t\t\tclick: bind( 'elementClicked' ) // Will be fired by the observable.\n\t *\t\t\t}\n\t *\t\t\tchildren: [\n\t *\t\t\t\t'Div text.'\n\t *\t\t\t]\n\t *\t\t} ).apply( element );\n\t *\n\t *\t\telement.outerHTML == \"<div id=\"first-div\" class=\"my-div\">Div text.</div>\"\n\t *\n\t * @see module:ui/template~Template#render\n\t * @see module:ui/template~Template#revert\n\t * @param {Node} node Root node for the template to apply.\n\t */\n\tapply( node ) {\n\t\tthis._revertData = getEmptyRevertData();\n\n\t\tthis._renderNode( {\n\t\t\tnode,\n\t\t\tisApplying: true,\n\t\t\trevertData: this._revertData\n\t\t} );\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Reverts a template {@link module:ui/template~Template#apply applied} to a DOM node.\n\t *\n\t * @param {Node} node The root node for the template to revert. In most of the cases, it is the\n\t * same node used by {@link module:ui/template~Template#apply}.\n\t */\n\trevert( node ) {\n\t\tif ( !this._revertData ) {\n\t\t\t/**\n\t\t\t * Attempting to revert a template which has not been applied yet.\n\t\t\t *\n\t\t\t * @error ui-template-revert-not-applied\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'ui-template-revert-not-applied: Attempting to revert a template which has not been applied yet.' );\n\t\t}\n\n\t\tthis._revertTemplateFromNode( node, this._revertData );\n\t}\n\n\t/**\n\t * Returns an iterator which traverses the template in search of {@link module:ui/view~View}\n\t * instances and returns them one by one.\n\t *\n\t *\t\tconst viewFoo = new View();\n\t *\t\tconst viewBar = new View();\n\t *\t\tconst viewBaz = new View();\n\t *\t\tconst template = new Template( {\n\t *\t\t\ttag: 'div',\n\t *\t\t\tchildren: [\n\t *\t\t\t\tviewFoo,\n\t *\t\t\t\t{\n\t *\t\t\t\t\ttag: 'div',\n\t *\t\t\t\t\tchildren: [\n\t *\t\t\t\t\t\tviewBar\n\t *\t\t\t\t\t]\n\t *\t\t\t\t},\n\t *\t\t\t\tviewBaz\n\t *\t\t\t]\n\t *\t\t} );\n\t *\n\t *\t\t// Logs: viewFoo, viewBar, viewBaz\n\t *\t\tfor ( const view of template.getViews() ) {\n\t *\t\t\tconsole.log( view );\n\t *\t\t}\n\t *\n\t * @returns {Iterable.<module:ui/view~View>}\n\t */\n\t* getViews() {\n\t\tfunction* search( def ) {\n\t\t\tif ( def.children ) {\n\t\t\t\tfor ( const child of def.children ) {\n\t\t\t\t\tif ( isView( child ) ) {\n\t\t\t\t\t\tyield child;\n\t\t\t\t\t} else if ( isTemplate( child ) ) {\n\t\t\t\t\t\tyield* search( child );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tyield* search( this );\n\t}\n\n\t/**\n\t * An entry point to the interface which binds DOM nodes to\n\t * {@link module:utils/observablemixin~Observable observables}.\n\t * There are two types of bindings:\n\t *\n\t * * HTML element attributes or text `textContent` synchronized with attributes of an\n\t * {@link module:utils/observablemixin~Observable}. Learn more about {@link module:ui/template~BindChain#to}\n\t * and {@link module:ui/template~BindChain#if}.\n\t *\n\t *\t\tconst bind = Template.bind( observable, emitter );\n\t *\n\t *\t\tnew Template( {\n\t *\t\t\tattrs: {\n\t *\t\t\t\t// Binds the element \"class\" attribute to observable#classAttribute.\n\t *\t\t\t\tclass: bind.to( 'classAttribute' )\n\t *\t\t\t}\n\t *\t\t} ).render();\n\t *\n\t * * DOM events fired on HTML element propagated through\n\t * {@link module:utils/observablemixin~Observable}. Learn more about {@link module:ui/template~BindChain#to}.\n\t *\n\t *\t\tconst bind = Template.bind( observable, emitter );\n\t *\n\t *\t\tnew Template( {\n\t *\t\t\ton: {\n\t *\t\t\t\t// Will be fired by the observable.\n\t *\t\t\t\tclick: bind( 'elementClicked' )\n\t *\t\t\t}\n\t *\t\t} ).render();\n\t *\n\t * Also see {@link module:ui/view~View#bindTemplate}.\n\t *\n\t * @param {module:utils/observablemixin~Observable} observable An observable which provides boundable attributes.\n\t * @param {module:utils/emittermixin~Emitter} emitter An emitter that listens to observable attribute\n\t * changes or DOM Events (depending on the kind of the binding). Usually, a {@link module:ui/view~View} instance.\n\t * @returns {module:ui/template~BindChain}\n\t */\n\tstatic bind( observable, emitter ) {\n\t\treturn {\n\t\t\tto( eventNameOrFunctionOrAttribute, callback ) {\n\t\t\t\treturn new TemplateToBinding( {\n\t\t\t\t\teventNameOrFunction: eventNameOrFunctionOrAttribute,\n\t\t\t\t\tattribute: eventNameOrFunctionOrAttribute,\n\t\t\t\t\tobservable, emitter, callback\n\t\t\t\t} );\n\t\t\t},\n\n\t\t\tif( attribute, valueIfTrue, callback ) {\n\t\t\t\treturn new TemplateIfBinding( {\n\t\t\t\t\tobservable, emitter, attribute, valueIfTrue, callback\n\t\t\t\t} );\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Extends an existing {@link module:ui/template~Template} instance with some additional content\n\t * from another {@link module:ui/template~TemplateDefinition}.\n\t *\n\t *\t\tconst bind = Template.bind( observable, emitter );\n\t *\n\t *\t\tconst template = new Template( {\n\t *\t\t\ttag: 'p',\n\t *\t\t\tattributes: {\n\t *\t\t\t\tclass: 'a',\n\t *\t\t\t\tdata-x: bind.to( 'foo' )\n\t *\t\t\t},\n\t *\t\t\tchildren: [\n\t *\t\t\t\t{\n\t *\t\t\t\t\ttag: 'span',\n\t *\t\t\t\t\tattributes: {\n\t *\t\t\t\t\t\tclass: 'b'\n\t *\t\t\t\t\t},\n\t *\t\t\t\t\tchildren: [\n\t *\t\t\t\t\t\t'Span'\n\t *\t\t\t\t\t]\n\t *\t\t\t\t}\n\t *\t\t\t]\n\t *\t\t } );\n\t *\n\t *\t\t// Instance-level extension.\n\t *\t\tTemplate.extend( template, {\n\t *\t\t\tattributes: {\n\t *\t\t\t\tclass: 'b',\n\t *\t\t\t\tdata-x: bind.to( 'bar' )\n\t *\t\t\t},\n\t *\t\t\tchildren: [\n\t *\t\t\t\t{\n\t *\t\t\t\t\tattributes: {\n\t *\t\t\t\t\t\tclass: 'c'\n\t *\t\t\t\t\t}\n\t *\t\t\t\t}\n\t *\t\t\t]\n\t *\t\t} );\n\t *\n\t *\t\t// Child extension.\n\t *\t\tTemplate.extend( template.children[ 0 ], {\n\t *\t\t\tattributes: {\n\t *\t\t\t\tclass: 'd'\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * the `outerHTML` of `template.render()` is:\n\t *\n\t *\t\t<p class=\"a b\" data-x=\"{ observable.foo } { observable.bar }\">\n\t *\t\t\t<span class=\"b c d\">Span</span>\n\t *\t\t</p>\n\t *\n\t * @param {module:ui/template~Template} template An existing template instance to be extended.\n\t * @param {module:ui/template~TemplateDefinition} def Additional definition to be applied to a template.\n\t */\n\tstatic extend( template, def ) {\n\t\tif ( template._isRendered ) {\n\t\t\t/**\n\t\t\t * Extending a template after rendering may not work as expected. To make sure\n\t\t\t * the {@link module:ui/template~Template.extend extending} works for an element,\n\t\t\t * make sure it happens before {@link #render} is called.\n\t\t\t *\n\t\t\t * @error template-extend-render\n\t\t\t */\n\t\t\tlog.warn( 'template-extend-render: Attempting to extend a template which has already been rendered.' );\n\t\t}\n\n\t\textendTemplate( template, normalize( clone( def ) ) );\n\t}\n\n\t/**\n\t * Renders a DOM Node (either an HTML element or text) out of the template.\n\t *\n\t * @protected\n\t * @param {module:ui/template~RenderData} data Rendering data.\n\t */\n\t_renderNode( data ) {\n\t\tlet isInvalid;\n\n\t\tif ( data.node ) {\n\t\t\t// When applying, a definition cannot have \"tag\" and \"text\" at the same time.\n\t\t\tisInvalid = this.tag && this.text;\n\t\t} else {\n\t\t\t// When rendering, a definition must have either \"tag\" or \"text\": XOR( this.tag, this.text ).\n\t\t\tisInvalid = this.tag ? this.text : !this.text;\n\t\t}\n\n\t\tif ( isInvalid ) {\n\t\t\t/**\n\t\t\t * Node definition cannot have the \"tag\" and \"text\" properties at the same time.\n\t\t\t * Node definition must have either \"tag\" or \"text\" when rendering a new Node.\n\t\t\t *\n\t\t\t * @error ui-template-wrong-syntax\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'ui-template-wrong-syntax: Node definition must have either \"tag\" or \"text\" when rendering a new Node.'\n\t\t\t);\n\t\t}\n\n\t\tif ( this.text ) {\n\t\t\treturn this._renderText( data );\n\t\t} else {\n\t\t\treturn this._renderElement( data );\n\t\t}\n\t}\n\n\t/**\n\t * Renders an HTML element out of the template.\n\t *\n\t * @protected\n\t * @param {module:ui/template~RenderData} data Rendering data.\n\t */\n\t_renderElement( data ) {\n\t\tlet node = data.node;\n\n\t\tif ( !node ) {\n\t\t\tnode = data.node = document.createElementNS( this.ns || xhtmlNs, this.tag );\n\t\t}\n\n\t\tthis._renderAttributes( data );\n\t\tthis._renderElementChildren( data );\n\t\tthis._setUpListeners( data );\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Renders a text node out of {@link module:ui/template~Template#text}.\n\t *\n\t * @protected\n\t * @param {module:ui/template~RenderData} data Rendering data.\n\t */\n\t_renderText( data ) {\n\t\tlet node = data.node;\n\n\t\t// Save the original textContent to revert it in #revert().\n\t\tif ( node ) {\n\t\t\tdata.revertData.text = node.textContent;\n\t\t} else {\n\t\t\tnode = data.node = document.createTextNode( '' );\n\t\t}\n\n\t\t// Check if this Text Node is bound to Observable. Cases:\n\t\t//\n\t\t//\t\ttext: [ Template.bind( ... ).to( ... ) ]\n\t\t//\n\t\t//\t\ttext: [\n\t\t//\t\t\t'foo',\n\t\t//\t\t\tTemplate.bind( ... ).to( ... ),\n\t\t//\t\t\t...\n\t\t//\t\t]\n\t\t//\n\t\tif ( hasTemplateBinding( this.text ) ) {\n\t\t\tthis._bindToObservable( {\n\t\t\t\tschema: this.text,\n\t\t\t\tupdater: getTextUpdater( node ),\n\t\t\t\tdata\n\t\t\t} );\n\t\t}\n\t\t// Simply set text. Cases:\n\t\t//\n\t\t//\t\ttext: [ 'all', 'are', 'static' ]\n\t\t//\n\t\t//\t\ttext: [ 'foo' ]\n\t\t//\n\t\telse {\n\t\t\tnode.textContent = this.text.join( '' );\n\t\t}\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Renders HTML element attributes out of {@link module:ui/template~Template#attributes}.\n\t *\n\t * @protected\n\t * @param {module:ui/template~RenderData} data Rendering data.\n\t */\n\t_renderAttributes( data ) {\n\t\tlet attrName, attrValue, domAttrValue, attrNs;\n\n\t\tif ( !this.attributes ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst node = data.node;\n\t\tconst revertData = data.revertData;\n\n\t\tfor ( attrName in this.attributes ) {\n\t\t\t// Current attribute value in DOM.\n\t\t\tdomAttrValue = node.getAttribute( attrName );\n\n\t\t\t// The value to be set.\n\t\t\tattrValue = this.attributes[ attrName ];\n\n\t\t\t// Save revert data.\n\t\t\tif ( revertData ) {\n\t\t\t\trevertData.attributes[ attrName ] = domAttrValue;\n\t\t\t}\n\n\t\t\t// Detect custom namespace:\n\t\t\t//\n\t\t\t//\t\tclass: {\n\t\t\t//\t\t\tns: 'abc',\n\t\t\t//\t\t\tvalue: Template.bind( ... ).to( ... )\n\t\t\t//\t\t}\n\t\t\t//\n\t\t\tattrNs = ( isObject( attrValue[ 0 ] ) && attrValue[ 0 ].ns ) ? attrValue[ 0 ].ns : null;\n\n\t\t\t// Activate binding if one is found. Cases:\n\t\t\t//\n\t\t\t//\t\tclass: [\n\t\t\t//\t\t\tTemplate.bind( ... ).to( ... )\n\t\t\t//\t\t]\n\t\t\t//\n\t\t\t//\t\tclass: [\n\t\t\t//\t\t\t'bar',\n\t\t\t//\t\t\tTemplate.bind( ... ).to( ... ),\n\t\t\t//\t\t\t'baz'\n\t\t\t//\t\t]\n\t\t\t//\n\t\t\t//\t\tclass: {\n\t\t\t//\t\t\tns: 'abc',\n\t\t\t//\t\t\tvalue: Template.bind( ... ).to( ... )\n\t\t\t//\t\t}\n\t\t\t//\n\t\t\tif ( hasTemplateBinding( attrValue ) ) {\n\t\t\t\t// Normalize attributes with additional data like namespace:\n\t\t\t\t//\n\t\t\t\t//\t\tclass: {\n\t\t\t\t//\t\t\tns: 'abc',\n\t\t\t\t//\t\t\tvalue: [ ... ]\n\t\t\t\t//\t\t}\n\t\t\t\t//\n\t\t\t\tconst valueToBind = attrNs ? attrValue[ 0 ].value : attrValue;\n\n\t\t\t\t// Extend the original value of attributes like \"style\" and \"class\",\n\t\t\t\t// don't override them.\n\t\t\t\tif ( revertData && shouldExtend( attrName ) ) {\n\t\t\t\t\tvalueToBind.unshift( domAttrValue );\n\t\t\t\t}\n\n\t\t\t\tthis._bindToObservable( {\n\t\t\t\t\tschema: valueToBind,\n\t\t\t\t\tupdater: getAttributeUpdater( node, attrName, attrNs ),\n\t\t\t\t\tdata\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// Style attribute could be an Object so it needs to be parsed in a specific way.\n\t\t\t//\n\t\t\t//\t\tstyle: {\n\t\t\t//\t\t\twidth: '100px',\n\t\t\t//\t\t\theight: Template.bind( ... ).to( ... )\n\t\t\t//\t\t}\n\t\t\t//\n\t\t\telse if ( attrName == 'style' && typeof attrValue[ 0 ] !== 'string' ) {\n\t\t\t\tthis._renderStyleAttribute( attrValue[ 0 ], data );\n\t\t\t}\n\n\t\t\t// Otherwise simply set the static attribute:\n\t\t\t//\n\t\t\t//\t\tclass: [ 'foo' ]\n\t\t\t//\n\t\t\t//\t\tclass: [ 'all', 'are', 'static' ]\n\t\t\t//\n\t\t\t//\t\tclass: [\n\t\t\t//\t\t\t{\n\t\t\t//\t\t\t\tns: 'abc',\n\t\t\t//\t\t\t\tvalue: [ 'foo' ]\n\t\t\t//\t\t\t}\n\t\t\t//\t\t]\n\t\t\t//\n\t\t\telse {\n\t\t\t\t// Extend the original value of attributes like \"style\" and \"class\",\n\t\t\t\t// don't override them.\n\t\t\t\tif ( revertData && domAttrValue && shouldExtend( attrName ) ) {\n\t\t\t\t\tattrValue.unshift( domAttrValue );\n\t\t\t\t}\n\n\t\t\t\tattrValue = attrValue\n\t\t\t\t\t// Retrieve \"values\" from:\n\t\t\t\t\t//\n\t\t\t\t\t//\t\tclass: [\n\t\t\t\t\t//\t\t\t{\n\t\t\t\t\t//\t\t\t\tns: 'abc',\n\t\t\t\t\t//\t\t\t\tvalue: [ ... ]\n\t\t\t\t\t//\t\t\t}\n\t\t\t\t\t//\t\t]\n\t\t\t\t\t//\n\t\t\t\t\t.map( val => val ? ( val.value || val ) : val )\n\t\t\t\t\t// Flatten the array.\n\t\t\t\t\t.reduce( ( prev, next ) => prev.concat( next ), [] )\n\t\t\t\t\t// Convert into string.\n\t\t\t\t\t.reduce( arrayValueReducer, '' );\n\n\t\t\t\tif ( !isFalsy( attrValue ) ) {\n\t\t\t\t\tnode.setAttributeNS( attrNs, attrName, attrValue );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Renders the `style` attribute of an HTML element based on\n\t * {@link module:ui/template~Template#attributes}.\n\t *\n\t * A style attribute is an {Object} with static values:\n\t *\n\t *\t\tattributes: {\n\t *\t\t\tstyle: {\n\t *\t\t\t\tcolor: 'red'\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t * or values bound to {@link module:ui/model~Model} properties:\n\t *\n\t *\t\tattributes: {\n\t *\t\t\tstyle: {\n\t *\t\t\t\tcolor: bind.to( ... )\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t * Note: The `style` attribute is rendered without setting the namespace. It does not seem to be\n\t * needed.\n\t *\n\t * @private\n\t * @param {Object} styles Styles located in `attributes.style` of {@link module:ui/template~TemplateDefinition}.\n\t * @param {module:ui/template~RenderData} data Rendering data.\n\t */\n\t_renderStyleAttribute( styles, data ) {\n\t\tconst node = data.node;\n\n\t\tfor ( const styleName in styles ) {\n\t\t\tconst styleValue = styles[ styleName ];\n\n\t\t\t// Cases:\n\t\t\t//\n\t\t\t//\t\tstyle: {\n\t\t\t//\t\t\tcolor: bind.to( 'attribute' )\n\t\t\t//\t\t}\n\t\t\t//\n\t\t\tif ( hasTemplateBinding( styleValue ) ) {\n\t\t\t\tthis._bindToObservable( {\n\t\t\t\t\tschema: [ styleValue ],\n\t\t\t\t\tupdater: getStyleUpdater( node, styleName ),\n\t\t\t\t\tdata\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// Cases:\n\t\t\t//\n\t\t\t//\t\tstyle: {\n\t\t\t//\t\t\tcolor: 'red'\n\t\t\t//\t\t}\n\t\t\t//\n\t\t\telse {\n\t\t\t\tnode.style[ styleName ] = styleValue;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Recursively renders HTML element's children from {@link module:ui/template~Template#children}.\n\t *\n\t * @protected\n\t * @param {module:ui/template~RenderData} data Rendering data.\n\t */\n\t_renderElementChildren( data ) {\n\t\tconst node = data.node;\n\t\tconst container = data.intoFragment ? document.createDocumentFragment() : node;\n\t\tconst isApplying = data.isApplying;\n\t\tlet childIndex = 0;\n\n\t\tfor ( const child of this.children ) {\n\t\t\tif ( isViewCollection( child ) ) {\n\t\t\t\tif ( !isApplying ) {\n\t\t\t\t\tchild.setParent( node );\n\n\t\t\t\t\t// Note: ViewCollection renders its children.\n\t\t\t\t\tfor ( const view of child ) {\n\t\t\t\t\t\tcontainer.appendChild( view.element );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if ( isView( child ) ) {\n\t\t\t\tif ( !isApplying ) {\n\t\t\t\t\tif ( !child.isRendered ) {\n\t\t\t\t\t\tchild.render();\n\t\t\t\t\t}\n\n\t\t\t\t\tcontainer.appendChild( child.element );\n\t\t\t\t}\n\t\t\t} else if ( isNode( child ) ) {\n\t\t\t\tcontainer.appendChild( child );\n\t\t\t} else {\n\t\t\t\tif ( isApplying ) {\n\t\t\t\t\tconst revertData = data.revertData;\n\t\t\t\t\tconst childRevertData = getEmptyRevertData();\n\n\t\t\t\t\trevertData.children.push( childRevertData );\n\n\t\t\t\t\tchild._renderNode( {\n\t\t\t\t\t\tnode: container.childNodes[ childIndex++ ],\n\t\t\t\t\t\tisApplying: true,\n\t\t\t\t\t\trevertData: childRevertData\n\t\t\t\t\t} );\n\t\t\t\t} else {\n\t\t\t\t\tcontainer.appendChild( child.render() );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( data.intoFragment ) {\n\t\t\tnode.appendChild( container );\n\t\t}\n\t}\n\n\t/**\n\t * Activates `on` event listeners from the {@link module:ui/template~TemplateDefinition}\n\t * on an HTML element.\n\t *\n\t * @protected\n\t * @param {module:ui/template~RenderData} data Rendering data.\n\t */\n\t_setUpListeners( data ) {\n\t\tif ( !this.eventListeners ) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor ( const key in this.eventListeners ) {\n\t\t\tconst revertBindings = this.eventListeners[ key ].map( schemaItem => {\n\t\t\t\tconst [ domEvtName, domSelector ] = key.split( '@' );\n\n\t\t\t\treturn schemaItem.activateDomEventListener( domEvtName, domSelector, data );\n\t\t\t} );\n\n\t\t\tif ( data.revertData ) {\n\t\t\t\tdata.revertData.bindings.push( revertBindings );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * For a given {@link module:ui/template~TemplateValueSchema} containing {@link module:ui/template~TemplateBinding}\n\t * activates the binding and sets its initial value.\n\t *\n\t * Note: {@link module:ui/template~TemplateValueSchema} can be for HTML element attributes or\n\t * text node `textContent`.\n\t *\n\t * @protected\n\t * @param {Object} options Binding options.\n\t * @param {module:ui/template~TemplateValueSchema} options.schema\n\t * @param {Function} options.updater A function which updates the DOM (like attribute or text).\n\t * @param {module:ui/template~RenderData} options.data Rendering data.\n\t */\n\t_bindToObservable( { schema, updater, data } ) {\n\t\tconst revertData = data.revertData;\n\n\t\t// Set initial values.\n\t\tsyncValueSchemaValue( schema, updater, data );\n\n\t\tconst revertBindings = schema\n\t\t\t// Filter \"falsy\" (false, undefined, null, '') value schema components out.\n\t\t\t.filter( item => !isFalsy( item ) )\n\t\t\t// Filter inactive bindings from schema, like static strings ('foo'), numbers (42), etc.\n\t\t\t.filter( item => item.observable )\n\t\t\t// Once only the actual binding are left, let the emitter listen to observable change:attribute event.\n\t\t\t// TODO: Reduce the number of listeners attached as many bindings may listen\n\t\t\t// to the same observable attribute.\n\t\t\t.map( templateBinding => templateBinding.activateAttributeListener( schema, updater, data ) );\n\n\t\tif ( revertData ) {\n\t\t\trevertData.bindings.push( revertBindings );\n\t\t}\n\t}\n\n\t/**\n\t * Reverts {@link module:ui/template~RenderData#revertData template data} from a node to\n\t * return it to the original state.\n\t *\n\t * @protected\n\t * @param {HTMLElement|Text} node A node to be reverted.\n\t * @param {module:ui/template~RenderData#revertData} revertData Stores information about\n\t * what changes have been made by {@link #apply} to the node.\n\t */\n\t_revertTemplateFromNode( node, revertData ) {\n\t\tfor ( const binding of revertData.bindings ) {\n\t\t\t// Each binding may consist of several observable+observable#attribute.\n\t\t\t// like the following has 2:\n\t\t\t//\n\t\t\t//\t\tclass: [\n\t\t\t//\t\t\t'x',\n\t\t\t//\t\t\tbind.to( 'foo' ),\n\t\t\t//\t\t\t'y',\n\t\t\t//\t\t\tbind.to( 'bar' )\n\t\t\t//\t\t]\n\t\t\t//\n\t\t\tfor ( const revertBinding of binding ) {\n\t\t\t\trevertBinding();\n\t\t\t}\n\t\t}\n\n\t\tif ( revertData.text ) {\n\t\t\tnode.textContent = revertData.text;\n\n\t\t\treturn;\n\t\t}\n\n\t\tfor ( const attrName in revertData.attributes ) {\n\t\t\tconst attrValue = revertData.attributes[ attrName ];\n\n\t\t\t// When the attribute has **not** been set before #apply().\n\t\t\tif ( attrValue === null ) {\n\t\t\t\tnode.removeAttribute( attrName );\n\t\t\t} else {\n\t\t\t\tnode.setAttribute( attrName, attrValue );\n\t\t\t}\n\t\t}\n\n\t\tfor ( let i = 0; i < revertData.children.length; ++i ) {\n\t\t\tthis._revertTemplateFromNode( node.childNodes[ i ], revertData.children[ i ] );\n\t\t}\n\t}\n}\n\nmix( Template, EmitterMixin );\n\n/**\n * Describes a binding created by the {@link module:ui/template~Template.bind} interface.\n *\n * @protected\n */\nexport class TemplateBinding {\n\t/**\n\t * Creates an instance of the {@link module:ui/template~TemplateBinding} class.\n\t *\n\t * @param {module:ui/template~TemplateDefinition} def The definition of the binding.\n\t */\n\tconstructor( def ) {\n\t\tObject.assign( this, def );\n\n\t\t/**\n\t\t * An observable instance of the binding. It either:\n\t\t *\n\t\t * * provides the attribute with the value,\n\t\t * * or passes the event when a corresponding DOM event is fired.\n\t\t *\n\t\t * @member {module:utils/observablemixin~ObservableMixin} module:ui/template~TemplateBinding#observable\n\t\t */\n\n\t\t/**\n\t\t * An {@link module:utils/emittermixin~Emitter} used by the binding to:\n\t\t *\n\t\t * * listen to the attribute change in the {@link module:ui/template~TemplateBinding#observable},\n\t\t * * or listen to the event in the DOM.\n\t\t *\n\t\t * @member {module:utils/emittermixin~EmitterMixin} module:ui/template~TemplateBinding#emitter\n\t\t */\n\n\t\t/**\n\t\t * The name of the {@link module:ui/template~TemplateBinding#observable observed attribute}.\n\t\t *\n\t\t * @member {String} module:ui/template~TemplateBinding#attribute\n\t\t */\n\n\t\t/**\n\t\t * A custom function to process the value of the {@link module:ui/template~TemplateBinding#attribute}.\n\t\t *\n\t\t * @member {Function} [module:ui/template~TemplateBinding#callback]\n\t\t */\n\t}\n\n\t/**\n\t * Returns the value of the binding. It is the value of the {@link module:ui/template~TemplateBinding#attribute} in\n\t * {@link module:ui/template~TemplateBinding#observable}. The value may be processed by the\n\t * {@link module:ui/template~TemplateBinding#callback}, if such has been passed to the binding.\n\t *\n\t * @param {Node} [node] A native DOM node, passed to the custom {@link module:ui/template~TemplateBinding#callback}.\n\t * @returns {*} The value of {@link module:ui/template~TemplateBinding#attribute} in\n\t * {@link module:ui/template~TemplateBinding#observable}.\n\t */\n\tgetValue( node ) {\n\t\tconst value = this.observable[ this.attribute ];\n\n\t\treturn this.callback ? this.callback( value, node ) : value;\n\t}\n\n\t/**\n\t * Activates the listener which waits for changes of the {@link module:ui/template~TemplateBinding#attribute} in\n\t * {@link module:ui/template~TemplateBinding#observable}, then updates the DOM with the aggregated\n\t * value of {@link module:ui/template~TemplateValueSchema}.\n\t *\n\t * @param {module:ui/template~TemplateValueSchema} schema A full schema to generate an attribute or text in the DOM.\n\t * @param {Function} updater A DOM updater function used to update the native DOM attribute or text.\n\t * @param {module:ui/template~RenderData} data Rendering data.\n\t * @returns {Function} A function to sever the listener binding.\n\t */\n\tactivateAttributeListener( schema, updater, data ) {\n\t\tconst callback = () => syncValueSchemaValue( schema, updater, data );\n\n\t\tthis.emitter.listenTo( this.observable, 'change:' + this.attribute, callback );\n\n\t\t// Allows revert of the listener.\n\t\treturn () => {\n\t\t\tthis.emitter.stopListening( this.observable, 'change:' + this.attribute, callback );\n\t\t};\n\t}\n}\n\n/**\n * Describes either:\n *\n * * a binding to an {@link module:utils/observablemixin~Observable},\n * * or a native DOM event binding.\n *\n * It is created by the {@link module:ui/template~BindChain#to} method.\n *\n * @protected\n */\nexport class TemplateToBinding extends TemplateBinding {\n\t/**\n\t * Activates the listener for the native DOM event, which when fired, is propagated by\n\t * the {@link module:ui/template~TemplateBinding#emitter}.\n\t *\n\t * @param {String} domEvtName The name of the native DOM event.\n\t * @param {String} domSelector The selector in the DOM to filter delegated events.\n\t * @param {module:ui/template~RenderData} data Rendering data.\n\t * @returns {Function} A function to sever the listener binding.\n\t */\n\tactivateDomEventListener( domEvtName, domSelector, data ) {\n\t\tconst callback = ( evt, domEvt ) => {\n\t\t\tif ( !domSelector || domEvt.target.matches( domSelector ) ) {\n\t\t\t\tif ( typeof this.eventNameOrFunction == 'function' ) {\n\t\t\t\t\tthis.eventNameOrFunction( domEvt );\n\t\t\t\t} else {\n\t\t\t\t\tthis.observable.fire( this.eventNameOrFunction, domEvt );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tthis.emitter.listenTo( data.node, domEvtName, callback );\n\n\t\t// Allows revert of the listener.\n\t\treturn () => {\n\t\t\tthis.emitter.stopListening( data.node, domEvtName, callback );\n\t\t};\n\t}\n}\n\n/**\n * Describes a binding to {@link module:utils/observablemixin~ObservableMixin} created by the {@link module:ui/template~BindChain#if}\n * method.\n *\n * @protected\n */\nexport class TemplateIfBinding extends TemplateBinding {\n\t/**\n\t * @inheritDoc\n\t */\n\tgetValue( node ) {\n\t\tconst value = super.getValue( node );\n\n\t\treturn isFalsy( value ) ? false : ( this.valueIfTrue || true );\n\t}\n\n\t/**\n\t * The value of the DOM attribute or text to be set if the {@link module:ui/template~TemplateBinding#attribute} in\n\t * {@link module:ui/template~TemplateBinding#observable} is `true`.\n\t *\n\t * @member {String} [module:ui/template~TemplateIfBinding#valueIfTrue]\n\t */\n}\n\n// Checks whether given {@link module:ui/template~TemplateValueSchema} contains a\n// {@link module:ui/template~TemplateBinding}.\n//\n// @param {module:ui/template~TemplateValueSchema} schema\n// @returns {Boolean}\nfunction hasTemplateBinding( schema ) {\n\tif ( !schema ) {\n\t\treturn false;\n\t}\n\n\t// Normalize attributes with additional data like namespace:\n\t//\n\t//\t\tclass: {\n\t//\t\t\tns: 'abc',\n\t//\t\t\tvalue: [ ... ]\n\t//\t\t}\n\t//\n\tif ( schema.value ) {\n\t\tschema = schema.value;\n\t}\n\n\tif ( Array.isArray( schema ) ) {\n\t\treturn schema.some( hasTemplateBinding );\n\t} else if ( schema instanceof TemplateBinding ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n// Assembles the value using {@link module:ui/template~TemplateValueSchema} and stores it in a form of\n// an Array. Each entry of the Array corresponds to one of {@link module:ui/template~TemplateValueSchema}\n// items.\n//\n// @param {module:ui/template~TemplateValueSchema} schema\n// @param {Node} node DOM Node updated when {@link module:utils/observablemixin~ObservableMixin} changes.\n// @returns {Array}\nfunction getValueSchemaValue( schema, node ) {\n\treturn schema.map( schemaItem => {\n\t\t// Process {@link module:ui/template~TemplateBinding} bindings.\n\t\tif ( schemaItem instanceof TemplateBinding ) {\n\t\t\treturn schemaItem.getValue( node );\n\t\t}\n\n\t\t// All static values like strings, numbers, and \"falsy\" values (false, null, undefined, '', etc.) just pass.\n\t\treturn schemaItem;\n\t} );\n}\n\n// A function executed each time the bound Observable attribute changes, which updates the DOM with a value\n// constructed from {@link module:ui/template~TemplateValueSchema}.\n//\n// @param {module:ui/template~TemplateValueSchema} schema\n// @param {Function} updater A function which updates the DOM (like attribute or text).\n// @param {Node} node DOM Node updated when {@link module:utils/observablemixin~ObservableMixin} changes.\nfunction syncValueSchemaValue( schema, updater, { node } ) {\n\tlet value = getValueSchemaValue( schema, node );\n\n\t// Check if schema is a single Template.bind.if, like:\n\t//\n\t//\t\tclass: Template.bind.if( 'foo' )\n\t//\n\tif ( schema.length == 1 && schema[ 0 ] instanceof TemplateIfBinding ) {\n\t\tvalue = value[ 0 ];\n\t} else {\n\t\tvalue = value.reduce( arrayValueReducer, '' );\n\t}\n\n\tif ( isFalsy( value ) ) {\n\t\tupdater.remove();\n\t} else {\n\t\tupdater.set( value );\n\t}\n}\n\n// Returns an object consisting of `set` and `remove` functions, which\n// can be used in the context of DOM Node to set or reset `textContent`.\n// @see module:ui/view~View#_bindToObservable\n//\n// @param {Node} node DOM Node to be modified.\n// @returns {Object}\nfunction getTextUpdater( node ) {\n\treturn {\n\t\tset( value ) {\n\t\t\tnode.textContent = value;\n\t\t},\n\n\t\tremove() {\n\t\t\tnode.textContent = '';\n\t\t}\n\t};\n}\n\n// Returns an object consisting of `set` and `remove` functions, which\n// can be used in the context of DOM Node to set or reset an attribute.\n// @see module:ui/view~View#_bindToObservable\n//\n// @param {Node} node DOM Node to be modified.\n// @param {String} attrName Name of the attribute to be modified.\n// @param {String} [ns=null] Namespace to use.\n// @returns {Object}\nfunction getAttributeUpdater( el, attrName, ns ) {\n\treturn {\n\t\tset( value ) {\n\t\t\tel.setAttributeNS( ns, attrName, value );\n\t\t},\n\n\t\tremove() {\n\t\t\tel.removeAttributeNS( ns, attrName );\n\t\t}\n\t};\n}\n\n// Returns an object consisting of `set` and `remove` functions, which\n// can be used in the context of CSSStyleDeclaration to set or remove a style.\n// @see module:ui/view~View#_bindToObservable\n//\n// @param {Node} node DOM Node to be modified.\n// @param {String} styleName Name of the style to be modified.\n// @returns {Object}\nfunction getStyleUpdater( el, styleName ) {\n\treturn {\n\t\tset( value ) {\n\t\t\tel.style[ styleName ] = value;\n\t\t},\n\n\t\tremove() {\n\t\t\tel.style[ styleName ] = null;\n\t\t}\n\t};\n}\n\n// Clones definition of the template.\n//\n// @param {module:ui/template~TemplateDefinition} def\n// @returns {module:ui/template~TemplateDefinition}\nfunction clone( def ) {\n\tconst clone = cloneDeepWith( def, value => {\n\t\t// Don't clone the `Template.bind`* bindings because of the references to Observable\n\t\t// and DomEmitterMixin instances inside, which would also be traversed and cloned by greedy\n\t\t// cloneDeepWith algorithm. There's no point in cloning Observable/DomEmitterMixins\n\t\t// along with the definition.\n\t\t//\n\t\t// Don't clone Template instances if provided as a child. They're simply #render()ed\n\t\t// and nothing should interfere.\n\t\t//\n\t\t// Also don't clone View instances if provided as a child of the Template. The template\n\t\t// instance will be extracted from the View during the normalization and there's no need\n\t\t// to clone it.\n\t\tif ( value && ( value instanceof TemplateBinding || isTemplate( value ) || isView( value ) || isViewCollection( value ) ) ) {\n\t\t\treturn value;\n\t\t}\n\t} );\n\n\treturn clone;\n}\n\n// Normalizes given {@link module:ui/template~TemplateDefinition}.\n//\n// See:\n// * {@link normalizeAttributes}\n// * {@link normalizeListeners}\n// * {@link normalizePlainTextDefinition}\n// * {@link normalizeTextDefinition}\n//\n// @param {module:ui/template~TemplateDefinition} def\n// @returns {module:ui/template~TemplateDefinition} Normalized definition.\nfunction normalize( def ) {\n\tif ( typeof def == 'string' ) {\n\t\tdef = normalizePlainTextDefinition( def );\n\t} else if ( def.text ) {\n\t\tnormalizeTextDefinition( def );\n\t}\n\n\tif ( def.on ) {\n\t\tdef.eventListeners = normalizeListeners( def.on );\n\n\t\t// Template mixes EmitterMixin, so delete #on to avoid collision.\n\t\tdelete def.on;\n\t}\n\n\tif ( !def.text ) {\n\t\tif ( def.attributes ) {\n\t\t\tnormalizeAttributes( def.attributes );\n\t\t}\n\n\t\tconst children = [];\n\n\t\tif ( def.children ) {\n\t\t\tif ( isViewCollection( def.children ) ) {\n\t\t\t\tchildren.push( def.children );\n\t\t\t} else {\n\t\t\t\tfor ( const child of def.children ) {\n\t\t\t\t\tif ( isTemplate( child ) || isView( child ) || isNode( child ) ) {\n\t\t\t\t\t\tchildren.push( child );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tchildren.push( new Template( child ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdef.children = children;\n\t}\n\n\treturn def;\n}\n\n// Normalizes \"attributes\" section of {@link module:ui/template~TemplateDefinition}.\n//\n//\t\tattributes: {\n//\t\t\ta: 'bar',\n//\t\t\tb: {@link module:ui/template~TemplateBinding},\n//\t\t\tc: {\n//\t\t\t\tvalue: 'bar'\n//\t\t\t}\n//\t\t}\n//\n// becomes\n//\n//\t\tattributes: {\n//\t\t\ta: [ 'bar' ],\n//\t\t\tb: [ {@link module:ui/template~TemplateBinding} ],\n//\t\t\tc: {\n//\t\t\t\tvalue: [ 'bar' ]\n//\t\t\t}\n//\t\t}\n//\n// @param {Object} attrs\nfunction normalizeAttributes( attrs ) {\n\tfor ( const a in attrs ) {\n\t\tif ( attrs[ a ].value ) {\n\t\t\tattrs[ a ].value = [].concat( attrs[ a ].value );\n\t\t}\n\n\t\tarrayify( attrs, a );\n\t}\n}\n\n// Normalizes \"on\" section of {@link module:ui/template~TemplateDefinition}.\n//\n//\t\ton: {\n//\t\t\ta: 'bar',\n//\t\t\tb: {@link module:ui/template~TemplateBinding},\n//\t\t\tc: [ {@link module:ui/template~TemplateBinding}, () => { ... } ]\n//\t\t}\n//\n// becomes\n//\n//\t\ton: {\n//\t\t\ta: [ 'bar' ],\n//\t\t\tb: [ {@link module:ui/template~TemplateBinding} ],\n//\t\t\tc: [ {@link module:ui/template~TemplateBinding}, () => { ... } ]\n//\t\t}\n//\n// @param {Object} listeners\n// @returns {Object} Object containing normalized listeners.\nfunction normalizeListeners( listeners ) {\n\tfor ( const l in listeners ) {\n\t\tarrayify( listeners, l );\n\t}\n\n\treturn listeners;\n}\n\n// Normalizes \"string\" {@link module:ui/template~TemplateDefinition}.\n//\n//\t\t\"foo\"\n//\n// becomes\n//\n//\t\t{ text: [ 'foo' ] },\n//\n// @param {String} def\n// @returns {module:ui/template~TemplateDefinition} Normalized template definition.\nfunction normalizePlainTextDefinition( def ) {\n\treturn {\n\t\ttext: [ def ]\n\t};\n}\n\n// Normalizes text {@link module:ui/template~TemplateDefinition}.\n//\n//\t\tchildren: [\n//\t\t\t{ text: 'def' },\n//\t\t\t{ text: {@link module:ui/template~TemplateBinding} }\n//\t\t]\n//\n// becomes\n//\n//\t\tchildren: [\n//\t\t\t{ text: [ 'def' ] },\n//\t\t\t{ text: [ {@link module:ui/template~TemplateBinding} ] }\n//\t\t]\n//\n// @param {module:ui/template~TemplateDefinition} def\nfunction normalizeTextDefinition( def ) {\n\tif ( !Array.isArray( def.text ) ) {\n\t\tdef.text = [ def.text ];\n\t}\n}\n\n// Wraps an entry in Object in an Array, if not already one.\n//\n//\t\t{\n//\t\t\tx: 'y',\n//\t\t\ta: [ 'b' ]\n//\t\t}\n//\n// becomes\n//\n//\t\t{\n//\t\t\tx: [ 'y' ],\n//\t\t\ta: [ 'b' ]\n//\t\t}\n//\n// @param {Object} obj\n// @param {String} key\nfunction arrayify( obj, key ) {\n\tif ( !Array.isArray( obj[ key ] ) ) {\n\t\tobj[ key ] = [ obj[ key ] ];\n\t}\n}\n\n// A helper which concatenates the value avoiding unwanted\n// leading white spaces.\n//\n// @param {String} prev\n// @param {String} cur\n// @returns {String}\nfunction arrayValueReducer( prev, cur ) {\n\tif ( isFalsy( cur ) ) {\n\t\treturn prev;\n\t} else if ( isFalsy( prev ) ) {\n\t\treturn cur;\n\t} else {\n\t\treturn `${ prev } ${ cur }`;\n\t}\n}\n\n// Extends one object defined in the following format:\n//\n//\t\t{\n//\t\t\tkey1: [Array1],\n//\t\t\tkey2: [Array2],\n//\t\t\t...\n//\t\t\tkeyN: [ArrayN]\n//\t\t}\n//\n// with another object of the same data format.\n//\n// @param {Object} obj Base object.\n// @param {Object} ext Object extending base.\n// @returns {String}\nfunction extendObjectValueArray( obj, ext ) {\n\tfor ( const a in ext ) {\n\t\tif ( obj[ a ] ) {\n\t\t\tobj[ a ].push( ...ext[ a ] );\n\t\t} else {\n\t\t\tobj[ a ] = ext[ a ];\n\t\t}\n\t}\n}\n\n// A helper for {@link module:ui/template~Template#extend}. Recursively extends {@link module:ui/template~Template} instance\n// with content from {@link module:ui/template~TemplateDefinition}. See {@link module:ui/template~Template#extend} to learn more.\n//\n// @param {module:ui/template~Template} def A template instance to be extended.\n// @param {module:ui/template~TemplateDefinition} def A definition which is to extend the template instance.\nfunction extendTemplate( template, def ) {\n\tif ( def.attributes ) {\n\t\tif ( !template.attributes ) {\n\t\t\ttemplate.attributes = {};\n\t\t}\n\n\t\textendObjectValueArray( template.attributes, def.attributes );\n\t}\n\n\tif ( def.eventListeners ) {\n\t\tif ( !template.eventListeners ) {\n\t\t\ttemplate.eventListeners = {};\n\t\t}\n\n\t\textendObjectValueArray( template.eventListeners, def.eventListeners );\n\t}\n\n\tif ( def.text ) {\n\t\ttemplate.text.push( ...def.text );\n\t}\n\n\tif ( def.children && def.children.length ) {\n\t\tif ( template.children.length != def.children.length ) {\n\t\t\t/**\n\t\t\t * The number of children in extended definition does not match.\n\t\t\t *\n\t\t\t * @error ui-template-extend-children-mismatch\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'ui-template-extend-children-mismatch: The number of children in extended definition does not match.'\n\t\t\t);\n\t\t}\n\n\t\tlet childIndex = 0;\n\n\t\tfor ( const childDef of def.children ) {\n\t\t\textendTemplate( template.children[ childIndex++ ], childDef );\n\t\t}\n\t}\n}\n\n// Checks if value is \"falsy\".\n// Note: 0 (Number) is not \"falsy\" in this context.\n//\n// @private\n// @param {*} value Value to be checked.\nfunction isFalsy( value ) {\n\treturn !value && value !== 0;\n}\n\n// Checks if the item is an instance of {@link module:ui/view~View}\n//\n// @private\n// @param {*} value Value to be checked.\nfunction isView( item ) {\n\treturn item instanceof View;\n}\n\n// Checks if the item is an instance of {@link module:ui/template~Template}\n//\n// @private\n// @param {*} value Value to be checked.\nfunction isTemplate( item ) {\n\treturn item instanceof Template;\n}\n\n// Checks if the item is an instance of {@link module:ui/viewcollection~ViewCollection}\n//\n// @private\n// @param {*} value Value to be checked.\nfunction isViewCollection( item ) {\n\treturn item instanceof ViewCollection;\n}\n\n// Creates an empty skeleton for {@link module:ui/template~Template#revert}\n// data.\n//\n// @private\nfunction getEmptyRevertData() {\n\treturn {\n\t\tchildren: [],\n\t\tbindings: [],\n\t\tattributes: {}\n\t};\n}\n\n// Checks whether an attribute should be extended when\n// {@link module:ui/template~Template#apply} is called.\n//\n// @private\n// @param {String} attrName Attribute name to check.\nfunction shouldExtend( attrName ) {\n\treturn attrName == 'class' || attrName == 'style';\n}\n\n/**\n * A definition of the {@link module:ui/template~Template}. It describes what kind of\n * node a template will render (HTML element or text), attributes of an element, DOM event\n * listeners and children.\n *\n * Also see:\n * * {@link module:ui/template~TemplateValueSchema} to learn about HTML element attributes,\n * * {@link module:ui/template~TemplateListenerSchema} to learn about DOM event listeners.\n *\n * A sample definition on an HTML element can look like this:\n *\n *\t\tnew Template( {\n *\t\t\ttag: 'p',\n *\t\t\tchildren: [\n *\t\t\t\t{\n *\t\t\t\t\ttag: 'span',\n *\t\t\t\t\tattributes: { ... },\n *\t\t\t\t\tchildren: [ ... ],\n *\t\t\t\t},\n *\t\t\t\t{\n *\t\t\t\t\ttext: 'static–text'\n *\t\t\t\t},\n *\t\t\t\t'also-static–text',\n *\t\t\t],\n *\t\t\tattributes: {\n *\t\t\t\tclass: {@link module:ui/template~TemplateValueSchema},\n *\t\t\t\tid: {@link module:ui/template~TemplateValueSchema},\n *\t\t\t\tstyle: {@link module:ui/template~TemplateValueSchema}\n *\n *\t\t\t\t// ...\n *\t\t\t},\n *\t\t\ton: {\n *\t\t\t\t'click': {@link module:ui/template~TemplateListenerSchema}\n *\n *\t\t\t\t// Document.querySelector format is also accepted.\n *\t\t\t\t'keyup@a.some-class': {@link module:ui/template~TemplateListenerSchema}\n *\n *\t\t\t\t// ...\n *\t\t\t}\n *\t\t} );\n *\n * A {@link module:ui/view~View}, another {@link module:ui/template~Template} or a native DOM node\n * can also become a child of a template. When a view is passed, its {@link module:ui/view~View#element} is used:\n *\n *\t\tconst view = new SomeView();\n *\t\tconst childTemplate = new Template( { ... } );\n *\t\tconst childNode = document.createElement( 'b' );\n *\n *\t\tnew Template( {\n *\t\t\ttag: 'p',\n *\n *\t\t\tchildren: [\n *\t\t\t\t// view#element will be added as a child of this <p>.\n *\t\t\t\tview,\n *\n * \t\t\t\t// The output of childTemplate.render() will be added here.\n *\t\t\t\tchildTemplate,\n *\n *\t\t\t\t// Native DOM nodes are included directly in the rendered output.\n *\t\t\t\tchildNode\n *\t\t\t]\n *\t\t} );\n *\n * An entire {@link module:ui/viewcollection~ViewCollection} can be used as a child in the definition:\n *\n *\t\tconst collection = new ViewCollection();\n *\t\tcollection.add( someView );\n *\n *\t\tnew Template( {\n *\t\t\ttag: 'p',\n *\n *\t\t\tchildren: collection\n *\t\t} );\n *\n * @typedef module:ui/template~TemplateDefinition\n * @type Object\n *\n * @property {String} tag See the template {@link module:ui/template~Template#tag} property.\n *\n * @property {Array.<module:ui/template~TemplateDefinition>} [children]\n * See the template {@link module:ui/template~Template#children} property.\n *\n * @property {Object.<String, module:ui/template~TemplateValueSchema>} [attributes]\n * See the template {@link module:ui/template~Template#attributes} property.\n *\n * @property {String|module:ui/template~TemplateValueSchema|Array.<String|module:ui/template~TemplateValueSchema>} [text]\n * See the template {@link module:ui/template~Template#text} property.\n *\n * @property {Object.<String, module:ui/template~TemplateListenerSchema>} [on]\n * See the template {@link module:ui/template~Template#eventListeners} property.\n */\n\n/**\n * Describes a value of an HTML element attribute or `textContent`. It allows combining multiple\n * data sources like static values and {@link module:utils/observablemixin~Observable} attributes.\n *\n * Also see:\n * * {@link module:ui/template~TemplateDefinition} to learn where to use it,\n * * {@link module:ui/template~Template.bind} to learn how to configure\n * {@link module:utils/observablemixin~Observable} attribute bindings,\n * * {@link module:ui/template~Template#render} to learn how to render a template,\n * * {@link module:ui/template~BindChain#to `to()`} and {@link module:ui/template~BindChain#if `if()`}\n * methods to learn more about bindings.\n *\n * Attribute values can be described in many different ways:\n *\n *\t\t// Bind helper will create bindings to attributes of the observable.\n *\t\tconst bind = Template.bind( observable, emitter );\n *\n *\t\tnew Template( {\n *\t\t\ttag: 'p',\n *\t\t\tattributes: {\n *\t\t\t\t// A plain string schema.\n *\t\t\t\t'class': 'static-text',\n *\n *\t\t\t\t// An object schema, binds to the \"foo\" attribute of the\n *\t\t\t\t// observable and follows its value.\n *\t\t\t\t'class': bind.to( 'foo' ),\n *\n *\t\t\t\t// An array schema, combines the above.\n *\t\t\t\t'class': [\n *\t\t\t\t\t'static-text',\n *\t\t\t\t\tbind.to( 'bar', () => { ... } ),\n *\n * \t\t\t\t\t// Bindings can also be conditional.\n *\t\t\t\t\tbind.if( 'baz', 'class-when-baz-is-true' )\n *\t\t\t\t],\n *\n *\t\t\t\t// An array schema, with a custom namespace, e.g. useful for creating SVGs.\n *\t\t\t\t'class': {\n *\t\t\t\t\tns: 'http://ns.url',\n *\t\t\t\t\tvalue: [\n *\t\t\t\t\t\tbind.if( 'baz', 'value-when-true' ),\n *\t\t\t\t\t\t'static-text'\n *\t\t\t\t\t]\n *\t\t\t\t},\n *\n *\t\t\t\t// An object schema, specific for styles.\n *\t\t\t\tstyle: {\n *\t\t\t\t\tcolor: 'red',\n *\t\t\t\t\tbackgroundColor: bind.to( 'qux', () => { ... } )\n *\t\t\t\t}\n *\t\t\t}\n *\t\t} );\n *\n * Text nodes can also have complex values:\n *\n *\t\tconst bind = Template.bind( observable, emitter );\n *\n *\t\t// Will render a \"foo\" text node.\n *\t\tnew Template( {\n *\t\t\ttext: 'foo'\n *\t\t} );\n *\n *\t\t// Will render a \"static text: {observable.foo}\" text node.\n *\t\t// The text of the node will be updated as the \"foo\" attribute changes.\n *\t\tnew Template( {\n *\t\t\ttext: [\n *\t\t\t\t'static text: ',\n *\t\t\t\tbind.to( 'foo', () => { ... } )\n *\t\t\t]\n *\t\t} );\n *\n * @typedef module:ui/template~TemplateValueSchema\n * @type {Object|String|Array}\n */\n\n/**\n * Describes an event listener attached to an HTML element. Such listener can propagate DOM events\n * through an {@link module:utils/observablemixin~Observable} instance, execute custom callbacks\n * or both, if necessary.\n *\n * Also see:\n * * {@link module:ui/template~TemplateDefinition} to learn more about template definitions,\n * * {@link module:ui/template~BindChain#to `to()`} method to learn more about bindings.\n *\n * Check out different ways of attaching event listeners below:\n *\n *\t\t// Bind helper will propagate events through the observable.\n *\t\tconst bind = Template.bind( observable, emitter );\n *\n *\t\tnew Template( {\n *\t\t\ttag: 'p',\n *\t\t\ton: {\n *\t\t\t\t// An object schema. The observable will fire the \"clicked\" event upon DOM \"click\".\n *\t\t\t\tclick: bind.to( 'clicked' )\n *\n *\t\t\t\t// An object schema. It will work for \"click\" event on \"a.foo\" children only.\n *\t\t\t\t'click@a.foo': bind.to( 'clicked' )\n *\n *\t\t\t\t// An array schema, makes the observable propagate multiple events.\n *\t\t\t\tclick: [\n *\t\t\t\t\tbind.to( 'clicked' ),\n *\t\t\t\t\tbind.to( 'executed' )\n *\t\t\t\t],\n *\n *\t\t\t\t// An array schema with a custom callback.\n *\t\t\t\t'click@a.foo': {\n *\t\t\t\t\tbind.to( 'clicked' ),\n *\t\t\t\t\tbind.to( evt => {\n *\t\t\t\t\t\tconsole.log( `${ evt.target } has been clicked!` );\n *\t\t\t\t\t} }\n *\t\t\t\t}\n *\t\t\t}\n *\t\t} );\n *\n * @typedef module:ui/template~TemplateListenerSchema\n * @type {Object|String|Array}\n */\n\n/**\n * The return value of {@link ~Template.bind `Template.bind()`}. It provides `to()` and `if()`\n * methods to create the {@link module:utils/observablemixin~Observable observable} attribute and event bindings.\n *\n * @interface module:ui/template~BindChain\n */\n\n/**\n * Binds an {@link module:utils/observablemixin~Observable observable} to either:\n *\n * * an HTML element attribute or a text node `textContent`, so it remains in sync with the observable\n * attribute as it changes,\n * * or an HTML element DOM event, so the DOM events are propagated through an observable.\n *\n * Some common use cases of `to()` bindings are presented below:\n *\n *\t\tconst bind = Template.bind( observable, emitter );\n *\n *\t\tnew Template( {\n *\t\t\ttag: 'p',\n *\t\t\tattributes: {\n *\t\t\t\t// class=\"...\" attribute gets bound to `observable#a`\n *\t\t\t\tclass: bind.to( 'a' )\n *\t\t\t},\n *\t\t\tchildren: [\n *\t\t\t\t// <p>...</p> gets bound to observable#b; always `toUpperCase()`.\n *\t\t\t\t{\n *\t\t\t\t\ttext: bind.to( 'b', ( value, node ) => value.toUpperCase() )\n *\t\t\t\t}\n *\t\t\t],\n *\t\t\ton: {\n *\t\t\t\tclick: [\n *\t\t\t\t\t// An observable will fire \"clicked\" upon \"click\" in the DOM.\n *\t\t\t\t\tbind.to( 'clicked' ),\n *\n *\t\t\t\t\t// A custom callback will be executed upon \"click\" in the DOM.\n *\t\t\t\t\tbind.to( () => {\n *\t\t\t\t\t\t...\n *\t\t\t\t\t} )\n *\t\t\t\t]\n *\t\t\t}\n *\t\t} ).render();\n *\n * Learn more about using `to()` in the {@link module:ui/template~TemplateValueSchema} and\n * {@link module:ui/template~TemplateListenerSchema}.\n *\n * @method #to\n * @param {String|Function} eventNameOrFunctionOrAttribute An attribute name of\n * {@link module:utils/observablemixin~Observable} or a DOM event name or an event callback.\n * @param {Function} [callback] Allows for processing of the value. Accepts `Node` and `value` as arguments.\n * @returns {module:ui/template~TemplateBinding}\n */\n\n/**\n * Binds an {@link module:utils/observablemixin~Observable observable} to an HTML element attribute or a text\n * node `textContent` so it remains in sync with the observable attribute as it changes.\n *\n * Unlike {@link module:ui/template~BindChain#to}, it controls the presence of the attribute or `textContent`\n * depending on the \"falseness\" of an {@link module:utils/observablemixin~Observable} attribute.\n *\n *\t\tconst bind = Template.bind( observable, emitter );\n *\n *\t\tnew Template( {\n *\t\t\ttag: 'input',\n *\t\t\tattributes: {\n *\t\t\t\t// <input checked> when `observable#a` is not undefined/null/false/''\n *\t\t\t\t// <input> when `observable#a` is undefined/null/false\n *\t\t\t\tchecked: bind.if( 'a' )\n *\t\t\t},\n *\t\t\tchildren: [\n *\t\t\t\t{\n *\t\t\t\t\t// <input>\"b-is-not-set\"</input> when `observable#b` is undefined/null/false/''\n *\t\t\t\t\t// <input></input> when `observable#b` is not \"falsy\"\n *\t\t\t\t\ttext: bind.if( 'b', 'b-is-not-set', ( value, node ) => !value )\n *\t\t\t\t}\n *\t\t\t]\n *\t\t} ).render();\n *\n * Learn more about using `if()` in the {@link module:ui/template~TemplateValueSchema}.\n *\n * @method #if\n * @param {String} attribute An attribute name of {@link module:utils/observablemixin~Observable} used in the binding.\n * @param {String} [valueIfTrue] Value set when the {@link module:utils/observablemixin~Observable} attribute is not\n * undefined/null/false/'' (empty string).\n * @param {Function} [callback] Allows for processing of the value. Accepts `Node` and `value` as arguments.\n * @returns {module:ui/template~TemplateBinding}\n */\n\n/**\n * The {@link module:ui/template~Template#_renderNode} configuration.\n *\n * @private\n * @interface module:ui/template~RenderData\n */\n\n/**\n * Tells {@link module:ui/template~Template#_renderNode} to render\n * children into `DocumentFragment` first and then append the fragment\n * to the parent element. It is a speed optimization.\n *\n * @member {Boolean} #intoFragment\n */\n\n/**\n * A node which is being rendered.\n *\n * @member {HTMLElement|Text} #node\n */\n\n/**\n * Indicates whether the {@module:ui/template~RenderNodeOptions#node} has\n * been provided by {@module:ui/template~Template#apply}.\n *\n * @member {Boolean} #isApplying\n */\n\n/**\n * An object storing the data that helps {@module:ui/template~Template#revert}\n * bringing back an element to its initial state, i.e. before\n * {@module:ui/template~Template#apply} was called.\n *\n * @member {Object} #revertData\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/view\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport ViewCollection from './viewcollection';\nimport Template from './template';\nimport DomEmitterMixin from '@ckeditor/ckeditor5-utils/src/dom/emittermixin';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport Collection from '@ckeditor/ckeditor5-utils/src/collection';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';\n\nimport '../theme/globals/globals.css';\n\n/**\n * The basic view class, which represents an HTML element created out of a\n * {@link module:ui/view~View#template}. Views are building blocks of the user interface and handle\n * interaction\n *\n * Views {@link module:ui/view~View#registerChild aggregate} children in\n * {@link module:ui/view~View#createCollection collections} and manage the life cycle of DOM\n * listeners e.g. by handling rendering and destruction.\n *\n * See the {@link module:ui/template~TemplateDefinition} syntax to learn more about shaping view\n * elements, attributes and listeners.\n *\n *\t\tclass SampleView extends View {\n *\t\t\tconstructor( locale ) {\n *\t\t\t\tsuper( locale );\n *\n *\t\t\t\tconst bind = this.bindTemplate;\n *\n *\t\t\t\t// Views define their interface (state) using observable attributes.\n *\t\t\t\tthis.set( 'elementClass', 'bar' );\n *\n *\t\t\t\tthis.setTemplate( {\n *\t\t\t\t\ttag: 'p',\n *\n *\t\t\t\t\t// The element of the view can be defined with its children.\n *\t\t\t\t\tchildren: [\n *\t\t\t\t\t\t'Hello',\n *\t\t\t\t\t\t{\n *\t\t\t\t\t\t\ttag: 'b',\n *\t\t\t\t\t\t\tchildren: [ 'world!' ]\n *\t\t\t\t\t\t}\n *\t\t\t\t\t],\n *\t\t\t\t\tattributes: {\n *\t\t\t\t\t\tclass: [\n *\t\t\t\t\t\t\t'foo',\n *\n *\t\t\t\t\t\t\t// Observable attributes control the state of the view in DOM.\n *\t\t\t\t\t\t\tbind.to( 'elementClass' )\n *\t\t\t\t\t\t]\n *\t\t\t\t\t},\n *\t\t\t\t\ton: {\n *\t\t\t\t\t\t// Views listen to DOM events and propagate them.\n *\t\t\t\t\t\tclick: bind.to( 'clicked' )\n *\t\t\t\t\t}\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n *\t\tconst view = new SampleView( locale );\n *\n *\t\tview.render();\n *\n *\t\t// Append <p class=\"foo bar\">Hello<b>world</b></p> to the <body>\n *\t\tdocument.body.appendChild( view.element );\n *\n *\t\t// Change the class attribute to <p class=\"foo baz\">Hello<b>world</b></p>\n *\t\tview.elementClass = 'baz';\n *\n *\t\t// Respond to the \"click\" event in DOM by executing a custom action.\n *\t\tview.on( 'clicked', () => {\n *\t\t\tconsole.log( 'The view has been clicked!' );\n *\t\t} );\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class View {\n\t/**\n\t * Creates an instance of the {@link module:ui/view~View} class.\n\t *\n\t * Also see {@link #render}.\n\t *\n\t * @param {module:utils/locale~Locale} [locale] The localization services instance.\n\t */\n\tconstructor( locale ) {\n\t\t/**\n\t\t * An HTML element of the view. `null` until {@link #render rendered}\n\t\t * from the {@link #template}.\n\t\t *\n\t\t *\t\tclass SampleView extends View {\n\t\t *\t\t\tconstructor() {\n\t\t *\t\t\t\tsuper();\n\t\t *\n\t\t *\t\t\t\t// A template instance the #element will be created from.\n\t\t *\t\t\t\tthis.setTemplate( {\n\t\t *\t\t\t\t\ttag: 'p'\n\t\t *\n\t\t *\t\t\t\t\t// ...\n\t\t *\t\t\t\t} );\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\n\t\t *\t\tconst view = new SampleView();\n\t\t *\n\t\t *\t\t// Renders the #template.\n\t\t *\t\tview.render();\n\t\t *\n\t\t *\t\t// Append the HTML element of the view to <body>.\n\t\t *\t\tdocument.body.appendChild( view.element );\n\t\t *\n\t\t * **Note**: The element of the view can also be assigned directly:\n\t\t *\n\t\t *\t\tview.element = document.querySelector( '#my-container' );\n\t\t *\n\t\t * @member {HTMLElement}\n\t\t */\n\t\tthis.element = null;\n\n\t\t/**\n\t\t * Set `true` when the view has already been {@link module:ui/view~View#render rendered}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} #isRendered\n\t\t */\n\t\tthis.isRendered = false;\n\n\t\t/**\n\t\t * A set of tools to localize the user interface.\n\t\t *\n\t\t * Also see {@link module:core/editor/editor~Editor#locale}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/locale~Locale}\n\t\t */\n\t\tthis.locale = locale;\n\n\t\t/**\n\t\t * Shorthand for {@link module:utils/locale~Locale#t}.\n\t\t *\n\t\t * Note: If {@link #locale} instance hasn't been passed to the view this method may not\n\t\t * be available.\n\t\t *\n\t\t * @see module:utils/locale~Locale#t\n\t\t * @method\n\t\t */\n\t\tthis.t = locale && locale.t;\n\n\t\t/**\n\t\t * Collections registered with {@link #createCollection}.\n\t\t *\n\t\t * @protected\n\t\t * @member {Set.<module:ui/viewcollection~ViewCollection>}\n\t\t */\n\t\tthis._viewCollections = new Collection();\n\n\t\t/**\n\t\t * A collection of view instances, which have been added directly\n\t\t * into the {@link module:ui/template~Template#children}.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis._unboundChildren = this.createCollection();\n\n\t\t// Pass parent locale to its children.\n\t\tthis._viewCollections.on( 'add', ( evt, collection ) => {\n\t\t\tcollection.locale = locale;\n\t\t} );\n\n\t\t/**\n\t\t * Template of this view. It provides the {@link #element} representing\n\t\t * the view in DOM, which is {@link #render rendered}.\n\t\t *\n\t\t * @member {module:ui/template~Template} #template\n\t\t */\n\n\t\t/**\n\t\t * Cached {@link module:ui/template~BindChain bind chain} object created by the\n\t\t * {@link #template}. See {@link #bindTemplate}.\n\t\t *\n\t\t * @private\n\t\t * @member {Object} #_bindTemplate\n\t\t */\n\n\t\tthis.decorate( 'render' );\n\t}\n\n\t/**\n\t * Shorthand for {@link module:ui/template~Template.bind}, a binding\n\t * {@link module:ui/template~BindChain interface} pre–configured for the view instance.\n\t *\n\t * It provides {@link module:ui/template~BindChain#to `to()`} and\n\t * {@link module:ui/template~BindChain#if `if()`} methods that initialize bindings with\n\t * observable attributes and attach DOM listeners.\n\t *\n\t *\t\tclass SampleView extends View {\n\t *\t\t\tconstructor( locale ) {\n\t *\t\t\t\tsuper( locale );\n\t *\n\t *\t\t\t\tconst bind = this.bindTemplate;\n\t *\n\t *\t\t\t\t// These {@link module:utils/observablemixin~Observable observable} attributes will control\n\t *\t\t\t\t// the state of the view in DOM.\n\t *\t\t\t\tthis.set( {\n\t *\t\t\t\t\telementClass: 'foo',\n\t *\t\t\t\t \tisEnabled: true\n\t *\t\t\t\t } );\n\t *\n\t *\t\t\t\tthis.setTemplate( {\n\t *\t\t\t\t\ttag: 'p',\n\t *\n\t *\t\t\t\t\tattributes: {\n\t *\t\t\t\t\t\t// The class HTML attribute will follow elementClass\n\t *\t\t\t\t\t\t// and isEnabled view attributes.\n\t *\t\t\t\t\t\tclass: [\n\t *\t\t\t\t\t\t\tbind.to( 'elementClass' )\n\t *\t\t\t\t\t\t\tbind.if( 'isEnabled', 'present-when-enabled' )\n\t *\t\t\t\t\t\t]\n\t *\t\t\t\t\t},\n\t *\n\t *\t\t\t\t\ton: {\n\t *\t\t\t\t\t\t// The view will fire the \"clicked\" event upon clicking <p> in DOM.\n\t *\t\t\t\t\t\tclick: bind.to( 'clicked' )\n\t *\t\t\t\t\t}\n\t *\t\t\t\t} );\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t * @method #bindTemplate\n\t */\n\tget bindTemplate() {\n\t\tif ( this._bindTemplate ) {\n\t\t\treturn this._bindTemplate;\n\t\t}\n\n\t\treturn ( this._bindTemplate = Template.bind( this, this ) );\n\t}\n\n\t/**\n\t * Creates a new collection of views, which can be used as\n\t * {@link module:ui/template~Template#children} of this view.\n\t *\n\t *\t\tclass SampleView extends View {\n\t *\t\t\tconstructor( locale ) {\n\t *\t\t\t\tsuper( locale );\n\t *\n\t *\t\t\t\tthis.items = this.createCollection();\n \t *\n\t *\t\t\t\tthis.setTemplate( {\n\t *\t\t\t\t\ttag: 'p',\n\t *\n\t *\t\t\t\t\t// `items` collection will render here.\n\t *\t\t\t\t\tchildren: this.items\n\t *\t\t\t\t} );\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t *\t\tconst view = new SampleView( locale );\n\t *\t\tconst child = new ChildView( locale );\n\t *\n\t *\t\tview.render();\n\t *\n\t *\t\t// It will append <p></p> to the <body>.\n\t *\t\tdocument.body.appendChild( view.element );\n\t *\n\t *\t\t// From now on the child is nested under its parent, which is also reflected in DOM.\n\t *\t\t// <p><child#element></p>\n\t *\t\tview.items.add( child );\n\t *\n\t * @returns {module:ui/viewcollection~ViewCollection} A new collection of view instances.\n\t */\n\tcreateCollection() {\n\t\tconst collection = new ViewCollection();\n\n\t\tthis._viewCollections.add( collection );\n\n\t\treturn collection;\n\t}\n\n\t/**\n\t * Registers a new child view under the view instance. Once registered, a child\n\t * view is managed by its parent, including {@link #render rendering}\n\t * and {@link #destroy destruction}.\n\t *\n\t * To revert this, use {@link #deregisterChild}.\n\t *\n\t *\t\tclass SampleView extends View {\n\t *\t\t\tconstructor( locale ) {\n\t *\t\t\t\tsuper( locale );\n\t *\n\t *\t\t\t\tthis.childA = new SomeChildView( locale );\n\t *\t\t\t\tthis.childB = new SomeChildView( locale );\n\t *\n\t *\t\t\t\tthis.setTemplate( { tag: 'p' } );\n\t *\n\t *\t\t\t\t// Register the children.\n\t *\t\t\t\tthis.registerChild( [ this.childA, this.childB ] );\n\t *\t\t\t}\n\t *\n\t *\t\t\trender() {\n\t *\t\t\t\tsuper.render();\n\t *\n\t *\t\t\t\tthis.element.appendChild( this.childA.element );\n\t *\t\t\t\tthis.element.appendChild( this.childB.element );\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t *\t\tconst view = new SampleView( locale );\n\t *\n\t *\t\tview.render();\n\t *\n\t *\t\t// Will append <p><childA#element><b></b><childB#element></p>.\n\t *\t\tdocument.body.appendChild( view.element );\n\t *\n\t * **Note**: There's no need to add child views if they're already referenced in the\n\t * {@link #template}:\n\t *\n\t *\t\tclass SampleView extends View {\n\t *\t\t\tconstructor( locale ) {\n\t *\t\t\t\tsuper( locale );\n\t *\n\t *\t\t\t\tthis.childA = new SomeChildView( locale );\n\t *\t\t\t\tthis.childB = new SomeChildView( locale );\n\t *\n\t *\t\t\t\tthis.setTemplate( {\n\t *\t\t\t\t\ttag: 'p',\n\t *\n \t *\t\t\t\t\t// These children will be added automatically. There's no\n \t *\t\t\t\t\t// need to call {@link #registerChild} for any of them.\n\t *\t\t\t\t\tchildren: [ this.childA, this.childB ]\n\t *\t\t\t\t} );\n\t *\t\t\t}\n\t *\n\t *\t\t\t// ...\n\t *\t\t}\n\t *\n\t * @param {module:ui/view~View|Iterable.<module:ui/view~View>} children Children views to be registered.\n\t */\n\tregisterChild( children ) {\n\t\tif ( !isIterable( children ) ) {\n\t\t\tchildren = [ children ];\n\t\t}\n\n\t\tfor ( const child of children ) {\n\t\t\tthis._unboundChildren.add( child );\n\t\t}\n\t}\n\n\t/**\n\t * The opposite of {@link #registerChild}. Removes a child view from this view instance.\n\t * Once removed, the child is no longer managed by its parent, e.g. it can safely\n\t * become a child of another parent view.\n\t *\n\t * @see #registerChild\n\t * @param {module:ui/view~View|Iterable.<module:ui/view~View>} children Child views to be removed.\n\t */\n\tderegisterChild( children ) {\n\t\tif ( !isIterable( children ) ) {\n\t\t\tchildren = [ children ];\n\t\t}\n\n\t\tfor ( const child of children ) {\n\t\t\tthis._unboundChildren.remove( child );\n\t\t}\n\t}\n\n\t/**\n\t * Sets the {@link #template} of the view with with given definition.\n\t *\n\t * A shorthand for:\n\t *\n\t *\t\tview.setTemplate( definition );\n\t *\n\t * @param {module:ui/template~TemplateDefinition} definition Definition of view's template.\n\t */\n\tsetTemplate( definition ) {\n\t\tthis.template = new Template( definition );\n\t}\n\n\t/**\n\t * {@link module:ui/template~Template.extend Extends} the {@link #template} of the view with\n\t * with given definition.\n\t *\n\t * A shorthand for:\n\t *\n\t *\t\tTemplate.extend( view.template, definition );\n\t *\n\t * **Note**: Is requires the {@link #template} to be already set. See {@link #setTemplate}.\n\t *\n\t * @param {module:ui/template~TemplateDefinition} definition Definition which\n\t * extends the {@link #template}.\n\t */\n\textendTemplate( definition ) {\n\t\tTemplate.extend( this.template, definition );\n\t}\n\n\t/**\n\t * Recursively renders the view.\n\t *\n\t * Once the view is rendered:\n\t * * the {@link #element} becomes an HTML element out of {@link #template},\n\t * * the {@link #isRendered} flag is set `true`.\n\t *\n\t * **Note**: The children of the view:\n\t * * defined directly in the {@link #template}\n\t * * residing in collections created by the {@link #createCollection} method,\n\t * * and added by {@link #registerChild}\n\t * are also rendered in the process.\n\t *\n\t * In general, `render()` method is the right place to keep the code which refers to the\n\t * {@link #element} and should be executed at the very beginning of the view's life cycle.\n\t *\n\t * It is possible to {@link module:ui/template~Template.extend} the {@link #template} before\n\t * the view is rendered. To allow an early customization of the view (e.g. by its parent),\n\t * such references should be done in `render()`.\n\t *\n\t *\t\tclass SampleView extends View {\n\t *\t\t\tconstructor() {\n\t *\t\t\t\tthis.setTemplate( {\n\t *\t\t\t\t\t// ...\n\t *\t\t\t\t} );\n\t *\t\t\t},\n\t *\n\t *\t\t\trender() {\n\t *\t\t\t\t// View#element becomes available.\n\t *\t\t\t\tsuper.render();\n\t *\n\t *\t\t\t\t// The \"scroll\" listener depends on #element.\n\t *\t\t\t\tthis.listenTo( window, 'scroll', () => {\n\t *\t\t\t\t\t// A reference to #element would render the #template and make it non-extendable.\n\t *\t\t\t\t\tif ( window.scrollY > 0 ) {\n\t *\t\t\t\t\t\tthis.element.scrollLeft = 100;\n\t *\t\t\t\t\t} else {\n\t *\t\t\t\t\t\tthis.element.scrollLeft = 0;\n\t *\t\t\t\t\t}\n\t *\t\t\t\t} );\n\t *\t\t\t}\n\t *\t\t}\n\t *\n\t *\t\tconst view = new SampleView();\n\t *\n\t *\t\t// Let's customize the view before it gets rendered.\n\t *\t\tview.extendTemplate( {\n\t *\t\t\tattributes: {\n\t *\t\t\t\tclass: [\n\t *\t\t\t\t\t'additional-class'\n\t *\t\t\t\t]\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t *\t\t// Late rendering allows customization of the view.\n\t *\t\tview.render();\n\t */\n\trender() {\n\t\tif ( this.isRendered ) {\n\t\t\t/**\n\t\t\t * This View has already been rendered.\n\t\t\t *\n\t\t\t * @error ui-view-render-rendered\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'ui-view-render-already-rendered: This View has already been rendered.' );\n\t\t}\n\n\t\t// Render #element of the view.\n\t\tif ( this.template ) {\n\t\t\tthis.element = this.template.render();\n\n\t\t\t// Auto–register view children from #template.\n\t\t\tthis.registerChild( this.template.getViews() );\n\t\t}\n\n\t\tthis.isRendered = true;\n\t}\n\n\t/**\n\t * Recursively destroys the view instance and child views added by {@link #registerChild} and\n\t * residing in collections created by the {@link #createCollection}.\n\t *\n\t * Destruction disables all event listeners:\n\t * * created on the view, e.g. `view.on( 'event', () => {} )`,\n\t * * defined in the {@link #template} for DOM events.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\n\t\tthis._viewCollections.map( c => c.destroy() );\n\n\t\t// Template isn't obligatory for views.\n\t\tif ( this.template && this.template._revertData ) {\n\t\t\tthis.template.revert( this.element );\n\t\t}\n\t}\n\n\t/**\n\t * Event fired by the {@link #render} method. Actual rendering is executed as a listener to\n\t * this event with the default priority.\n\t *\n\t * See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples.\n\t *\n\t * @event render\n\t */\n}\n\nmix( View, DomEmitterMixin );\nmix( View, ObservableMixin );\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/editorui/editoruiview\n */\n\n/* globals document */\n\nimport View from '../view';\nimport Template from '../template';\n\nimport '../../theme/components/editorui/editorui.css';\n\n/**\n * The editor UI view class. Base class for the editor main views.\n *\n * @extends module:ui/view~View\n */\nexport default class EditorUIView extends View {\n\t/**\n\t * Creates an instance of the editor UI view class.\n\t *\n\t * @param {module:utils/locale~Locale} [locale] The locale instance.\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\t/**\n\t\t * Collection of the child views, detached from the DOM\n\t\t * structure of the editor, like panels, icons etc.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection} #body\n\t\t */\n\t\tthis.body = this.createCollection();\n\n\t\t/**\n\t\t * The element holding elements of the 'body' region.\n\t\t *\n\t\t * @private\n\t\t * @member {HTMLElement} #_bodyCollectionContainer\n\t\t */\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\tthis._renderBodyCollection();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis._bodyCollectionContainer.remove();\n\n\t\treturn super.destroy();\n\t}\n\n\t/**\n\t * Creates and appends to `<body>` the {@link #body} collection container.\n\t *\n\t * @private\n\t */\n\t_renderBodyCollection() {\n\t\tconst bodyElement = this._bodyCollectionContainer = new Template( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-reset_all',\n\t\t\t\t\t'ck-body',\n\t\t\t\t\t'ck-rounded-corners'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: this.body\n\t\t} ).render();\n\n\t\tdocument.body.appendChild( bodyElement );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/label/labelview\n */\n\nimport View from '../view';\n\nimport '../../theme/components/label/label.css';\n\n/**\n * The label view class.\n *\n * @extends module:ui/view~View\n */\nexport default class LabelView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\t/**\n\t\t * The text of the label.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #text\n\t\t */\n\t\tthis.set( 'text' );\n\n\t\t/**\n\t\t * The `for` attribute of the label (i.e. to pair with an `<input>` element).\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #for\n\t\t */\n\t\tthis.set( 'for' );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'label',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-label'\n\t\t\t\t],\n\t\t\t\tfor: bind.to( 'for' )\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttext: bind.to( 'text' )\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module ui/editorui/boxed/boxededitoruiview\n */\nimport EditorUIView from '../../editorui/editoruiview';\nimport LabelView from '../../label/labelview';\nimport uid from '@ckeditor/ckeditor5-utils/src/uid';\n/**\n * The boxed editor UI view class. This class represents an editor interface\n * consisting of a toolbar and an editable area, enclosed within a box.\n *\n * @extends module:ui/editorui/editoruiview~EditorUIView\n */\nexport default class BoxedEditorUIView extends EditorUIView {\n /**\n\t * Creates an instance of the boxed editor UI view class.\n\t *\n\t * @param {module:utils/locale~Locale} locale The locale instance..\n\t */\n constructor(locale) {\n super(locale);\n const ariaLabelUid = uid();\n /**\n\t\t * Collection of the child views located in the top (`.ck-editor__top`)\n\t\t * area of the UI.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n this.top = this.createCollection();\n /**\n\t\t * Collection of the child views located in the main (`.ck-editor__main`)\n\t\t * area of the UI.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n this.main = this.createCollection();\n /**\n\t\t * Voice label of the UI.\n\t\t *\n\t\t * @protected\n\t\t * @readonly\n\t\t * @member {module:ui/view~View} #_voiceLabelView\n\t\t */\n this._voiceLabelView = this._createVoiceLabel(ariaLabelUid);\n this.setTemplate({\n tag: 'div',\n attributes: {\n class: [\n 'ck',\n 'ck-reset',\n 'ck-editor',\n 'ck-rounded-corners'\n ],\n role: 'application',\n dir: 'ltr',\n lang: locale.language,\n 'aria-labelledby': `ck-editor__aria-label_${ ariaLabelUid }`\n },\n children: [\n this._voiceLabelView,\n {\n tag: 'div',\n attributes: {\n class: [\n 'ck',\n 'ck-editor__top',\n 'ck-reset_all'\n ],\n role: 'presentation'\n },\n children: this.top\n },\n {\n tag: 'div',\n attributes: {\n class: [\n 'ck',\n 'ck-editor__main'\n ],\n role: 'presentation'\n },\n children: this.main\n }\n ]\n });\n }\n /**\n\t * Creates a voice label view instance.\n\t *\n\t * @private\n\t * @returns {module:ui/label/labelview~LabelView}\n\t */\n _createVoiceLabel(ariaLabelUid) {\n const t = this.t;\n const voiceLabel = new LabelView();\n voiceLabel.text = t('x');\n voiceLabel.extendTemplate({\n attributes: {\n id: `ck-editor__aria-label_${ ariaLabelUid }`,\n class: 'ck-voice-label'\n }\n });\n return voiceLabel;\n }\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/editableui/editableuiview\n */\n\nimport View from '../view';\n\n/**\n * The editable UI view class.\n *\n * @extends module:ui/view~View\n */\nexport default class EditableUIView extends View {\n\t/**\n\t * Creates an instance of EditableUIView class.\n\t *\n\t * @param {module:utils/locale~Locale} [locale] The locale instance.\n\t * @param {module:engine/view/view~View} editingView The editing view instance the editable is related to.\n\t * @param {HTMLElement} [editableElement] The editable element. If not specified, this view\n\t * should create it. Otherwise, the existing element should be used.\n\t */\n\tconstructor( locale, editingView, editableElement ) {\n\t\tsuper( locale );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-content',\n\t\t\t\t\t'ck-editor__editable',\n\t\t\t\t\t'ck-rounded-corners'\n\t\t\t\t]\n\t\t\t}\n\t\t} );\n\n\t\t/**\n\t\t * The name of the editable UI view.\n\t\t *\n\t\t * @member {String} #name\n\t\t */\n\t\tthis.name = null;\n\n\t\t/**\n\t\t * Controls whether the editable is focused, i.e. the user is typing in it.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isFocused\n\t\t */\n\t\tthis.set( 'isFocused', false );\n\n\t\t/**\n\t\t * The element which is the main editable element (usually the one with `contentEditable=\"true\"`).\n\t\t *\n\t\t * @private\n\t\t * @member {HTMLElement} #_editableElement\n\t\t */\n\t\tthis._editableElement = editableElement;\n\n\t\t/**\n\t\t * Whether an external {@link #_editableElement} was passed into the constructor, which also means\n\t\t * the view will not render its {@link #template}.\n\t\t *\n\t\t * @private\n\t\t * @member {Boolean} #_hasExternalElement\n\t\t */\n\t\tthis._hasExternalElement = !!this._editableElement;\n\n\t\t/**\n\t\t * The editing view instance the editable is related to. Editable uses the editing\n\t\t * view to dynamically modify its certain DOM attributes after {@link #render rendering}.\n\t\t *\n\t\t * **Note**: The DOM attributes are performed by the editing view and not UI\n\t\t * {@link module:ui/view~View#bindTemplate template bindings} because once rendered,\n\t\t * the editable DOM element must remain under the full control of the engine to work properly.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:engine/view/view~View} #isFocused\n\t\t */\n\t\tthis._editingView = editingView;\n\t}\n\n\t/**\n\t * Renders the view by either applying the {@link #template} to the existing\n\t * {@link #_editableElement} or assigning {@link #element} as {@link #_editableElement}.\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\tif ( this._hasExternalElement ) {\n\t\t\tthis.template.apply( this.element = this._editableElement );\n\t\t} else {\n\t\t\tthis._editableElement = this.element;\n\t\t}\n\n\t\tthis.on( 'change:isFocused', () => this._updateIsFocusedClasses() );\n\t\tthis._updateIsFocusedClasses();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tif ( this._hasExternalElement ) {\n\t\t\tthis.template.revert( this._editableElement );\n\t\t}\n\n\t\tsuper.destroy();\n\t}\n\n\t/**\n\t * Updates the `ck-focused` and `ck-blurred` CSS classes on the {@link #element} according to\n\t * the {@link #isFocused} property value using the {@link #_editingView editing view} API.\n\t *\n\t * @private\n\t */\n\t_updateIsFocusedClasses() {\n\t\tconst editingView = this._editingView;\n\n\t\tif ( editingView.isRenderingInProgress ) {\n\t\t\tupdateAfterRender( this );\n\t\t} else {\n\t\t\tupdate( this );\n\t\t}\n\n\t\tfunction update( view ) {\n\t\t\teditingView.change( writer => {\n\t\t\t\tconst viewRoot = editingView.document.getRoot( view.name );\n\n\t\t\t\twriter.addClass( view.isFocused ? 'ck-focused' : 'ck-blurred', viewRoot );\n\t\t\t\twriter.removeClass( view.isFocused ? 'ck-blurred' : 'ck-focused', viewRoot );\n\t\t\t} );\n\t\t}\n\n\t\t// In a case of a multi-root editor, a callback will be attached more than once (one callback for each root).\n\t\t// While executing one callback the `isRenderingInProgress` observable is changing what causes executing another\n\t\t// callback and render is called inside the already pending render.\n\t\t// We need to be sure that callback is executed only when the value has changed from `true` to `false`.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/1676.\n\t\tfunction updateAfterRender( view ) {\n\t\t\teditingView.once( 'change:isRenderingInProgress', ( evt, name, value ) => {\n\t\t\t\tif ( !value ) {\n\t\t\t\t\tupdate( view );\n\t\t\t\t} else {\n\t\t\t\t\tupdateAfterRender( view );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module ui/editableui/inline/inlineeditableuiview\n */\nimport EditableUIView from '../../editableui/editableuiview';\n/**\n * The inline editable UI class implementing an inline {@link module:ui/editableui/editableuiview~EditableUIView}.\n *\n * @extends module:ui/editableui/editableuiview~EditableUIView\n */\nexport default class InlineEditableUIView extends EditableUIView {\n /**\n\t * Creates an instance of the InlineEditableUIView class.\n\t *\n\t * @param {module:utils/locale~Locale} [locale] The locale instance.\n\t * @param {module:engine/view/view~View} editingView The editing view instance the editable is related to.\n\t * @param {HTMLElement} [editableElement] The editable element. If not specified, the\n\t * {@link module:ui/editableui/editableuiview~EditableUIView}\n\t * will create it. Otherwise, the existing element will be used.\n\t */\n constructor(locale, editingView, editableElement) {\n super(locale, editingView, editableElement);\n this.extendTemplate({\n attributes: {\n role: 'textbox',\n class: 'ck-editor__editable_inline'\n }\n });\n }\n /**\n\t * @inheritDoc\n\t */\n render() {\n super.render();\n const editingView = this._editingView;\n const t = this.t;\n editingView.change(writer => {\n const viewRoot = editingView.document.getRoot(this.name);\n writer.setAttribute('aria-label', t('ad', [this.name]), viewRoot);\n });\n }\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/tounit\n */\n\n/**\n * Returns a helper function, which adds a desired trailing\n * `unit` to the passed value.\n *\n * @param {String} unit An unit like \"px\" or \"em\".\n * @returns {module:utils/dom/tounit~helper}\n */\nexport default function toUnit( unit ) {\n\t/**\n\t * A function, which adds a pre–defined trailing `unit`\n\t * to the passed `value`.\n\t *\n\t * @function helper\n \t * @param {*} value A value to be given the unit.\n \t * @returns {String} A value with the trailing unit.\n\t */\n\treturn value => value + unit;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/panel/sticky/stickypanelview\n */\n\nimport global from '@ckeditor/ckeditor5-utils/src/dom/global';\nimport View from '../../view';\nimport Template from '../../template';\nimport toUnit from '@ckeditor/ckeditor5-utils/src/dom/tounit';\n\nimport '../../../theme/components/panel/stickypanel.css';\n\nconst toPx = toUnit( 'px' );\n\n/**\n * The sticky panel view class.\n */\nexport default class StickyPanelView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * Controls whether the sticky panel should be active.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Boolean} #isActive\n\t\t */\n\t\tthis.set( 'isActive', false );\n\n\t\t/**\n\t\t * Controls whether the sticky panel is in the \"sticky\" state.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Boolean} #isSticky\n\t\t */\n\t\tthis.set( 'isSticky', false );\n\n\t\t/**\n\t\t * The limiter element for the sticky panel instance. Its bounding rect limits\n\t\t * the \"stickyness\" of the panel, i.e. when the panel reaches the bottom\n\t\t * edge of the limiter, it becomes sticky to that edge and does not float\n\t\t * off the limiter. It is mandatory for the panel to work properly and once\n\t\t * set, it cannot be changed.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {HTMLElement} #limiterElement\n\t\t */\n\t\tthis.set( 'limiterElement', null );\n\n\t\t/**\n\t\t * The offset from the bottom edge of {@link #limiterElement}\n\t\t * which stops the panel from stickying any further to prevent limiter's content\n\t\t * from being completely covered.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @default 50\n\t\t * @member {Number} #limiterBottomOffset\n\t\t */\n\t\tthis.set( 'limiterBottomOffset', 50 );\n\n\t\t/**\n\t\t * The offset from the top edge of the web browser's viewport which makes the\n\t\t * panel become sticky. The default value is `0`, which means the panel becomes\n\t\t * sticky when it's upper edge touches the top of the page viewport.\n\t\t *\n\t\t * This attribute is useful when the web page has UI elements positioned to the top\n\t\t * either using `position: fixed` or `position: sticky`, which would cover the\n\t\t * sticky panel or vice–versa (depending on the `z-index` hierarchy).\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @default 0\n\t\t * @member {Number} #viewportTopOffset\n\t\t */\n\t\tthis.set( 'viewportTopOffset', 0 );\n\n\t\t/**\n\t\t * Controls the `margin-left` CSS style of the panel.\n\t\t *\n\t\t * @protected\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {String} #_marginLeft\n\t\t */\n\t\tthis.set( '_marginLeft', null );\n\n\t\t/**\n\t\t * Set `true` if the sticky panel reached the bottom edge of the\n\t\t * {@link #limiterElement}.\n\t\t *\n\t\t * @protected\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Boolean} #_isStickyToTheLimiter\n\t\t */\n\t\tthis.set( '_isStickyToTheLimiter', false );\n\n\t\t/**\n\t\t * Set `true` if the sticky panel uses the {@link #viewportTopOffset},\n\t\t * i.e. not {@link #_isStickyToTheLimiter} and the {@link #viewportTopOffset}\n\t\t * is not `0`.\n\t\t *\n\t\t * @protected\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Boolean} #_hasViewportTopOffset\n\t\t */\n\t\tthis.set( '_hasViewportTopOffset', false );\n\n\t\t/**\n\t\t * Collection of the child views which creates balloon panel contents.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.content = this.createCollection();\n\n\t\t/**\n\t\t * The DOM bounding client rect of the {@link module:ui/view~View#element} of the panel.\n\t\t *\n\t\t * @protected\n\t\t * @member {Object} #_panelRect\n\t\t */\n\n\t\t/**\n\t\t * The DOM bounding client rect of the {@link #limiterElement}\n\t\t * of the panel.\n\t\t *\n\t\t * @protected\n\t\t * @member {Object} #_limiterRect\n\t\t */\n\n\t\t/**\n\t\t * A dummy element which visually fills the space as long as the\n\t\t * actual panel is sticky. It prevents flickering of the UI.\n\t\t *\n\t\t * @protected\n\t\t * @property {HTMLElement}\n\t\t */\n\t\tthis._contentPanelPlaceholder = new Template( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-sticky-panel__placeholder'\n\t\t\t\t],\n\t\t\t\tstyle: {\n\t\t\t\t\tdisplay: bind.to( 'isSticky', isSticky => isSticky ? 'block' : 'none' ),\n\t\t\t\t\theight: bind.to( 'isSticky', isSticky => {\n\t\t\t\t\t\treturn isSticky ? toPx( this._panelRect.height ) : null;\n\t\t\t\t\t} )\n\t\t\t\t}\n\t\t\t}\n\t\t} ).render();\n\n\t\t/**\n\t\t * The panel which accepts children into {@link #content} collection.\n\t\t * Also an element which is positioned when {@link #isSticky}.\n\t\t *\n\t\t * @protected\n\t\t * @property {HTMLElement}\n\t\t */\n\t\tthis._contentPanel = new Template( {\n\t\t\ttag: 'div',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-sticky-panel__content',\n\t\t\t\t\t// Toggle class of the panel when \"sticky\" state changes in the view.\n\t\t\t\t\tbind.if( 'isSticky', 'ck-sticky-panel__content_sticky' ),\n\t\t\t\t\tbind.if( '_isStickyToTheLimiter', 'ck-sticky-panel__content_sticky_bottom-limit' ),\n\t\t\t\t],\n\t\t\t\tstyle: {\n\t\t\t\t\twidth: bind.to( 'isSticky', isSticky => {\n\t\t\t\t\t\treturn isSticky ? toPx( this._contentPanelPlaceholder.getBoundingClientRect().width ) : null;\n\t\t\t\t\t} ),\n\n\t\t\t\t\ttop: bind.to( '_hasViewportTopOffset', _hasViewportTopOffset => {\n\t\t\t\t\t\treturn _hasViewportTopOffset ? toPx( this.viewportTopOffset ) : null;\n\t\t\t\t\t} ),\n\n\t\t\t\t\tbottom: bind.to( '_isStickyToTheLimiter', _isStickyToTheLimiter => {\n\t\t\t\t\t\treturn _isStickyToTheLimiter ? toPx( this.limiterBottomOffset ) : null;\n\t\t\t\t\t} ),\n\n\t\t\t\t\tmarginLeft: bind.to( '_marginLeft' )\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tchildren: this.content\n\t\t} ).render();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-sticky-panel'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\tthis._contentPanelPlaceholder,\n\t\t\t\tthis._contentPanel\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\t// Check if the panel should go into the sticky state immediately.\n\t\tthis._checkIfShouldBeSticky();\n\n\t\t// Update sticky state of the panel as the window is being scrolled.\n\t\tthis.listenTo( global.window, 'scroll', () => {\n\t\t\tthis._checkIfShouldBeSticky();\n\t\t} );\n\n\t\t// Synchronize with `model.isActive` because sticking an inactive panel is pointless.\n\t\tthis.listenTo( this, 'change:isActive', () => {\n\t\t\tthis._checkIfShouldBeSticky();\n\t\t} );\n\t}\n\n\t/**\n\t * Analyzes the environment to decide whether the panel should\n\t * be sticky or not.\n\t *\n\t * @protected\n\t */\n\t_checkIfShouldBeSticky() {\n\t\tconst panelRect = this._panelRect = this._contentPanel.getBoundingClientRect();\n\t\tlet limiterRect;\n\n\t\tif ( !this.limiterElement ) {\n\t\t\tthis.isSticky = false;\n\t\t} else {\n\t\t\tlimiterRect = this._limiterRect = this.limiterElement.getBoundingClientRect();\n\n\t\t\t// The panel must be active to become sticky.\n\t\t\tthis.isSticky = this.isActive &&\n\t\t\t\t// The limiter's top edge must be beyond the upper edge of the visible viewport (+the viewportTopOffset).\n\t\t\t\tlimiterRect.top < this.viewportTopOffset &&\n\t\t\t\t// The model#limiterElement's height mustn't be smaller than the panel's height and model#limiterBottomOffset.\n\t\t\t\t// There's no point in entering the sticky mode if the model#limiterElement is very, very small, because\n\t\t\t\t// it would immediately set model#_isStickyToTheLimiter true and, given model#limiterBottomOffset, the panel\n\t\t\t\t// would be positioned before the model#limiterElement.\n\t\t\t\tthis._panelRect.height + this.limiterBottomOffset < limiterRect.height;\n\t\t}\n\n\t\t// Stick the panel to the top edge of the viewport simulating CSS position:sticky.\n\t\t// TODO: Possibly replaced by CSS in the future http://caniuse.com/#feat=css-sticky\n\t\tif ( this.isSticky ) {\n\t\t\tthis._isStickyToTheLimiter =\n\t\t\t\tlimiterRect.bottom < panelRect.height + this.limiterBottomOffset + this.viewportTopOffset;\n\t\t\tthis._hasViewportTopOffset = !this._isStickyToTheLimiter && !!this.viewportTopOffset;\n\t\t\tthis._marginLeft = this._isStickyToTheLimiter ? null : toPx( -global.window.scrollX );\n\t\t}\n\t\t// Detach the panel from the top edge of the viewport.\n\t\telse {\n\t\t\tthis._isStickyToTheLimiter = false;\n\t\t\tthis._hasViewportTopOffset = false;\n\t\t\tthis._marginLeft = null;\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/focuscycler\n */\n\nimport global from '@ckeditor/ckeditor5-utils/src/dom/global';\n\n/**\n * A utility class that helps cycling over focusable {@link module:ui/view~View views} in a\n * {@link module:ui/viewcollection~ViewCollection} when the focus is tracked by the\n * {@link module:utils/focustracker~FocusTracker} instance. It helps implementing keyboard\n * navigation in HTML forms, toolbars, lists and the like.\n *\n * To work properly it requires:\n * * a collection of focusable (HTML `tabindex` attribute) views that implement the `focus()` method,\n * * an associated focus tracker to determine which view is focused.\n *\n * A simple cycler setup can look like this:\n *\n *\t\tconst focusables = new ViewCollection();\n *\t\tconst focusTracker = new FocusTracker();\n *\n *\t\t// Add focusable views to the focus tracker.\n *\t\tfocusTracker.add( ... );\n *\n * Then, the cycler can be used manually:\n *\n *\t\tconst cycler = new FocusCycler( { focusables, focusTracker } );\n *\n *\t\t// Will focus the first focusable view in #focusables.\n *\t\tcycler.focusFirst();\n *\n *\t\t// Will log the next focusable item in #focusables.\n *\t\tconsole.log( cycler.next );\n *\n * Alternatively, it can work side by side with the {@link module:utils/keystrokehandler~KeystrokeHandler}:\n *\n *\t\tconst keystrokeHandler = new KeystrokeHandler();\n *\n *\t\t// Activate the keystroke handler.\n *\t\tkeystrokeHandler.listenTo( sourceOfEvents );\n *\n *\t\tconst cycler = new FocusCycler( {\n *\t\t\tfocusables, focusTracker, keystrokeHandler,\n *\t\t\tactions: {\n *\t\t\t\t// When arrowup of arrowleft is detected by the #keystrokeHandler,\n *\t\t\t\t// focusPrevious() will be called on the cycler.\n *\t\t\t\tfocusPrevious: [ 'arrowup', 'arrowleft' ],\n *\t\t\t}\n *\t\t} );\n */\nexport default class FocusCycler {\n\t/**\n\t * Creates an instance of the focus cycler utility.\n\t *\n\t * @param {Object} options Configuration options.\n\t * @param {module:utils/collection~Collection|Object} options.focusables\n\t * @param {module:utils/focustracker~FocusTracker} options.focusTracker\n\t * @param {module:utils/keystrokehandler~KeystrokeHandler} [options.keystrokeHandler]\n\t * @param {Object} [options.actions]\n\t */\n\tconstructor( options ) {\n\t\tObject.assign( this, options );\n\n\t\t/**\n\t\t * A {@link module:ui/view~View view} collection that the cycler operates on.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/collection~Collection} #focusables\n\t\t */\n\n\t\t/**\n\t\t * A focus tracker instance that the cycler uses to determine the current focus\n\t\t * state in {@link #focusables}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/focustracker~FocusTracker} #focusTracker\n\t\t */\n\n\t\t/**\n\t\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}\n\t\t * which can respond to certain keystrokes and cycle the focus.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/keystrokehandler~KeystrokeHandler} #keystrokeHandler\n\t\t */\n\n\t\t/**\n\t\t * Actions that the cycler can take when a keystroke is pressed. Requires\n\t\t * `options.keystrokeHandler` to be passed and working. When an action is\n\t\t * performed, `preventDefault` and `stopPropagation` will be called on the event\n\t\t * the keystroke fired in the DOM.\n\t\t *\n\t\t *\t\tactions: {\n\t\t *\t\t\t// Will call #focusPrevious() when arrowleft or arrowup is pressed.\n\t\t *\t\t\tfocusPrevious: [ 'arrowleft', 'arrowup' ],\n\t\t *\n\t\t *\t\t\t// Will call #focusNext() when arrowdown is pressed.\n\t\t *\t\t\tfocusNext: 'arrowdown'\n\t\t *\t\t}\n\t\t *\n\t\t * @readonly\n\t\t * @member {Object} #actions\n\t\t */\n\n\t\tif ( options.actions && options.keystrokeHandler ) {\n\t\t\tfor ( const methodName in options.actions ) {\n\t\t\t\tlet actions = options.actions[ methodName ];\n\n\t\t\t\tif ( typeof actions == 'string' ) {\n\t\t\t\t\tactions = [ actions ];\n\t\t\t\t}\n\n\t\t\t\tfor ( const keystroke of actions ) {\n\t\t\t\t\toptions.keystrokeHandler.set( keystroke, ( data, cancel ) => {\n\t\t\t\t\t\tthis[ methodName ]();\n\t\t\t\t\t\tcancel();\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns the first focusable view in {@link #focusables}.\n\t * Returns `null` if there is none.\n\t *\n\t * @readonly\n\t * @member {module:ui/view~View|null} #first\n\t */\n\tget first() {\n\t\treturn this.focusables.find( isFocusable ) || null;\n\t}\n\n\t/**\n\t * Returns the last focusable view in {@link #focusables}.\n\t * Returns `null` if there is none.\n\t *\n\t * @readonly\n\t * @member {module:ui/view~View|null} #last\n\t */\n\tget last() {\n\t\treturn this.focusables.filter( isFocusable ).slice( -1 )[ 0 ] || null;\n\t}\n\n\t/**\n\t * Returns the next focusable view in {@link #focusables} based on {@link #current}.\n\t * Returns `null` if there is none.\n\t *\n\t * @readonly\n\t * @member {module:ui/view~View|null} #next\n\t */\n\tget next() {\n\t\treturn this._getFocusableItem( 1 );\n\t}\n\n\t/**\n\t * Returns the previous focusable view in {@link #focusables} based on {@link #current}.\n\t * Returns `null` if there is none.\n\t *\n\t * @readonly\n\t * @member {module:ui/view~View|null} #previous\n\t */\n\tget previous() {\n\t\treturn this._getFocusableItem( -1 );\n\t}\n\n\t/**\n\t * An index of the view in the {@link #focusables} which is focused according\n\t * to {@link #focusTracker}. Returns `null` when there is no such view.\n\t *\n\t * @readonly\n\t * @member {Number|null} #current\n\t */\n\tget current() {\n\t\tlet index = null;\n\n\t\t// There's no focused view in the focusables.\n\t\tif ( this.focusTracker.focusedElement === null ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tthis.focusables.find( ( view, viewIndex ) => {\n\t\t\tconst focused = view.element === this.focusTracker.focusedElement;\n\n\t\t\tif ( focused ) {\n\t\t\t\tindex = viewIndex;\n\t\t\t}\n\n\t\t\treturn focused;\n\t\t} );\n\n\t\treturn index;\n\t}\n\n\t/**\n\t * Focuses the {@link #first} item in {@link #focusables}.\n\t */\n\tfocusFirst() {\n\t\tthis._focus( this.first );\n\t}\n\n\t/**\n\t * Focuses the {@link #last} item in {@link #focusables}.\n\t */\n\tfocusLast() {\n\t\tthis._focus( this.last );\n\t}\n\n\t/**\n\t * Focuses the {@link #next} item in {@link #focusables}.\n\t */\n\tfocusNext() {\n\t\tthis._focus( this.next );\n\t}\n\n\t/**\n\t * Focuses the {@link #previous} item in {@link #focusables}.\n\t */\n\tfocusPrevious() {\n\t\tthis._focus( this.previous );\n\t}\n\n\t/**\n\t * Focuses the given view if it exists.\n\t *\n\t * @protected\n\t * @param {module:ui/view~View} view\n\t */\n\t_focus( view ) {\n\t\tif ( view ) {\n\t\t\tview.focus();\n\t\t}\n\t}\n\n\t/**\n\t * Returns the next or previous focusable view in {@link #focusables} with respect\n\t * to {@link #current}.\n\t *\n\t * @protected\n\t * @param {Number} step Either `1` for checking forward from {@link #current} or\n\t * `-1` for checking backwards.\n\t * @returns {module:ui/view~View|null}\n\t */\n\t_getFocusableItem( step ) {\n\t\t// Cache for speed.\n\t\tconst current = this.current;\n\t\tconst collectionLength = this.focusables.length;\n\n\t\tif ( !collectionLength ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Start from the beginning if no view is focused.\n\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/206\n\t\tif ( current === null ) {\n\t\t\treturn this[ step === 1 ? 'first' : 'last' ];\n\t\t}\n\n\t\t// Cycle in both directions.\n\t\tlet index = ( current + collectionLength + step ) % collectionLength;\n\n\t\tdo {\n\t\t\tconst view = this.focusables.get( index );\n\n\t\t\t// TODO: Check if view is visible.\n\t\t\tif ( isFocusable( view ) ) {\n\t\t\t\treturn view;\n\t\t\t}\n\n\t\t\t// Cycle in both directions.\n\t\t\tindex = ( index + collectionLength + step ) % collectionLength;\n\t\t} while ( index !== current );\n\n\t\treturn null;\n\t}\n}\n\n// Checks whether a view is focusable.\n//\n// @private\n// @param {module:ui/view~View} view A view to be checked.\n// @returns {Boolean}\nfunction isFocusable( view ) {\n\treturn !!( view.focus && global.window.getComputedStyle( view.element ).display != 'none' );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/toolbar/toolbarseparatorview\n */\n\nimport View from '../view';\n\n/**\n * The toolbar separator view class.\n *\n * @extends module:ui/view~View\n */\nexport default class ToolbarSeparatorView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'span',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-toolbar__separator'\n\t\t\t\t]\n\t\t\t}\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/toolbar/toolbarview\n */\n\nimport View from '../view';\nimport FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';\nimport FocusCycler from '../focuscycler';\nimport KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';\nimport ToolbarSeparatorView from './toolbarseparatorview';\nimport preventDefault from '../bindings/preventdefault.js';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\n\nimport '../../theme/components/toolbar/toolbar.css';\n\n/**\n * The toolbar view class.\n *\n * @extends module:ui/view~View\n * @implements module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable\n */\nexport default class ToolbarView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * Collection of the toolbar items (like buttons).\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.items = this.createCollection();\n\n\t\t/**\n\t\t * Tracks information about DOM focus in the list.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/focustracker~FocusTracker}\n\t\t */\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\t/**\n\t\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/keystrokehandler~KeystrokeHandler}\n\t\t */\n\t\tthis.keystrokes = new KeystrokeHandler();\n\n\t\t/**\n\t\t * Controls the orientation of toolbar items.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isVertical\n\t\t */\n\t\tthis.set( 'isVertical', false );\n\n\t\t/**\n\t\t * An additional CSS class added to the {@link #element}.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #class\n\t\t */\n\t\tthis.set( 'class' );\n\n\t\t/**\n\t\t * Helps cycling over focusable {@link #items} in the toolbar.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/focuscycler~FocusCycler}\n\t\t */\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this.items,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate toolbar items backwards using the arrow[left,up] keys.\n\t\t\t\tfocusPrevious: [ 'arrowleft', 'arrowup' ],\n\n\t\t\t\t// Navigate toolbar items forwards using the arrow[right,down] keys.\n\t\t\t\tfocusNext: [ 'arrowright', 'arrowdown' ]\n\t\t\t}\n\t\t} );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-toolbar',\n\t\t\t\t\tbind.if( 'isVertical', 'ck-toolbar_vertical' ),\n\t\t\t\t\tbind.to( 'class' )\n\t\t\t\t]\n\t\t\t},\n\n\t\t\tchildren: this.items,\n\n\t\t\ton: {\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/206\n\t\t\t\tmousedown: preventDefault( this )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\t// Items added before rendering should be known to the #focusTracker.\n\t\tfor ( const item of this.items ) {\n\t\t\tthis.focusTracker.add( item.element );\n\t\t}\n\n\t\tthis.items.on( 'add', ( evt, item ) => {\n\t\t\tthis.focusTracker.add( item.element );\n\t\t} );\n\n\t\tthis.items.on( 'remove', ( evt, item ) => {\n\t\t\tthis.focusTracker.remove( item.element );\n\t\t} );\n\n\t\t// Start listening for the keystrokes coming from #element.\n\t\tthis.keystrokes.listenTo( this.element );\n\t}\n\n\t/**\n\t * Focuses the first focusable in {@link #items}.\n\t */\n\tfocus() {\n\t\tthis._focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * Focuses the last focusable in {@link #items}.\n\t */\n\tfocusLast() {\n\t\tthis._focusCycler.focusLast();\n\t}\n\n\t/**\n\t * A utility which expands a plain toolbar configuration into\n\t * {@link module:ui/toolbar/toolbarview~ToolbarView#items} using a given component factory.\n\t *\n\t * @param {Array.<String>} config The toolbar items config.\n\t * @param {module:ui/componentfactory~ComponentFactory} factory A factory producing toolbar items.\n\t */\n\tfillFromConfig( config, factory ) {\n\t\tconfig.map( name => {\n\t\t\tif ( name == '|' ) {\n\t\t\t\tthis.items.add( new ToolbarSeparatorView() );\n\t\t\t} else if ( factory.has( name ) ) {\n\t\t\t\tthis.items.add( factory.create( name ) );\n\t\t\t} else {\n\t\t\t\t/**\n\t\t\t\t * There was a problem processing the configuration of the toolbar. The item with the given\n\t\t\t\t * name does not exist so it was omitted when rendering the toolbar.\n\t\t\t\t *\n\t\t\t\t * This warning usually shows up when the {@link module:core/plugin~Plugin} which is supposed\n\t\t\t\t * to provide a toolbar item has not been loaded or there is a typo in the configuration.\n\t\t\t\t *\n\t\t\t\t * Make sure the plugin responsible for this toolbar item is loaded and the toolbar configuration\n\t\t\t\t * is correct, e.g. {@link module:basic-styles/bold~Bold} is loaded for the `'bold'` toolbar item.\n\t\t\t\t *\n\t\t\t\t * You can use the following snippet to retrieve all available toolbar items:\n\t\t\t\t *\n\t\t\t\t *\t\tArray.from( editor.ui.componentFactory.names() );\n\t\t\t\t *\n\t\t\t\t * @error toolbarview-item-unavailable\n\t\t\t\t * @param {String} name The name of the component.\n\t\t\t\t */\n\t\t\t\tlog.warn(\n\t\t\t\t\t'toolbarview-item-unavailable: The requested toolbar item is unavailable.',\n\t\t\t\t\t{ name }\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\t}\n}\n\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/bindings/preventdefault\n */\n\n/**\n * A helper which executes a native `Event.preventDefault()` if the target of an event equals the\n * {@link module:ui/view~View#element element of the view}. It shortens the definition of a\n * {@link module:ui/view~View#template template}.\n *\n *\t\t// In a class extending View.\n *\t\timport preventDefault from '@ckeditor/ckeditor5-ui/src/bindings/preventdefault';\n *\n *\t\t// ...\n *\n *\t\tthis.setTemplate( {\n *\t\t\ttag: 'div',\n *\n *\t\t\ton: {\n *\t\t\t\t// Prevent the default mousedown action on this view.\n *\t\t\t\tmousedown: preventDefault( this )\n *\t\t\t}\n *\t\t} );\n *\n * @param {module:ui/view~View} view View instance that defines the template.\n * @returns {module:ui/template~TemplateToBinding}\n */\nexport default function preventDefault( view ) {\n\treturn view.bindTemplate.to( evt => {\n\t\tif ( evt.target === view.element ) {\n\t\t\tevt.preventDefault();\n\t\t}\n\t} );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module editor-classic/classiceditoruiview\n */\n\nimport BoxedEditorUIView from '@ckeditor/ckeditor5-ui/src/editorui/boxed/boxededitoruiview';\nimport InlineEditableUIView from '@ckeditor/ckeditor5-ui/src/editableui/inline/inlineeditableuiview';\nimport StickyPanelView from '@ckeditor/ckeditor5-ui/src/panel/sticky/stickypanelview';\nimport ToolbarView from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview';\n\nimport '../theme/classiceditor.css';\n\n/**\n * Classic editor UI view. Uses an inline editable and a sticky toolbar, all\n * enclosed in a boxed UI view.\n *\n * @extends module:ui/editorui/boxed/boxededitoruiview~BoxedEditorUIView\n */\nexport default class ClassicEditorUIView extends BoxedEditorUIView {\n\t/**\n\t * Creates an instance of the classic editor UI view.\n\t *\n\t * @param {module:utils/locale~Locale} locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param {module:engine/view/view~View} editingView The editing view instance this view is related to.\n\t */\n\tconstructor( locale, editingView ) {\n\t\tsuper( locale );\n\n\t\t/**\n\t\t * Sticky panel view instance. This is a parent view of a {@link #toolbar}\n\t\t * that makes toolbar sticky.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/panel/sticky/stickypanelview~StickyPanelView}\n\t\t */\n\t\tthis.stickyPanel = new StickyPanelView( locale );\n\n\t\t/**\n\t\t * Toolbar view instance.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/toolbar/toolbarview~ToolbarView}\n\t\t */\n\t\tthis.toolbar = new ToolbarView( locale );\n\n\t\t/**\n\t\t * Editable UI view.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/editableui/inline/inlineeditableuiview~InlineEditableUIView}\n\t\t */\n\t\tthis.editable = new InlineEditableUIView( locale, editingView );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\t// Set toolbar as a child of a stickyPanel and makes toolbar sticky.\n\t\tthis.stickyPanel.content.add( this.toolbar );\n\n\t\tthis.top.add( this.stickyPanel );\n\t\tthis.main.add( this.editable );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module editor-classic/classiceditor\n */\n\nimport Editor from '@ckeditor/ckeditor5-core/src/editor/editor';\nimport DataApiMixin from '@ckeditor/ckeditor5-core/src/editor/utils/dataapimixin';\nimport ElementApiMixin from '@ckeditor/ckeditor5-core/src/editor/utils/elementapimixin';\nimport attachToForm from '@ckeditor/ckeditor5-core/src/editor/utils/attachtoform';\nimport HtmlDataProcessor from '@ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor';\nimport ClassicEditorUI from './classiceditorui';\nimport ClassicEditorUIView from './classiceditoruiview';\nimport getDataFromElement from '@ckeditor/ckeditor5-utils/src/dom/getdatafromelement';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport { isElement } from 'lodash-es';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * The {@glink builds/guides/overview#classic-editor classic editor} implementation.\n * It uses an inline editable and a sticky toolbar, all enclosed in a boxed UI.\n * See the {@glink examples/builds/classic-editor demo}.\n *\n * In order to create a classic editor instance, use the static\n * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`} method.\n *\n * # Classic editor and classic build\n *\n * The classic editor can be used directly from source (if you installed the\n * [`@ckeditor/ckeditor5-editor-classic`](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-classic) package)\n * but it is also available in the {@glink builds/guides/overview#classic-editor classic build}.\n *\n * {@glink builds/guides/overview Builds} are ready-to-use editors with plugins bundled in. When using the editor from\n * source you need to take care of loading all plugins by yourself\n * (through the {@link module:core/editor/editorconfig~EditorConfig#plugins `config.plugins`} option).\n * Using the editor from source gives much better flexibility and allows easier customization.\n *\n * Read more about initializing the editor from source or as a build in\n * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`}.\n *\n * @mixes module:core/editor/utils/dataapimixin~DataApiMixin\n * @mixes module:core/editor/utils/elementapimixin~ElementApiMixin\n * @implements module:core/editor/editorwithui~EditorWithUI\n * @extends module:core/editor/editor~Editor\n */\nexport default class ClassicEditor extends Editor {\n\t/**\n\t * Creates an instance of the classic editor.\n\t *\n\t * **Note:** do not use the constructor to create editor instances. Use the static\n\t * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`} method instead.\n\t *\n\t * @protected\n\t * @param {HTMLElement|String} sourceElementOrData The DOM element that will be the source for the created editor\n\t * or the editor's initial data. For more information see\n\t * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`}.\n\t * @param {module:core/editor/editorconfig~EditorConfig} config The editor configuration.\n\t */\n\tconstructor( sourceElementOrData, config ) {\n\t\tsuper( config );\n\n\t\tif ( isElement( sourceElementOrData ) ) {\n\t\t\tthis.sourceElement = sourceElementOrData;\n\t\t}\n\n\t\tthis.data.processor = new HtmlDataProcessor();\n\n\t\tthis.model.document.createRoot();\n\n\t\tthis.ui = new ClassicEditorUI( this, new ClassicEditorUIView( this.locale, this.editing.view ) );\n\n\t\tattachToForm( this );\n\t}\n\n\t/**\n\t * Destroys the editor instance, releasing all resources used by it.\n\t *\n\t * Updates the editor's source element with the data.\n\t *\n\t * @returns {Promise}\n\t */\n\tdestroy() {\n\t\tif ( this.sourceElement ) {\n\t\t\tthis.updateSourceElement();\n\t\t}\n\n\t\tthis.ui.destroy();\n\n\t\treturn super.destroy();\n\t}\n\n\t/**\n\t * Creates a new classic editor instance.\n\t *\n\t * There are three ways how the editor can be initialized.\n\t *\n\t * # Replacing a DOM element (and loading data from it)\n\t *\n\t * You can initialize the editor using an existing DOM element:\n\t *\n\t *\t\tClassicEditor\n\t *\t\t\t.create( document.querySelector( '#editor' ) )\n\t *\t\t\t.then( editor => {\n\t *\t\t\t\tconsole.log( 'Editor was initialized', editor );\n\t *\t\t\t} )\n\t *\t\t\t.catch( err => {\n\t *\t\t\t\tconsole.error( err.stack );\n\t *\t\t\t} );\n\t *\n\t * The element's content will be used as the editor data and the element will be replaced by the editor UI.\n\t *\n\t * # Creating a detached editor\n\t *\n\t * Alternatively, you can initialize the editor by passing the initial data directly as a string.\n\t * In this case, the editor will render an element that must be inserted into the DOM:\n\t *\n\t *\t\tClassicEditor\n\t *\t\t\t.create( '<p>Hello world!</p>' )\n\t *\t\t\t.then( editor => {\n\t *\t\t\t\tconsole.log( 'Editor was initialized', editor );\n\t *\n\t *\t\t\t\t// Initial data was provided so the editor UI element needs to be added manually to the DOM.\n\t *\t\t\t\tdocument.body.appendChild( editor.ui.element );\n\t *\t\t\t} )\n\t *\t\t\t.catch( err => {\n\t *\t\t\t\tconsole.error( err.stack );\n\t *\t\t\t} );\n\t *\n\t * This lets you dynamically append the editor to your web page whenever it is convenient for you. You may use this method if your\n\t * web page content is generated on the client-side and the DOM structure is not ready at the moment when you initialize the editor.\n\t *\n\t * # Replacing a DOM element (and data provided in `config.initialData`)\n\t *\n\t * You can also mix those two ways by providing a DOM element to be used and passing the initial data through the config:\n\t *\n\t *\t\tClassicEditor\n\t *\t\t\t.create( document.querySelector( '#editor' ), {\n\t *\t\t\t\tinitialData: '<h2>Initial data</h2><p>Foo bar.</p>'\n\t *\t\t\t} )\n\t *\t\t\t.then( editor => {\n\t *\t\t\t\tconsole.log( 'Editor was initialized', editor );\n\t *\t\t\t} )\n\t *\t\t\t.catch( err => {\n\t *\t\t\t\tconsole.error( err.stack );\n\t *\t\t\t} );\n\t *\n\t * This method can be used to initialize the editor on an existing element with specified content in case if your integration\n\t * makes it difficult to set the content of the source element.\n\t *\n\t * Note that an error will be thrown if you pass initial data both as the first parameter and also in the config.\n\t *\n\t * # Configuring the editor\n\t *\n\t * See the {@link module:core/editor/editorconfig~EditorConfig editor configuration documentation} to learn more about\n\t * customizing plugins, toolbar and other.\n\t *\n\t * # Using the editor from source\n\t *\n\t * The code samples listed in the previous sections of this documentation assume that you are using an\n\t * {@glink builds/guides/overview editor build} (for example – `@ckeditor/ckeditor5-build-classic`).\n\t *\n\t * If you want to use the classic editor from source (`@ckeditor/ckeditor5-editor-classic/src/classiceditor`),\n\t * then you need to define the list of\n\t * {@link module:core/editor/editorconfig~EditorConfig#plugins plugins to be initialized} and\n\t * {@link module:core/editor/editorconfig~EditorConfig#toolbar toolbar items}. Read more about using the editor from\n\t * source in the {@glink builds/guides/integration/advanced-setup \"Advanced setup\" guide}.\n\t *\n\t * @param {HTMLElement|String} sourceElementOrData The DOM element that will be the source for the created editor\n\t * or the editor's initial data.\n\t *\n\t * If a DOM element is passed, its content will be automatically loaded to the editor upon initialization\n\t * and the {@link module:editor-classic/classiceditorui~ClassicEditorUI#element editor element} will replace the passed element\n\t * in the DOM (the original one will be hidden and the editor will be injected next to it).\n\t *\n\t * Moreover, the editor data will be set back to the original element once the editor is destroyed and when a form, in which\n\t * this element is contained, is submitted (if the original element is a `<textarea>`). This ensures seamless integration with native\n\t * web forms.\n\t *\n\t * If the initial data is passed, a detached editor will be created. In this case you need to insert it into the DOM manually.\n\t * It is available under {@link module:editor-classic/classiceditorui~ClassicEditorUI#element `editor.ui.element`} property.\n\t *\n\t * @param {module:core/editor/editorconfig~EditorConfig} [config] The editor configuration.\n\t * @returns {Promise} A promise resolved once the editor is ready. The promise resolves with the created editor instance.\n\t */\n\tstatic create( sourceElementOrData, config = {} ) {\n\t\treturn new Promise( resolve => {\n\t\t\tconst editor = new this( sourceElementOrData, config );\n\n\t\t\tresolve(\n\t\t\t\teditor.initPlugins()\n\t\t\t\t\t.then( () => editor.ui.init( isElement( sourceElementOrData ) ? sourceElementOrData : null ) )\n\t\t\t\t\t.then( () => {\n\t\t\t\t\t\tif ( !isElement( sourceElementOrData ) && config.initialData ) {\n\t\t\t\t\t\t\t// Documented in core/editor/editorconfig.jdoc.\n\t\t\t\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t\t\t\t'editor-create-initial-data: ' +\n\t\t\t\t\t\t\t\t'The config.initialData option cannot be used together with initial data passed in Editor.create().'\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst initialData = config.initialData || getInitialData( sourceElementOrData );\n\n\t\t\t\t\t\treturn editor.data.init( initialData );\n\t\t\t\t\t} )\n\t\t\t\t\t.then( () => editor.fire( 'ready' ) )\n\t\t\t\t\t.then( () => editor )\n\t\t\t);\n\t\t} );\n\t}\n}\n\nmix( ClassicEditor, DataApiMixin );\nmix( ClassicEditor, ElementApiMixin );\n\nfunction getInitialData( sourceElementOrData ) {\n\treturn isElement( sourceElementOrData ) ? getDataFromElement( sourceElementOrData ) : sourceElementOrData;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\nimport { isFunction } from 'lodash-es';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * @module core/editor/utils/attachtoform\n */\n\n/**\n * Checks if the editor is initialized on a `<textarea>` element that belongs to a form. If yes, it updates the editor's element\n * content before submitting the form.\n *\n * This helper requires the {@link module:core/editor/utils/elementapimixin~ElementApi ElementApi interface}.\n *\n * @param {module:core/editor/editor~Editor} editor Editor instance.\n */\nexport default function attachToForm( editor ) {\n\tif ( !isFunction( editor.updateSourceElement ) ) {\n\t\t/**\n\t\t * The editor passed to `attachToForm()` must implement the\n\t\t * {@link module:core/editor/utils/elementapimixin~ElementApi} interface.\n\t\t *\n\t\t * @error attachtoform-missing-elementapi-interface\n\t\t */\n\t\tthrow new CKEditorError( 'attachtoform-missing-elementapi-interface: Editor passed to attachToForm() must implement ElementApi.' );\n\t}\n\n\tconst sourceElement = editor.sourceElement;\n\n\t// Only when replacing a textarea which is inside of a form element.\n\tif ( sourceElement && sourceElement.tagName.toLowerCase() === 'textarea' && sourceElement.form ) {\n\t\tlet originalSubmit;\n\t\tconst form = sourceElement.form;\n\t\tconst onSubmit = () => editor.updateSourceElement();\n\n\t\t// Replace the original form#submit() to call a custom submit function first.\n\t\t// Check if #submit is a function because the form might have an input named \"submit\".\n\t\tif ( isFunction( form.submit ) ) {\n\t\t\toriginalSubmit = form.submit;\n\n\t\t\tform.submit = () => {\n\t\t\t\tonSubmit();\n\t\t\t\toriginalSubmit.apply( form );\n\t\t\t};\n\t\t}\n\n\t\t// Update the replaced textarea with data before each form#submit event.\n\t\tform.addEventListener( 'submit', onSubmit );\n\n\t\t// Remove the submit listener and revert the original submit method on\n\t\t// editor#destroy.\n\t\teditor.on( 'destroy', () => {\n\t\t\tform.removeEventListener( 'submit', onSubmit );\n\n\t\t\tif ( originalSubmit ) {\n\t\t\t\tform.submit = originalSubmit;\n\t\t\t}\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* globals HTMLTextAreaElement */\n\n/**\n * @module utils/dom/getdatafromelement\n */\n\n/**\n * Gets data from a given source element.\n *\n * @param {HTMLElement} el The element from which the data will be retrieved.\n * @returns {String} The data string.\n */\nexport default function getDataFromElement( el ) {\n\tif ( el instanceof HTMLTextAreaElement ) {\n\t\treturn el.value;\n\t}\n\n\treturn el.innerHTML;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* global DOMParser */\n\n/**\n * @module ui/icon/iconview\n */\n\nimport View from '../view';\n\nimport '../../theme/components/icon/icon.css';\n\n/**\n * The icon view class.\n *\n * @extends module:ui/view~View\n */\nexport default class IconView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * The SVG source of the icon.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #content\n\t\t */\n\t\tthis.set( 'content', '' );\n\n\t\t/**\n\t\t * This attribute specifies the boundaries to which the\n\t\t * icon content should stretch.\n\t\t *\n\t\t * @observable\n\t\t * @default '0 0 20 20'\n\t\t * @member {String} #viewBox\n\t\t */\n\t\tthis.set( 'viewBox', '0 0 20 20' );\n\n\t\t/**\n\t\t * The fill color of the child `path.ck-icon__fill`.\n\t\t *\n\t\t * @observable\n\t\t * @default ''\n\t\t * @member {String} #fillColor\n\t\t */\n\t\tthis.set( 'fillColor', '' );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'svg',\n\t\t\tns: 'http://www.w3.org/2000/svg',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-icon'\n\t\t\t\t],\n\t\t\t\tviewBox: bind.to( 'viewBox' )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\tthis._updateXMLContent();\n\t\tthis._colorFillPaths();\n\n\t\t// This is a hack for lack of innerHTML binding.\n\t\t// See: https://github.com/ckeditor/ckeditor5-ui/issues/99.\n\t\tthis.on( 'change:content', () => {\n\t\t\tthis._updateXMLContent();\n\t\t\tthis._colorFillPaths();\n\t\t} );\n\n\t\tthis.on( 'change:fillColor', () => {\n\t\t\tthis._colorFillPaths();\n\t\t} );\n\t}\n\n\t/**\n\t * Updates the {@link #element} with the value of {@link #content}.\n\t *\n\t * @private\n\t */\n\t_updateXMLContent() {\n\t\tif ( this.content ) {\n\t\t\tconst parsed = new DOMParser().parseFromString( this.content.trim(), 'image/svg+xml' );\n\t\t\tconst svg = parsed.querySelector( 'svg' );\n\t\t\tconst viewBox = svg.getAttribute( 'viewBox' );\n\n\t\t\tif ( viewBox ) {\n\t\t\t\tthis.viewBox = viewBox;\n\t\t\t}\n\n\t\t\tthis.element.innerHTML = '';\n\n\t\t\twhile ( svg.childNodes.length > 0 ) {\n\t\t\t\tthis.element.appendChild( svg.childNodes[ 0 ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Fills all child `path.ck-icon__fill` with the `#fillColor`.\n\t *\n\t * @private\n\t */\n\t_colorFillPaths() {\n\t\tif ( this.fillColor ) {\n\t\t\tthis.element.querySelectorAll( '.ck-icon__fill' ).forEach( path => {\n\t\t\t\tpath.style.fill = this.fillColor;\n\t\t\t} );\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/tooltip/tooltipview\n */\n\nimport View from '../view';\n\nimport '../../theme/components/tooltip/tooltip.css';\n\n/**\n * The tooltip view class.\n *\n * @extends module:ui/view~View\n */\nexport default class TooltipView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\t/**\n\t\t * The text of the tooltip visible to the user.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #text\n\t\t */\n\t\tthis.set( 'text', '' );\n\n\t\t/**\n\t\t * The position of the tooltip (south or north).\n\t\t *\n\t\t *\t\t+-----------+\n\t\t *\t\t| north |\n\t\t *\t\t+-----------+\n\t\t *\t\t V\n\t\t *\t\t [element]\n\t\t *\n\t\t *\t\t [element]\n\t\t *\t\t ^\n\t\t *\t\t+-----------+\n\t\t *\t\t| south |\n\t\t *\t\t+-----------+\n\t\t *\n\t\t * @observable\n\t\t * @default 's'\n\t\t * @member {'s'|'n'} #position\n\t\t */\n\t\tthis.set( 'position', 's' );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'span',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-tooltip',\n\t\t\t\t\tbind.to( 'position', position => 'ck-tooltip_' + position ),\n\t\t\t\t\tbind.if( 'text', 'ck-hidden', value => !value.trim() )\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'span',\n\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [\n\t\t\t\t\t\t\t'ck',\n\t\t\t\t\t\t\t'ck-tooltip__text'\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttext: bind.to( 'text' ),\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/button/buttonview\n */\n\nimport View from '../view';\nimport IconView from '../icon/iconview';\nimport TooltipView from '../tooltip/tooltipview';\n\nimport uid from '@ckeditor/ckeditor5-utils/src/uid';\nimport { getEnvKeystrokeText } from '@ckeditor/ckeditor5-utils/src/keyboard';\n\nimport '../../theme/components/button/button.css';\n\n/**\n * The button view class.\n *\n *\t\tconst view = new ButtonView();\n *\n *\t\tview.set( {\n *\t\t\tlabel: 'A button',\n *\t\t\tkeystroke: 'Ctrl+B',\n *\t\t\ttooltip: true,\n *\t\t\twithText: true\n *\t\t} );\n *\n *\t\tview.render();\n *\n *\t\tdocument.body.append( view.element );\n *\n * @extends module:ui/view~View\n * @implements module:ui/button/button~Button\n */\nexport default class ButtonView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\t\tconst ariaLabelUid = uid();\n\n\t\t// Implement the Button interface.\n\t\tthis.set( 'class' );\n\t\tthis.set( 'labelStyle' );\n\t\tthis.set( 'icon' );\n\t\tthis.set( 'isEnabled', true );\n\t\tthis.set( 'isOn', false );\n\t\tthis.set( 'isVisible', true );\n\t\tthis.set( 'keystroke' );\n\t\tthis.set( 'label' );\n\t\tthis.set( 'tabindex', -1 );\n\t\tthis.set( 'tooltip' );\n\t\tthis.set( 'tooltipPosition', 's' );\n\t\tthis.set( 'type', 'button' );\n\t\tthis.set( 'withText', false );\n\n\t\t/**\n\t\t * Collection of the child views inside of the button {@link #element}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.children = this.createCollection();\n\n\t\t/**\n\t\t * Tooltip of the button view. It is configurable using the {@link #tooltip tooltip attribute}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/tooltip/tooltipview~TooltipView} #tooltipView\n\t\t */\n\t\tthis.tooltipView = this._createTooltipView();\n\n\t\t/**\n\t\t * Label of the button view. It is configurable using the {@link #label label attribute}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/view~View} #labelView\n\t\t */\n\t\tthis.labelView = this._createLabelView( ariaLabelUid );\n\n\t\t/**\n\t\t * The icon view of the button. Will be added to {@link #children} when the\n\t\t * {@link #icon icon attribute} is defined.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/icon/iconview~IconView} #iconView\n\t\t */\n\t\tthis.iconView = new IconView();\n\n\t\tthis.iconView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-button__icon'\n\t\t\t}\n\t\t} );\n\n\t\t/**\n\t\t * Tooltip of the button bound to the template.\n\t\t *\n\t\t * @see #tooltip\n\t\t * @see #_getTooltipString\n\t\t * @private\n\t\t * @observable\n\t\t * @member {Boolean} #_tooltipString\n\t\t */\n\t\tthis.bind( '_tooltipString' ).to(\n\t\t\tthis, 'tooltip',\n\t\t\tthis, 'label',\n\t\t\tthis, 'keystroke',\n\t\t\tthis._getTooltipString.bind( this )\n\t\t);\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'button',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-button',\n\t\t\t\t\tbind.to( 'class' ),\n\t\t\t\t\tbind.if( 'isEnabled', 'ck-disabled', value => !value ),\n\t\t\t\t\tbind.if( 'isVisible', 'ck-hidden', value => !value ),\n\t\t\t\t\tbind.to( 'isOn', value => value ? 'ck-on' : 'ck-off' ),\n\t\t\t\t\tbind.if( 'withText', 'ck-button_with-text' )\n\t\t\t\t],\n\t\t\t\ttype: bind.to( 'type', value => value ? value : 'button' ),\n\t\t\t\ttabindex: bind.to( 'tabindex' ),\n\t\t\t\t'aria-labelledby': `ck-editor__aria-label_${ ariaLabelUid }`,\n\t\t\t\t'aria-disabled': bind.if( 'isEnabled', true, value => !value ),\n\t\t\t\t'aria-pressed': bind.if( 'isOn', true )\n\t\t\t},\n\n\t\t\tchildren: this.children,\n\n\t\t\ton: {\n\t\t\t\tmousedown: bind.to( evt => {\n\t\t\t\t\tevt.preventDefault();\n\t\t\t\t} ),\n\n\t\t\t\tclick: bind.to( evt => {\n\t\t\t\t\t// We can't make the button disabled using the disabled attribute, because it won't be focusable.\n\t\t\t\t\t// Though, shouldn't this condition be moved to the button controller?\n\t\t\t\t\tif ( this.isEnabled ) {\n\t\t\t\t\t\tthis.fire( 'execute' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Prevent the default when button is disabled, to block e.g.\n\t\t\t\t\t\t// automatic form submitting. See ckeditor/ckeditor5-link#74.\n\t\t\t\t\t\tevt.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t} )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\tif ( this.icon ) {\n\t\t\tthis.iconView.bind( 'content' ).to( this, 'icon' );\n\t\t\tthis.children.add( this.iconView );\n\t\t}\n\n\t\tthis.children.add( this.tooltipView );\n\t\tthis.children.add( this.labelView );\n\t}\n\n\t/**\n\t * Focuses the {@link #element} of the button.\n\t */\n\tfocus() {\n\t\tthis.element.focus();\n\t}\n\n\t/**\n\t * Creates a {@link module:ui/tooltip/tooltipview~TooltipView} instance and binds it with button\n\t * attributes.\n\t *\n\t * @private\n\t * @returns {module:ui/tooltip/tooltipview~TooltipView}\n\t */\n\t_createTooltipView() {\n\t\tconst tooltipView = new TooltipView();\n\n\t\ttooltipView.bind( 'text' ).to( this, '_tooltipString' );\n\t\ttooltipView.bind( 'position' ).to( this, 'tooltipPosition' );\n\n\t\treturn tooltipView;\n\t}\n\n\t/**\n\t * Creates a label view instance and binds it with button attributes.\n\t *\n\t * @private\n\t * @param {String} ariaLabelUid The aria label UID.\n\t * @returns {module:ui/view~View}\n\t */\n\t_createLabelView( ariaLabelUid ) {\n\t\tconst labelView = new View();\n\t\tconst bind = this.bindTemplate;\n\n\t\tlabelView.setTemplate( {\n\t\t\ttag: 'span',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-button__label'\n\t\t\t\t],\n\t\t\t\tstyle: bind.to( 'labelStyle' ),\n\t\t\t\tid: `ck-editor__aria-label_${ ariaLabelUid }`,\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttext: this.bindTemplate.to( 'label' )\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\n\t\treturn labelView;\n\t}\n\n\t/**\n\t * Gets the text for the {@link #tooltipView} from the combination of\n\t * {@link #tooltip}, {@link #label} and {@link #keystroke} attributes.\n\t *\n\t * @private\n\t * @see #tooltip\n\t * @see #_tooltipString\n\t * @param {Boolean|String|Function} tooltip Button tooltip.\n\t * @param {String} label Button label.\n\t * @param {String} keystroke Button keystroke.\n\t * @returns {String}\n\t */\n\t_getTooltipString( tooltip, label, keystroke ) {\n\t\tif ( tooltip ) {\n\t\t\tif ( typeof tooltip == 'string' ) {\n\t\t\t\treturn tooltip;\n\t\t\t} else {\n\t\t\t\tif ( keystroke ) {\n\t\t\t\t\tkeystroke = getEnvKeystrokeText( keystroke );\n\t\t\t\t}\n\n\t\t\t\tif ( tooltip instanceof Function ) {\n\t\t\t\t\treturn tooltip( label, keystroke );\n\t\t\t\t} else {\n\t\t\t\t\treturn `${ label }${ keystroke ? ` (${ keystroke })` : '' }`;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn '';\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/spy\n */\n\n/**\n * Creates a spy function (ala Sinon.js) that can be used to inspect call to it.\n *\n * The following are the present features:\n *\n * * spy.called: property set to `true` if the function has been called at least once.\n *\n * @returns {Function} The spy function.\n */\nfunction spy() {\n\treturn function spy() {\n\t\tspy.called = true;\n\t};\n}\n\nexport default spy;\n","/**\n * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/eventinfo\n */\n\nimport spy from './spy';\n\n/**\n * The event object passed to event callbacks. It is used to provide information about the event as well as a tool to\n * manipulate it.\n */\nexport default class EventInfo {\n\t/**\n\t * @param {Object} source The emitter.\n\t * @param {String} name The event name.\n\t */\n\tconstructor( source, name ) {\n\t\t/**\n\t\t * The object that fired the event.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Object}\n\t\t */\n\t\tthis.source = source;\n\n\t\t/**\n\t\t * The event name.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.name = name;\n\n\t\t/**\n\t\t * Path this event has followed. See {@link module:utils/emittermixin~EmitterMixin#delegate}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Array.<Object>}\n\t\t */\n\t\tthis.path = [];\n\n\t\t// The following methods are defined in the constructor because they must be re-created per instance.\n\n\t\t/**\n\t\t * Stops the event emitter to call further callbacks for this event interaction.\n\t\t *\n\t\t * @method #stop\n\t\t */\n\t\tthis.stop = spy();\n\n\t\t/**\n\t\t * Removes the current callback from future interactions of this event.\n\t\t *\n\t\t * @method #off\n\t\t */\n\t\tthis.off = spy();\n\n\t\t/**\n\t\t * The value which will be returned by {@link module:utils/emittermixin~EmitterMixin#fire}.\n\t\t *\n\t\t * It's `undefined` by default and can be changed by an event listener:\n\t\t *\n\t\t *\t\tdataController.fire( 'getSelectedContent', ( evt ) => {\n\t\t *\t\t\t// This listener will make `dataController.fire( 'getSelectedContent' )`\n\t\t *\t\t\t// always return an empty DocumentFragment.\n\t\t *\t\t\tevt.return = new DocumentFragment();\n\t\t *\n\t\t *\t\t\t// Make sure no other listeners are executed.\n\t\t *\t\t\tevt.stop();\n\t\t *\t\t} );\n\t\t *\n\t\t * @member #return\n\t\t */\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/priorities\n */\n\n/**\n * String representing a priority value.\n *\n * @typedef {'highest'|'high'|'normal'|'low'|'lowest'} module:utils/priorities~PriorityString\n */\n\n/**\n * Provides group of constants to use instead of hardcoding numeric priority values.\n *\n * @namespace\n */\nconst priorities = {\n\t/**\n\t * Converts a string with priority name to it's numeric value. If `Number` is given, it just returns it.\n\t *\n\t * @static\n\t * @param {module:utils/priorities~PriorityString|Number} priority Priority to convert.\n\t * @returns {Number} Converted priority.\n\t */\n\tget( priority ) {\n\t\tif ( typeof priority != 'number' ) {\n\t\t\treturn this[ priority ] || this.normal;\n\t\t} else {\n\t\t\treturn priority;\n\t\t}\n\t},\n\n\thighest: 100000,\n\thigh: 1000,\n\tnormal: 0,\n\tlow: -1000,\n\tlowest: -100000\n};\n\nexport default priorities;\n","/**\n * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/emittermixin\n */\n\nimport EventInfo from './eventinfo';\nimport uid from './uid';\nimport priorities from './priorities';\n\nconst _listeningTo = Symbol( 'listeningTo' );\nconst _emitterId = Symbol( 'emitterId' );\n\n/**\n * Mixin that injects the {@link ~Emitter events API} into its host.\n *\n * @mixin EmitterMixin\n * @implements module:utils/emittermixin~Emitter\n */\nconst EmitterMixin = {\n\t/**\n\t * @inheritDoc\n\t */\n\ton( event, callback, options = {} ) {\n\t\tthis.listenTo( this, event, callback, options );\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tonce( event, callback, options ) {\n\t\tconst onceCallback = function( event, ...args ) {\n\t\t\t// Go off() at the first call.\n\t\t\tevent.off();\n\n\t\t\t// Go with the original callback.\n\t\t\tcallback.call( this, event, ...args );\n\t\t};\n\n\t\t// Make a similar on() call, simply replacing the callback.\n\t\tthis.listenTo( this, event, onceCallback, options );\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\toff( event, callback ) {\n\t\tthis.stopListening( this, event, callback );\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tlistenTo( emitter, event, callback, options = {} ) {\n\t\tlet emitterInfo, eventCallbacks;\n\n\t\t// _listeningTo contains a list of emitters that this object is listening to.\n\t\t// This list has the following format:\n\t\t//\n\t\t// _listeningTo: {\n\t\t// emitterId: {\n\t\t// emitter: emitter,\n\t\t// callbacks: {\n\t\t// event1: [ callback1, callback2, ... ]\n\t\t// ....\n\t\t// }\n\t\t// },\n\t\t// ...\n\t\t// }\n\n\t\tif ( !this[ _listeningTo ] ) {\n\t\t\tthis[ _listeningTo ] = {};\n\t\t}\n\n\t\tconst emitters = this[ _listeningTo ];\n\n\t\tif ( !_getEmitterId( emitter ) ) {\n\t\t\t_setEmitterId( emitter );\n\t\t}\n\n\t\tconst emitterId = _getEmitterId( emitter );\n\n\t\tif ( !( emitterInfo = emitters[ emitterId ] ) ) {\n\t\t\temitterInfo = emitters[ emitterId ] = {\n\t\t\t\temitter,\n\t\t\t\tcallbacks: {}\n\t\t\t};\n\t\t}\n\n\t\tif ( !( eventCallbacks = emitterInfo.callbacks[ event ] ) ) {\n\t\t\teventCallbacks = emitterInfo.callbacks[ event ] = [];\n\t\t}\n\n\t\teventCallbacks.push( callback );\n\n\t\t// Finally register the callback to the event.\n\t\tcreateEventNamespace( emitter, event );\n\t\tconst lists = getCallbacksListsForNamespace( emitter, event );\n\t\tconst priority = priorities.get( options.priority );\n\n\t\tconst callbackDefinition = {\n\t\t\tcallback,\n\t\t\tpriority\n\t\t};\n\n\t\t// Add the callback to all callbacks list.\n\t\tfor ( const callbacks of lists ) {\n\t\t\t// Add the callback to the list in the right priority position.\n\t\t\tlet added = false;\n\n\t\t\tfor ( let i = 0; i < callbacks.length; i++ ) {\n\t\t\t\tif ( callbacks[ i ].priority < priority ) {\n\t\t\t\t\tcallbacks.splice( i, 0, callbackDefinition );\n\t\t\t\t\tadded = true;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add at the end, if right place was not found.\n\t\t\tif ( !added ) {\n\t\t\t\tcallbacks.push( callbackDefinition );\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstopListening( emitter, event, callback ) {\n\t\tconst emitters = this[ _listeningTo ];\n\t\tlet emitterId = emitter && _getEmitterId( emitter );\n\t\tconst emitterInfo = emitters && emitterId && emitters[ emitterId ];\n\t\tconst eventCallbacks = emitterInfo && event && emitterInfo.callbacks[ event ];\n\n\t\t// Stop if nothing has been listened.\n\t\tif ( !emitters || ( emitter && !emitterInfo ) || ( event && !eventCallbacks ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// All params provided. off() that single callback.\n\t\tif ( callback ) {\n\t\t\tremoveCallback( emitter, event, callback );\n\t\t}\n\t\t// Only `emitter` and `event` provided. off() all callbacks for that event.\n\t\telse if ( eventCallbacks ) {\n\t\t\twhile ( ( callback = eventCallbacks.pop() ) ) {\n\t\t\t\tremoveCallback( emitter, event, callback );\n\t\t\t}\n\n\t\t\tdelete emitterInfo.callbacks[ event ];\n\t\t}\n\t\t// Only `emitter` provided. off() all events for that emitter.\n\t\telse if ( emitterInfo ) {\n\t\t\tfor ( event in emitterInfo.callbacks ) {\n\t\t\t\tthis.stopListening( emitter, event );\n\t\t\t}\n\t\t\tdelete emitters[ emitterId ];\n\t\t}\n\t\t// No params provided. off() all emitters.\n\t\telse {\n\t\t\tfor ( emitterId in emitters ) {\n\t\t\t\tthis.stopListening( emitters[ emitterId ].emitter );\n\t\t\t}\n\t\t\tdelete this[ _listeningTo ];\n\t\t}\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tfire( eventOrInfo, ...args ) {\n\t\tconst eventInfo = eventOrInfo instanceof EventInfo ? eventOrInfo : new EventInfo( this, eventOrInfo );\n\t\tconst event = eventInfo.name;\n\t\tlet callbacks = getCallbacksForEvent( this, event );\n\n\t\t// Record that the event passed this emitter on its path.\n\t\teventInfo.path.push( this );\n\n\t\t// Handle event listener callbacks first.\n\t\tif ( callbacks ) {\n\t\t\t// Arguments passed to each callback.\n\t\t\tconst callbackArgs = [ eventInfo, ...args ];\n\n\t\t\t// Copying callbacks array is the easiest and most secure way of preventing infinite loops, when event callbacks\n\t\t\t// are added while processing other callbacks. Previous solution involved adding counters (unique ids) but\n\t\t\t// failed if callbacks were added to the queue before currently processed callback.\n\t\t\t// If this proves to be too inefficient, another method is to change `.on()` so callbacks are stored if same\n\t\t\t// event is currently processed. Then, `.fire()` at the end, would have to add all stored events.\n\t\t\tcallbacks = Array.from( callbacks );\n\n\t\t\tfor ( let i = 0; i < callbacks.length; i++ ) {\n\t\t\t\tcallbacks[ i ].callback.apply( this, callbackArgs );\n\n\t\t\t\t// Remove the callback from future requests if off() has been called.\n\t\t\t\tif ( eventInfo.off.called ) {\n\t\t\t\t\t// Remove the called mark for the next calls.\n\t\t\t\t\tdelete eventInfo.off.called;\n\n\t\t\t\t\tremoveCallback( this, event, callbacks[ i ].callback );\n\t\t\t\t}\n\n\t\t\t\t// Do not execute next callbacks if stop() was called.\n\t\t\t\tif ( eventInfo.stop.called ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Delegate event to other emitters if needed.\n\t\tif ( this._delegations ) {\n\t\t\tconst destinations = this._delegations.get( event );\n\t\t\tconst passAllDestinations = this._delegations.get( '*' );\n\n\t\t\tif ( destinations ) {\n\t\t\t\tfireDelegatedEvents( destinations, eventInfo, args );\n\t\t\t}\n\n\t\t\tif ( passAllDestinations ) {\n\t\t\t\tfireDelegatedEvents( passAllDestinations, eventInfo, args );\n\t\t\t}\n\t\t}\n\n\t\treturn eventInfo.return;\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdelegate( ...events ) {\n\t\treturn {\n\t\t\tto: ( emitter, nameOrFunction ) => {\n\t\t\t\tif ( !this._delegations ) {\n\t\t\t\t\tthis._delegations = new Map();\n\t\t\t\t}\n\n\t\t\t\tfor ( const eventName of events ) {\n\t\t\t\t\tconst destinations = this._delegations.get( eventName );\n\n\t\t\t\t\tif ( !destinations ) {\n\t\t\t\t\t\tthis._delegations.set( eventName, new Map( [ [ emitter, nameOrFunction ] ] ) );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdestinations.set( emitter, nameOrFunction );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstopDelegating( event, emitter ) {\n\t\tif ( !this._delegations ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !event ) {\n\t\t\tthis._delegations.clear();\n\t\t} else if ( !emitter ) {\n\t\t\tthis._delegations.delete( event );\n\t\t} else {\n\t\t\tconst destinations = this._delegations.get( event );\n\n\t\t\tif ( destinations ) {\n\t\t\t\tdestinations.delete( emitter );\n\t\t\t}\n\t\t}\n\t}\n};\n\nexport default EmitterMixin;\n\n/**\n * Emitter/listener interface.\n *\n * Can be easily implemented by a class by mixing the {@link module:utils/emittermixin~EmitterMixin} mixin.\n *\n * @interface Emitter\n */\n\n/**\n * Registers a callback function to be executed when an event is fired.\n *\n * Shorthand for {@link #listenTo `this.listenTo( this, event, callback, options )`} (it makes the emitter\n * listen on itself).\n *\n * @method #on\n * @param {String} event The name of the event.\n * @param {Function} callback The function to be called on event.\n * @param {Object} [options={}] Additional options.\n * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of this event callback. The higher\n * the priority value the sooner the callback will be fired. Events having the same priority are called in the\n * order they were added.\n */\n\n/**\n * Registers a callback function to be executed on the next time the event is fired only. This is similar to\n * calling {@link #on} followed by {@link #off} in the callback.\n *\n * @method #once\n * @param {String} event The name of the event.\n * @param {Function} callback The function to be called on event.\n * @param {Object} [options={}] Additional options.\n * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of this event callback. The higher\n * the priority value the sooner the callback will be fired. Events having the same priority are called in the\n * order they were added.\n */\n\n/**\n * Stops executing the callback on the given event.\n * Shorthand for {@link #stopListening `this.stopListening( this, event, callback )`}.\n *\n * @method #off\n * @param {String} event The name of the event.\n * @param {Function} callback The function to stop being called.\n */\n\n/**\n * Registers a callback function to be executed when an event is fired in a specific (emitter) object.\n *\n * Events can be grouped in namespaces using `:`.\n * When namespaced event is fired, it additionally fires all callbacks for that namespace.\n *\n *\t\t// myEmitter.on( ... ) is a shorthand for myEmitter.listenTo( myEmitter, ... ).\n *\t\tmyEmitter.on( 'myGroup', genericCallback );\n *\t\tmyEmitter.on( 'myGroup:myEvent', specificCallback );\n *\n *\t\t// genericCallback is fired.\n *\t\tmyEmitter.fire( 'myGroup' );\n *\t\t// both genericCallback and specificCallback are fired.\n *\t\tmyEmitter.fire( 'myGroup:myEvent' );\n *\t\t// genericCallback is fired even though there are no callbacks for \"foo\".\n *\t\tmyEmitter.fire( 'myGroup:foo' );\n *\n * An event callback can {@link module:utils/eventinfo~EventInfo#stop stop the event} and\n * set the {@link module:utils/eventinfo~EventInfo#return return value} of the {@link #fire} method.\n *\n * @method #listenTo\n * @param {module:utils/emittermixin~Emitter} emitter The object that fires the event.\n * @param {String} event The name of the event.\n * @param {Function} callback The function to be called on event.\n * @param {Object} [options={}] Additional options.\n * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of this event callback. The higher\n * the priority value the sooner the callback will be fired. Events having the same priority are called in the\n * order they were added.\n */\n\n/**\n * Stops listening for events. It can be used at different levels:\n *\n * * To stop listening to a specific callback.\n * * To stop listening to a specific event.\n * * To stop listening to all events fired by a specific object.\n * * To stop listening to all events fired by all objects.\n *\n * @method #stopListening\n * @param {module:utils/emittermixin~Emitter} [emitter] The object to stop listening to. If omitted, stops it for all objects.\n * @param {String} [event] (Requires the `emitter`) The name of the event to stop listening to. If omitted, stops it\n * for all events from `emitter`.\n * @param {Function} [callback] (Requires the `event`) The function to be removed from the call list for the given\n * `event`.\n */\n\n/**\n * Fires an event, executing all callbacks registered for it.\n *\n * The first parameter passed to callbacks is an {@link module:utils/eventinfo~EventInfo} object,\n * followed by the optional `args` provided in the `fire()` method call.\n *\n * @method #fire\n * @param {String|module:utils/eventinfo~EventInfo} eventOrInfo The name of the event or `EventInfo` object if event is delegated.\n * @param {...*} [args] Additional arguments to be passed to the callbacks.\n * @returns {*} By default the method returns `undefined`. However, the return value can be changed by listeners\n * through modification of the {@link module:utils/eventinfo~EventInfo#return `evt.return`}'s property (the event info\n * is the first param of every callback).\n */\n\n/**\n * Delegates selected events to another {@link module:utils/emittermixin~Emitter}. For instance:\n *\n *\t\temitterA.delegate( 'eventX' ).to( emitterB );\n *\t\temitterA.delegate( 'eventX', 'eventY' ).to( emitterC );\n *\n * then `eventX` is delegated (fired by) `emitterB` and `emitterC` along with `data`:\n *\n *\t\temitterA.fire( 'eventX', data );\n *\n * and `eventY` is delegated (fired by) `emitterC` along with `data`:\n *\n *\t\temitterA.fire( 'eventY', data );\n *\n * @method #delegate\n * @param {...String} events Event names that will be delegated to another emitter.\n * @returns {module:utils/emittermixin~EmitterMixinDelegateChain}\n */\n\n/**\n * Stops delegating events. It can be used at different levels:\n *\n * * To stop delegating all events.\n * * To stop delegating a specific event to all emitters.\n * * To stop delegating a specific event to a specific emitter.\n *\n * @method #stopDelegating\n * @param {String} [event] The name of the event to stop delegating. If omitted, stops it all delegations.\n * @param {module:utils/emittermixin~Emitter} [emitter] (requires `event`) The object to stop delegating a particular event to.\n * If omitted, stops delegation of `event` to all emitters.\n */\n\n/**\n * Checks if `listeningEmitter` listens to an emitter with given `listenedToEmitterId` and if so, returns that emitter.\n * If not, returns `null`.\n *\n * @protected\n * @param {module:utils/emittermixin~EmitterMixin} listeningEmitter Emitter that listens.\n * @param {String} listenedToEmitterId Unique emitter id of emitter listened to.\n * @returns {module:utils/emittermixin~EmitterMixin|null}\n */\nexport function _getEmitterListenedTo( listeningEmitter, listenedToEmitterId ) {\n\tif ( listeningEmitter[ _listeningTo ] && listeningEmitter[ _listeningTo ][ listenedToEmitterId ] ) {\n\t\treturn listeningEmitter[ _listeningTo ][ listenedToEmitterId ].emitter;\n\t}\n\n\treturn null;\n}\n\n/**\n * Sets emitter's unique id.\n *\n * **Note:** `_emitterId` can be set only once.\n *\n * @protected\n * @param {module:utils/emittermixin~EmitterMixin} emitter Emitter for which id will be set.\n * @param {String} [id] Unique id to set. If not passed, random unique id will be set.\n */\nexport function _setEmitterId( emitter, id ) {\n\tif ( !emitter[ _emitterId ] ) {\n\t\temitter[ _emitterId ] = id || uid();\n\t}\n}\n\n/**\n * Returns emitter's unique id.\n *\n * @protected\n * @param {module:utils/emittermixin~EmitterMixin} emitter Emitter which id will be returned.\n */\nexport function _getEmitterId( emitter ) {\n\treturn emitter[ _emitterId ];\n}\n\n// Gets the internal `_events` property of the given object.\n// `_events` property store all lists with callbacks for registered event names.\n// If there were no events registered on the object, empty `_events` object is created.\nfunction getEvents( source ) {\n\tif ( !source._events ) {\n\t\tObject.defineProperty( source, '_events', {\n\t\t\tvalue: {}\n\t\t} );\n\t}\n\n\treturn source._events;\n}\n\n// Creates event node for generic-specific events relation architecture.\nfunction makeEventNode() {\n\treturn {\n\t\tcallbacks: [],\n\t\tchildEvents: []\n\t};\n}\n\n// Creates an architecture for generic-specific events relation.\n// If needed, creates all events for given eventName, i.e. if the first registered event\n// is foo:bar:abc, it will create foo:bar:abc, foo:bar and foo event and tie them together.\n// It also copies callbacks from more generic events to more specific events when\n// specific events are created.\nfunction createEventNamespace( source, eventName ) {\n\tconst events = getEvents( source );\n\n\t// First, check if the event we want to add to the structure already exists.\n\tif ( events[ eventName ] ) {\n\t\t// If it exists, we don't have to do anything.\n\t\treturn;\n\t}\n\n\t// In other case, we have to create the structure for the event.\n\t// Note, that we might need to create intermediate events too.\n\t// I.e. if foo:bar:abc is being registered and we only have foo in the structure,\n\t// we need to also register foo:bar.\n\n\t// Currently processed event name.\n\tlet name = eventName;\n\t// Name of the event that is a child event for currently processed event.\n\tlet childEventName = null;\n\n\t// Array containing all newly created specific events.\n\tconst newEventNodes = [];\n\n\t// While loop can't check for ':' index because we have to handle generic events too.\n\t// In each loop, we truncate event name, going from the most specific name to the generic one.\n\t// I.e. foo:bar:abc -> foo:bar -> foo.\n\twhile ( name !== '' ) {\n\t\tif ( events[ name ] ) {\n\t\t\t// If the currently processed event name is already registered, we can be sure\n\t\t\t// that it already has all the structure created, so we can break the loop here\n\t\t\t// as no more events need to be registered.\n\t\t\tbreak;\n\t\t}\n\n\t\t// If this event is not yet registered, create a new object for it.\n\t\tevents[ name ] = makeEventNode();\n\t\t// Add it to the array with newly created events.\n\t\tnewEventNodes.push( events[ name ] );\n\n\t\t// Add previously processed event name as a child of this event.\n\t\tif ( childEventName ) {\n\t\t\tevents[ name ].childEvents.push( childEventName );\n\t\t}\n\n\t\tchildEventName = name;\n\t\t// If `.lastIndexOf()` returns -1, `.substr()` will return '' which will break the loop.\n\t\tname = name.substr( 0, name.lastIndexOf( ':' ) );\n\t}\n\n\tif ( name !== '' ) {\n\t\t// If name is not empty, we found an already registered event that was a parent of the\n\t\t// event we wanted to register.\n\n\t\t// Copy that event's callbacks to newly registered events.\n\t\tfor ( const node of newEventNodes ) {\n\t\t\tnode.callbacks = events[ name ].callbacks.slice();\n\t\t}\n\n\t\t// Add last newly created event to the already registered event.\n\t\tevents[ name ].childEvents.push( childEventName );\n\t}\n}\n\n// Gets an array containing callbacks list for a given event and it's more specific events.\n// I.e. if given event is foo:bar and there is also foo:bar:abc event registered, this will\n// return callback list of foo:bar and foo:bar:abc (but not foo).\nfunction getCallbacksListsForNamespace( source, eventName ) {\n\tconst eventNode = getEvents( source )[ eventName ];\n\n\tif ( !eventNode ) {\n\t\treturn [];\n\t}\n\n\tlet callbacksLists = [ eventNode.callbacks ];\n\n\tfor ( let i = 0; i < eventNode.childEvents.length; i++ ) {\n\t\tconst childCallbacksLists = getCallbacksListsForNamespace( source, eventNode.childEvents[ i ] );\n\n\t\tcallbacksLists = callbacksLists.concat( childCallbacksLists );\n\t}\n\n\treturn callbacksLists;\n}\n\n// Get the list of callbacks for a given event, but only if there any callbacks have been registered.\n// If there are no callbacks registered for given event, it checks if this is a specific event and looks\n// for callbacks for it's more generic version.\nfunction getCallbacksForEvent( source, eventName ) {\n\tlet event;\n\n\tif ( !source._events || !( event = source._events[ eventName ] ) || !event.callbacks.length ) {\n\t\t// There are no callbacks registered for specified eventName.\n\t\t// But this could be a specific-type event that is in a namespace.\n\t\tif ( eventName.indexOf( ':' ) > -1 ) {\n\t\t\t// If the eventName is specific, try to find callback lists for more generic event.\n\t\t\treturn getCallbacksForEvent( source, eventName.substr( 0, eventName.lastIndexOf( ':' ) ) );\n\t\t} else {\n\t\t\t// If this is a top-level generic event, return null;\n\t\t\treturn null;\n\t\t}\n\t}\n\n\treturn event.callbacks;\n}\n\n// Fires delegated events for given map of destinations.\n//\n// @private\n// * @param {Map.<utils.Emitter>} destinations A map containing `[ {@link utils.Emitter}, \"event name\" ]` pair destinations.\n// * @param {utils.EventInfo} eventInfo The original event info object.\n// * @param {Array.<*>} fireArgs Arguments the original event was fired with.\nfunction fireDelegatedEvents( destinations, eventInfo, fireArgs ) {\n\tfor ( let [ emitter, name ] of destinations ) {\n\t\tif ( !name ) {\n\t\t\tname = eventInfo.name;\n\t\t} else if ( typeof name == 'function' ) {\n\t\t\tname = name( eventInfo.name );\n\t\t}\n\n\t\tconst delegatedInfo = new EventInfo( eventInfo.source, name );\n\n\t\tdelegatedInfo.path = [ ...eventInfo.path ];\n\n\t\temitter.fire( delegatedInfo, ...fireArgs );\n\t}\n}\n\n// Removes callback from emitter for given event.\n//\n// @param {module:utils/emittermixin~Emitter} emitter\n// @param {String} event\n// @param {Function} callback\nfunction removeCallback( emitter, event, callback ) {\n\tconst lists = getCallbacksListsForNamespace( emitter, event );\n\n\tfor ( const callbacks of lists ) {\n\t\tfor ( let i = 0; i < callbacks.length; i++ ) {\n\t\t\tif ( callbacks[ i ].callback == callback ) {\n\t\t\t\t// Remove the callback from the list (fixing the next index).\n\t\t\t\tcallbacks.splice( i, 1 );\n\t\t\t\ti--;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * The return value of {@link ~EmitterMixin#delegate}.\n *\n * @interface module:utils/emittermixin~EmitterMixinDelegateChain\n */\n\n/**\n * Selects destination for {@link module:utils/emittermixin~EmitterMixin#delegate} events.\n *\n * @method #to\n * @param {module:utils/emittermixin~Emitter} emitter An `EmitterMixin` instance which is the destination for delegated events.\n * @param {String|Function} [nameOrFunction] A custom event name or function which converts the original name string.\n */\n","/**\n * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/uid\n */\n\n/**\n * Returns a unique id. This id consist of an 'e' character and a randomly generated string of 32 aphanumeric characters.\n * Each character in uid string represents a hexadecimal digit (base 16).\n *\n * @returns {String} A hexadecimal number representing the id.\n */\nexport default function uid() {\n\tlet uuid = 'e'; // Make sure that id does not start with number.\n\n\tfor ( let i = 0; i < 8; i++ ) {\n\t\tuuid += Math.floor( ( 1 + Math.random() ) * 0x10000 ).toString( 16 ).substring( 1 );\n\t}\n\n\treturn uuid;\n}\n","/**\n * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/ckeditorerror\n */\n\n/**\n * URL to the documentation with error codes.\n */\nexport const DOCUMENTATION_URL =\n\t'https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/error-codes.html';\n\n/**\n * The CKEditor error class.\n *\n * All errors will be shortened during the minification process in order to reduce the code size.\n * Therefore, all error messages should be documented in the same way as those in {@link module:utils/log}.\n *\n * Read more in the {@link module:utils/log} module.\n *\n * @extends Error\n */\nexport default class CKEditorError extends Error {\n\t/**\n\t * Creates an instance of the CKEditorError class.\n\t *\n\t * Read more about error logging in the {@link module:utils/log} module.\n\t *\n\t * @param {String} message The error message in an `error-name: Error message.` format.\n\t * During the minification process the \"Error message\" part will be removed to limit the code size\n\t * and a link to this error documentation will be added to the `message`.\n\t * @param {Object} [data] Additional data describing the error. A stringified version of this object\n\t * will be appended to the error message, so the data are quickly visible in the console. The original\n\t * data object will also be later available under the {@link #data} property.\n\t */\n\tconstructor( message, data ) {\n\t\tmessage = attachLinkToDocumentation( message );\n\n\t\tif ( data ) {\n\t\t\tmessage += ' ' + JSON.stringify( data );\n\t\t}\n\n\t\tsuper( message );\n\n\t\t/**\n\t\t * @member {String}\n\t\t */\n\t\tthis.name = 'CKEditorError';\n\n\t\t/**\n\t\t * The additional error data passed to the constructor. Undefined if none was passed.\n\t\t *\n\t\t * @member {Object|undefined}\n\t\t */\n\t\tthis.data = data;\n\t}\n\n\t/**\n\t * Checks if error is an instance of CKEditorError class.\n\t *\n\t * @param {Object} error Object to check.\n\t * @returns {Boolean}\n\t */\n\tstatic isCKEditorError( error ) {\n\t\treturn error instanceof CKEditorError;\n\t}\n}\n\n/**\n * Attaches link to the documentation at the end of the error message.\n *\n * @param {String} message Message to be logged.\n * @returns {String}\n */\nexport function attachLinkToDocumentation( message ) {\n\tconst matchedErrorName = message.match( /^([^:]+):/ );\n\n\tif ( !matchedErrorName ) {\n\t\treturn message;\n\t}\n\n\treturn message + ` Read more: ${ DOCUMENTATION_URL }#error-${ matchedErrorName[ 1 ] }\\n`;\n}\n","/**\n * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/observablemixin\n */\n\nimport EmitterMixin from './emittermixin';\nimport CKEditorError from './ckeditorerror';\nimport { extend, isObject } from 'lodash-es';\n\nconst observablePropertiesSymbol = Symbol( 'observableProperties' );\nconst boundObservablesSymbol = Symbol( 'boundObservables' );\nconst boundPropertiesSymbol = Symbol( 'boundProperties' );\n\n/**\n * Mixin that injects the \"observable properties\" and data binding functionality described in the\n * {@link ~Observable} interface.\n *\n * Read more about the concept of observables in the:\n * * {@glink framework/guides/architecture/core-editor-architecture#event-system-and-observables \"Event system and observables\"}\n * section of the {@glink framework/guides/architecture/core-editor-architecture \"Core editor architecture\"} guide,\n * * {@glink framework/guides/deep-dive/observables \"Observables\" deep dive} guide.\n *\n * @mixin ObservableMixin\n * @mixes module:utils/emittermixin~EmitterMixin\n * @implements module:utils/observablemixin~Observable\n */\nconst ObservableMixin = {\n\t/**\n\t * @inheritDoc\n\t */\n\tset( name, value ) {\n\t\t// If the first parameter is an Object, iterate over its properties.\n\t\tif ( isObject( name ) ) {\n\t\t\tObject.keys( name ).forEach( property => {\n\t\t\t\tthis.set( property, name[ property ] );\n\t\t\t}, this );\n\n\t\t\treturn;\n\t\t}\n\n\t\tinitObservable( this );\n\n\t\tconst properties = this[ observablePropertiesSymbol ];\n\n\t\tif ( ( name in this ) && !properties.has( name ) ) {\n\t\t\t/**\n\t\t\t * Cannot override an existing property.\n\t\t\t *\n\t\t\t * This error is thrown when trying to {@link ~Observable#set set} an property with\n\t\t\t * a name of an already existing property. For example:\n\t\t\t *\n\t\t\t *\t\tlet observable = new Model();\n\t\t\t *\t\tobservable.property = 1;\n\t\t\t *\t\tobservable.set( 'property', 2 );\t\t\t// throws\n\t\t\t *\n\t\t\t *\t\tobservable.set( 'property', 1 );\n\t\t\t *\t\tobservable.set( 'property', 2 );\t\t\t// ok, because this is an existing property.\n\t\t\t *\n\t\t\t * @error observable-set-cannot-override\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'observable-set-cannot-override: Cannot override an existing property.' );\n\t\t}\n\n\t\tObject.defineProperty( this, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget() {\n\t\t\t\treturn properties.get( name );\n\t\t\t},\n\n\t\t\tset( value ) {\n\t\t\t\tconst oldValue = properties.get( name );\n\n\t\t\t\t// Fire `set` event before the new value will be set to make it possible\n\t\t\t\t// to override observable property without affecting `change` event.\n\t\t\t\t// See https://github.com/ckeditor/ckeditor5-utils/issues/171.\n\t\t\t\tlet newValue = this.fire( 'set:' + name, name, value, oldValue );\n\n\t\t\t\tif ( newValue === undefined ) {\n\t\t\t\t\tnewValue = value;\n\t\t\t\t}\n\n\t\t\t\t// Allow undefined as an initial value like A.define( 'x', undefined ) (#132).\n\t\t\t\t// Note: When properties map has no such own property, then its value is undefined.\n\t\t\t\tif ( oldValue !== newValue || !properties.has( name ) ) {\n\t\t\t\t\tproperties.set( name, newValue );\n\t\t\t\t\tthis.fire( 'change:' + name, name, newValue, oldValue );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\tthis[ name ] = value;\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tbind( ...bindProperties ) {\n\t\tif ( !bindProperties.length || !isStringArray( bindProperties ) ) {\n\t\t\t/**\n\t\t\t * All properties must be strings.\n\t\t\t *\n\t\t\t * @error observable-bind-wrong-properties\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'observable-bind-wrong-properties: All properties must be strings.' );\n\t\t}\n\n\t\tif ( ( new Set( bindProperties ) ).size !== bindProperties.length ) {\n\t\t\t/**\n\t\t\t * Properties must be unique.\n\t\t\t *\n\t\t\t * @error observable-bind-duplicate-properties\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'observable-bind-duplicate-properties: Properties must be unique.' );\n\t\t}\n\n\t\tinitObservable( this );\n\n\t\tconst boundProperties = this[ boundPropertiesSymbol ];\n\n\t\tbindProperties.forEach( propertyName => {\n\t\t\tif ( boundProperties.has( propertyName ) ) {\n\t\t\t\t/**\n\t\t\t\t * Cannot bind the same property more that once.\n\t\t\t\t *\n\t\t\t\t * @error observable-bind-rebind\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'observable-bind-rebind: Cannot bind the same property more that once.' );\n\t\t\t}\n\t\t} );\n\n\t\tconst bindings = new Map();\n\n\t\t// @typedef {Object} Binding\n\t\t// @property {Array} property Property which is bound.\n\t\t// @property {Array} to Array of observable–property components of the binding (`{ observable: ..., property: .. }`).\n\t\t// @property {Array} callback A function which processes `to` components.\n\t\tbindProperties.forEach( a => {\n\t\t\tconst binding = { property: a, to: [] };\n\n\t\t\tboundProperties.set( a, binding );\n\t\t\tbindings.set( a, binding );\n\t\t} );\n\n\t\t// @typedef {Object} BindChain\n\t\t// @property {Function} to See {@link ~ObservableMixin#_bindTo}.\n\t\t// @property {Function} toMany See {@link ~ObservableMixin#_bindToMany}.\n\t\t// @property {module:utils/observablemixin~Observable} _observable The observable which initializes the binding.\n\t\t// @property {Array} _bindProperties Array of `_observable` properties to be bound.\n\t\t// @property {Array} _to Array of `to()` observable–properties (`{ observable: toObservable, properties: ...toProperties }`).\n\t\t// @property {Map} _bindings Stores bindings to be kept in\n\t\t// {@link ~ObservableMixin#_boundProperties}/{@link ~ObservableMixin#_boundObservables}\n\t\t// initiated in this binding chain.\n\t\treturn {\n\t\t\tto: bindTo,\n\t\t\ttoMany: bindToMany,\n\n\t\t\t_observable: this,\n\t\t\t_bindProperties: bindProperties,\n\t\t\t_to: [],\n\t\t\t_bindings: bindings\n\t\t};\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tunbind( ...unbindProperties ) {\n\t\t// Nothing to do here if not inited yet.\n\t\tif ( !( observablePropertiesSymbol in this ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst boundProperties = this[ boundPropertiesSymbol ];\n\t\tconst boundObservables = this[ boundObservablesSymbol ];\n\n\t\tif ( unbindProperties.length ) {\n\t\t\tif ( !isStringArray( unbindProperties ) ) {\n\t\t\t\t/**\n\t\t\t\t * Properties must be strings.\n\t\t\t\t *\n\t\t\t\t * @error observable-unbind-wrong-properties\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'observable-unbind-wrong-properties: Properties must be strings.' );\n\t\t\t}\n\n\t\t\tunbindProperties.forEach( propertyName => {\n\t\t\t\tconst binding = boundProperties.get( propertyName );\n\n\t\t\t\t// Nothing to do if the binding is not defined\n\t\t\t\tif ( !binding ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlet toObservable, toProperty, toProperties, toPropertyBindings;\n\n\t\t\t\tbinding.to.forEach( to => {\n\t\t\t\t\t// TODO: ES6 destructuring.\n\t\t\t\t\ttoObservable = to[ 0 ];\n\t\t\t\t\ttoProperty = to[ 1 ];\n\t\t\t\t\ttoProperties = boundObservables.get( toObservable );\n\t\t\t\t\ttoPropertyBindings = toProperties[ toProperty ];\n\n\t\t\t\t\ttoPropertyBindings.delete( binding );\n\n\t\t\t\t\tif ( !toPropertyBindings.size ) {\n\t\t\t\t\t\tdelete toProperties[ toProperty ];\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !Object.keys( toProperties ).length ) {\n\t\t\t\t\t\tboundObservables.delete( toObservable );\n\t\t\t\t\t\tthis.stopListening( toObservable, 'change' );\n\t\t\t\t\t}\n\t\t\t\t} );\n\n\t\t\t\tboundProperties.delete( propertyName );\n\t\t\t} );\n\t\t} else {\n\t\t\tboundObservables.forEach( ( bindings, boundObservable ) => {\n\t\t\t\tthis.stopListening( boundObservable, 'change' );\n\t\t\t} );\n\n\t\t\tboundObservables.clear();\n\t\t\tboundProperties.clear();\n\t\t}\n\t},\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdecorate( methodName ) {\n\t\tconst originalMethod = this[ methodName ];\n\n\t\tif ( !originalMethod ) {\n\t\t\t/**\n\t\t\t * Cannot decorate an undefined method.\n\t\t\t *\n\t\t\t * @error observablemixin-cannot-decorate-undefined\n\t\t\t * @param {Object} object The object which method should be decorated.\n\t\t\t * @param {String} methodName Name of the method which does not exist.\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'observablemixin-cannot-decorate-undefined: Cannot decorate an undefined method.',\n\t\t\t\t{ object: this, methodName }\n\t\t\t);\n\t\t}\n\n\t\tthis.on( methodName, ( evt, args ) => {\n\t\t\tevt.return = originalMethod.apply( this, args );\n\t\t} );\n\n\t\tthis[ methodName ] = function( ...args ) {\n\t\t\treturn this.fire( methodName, args );\n\t\t};\n\t}\n};\n\nextend( ObservableMixin, EmitterMixin );\n\nexport default ObservableMixin;\n\n// Init symbol properties needed to for the observable mechanism to work.\n//\n// @private\n// @param {module:utils/observablemixin~ObservableMixin} observable\nfunction initObservable( observable ) {\n\t// Do nothing if already inited.\n\tif ( observablePropertiesSymbol in observable ) {\n\t\treturn;\n\t}\n\n\t// The internal hash containing the observable's state.\n\t//\n\t// @private\n\t// @type {Map}\n\tObject.defineProperty( observable, observablePropertiesSymbol, {\n\t\tvalue: new Map()\n\t} );\n\n\t// Map containing bindings to external observables. It shares the binding objects\n\t// (`{ observable: A, property: 'a', to: ... }`) with {@link module:utils/observablemixin~ObservableMixin#_boundProperties} and\n\t// it is used to observe external observables to update own properties accordingly.\n\t// See {@link module:utils/observablemixin~ObservableMixin#bind}.\n\t//\n\t//\t\tA.bind( 'a', 'b', 'c' ).to( B, 'x', 'y', 'x' );\n\t//\t\tconsole.log( A._boundObservables );\n\t//\n\t//\t\t\tMap( {\n\t//\t\t\t\tB: {\n\t//\t\t\t\t\tx: Set( [\n\t//\t\t\t\t\t\t{ observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\t\t\t{ observable: A, property: 'c', to: [ [ B, 'x' ] ] }\n\t//\t\t\t\t\t] ),\n\t//\t\t\t\t\ty: Set( [\n\t//\t\t\t\t\t\t{ observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n\t//\t\t\t\t\t] )\n\t//\t\t\t\t}\n\t//\t\t\t} )\n\t//\n\t//\t\tA.bind( 'd' ).to( B, 'z' ).to( C, 'w' ).as( callback );\n\t//\t\tconsole.log( A._boundObservables );\n\t//\n\t//\t\t\tMap( {\n\t//\t\t\t\tB: {\n\t//\t\t\t\t\tx: Set( [\n\t//\t\t\t\t\t\t{ observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\t\t\t{ observable: A, property: 'c', to: [ [ B, 'x' ] ] }\n\t//\t\t\t\t\t] ),\n\t//\t\t\t\t\ty: Set( [\n\t//\t\t\t\t\t\t{ observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n\t//\t\t\t\t\t] ),\n\t//\t\t\t\t\tz: Set( [\n\t//\t\t\t\t\t\t{ observable: A, property: 'd', to: [ [ B, 'z' ], [ C, 'w' ] ], callback: callback }\n\t//\t\t\t\t\t] )\n\t//\t\t\t\t},\n\t//\t\t\t\tC: {\n\t//\t\t\t\t\tw: Set( [\n\t//\t\t\t\t\t\t{ observable: A, property: 'd', to: [ [ B, 'z' ], [ C, 'w' ] ], callback: callback }\n\t//\t\t\t\t\t] )\n\t//\t\t\t\t}\n\t//\t\t\t} )\n\t//\n\t// @private\n\t// @type {Map}\n\tObject.defineProperty( observable, boundObservablesSymbol, {\n\t\tvalue: new Map()\n\t} );\n\n\t// Object that stores which properties of this observable are bound and how. It shares\n\t// the binding objects (`{ observable: A, property: 'a', to: ... }`) with {@link utils.ObservableMixin#_boundObservables}.\n\t// This data structure is a reverse of {@link utils.ObservableMixin#_boundObservables} and it is helpful for\n\t// {@link utils.ObservableMixin#unbind}.\n\t//\n\t// See {@link utils.ObservableMixin#bind}.\n\t//\n\t//\t\tA.bind( 'a', 'b', 'c' ).to( B, 'x', 'y', 'x' );\n\t//\t\tconsole.log( A._boundProperties );\n\t//\n\t//\t\t\tMap( {\n\t//\t\t\t\ta: { observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\tb: { observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n\t//\t\t\t\tc: { observable: A, property: 'c', to: [ [ B, 'x' ] ] }\n\t//\t\t\t} )\n\t//\n\t//\t\tA.bind( 'd' ).to( B, 'z' ).to( C, 'w' ).as( callback );\n\t//\t\tconsole.log( A._boundProperties );\n\t//\n\t//\t\t\tMap( {\n\t//\t\t\t\ta: { observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\tb: { observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n\t//\t\t\t\tc: { observable: A, property: 'c', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\td: { observable: A, property: 'd', to: [ [ B, 'z' ], [ C, 'w' ] ], callback: callback }\n\t//\t\t\t} )\n\t//\n\t// @private\n\t// @type {Map}\n\tObject.defineProperty( observable, boundPropertiesSymbol, {\n\t\tvalue: new Map()\n\t} );\n}\n\n// A chaining for {@link module:utils/observablemixin~ObservableMixin#bind} providing `.to()` interface.\n//\n// @private\n// @param {...[Observable|String|Function]} args Arguments of the `.to( args )` binding.\nfunction bindTo( ...args ) {\n\tconst parsedArgs = parseBindToArgs( ...args );\n\tconst bindingsKeys = Array.from( this._bindings.keys() );\n\tconst numberOfBindings = bindingsKeys.length;\n\n\t// Eliminate A.bind( 'x' ).to( B, C )\n\tif ( !parsedArgs.callback && parsedArgs.to.length > 1 ) {\n\t\t/**\n\t\t * Binding multiple observables only possible with callback.\n\t\t *\n\t\t * @error observable-bind-no-callback\n\t\t */\n\t\tthrow new CKEditorError( 'observable-bind-to-no-callback: Binding multiple observables only possible with callback.' );\n\t}\n\n\t// Eliminate A.bind( 'x', 'y' ).to( B, callback )\n\tif ( numberOfBindings > 1 && parsedArgs.callback ) {\n\t\t/**\n\t\t * Cannot bind multiple properties and use a callback in one binding.\n\t\t *\n\t\t * @error observable-bind-to-extra-callback\n\t\t */\n\t\tthrow new CKEditorError( 'observable-bind-to-extra-callback: Cannot bind multiple properties and use a callback in one binding.' );\n\t}\n\n\tparsedArgs.to.forEach( to => {\n\t\t// Eliminate A.bind( 'x', 'y' ).to( B, 'a' )\n\t\tif ( to.properties.length && to.properties.length !== numberOfBindings ) {\n\t\t\t/**\n\t\t\t * The number of properties must match.\n\t\t\t *\n\t\t\t * @error observable-bind-to-properties-length\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'observable-bind-to-properties-length: The number of properties must match.' );\n\t\t}\n\n\t\t// When no to.properties specified, observing source properties instead i.e.\n\t\t// A.bind( 'x', 'y' ).to( B ) -> Observe B.x and B.y\n\t\tif ( !to.properties.length ) {\n\t\t\tto.properties = this._bindProperties;\n\t\t}\n\t} );\n\n\tthis._to = parsedArgs.to;\n\n\t// Fill {@link BindChain#_bindings} with callback. When the callback is set there's only one binding.\n\tif ( parsedArgs.callback ) {\n\t\tthis._bindings.get( bindingsKeys[ 0 ] ).callback = parsedArgs.callback;\n\t}\n\n\tattachBindToListeners( this._observable, this._to );\n\n\t// Update observable._boundProperties and observable._boundObservables.\n\tupdateBindToBound( this );\n\n\t// Set initial values of bound properties.\n\tthis._bindProperties.forEach( propertyName => {\n\t\tupdateBoundObservableProperty( this._observable, propertyName );\n\t} );\n}\n\n// Binds to an attribute in a set of iterable observables.\n//\n// @private\n// @param {Array.<Observable>} observables\n// @param {String} attribute\n// @param {Function} callback\nfunction bindToMany( observables, attribute, callback ) {\n\tif ( this._bindings.size > 1 ) {\n\t\t/**\n\t\t * Binding one attribute to many observables only possible with one attribute.\n\t\t *\n\t\t * @error observable-bind-to-many-not-one-binding\n\t\t */\n\t\tthrow new CKEditorError( 'observable-bind-to-many-not-one-binding: Cannot bind multiple properties with toMany().' );\n\t}\n\n\tthis.to(\n\t\t// Bind to #attribute of each observable...\n\t\t...getBindingTargets( observables, attribute ),\n\t\t// ...using given callback to parse attribute values.\n\t\tcallback\n\t);\n}\n\n// Returns an array of binding components for\n// {@link Observable#bind} from a set of iterable observables.\n//\n// @param {Array.<Observable>} observables\n// @param {String} attribute\n// @returns {Array.<String|Observable>}\nfunction getBindingTargets( observables, attribute ) {\n\tconst observableAndAttributePairs = observables.map( observable => [ observable, attribute ] );\n\n\t// Merge pairs to one-dimension array of observables and attributes.\n\treturn Array.prototype.concat.apply( [], observableAndAttributePairs );\n}\n\n// Check if all entries of the array are of `String` type.\n//\n// @private\n// @param {Array} arr An array to be checked.\n// @returns {Boolean}\nfunction isStringArray( arr ) {\n\treturn arr.every( a => typeof a == 'string' );\n}\n\n// Parses and validates {@link Observable#bind}`.to( args )` arguments and returns\n// an object with a parsed structure. For example\n//\n//\t\tA.bind( 'x' ).to( B, 'a', C, 'b', call );\n//\n// becomes\n//\n//\t\t{\n//\t\t\tto: [\n//\t\t\t\t{ observable: B, properties: [ 'a' ] },\n//\t\t\t\t{ observable: C, properties: [ 'b' ] },\n//\t\t\t],\n//\t\t\tcallback: call\n// \t\t}\n//\n// @private\n// @param {...*} args Arguments of {@link Observable#bind}`.to( args )`.\n// @returns {Object}\nfunction parseBindToArgs( ...args ) {\n\t// Eliminate A.bind( 'x' ).to()\n\tif ( !args.length ) {\n\t\t/**\n\t\t * Invalid argument syntax in `to()`.\n\t\t *\n\t\t * @error observable-bind-to-parse-error\n\t\t */\n\t\tthrow new CKEditorError( 'observable-bind-to-parse-error: Invalid argument syntax in `to()`.' );\n\t}\n\n\tconst parsed = { to: [] };\n\tlet lastObservable;\n\n\tif ( typeof args[ args.length - 1 ] == 'function' ) {\n\t\tparsed.callback = args.pop();\n\t}\n\n\targs.forEach( a => {\n\t\tif ( typeof a == 'string' ) {\n\t\t\tlastObservable.properties.push( a );\n\t\t} else if ( typeof a == 'object' ) {\n\t\t\tlastObservable = { observable: a, properties: [] };\n\t\t\tparsed.to.push( lastObservable );\n\t\t} else {\n\t\t\tthrow new CKEditorError( 'observable-bind-to-parse-error: Invalid argument syntax in `to()`.' );\n\t\t}\n\t} );\n\n\treturn parsed;\n}\n\n// Synchronizes {@link module:utils/observablemixin#_boundObservables} with {@link Binding}.\n//\n// @private\n// @param {Binding} binding A binding to store in {@link Observable#_boundObservables}.\n// @param {Observable} toObservable A observable, which is a new component of `binding`.\n// @param {String} toPropertyName A name of `toObservable`'s property, a new component of the `binding`.\nfunction updateBoundObservables( observable, binding, toObservable, toPropertyName ) {\n\tconst boundObservables = observable[ boundObservablesSymbol ];\n\tconst bindingsToObservable = boundObservables.get( toObservable );\n\tconst bindings = bindingsToObservable || {};\n\n\tif ( !bindings[ toPropertyName ] ) {\n\t\tbindings[ toPropertyName ] = new Set();\n\t}\n\n\t// Pass the binding to a corresponding Set in `observable._boundObservables`.\n\tbindings[ toPropertyName ].add( binding );\n\n\tif ( !bindingsToObservable ) {\n\t\tboundObservables.set( toObservable, bindings );\n\t}\n}\n\n// Synchronizes {@link Observable#_boundProperties} and {@link Observable#_boundObservables}\n// with {@link BindChain}.\n//\n// Assuming the following binding being created\n//\n// \t\tA.bind( 'a', 'b' ).to( B, 'x', 'y' );\n//\n// the following bindings were initialized by {@link Observable#bind} in {@link BindChain#_bindings}:\n//\n// \t\t{\n// \t\t\ta: { observable: A, property: 'a', to: [] },\n// \t\t\tb: { observable: A, property: 'b', to: [] },\n// \t\t}\n//\n// Iterate over all bindings in this chain and fill their `to` properties with\n// corresponding to( ... ) arguments (components of the binding), so\n//\n// \t\t{\n// \t\t\ta: { observable: A, property: 'a', to: [ B, 'x' ] },\n// \t\t\tb: { observable: A, property: 'b', to: [ B, 'y' ] },\n// \t\t}\n//\n// Then update the structure of {@link Observable#_boundObservables} with updated\n// binding, so it becomes:\n//\n// \t\tMap( {\n// \t\t\tB: {\n// \t\t\t\tx: Set( [\n// \t\t\t\t\t{ observable: A, property: 'a', to: [ [ B, 'x' ] ] }\n// \t\t\t\t] ),\n// \t\t\t\ty: Set( [\n// \t\t\t\t\t{ observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n// \t\t\t\t] )\n//\t\t\t}\n// \t\t} )\n//\n// @private\n// @param {BindChain} chain The binding initialized by {@link Observable#bind}.\nfunction updateBindToBound( chain ) {\n\tlet toProperty;\n\n\tchain._bindings.forEach( ( binding, propertyName ) => {\n\t\t// Note: For a binding without a callback, this will run only once\n\t\t// like in A.bind( 'x', 'y' ).to( B, 'a', 'b' )\n\t\t// TODO: ES6 destructuring.\n\t\tchain._to.forEach( to => {\n\t\t\ttoProperty = to.properties[ binding.callback ? 0 : chain._bindProperties.indexOf( propertyName ) ];\n\n\t\t\tbinding.to.push( [ to.observable, toProperty ] );\n\t\t\tupdateBoundObservables( chain._observable, binding, to.observable, toProperty );\n\t\t} );\n\t} );\n}\n\n// Updates an property of a {@link Observable} with a value\n// determined by an entry in {@link Observable#_boundProperties}.\n//\n// @private\n// @param {Observable} observable A observable which property is to be updated.\n// @param {String} propertyName An property to be updated.\nfunction updateBoundObservableProperty( observable, propertyName ) {\n\tconst boundProperties = observable[ boundPropertiesSymbol ];\n\tconst binding = boundProperties.get( propertyName );\n\tlet propertyValue;\n\n\t// When a binding with callback is created like\n\t//\n\t// \t\tA.bind( 'a' ).to( B, 'b', C, 'c', callback );\n\t//\n\t// collect B.b and C.c, then pass them to callback to set A.a.\n\tif ( binding.callback ) {\n\t\tpropertyValue = binding.callback.apply( observable, binding.to.map( to => to[ 0 ][ to[ 1 ] ] ) );\n\t} else {\n\t\tpropertyValue = binding.to[ 0 ];\n\t\tpropertyValue = propertyValue[ 0 ][ propertyValue[ 1 ] ];\n\t}\n\n\tif ( observable.hasOwnProperty( propertyName ) ) {\n\t\tobservable[ propertyName ] = propertyValue;\n\t} else {\n\t\tobservable.set( propertyName, propertyValue );\n\t}\n}\n\n// Starts listening to changes in {@link BindChain._to} observables to update\n// {@link BindChain._observable} {@link BindChain._bindProperties}. Also sets the\n// initial state of {@link BindChain._observable}.\n//\n// @private\n// @param {BindChain} chain The chain initialized by {@link Observable#bind}.\nfunction attachBindToListeners( observable, toBindings ) {\n\ttoBindings.forEach( to => {\n\t\tconst boundObservables = observable[ boundObservablesSymbol ];\n\t\tlet bindings;\n\n\t\t// If there's already a chain between the observables (`observable` listens to\n\t\t// `to.observable`), there's no need to create another `change` event listener.\n\t\tif ( !boundObservables.get( to.observable ) ) {\n\t\t\tobservable.listenTo( to.observable, 'change', ( evt, propertyName ) => {\n\t\t\t\tbindings = boundObservables.get( to.observable )[ propertyName ];\n\n\t\t\t\t// Note: to.observable will fire for any property change, react\n\t\t\t\t// to changes of properties which are bound only.\n\t\t\t\tif ( bindings ) {\n\t\t\t\t\tbindings.forEach( binding => {\n\t\t\t\t\t\tupdateBoundObservableProperty( observable, binding.property );\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t} );\n}\n\n/**\n * Interface which adds \"observable properties\" and data binding functionality.\n *\n * Can be easily implemented by a class by mixing the {@link module:utils/observablemixin~ObservableMixin} mixin.\n *\n * Read more about the usage of this interface in the:\n * * {@glink framework/guides/architecture/core-editor-architecture#event-system-and-observables \"Event system and observables\"}\n * section of the {@glink framework/guides/architecture/core-editor-architecture \"Core editor architecture\"} guide,\n * * {@glink framework/guides/deep-dive/observables \"Observables\" deep dive} guide.\n *\n * @interface Observable\n * @extends module:utils/emittermixin~Emitter\n */\n\n/**\n * Fired when a property changed value.\n *\n *\t\tobservable.set( 'prop', 1 );\n *\n *\t\tobservable.on( 'change:prop', ( evt, propertyName, newValue, oldValue ) => {\n *\t\t\tconsole.log( `${ propertyName } has changed from ${ oldValue } to ${ newValue }` );\n *\t\t} );\n *\n *\t\tobservable.prop = 2; // -> 'prop has changed from 1 to 2'\n *\n * @event change:{property}\n * @param {String} name The property name.\n * @param {*} value The new property value.\n * @param {*} oldValue The previous property value.\n */\n\n/**\n * Fired when a property value is going to be set but is not set yet (before the `change` event is fired).\n *\n * You can control the final value of the property by using\n * the {@link module:utils/eventinfo~EventInfo#return event's `return` property}.\n *\n *\t\tobservable.set( 'prop', 1 );\n *\n *\t\tobservable.on( 'set:prop', ( evt, propertyName, newValue, oldValue ) => {\n *\t\t\tconsole.log( `Value is going to be changed from ${ oldValue } to ${ newValue }` );\n *\t\t\tconsole.log( `Current property value is ${ observable[ propertyName ] }` );\n *\n *\t\t\t// Let's override the value.\n *\t\t\tevt.return = 3;\n *\t\t} );\n *\n *\t\tobservable.on( 'change:prop', ( evt, propertyName, newValue, oldValue ) => {\n *\t\t\tconsole.log( `Value has changed from ${ oldValue } to ${ newValue }` );\n *\t\t} );\n *\n *\t\tobservable.prop = 2; // -> 'Value is going to be changed from 1 to 2'\n *\t\t // -> 'Current property value is 1'\n *\t\t // -> 'Value has changed from 1 to 3'\n *\n * **Note:** Event is fired even when the new value is the same as the old value.\n *\n * @event set:{property}\n * @param {String} name The property name.\n * @param {*} value The new property value.\n * @param {*} oldValue The previous property value.\n */\n\n/**\n * Creates and sets the value of an observable property of this object. Such an property becomes a part\n * of the state and is be observable.\n *\n * It accepts also a single object literal containing key/value pairs with properties to be set.\n *\n * This method throws the `observable-set-cannot-override` error if the observable instance already\n * have a property with the given property name. This prevents from mistakenly overriding existing\n * properties and methods, but means that `foo.set( 'bar', 1 )` may be slightly slower than `foo.bar = 1`.\n *\n * @method #set\n * @param {String|Object} name The property's name or object with `name=>value` pairs.\n * @param {*} [value] The property's value (if `name` was passed in the first parameter).\n */\n\n/**\n * Binds {@link #set obvervable properties} to other objects implementing the\n * {@link module:utils/observablemixin~Observable} interface.\n *\n * Read more in the {@glink framework/guides/deep-dive/observables#property-bindings dedicated guide}\n * covering the topic of property bindings with some additional examples.\n *\n * Let's consider two objects: a `button` and an associated `command` (both `Observable`).\n *\n * A simple property binding could be as follows:\n *\n *\t\tbutton.bind( 'isEnabled' ).to( command, 'isEnabled' );\n *\n * or even shorter:\n *\n *\t\tbutton.bind( 'isEnabled' ).to( command );\n *\n * which works in the following way:\n *\n * * `button.isEnabled` **instantly equals** `command.isEnabled`,\n * * whenever `command.isEnabled` changes, `button.isEnabled` will immediately reflect its value.\n *\n * **Note**: To release the binding use {@link module:utils/observablemixin~Observable#unbind}.\n *\n * You can also \"rename\" the property in the binding by specifying the new name in the `to()` chain:\n *\n *\t\tbutton.bind( 'isEnabled' ).to( command, 'isWorking' );\n *\n * It is possible to bind more than one property at a time to shorten the code:\n *\n *\t\tbutton.bind( 'isEnabled', 'value' ).to( command );\n *\n * which corresponds to:\n *\n *\t\tbutton.bind( 'isEnabled' ).to( command );\n *\t\tbutton.bind( 'value' ).to( command );\n *\n * The binding can include more than one observable, combining multiple data sources in a custom callback:\n *\n *\t\tbutton.bind( 'isEnabled' ).to( command, 'isEnabled', ui, 'isVisible',\n *\t\t\t( isCommandEnabled, isUIVisible ) => isCommandEnabled && isUIVisible );\n *\n * It is also possible to bind to the same property in an array of observables.\n * To bind a `button` to multiple commands (also `Observables`) so that each and every one of them\n * must be enabled for the button to become enabled, use the following code:\n *\n *\t\tbutton.bind( 'isEnabled' ).toMany( [ commandA, commandB, commandC ], 'isEnabled',\n *\t\t\t( isAEnabled, isBEnabled, isCEnabled ) => isAEnabled && isBEnabled && isCEnabled );\n *\n * @method #bind\n * @param {...String} bindProperties Observable properties that will be bound to another observable(s).\n * @returns {Object} The bind chain with the `to()` and `toMany()` methods.\n */\n\n/**\n * Removes the binding created with {@link #bind}.\n *\n *\t\t// Removes the binding for the 'a' property.\n *\t\tA.unbind( 'a' );\n *\n *\t\t// Removes bindings for all properties.\n *\t\tA.unbind();\n *\n * @method #unbind\n * @param {...String} [unbindProperties] Observable properties to be unbound. All the bindings will\n * be released if no properties provided.\n */\n\n/**\n * Turns the given methods of this object into event-based ones. This means that the new method will fire an event\n * (named after the method) and the original action will be plugged as a listener to that event.\n *\n * Read more in the {@glink framework/guides/deep-dive/observables#decorating-object-methods dedicated guide}\n * covering the topic of decorating methods with some additional examples.\n *\n * Decorating the method does not change its behavior (it only adds an event),\n * but it allows to modify it later on by listening to the method's event.\n *\n * For example, to cancel the method execution the event can be {@link module:utils/eventinfo~EventInfo#stop stopped}:\n *\n *\t\tclass Foo {\n *\t\t\tconstructor() {\n *\t\t\t\tthis.decorate( 'method' );\n *\t\t\t}\n *\n *\t\t\tmethod() {\n *\t\t\t\tconsole.log( 'called!' );\n *\t\t\t}\n *\t\t}\n *\n *\t\tconst foo = new Foo();\n *\t\tfoo.on( 'method', ( evt ) => {\n *\t\t\tevt.stop();\n *\t\t}, { priority: 'high' } );\n *\n *\t\tfoo.method(); // Nothing is logged.\n *\n *\n * **Note**: The high {@link module:utils/priorities~PriorityString priority} listener\n * has been used to execute this particular callback before the one which calls the original method\n * (which uses the \"normal\" priority).\n *\n * It is also possible to change the returned value:\n *\n *\t\tfoo.on( 'method', ( evt ) => {\n *\t\t\tevt.return = 'Foo!';\n *\t\t} );\n *\n *\t\tfoo.method(); // -> 'Foo'\n *\n * Finally, it is possible to access and modify the arguments the method is called with:\n *\n *\t\tmethod( a, b ) {\n *\t\t\tconsole.log( `${ a }, ${ b }` );\n *\t\t}\n *\n *\t\t// ...\n *\n *\t\tfoo.on( 'method', ( evt, args ) => {\n *\t\t\targs[ 0 ] = 3;\n *\n *\t\t\tconsole.log( args[ 1 ] ); // -> 2\n *\t\t}, { priority: 'high' } );\n *\n *\t\tfoo.method( 1, 2 ); // -> '3, 2'\n *\n * @method #decorate\n * @param {String} methodName Name of the method to decorate.\n */\n","/**\n * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/mix\n */\n\n/**\n * Copies enumerable properties and symbols from the objects given as 2nd+ parameters to the\n * prototype of first object (a constructor).\n *\n *\t\tclass Editor {\n *\t\t\t...\n *\t\t}\n *\n *\t\tconst SomeMixin = {\n *\t\t\ta() {\n *\t\t\t\treturn 'a';\n *\t\t\t}\n *\t\t};\n *\n *\t\tmix( Editor, SomeMixin, ... );\n *\n *\t\tnew Editor().a(); // -> 'a'\n *\n * Note: Properties which already exist in the base class will not be overriden.\n *\n * @param {Function} [baseClass] Class which prototype will be extended.\n * @param {Object} [...mixins] Objects from which to get properties.\n */\nexport default function mix( baseClass, ...mixins ) {\n\tmixins.forEach( mixin => {\n\t\tObject.getOwnPropertyNames( mixin ).concat( Object.getOwnPropertySymbols( mixin ) )\n\t\t\t.forEach( key => {\n\t\t\t\tif ( key in baseClass.prototype ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst sourceDescriptor = Object.getOwnPropertyDescriptor( mixin, key );\n\t\t\t\tsourceDescriptor.enumerable = false;\n\n\t\t\t\tObject.defineProperty( baseClass.prototype, key, sourceDescriptor );\n\t\t\t} );\n\t} );\n}\n","/**\n * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor, 'dataReady', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module widget/highlightstack\n */\n\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * Class used to handle correct order of highlights on elements.\n *\n * When different highlights are applied to same element correct order should be preserved:\n *\n * * highlight with highest priority should be applied,\n * * if two highlights have same priority - sort by CSS class provided in\n * {@link module:engine/conversion/downcasthelpers~HighlightDescriptor}.\n *\n * This way, highlight will be applied with the same rules it is applied on texts.\n */\nexport default class HighlightStack {\n\t/**\n\t * Creates class instance.\n\t */\n\tconstructor() {\n\t\tthis._stack = [];\n\t}\n\n\t/**\n\t * Adds highlight descriptor to the stack.\n\t *\n\t * @fires change:top\n\t * @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} descriptor\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer\n\t */\n\tadd( descriptor, writer ) {\n\t\tconst stack = this._stack;\n\n\t\t// Save top descriptor and insert new one. If top is changed - fire event.\n\t\tconst oldTop = stack[ 0 ];\n\t\tthis._insertDescriptor( descriptor );\n\t\tconst newTop = stack[ 0 ];\n\n\t\t// When new object is at the top and stores different information.\n\t\tif ( oldTop !== newTop && !compareDescriptors( oldTop, newTop ) ) {\n\t\t\tthis.fire( 'change:top', {\n\t\t\t\toldDescriptor: oldTop,\n\t\t\t\tnewDescriptor: newTop,\n\t\t\t\twriter\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Removes highlight descriptor from the stack.\n\t *\n\t * @fires change:top\n\t * @param {String} id Id of the descriptor to remove.\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer\n\t */\n\tremove( id, writer ) {\n\t\tconst stack = this._stack;\n\n\t\tconst oldTop = stack[ 0 ];\n\t\tthis._removeDescriptor( id );\n\t\tconst newTop = stack[ 0 ];\n\n\t\t// When new object is at the top and stores different information.\n\t\tif ( oldTop !== newTop && !compareDescriptors( oldTop, newTop ) ) {\n\t\t\tthis.fire( 'change:top', {\n\t\t\t\toldDescriptor: oldTop,\n\t\t\t\tnewDescriptor: newTop,\n\t\t\t\twriter\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Inserts given descriptor in correct place in the stack. It also takes care about updating information when\n\t * descriptor with same id is already present.\n\t *\n\t * @private\n\t * @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} descriptor\n\t */\n\t_insertDescriptor( descriptor ) {\n\t\tconst stack = this._stack;\n\t\tconst index = stack.findIndex( item => item.id === descriptor.id );\n\n\t\t// Inserting exact same descriptor - do nothing.\n\t\tif ( compareDescriptors( descriptor, stack[ index ] ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If descriptor with same id but with different information is on the stack - remove it.\n\t\tif ( index > -1 ) {\n\t\t\tstack.splice( index, 1 );\n\t\t}\n\n\t\t// Find correct place to insert descriptor in the stack.\n\t\t// It have different information (for example priority) so it must be re-inserted in correct place.\n\t\tlet i = 0;\n\n\t\twhile ( stack[ i ] && shouldABeBeforeB( stack[ i ], descriptor ) ) {\n\t\t\ti++;\n\t\t}\n\n\t\tstack.splice( i, 0, descriptor );\n\t}\n\n\t/**\n\t * Removes descriptor with given id from the stack.\n\t *\n\t * @private\n\t * @param {String} id Descriptor's id.\n\t */\n\t_removeDescriptor( id ) {\n\t\tconst stack = this._stack;\n\t\tconst index = stack.findIndex( item => item.id === id );\n\n\t\t// If descriptor with same id is on the list - remove it.\n\t\tif ( index > -1 ) {\n\t\t\tstack.splice( index, 1 );\n\t\t}\n\t}\n}\n\nmix( HighlightStack, EmitterMixin );\n\n// Compares two descriptors by checking their priority and class list.\n//\n// @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} a\n// @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} b\n// @returns {Boolean} Returns true if both descriptors are defined and have same priority and classes.\nfunction compareDescriptors( a, b ) {\n\treturn a && b && a.priority == b.priority && classesToString( a.classes ) == classesToString( b.classes );\n}\n\n// Checks whenever first descriptor should be placed in the stack before second one.\n//\n// @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} a\n// @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} b\n// @returns {Boolean}\nfunction shouldABeBeforeB( a, b ) {\n\tif ( a.priority > b.priority ) {\n\t\treturn true;\n\t} else if ( a.priority < b.priority ) {\n\t\treturn false;\n\t}\n\n\t// When priorities are equal and names are different - use classes to compare.\n\treturn classesToString( a.classes ) > classesToString( b.classes );\n}\n\n// Converts CSS classes passed with {@link module:engine/conversion/downcasthelpers~HighlightDescriptor} to\n// sorted string.\n//\n// @param {String|Array<String>} descriptor\n// @returns {String}\nfunction classesToString( classes ) {\n\treturn Array.isArray( classes ) ? classes.sort().join( ',' ) : classes;\n}\n\n/**\n * Fired when top element on {@link module:widget/highlightstack~HighlightStack} has been changed\n *\n * @event change:top\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} [data.newDescriptor] New highlight\n * descriptor. It will be `undefined` when last descriptor is removed from the stack.\n * @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} [data.oldDescriptor] Old highlight\n * descriptor. It will be `undefined` when first descriptor is added to the stack.\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer View writer that can be used to modify element.\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module widget/utils\n */\n\nimport HighlightStack from './highlightstack';\nimport IconView from '@ckeditor/ckeditor5-ui/src/icon/iconview';\nimport env from '@ckeditor/ckeditor5-utils/src/env';\n\nimport dragHandlerIcon from '../theme/icons/drag-handler.svg';\n\n/**\n * CSS class added to each widget element.\n *\n * @const {String}\n */\nexport const WIDGET_CLASS_NAME = 'ck-widget';\n\n/**\n * CSS class added to currently selected widget element.\n *\n * @const {String}\n */\nexport const WIDGET_SELECTED_CLASS_NAME = 'ck-widget_selected';\n\n/**\n * Returns `true` if given {@link module:engine/view/node~Node} is an {@link module:engine/view/element~Element} and a widget.\n *\n * @param {module:engine/view/node~Node} node\n * @returns {Boolean}\n */\nexport function isWidget( node ) {\n\tif ( !node.is( 'element' ) ) {\n\t\treturn false;\n\t}\n\n\treturn !!node.getCustomProperty( 'widget' );\n}\n\n/* eslint-disable max-len */\n/**\n * Converts the given {@link module:engine/view/element~Element} to a widget in the following way:\n *\n * * sets the `contenteditable` attribute to `\"true\"`,\n * * adds the `ck-widget` CSS class,\n * * adds a custom {@link module:engine/view/element~Element#getFillerOffset `getFillerOffset()`} method returning `null`,\n * * adds a custom property allowing to recognize widget elements by using {@link ~isWidget `isWidget()`},\n * * implements the {@link ~setHighlightHandling view highlight on widgets}.\n *\n * This function needs to be used in conjunction with\n * {@link module:engine/conversion/downcasthelpers~DowncastHelpers downcast conversion helpers}\n * like {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`}.\n * Moreover, typically you will want to use `toWidget()` only for `editingDowncast`, while keeping the `dataDowncast` clean.\n *\n * For example, in order to convert a `<widget>` model element to `<div class=\"widget\">` in the view, you can define\n * such converters:\n *\n *\t\teditor.conversion.for( 'editingDowncast' )\n *\t\t\t.elementToElement( {\n *\t\t\t\tmodel: 'widget',\n *\t\t\t\tview: ( modelItem, writer ) => {\n *\t\t\t\t\tconst div = writer.createContainerElement( 'div', { class: 'widget' } );\n *\n *\t\t\t\t\treturn toWidget( div, writer, { label: 'some widget' } );\n *\t\t\t\t}\n *\t\t\t} );\n *\n *\t\teditor.conversion.for( 'dataDowncast' )\n *\t\t\t.elementToElement( {\n *\t\t\t\tmodel: 'widget',\n *\t\t\t\tview: ( modelItem, writer ) => {\n *\t\t\t\t\treturn writer.createContainerElement( 'div', { class: 'widget' } );\n *\t\t\t\t}\n *\t\t\t} );\n *\n * See the full source code of the widget (with a nested editable) schema definition and converters in\n * [this sample](https://github.com/ckeditor/ckeditor5-widget/blob/master/tests/manual/widget-with-nestededitable.js).\n *\n * @param {module:engine/view/element~Element} element\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer\n * @param {Object} [options={}]\n * @param {String|Function} [options.label] Element's label provided to the {@link ~setLabel} function. It can be passed as\n * a plain string or a function returning a string. It represents the widget for assistive technologies (like screen readers).\n * @param {Boolean} [options.hasSelectionHandler=false] If `true`, the widget will have a selection handler added.\n * @returns {module:engine/view/element~Element} Returns the same element.\n */\n/* eslint-enable max-len */\nexport function toWidget( element, writer, options = {} ) {\n\t// The selection on Edge behaves better when the whole editor contents is in a single contenteditable element.\n\t// https://github.com/ckeditor/ckeditor5/issues/1079\n\tif ( !env.isEdge ) {\n\t\twriter.setAttribute( 'contenteditable', 'false', element );\n\t}\n\n\twriter.addClass( WIDGET_CLASS_NAME, element );\n\twriter.setCustomProperty( 'widget', true, element );\n\telement.getFillerOffset = getFillerOffset;\n\n\tif ( options.label ) {\n\t\tsetLabel( element, options.label, writer );\n\t}\n\n\tif ( options.hasSelectionHandler ) {\n\t\taddSelectionHandler( element, writer );\n\t}\n\n\tsetHighlightHandling(\n\t\telement,\n\t\twriter,\n\t\t( element, descriptor, writer ) => writer.addClass( normalizeToArray( descriptor.classes ), element ),\n\t\t( element, descriptor, writer ) => writer.removeClass( normalizeToArray( descriptor.classes ), element )\n\t);\n\n\treturn element;\n\n\t// Normalizes CSS class in descriptor that can be provided in form of an array or a string.\n\tfunction normalizeToArray( classes ) {\n\t\treturn Array.isArray( classes ) ? classes : [ classes ];\n\t}\n}\n\n/**\n * Sets highlight handling methods. Uses {@link module:widget/highlightstack~HighlightStack} to\n * properly determine which highlight descriptor should be used at given time.\n *\n * @param {module:engine/view/element~Element} element\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer\n * @param {Function} add\n * @param {Function} remove\n */\nexport function setHighlightHandling( element, writer, add, remove ) {\n\tconst stack = new HighlightStack();\n\n\tstack.on( 'change:top', ( evt, data ) => {\n\t\tif ( data.oldDescriptor ) {\n\t\t\tremove( element, data.oldDescriptor, data.writer );\n\t\t}\n\n\t\tif ( data.newDescriptor ) {\n\t\t\tadd( element, data.newDescriptor, data.writer );\n\t\t}\n\t} );\n\n\twriter.setCustomProperty( 'addHighlight', ( element, descriptor, writer ) => stack.add( descriptor, writer ), element );\n\twriter.setCustomProperty( 'removeHighlight', ( element, id, writer ) => stack.remove( id, writer ), element );\n}\n\n/**\n * Sets label for given element.\n * It can be passed as a plain string or a function returning a string. Function will be called each time label is retrieved by\n * {@link ~getLabel `getLabel()`}.\n *\n * @param {module:engine/view/element~Element} element\n * @param {String|Function} labelOrCreator\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer\n */\nexport function setLabel( element, labelOrCreator, writer ) {\n\twriter.setCustomProperty( 'widgetLabel', labelOrCreator, element );\n}\n\n/**\n * Returns the label of the provided element.\n *\n * @param {module:engine/view/element~Element} element\n * @returns {String}\n */\nexport function getLabel( element ) {\n\tconst labelCreator = element.getCustomProperty( 'widgetLabel' );\n\n\tif ( !labelCreator ) {\n\t\treturn '';\n\t}\n\n\treturn typeof labelCreator == 'function' ? labelCreator() : labelCreator;\n}\n\n/**\n * Adds functionality to the provided {@link module:engine/view/editableelement~EditableElement} to act as a widget's editable:\n *\n * * sets the `contenteditable` attribute to `true` when {@link module:engine/view/editableelement~EditableElement#isReadOnly} is `false`,\n * otherwise sets it to `false`,\n * * adds the `ck-editor__editable` and `ck-editor__nested-editable` CSS classes,\n * * adds the `ck-editor__nested-editable_focused` CSS class when the editable is focused and removes it when it is blurred.\n *\n * Similarly to {@link ~toWidget `toWidget()`} this function should be used in `dataDowncast` only and it is usually\n * used together with {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`}.\n *\n * For example, in order to convert a `<nested>` model element to `<div class=\"nested\">` in the view, you can define\n * such converters:\n *\n *\t\teditor.conversion.for( 'editingDowncast' )\n *\t\t\t.elementToElement( {\n *\t\t\t\tmodel: 'nested',\n *\t\t\t\tview: ( modelItem, writer ) => {\n *\t\t\t\t\tconst div = writer.createEditableElement( 'div', { class: 'nested' } );\n *\n *\t\t\t\t\treturn toWidgetEditable( nested, writer );\n *\t\t\t\t}\n *\t\t\t} );\n *\n *\t\teditor.conversion.for( 'dataDowncast' )\n *\t\t\t.elementToElement( {\n *\t\t\t\tmodel: 'nested',\n *\t\t\t\tview: ( modelItem, writer ) => {\n *\t\t\t\t\treturn writer.createContainerElement( 'div', { class: 'nested' } );\n *\t\t\t\t}\n *\t\t\t} );\n *\n * See the full source code of the widget (with nested editable) schema definition and converters in\n * [this sample](https://github.com/ckeditor/ckeditor5-widget/blob/master/tests/manual/widget-with-nestededitable.js).\n *\n * @param {module:engine/view/editableelement~EditableElement} editable\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer\n * @returns {module:engine/view/editableelement~EditableElement} Returns the same element that was provided in the `editable` parameter\n */\nexport function toWidgetEditable( editable, writer ) {\n\twriter.addClass( [ 'ck-editor__editable', 'ck-editor__nested-editable' ], editable );\n\n\t// The selection on Edge behaves better when the whole editor contents is in a single contentedible element.\n\t// https://github.com/ckeditor/ckeditor5/issues/1079\n\tif ( !env.isEdge ) {\n\t\t// Set initial contenteditable value.\n\t\twriter.setAttribute( 'contenteditable', editable.isReadOnly ? 'false' : 'true', editable );\n\n\t\t// Bind the contenteditable property to element#isReadOnly.\n\t\teditable.on( 'change:isReadOnly', ( evt, property, is ) => {\n\t\t\twriter.setAttribute( 'contenteditable', is ? 'false' : 'true', editable );\n\t\t} );\n\t}\n\n\teditable.on( 'change:isFocused', ( evt, property, is ) => {\n\t\tif ( is ) {\n\t\t\twriter.addClass( 'ck-editor__nested-editable_focused', editable );\n\t\t} else {\n\t\t\twriter.removeClass( 'ck-editor__nested-editable_focused', editable );\n\t\t}\n\t} );\n\n\treturn editable;\n}\n\n/**\n * Returns a model position which is optimal (in terms of UX) for inserting a widget block.\n *\n * For instance, if a selection is in the middle of a paragraph, the position before this paragraph\n * will be returned so that it is not split. If the selection is at the end of a paragraph,\n * the position after this paragraph will be returned.\n *\n * Note: If the selection is placed in an empty block, that block will be returned. If that position\n * is then passed to {@link module:engine/model/model~Model#insertContent},\n * the block will be fully replaced by the image.\n *\n * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection\n * The selection based on which the insertion position should be calculated.\n * @param {module:engine/model/model~Model} model Model instance.\n * @returns {module:engine/model/position~Position} The optimal position.\n */\nexport function findOptimalInsertionPosition( selection, model ) {\n\tconst selectedElement = selection.getSelectedElement();\n\n\tif ( selectedElement && model.schema.isBlock( selectedElement ) ) {\n\t\treturn model.createPositionAfter( selectedElement );\n\t}\n\n\tconst firstBlock = selection.getSelectedBlocks().next().value;\n\n\tif ( firstBlock ) {\n\t\t// If inserting into an empty block – return position in that block. It will get\n\t\t// replaced with the image by insertContent(). #42.\n\t\tif ( firstBlock.isEmpty ) {\n\t\t\treturn model.createPositionAt( firstBlock, 0 );\n\t\t}\n\n\t\tconst positionAfter = model.createPositionAfter( firstBlock );\n\n\t\t// If selection is at the end of the block - return position after the block.\n\t\tif ( selection.focus.isTouching( positionAfter ) ) {\n\t\t\treturn positionAfter;\n\t\t}\n\n\t\t// Otherwise return position before the block.\n\t\treturn model.createPositionBefore( firstBlock );\n\t}\n\n\treturn selection.focus;\n}\n\n/**\n * A util to be used in order to map view positions to correct model positions when implementing a widget\n * which renders non-empty view element for an empty model element.\n *\n * For example:\n *\n *\t\t// Model:\n *\t\t<placeholder type=\"name\"></placeholder>\n *\n *\t\t// View:\n *\t\t<span class=\"placeholder\">name</span>\n *\n * In such case, view positions inside `<span>` cannot be correct mapped to the model (because the model element is empty).\n * To handle mapping positions inside `<span class=\"placeholder\">` to the model use this util as follows:\n *\n *\t\teditor.editing.mapper.on(\n *\t\t\t'viewToModelPosition',\n *\t\t\tviewToModelPositionOutsideModelElement( model, viewElement => viewElement.hasClass( 'placeholder' ) )\n *\t\t);\n *\n * The callback will try to map the view offset of selection to an expected model position.\n *\n * 1. When the position is at the end (or in the middle) of the inline widget:\n *\n *\t\t// View:\n *\t\t<p>foo <span class=\"placeholder\">name|</span> bar</p>\n *\n *\t\t// Model:\n *\t\t<paragraph>foo <placeholder type=\"name\"></placeholder>| bar</paragraph>\n *\n * 2. When the position is at the beginning of the inline widget:\n *\n *\t\t// View:\n *\t\t<p>foo <span class=\"placeholder\">|name</span> bar</p>\n *\n *\t\t// Model:\n *\t\t<paragraph>foo |<placeholder type=\"name\"></placeholder> bar</paragraph>\n *\n * @param {module:engine/model/model~Model} model Model instance on which the callback operates.\n * @param {Function} viewElementMatcher Function that is passed a view element and should return `true` if the custom mapping\n * should be applied to the given view element.\n * @return {Function}\n */\nexport function viewToModelPositionOutsideModelElement( model, viewElementMatcher ) {\n\treturn ( evt, data ) => {\n\t\tconst { mapper, viewPosition } = data;\n\n\t\tconst viewParent = mapper.findMappedViewAncestor( viewPosition );\n\n\t\tif ( !viewElementMatcher( viewParent ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelParent = mapper.toModelElement( viewParent );\n\n\t\tdata.modelPosition = model.createPositionAt( modelParent, viewPosition.isAtStart ? 'before' : 'after' );\n\t};\n}\n\n// Default filler offset function applied to all widget elements.\n//\n// @returns {null}\nfunction getFillerOffset() {\n\treturn null;\n}\n\n// Adds a drag handler to the editable element.\n//\n// @param {module:engine/view/editableelement~EditableElement}\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\nfunction addSelectionHandler( editable, writer ) {\n\tconst selectionHandler = writer.createUIElement( 'div', { class: 'ck ck-widget__selection-handler' }, function( domDocument ) {\n\t\tconst domElement = this.toDomElement( domDocument );\n\n\t\t// Use the IconView from the ui library.\n\t\tconst icon = new IconView();\n\t\ticon.set( 'content', dragHandlerIcon );\n\n\t\t// Render the icon view right away to append its #element to the selectionHandler DOM element.\n\t\ticon.render();\n\n\t\tdomElement.appendChild( icon.element );\n\n\t\treturn domElement;\n\t} );\n\n\t// Append the selection handler into the widget wrapper.\n\twriter.insert( writer.createPositionAt( editable, 0 ), selectionHandler );\n\twriter.addClass( [ 'ck-widget_with-selection-handler' ], editable );\n}\n","import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport { toWidget } from '@ckeditor/ckeditor5-widget/src/utils';\nimport ViewPosition from '@ckeditor/ckeditor5-engine/src/view/position';\n\nexport default class OPMacroTocPlugin extends Plugin {\n\n\tstatic get pluginName() {\n\t\treturn 'OPMacroToc';\n\t}\n\n\tstatic get buttonName() {\n\t\treturn 'insertToc';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst conversion = editor.conversion;\n\n\t\t// Schema.\n\t\tmodel.schema.register( 'op-macro-toc', {\n\t\t\tallowWhere: '$block',\n\t\t\tisBlock: true,\n\t\t isLimit: true\n\t\t});\n\n\t\tconversion.for( 'upcast' )\n\t\t\t.elementToElement( {\n\t\t\t\tview: {\n\t\t\t\t\tname: 'macro',\n\t\t\t\t\tclasses: 'toc'\n\t\t\t\t},\n\t\t\t\tmodel: 'op-macro-toc'\n\t\t\t} );\n\n\n\t\tconversion.for( 'editingDowncast' ).elementToElement( {\n\t\t\tmodel: 'op-macro-toc',\n\t\t\tview: (modelElement, viewWriter) => {\n\t\t\t\treturn toWidget(this.createTocViewElement(viewWriter), viewWriter, { label: this.label } )\n\t\t\t}\n\t } );\n\n\t\tconversion.for('dataDowncast').elementToElement({\n\t\t\tmodel: 'op-macro-toc',\n\t\t\tview: (modelElement, viewWriter) => {\n\t\t\t\treturn this.createTocDataElement(viewWriter)\n\t\t\t}\n\t\t});\n\n\t\teditor.ui.componentFactory.add( OPMacroTocPlugin.buttonName, locale => {\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\tlabel: this.label,\n\t\t\t\twithText: true,\n\t\t\t} );\n\n\t\t\t// Callback executed once the image is clicked.\n\t\t\tview.on( 'execute', () => {\n\t\t\t\teditor.model.change( writer => {\n\t\t\t\t\tconst tocElement = writer.createElement( 'op-macro-toc', {});\n\n\t\t\t\t\t// Insert the image in the current selection location.\n\t\t\t\t\teditor.model.insertContent( tocElement, editor.model.document.selection );\n\t\t\t\t} );\n\t\t\t} );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n\n\tget label() {\n\t\treturn window.I18n.t('js.editor.macro.toc');\n\t}\n\n\tcreateTocViewElement(writer) {\n\t\tconst placeholder = writer.createText( this.label );\n\t\tconst container = writer.createContainerElement( 'div', { class: 'macro -toc' } );\n\n\t\twriter.insert( writer.createPositionAt( container, 0 ), placeholder );\n\t\treturn container;\n\t}\n\n\tcreateTocDataElement(writer) {\n\t\treturn writer.createContainerElement('macro', { class: 'toc' } );\n\t}\n\n}\n","const embeddedTableSymbol = Symbol( 'isOPEmbeddedTable' );\nimport {toWidget, isWidget} from '@ckeditor/ckeditor5-widget/src/utils';\n\nexport function toEmbeddedTableWidget( viewElement, writer, label ) {\n\twriter.setCustomProperty( embeddedTableSymbol, true, viewElement );\n\treturn toWidget( viewElement, writer, { label: 'your label here' } );\n}\n\n\nexport function isEmbeddedTableWidget( viewElement ) {\n\treturn !!viewElement.getCustomProperty( embeddedTableSymbol ) && isWidget( viewElement );\n}\n\n\nexport function isEmbeddedTableWidgetSelected( selection ) {\n\tconst viewElement = selection.getSelectedElement();\n\n\treturn !!( viewElement && isEmbeddedTableWidget( viewElement ) );\n}\n","export function getOP(editor) {\n\treturn _.get(editor.config, '_config.openProject');\n}\n\nexport function getOPService(editor, name) {\n\treturn getPluginContext(editor).services[name];\n}\n\nexport function getPluginContext(editor) {\n\treturn _.get(editor.config, '_config.openProject.pluginContext');\n}\n\nexport function getOPResource(editor) {\n\treturn _.get(editor.config, '_config.openProject.context.resource');\n}\n\nexport function getOPPreviewContext(editor) {\n\treturn _.get(editor.config, '_config.openProject.context.previewContext');\n}\n\nexport function getOPPath(editor, pathName) {\n\treturn getOPService(editor,'pathHelperService');\n\n}\n","import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport {toEmbeddedTableWidget} from './utils';\nimport ViewPosition from '@ckeditor/ckeditor5-engine/src/view/position';\nimport {getPluginContext} from '../op-context/op-context';\n\nexport default class EmbeddedTableEditing extends Plugin {\n\n\tstatic get pluginName() {\n\t\treturn 'EmbeddedTableEditing';\n\t}\n\n\tstatic get buttonName() {\n\t\treturn 'insertEmbeddedTable';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst conversion = editor.conversion;\n\t\tconst pluginContext = getPluginContext(editor);\n\n\t\tthis.text = {\n\t\t\tbutton: window.I18n.t('js.editor.macro.embedded_table.button'),\n\t\t\tmacro_text: window.I18n.t('js.editor.macro.embedded_table.text'),\n\t\t};\n\n\t\t// Schema.\n\t\tmodel.schema.register( 'op-macro-embedded-table', {\n\t\t\tallowWhere: '$block',\n\t\t\tallowAttributes: ['opEmbeddedTableQuery'],\n\t\t\tisBlock: true,\n\t\t\tisObject: true\n\t\t});\n\n\t\tconversion.for( 'upcast' )\n\t\t\t.elementToElement( {\n\t\t\t\tview: {\n\t\t\t\t\tname: 'macro',\n\t\t\t\t\tclasses: 'embedded-table',\n\t\t\t\t},\n\t\t\t\tmodel: ( viewElement, modelWriter ) => {\n\t\t\t\t\tconst queryProps = viewElement.getAttribute( 'data-query-props' );\n\t\t\t\t\treturn modelWriter.createElement(\n\t\t\t\t\t\t'op-macro-embedded-table',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\topEmbeddedTableQuery: queryProps ? JSON.parse(queryProps) : {}\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} );\n\n\n\t\tconversion.for( 'editingDowncast' ).elementToElement( {\n\t\t\tmodel: 'op-macro-embedded-table',\n\t\t\tview: (modelElement, viewWriter) => {\n\t\t\t\treturn toEmbeddedTableWidget(this.createEmbeddedTableView(viewWriter), viewWriter, { label: this.label } )\n\t\t\t}\n\t } );\n\n\t\tconversion.for('dataDowncast').elementToElement({\n\t\t\tmodel: 'op-macro-embedded-table',\n\t\t\tview: (modelElement, viewWriter) => {\n\t\t\t\treturn this.createEmbeddedTableDataElement(modelElement, viewWriter)\n\t\t\t}\n\t\t});\n\n\t\teditor.ui.componentFactory.add( EmbeddedTableEditing.buttonName, locale => {\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\tlabel: this.text.button,\n\t\t\t\twithText: true\n\t\t\t} );\n\n\t\t\t// Callback executed once the widget is clicked.\n\t\t\tview.on( 'execute', () => pluginContext.runInZone(() => {\n\t\t\t\tconst externalQueryConfiguration = pluginContext.services.externalQueryConfiguration;\n\t\t\t\tconst currentQuery = {}; // Initial query currently empty, we may want to provide context here.\n\n\t\t\t\texternalQueryConfiguration.show(\n\t\t\t\t\tcurrentQuery,\n\t\t\t\t\t(newQuery) => editor.model.change(writer => {\n\t\t\t\t\t\tconst element = writer.createElement( 'op-macro-embedded-table', { opEmbeddedTableQuery: newQuery });\n\n\t\t\t\t\t\t// Insert the widget in the current selection location.\n\t\t\t\t\t\teditor.model.insertContent( element, editor.model.document.selection );\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t} ) );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n\n\tcreateEmbeddedTableView(writer) {\n\t\tconst placeholder = writer.createText( this.text.macro_text );\n\t\tconst container = writer.createContainerElement( 'div', { class: 'macro -embedded-table' } );\n\n\t\twriter.insert( writer.createPositionAt( container, 0 ), placeholder );\n\t\treturn container;\n\n\t\t// The following doesnt work when removing the widget...\n\t\t// let that = this;\n\t\t// return writer.createUIElement( 'div', { class: 'macro -embedded-table' }, function(containerDocument) {\n\t\t// \tconst containerElement = this.toDomElement(containerDocument);\n\t\t// \tcontainerElement.innerHTML = imageIcon + '<div class=\"macro--description\">' + that.text.macro_text + '</div>';\n\n\t\t// \treturn containerElement;\n\t\t// } );\n\t}\n\n\tcreateEmbeddedTableDataElement(modelElement, writer) {\n\t\tconst queryProps = modelElement.getAttribute('opEmbeddedTableQuery') || {};\n\t\tconst element = writer.createContainerElement(\n\t\t\t'macro',\n\t\t\t{\n\t\t\t\t'class': 'embedded-table',\n\t\t\t\t'data-query-props': JSON.stringify(queryProps)\n\t\t\t}\n\t\t);\n\n\t\treturn element;\n\t}\n\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor.data, 'ready', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n/**\n * Array of loaded plugins.\n *\n * @typedef {Array.<module:core/plugin~PluginInterface>} module:core/plugin~LoadedPlugins\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/mouseobserver\n */\n\nimport DomEventObserver from './domeventobserver';\n\n/**\n * Mouse events observer.\n *\n * Note that this observer is not available by default. To make it available it needs to be added to\n * {@link module:engine/view/view~View} by {@link module:engine/view/view~View#addObserver} method.\n *\n * @extends module:engine/view/observer/domeventobserver~DomEventObserver\n */\nexport default class MouseObserver extends DomEventObserver {\n\tconstructor( view ) {\n\t\tsuper( view );\n\n\t\tthis.domEventType = 'mousedown';\n\t}\n\n\tonDomEvent( domEvent ) {\n\t\tthis.fire( domEvent.type, domEvent );\n\t}\n}\n\n/**\n * Fired when mouse button is pressed down on one of the editables.\n *\n * Introduced by {@link module:engine/view/observer/mouseobserver~MouseObserver}.\n *\n * Note that this event is not available by default. To make it available {@link module:engine/view/observer/mouseobserver~MouseObserver}\n * needs to be added to {@link module:engine/view/view~View} by a {@link module:engine/view/view~View#addObserver} method.\n *\n * @see module:engine/view/observer/mouseobserver~MouseObserver\n * @event module:engine/view/document~Document#event:mousedown\n * @param {module:engine/view/observer/domeventdata~DomEventData} data Event data.\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module widget/widget\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport MouseObserver from '@ckeditor/ckeditor5-engine/src/view/observer/mouseobserver';\nimport { getLabel, isWidget, WIDGET_SELECTED_CLASS_NAME } from './utils';\nimport { getCode, keyCodes, parseKeystroke } from '@ckeditor/ckeditor5-utils/src/keyboard';\nimport env from '@ckeditor/ckeditor5-utils/src/env';\n\nimport '../theme/widget.css';\n\nconst selectAllKeystrokeCode = parseKeystroke( 'Ctrl+A' );\n\n/**\n * The widget plugin. It enables base support for widgets.\n *\n * See {@glink api/widget package page} for more details and documentation.\n *\n * This plugin enables multiple behaviors required by widgets:\n *\n * * The model to view selection converter for the editing pipeline (it handles widget custom selection rendering).\n * If a converted selection wraps around a widget element, that selection is marked as\n * {@link module:engine/view/selection~Selection#isFake fake}. Additionally, the `ck-widget_selected` CSS class\n * is added to indicate that widget has been selected.\n * * The mouse and keyboard events handling on and around widget elements.\n *\n * @extends module:core/plugin~Plugin.\n */\nexport default class Widget extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Widget';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst view = this.editor.editing.view;\n\t\tconst viewDocument = view.document;\n\n\t\t/**\n\t\t * Holds previously selected widgets.\n\t\t *\n\t\t * @private\n\t\t * @type {Set.<module:engine/view/element~Element>}\n\t\t */\n\t\tthis._previouslySelected = new Set();\n\n\t\t// Model to view selection converter.\n\t\t// Converts selection placed over widget element to fake selection\n\t\tthis.editor.editing.downcastDispatcher.on( 'selection', ( evt, data, conversionApi ) => {\n\t\t\t// Remove selected class from previously selected widgets.\n\t\t\tthis._clearPreviouslySelectedWidgets( conversionApi.writer );\n\n\t\t\tconst viewWriter = conversionApi.writer;\n\t\t\tconst viewSelection = viewWriter.document.selection;\n\t\t\tconst selectedElement = viewSelection.getSelectedElement();\n\t\t\tlet lastMarked = null;\n\n\t\t\tfor ( const range of viewSelection.getRanges() ) {\n\t\t\t\tfor ( const value of range ) {\n\t\t\t\t\tconst node = value.item;\n\n\t\t\t\t\t// Do not mark nested widgets in selected one. See: #57.\n\t\t\t\t\tif ( isWidget( node ) && !isChild( node, lastMarked ) ) {\n\t\t\t\t\t\tviewWriter.addClass( WIDGET_SELECTED_CLASS_NAME, node );\n\n\t\t\t\t\t\tthis._previouslySelected.add( node );\n\t\t\t\t\t\tlastMarked = node;\n\n\t\t\t\t\t\t// Check if widget is a single element selected.\n\t\t\t\t\t\tif ( node == selectedElement ) {\n\t\t\t\t\t\t\tviewWriter.setSelection( viewSelection.getRanges(), { fake: true, label: getLabel( selectedElement ) } );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\n\t\t// If mouse down is pressed on widget - create selection over whole widget.\n\t\tview.addObserver( MouseObserver );\n\t\tthis.listenTo( viewDocument, 'mousedown', ( ...args ) => this._onMousedown( ...args ) );\n\n\t\t// Handle custom keydown behaviour.\n\t\tthis.listenTo( viewDocument, 'keydown', ( ...args ) => this._onKeydown( ...args ), { priority: 'high' } );\n\n\t\t// Handle custom delete behaviour.\n\t\tthis.listenTo( viewDocument, 'delete', ( evt, data ) => {\n\t\t\tif ( this._handleDelete( data.direction == 'forward' ) ) {\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\t}\n\n\t/**\n\t * Handles {@link module:engine/view/document~Document#event:mousedown mousedown} events on widget elements.\n\t *\n\t * @private\n\t * @param {module:utils/eventinfo~EventInfo} eventInfo\n\t * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData\n\t */\n\t_onMousedown( eventInfo, domEventData ) {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\t\tlet element = domEventData.target;\n\n\t\t// Do nothing for single or double click inside nested editable.\n\t\tif ( isInsideNestedEditable( element ) ) {\n\t\t\t// But at least triple click inside nested editable causes broken selection in Safari.\n\t\t\t// For such event, we select the entire nested editable element.\n\t\t\t// See: https://github.com/ckeditor/ckeditor5/issues/1463.\n\t\t\tif ( env.isSafari && domEventData.domEvent.detail >= 3 ) {\n\t\t\t\tconst mapper = editor.editing.mapper;\n\t\t\t\tconst modelElement = mapper.toModelElement( element );\n\n\t\t\t\tthis.editor.model.change( writer => {\n\t\t\t\t\tdomEventData.preventDefault();\n\t\t\t\t\twriter.setSelection( modelElement, 'in' );\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// If target is not a widget element - check if one of the ancestors is.\n\t\tif ( !isWidget( element ) ) {\n\t\t\telement = element.findAncestor( isWidget );\n\n\t\t\tif ( !element ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tdomEventData.preventDefault();\n\n\t\t// Focus editor if is not focused already.\n\t\tif ( !viewDocument.isFocused ) {\n\t\t\tview.focus();\n\t\t}\n\n\t\t// Create model selection over widget.\n\t\tconst modelElement = editor.editing.mapper.toModelElement( element );\n\n\t\tthis._setSelectionOverElement( modelElement );\n\t}\n\n\t/**\n\t * Handles {@link module:engine/view/document~Document#event:keydown keydown} events.\n\t *\n\t * @private\n\t * @param {module:utils/eventinfo~EventInfo} eventInfo\n\t * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData\n\t */\n\t_onKeydown( eventInfo, domEventData ) {\n\t\tconst keyCode = domEventData.keyCode;\n\t\tconst isForward = keyCode == keyCodes.arrowdown || keyCode == keyCodes.arrowright;\n\t\tlet wasHandled = false;\n\n\t\t// Checks if the keys were handled and then prevents the default event behaviour and stops\n\t\t// the propagation.\n\t\tif ( isArrowKeyCode( keyCode ) ) {\n\t\t\twasHandled = this._handleArrowKeys( isForward );\n\t\t} else if ( isSelectAllKeyCode( domEventData ) ) {\n\t\t\twasHandled = this._selectAllNestedEditableContent() || this._selectAllContent();\n\t\t} else if ( keyCode === keyCodes.enter ) {\n\t\t\twasHandled = this._handleEnterKey( domEventData.shiftKey );\n\t\t}\n\n\t\tif ( wasHandled ) {\n\t\t\tdomEventData.preventDefault();\n\t\t\teventInfo.stop();\n\t\t}\n\t}\n\n\t/**\n\t * Handles delete keys: backspace and delete.\n\t *\n\t * @private\n\t * @param {Boolean} isForward Set to true if delete was performed in forward direction.\n\t * @returns {Boolean|undefined} Returns `true` if keys were handled correctly.\n\t */\n\t_handleDelete( isForward ) {\n\t\t// Do nothing when the read only mode is enabled.\n\t\tif ( this.editor.isReadOnly ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelDocument = this.editor.model.document;\n\t\tconst modelSelection = modelDocument.selection;\n\n\t\t// Do nothing on non-collapsed selection.\n\t\tif ( !modelSelection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst objectElement = this._getObjectElementNextToSelection( isForward );\n\n\t\tif ( objectElement ) {\n\t\t\tthis.editor.model.change( writer => {\n\t\t\t\tlet previousNode = modelSelection.anchor.parent;\n\n\t\t\t\t// Remove previous element if empty.\n\t\t\t\twhile ( previousNode.isEmpty ) {\n\t\t\t\t\tconst nodeToRemove = previousNode;\n\t\t\t\t\tpreviousNode = nodeToRemove.parent;\n\n\t\t\t\t\twriter.remove( nodeToRemove );\n\t\t\t\t}\n\n\t\t\t\tthis._setSelectionOverElement( objectElement );\n\t\t\t} );\n\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t/**\n\t * Handles arrow keys.\n\t *\n\t * @private\n\t * @param {Boolean} isForward Set to true if arrow key should be handled in forward direction.\n\t * @returns {Boolean|undefined} Returns `true` if keys were handled correctly.\n\t */\n\t_handleArrowKeys( isForward ) {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\t\tconst modelDocument = model.document;\n\t\tconst modelSelection = modelDocument.selection;\n\t\tconst objectElement = modelSelection.getSelectedElement();\n\n\t\t// If object element is selected.\n\t\tif ( objectElement && schema.isObject( objectElement ) ) {\n\t\t\tconst position = isForward ? modelSelection.getLastPosition() : modelSelection.getFirstPosition();\n\t\t\tconst newRange = schema.getNearestSelectionRange( position, isForward ? 'forward' : 'backward' );\n\n\t\t\tif ( newRange ) {\n\t\t\t\tmodel.change( writer => {\n\t\t\t\t\twriter.setSelection( newRange );\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\t// If selection is next to object element.\n\t\t// Return if not collapsed.\n\t\tif ( !modelSelection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst objectElement2 = this._getObjectElementNextToSelection( isForward );\n\n\t\tif ( !!objectElement2 && schema.isObject( objectElement2 ) ) {\n\t\t\tthis._setSelectionOverElement( objectElement2 );\n\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t/**\n\t * Handles the enter key, giving users and access to positions in the editable directly before\n\t * (<kbd>Shift</kbd>+<kbd>Enter</kbd>) or after (<kbd>Enter</kbd>) the selected widget.\n\t * It improves the UX, mainly when the widget is the first or last child of the root editable\n\t * and there's no other way to type after or before it.\n\t *\n\t * @private\n\t * @param {Boolean} isBackwards Set to true if the new paragraph is to be inserted before\n\t * the selected widget (<kbd>Shift</kbd>+<kbd>Enter</kbd>).\n\t * @returns {Boolean|undefined} Returns `true` if keys were handled correctly.\n\t */\n\t_handleEnterKey( isBackwards ) {\n\t\tconst model = this.editor.model;\n\t\tconst modelSelection = model.document.selection;\n\t\tconst selectedElement = modelSelection.getSelectedElement();\n\n\t\tif ( shouldInsertParagraph( selectedElement, model.schema ) ) {\n\t\t\tmodel.change( writer => {\n\t\t\t\tlet position = writer.createPositionAt( selectedElement, isBackwards ? 'before' : 'after' );\n\t\t\t\tconst paragraph = writer.createElement( 'paragraph' );\n\n\t\t\t\t// Split the parent when inside a block element.\n\t\t\t\t// https://github.com/ckeditor/ckeditor5/issues/1529\n\t\t\t\tif ( model.schema.isBlock( selectedElement.parent ) ) {\n\t\t\t\t\tconst paragraphLimit = model.schema.findAllowedParent( position, paragraph );\n\n\t\t\t\t\tposition = writer.split( position, paragraphLimit ).position;\n\t\t\t\t}\n\n\t\t\t\twriter.insert( paragraph, position );\n\t\t\t\twriter.setSelection( paragraph, 'in' );\n\t\t\t} );\n\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t/**\n\t * Extends the {@link module:engine/model/selection~Selection document's selection} to span the entire\n\t * content of the nested editable if already anchored in one.\n\t *\n\t * See: {@link module:engine/model/schema~Schema#getLimitElement}.\n\t *\n\t * @private\n\t */\n\t_selectAllNestedEditableContent() {\n\t\tconst model = this.editor.model;\n\t\tconst documentSelection = model.document.selection;\n\t\tconst limitElement = model.schema.getLimitElement( documentSelection );\n\n\t\tif ( documentSelection.getFirstRange().root == limitElement ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\twriter.setSelection( writer.createRangeIn( limitElement ) );\n\t\t} );\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Handles <kbd>CTRL + A</kbd> when widget is selected.\n\t *\n\t * @private\n\t * @returns {Boolean} Returns true if widget was selected and selecting all was handled by this method.\n\t */\n\t_selectAllContent() {\n\t\tconst model = this.editor.model;\n\t\tconst editing = this.editor.editing;\n\t\tconst view = editing.view;\n\t\tconst viewDocument = view.document;\n\t\tconst viewSelection = viewDocument.selection;\n\n\t\tconst selectedElement = viewSelection.getSelectedElement();\n\n\t\t// Only widget is selected.\n\t\t// https://github.com/ckeditor/ckeditor5-widget/issues/23\n\t\tif ( selectedElement && isWidget( selectedElement ) ) {\n\t\t\tconst widgetParent = editing.mapper.toModelElement( selectedElement.parent );\n\n\t\t\tmodel.change( writer => {\n\t\t\t\twriter.setSelection( writer.createRangeIn( widgetParent ) );\n\t\t\t} );\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Sets {@link module:engine/model/selection~Selection document's selection} over given element.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} element\n\t */\n\t_setSelectionOverElement( element ) {\n\t\tthis.editor.model.change( writer => {\n\t\t\twriter.setSelection( writer.createRangeOn( element ) );\n\t\t} );\n\t}\n\n\t/**\n\t * Checks if {@link module:engine/model/element~Element element} placed next to the current\n\t * {@link module:engine/model/selection~Selection model selection} exists and is marked in\n\t * {@link module:engine/model/schema~Schema schema} as `object`.\n\t *\n\t * @private\n\t * @param {Boolean} forward Direction of checking.\n\t * @returns {module:engine/model/element~Element|null}\n\t */\n\t_getObjectElementNextToSelection( forward ) {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\t\tconst modelSelection = model.document.selection;\n\n\t\t// Clone current selection to use it as a probe. We must leave default selection as it is so it can return\n\t\t// to its current state after undo.\n\t\tconst probe = model.createSelection( modelSelection );\n\t\tmodel.modifySelection( probe, { direction: forward ? 'forward' : 'backward' } );\n\t\tconst objectElement = forward ? probe.focus.nodeBefore : probe.focus.nodeAfter;\n\n\t\tif ( !!objectElement && schema.isObject( objectElement ) ) {\n\t\t\treturn objectElement;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Removes CSS class from previously selected widgets.\n\t *\n\t * @private\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer\n\t */\n\t_clearPreviouslySelectedWidgets( writer ) {\n\t\tfor ( const widget of this._previouslySelected ) {\n\t\t\twriter.removeClass( WIDGET_SELECTED_CLASS_NAME, widget );\n\t\t}\n\n\t\tthis._previouslySelected.clear();\n\t}\n}\n\n// Returns 'true' if provided key code represents one of the arrow keys.\n//\n// @param {Number} keyCode\n// @returns {Boolean}\nfunction isArrowKeyCode( keyCode ) {\n\treturn keyCode == keyCodes.arrowright ||\n\t\tkeyCode == keyCodes.arrowleft ||\n\t\tkeyCode == keyCodes.arrowup ||\n\t\tkeyCode == keyCodes.arrowdown;\n}\n\n// Returns 'true' if provided (DOM) key event data corresponds with the Ctrl+A keystroke.\n//\n// @param {module:engine/view/observer/keyobserver~KeyEventData} domEventData\n// @returns {Boolean}\nfunction isSelectAllKeyCode( domEventData ) {\n\treturn getCode( domEventData ) == selectAllKeystrokeCode;\n}\n\n// Returns `true` when element is a nested editable or is placed inside one.\n//\n// @param {module:engine/view/element~Element}\n// @returns {Boolean}\nfunction isInsideNestedEditable( element ) {\n\twhile ( element ) {\n\t\tif ( element.is( 'editableElement' ) && !element.is( 'rootElement' ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Click on nested widget should select it.\n\t\tif ( isWidget( element ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\telement = element.parent;\n\t}\n\n\treturn false;\n}\n\n// Checks whether the specified `element` is a child of the `parent` element.\n//\n// @param {module:engine/view/element~Element} element An element to check.\n// @param {module:engine/view/element~Element|null} parent A parent for the element.\n// @returns {Boolean}\nfunction isChild( element, parent ) {\n\tif ( !parent ) {\n\t\treturn false;\n\t}\n\n\treturn Array.from( element.getAncestors() ).includes( parent );\n}\n\n// Checks if enter key should insert paragraph. This should be done only on elements of type object (excluding inline objects).\n//\n// @param {module:engine/model/element~Element} element And element to check.\n// @param {module:engine/model/schema~Schema} schema\nfunction shouldInsertParagraph( element, schema ) {\n\treturn element && schema.isObject( element ) && !schema.isInline( element );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor.data, 'ready', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n/**\n * Array of loaded plugins.\n *\n * @typedef {Array.<module:core/plugin~PluginInterface>} module:core/plugin~LoadedPlugins\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/position\n */\n\nimport global from './global';\nimport Rect from './rect';\nimport getPositionedAncestor from './getpositionedancestor';\nimport getBorderWidths from './getborderwidths';\nimport { isFunction } from 'lodash-es';\n\n/**\n * Calculates the `position: absolute` coordinates of a given element so it can be positioned with respect to the\n * target in the visually most efficient way, taking various restrictions like viewport or limiter geometry\n * into consideration.\n *\n *\t\t// The element which is to be positioned.\n *\t\tconst element = document.body.querySelector( '#toolbar' );\n *\n *\t\t// A target to which the element is positioned relatively.\n *\t\tconst target = document.body.querySelector( '#container' );\n *\n *\t\t// Finding the optimal coordinates for the positioning.\n *\t\tconst { left, top, name } = getOptimalPosition( {\n *\t\t\telement: element,\n *\t\t\ttarget: target,\n *\n * \t\t\t// The algorithm will chose among these positions to meet the requirements such\n * \t\t\t// as \"limiter\" element or \"fitInViewport\", set below. The positions are considered\n * \t\t\t// in the order of the array.\n *\t\t\tpositions: [\n *\t\t\t\t//\n *\t\t\t \t//\t[ Target ]\n *\t\t\t\t//\t+-----------------+\n *\t\t\t\t//\t| Element |\n *\t\t\t\t//\t+-----------------+\n *\t\t\t\t//\n *\t\t\t\ttargetRect => ( {\n *\t\t\t\t\ttop: targetRect.bottom,\n *\t\t\t\t\tleft: targetRect.left,\n *\t\t\t\t\tname: 'mySouthEastPosition'\n *\t\t\t\t} ),\n *\n *\t\t\t\t//\n *\t\t\t\t//\t+-----------------+\n *\t\t\t\t//\t| Element |\n *\t\t\t\t//\t+-----------------+\n *\t\t\t\t//\t[ Target ]\n *\t\t\t\t//\n *\t\t\t\t( targetRect, elementRect ) => ( {\n *\t\t\t\t\ttop: targetRect.top - elementRect.height,\n *\t\t\t\t\tleft: targetRect.left,\n *\t\t\t\t\tname: 'myNorthEastPosition'\n *\t\t\t\t} )\n *\t\t\t],\n *\n *\t\t\t// Find a position such guarantees the element remains within visible boundaries of <body>.\n *\t\t\tlimiter: document.body,\n *\n *\t\t\t// Find a position such guarantees the element remains within visible boundaries of the browser viewport.\n *\t\t\tfitInViewport: true\n *\t\t} );\n *\n *\t\t// The best position which fits into document.body and the viewport. May be useful\n *\t\t// to set proper class on the `element`.\n *\t\tconsole.log( name ); // -> \"myNorthEastPosition\"\n *\n *\t\t// Using the absolute coordinates which has been found to position the element\n *\t\t// as in the diagram depicting the \"myNorthEastPosition\" position.\n *\t\telement.style.top = top;\n *\t\telement.style.left = left;\n *\n * @param {module:utils/dom/position~Options} options Positioning options object.\n * @returns {module:utils/dom/position~Position}\n */\nexport function getOptimalPosition( { element, target, positions, limiter, fitInViewport } ) {\n\t// If the {@link module:utils/dom/position~Options#target} is a function, use what it returns.\n\t// https://github.com/ckeditor/ckeditor5-utils/issues/157\n\tif ( isFunction( target ) ) {\n\t\ttarget = target();\n\t}\n\n\t// If the {@link module:utils/dom/position~Options#limiter} is a function, use what it returns.\n\t// https://github.com/ckeditor/ckeditor5-ui/issues/260\n\tif ( isFunction( limiter ) ) {\n\t\tlimiter = limiter();\n\t}\n\n\tconst positionedElementAncestor = getPositionedAncestor( element.parentElement );\n\tconst elementRect = new Rect( element );\n\tconst targetRect = new Rect( target );\n\n\tlet bestPosition;\n\tlet name;\n\n\t// If there are no limits, just grab the very first position and be done with that drama.\n\tif ( !limiter && !fitInViewport ) {\n\t\t[ name, bestPosition ] = getPosition( positions[ 0 ], targetRect, elementRect );\n\t} else {\n\t\tconst limiterRect = limiter && new Rect( limiter ).getVisible();\n\t\tconst viewportRect = fitInViewport && new Rect( global.window );\n\n\t\t[ name, bestPosition ] =\n\t\t\tgetBestPosition( positions, targetRect, elementRect, limiterRect, viewportRect ) ||\n\t\t\t// If there's no best position found, i.e. when all intersections have no area because\n\t\t\t// rects have no width or height, then just use the first available position.\n\t\t\tgetPosition( positions[ 0 ], targetRect, elementRect );\n\t}\n\n\tlet { left, top } = getAbsoluteRectCoordinates( bestPosition );\n\n\tif ( positionedElementAncestor ) {\n\t\tconst ancestorPosition = getAbsoluteRectCoordinates( new Rect( positionedElementAncestor ) );\n\t\tconst ancestorBorderWidths = getBorderWidths( positionedElementAncestor );\n\n\t\t// (https://github.com/ckeditor/ckeditor5-ui-default/issues/126)\n\t\t// If there's some positioned ancestor of the panel, then its `Rect` must be taken into\n\t\t// consideration. `Rect` is always relative to the viewport while `position: absolute` works\n\t\t// with respect to that positioned ancestor.\n\t\tleft -= ancestorPosition.left;\n\t\ttop -= ancestorPosition.top;\n\n\t\t// (https://github.com/ckeditor/ckeditor5-utils/issues/139)\n\t\t// If there's some positioned ancestor of the panel, not only its position must be taken into\n\t\t// consideration (see above) but also its internal scrolls. Scroll have an impact here because `Rect`\n\t\t// is relative to the viewport (it doesn't care about scrolling), while `position: absolute`\n\t\t// must compensate that scrolling.\n\t\tleft += positionedElementAncestor.scrollLeft;\n\t\ttop += positionedElementAncestor.scrollTop;\n\n\t\t// (https://github.com/ckeditor/ckeditor5-utils/issues/139)\n\t\t// If there's some positioned ancestor of the panel, then its `Rect` includes its CSS `borderWidth`\n\t\t// while `position: absolute` positioning does not consider it.\n\t\t// E.g. `{ position: absolute, top: 0, left: 0 }` means upper left corner of the element,\n\t\t// not upper-left corner of its border.\n\t\tleft -= ancestorBorderWidths.left;\n\t\ttop -= ancestorBorderWidths.top;\n\t}\n\n\treturn { left, top, name };\n}\n\n// For given position function, returns a corresponding `Rect` instance.\n//\n// @private\n// @param {Function} position A function returning {@link module:utils/dom/position~Position}.\n// @param {utils/dom/rect~Rect} targetRect A rect of the target.\n// @param {utils/dom/rect~Rect} elementRect A rect of positioned element.\n// @returns {Array} An array containing position name and its Rect.\nfunction getPosition( position, targetRect, elementRect ) {\n\tconst { left, top, name } = position( targetRect, elementRect );\n\n\treturn [ name, elementRect.clone().moveTo( left, top ) ];\n}\n\n// For a given array of positioning functions, returns such that provides the best\n// fit of the `elementRect` into the `limiterRect` and `viewportRect`.\n//\n// @private\n// @param {module:utils/dom/position~Options#positions} positions Functions returning\n// {@link module:utils/dom/position~Position} to be checked, in the order of preference.\n// @param {utils/dom/rect~Rect} targetRect A rect of the {@link module:utils/dom/position~Options#target}.\n// @param {utils/dom/rect~Rect} elementRect A rect of positioned {@link module:utils/dom/position~Options#element}.\n// @param {utils/dom/rect~Rect} limiterRect A rect of the {@link module:utils/dom/position~Options#limiter}.\n// @param {utils/dom/rect~Rect} viewportRect A rect of the viewport.\n// @returns {Array} An array containing the name of the position and it's rect.\nfunction getBestPosition( positions, targetRect, elementRect, limiterRect, viewportRect ) {\n\tlet maxLimiterIntersectArea = 0;\n\tlet maxViewportIntersectArea = 0;\n\tlet bestPositionRect;\n\tlet bestPositionName;\n\n\t// This is when element is fully visible.\n\tconst elementRectArea = elementRect.getArea();\n\n\tpositions.some( position => {\n\t\tconst [ positionName, positionRect ] = getPosition( position, targetRect, elementRect );\n\t\tlet limiterIntersectArea;\n\t\tlet viewportIntersectArea;\n\n\t\tif ( limiterRect ) {\n\t\t\tif ( viewportRect ) {\n\t\t\t\t// Consider only the part of the limiter which is visible in the viewport. So the limiter is getting limited.\n\t\t\t\tconst limiterViewportIntersectRect = limiterRect.getIntersection( viewportRect );\n\n\t\t\t\tif ( limiterViewportIntersectRect ) {\n\t\t\t\t\t// If the limiter is within the viewport, then check the intersection between that part of the\n\t\t\t\t\t// limiter and actual position.\n\t\t\t\t\tlimiterIntersectArea = limiterViewportIntersectRect.getIntersectionArea( positionRect );\n\t\t\t\t} else {\n\t\t\t\t\tlimiterIntersectArea = 0;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlimiterIntersectArea = limiterRect.getIntersectionArea( positionRect );\n\t\t\t}\n\t\t}\n\n\t\tif ( viewportRect ) {\n\t\t\tviewportIntersectArea = viewportRect.getIntersectionArea( positionRect );\n\t\t}\n\n\t\t// The only criterion: intersection with the viewport.\n\t\tif ( viewportRect && !limiterRect ) {\n\t\t\tif ( viewportIntersectArea > maxViewportIntersectArea ) {\n\t\t\t\tsetBestPosition();\n\t\t\t}\n\t\t}\n\t\t// The only criterion: intersection with the limiter.\n\t\telse if ( !viewportRect && limiterRect ) {\n\t\t\tif ( limiterIntersectArea > maxLimiterIntersectArea ) {\n\t\t\t\tsetBestPosition();\n\t\t\t}\n\t\t}\n\t\t// Two criteria: intersection with the viewport and the limiter visible in the viewport.\n\t\telse {\n\t\t\tif ( viewportIntersectArea > maxViewportIntersectArea && limiterIntersectArea >= maxLimiterIntersectArea ) {\n\t\t\t\tsetBestPosition();\n\t\t\t} else if ( viewportIntersectArea >= maxViewportIntersectArea && limiterIntersectArea > maxLimiterIntersectArea ) {\n\t\t\t\tsetBestPosition();\n\t\t\t}\n\t\t}\n\n\t\tfunction setBestPosition() {\n\t\t\tmaxViewportIntersectArea = viewportIntersectArea;\n\t\t\tmaxLimiterIntersectArea = limiterIntersectArea;\n\t\t\tbestPositionRect = positionRect;\n\t\t\tbestPositionName = positionName;\n\t\t}\n\n\t\t// If a such position is found that element is fully container by the limiter then, obviously,\n\t\t// there will be no better one, so finishing.\n\t\treturn limiterIntersectArea === elementRectArea;\n\t} );\n\n\treturn bestPositionRect ? [ bestPositionName, bestPositionRect ] : null;\n}\n\n// DOMRect (also Rect) works in a scroll–independent geometry but `position: absolute` doesn't.\n// This function converts Rect to `position: absolute` coordinates.\n//\n// @private\n// @param {utils/dom/rect~Rect} rect A rect to be converted.\n// @returns {Object} Object containing `left` and `top` properties, in absolute coordinates.\nfunction getAbsoluteRectCoordinates( { left, top } ) {\n\tconst { scrollX, scrollY } = global.window;\n\n\treturn {\n\t\tleft: left + scrollX,\n\t\ttop: top + scrollY,\n\t};\n}\n\n/**\n * The `getOptimalPosition` helper options.\n *\n * @interface module:utils/dom/position~Options\n */\n\n/**\n * Element that is to be positioned.\n *\n * @member {HTMLElement} #element\n */\n\n/**\n * Target with respect to which the `element` is to be positioned.\n *\n * @member {HTMLElement|Range|ClientRect|Rect|Function} #target\n */\n\n/**\n * An array of functions which return {@link module:utils/dom/position~Position} relative\n * to the `target`, in the order of preference.\n *\n * @member {Array.<Function>} #positions\n */\n\n/**\n * When set, the algorithm will chose position which fits the most in the\n * limiter's bounding rect.\n *\n * @member {HTMLElement|Range|ClientRect|Rect|Function} #limiter\n */\n\n/**\n * When set, the algorithm will chose such a position which fits `element`\n * the most inside visible viewport.\n *\n * @member {Boolean} #fitInViewport\n */\n\n/**\n * An object describing a position in `position: absolute` coordinate\n * system, along with position name.\n *\n * @typedef {Object} module:utils/dom/position~Position\n *\n * @property {Number} top Top position offset.\n * @property {Number} left Left position offset.\n * @property {String} name Name of the position.\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/dom/getpositionedancestor\n */\n\nimport global from './global';\n\n/**\n * For a given element, returns the nearest ancestor element which CSS position is not \"static\".\n *\n * @param {HTMLElement} element The native DOM element to be checked.\n * @returns {HTMLElement|null}\n */\nexport default function getPositionedAncestor( element ) {\n\twhile ( element && element.tagName.toLowerCase() != 'html' ) {\n\t\tif ( global.window.getComputedStyle( element ).position != 'static' ) {\n\t\t\treturn element;\n\t\t}\n\n\t\telement = element.parentElement;\n\t}\n\n\treturn null;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/panel/balloon/balloonpanelview\n */\n\nimport View from '../../view';\nimport { getOptimalPosition } from '@ckeditor/ckeditor5-utils/src/dom/position';\nimport isRange from '@ckeditor/ckeditor5-utils/src/dom/isrange';\nimport toUnit from '@ckeditor/ckeditor5-utils/src/dom/tounit';\nimport global from '@ckeditor/ckeditor5-utils/src/dom/global';\nimport { isElement } from 'lodash-es';\n\nimport '../../../theme/components/panel/balloonpanel.css';\n\nconst toPx = toUnit( 'px' );\nconst defaultLimiterElement = global.document.body;\n\n/**\n * The balloon panel view class.\n *\n * A floating container which can\n * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#pin pin} to any\n * {@link module:utils/dom/position~Options#target target} in DOM and remain in that position\n * e.g. when the web page is scrolled.\n *\n * The balloon panel can be used to display contextual, non-blocking UI like forms, toolbars and\n * the like in its {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#content} view\n * collection.\n *\n * There is a number of {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}\n * that the balloon can use, automatically switching from one to another when the viewport space becomes\n * scarce to keep the balloon visible to the user as long as it is possible. The balloon will also\n * accept any custom position set provided by the user compatible with the\n * {@link module:utils/dom/position~Options options}.\n *\n *\t\tconst panel = new BalloonPanelView( locale );\n *\t\tconst childView = new ChildView();\n *\t\tconst positions = BalloonPanelView.defaultPositions;\n *\n *\t\tpanel.render();\n *\n *\t\t// Add a child view to the panel's content collection.\n *\t\tpanel.content.add( childView );\n *\n *\t\t// Start pinning the panel to an element with the \"target\" id DOM.\n *\t\t// The balloon will remain pinned until unpin() is called.\n *\t\tpanel.pin( {\n *\t\t\ttarget: document.querySelector( '#target' ),\n *\t\t\tpositions: [\n *\t\t\t\tpositions.northArrowSouth,\n *\t\t\t\tpositions.southArrowNorth\n *\t\t\t]\n *\t\t} );\n *\n * @extends module:ui/view~View\n */\nexport default class BalloonPanelView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * The absolute top position of the balloon panel in pixels.\n\t\t *\n\t\t * @observable\n\t\t * @default 0\n\t\t * @member {Number} #top\n\t\t */\n\t\tthis.set( 'top', 0 );\n\n\t\t/**\n\t\t * The absolute left position of the balloon panel in pixels.\n\t\t *\n\t\t * @observable\n\t\t * @default 0\n\t\t * @member {Number} #left\n\t\t */\n\t\tthis.set( 'left', 0 );\n\n\t\t/**\n\t\t * Balloon panel's current position. The position name is reflected in the CSS class set\n\t\t * to the balloon, i.e. `.ck-balloon-panel_arrow_nw` for \"arrow_nw\" position. The class\n\t\t * controls the minor aspects of the balloon's visual appearance like placement\n\t\t * of an {@link #withArrow arrow}. To support a new position, an additional CSS must be created.\n\t\t *\n\t\t * Default position names correspond with\n\t\t * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}.\n\t\t *\n\t\t * See the {@link #attachTo} and {@link #pin} methods to learn about custom balloon positions.\n\t\t *\n\t\t * @observable\n\t\t * @default 'arrow_nw'\n\t\t * @member {'arrow_nw'|'arrow_ne'|'arrow_sw'|'arrow_se'} #position\n\t\t */\n\t\tthis.set( 'position', 'arrow_nw' );\n\n\t\t/**\n\t\t * Controls whether the balloon panel is visible or not.\n\t\t *\n\t\t * @observable\n\t\t * @default false\n\t\t * @member {Boolean} #isVisible\n\t\t */\n\t\tthis.set( 'isVisible', false );\n\n\t\t/**\n\t\t * Controls whether the balloon panel has an arrow. The presence of the arrow\n\t\t * is reflected in `ck-balloon-panel_with-arrow` CSS class.\n\t\t *\n\t\t * @observable\n\t\t * @default true\n\t\t * @member {Boolean} #withArrow\n\t\t */\n\t\tthis.set( 'withArrow', true );\n\n\t\t/**\n\t\t * An additional CSS class added to the {@link #element}.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #class\n\t\t */\n\t\tthis.set( 'class' );\n\n\t\t/**\n\t\t * A callback that starts pining the panel when {@link #isVisible} gets\n\t\t * `true`. Used by {@link #pin}.\n\t\t *\n\t\t * @private\n\t\t * @member {Function} #_pinWhenIsVisibleCallback\n\t\t */\n\n\t\t/**\n\t\t * Collection of the child views which creates balloon panel contents.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.content = this.createCollection();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-balloon-panel',\n\t\t\t\t\tbind.to( 'position', value => `ck-balloon-panel_${ value }` ),\n\t\t\t\t\tbind.if( 'isVisible', 'ck-balloon-panel_visible' ),\n\t\t\t\t\tbind.if( 'withArrow', 'ck-balloon-panel_with-arrow' ),\n\t\t\t\t\tbind.to( 'class' )\n\t\t\t\t],\n\n\t\t\t\tstyle: {\n\t\t\t\t\ttop: bind.to( 'top', toPx ),\n\t\t\t\t\tleft: bind.to( 'left', toPx )\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tchildren: this.content\n\t\t} );\n\t}\n\n\t/**\n\t * Shows the panel.\n\t *\n\t * See {@link #isVisible}.\n\t */\n\tshow() {\n\t\tthis.isVisible = true;\n\t}\n\n\t/**\n\t * Hides the panel.\n\t *\n\t * See {@link #isVisible}.\n\t */\n\thide() {\n\t\tthis.isVisible = false;\n\t}\n\n\t/**\n\t * Attaches the panel to a specified {@link module:utils/dom/position~Options#target} with a\n\t * smart positioning heuristics that choses from available positions to make sure the panel\n\t * is visible to the user i.e. within the limits of the viewport.\n\t *\n\t * This method accepts configuration {@link module:utils/dom/position~Options options}\n\t * to set the `target`, optional `limiter` and `positions` the balloon should chose from.\n\t *\n\t *\t\tconst panel = new BalloonPanelView( locale );\n\t *\t\tconst positions = BalloonPanelView.defaultPositions;\n\t *\n\t *\t\tpanel.render();\n\t *\n\t *\t\t// Attach the panel to an element with the \"target\" id DOM.\n\t *\t\tpanel.attachTo( {\n\t *\t\t\ttarget: document.querySelector( '#target' ),\n\t *\t\t\tpositions: [\n\t *\t\t\t\tpositions.northArrowSouth,\n\t *\t\t\t\tpositions.southArrowNorth\n\t *\t\t\t]\n\t *\t\t} );\n\t *\n\t * **Note**: Attaching the panel will also automatically {@link #show} it.\n\t *\n\t * **Note**: An attached panel will not follow its target when the window is scrolled or resized.\n\t * See the {@link #pin} method for more permanent positioning strategy.\n\t *\n\t * @param {module:utils/dom/position~Options} options Positioning options compatible with\n\t * {@link module:utils/dom/position~getOptimalPosition}. Default `positions` array is\n\t * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}.\n\t */\n\tattachTo( options ) {\n\t\tthis.show();\n\n\t\tconst defaultPositions = BalloonPanelView.defaultPositions;\n\t\tconst positionOptions = Object.assign( {}, {\n\t\t\telement: this.element,\n\t\t\tpositions: [\n\t\t\t\tdefaultPositions.southArrowNorth,\n\t\t\t\tdefaultPositions.southArrowNorthWest,\n\t\t\t\tdefaultPositions.southArrowNorthEast,\n\t\t\t\tdefaultPositions.northArrowSouth,\n\t\t\t\tdefaultPositions.northArrowSouthWest,\n\t\t\t\tdefaultPositions.northArrowSouthEast\n\t\t\t],\n\t\t\tlimiter: defaultLimiterElement,\n\t\t\tfitInViewport: true\n\t\t}, options );\n\n\t\tconst { top, left, name: position } = BalloonPanelView._getOptimalPosition( positionOptions );\n\n\t\tObject.assign( this, { top, left, position } );\n\t}\n\n\t/**\n\t * Works the same way as the {@link #attachTo} method except that the position of the panel is\n\t * continuously updated when:\n\t *\n\t * * any ancestor of the {@link module:utils/dom/position~Options#target}\n\t * or {@link module:utils/dom/position~Options#limiter} is scrolled,\n\t * * the browser window gets resized or scrolled.\n\t *\n\t * Thanks to that, the panel always sticks to the {@link module:utils/dom/position~Options#target},\n\t * immune to the changing environment.\n\t *\n\t *\t\tconst panel = new BalloonPanelView( locale );\n\t *\t\tconst positions = BalloonPanelView.defaultPositions;\n\t *\n\t *\t\tpanel.render();\n\t *\n\t *\t\t// Pin the panel to an element with the \"target\" id DOM.\n\t *\t\tpanel.pin( {\n\t *\t\t\ttarget: document.querySelector( '#target' ),\n\t *\t\t\tpositions: [\n\t *\t\t\t\tpositions.northArrowSouth,\n\t *\t\t\t\tpositions.southArrowNorth\n\t *\t\t\t]\n\t *\t\t} );\n\t *\n\t * To leave the pinned state, use the {@link #unpin} method.\n\t *\n\t * **Note**: Pinning the panel will also automatically {@link #show} it.\n\t *\n\t * @param {module:utils/dom/position~Options} options Positioning options compatible with\n\t * {@link module:utils/dom/position~getOptimalPosition}. Default `positions` array is\n\t * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}.\n\t */\n\tpin( options ) {\n\t\tthis.unpin();\n\n\t\tthis._pinWhenIsVisibleCallback = () => {\n\t\t\tif ( this.isVisible ) {\n\t\t\t\tthis._startPinning( options );\n\t\t\t} else {\n\t\t\t\tthis._stopPinning();\n\t\t\t}\n\t\t};\n\n\t\tthis._startPinning( options );\n\n\t\t// Control the state of the listeners depending on whether the panel is visible\n\t\t// or not.\n\t\t// TODO: Use on() (https://github.com/ckeditor/ckeditor5-utils/issues/144).\n\t\tthis.listenTo( this, 'change:isVisible', this._pinWhenIsVisibleCallback );\n\t}\n\n\t/**\n\t * Stops pinning the panel, as set up by {@link #pin}.\n\t */\n\tunpin() {\n\t\tif ( this._pinWhenIsVisibleCallback ) {\n\t\t\t// Deactivate listeners attached by pin().\n\t\t\tthis._stopPinning();\n\n\t\t\t// Deactivate the panel pin() control logic.\n\t\t\t// TODO: Use off() (https://github.com/ckeditor/ckeditor5-utils/issues/144).\n\t\t\tthis.stopListening( this, 'change:isVisible', this._pinWhenIsVisibleCallback );\n\n\t\t\tthis._pinWhenIsVisibleCallback = null;\n\n\t\t\tthis.hide();\n\t\t}\n\t}\n\n\t/**\n\t * Starts managing the pinned state of the panel. See {@link #pin}.\n\t *\n\t * @private\n\t * @param {module:utils/dom/position~Options} options Positioning options compatible with\n\t * {@link module:utils/dom/position~getOptimalPosition}.\n\t */\n\t_startPinning( options ) {\n\t\tthis.attachTo( options );\n\n\t\tconst targetElement = getDomElement( options.target );\n\t\tconst limiterElement = options.limiter ? getDomElement( options.limiter ) : defaultLimiterElement;\n\n\t\t// Then we need to listen on scroll event of eny element in the document.\n\t\tthis.listenTo( global.document, 'scroll', ( evt, domEvt ) => {\n\t\t\tconst scrollTarget = domEvt.target;\n\n\t\t\t// The position needs to be updated if the positioning target is within the scrolled element.\n\t\t\tconst isWithinScrollTarget = targetElement && scrollTarget.contains( targetElement );\n\n\t\t\t// The position needs to be updated if the positioning limiter is within the scrolled element.\n\t\t\tconst isLimiterWithinScrollTarget = limiterElement && scrollTarget.contains( limiterElement );\n\n\t\t\t// The positioning target and/or limiter can be a Rect, object etc..\n\t\t\t// There's no way to optimize the listener then.\n\t\t\tif ( isWithinScrollTarget || isLimiterWithinScrollTarget || !targetElement || !limiterElement ) {\n\t\t\t\tthis.attachTo( options );\n\t\t\t}\n\t\t}, { useCapture: true } );\n\n\t\t// We need to listen on window resize event and update position.\n\t\tthis.listenTo( global.window, 'resize', () => {\n\t\t\tthis.attachTo( options );\n\t\t} );\n\t}\n\n\t/**\n\t * Stops managing the pinned state of the panel. See {@link #pin}.\n\t *\n\t * @private\n\t */\n\t_stopPinning() {\n\t\tthis.stopListening( global.document, 'scroll' );\n\t\tthis.stopListening( global.window, 'resize' );\n\t}\n}\n\n// Returns the DOM element for given object or null, if there's none,\n// e.g. when passed object is a Rect instance or so.\n//\n// @private\n// @param {*} object\n// @returns {HTMLElement|null}\nfunction getDomElement( object ) {\n\tif ( isElement( object ) ) {\n\t\treturn object;\n\t}\n\n\tif ( isRange( object ) ) {\n\t\treturn object.commonAncestorContainer;\n\t}\n\n\tif ( typeof object == 'function' ) {\n\t\treturn getDomElement( object() );\n\t}\n\n\treturn null;\n}\n\n/**\n * A horizontal offset of the arrow tip from the edge of the balloon. Controlled by CSS.\n *\n *\t\t +-----|---------...\n *\t\t | |\n *\t\t | |\n *\t\t | |\n *\t\t | |\n *\t\t +--+ | +------...\n *\t\t \\ | /\n *\t\t \\|/\n *\t >|-----|<---------------- horizontal offset\n *\n * @default 30\n * @member {Number} module:ui/panel/balloon/balloonpanelview~BalloonPanelView.arrowHorizontalOffset\n */\nBalloonPanelView.arrowHorizontalOffset = 25;\n\n/**\n * A vertical offset of the arrow from the edge of the balloon. Controlled by CSS.\n *\n *\t\t +-------------...\n *\t\t |\n *\t\t |\n *\t\t | /-- vertical offset\n *\t\t | V\n *\t\t +--+ +-----... ---------\n *\t\t \\ / |\n *\t\t \\/ |\n *\t\t-------------------------------\n *\t\t ^\n *\n * @default 15\n * @member {Number} module:ui/panel/balloon/balloonpanelview~BalloonPanelView.arrowVerticalOffset\n */\nBalloonPanelView.arrowVerticalOffset = 10;\n\n/**\n * Function used to calculate the optimal position for the balloon.\n *\n * @protected\n * @member {Function} module:ui/panel/balloon/balloonpanelview~BalloonPanelView._getOptimalPosition\n */\nBalloonPanelView._getOptimalPosition = getOptimalPosition;\n\n/**\n * A default set of positioning functions used by the balloon panel view\n * when attaching using {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#attachTo} method.\n *\n * The available positioning functions are as follow:\n *\n * **North**\n *\n * * `northArrowSouth`\n *\n * \t\t+-----------------+\n * \t\t| Balloon |\n * \t\t+-----------------+\n * \t\t V\n * \t\t [ Target ]\n *\n * * `northArrowSouthEast`\n *\n * \t\t+-----------------+\n * \t\t| Balloon |\n * \t\t+-----------------+\n * \t\t V\n * \t\t [ Target ]\n *\n * * `northArrowSouthWest`\n *\n * \t\t +-----------------+\n * \t\t | Balloon |\n * \t\t +-----------------+\n * \t\t V\n * \t\t[ Target ]\n *\n * **North west**\n *\n * * `northWestArrowSouth`\n *\n * \t\t+-----------------+\n * \t\t| Balloon |\n * \t\t+-----------------+\n * \t\t V\n * \t\t [ Target ]\n *\n * * `northWestArrowSouthWest`\n *\n * \t\t+-----------------+\n * \t\t| Balloon |\n * \t\t+-----------------+\n * \t\t V\n * \t\t [ Target ]\n *\n * * `northWestArrowSouthEast`\n *\n * \t\t+-----------------+\n * \t\t| Balloon |\n * \t\t+-----------------+\n * \t\t V\n * \t\t [ Target ]\n *\n * **North east**\n *\n * * `northEastArrowSouth`\n *\n * \t\t+-----------------+\n * \t\t| Balloon |\n * \t\t+-----------------+\n * \t\t V\n * \t\t[ Target ]\n *\n * * `northEastArrowSouthEast`\n *\n * \t\t+-----------------+\n * \t\t| Balloon |\n * \t\t+-----------------+\n * \t\t V\n * \t\t [ Target ]\n *\n * * `northEastArrowSouthWest`\n *\n * \t\t +-----------------+\n * \t\t | Balloon |\n * \t\t +-----------------+\n * \t\t V\n * \t\t[ Target ]\n *\n * **South**\n *\n * * `southArrowNorth`\n *\n *\t\t [ Target ]\n *\t\t ^\n *\t\t+-----------------+\n *\t\t| Balloon |\n *\t\t+-----------------+\n *\n * * `southArrowNorthEast`\n *\n *\t\t [ Target ]\n *\t\t ^\n *\t\t+-----------------+\n *\t\t| Balloon |\n *\t\t+-----------------+\n *\n * * `southArrowNorthWest`\n *\n *\t\t[ Target ]\n *\t\t ^\n *\t\t +-----------------+\n *\t\t | Balloon |\n *\t\t +-----------------+\n *\n * **South west**\n *\n * * `southWestArrowNorth`\n *\n *\t\t [ Target ]\n *\t\t ^\n *\t\t+-----------------+\n *\t\t| Balloon |\n *\t\t+-----------------+\n *\n * * `southWestArrowNorthWest`\n *\n *\t\t [ Target ]\n *\t\t ^\n *\t\t+-----------------+\n *\t\t| Balloon |\n *\t\t+-----------------+\n *\n * * `southWestArrowNorthEast`\n *\n *\t\t [ Target ]\n *\t\t ^\n *\t\t+-----------------+\n *\t\t| Balloon |\n *\t\t+-----------------+\n *\n * **South east**\n *\n * * `southEastArrowNorth`\n *\n *\t\t[ Target ]\n *\t\t ^\n *\t\t+-----------------+\n *\t\t| Balloon |\n *\t\t+-----------------+\n *\n * * `southEastArrowNorthEast`\n *\n *\t\t [ Target ]\n *\t\t ^\n *\t\t+-----------------+\n *\t\t| Balloon |\n *\t\t+-----------------+\n *\n * * `southEastArrowNorthWest`\n *\n *\t\t[ Target ]\n *\t\t ^\n *\t\t +-----------------+\n *\t\t | Balloon |\n *\t\t +-----------------+\n *\n * See {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#attachTo}.\n *\n * Positioning functions must be compatible with {@link module:utils/dom/position~Position}.\n *\n * The name that position function returns will be reflected in balloon panel's class that\n * controls the placement of the \"arrow\". See {@link #position} to learn more.\n *\n * @member {Object} module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions\n */\nBalloonPanelView.defaultPositions = {\n\t// ------- North\n\n\tnorthArrowSouth: ( targetRect, balloonRect ) => ( {\n\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left + targetRect.width / 2 - balloonRect.width / 2,\n\t\tname: 'arrow_s'\n\t} ),\n\n\tnorthArrowSouthEast: ( targetRect, balloonRect ) => ( {\n\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left + targetRect.width / 2 - balloonRect.width + BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_se'\n\t} ),\n\n\tnorthArrowSouthWest: ( targetRect, balloonRect ) => ( {\n\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left + targetRect.width / 2 - BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_sw'\n\t} ),\n\n\t// ------- North west\n\n\tnorthWestArrowSouth: ( targetRect, balloonRect ) => ( {\n\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left - balloonRect.width / 2,\n\t\tname: 'arrow_s'\n\t} ),\n\n\tnorthWestArrowSouthWest: ( targetRect, balloonRect ) => ( {\n\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left - BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_sw'\n\t} ),\n\n\tnorthWestArrowSouthEast: ( targetRect, balloonRect ) => ( {\n\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left - balloonRect.width + BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_se'\n\t} ),\n\n\t// ------- North east\n\n\tnorthEastArrowSouth: ( targetRect, balloonRect ) => ( {\n\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.right - balloonRect.width / 2,\n\t\tname: 'arrow_s'\n\t} ),\n\n\tnorthEastArrowSouthEast: ( targetRect, balloonRect ) => ( {\n\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.right - balloonRect.width + BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_se'\n\t} ),\n\n\tnorthEastArrowSouthWest: ( targetRect, balloonRect ) => ( {\n\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.right - BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_sw'\n\t} ),\n\n\t// ------- South\n\n\tsouthArrowNorth: ( targetRect, balloonRect ) => ( {\n\t\ttop: getSouthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left + targetRect.width / 2 - balloonRect.width / 2,\n\t\tname: 'arrow_n'\n\t} ),\n\n\tsouthArrowNorthEast: ( targetRect, balloonRect ) => ( {\n\t\ttop: getSouthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left + targetRect.width / 2 - balloonRect.width + BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_ne'\n\t} ),\n\n\tsouthArrowNorthWest: ( targetRect, balloonRect ) => ( {\n\t\ttop: getSouthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left + targetRect.width / 2 - BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_nw'\n\t} ),\n\n\t// ------- South west\n\n\tsouthWestArrowNorth: ( targetRect, balloonRect ) => ( {\n\t\ttop: getSouthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left - balloonRect.width / 2,\n\t\tname: 'arrow_n'\n\t} ),\n\n\tsouthWestArrowNorthWest: ( targetRect, balloonRect ) => ( {\n\t\ttop: getSouthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left - BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_nw'\n\t} ),\n\n\tsouthWestArrowNorthEast: ( targetRect, balloonRect ) => ( {\n\t\ttop: getSouthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.left - balloonRect.width + BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_ne'\n\t} ),\n\n\t// ------- South east\n\n\tsouthEastArrowNorth: ( targetRect, balloonRect ) => ( {\n\t\ttop: getSouthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.right - balloonRect.width / 2,\n\t\tname: 'arrow_n'\n\t} ),\n\n\tsouthEastArrowNorthEast: ( targetRect, balloonRect ) => ( {\n\t\ttop: getSouthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.right - balloonRect.width + BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_ne'\n\t} ),\n\n\tsouthEastArrowNorthWest: ( targetRect, balloonRect ) => ( {\n\t\ttop: getSouthTop( targetRect, balloonRect ),\n\t\tleft: targetRect.right - BalloonPanelView.arrowHorizontalOffset,\n\t\tname: 'arrow_nw'\n\t} ),\n};\n\n// Returns the top coordinate for positions starting with `north*`.\n//\n// @private\n// @param {utils/dom/rect~Rect} targetRect A rect of the target.\n// @param {utils/dom/rect~Rect} elementRect A rect of the balloon.\n// @returns {Number}\nfunction getNorthTop( targetRect, balloonRect ) {\n\treturn targetRect.top - balloonRect.height - BalloonPanelView.arrowVerticalOffset;\n}\n\n// Returns the top coordinate for positions starting with `south*`.\n//\n// @private\n// @param {utils/dom/rect~Rect} targetRect A rect of the target.\n// @param {utils/dom/rect~Rect} elementRect A rect of the balloon.\n// @returns {Number}\nfunction getSouthTop( targetRect ) {\n\treturn targetRect.bottom + BalloonPanelView.arrowVerticalOffset;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/panel/balloon/contextualballoon\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport BalloonPanelView from './balloonpanelview';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Provides the common contextual balloon panel for the editor.\n *\n * This plugin allows reusing a single {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView} instance\n * to display multiple contextual balloon panels in the editor.\n *\n * Child views of such a panel are stored in the stack and the last one in the stack is visible. When the\n * visible view is removed from the stack, the previous view becomes visible, etc. If there are no more\n * views in the stack, the balloon panel will hide.\n *\n * It simplifies managing the views and helps\n * avoid the unnecessary complexity of handling multiple {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView}\n * instances in the editor.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ContextualBalloon extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ContextualBalloon';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\t/**\n\t\t * The common balloon panel view.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/panel/balloon/balloonpanelview~BalloonPanelView} #view\n\t\t */\n\t\tthis.view = new BalloonPanelView();\n\n\t\t/**\n\t\t * The {@link module:utils/dom/position~Options#limiter position limiter}\n\t\t * for the {@link #view}, used when no `limiter` has been passed into {@link #add}\n\t\t * or {@link #updatePosition}.\n\t\t *\n\t\t * By default, a function, which obtains the farthest DOM\n\t\t * {@link module:engine/view/rooteditableelement~RootEditableElement}\n\t\t * of the {@link module:engine/view/document~Document#selection}.\n\t\t *\n\t\t * @member {module:utils/dom/position~Options#limiter} #positionLimiter\n\t\t */\n\t\tthis.positionLimiter = () => {\n\t\t\tconst view = this.editor.editing.view;\n\t\t\tconst viewDocument = view.document;\n\t\t\tconst editableElement = viewDocument.selection.editableElement;\n\n\t\t\tif ( editableElement ) {\n\t\t\t\treturn view.domConverter.mapViewToDom( editableElement.root );\n\t\t\t}\n\n\t\t\treturn null;\n\t\t};\n\n\t\t/**\n\t\t * Stack of the views injected into the balloon. Last one in the stack is displayed\n\t\t * as a content of {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon#view}.\n\t\t *\n\t\t * @private\n\t\t * @member {Map} #_stack\n\t\t */\n\t\tthis._stack = new Map();\n\n\t\t// Add balloon panel view to editor `body` collection and wait until view will be ready.\n\t\tthis.editor.ui.view.body.add( this.view );\n\n\t\t// Editor should be focused when contextual balloon is focused.\n\t\tthis.editor.ui.focusTracker.add( this.view.element );\n\t}\n\n\t/**\n\t * Returns the currently visible view or `null` when there are no\n\t * views in the stack.\n\t *\n\t * @returns {module:ui/view~View|null}\n\t */\n\tget visibleView() {\n\t\tconst item = this._stack.get( this.view.content.get( 0 ) );\n\n\t\treturn item ? item.view : null;\n\t}\n\n\t/**\n\t * Returns `true` when the given view is in the stack. Otherwise returns `false`.\n\t *\n\t * @param {module:ui/view~View} view\n\t * @returns {Boolean}\n\t */\n\thasView( view ) {\n\t\treturn this._stack.has( view );\n\t}\n\n\t/**\n\t * Adds a new view to the stack and makes it visible.\n\t *\n\t * @param {Object} data Configuration of the view.\n\t * @param {module:ui/view~View} [data.view] Content of the balloon.\n\t * @param {module:utils/dom/position~Options} [data.position] Positioning options.\n\t * @param {String} [data.balloonClassName] Additional css class for {@link #view} added when given view is visible.\n\t */\n\tadd( data ) {\n\t\tif ( this.hasView( data.view ) ) {\n\t\t\t/**\n\t\t\t * Trying to add configuration of the same view more than once.\n\t\t\t *\n\t\t\t * @error contextualballoon-add-view-exist\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'contextualballoon-add-view-exist: Cannot add configuration of the same view twice.' );\n\t\t}\n\n\t\t// When adding view to the not empty balloon.\n\t\tif ( this.visibleView ) {\n\t\t\t// Remove displayed content from the view.\n\t\t\tthis.view.content.remove( this.visibleView );\n\t\t}\n\n\t\t// Add new view to the stack.\n\t\tthis._stack.set( data.view, data );\n\n\t\t// And display it.\n\t\tthis._show( data );\n\t}\n\n\t/**\n\t * Removes the given view from the stack. If the removed view was visible,\n\t * then the view preceding it in the stack will become visible instead.\n\t * When there is no view in the stack then balloon will hide.\n\t *\n\t * @param {module:ui/view~View} view A view to be removed from the balloon.\n\t */\n\tremove( view ) {\n\t\tif ( !this.hasView( view ) ) {\n\t\t\t/**\n\t\t\t * Trying to remove configuration of the view not defined in the stack.\n\t\t\t *\n\t\t\t * @error contextualballoon-remove-view-not-exist\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'contextualballoon-remove-view-not-exist: Cannot remove configuration of not existing view.' );\n\t\t}\n\n\t\t// When visible view is being removed.\n\t\tif ( this.visibleView === view ) {\n\t\t\t// We need to remove it from the view content.\n\t\t\tthis.view.content.remove( view );\n\n\t\t\t// And then remove from the stack.\n\t\t\tthis._stack.delete( view );\n\n\t\t\t// Next we need to check if there is other view in stack to show.\n\t\t\tconst last = Array.from( this._stack.values() ).pop();\n\n\t\t\t// If it is some other view.\n\t\t\tif ( last ) {\n\t\t\t\t// Just show it.\n\t\t\t\tthis._show( last );\n\t\t\t} else {\n\t\t\t\t// Hide the balloon panel.\n\t\t\t\tthis.view.hide();\n\t\t\t}\n\t\t} else {\n\t\t\t// Just remove given view from the stack.\n\t\t\tthis._stack.delete( view );\n\t\t}\n\t}\n\n\t/**\n\t * Updates the position of the balloon using position data of the first visible view in the stack.\n\t * When new position data is given then position data of currently visible panel will be updated.\n\t *\n\t * @param {module:utils/dom/position~Options} [position] position options.\n\t */\n\tupdatePosition( position ) {\n\t\tif ( position ) {\n\t\t\tthis._stack.get( this.visibleView ).position = position;\n\t\t}\n\n\t\tthis.view.pin( this._getBalloonPosition() );\n\t}\n\n\t/**\n\t * Sets the view as a content of the balloon and attaches balloon using position\n\t * options of the first view.\n\t *\n\t * @private\n\t * @param {Object} data Configuration.\n\t * @param {module:ui/view~View} [data.view] View to show in the balloon.\n\t * @param {String} [data.balloonClassName=''] Additional class name which will added to the {#_balloon} view.\n\t */\n\t_show( { view, balloonClassName = '' } ) {\n\t\tthis.view.class = balloonClassName;\n\n\t\tthis.view.content.add( view );\n\t\tthis.view.pin( this._getBalloonPosition() );\n\t}\n\n\t/**\n\t * Returns position options of the last view in the stack.\n\t * This keeps the balloon in the same position when view is changed.\n\t *\n\t * @private\n\t * @returns {module:utils/dom/position~Options}\n\t */\n\t_getBalloonPosition() {\n\t\tlet position = Array.from( this._stack.values() ).pop().position;\n\n\t\t// Use the default limiter if none has been specified.\n\t\tif ( position && !position.limiter ) {\n\t\t\t// Don't modify the original options object.\n\t\t\tposition = Object.assign( {}, position, {\n\t\t\t\tlimiter: this.positionLimiter\n\t\t\t} );\n\t\t}\n\n\t\treturn position;\n\t}\n}\n","import imageIcon from '../icons/edit.svg';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\n\nexport function createToolbarEditButton(editor, name, callback) {\n\t// Add editing button\n\teditor.ui.componentFactory.add( name, locale => {\n\t\tconst view = new ButtonView( locale );\n\n\t\tview.set( {\n\t\t\tlabel: I18n.t('js.button_edit'),\n\t\t\ticon: imageIcon,\n\t\t\ttooltip: true\n\t\t} );\n\n\t\t// Callback executed once the widget is clicked.\n\t\tview.on( 'execute', () => {\n\n\t\t\tconst widget = editor.model.document.selection.getSelectedElement();\n\n\t\t\tif (!widget) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcallback(widget);\n\t\t} );\n\n\t\treturn view;\n\t} );\n}\n","import ToolbarView from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview';\nimport BalloonPanelView from '@ckeditor/ckeditor5-ui/src/panel/balloon/balloonpanelview';\n\nconst balloonClassName = 'ck-toolbar-container';\n\nexport function createEditToolbar(\n\t// Plugin instance\n\tplugin,\n\t// Editor instance\n\teditor,\n\t// Configuration namespace in op-ckeditor.js\n\tconfig_namespace,\n\t// Callback to check if widget is selected\n\tisWidgetSelected\n) {\n\n\tconst toolbarConfig = editor.config.get( config_namespace + '.toolbar' );\n\n\t// Don't add the toolbar if there is no configuration.\n\tif ( !toolbarConfig || !toolbarConfig.length ) {\n\t\treturn;\n\t}\n\n\tconst _balloon = editor.plugins.get( 'ContextualBalloon' );\n\tconst _toolbar = new ToolbarView();\n\n\tfunction _checkIsVisible() {\n\t\tif ( !editor.ui.focusTracker.isFocused ) {\n\t\t\t_hideToolbar();\n\t\t} else {\n\t\t\tif ( isWidgetSelected(editor.editing.view.document.selection ) ) {\n\t\t\t\t_showToolbar();\n\t\t\t} else {\n\t\t\t\t_hideToolbar();\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction _showToolbar() {\n\t\tif ( _isVisible() ) {\n\t\t\trepositionContextualBalloon( editor, isWidgetSelected );\n\t\t} else if ( !_balloon.hasView( _toolbar ) ) {\n\t\t\t_balloon.add( {\n\t\t\t\tview: _toolbar,\n\t\t\t\tposition: getBalloonPositionData( editor ),\n\t\t\t\tballoonClassName\n\t\t\t} );\n\t\t}\n\t}\n\n\tfunction _hideToolbar() {\n\t\tif ( !_isVisible() ) {\n\t\t\treturn;\n\t\t}\n\n\t\t_balloon.remove( _toolbar );\n\t}\n\n\tfunction _isVisible() {\n\t\treturn _balloon.visibleView == _toolbar;\n\t}\n\n\t// Add buttons to the toolbar.\n\t_toolbar.fillFromConfig( toolbarConfig, editor.ui.componentFactory );\n\n\t// Show balloon panel each time the widget is selected.\n\t// TODO: This has changed in master with https://github.com/ckeditor/ckeditor5-image/pull/215\n\tplugin.listenTo( editor.editing.view, 'render', _checkIsVisible);\n\n\t// UI#update is not fired after focus is back in editor, we need to check if balloon panel should be visible.\n\tplugin.listenTo( editor.ui.focusTracker, 'change:isFocused', _checkIsVisible, { priority: 'low' } );\n}\n\n\n/**\n * A helper utility that positions the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} instance\n * with respect to the element in the editor content, if one is selected.\n *\n * @param {module:core/editor/editor~Editor} editor The editor instance.\n */\nfunction repositionContextualBalloon( editor, selectionCallback ) {\n\tconst balloon = editor.plugins.get( 'ContextualBalloon' );\n\n\tif ( selectionCallback( editor.editing.view.document.selection ) ) {\n\t\tconst position = getBalloonPositionData( editor );\n\n\t\tballoon.updatePosition( position );\n\t}\n}\n\n\n/**\n * Returns the positioning options that control the geometry of the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} with respect\n * to the selected element in the editor content.\n *\n * @param {module:core/editor/editor~Editor} editor The editor instance.\n * @returns {module:utils/dom/position~Options}\n */\nfunction getBalloonPositionData( editor ) {\n\tconst editingView = editor.editing.view;\n\tconst defaultPositions = BalloonPanelView.defaultPositions;\n\n\treturn {\n\t\ttarget: editingView.domConverter.viewToDom( editingView.document.selection.getSelectedElement() ),\n\t\tpositions: [\n\t\t\tdefaultPositions.northArrowSouth,\n\t\t\tdefaultPositions.northArrowSouthWest,\n\t\t\tdefaultPositions.northArrowSouthEast,\n\t\t\tdefaultPositions.southArrowNorth,\n\t\t\tdefaultPositions.southArrowNorthWest,\n\t\t\tdefaultPositions.southArrowNorthEast\n\t\t]\n\t};\n}\n","import Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ContextualBalloon from '@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon';\n\nimport {isEmbeddedTableWidgetSelected} from './utils';\nimport {createToolbarEditButton} from '../../helpers/create-toolbar-edit-button';\nimport {createEditToolbar} from '../../helpers/create-toolbar';\nimport {getPluginContext} from '../op-context/op-context';\n\n\nconst balloonClassName = 'ck-toolbar-container';\n\nexport default class EmbeddedTableToolbar extends Plugin {\n\tstatic get requires() {\n\t\treturn [ ContextualBalloon ];\n\t}\n\n\tstatic get pluginName() {\n\t\treturn 'EmbeddedTableToolbar';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = this.editor.model;\n\t\tconst pluginContext = getPluginContext(editor);\n\n\t\t// Add editing button\n\t\tcreateToolbarEditButton( editor, 'opEditEmbeddedTableQuery', widget => {\n\t\t\tconst externalQueryConfiguration = pluginContext.services.externalQueryConfiguration;\n\t\t\tconst currentQuery = widget.getAttribute('opEmbeddedTableQuery') || {};\n\n\t\t\tpluginContext.runInZone(() => {\n\t\t\t\texternalQueryConfiguration.show(\n\t\t\t\t\tcurrentQuery,\n\t\t\t\t\t(newQuery) => model.change(writer => {\n\t\t\t\t\t\twriter.setAttribute( 'opEmbeddedTableQuery', newQuery, widget );\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t});\n\t\t} );\n\t}\n\n\tafterInit() {\n\t\t// Add actual toolbar\n\t\tcreateEditToolbar(\n\t\t\tthis,\n\t\t\tthis.editor,\n\t\t\t'OPMacroEmbeddedTable',\n\t\t\tisEmbeddedTableWidgetSelected\n\t\t);\n\t}\n}\n","const wpButtonMacroSymbol = Symbol( 'isWpButtonMacroSymbol' );\nimport {toWidget, isWidget} from '@ckeditor/ckeditor5-widget/src/utils';\n\nexport function toWpButtonMacroWidget( viewElement, writer, label ) {\n\twriter.setCustomProperty( wpButtonMacroSymbol, true, viewElement );\n\treturn toWidget( viewElement, writer, { label: label });\n}\n\n\nexport function isWpButtonMacroWidget( viewElement ) {\n\treturn !!viewElement.getCustomProperty( wpButtonMacroSymbol ) && isWidget( viewElement );\n}\n\n\nexport function isWpButtonMacroWidgetSelected( selection ) {\n\tconst viewElement = selection.getSelectedElement();\n\n\treturn !!( viewElement && isWpButtonMacroWidget( viewElement ) );\n}\n","import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport {toWpButtonMacroWidget} from './utils';\nimport {getPluginContext} from '../op-context/op-context';\n\nexport default class OPMacroWpButtonEditing extends Plugin {\n\n\tstatic get pluginName() {\n\t\treturn 'OPMacroWpButtonEditing';\n\t}\n\n\tstatic get buttonName() {\n\t\treturn 'insertWorkPackageButton';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst conversion = editor.conversion;\n\t\tconst pluginContext = getPluginContext(editor);\n\n\t\t// Schema.\n\t\tmodel.schema.register( 'op-macro-wp-button', {\n\t\t\tallowWhere: ['$block'],\n\t\t\tallowAttributes: ['type', 'classes'],\n\t\t\tisBlock: true,\n\t\t isLimit: true\n\t\t});\n\n\t\tconversion.for( 'upcast' )\n\t\t\t.elementToElement( {\n\t\t\t\tview: {\n\t\t\t\t\tname: 'macro',\n\t\t\t\t\tclasses: 'create_work_package_link'\n\t\t\t\t},\n\t\t\t\tmodel: ( viewElement, modelWriter ) => {\n\t\t\t\t\tconst type = viewElement.getAttribute( 'data-type' ) || '';\n\t\t\t\t\tconst classes = viewElement.getAttribute( 'data-classes' ) || '';\n\n\t\t\t\t\treturn modelWriter.createElement(\n\t\t\t\t\t\t'op-macro-wp-button',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: type,\n\t\t\t\t\t\t\tclasses: classes\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} );\n\n\n\t\tconversion.for( 'editingDowncast' ).elementToElement( {\n\t\t\tmodel: 'op-macro-wp-button',\n\t\t\tview: (modelElement, writer) => {\n\t\t\t\treturn this.createMacroViewElement(modelElement, writer);\n\t\t\t}\n\t } );\n\n\t\tconversion.for('dataDowncast').elementToElement({\n\t\t\tmodel: 'op-macro-wp-button',\n\t\t\tview: (modelElement, writer) => {\n\t\t\t\tconst element = writer.createContainerElement(\n\t\t\t\t\t'macro',\n\t\t\t\t\t{\n\t\t\t\t\t\t'class': 'create_work_package_link',\n\t\t\t\t\t\t'data-type': modelElement.getAttribute('type') || '',\n\t\t\t\t\t\t'data-classes': modelElement.getAttribute('classes') || '',\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\treturn element;\n\t\t\t}\n\t\t});\n\n\t\teditor.ui.componentFactory.add( OPMacroWpButtonEditing.buttonName, locale => {\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\tlabel: window.I18n.t('js.editor.macro.work_package_button.button'),\n\t\t\t\twithText: true\n\t\t\t} );\n\n\t\t\t// Callback executed once the image is clicked.\n\t\t\tview.on( 'execute', () => {\n\t\t\t\tconst macroService = pluginContext.services.macros;\n\n\t\t\t\tmacroService\n\t\t\t\t\t.configureWorkPackageButton()\n\t\t\t\t\t.then((result) => editor.model.change(writer => {\n\t\t\t\t\t\tconst element = writer.createElement( 'op-macro-wp-button', {});\n\t\t\t\t\t\twriter.setAttribute( 'type', result.type, element );\n\t\t\t\t\t\twriter.setAttribute( 'classes', result.classes, element );\n\n\t\t\t\t\t\teditor.model.insertContent( element, editor.model.document.selection );\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t} );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n\n\tmacroLabel(type) {\n\t\tif (type) {\n\t\t\treturn window.I18n.t('js.editor.macro.work_package_button.with_type', { typename: type });\n\t\t} else {\n\t\t\treturn window.I18n.t('js.editor.macro.work_package_button.without_type');\n\t\t}\n\t}\n\n\tcreateMacroViewElement(modelElement, writer) {\n\t\tconst type = modelElement.getAttribute('type');\n\t\tconst classes = modelElement.getAttribute('classes') || '';\n\t\tconst label = this.macroLabel(); // TODO: Pass type, it is not updated on coming back from the modal..\n\t\tconst placeholder = writer.createText( label );\n\t\tconst container = writer.createContainerElement( 'span', { class: 'macro -create_work_package_link ' + classes } );\n\n\t\twriter.insert( writer.createPositionAt( container, 0 ), placeholder );\n\t\treturn toWpButtonMacroWidget(container, writer, { label: label } )\n\t}\n}\n","import Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ContextualBalloon from '@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon';\n\nimport {isWpButtonMacroWidgetSelected} from './utils';\nimport {createToolbarEditButton} from '../../helpers/create-toolbar-edit-button';\nimport {createEditToolbar} from '../../helpers/create-toolbar';\nimport {getPluginContext} from '../op-context/op-context';\n\n\nconst balloonClassName = 'ck-toolbar-container';\n\nexport default class OPMacroWpButtonToolbar extends Plugin {\n\tstatic get requires() {\n\t\treturn [ ContextualBalloon ];\n\t}\n\n\tstatic get pluginName() {\n\t\treturn 'OPMacroWpButtonToolbar';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = this.editor.model;\n\t\tconst pluginContext = getPluginContext(editor);\n\n\t\t// Add editing button\n\t\tcreateToolbarEditButton( editor, 'opEditWpMacroButton', widget => {\n\t\t\tconst macroService = pluginContext.services.macros;\n\t\t\tconst type = widget.getAttribute('type');\n\t\t\tconst classes = widget.getAttribute('classes');\n\n\t\t\tmacroService\n\t\t\t\t.configureWorkPackageButton(type, classes)\n\t\t\t\t.then((result) => editor.model.change(writer => {\n\t\t\t\t\twriter.setAttribute( 'classes', result.classes, widget );\n\t\t\t\t\twriter.setAttribute( 'type', result.type, widget );\n\t\t\t\t})\n\t\t\t);\n\t\t} );\n\t}\n\n\tafterInit() {\n\t\t// Add actual toolbar\n\t\tcreateEditToolbar(\n\t\t\tthis,\n\t\t\tthis.editor,\n\t\t\t'OPMacroWpButton',\n\t\t\tisWpButtonMacroWidgetSelected\n\t\t);\n\t}\n}\n","const wikiIncludeMacroSymbol = Symbol( 'isWpButtonMacroSymbol' );\nimport {toWidget, isWidget} from '@ckeditor/ckeditor5-widget/src/utils';\n\nexport function toWikiIncludeMacroWidget( viewElement, writer, label ) {\n\twriter.setCustomProperty( wikiIncludeMacroSymbol, true, viewElement );\n\treturn toWidget( viewElement, writer, { label: label });\n}\n\n\nexport function isWikiIncludeMacroWidget( viewElement ) {\n\treturn !!viewElement.getCustomProperty( wikiIncludeMacroSymbol ) && isWidget( viewElement );\n}\n\n\nexport function isWikiIncludeMacroWidgetSelected( selection ) {\n\tconst viewElement = selection.getSelectedElement();\n\n\treturn !!( viewElement && isWikiIncludeMacroWidget( viewElement ) );\n}\n","import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport ViewPosition from '@ckeditor/ckeditor5-engine/src/view/position';\nimport {toWikiIncludeMacroWidget} from './utils';\nimport ViewRange from \"@ckeditor/ckeditor5-engine/src/view/range\";\nimport { getPluginContext } from '../op-context/op-context';\n\nexport default class OPWikiIncludePageEditing extends Plugin {\n\n\tstatic get pluginName() {\n\t\treturn 'OPWikiIncludePageEditing';\n\t}\n\n\tstatic get buttonName() {\n\t\treturn 'insertWikiPageInclude';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst conversion = editor.conversion;\n\t\tconst pluginContext = getPluginContext(editor);\n\n\t\t// Schema.\n\t\tmodel.schema.register( 'op-macro-wiki-page-include', {\n\t\t\tallowWhere: ['$block'],\n\t\t\tallowAttributes: ['page'],\n\t\t\tisBlock: true,\n\t\t isLimit: true\n\t\t});\n\n\t\tconversion.for( 'upcast' )\n\t\t\t.elementToElement( {\n\t\t\t\tview: {\n\t\t\t\t\tname: 'macro',\n\t\t\t\t\tclasses: 'include_wiki_page'\n\t\t\t\t},\n\t\t\t\tmodel: ( viewElement, modelWriter ) => {\n\t\t\t\t\tconst page = viewElement.getAttribute( 'data-page' ) || '';\n\n\t\t\t\t\treturn modelWriter.createElement(\n\t\t\t\t\t\t'op-macro-wiki-page-include',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpage: page\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} );\n\n\n\t\tconversion.for( 'editingDowncast' )\n\t\t\t.elementToElement( {\n\t\t\t\tmodel: 'op-macro-wiki-page-include',\n\t\t\t\tview: (modelElement, writer) => {\n\t\t\t\t\treturn this.createMacroViewElement(modelElement, writer);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.add(dispatcher => dispatcher.on( 'attribute:page', this.modelAttributeToView.bind(this)));\n\n\t\tconversion.for('dataDowncast').elementToElement({\n\t\t\tmodel: 'op-macro-wiki-page-include',\n\t\t\tview: (modelElement, writer) => {\n\t\t\t\tconst element = writer.createContainerElement(\n\t\t\t\t\t'macro',\n\t\t\t\t\t{\n\t\t\t\t\t\t'class': 'include_wiki_page',\n\t\t\t\t\t\t'data-page': modelElement.getAttribute('page') || '',\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\treturn element;\n\t\t\t}\n\t\t});\n\n\t\teditor.ui.componentFactory.add( OPWikiIncludePageEditing.buttonName, locale => {\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\tlabel: window.I18n.t('js.editor.macro.wiki_page_include.button'),\n\t\t\t\twithText: true\n\t\t\t} );\n\n\t\t\t// Callback executed once the image is clicked.\n\t\t\tview.on( 'execute', () => {\n\t\t\t\tconst macroService = pluginContext.services.macros;\n\n\t\t\t\tmacroService\n\t\t\t\t\t.configureWikiPageInclude()\n\t\t\t\t\t.then((page) => editor.model.change(writer => {\n\t\t\t\t\t\tconst element = writer.createElement( 'op-macro-wiki-page-include', {});\n\t\t\t\t\t\twriter.setAttribute( 'page', page, element );\n\n\t\t\t\t\t\teditor.model.insertContent( element, editor.model.document.selection );\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t} );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n\n\tmodelAttributeToView( evt, data, conversionApi ) {\n\t\tconst modelElement = data.item;\n\t\tif (!modelElement.is('op-macro-wiki-page-include')) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Mark element as consumed by conversion.\n\t\tconversionApi.consumable.consume(data.item, evt.name);\n\n\t\t// Get mapped view element to update.\n\t\tconst viewElement = conversionApi.mapper.toViewElement(modelElement);\n\n\t\t// Remove current <div> element contents.\n\t\tconversionApi.writer.remove(conversionApi.writer.createRangeIn(viewElement));\n\n\t\t// Set current content\n\t\tthis.setPlaceholderContent(conversionApi.writer, modelElement, viewElement);\n\t}\n\n\tmacroLabel() {\n\t\treturn window.I18n.t('js.editor.macro.wiki_page_include.text');\n\t}\n\n\tpageLabel(page) {\n\t\tif (page && page.length > 0) {\n\t\t\treturn page\n\t\t} else {\n\t\t\treturn window.I18n.t('js.editor.macro.wiki_page_include.not_set');\n\t\t}\n\t}\n\n\tcreateMacroViewElement(modelElement, writer) {\n\t\tconst placeholderContainer = writer.createContainerElement( 'div', { class: 'macro -wiki_page_include' } );\n\n\t\tthis.setPlaceholderContent( writer, modelElement, placeholderContainer );\n\n\t\treturn toWikiIncludeMacroWidget(placeholderContainer, writer, { label: this.macroLabel() } )\n\t}\n\n\tsetPlaceholderContent(writer, modelElement, placeholderContainer ) {\n\t\tconst page = modelElement.getAttribute('page');\n\t\tconst macroLabel = this.macroLabel();\n\t\tconst pageLabel = this.pageLabel(page);\n\t\tconst pageLabelContainer = writer.createContainerElement( 'span', { class: 'macro-value' } );\n\t\tlet placeholderContent = [ writer.createText( `${macroLabel} ` ) ];\n\t\twriter.insert( writer.createPositionAt( pageLabelContainer, 0 ), writer.createText( `${pageLabel}` ) )\n\t\tplaceholderContent.push( pageLabelContainer );\n\n\t\twriter.insert( writer.createPositionAt( placeholderContainer, 0 ), placeholderContent );\n\t}\n}\n","import Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ContextualBalloon from '@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon';\n\nimport {isWikiIncludeMacroWidgetSelected} from './utils';\nimport {createToolbarEditButton} from '../../helpers/create-toolbar-edit-button';\nimport {createEditToolbar} from '../../helpers/create-toolbar';\nimport {getPluginContext} from '../op-context/op-context';\n\n\nconst balloonClassName = 'ck-toolbar-container';\n\nexport default class OPWikiIncludePageToolbar extends Plugin {\n\tstatic get requires() {\n\t\treturn [ ContextualBalloon ];\n\t}\n\n\tstatic get pluginName() {\n\t\treturn 'OPWikiIncludePageToolbar';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = this.editor.model;\n\t\tconst pluginContext = getPluginContext(editor);\n\n\t\t// Add editing button\n\t\tcreateToolbarEditButton( editor, 'opEditWikiIncludeMacroButton', widget => {\n\t\t\tconst macroService = pluginContext.services.macros;\n\t\t\tconst page = widget.getAttribute('page');\n\n\t\t\tmacroService\n\t\t\t\t.configureWikiPageInclude(page)\n\t\t\t\t.then((newPage) => editor.model.change(writer => {\n\t\t\t\t\twriter.setAttribute( 'page', newPage, widget );\n\t\t\t\t})\n\t\t\t);\n\t\t} );\n\t}\n\n\tafterInit() {\n\t\t// Add actual toolbar\n\t\tcreateEditToolbar(\n\t\t\tthis,\n\t\t\tthis.editor,\n\t\t\t'OPWikiIncludePage',\n\t\t\tisWikiIncludeMacroWidgetSelected\n\t\t);\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor.data, 'ready', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n/**\n * Array of loaded plugins.\n *\n * @typedef {Array.<module:core/plugin~PluginInterface>} module:core/plugin~LoadedPlugins\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/pendingactions\n */\n\nimport Plugin from './plugin';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport Collection from '@ckeditor/ckeditor5-utils/src/collection';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * The list of pending editor actions.\n *\n * This plugin should be used to synchronise plugins that execute long-lasting actions\n * (e.g. file upload) with the editor integration. It gives the developer who integrates the editor\n * an easy way to check if there are any actions pending whenever such information is needed.\n * All plugins that register a pending action also provide a message about the action that is ongoing\n * which can be displayed to the user. This lets them decide if they want to interrupt the action or wait.\n *\n * Adding and updating a pending action:\n *\n * \t\tconst pendingActions = editor.plugins.get( 'PendingActions' );\n * \t\tconst action = pendingActions.add( 'Upload in progress: 0%.' );\n *\n *\t\t// You can update the message:\n * \t\taction.message = 'Upload in progress: 10%.';\n *\n * Removing a pending action:\n *\n * \t\tconst pendingActions = editor.plugins.get( 'PendingActions' );\n * \t\tconst action = pendingActions.add( 'Unsaved changes.' );\n *\n * \t\tpendingActions.remove( action );\n *\n * Getting pending actions:\n *\n * \t\tconst pendingActions = editor.plugins.get( 'PendingActions' );\n *\n * \t\tconst action1 = pendingActions.add( 'Action 1' );\n * \t\tconst action2 = pendingActions.add( 'Action 2' );\n *\n * \t\tpendingActions.first; // Returns action1\n * \t\tArray.from( pendingActions ); // Returns [ action1, action2 ]\n *\n * This plugin is used by features like {@link module:upload/filerepository~FileRepository} to register their ongoing actions\n * and by features like {@link module:autosave/autosave~Autosave} to detect whether there are any ongoing actions.\n * Read more about saving the data in the {@glink builds/guides/integration/saving-data Saving and getting data} guide.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class PendingActions extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'PendingActions';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\t/**\n\t\t * Defines whether there is any registered pending action.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Boolean} #hasAny\n\t\t */\n\t\tthis.set( 'hasAny', false );\n\n\t\t/**\n\t\t * A list of pending actions.\n\t\t *\n\t\t * @private\n\t\t * @type {module:utils/collection~Collection}\n\t\t */\n\t\tthis._actions = new Collection( { idProperty: '_id' } );\n\t\tthis._actions.delegate( 'add', 'remove' ).to( this );\n\t}\n\n\t/**\n\t * Adds an action to the list of pending actions.\n\t *\n\t * This method returns an action object with an observable message property.\n\t * The action object can be later used in the {@link #remove} method. It also allows you to change the message.\n\t *\n\t * @param {String} message The action message.\n\t * @returns {Object} An observable object that represents a pending action.\n\t */\n\tadd( message ) {\n\t\tif ( typeof message !== 'string' ) {\n\t\t\t/**\n\t\t\t * The message must be a string.\n\t\t\t *\n\t\t\t * @error pendingactions-add-invalid-message\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'pendingactions-add-invalid-message: The message must be a string.' );\n\t\t}\n\n\t\tconst action = Object.create( ObservableMixin );\n\n\t\taction.set( 'message', message );\n\t\tthis._actions.add( action );\n\t\tthis.hasAny = true;\n\n\t\treturn action;\n\t}\n\n\t/**\n\t * Removes an action from the list of pending actions.\n\t *\n\t * @param {Object} action An action object.\n\t */\n\tremove( action ) {\n\t\tthis._actions.remove( action );\n\t\tthis.hasAny = !!this._actions.length;\n\t}\n\n\t/**\n\t * Returns the first action from the list or null when list is empty\n\t *\n\t * returns {Object|null} The pending action object.\n\t */\n\tget first() {\n\t\treturn this._actions.get( 0 );\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * @returns {Iterable.<*>}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this._actions[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Fired when an action is added to the list.\n\t *\n\t * @event add\n\t * @param {Object} action The added action.\n\t */\n\n\t/**\n\t * Fired when an action is removed from the list.\n\t *\n\t * @event remove\n\t * @param {Object} action The removed action.\n\t */\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module upload/filereader\n */\n\n/* globals window */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * Wrapper over the native `FileReader`.\n */\nexport default class FileReader {\n\t/**\n\t * Creates an instance of the FileReader.\n\t */\n\tconstructor() {\n\t\tconst reader = new window.FileReader();\n\n\t\t/**\n\t\t * Instance of native FileReader.\n\t\t *\n\t\t * @private\n\t\t * @member {FileReader} #_reader\n\t\t */\n\t\tthis._reader = reader;\n\n\t\t/**\n\t\t * Number of bytes loaded.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Number} #loaded\n\t\t */\n\t\tthis.set( 'loaded', 0 );\n\n\t\treader.onprogress = evt => {\n\t\t\tthis.loaded = evt.loaded;\n\t\t};\n\t}\n\n\t/**\n\t * Returns error that occurred during file reading.\n\t *\n\t * @returns {Error}\n\t */\n\tget error() {\n\t\treturn this._reader.error;\n\t}\n\n\t/**\n\t * Reads the provided file.\n\t *\n\t * @param {File} file Native File object.\n\t * @returns {Promise.<String>} Returns a promise that will be resolved with file's content.\n\t * The promise will be rejected in case of an error or when the reading process is aborted.\n\t */\n\tread( file ) {\n\t\tconst reader = this._reader;\n\t\tthis.total = file.size;\n\n\t\treturn new Promise( ( resolve, reject ) => {\n\t\t\treader.onload = () => {\n\t\t\t\tresolve( reader.result );\n\t\t\t};\n\n\t\t\treader.onerror = () => {\n\t\t\t\treject( 'error' );\n\t\t\t};\n\n\t\t\treader.onabort = () => {\n\t\t\t\treject( 'aborted' );\n\t\t\t};\n\n\t\t\tthis._reader.readAsDataURL( file );\n\t\t} );\n\t}\n\n\t/**\n\t * Aborts file reader.\n\t */\n\tabort() {\n\t\tthis._reader.abort();\n\t}\n}\n\nmix( FileReader, ObservableMixin );\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module upload/filerepository\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport PendingActions from '@ckeditor/ckeditor5-core/src/pendingactions';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport Collection from '@ckeditor/ckeditor5-utils/src/collection';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\nimport FileReader from './filereader.js';\nimport uid from '@ckeditor/ckeditor5-utils/src/uid.js';\n/**\n * File repository plugin. A central point for managing file upload.\n *\n * To use it, first you need an upload adapter. Upload adapter's job is to handle communication with the server\n * (sending the file and handling server's response). You can use one of the existing plugins introducing upload adapters\n * (e.g. {@link module:easy-image/cloudservicesuploadadapter~CloudServicesUploadAdapter} or\n * {@link module:adapter-ckfinder/uploadadapter~CKFinderUploadAdapter}) or write your own one – see\n * the {@glink framework/guides/deep-dive/upload-adapter \"Custom image upload adapter\" deep dive guide}.\n *\n * Then, you can use {@link module:upload/filerepository~FileRepository#createLoader `createLoader()`} and the returned\n * {@link module:upload/filerepository~FileLoader} instance to load and upload files.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class FileRepository extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n static get pluginName() {\n return 'FileRepository';\n }\n /**\n\t * @inheritDoc\n\t */\n static get requires() {\n return [PendingActions];\n }\n /**\n\t * @inheritDoc\n\t */\n init() {\n /**\n\t\t * Collection of loaders associated with this repository.\n\t\t *\n\t\t * @member {module:utils/collection~Collection} #loaders\n\t\t */\n this.loaders = new Collection();\n // Keeps upload in a sync with pending actions.\n this.loaders.on('add', () => this._updatePendingAction());\n this.loaders.on('remove', () => this._updatePendingAction());\n /**\n\t\t * Loaders mappings used to retrieve loaders references.\n\t\t *\n\t\t * @private\n\t\t * @member {Map<File|Promise, FileLoader>} #_loadersMap\n\t\t */\n this._loadersMap = new Map();\n /**\n\t\t * Reference to a pending action registered in a {@link module:core/pendingactions~PendingActions} plugin\n\t\t * while upload is in progress. When there is no upload then value is `null`.\n\t\t *\n\t\t * @private\n\t\t * @member {Object} #_pendingAction\n\t\t */\n this._pendingAction = null;\n /**\n\t\t * A factory function which should be defined before using `FileRepository`.\n\t\t *\n\t\t * It should return a new instance of {@link module:upload/filerepository~UploadAdapter} that will be used to upload files.\n\t\t * {@link module:upload/filerepository~FileLoader} instance associated with the adapter\n\t\t * will be passed to that function.\n\t\t *\n\t\t * For more information and example see {@link module:upload/filerepository~UploadAdapter}.\n\t\t *\n\t\t * @member {Function} #createUploadAdapter\n\t\t */\n /**\n\t\t * Number of bytes uploaded.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Number} #uploaded\n\t\t */\n this.set('uploaded', 0);\n /**\n\t\t * Number of total bytes to upload.\n\t\t *\n\t\t * It might be different than the file size because of headers and additional data.\n\t\t * It contains `null` if value is not available yet, so it's better to use {@link #uploadedPercent} to monitor\n\t\t * the progress.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Number|null} #uploadTotal\n\t\t */\n this.set('uploadTotal', null);\n /**\n\t\t * Upload progress in percents.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Number} #uploadedPercent\n\t\t */\n this.bind('uploadedPercent').to(this, 'uploaded', this, 'uploadTotal', (uploaded, total) => {\n return total ? uploaded / total * 100 : 0;\n });\n }\n /**\n\t * Returns the loader associated with specified file or promise.\n\t *\n\t * To get loader by id use `fileRepository.loaders.get( id )`.\n\t *\n\t * @param {File|Promise.<File>} fileOrPromise Native file or promise handle.\n\t * @returns {module:upload/filerepository~FileLoader|null}\n\t */\n getLoader(fileOrPromise) {\n return this._loadersMap.get(fileOrPromise) || null;\n }\n /**\n\t * Creates a loader instance for the given file.\n\t *\n\t * Requires {@link #createUploadAdapter} factory to be defined.\n\t *\n\t * @param {File|Promise.<File>} fileOrPromise Native File object or native Promise object which resolves to a File.\n\t * @returns {module:upload/filerepository~FileLoader|null}\n\t */\n createLoader(fileOrPromise) {\n if (!this.createUploadAdapter) {\n /**\n\t\t\t * You need to enable an upload adapter in order to be able to upload files.\n\t\t\t *\n\t\t\t * This warning shows up when {@link module:upload/filerepository~FileRepository} is being used\n\t\t\t * without {@link #createUploadAdapter definining an upload adapter}.\n\t\t\t *\n\t\t\t * **If you see this warning when using one of the {@glink builds/index CKEditor 5 Builds}**\n\t\t\t * it means that you did not configure any of the upload adapters available by default in those builds.\n\t\t\t *\n\t\t\t * See the {@glink features/image-upload/image-upload comprehensive \"Image upload overview\"} to learn which upload\n\t\t\t * adapters are available in the builds and how to configure them.\n\t\t\t *\n\t\t\t * **If you see this warning when using a custom build** there is a chance that you enabled\n\t\t\t * a feature like {@link module:image/imageupload~ImageUpload},\n\t\t\t * or {@link module:image/imageupload/imageuploadui~ImageUploadUI} but you did not enable any upload adapter.\n\t\t\t * You can choose one of the existing upload adapters listed in the\n\t\t\t * {@glink features/image-upload/image-upload \"Image upload overview\"}.\n\t\t\t *\n\t\t\t * You can also implement your {@glink framework/guides/deep-dive/upload-adapter own image upload adapter}.\n\t\t\t *\n\t\t\t * @error filerepository-no-upload-adapter\n\t\t\t */\n log.error('filerepository-no-upload-adapter: Upload adapter is not defined.');\n return null;\n }\n const loader = new FileLoader(Promise.resolve(fileOrPromise), this.createUploadAdapter);\n this.loaders.add(loader);\n this._loadersMap.set(fileOrPromise, loader);\n // Store also file => loader mapping so loader can be retrieved by file instance returned upon Promise resolution.\n if (fileOrPromise instanceof Promise) {\n loader.file.then(file => {\n this._loadersMap.set(file, loader);\n });\n }\n // Catch the file promise rejection. If there are no `catch` clause, the browser\n // will throw an error (see https://github.com/ckeditor/ckeditor5-upload/pull/90).\n loader.file.catch(() => {\n });\n loader.on('change:uploaded', () => {\n let aggregatedUploaded = 0;\n for (const loader of this.loaders) {\n aggregatedUploaded += loader.uploaded;\n }\n this.uploaded = aggregatedUploaded;\n });\n loader.on('change:uploadTotal', () => {\n let aggregatedTotal = 0;\n for (const loader of this.loaders) {\n if (loader.uploadTotal) {\n aggregatedTotal += loader.uploadTotal;\n }\n }\n this.uploadTotal = aggregatedTotal;\n });\n return loader;\n }\n /**\n\t * Destroys the given loader.\n\t *\n\t * @param {File|Promise|module:upload/filerepository~FileLoader} fileOrPromiseOrLoader File or Promise associated\n\t * with that loader or loader itself.\n\t */\n destroyLoader(fileOrPromiseOrLoader) {\n const loader = fileOrPromiseOrLoader instanceof FileLoader ? fileOrPromiseOrLoader : this.getLoader(fileOrPromiseOrLoader);\n loader._destroy();\n this.loaders.remove(loader);\n this._loadersMap.forEach((value, key) => {\n if (value === loader) {\n this._loadersMap.delete(key);\n }\n });\n }\n /**\n\t * Registers or deregisters pending action bound with upload progress.\n\t *\n\t * @private\n\t */\n _updatePendingAction() {\n const pendingActions = this.editor.plugins.get(PendingActions);\n if (this.loaders.length) {\n if (!this._pendingAction) {\n const t = this.editor.t;\n const getMessage = value => `${ t('d') } ${ parseInt(value) }%.`;\n this._pendingAction = pendingActions.add(getMessage(this.uploadedPercent));\n this._pendingAction.bind('message').to(this, 'uploadedPercent', getMessage);\n }\n } else {\n pendingActions.remove(this._pendingAction);\n this._pendingAction = null;\n }\n }\n}\nmix(FileRepository, ObservableMixin);\n/**\n * File loader class.\n *\n * It is used to control the process of reading the file and uploading it using the specified upload adapter.\n */\nclass FileLoader {\n /**\n\t * Creates a new instance of `FileLoader`.\n\t *\n\t * @param {Promise.<File>} filePromise A promise which resolves to a file instance.\n\t * @param {Function} uploadAdapterCreator The function which returns {@link module:upload/filerepository~UploadAdapter} instance.\n\t */\n constructor(filePromise, uploadAdapterCreator) {\n /**\n\t\t * Unique id of FileLoader instance.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t */\n this.id = uid();\n /**\n\t\t * Additional wrapper over the initial file promise passed to this loader.\n\t\t *\n\t\t * @private\n\t\t * @member {module:upload/filerepository~FilePromiseWrapper}\n\t\t */\n this._filePromiseWrapper = this._createFilePromiseWrapper(filePromise);\n /**\n\t\t * Adapter instance associated with this file loader.\n\t\t *\n\t\t * @private\n\t\t * @member {module:upload/filerepository~UploadAdapter}\n\t\t */\n this._adapter = uploadAdapterCreator(this);\n /**\n\t\t * FileReader used by FileLoader.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:upload/filereader~FileReader}\n\t\t */\n this._reader = new FileReader();\n /**\n\t\t * Current status of FileLoader. It can be one of the following:\n\t\t *\n\t\t * * 'idle',\n\t\t * * 'reading',\n\t\t * * 'uploading',\n\t\t * * 'aborted',\n\t\t * * 'error'.\n\t\t *\n\t\t * When reading status can change in a following way:\n\t\t *\n\t\t * `idle` -> `reading` -> `idle`\n\t\t * `idle` -> `reading -> `aborted`\n\t\t * `idle` -> `reading -> `error`\n\t\t *\n\t\t * When uploading status can change in a following way:\n\t\t *\n\t\t * `idle` -> `uploading` -> `idle`\n\t\t * `idle` -> `uploading` -> `aborted`\n\t\t * `idle` -> `uploading` -> `error`\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {String} #status\n\t\t */\n this.set('status', 'idle');\n /**\n\t\t * Number of bytes uploaded.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Number} #uploaded\n\t\t */\n this.set('uploaded', 0);\n /**\n\t\t * Number of total bytes to upload.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Number|null} #uploadTotal\n\t\t */\n this.set('uploadTotal', null);\n /**\n\t\t * Upload progress in percents.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Number} #uploadedPercent\n\t\t */\n this.bind('uploadedPercent').to(this, 'uploaded', this, 'uploadTotal', (uploaded, total) => {\n return total ? uploaded / total * 100 : 0;\n });\n /**\n\t\t * Response of the upload.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Object|null} #uploadResponse\n\t\t */\n this.set('uploadResponse', null);\n }\n /**\n\t * A `Promise` which resolves to a `File` instance associated with this file loader.\n\t *\n\t * @type {Promise.<File|null>}\n\t */\n get file() {\n if (!this._filePromiseWrapper) {\n // Loader was destroyed, return promise which resolves to null.\n return Promise.resolve(null);\n } else {\n // The `this._filePromiseWrapper.promise` is chained and not simply returned to handle a case when:\n //\n //\t\t* The `loader.file.then( ... )` is called by external code (returned promise is pending).\n //\t\t* Then `loader._destroy()` is called (call is synchronous) which destroys the `loader`.\n //\t\t* Promise returned by the first `loader.file.then( ... )` call is resolved.\n //\n // Returning `this._filePromiseWrapper.promise` will still resolve to a `File` instance so there\n // is an additional check needed in the chain to see if `loader` was destroyed in the meantime.\n return this._filePromiseWrapper.promise.then(file => this._filePromiseWrapper ? file : null);\n }\n }\n /**\n\t * Reads file using {@link module:upload/filereader~FileReader}.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `filerepository-read-wrong-status` when status\n\t * is different than `idle`.\n\t *\n\t * Example usage:\n\t *\n\t *\tfileLoader.read()\n\t *\t\t.then( data => { ... } )\n\t *\t\t.catch( err => {\n\t *\t\t\tif ( err === 'aborted' ) {\n\t *\t\t\t\tconsole.log( 'Reading aborted.' );\n\t *\t\t\t} else {\n\t *\t\t\t\tconsole.log( 'Reading error.', err );\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * @returns {Promise.<String>} Returns promise that will be resolved with read data. Promise will be rejected if error\n\t * occurs or if read process is aborted.\n\t */\n read() {\n if (this.status != 'idle') {\n throw new CKEditorError('filerepository-read-wrong-status: You cannot call read if the status is different than idle.');\n }\n this.status = 'reading';\n return this._filePromiseWrapper.promise.then(file => this._reader.read(file)).then(data => {\n this.status = 'idle';\n return data;\n }).catch(err => {\n if (err === 'aborted') {\n this.status = 'aborted';\n throw 'aborted';\n }\n this.status = 'error';\n throw this._reader.error ? this._reader.error : err;\n });\n }\n /**\n\t * Reads file using the provided {@link module:upload/filerepository~UploadAdapter}.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `filerepository-upload-wrong-status` when status\n\t * is different than `idle`.\n\t * Example usage:\n\t *\n\t *\tfileLoader.upload()\n\t *\t\t.then( data => { ... } )\n\t *\t\t.catch( e => {\n\t *\t\t\tif ( e === 'aborted' ) {\n\t *\t\t\t\tconsole.log( 'Uploading aborted.' );\n\t *\t\t\t} else {\n\t *\t\t\t\tconsole.log( 'Uploading error.', e );\n\t *\t\t\t}\n\t *\t\t} );\n\t *\n\t * @returns {Promise.<Object>} Returns promise that will be resolved with response data. Promise will be rejected if error\n\t * occurs or if read process is aborted.\n\t */\n upload() {\n if (this.status != 'idle') {\n throw new CKEditorError('filerepository-upload-wrong-status: You cannot call upload if the status is different than idle.');\n }\n this.status = 'uploading';\n return this._filePromiseWrapper.promise.then(() => this._adapter.upload()).then(data => {\n this.uploadResponse = data;\n this.status = 'idle';\n return data;\n }).catch(err => {\n if (this.status === 'aborted') {\n throw 'aborted';\n }\n this.status = 'error';\n throw err;\n });\n }\n /**\n\t * Aborts loading process.\n\t */\n abort() {\n const status = this.status;\n this.status = 'aborted';\n if (!this._filePromiseWrapper.isFulfilled) {\n this._filePromiseWrapper.rejecter('aborted');\n } else if (status == 'reading') {\n this._reader.abort();\n } else if (status == 'uploading' && this._adapter.abort) {\n this._adapter.abort();\n }\n this._destroy();\n }\n /**\n\t * Performs cleanup.\n\t *\n\t * @private\n\t */\n _destroy() {\n this._filePromiseWrapper = undefined;\n this._reader = undefined;\n this._adapter = undefined;\n this.data = undefined;\n this.uploadResponse = undefined;\n }\n /**\n\t * Wraps a given file promise into another promise giving additional\n\t * control (resolving, rejecting, checking if fulfilled) over it.\n\t *\n\t * @private\n\t * @param filePromise The initial file promise to be wrapped.\n\t * @returns {module:upload/filerepository~FilePromiseWrapper}\n\t */\n _createFilePromiseWrapper(filePromise) {\n const wrapper = {};\n wrapper.promise = new Promise((resolve, reject) => {\n wrapper.resolver = resolve;\n wrapper.rejecter = reject;\n wrapper.isFulfilled = false;\n filePromise.then(file => {\n wrapper.isFulfilled = true;\n resolve(file);\n }).catch(err => {\n wrapper.isFulfilled = true;\n reject(err);\n });\n });\n return wrapper;\n }\n}\nmix(FileLoader, ObservableMixin); /**\n * Upload adapter interface used by the {@link module:upload/filerepository~FileRepository file repository}\n * to handle file upload. An upload adapter is a bridge between the editor and server that handles file uploads.\n * It should contain a logic necessary to initiate an upload process and monitor its progress.\n *\n * Learn how to develop your own upload adapter for CKEditor 5 in the\n * {@glink framework/guides/deep-dive/upload-adapter \"Custom upload adapter\" guide}.\n *\n * @interface UploadAdapter\n */\n /**\n * Executes the upload process.\n * This method should return a promise that will resolve when data will be uploaded to server. Promise should be\n * resolved with an object containing information about uploaded file:\n *\n *\t\t{\n *\t\t\tdefault: 'http://server/default-size.image.png'\n *\t\t}\n *\n * Additionally, other image sizes can be provided:\n *\n *\t\t{\n *\t\t\tdefault: 'http://server/default-size.image.png',\n *\t\t\t'160': 'http://server/size-160.image.png',\n *\t\t\t'500': 'http://server/size-500.image.png',\n *\t\t\t'1000': 'http://server/size-1000.image.png',\n *\t\t\t'1052': 'http://server/default-size.image.png'\n *\t\t}\n *\n * NOTE: When returning multiple images, the widest returned one should equal the default one. It is essential to\n * correctly set `width` attribute of the image. See this discussion:\n * https://github.com/ckeditor/ckeditor5-easy-image/issues/4 for more information.\n *\n * Take a look at {@link module:upload/filerepository~UploadAdapter example Adapter implementation} and\n * {@link module:upload/filerepository~FileRepository#createUploadAdapter createUploadAdapter method}.\n *\n * @method module:upload/filerepository~UploadAdapter#upload\n * @returns {Promise.<Object>} Promise that should be resolved when data is uploaded.\n */\n /**\n * Aborts the upload process.\n * After aborting it should reject promise returned from {@link #upload upload()}.\n *\n * Take a look at {@link module:upload/filerepository~UploadAdapter example Adapter implementation} and\n * {@link module:upload/filerepository~FileRepository#createUploadAdapter createUploadAdapter method}.\n *\n * @method module:upload/filerepository~UploadAdapter#abort\n */\n /**\n * Object returned by {@link module:upload/filerepository~FileLoader#_createFilePromiseWrapper} method\n * to add more control over the initial file promise passed to {@link module:upload/filerepository~FileLoader}.\n *\n * @typedef {Object} module:upload/filerepository~FilePromiseWrapper\n * @property {Promise.<File>} promise Wrapper promise which can be chained for further processing.\n * @property {Function} resolver Resolves the promise when called.\n * @property {Function} rejecter Rejects the promise when called.\n * @property {Boolean} isFulfilled Whether original promise is already fulfilled.\n */","export default class OpUploadResourceAdapter {\n constructor(loader, resource, editor) {\n this.loader = loader;\n this.resource = resource;\n this.editor = editor;\n }\n\n upload() {\n\t\tconst resource = this.resource;\n if (!(resource && resource.uploadAttachments)) {\n\t\t\tconst resourceContext = resource ? resource.name : 'Missing context';\n console.warn(`uploadAttachments not present on context: ${resourceContext}`);\n return Promise.reject(\"You're not allowed to upload attachments on this resource.\");\n\t\t}\n\n\t\treturn this.loader.file\n\t\t\t.then(file => {\n\t\t\treturn resource\n\t\t\t\t.uploadAttachments([file])\n\t\t\t\t.then((result) => {\n\t\t\t\t\tthis.editor.model.fire('op:attachment-added', result);\n\n\t\t\t\t\treturn this.buildResponse(result[0])\n\t\t\t\t}).catch((error) => {\n\t\t\t\t\tconsole.error(\"Failed upload %O\", error);\n\t\t\t\t});\n\t\t})\n\n\t}\n\n\tbuildResponse(result) {\n\t\treturn { default: result.uploadUrl };\n\t}\n\n abort() {\n\t\treturn false;\n }\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor.data, 'ready', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n/**\n * Array of loaded plugins.\n *\n * @typedef {Array.<module:core/plugin~PluginInterface>} module:core/plugin~LoadedPlugins\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module upload/ui/filedialogbuttonview\n */\n\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport View from '@ckeditor/ckeditor5-ui/src/view';\n\n/**\n * The file dialog button view.\n *\n * This component provides a button that opens the native file selection dialog.\n * It can be used to implement the UI of a file upload feature.\n *\n *\t\tconst view = new FileDialogButtonView( locale );\n *\n *\t\tview.set( {\n *\t\t\tacceptedType: 'image/*',\n *\t\t\tallowMultipleFiles: true\n *\t\t} );\n *\n *\t\tview.buttonView.set( {\n *\t\t\tlabel: t( 'Insert image' ),\n *\t\t\ticon: imageIcon,\n *\t\t\ttooltip: true\n *\t\t} );\n *\n *\t\tview.on( 'done', ( evt, files ) => {\n *\t\t\tfor ( const file of Array.from( files ) ) {\n *\t\t\t\tconsole.log( 'Selected file', file );\n *\t\t\t}\n *\t\t} );\n *\n * @extends module:ui/view~View\n */\nexport default class FileDialogButtonView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\t/**\n\t\t * The button view of the component.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView}\n\t\t */\n\t\tthis.buttonView = new ButtonView( locale );\n\n\t\t/**\n\t\t * A hidden `<input>` view used to execute file dialog.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:upload/ui/filedialogbuttonview~FileInputView}\n\t\t */\n\t\tthis._fileInputView = new FileInputView( locale );\n\n\t\t/**\n\t\t * Accepted file types. Can be provided in form of file extensions, media type or one of:\n\t\t * * `audio/*`,\n\t\t * * `video/*`,\n\t\t * * `image/*`.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #acceptedType\n\t\t */\n\t\tthis._fileInputView.bind( 'acceptedType' ).to( this );\n\n\t\t/**\n\t\t * Indicates if multiple files can be selected. Defaults to `true`.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #allowMultipleFiles\n\t\t */\n\t\tthis._fileInputView.bind( 'allowMultipleFiles' ).to( this );\n\n\t\t/**\n\t\t * Fired when file dialog is closed with file selected.\n\t\t *\n\t\t *\t\tview.on( 'done', ( evt, files ) => {\n\t\t *\t\t\tfor ( const file of files ) {\n\t\t *\t\t\t\tconsole.log( 'Selected file', file );\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\n\t\t * @event done\n\t\t * @param {Array.<File>} files Array of selected files.\n\t\t */\n\t\tthis._fileInputView.delegate( 'done' ).to( this );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'span',\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-file-dialog-button',\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\tthis.buttonView,\n\t\t\t\tthis._fileInputView\n\t\t\t]\n\t\t} );\n\n\t\tthis.buttonView.on( 'execute', () => {\n\t\t\tthis._fileInputView.open();\n\t\t} );\n\t}\n\n\t/**\n\t * Focuses the {@link #buttonView}.\n\t */\n\tfocus() {\n\t\tthis.buttonView.focus();\n\t}\n}\n\n/**\n * The hidden file input view class.\n *\n * @private\n * @extends {module:ui/view~View}\n */\nclass FileInputView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\t/**\n\t\t * Accepted file types. Can be provided in form of file extensions, media type or one of:\n\t\t * * `audio/*`,\n\t\t * * `video/*`,\n\t\t * * `image/*`.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #acceptedType\n\t\t */\n\t\tthis.set( 'acceptedType' );\n\n\t\t/**\n\t\t * Indicates if multiple files can be selected. Defaults to `false`.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #allowMultipleFiles\n\t\t */\n\t\tthis.set( 'allowMultipleFiles', false );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'input',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-hidden'\n\t\t\t\t],\n\t\t\t\ttype: 'file',\n\t\t\t\ttabindex: '-1',\n\t\t\t\taccept: bind.to( 'acceptedType' ),\n\t\t\t\tmultiple: bind.to( 'allowMultipleFiles' )\n\t\t\t},\n\n\t\t\ton: {\n\t\t\t\t// Removing from code coverage since we cannot programmatically set input element files.\n\t\t\t\tchange: bind.to( /* istanbul ignore next */ () => {\n\t\t\t\t\tif ( this.element && this.element.files && this.element.files.length ) {\n\t\t\t\t\t\tthis.fire( 'done', this.element.files );\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.element.value = '';\n\t\t\t\t} )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Opens file dialog.\n\t */\n\topen() {\n\t\tthis.element.click();\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imageupload/utils\n */\n\n/* global fetch, File */\n\n/**\n * Checks if a given file is an image.\n *\n * @param {File} file\n * @returns {Boolean}\n */\nexport function isImageType( file ) {\n\tconst types = /^image\\/(jpeg|png|gif|bmp)$/;\n\n\treturn types.test( file.type );\n}\n\n/**\n * Creates a promise which fetches the image local source (base64 or blob) and resolves with a `File` object.\n *\n * @param {module:engine/view/element~Element} image Image which source to fetch.\n * @returns {Promise.<File>} A promise which resolves when image source is fetched and converted to `File` instance.\n * It resolves with a `File` object. If there were any errors during file processing the promise will be rejected.\n */\nexport function fetchLocalImage( image ) {\n\treturn new Promise( ( resolve, reject ) => {\n\t\tconst imageSrc = image.getAttribute( 'src' );\n\n\t\t// Fetch works asynchronously and so does not block browser UI when processing data.\n\t\tfetch( imageSrc )\n\t\t\t.then( resource => resource.blob() )\n\t\t\t.then( blob => {\n\t\t\t\tconst mimeType = getImageMimeType( blob, imageSrc );\n\t\t\t\tconst ext = mimeType.replace( 'image/', '' );\n\t\t\t\tconst filename = `image.${ ext }`;\n\t\t\t\tconst file = createFileFromBlob( blob, filename, mimeType );\n\n\t\t\t\tfile ? resolve( file ) : reject();\n\t\t\t} )\n\t\t\t.catch( reject );\n\t} );\n}\n\n/**\n * Checks whether given node is an image element with local source (base64 or blob).\n *\n * @param {module:engine/view/node~Node} node Node to check.\n * @returns {Boolean}\n */\nexport function isLocalImage( node ) {\n\tif ( !node.is( 'element', 'img' ) || !node.getAttribute( 'src' ) ) {\n\t\treturn false;\n\t}\n\n\treturn node.getAttribute( 'src' ).match( /^data:image\\/\\w+;base64,/g ) ||\n\t\tnode.getAttribute( 'src' ).match( /^blob:/g );\n}\n\n// Extracts image type based on its blob representation or its source.\n//\n// @param {String} src Image src attribute value.\n// @param {Blob} blob Image blob representation.\n// @returns {String}\nfunction getImageMimeType( blob, src ) {\n\tif ( blob.type ) {\n\t\treturn blob.type;\n\t} else if ( src.match( /data:(image\\/\\w+);base64/ ) ) {\n\t\treturn src.match( /data:(image\\/\\w+);base64/ )[ 1 ].toLowerCase();\n\t} else {\n\t\t// Fallback to 'jpeg' as common extension.\n\t\treturn 'image/jpeg';\n\t}\n}\n\n// Creates `File` instance from the given `Blob` instance using specified filename.\n//\n// @param {Blob} blob The `Blob` instance from which file will be created.\n// @param {String} filename Filename used during file creation.\n// @param {String} mimeType File mime type.\n// @returns {File|null} The `File` instance created from the given blob or `null` if `File API` is not available.\nfunction createFileFromBlob( blob, filename, mimeType ) {\n\ttry {\n\t\treturn new File( [ blob ], filename, { type: mimeType } );\n\t} catch ( err ) {\n\t\t// Edge does not support `File` constructor ATM, see https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/9551546/.\n\t\t// However, the `File` function is present (so cannot be checked with `!window.File` or `typeof File === 'function'`), but\n\t\t// calling it with `new File( ... )` throws an error. This try-catch prevents that. Also when the function will\n\t\t// be implemented correctly in Edge the code will start working without any changes (see #247).\n\t\treturn null;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module image/imageupload/imageuploadui\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport FileDialogButtonView from '@ckeditor/ckeditor5-upload/src/ui/filedialogbuttonview';\nimport imageIcon from '@ckeditor/ckeditor5-core/theme/icons/image.svg';\nimport { isImageType } from './utils';\n/**\n * The image upload button plugin.\n *\n * For a detailed overview, check the {@glink features/image-upload/image-upload Image upload feature} documentation.\n *\n * Adds the `'imageUpload'` button to the {@link module:ui/componentfactory~ComponentFactory UI component factory}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageUploadUI extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const t = editor.t;\n // Setup `imageUpload` button.\n editor.ui.componentFactory.add('imageUpload', locale => {\n const view = new FileDialogButtonView(locale);\n const command = editor.commands.get('imageUpload');\n view.set({\n acceptedType: 'image/*',\n allowMultipleFiles: true\n });\n view.buttonView.set({\n label: t('ah'),\n icon: imageIcon,\n tooltip: true\n });\n view.buttonView.bind('isEnabled').to(command);\n view.on('done', (evt, files) => {\n const imagesToUpload = Array.from(files).filter(isImageType);\n if (imagesToUpload.length) {\n editor.execute('imageUpload', { file: imagesToUpload });\n }\n });\n return view;\n });\n }\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imageupload/imageuploadprogress\n */\n\n/* globals setTimeout */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport FileRepository from '@ckeditor/ckeditor5-upload/src/filerepository';\nimport uploadingPlaceholder from '../../theme/icons/image_placeholder.svg';\nimport env from '@ckeditor/ckeditor5-utils/src/env';\n\nimport '../../theme/imageuploadprogress.css';\nimport '../../theme/imageuploadicon.css';\nimport '../../theme/imageuploadloader.css';\n\n/**\n * The image upload progress plugin.\n * It shows a placeholder when the image is read from the disk and a progress bar while the image is uploading.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageUploadProgress extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The image placeholder that is displayed before real image data can be accessed.\n\t\t *\n\t\t * @protected\n\t\t * @member {String} #placeholder\n\t\t */\n\t\tthis.placeholder = 'data:image/svg+xml;utf8,' + encodeURIComponent( uploadingPlaceholder );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\n\t\t// Upload status change - update image's view according to that status.\n\t\teditor.editing.downcastDispatcher.on( 'attribute:uploadStatus:image', ( ...args ) => this.uploadStatusChange( ...args ) );\n\t}\n\n\t/**\n\t * This method is called each time the image `uploadStatus` attribute is changed.\n\t *\n\t * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\n\t */\n\tuploadStatusChange( evt, data, conversionApi ) {\n\t\tconst editor = this.editor;\n\t\tconst modelImage = data.item;\n\t\tconst uploadId = modelImage.getAttribute( 'uploadId' );\n\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst fileRepository = editor.plugins.get( FileRepository );\n\t\tconst status = uploadId ? data.attributeNewValue : null;\n\t\tconst placeholder = this.placeholder;\n\t\tconst viewFigure = editor.editing.mapper.toViewElement( modelImage );\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\tif ( status == 'reading' ) {\n\t\t\t// Start \"appearing\" effect and show placeholder with infinite progress bar on the top\n\t\t\t// while image is read from disk.\n\t\t\t_startAppearEffect( viewFigure, viewWriter );\n\t\t\t_showPlaceholder( placeholder, viewFigure, viewWriter );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Show progress bar on the top of the image when image is uploading.\n\t\tif ( status == 'uploading' ) {\n\t\t\tconst loader = fileRepository.loaders.get( uploadId );\n\n\t\t\t// Start appear effect if needed - see https://github.com/ckeditor/ckeditor5-image/issues/191.\n\t\t\t_startAppearEffect( viewFigure, viewWriter );\n\n\t\t\tif ( !loader ) {\n\t\t\t\t// There is no loader associated with uploadId - this means that image came from external changes.\n\t\t\t\t// In such cases we still want to show the placeholder until image is fully uploaded.\n\t\t\t\t// Show placeholder if needed - see https://github.com/ckeditor/ckeditor5-image/issues/191.\n\t\t\t\t_showPlaceholder( placeholder, viewFigure, viewWriter );\n\t\t\t} else {\n\t\t\t\t// Hide placeholder and initialize progress bar showing upload progress.\n\t\t\t\t_hidePlaceholder( viewFigure, viewWriter );\n\t\t\t\t_showProgressBar( viewFigure, viewWriter, loader, editor.editing.view );\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Because in Edge there is no way to show fancy animation of completeIcon we need to skip it.\n\t\tif ( status == 'complete' && fileRepository.loaders.get( uploadId ) && !env.isEdge ) {\n\t\t\t_showCompleteIcon( viewFigure, viewWriter, editor.editing.view );\n\t\t}\n\n\t\t// Clean up.\n\t\t_hideProgressBar( viewFigure, viewWriter );\n\t\t_hidePlaceholder( viewFigure, viewWriter );\n\t\t_stopAppearEffect( viewFigure, viewWriter );\n\t}\n}\n\n// Adds ck-appear class to the image figure if one is not already applied.\n//\n// @param {module:engine/view/containerelement~ContainerElement} viewFigure\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\nfunction _startAppearEffect( viewFigure, writer ) {\n\tif ( !viewFigure.hasClass( 'ck-appear' ) ) {\n\t\twriter.addClass( 'ck-appear', viewFigure );\n\t}\n}\n\n// Removes ck-appear class to the image figure if one is not already removed.\n//\n// @param {module:engine/view/containerelement~ContainerElement} viewFigure\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\nfunction _stopAppearEffect( viewFigure, writer ) {\n\twriter.removeClass( 'ck-appear', viewFigure );\n}\n\n// Shows placeholder together with infinite progress bar on given image figure.\n//\n// @param {String} Data-uri with a svg placeholder.\n// @param {module:engine/view/containerelement~ContainerElement} viewFigure\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\nfunction _showPlaceholder( placeholder, viewFigure, writer ) {\n\tif ( !viewFigure.hasClass( 'ck-image-upload-placeholder' ) ) {\n\t\twriter.addClass( 'ck-image-upload-placeholder', viewFigure );\n\t}\n\n\tconst viewImg = viewFigure.getChild( 0 );\n\n\tif ( viewImg.getAttribute( 'src' ) !== placeholder ) {\n\t\twriter.setAttribute( 'src', placeholder, viewImg );\n\t}\n\n\tif ( !_getUIElement( viewFigure, 'placeholder' ) ) {\n\t\twriter.insert( writer.createPositionAfter( viewImg ), _createPlaceholder( writer ) );\n\t}\n}\n\n// Removes placeholder together with infinite progress bar on given image figure.\n//\n// @param {module:engine/view/containerelement~ContainerElement} viewFigure\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\nfunction _hidePlaceholder( viewFigure, writer ) {\n\tif ( viewFigure.hasClass( 'ck-image-upload-placeholder' ) ) {\n\t\twriter.removeClass( 'ck-image-upload-placeholder', viewFigure );\n\t}\n\n\t_removeUIElement( viewFigure, writer, 'placeholder' );\n}\n\n// Shows progress bar displaying upload progress.\n// Attaches it to the file loader to update when upload percentace is changed.\n//\n// @param {module:engine/view/containerelement~ContainerElement} viewFigure\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\n// @param {module:upload/filerepository~FileLoader} loader\n// @param {module:engine/view/view~View} view\nfunction _showProgressBar( viewFigure, writer, loader, view ) {\n\tconst progressBar = _createProgressBar( writer );\n\twriter.insert( writer.createPositionAt( viewFigure, 'end' ), progressBar );\n\n\t// Update progress bar width when uploadedPercent is changed.\n\tloader.on( 'change:uploadedPercent', ( evt, name, value ) => {\n\t\tview.change( writer => {\n\t\t\twriter.setStyle( 'width', value + '%', progressBar );\n\t\t} );\n\t} );\n}\n\n// Hides upload progress bar.\n//\n// @param {module:engine/view/containerelement~ContainerElement} viewFigure\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\nfunction _hideProgressBar( viewFigure, writer ) {\n\t_removeUIElement( viewFigure, writer, 'progressBar' );\n}\n\n// Shows complete icon and hides after a certain amount of time.\n//\n// @param {module:engine/view/containerelement~ContainerElement} viewFigure\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\n// @param {module:engine/view/view~View} view\nfunction _showCompleteIcon( viewFigure, writer, view ) {\n\tconst completeIcon = writer.createUIElement( 'div', { class: 'ck-image-upload-complete-icon' } );\n\n\twriter.insert( writer.createPositionAt( viewFigure, 'end' ), completeIcon );\n\n\tsetTimeout( () => {\n\t\tview.change( writer => writer.remove( writer.createRangeOn( completeIcon ) ) );\n\t}, 3000 );\n}\n\n// Create progress bar element using {@link module:engine/view/uielement~UIElement}.\n//\n// @private\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\n// @returns {module:engine/view/uielement~UIElement}\nfunction _createProgressBar( writer ) {\n\tconst progressBar = writer.createUIElement( 'div', { class: 'ck-progress-bar' } );\n\n\twriter.setCustomProperty( 'progressBar', true, progressBar );\n\n\treturn progressBar;\n}\n\n// Create placeholder element using {@link module:engine/view/uielement~UIElement}.\n//\n// @private\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\n// @returns {module:engine/view/uielement~UIElement}\nfunction _createPlaceholder( writer ) {\n\tconst placeholder = writer.createUIElement( 'div', { class: 'ck-upload-placeholder-loader' } );\n\n\twriter.setCustomProperty( 'placeholder', true, placeholder );\n\n\treturn placeholder;\n}\n\n// Returns {@link module:engine/view/uielement~UIElement} of given unique property from image figure element.\n// Returns `undefined` if element is not found.\n//\n// @private\n// @param {module:engine/view/element~Element} imageFigure\n// @param {String} uniqueProperty\n// @returns {module:engine/view/uielement~UIElement|undefined}\nfunction _getUIElement( imageFigure, uniqueProperty ) {\n\tfor ( const child of imageFigure.getChildren() ) {\n\t\tif ( child.getCustomProperty( uniqueProperty ) ) {\n\t\t\treturn child;\n\t\t}\n\t}\n}\n\n// Removes {@link module:engine/view/uielement~UIElement} of given unique property from image figure element.\n//\n// @private\n// @param {module:engine/view/element~Element} imageFigure\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\n// @param {String} uniqueProperty\nfunction _removeUIElement( viewFigure, writer, uniqueProperty ) {\n\tconst element = _getUIElement( viewFigure, uniqueProperty );\n\n\tif ( element ) {\n\t\twriter.remove( writer.createRangeOn( element ) );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/notification/notification\n */\n\n/* globals window */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\n/**\n * The Notification plugin.\n *\n * This plugin sends few base types of notifications: `success`, `info` and `warning`. This notifications need to be\n * handled and displayed by plugin responsible for showing UI of the notifications. Using this plugin for dispatching\n * notifications makes possible to switch the notifications UI.\n *\n * Note that every unhandled and not stopped `warning` notification will be displayed as system alert.\n * See {@link module:ui/notification/notification~Notification#showWarning}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Notification extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Notification';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\t// Each unhandled and not stopped `show:warning` event is displayed as system alert.\n\t\tthis.on( 'show:warning', ( evt, data ) => {\n\t\t\twindow.alert( data.message ); // eslint-disable-line no-alert\n\t\t}, { priority: 'lowest' } );\n\t}\n\n\t/**\n\t * Shows success notification.\n\t *\n\t * At default it fires `show:success` event with given data but event namespace can be extended\n\t * by `data.namespace` option e.g.\n\t *\n\t * \t\tshowSuccess( 'Image is uploaded.', {\n\t * \t\t\tnamespace: 'upload:image'\n\t * \t\t} );\n\t *\n\t * will fire `show:success:upload:image` event.\n\t * Title of the notification can be provided:\n\t *\n\t *\t\tshowSuccess( 'Image is uploaded.', {\n\t *\t\t\ttitle: 'Image upload success'\n\t *\t\t});\n\t *\n\t * @param {String} message Content of the notification.\n\t * @param {Object} [data={}] Additional data.\n\t * @param {String} [data.namespace] Additional event namespace.\n\t * @param {String} [data.title] Title of the notification.\n\t */\n\tshowSuccess( message, data = {} ) {\n\t\tthis._showNotification( {\n\t\t\tmessage,\n\t\t\ttype: 'success',\n\t\t\tnamespace: data.namespace,\n\t\t\ttitle: data.title\n\t\t} );\n\t}\n\n\t/**\n\t * Shows info notification.\n\t *\n\t * At default it fires `show:info` event with given data but event namespace can be extended\n\t * by `data.namespace` option e.g.\n\t *\n\t * \t\tshowInfo( 'Editor is offline.', {\n\t * \t\t\tnamespace: 'editor:status'\n\t * \t\t} );\n\t *\n\t * will fire `show:info:editor:status` event.\n\t * Title of the notification can be provided:\n\t *\n\t *\t\tshowInfo( 'Editor is offline.', {\n\t *\t\t\ttitle: 'Network information'\n\t *\t\t});\n\t *\n\t * @param {String} message Content of the notification.\n\t * @param {Object} [data={}] Additional data.\n\t * @param {String} [data.namespace] Additional event namespace.\n\t * @param {String} [data.title] Title of the notification.\n\t */\n\tshowInfo( message, data = {} ) {\n\t\tthis._showNotification( {\n\t\t\tmessage,\n\t\t\ttype: 'info',\n\t\t\tnamespace: data.namespace,\n\t\t\ttitle: data.title\n\t\t} );\n\t}\n\n\t/**\n\t * Shows warning notification.\n\t *\n\t * At default it fires `show:warning` event with given data but event namespace can be extended\n\t * by `data.namespace` option e.g.\n\t *\n\t * \t\tshowWarning( 'Image upload error.', {\n\t * \t\t\tnamespace: 'upload:image'\n\t * \t\t} );\n\t *\n\t * will fire `show:warning:upload:image` event.\n\t * Title of the notification can be provided:\n\t *\n\t *\t\tshowWarning( 'Image upload error.', {\n\t *\t\t\ttitle: 'Upload failed'\n\t *\t\t});\n\t *\n\t * Note that each unhandled and not stopped `warning` notification will be displayed as system alert.\n\t * Plugin responsible for displaying warnings should `stop()` the event to prevent of displaying it as alert:\n\t *\n\t * \t\tnotifications.on( 'show:warning', ( evt, data ) => {\n\t * \t\t\t// Do something with data.\n\t *\n\t * \t\t\t// Stop this event to prevent of displaying as alert.\n\t * \t\t\tevt.stop();\n\t * \t\t} );\n\t *\n\t * You can attach many listeners to the same event and `stop()` this event in the listener with the low priority:\n\t *\n\t * \t\tnotifications.on( 'show:warning', ( evt, data ) => {\n\t * \t\t\t// Show warning in the UI, but not stop it.\n\t * \t\t} );\n\t *\n\t * \t\tnotifications.on( 'show:warning', ( evt, data ) => {\n\t * \t\t\t// Log warning to some error tracker.\n\t *\n\t * \t\t\t// Stop this event to prevent of displaying as alert.\n\t * \t\t\tevt.stop();\n\t * \t\t}, { priority: 'low' } );\n\t *\n\t * @param {String} message Content of the notification.\n\t * @param {Object} [data={}] Additional data.\n\t * @param {String} [data.namespace] Additional event namespace.\n\t * @param {String} [data.title] Title of the notification.\n\t */\n\tshowWarning( message, data = {} ) {\n\t\tthis._showNotification( {\n\t\t\tmessage,\n\t\t\ttype: 'warning',\n\t\t\tnamespace: data.namespace,\n\t\t\ttitle: data.title\n\t\t} );\n\t}\n\n\t/**\n\t * Fires `show` event with specified type, namespace and message.\n\t *\n\t * @private\n\t * @param {Object} data Message data.\n\t * @param {String} data.message Content of the notification.\n\t * @param {'success'|'info'|'warning'} data.type Type of message.\n\t * @param {String} [data.namespace] Additional event namespace.\n\t * @param {String} [data.title=''] Title of the notification.\n\t */\n\t_showNotification( data ) {\n\t\tconst event = `show:${ data.type }` + ( data.namespace ? `:${ data.namespace }` : '' );\n\n\t\tthis.fire( event, {\n\t\t\tmessage: data.message,\n\t\t\ttype: data.type,\n\t\t\ttitle: data.title || ''\n\t\t} );\n\t}\n\n\t/**\n\t * Fired when one of `showSuccess`, `showInfo`, `showWarning` methods is called.\n\t *\n\t * @event show\n\t * @param {Object} data Notification data.\n\t * @param {String} data.message Content of the notification.\n\t * @param {String} data.title Title of the notification.\n\t * @param {'success'|'info'|'warning'} data.type Type of notification.\n\t */\n\n\t/**\n\t * Fired when `showSuccess` method is called.\n\t *\n\t * @event show:success\n\t * @param {Object} data Notification data.\n\t * @param {String} data.message Content of the notification.\n\t * @param {String} data.title Title of the notification.\n\t * @param {'success'} data.type Type of notification.\n\t */\n\n\t/**\n\t * Fired when `showInfo` method is called.\n\t *\n\t * @event show:info\n\t * @param {Object} data Notification data.\n\t * @param {String} data.message Content of the notification.\n\t * @param {String} data.title Title of the notification.\n\t * @param {'info'} data.type Type of notification.\n\t */\n\n\t/**\n\t * Fired when `showWarning` method is called.\n\t *\n\t * When this event won't be handled and stopped by `event.stop()` then data.message of this event will\n\t * be automatically displayed as system alert.\n\t *\n\t * @event show:warning\n\t * @param {Object} data Notification data.\n\t * @param {String} data.message Content of the notification.\n\t * @param {String} data.title Title of the notification.\n\t * @param {'warning'} data.type Type of notification.\n\t */\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module module:engine/view/upcastwriter\n */\n\nimport DocumentFragment from './documentfragment';\nimport Element from './element';\nimport Text from './text';\nimport { isPlainObject } from 'lodash-es';\nimport Position from './position';\nimport Range from './range';\nimport Selection from './selection';\n\n/**\n * View upcast writer. It provides a set of methods used to manipulate non-semantic view trees.\n *\n * It should be used only while working on a non-semantic view\n * (e.g. a view created from HTML string on paste).\n * To manipulate a view which was or is being downcasted from the the model use the\n * {@link module:engine/view/downcastwriter~DowncastWriter downcast writer}.\n *\n * Read more about changing the view in the {@glink framework/guides/architecture/editing-engine#changing-the-view Changing the view}\n * section of the {@glink framework/guides/architecture/editing-engine Editing engine architecture} guide.\n *\n * Unlike `DowncastWriter`, which is available in the {@link module:engine/view/view~View#change `View#change()`} block,\n * `UpcastWriter` can wherever you need it:\n *\n *\t\tconst writer = new UpcastWriter();\n *\t\tconst text = writer.createText( 'foo!' );\n *\n *\t\twriter.appendChild( text, someViewElement );\n */\nexport default class UpcastWriter {\n\t/**\n\t * Creates a new {@link module:engine/view/documentfragment~DocumentFragment} instance.\n\t *\n\t * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children]\n\t * A list of nodes to be inserted into the created document fragment.\n\t * @returns {module:engine/view/documentfragment~DocumentFragment} The created document fragment.\n\t */\n\tcreateDocumentFragment( children ) {\n\t\treturn new DocumentFragment( children );\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/element~Element} instance.\n\t *\n\t * Attributes can be passed in various formats:\n\t *\n\t *\t\tupcastWriter.createElement( 'div', { class: 'editor', contentEditable: 'true' } ); // object\n\t *\t\tupcastWriter.createElement( 'div', [ [ 'class', 'editor' ], [ 'contentEditable', 'true' ] ] ); // map-like iterator\n\t *\t\tupcastWriter.createElement( 'div', mapOfAttributes ); // map\n\t *\n\t * @param {String} name Node name.\n\t * @param {Object|Iterable} [attrs] Collection of attributes.\n\t * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children]\n\t * A list of nodes to be inserted into created element.\n\t * @returns {module:engine/view/element~Element} Created element.\n\t */\n\tcreateElement( name, attrs, children ) {\n\t\treturn new Element( name, attrs, children );\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/text~Text} instance.\n\t *\n\t * @param {String} data The text's data.\n\t * @returns {module:engine/view/text~Text} The created text node.\n\t */\n\tcreateText( data ) {\n\t\treturn new Text( data );\n\t}\n\n\t/**\n\t * Clones the provided element.\n\t *\n\t * @see module:engine/view/element~Element#_clone\n\t * @param {module:engine/view/element~Element} element Element to be cloned.\n\t * @param {Boolean} [deep=false] If set to `true` clones element and all its children recursively. When set to `false`,\n\t * element will be cloned without any children.\n\t * @returns {module:engine/view/element~Element} Clone of this element.\n\t */\n\tclone( element, deep = false ) {\n\t\treturn element._clone( deep );\n\t}\n\n\t/**\n\t * Appends a child node or a list of child nodes at the end of this node\n\t * and sets the parent of these nodes to this element.\n\t *\n\t * @see module:engine/view/element~Element#_appendChild\n\t * @param {module:engine/view/item~Item|Iterable.<module:engine/view/item~Item>} items Items to be inserted.\n\t * @param {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment} element Element\n\t * to which items will be appended.\n\t * @fires module:engine/view/node~Node#event:change\n\t * @returns {Number} Number of appended nodes.\n\t */\n\tappendChild( items, element ) {\n\t\treturn element._appendChild( items );\n\t}\n\n\t/**\n\t * Inserts a child node or a list of child nodes on the given index and sets the parent of these nodes to\n\t * this element.\n\t *\n\t * @see module:engine/view/element~Element#_insertChild\n\t * @param {Number} index Offset at which nodes should be inserted.\n\t * @param {module:engine/view/item~Item|Iterable.<module:engine/view/item~Item>} items Items to be inserted.\n\t * @param {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment} element Element\n\t * to which items will be inserted.\n\t * @fires module:engine/view/node~Node#event:change\n\t * @returns {Number} Number of inserted nodes.\n\t */\n\tinsertChild( index, items, element ) {\n\t\treturn element._insertChild( index, items );\n\t}\n\n\t/**\n\t * Removes the given number of child nodes starting at the given index and set the parent of these nodes to `null`.\n\t *\n\t * @see module:engine/view/element~Element#_removeChildren\n\t * @param {Number} index Offset from which nodes will be removed.\n\t * @param {Number} howMany Number of nodes to remove.\n\t * @param {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment} element Element\n\t * which children will be removed.\n\t * @fires module:engine/view/node~Node#event:change\n\t * @returns {Array.<module:engine/view/node~Node>} The array containing removed nodes.\n\t */\n\tremoveChildren( index, howMany, element ) {\n\t\treturn element._removeChildren( index, howMany );\n\t}\n\n\t/**\n\t * Removes given element from the view structure. Will not have effect on detached elements.\n\t *\n\t * @param {module:engine/view/element~Element} element Element which will be removed.\n\t * @returns {Array.<module:engine/view/node~Node>} The array containing removed nodes.\n\t */\n\tremove( element ) {\n\t\tconst parent = element.parent;\n\n\t\tif ( parent ) {\n\t\t\treturn this.removeChildren( parent.getChildIndex( element ), 1, parent );\n\t\t}\n\n\t\treturn [];\n\t}\n\n\t/**\n\t * Replaces given element with the new one in the view structure. Will not have effect on detached elements.\n\t *\n\t * @param {module:engine/view/element~Element} oldElement Element which will be replaced.\n\t * @param {module:engine/view/element~Element} newElement Element which will be inserted in the place of the old element.\n\t * @returns {Boolean} Whether old element was successfully replaced.\n\t */\n\treplace( oldElement, newElement ) {\n\t\tconst parent = oldElement.parent;\n\n\t\tif ( parent ) {\n\t\t\tconst index = parent.getChildIndex( oldElement );\n\n\t\t\tthis.removeChildren( index, 1, parent );\n\t\t\tthis.insertChild( index, newElement, parent );\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Renames element by creating a copy of a given element but with its name changed and then moving contents of the\n\t * old element to the new one.\n\t *\n\t * Since this function creates a new element and removes the given one, the new element is returned to keep reference.\n\t *\n\t * @param {String} newName New element name.\n\t * @param {module:engine/view/element~Element} element Element to be renamed.\n\t * @returns {module:engine/view/element~Element|null} New element or null if the old element\n\t * was not replaced (happens for detached elements).\n\t */\n\trename( newName, element ) {\n\t\tconst newElement = new Element( newName, element.getAttributes(), element.getChildren() );\n\n\t\treturn this.replace( element, newElement ) ? newElement : null;\n\t}\n\n\t/**\n\t * Adds or overwrites element's attribute with a specified key and value.\n\t *\n\t *\t\twriter.setAttribute( linkElement, 'href', 'http://ckeditor.com' );\n\t *\n\t * @see module:engine/view/element~Element#_setAttribute\n\t * @param {String} key Attribute key.\n\t * @param {String} value Attribute value.\n\t * @param {module:engine/view/element~Element} element Element for which attribute will be set.\n\t */\n\tsetAttribute( key, value, element ) {\n\t\telement._setAttribute( key, value );\n\t}\n\n\t/**\n\t * Removes attribute from the element.\n\t *\n\t *\t\twriter.removeAttribute( linkElement, 'href' );\n\t *\n\t * @see module:engine/view/element~Element#_removeAttribute\n\t * @param {String} key Attribute key.\n\t * @param {module:engine/view/element~Element} element Element from which attribute will be removed.\n\t */\n\tremoveAttribute( key, element ) {\n\t\telement._removeAttribute( key );\n\t}\n\n\t/**\n\t * Adds specified class to the element.\n\t *\n\t *\t\twriter.addClass( linkElement, 'foo' );\n\t *\t\twriter.addClass( linkElement, [ 'foo', 'bar' ] );\n\t *\n\t * @see module:engine/view/element~Element#_addClass\n\t * @param {Array.<String>|String} className Single class name or array of class names which will be added.\n\t * @param {module:engine/view/element~Element} element Element for which class will be added.\n\t */\n\taddClass( className, element ) {\n\t\telement._addClass( className );\n\t}\n\n\t/**\n\t * Removes specified class from the element.\n\t *\n\t *\t\twriter.removeClass( linkElement, 'foo' );\n\t *\t\twriter.removeClass( linkElement, [ 'foo', 'bar' ] );\n\t *\n\t * @see module:engine/view/element~Element#_removeClass\n\t * @param {Array.<String>|String} className Single class name or array of class names which will be removed.\n\t * @param {module:engine/view/element~Element} element Element from which class will be removed.\n\t */\n\tremoveClass( className, element ) {\n\t\telement._removeClass( className );\n\t}\n\n\t/**\n\t * Adds style to the element.\n\t *\n\t *\t\twriter.setStyle( element, 'color', 'red' );\n\t *\t\twriter.setStyle( element, {\n\t *\t\t\tcolor: 'red',\n\t *\t\t\tposition: 'fixed'\n\t *\t\t} );\n\t *\n\t * @see module:engine/view/element~Element#_setStyle\n\t * @param {String|Object} property Property name or object with key - value pairs.\n\t * @param {String} [value] Value to set. This parameter is ignored if object is provided as the first parameter.\n\t * @param {module:engine/view/element~Element} element Element for which style will be added.\n\t */\n\tsetStyle( property, value, element ) {\n\t\tif ( isPlainObject( property ) && element === undefined ) {\n\t\t\telement = value;\n\t\t}\n\t\telement._setStyle( property, value );\n\t}\n\n\t/**\n\t * Removes specified style from the element.\n\t *\n\t *\t\twriter.removeStyle( element, 'color' ); // Removes 'color' style.\n\t *\t\twriter.removeStyle( element, [ 'color', 'border-top' ] ); // Removes both 'color' and 'border-top' styles.\n\t *\n\t * @see module:engine/view/element~Element#_removeStyle\n\t * @param {Array.<String>|String} property Style property name or names to be removed.\n\t * @param {module:engine/view/element~Element} element Element from which style will be removed.\n\t */\n\tremoveStyle( property, element ) {\n\t\telement._removeStyle( property );\n\t}\n\n\t/**\n\t * Sets a custom property on element. Unlike attributes, custom properties are not rendered to the DOM,\n\t * so they can be used to add special data to elements.\n\t *\n\t * @see module:engine/view/element~Element#_setCustomProperty\n\t * @param {String|Symbol} key Custom property name/key.\n\t * @param {*} value Custom property value to be stored.\n\t * @param {module:engine/view/element~Element} element Element for which custom property will be set.\n\t */\n\tsetCustomProperty( key, value, element ) {\n\t\telement._setCustomProperty( key, value );\n\t}\n\n\t/**\n\t * Removes a custom property stored under the given key.\n\t *\n\t * @see module:engine/view/element~Element#_removeCustomProperty\n\t * @param {String|Symbol} key Name/key of the custom property to be removed.\n\t * @param {module:engine/view/element~Element} element Element from which the custom property will be removed.\n\t * @returns {Boolean} Returns true if property was removed.\n\t */\n\tremoveCustomProperty( key, element ) {\n\t\treturn element._removeCustomProperty( key );\n\t}\n\n\t/**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/view/position~Position position},\n\t * * parent element and offset (offset defaults to `0`),\n\t * * parent element and `'end'` (sets position at the end of that element),\n\t * * {@link module:engine/view/item~Item view item} and `'before'` or `'after'` (sets position before or after given view item).\n\t *\n\t * This method is a shortcut to other constructors such as:\n\t *\n\t * * {@link #createPositionBefore},\n\t * * {@link #createPositionAfter},\n\t *\n\t * @param {module:engine/view/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tcreatePositionAt( itemOrPosition, offset ) {\n\t\treturn Position._createAt( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Creates a new position after given view item.\n\t *\n\t * @param {module:engine/view/item~Item} item View item after which the position should be located.\n\t * @returns {module:engine/view/position~Position}\n\t */\n\tcreatePositionAfter( item ) {\n\t\treturn Position._createAfter( item );\n\t}\n\n\t/**\n\t * Creates a new position before given view item.\n\t *\n\t * @param {module:engine/view/item~Item} item View item before which the position should be located.\n\t * @returns {module:engine/view/position~Position}\n\t */\n\tcreatePositionBefore( item ) {\n\t\treturn Position._createBefore( item );\n\t}\n\n\t/**\n\t * Creates a range spanning from `start` position to `end` position.\n\t *\n\t * **Note:** This factory method creates it's own {@link module:engine/view/position~Position} instances basing on passed values.\n\t *\n\t * @param {module:engine/view/position~Position} start Start position.\n\t * @param {module:engine/view/position~Position} [end] End position. If not set, range will be collapsed at `start` position.\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tcreateRange( start, end ) {\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Creates a range that starts before given {@link module:engine/view/item~Item view item} and ends after it.\n\t *\n\t * @param {module:engine/view/item~Item} item\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tcreateRangeOn( item ) {\n\t\treturn Range._createOn( item );\n\t}\n\n\t/**\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * @param {module:engine/view/element~Element} element Element which is a parent for the range.\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tcreateRangeIn( element ) {\n\t\treturn Range._createIn( element );\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/selection~Selection} instance.\n\t *\n\t * \t\t// Creates empty selection without ranges.\n\t *\t\tconst selection = writer.createSelection();\n\t *\n\t *\t\t// Creates selection at the given range.\n\t *\t\tconst range = writer.createRange( start, end );\n\t *\t\tconst selection = writer.createSelection( range );\n\t *\n\t *\t\t// Creates selection at the given ranges\n\t * \t\tconst ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t *\t\tconst selection = writer.createSelection( ranges );\n\t *\n\t *\t\t// Creates selection from the other selection.\n\t *\t\tconst otherSelection = writer.createSelection();\n\t *\t\tconst selection = writer.createSelection( otherSelection );\n\t *\n\t *\t\t// Creates selection from the document selection.\n\t *\t\tconst selection = writer.createSelection( editor.editing.view.document.selection );\n\t *\n\t * \t\t// Creates selection at the given position.\n\t *\t\tconst position = writer.createPositionFromPath( root, path );\n\t *\t\tconst selection = writer.createSelection( position );\n\t *\n\t *\t\t// Creates collapsed selection at the position of given item and offset.\n\t *\t\tconst paragraph = writer.createContainerElement( 'paragraph' );\n\t *\t\tconst selection = writer.createSelection( paragraph, offset );\n\t *\n\t *\t\t// Creates a range inside an {@link module:engine/view/element~Element element} which starts before the\n\t *\t\t// first child of that element and ends after the last child of that element.\n\t *\t\tconst selection = writer.createSelection( paragraph, 'in' );\n\t *\n\t *\t\t// Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends\n\t *\t\t// just after the item.\n\t *\t\tconst selection = writer.createSelection( paragraph, 'on' );\n\t *\n\t * `Selection`'s constructor allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t *\t\t// Creates backward selection.\n\t *\t\tconst selection = writer.createSelection( range, { backward: true } );\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be properly handled by screen readers).\n\t *\n\t *\t\t// Creates fake selection with label.\n\t *\t\tconst selection = writer.createSelection( range, { fake: true, label: 'foo' } );\n\t *\n\t * @param {module:engine/view/selection~Selectable} [selectable=null]\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Offset or place when selectable is an `Item`.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.backward] Sets this selection instance to be backward.\n\t * @param {Boolean} [options.fake] Sets this selection instance to be marked as `fake`.\n\t * @param {String} [options.label] Label for the fake selection.\n\t * @returns {module:engine/view/selection~Selection}\n\t */\n\tcreateSelection( selectable, placeOrOffset, options ) {\n\t\treturn new Selection( selectable, placeOrOffset, options );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/command\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor commands.\n *\n * Commands are the main way to manipulate editor contents and state. They are mostly used by UI elements (or by other\n * commands) to make changes in the model. Commands are available in every part of code that has access to\n * the {@link module:core/editor/editor~Editor editor} instance.\n *\n * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n *\n * By default commands are disabled when the editor is in {@link module:core/editor/editor~Editor#isReadOnly read-only} mode.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Command {\n\t/**\n\t * Creates a new `Command` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor Editor on which this command will be used.\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor on which this command will be used.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * The value of the command. A concrete command class should define what it represents for it.\n\t\t *\n\t\t * For example, the `'bold'` command's value indicates whether the selection starts in a bolded text.\n\t\t * And the value of the `'link'` command may be an object with links details.\n\t\t *\n\t\t * It is possible for a command to have no value (e.g. for stateless actions such as `'imageUpload'`).\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member #value\n\t\t */\n\t\tthis.set( 'value', undefined );\n\n\t\t/**\n\t\t * Flag indicating whether a command is enabled or disabled.\n\t\t * A disabled command will do nothing when executed.\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * It is possible to disable a command from \"outside\". For instance, in your integration you may want to disable\n\t\t * a certain set of commands for the time being. To do that, you can use the fact that `isEnabled` is observable\n\t\t * and it fires the `set:isEnabled` event every time anyone tries to modify its value:\n\t\t *\n\t\t *\t\tfunction disableCommand( cmd ) {\n\t\t *\t\t\tcmd.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t *\n\t\t *\t\t\tcmd.isEnabled = false;\n\t\t *\n\t\t *\t\t\t// Make it possible to enable the command again.\n\t\t *\t\t\treturn () => {\n\t\t *\t\t\t\tcmd.off( 'set:isEnabled', forceDisable );\n\t\t *\t\t\t\tcmd.refresh();\n\t\t *\t\t\t};\n\t\t *\n\t\t *\t\t\tfunction forceDisable( evt ) {\n\t\t *\t\t\t\tevt.return = false;\n\t\t *\t\t\t\tevt.stop();\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\n\t\t *\t\t// Usage:\n\t\t *\n\t\t *\t\t// Disabling the command.\n\t\t *\t\tconst enableBold = disableCommand( editor.commands.get( 'bold' ) );\n\t\t *\n\t\t *\t\t// Enabling the command again.\n\t\t *\t\tenableBold();\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\t\tthis.set( 'isEnabled', false );\n\n\t\t/**\n\t\t * Holds identifiers for {@link #forceDisabled} mechanism.\n\t\t *\n\t\t * @type {Set.<String>}\n\t\t * @private\n\t\t */\n\t\tthis._disableStack = new Set();\n\n\t\tthis.decorate( 'execute' );\n\n\t\t// By default every command is refreshed when changes are applied to the model.\n\t\tthis.listenTo( this.editor.model.document, 'change', () => {\n\t\t\tthis.refresh();\n\t\t} );\n\n\t\tthis.on( 'execute', evt => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// By default commands are disabled when the editor is in read-only mode.\n\t\tthis.listenTo( editor, 'change:isReadOnly', ( evt, name, value ) => {\n\t\t\tif ( value ) {\n\t\t\t\tthis.forceDisabled( 'readOnlyMode' );\n\t\t\t} else {\n\t\t\t\tthis.clearForceDisabled( 'readOnlyMode' );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties\n\t * in this method.\n\t *\n\t * This method is automatically called when\n\t * {@link module:engine/model/document~Document#event:change any changes are applied to the document}.\n\t */\n\trefresh() {\n\t\tthis.isEnabled = true;\n\t}\n\n\t/**\n\t * Disables the command.\n\t *\n\t * Command may be disabled by multiple features or algorithms (at once). When disabling a command, unique id should be passed\n\t * (e.g. feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the command.\n\t * The command becomes enabled only after all features {@link #clearForceDisabled enabled it back}.\n\t *\n\t * Disabling and enabling a command:\n\t *\n\t *\t\tcommand.isEnabled; // -> true\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Command disabled by multiple features:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'OtherFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'OtherFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Multiple disabling with the same identifier is redundant:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * **Note:** some commands or algorithms may have more complex logic when it comes to enabling or disabling certain commands,\n\t * so the command might be still disabled after {@link #clearForceDisabled} was used.\n\t *\n\t * @param {String} id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the command.\n\t */\n\tforceDisabled( id ) {\n\t\tthis._disableStack.add( id );\n\n\t\tif ( this._disableStack.size == 1 ) {\n\t\t\tthis.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * Clears forced disable previously set through {@link #clearForceDisabled}. See {@link #clearForceDisabled}.\n\t *\n\t * @param {String} id Unique identifier, equal to the one passed in {@link #forceDisabled} call.\n\t */\n\tclearForceDisabled( id ) {\n\t\tthis._disableStack.delete( id );\n\n\t\tif ( this._disableStack.size == 0 ) {\n\t\t\tthis.off( 'set:isEnabled', forceDisable );\n\t\t\tthis.refresh();\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`}\n\t * to the command.\n\t *\n\t * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`).\n\t * This behavior is implemented by a high priority listener to the {@link #event:execute} event.\n\t *\n\t * In order to see how to disable a command from \"outside\" see the {@link #isEnabled} documentation.\n\t *\n\t * @fires execute\n\t */\n\texecute() {}\n\n\t/**\n\t * Destroys the command.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Event fired by the {@link #execute} method. The command action is a listener to this event so it's\n\t * possible to change/cancel the behavior of the command by listening to this event.\n\t *\n\t * See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples.\n\t *\n\t * **Note:** This event is fired even if command is disabled. However, it is automatically blocked\n\t * by a high priority listener in order to prevent command execution.\n\t *\n\t * @event execute\n\t */\n}\n\nmix( Command, ObservableMixin );\n\n// Helper function that forces command to be disabled.\nfunction forceDisable( evt ) {\n\tevt.return = false;\n\tevt.stop();\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/image/utils\n */\n\nimport { findOptimalInsertionPosition, isWidget, toWidget } from '@ckeditor/ckeditor5-widget/src/utils';\n\n/**\n * Converts a given {@link module:engine/view/element~Element} to an image widget:\n * * Adds a {@link module:engine/view/element~Element#_setCustomProperty custom property} allowing to recognize the image widget element.\n * * Calls the {@link module:widget/utils~toWidget} function with the proper element's label creator.\n *\n * @param {module:engine/view/element~Element} viewElement\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer An instance of the view writer.\n * @param {String} label The element's label. It will be concatenated with the image `alt` attribute if one is present.\n * @returns {module:engine/view/element~Element}\n */\nexport function toImageWidget( viewElement, writer, label ) {\n\twriter.setCustomProperty( 'image', true, viewElement );\n\n\treturn toWidget( viewElement, writer, { label: labelCreator } );\n\n\tfunction labelCreator() {\n\t\tconst imgElement = viewElement.getChild( 0 );\n\t\tconst altText = imgElement.getAttribute( 'alt' );\n\n\t\treturn altText ? `${ altText } ${ label }` : label;\n\t}\n}\n\n/**\n * Checks if a given view element is an image widget.\n *\n * @param {module:engine/view/element~Element} viewElement\n * @returns {Boolean}\n */\nexport function isImageWidget( viewElement ) {\n\treturn !!viewElement.getCustomProperty( 'image' ) && isWidget( viewElement );\n}\n\n/**\n * Returns an image widget editing view element if one is selected.\n *\n * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} selection\n * @returns {module:engine/view/element~Element|null}\n */\nexport function getSelectedImageWidget( selection ) {\n\tconst viewElement = selection.getSelectedElement();\n\n\tif ( viewElement && isImageWidget( viewElement ) ) {\n\t\treturn viewElement;\n\t}\n\n\treturn null;\n}\n\n/**\n * Checks if the provided model element is an `image`.\n *\n * @param {module:engine/model/element~Element} modelElement\n * @returns {Boolean}\n */\nexport function isImage( modelElement ) {\n\treturn !!modelElement && modelElement.is( 'image' );\n}\n\n/**\n * Handles inserting single file. This method unifies image insertion using {@link module:widget/utils~findOptimalInsertionPosition} method.\n *\n *\t\tmodel.change( writer => {\n *\t\t\tinsertImage( writer, model, { src: 'path/to/image.jpg' } );\n *\t\t} );\n *\n * @param {module:engine/model/writer~Writer} writer\n * @param {module:engine/model/model~Model} model\n * @param {Object} [attributes={}] Attributes of inserted image\n */\nexport function insertImage( writer, model, attributes = {} ) {\n\tconst imageElement = writer.createElement( 'image', attributes );\n\n\tconst insertAtSelection = findOptimalInsertionPosition( model.document.selection, model );\n\n\tmodel.insertContent( imageElement, insertAtSelection );\n\n\t// Inserting an image might've failed due to schema regulations.\n\tif ( imageElement.parent ) {\n\t\twriter.setSelection( imageElement, 'on' );\n\t}\n}\n\n/**\n * Checks if image can be inserted at current model selection.\n *\n * @param {module:engine/model/model~Model} model\n * @returns {Boolean}\n */\nexport function isImageAllowed( model ) {\n\tconst schema = model.schema;\n\tconst selection = model.document.selection;\n\n\treturn isImageAllowedInParent( selection, schema, model ) &&\n\t\t!checkSelectionOnObject( selection, schema ) &&\n\t\tisInOtherImage( selection );\n}\n\n// Checks if image is allowed by schema in optimal insertion parent.\n//\n// @returns {Boolean}\nfunction isImageAllowedInParent( selection, schema, model ) {\n\tconst parent = getInsertImageParent( selection, model );\n\n\treturn schema.checkChild( parent, 'image' );\n}\n\n// Check if selection is on object.\n//\n// @returns {Boolean}\nfunction checkSelectionOnObject( selection, schema ) {\n\tconst selectedElement = selection.getSelectedElement();\n\n\treturn selectedElement && schema.isObject( selectedElement );\n}\n\n// Checks if selection is placed in other image (ie. in caption).\nfunction isInOtherImage( selection ) {\n\treturn [ ...selection.focus.getAncestors() ].every( ancestor => !ancestor.is( 'image' ) );\n}\n\n// Returns a node that will be used to insert image with `model.insertContent` to check if image can be placed there.\nfunction getInsertImageParent( selection, model ) {\n\tconst insertAt = findOptimalInsertionPosition( selection, model );\n\n\tconst parent = insertAt.parent;\n\n\tif ( parent.isEmpty && !parent.is( '$root' ) ) {\n\t\treturn parent.parent;\n\t}\n\n\treturn parent;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\nimport FileRepository from '@ckeditor/ckeditor5-upload/src/filerepository';\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport { insertImage, isImageAllowed } from '../image/utils';\n\n/**\n * @module image/imageupload/imageuploadcommand\n */\n\n/**\n * Image upload command.\n *\n * The command is registered by the {@link module:image/imageupload/imageuploadediting~ImageUploadEditing} plugin as `'imageUpload'`.\n *\n * In order to upload an image at the current selection position\n * (according to the {@link module:widget/utils~findOptimalInsertionPosition} algorithm),\n * execute the command and pass the native image file instance:\n *\n *\t\tthis.listenTo( editor.editing.view.document, 'clipboardInput', ( evt, data ) => {\n *\t\t\t// Assuming that only images were pasted:\n *\t\t\tconst images = Array.from( data.dataTransfer.files );\n *\n *\t\t\t// Upload the first image:\n *\t\t\teditor.execute( 'imageUpload', { file: images[ 0 ] } );\n *\t\t} );\n *\n * It is also possible to insert multiple images at once:\n *\n *\t\teditor.execute( 'imageUpload', {\n *\t\t\tfile: [\n *\t\t\t\tfile1,\n *\t\t\t\tfile2\n *\t\t\t]\n *\t\t} );\n *\n * @extends module:core/command~Command\n */\nexport default class ImageUploadCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.isEnabled = isImageAllowed( this.editor.model );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} options Options for the executed command.\n\t * @param {File|Array.<File>} options.file The image file or an array of image files to upload.\n\t */\n\texecute( options ) {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\n\t\tconst fileRepository = editor.plugins.get( FileRepository );\n\n\t\tmodel.change( writer => {\n\t\t\tconst filesToUpload = Array.isArray( options.file ) ? options.file : [ options.file ];\n\n\t\t\tfor ( const file of filesToUpload ) {\n\t\t\t\tuploadImage( writer, model, fileRepository, file );\n\t\t\t}\n\t\t} );\n\t}\n}\n\n// Handles uploading single file.\n//\n// @param {module:engine/model/writer~writer} writer\n// @param {module:engine/model/model~Model} model\n// @param {File} file\nfunction uploadImage( writer, model, fileRepository, file ) {\n\tconst loader = fileRepository.createLoader( file );\n\n\t// Do not throw when upload adapter is not set. FileRepository will log an error anyway.\n\tif ( !loader ) {\n\t\treturn;\n\t}\n\n\tinsertImage( writer, model, { uploadId: loader.id } );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module image/imageupload/imageuploadediting\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport FileRepository from '@ckeditor/ckeditor5-upload/src/filerepository';\nimport Notification from '@ckeditor/ckeditor5-ui/src/notification/notification';\nimport UpcastWriter from '@ckeditor/ckeditor5-engine/src/view/upcastwriter';\nimport ImageUploadCommand from '../../src/imageupload/imageuploadcommand';\nimport {\n isImageType,\n isLocalImage,\n fetchLocalImage\n} from '../../src/imageupload/utils';\n/**\n * The editing part of the image upload feature. It registers the `'imageUpload'` command.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageUploadEditing extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n static get requires() {\n return [\n FileRepository,\n Notification\n ];\n }\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const doc = editor.model.document;\n const schema = editor.model.schema;\n const conversion = editor.conversion;\n const fileRepository = editor.plugins.get(FileRepository);\n // Setup schema to allow uploadId and uploadStatus for images.\n schema.extend('image', {\n allowAttributes: [\n 'uploadId',\n 'uploadStatus'\n ]\n });\n // Register imageUpload command.\n editor.commands.add('imageUpload', new ImageUploadCommand(editor));\n // Register upcast converter for uploadId.\n conversion.for('upcast').attributeToAttribute({\n view: {\n name: 'img',\n key: 'uploadId'\n },\n model: 'uploadId'\n });\n // Handle pasted images.\n // For every image file, a new file loader is created and a placeholder image is\n // inserted into the content. Then, those images are uploaded once they appear in the model\n // (see Document#change listener below).\n this.listenTo(editor.editing.view.document, 'clipboardInput', (evt, data) => {\n // Skip if non empty HTML data is included.\n // https://github.com/ckeditor/ckeditor5-upload/issues/68\n if (isHtmlIncluded(data.dataTransfer)) {\n return;\n }\n const images = Array.from(data.dataTransfer.files).filter(file => {\n // See https://github.com/ckeditor/ckeditor5-image/pull/254.\n if (!file) {\n return false;\n }\n return isImageType(file);\n });\n const ranges = data.targetRanges.map(viewRange => editor.editing.mapper.toModelRange(viewRange));\n editor.model.change(writer => {\n // Set selection to paste target.\n writer.setSelection(ranges);\n if (images.length) {\n evt.stop();\n // Upload images after the selection has changed in order to ensure the command's state is refreshed.\n editor.model.enqueueChange('default', () => {\n editor.execute('imageUpload', { file: images });\n });\n }\n });\n });\n // Handle HTML pasted with images with base64 or blob sources.\n // For every image file, a new file loader is created and a placeholder image is\n // inserted into the content. Then, those images are uploaded once they appear in the model\n // (see Document#change listener below).\n if (editor.plugins.has('Clipboard')) {\n this.listenTo(editor.plugins.get('Clipboard'), 'inputTransformation', (evt, data) => {\n const fetchableImages = Array.from(editor.editing.view.createRangeIn(data.content)).filter(value => isLocalImage(value.item) && !value.item.getAttribute('uploadProcessed')).map(value => {\n return {\n promise: fetchLocalImage(value.item),\n imageElement: value.item\n };\n });\n if (!fetchableImages.length) {\n return;\n }\n const writer = new UpcastWriter();\n for (const fetchableImage of fetchableImages) {\n // Set attribute marking that the image was processed already.\n writer.setAttribute('uploadProcessed', true, fetchableImage.imageElement);\n const loader = fileRepository.createLoader(fetchableImage.promise);\n if (loader) {\n writer.setAttribute('src', '', fetchableImage.imageElement);\n writer.setAttribute('uploadId', loader.id, fetchableImage.imageElement);\n }\n }\n });\n }\n // Prevents from the browser redirecting to the dropped image.\n editor.editing.view.document.on('dragover', (evt, data) => {\n data.preventDefault();\n });\n // Upload placeholder images that appeared in the model.\n doc.on('change', () => {\n const changes = doc.differ.getChanges({ includeChangesInGraveyard: true });\n for (const entry of changes) {\n if (entry.type == 'insert' && entry.name == 'image') {\n const item = entry.position.nodeAfter;\n const isInGraveyard = entry.position.root.rootName == '$graveyard';\n // Check if the image element still has upload id.\n const uploadId = item.getAttribute('uploadId');\n if (!uploadId) {\n continue;\n }\n // Check if the image is loaded on this client.\n const loader = fileRepository.loaders.get(uploadId);\n if (!loader) {\n continue;\n }\n if (isInGraveyard) {\n // If the image was inserted to the graveyard - abort the loading process.\n loader.abort();\n } else if (loader.status == 'idle') {\n // If the image was inserted into content and has not been loaded yet, start loading it.\n this._readAndUpload(loader, item);\n }\n }\n }\n });\n }\n /**\n\t * Read and upload an image.\n\t *\n\t * The image is read from the disk and as a base64 encoded string it is set temporarily to\n\t * `image[src]`. When the image is successfully uploaded the temporary data is replaced with the target\n\t * image's URL (the URL to the uploaded image on the server).\n\t *\n\t * @protected\n\t * @param {module:upload/filerepository~FileLoader} loader\n\t * @param {module:engine/model/element~Element} imageElement\n\t * @returns {Promise}\n\t */\n _readAndUpload(loader, imageElement) {\n const editor = this.editor;\n const model = editor.model;\n const t = editor.locale.t;\n const fileRepository = editor.plugins.get(FileRepository);\n const notification = editor.plugins.get(Notification);\n model.enqueueChange('transparent', writer => {\n writer.setAttribute('uploadStatus', 'reading', imageElement);\n });\n return loader.read().then(data => {\n const viewFigure = editor.editing.mapper.toViewElement(imageElement);\n const viewImg = viewFigure.getChild(0);\n const promise = loader.upload();\n editor.editing.view.change(writer => {\n writer.setAttribute('src', data, viewImg);\n });\n model.enqueueChange('transparent', writer => {\n writer.setAttribute('uploadStatus', 'uploading', imageElement);\n });\n return promise;\n }).then(data => {\n model.enqueueChange('transparent', writer => {\n writer.setAttributes({\n uploadStatus: 'complete',\n src: data.default\n }, imageElement);\n this._parseAndSetSrcsetAttributeOnImage(data, imageElement, writer);\n });\n clean();\n }).catch(error => {\n // If status is not 'error' nor 'aborted' - throw error because it means that something else went wrong,\n // it might be generic error and it would be real pain to find what is going on.\n if (loader.status !== 'error' && loader.status !== 'aborted') {\n throw error;\n }\n // Might be 'aborted'.\n if (loader.status == 'error' && error) {\n notification.showWarning(error, {\n title: t('ag'),\n namespace: 'upload'\n });\n }\n clean();\n // Permanently remove image from insertion batch.\n model.enqueueChange('transparent', writer => {\n writer.remove(imageElement);\n });\n });\n function clean() {\n model.enqueueChange('transparent', writer => {\n writer.removeAttribute('uploadId', imageElement);\n writer.removeAttribute('uploadStatus', imageElement);\n });\n fileRepository.destroyLoader(loader);\n }\n }\n /**\n\t * Creates `srcset` attribute based on a given file upload response and sets it as an attribute to a specific image element.\n\t *\n\t * @protected\n\t * @param {Object} data Data object from which `srcset` will be created.\n\t * @param {module:engine/model/element~Element} image The image element on which `srcset` attribute will be set.\n\t * @param {module:engine/model/writer~Writer} writer\n\t */\n _parseAndSetSrcsetAttributeOnImage(data, image, writer) {\n // Srcset attribute for responsive images support.\n let maxWidth = 0;\n const srcsetAttribute = Object.keys(data) // Filter out keys that are not integers.\n.filter(key => {\n const width = parseInt(key, 10);\n if (!isNaN(width)) {\n maxWidth = Math.max(maxWidth, width);\n return true;\n }\n }) // Convert each key to srcset entry.\n.map(key => `${ data[key] } ${ key }w`) // Join all entries.\n.join(', ');\n if (srcsetAttribute != '') {\n writer.setAttribute('srcset', {\n data: srcsetAttribute,\n width: maxWidth\n }, image);\n }\n }\n}\n// Returns `true` if non-empty `text/html` is included in the data transfer.\n//\n// @param {module:clipboard/datatransfer~DataTransfer} dataTransfer\n// @returns {Boolean}\nexport function isHtmlIncluded(dataTransfer) {\n return Array.from(dataTransfer.types).includes('text/html') && dataTransfer.getData('text/html') !== '';\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imageupload\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ImageUploadUI from './imageupload/imageuploadui';\nimport ImageUploadProgress from './imageupload/imageuploadprogress';\nimport ImageUploadEditing from './imageupload/imageuploadediting';\n\n/**\n * The image upload plugin.\n *\n * For a detailed overview, check the {@glink features/image-upload/image-upload image upload feature} documentation.\n *\n * This plugin does not do anything directly, but it loads a set of specific plugins to enable image uploading:\n *\n * * {@link module:image/imageupload/imageuploadediting~ImageUploadEditing},\n * * {@link module:image/imageupload/imageuploadui~ImageUploadUI},\n * * {@link module:image/imageupload/imageuploadprogress~ImageUploadProgress}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageUpload extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageUpload';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ImageUploadEditing, ImageUploadUI, ImageUploadProgress ];\n\t}\n}\n","const childPagesMacroSymbol = Symbol( 'isWpButtonMacroSymbol' );\nimport {toWidget, isWidget} from '@ckeditor/ckeditor5-widget/src/utils';\n\nexport function toChildPagesMacroWidget( viewElement, writer, label ) {\n\twriter.setCustomProperty( childPagesMacroSymbol, true, viewElement );\n\treturn toWidget( viewElement, writer, { label: label });\n}\n\n\nexport function isChildPagesMacroWidget( viewElement ) {\n\treturn !!viewElement.getCustomProperty( childPagesMacroSymbol ) && isWidget( viewElement );\n}\n\n\nexport function isChildPagesMacroWidgetSelected( selection ) {\n\tconst viewElement = selection.getSelectedElement();\n\n\treturn !!( viewElement && isChildPagesMacroWidget( viewElement ) );\n}\n","import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport ViewPosition from '@ckeditor/ckeditor5-engine/src/view/position';\nimport ViewRange from '@ckeditor/ckeditor5-engine/src/view/range';\n\nimport {toChildPagesMacroWidget} from './utils';\n\nexport default class OPChildPagesEditing extends Plugin {\n\n\tstatic get pluginName() {\n\t\treturn 'OPChildPagesEditing';\n\t}\n\n\tstatic get buttonName(){\n\t\treturn \"insertChildPages\";\n\t}\n\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst conversion = editor.conversion;\n\n\t\t// Schema.\n\t\tmodel.schema.register( 'op-macro-child-pages', {\n\t\t\tallowWhere: ['$block'],\n\t\t\tallowAttributes: ['page'],\n\t\t\tisBlock: true,\n\t\t\tisLimit: true\n\t\t});\n\n\t\tconversion.for( 'upcast' )\n\t\t\t.elementToElement( {\n\t\t\t\tview: {\n\t\t\t\t\tname: 'macro',\n\t\t\t\t\tclasses: 'child_pages'\n\t\t\t\t},\n\t\t\t\tmodel: ( viewElement, modelWriter ) => {\n\t\t\t\t\tconst page = viewElement.getAttribute( 'data-page' ) || '';\n\t\t\t\t\tconst includeParent = viewElement.getAttribute( 'data-include-parent' ) == 'true';\n\n\t\t\t\t\treturn modelWriter.createElement(\n\t\t\t\t\t\t'op-macro-child-pages',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpage: page,\n\t\t\t\t\t\t\tincludeParent: includeParent\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} );\n\n\n\t\tconversion.for( 'editingDowncast' )\n\t\t\t.elementToElement({\n\t\t\t\tmodel: 'op-macro-child-pages',\n\t\t\t\tview: (modelElement, writer) => {\n\t\t\t\t\treturn this.createMacroViewElement(modelElement, writer);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.add(dispatcher => dispatcher.on( 'attribute:page', this.modelAttributeToView.bind(this)))\n\t\t\t.add(dispatcher => dispatcher.on( 'attribute:includeParent', this.modelAttributeToView.bind(this)));\n\n\t\tconversion.for('dataDowncast').elementToElement({\n\t\t\tmodel: 'op-macro-child-pages',\n\t\t\tview: (modelElement, writer) => {\n\t\t\t\tconst element = writer.createContainerElement(\n\t\t\t\t\t'macro',\n\t\t\t\t\t{\n\t\t\t\t\t\t'class': 'child_pages',\n\t\t\t\t\t\t'data-page': modelElement.getAttribute('page') || '',\n\t\t\t\t\t\t'data-include-parent': modelElement.getAttribute('includeParent') || ''\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\treturn element;\n\t\t\t}\n\t\t});\n\n\t\teditor.ui.componentFactory.add( OPChildPagesEditing.buttonName, locale => {\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\tlabel: window.I18n.t('js.editor.macro.child_pages.button'),\n\t\t\t\twithText: true\n\t\t\t} );\n\n\t\t\t// Callback executed once the image is clicked.\n\t\t\tview.on( 'execute', () => {\n\t\t\t\teditor.model.change(writer => {\n\t\t\t\t\tconst element = writer.createElement( 'op-macro-child-pages', {});\n\n\t\t\t\t\teditor.model.insertContent( element, editor.model.document.selection );\n\t\t\t\t});\n\t\t\t} );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n\n\tmodelAttributeToView( evt, data, conversionApi ) {\n\t\tconst modelElement = data.item;\n\t\tif (!modelElement.is('op-macro-child-pages')) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Mark element as consumed by conversion.\n\t\tconversionApi.consumable.consume(data.item, evt.name);\n\n\t\t// Get mapped view element to update.\n\t\tconst viewElement = conversionApi.mapper.toViewElement(modelElement);\n\n\t\t// Remove current <div> element contents.\n\t\tconversionApi.writer.remove(conversionApi.writer.createRangeIn(viewElement));\n\n\t\t// Set current content\n\t\tthis.setPlaceholderContent(conversionApi.writer, modelElement, viewElement);\n\t}\n\n\tmacroLabel() {\n\t\treturn window.I18n.t('js.editor.macro.child_pages.text');\n\t}\n\n\tpageLabel(page) {\n\t\tif (page && page.length > 0) {\n\t\t\treturn page\n\t\t} else {\n\t\t\treturn window.I18n.t('js.editor.macro.child_pages.this_page');\n\t\t}\n\t}\n\n\tincludeParentText(includeParent) {\n\t\tif (includeParent) {\n\t\t\treturn ` (${window.I18n.t('js.editor.macro.child_pages.include_parent')})`;\n\t\t} else {\n\t\t\treturn '';\n\t\t}\n\t}\n\n\tcreateMacroViewElement(modelElement, writer) {\n\t\tconst placeholderContainer = writer.createContainerElement( 'div', { class: 'macro -child_pages' } );\n\n\t\tthis.setPlaceholderContent( writer, modelElement, placeholderContainer );\n\n\t\treturn toChildPagesMacroWidget(placeholderContainer, writer, { label: this.macroLabel() } )\n\t}\n\n\tsetPlaceholderContent(writer, modelElement, placeholderContainer ) {\n\t\tconst page = modelElement.getAttribute('page');\n\t\tconst includeParent = modelElement.getAttribute('includeParent');\n\t\tconst macroLabel = this.macroLabel();\n\t\tconst pageLabel = this.pageLabel(page);\n\t\tconst pageLabelContainer = writer.createContainerElement( 'span', { class: 'macro-value' } );\n\t\tlet placeholderContent = [ writer.createText( `${macroLabel} ` ) ];\n\t\twriter.insert( writer.createPositionAt( pageLabelContainer, 0 ), writer.createText( `${pageLabel}` ) )\n\t\tplaceholderContent.push( pageLabelContainer );\n\t\tplaceholderContent.push( writer.createText( this.includeParentText(includeParent) ));\n\n\t\twriter.insert( writer.createPositionAt( placeholderContainer, 0 ), placeholderContent );\n\t}\n}\n","import Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ContextualBalloon from '@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon';\n\nimport {isChildPagesMacroWidgetSelected} from './utils';\nimport {createToolbarEditButton} from '../../helpers/create-toolbar-edit-button';\nimport {createEditToolbar} from '../../helpers/create-toolbar';\nimport {getPluginContext} from '../op-context/op-context';\n\n\nconst balloonClassName = 'ck-toolbar-container';\n\nexport default class OPChildPagesToolbar extends Plugin {\n\tstatic get requires() {\n\t\treturn [ ContextualBalloon ];\n\t}\n\n\tstatic get pluginName() {\n\t\treturn 'OPChildPagesToolbar';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = this.editor.model;\n\t\tconst pluginContext = getPluginContext(editor);\n\n\t\t// Add editing button\n\t\tcreateToolbarEditButton( editor, 'opEditChildPagesMacroButton', widget => {\n\t\t\tconst macroService = pluginContext.services.macros;\n\t\t\tconst pageAttribute = widget.getAttribute('page');\n\t\t\tconst includeParent = widget.getAttribute('includeParent');\n\t\t\tconst page = (pageAttribute && pageAttribute.length > 0) ? pageAttribute : '';\n\t\t\tmacroService\n\t\t\t\t.configureChildPages(page, includeParent)\n\t\t\t\t.then((macroConf) => model.change(writer => {\n\t\t\t\t\t\twriter.setAttribute( 'page', macroConf.page, widget );\n\t\t\t\t\t\twriter.setAttribute( 'includeParent', macroConf.includeParent, widget );\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t} );\n\t}\n\n\tafterInit() {\n\t\t// Add actual toolbar\n\t\tcreateEditToolbar(\n\t\t\tthis,\n\t\t\tthis.editor,\n\t\t\t'OPChildPages',\n\t\t\tisChildPagesMacroWidgetSelected\n\t\t);\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor.data, 'ready', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n/**\n * Array of loaded plugins.\n *\n * @typedef {Array.<module:core/plugin~PluginInterface>} module:core/plugin~LoadedPlugins\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor.data, 'ready', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n/**\n * Array of loaded plugins.\n *\n * @typedef {Array.<module:core/plugin~PluginInterface>} module:core/plugin~LoadedPlugins\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module clipboard/datatransfer\n */\n\n/**\n * Facade over the native [`DataTransfer`](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer) object.\n */\nexport default class DataTransfer {\n\tconstructor( nativeDataTransfer ) {\n\t\t/**\n\t\t * The array of files created from the native `DataTransfer#files` or `DataTransfer#items`.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Array.<File>} #files\n\t\t */\n\t\tthis.files = getFiles( nativeDataTransfer );\n\n\t\t/**\n\t\t * The native DataTransfer object.\n\t\t *\n\t\t * @private\n\t\t * @member {DataTransfer} #_native\n\t\t */\n\t\tthis._native = nativeDataTransfer;\n\t}\n\n\t/**\n\t * Returns an array of available native content types.\n\t *\n\t * @returns {Array.<String>}\n\t */\n\tget types() {\n\t\treturn this._native.types;\n\t}\n\n\t/**\n\t * Gets data from the data transfer by its mime type.\n\t *\n\t *\t\tdataTransfer.getData( 'text/plain' );\n\t *\n\t * @param {String} type The mime type. E.g. `text/html` or `text/plain`.\n\t * @returns {String}\n\t */\n\tgetData( type ) {\n\t\treturn this._native.getData( type );\n\t}\n\n\t/**\n\t * Sets data in the data transfer.\n\t *\n\t * @param {String} type The mime type. E.g. `text/html` or `text/plain`.\n\t * @param {String} data\n\t */\n\tsetData( type, data ) {\n\t\tthis._native.setData( type, data );\n\t}\n}\n\nfunction getFiles( nativeDataTransfer ) {\n\t// DataTransfer.files and items are Array-like and might not have an iterable interface.\n\tconst files = nativeDataTransfer.files ? Array.from( nativeDataTransfer.files ) : [];\n\tconst items = nativeDataTransfer.items ? Array.from( nativeDataTransfer.items ) : [];\n\n\tif ( files.length ) {\n\t\treturn files;\n\t}\n\t// Chrome have empty DataTransfer.files, but let get files through the items interface.\n\treturn items\n\t\t.filter( item => item.kind === 'file' )\n\t\t.map( item => item.getAsFile() );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module clipboard/clipboardobserver\n */\n\nimport DomEventObserver from '@ckeditor/ckeditor5-engine/src/view/observer/domeventobserver';\nimport EventInfo from '@ckeditor/ckeditor5-utils/src/eventinfo';\nimport DataTransfer from './datatransfer';\n\n/**\n * Clipboard events observer.\n *\n * Fires the following events:\n *\n * * {@link module:engine/view/document~Document#event:clipboardInput}\n * * {@link module:engine/view/document~Document#event:dragover}\n * * {@link module:engine/view/document~Document#event:drop}\n * * {@link module:engine/view/document~Document#event:paste}\n * * {@link module:engine/view/document~Document#event:copy}\n * * {@link module:engine/view/document~Document#event:cut}\n *\n * Note that this observer is not available by default (it is not added by the engine).\n * To make it available it needs to be added to {@link module:engine/view/document~Document} by\n * the {@link module:engine/view/view~View#addObserver `View#addObserver()`} method. You can also load the\n * {@link module:clipboard/clipboard~Clipboard} plugin which adds this observer automatically (because it uses it).\n *\n * @extends module:engine/view/observer/domeventobserver~DomEventObserver\n */\nexport default class ClipboardObserver extends DomEventObserver {\n\tconstructor( view ) {\n\t\tsuper( view );\n\n\t\tconst viewDocument = this.document;\n\n\t\tthis.domEventType = [ 'paste', 'copy', 'cut', 'drop', 'dragover' ];\n\n\t\tthis.listenTo( viewDocument, 'paste', handleInput, { priority: 'low' } );\n\t\tthis.listenTo( viewDocument, 'drop', handleInput, { priority: 'low' } );\n\n\t\tfunction handleInput( evt, data ) {\n\t\t\tdata.preventDefault();\n\n\t\t\tconst targetRanges = data.dropRange ? [ data.dropRange ] : Array.from( viewDocument.selection.getRanges() );\n\n\t\t\tconst eventInfo = new EventInfo( viewDocument, 'clipboardInput' );\n\n\t\t\tviewDocument.fire( eventInfo, {\n\t\t\t\tdataTransfer: data.dataTransfer,\n\t\t\t\ttargetRanges\n\t\t\t} );\n\n\t\t\t// If CKEditor handled the input, do not bubble the original event any further.\n\t\t\t// This helps external integrations recognize that fact and act accordingly.\n\t\t\t// https://github.com/ckeditor/ckeditor5-upload/issues/92\n\t\t\tif ( eventInfo.stop.called ) {\n\t\t\t\tdata.stopPropagation();\n\t\t\t}\n\t\t}\n\t}\n\n\tonDomEvent( domEvent ) {\n\t\tconst evtData = {\n\t\t\tdataTransfer: new DataTransfer( domEvent.clipboardData ? domEvent.clipboardData : domEvent.dataTransfer )\n\t\t};\n\n\t\tif ( domEvent.type == 'drop' ) {\n\t\t\tevtData.dropRange = getDropViewRange( this.view, domEvent );\n\t\t}\n\n\t\tthis.fire( domEvent.type, domEvent, evtData );\n\t}\n}\n\nfunction getDropViewRange( view, domEvent ) {\n\tconst domDoc = domEvent.target.ownerDocument;\n\tconst x = domEvent.clientX;\n\tconst y = domEvent.clientY;\n\tlet domRange;\n\n\t// Webkit & Blink.\n\tif ( domDoc.caretRangeFromPoint && domDoc.caretRangeFromPoint( x, y ) ) {\n\t\tdomRange = domDoc.caretRangeFromPoint( x, y );\n\t}\n\t// FF.\n\telse if ( domEvent.rangeParent ) {\n\t\tdomRange = domDoc.createRange();\n\t\tdomRange.setStart( domEvent.rangeParent, domEvent.rangeOffset );\n\t\tdomRange.collapse( true );\n\t}\n\n\tif ( domRange ) {\n\t\treturn view.domConverter.domRangeToView( domRange );\n\t} else {\n\t\treturn view.document.selection.getFirstRange();\n\t}\n}\n\n/**\n * Fired as a continuation of {@link #event:paste} and {@link #event:drop} events.\n *\n * It is a part of the {@glink framework/guides/deep-dive/clipboard#input-pipeline \"clipboard input pipeline\"}.\n *\n * Fired with a `dataTransfer` which comes from the clipboard and which content should be processed\n * and inserted into the editor.\n *\n * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/view~View#addObserver} method.\n * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually.\n *\n * @see module:clipboard/clipboardobserver~ClipboardObserver\n * @see module:clipboard/clipboard~Clipboard\n * @event module:engine/view/document~Document#event:clipboardInput\n * @param {Object} data Event data.\n * @param {module:clipboard/datatransfer~DataTransfer} data.dataTransfer Data transfer instance.\n * @param {Array.<module:engine/view/range~Range>} data.targetRanges Ranges which are the target of the operation\n * (usually – into which the content should be inserted).\n * If clipboard input was triggered by a paste operation, then these are the selection ranges. If by a drop operation,\n * then it's the drop position (which can be different than the selection at the moment of drop).\n */\n\n/**\n * Fired when user drags content over one of the editables.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/view~View#addObserver} method.\n * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually.\n *\n * @see module:engine/view/document~Document#event:clipboardInput\n * @event module:engine/view/document~Document#event:dragover\n * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data.\n */\n\n/**\n * Fired when user dropped content into one of the editables.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/view~View#addObserver} method.\n * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually.\n *\n * @see module:engine/view/document~Document#event:clipboardInput\n * @event module:engine/view/document~Document#event:drop\n * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data.\n * @param {module:engine/view/range~Range} dropRange The position into which the content is dropped.\n */\n\n/**\n * Fired when user pasted content into one of the editables.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/view~View#addObserver} method.\n * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually.\n *\n * @see module:engine/view/document~Document#event:clipboardInput\n * @event module:engine/view/document~Document#event:paste\n * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data.\n */\n\n/**\n * Fired when user copied content from one of the editables.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/view~View#addObserver} method.\n * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually.\n *\n * @see module:clipboard/clipboardobserver~ClipboardObserver\n * @event module:engine/view/document~Document#event:copy\n * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data.\n */\n\n/**\n * Fired when user cut content from one of the editables.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/view~View#addObserver} method.\n * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually.\n *\n * @see module:clipboard/clipboardobserver~ClipboardObserver\n * @event module:engine/view/document~Document#event:cut\n * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data.\n */\n\n/**\n * The value of the {@link module:engine/view/document~Document#event:paste},\n * {@link module:engine/view/document~Document#event:copy} and {@link module:engine/view/document~Document#event:cut} events.\n *\n * In order to access clipboard data use `dataTransfer` property.\n *\n * @class module:clipboard/clipboardobserver~ClipboardEventData\n * @extends module:engine/view/observer/domeventdata~DomEventData\n */\n\n/**\n * Data transfer instance.\n *\n * @readonly\n * @member {module:clipboard/datatransfer~DataTransfer} module:clipboard/clipboardobserver~ClipboardEventData#dataTransfer\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module clipboard/utils/viewtoplaintext\n */\n\n// Elements which should not have empty-line padding.\n// Most `view.ContainerElement` want to be separate by new-line, but some are creating one structure\n// together (like `<li>`) so it is better to separate them by only one \"\\n\".\nconst smallPaddingElements = [ 'figcaption', 'li' ];\n\n/**\n * Converts {@link module:engine/view/item~Item view item} and all of its children to plain text.\n *\n * @param {module:engine/view/item~Item} viewItem View item to convert.\n * @returns {String} Plain text representation of `viewItem`.\n */\nexport default function viewToPlainText( viewItem ) {\n\tlet text = '';\n\n\tif ( viewItem.is( 'text' ) || viewItem.is( 'textProxy' ) ) {\n\t\t// If item is `Text` or `TextProxy` simple take its text data.\n\t\ttext = viewItem.data;\n\t} else if ( viewItem.is( 'img' ) && viewItem.hasAttribute( 'alt' ) ) {\n\t\t// Special case for images - use alt attribute if it is provided.\n\t\ttext = viewItem.getAttribute( 'alt' );\n\t} else {\n\t\t// Other elements are document fragments, attribute elements or container elements.\n\t\t// They don't have their own text value, so convert their children.\n\t\tlet prev = null;\n\n\t\tfor ( const child of viewItem.getChildren() ) {\n\t\t\tconst childText = viewToPlainText( child );\n\n\t\t\t// Separate container element children with one or more new-line characters.\n\t\t\tif ( prev && ( prev.is( 'containerElement' ) || child.is( 'containerElement' ) ) ) {\n\t\t\t\tif ( smallPaddingElements.includes( prev.name ) || smallPaddingElements.includes( child.name ) ) {\n\t\t\t\t\ttext += '\\n';\n\t\t\t\t} else {\n\t\t\t\t\ttext += '\\n\\n';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttext += childText;\n\t\t\tprev = child;\n\t\t}\n\t}\n\n\treturn text;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module clipboard/clipboard\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport ClipboardObserver from './clipboardobserver';\n\nimport plainTextToHtml from './utils/plaintexttohtml';\nimport normalizeClipboardHtml from './utils/normalizeclipboarddata';\nimport viewToPlainText from './utils/viewtoplaintext.js';\n\nimport HtmlDataProcessor from '@ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor';\n\n/**\n * The clipboard feature. It is responsible for intercepting the `paste` and `drop` events and\n * passing the pasted content through the clipboard pipeline in order to insert it into the editor's content.\n * It also handles the `cut` and `copy` events to fill the native clipboard with serialized editor's data.\n *\n * Read more about the clipboard integration in {@glink framework/guides/deep-dive/clipboard \"Clipboard\" deep dive} guide.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Clipboard extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Clipboard';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst modelDocument = editor.model.document;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\n\t\t/**\n\t\t * Data processor used to convert pasted HTML to a view structure.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/dataprocessor/htmldataprocessor~HtmlDataProcessor} #_htmlDataProcessor\n\t\t */\n\t\tthis._htmlDataProcessor = new HtmlDataProcessor();\n\n\t\tview.addObserver( ClipboardObserver );\n\n\t\t// The clipboard paste pipeline.\n\n\t\t// Pasting and dropping is disabled when editor is read-only.\n\t\t// See: https://github.com/ckeditor/ckeditor5-clipboard/issues/26.\n\t\tthis.listenTo( viewDocument, 'clipboardInput', evt => {\n\t\t\tif ( editor.isReadOnly ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'highest' } );\n\n\t\tthis.listenTo( viewDocument, 'clipboardInput', ( evt, data ) => {\n\t\t\tconst dataTransfer = data.dataTransfer;\n\t\t\tlet content = '';\n\n\t\t\tif ( dataTransfer.getData( 'text/html' ) ) {\n\t\t\t\tcontent = normalizeClipboardHtml( dataTransfer.getData( 'text/html' ) );\n\t\t\t} else if ( dataTransfer.getData( 'text/plain' ) ) {\n\t\t\t\tcontent = plainTextToHtml( dataTransfer.getData( 'text/plain' ) );\n\t\t\t}\n\n\t\t\tcontent = this._htmlDataProcessor.toView( content );\n\n\t\t\tthis.fire( 'inputTransformation', { content, dataTransfer } );\n\n\t\t\tview.scrollToTheSelection();\n\t\t}, { priority: 'low' } );\n\n\t\tthis.listenTo( this, 'inputTransformation', ( evt, data ) => {\n\t\t\tif ( !data.content.isEmpty ) {\n\t\t\t\tconst dataController = this.editor.data;\n\t\t\t\tconst model = this.editor.model;\n\n\t\t\t\t// Convert the pasted content to a model document fragment.\n\t\t\t\t// Conversion is contextual, but in this case we need an \"all allowed\" context and for that\n\t\t\t\t// we use the $clipboardHolder item.\n\t\t\t\tconst modelFragment = dataController.toModel( data.content, '$clipboardHolder' );\n\n\t\t\t\tif ( modelFragment.childCount == 0 ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tmodel.insertContent( modelFragment );\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\n\t\t// The clipboard copy/cut pipeline.\n\n\t\tfunction onCopyCut( evt, data ) {\n\t\t\tconst dataTransfer = data.dataTransfer;\n\n\t\t\tdata.preventDefault();\n\n\t\t\tconst content = editor.data.toView( editor.model.getSelectedContent( modelDocument.selection ) );\n\n\t\t\tviewDocument.fire( 'clipboardOutput', { dataTransfer, content, method: evt.name } );\n\t\t}\n\n\t\tthis.listenTo( viewDocument, 'copy', onCopyCut, { priority: 'low' } );\n\t\tthis.listenTo( viewDocument, 'cut', ( evt, data ) => {\n\t\t\t// Cutting is disabled when editor is read-only.\n\t\t\t// See: https://github.com/ckeditor/ckeditor5-clipboard/issues/26.\n\t\t\tif ( editor.isReadOnly ) {\n\t\t\t\tdata.preventDefault();\n\t\t\t} else {\n\t\t\t\tonCopyCut( evt, data );\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\n\t\tthis.listenTo( viewDocument, 'clipboardOutput', ( evt, data ) => {\n\t\t\tif ( !data.content.isEmpty ) {\n\t\t\t\tdata.dataTransfer.setData( 'text/html', this._htmlDataProcessor.toData( data.content ) );\n\t\t\t\tdata.dataTransfer.setData( 'text/plain', viewToPlainText( data.content ) );\n\t\t\t}\n\n\t\t\tif ( data.method == 'cut' ) {\n\t\t\t\teditor.model.deleteContent( modelDocument.selection );\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\t}\n}\n\n/**\n * Fired with a `content` and `dataTransfer` objects. The `content` which comes from the clipboard (was pasted or dropped)\n * should be processed in order to be inserted into the editor. The `dataTransfer` object is available\n * in case the transformation functions needs access to a raw clipboard data.\n *\n * It is a part of the {@glink framework/guides/deep-dive/clipboard#input-pipeline \"clipboard input pipeline\"}.\n *\n * @see module:clipboard/clipboardobserver~ClipboardObserver\n * @see module:clipboard/clipboard~Clipboard\n * @event module:clipboard/clipboard~Clipboard#event:inputTransformation\n * @param {Object} data Event data.\n * @param {module:engine/view/documentfragment~DocumentFragment} data.content Event data. Content to be inserted into the editor.\n * It can be modified by the event listeners. Read more about the clipboard pipelines in\n * {@glink framework/guides/deep-dive/clipboard \"Clipboard\" deep dive}.\n * @param {module:clipboard/datatransfer~DataTransfer} data.dataTransfer Data transfer instance.\n */\n\n/**\n * Fired on {@link module:engine/view/document~Document#event:copy} and {@link module:engine/view/document~Document#event:cut}\n * with a copy of selected content. The content can be processed before it ends up in the clipboard.\n *\n * It is a part of the {@glink framework/guides/deep-dive/clipboard#output-pipeline \"clipboard output pipeline\"}.\n *\n * @see module:clipboard/clipboardobserver~ClipboardObserver\n * @see module:clipboard/clipboard~Clipboard\n * @event module:engine/view/document~Document#event:clipboardOutput\n * @param {module:clipboard/clipboard~ClipboardOutputEventData} data Event data.\n */\n\n/**\n * The value of the {@link module:engine/view/document~Document#event:clipboardOutput} event.\n *\n * @class module:clipboard/clipboard~ClipboardOutputEventData\n */\n\n/**\n * Data transfer instance.\n *\n * @readonly\n * @member {module:clipboard/datatransfer~DataTransfer} module:clipboard/clipboard~ClipboardOutputEventData#dataTransfer\n */\n\n/**\n * Content to be put into the clipboard. It can be modified by the event listeners.\n * Read more about the clipboard pipelines in {@glink framework/guides/deep-dive/clipboard \"Clipboard\" deep dive}.\n *\n * @member {module:engine/view/documentfragment~DocumentFragment} module:clipboard/clipboard~ClipboardOutputEventData#content\n */\n\n/**\n * Whether the event was triggered by copy or cut operation.\n *\n * @member {'copy'|'cut'} module:clipboard/clipboard~ClipboardOutputEventData#method\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module clipboard/utils/normalizeclipboarddata\n */\n\n/**\n * Removes some popular browser quirks out of the clipboard data (HTML).\n *\n * @param {String} data The HTML data to normalize.\n * @returns {String} Normalized HTML.\n */\nexport default function normalizeClipboardData( data ) {\n\treturn data\n\t\t.replace( /<span(?: class=\"Apple-converted-space\"|)>(\\s+)<\\/span>/g, ( fullMatch, spaces ) => {\n\t\t\t// Handle the most popular and problematic case when even a single space becomes an nbsp;.\n\t\t\t// Decode those to normal spaces. Read more in https://github.com/ckeditor/ckeditor5-clipboard/issues/2.\n\t\t\tif ( spaces.length == 1 ) {\n\t\t\t\treturn ' ';\n\t\t\t}\n\n\t\t\treturn spaces;\n\t\t} );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module clipboard/utils/plaintexttohtml\n */\n\n/**\n * Converts plain text to its HTML-ized version.\n *\n * @param {String} text The plain text to convert.\n * @returns {String} HTML generated from the plain text.\n */\nexport default function plainTextToHtml( text ) {\n\ttext = text\n\t\t// Encode <>.\n\t\t.replace( /</g, '&lt;' )\n\t\t.replace( />/g, '&gt;' )\n\t\t// Creates paragraphs for double line breaks and change single line breaks to <br>s.\n\t\t.replace( /\\n\\n/g, '</p><p>' )\n\t\t.replace( /\\n/g, '<br>' )\n\t\t// Preserve trailing spaces (only the first and last one – the rest is handled below).\n\t\t.replace( /^\\s/, '&nbsp;' )\n\t\t.replace( /\\s$/, '&nbsp;' )\n\t\t// Preserve other subsequent spaces now.\n\t\t.replace( /\\s\\s/g, ' &nbsp;' );\n\n\tif ( text.indexOf( '</p><p>' ) > -1 ) {\n\t\t// If we created paragraphs above, add the trailing ones.\n\t\ttext = `<p>${ text }</p>`;\n\t}\n\n\t// TODO:\n\t// * What about '\\nfoo' vs ' foo'?\n\n\treturn text;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor.data, 'ready', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n/**\n * Array of loaded plugins.\n *\n * @typedef {Array.<module:core/plugin~PluginInterface>} module:core/plugin~LoadedPlugins\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/command\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor commands.\n *\n * Commands are the main way to manipulate editor contents and state. They are mostly used by UI elements (or by other\n * commands) to make changes in the model. Commands are available in every part of code that has access to\n * the {@link module:core/editor/editor~Editor editor} instance.\n *\n * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n *\n * By default commands are disabled when the editor is in {@link module:core/editor/editor~Editor#isReadOnly read-only} mode.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Command {\n\t/**\n\t * Creates a new `Command` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor Editor on which this command will be used.\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor on which this command will be used.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * The value of the command. A concrete command class should define what it represents for it.\n\t\t *\n\t\t * For example, the `'bold'` command's value indicates whether the selection starts in a bolded text.\n\t\t * And the value of the `'link'` command may be an object with links details.\n\t\t *\n\t\t * It is possible for a command to have no value (e.g. for stateless actions such as `'imageUpload'`).\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member #value\n\t\t */\n\t\tthis.set( 'value', undefined );\n\n\t\t/**\n\t\t * Flag indicating whether a command is enabled or disabled.\n\t\t * A disabled command will do nothing when executed.\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * It is possible to disable a command from \"outside\". For instance, in your integration you may want to disable\n\t\t * a certain set of commands for the time being. To do that, you can use the fact that `isEnabled` is observable\n\t\t * and it fires the `set:isEnabled` event every time anyone tries to modify its value:\n\t\t *\n\t\t *\t\tfunction disableCommand( cmd ) {\n\t\t *\t\t\tcmd.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t *\n\t\t *\t\t\tcmd.isEnabled = false;\n\t\t *\n\t\t *\t\t\t// Make it possible to enable the command again.\n\t\t *\t\t\treturn () => {\n\t\t *\t\t\t\tcmd.off( 'set:isEnabled', forceDisable );\n\t\t *\t\t\t\tcmd.refresh();\n\t\t *\t\t\t};\n\t\t *\n\t\t *\t\t\tfunction forceDisable( evt ) {\n\t\t *\t\t\t\tevt.return = false;\n\t\t *\t\t\t\tevt.stop();\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\n\t\t *\t\t// Usage:\n\t\t *\n\t\t *\t\t// Disabling the command.\n\t\t *\t\tconst enableBold = disableCommand( editor.commands.get( 'bold' ) );\n\t\t *\n\t\t *\t\t// Enabling the command again.\n\t\t *\t\tenableBold();\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\t\tthis.set( 'isEnabled', false );\n\n\t\t/**\n\t\t * Holds identifiers for {@link #forceDisabled} mechanism.\n\t\t *\n\t\t * @type {Set.<String>}\n\t\t * @private\n\t\t */\n\t\tthis._disableStack = new Set();\n\n\t\tthis.decorate( 'execute' );\n\n\t\t// By default every command is refreshed when changes are applied to the model.\n\t\tthis.listenTo( this.editor.model.document, 'change', () => {\n\t\t\tthis.refresh();\n\t\t} );\n\n\t\tthis.on( 'execute', evt => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// By default commands are disabled when the editor is in read-only mode.\n\t\tthis.listenTo( editor, 'change:isReadOnly', ( evt, name, value ) => {\n\t\t\tif ( value ) {\n\t\t\t\tthis.forceDisabled( 'readOnlyMode' );\n\t\t\t} else {\n\t\t\t\tthis.clearForceDisabled( 'readOnlyMode' );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties\n\t * in this method.\n\t *\n\t * This method is automatically called when\n\t * {@link module:engine/model/document~Document#event:change any changes are applied to the document}.\n\t */\n\trefresh() {\n\t\tthis.isEnabled = true;\n\t}\n\n\t/**\n\t * Disables the command.\n\t *\n\t * Command may be disabled by multiple features or algorithms (at once). When disabling a command, unique id should be passed\n\t * (e.g. feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the command.\n\t * The command becomes enabled only after all features {@link #clearForceDisabled enabled it back}.\n\t *\n\t * Disabling and enabling a command:\n\t *\n\t *\t\tcommand.isEnabled; // -> true\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Command disabled by multiple features:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'OtherFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'OtherFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Multiple disabling with the same identifier is redundant:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * **Note:** some commands or algorithms may have more complex logic when it comes to enabling or disabling certain commands,\n\t * so the command might be still disabled after {@link #clearForceDisabled} was used.\n\t *\n\t * @param {String} id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the command.\n\t */\n\tforceDisabled( id ) {\n\t\tthis._disableStack.add( id );\n\n\t\tif ( this._disableStack.size == 1 ) {\n\t\t\tthis.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * Clears forced disable previously set through {@link #clearForceDisabled}. See {@link #clearForceDisabled}.\n\t *\n\t * @param {String} id Unique identifier, equal to the one passed in {@link #forceDisabled} call.\n\t */\n\tclearForceDisabled( id ) {\n\t\tthis._disableStack.delete( id );\n\n\t\tif ( this._disableStack.size == 0 ) {\n\t\t\tthis.off( 'set:isEnabled', forceDisable );\n\t\t\tthis.refresh();\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`}\n\t * to the command.\n\t *\n\t * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`).\n\t * This behavior is implemented by a high priority listener to the {@link #event:execute} event.\n\t *\n\t * In order to see how to disable a command from \"outside\" see the {@link #isEnabled} documentation.\n\t *\n\t * @fires execute\n\t */\n\texecute() {}\n\n\t/**\n\t * Destroys the command.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Event fired by the {@link #execute} method. The command action is a listener to this event so it's\n\t * possible to change/cancel the behavior of the command by listening to this event.\n\t *\n\t * See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples.\n\t *\n\t * **Note:** This event is fired even if command is disabled. However, it is automatically blocked\n\t * by a high priority listener in order to prevent command execution.\n\t *\n\t * @event execute\n\t */\n}\n\nmix( Command, ObservableMixin );\n\n// Helper function that forces command to be disabled.\nfunction forceDisable( evt ) {\n\tevt.return = false;\n\tevt.stop();\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module enter/entercommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\n\n/**\n * Enter command. It is used by the {@link module:enter/enter~Enter Enter feature} to handle the <kbd>Enter</kbd> key.\n *\n * @extends module:core/command~Command\n */\nexport default class EnterCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\n\t\tmodel.change( writer => {\n\t\t\tenterBlock( this.editor.model, writer, doc.selection, model.schema );\n\t\t\tthis.fire( 'afterExecute', { writer } );\n\t\t} );\n\t}\n}\n\n// Creates a new block in the way that the <kbd>Enter</kbd> key is expected to work.\n//\n// @param {module:engine/model~Model} model\n// @param {module:engine/model/writer~Writer} writer\n// @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection\n// Selection on which the action should be performed.\n// @param {module:engine/model/schema~Schema} schema\nfunction enterBlock( model, writer, selection, schema ) {\n\tconst isSelectionEmpty = selection.isCollapsed;\n\tconst range = selection.getFirstRange();\n\tconst startElement = range.start.parent;\n\tconst endElement = range.end.parent;\n\n\t// Don't touch the roots and other limit elements.\n\tif ( schema.isLimit( startElement ) || schema.isLimit( endElement ) ) {\n\t\t// Delete the selected content but only if inside a single limit element.\n\t\t// Abort, when crossing limit elements boundary (e.g. <limit1>x[x</limit1>donttouchme<limit2>y]y</limit2>).\n\t\t// This is an edge case and it's hard to tell what should actually happen because such a selection\n\t\t// is not entirely valid.\n\t\tif ( !isSelectionEmpty && startElement == endElement ) {\n\t\t\tmodel.deleteContent( selection );\n\t\t}\n\n\t\treturn;\n\t}\n\n\tif ( isSelectionEmpty ) {\n\t\tsplitBlock( writer, range.start );\n\t} else {\n\t\tconst leaveUnmerged = !( range.start.isAtStart && range.end.isAtEnd );\n\t\tconst isContainedWithinOneElement = ( startElement == endElement );\n\n\t\tmodel.deleteContent( selection, { leaveUnmerged } );\n\n\t\tif ( leaveUnmerged ) {\n\t\t\t// Partially selected elements.\n\t\t\t//\n\t\t\t// <h>x[xx]x</h>\t\t-> <h>x^x</h>\t\t\t-> <h>x</h><h>^x</h>\n\t\t\tif ( isContainedWithinOneElement ) {\n\t\t\t\tsplitBlock( writer, selection.focus );\n\t\t\t}\n\t\t\t// Selection over multiple elements.\n\t\t\t//\n\t\t\t// <h>x[x</h><p>y]y<p>\t-> <h>x^</h><p>y</p>\t-> <h>x</h><p>^y</p>\n\t\t\telse {\n\t\t\t\twriter.setSelection( endElement, 0 );\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction splitBlock( writer, splitPos ) {\n\twriter.split( splitPos );\n\twriter.setSelection( splitPos.parent.nextSibling, 0 );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module enter/enterobserver\n */\n\nimport Observer from '@ckeditor/ckeditor5-engine/src/view/observer/observer';\nimport DomEventData from '@ckeditor/ckeditor5-engine/src/view/observer/domeventdata';\nimport { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';\n\n/**\n * Enter observer introduces the {@link module:engine/view/document~Document#event:enter} event.\n *\n * @extends module:engine/view/observer~Observer\n */\nexport default class EnterObserver extends Observer {\n\tconstructor( view ) {\n\t\tsuper( view );\n\n\t\tconst doc = this.document;\n\n\t\tdoc.on( 'keydown', ( evt, data ) => {\n\t\t\tif ( this.isEnabled && data.keyCode == keyCodes.enter ) {\n\t\t\t\t// Save the event object to check later if it was stopped or not.\n\t\t\t\tlet event;\n\t\t\t\tdoc.once( 'enter', evt => ( event = evt ), { priority: 'highest' } );\n\n\t\t\t\tdoc.fire( 'enter', new DomEventData( doc, data.domEvent, {\n\t\t\t\t\tisSoft: data.shiftKey\n\t\t\t\t} ) );\n\n\t\t\t\t// Stop `keydown` event if `enter` event was stopped.\n\t\t\t\t// https://github.com/ckeditor/ckeditor5/issues/753\n\t\t\t\tif ( event && event.stop.called ) {\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tobserve() {}\n}\n\n/**\n * Event fired when the user presses the <kbd>Enter</kbd> key.\n *\n * Note: This event is fired by the {@link module:enter/enterobserver~EnterObserver observer}\n * (usually registered by the {@link module:enter/enter~Enter Enter feature} and\n * {@link module:enter/shiftenter~ShiftEnter ShiftEnter feature}).\n *\n * @event module:engine/view/document~Document#event:enter\n * @param {module:engine/view/observer/domeventdata~DomEventData} data\n * @param {Boolean} data.isSoft Whether it's a soft enter (<kbd>Shift</kbd>+<kbd>Enter</kbd>) or hard enter (<kbd>Enter</kbd>).\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module enter/enter\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport EnterCommand from './entercommand';\nimport EnterObserver from './enterobserver';\n\n/**\n * This plugin handles the <kbd>Enter</kbd> key (hard line break) in the editor.\n *\n * See also the {@link module:enter/shiftenter~ShiftEnter} plugin.\n *\n * For more information about this feature see the {@glink api/enter package page}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Enter extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Enter';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\n\t\tview.addObserver( EnterObserver );\n\n\t\teditor.commands.add( 'enter', new EnterCommand( editor ) );\n\n\t\tthis.listenTo( viewDocument, 'enter', ( evt, data ) => {\n\t\t\tdata.preventDefault();\n\n\t\t\t// The soft enter key is handled by the ShiftEnter plugin.\n\t\t\tif ( data.isSoft ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\teditor.execute( 'enter' );\n\t\t\tview.scrollToTheSelection();\n\t\t}, { priority: 'low' } );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module enter/shiftentercommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\n\n/**\n * ShiftEnter command. It is used by the {@link module:enter/shiftenter~ShiftEnter ShiftEnter feature} to handle\n * the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke.\n *\n * @extends module:core/command~Command\n */\nexport default class ShiftEnterCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\n\t\tmodel.change( writer => {\n\t\t\tsoftBreakAction( model, writer, doc.selection );\n\t\t\tthis.fire( 'afterExecute', { writer } );\n\t\t} );\n\t}\n\n\trefresh() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\n\t\tthis.isEnabled = isEnabled( model.schema, doc.selection );\n\t}\n}\n\n// Checks whether the ShiftEnter command should be enabled in the specified selection.\n//\n// @param {module:engine/model/schema~Schema} schema\n// @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection\nfunction isEnabled( schema, selection ) {\n\t// At this moment it is okay to support single range selections only.\n\t// But in the future we may need to change that.\n\tif ( selection.rangeCount > 1 ) {\n\t\treturn false;\n\t}\n\n\tconst anchorPos = selection.anchor;\n\n\t// Check whether the break element can be inserted in the current selection anchor.\n\tif ( !anchorPos || !schema.checkChild( anchorPos, 'softBreak' ) ) {\n\t\treturn false;\n\t}\n\n\tconst range = selection.getFirstRange();\n\tconst startElement = range.start.parent;\n\tconst endElement = range.end.parent;\n\n\t// Do not modify the content if selection is cross-limit elements.\n\tif ( ( isInsideLimitElement( startElement, schema ) || isInsideLimitElement( endElement, schema ) ) && startElement !== endElement ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n// Creates a break in the way that the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke is expected to work.\n//\n// @param {module:engine/model~Model} model\n// @param {module:engine/model/writer~Writer} writer\n// @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection\n// Selection on which the action should be performed.\nfunction softBreakAction( model, writer, selection ) {\n\tconst isSelectionEmpty = selection.isCollapsed;\n\tconst range = selection.getFirstRange();\n\tconst startElement = range.start.parent;\n\tconst endElement = range.end.parent;\n\tconst isContainedWithinOneElement = ( startElement == endElement );\n\n\tif ( isSelectionEmpty ) {\n\t\tinsertBreak( writer, range.end );\n\t} else {\n\t\tconst leaveUnmerged = !( range.start.isAtStart && range.end.isAtEnd );\n\t\tmodel.deleteContent( selection, { leaveUnmerged } );\n\n\t\t// Selection within one element:\n\t\t//\n\t\t// <h>x[xx]x</h>\t\t-> <h>x^x</h>\t\t\t-> <h>x<br>^x</h>\n\t\tif ( isContainedWithinOneElement ) {\n\t\t\tinsertBreak( writer, selection.focus );\n\t\t}\n\t\t// Selection over multiple elements.\n\t\t//\n\t\t// <h>x[x</h><p>y]y<p>\t-> <h>x^</h><p>y</p>\t-> <h>x</h><p>^y</p>\n\t\t//\n\t\t// We chose not to insert a line break in this case because:\n\t\t//\n\t\t// * it's not a very common scenario,\n\t\t// * it actually surprised me when I saw the \"expected behavior\" in real life.\n\t\t//\n\t\t// It's ok if the user will need to be more specific where they want the <br> to be inserted.\n\t\telse {\n\t\t\t// Move the selection to the 2nd element (last step of the example above).\n\t\t\tif ( leaveUnmerged ) {\n\t\t\t\twriter.setSelection( endElement, 0 );\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction insertBreak( writer, position ) {\n\tconst breakLineElement = writer.createElement( 'softBreak' );\n\n\twriter.insert( breakLineElement, position );\n\twriter.setSelection( breakLineElement, 'after' );\n}\n\n// Checks whether the specified `element` is a child of the limit element.\n//\n// Checking whether the `<p>` element is inside a limit element:\n// - <$root><p>Text.</p></$root> => false\n// - <$root><limitElement><p>Text</p></limitElement></$root> => true\n//\n// @param {module:engine/model/element~Element} element\n// @param {module:engine/schema~Schema} schema\n// @returns {Boolean}\nfunction isInsideLimitElement( element, schema ) {\n\t// `$root` is a limit element but in this case is an invalid element.\n\tif ( element.is( 'rootElement' ) ) {\n\t\treturn false;\n\t}\n\n\treturn schema.isLimit( element ) || isInsideLimitElement( element.parent, schema );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module enter/shiftenter\n */\n\nimport ShiftEnterCommand from './shiftentercommand';\nimport EnterObserver from './enterobserver';\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\n/**\n * This plugin handles the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke (soft line break) in the editor.\n *\n * See also the {@link module:enter/enter~Enter} plugin.\n *\n * For more information about this feature see the {@glink api/enter package page}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ShiftEnter extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ShiftEnter';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\t\tconst conversion = editor.conversion;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\n\t\t// Configure the schema.\n\t\tschema.register( 'softBreak', {\n\t\t\tallowWhere: '$text',\n\t\t\tisInline: true\n\t\t} );\n\n\t\t// Configure converters.\n\t\tconversion.for( 'upcast' )\n\t\t\t.elementToElement( {\n\t\t\t\tmodel: 'softBreak',\n\t\t\t\tview: 'br'\n\t\t\t} );\n\n\t\tconversion.for( 'downcast' )\n\t\t\t.elementToElement( {\n\t\t\t\tmodel: 'softBreak',\n\t\t\t\tview: ( modelElement, viewWriter ) => viewWriter.createEmptyElement( 'br' )\n\t\t\t} );\n\n\t\tview.addObserver( EnterObserver );\n\n\t\teditor.commands.add( 'shiftEnter', new ShiftEnterCommand( editor ) );\n\n\t\tthis.listenTo( viewDocument, 'enter', ( evt, data ) => {\n\t\t\tdata.preventDefault();\n\n\t\t\t// The hard enter key is handled by the Enter plugin.\n\t\t\tif ( !data.isSoft ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\teditor.execute( 'shiftEnter' );\n\t\t\tview.scrollToTheSelection();\n\t\t}, { priority: 'low' } );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor.data, 'ready', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n/**\n * Array of loaded plugins.\n *\n * @typedef {Array.<module:core/plugin~PluginInterface>} module:core/plugin~LoadedPlugins\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/command\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor commands.\n *\n * Commands are the main way to manipulate editor contents and state. They are mostly used by UI elements (or by other\n * commands) to make changes in the model. Commands are available in every part of code that has access to\n * the {@link module:core/editor/editor~Editor editor} instance.\n *\n * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n *\n * By default commands are disabled when the editor is in {@link module:core/editor/editor~Editor#isReadOnly read-only} mode.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Command {\n\t/**\n\t * Creates a new `Command` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor Editor on which this command will be used.\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor on which this command will be used.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * The value of the command. A concrete command class should define what it represents for it.\n\t\t *\n\t\t * For example, the `'bold'` command's value indicates whether the selection starts in a bolded text.\n\t\t * And the value of the `'link'` command may be an object with links details.\n\t\t *\n\t\t * It is possible for a command to have no value (e.g. for stateless actions such as `'imageUpload'`).\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member #value\n\t\t */\n\t\tthis.set( 'value', undefined );\n\n\t\t/**\n\t\t * Flag indicating whether a command is enabled or disabled.\n\t\t * A disabled command will do nothing when executed.\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * It is possible to disable a command from \"outside\". For instance, in your integration you may want to disable\n\t\t * a certain set of commands for the time being. To do that, you can use the fact that `isEnabled` is observable\n\t\t * and it fires the `set:isEnabled` event every time anyone tries to modify its value:\n\t\t *\n\t\t *\t\tfunction disableCommand( cmd ) {\n\t\t *\t\t\tcmd.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t *\n\t\t *\t\t\tcmd.isEnabled = false;\n\t\t *\n\t\t *\t\t\t// Make it possible to enable the command again.\n\t\t *\t\t\treturn () => {\n\t\t *\t\t\t\tcmd.off( 'set:isEnabled', forceDisable );\n\t\t *\t\t\t\tcmd.refresh();\n\t\t *\t\t\t};\n\t\t *\n\t\t *\t\t\tfunction forceDisable( evt ) {\n\t\t *\t\t\t\tevt.return = false;\n\t\t *\t\t\t\tevt.stop();\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\n\t\t *\t\t// Usage:\n\t\t *\n\t\t *\t\t// Disabling the command.\n\t\t *\t\tconst enableBold = disableCommand( editor.commands.get( 'bold' ) );\n\t\t *\n\t\t *\t\t// Enabling the command again.\n\t\t *\t\tenableBold();\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\t\tthis.set( 'isEnabled', false );\n\n\t\t/**\n\t\t * Holds identifiers for {@link #forceDisabled} mechanism.\n\t\t *\n\t\t * @type {Set.<String>}\n\t\t * @private\n\t\t */\n\t\tthis._disableStack = new Set();\n\n\t\tthis.decorate( 'execute' );\n\n\t\t// By default every command is refreshed when changes are applied to the model.\n\t\tthis.listenTo( this.editor.model.document, 'change', () => {\n\t\t\tthis.refresh();\n\t\t} );\n\n\t\tthis.on( 'execute', evt => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// By default commands are disabled when the editor is in read-only mode.\n\t\tthis.listenTo( editor, 'change:isReadOnly', ( evt, name, value ) => {\n\t\t\tif ( value ) {\n\t\t\t\tthis.forceDisabled( 'readOnlyMode' );\n\t\t\t} else {\n\t\t\t\tthis.clearForceDisabled( 'readOnlyMode' );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties\n\t * in this method.\n\t *\n\t * This method is automatically called when\n\t * {@link module:engine/model/document~Document#event:change any changes are applied to the document}.\n\t */\n\trefresh() {\n\t\tthis.isEnabled = true;\n\t}\n\n\t/**\n\t * Disables the command.\n\t *\n\t * Command may be disabled by multiple features or algorithms (at once). When disabling a command, unique id should be passed\n\t * (e.g. feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the command.\n\t * The command becomes enabled only after all features {@link #clearForceDisabled enabled it back}.\n\t *\n\t * Disabling and enabling a command:\n\t *\n\t *\t\tcommand.isEnabled; // -> true\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Command disabled by multiple features:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'OtherFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'OtherFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Multiple disabling with the same identifier is redundant:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * **Note:** some commands or algorithms may have more complex logic when it comes to enabling or disabling certain commands,\n\t * so the command might be still disabled after {@link #clearForceDisabled} was used.\n\t *\n\t * @param {String} id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the command.\n\t */\n\tforceDisabled( id ) {\n\t\tthis._disableStack.add( id );\n\n\t\tif ( this._disableStack.size == 1 ) {\n\t\t\tthis.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * Clears forced disable previously set through {@link #clearForceDisabled}. See {@link #clearForceDisabled}.\n\t *\n\t * @param {String} id Unique identifier, equal to the one passed in {@link #forceDisabled} call.\n\t */\n\tclearForceDisabled( id ) {\n\t\tthis._disableStack.delete( id );\n\n\t\tif ( this._disableStack.size == 0 ) {\n\t\t\tthis.off( 'set:isEnabled', forceDisable );\n\t\t\tthis.refresh();\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`}\n\t * to the command.\n\t *\n\t * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`).\n\t * This behavior is implemented by a high priority listener to the {@link #event:execute} event.\n\t *\n\t * In order to see how to disable a command from \"outside\" see the {@link #isEnabled} documentation.\n\t *\n\t * @fires execute\n\t */\n\texecute() {}\n\n\t/**\n\t * Destroys the command.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Event fired by the {@link #execute} method. The command action is a listener to this event so it's\n\t * possible to change/cancel the behavior of the command by listening to this event.\n\t *\n\t * See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples.\n\t *\n\t * **Note:** This event is fired even if command is disabled. However, it is automatically blocked\n\t * by a high priority listener in order to prevent command execution.\n\t *\n\t * @event execute\n\t */\n}\n\nmix( Command, ObservableMixin );\n\n// Helper function that forces command to be disabled.\nfunction forceDisable( evt ) {\n\tevt.return = false;\n\tevt.stop();\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module typing/utils/changebuffer\n */\n\n/**\n * Change buffer allows to group atomic changes (like characters that have been typed) into\n * {@link module:engine/model/batch~Batch batches}.\n *\n * Batches represent single undo steps, hence changes added to one single batch are undone together.\n *\n * The buffer has a configurable limit of atomic changes that it can accommodate. After the limit was\n * exceeded (see {@link ~ChangeBuffer#input}), a new batch is created in {@link ~ChangeBuffer#batch}.\n *\n * To use the change buffer you need to let it know about the number of changes that were added to the batch:\n *\n *\t\tconst buffer = new ChangeBuffer( model, LIMIT );\n *\n *\t\t// Later on in your feature:\n *\t\tbuffer.batch.insert( pos, insertedCharacters );\n *\t\tbuffer.input( insertedCharacters.length );\n *\n */\nexport default class ChangeBuffer {\n\t/**\n\t * Creates a new instance of the change buffer.\n\t *\n\t * @param {module:engine/model/model~Model} model\n\t * @param {Number} [limit=20] The maximum number of atomic changes which can be contained in one batch.\n\t */\n\tconstructor( model, limit = 20 ) {\n\t\t/**\n\t\t * The model instance.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/model~Model} #model\n\t\t */\n\t\tthis.model = model;\n\n\t\t/**\n\t\t * The number of atomic changes in the buffer. Once it exceeds the {@link #limit},\n\t\t * the {@link #batch batch} is set to a new one.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} #size\n\t\t */\n\t\tthis.size = 0;\n\n\t\t/**\n\t\t * The maximum number of atomic changes which can be contained in one batch.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number} #limit\n\t\t */\n\t\tthis.limit = limit;\n\n\t\t/**\n\t\t * Whether the buffer is locked. A locked buffer cannot be reset unless it gets unlocked.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} #isLocked\n\t\t */\n\t\tthis.isLocked = false;\n\n\t\t// The function to be called in order to notify the buffer about batches which appeared in the document.\n\t\t// The callback will check whether it is a new batch and in that case the buffer will be flushed.\n\t\t//\n\t\t// The reason why the buffer needs to be flushed whenever a new batch appears is that the changes added afterwards\n\t\t// should be added to a new batch. For instance, when the user types, then inserts an image, and then types again,\n\t\t// the characters typed after inserting the image should be added to a different batch than the characters typed before.\n\t\tthis._changeCallback = ( evt, batch ) => {\n\t\t\tif ( batch.type != 'transparent' && batch !== this._batch ) {\n\t\t\t\tthis._reset( true );\n\t\t\t}\n\t\t};\n\n\t\tthis._selectionChangeCallback = () => {\n\t\t\tthis._reset();\n\t\t};\n\n\t\tthis.model.document.on( 'change', this._changeCallback );\n\n\t\tthis.model.document.selection.on( 'change:range', this._selectionChangeCallback );\n\t\tthis.model.document.selection.on( 'change:attribute', this._selectionChangeCallback );\n\n\t\t/**\n\t\t * The current batch instance.\n\t\t *\n\t\t * @private\n\t\t * @member #_batch\n\t\t */\n\n\t\t/**\n\t\t * The callback to document the change event which later needs to be removed.\n\t\t *\n\t\t * @private\n\t\t * @member #_changeCallback\n\t\t */\n\n\t\t/**\n\t\t * The callback to document selection `change:attribute` and `change:range` events which resets the buffer.\n\t\t *\n\t\t * @private\n\t\t * @member #_selectionChangeCallback\n\t\t */\n\t}\n\n\t/**\n\t * The current batch to which a feature should add its operations. Once the {@link #size}\n\t * is reached or exceeds the {@link #limit}, the batch is set to a new instance and the size is reset.\n\t *\n\t * @type {module:engine/model/batch~Batch}\n\t */\n\tget batch() {\n\t\tif ( !this._batch ) {\n\t\t\tthis._batch = this.model.createBatch();\n\t\t}\n\n\t\treturn this._batch;\n\t}\n\n\t/**\n\t * The input number of changes into the buffer. Once the {@link #size} is\n\t * reached or exceeds the {@link #limit}, the batch is set to a new instance and the size is reset.\n\t *\n\t * @param {Number} changeCount The number of atomic changes to input.\n\t */\n\tinput( changeCount ) {\n\t\tthis.size += changeCount;\n\n\t\tif ( this.size >= this.limit ) {\n\t\t\tthis._reset( true );\n\t\t}\n\t}\n\n\t/**\n\t * Locks the buffer.\n\t */\n\tlock() {\n\t\tthis.isLocked = true;\n\t}\n\n\t/**\n\t * Unlocks the buffer.\n\t */\n\tunlock() {\n\t\tthis.isLocked = false;\n\t}\n\n\t/**\n\t * Destroys the buffer.\n\t */\n\tdestroy() {\n\t\tthis.model.document.off( 'change', this._changeCallback );\n\t\tthis.model.document.selection.off( 'change:range', this._selectionChangeCallback );\n\t\tthis.model.document.selection.off( 'change:attribute', this._selectionChangeCallback );\n\t}\n\n\t/**\n\t * Resets the change buffer.\n\t *\n\t * @private\n\t * @param {Boolean} [ignoreLock] Whether internal lock {@link #isLocked} should be ignored.\n\t */\n\t_reset( ignoreLock ) {\n\t\tif ( !this.isLocked || ignoreLock ) {\n\t\t\tthis._batch = null;\n\t\t\tthis.size = 0;\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module typing/inputcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\n\nimport ChangeBuffer from './utils/changebuffer';\n\n/**\n * The input command. Used by the {@link module:typing/input~Input input feature} to handle typing.\n *\n * @extends module:core/command~Command\n */\nexport default class InputCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor\n\t * @param {Number} undoStepSize The maximum number of atomic changes\n\t * which can be contained in one batch in the command buffer.\n\t */\n\tconstructor( editor, undoStepSize ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * Typing's change buffer used to group subsequent changes into batches.\n\t\t *\n\t\t * @readonly\n\t\t * @private\n\t\t * @member {module:typing/utils/changebuffer~ChangeBuffer} #_buffer\n\t\t */\n\t\tthis._buffer = new ChangeBuffer( editor.model, undoStepSize );\n\t}\n\n\t/**\n\t * The current change buffer.\n\t *\n\t * @type {module:typing/utils/changebuffer~ChangeBuffer}\n\t */\n\tget buffer() {\n\t\treturn this._buffer;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tsuper.destroy();\n\n\t\tthis._buffer.destroy();\n\t}\n\n\t/**\n\t * Executes the input command. It replaces the content within the given range with the given text.\n\t * Replacing is a two step process, first the content within the range is removed and then the new text is inserted\n\t * at the beginning of the range (which after the removal is a collapsed range).\n\t *\n\t * @fires execute\n\t * @param {Object} [options] The command options.\n\t * @param {String} [options.text=''] The text to be inserted.\n\t * @param {module:engine/model/range~Range} [options.range] The range in which the text is inserted. Defaults\n\t * to the first range in the current selection.\n\t * @param {module:engine/model/range~Range} [options.resultRange] The range where the selection\n\t * should be placed after the insertion. If not specified, the selection will be placed right after\n\t * the inserted text.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tconst text = options.text || '';\n\t\tconst textInsertions = text.length;\n\t\tconst range = options.range || doc.selection.getFirstRange();\n\t\tconst resultRange = options.resultRange;\n\n\t\tmodel.enqueueChange( this._buffer.batch, writer => {\n\t\t\tconst isCollapsedRange = range.isCollapsed;\n\n\t\t\tthis._buffer.lock();\n\n\t\t\tif ( !isCollapsedRange ) {\n\t\t\t\tmodel.deleteContent( model.createSelection( range ) );\n\t\t\t}\n\n\t\t\tif ( text ) {\n\t\t\t\twriter.insertText( text, doc.selection.getAttributes(), range.start );\n\t\t\t}\n\n\t\t\tif ( resultRange ) {\n\t\t\t\twriter.setSelection( resultRange );\n\t\t\t} else if ( isCollapsedRange ) {\n\t\t\t\t// If range was collapsed just shift the selection by the number of inserted characters.\n\t\t\t\twriter.setSelection( range.start.getShiftedBy( textInsertions ) );\n\t\t\t}\n\n\t\t\tthis._buffer.unlock();\n\n\t\t\tthis._buffer.input( textInsertions );\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module typing/utils/injectunsafekeystrokeshandling\n */\n\nimport { getCode } from '@ckeditor/ckeditor5-utils/src/keyboard';\n\n/**\n * Handles keystrokes which are unsafe for typing. This handler's logic is explained\n * in https://github.com/ckeditor/ckeditor5-typing/issues/83#issuecomment-398690251.\n *\n * @param {module:core/editor/editor~Editor} editor The editor instance.\n */\nexport default function injectUnsafeKeystrokesHandling( editor ) {\n\tlet latestCompositionSelection = null;\n\n\tconst model = editor.model;\n\tconst view = editor.editing.view;\n\tconst inputCommand = editor.commands.get( 'input' );\n\n\tview.document.on( 'keydown', ( evt, evtData ) => handleKeydown( evtData ), { priority: 'lowest' } );\n\n\tview.document.on( 'compositionstart', handleCompositionStart, { priority: 'lowest' } );\n\n\tview.document.on( 'compositionend', () => {\n\t\tlatestCompositionSelection = model.createSelection( model.document.selection );\n\t}, { priority: 'lowest' } );\n\n\t// Handles the keydown event. We need to guess whether such keystroke is going to result\n\t// in typing. If so, then before character insertion happens, any selected content needs\n\t// to be deleted. Otherwise the default browser deletion mechanism would be\n\t// triggered, resulting in:\n\t//\n\t// * Hundreds of mutations which could not be handled.\n\t// * But most importantly, loss of control over how the content is being deleted.\n\t//\n\t// The method is used in a low-priority listener, hence allowing other listeners (e.g. delete or enter features)\n\t// to handle the event.\n\t//\n\t// @param {module:engine/view/observer/keyobserver~KeyEventData} evtData\n\tfunction handleKeydown( evtData ) {\n\t\tconst doc = model.document;\n\t\tconst isComposing = view.document.isComposing;\n\t\tconst isSelectionUnchanged = latestCompositionSelection && latestCompositionSelection.isEqual( doc.selection );\n\n\t\t// Reset stored composition selection.\n\t\tlatestCompositionSelection = null;\n\n\t\t// By relying on the state of the input command we allow disabling the entire input easily\n\t\t// by just disabling the input command. We could’ve used here the delete command but that\n\t\t// would mean requiring the delete feature which would block loading one without the other.\n\t\t// We could also check the editor.isReadOnly property, but that wouldn't allow to block\n\t\t// the input without blocking other features.\n\t\tif ( !inputCommand.isEnabled ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( isSafeKeystroke( evtData ) || doc.selection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If during composition, deletion should be prevented as it may remove composed sequence (#83).\n\t\tif ( isComposing && evtData.keyCode === 229 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there is a `keydown` event fired with '229' keycode it might be related\n\t\t// to recent composition. Check if selection is the same as upon ending recent composition,\n\t\t// if so do not remove selected content as it will remove composed sequence (#83).\n\t\tif ( !isComposing && evtData.keyCode === 229 && isSelectionUnchanged ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdeleteSelectionContent();\n\t}\n\n\t// Handles the `compositionstart` event. It is used only in special cases to remove the contents\n\t// of a non-collapsed selection so composition itself does not result in complex mutations.\n\t//\n\t// The special case mentioned above is a situation in which the `keydown` event is fired after\n\t// `compositionstart` event. In such cases {@link #handleKeydown} cannot clear current selection\n\t// contents (because it is too late and will break the composition) so the composition handler takes care of it.\n\tfunction handleCompositionStart() {\n\t\tconst doc = model.document;\n\t\tconst isFlatSelection = doc.selection.rangeCount === 1 ? doc.selection.getFirstRange().isFlat : true;\n\n\t\t// If on `compositionstart` there is a non-collapsed selection which start and end have different parents\n\t\t// it means the `handleKeydown()` method did not remove its contents. It happens usually because\n\t\t// of different order of events (`compositionstart` before `keydown` - in Safari). In such cases\n\t\t// we need to remove selection contents on composition start (#83).\n\t\tif ( doc.selection.isCollapsed || isFlatSelection ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdeleteSelectionContent();\n\t}\n\n\tfunction deleteSelectionContent() {\n\t\tconst buffer = inputCommand.buffer;\n\n\t\tbuffer.lock();\n\n\t\tmodel.enqueueChange( buffer.batch, () => {\n\t\t\tmodel.deleteContent( model.document.selection );\n\t\t} );\n\n\t\tbuffer.unlock();\n\t}\n}\n\nconst safeKeycodes = [\n\tgetCode( 'arrowUp' ),\n\tgetCode( 'arrowRight' ),\n\tgetCode( 'arrowDown' ),\n\tgetCode( 'arrowLeft' ),\n\t9, // Tab\n\t16, // Shift\n\t17, // Ctrl\n\t18, // Alt\n\t19, // Pause\n\t20, // CapsLock\n\t27, // Escape\n\t33, // PageUp\n\t34, // PageDown\n\t35, // Home\n\t36, // End,\n\t45, // Insert,\n\t91, // Windows,\n\t93, // Menu key,\n\t144, // NumLock\n\t145, // ScrollLock,\n\t173, // Mute/Unmute\n\t174, // Volume up\n\t175, // Volume down,\n\t176, // Next song,\n\t177, // Previous song,\n\t178, // Stop,\n\t179, // Play/Pause,\n\t255 // Display brightness (increase and decrease)\n];\n\n// Function keys.\nfor ( let code = 112; code <= 135; code++ ) {\n\tsafeKeycodes.push( code );\n}\n\n// Returns `true` if a keystroke should not cause any content change caused by \"typing\".\n//\n// Note: This implementation is very simple and will need to be refined with time.\n//\n// @private\n// @param {engine.view.observer.keyObserver.KeyEventData} keyData\n// @returns {Boolean}\nfunction isSafeKeystroke( keyData ) {\n\t// Keystrokes which contain Ctrl don't represent typing.\n\tif ( keyData.ctrlKey ) {\n\t\treturn true;\n\t}\n\n\treturn safeKeycodes.includes( keyData.keyCode );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module typing/utils/utils\n */\n\nimport diff from '@ckeditor/ckeditor5-utils/src/diff';\nimport diffToChanges from '@ckeditor/ckeditor5-utils/src/difftochanges';\n\n/**\n * Returns true if container children have mutated or more than a single text node was changed.\n *\n * @private\n * @param {Array.<module:engine/view/observer/mutationobserver~MutatedText|\n * module:engine/view/observer/mutationobserver~MutatedChildren>} mutations\n * @returns {Boolean}\n */\nexport function containerChildrenMutated( mutations ) {\n\tif ( mutations.length == 0 ) {\n\t\treturn false;\n\t}\n\n\t// Check if there is any mutation of `children` type or any mutation that changes more than one text node.\n\tfor ( const mutation of mutations ) {\n\t\tif ( mutation.type === 'children' && !getSingleTextNodeChange( mutation ) ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Returns change made to a single text node.\n *\n * @private\n * @param {module:engine/view/observer/mutationobserver~MutatedText|\n * module:engine/view/observer/mutationobserver~MutatedChildren} mutation\n * @returns {Object|undefined} Change object (see {@link module:utils/difftochanges~diffToChanges} output)\n * or undefined if more than a single text node was changed.\n */\nexport function getSingleTextNodeChange( mutation ) {\n\t// One new node.\n\tif ( mutation.newChildren.length - mutation.oldChildren.length != 1 ) {\n\t\treturn;\n\t}\n\n\t// Which is text.\n\tconst diffResult = diff( mutation.oldChildren, mutation.newChildren, compareChildNodes );\n\tconst changes = diffToChanges( diffResult, mutation.newChildren );\n\n\t// In case of [ delete, insert, insert ] the previous check will not exit.\n\tif ( changes.length > 1 ) {\n\t\treturn;\n\t}\n\n\tconst change = changes[ 0 ];\n\n\t// Which is text.\n\tif ( !( !!change.values[ 0 ] && change.values[ 0 ].is( 'text' ) ) ) {\n\t\treturn;\n\t}\n\n\treturn change;\n}\n\n/**\n * Checks whether two view nodes are identical, which means they are the same object\n * or contain exactly same data (in case of text nodes).\n *\n * @private\n * @param {module:engine/view/node~Node} oldChild\n * @param {module:engine/view/node~Node} newChild\n * @returns {Boolean}\n */\nexport function compareChildNodes( oldChild, newChild ) {\n\tif ( !!oldChild && oldChild.is( 'text' ) && !!newChild && newChild.is( 'text' ) ) {\n\t\treturn oldChild.data === newChild.data;\n\t} else {\n\t\treturn oldChild === newChild;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/difftochanges\n */\n\n/**\n * Creates a set of changes which need to be applied to the input in order to transform\n * it into the output. This function can be used with strings or arrays.\n *\n *\t\tconst input = Array.from( 'abc' );\n *\t\tconst output = Array.from( 'xaby' );\n *\t\tconst changes = diffToChanges( diff( input, output ), output );\n *\n *\t\tchanges.forEach( change => {\n *\t\t\tif ( change.type == 'insert' ) {\n *\t\t\t\tinput.splice( change.index, 0, ...change.values );\n *\t\t\t} else if ( change.type == 'delete' ) {\n *\t\t\t\tinput.splice( change.index, change.howMany );\n *\t\t\t}\n *\t\t} );\n *\n *\t\tinput.join( '' ) == output.join( '' ); // -> true\n *\n * @param {Array.<'equal'|'insert'|'delete'>} diff Result of {@link module:utils/diff~diff}.\n * @param {String|Array} output The string or array which was passed as diff's output.\n * @returns {Array.<Object>} Set of changes (insert or delete) which need to be applied to the input\n * in order to transform it into the output.\n */\nexport default function diffToChanges( diff, output ) {\n\tconst changes = [];\n\tlet index = 0;\n\tlet lastOperation;\n\n\tdiff.forEach( change => {\n\t\tif ( change == 'equal' ) {\n\t\t\tpushLast();\n\n\t\t\tindex++;\n\t\t} else if ( change == 'insert' ) {\n\t\t\tif ( isContinuationOf( 'insert' ) ) {\n\t\t\t\tlastOperation.values.push( output[ index ] );\n\t\t\t} else {\n\t\t\t\tpushLast();\n\n\t\t\t\tlastOperation = {\n\t\t\t\t\ttype: 'insert',\n\t\t\t\t\tindex,\n\t\t\t\t\tvalues: [ output[ index ] ]\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tindex++;\n\t\t} else /* if ( change == 'delete' ) */ {\n\t\t\tif ( isContinuationOf( 'delete' ) ) {\n\t\t\t\tlastOperation.howMany++;\n\t\t\t} else {\n\t\t\t\tpushLast();\n\n\t\t\t\tlastOperation = {\n\t\t\t\t\ttype: 'delete',\n\t\t\t\t\tindex,\n\t\t\t\t\thowMany: 1\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t} );\n\n\tpushLast();\n\n\treturn changes;\n\n\tfunction pushLast() {\n\t\tif ( lastOperation ) {\n\t\t\tchanges.push( lastOperation );\n\t\t\tlastOperation = null;\n\t\t}\n\t}\n\n\tfunction isContinuationOf( expected ) {\n\t\treturn lastOperation && lastOperation.type == expected;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module typing/utils/injecttypingmutationshandling\n */\n\nimport diff from '@ckeditor/ckeditor5-utils/src/diff';\nimport DomConverter from '@ckeditor/ckeditor5-engine/src/view/domconverter';\n\nimport { getSingleTextNodeChange, containerChildrenMutated } from './utils';\n\n/**\n * Handles mutations caused by normal typing.\n *\n * @param {module:core/editor/editor~Editor} editor The editor instance.\n */\nexport default function injectTypingMutationsHandling( editor ) {\n\teditor.editing.view.document.on( 'mutations', ( evt, mutations, viewSelection ) => {\n\t\tnew MutationHandler( editor ).handle( mutations, viewSelection );\n\t} );\n}\n\n/**\n * Helper class for translating DOM mutations into model changes.\n *\n * @private\n */\nclass MutationHandler {\n\t/**\n\t * Creates an instance of the mutation handler.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * Editor instance for which mutations are handled.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * The editing controller.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/controller/editingcontroller~EditingController} #editing\n\t\t */\n\t\tthis.editing = this.editor.editing;\n\t}\n\n\t/**\n\t * Handles given mutations.\n\t *\n\t * @param {Array.<module:engine/view/observer/mutationobserver~MutatedText|\n\t * module:engine/view/observer/mutationobserver~MutatedChildren>} mutations\n\t * @param {module:engine/view/selection~Selection|null} viewSelection\n\t */\n\thandle( mutations, viewSelection ) {\n\t\tif ( containerChildrenMutated( mutations ) ) {\n\t\t\tthis._handleContainerChildrenMutations( mutations, viewSelection );\n\t\t} else {\n\t\t\tfor ( const mutation of mutations ) {\n\t\t\t\t// Fortunately it will never be both.\n\t\t\t\tthis._handleTextMutation( mutation, viewSelection );\n\t\t\t\tthis._handleTextNodeInsertion( mutation );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Handles situations when container's children mutated during input. This can happen when\n\t * the browser is trying to \"fix\" DOM in certain situations. For example, when the user starts to type\n\t * in `<p><a href=\"\"><i>Link{}</i></a></p>`, the browser might change the order of elements\n\t * to `<p><i><a href=\"\">Link</a>x{}</i></p>`. A similar situation happens when the spell checker\n\t * replaces a word wrapped with `<strong>` with a word wrapped with a `<b>` element.\n\t *\n\t * To handle such situations, the common DOM ancestor of all mutations is converted to the model representation\n\t * and then compared with the current model to calculate the proper text change.\n\t *\n\t * Note: Single text node insertion is handled in {@link #_handleTextNodeInsertion} and text node mutation is handled\n\t * in {@link #_handleTextMutation}).\n\t *\n\t * @private\n\t * @param {Array.<module:engine/view/observer/mutationobserver~MutatedText|\n\t * module:engine/view/observer/mutationobserver~MutatedChildren>} mutations\n\t * @param {module:engine/view/selection~Selection|null} viewSelection\n\t */\n\t_handleContainerChildrenMutations( mutations, viewSelection ) {\n\t\t// Get common ancestor of all mutations.\n\t\tconst mutationsCommonAncestor = getMutationsContainer( mutations );\n\n\t\t// Quit if there is no common ancestor.\n\t\tif ( !mutationsCommonAncestor ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst domConverter = this.editor.editing.view.domConverter;\n\n\t\t// Get common ancestor in DOM.\n\t\tconst domMutationCommonAncestor = domConverter.mapViewToDom( mutationsCommonAncestor );\n\n\t\t// Create fresh DomConverter so it will not use existing mapping and convert current DOM to model.\n\t\t// This wouldn't be needed if DomConverter would allow to create fresh view without checking any mappings.\n\t\tconst freshDomConverter = new DomConverter();\n\t\tconst modelFromCurrentDom = this.editor.data.toModel(\n\t\t\tfreshDomConverter.domToView( domMutationCommonAncestor )\n\t\t).getChild( 0 );\n\n\t\t// Current model.\n\t\tconst currentModel = this.editor.editing.mapper.toModelElement( mutationsCommonAncestor );\n\n\t\t// If common ancestor is not mapped, do not do anything. It probably is a parent of another view element.\n\t\t// That means that we would need to diff model elements (see `if` below). Better return early instead of\n\t\t// trying to get a reasonable model ancestor. It will fell into the `if` below anyway.\n\t\t// This situation happens for example for lists. If `<ul>` is a common ancestor, `currentModel` is `undefined`\n\t\t// because `<ul>` is not mapped (`<li>`s are).\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/718.\n\t\tif ( !currentModel ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Get children from both ancestors.\n\t\tconst modelFromDomChildren = Array.from( modelFromCurrentDom.getChildren() );\n\t\tconst currentModelChildren = Array.from( currentModel.getChildren() );\n\n\t\t// Remove the last `<softBreak>` from the end of `modelFromDomChildren` if there is no `<softBreak>` in current model.\n\t\t// If the described scenario happened, it means that this is a bogus `<br />` added by a browser.\n\t\tconst lastDomChild = modelFromDomChildren[ modelFromDomChildren.length - 1 ];\n\t\tconst lastCurrentChild = currentModelChildren[ currentModelChildren.length - 1 ];\n\n\t\tif ( lastDomChild && lastDomChild.is( 'softBreak' ) && lastCurrentChild && !lastCurrentChild.is( 'softBreak' ) ) {\n\t\t\tmodelFromDomChildren.pop();\n\t\t}\n\n\t\tconst schema = this.editor.model.schema;\n\n\t\t// Skip situations when common ancestor has any container elements.\n\t\tif ( !isSafeForTextMutation( modelFromDomChildren, schema ) || !isSafeForTextMutation( currentModelChildren, schema ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Replace &nbsp; inserted by the browser with normal space. See comment in `_handleTextMutation`.\n\t\t// Replace non-texts with any character. This is potentially dangerous but passes in manual tests. The thing is\n\t\t// that we need to take care of proper indexes so we cannot simply remove non-text elements from the content.\n\t\t// By inserting a character we keep all the real texts on their indexes.\n\t\tconst newText = modelFromDomChildren.map( item => item.is( 'text' ) ? item.data : '@' ).join( '' ).replace( /\\u00A0/g, ' ' );\n\t\tconst oldText = currentModelChildren.map( item => item.is( 'text' ) ? item.data : '@' ).join( '' ).replace( /\\u00A0/g, ' ' );\n\n\t\t// Do nothing if mutations created same text.\n\t\tif ( oldText === newText ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst diffResult = diff( oldText, newText );\n\n\t\tconst { firstChangeAt, insertions, deletions } = calculateChanges( diffResult );\n\n\t\t// Try setting new model selection according to passed view selection.\n\t\tlet modelSelectionRange = null;\n\n\t\tif ( viewSelection ) {\n\t\t\tmodelSelectionRange = this.editing.mapper.toModelRange( viewSelection.getFirstRange() );\n\t\t}\n\n\t\tconst insertText = newText.substr( firstChangeAt, insertions );\n\t\tconst removeRange = this.editor.model.createRange(\n\t\t\tthis.editor.model.createPositionAt( currentModel, firstChangeAt ),\n\t\t\tthis.editor.model.createPositionAt( currentModel, firstChangeAt + deletions )\n\t\t);\n\n\t\tthis.editor.execute( 'input', {\n\t\t\ttext: insertText,\n\t\t\trange: removeRange,\n\t\t\tresultRange: modelSelectionRange\n\t\t} );\n\t}\n\n\t/**\n\t * @private\n\t */\n\t_handleTextMutation( mutation, viewSelection ) {\n\t\tif ( mutation.type != 'text' ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Replace &nbsp; inserted by the browser with normal space.\n\t\t// We want only normal spaces in the model and in the view. Renderer and DOM Converter will be then responsible\n\t\t// for rendering consecutive spaces using &nbsp;, but the model and the view has to be clear.\n\t\t// Other feature may introduce inserting non-breakable space on specific key stroke (for example shift + space).\n\t\t// However then it will be handled outside of mutations, like enter key is.\n\t\t// The replacing is here because it has to be done before `diff` and `diffToChanges` functions, as they\n\t\t// take `newText` and compare it to (cleaned up) view.\n\t\t// It could also be done in mutation observer too, however if any outside plugin would like to\n\t\t// introduce additional events for mutations, they would get already cleaned up version (this may be good or not).\n\t\tconst newText = mutation.newText.replace( /\\u00A0/g, ' ' );\n\t\t// To have correct `diffResult`, we also compare view node text data with &nbsp; replaced by space.\n\t\tconst oldText = mutation.oldText.replace( /\\u00A0/g, ' ' );\n\n\t\t// Do nothing if mutations created same text.\n\t\tif ( oldText === newText ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst diffResult = diff( oldText, newText );\n\n\t\tconst { firstChangeAt, insertions, deletions } = calculateChanges( diffResult );\n\n\t\t// Try setting new model selection according to passed view selection.\n\t\tlet modelSelectionRange = null;\n\n\t\tif ( viewSelection ) {\n\t\t\tmodelSelectionRange = this.editing.mapper.toModelRange( viewSelection.getFirstRange() );\n\t\t}\n\n\t\t// Get the position in view and model where the changes will happen.\n\t\tconst viewPos = this.editing.view.createPositionAt( mutation.node, firstChangeAt );\n\t\tconst modelPos = this.editing.mapper.toModelPosition( viewPos );\n\t\tconst removeRange = this.editor.model.createRange( modelPos, modelPos.getShiftedBy( deletions ) );\n\t\tconst insertText = newText.substr( firstChangeAt, insertions );\n\n\t\tthis.editor.execute( 'input', {\n\t\t\ttext: insertText,\n\t\t\trange: removeRange,\n\t\t\tresultRange: modelSelectionRange\n\t\t} );\n\t}\n\n\t/**\n\t * @private\n\t */\n\t_handleTextNodeInsertion( mutation ) {\n\t\tif ( mutation.type != 'children' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst change = getSingleTextNodeChange( mutation );\n\t\tconst viewPos = this.editing.view.createPositionAt( mutation.node, change.index );\n\t\tconst modelPos = this.editing.mapper.toModelPosition( viewPos );\n\t\tconst insertedText = change.values[ 0 ].data;\n\n\t\tthis.editor.execute( 'input', {\n\t\t\t// Replace &nbsp; inserted by the browser with normal space.\n\t\t\t// See comment in `_handleTextMutation`.\n\t\t\t// In this case we don't need to do this before `diff` because we diff whole nodes.\n\t\t\t// Just change &nbsp; in case there are some.\n\t\t\ttext: insertedText.replace( /\\u00A0/g, ' ' ),\n\t\t\trange: this.editor.model.createRange( modelPos )\n\t\t} );\n\t}\n}\n\n// Returns first common ancestor of all mutations that is either {@link module:engine/view/containerelement~ContainerElement}\n// or {@link module:engine/view/rootelement~RootElement}.\n//\n// @private\n// @param {Array.<module:engine/view/observer/mutationobserver~MutatedText|\n// module:engine/view/observer/mutationobserver~MutatedChildren>} mutations\n// @returns {module:engine/view/containerelement~ContainerElement|engine/view/rootelement~RootElement|undefined}\nfunction getMutationsContainer( mutations ) {\n\tconst lca = mutations\n\t\t.map( mutation => mutation.node )\n\t\t.reduce( ( commonAncestor, node ) => {\n\t\t\treturn commonAncestor.getCommonAncestor( node, { includeSelf: true } );\n\t\t} );\n\n\tif ( !lca ) {\n\t\treturn;\n\t}\n\n\t// We need to look for container and root elements only, so check all LCA's\n\t// ancestors (starting from itself).\n\treturn lca.getAncestors( { includeSelf: true, parentFirst: true } )\n\t\t.find( element => element.is( 'containerElement' ) || element.is( 'rootElement' ) );\n}\n\n// Returns true if provided array contains content that won't be problematic during diffing and text mutation handling.\n//\n// @param {Array.<module:engine/model/node~Node>} children\n// @param {module:engine/model/schema~Schema} schema\n// @returns {Boolean}\nfunction isSafeForTextMutation( children, schema ) {\n\treturn children.every( child => schema.isInline( child ) );\n}\n\n// Calculates first change index and number of characters that should be inserted and deleted starting from that index.\n//\n// @private\n// @param diffResult\n// @returns {{insertions: number, deletions: number, firstChangeAt: *}}\nfunction calculateChanges( diffResult ) {\n\t// Index where the first change happens. Used to set the position from which nodes will be removed and where will be inserted.\n\tlet firstChangeAt = null;\n\t// Index where the last change happens. Used to properly count how many characters have to be removed and inserted.\n\tlet lastChangeAt = null;\n\n\t// Get `firstChangeAt` and `lastChangeAt`.\n\tfor ( let i = 0; i < diffResult.length; i++ ) {\n\t\tconst change = diffResult[ i ];\n\n\t\tif ( change != 'equal' ) {\n\t\t\tfirstChangeAt = firstChangeAt === null ? i : firstChangeAt;\n\t\t\tlastChangeAt = i;\n\t\t}\n\t}\n\n\t// How many characters, starting from `firstChangeAt`, should be removed.\n\tlet deletions = 0;\n\t// How many characters, starting from `firstChangeAt`, should be inserted.\n\tlet insertions = 0;\n\n\tfor ( let i = firstChangeAt; i <= lastChangeAt; i++ ) {\n\t\t// If there is no change (equal) or delete, the character is existing in `oldText`. We count it for removing.\n\t\tif ( diffResult[ i ] != 'insert' ) {\n\t\t\tdeletions++;\n\t\t}\n\n\t\t// If there is no change (equal) or insert, the character is existing in `newText`. We count it for inserting.\n\t\tif ( diffResult[ i ] != 'delete' ) {\n\t\t\tinsertions++;\n\t\t}\n\t}\n\n\treturn { insertions, deletions, firstChangeAt };\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module typing/input\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport InputCommand from './inputcommand';\n\nimport injectUnsafeKeystrokesHandling from './utils/injectunsafekeystrokeshandling';\nimport injectTypingMutationsHandling from './utils/injecttypingmutationshandling';\n\n/**\n * Handles text input coming from the keyboard or other input methods.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Input extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Input';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\n\t\t// TODO The above default configuration value should be defined using editor.config.define() once it's fixed.\n\t\tconst inputCommand = new InputCommand( editor, editor.config.get( 'typing.undoStep' ) || 20 );\n\n\t\teditor.commands.add( 'input', inputCommand );\n\n\t\tinjectUnsafeKeystrokesHandling( editor );\n\t\tinjectTypingMutationsHandling( editor );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module typing/deletecommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport count from '@ckeditor/ckeditor5-utils/src/count';\n\nimport ChangeBuffer from './utils/changebuffer';\n\n/**\n * The delete command. Used by the {@link module:typing/delete~Delete delete feature} to handle the <kbd>Delete</kbd> and\n * <kbd>Backspace</kbd> keys.\n *\n * @extends module:core/command~Command\n */\nexport default class DeleteCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor\n\t * @param {'forward'|'backward'} direction The directionality of the delete describing in what direction it\n\t * should consume the content when the selection is collapsed.\n\t */\n\tconstructor( editor, direction ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The directionality of the delete describing in what direction it should\n\t\t * consume the content when the selection is collapsed.\n\t\t *\n\t\t * @readonly\n\t\t * @member {'forward'|'backward'} #direction\n\t\t */\n\t\tthis.direction = direction;\n\n\t\t/**\n\t\t * Delete's change buffer used to group subsequent changes into batches.\n\t\t *\n\t\t * @readonly\n\t\t * @private\n\t\t * @member {typing.ChangeBuffer} #buffer\n\t\t */\n\t\tthis._buffer = new ChangeBuffer( editor.model, editor.config.get( 'typing.undoStep' ) );\n\t}\n\n\t/**\n\t * The current change buffer.\n\t *\n\t * @type {module:typing/utils/changebuffer~ChangeBuffer}\n\t */\n\tget buffer() {\n\t\treturn this._buffer;\n\t}\n\n\t/**\n\t * Executes the delete command. Depending on whether the selection is collapsed or not, deletes its content\n\t * or a piece of content in the {@link #direction defined direction}.\n\t *\n\t * @fires execute\n\t * @param {Object} [options] The command options.\n\t * @param {'character'} [options.unit='character'] See {@link module:engine/model/utils/modifyselection~modifySelection}'s options.\n\t * @param {Number} [options.sequence=1] A number describing which subsequent delete event it is without the key being released.\n\t * See the {@link module:engine/view/document~Document#event:delete} event data.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\n\t\tmodel.enqueueChange( this._buffer.batch, writer => {\n\t\t\tthis._buffer.lock();\n\n\t\t\tconst selection = writer.createSelection( doc.selection );\n\n\t\t\t// Do not replace the whole selected content if selection was collapsed.\n\t\t\t// This prevents such situation:\n\t\t\t//\n\t\t\t// <h1></h1><p>[]</p>\t--> <h1>[</h1><p>]</p> \t\t--> <p></p>\n\t\t\t// starting content\t\t--> after `modifySelection`\t--> after `deleteContent`.\n\t\t\tconst doNotResetEntireContent = selection.isCollapsed;\n\n\t\t\t// Try to extend the selection in the specified direction.\n\t\t\tif ( selection.isCollapsed ) {\n\t\t\t\tmodel.modifySelection( selection, { direction: this.direction, unit: options.unit } );\n\t\t\t}\n\n\t\t\t// Check if deleting in an empty editor. See #61.\n\t\t\tif ( this._shouldEntireContentBeReplacedWithParagraph( options.sequence || 1 ) ) {\n\t\t\t\tthis._replaceEntireContentWithParagraph( writer );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If selection is still collapsed, then there's nothing to delete.\n\t\t\tif ( selection.isCollapsed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet changeCount = 0;\n\n\t\t\tselection.getFirstRange().getMinimalFlatRanges().forEach( range => {\n\t\t\t\tchangeCount += count(\n\t\t\t\t\trange.getWalker( { singleCharacters: true, ignoreElementEnd: true, shallow: true } )\n\t\t\t\t);\n\t\t\t} );\n\n\t\t\tmodel.deleteContent( selection, { doNotResetEntireContent } );\n\t\t\tthis._buffer.input( changeCount );\n\n\t\t\twriter.setSelection( selection );\n\n\t\t\tthis._buffer.unlock();\n\t\t} );\n\t}\n\n\t/**\n\t * If the user keeps <kbd>Backspace</kbd> or <kbd>Delete</kbd> key pressed, the content of the current\n\t * editable will be cleared. However, this will not yet lead to resetting the remaining block to a paragraph\n\t * (which happens e.g. when the user does <kbd>Ctrl</kbd> + <kbd>A</kbd>, <kbd>Backspace</kbd>).\n\t *\n\t * But, if the user pressed the key in an empty editable for the first time,\n\t * we want to replace the entire content with a paragraph if:\n\t *\n\t * * the current limit element is empty,\n\t * * the paragraph is allowed in the limit element,\n\t * * the limit doesn't already have a paragraph inside.\n\t *\n\t * See https://github.com/ckeditor/ckeditor5-typing/issues/61.\n\t *\n\t * @private\n\t * @param {Number} sequence A number describing which subsequent delete event it is without the key being released.\n\t * @returns {Boolean}\n\t */\n\t_shouldEntireContentBeReplacedWithParagraph( sequence ) {\n\t\t// Does nothing if user pressed and held the \"Backspace\" or \"Delete\" key.\n\t\tif ( sequence > 1 ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tconst selection = doc.selection;\n\t\tconst limitElement = model.schema.getLimitElement( selection );\n\n\t\t// If a collapsed selection contains the whole content it means that the content is empty\n\t\t// (from the user perspective).\n\t\tconst limitElementIsEmpty = selection.isCollapsed && selection.containsEntireContent( limitElement );\n\n\t\tif ( !limitElementIsEmpty ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( !model.schema.checkChild( limitElement, 'paragraph' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst limitElementFirstChild = limitElement.getChild( 0 );\n\n\t\t// Does nothing if the limit element already contains only a paragraph.\n\t\t// We ignore the case when paragraph might have some inline elements (<p><inlineWidget>[]</inlineWidget></p>)\n\t\t// because we don't support such cases yet and it's unclear whether inlineWidget shouldn't be a limit itself.\n\t\tif ( limitElementFirstChild && limitElementFirstChild.name === 'paragraph' ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * The entire content is replaced with the paragraph. Selection is moved inside the paragraph.\n\t *\n\t * @private\n\t */\n\t_replaceEntireContentWithParagraph( writer ) {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tconst selection = doc.selection;\n\t\tconst limitElement = model.schema.getLimitElement( selection );\n\t\tconst paragraph = writer.createElement( 'paragraph' );\n\n\t\twriter.remove( writer.createRangeIn( limitElement ) );\n\t\twriter.insert( paragraph, limitElement );\n\n\t\twriter.setSelection( paragraph, 0 );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module typing/deleteobserver\n */\n\nimport Observer from '@ckeditor/ckeditor5-engine/src/view/observer/observer';\nimport DomEventData from '@ckeditor/ckeditor5-engine/src/view/observer/domeventdata';\nimport { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';\nimport env from '@ckeditor/ckeditor5-utils/src/env';\n\n/**\n * Delete observer introduces the {@link module:engine/view/document~Document#event:delete} event.\n *\n * @extends module:engine/view/observer/observer~Observer\n */\nexport default class DeleteObserver extends Observer {\n\tconstructor( view ) {\n\t\tsuper( view );\n\n\t\tconst document = view.document;\n\t\tlet sequence = 0;\n\n\t\tdocument.on( 'keyup', ( evt, data ) => {\n\t\t\tif ( data.keyCode == keyCodes.delete || data.keyCode == keyCodes.backspace ) {\n\t\t\t\tsequence = 0;\n\t\t\t}\n\t\t} );\n\n\t\tdocument.on( 'keydown', ( evt, data ) => {\n\t\t\tconst deleteData = {};\n\n\t\t\tif ( data.keyCode == keyCodes.delete ) {\n\t\t\t\tdeleteData.direction = 'forward';\n\t\t\t\tdeleteData.unit = 'character';\n\t\t\t} else if ( data.keyCode == keyCodes.backspace ) {\n\t\t\t\tdeleteData.direction = 'backward';\n\t\t\t\tdeleteData.unit = 'codePoint';\n\t\t\t} else {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst hasWordModifier = env.isMac ? data.altKey : data.ctrlKey;\n\t\t\tdeleteData.unit = hasWordModifier ? 'word' : deleteData.unit;\n\t\t\tdeleteData.sequence = ++sequence;\n\n\t\t\t// Save the event object to check later if it was stopped or not.\n\t\t\tlet event;\n\t\t\tdocument.once( 'delete', evt => ( event = evt ), { priority: Number.POSITIVE_INFINITY } );\n\n\t\t\tconst domEvtData = new DomEventData( document, data.domEvent, deleteData );\n\t\t\tdocument.fire( 'delete', domEvtData );\n\n\t\t\t// Stop `keydown` event if `delete` event was stopped.\n\t\t\t// https://github.com/ckeditor/ckeditor5/issues/753\n\t\t\tif ( event && event.stop.called ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tobserve() {}\n}\n\n/**\n * Event fired when the user tries to delete content (e.g. presses <kbd>Delete</kbd> or <kbd>Backspace</kbd>).\n *\n * Note: This event is fired by the {@link module:typing/deleteobserver~DeleteObserver observer}\n * (usually registered by the {@link module:typing/delete~Delete delete feature}).\n *\n * @event module:engine/view/document~Document#event:delete\n * @param {module:engine/view/observer/domeventdata~DomEventData} data\n * @param {'forward'|'delete'} data.direction The direction in which the deletion should happen.\n * @param {'character'|'word'} data.unit The \"amount\" of content that should be deleted.\n * @param {Number} data.sequence A number describing which subsequent delete event it is without the key being released.\n * If it's 2 or more it means that the key was pressed and hold.\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module typing/utils/injectandroidbackspacenutationshandling\n */\n\nimport diff from '@ckeditor/ckeditor5-utils/src/diff';\n\nimport { containerChildrenMutated } from './utils';\n\n/**\n * Handles mutations triggered by <kbd>Backspace</kbd> on Android.\n * Due to the fact that on Android `keydown` events don't have the `keyCode` set, we are not able\n * to handle backspacing directly. We need to guess that from mutations which the IME\n * on Android caused.\n *\n * @param {module:core/editor/editor~Editor} editor The editor instance.\n */\nexport default function injectAndroidBackspaceMutationsHandling( editor ) {\n\tconst model = editor.model;\n\tconst view = editor.editing.view;\n\tconst selectionChangeToleranceMs = 200;\n\n\tlet previousSelection = null;\n\tlet currentSelection = model.createSelection( model.document.selection );\n\tlet latestSelectionChangeMs = Date.now();\n\n\tmodel.document.selection.on( 'change', handleSelectionChange );\n\n\tview.document.on( 'mutations', handleMutations, { priority: 'highest' } );\n\n\t// Saves current and previous selection when it changes. Saved selections are used\n\t// to remove correct piece of content when `Backspace` mutations are detected.\n\t//\n\t// @param {Object} evt\n\tfunction handleSelectionChange( evt ) {\n\t\tconst newSelection = model.createSelection( evt.source );\n\t\tif ( !currentSelection.isEqual( newSelection ) ) {\n\t\t\tpreviousSelection = currentSelection;\n\t\t\tcurrentSelection = newSelection;\n\t\t\tlatestSelectionChangeMs = Date.now();\n\t\t}\n\t}\n\n\t// Handles DOM mutations and checks if they should be processed as block elements removal mutations.\n\t//\n\t// @param {Object} evt\n\t// @param {Array.<module:engine/view/observer/mutationobserver~MutatedText|\n\t// module:engine/view/observer/mutationobserver~MutatedChildren>} mutations\n\tfunction handleMutations( evt, mutations ) {\n\t\tif ( containerChildrenMutated( mutations ) && containsContainersRemoval( mutations ) ) {\n\t\t\thandleContainerRemovalMutations();\n\n\t\t\t// Stop mutations event propagation so other mutation handlers are not triggered.\n\t\t\tevt.stop();\n\t\t}\n\t}\n\n\t// Handles situations when mutations were generated by container removal.\n\t// It happens on Android devices where every typing input has `229` key code\n\t// and delete observer will not be triggered. In such cases we need to handle\n\t// container removal mutations manually.\n\tfunction handleContainerRemovalMutations() {\n\t\tif ( shouldUsePreviousSelection() ) {\n\t\t\t// If previous selection is used, update model selection in order\n\t\t\t// to use `delete` command and to make `undo` work correctly.\n\t\t\tmodel.enqueueChange( writer => {\n\t\t\t\twriter.setSelection( previousSelection );\n\t\t\t} );\n\t\t}\n\n\t\teditor.execute( 'delete' );\n\t}\n\n\t// Whether previously saved selection should be used instead of the current one to remove content.\n\t//\n\t// On Android devices when pressing backspace on non-collapsed selection, selection like:\n\t//\n\t//\t\t`<h1>[Foo</h1><p>Bar]</p>`\n\t//\n\t// is changed to:\n\t//\n\t//\t\t`<h1>Foo</h1><p>Bar[]</p>`\n\t//\n\t// even before `keypress` event, so in such cases we have to rely on previous selection to correctly process selected content.\n\t//\n\t// Previous selection will be used if:\n\t//\n\t//\t\t* current selection is collapsed (see example above),\n\t//\t\t* previous selection exists, is non-collapsed and has same ending (last position) as the current one,\n\t//\t\t* change of the selection happened not earlier than X milliseconds ago (see `selectionChangeToleranceMs`).\n\t//\n\t// The last check is needed, because user can manually collapse the selection on its current end and then press `Backspace`.\n\t// In such situations timing determines if the selection change was caused by the user or browser native behaviour.\n\t// However, this happens only if selection was collapsed by the user on the beginning of the paragraph (so mutations\n\t// still will show container removal).\n\t//\n\t// @returns {Boolean}\n\tfunction shouldUsePreviousSelection() {\n\t\treturn Date.now() - latestSelectionChangeMs < selectionChangeToleranceMs &&\n\t\t\tpreviousSelection && !previousSelection.isCollapsed && currentSelection.isCollapsed &&\n\t\t\tcurrentSelection.getLastPosition().isEqual( previousSelection.getLastPosition() );\n\t}\n}\n\n// Checks whether mutations array contains mutation generated by container/containers removal.\n// For example mutations generated on Android when pressing `backspace` on the beginning of the line:\n//\n//\t\t<h1>Header1</h1>\n//\t\t<p>{}Paragraph</p>\n//\n// are:\n//\n//\t\t[\n//\t\t\t{ newChildren: [], oldChildren: [ 'Paragraph' ], node: P, type: 'children' },\n//\t\t\t{ newChildren: [ ContainerElement ], oldChildren: [ ContainerElement, ContainerElement ], node: Root, type: 'children' },\n//\t\t\t{ newChildren: [ 'Heading 1Paragraph' ], oldChildren: [ 'Heading 1' ], node: H1, type: 'children' }\n//\t\t]\n//\n// The 1st and 3rd mutations are just changes in a text (1st - text in `p` element was removed, 3rd - text in `h2` was changed)\n// and the 2nd one shows that one `ContainerElement` was removed. We have to recognize if mutations like 2nd one are present.\n// Based on that heuristic mutations are treated as the one removing container element.\n//\n// @private\n// @param {Array.<module:engine/view/observer/mutationobserver~MutatedText|\n// module:engine/view/observer/mutationobserver~MutatedChildren>} mutations\n// @returns {Boolean}\nfunction containsContainersRemoval( mutations ) {\n\tfor ( const mutation of mutations ) {\n\t\tif ( mutation.type !== 'children' ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst childrenBefore = mutation.oldChildren;\n\t\tconst childrenAfter = mutation.newChildren;\n\n\t\t// Check if only containers were present before the mutation.\n\t\tif ( !hasOnlyContainers( childrenBefore ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst diffResult = diff( childrenBefore, childrenAfter );\n\n\t\t// Check if there was only removing in that mutation without any insertions.\n\t\tconst hasDelete = diffResult.some( item => item === 'delete' );\n\t\tconst hasInsert = diffResult.some( item => item === 'insert' );\n\n\t\tif ( hasDelete && !hasInsert ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n// Whether provided array contains only nodes of `containerElement` type.\n//\n// @private\n// @param {Array.<module:engine/view/node~Node>} children\n// @returns {Boolean}\nfunction hasOnlyContainers( children ) {\n\treturn children.every( child => child.is( 'containerElement' ) );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module typing/delete\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport DeleteCommand from './deletecommand';\nimport DeleteObserver from './deleteobserver';\n\nimport injectAndroidBackspaceMutationsHandling from './utils/injectandroidbackspacemutationshandling';\n\n/**\n * The delete and backspace feature. Handles the <kbd>Delete</kbd> and <kbd>Backspace</kbd> keys in the editor.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Delete extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Delete';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\n\t\tview.addObserver( DeleteObserver );\n\n\t\teditor.commands.add( 'forwardDelete', new DeleteCommand( editor, 'forward' ) );\n\t\teditor.commands.add( 'delete', new DeleteCommand( editor, 'backward' ) );\n\n\t\tthis.listenTo( viewDocument, 'delete', ( evt, data ) => {\n\t\t\teditor.execute( data.direction == 'forward' ? 'forwardDelete' : 'delete', { unit: data.unit, sequence: data.sequence } );\n\t\t\tdata.preventDefault();\n\t\t\tview.scrollToTheSelection();\n\t\t} );\n\n\t\tinjectAndroidBackspaceMutationsHandling( editor );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module typing/typing\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport Input from './input';\nimport Delete from './delete';\n\n/**\n * The typing feature. It handles typing.\n *\n * This is a \"glue\" plugin which loads the {@link module:typing/input~Input} and {@link module:typing/delete~Delete}\n * plugins.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Typing extends Plugin {\n\tstatic get requires() {\n\t\treturn [ Input, Delete ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Typing';\n\t}\n}\n\n/**\n * The configuration of the typing features. Used by the features from the `@ckeditor/ckeditor5-typing` package.\n *\n * Read more in {@link module:typing/typing~TypingConfig}.\n *\n * @member {module:typing/typing~TypingConfig} module:core/editor/editorconfig~EditorConfig#typing\n */\n\n/**\n * The configuration of the typing features. Used by the typing features in `@ckeditor/ckeditor5-typing` package.\n *\n *\t\tClassicEditor\n *\t\t\t.create( editorElement, {\n * \t\t\t\ttyping: ... // Typing feature options.\n *\t\t\t} )\n *\t\t\t.then( ... )\n *\t\t\t.catch( ... );\n *\n * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.\n *\n * @interface TypingConfig\n */\n\n/**\n * The granularity of undo/redo for typing and deleting. The value `20` means (more or less) that a new undo step\n * is created every 20 characters are inserted or deleted.\n *\n * @member {Number} [module:typing/typing~TypingConfig#undoStep=20]\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor.data, 'ready', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n/**\n * Array of loaded plugins.\n *\n * @typedef {Array.<module:core/plugin~PluginInterface>} module:core/plugin~LoadedPlugins\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/command\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor commands.\n *\n * Commands are the main way to manipulate editor contents and state. They are mostly used by UI elements (or by other\n * commands) to make changes in the model. Commands are available in every part of code that has access to\n * the {@link module:core/editor/editor~Editor editor} instance.\n *\n * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n *\n * By default commands are disabled when the editor is in {@link module:core/editor/editor~Editor#isReadOnly read-only} mode.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Command {\n\t/**\n\t * Creates a new `Command` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor Editor on which this command will be used.\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor on which this command will be used.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * The value of the command. A concrete command class should define what it represents for it.\n\t\t *\n\t\t * For example, the `'bold'` command's value indicates whether the selection starts in a bolded text.\n\t\t * And the value of the `'link'` command may be an object with links details.\n\t\t *\n\t\t * It is possible for a command to have no value (e.g. for stateless actions such as `'imageUpload'`).\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member #value\n\t\t */\n\t\tthis.set( 'value', undefined );\n\n\t\t/**\n\t\t * Flag indicating whether a command is enabled or disabled.\n\t\t * A disabled command will do nothing when executed.\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * It is possible to disable a command from \"outside\". For instance, in your integration you may want to disable\n\t\t * a certain set of commands for the time being. To do that, you can use the fact that `isEnabled` is observable\n\t\t * and it fires the `set:isEnabled` event every time anyone tries to modify its value:\n\t\t *\n\t\t *\t\tfunction disableCommand( cmd ) {\n\t\t *\t\t\tcmd.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t *\n\t\t *\t\t\tcmd.isEnabled = false;\n\t\t *\n\t\t *\t\t\t// Make it possible to enable the command again.\n\t\t *\t\t\treturn () => {\n\t\t *\t\t\t\tcmd.off( 'set:isEnabled', forceDisable );\n\t\t *\t\t\t\tcmd.refresh();\n\t\t *\t\t\t};\n\t\t *\n\t\t *\t\t\tfunction forceDisable( evt ) {\n\t\t *\t\t\t\tevt.return = false;\n\t\t *\t\t\t\tevt.stop();\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\n\t\t *\t\t// Usage:\n\t\t *\n\t\t *\t\t// Disabling the command.\n\t\t *\t\tconst enableBold = disableCommand( editor.commands.get( 'bold' ) );\n\t\t *\n\t\t *\t\t// Enabling the command again.\n\t\t *\t\tenableBold();\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\t\tthis.set( 'isEnabled', false );\n\n\t\t/**\n\t\t * Holds identifiers for {@link #forceDisabled} mechanism.\n\t\t *\n\t\t * @type {Set.<String>}\n\t\t * @private\n\t\t */\n\t\tthis._disableStack = new Set();\n\n\t\tthis.decorate( 'execute' );\n\n\t\t// By default every command is refreshed when changes are applied to the model.\n\t\tthis.listenTo( this.editor.model.document, 'change', () => {\n\t\t\tthis.refresh();\n\t\t} );\n\n\t\tthis.on( 'execute', evt => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// By default commands are disabled when the editor is in read-only mode.\n\t\tthis.listenTo( editor, 'change:isReadOnly', ( evt, name, value ) => {\n\t\t\tif ( value ) {\n\t\t\t\tthis.forceDisabled( 'readOnlyMode' );\n\t\t\t} else {\n\t\t\t\tthis.clearForceDisabled( 'readOnlyMode' );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties\n\t * in this method.\n\t *\n\t * This method is automatically called when\n\t * {@link module:engine/model/document~Document#event:change any changes are applied to the document}.\n\t */\n\trefresh() {\n\t\tthis.isEnabled = true;\n\t}\n\n\t/**\n\t * Disables the command.\n\t *\n\t * Command may be disabled by multiple features or algorithms (at once). When disabling a command, unique id should be passed\n\t * (e.g. feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the command.\n\t * The command becomes enabled only after all features {@link #clearForceDisabled enabled it back}.\n\t *\n\t * Disabling and enabling a command:\n\t *\n\t *\t\tcommand.isEnabled; // -> true\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Command disabled by multiple features:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'OtherFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'OtherFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Multiple disabling with the same identifier is redundant:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * **Note:** some commands or algorithms may have more complex logic when it comes to enabling or disabling certain commands,\n\t * so the command might be still disabled after {@link #clearForceDisabled} was used.\n\t *\n\t * @param {String} id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the command.\n\t */\n\tforceDisabled( id ) {\n\t\tthis._disableStack.add( id );\n\n\t\tif ( this._disableStack.size == 1 ) {\n\t\t\tthis.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * Clears forced disable previously set through {@link #clearForceDisabled}. See {@link #clearForceDisabled}.\n\t *\n\t * @param {String} id Unique identifier, equal to the one passed in {@link #forceDisabled} call.\n\t */\n\tclearForceDisabled( id ) {\n\t\tthis._disableStack.delete( id );\n\n\t\tif ( this._disableStack.size == 0 ) {\n\t\t\tthis.off( 'set:isEnabled', forceDisable );\n\t\t\tthis.refresh();\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`}\n\t * to the command.\n\t *\n\t * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`).\n\t * This behavior is implemented by a high priority listener to the {@link #event:execute} event.\n\t *\n\t * In order to see how to disable a command from \"outside\" see the {@link #isEnabled} documentation.\n\t *\n\t * @fires execute\n\t */\n\texecute() {}\n\n\t/**\n\t * Destroys the command.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Event fired by the {@link #execute} method. The command action is a listener to this event so it's\n\t * possible to change/cancel the behavior of the command by listening to this event.\n\t *\n\t * See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples.\n\t *\n\t * **Note:** This event is fired even if command is disabled. However, it is automatically blocked\n\t * by a high priority listener in order to prevent command execution.\n\t *\n\t * @event execute\n\t */\n}\n\nmix( Command, ObservableMixin );\n\n// Helper function that forces command to be disabled.\nfunction forceDisable( evt ) {\n\tevt.return = false;\n\tevt.stop();\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/model/operation/nooperation\n */\n\nimport Operation from './operation';\n\n/**\n * Operation which is doing nothing (\"empty operation\", \"do-nothing operation\", \"noop\"). This is an operation,\n * which when executed does not change the tree model. It still has some parameters defined for transformation purposes.\n *\n * In most cases this operation is a result of transforming operations. When transformation returns\n * {@link module:engine/model/operation/nooperation~NoOperation} it means that changes done by the transformed operation\n * have already been applied.\n *\n * @extends module:engine/model/operation/operation~Operation\n */\nexport default class NoOperation extends Operation {\n\tget type() {\n\t\treturn 'noop';\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns {module:engine/model/operation/nooperation~NoOperation} Clone of this operation.\n\t */\n\tclone() {\n\t\treturn new NoOperation( this.baseVersion );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t *\n\t * @returns {module:engine/model/operation/nooperation~NoOperation}\n\t */\n\tgetReversed() {\n\t\treturn new NoOperation( this.baseVersion + 1 );\n\t}\n\n\t_execute() {\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get className() {\n\t\treturn 'NoOperation';\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\nimport InsertOperation from './insertoperation';\nimport AttributeOperation from './attributeoperation';\nimport RenameOperation from './renameoperation';\nimport MarkerOperation from './markeroperation';\nimport MoveOperation from './moveoperation';\nimport RootAttributeOperation from './rootattributeoperation';\nimport MergeOperation from './mergeoperation';\nimport SplitOperation from './splitoperation';\nimport NoOperation from './nooperation';\nimport Range from '../range';\nimport Position from '../position';\n\nimport compareArrays from '@ckeditor/ckeditor5-utils/src/comparearrays';\nimport log from '@ckeditor/ckeditor5-utils/src/log';\n\nconst transformations = new Map();\n\n/**\n * @module engine/model/operation/transform\n */\n\n/**\n * Sets a transformation function to be be used to transform instances of class `OperationA` by instances of class `OperationB`.\n *\n * The `transformationFunction` is passed three parameters:\n *\n * * `a` - operation to be transformed, an instance of `OperationA`,\n * * `b` - operation to be transformed by, an instance of `OperationB`,\n * * {@link module:engine/model/operation/transform~TransformationContext `context`} - object with additional information about\n * transformation context.\n *\n * The `transformationFunction` should return transformation result, which is an array with one or multiple\n * {@link module:engine/model/operation/operation~Operation operation} instances.\n *\n * @protected\n * @param {Function} OperationA\n * @param {Function} OperationB\n * @param {Function} transformationFunction Function to use for transforming.\n */\nfunction setTransformation( OperationA, OperationB, transformationFunction ) {\n\tlet aGroup = transformations.get( OperationA );\n\n\tif ( !aGroup ) {\n\t\taGroup = new Map();\n\t\ttransformations.set( OperationA, aGroup );\n\t}\n\n\taGroup.set( OperationB, transformationFunction );\n}\n\n/**\n * Returns a previously set transformation function for transforming an instance of `OperationA` by an instance of `OperationB`.\n *\n * If no transformation was set for given pair of operations, {@link module:engine/model/operation/transform~noUpdateTransformation}\n * is returned. This means that if no transformation was set, the `OperationA` instance will not change when transformed\n * by the `OperationB` instance.\n *\n * @private\n * @param {Function} OperationA\n * @param {Function} OperationB\n * @returns {Function} Function set to transform an instance of `OperationA` by an instance of `OperationB`.\n */\nfunction getTransformation( OperationA, OperationB ) {\n\tconst aGroup = transformations.get( OperationA );\n\n\tif ( aGroup && aGroup.has( OperationB ) ) {\n\t\treturn aGroup.get( OperationB );\n\t}\n\n\treturn noUpdateTransformation;\n}\n\n/**\n * A transformation function that only clones operation to transform, without changing it.\n *\n * @private\n * @param {module:engine/model/operation/operation~Operation} a Operation to transform.\n * @returns {Array.<module:engine/model/operation/operation~Operation>}\n */\nfunction noUpdateTransformation( a ) {\n\treturn [ a ];\n}\n\n/**\n * Transforms operation `a` by operation `b`.\n *\n * @param {module:engine/model/operation/operation~Operation} a Operation to be transformed.\n * @param {module:engine/model/operation/operation~Operation} b Operation to transform by.\n * @param {module:engine/model/operation/transform~TransformationContext} context Transformation context for this transformation.\n * @returns {Array.<module:engine/model/operation/operation~Operation>} Transformation result.\n */\nexport function transform( a, b, context = {} ) {\n\tconst transformationFunction = getTransformation( a.constructor, b.constructor );\n\n\ttry {\n\t\ta = a.clone();\n\n\t\treturn transformationFunction( a, b, context );\n\t} catch ( e ) {\n\t\tlog.error( 'Error during operation transformation!', e.message );\n\t\tlog.error( 'Transformed operation', a );\n\t\tlog.error( 'Operation transformed by', b );\n\t\tlog.error( 'context.aIsStrong', context.aIsStrong );\n\t\tlog.error( 'context.aWasUndone', context.aWasUndone );\n\t\tlog.error( 'context.bWasUndone', context.bWasUndone );\n\t\tlog.error( 'context.abRelation', context.abRelation );\n\t\tlog.error( 'context.baRelation', context.baRelation );\n\n\t\tthrow e;\n\t}\n}\n\n/**\n * Performs a transformation of two sets of operations - `operationsA` and `operationsB`. The transformation is two-way -\n * both transformed `operationsA` and transformed `operationsB` are returned.\n *\n * Note, that the first operation in each set should base on the same document state (\n * {@link module:engine/model/document~Document#version document version}).\n *\n * It is assumed that `operationsA` are \"more important\" during conflict resolution between two operations.\n *\n * New copies of both passed arrays and operations inside them are returned. Passed arguments are not altered.\n *\n * Base versions of the transformed operations sets are updated accordingly. For example, assume that base versions are `4`\n * and there are `3` operations in `operationsA` and `5` operations in `operationsB`. Then:\n *\n * * transformed `operationsA` will start from base version `9` (`4` base version + `5` operations B),\n * * transformed `operationsB` will start from base version `7` (`4` base version + `3` operations A).\n *\n * If no operation was broken into two during transformation, then both sets will end up with an operation that bases on version `11`:\n *\n * * transformed `operationsA` start from `9` and there are `3` of them, so the last will have `baseVersion` equal to `11`,\n * * transformed `operationsB` start from `7` and there are `5` of them, so the last will have `baseVersion` equal to `11`.\n *\n * @param {Array.<module:engine/model/operation/operation~Operation>} operationsA\n * @param {Array.<module:engine/model/operation/operation~Operation>} operationsB\n * @param {Object} options Additional transformation options.\n * @param {module:engine/model/document~Document|null} options.document Document which the operations change.\n * @param {Boolean} [options.useRelations=false] Whether during transformation relations should be used (used during undo for\n * better conflict resolution).\n * @param {Boolean} [options.padWithNoOps=false] Whether additional {@link module:engine/model/operation/nooperation~NoOperation}s\n * should be added to the transformation results to force the same last base version for both transformed sets (in case\n * if some operations got broken into multiple operations during transformation).\n * @returns {Object} Transformation result.\n * @returns {Array.<module:engine/model/operation/operation~Operation>} return.operationsA Transformed `operationsA`.\n * @returns {Array.<module:engine/model/operation/operation~Operation>} return.operationsB Transformed `operationsB`.\n */\nexport function transformSets( operationsA, operationsB, options ) {\n\t// Create new arrays so the originally passed arguments are not changed.\n\t// No need to clone operations, they are cloned as they are transformed.\n\toperationsA = operationsA.slice();\n\toperationsB = operationsB.slice();\n\n\t// If one of sets is empty there is simply nothing to transform, so return sets as they are.\n\tif ( operationsA.length == 0 || operationsB.length == 0 ) {\n\t\treturn { operationsA, operationsB };\n\t}\n\t//\n\t// Following is a description of transformation process:\n\t//\n\t// There are `operationsA` and `operationsB` to be transformed, both by both.\n\t//\n\t// So, suppose we have sets of two operations each: `operationsA` = `[ a1, a2 ]`, `operationsB` = `[ b1, b2 ]`.\n\t//\n\t// Remember, that we can only transform operations that base on the same context. We assert that `a1` and `b1` base on\n\t// the same context and we transform them. Then, we get `a1'` and `b1'`. `a2` bases on a context with `a1` -- `a2`\n\t// is an operation that followed `a1`. Similarly, `b2` bases on a context with `b1`.\n\t//\n\t// However, since `a1'` is a result of transformation by `b1`, `a1'` now also has a context with `b1`. This means that\n\t// we can safely transform `a1'` by `b2`. As we finish transforming `a1`, we also transformed all `operationsB`.\n\t// All `operationsB` also have context including `a1`. Now, we can properly transform `a2` by those operations.\n\t//\n\t// The transformation process can be visualized on a transformation diagram (\"diamond diagram\"):\n\t//\n\t// [the initial state]\n\t// [common for a1 and b1]\n\t//\n\t// *\n\t// / \\\n\t// / \\\n\t// b1 a1\n\t// / \\\n\t// / \\\n\t// * *\n\t// / \\ / \\\n\t// / \\ / \\\n\t// b2 a1' b1' a2\n\t// / \\ / \\\n\t// / \\ / \\\n\t// * * *\n\t// \\ / \\ /\n\t// \\ / \\ /\n\t// a1'' b2' a2' b1''\n\t// \\ / \\ /\n\t// \\ / \\ /\n\t// * *\n\t// \\ /\n\t// \\ /\n\t// a2'' b2''\n\t// \\ /\n\t// \\ /\n\t// *\n\t//\n\t// [the final state]\n\t//\n\t// The final state can be reached from the initial state by applying `a1`, `a2`, `b1''` and `b2''`, as well as by\n\t// applying `b1`, `b2`, `a1''`, `a2''`. Note how the operations get to a proper common state before each pair is\n\t// transformed.\n\t//\n\t// Another thing to consider is that an operation during transformation can be broken into multiple operations.\n\t// Suppose that `a1` * `b1` = `[ a11', a12' ]` (instead of `a1'` that we considered previously).\n\t//\n\t// In that case, we leave `a12'` for later and we continue transforming `a11'` until it is transformed by all `operationsB`\n\t// (in our case it is just `b2`). At this point, `b1` is transformed by \"whole\" `a1`, while `b2` is only transformed\n\t// by `a11'`. Similarly, `a12'` is only transformed by `b1`. This leads to a conclusion that we need to start transforming `a12'`\n\t// from the moment just after it was broken. So, `a12'` is transformed by `b2`. Now, \"the whole\" `a1` is transformed\n\t// by `operationsB`, while all `operationsB` are transformed by \"the whole\" `a1`. This means that we can continue with\n\t// following `operationsA` (in our case it is just `a2`).\n\t//\n\t// Of course, also `operationsB` can be broken. However, since we focus on transforming operation `a` to the end,\n\t// the only thing to do is to store both pieces of operation `b`, so that the next transformed operation `a` will\n\t// be transformed by both of them.\n\t//\n\t// *\n\t// / \\\n\t// / \\\n\t// / \\\n\t// b1 a1\n\t// / \\\n\t// / \\\n\t// / \\\n\t// * *\n\t// / \\ / \\\n\t// / a11' / \\\n\t// / \\ / \\\n\t// b2 * b1' a2\n\t// / / \\ / \\\n\t// / / a12' / \\\n\t// / / \\ / \\\n\t// * b2' * *\n\t// \\ / / \\ /\n\t// a11'' / b21'' \\ /\n\t// \\ / / \\ /\n\t// * * a2' b1''\n\t// \\ / \\ \\ /\n\t// a12'' b22''\\ \\ /\n\t// \\ / \\ \\ /\n\t// * a2'' *\n\t// \\ \\ /\n\t// \\ \\ b21'''\n\t// \\ \\ /\n\t// a2''' *\n\t// \\ /\n\t// \\ b22'''\n\t// \\ /\n\t// *\n\t//\n\t// Note, how `a1` is broken and transformed into `a11'` and `a12'`, while `b2'` got broken and transformed into `b21''` and `b22''`.\n\t//\n\t// Having all that on mind, here is an outline for the transformation process algorithm:\n\t//\n\t// 1. We have `operationsA` and `operationsB` array, which we dynamically update as the transformation process goes.\n\t//\n\t// 2. We take next (or first) operation from `operationsA` and check from which operation `b` we need to start transforming it.\n\t// All original `operationsA` are set to be transformed starting from the first operation `b`.\n\t//\n\t// 3. We take operations from `operationsB`, one by one, starting from the correct one, and transform operation `a`\n\t// by operation `b` (and vice versa). We update `operationsA` and `operationsB` by replacing the original operations\n\t// with the transformation results.\n\t//\n\t// 4. If operation is broken into multiple operations, we save all the new operations in the place of the\n\t// original operation.\n\t//\n\t// 5. Additionally, if operation `a` was broken, for the \"new\" operation, we remember from which operation `b` it should\n\t// be transformed by.\n\t//\n\t// 6. We continue transforming \"current\" operation `a` until it is transformed by all `operationsB`. Then, go to 2.\n\t// unless the last operation `a` was transformed.\n\t//\n\t// The actual implementation of the above algorithm is slightly different, as only one loop (while) is used.\n\t// The difference is that we have \"current\" `a` operation to transform and we store the index of the next `b` operation\n\t// to transform by. Each loop operates on two indexes then: index pointing to currently processed `a` operation and\n\t// index pointing to next `b` operation. Each loop is just one `a * b` + `b * a` transformation. After each loop\n\t// operation `b` index is updated. If all `b` operations were visited for the current `a` operation, we change\n\t// current `a` operation index to the next one.\n\t//\n\n\t// For each operation `a`, keeps information what is the index in `operationsB` from which the transformation should start.\n\tconst nextTransformIndex = new WeakMap();\n\n\t// For all the original `operationsA`, set that they should be transformed starting from the first of `operationsB`.\n\tfor ( const op of operationsA ) {\n\t\tnextTransformIndex.set( op, 0 );\n\t}\n\n\t// Additional data that is used for some postprocessing after the main transformation process is done.\n\tconst data = {\n\t\tnextBaseVersionA: operationsA[ operationsA.length - 1 ].baseVersion + 1,\n\t\tnextBaseVersionB: operationsB[ operationsB.length - 1 ].baseVersion + 1,\n\t\toriginalOperationsACount: operationsA.length,\n\t\toriginalOperationsBCount: operationsB.length\n\t};\n\n\tconst contextFactory = new ContextFactory( options.document, options.useRelations, options.forceWeakRemove );\n\tcontextFactory.setOriginalOperations( operationsA );\n\tcontextFactory.setOriginalOperations( operationsB );\n\n\t// Index of currently transformed operation `a`.\n\tlet i = 0;\n\n\t// While not all `operationsA` are transformed...\n\twhile ( i < operationsA.length ) {\n\t\t// Get \"current\" operation `a`.\n\t\tconst opA = operationsA[ i ];\n\n\t\t// For the \"current\" operation `a`, get the index of the next operation `b` to transform by.\n\t\tconst indexB = nextTransformIndex.get( opA );\n\n\t\t// If operation `a` was already transformed by every operation `b`, change \"current\" operation `a` to the next one.\n\t\tif ( indexB == operationsB.length ) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst opB = operationsB[ indexB ];\n\n\t\t// Transform `a` by `b` and `b` by `a`.\n\t\tconst newOpsA = transform( opA, opB, contextFactory.getContext( opA, opB, true ) );\n\t\tconst newOpsB = transform( opB, opA, contextFactory.getContext( opB, opA, false ) );\n\t\t// As a result we get one or more `newOpsA` and one or more `newOpsB` operations.\n\n\t\t// Update contextual information about operations.\n\t\tcontextFactory.updateRelation( opA, opB );\n\n\t\tcontextFactory.setOriginalOperations( newOpsA, opA );\n\t\tcontextFactory.setOriginalOperations( newOpsB, opB );\n\n\t\t// For new `a` operations, update their index of the next operation `b` to transform them by.\n\t\t//\n\t\t// This is needed even if there was only one result (`a` was not broken) because that information is used\n\t\t// at the beginning of this loop every time.\n\t\tfor ( const newOpA of newOpsA ) {\n\t\t\t// Acknowledge, that operation `b` also might be broken into multiple operations.\n\t\t\t//\n\t\t\t// This is why we raise `indexB` not just by 1. If `newOpsB` are multiple operations, they will be\n\t\t\t// spliced in the place of `opB`. So we need to change `transformBy` accordingly, so that an operation won't\n\t\t\t// be transformed by the same operation (part of it) again.\n\t\t\tnextTransformIndex.set( newOpA, indexB + newOpsB.length );\n\t\t}\n\n\t\t// Update `operationsA` and `operationsB` with the transformed versions.\n\t\toperationsA.splice( i, 1, ...newOpsA );\n\t\toperationsB.splice( indexB, 1, ...newOpsB );\n\t}\n\n\tif ( options.padWithNoOps ) {\n\t\t// If no-operations padding is enabled, count how many extra `a` and `b` operations were generated.\n\t\tconst brokenOperationsACount = operationsA.length - data.originalOperationsACount;\n\t\tconst brokenOperationsBCount = operationsB.length - data.originalOperationsBCount;\n\n\t\t// Then, if that number is not the same, pad `operationsA` or `operationsB` with correct number of no-ops so\n\t\t// that the base versions are equalled.\n\t\t//\n\t\t// Note that only one array will be updated, as only one of those subtractions can be greater than zero.\n\t\tpadWithNoOps( operationsA, brokenOperationsBCount - brokenOperationsACount );\n\t\tpadWithNoOps( operationsB, brokenOperationsACount - brokenOperationsBCount );\n\t}\n\n\t// Finally, update base versions of transformed operations.\n\tupdateBaseVersions( operationsA, data.nextBaseVersionB );\n\tupdateBaseVersions( operationsB, data.nextBaseVersionA );\n\n\treturn { operationsA, operationsB };\n}\n\n// Gathers additional data about operations processed during transformation. Can be used to obtain contextual information\n// about two operations that are about to be transformed. This contextual information can be used for better conflict resolution.\nclass ContextFactory {\n\t// Creates `ContextFactory` instance.\n\t//\n\t// @param {module:engine/model/document~Document} document Document which the operations change.\n\t// @param {Boolean} useRelations Whether during transformation relations should be used (used during undo for\n\t// better conflict resolution).\n\t// @param {Boolean} [forceWeakRemove=false] If set to `false`, remove operation will be always stronger than move operation,\n\t// so the removed nodes won't end up back in the document root. When set to `true`, context data will be used.\n\tconstructor( document, useRelations, forceWeakRemove = false ) {\n\t\t// `model.History` instance which information about undone operations will be taken from.\n\t\tthis._history = document.history;\n\n\t\t// Whether additional context should be used.\n\t\tthis._useRelations = useRelations;\n\n\t\tthis._forceWeakRemove = !!forceWeakRemove;\n\n\t\t// For each operation that is created during transformation process, we keep a reference to the original operation\n\t\t// which it comes from. The original operation works as a kind of \"identifier\". Every contextual information\n\t\t// gathered during transformation that we want to save for given operation, is actually saved for the original operation.\n\t\t// This way no matter if operation `a` is cloned, then transformed, even breaks, we still have access to the previously\n\t\t// gathered data through original operation reference.\n\t\tthis._originalOperations = new Map();\n\n\t\t// Relations is a double-map structure (maps in map) where for two operations we store how those operations were related\n\t\t// to each other. Those relations are evaluated during transformation process. For every transformated pair of operations\n\t\t// we keep relations between them.\n\t\tthis._relations = new Map();\n\t}\n\n\t// Sets \"original operation\" for given operations.\n\t//\n\t// During transformation process, operations are cloned, then changed, then processed again, sometimes broken into two\n\t// or multiple operations. When gathering additional data it is important that all operations can be somehow linked\n\t// so a cloned and transformed \"version\" still kept track of the data assigned earlier to it.\n\t//\n\t// The original operation object will be used as such an universal linking id. Throughout the transformation process\n\t// all cloned operations will refer to \"the original operation\" when storing and reading additional data.\n\t//\n\t// If `takeFrom` is not set, each operation from `operations` array will be assigned itself as \"the original operation\".\n\t// This should be used as an initialization step.\n\t//\n\t// If `takeFrom` is set, each operation from `operations` will be assigned the same original operation as assigned\n\t// for `takeFrom` operation. This should be used to update original operations. It should be used in a way that\n\t// `operations` are the result of `takeFrom` transformation to ensure proper \"original operation propagation\".\n\t//\n\t// @param {Array.<module:engine/model/operation/operation~Operation>} operations\n\t// @param {module:engine/model/operation/operation~Operation|null} [takeFrom=null]\n\tsetOriginalOperations( operations, takeFrom = null ) {\n\t\tconst originalOperation = takeFrom ? this._originalOperations.get( takeFrom ) : null;\n\n\t\tfor ( const operation of operations ) {\n\t\t\tthis._originalOperations.set( operation, originalOperation || operation );\n\t\t}\n\t}\n\n\t// Saves a relation between operations `opA` and `opB`.\n\t//\n\t// Relations are then later used to help solve conflicts when operations are transformed.\n\t//\n\t// @param {module:engine/model/operation/operation~Operation} opA\n\t// @param {module:engine/model/operation/operation~Operation} opB\n\tupdateRelation( opA, opB ) {\n\t\t// The use of relations is described in a bigger detail in transformation functions.\n\t\t//\n\t\t// In brief, this function, for specified pairs of operation types, checks how positions defined in those operations relate.\n\t\t// Then those relations are saved. For example, for two move operations, it is saved if one of those operations target\n\t\t// position is before the other operation source position. This kind of information gives contextual information when\n\t\t// transformation is used during undo. Similar checks are done for other pairs of operations.\n\t\t//\n\t\tswitch ( opA.constructor ) {\n\t\t\tcase MoveOperation: {\n\t\t\t\tswitch ( opB.constructor ) {\n\t\t\t\t\tcase MergeOperation: {\n\t\t\t\t\t\tif ( opA.targetPosition.isEqual( opB.sourcePosition ) || opB.movedRange.containsPosition( opA.targetPosition ) ) {\n\t\t\t\t\t\t\tthis._setRelation( opA, opB, 'insertAtSource' );\n\t\t\t\t\t\t} else if ( opA.targetPosition.isEqual( opB.deletionPosition ) ) {\n\t\t\t\t\t\t\tthis._setRelation( opA, opB, 'insertBetween' );\n\t\t\t\t\t\t} else if ( opA.targetPosition.isAfter( opB.sourcePosition ) ) {\n\t\t\t\t\t\t\tthis._setRelation( opA, opB, 'moveTargetAfter' );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase MoveOperation: {\n\t\t\t\t\t\tif ( opA.targetPosition.isEqual( opB.sourcePosition ) || opA.targetPosition.isBefore( opB.sourcePosition ) ) {\n\t\t\t\t\t\t\tthis._setRelation( opA, opB, 'insertBefore' );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis._setRelation( opA, opB, 'insertAfter' );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase SplitOperation: {\n\t\t\t\tswitch ( opB.constructor ) {\n\t\t\t\t\tcase MergeOperation: {\n\t\t\t\t\t\tif ( opA.splitPosition.isBefore( opB.sourcePosition ) ) {\n\t\t\t\t\t\t\tthis._setRelation( opA, opB, 'splitBefore' );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase MoveOperation: {\n\t\t\t\t\t\tif ( opA.splitPosition.isEqual( opB.sourcePosition ) || opA.splitPosition.isBefore( opB.sourcePosition ) ) {\n\t\t\t\t\t\t\tthis._setRelation( opA, opB, 'splitBefore' );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MergeOperation: {\n\t\t\t\tswitch ( opB.constructor ) {\n\t\t\t\t\tcase MergeOperation: {\n\t\t\t\t\t\tif ( !opA.targetPosition.isEqual( opB.sourcePosition ) ) {\n\t\t\t\t\t\t\tthis._setRelation( opA, opB, 'mergeTargetNotMoved' );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( opA.sourcePosition.isEqual( opB.targetPosition ) ) {\n\t\t\t\t\t\t\tthis._setRelation( opA, opB, 'mergeSourceNotMoved' );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( opA.sourcePosition.isEqual( opB.sourcePosition ) ) {\n\t\t\t\t\t\t\tthis._setRelation( opA, opB, 'mergeSameElement' );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase SplitOperation: {\n\t\t\t\t\t\tif ( opA.sourcePosition.isEqual( opB.splitPosition ) ) {\n\t\t\t\t\t\t\tthis._setRelation( opA, opB, 'splitAtSource' );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarkerOperation: {\n\t\t\t\tconst markerRange = opA.newRange;\n\n\t\t\t\tif ( !markerRange ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tswitch ( opB.constructor ) {\n\t\t\t\t\tcase MoveOperation: {\n\t\t\t\t\t\tconst movedRange = Range._createFromPositionAndShift( opB.sourcePosition, opB.howMany );\n\n\t\t\t\t\t\tconst affectedLeft = movedRange.containsPosition( markerRange.start ) ||\n\t\t\t\t\t\t\tmovedRange.start.isEqual( markerRange.start );\n\n\t\t\t\t\t\tconst affectedRight = movedRange.containsPosition( markerRange.end ) ||\n\t\t\t\t\t\t\tmovedRange.end.isEqual( markerRange.end );\n\n\t\t\t\t\t\tif ( ( affectedLeft || affectedRight ) && !movedRange.containsRange( markerRange ) ) {\n\t\t\t\t\t\t\tthis._setRelation( opA, opB, {\n\t\t\t\t\t\t\t\tside: affectedLeft ? 'left' : 'right',\n\t\t\t\t\t\t\t\tpath: affectedLeft ? markerRange.start.path.slice() : markerRange.end.path.slice()\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase MergeOperation: {\n\t\t\t\t\t\tconst wasInLeftElement = markerRange.start.isEqual( opB.targetPosition );\n\t\t\t\t\t\tconst wasStartBeforeMergedElement = markerRange.start.isEqual( opB.deletionPosition );\n\t\t\t\t\t\tconst wasEndBeforeMergedElement = markerRange.end.isEqual( opB.deletionPosition );\n\t\t\t\t\t\tconst wasInRightElement = markerRange.end.isEqual( opB.sourcePosition );\n\n\t\t\t\t\t\tif ( wasInLeftElement || wasStartBeforeMergedElement || wasEndBeforeMergedElement || wasInRightElement ) {\n\t\t\t\t\t\t\tthis._setRelation( opA, opB, {\n\t\t\t\t\t\t\t\twasInLeftElement,\n\t\t\t\t\t\t\t\twasStartBeforeMergedElement,\n\t\t\t\t\t\t\t\twasEndBeforeMergedElement,\n\t\t\t\t\t\t\t\twasInRightElement\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Evaluates and returns contextual information about two given operations `opA` and `opB` which are about to be transformed.\n\t//\n\t// @param {module:engine/model/operation/operation~Operation} opA\n\t// @param {module:engine/model/operation/operation~Operation} opB\n\t// @returns {module:engine/model/operation/transform~TransformationContext}\n\tgetContext( opA, opB, aIsStrong ) {\n\t\treturn {\n\t\t\taIsStrong,\n\t\t\taWasUndone: this._wasUndone( opA ),\n\t\t\tbWasUndone: this._wasUndone( opB ),\n\t\t\tabRelation: this._useRelations ? this._getRelation( opA, opB ) : null,\n\t\t\tbaRelation: this._useRelations ? this._getRelation( opB, opA ) : null,\n\t\t\tforceWeakRemove: this._forceWeakRemove\n\t\t};\n\t}\n\n\t// Returns whether given operation `op` has already been undone.\n\t//\n\t// Information whether an operation was undone gives more context when making a decision when two operations are in conflict.\n\t//\n\t// @param {module:engine/model/operation/operation~Operation} op\n\t// @returns {Boolean}\n\t_wasUndone( op ) {\n\t\t// For `op`, get its original operation. After all, if `op` is a clone (or even transformed clone) of another\n\t\t// operation, literally `op` couldn't be undone. It was just generated. If anything, it was the operation it origins\n\t\t// from which was undone. So get that original operation.\n\t\tconst originalOp = this._originalOperations.get( op );\n\n\t\t// And check with the document if the original operation was undone.\n\t\treturn originalOp.wasUndone || this._history.isUndoneOperation( originalOp );\n\t}\n\n\t// Returns a relation between `opA` and an operation which is undone by `opB`. This can be `String` value if a relation\n\t// was set earlier or `null` if there was no relation between those operations.\n\t//\n\t// This is a little tricky to understand, so let's compare it to `ContextFactory#_wasUndone`.\n\t//\n\t// When `wasUndone( opB )` is used, we check if the `opB` has already been undone. It is obvious, that the\n\t// undoing operation must happen after the undone operation. So, essentially, we have `opB`, we take document history,\n\t// we look forward in the future and ask if in that future `opB` was undone.\n\t//\n\t// Relations is a backward process to `wasUndone()`.\n\t//\n\t// Long story short - using relations is asking what happened in the past. Looking back. This time we have an undoing\n\t// operation `opB` which has undone some other operation. When there is a transformation `opA` x `opB` and there is\n\t// a conflict to solve and `opB` is an undoing operation, we can look back in the history and see what was a relation\n\t// between `opA` and the operation which `opB` undone. Basing on that relation from the past, we can now make\n\t// a better decision when resolving a conflict between two operations, because we know more about the context of\n\t// those two operations.\n\t//\n\t// This is why this function does not return a relation directly between `opA` and `opB` because we need to look\n\t// back to search for a meaningful contextual information.\n\t//\n\t// @param {module:engine/model/operation/operation~Operation} opA\n\t// @param {module:engine/model/operation/operation~Operation} opB\n\t// @returns {String|null}\n\t_getRelation( opA, opB ) {\n\t\t// Get the original operation. Similarly as in `wasUndone()` it is used as an universal identifier for stored data.\n\t\tconst origB = this._originalOperations.get( opB );\n\t\tconst undoneB = this._history.getUndoneOperation( origB );\n\n\t\t// If `opB` is not undoing any operation, there is no relation.\n\t\tif ( !undoneB ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst origA = this._originalOperations.get( opA );\n\t\tconst relationsA = this._relations.get( origA );\n\n\t\t// Get all relations for `opA`, and check if there is a relation with `opB`-undone-counterpart. If so, return it.\n\t\tif ( relationsA ) {\n\t\t\treturn relationsA.get( undoneB ) || null;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t// Helper function for `ContextFactory#updateRelations`.\n\t//\n\t// @private\n\t// @param {module:engine/model/operation/operation~Operation} opA\n\t// @param {module:engine/model/operation/operation~Operation} opB\n\t// @param {String} relation\n\t_setRelation( opA, opB, relation ) {\n\t\t// As always, setting is for original operations, not the clones/transformed operations.\n\t\tconst origA = this._originalOperations.get( opA );\n\t\tconst origB = this._originalOperations.get( opB );\n\n\t\tlet relationsA = this._relations.get( origA );\n\n\t\tif ( !relationsA ) {\n\t\t\trelationsA = new Map();\n\t\t\tthis._relations.set( origA, relationsA );\n\t\t}\n\n\t\trelationsA.set( origB, relation );\n\t}\n}\n\n/**\n * Holds additional contextual information about a transformed pair of operations (`a` and `b`). Those information\n * can be used for better conflict resolving.\n *\n * @typedef {Object} module:engine/model/operation/transform~TransformationContext\n *\n * @property {Boolean} aIsStrong Whether `a` is strong operation in this transformation, or weak.\n * @property {Boolean} aWasUndone Whether `a` operation was undone.\n * @property {Boolean} bWasUndone Whether `b` operation was undone.\n * @property {String|null} abRelation The relation between `a` operation and an operation undone by `b` operation.\n * @property {String|null} baRelation The relation between `b` operation and an operation undone by `a` operation.\n */\n\n/**\n * An utility function that updates {@link module:engine/model/operation/operation~Operation#baseVersion base versions}\n * of passed operations.\n *\n * The function simply sets `baseVersion` as a base version of the first passed operation and then increments it for\n * each following operation in `operations`.\n *\n * @private\n * @param {Array.<module:engine/model/operation/operation~Operation>} operations Operations to update.\n * @param {Number} baseVersion Base version to set for the first operation in `operations`.\n */\nfunction updateBaseVersions( operations, baseVersion ) {\n\tfor ( const operation of operations ) {\n\t\toperation.baseVersion = baseVersion++;\n\t}\n}\n\n/**\n * Adds `howMany` instances of {@link module:engine/model/operation/nooperation~NoOperation} to `operations` set.\n *\n * @private\n * @param {Array.<module:engine/model/operation/operation~Operation>} operations\n * @param {Number} howMany\n */\nfunction padWithNoOps( operations, howMany ) {\n\tfor ( let i = 0; i < howMany; i++ ) {\n\t\toperations.push( new NoOperation( 0 ) );\n\t}\n}\n\n// -----------------------\n\nsetTransformation( AttributeOperation, AttributeOperation, ( a, b, context ) => {\n\tif ( a.key === b.key ) {\n\t\t// If operations attributes are in conflict, check if their ranges intersect and manage them properly.\n\n\t\t// First, we want to apply change to the part of a range that has not been changed by the other operation.\n\t\tconst operations = a.range.getDifference( b.range ).map( range => {\n\t\t\treturn new AttributeOperation( range, a.key, a.oldValue, a.newValue, 0 );\n\t\t} );\n\n\t\t// Then we take care of the common part of ranges.\n\t\tconst common = a.range.getIntersection( b.range );\n\n\t\tif ( common ) {\n\t\t\t// If this operation is more important, we also want to apply change to the part of the\n\t\t\t// original range that has already been changed by the other operation. Since that range\n\t\t\t// got changed we also have to update `oldValue`.\n\t\t\tif ( context.aIsStrong ) {\n\t\t\t\toperations.push( new AttributeOperation( common, b.key, b.newValue, a.newValue, 0 ) );\n\t\t\t}\n\t\t}\n\n\t\tif ( operations.length == 0 ) {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t}\n\n\t\treturn operations;\n\t} else {\n\t\t// If operations don't conflict, simply return an array containing just a clone of this operation.\n\t\treturn [ a ];\n\t}\n} );\n\nsetTransformation( AttributeOperation, InsertOperation, ( a, b ) => {\n\t// Case 1:\n\t//\n\t// The attribute operation range includes the position where nodes were inserted.\n\t// There are two possible scenarios: the inserted nodes were text and they should receive attributes or\n\t// the inserted nodes were elements and they should not receive attributes.\n\t//\n\tif ( a.range.start.hasSameParentAs( b.position ) && a.range.containsPosition( b.position ) ) {\n\t\t// If new nodes should not receive attributes, two separated ranges will be returned.\n\t\t// Otherwise, one expanded range will be returned.\n\t\tconst range = a.range._getTransformedByInsertion( b.position, b.howMany, !b.shouldReceiveAttributes );\n\t\tconst result = range.map( r => {\n\t\t\treturn new AttributeOperation( r, a.key, a.oldValue, a.newValue, a.baseVersion );\n\t\t} );\n\n\t\tif ( b.shouldReceiveAttributes ) {\n\t\t\t// `AttributeOperation#range` includes some newly inserted text.\n\t\t\t// The operation should also change the attribute of that text. An example:\n\t\t\t//\n\t\t\t// Bold should be applied on the following range:\n\t\t\t// <p>Fo[zb]ar</p>\n\t\t\t//\n\t\t\t// In meantime, new text is typed:\n\t\t\t// <p>Fozxxbar</p>\n\t\t\t//\n\t\t\t// Bold should be applied also on the new text:\n\t\t\t// <p>Fo[zxxb]ar</p>\n\t\t\t// <p>Fo<$text bold=\"true\">zxxb</$text>ar</p>\n\t\t\t//\n\t\t\t// There is a special case to consider here to consider.\n\t\t\t//\n\t\t\t// Consider setting an attribute with multiple possible values, for example `highlight`. The inserted text might\n\t\t\t// have already an attribute value applied and the `oldValue` property of the attribute operation might be wrong:\n\t\t\t//\n\t\t\t// Attribute `highlight=\"yellow\"` should be applied on the following range:\n\t\t\t// <p>Fo[zb]ar<p>\n\t\t\t//\n\t\t\t// In meantime, character `x` with `highlight=\"red\"` is typed:\n\t\t\t// <p>Fo[z<$text highlight=\"red\">x</$text>b]ar</p>\n\t\t\t//\n\t\t\t// In this case we cannot simply apply operation changing the attribute value from `null` to `\"yellow\"` for the whole range\n\t\t\t// because that would lead to an exception (`oldValue` is incorrect for `x`).\n\t\t\t//\n\t\t\t// We also cannot break the original range as this would mess up a scenario when there are multiple following\n\t\t\t// insert operations, because then only the first inserted character is included in those ranges:\n\t\t\t// <p>Fo[z][x][b]ar</p> --> <p>Fo[z][x]x[b]ar</p> --> <p>Fo[z][x]xx[b]ar</p>\n\t\t\t//\n\t\t\t// So, the attribute range needs be expanded, no matter what attributes are set on the inserted nodes:\n\t\t\t//\n\t\t\t// <p>Fo[z<$text highlight=\"red\">x</$text>b]ar</p> <--- Change from `null` to `yellow`, throwing an exception.\n\t\t\t//\n\t\t\t// But before that operation would be applied, we will add an additional attribute operation that will change\n\t\t\t// attributes on the inserted nodes in a way which would make the original operation correct:\n\t\t\t//\n\t\t\t// <p>Fo[z{<$text highlight=\"red\">}x</$text>b]ar</p> <--- Change range `{}` from `red` to `null`.\n\t\t\t// <p>Fo[zxb]ar</p> <--- Now change from `null` to `yellow` is completely fine.\n\t\t\t//\n\n\t\t\t// Generate complementary attribute operation. Be sure to add it before the original operation.\n\t\t\tconst op = _getComplementaryAttributeOperations( b, a.key, a.oldValue );\n\n\t\t\tif ( op ) {\n\t\t\t\tresult.unshift( op );\n\t\t\t}\n\t\t}\n\n\t\t// If nodes should not receive new attribute, we are done here.\n\t\treturn result;\n\t}\n\n\t// If insert operation is not expanding the attribute operation range, simply transform the range.\n\ta.range = a.range._getTransformedByInsertion( b.position, b.howMany, false )[ 0 ];\n\n\treturn [ a ];\n} );\n\n/**\n * Helper function for `AttributeOperation` x `InsertOperation` (and reverse) transformation.\n *\n * For given `insertOperation` it checks the inserted node if it has an attribute `key` set to a value different\n * than `newValue`. If so, it generates an `AttributeOperation` which changes the value of `key` attribute to `newValue`.\n *\n * @private\n * @param {module:engine/model/operation/insertoperation~InsertOperation} insertOperation\n * @param {String} key\n * @param {*} newValue\n * @returns {module:engine/model/operation/attributeoperation~AttributeOperation|null}\n */\nfunction _getComplementaryAttributeOperations( insertOperation, key, newValue ) {\n\tconst nodes = insertOperation.nodes;\n\n\t// At the beginning we store the attribute value from the first node.\n\tconst insertValue = nodes.getNode( 0 ).getAttribute( key );\n\n\tif ( insertValue == newValue ) {\n\t\treturn null;\n\t}\n\n\tconst range = new Range( insertOperation.position, insertOperation.position.getShiftedBy( insertOperation.howMany ) );\n\n\treturn new AttributeOperation( range, key, insertValue, newValue, 0 );\n}\n\nsetTransformation( AttributeOperation, MergeOperation, ( a, b ) => {\n\tconst ranges = [];\n\n\t// Case 1:\n\t//\n\t// Attribute change on the merged element. In this case, the merged element was moved to the graveyard.\n\t// An additional attribute operation that will change the (re)moved element needs to be generated.\n\t//\n\tif ( a.range.start.hasSameParentAs( b.deletionPosition ) ) {\n\t\tif ( a.range.containsPosition( b.deletionPosition ) || a.range.start.isEqual( b.deletionPosition ) ) {\n\t\t\tranges.push( Range._createFromPositionAndShift( b.graveyardPosition, 1 ) );\n\t\t}\n\t}\n\n\tconst range = a.range._getTransformedByMergeOperation( b );\n\n\t// Do not add empty (collapsed) ranges to the result. `range` may be collapsed if it contained only the merged element.\n\tif ( !range.isCollapsed ) {\n\t\tranges.push( range );\n\t}\n\n\t// Create `AttributeOperation`s out of the ranges.\n\treturn ranges.map( range => {\n\t\treturn new AttributeOperation( range, a.key, a.oldValue, a.newValue, a.baseVersion );\n\t} );\n} );\n\nsetTransformation( AttributeOperation, MoveOperation, ( a, b ) => {\n\tconst ranges = _breakRangeByMoveOperation( a.range, b );\n\n\t// Create `AttributeOperation`s out of the ranges.\n\treturn ranges.map( range => new AttributeOperation( range, a.key, a.oldValue, a.newValue, a.baseVersion ) );\n} );\n\n// Helper function for `AttributeOperation` x `MoveOperation` transformation.\n//\n// Takes the passed `range` and transforms it by move operation `moveOp` in a specific way. Only top-level nodes of `range`\n// are considered to be in the range. If move operation moves nodes deep from inside of the range, those nodes won't\n// be included in the result. In other words, top-level nodes of the ranges from the result are exactly the same as\n// top-level nodes of the original `range`.\n//\n// This is important for `AttributeOperation` because, for its range, it changes only the top-level nodes. So we need to\n// track only how those nodes have been affected by `MoveOperation`.\n//\n// @private\n// @param {module:engine/model/range~Range} range\n// @param {module:engine/model/operation/moveoperation~MoveOperation} moveOp\n// @returns {Array.<module:engine/model/range~Range>}\nfunction _breakRangeByMoveOperation( range, moveOp ) {\n\tconst moveRange = Range._createFromPositionAndShift( moveOp.sourcePosition, moveOp.howMany );\n\n\t// We are transforming `range` (original range) by `moveRange` (range moved by move operation). As usual when it comes to\n\t// transforming a ranges, we may have a common part of the ranges and we may have a difference part (zero to two ranges).\n\tlet common = null;\n\tlet difference = [];\n\n\t// Let's compare the ranges.\n\tif ( moveRange.containsRange( range, true ) ) {\n\t\t// If the whole original range is moved, treat it whole as a common part. There's also no difference part.\n\t\tcommon = range;\n\t} else if ( range.start.hasSameParentAs( moveRange.start ) ) {\n\t\t// If the ranges are \"on the same level\" (in the same parent) then move operation may move exactly those nodes\n\t\t// that are changed by the attribute operation. In this case we get common part and difference part in the usual way.\n\t\tdifference = range.getDifference( moveRange );\n\t\tcommon = range.getIntersection( moveRange );\n\t} else {\n\t\t// In any other situation we assume that original range is different than move range, that is that move operation\n\t\t// moves other nodes that attribute operation change. Even if the moved range is deep inside in the original range.\n\t\t//\n\t\t// Note that this is different than in `.getIntersection` (we would get a common part in that case) and different\n\t\t// than `.getDifference` (we would get two ranges).\n\t\tdifference = [ range ];\n\t}\n\n\tconst result = [];\n\n\t// The default behaviour of `_getTransformedByMove` might get wrong results for difference part, though, so\n\t// we do it by hand.\n\tfor ( let diff of difference ) {\n\t\t// First, transform the range by removing moved nodes. Since this is a difference, this is safe, `null` won't be returned\n\t\t// as the range is different than the moved range.\n\t\tdiff = diff._getTransformedByDeletion( moveOp.sourcePosition, moveOp.howMany );\n\n\t\t// Transform also `targetPosition`.\n\t\tconst targetPosition = moveOp.getMovedRangeStart();\n\n\t\t// Spread the range only if moved nodes are inserted only between the top-level nodes of the `diff` range.\n\t\tconst spread = diff.start.hasSameParentAs( targetPosition );\n\n\t\t// Transform by insertion of moved nodes.\n\t\tdiff = diff._getTransformedByInsertion( targetPosition, moveOp.howMany, spread );\n\n\t\tresult.push( ...diff );\n\t}\n\n\t// Common part can be simply transformed by the move operation. This is because move operation will not target to\n\t// that common part (the operation would have to target inside its own moved range).\n\tif ( common ) {\n\t\tresult.push(\n\t\t\tcommon._getTransformedByMove( moveOp.sourcePosition, moveOp.targetPosition, moveOp.howMany, false )[ 0 ]\n\t\t);\n\t}\n\n\treturn result;\n}\n\nsetTransformation( AttributeOperation, SplitOperation, ( a, b ) => {\n\t// Case 1:\n\t//\n\t// Split node is the last node in `AttributeOperation#range`.\n\t// `AttributeOperation#range` needs to be expanded to include the new (split) node.\n\t//\n\t// Attribute `type` to be changed to `numbered` but the `listItem` is split.\n\t// <listItem type=\"bulleted\">foobar</listItem>\n\t//\n\t// After split:\n\t// <listItem type=\"bulleted\">foo</listItem><listItem type=\"bulleted\">bar</listItem>\n\t//\n\t// After attribute change:\n\t// <listItem type=\"numbered\">foo</listItem><listItem type=\"numbered\">foo</listItem>\n\t//\n\tif ( a.range.end.isEqual( b.insertionPosition ) ) {\n\t\tif ( !b.graveyardPosition ) {\n\t\t\ta.range.end.offset++;\n\t\t}\n\n\t\treturn [ a ];\n\t}\n\n\t// Case 2:\n\t//\n\t// Split position is inside `AttributeOperation#range`, at the same level, so the nodes to change are\n\t// not going to make a flat range.\n\t//\n\t// Content with range-to-change and split position:\n\t// <p>Fo[zb^a]r</p>\n\t//\n\t// After split:\n\t// <p>Fozb</p><p>ar</p>\n\t//\n\t// Make two separate ranges containing all nodes to change:\n\t// <p>Fo[zb]</p><p>[a]r</p>\n\t//\n\tif ( a.range.start.hasSameParentAs( b.splitPosition ) && a.range.containsPosition( b.splitPosition ) ) {\n\t\tconst secondPart = a.clone();\n\n\t\tsecondPart.range = new Range(\n\t\t\tb.moveTargetPosition.clone(),\n\t\t\ta.range.end._getCombined( b.splitPosition, b.moveTargetPosition )\n\t\t);\n\n\t\ta.range.end = b.splitPosition.clone();\n\t\ta.range.end.stickiness = 'toPrevious';\n\n\t\treturn [ a, secondPart ];\n\t}\n\n\t// The default case.\n\t//\n\ta.range = a.range._getTransformedBySplitOperation( b );\n\n\treturn [ a ];\n} );\n\nsetTransformation( InsertOperation, AttributeOperation, ( a, b ) => {\n\tconst result = [ a ];\n\n\t// Case 1:\n\t//\n\t// The attribute operation range includes the position where nodes were inserted.\n\t// There are two possible scenarios: the inserted nodes were text and they should receive attributes or\n\t// the inserted nodes were elements and they should not receive attributes.\n\t//\n\t// This is a mirror scenario to the one described in `AttributeOperation` x `InsertOperation` transformation,\n\t// although this case is a little less complicated. In this case we simply need to change attributes of the\n\t// inserted nodes and that's it.\n\t//\n\tif ( a.shouldReceiveAttributes && a.position.hasSameParentAs( b.range.start ) && b.range.containsPosition( a.position ) ) {\n\t\tconst op = _getComplementaryAttributeOperations( a, b.key, b.newValue );\n\n\t\tif ( op ) {\n\t\t\tresult.push( op );\n\t\t}\n\t}\n\n\t// The default case is: do nothing.\n\t// `AttributeOperation` does not change the model tree structure so `InsertOperation` does not need to be changed.\n\t//\n\treturn result;\n} );\n\nsetTransformation( InsertOperation, InsertOperation, ( a, b, context ) => {\n\t// Case 1:\n\t//\n\t// Two insert operations insert nodes at the same position. Since they are the same, it needs to be decided\n\t// what will be the order of inserted nodes. However, there is no additional information to help in that\n\t// decision. Also, when `b` will be transformed by `a`, the same order must be maintained.\n\t//\n\t// To achieve that, we will check if the operation is strong.\n\t// If it is, it won't get transformed. If it is not, it will be moved.\n\t//\n\tif ( a.position.isEqual( b.position ) && context.aIsStrong ) {\n\t\treturn [ a ];\n\t}\n\n\t// The default case.\n\t//\n\ta.position = a.position._getTransformedByInsertOperation( b );\n\n\treturn [ a ];\n} );\n\nsetTransformation( InsertOperation, MoveOperation, ( a, b ) => {\n\t// The default case.\n\t//\n\ta.position = a.position._getTransformedByMoveOperation( b );\n\n\treturn [ a ];\n} );\n\nsetTransformation( InsertOperation, SplitOperation, ( a, b ) => {\n\t// The default case.\n\t//\n\ta.position = a.position._getTransformedBySplitOperation( b );\n\n\treturn [ a ];\n} );\n\nsetTransformation( InsertOperation, MergeOperation, ( a, b ) => {\n\ta.position = a.position._getTransformedByMergeOperation( b );\n\n\treturn [ a ];\n} );\n\n// -----------------------\n\nsetTransformation( MarkerOperation, InsertOperation, ( a, b ) => {\n\tif ( a.oldRange ) {\n\t\ta.oldRange = a.oldRange._getTransformedByInsertOperation( b )[ 0 ];\n\t}\n\n\tif ( a.newRange ) {\n\t\ta.newRange = a.newRange._getTransformedByInsertOperation( b )[ 0 ];\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( MarkerOperation, MarkerOperation, ( a, b, context ) => {\n\tif ( a.name == b.name ) {\n\t\tif ( context.aIsStrong ) {\n\t\t\ta.oldRange = b.newRange ? b.newRange.clone() : null;\n\t\t} else {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t}\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( MarkerOperation, MergeOperation, ( a, b ) => {\n\tif ( a.oldRange ) {\n\t\ta.oldRange = a.oldRange._getTransformedByMergeOperation( b );\n\t}\n\n\tif ( a.newRange ) {\n\t\ta.newRange = a.newRange._getTransformedByMergeOperation( b );\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( MarkerOperation, MoveOperation, ( a, b, context ) => {\n\tif ( a.oldRange ) {\n\t\ta.oldRange = Range._createFromRanges( a.oldRange._getTransformedByMoveOperation( b ) );\n\t}\n\n\tif ( a.newRange ) {\n\t\tif ( context.abRelation ) {\n\t\t\tconst aNewRange = Range._createFromRanges( a.newRange._getTransformedByMoveOperation( b ) );\n\n\t\t\tif ( context.abRelation.side == 'left' && b.targetPosition.isEqual( a.newRange.start ) ) {\n\t\t\t\ta.newRange.start.path = context.abRelation.path;\n\t\t\t\ta.newRange.end = aNewRange.end;\n\n\t\t\t\treturn [ a ];\n\t\t\t} else if ( context.abRelation.side == 'right' && b.targetPosition.isEqual( a.newRange.end ) ) {\n\t\t\t\ta.newRange.start = aNewRange.start;\n\t\t\t\ta.newRange.end.path = context.abRelation.path;\n\n\t\t\t\treturn [ a ];\n\t\t\t}\n\t\t}\n\n\t\ta.newRange = Range._createFromRanges( a.newRange._getTransformedByMoveOperation( b ) );\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( MarkerOperation, SplitOperation, ( a, b, context ) => {\n\tif ( a.oldRange ) {\n\t\ta.oldRange = a.oldRange._getTransformedBySplitOperation( b );\n\t}\n\n\tif ( a.newRange ) {\n\t\tif ( context.abRelation ) {\n\t\t\tconst aNewRange = a.newRange._getTransformedBySplitOperation( b );\n\n\t\t\tif ( a.newRange.start.isEqual( b.splitPosition ) && context.abRelation.wasStartBeforeMergedElement ) {\n\t\t\t\ta.newRange.start = Position._createAt( b.insertionPosition );\n\t\t\t} else if ( a.newRange.start.isEqual( b.splitPosition ) && !context.abRelation.wasInLeftElement ) {\n\t\t\t\ta.newRange.start = Position._createAt( b.moveTargetPosition );\n\t\t\t}\n\n\t\t\tif ( a.newRange.end.isEqual( b.splitPosition ) && context.abRelation.wasInRightElement ) {\n\t\t\t\ta.newRange.end = Position._createAt( b.moveTargetPosition );\n\t\t\t} else if ( a.newRange.end.isEqual( b.splitPosition ) && context.abRelation.wasEndBeforeMergedElement ) {\n\t\t\t\ta.newRange.end = Position._createAt( b.insertionPosition );\n\t\t\t} else {\n\t\t\t\ta.newRange.end = aNewRange.end;\n\t\t\t}\n\n\t\t\treturn [ a ];\n\t\t}\n\n\t\ta.newRange = a.newRange._getTransformedBySplitOperation( b );\n\t}\n\n\treturn [ a ];\n} );\n\n// -----------------------\n\nsetTransformation( MergeOperation, InsertOperation, ( a, b ) => {\n\tif ( a.sourcePosition.hasSameParentAs( b.position ) ) {\n\t\ta.howMany += b.howMany;\n\t}\n\n\ta.sourcePosition = a.sourcePosition._getTransformedByInsertOperation( b );\n\ta.targetPosition = a.targetPosition._getTransformedByInsertOperation( b );\n\n\treturn [ a ];\n} );\n\nsetTransformation( MergeOperation, MergeOperation, ( a, b, context ) => {\n\t// Case 1:\n\t//\n\t// Same merge operations.\n\t//\n\t// Both operations have same source and target positions. So the element already got merged and there is\n\t// theoretically nothing to do.\n\t//\n\tif ( a.sourcePosition.isEqual( b.sourcePosition ) && a.targetPosition.isEqual( b.targetPosition ) ) {\n\t\t// There are two ways that we can provide a do-nothing operation.\n\t\t//\n\t\t// First is simply a NoOperation instance. We will use it if `b` operation was not undone.\n\t\t//\n\t\t// Second is a merge operation that has the source operation in the merged element - in the graveyard -\n\t\t// same target position and `howMany` equal to `0`. So it is basically merging an empty element from graveyard\n\t\t// which is almost the same as NoOperation.\n\t\t//\n\t\t// This way the merge operation can be later transformed by split operation\n\t\t// to provide correct undo. This will be used if `b` operation was undone (only then it is correct).\n\t\t//\n\t\tif ( !context.bWasUndone ) {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t} else {\n\t\t\tconst path = b.graveyardPosition.path.slice();\n\t\t\tpath.push( 0 );\n\n\t\t\ta.sourcePosition = new Position( b.graveyardPosition.root, path );\n\t\t\ta.howMany = 0;\n\n\t\t\treturn [ a ];\n\t\t}\n\t}\n\n\t// Case 2:\n\t//\n\t// Same merge source position but different target position.\n\t//\n\t// This can happen during collaboration. For example, if one client merged a paragraph to the previous paragraph\n\t// and the other person removed that paragraph and merged the same paragraph to something before:\n\t//\n\t// Client A:\n\t// <p>Foo</p><p>Bar</p><p>[]Xyz</p>\n\t// <p>Foo</p><p>BarXyz</p>\n\t//\n\t// Client B:\n\t// <p>Foo</p>[<p>Bar</p>]<p>Xyz</p>\n\t// <p>Foo</p><p>[]Xyz</p>\n\t// <p>FooXyz</p>\n\t//\n\t// In this case we need to decide where finally \"Xyz\" will land:\n\t//\n\t// <p>FooXyz</p> graveyard: <p>Bar</p>\n\t// <p>Foo</p> graveyard: <p>BarXyz</p>\n\t//\n\t// Let's move it in a way so that a merge operation that does not target to graveyard is more important so that\n\t// nodes does not end up in the graveyard. It makes sense. Both for Client A and for Client B \"Xyz\" finally did not\n\t// end up in the graveyard (see above).\n\t//\n\t// If neither or both operations point to graveyard, then let `aIsStrong` decide.\n\t//\n\tif (\n\t\ta.sourcePosition.isEqual( b.sourcePosition ) && !a.targetPosition.isEqual( b.targetPosition ) &&\n\t\t!context.bWasUndone && context.abRelation != 'splitAtSource'\n\t) {\n\t\tconst aToGraveyard = a.targetPosition.root.rootName == '$graveyard';\n\t\tconst bToGraveyard = b.targetPosition.root.rootName == '$graveyard';\n\n\t\t// If `aIsWeak` it means that `a` points to graveyard while `b` doesn't. Don't move nodes then.\n\t\tconst aIsWeak = aToGraveyard && !bToGraveyard;\n\n\t\t// If `bIsWeak` it means that `b` points to graveyard while `a` doesn't. Force moving nodes then.\n\t\tconst bIsWeak = bToGraveyard && !aToGraveyard;\n\n\t\t// Force move if `b` is weak or neither operation is weak but `a` is stronger through `context.aIsStrong`.\n\t\tconst forceMove = bIsWeak || ( !aIsWeak && context.aIsStrong );\n\n\t\tif ( forceMove ) {\n\t\t\tconst sourcePosition = b.targetPosition._getTransformedByMergeOperation( b );\n\t\t\tconst targetPosition = a.targetPosition._getTransformedByMergeOperation( b );\n\n\t\t\treturn [ new MoveOperation( sourcePosition, a.howMany, targetPosition, 0 ) ];\n\t\t} else {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t}\n\t}\n\n\t// The default case.\n\t//\n\tif ( a.sourcePosition.hasSameParentAs( b.targetPosition ) ) {\n\t\ta.howMany += b.howMany;\n\t}\n\n\ta.sourcePosition = a.sourcePosition._getTransformedByMergeOperation( b );\n\ta.targetPosition = a.targetPosition._getTransformedByMergeOperation( b );\n\n\t// Handle positions in graveyard.\n\t// If graveyard positions are same and `a` operation is strong - do not transform.\n\tif ( !a.graveyardPosition.isEqual( b.graveyardPosition ) || !context.aIsStrong ) {\n\t\ta.graveyardPosition = a.graveyardPosition._getTransformedByMergeOperation( b );\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( MergeOperation, MoveOperation, ( a, b, context ) => {\n\t// Case 1:\n\t//\n\t// The element to merge got removed.\n\t//\n\t// Merge operation does support merging elements which are not siblings. So it would not be a problem\n\t// from technical point of view. However, if the element was removed, the intention of the user deleting it\n\t// was to have it all deleted, together with its children. From user experience point of view, moving back the\n\t// removed nodes might be unexpected. This means that in this scenario we will block the merging.\n\t//\n\t// The exception of this rule would be if the remove operation was later undone.\n\t//\n\tconst removedRange = Range._createFromPositionAndShift( b.sourcePosition, b.howMany );\n\n\tif ( b.type == 'remove' && !context.bWasUndone && !context.forceWeakRemove ) {\n\t\tif ( a.deletionPosition.hasSameParentAs( b.sourcePosition ) && removedRange.containsPosition( a.sourcePosition ) ) {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t}\n\t}\n\n\t// The default case.\n\t//\n\tif ( a.sourcePosition.hasSameParentAs( b.targetPosition ) ) {\n\t\ta.howMany += b.howMany;\n\t}\n\n\tif ( a.sourcePosition.hasSameParentAs( b.sourcePosition ) ) {\n\t\ta.howMany -= b.howMany;\n\t}\n\n\ta.sourcePosition = a.sourcePosition._getTransformedByMoveOperation( b );\n\ta.targetPosition = a.targetPosition._getTransformedByMoveOperation( b );\n\n\t// `MergeOperation` graveyard position is like `MoveOperation` target position. It is a position where element(s) will\n\t// be moved. Like in other similar cases, we need to consider the scenario when those positions are same.\n\t// Here, we will treat `MergeOperation` like it is always strong (see `InsertOperation` x `InsertOperation` for comparison).\n\t// This means that we won't transform graveyard position if it is equal to move operation target position.\n\tif ( !a.graveyardPosition.isEqual( b.targetPosition ) ) {\n\t\ta.graveyardPosition = a.graveyardPosition._getTransformedByMoveOperation( b );\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( MergeOperation, SplitOperation, ( a, b, context ) => {\n\tif ( b.graveyardPosition ) {\n\t\t// If `b` operation defines graveyard position, a node from graveyard will be moved. This means that we need to\n\t\t// transform `a.graveyardPosition` accordingly.\n\t\ta.graveyardPosition = a.graveyardPosition._getTransformedByDeletion( b.graveyardPosition, 1 );\n\n\t\t// This is a scenario foreseen in `MergeOperation` x `MergeOperation`, with two identical merge operations.\n\t\t//\n\t\t// So, there was `MergeOperation` x `MergeOperation` transformation earlier. Now, `a` is a merge operation which\n\t\t// source position is in graveyard. Interestingly, split operation wants to use the node to be merged by `a`. This\n\t\t// means that `b` is undoing that merge operation from earlier, which caused `a` to be in graveyard.\n\t\t//\n\t\t// If that's the case, at this point, we will only \"fix\" `a.howMany`. It was earlier set to `0` in\n\t\t// `MergeOperation` x `MergeOperation` transformation. Later transformations in this function will change other\n\t\t// properties.\n\t\t//\n\t\tif ( a.deletionPosition.isEqual( b.graveyardPosition ) ) {\n\t\t\ta.howMany = b.howMany;\n\t\t}\n\t}\n\n\t// Case 1:\n\t//\n\t// Merge operation moves nodes to the place where split happens.\n\t// This is a classic situation when there are two paragraphs, and there is a split (enter) after the first\n\t// paragraph and there is a merge (delete) at the beginning of the second paragraph:\n\t//\n\t// <p>Foo{}</p><p>[]Bar</p>.\n\t//\n\t// Split is after `Foo`, while merge is from `Bar` to the end of `Foo`.\n\t//\n\t// State after split:\n\t// <p>Foo</p><p></p><p>Bar</p>\n\t//\n\t// Now, `Bar` should be merged to the new paragraph:\n\t// <p>Foo</p><p>Bar</p>\n\t//\n\t// Instead of merging it to the original paragraph:\n\t// <p>FooBar</p><p></p>\n\t//\n\t// This means that `targetPosition` needs to be transformed. This is the default case though.\n\t// For example, if the split would be after `F`, `targetPosition` should also be transformed.\n\t//\n\t// There are three exceptions, though, when we want to keep `targetPosition` as it was.\n\t//\n\t// First exception is when the merge target position is inside an element (not at the end, as usual). This\n\t// happens when the merge operation earlier was transformed by \"the same\" merge operation. If merge operation\n\t// targets inside the element we want to keep the original target position (and not transform it) because\n\t// we have additional context telling us that we want to merge to the original element. We can check if the\n\t// merge operation points inside element by checking what is `SplitOperation#howMany`. Since merge target position\n\t// is same as split position, if `howMany` is non-zero, it means that the merge target position is inside an element.\n\t//\n\t// Second exception is when the element to merge is in the graveyard and split operation uses it. In that case\n\t// if target position would be transformed, the merge operation would target at the source position:\n\t//\n\t// root: <p>Foo</p>\t\t\t\tgraveyard: <p></p>\n\t//\n\t// SplitOperation: root [ 0, 3 ] using graveyard [ 0 ] (howMany = 0)\n\t// MergeOperation: graveyard [ 0, 0 ] -> root [ 0, 3 ] (howMany = 0)\n\t//\n\t// Since split operation moves the graveyard node back to the root, the merge operation source position changes.\n\t// We would like to merge from the empty <p> to the \"Foo\" <p>:\n\t//\n\t// root: <p>Foo</p><p></p>\t\t\tgraveyard:\n\t//\n\t// MergeOperation#sourcePosition = root [ 1, 0 ]\n\t//\n\t// If `targetPosition` is transformed, it would become root [ 1, 0 ] as well. It has to be kept as it was.\n\t//\n\t// Third exception is connected with relations. If this happens during undo and we have explicit information\n\t// that target position has not been affected by the operation which is undone by this split then this split should\n\t// not move the target position either.\n\t//\n\tif ( a.targetPosition.isEqual( b.splitPosition ) ) {\n\t\tconst mergeInside = b.howMany != 0;\n\t\tconst mergeSplittingElement = b.graveyardPosition && a.deletionPosition.isEqual( b.graveyardPosition );\n\n\t\tif ( mergeInside || mergeSplittingElement || context.abRelation == 'mergeTargetNotMoved' ) {\n\t\t\ta.sourcePosition = a.sourcePosition._getTransformedBySplitOperation( b );\n\n\t\t\treturn [ a ];\n\t\t}\n\t}\n\n\t// Case 2:\n\t//\n\t// Merge source is at the same position as split position. This sometimes happen, mostly during undo.\n\t// The decision here is mostly to choose whether merge source position should stay where it is (so it will be at the end of the\n\t// split element) or should be move to the beginning of the new element.\n\t//\n\tif ( a.sourcePosition.isEqual( b.splitPosition ) ) {\n\t\t// Use context to check if `SplitOperation` is not undoing a merge operation, that didn't change the `a` operation.\n\t\t// This scenario happens the undone merge operation moved nodes at the source position of `a` operation.\n\t\t// In that case `a` operation source position should stay where it is.\n\t\tif ( context.abRelation == 'mergeSourceNotMoved' ) {\n\t\t\ta.howMany = 0;\n\t\t\ta.targetPosition = a.targetPosition._getTransformedBySplitOperation( b );\n\n\t\t\treturn [ a ];\n\t\t}\n\n\t\t// This merge operation might have been earlier transformed by a merge operation which both merged the same element.\n\t\t// See that case in `MergeOperation` x `MergeOperation` transformation. In that scenario, if the merge operation has been undone,\n\t\t// the special case is not applied.\n\t\t//\n\t\t// Now, the merge operation is transformed by the split which has undone that previous merge operation.\n\t\t// So now we are fixing situation which was skipped in `MergeOperation` x `MergeOperation` case.\n\t\t//\n\t\tif ( context.abRelation == 'mergeSameElement' || a.sourcePosition.offset > 0 ) {\n\t\t\ta.sourcePosition = b.moveTargetPosition.clone();\n\t\t\ta.targetPosition = a.targetPosition._getTransformedBySplitOperation( b );\n\n\t\t\treturn [ a ];\n\t\t}\n\t}\n\n\t// The default case.\n\t//\n\tif ( a.sourcePosition.hasSameParentAs( b.splitPosition ) ) {\n\t\ta.howMany = b.splitPosition.offset;\n\t}\n\n\ta.sourcePosition = a.sourcePosition._getTransformedBySplitOperation( b );\n\ta.targetPosition = a.targetPosition._getTransformedBySplitOperation( b );\n\n\treturn [ a ];\n} );\n\n// -----------------------\n\nsetTransformation( MoveOperation, InsertOperation, ( a, b ) => {\n\tconst moveRange = Range._createFromPositionAndShift( a.sourcePosition, a.howMany );\n\tconst transformed = moveRange._getTransformedByInsertOperation( b, false )[ 0 ];\n\n\ta.sourcePosition = transformed.start;\n\ta.howMany = transformed.end.offset - transformed.start.offset;\n\n\t// See `InsertOperation` x `MoveOperation` transformation for details on this case.\n\t//\n\t// In summary, both operations point to the same place, so the order of nodes needs to be decided.\n\t// `MoveOperation` is considered weaker, so it is always transformed, unless there was a certain relation\n\t// between operations.\n\t//\n\tif ( !a.targetPosition.isEqual( b.position ) ) {\n\t\ta.targetPosition = a.targetPosition._getTransformedByInsertOperation( b );\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( MoveOperation, MoveOperation, ( a, b, context ) => {\n\t//\n\t// Setting and evaluating some variables that will be used in special cases and default algorithm.\n\t//\n\t// Create ranges from `MoveOperations` properties.\n\tconst rangeA = Range._createFromPositionAndShift( a.sourcePosition, a.howMany );\n\tconst rangeB = Range._createFromPositionAndShift( b.sourcePosition, b.howMany );\n\n\t// Assign `context.aIsStrong` to a different variable, because the value may change during execution of\n\t// this algorithm and we do not want to override original `context.aIsStrong` that will be used in later transformations.\n\tlet aIsStrong = context.aIsStrong;\n\n\t// This will be used to decide the order of nodes if both operations target at the same position.\n\t// By default, use strong/weak operation mechanism.\n\tlet insertBefore = !context.aIsStrong;\n\n\t// If the relation is set, then use it to decide nodes order.\n\tif ( context.abRelation == 'insertBefore' || context.baRelation == 'insertAfter' ) {\n\t\tinsertBefore = true;\n\t} else if ( context.abRelation == 'insertAfter' || context.baRelation == 'insertBefore' ) {\n\t\tinsertBefore = false;\n\t}\n\n\t// `a.targetPosition` could be affected by the `b` operation. We will transform it.\n\tlet newTargetPosition;\n\n\tif ( a.targetPosition.isEqual( b.targetPosition ) && insertBefore ) {\n\t\tnewTargetPosition = a.targetPosition._getTransformedByDeletion(\n\t\t\tb.sourcePosition,\n\t\t\tb.howMany\n\t\t);\n\t} else {\n\t\tnewTargetPosition = a.targetPosition._getTransformedByMove(\n\t\t\tb.sourcePosition,\n\t\t\tb.targetPosition,\n\t\t\tb.howMany\n\t\t);\n\t}\n\n\t//\n\t// Special case #1 + mirror.\n\t//\n\t// Special case when both move operations' target positions are inside nodes that are\n\t// being moved by the other move operation. So in other words, we move ranges into inside of each other.\n\t// This case can't be solved reasonably (on the other hand, it should not happen often).\n\tif ( _moveTargetIntoMovedRange( a, b ) && _moveTargetIntoMovedRange( b, a ) ) {\n\t\t// Instead of transforming operation, we return a reverse of the operation that we transform by.\n\t\t// So when the results of this \"transformation\" will be applied, `b` MoveOperation will get reversed.\n\t\treturn [ b.getReversed() ];\n\t}\n\t//\n\t// End of special case #1.\n\t//\n\n\t//\n\t// Special case #2.\n\t//\n\t// Check if `b` operation targets inside `rangeA`.\n\tconst bTargetsToA = rangeA.containsPosition( b.targetPosition );\n\n\t// If `b` targets to `rangeA` and `rangeA` contains `rangeB`, `b` operation has no influence on `a` operation.\n\t// You might say that operation `b` is captured inside operation `a`.\n\tif ( bTargetsToA && rangeA.containsRange( rangeB, true ) ) {\n\t\t// There is a mini-special case here, where `rangeB` is on other level than `rangeA`. That's why\n\t\t// we need to transform `a` operation anyway.\n\t\trangeA.start = rangeA.start._getTransformedByMove( b.sourcePosition, b.targetPosition, b.howMany );\n\t\trangeA.end = rangeA.end._getTransformedByMove( b.sourcePosition, b.targetPosition, b.howMany );\n\n\t\treturn _makeMoveOperationsFromRanges( [ rangeA ], newTargetPosition );\n\t}\n\n\t//\n\t// Special case #2 mirror.\n\t//\n\tconst aTargetsToB = rangeB.containsPosition( a.targetPosition );\n\n\tif ( aTargetsToB && rangeB.containsRange( rangeA, true ) ) {\n\t\t// `a` operation is \"moved together\" with `b` operation.\n\t\t// Here, just move `rangeA` \"inside\" `rangeB`.\n\t\trangeA.start = rangeA.start._getCombined( b.sourcePosition, b.getMovedRangeStart() );\n\t\trangeA.end = rangeA.end._getCombined( b.sourcePosition, b.getMovedRangeStart() );\n\n\t\treturn _makeMoveOperationsFromRanges( [ rangeA ], newTargetPosition );\n\t}\n\t//\n\t// End of special case #2.\n\t//\n\n\t//\n\t// Special case #3 + mirror.\n\t//\n\t// `rangeA` has a node which is an ancestor of `rangeB`. In other words, `rangeB` is inside `rangeA`\n\t// but not on the same tree level. In such case ranges have common part but we have to treat it\n\t// differently, because in such case those ranges are not really conflicting and should be treated like\n\t// two separate ranges. Also we have to discard two difference parts.\n\tconst aCompB = compareArrays( a.sourcePosition.getParentPath(), b.sourcePosition.getParentPath() );\n\n\tif ( aCompB == 'prefix' || aCompB == 'extension' ) {\n\t\t// Transform `rangeA` by `b` operation and make operation out of it, and that's all.\n\t\t// Note that this is a simplified version of default case, but here we treat the common part (whole `rangeA`)\n\t\t// like a one difference part.\n\t\trangeA.start = rangeA.start._getTransformedByMove( b.sourcePosition, b.targetPosition, b.howMany );\n\t\trangeA.end = rangeA.end._getTransformedByMove( b.sourcePosition, b.targetPosition, b.howMany );\n\n\t\treturn _makeMoveOperationsFromRanges( [ rangeA ], newTargetPosition );\n\t}\n\t//\n\t// End of special case #3.\n\t//\n\n\t//\n\t// Default case - ranges are on the same level or are not connected with each other.\n\t//\n\t// Modifier for default case.\n\t// Modifies `aIsStrong` flag in certain conditions.\n\t//\n\t// If only one of operations is a remove operation, we force remove operation to be the \"stronger\" one\n\t// to provide more expected results.\n\tif ( a.type == 'remove' && b.type != 'remove' && !context.aWasUndone && !context.forceWeakRemove ) {\n\t\taIsStrong = true;\n\t} else if ( a.type != 'remove' && b.type == 'remove' && !context.bWasUndone && !context.forceWeakRemove ) {\n\t\taIsStrong = false;\n\t}\n\n\t// Handle operation's source ranges - check how `rangeA` is affected by `b` operation.\n\t// This will aggregate transformed ranges.\n\tconst ranges = [];\n\n\t// Get the \"difference part\" of `a` operation source range.\n\t// This is an array with one or two ranges. Two ranges if `rangeB` is inside `rangeA`.\n\tconst difference = rangeA.getDifference( rangeB );\n\n\tfor ( const range of difference ) {\n\t\t// Transform those ranges by `b` operation. For example if `b` moved range from before those ranges, fix those ranges.\n\t\trange.start = range.start._getTransformedByDeletion( b.sourcePosition, b.howMany );\n\t\trange.end = range.end._getTransformedByDeletion( b.sourcePosition, b.howMany );\n\n\t\t// If `b` operation targets into `rangeA` on the same level, spread `rangeA` into two ranges.\n\t\tconst shouldSpread = compareArrays( range.start.getParentPath(), b.getMovedRangeStart().getParentPath() ) == 'same';\n\t\tconst newRanges = range._getTransformedByInsertion( b.getMovedRangeStart(), b.howMany, shouldSpread );\n\n\t\tranges.push( ...newRanges );\n\t}\n\n\t// Then, we have to manage the \"common part\" of both move ranges.\n\tconst common = rangeA.getIntersection( rangeB );\n\n\tif ( common !== null && aIsStrong ) {\n\t\t// Calculate the new position of that part of original range.\n\t\tcommon.start = common.start._getCombined( b.sourcePosition, b.getMovedRangeStart() );\n\t\tcommon.end = common.end._getCombined( b.sourcePosition, b.getMovedRangeStart() );\n\n\t\t// Take care of proper range order.\n\t\t//\n\t\t// Put `common` at appropriate place. Keep in mind that we are interested in original order.\n\t\t// Basically there are only three cases: there is zero, one or two difference ranges.\n\t\t//\n\t\t// If there is zero difference ranges, just push `common` in the array.\n\t\tif ( ranges.length === 0 ) {\n\t\t\tranges.push( common );\n\t\t}\n\t\t// If there is one difference range, we need to check whether common part was before it or after it.\n\t\telse if ( ranges.length == 1 ) {\n\t\t\tif ( rangeB.start.isBefore( rangeA.start ) || rangeB.start.isEqual( rangeA.start ) ) {\n\t\t\t\tranges.unshift( common );\n\t\t\t} else {\n\t\t\t\tranges.push( common );\n\t\t\t}\n\t\t}\n\t\t// If there are more ranges (which means two), put common part between them. This is the only scenario\n\t\t// where there could be two difference ranges so we don't have to make any comparisons.\n\t\telse {\n\t\t\tranges.splice( 1, 0, common );\n\t\t}\n\t}\n\n\tif ( ranges.length === 0 ) {\n\t\t// If there are no \"source ranges\", nothing should be changed.\n\t\t// Note that this can happen only if `aIsStrong == false` and `rangeA.isEqual( rangeB )`.\n\t\treturn [ new NoOperation( a.baseVersion ) ];\n\t}\n\n\treturn _makeMoveOperationsFromRanges( ranges, newTargetPosition );\n} );\n\nsetTransformation( MoveOperation, SplitOperation, ( a, b, context ) => {\n\tlet newTargetPosition = a.targetPosition.clone();\n\n\t// Do not transform if target position is same as split insertion position and this split comes from undo.\n\t// This should be done on relations but it is too much work for now as it would require relations working in collaboration.\n\t// We need to make a decision how we will resolve such conflict and this is less harmful way.\n\tif ( !a.targetPosition.isEqual( b.insertionPosition ) || !b.graveyardPosition || context.abRelation == 'moveTargetAfter' ) {\n\t\tnewTargetPosition = a.targetPosition._getTransformedBySplitOperation( b );\n\t}\n\n\t// Case 1:\n\t//\n\t// Last element in the moved range got split.\n\t//\n\t// In this case the default range transformation will not work correctly as the element created by\n\t// split operation would be outside the range. The range to move needs to be fixed manually.\n\t//\n\tconst moveRange = Range._createFromPositionAndShift( a.sourcePosition, a.howMany );\n\n\tif ( moveRange.end.isEqual( b.insertionPosition ) ) {\n\t\t// Do it only if this is a \"natural\" split, not a one that comes from undo.\n\t\t// If this is undo split, only `targetPosition` needs to be changed (if the move is a remove).\n\t\tif ( !b.graveyardPosition ) {\n\t\t\ta.howMany++;\n\t\t}\n\n\t\ta.targetPosition = newTargetPosition;\n\n\t\treturn [ a ];\n\t}\n\n\t// Case 2:\n\t//\n\t// Split happened between the moved nodes. In this case two ranges to move need to be generated.\n\t//\n\t// Characters `ozba` are moved to the end of paragraph `Xyz` but split happened.\n\t// <p>F[oz|ba]r</p><p>Xyz</p>\n\t//\n\t// After split:\n\t// <p>F[oz</p><p>ba]r</p><p>Xyz</p>\n\t//\n\t// Correct ranges:\n\t// <p>F[oz]</p><p>[ba]r</p><p>Xyz</p>\n\t//\n\t// After move:\n\t// <p>F</p><p>r</p><p>Xyzozba</p>\n\t//\n\tif ( moveRange.start.hasSameParentAs( b.splitPosition ) && moveRange.containsPosition( b.splitPosition ) ) {\n\t\tlet rightRange = new Range( b.splitPosition, moveRange.end );\n\t\trightRange = rightRange._getTransformedBySplitOperation( b );\n\n\t\tconst ranges = [\n\t\t\tnew Range( moveRange.start, b.splitPosition ),\n\t\t\trightRange\n\t\t];\n\n\t\treturn _makeMoveOperationsFromRanges( ranges, newTargetPosition );\n\t}\n\n\t// Case 3:\n\t//\n\t// Move operation targets at the split position. We need to decide if the nodes should be inserted\n\t// at the end of the split element or at the beginning of the new element.\n\t//\n\tif ( a.targetPosition.isEqual( b.splitPosition ) && context.abRelation == 'insertAtSource' ) {\n\t\tnewTargetPosition = b.moveTargetPosition;\n\t}\n\n\t// Case 4:\n\t//\n\t// Move operation targets just after the split element. We need to decide if the nodes should be inserted\n\t// between two parts of split element, or after the new element.\n\t//\n\t// Split at `|`, while move operation moves `<p>Xyz</p>` and targets at `^`:\n\t// <p>Foo|bar</p>^<p>baz</p>\n\t// <p>Foo</p>^<p>bar</p><p>baz</p> or <p>Foo</p><p>bar</p>^<p>baz</p>?\n\t//\n\t// If there is no contextual information between operations (for example, they come from collaborative\n\t// editing), we don't want to put some unrelated content (move) between parts of related content (split parts).\n\t// However, if the split is from undo, in the past, the moved content might be targeting between the\n\t// split parts, meaning that was exactly user's intention:\n\t//\n\t// <p>Foo</p>^<p>bar</p>\t\t<--- original situation, in \"past\".\n\t// <p>Foobar</p>^\t\t\t\t<--- after merge target position is transformed.\n\t// <p>Foo|bar</p>^\t\t\t\t<--- then the merge is undone, and split happens, which leads us to current situation.\n\t//\n\t// In this case it is pretty clear that the intention was to put new paragraph between those nodes,\n\t// so we need to transform accordingly. We can detect this scenario thanks to relations.\n\t//\n\tif ( a.targetPosition.isEqual( b.insertionPosition ) && context.abRelation == 'insertBetween' ) {\n\t\tnewTargetPosition = a.targetPosition;\n\t}\n\n\t// The default case.\n\t//\n\tconst transformed = moveRange._getTransformedBySplitOperation( b );\n\tconst ranges = [ transformed ];\n\n\t// Case 5:\n\t//\n\t// Moved range contains graveyard element used by split operation. Add extra move operation to the result.\n\t//\n\tif ( b.graveyardPosition ) {\n\t\tconst movesGraveyardElement = moveRange.start.isEqual( b.graveyardPosition ) || moveRange.containsPosition( b.graveyardPosition );\n\n\t\tif ( a.howMany > 1 && movesGraveyardElement && !context.aWasUndone ) {\n\t\t\tranges.push( Range._createFromPositionAndShift( b.insertionPosition, 1 ) );\n\t\t}\n\t}\n\n\treturn _makeMoveOperationsFromRanges( ranges, newTargetPosition );\n} );\n\nsetTransformation( MoveOperation, MergeOperation, ( a, b, context ) => {\n\tconst movedRange = Range._createFromPositionAndShift( a.sourcePosition, a.howMany );\n\n\tif ( b.deletionPosition.hasSameParentAs( a.sourcePosition ) && movedRange.containsPosition( b.sourcePosition ) ) {\n\t\tif ( a.type == 'remove' && !context.forceWeakRemove ) {\n\t\t\t// Case 1:\n\t\t\t//\n\t\t\t// The element to remove got merged.\n\t\t\t//\n\t\t\t// Merge operation does support merging elements which are not siblings. So it would not be a problem\n\t\t\t// from technical point of view. However, if the element was removed, the intention of the user\n\t\t\t// deleting it was to have it all deleted. From user experience point of view, moving back the\n\t\t\t// removed nodes might be unexpected. This means that in this scenario we will reverse merging and remove the element.\n\t\t\t//\n\t\t\tif ( !context.aWasUndone ) {\n\t\t\t\tconst results = [];\n\n\t\t\t\tlet gyMoveSource = b.graveyardPosition.clone();\n\t\t\t\tlet splitNodesMoveSource = b.targetPosition._getTransformedByMergeOperation( b );\n\n\t\t\t\tif ( a.howMany > 1 ) {\n\t\t\t\t\tresults.push( new MoveOperation( a.sourcePosition, a.howMany - 1, a.targetPosition, 0 ) );\n\n\t\t\t\t\tgyMoveSource = gyMoveSource._getTransformedByMove( a.sourcePosition, a.targetPosition, a.howMany - 1 );\n\t\t\t\t\tsplitNodesMoveSource = splitNodesMoveSource._getTransformedByMove( a.sourcePosition, a.targetPosition, a.howMany - 1 );\n\t\t\t\t}\n\n\t\t\t\tconst gyMoveTarget = b.deletionPosition._getCombined( a.sourcePosition, a.targetPosition );\n\t\t\t\tconst gyMove = new MoveOperation( gyMoveSource, 1, gyMoveTarget, 0 );\n\n\t\t\t\tconst splitNodesMoveTargetPath = gyMove.getMovedRangeStart().path.slice();\n\t\t\t\tsplitNodesMoveTargetPath.push( 0 );\n\n\t\t\t\tconst splitNodesMoveTarget = new Position( gyMove.targetPosition.root, splitNodesMoveTargetPath );\n\t\t\t\tsplitNodesMoveSource = splitNodesMoveSource._getTransformedByMove( gyMoveSource, gyMoveTarget, 1 );\n\t\t\t\tconst splitNodesMove = new MoveOperation( splitNodesMoveSource, b.howMany, splitNodesMoveTarget, 0 );\n\n\t\t\t\tresults.push( gyMove );\n\t\t\t\tresults.push( splitNodesMove );\n\n\t\t\t\treturn results;\n\t\t\t}\n\t\t} else {\n\t\t\t// Case 2:\n\t\t\t//\n\t\t\t// The element to move got merged and it was the only element to move.\n\t\t\t// In this case just don't do anything, leave the node in the graveyard. Without special case\n\t\t\t// it would be a move operation that moves 0 nodes, so maybe it is better just to return no-op.\n\t\t\t//\n\t\t\tif ( a.howMany == 1 ) {\n\t\t\t\tif ( !context.bWasUndone ) {\n\t\t\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t\t\t} else {\n\t\t\t\t\ta.sourcePosition = b.graveyardPosition.clone();\n\t\t\t\t\ta.targetPosition = a.targetPosition._getTransformedByMergeOperation( b );\n\n\t\t\t\t\treturn [ a ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// The default case.\n\t//\n\tconst moveRange = Range._createFromPositionAndShift( a.sourcePosition, a.howMany );\n\tconst transformed = moveRange._getTransformedByMergeOperation( b );\n\n\ta.sourcePosition = transformed.start;\n\ta.howMany = transformed.end.offset - transformed.start.offset;\n\ta.targetPosition = a.targetPosition._getTransformedByMergeOperation( b );\n\n\treturn [ a ];\n} );\n\n// -----------------------\n\nsetTransformation( RenameOperation, InsertOperation, ( a, b ) => {\n\ta.position = a.position._getTransformedByInsertOperation( b );\n\n\treturn [ a ];\n} );\n\nsetTransformation( RenameOperation, MergeOperation, ( a, b ) => {\n\t// Case 1:\n\t//\n\t// Element to rename got merged, so it was moved to `b.graveyardPosition`.\n\t//\n\tif ( a.position.isEqual( b.deletionPosition ) ) {\n\t\ta.position = b.graveyardPosition.clone();\n\t\ta.position.stickiness = 'toNext';\n\n\t\treturn [ a ];\n\t}\n\n\ta.position = a.position._getTransformedByMergeOperation( b );\n\n\treturn [ a ];\n} );\n\nsetTransformation( RenameOperation, MoveOperation, ( a, b ) => {\n\ta.position = a.position._getTransformedByMoveOperation( b );\n\n\treturn [ a ];\n} );\n\nsetTransformation( RenameOperation, RenameOperation, ( a, b, context ) => {\n\tif ( a.position.isEqual( b.position ) ) {\n\t\tif ( context.aIsStrong ) {\n\t\t\ta.oldName = b.newName;\n\t\t} else {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t}\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( RenameOperation, SplitOperation, ( a, b ) => {\n\t// Case 1:\n\t//\n\t// The element to rename has been split. In this case, the new element should be also renamed.\n\t//\n\t// User decides to change the paragraph to a list item:\n\t// <paragraph>Foobar</paragraph>\n\t//\n\t// However, in meantime, split happens:\n\t// <paragraph>Foo</paragraph><paragraph>bar</paragraph>\n\t//\n\t// As a result, rename both elements:\n\t// <listItem>Foo</listItem><listItem>bar</listItem>\n\t//\n\tconst renamePath = a.position.path;\n\tconst splitPath = b.splitPosition.getParentPath();\n\n\tif ( compareArrays( renamePath, splitPath ) == 'same' && !b.graveyardPosition ) {\n\t\tconst extraRename = new RenameOperation( a.position.getShiftedBy( 1 ), a.oldName, a.newName, 0 );\n\n\t\treturn [ a, extraRename ];\n\t}\n\n\t// The default case.\n\t//\n\ta.position = a.position._getTransformedBySplitOperation( b );\n\n\treturn [ a ];\n} );\n\n// -----------------------\n\nsetTransformation( RootAttributeOperation, RootAttributeOperation, ( a, b, context ) => {\n\tif ( a.root === b.root && a.key === b.key ) {\n\t\tif ( !context.aIsStrong || a.newValue === b.newValue ) {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t} else {\n\t\t\ta.oldValue = b.newValue;\n\t\t}\n\t}\n\n\treturn [ a ];\n} );\n\n// -----------------------\n\nsetTransformation( SplitOperation, InsertOperation, ( a, b ) => {\n\t// The default case.\n\t//\n\tif ( a.splitPosition.hasSameParentAs( b.position ) && a.splitPosition.offset < b.position.offset ) {\n\t\ta.howMany += b.howMany;\n\t}\n\n\ta.splitPosition = a.splitPosition._getTransformedByInsertOperation( b );\n\ta.insertionPosition = SplitOperation.getInsertionPosition( a.splitPosition );\n\n\treturn [ a ];\n} );\n\nsetTransformation( SplitOperation, MergeOperation, ( a, b, context ) => {\n\t// Case 1:\n\t//\n\t// Split element got merged. If two different elements were merged, clients will have different content.\n\t//\n\t// Example. Merge at `{}`, split at `[]`:\n\t// <heading>Foo</heading>{}<paragraph>B[]ar</paragraph>\n\t//\n\t// On merge side it will look like this:\n\t// <heading>FooB[]ar</heading>\n\t// <heading>FooB</heading><heading>ar</heading>\n\t//\n\t// On split side it will look like this:\n\t// <heading>Foo</heading>{}<paragraph>B</paragraph><paragraph>ar</paragraph>\n\t// <heading>FooB</heading><paragraph>ar</paragraph>\n\t//\n\t// Clearly, the second element is different for both clients.\n\t//\n\t// We could use the removed merge element from graveyard as a split element but then clients would have a different\n\t// model state (in graveyard), because the split side client would still have an element in graveyard (removed by merge).\n\t//\n\t// To overcome this, in `SplitOperation` x `MergeOperation` transformation we will add additional `SplitOperation`\n\t// in the graveyard, which will actually clone the merged-and-deleted element. Then, that cloned element will be\n\t// used for splitting. Example below.\n\t//\n\t// Original state:\n\t// <heading>Foo</heading>{}<paragraph>B[]ar</paragraph>\n\t//\n\t// Merge side client:\n\t//\n\t// After merge:\n\t// <heading>FooB[]ar</heading> graveyard: <paragraph></paragraph>\n\t//\n\t// Extra split:\n\t// <heading>FooB[]ar</heading> graveyard: <paragraph></paragraph><paragraph></paragraph>\n\t//\n\t// Use the \"cloned\" element from graveyard:\n\t// <heading>FooB</heading><paragraph>ar</paragraph> graveyard: <paragraph></paragraph>\n\t//\n\t// Split side client:\n\t//\n\t// After split:\n\t// <heading>Foo</heading>{}<paragraph>B</paragraph><paragraph>ar</paragraph>\n\t//\n\t// After merge:\n\t// <heading>FooB</heading><paragraph>ar</paragraph> graveyard: <paragraph></paragraph>\n\t//\n\t// This special case scenario only applies if the original split operation clones the split element.\n\t// If the original split operation has `graveyardPosition` set, it all doesn't have sense because split operation\n\t// knows exactly which element it should use. So there would be no original problem with different contents.\n\t//\n\t// Additionally, the special case applies only if the merge wasn't already undone.\n\t//\n\tif ( !a.graveyardPosition && !context.bWasUndone && a.splitPosition.hasSameParentAs( b.sourcePosition ) ) {\n\t\tconst splitPath = b.graveyardPosition.path.slice();\n\t\tsplitPath.push( 0 );\n\n\t\tconst splitPosition = new Position( b.graveyardPosition.root, splitPath );\n\t\tconst insertionPosition = SplitOperation.getInsertionPosition( new Position( b.graveyardPosition.root, splitPath ) );\n\n\t\tconst additionalSplit = new SplitOperation( splitPosition, 0, null, 0 );\n\t\tadditionalSplit.insertionPosition = insertionPosition;\n\n\t\ta.splitPosition = a.splitPosition._getTransformedByMergeOperation( b );\n\t\ta.insertionPosition = SplitOperation.getInsertionPosition( a.splitPosition );\n\t\ta.graveyardPosition = additionalSplit.insertionPosition.clone();\n\t\ta.graveyardPosition.stickiness = 'toNext';\n\n\t\treturn [ additionalSplit, a ];\n\t}\n\n\t// The default case.\n\t//\n\tif ( a.splitPosition.hasSameParentAs( b.deletionPosition ) && !a.splitPosition.isAfter( b.deletionPosition ) ) {\n\t\ta.howMany--;\n\t}\n\n\tif ( a.splitPosition.hasSameParentAs( b.targetPosition ) ) {\n\t\ta.howMany += b.howMany;\n\t}\n\n\ta.splitPosition = a.splitPosition._getTransformedByMergeOperation( b );\n\ta.insertionPosition = SplitOperation.getInsertionPosition( a.splitPosition );\n\n\tif ( a.graveyardPosition ) {\n\t\ta.graveyardPosition = a.graveyardPosition._getTransformedByMergeOperation( b );\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( SplitOperation, MoveOperation, ( a, b, context ) => {\n\tconst rangeToMove = Range._createFromPositionAndShift( b.sourcePosition, b.howMany );\n\n\tif ( a.graveyardPosition ) {\n\t\t// Case 1:\n\t\t//\n\t\t// Split operation graveyard node was moved. In this case move operation is stronger. Since graveyard element\n\t\t// is already moved to the correct position, we need to only move the nodes after the split position.\n\t\t// This will be done by `MoveOperation` instead of `SplitOperation`.\n\t\t//\n\t\tconst gyElementMoved = rangeToMove.start.isEqual( a.graveyardPosition ) || rangeToMove.containsPosition( a.graveyardPosition );\n\n\t\tif ( !context.bWasUndone && gyElementMoved ) {\n\t\t\tconst sourcePosition = a.splitPosition._getTransformedByMoveOperation( b );\n\n\t\t\tconst newParentPosition = a.graveyardPosition._getTransformedByMoveOperation( b );\n\t\t\tconst newTargetPath = newParentPosition.path.slice();\n\t\t\tnewTargetPath.push( 0 );\n\n\t\t\tconst newTargetPosition = new Position( newParentPosition.root, newTargetPath );\n\t\t\tconst moveOp = new MoveOperation( sourcePosition, a.howMany, newTargetPosition, 0 );\n\n\t\t\treturn [ moveOp ];\n\t\t}\n\n\t\ta.graveyardPosition = a.graveyardPosition._getTransformedByMoveOperation( b );\n\t}\n\n\t// Case 2:\n\t//\n\t// If the split position is inside the moved range, we need to shift the split position to a proper place.\n\t// The position cannot be moved together with moved range because that would result in splitting of an incorrect element.\n\t//\n\t// Characters `bc` should be moved to the second paragraph while split position is between them:\n\t// <paragraph>A[b|c]d</paragraph><paragraph>Xyz</paragraph>\n\t//\n\t// After move, new split position is incorrect:\n\t// <paragraph>Ad</paragraph><paragraph>Xb|cyz</paragraph>\n\t//\n\t// Correct split position:\n\t// <paragraph>A|d</paragraph><paragraph>Xbcyz</paragraph>\n\t//\n\t// After split:\n\t// <paragraph>A</paragraph><paragraph>d</paragraph><paragraph>Xbcyz</paragraph>\n\t//\n\tif ( a.splitPosition.hasSameParentAs( b.sourcePosition ) && rangeToMove.containsPosition( a.splitPosition ) ) {\n\t\tconst howManyRemoved = b.howMany - ( a.splitPosition.offset - b.sourcePosition.offset );\n\t\ta.howMany -= howManyRemoved;\n\n\t\tif ( a.splitPosition.hasSameParentAs( b.targetPosition ) && a.splitPosition.offset < b.targetPosition.offset ) {\n\t\t\ta.howMany += b.howMany;\n\t\t}\n\n\t\ta.splitPosition = b.sourcePosition.clone();\n\t\ta.insertionPosition = SplitOperation.getInsertionPosition( a.splitPosition );\n\n\t\treturn [ a ];\n\t}\n\n\t// Case 3:\n\t//\n\t// Split is at a position where nodes were moved.\n\t//\n\t// This is a scenario described in `MoveOperation` x `SplitOperation` transformation but from the\n\t// \"split operation point of view\".\n\t//\n\tconst splitAtTarget = a.splitPosition.isEqual( b.targetPosition );\n\n\tif ( splitAtTarget && ( context.baRelation == 'insertAtSource' || context.abRelation == 'splitBefore' ) ) {\n\t\ta.howMany += b.howMany;\n\t\ta.splitPosition = a.splitPosition._getTransformedByDeletion( b.sourcePosition, b.howMany );\n\t\ta.insertionPosition = SplitOperation.getInsertionPosition( a.splitPosition );\n\n\t\treturn [ a ];\n\t}\n\n\t// The default case.\n\t// Don't change `howMany` if move operation does not really move anything.\n\t//\n\tif ( !b.sourcePosition.isEqual( b.targetPosition ) ) {\n\t\tif ( a.splitPosition.hasSameParentAs( b.sourcePosition ) && a.splitPosition.offset <= b.sourcePosition.offset ) {\n\t\t\ta.howMany -= b.howMany;\n\t\t}\n\n\t\tif ( a.splitPosition.hasSameParentAs( b.targetPosition ) && a.splitPosition.offset < b.targetPosition.offset ) {\n\t\t\ta.howMany += b.howMany;\n\t\t}\n\t}\n\n\t// Change position stickiness to force a correct transformation.\n\ta.splitPosition.stickiness = 'toNone';\n\ta.splitPosition = a.splitPosition._getTransformedByMoveOperation( b );\n\ta.splitPosition.stickiness = 'toNext';\n\n\tif ( a.graveyardPosition ) {\n\t\ta.insertionPosition = a.insertionPosition._getTransformedByMoveOperation( b );\n\t} else {\n\t\ta.insertionPosition = SplitOperation.getInsertionPosition( a.splitPosition );\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( SplitOperation, SplitOperation, ( a, b, context ) => {\n\t// Case 1:\n\t//\n\t// Split at the same position.\n\t//\n\t// If there already was a split at the same position as in `a` operation, it means that the intention\n\t// conveyed by `a` operation has already been fulfilled and `a` should not do anything (to avoid double split).\n\t//\n\t// However, there is a difference if these are new splits or splits created by undo. These have different\n\t// intentions. Also splits moving back different elements from graveyard have different intentions. They\n\t// are just different operations.\n\t//\n\t// So we cancel split operation only if it was really identical.\n\t//\n\t// Also, there is additional case, where split operations aren't identical and should not be cancelled, however the\n\t// default transformation is incorrect too.\n\t//\n\tif ( a.splitPosition.isEqual( b.splitPosition ) ) {\n\t\tif ( !a.graveyardPosition && !b.graveyardPosition ) {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t}\n\n\t\tif ( a.graveyardPosition && b.graveyardPosition && a.graveyardPosition.isEqual( b.graveyardPosition ) ) {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t}\n\n\t\t// Use context to know that the `a.splitPosition` should stay where it is.\n\t\t// This happens during undo when first a merge operation moved nodes to `a.splitPosition` and now `b` operation undoes that merge.\n\t\tif ( context.abRelation == 'splitBefore' ) {\n\t\t\t// Since split is at the same position, there are no nodes left to split.\n\t\t\ta.howMany = 0;\n\n\t\t\t// Note: there was `if ( a.graveyardPosition )` here but it was uncovered in tests and I couldn't find any scenarios for now.\n\t\t\t// That would have to be a `SplitOperation` that didn't come from undo but is transformed by operations that were undone.\n\t\t\t// It could happen if `context` is enabled in collaboration.\n\t\t\ta.graveyardPosition = a.graveyardPosition._getTransformedBySplitOperation( b );\n\n\t\t\treturn [ a ];\n\t\t}\n\t}\n\n\t// Case 2:\n\t//\n\t// Same node is using to split different elements. This happens in undo when previously same element was merged to\n\t// two different elements. This is described in `MergeOperation` x `MergeOperation` transformation.\n\t//\n\t// In this case we will follow the same logic. We will assume that `insertionPosition` is same for both\n\t// split operations. This might not always be true but in the real cases that were experienced it was. After all,\n\t// if these splits are reverses of merge operations that were merging the same element, then the `insertionPosition`\n\t// should be same for both of those splits.\n\t//\n\t// Again, we will decide which operation is stronger by checking if split happens in graveyard or in non-graveyard root.\n\t//\n\tif ( a.graveyardPosition && b.graveyardPosition && a.graveyardPosition.isEqual( b.graveyardPosition ) ) {\n\t\tconst aInGraveyard = a.splitPosition.root.rootName == '$graveyard';\n\t\tconst bInGraveyard = b.splitPosition.root.rootName == '$graveyard';\n\n\t\t// If `aIsWeak` it means that `a` points to graveyard while `b` doesn't. Don't move nodes then.\n\t\tconst aIsWeak = aInGraveyard && !bInGraveyard;\n\n\t\t// If `bIsWeak` it means that `b` points to graveyard while `a` doesn't. Force moving nodes then.\n\t\tconst bIsWeak = bInGraveyard && !aInGraveyard;\n\n\t\t// Force move if `b` is weak or neither operation is weak but `a` is stronger through `context.aIsStrong`.\n\t\tconst forceMove = bIsWeak || ( !aIsWeak && context.aIsStrong );\n\n\t\tif ( forceMove ) {\n\t\t\tconst result = [];\n\n\t\t\t// First we need to move any nodes split by `b` back to where they were.\n\t\t\t// Do it only if `b` actually moved something.\n\t\t\tif ( b.howMany ) {\n\t\t\t\tresult.push( new MoveOperation( b.moveTargetPosition, b.howMany, b.splitPosition, 0 ) );\n\t\t\t}\n\n\t\t\t// Then we need to move nodes from `a` split position to their new element.\n\t\t\t// Do it only if `a` actually should move something.\n\t\t\tif ( a.howMany ) {\n\t\t\t\tresult.push( new MoveOperation( a.splitPosition, a.howMany, a.moveTargetPosition, 0 ) );\n\t\t\t}\n\n\t\t\treturn result;\n\t\t} else {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t}\n\t}\n\n\tif ( a.graveyardPosition ) {\n\t\ta.graveyardPosition = a.graveyardPosition._getTransformedBySplitOperation( b );\n\t}\n\n\t// Case 3:\n\t//\n\t// Position where operation `b` inserted a new node after split is the same as the operation `a` split position.\n\t// As in similar cases, there is ambiguity if the split should be before the new node (created by `b`) or after.\n\t//\n\tif ( a.splitPosition.isEqual( b.insertionPosition ) && context.abRelation == 'splitBefore' ) {\n\t\ta.howMany++;\n\n\t\treturn [ a ];\n\t}\n\n\t// Case 4:\n\t//\n\t// This is a mirror to the case 2. above.\n\t//\n\tif ( b.splitPosition.isEqual( a.insertionPosition ) && context.baRelation == 'splitBefore' ) {\n\t\tconst newPositionPath = b.insertionPosition.path.slice();\n\t\tnewPositionPath.push( 0 );\n\n\t\tconst newPosition = new Position( b.insertionPosition.root, newPositionPath );\n\t\tconst moveOp = new MoveOperation( a.insertionPosition, 1, newPosition, 0 );\n\n\t\treturn [ a, moveOp ];\n\t}\n\n\t// The default case.\n\t//\n\tif ( a.splitPosition.hasSameParentAs( b.splitPosition ) && a.splitPosition.offset < b.splitPosition.offset ) {\n\t\ta.howMany -= b.howMany;\n\t}\n\n\ta.splitPosition = a.splitPosition._getTransformedBySplitOperation( b );\n\ta.insertionPosition = SplitOperation.getInsertionPosition( a.splitPosition );\n\n\treturn [ a ];\n} );\n\n// Checks whether `MoveOperation` `targetPosition` is inside a node from the moved range of the other `MoveOperation`.\n//\n// @private\n// @param {module:engine/model/operation/moveoperation~MoveOperation} a\n// @param {module:engine/model/operation/moveoperation~MoveOperation} b\n// @returns {Boolean}\nfunction _moveTargetIntoMovedRange( a, b ) {\n\treturn a.targetPosition._getTransformedByDeletion( b.sourcePosition, b.howMany ) === null;\n}\n\n// Helper function for `MoveOperation` x `MoveOperation` transformation. Converts given ranges and target position to\n// move operations and returns them.\n//\n// Ranges and target position will be transformed on-the-fly when generating operations.\n//\n// Given `ranges` should be in the order of how they were in the original transformed operation.\n//\n// Given `targetPosition` is the target position of the first range from `ranges`.\n//\n// @private\n// @param {Array.<module:engine/model/range~Range>} ranges\n// @param {module:engine/model/position~Position} targetPosition\n// @returns {Array.<module:engine/model/operation/moveoperation~MoveOperation>}\nfunction _makeMoveOperationsFromRanges( ranges, targetPosition ) {\n\t// At this moment we have some ranges and a target position, to which those ranges should be moved.\n\t// Order in `ranges` array is the go-to order of after transformation.\n\t//\n\t// We are almost done. We have `ranges` and `targetPosition` to make operations from.\n\t// Unfortunately, those operations may affect each other. Precisely, first operation after move\n\t// may affect source range and target position of second and third operation. Same with second\n\t// operation affecting third.\n\t//\n\t// We need to fix those source ranges and target positions once again, before converting `ranges` to operations.\n\tconst operations = [];\n\n\t// Keep in mind that nothing will be transformed if there is just one range in `ranges`.\n\tfor ( let i = 0; i < ranges.length; i++ ) {\n\t\t// Create new operation out of a range and target position.\n\t\tconst range = ranges[ i ];\n\t\tconst op = new MoveOperation(\n\t\t\trange.start,\n\t\t\trange.end.offset - range.start.offset,\n\t\t\ttargetPosition,\n\t\t\t0\n\t\t);\n\n\t\toperations.push( op );\n\n\t\t// Transform other ranges by the generated operation.\n\t\tfor ( let j = i + 1; j < ranges.length; j++ ) {\n\t\t\t// All ranges in `ranges` array should be:\n\t\t\t//\n\t\t\t// * non-intersecting (these are part of original operation source range), and\n\t\t\t// * `targetPosition` does not target into them (opposite would mean that transformed operation targets \"inside itself\").\n\t\t\t//\n\t\t\t// This means that the transformation will be \"clean\" and always return one result.\n\t\t\tranges[ j ] = ranges[ j ]._getTransformedByMove( op.sourcePosition, op.targetPosition, op.howMany )[ 0 ];\n\t\t}\n\n\t\ttargetPosition = targetPosition._getTransformedByMove( op.sourcePosition, op.targetPosition, op.howMany );\n\t}\n\n\treturn operations;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module undo/basecommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport { transformSets } from '@ckeditor/ckeditor5-engine/src/model/operation/transform';\n\n/**\n * Base class for undo feature commands: {@link module:undo/undocommand~UndoCommand} and {@link module:undo/redocommand~RedoCommand}.\n *\n * @protected\n * @extends module:core/command~Command\n */\nexport default class BaseCommand extends Command {\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * Stack of items stored by the command. These are pairs of:\n\t\t *\n\t\t * * {@link module:engine/model/batch~Batch batch} saved by the command,\n\t\t * * {@link module:engine/model/selection~Selection selection} state at the moment of saving the batch.\n\t\t *\n\t\t * @protected\n\t\t * @member {Array} #_stack\n\t\t */\n\t\tthis._stack = [];\n\n\t\t/**\n\t\t * Stores all batches that were created by this command.\n\t\t *\n\t\t * @protected\n\t\t * @member {WeakSet.<module:engine/model/batch~Batch>} #_createdBatches\n\t\t */\n\t\tthis._createdBatches = new WeakSet();\n\n\t\t// Refresh state, so the command is inactive right after initialization.\n\t\tthis.refresh();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.isEnabled = this._stack.length > 0;\n\t}\n\n\t/**\n\t * Stores a batch in the command, together with the selection state of the {@link module:engine/model/document~Document document}\n\t * created by the editor which this command is registered to.\n\t *\n\t * @param {module:engine/model/batch~Batch} batch The batch to add.\n\t */\n\taddBatch( batch ) {\n\t\tconst docSelection = this.editor.model.document.selection;\n\n\t\tconst selection = {\n\t\t\tranges: docSelection.hasOwnRange ? Array.from( docSelection.getRanges() ) : [],\n\t\t\tisBackward: docSelection.isBackward\n\t\t};\n\n\t\tthis._stack.push( { batch, selection } );\n\t\tthis.refresh();\n\t}\n\n\t/**\n\t * Removes all items from the stack.\n\t */\n\tclearStack() {\n\t\tthis._stack = [];\n\t\tthis.refresh();\n\t}\n\n\t/**\n\t * Restores the {@link module:engine/model/document~Document#selection document selection} state after a batch was undone.\n\t *\n\t * @protected\n\t * @param {Array.<module:engine/model/range~Range>} ranges Ranges to be restored.\n\t * @param {Boolean} isBackward A flag describing whether the restored range was selected forward or backward.\n\t * @param {Array.<module:engine/model/operation/operation~Operation>} operations Operations which has been applied\n\t * since selection has been stored.\n\t */\n\t_restoreSelection( ranges, isBackward, operations ) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\t// This will keep the transformed selection ranges.\n\t\tconst selectionRanges = [];\n\n\t\t// Transform all ranges from the restored selection.\n\t\tfor ( const range of ranges ) {\n\t\t\tconst transformed = transformSelectionRange( range, operations );\n\n\t\t\t// For each `range` from `ranges`, we take only one transformed range.\n\t\t\t// This is because we want to prevent situation where single-range selection\n\t\t\t// got transformed to multi-range selection. We will take the first range that\n\t\t\t// is not in the graveyard.\n\t\t\tconst newRange = transformed.find(\n\t\t\t\trange => range.start.root != document.graveyard\n\t\t\t);\n\n\t\t\t// `transformedRange` might be `undefined` if transformed range ended up in graveyard.\n\t\t\tif ( newRange ) {\n\t\t\t\tselectionRanges.push( newRange );\n\t\t\t}\n\t\t}\n\n\t\t// `selectionRanges` may be empty if all ranges ended up in graveyard. If that is the case, do not restore selection.\n\t\tif ( selectionRanges.length ) {\n\t\t\tmodel.change( writer => {\n\t\t\t\twriter.setSelection( selectionRanges, { backward: isBackward } );\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Undoes a batch by reversing that batch, transforming reversed batch and finally applying it.\n\t * This is a helper method for {@link #execute}.\n\t *\n\t * @protected\n\t * @param {module:engine/model/batch~Batch} batchToUndo The batch to be undone.\n\t * @param {module:engine/model/batch~Batch} undoingBatch The batch that will contain undoing changes.\n\t */\n\t_undo( batchToUndo, undoingBatch ) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\t// All changes done by the command execution will be saved as one batch.\n\t\tthis._createdBatches.add( undoingBatch );\n\n\t\tconst operationsToUndo = batchToUndo.operations.slice().filter( operation => operation.isDocumentOperation );\n\t\toperationsToUndo.reverse();\n\n\t\t// We will process each operation from `batchToUndo`, in reverse order. If there were operations A, B and C in undone batch,\n\t\t// we need to revert them in reverse order, so first C' (reversed C), then B', then A'.\n\t\tfor ( const operationToUndo of operationsToUndo ) {\n\t\t\tconst nextBaseVersion = operationToUndo.baseVersion + 1;\n\t\t\tconst historyOperations = Array.from( document.history.getOperations( nextBaseVersion ) );\n\n\t\t\tconst transformedSets = transformSets(\n\t\t\t\t[ operationToUndo.getReversed() ],\n\t\t\t\thistoryOperations,\n\t\t\t\t{\n\t\t\t\t\tuseRelations: true,\n\t\t\t\t\tdocument: this.editor.model.document,\n\t\t\t\t\tpadWithNoOps: false,\n\t\t\t\t\tforceWeakRemove: true\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tconst reversedOperations = transformedSets.operationsA;\n\n\t\t\t// After reversed operation has been transformed by all history operations, apply it.\n\t\t\tfor ( const operation of reversedOperations ) {\n\t\t\t\t// Before applying, add the operation to the `undoingBatch`.\n\t\t\t\tundoingBatch.addOperation( operation );\n\t\t\t\tmodel.applyOperation( operation );\n\n\t\t\t\tdocument.history.setOperationAsUndone( operationToUndo, operation );\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Transforms given range `range` by given `operations`.\n// Returns an array containing one or more ranges, which are result of the transformation.\nfunction transformSelectionRange( range, operations ) {\n\tconst transformed = range.getTransformedByOperations( operations );\n\n\t// After `range` got transformed, we have an array of ranges. Some of those\n\t// ranges may be \"touching\" -- they can be next to each other and could be merged.\n\t// First, we have to sort those ranges to assure that they are in order.\n\ttransformed.sort( ( a, b ) => a.start.isBefore( b.start ) ? -1 : 1 );\n\n\t// Then, we check if two consecutive ranges are touching.\n\tfor ( let i = 1; i < transformed.length; i++ ) {\n\t\tconst a = transformed[ i - 1 ];\n\t\tconst b = transformed[ i ];\n\n\t\tif ( a.end.isTouching( b.start ) ) {\n\t\t\t// And join them together if they are.\n\t\t\ta.end = b.end;\n\t\t\ttransformed.splice( i, 1 );\n\t\t\ti--;\n\t\t}\n\t}\n\n\treturn transformed;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module undo/undocommand\n */\n\nimport BaseCommand from './basecommand';\n\n/**\n * The undo command stores {@link module:engine/model/batch~Batch batches} applied to the\n * {@link module:engine/model/document~Document document} and is able to undo a batch by reversing it and transforming by\n * batches from {@link module:engine/model/document~Document#history history} that happened after the reversed batch.\n *\n * The undo command also takes care of restoring the {@link module:engine/model/document~Document#selection document selection}.\n *\n * @extends module:undo/basecommand~BaseCommand\n */\nexport default class UndoCommand extends BaseCommand {\n\t/**\n\t * Executes the command. This method reverts a {@link module:engine/model/batch~Batch batch} added to the command's stack, transforms\n\t * and applies the reverted version on the {@link module:engine/model/document~Document document} and removes the batch from the stack.\n\t * Then, it restores the {@link module:engine/model/document~Document#selection document selection}.\n\t *\n\t * @fires execute\n\t * @fires revert\n\t * @param {module:engine/model/batch~Batch} [batch] A batch that should be undone. If not set, the last added batch will be undone.\n\t */\n\texecute( batch = null ) {\n\t\t// If batch is not given, set `batchIndex` to the last index in command stack.\n\t\tconst batchIndex = batch ? this._stack.findIndex( a => a.batch == batch ) : this._stack.length - 1;\n\n\t\tconst item = this._stack.splice( batchIndex, 1 )[ 0 ];\n\t\tconst undoingBatch = this.editor.model.createBatch();\n\n\t\t// All changes has to be done in one `enqueueChange` callback so other listeners will not\n\t\t// step between consecutive operations, or won't do changes to the document before selection is properly restored.\n\t\tthis.editor.model.enqueueChange( undoingBatch, () => {\n\t\t\tthis._undo( item.batch, undoingBatch );\n\n\t\t\tconst operations = this.editor.model.document.history.getOperations( item.batch.baseVersion );\n\t\t\tthis._restoreSelection( item.selection.ranges, item.selection.isBackward, operations );\n\n\t\t\tthis.fire( 'revert', item.batch, undoingBatch );\n\t\t} );\n\n\t\tthis.refresh();\n\t}\n}\n\n/**\n * Fired when execution of the command reverts some batch.\n *\n * @event revert\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module undo/redocommand\n */\n\nimport BaseCommand from './basecommand';\n\n/**\n * The redo command stores {@link module:engine/model/batch~Batch batches} that were used to undo a batch by\n * {@link module:undo/undocommand~UndoCommand}. It is able to redo a previously undone batch by reversing the undoing\n * batches created by `UndoCommand`. The reversed batch is transformed by all the batches from\n * {@link module:engine/model/document~Document#history history} that happened after the reversed undo batch.\n *\n * The redo command also takes care of restoring the {@link module:engine/model/document~Document#selection document selection}.\n *\n * @extends module:undo/basecommand~BaseCommand\n */\nexport default class RedoCommand extends BaseCommand {\n\t/**\n\t * Executes the command. This method reverts the last {@link module:engine/model/batch~Batch batch} added to\n\t * the command's stack, applies the reverted and transformed version on the\n\t * {@link module:engine/model/document~Document document} and removes the batch from the stack.\n\t * Then, it restores the {@link module:engine/model/document~Document#selection document selection}.\n\t *\n\t * @fires execute\n\t */\n\texecute() {\n\t\tconst item = this._stack.pop();\n\t\tconst redoingBatch = this.editor.model.createBatch();\n\n\t\t// All changes have to be done in one `enqueueChange` callback so other listeners will not step between consecutive\n\t\t// operations, or won't do changes to the document before selection is properly restored.\n\t\tthis.editor.model.enqueueChange( redoingBatch, () => {\n\t\t\tconst lastOperation = item.batch.operations[ item.batch.operations.length - 1 ];\n\t\t\tconst nextBaseVersion = lastOperation.baseVersion + 1;\n\t\t\tconst operations = this.editor.model.document.history.getOperations( nextBaseVersion );\n\n\t\t\tthis._restoreSelection( item.selection.ranges, item.selection.isBackward, operations );\n\t\t\tthis._undo( item.batch, redoingBatch );\n\t\t} );\n\n\t\tthis.refresh();\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module undo/undoediting\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport UndoCommand from './undocommand';\nimport RedoCommand from './redocommand';\n\n/**\n * The undo engine feature.\n *\n * It introduces the `'undo'` and `'redo'` commands to the editor.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class UndoEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The command that manages undo {@link module:engine/model/batch~Batch batches} stack (history).\n\t\t * Created and registered during the {@link #init feature initialization}.\n\t\t *\n\t\t * @private\n\t\t * @member {module:undo/undocommand~UndoCommand} #_undoCommand\n\t\t */\n\n\t\t/**\n\t\t * The command that manages redo {@link module:engine/model/batch~Batch batches} stack (history).\n\t\t * Created and registered during the {@link #init feature initialization}.\n\t\t *\n\t\t * @private\n\t\t * @member {module:undo/undocommand~UndoCommand} #_redoCommand\n\t\t */\n\n\t\t/**\n\t\t * Keeps track of which batches were registered in undo.\n\t\t *\n\t\t * @private\n\t\t * @member {WeakSet.<module:engine/model/batch~Batch>}\n\t\t */\n\t\tthis._batchRegistry = new WeakSet();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\n\t\t// Create commands.\n\t\tthis._undoCommand = new UndoCommand( editor );\n\t\tthis._redoCommand = new RedoCommand( editor );\n\n\t\t// Register command to the editor.\n\t\teditor.commands.add( 'undo', this._undoCommand );\n\t\teditor.commands.add( 'redo', this._redoCommand );\n\n\t\tthis.listenTo( editor.model, 'applyOperation', ( evt, args ) => {\n\t\t\tconst operation = args[ 0 ];\n\n\t\t\t// Do not register batch if the operation is not a document operation.\n\t\t\t// This prevents from creating empty undo steps, where all operations where non-document operations.\n\t\t\t// Non-document operations creates and alters content in detached tree fragments (for example, document fragments).\n\t\t\t// Most of time this is preparing data before it is inserted into actual tree (for example during copy & paste).\n\t\t\t// Such operations should not be reversed.\n\t\t\tif ( !operation.isDocumentOperation ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst batch = operation.batch;\n\n\t\t\t// If changes are not a part of a batch or this is not a new batch, omit those changes.\n\t\t\tif ( this._batchRegistry.has( batch ) || batch.type == 'transparent' ) {\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tif ( this._redoCommand._createdBatches.has( batch ) ) {\n\t\t\t\t\t// If this batch comes from `redoCommand`, add it to `undoCommand` stack.\n\t\t\t\t\tthis._undoCommand.addBatch( batch );\n\t\t\t\t} else if ( !this._undoCommand._createdBatches.has( batch ) ) {\n\t\t\t\t\t// A default batch - these are new changes in the document, not introduced by undo feature.\n\t\t\t\t\t// Add them to `undoCommand` stack and clear `redoCommand` stack.\n\t\t\t\t\tthis._undoCommand.addBatch( batch );\n\t\t\t\t\tthis._redoCommand.clearStack();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add the batch to the registry so it will not be processed again.\n\t\t\tthis._batchRegistry.add( batch );\n\t\t}, { priority: 'highest' } );\n\n\t\tthis.listenTo( this._undoCommand, 'revert', ( evt, undoneBatch, undoingBatch ) => {\n\t\t\tthis._redoCommand.addBatch( undoingBatch );\n\t\t} );\n\n\t\teditor.keystrokes.set( 'CTRL+Z', 'undo' );\n\t\teditor.keystrokes.set( 'CTRL+Y', 'redo' );\n\t\teditor.keystrokes.set( 'CTRL+SHIFT+Z', 'redo' );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module undo/undoui\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport undoIcon from '../theme/icons/undo.svg';\nimport redoIcon from '../theme/icons/redo.svg';\n/**\n * The undo UI feature. It introduces the `'undo'` and `'redo'` buttons to the editor.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class UndoUI extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const t = editor.t;\n this._addButton('undo', t('ae'), 'CTRL+Z', undoIcon);\n this._addButton('redo', t('af'), 'CTRL+Y', redoIcon);\n }\n /**\n\t * Creates a button for the specified command.\n\t *\n\t * @private\n\t * @param {String} name Command name.\n\t * @param {String} label Button label.\n\t * @param {String} keystroke Command keystroke.\n\t * @param {String} Icon Source of the icon.\n\t */\n _addButton(name, label, keystroke, Icon) {\n const editor = this.editor;\n editor.ui.componentFactory.add(name, locale => {\n const command = editor.commands.get(name);\n const view = new ButtonView(locale);\n view.set({\n label,\n icon: Icon,\n keystroke,\n tooltip: true\n });\n view.bind('isEnabled').to(command, 'isEnabled');\n this.listenTo(view, 'execute', () => editor.execute(name));\n return view;\n });\n }\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module undo/undo\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport UndoEditing from './undoediting';\nimport UndoUI from './undoui';\n\n/**\n * The undo feature.\n *\n * This is a \"glue\" plugin which loads the {@link module:undo/undoediting~UndoEditing undo editing feature}\n * and {@link module:undo/undoui~UndoUI undo UI feature}.\n *\n * Below is the explanation of the undo mechanism working together with {@link module:engine/model/history~History History}:\n *\n * Whenever a {@link module:engine/model/operation/operation~Operation operation} is applied to the\n * {@link module:engine/model/document~Document document}, it is saved to `History` as is.\n * The {@link module:engine/model/batch~Batch batch} that owns that operation is also saved, in\n * {@link module:undo/undocommand~UndoCommand}, together with the selection that was present in the document before the\n * operation was applied. A batch is saved instead of the operation because changes are undone batch-by-batch, not operation-by-operation\n * and a batch is seen as one undo step.\n *\n * After some changes happen to the document, the `History` and `UndoCommand` stack can be represented as follows:\n *\n *\t\t History Undo stack\n *\t\t============== ==================================\n *\t\t[operation A1] [batch A]\n *\t\t[operation B1] [batch B]\n *\t\t[operation B2] [batch C]\n *\t\t[operation C1]\n *\t\t[operation C2]\n *\t\t[operation B3]\n *\t\t[operation C3]\n *\n * Where operations starting with the same letter are from same batch.\n *\n * Undoing a batch means that a set of operations which will reverse the effects of that batch needs to be generated.\n * For example, if a batch added several letters, undoing the batch should remove them. It is important to apply undoing\n * operations in the reversed order, so if a batch has operation `X`, `Y`, `Z`, reversed operations `Zr`, `Yr` and `Xr`\n * need to be applied. Otherwise reversed operation `Xr` would operate on a wrong document state, because operation `X`\n * does not know that operations `Y` and `Z` happened.\n *\n * After operations from an undone batch got {@link module:engine/model/operation/operation~Operation#getReversed reversed},\n * one needs to make sure if they are ready to be applied. In the scenario above, operation `C3` is the last operation and `C3r`\n * bases on up-to-date document state, so it can be applied to the document.\n *\n *\t\t History Undo stack\n *\t\t================= ==================================\n *\t\t[ operation A1 ] [ batch A ]\n *\t\t[ operation B1 ] [ batch B ]\n *\t\t[ operation B2 ] [ processing undoing batch C ]\n *\t\t[ operation C1 ]\n *\t\t[ operation C2 ]\n *\t\t[ operation B3 ]\n *\t\t[ operation C3 ]\n *\t\t[ operation C3r ]\n *\n * Next is operation `C2`, reversed to `C2r`. `C2r` bases on `C2`, so it bases on the wrong document state. It needs to be\n * transformed by operations from history that happened after it, so it \"knows\" about them. Let us assume that `C2' = C2r * B3 * C3 * C3r`,\n * where `*` means \"transformed by\". Rest of operations from that batch are processed in the same fashion.\n *\n *\t\t History Undo stack Redo stack\n *\t\t================= ================================== ==================================\n *\t\t[ operation A1 ] [ batch A ] [ batch Cr ]\n *\t\t[ operation B1 ] [ batch B ]\n *\t\t[ operation B2 ]\n *\t\t[ operation C1 ]\n *\t\t[ operation C2 ]\n *\t\t[ operation B3 ]\n *\t\t[ operation C3 ]\n *\t\t[ operation C3r ]\n *\t\t[ operation C2' ]\n *\t\t[ operation C1' ]\n *\n * Selective undo works on the same basis, however, instead of undoing the last batch in the undo stack, any batch can be undone.\n * The same algorithm applies: operations from a batch (i.e. `A1`) are reversed and then transformed by operations stored in history.\n *\n * Redo also is very similar to undo. It has its own stack that is filled with undoing (reversed batches). Operations from\n * batch that is re-done are reversed-back, transformed in proper order and applied to the document.\n *\n *\t\t History Undo stack Redo stack\n *\t\t================= ================================== ==================================\n *\t\t[ operation A1 ] [ batch A ]\n *\t\t[ operation B1 ] [ batch B ]\n *\t\t[ operation B2 ] [ batch Crr ]\n *\t\t[ operation C1 ]\n *\t\t[ operation C2 ]\n *\t\t[ operation B3 ]\n *\t\t[ operation C3 ]\n *\t\t[ operation C3r ]\n *\t\t[ operation C2' ]\n *\t\t[ operation C1' ]\n *\t\t[ operation C1'r]\n *\t\t[ operation C2'r]\n *\t\t[ operation C3rr]\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Undo extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ UndoEditing, UndoUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Undo';\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor.data, 'ready', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n/**\n * Array of loaded plugins.\n *\n * @typedef {Array.<module:core/plugin~PluginInterface>} module:core/plugin~LoadedPlugins\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/* globals window, document */\n\n/**\n * @module adapter-ckfinder/utils\n */\n\nconst TOKEN_COOKIE_NAME = 'ckCsrfToken';\nconst TOKEN_LENGTH = 40;\nconst tokenCharset = 'abcdefghijklmnopqrstuvwxyz0123456789';\n\n/**\n * Returns the CSRF token value. The value is a hash stored in `document.cookie`\n * under the `ckCsrfToken` key. The CSRF token can be used to secure the communication\n * between the web browser and the CKFinder server.\n *\n * @returns {String}\n */\nexport function getCsrfToken() {\n\tlet token = getCookie( TOKEN_COOKIE_NAME );\n\n\tif ( !token || token.length != TOKEN_LENGTH ) {\n\t\ttoken = generateToken( TOKEN_LENGTH );\n\t\tsetCookie( TOKEN_COOKIE_NAME, token );\n\t}\n\n\treturn token;\n}\n\n/**\n * Returns the value of the cookie with a given name or `null` if the cookie is not found.\n *\n * @param {String} name\n * @returns {String|null}\n */\nexport function getCookie( name ) {\n\tname = name.toLowerCase();\n\tconst parts = document.cookie.split( ';' );\n\n\tfor ( const part of parts ) {\n\t\tconst pair = part.split( '=' );\n\t\tconst key = decodeURIComponent( pair[ 0 ].trim().toLowerCase() );\n\n\t\tif ( key === name ) {\n\t\t\treturn decodeURIComponent( pair[ 1 ] );\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Sets the value of the cookie with a given name.\n *\n * @param {String} name\n * @param {String} value\n */\nexport function setCookie( name, value ) {\n\tdocument.cookie = encodeURIComponent( name ) + '=' + encodeURIComponent( value ) + ';path=/';\n}\n\n// Generates the CSRF token with the given length.\n//\n// @private\n// @param {Number} length\n// @returns {string}\nfunction generateToken( length ) {\n\tlet result = '';\n\tconst randValues = new Uint8Array( length );\n\n\twindow.crypto.getRandomValues( randValues );\n\n\tfor ( let j = 0; j < randValues.length; j++ ) {\n\t\tconst character = tokenCharset.charAt( randValues[ j ] % tokenCharset.length );\n\t\tresult += Math.random() > 0.5 ? character.toUpperCase() : character;\n\t}\n\n\treturn result;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/* globals XMLHttpRequest, FormData */\n/**\n * @module adapter-ckfinder/uploadadapter\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport FileRepository from '@ckeditor/ckeditor5-upload/src/filerepository';\nimport { getCsrfToken } from './utils';\n/**\n * A plugin that enables file uploads in CKEditor 5 using the CKFinder server–side connector.\n *\n * See the {@glink features/image-upload/ckfinder \"CKFinder file manager integration\" guide} to learn how to configure\n * and use this feature as well as find out more about the full integration with the file manager\n * provided by the {@link module:ckfinder/ckfinder~CKFinder} plugin.\n *\n * Check out the {@glink features/image-upload/image-upload comprehensive \"Image upload overview\"} to learn about\n * other ways to upload images into CKEditor 5.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class CKFinderUploadAdapter extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n static get requires() {\n return [FileRepository];\n }\n /**\n\t * @inheritDoc\n\t */\n static get pluginName() {\n return 'CKFinderUploadAdapter';\n }\n /**\n\t * @inheritDoc\n\t */\n init() {\n const url = this.editor.config.get('ckfinder.uploadUrl');\n if (!url) {\n return;\n }\n // Register CKFinderAdapter\n this.editor.plugins.get(FileRepository).createUploadAdapter = loader => new UploadAdapter(loader, url, this.editor.t);\n }\n}\n/**\n * Upload adapter for CKFinder.\n *\n * @private\n * @implements module:upload/filerepository~UploadAdapter\n */\nclass UploadAdapter {\n /**\n\t * Creates a new adapter instance.\n\t *\n\t * @param {module:upload/filerepository~FileLoader} loader\n\t * @param {String} url\n\t * @param {module:utils/locale~Locale#t} t\n\t */\n constructor(loader, url, t) {\n /**\n\t\t * FileLoader instance to use during the upload.\n\t\t *\n\t\t * @member {module:upload/filerepository~FileLoader} #loader\n\t\t */\n this.loader = loader;\n /**\n\t\t * Upload URL.\n\t\t *\n\t\t * @member {String} #url\n\t\t */\n this.url = url;\n /**\n\t\t * Locale translation method.\n\t\t *\n\t\t * @member {module:utils/locale~Locale#t} #t\n\t\t */\n this.t = t;\n }\n /**\n\t * Starts the upload process.\n\t *\n\t * @see module:upload/filerepository~UploadAdapter#upload\n\t * @returns {Promise.<Object>}\n\t */\n upload() {\n return this.loader.file.then(file => {\n return new Promise((resolve, reject) => {\n this._initRequest();\n this._initListeners(resolve, reject, file);\n this._sendRequest(file);\n });\n });\n }\n /**\n\t * Aborts the upload process.\n\t *\n\t * @see module:upload/filerepository~UploadAdapter#abort\n\t */\n abort() {\n if (this.xhr) {\n this.xhr.abort();\n }\n }\n /**\n\t * Initializes the XMLHttpRequest object.\n\t *\n\t * @private\n\t */\n _initRequest() {\n const xhr = this.xhr = new XMLHttpRequest();\n xhr.open('POST', this.url, true);\n xhr.responseType = 'json';\n }\n /**\n\t * Initializes XMLHttpRequest listeners.\n\t *\n\t * @private\n\t * @param {Function} resolve Callback function to be called when the request is successful.\n\t * @param {Function} reject Callback function to be called when the request cannot be completed.\n\t * @param {File} file File instance to be uploaded.\n\t */\n _initListeners(resolve, reject, file) {\n const xhr = this.xhr;\n const loader = this.loader;\n const t = this.t;\n const genericError = t('a') + ` ${ file.name }.`;\n xhr.addEventListener('error', () => reject(genericError));\n xhr.addEventListener('abort', () => reject());\n xhr.addEventListener('load', () => {\n const response = xhr.response;\n if (!response || !response.uploaded) {\n return reject(response && response.error && response.error.message ? response.error.message : genericError);\n }\n resolve({ default: response.url });\n });\n // Upload progress when it's supported.\n /* istanbul ignore else */\n if (xhr.upload) {\n xhr.upload.addEventListener('progress', evt => {\n if (evt.lengthComputable) {\n loader.uploadTotal = evt.total;\n loader.uploaded = evt.loaded;\n }\n });\n }\n }\n /**\n\t * Prepares the data and sends the request.\n\t *\n\t * @private\n\t * @param {File} file File instance to be uploaded.\n\t */\n _sendRequest(file) {\n // Prepare form data.\n const data = new FormData();\n data.append('upload', file);\n data.append('ckCsrfToken', getCsrfToken());\n // Send request.\n this.xhr.send(data);\n }\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module autoformat/blockautoformatediting\n */\n\nimport LiveRange from '@ckeditor/ckeditor5-engine/src/model/liverange';\n\n/**\n * The block autoformatting engine. It allows to format various block patterns. For example,\n * it can be configured to turn a paragraph starting with `*` and followed by a space into a list item.\n *\n * The autoformatting operation is integrated with the undo manager,\n * so the autoformatting step can be undone if the user's intention was not to format the text.\n *\n * See the constructors documentation to learn how to create custom inline autoformatters. You can also use\n * the {@link module:autoformat/autoformat~Autoformat} feature which enables a set of default autoformatters\n * (lists, headings, bold and italic).\n */\nexport default class BlockAutoformatEditing {\n\t/**\n\t * Creates a listener triggered on `change` event in the document.\n\t * Calls the callback when inserted text matches the regular expression or the command name\n\t * if provided instead of the callback.\n\t *\n\t * Examples of usage:\n\t *\n\t * To convert a paragraph to heading 1 when `- ` is typed, using just the command name:\n\t *\n\t *\t\tnew BlockAutoformatEditing( editor, /^\\- $/, 'heading1' );\n\t *\n\t * To convert a paragraph to heading 1 when `- ` is typed, using just the callback:\n\t *\n\t *\t\tnew BlockAutoformatEditing( editor, /^\\- $/, ( context ) => {\n\t *\t\t\tconst { match } = context;\n\t *\t\t\tconst headingLevel = match[ 1 ].length;\n\t *\n\t *\t\t\teditor.execute( 'heading', {\n\t *\t\t\t\tformatId: `heading${ headingLevel }`\n\t *\t\t\t} );\n\t * \t\t} );\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {RegExp} pattern The regular expression to execute on just inserted text.\n\t * @param {Function|String} callbackOrCommand The callback to execute or the command to run when the text is matched.\n\t * In case of providing the callback, it receives the following parameter:\n\t * * {Object} match RegExp.exec() result of matching the pattern to inserted text.\n\t */\n\tconstructor( editor, pattern, callbackOrCommand ) {\n\t\tlet callback;\n\t\tlet command = null;\n\n\t\tif ( typeof callbackOrCommand == 'function' ) {\n\t\t\tcallback = callbackOrCommand;\n\t\t} else {\n\t\t\t// We assume that the actual command name was provided.\n\t\t\tcommand = editor.commands.get( callbackOrCommand );\n\n\t\t\tcallback = () => {\n\t\t\t\teditor.execute( callbackOrCommand );\n\t\t\t};\n\t\t}\n\n\t\teditor.model.document.on( 'change', ( evt, batch ) => {\n\t\t\tif ( command && !command.isEnabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( batch.type == 'transparent' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst changes = Array.from( editor.model.document.differ.getChanges() );\n\t\t\tconst entry = changes[ 0 ];\n\n\t\t\t// Typing is represented by only a single change.\n\t\t\tif ( changes.length != 1 || entry.type !== 'insert' || entry.name != '$text' || entry.length != 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst item = entry.position.textNode || entry.position.nodeAfter;\n\n\t\t\tif ( !item.parent.is( 'paragraph' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst match = pattern.exec( item.data );\n\n\t\t\tif ( !match ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Use enqueueChange to create new batch to separate typing batch from the auto-format changes.\n\t\t\teditor.model.enqueueChange( writer => {\n\t\t\t\t// Matched range.\n\t\t\t\tconst start = writer.createPositionAt( item.parent, 0 );\n\t\t\t\tconst end = writer.createPositionAt( item.parent, match[ 0 ].length );\n\t\t\t\tconst range = new LiveRange( start, end );\n\n\t\t\t\tconst wasChanged = callback( { match } );\n\n\t\t\t\t// Remove matched text.\n\t\t\t\tif ( wasChanged !== false ) {\n\t\t\t\t\twriter.remove( range );\n\t\t\t\t}\n\n\t\t\t\trange.detach();\n\t\t\t} );\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module autoformat/inlineautoformatediting\n */\n\n/**\n * The inline autoformatting engine. It allows to format various inline patterns. For example,\n * it can be configured to make \"foo\" bold when typed `**foo**` (the `**` markers will be removed).\n *\n * The autoformatting operation is integrated with the undo manager,\n * so the autoformatting step can be undone if the user's intention was not to format the text.\n *\n * See the constructors documentation to learn how to create custom inline autoformatters. You can also use\n * the {@link module:autoformat/autoformat~Autoformat} feature which enables a set of default autoformatters\n * (lists, headings, bold and italic).\n */\nexport default class InlineAutoformatEditing {\n\t/**\n\t * Enables autoformatting mechanism for a given {@link module:core/editor/editor~Editor}.\n\t *\n\t * It formats the matched text by applying the given model attribute or by running the provided formatting callback.\n\t * On every change applied to the model the autoformatting engine checks the text on the left of the selection\n\t * and executes the provided action if the text matches given criteria (regular expression or callback).\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {Function|RegExp} testRegexpOrCallback The regular expression or callback to execute on text.\n\t * Provided regular expression *must* have three capture groups. The first and the third capture group\n\t * should match opening and closing delimiters. The second capture group should match the text to format.\n\t *\n\t *\t\t// Matches the `**bold text**` pattern.\n\t *\t\t// There are three capturing groups:\n\t *\t\t// - The first to match the starting `**` delimiter.\n\t *\t\t// - The second to match the text to format.\n\t *\t\t// - The third to match the ending `**` delimiter.\n\t *\t\tnew InlineAutoformatEditing( editor, /(\\*\\*)([^\\*]+?)(\\*\\*)$/g, 'bold' );\n\t *\n\t * When a function is provided instead of the regular expression, it will be executed with the text to match as a parameter.\n\t * The function should return proper \"ranges\" to delete and format.\n\t *\n\t *\t\t{\n\t *\t\t\tremove: [\n\t *\t\t\t\t[ 0, 1 ],\t// Remove the first letter from the given text.\n\t *\t\t\t\t[ 5, 6 ]\t// Remove the 6th letter from the given text.\n\t *\t\t\t],\n\t *\t\t\tformat: [\n\t *\t\t\t\t[ 1, 5 ]\t// Format all letters from 2nd to 5th.\n\t *\t\t\t]\n\t *\t\t}\n\t *\n\t * @param {Function|String} attributeOrCallback The name of attribute to apply on matching text or a callback for manual\n\t * formatting. If callback is passed it should return `false` if changes should not be applied (e.g. if a command is disabled).\n\t *\n\t *\t\t// Use attribute name:\n\t *\t\tnew InlineAutoformatEditing( editor, /(\\*\\*)([^\\*]+?)(\\*\\*)$/g, 'bold' );\n\t *\n\t *\t\t// Use formatting callback:\n\t *\t\tnew InlineAutoformatEditing( editor, /(\\*\\*)([^\\*]+?)(\\*\\*)$/g, ( writer, rangesToFormat ) => {\n\t *\t\t\tconst command = editor.commands.get( 'bold' );\n\t *\n\t *\t\t\tif ( !command.isEnabled ) {\n\t *\t\t\t\treturn false;\n\t *\t\t\t}\n\t *\n\t *\t\t\tconst validRanges = editor.model.schema.getValidRanges( rangesToFormat, 'bold' );\n\t *\n\t *\t\t\tfor ( let range of validRanges ) {\n\t *\t\t\t\twriter.setAttribute( 'bold', true, range );\n\t *\t\t\t}\n\t *\t\t} );\n\t */\n\tconstructor( editor, testRegexpOrCallback, attributeOrCallback ) {\n\t\tlet regExp;\n\t\tlet attributeKey;\n\t\tlet testCallback;\n\t\tlet formatCallback;\n\n\t\tif ( testRegexpOrCallback instanceof RegExp ) {\n\t\t\tregExp = testRegexpOrCallback;\n\t\t} else {\n\t\t\ttestCallback = testRegexpOrCallback;\n\t\t}\n\n\t\tif ( typeof attributeOrCallback == 'string' ) {\n\t\t\tattributeKey = attributeOrCallback;\n\t\t} else {\n\t\t\tformatCallback = attributeOrCallback;\n\t\t}\n\n\t\t// A test callback run on changed text.\n\t\ttestCallback = testCallback || ( text => {\n\t\t\tlet result;\n\t\t\tconst remove = [];\n\t\t\tconst format = [];\n\n\t\t\twhile ( ( result = regExp.exec( text ) ) !== null ) {\n\t\t\t\t// There should be full match and 3 capture groups.\n\t\t\t\tif ( result && result.length < 4 ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tlet {\n\t\t\t\t\tindex,\n\t\t\t\t\t'1': leftDel,\n\t\t\t\t\t'2': content,\n\t\t\t\t\t'3': rightDel\n\t\t\t\t} = result;\n\n\t\t\t\t// Real matched string - there might be some non-capturing groups so we need to recalculate starting index.\n\t\t\t\tconst found = leftDel + content + rightDel;\n\t\t\t\tindex += result[ 0 ].length - found.length;\n\n\t\t\t\t// Start and End offsets of delimiters to remove.\n\t\t\t\tconst delStart = [\n\t\t\t\t\tindex,\n\t\t\t\t\tindex + leftDel.length\n\t\t\t\t];\n\t\t\t\tconst delEnd = [\n\t\t\t\t\tindex + leftDel.length + content.length,\n\t\t\t\t\tindex + leftDel.length + content.length + rightDel.length\n\t\t\t\t];\n\n\t\t\t\tremove.push( delStart );\n\t\t\t\tremove.push( delEnd );\n\n\t\t\t\tformat.push( [ index + leftDel.length, index + leftDel.length + content.length ] );\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tremove,\n\t\t\t\tformat\n\t\t\t};\n\t\t} );\n\n\t\t// A format callback run on matched text.\n\t\tformatCallback = formatCallback || ( ( writer, rangesToFormat ) => {\n\t\t\tconst validRanges = editor.model.schema.getValidRanges( rangesToFormat, attributeKey );\n\n\t\t\tfor ( const range of validRanges ) {\n\t\t\t\twriter.setAttribute( attributeKey, true, range );\n\t\t\t}\n\n\t\t\t// After applying attribute to the text, remove given attribute from the selection.\n\t\t\t// This way user is able to type a text without attribute used by auto formatter.\n\t\t\twriter.removeSelectionAttribute( attributeKey );\n\t\t} );\n\n\t\teditor.model.document.on( 'change', ( evt, batch ) => {\n\t\t\tif ( batch.type == 'transparent' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst selection = editor.model.document.selection;\n\n\t\t\t// Do nothing if selection is not collapsed.\n\t\t\tif ( !selection.isCollapsed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst changes = Array.from( editor.model.document.differ.getChanges() );\n\t\t\tconst entry = changes[ 0 ];\n\n\t\t\t// Typing is represented by only a single change.\n\t\t\tif ( changes.length != 1 || entry.type !== 'insert' || entry.name != '$text' || entry.length != 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst block = selection.focus.parent;\n\t\t\tconst text = getText( block ).slice( 0, selection.focus.offset );\n\t\t\tconst testOutput = testCallback( text );\n\t\t\tconst rangesToFormat = testOutputToRanges( block, testOutput.format, editor.model );\n\t\t\tconst rangesToRemove = testOutputToRanges( block, testOutput.remove, editor.model );\n\n\t\t\tif ( !( rangesToFormat.length && rangesToRemove.length ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Use enqueueChange to create new batch to separate typing batch from the auto-format changes.\n\t\t\teditor.model.enqueueChange( writer => {\n\t\t\t\t// Apply format.\n\t\t\t\tconst hasChanged = formatCallback( writer, rangesToFormat );\n\n\t\t\t\t// Strict check on `false` to have backward compatibility (when callbacks were returning `undefined`).\n\t\t\t\tif ( hasChanged === false ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Remove delimiters - use reversed order to not mix the offsets while removing.\n\t\t\t\tfor ( const range of rangesToRemove.reverse() ) {\n\t\t\t\t\twriter.remove( range );\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n}\n\n// Returns whole text from parent element by adding all data from text nodes together.\n//\n// @private\n// @param {module:engine/model/element~Element} element\n// @returns {String}\nfunction getText( element ) {\n\treturn Array.from( element.getChildren() ).reduce( ( a, b ) => a + b.data, '' );\n}\n\n// Converts output of the test function provided to the InlineAutoformatEditing and converts it to the model ranges\n// inside provided block.\n//\n// @private\n// @param {module:engine/model/element~Element} block\n// @param {Array.<Array>} arrays\n// @param {module:engine/model/model~Model} model\nfunction testOutputToRanges( block, arrays, model ) {\n\treturn arrays\n\t\t.filter( array => ( array[ 0 ] !== undefined && array[ 1 ] !== undefined ) )\n\t\t.map( array => {\n\t\t\treturn model.createRange( model.createPositionAt( block, array[ 0 ] ), model.createPositionAt( block, array[ 1 ] ) );\n\t\t} );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor.data, 'ready', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n/**\n * Array of loaded plugins.\n *\n * @typedef {Array.<module:core/plugin~PluginInterface>} module:core/plugin~LoadedPlugins\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module autoformat/autoformat\n */\n\nimport BlockAutoformatEditing from './blockautoformatediting';\nimport InlineAutoformatEditing from './inlineautoformatediting';\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\n/**\n * Enables a set of predefined autoformatting actions.\n *\n * For a detailed overview, check the {@glink features/autoformat Autoformatting feature documentation}\n * and the {@glink api/autoformat package page}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Autoformat extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Autoformat';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tafterInit() {\n\t\tthis._addListAutoformats();\n\t\tthis._addBasicStylesAutoformats();\n\t\tthis._addHeadingAutoformats();\n\t\tthis._addBlockQuoteAutoformats();\n\t}\n\n\t/**\n\t * Adds autoformatting related to the {@link module:list/list~List}.\n\t *\n\t * When typed:\n\t * - `* ` or `- ` &ndash; A paragraph will be changed to a bulleted list.\n\t * - `1. ` or `1) ` &ndash; A paragraph will be changed to a numbered list (\"1\" can be any digit or a list of digits).\n\t *\n\t * @private\n\t */\n\t_addListAutoformats() {\n\t\tconst commands = this.editor.commands;\n\n\t\tif ( commands.get( 'bulletedList' ) ) {\n\t\t\t// eslint-disable-next-line no-new\n\t\t\tnew BlockAutoformatEditing( this.editor, /^[*-]\\s$/, 'bulletedList' );\n\t\t}\n\n\t\tif ( commands.get( 'numberedList' ) ) {\n\t\t\t// eslint-disable-next-line no-new\n\t\t\tnew BlockAutoformatEditing( this.editor, /^1[.|)]\\s$/, 'numberedList' );\n\t\t}\n\t}\n\n\t/**\n\t * Adds autoformatting related to the {@link module:basic-styles/bold~Bold},\n\t * {@link module:basic-styles/italic~Italic} and {@link module:basic-styles/code~Code}.\n\t *\n\t * When typed:\n\t * - `**foobar**` &ndash; `**` characters are removed and `foobar` is set to bold,\n\t * - `__foobar__` &ndash; `__` characters are removed and `foobar` is set to bold,\n\t * - `*foobar*` &ndash; `*` characters are removed and `foobar` is set to italic,\n\t * - `_foobar_` &ndash; `_` characters are removed and `foobar` is set to italic,\n\t * - ``` `foobar` &ndash; ``` ` ``` characters are removed and `foobar` is set to code.\n\t *\n\t * @private\n\t */\n\t_addBasicStylesAutoformats() {\n\t\tconst commands = this.editor.commands;\n\n\t\tif ( commands.get( 'bold' ) ) {\n\t\t\t/* eslint-disable no-new */\n\t\t\tconst boldCallback = getCallbackFunctionForInlineAutoformat( this.editor, 'bold' );\n\n\t\t\tnew InlineAutoformatEditing( this.editor, /(\\*\\*)([^*]+)(\\*\\*)$/g, boldCallback );\n\t\t\tnew InlineAutoformatEditing( this.editor, /(__)([^_]+)(__)$/g, boldCallback );\n\t\t\t/* eslint-enable no-new */\n\t\t}\n\n\t\tif ( commands.get( 'italic' ) ) {\n\t\t\t/* eslint-disable no-new */\n\t\t\tconst italicCallback = getCallbackFunctionForInlineAutoformat( this.editor, 'italic' );\n\n\t\t\t// The italic autoformatter cannot be triggered by the bold markers, so we need to check the\n\t\t\t// text before the pattern (e.g. `(?:^|[^\\*])`).\n\t\t\tnew InlineAutoformatEditing( this.editor, /(?:^|[^*])(\\*)([^*_]+)(\\*)$/g, italicCallback );\n\t\t\tnew InlineAutoformatEditing( this.editor, /(?:^|[^_])(_)([^_]+)(_)$/g, italicCallback );\n\t\t\t/* eslint-enable no-new */\n\t\t}\n\n\t\tif ( commands.get( 'code' ) ) {\n\t\t\t/* eslint-disable no-new */\n\t\t\tconst codeCallback = getCallbackFunctionForInlineAutoformat( this.editor, 'code' );\n\n\t\t\tnew InlineAutoformatEditing( this.editor, /(`)([^`]+)(`)$/g, codeCallback );\n\t\t\t/* eslint-enable no-new */\n\t\t}\n\t}\n\n\t/**\n\t * Adds autoformatting related to {@link module:heading/heading~Heading}.\n\t *\n\t * It is using a number at the end of the command name to associate it with the proper trigger:\n\t *\n\t * * `heading` with value `heading1` will be executed when typing `#`,\n\t * * `heading` with value `heading2` will be executed when typing `##`,\n\t * * ... up to `heading6` and `######`.\n\t *\n\t * @private\n\t */\n\t_addHeadingAutoformats() {\n\t\tconst command = this.editor.commands.get( 'heading' );\n\n\t\tif ( command ) {\n\t\t\tcommand.modelElements\n\t\t\t\t.filter( name => name.match( /^heading[1-6]$/ ) )\n\t\t\t\t.forEach( commandValue => {\n\t\t\t\t\tconst level = commandValue[ 7 ];\n\t\t\t\t\tconst pattern = new RegExp( `^(#{${ level }})\\\\s$` );\n\n\t\t\t\t\t// eslint-disable-next-line no-new\n\t\t\t\t\tnew BlockAutoformatEditing( this.editor, pattern, () => {\n\t\t\t\t\t\tif ( !command.isEnabled ) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis.editor.execute( 'heading', { value: commandValue } );\n\t\t\t\t\t} );\n\t\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Adds autoformatting related to {@link module:block-quote/blockquote~BlockQuote}.\n\t *\n\t * When typed:\n\t * * `> ` &ndash; A paragraph will be changed to a block quote.\n\t *\n\t * @private\n\t */\n\t_addBlockQuoteAutoformats() {\n\t\tif ( this.editor.commands.get( 'blockQuote' ) ) {\n\t\t\t// eslint-disable-next-line no-new\n\t\t\tnew BlockAutoformatEditing( this.editor, /^>\\s$/, 'blockQuote' );\n\t\t}\n\t}\n}\n\n// Helper function for getting `InlineAutoformatEditing` callbacks that checks if command is enabled.\n//\n// @param {module:core/editor/editor~Editor} editor\n// @param {String} attributeKey\n// @returns {Function}\nfunction getCallbackFunctionForInlineAutoformat( editor, attributeKey ) {\n\treturn ( writer, rangesToFormat ) => {\n\t\tconst command = editor.commands.get( attributeKey );\n\n\t\tif ( !command.isEnabled ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst validRanges = editor.model.schema.getValidRanges( rangesToFormat, attributeKey );\n\n\t\tfor ( const range of validRanges ) {\n\t\t\twriter.setAttribute( attributeKey, true, range );\n\t\t}\n\n\t\t// After applying attribute to the text, remove given attribute from the selection.\n\t\t// This way user is able to type a text without attribute used by auto formatter.\n\t\twriter.removeSelectionAttribute( attributeKey );\n\t};\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor.data, 'ready', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n/**\n * Array of loaded plugins.\n *\n * @typedef {Array.<module:core/plugin~PluginInterface>} module:core/plugin~LoadedPlugins\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/command\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor commands.\n *\n * Commands are the main way to manipulate editor contents and state. They are mostly used by UI elements (or by other\n * commands) to make changes in the model. Commands are available in every part of code that has access to\n * the {@link module:core/editor/editor~Editor editor} instance.\n *\n * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n *\n * By default commands are disabled when the editor is in {@link module:core/editor/editor~Editor#isReadOnly read-only} mode.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Command {\n\t/**\n\t * Creates a new `Command` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor Editor on which this command will be used.\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor on which this command will be used.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * The value of the command. A concrete command class should define what it represents for it.\n\t\t *\n\t\t * For example, the `'bold'` command's value indicates whether the selection starts in a bolded text.\n\t\t * And the value of the `'link'` command may be an object with links details.\n\t\t *\n\t\t * It is possible for a command to have no value (e.g. for stateless actions such as `'imageUpload'`).\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member #value\n\t\t */\n\t\tthis.set( 'value', undefined );\n\n\t\t/**\n\t\t * Flag indicating whether a command is enabled or disabled.\n\t\t * A disabled command will do nothing when executed.\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * It is possible to disable a command from \"outside\". For instance, in your integration you may want to disable\n\t\t * a certain set of commands for the time being. To do that, you can use the fact that `isEnabled` is observable\n\t\t * and it fires the `set:isEnabled` event every time anyone tries to modify its value:\n\t\t *\n\t\t *\t\tfunction disableCommand( cmd ) {\n\t\t *\t\t\tcmd.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t *\n\t\t *\t\t\tcmd.isEnabled = false;\n\t\t *\n\t\t *\t\t\t// Make it possible to enable the command again.\n\t\t *\t\t\treturn () => {\n\t\t *\t\t\t\tcmd.off( 'set:isEnabled', forceDisable );\n\t\t *\t\t\t\tcmd.refresh();\n\t\t *\t\t\t};\n\t\t *\n\t\t *\t\t\tfunction forceDisable( evt ) {\n\t\t *\t\t\t\tevt.return = false;\n\t\t *\t\t\t\tevt.stop();\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\n\t\t *\t\t// Usage:\n\t\t *\n\t\t *\t\t// Disabling the command.\n\t\t *\t\tconst enableBold = disableCommand( editor.commands.get( 'bold' ) );\n\t\t *\n\t\t *\t\t// Enabling the command again.\n\t\t *\t\tenableBold();\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\t\tthis.set( 'isEnabled', false );\n\n\t\t/**\n\t\t * Holds identifiers for {@link #forceDisabled} mechanism.\n\t\t *\n\t\t * @type {Set.<String>}\n\t\t * @private\n\t\t */\n\t\tthis._disableStack = new Set();\n\n\t\tthis.decorate( 'execute' );\n\n\t\t// By default every command is refreshed when changes are applied to the model.\n\t\tthis.listenTo( this.editor.model.document, 'change', () => {\n\t\t\tthis.refresh();\n\t\t} );\n\n\t\tthis.on( 'execute', evt => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// By default commands are disabled when the editor is in read-only mode.\n\t\tthis.listenTo( editor, 'change:isReadOnly', ( evt, name, value ) => {\n\t\t\tif ( value ) {\n\t\t\t\tthis.forceDisabled( 'readOnlyMode' );\n\t\t\t} else {\n\t\t\t\tthis.clearForceDisabled( 'readOnlyMode' );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties\n\t * in this method.\n\t *\n\t * This method is automatically called when\n\t * {@link module:engine/model/document~Document#event:change any changes are applied to the document}.\n\t */\n\trefresh() {\n\t\tthis.isEnabled = true;\n\t}\n\n\t/**\n\t * Disables the command.\n\t *\n\t * Command may be disabled by multiple features or algorithms (at once). When disabling a command, unique id should be passed\n\t * (e.g. feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the command.\n\t * The command becomes enabled only after all features {@link #clearForceDisabled enabled it back}.\n\t *\n\t * Disabling and enabling a command:\n\t *\n\t *\t\tcommand.isEnabled; // -> true\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Command disabled by multiple features:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'OtherFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'OtherFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Multiple disabling with the same identifier is redundant:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * **Note:** some commands or algorithms may have more complex logic when it comes to enabling or disabling certain commands,\n\t * so the command might be still disabled after {@link #clearForceDisabled} was used.\n\t *\n\t * @param {String} id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the command.\n\t */\n\tforceDisabled( id ) {\n\t\tthis._disableStack.add( id );\n\n\t\tif ( this._disableStack.size == 1 ) {\n\t\t\tthis.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * Clears forced disable previously set through {@link #clearForceDisabled}. See {@link #clearForceDisabled}.\n\t *\n\t * @param {String} id Unique identifier, equal to the one passed in {@link #forceDisabled} call.\n\t */\n\tclearForceDisabled( id ) {\n\t\tthis._disableStack.delete( id );\n\n\t\tif ( this._disableStack.size == 0 ) {\n\t\t\tthis.off( 'set:isEnabled', forceDisable );\n\t\t\tthis.refresh();\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`}\n\t * to the command.\n\t *\n\t * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`).\n\t * This behavior is implemented by a high priority listener to the {@link #event:execute} event.\n\t *\n\t * In order to see how to disable a command from \"outside\" see the {@link #isEnabled} documentation.\n\t *\n\t * @fires execute\n\t */\n\texecute() {}\n\n\t/**\n\t * Destroys the command.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Event fired by the {@link #execute} method. The command action is a listener to this event so it's\n\t * possible to change/cancel the behavior of the command by listening to this event.\n\t *\n\t * See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples.\n\t *\n\t * **Note:** This event is fired even if command is disabled. However, it is automatically blocked\n\t * by a high priority listener in order to prevent command execution.\n\t *\n\t * @event execute\n\t */\n}\n\nmix( Command, ObservableMixin );\n\n// Helper function that forces command to be disabled.\nfunction forceDisable( evt ) {\n\tevt.return = false;\n\tevt.stop();\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module basic-styles/attributecommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\n\n/**\n * An extension of the base {@link module:core/command~Command} class, which provides utilities for a command\n * that toggles a single attribute on a text or an element.\n *\n * `AttributeCommand` uses {@link module:engine/model/document~Document#selection}\n * to decide which nodes (if any) should be changed, and applies or removes the attribute from them.\n *\n * The command checks the {@link module:engine/model/model~Model#schema} to decide if it can be enabled\n * for the current selection and to which nodes the attribute can be applied.\n *\n * @extends module:core/command~Command\n */\nexport default class AttributeCommand extends Command {\n\t/**\n\t * @param {module:core/editor/editor~Editor} editor\n\t * @param {String} attributeKey Attribute that will be set by the command.\n\t */\n\tconstructor( editor, attributeKey ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The attribute that will be set by the command.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.attributeKey = attributeKey;\n\n\t\t/**\n\t\t * Flag indicating whether the command is active. The command is active when the\n\t\t * {@link module:engine/model/selection~Selection#hasAttribute selection has the attribute} which means that:\n\t\t *\n\t\t * * If the selection is not empty &ndash; That the attribute is set on the first node in the selection that allows this attribute.\n\t\t * * If the selection is empty &ndash; That the selection has the attribute itself (which means that newly typed\n\t\t * text will have this attribute, too).\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #value\n\t\t */\n\t}\n\n\t/**\n\t * Updates the command's {@link #value} and {@link #isEnabled} based on the current selection.\n\t */\n\trefresh() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\n\t\tthis.value = this._getValueFromFirstAllowedNode();\n\t\tthis.isEnabled = model.schema.checkAttributeInSelection( doc.selection, this.attributeKey );\n\t}\n\n\t/**\n\t * Executes the command &mdash; applies the attribute to the selection or removes it from the selection.\n\t *\n\t * If the command is active (`value == true`), it will remove attributes. Otherwise, it will set attributes.\n\t *\n\t * The execution result differs, depending on the {@link module:engine/model/document~Document#selection}:\n\t *\n\t * * If the selection is on a range, the command applies the attribute to all nodes in that range\n\t * (if they are allowed to have this attribute by the {@link module:engine/model/schema~Schema schema}).\n\t * * If the selection is collapsed in a non-empty node, the command applies the attribute to the\n\t * {@link module:engine/model/document~Document#selection} itself (note that typed characters copy attributes from the selection).\n\t * * If the selection is collapsed in an empty node, the command applies the attribute to the parent node of the selection (note\n\t * that the selection inherits all attributes from a node if it is in an empty node).\n\t *\n\t * @fires execute\n\t * @param {Object} [options] Command options.\n\t * @param {Boolean} [options.forceValue] If set, it will force the command behavior. If `true`, the command will apply the attribute,\n\t * otherwise the command will remove the attribute.\n\t * If not set, the command will look for its current value to decide what it should do.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tconst selection = doc.selection;\n\t\tconst value = ( options.forceValue === undefined ) ? !this.value : options.forceValue;\n\n\t\tmodel.change( writer => {\n\t\t\tif ( selection.isCollapsed ) {\n\t\t\t\tif ( value ) {\n\t\t\t\t\twriter.setSelectionAttribute( this.attributeKey, true );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeSelectionAttribute( this.attributeKey );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst ranges = model.schema.getValidRanges( selection.getRanges(), this.attributeKey );\n\n\t\t\t\tfor ( const range of ranges ) {\n\t\t\t\t\tif ( value ) {\n\t\t\t\t\t\twriter.setAttribute( this.attributeKey, value, range );\n\t\t\t\t\t} else {\n\t\t\t\t\t\twriter.removeAttribute( this.attributeKey, range );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the attribute value of the first node in the selection that allows the attribute.\n\t * For the collapsed selection returns the selection attribute.\n\t *\n\t * @private\n\t * @returns {Boolean} The attribute value.\n\t */\n\t_getValueFromFirstAllowedNode() {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\t\tconst selection = model.document.selection;\n\n\t\tif ( selection.isCollapsed ) {\n\t\t\treturn selection.hasAttribute( this.attributeKey );\n\t\t}\n\n\t\tfor ( const range of selection.getRanges() ) {\n\t\t\tfor ( const item of range.getItems() ) {\n\t\t\t\tif ( schema.checkAttribute( item, this.attributeKey ) ) {\n\t\t\t\t\treturn item.hasAttribute( this.attributeKey );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module basic-styles/bold/boldediting\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport AttributeCommand from '../attributecommand';\n\nconst BOLD = 'bold';\n\n/**\n * The bold editing feature.\n *\n * It registers the `'bold'` command and introduces the `bold` attribute in the model which renders to the view\n * as a `<strong>` element.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class BoldEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\t// Allow bold attribute on text nodes.\n\t\teditor.model.schema.extend( '$text', { allowAttributes: BOLD } );\n\t\teditor.model.schema.setAttributeProperties( BOLD, { isFormatting: true } );\n\n\t\t// Build converter from model to view for data and editing pipelines.\n\n\t\teditor.conversion.attributeToElement( {\n\t\t\tmodel: BOLD,\n\t\t\tview: 'strong',\n\t\t\tupcastAlso: [\n\t\t\t\t'b',\n\t\t\t\t{\n\t\t\t\t\tstyles: {\n\t\t\t\t\t\t'font-weight': 'bold'\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\n\t\t// Create bold command.\n\t\teditor.commands.add( BOLD, new AttributeCommand( editor, BOLD ) );\n\n\t\t// Set the Ctrl+B keystroke.\n\t\teditor.keystrokes.set( 'CTRL+B', BOLD );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module basic-styles/bold/boldui\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport boldIcon from '../../theme/icons/bold.svg';\nconst BOLD = 'bold';\n/**\n * The bold UI feature. It introduces the Bold button.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class BoldUI extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const t = editor.t;\n // Add bold button to feature components.\n editor.ui.componentFactory.add(BOLD, locale => {\n const command = editor.commands.get(BOLD);\n const view = new ButtonView(locale);\n view.set({\n label: t('b'),\n icon: boldIcon,\n keystroke: 'CTRL+B',\n tooltip: true\n });\n view.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');\n // Execute command.\n this.listenTo(view, 'execute', () => editor.execute(BOLD));\n return view;\n });\n }\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module basic-styles/code/codeediting\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport AttributeCommand from '../attributecommand';\n\nconst CODE = 'code';\n\n/**\n * The code editing feature.\n *\n * It registers the `'code'` command and introduces the `code` attribute in the model which renders to the view\n * as a `<code>` element.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class CodeEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\n\t\t// Allow code attribute on text nodes.\n\t\teditor.model.schema.extend( '$text', { allowAttributes: CODE } );\n\t\teditor.model.schema.setAttributeProperties( CODE, { isFormatting: true } );\n\n\t\teditor.conversion.attributeToElement( {\n\t\t\tmodel: CODE,\n\t\t\tview: 'code',\n\t\t\tupcastAlso: {\n\t\t\t\tstyles: {\n\t\t\t\t\t'word-wrap': 'break-word'\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Create code command.\n\t\teditor.commands.add( CODE, new AttributeCommand( editor, CODE ) );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module basic-styles/code/codeui\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport codeIcon from '../../theme/icons/code.svg';\nimport '../../theme/code.css';\nconst CODE = 'code';\n/**\n * The code UI feature. It introduces the Code button.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class CodeUI extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const t = editor.t;\n // Add code button to feature components.\n editor.ui.componentFactory.add(CODE, locale => {\n const command = editor.commands.get(CODE);\n const view = new ButtonView(locale);\n view.set({\n label: t('c'),\n icon: codeIcon,\n tooltip: true\n });\n view.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');\n // Execute command.\n this.listenTo(view, 'execute', () => editor.execute(CODE));\n return view;\n });\n }\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module basic-styles/strikethrough/strikethroughediting\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport AttributeCommand from '../attributecommand';\n\nconst STRIKETHROUGH = 'strikethrough';\n\n/**\n * The strikethrough editing feature.\n *\n * It registers the `'strikethrough'` command, the <kbd>Ctrl+Shift+X</kbd> keystroke and introduces the\n * `strikethroughsthrough` attribute in the model which renders to the view\n * as a `<s>` element.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class StrikethroughEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\n\t\t// Allow strikethrough attribute on text nodes.\n\t\teditor.model.schema.extend( '$text', { allowAttributes: STRIKETHROUGH } );\n\t\teditor.model.schema.setAttributeProperties( STRIKETHROUGH, { isFormatting: true } );\n\n\t\teditor.conversion.attributeToElement( {\n\t\t\tmodel: STRIKETHROUGH,\n\t\t\tview: 's',\n\t\t\tupcastAlso: [\n\t\t\t\t'del',\n\t\t\t\t'strike',\n\t\t\t\t{\n\t\t\t\t\tstyles: {\n\t\t\t\t\t\t'text-decoration': 'line-through'\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\n\t\t// Create strikethrough command.\n\t\teditor.commands.add( STRIKETHROUGH, new AttributeCommand( editor, STRIKETHROUGH ) );\n\n\t\t// Set the Ctrl+Shift+X keystroke.\n\t\teditor.keystrokes.set( 'CTRL+SHIFT+X', 'strikethrough' );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module basic-styles/strikethrough/strikethroughui\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport strikethroughIcon from '../../theme/icons/strikethrough.svg';\nconst STRIKETHROUGH = 'strikethrough';\n/**\n * The strikethrough UI feature. It introduces the Strikethrough button.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class StrikethroughUI extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const t = editor.t;\n // Add strikethrough button to feature components.\n editor.ui.componentFactory.add(STRIKETHROUGH, locale => {\n const command = editor.commands.get(STRIKETHROUGH);\n const view = new ButtonView(locale);\n view.set({\n label: t('aq'),\n icon: strikethroughIcon,\n keystroke: 'CTRL+SHIFT+X',\n tooltip: true\n });\n view.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');\n // Execute command.\n this.listenTo(view, 'execute', () => editor.execute(STRIKETHROUGH));\n return view;\n });\n }\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module basic-styles/italic/italicediting\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport AttributeCommand from '../attributecommand';\n\nconst ITALIC = 'italic';\n\n/**\n * The italic editing feature.\n *\n * It registers the `'italic'` command, the <kbd>Ctrl+I</kbd> keystroke and introduces the `italic` attribute in the model\n * which renders to the view as an `<em>` element.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ItalicEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\n\t\t// Allow italic attribute on text nodes.\n\t\teditor.model.schema.extend( '$text', { allowAttributes: ITALIC } );\n\t\teditor.model.schema.setAttributeProperties( ITALIC, { isFormatting: true } );\n\n\t\teditor.conversion.attributeToElement( {\n\t\t\tmodel: ITALIC,\n\t\t\tview: 'i',\n\t\t\tupcastAlso: [\n\t\t\t\t'em',\n\t\t\t\t{\n\t\t\t\t\tstyles: {\n\t\t\t\t\t\t'font-style': 'italic'\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\n\t\t// Create italic command.\n\t\teditor.commands.add( ITALIC, new AttributeCommand( editor, ITALIC ) );\n\n\t\t// Set the Ctrl+I keystroke.\n\t\teditor.keystrokes.set( 'CTRL+I', ITALIC );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module basic-styles/italic/italicui\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport italicIcon from '../../theme/icons/italic.svg';\nconst ITALIC = 'italic';\n/**\n * The italic UI feature. It introduces the Italic button.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ItalicUI extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const t = editor.t;\n // Add bold button to feature components.\n editor.ui.componentFactory.add(ITALIC, locale => {\n const command = editor.commands.get(ITALIC);\n const view = new ButtonView(locale);\n view.set({\n label: t('ap'),\n icon: italicIcon,\n keystroke: 'CTRL+I',\n tooltip: true\n });\n view.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');\n // Execute command.\n this.listenTo(view, 'execute', () => editor.execute(ITALIC));\n return view;\n });\n }\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor.data, 'ready', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n/**\n * Array of loaded plugins.\n *\n * @typedef {Array.<module:core/plugin~PluginInterface>} module:core/plugin~LoadedPlugins\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/command\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor commands.\n *\n * Commands are the main way to manipulate editor contents and state. They are mostly used by UI elements (or by other\n * commands) to make changes in the model. Commands are available in every part of code that has access to\n * the {@link module:core/editor/editor~Editor editor} instance.\n *\n * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n *\n * By default commands are disabled when the editor is in {@link module:core/editor/editor~Editor#isReadOnly read-only} mode.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Command {\n\t/**\n\t * Creates a new `Command` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor Editor on which this command will be used.\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor on which this command will be used.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * The value of the command. A concrete command class should define what it represents for it.\n\t\t *\n\t\t * For example, the `'bold'` command's value indicates whether the selection starts in a bolded text.\n\t\t * And the value of the `'link'` command may be an object with links details.\n\t\t *\n\t\t * It is possible for a command to have no value (e.g. for stateless actions such as `'imageUpload'`).\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member #value\n\t\t */\n\t\tthis.set( 'value', undefined );\n\n\t\t/**\n\t\t * Flag indicating whether a command is enabled or disabled.\n\t\t * A disabled command will do nothing when executed.\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * It is possible to disable a command from \"outside\". For instance, in your integration you may want to disable\n\t\t * a certain set of commands for the time being. To do that, you can use the fact that `isEnabled` is observable\n\t\t * and it fires the `set:isEnabled` event every time anyone tries to modify its value:\n\t\t *\n\t\t *\t\tfunction disableCommand( cmd ) {\n\t\t *\t\t\tcmd.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t *\n\t\t *\t\t\tcmd.isEnabled = false;\n\t\t *\n\t\t *\t\t\t// Make it possible to enable the command again.\n\t\t *\t\t\treturn () => {\n\t\t *\t\t\t\tcmd.off( 'set:isEnabled', forceDisable );\n\t\t *\t\t\t\tcmd.refresh();\n\t\t *\t\t\t};\n\t\t *\n\t\t *\t\t\tfunction forceDisable( evt ) {\n\t\t *\t\t\t\tevt.return = false;\n\t\t *\t\t\t\tevt.stop();\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\n\t\t *\t\t// Usage:\n\t\t *\n\t\t *\t\t// Disabling the command.\n\t\t *\t\tconst enableBold = disableCommand( editor.commands.get( 'bold' ) );\n\t\t *\n\t\t *\t\t// Enabling the command again.\n\t\t *\t\tenableBold();\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\t\tthis.set( 'isEnabled', false );\n\n\t\t/**\n\t\t * Holds identifiers for {@link #forceDisabled} mechanism.\n\t\t *\n\t\t * @type {Set.<String>}\n\t\t * @private\n\t\t */\n\t\tthis._disableStack = new Set();\n\n\t\tthis.decorate( 'execute' );\n\n\t\t// By default every command is refreshed when changes are applied to the model.\n\t\tthis.listenTo( this.editor.model.document, 'change', () => {\n\t\t\tthis.refresh();\n\t\t} );\n\n\t\tthis.on( 'execute', evt => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// By default commands are disabled when the editor is in read-only mode.\n\t\tthis.listenTo( editor, 'change:isReadOnly', ( evt, name, value ) => {\n\t\t\tif ( value ) {\n\t\t\t\tthis.forceDisabled( 'readOnlyMode' );\n\t\t\t} else {\n\t\t\t\tthis.clearForceDisabled( 'readOnlyMode' );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties\n\t * in this method.\n\t *\n\t * This method is automatically called when\n\t * {@link module:engine/model/document~Document#event:change any changes are applied to the document}.\n\t */\n\trefresh() {\n\t\tthis.isEnabled = true;\n\t}\n\n\t/**\n\t * Disables the command.\n\t *\n\t * Command may be disabled by multiple features or algorithms (at once). When disabling a command, unique id should be passed\n\t * (e.g. feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the command.\n\t * The command becomes enabled only after all features {@link #clearForceDisabled enabled it back}.\n\t *\n\t * Disabling and enabling a command:\n\t *\n\t *\t\tcommand.isEnabled; // -> true\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Command disabled by multiple features:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'OtherFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'OtherFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Multiple disabling with the same identifier is redundant:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * **Note:** some commands or algorithms may have more complex logic when it comes to enabling or disabling certain commands,\n\t * so the command might be still disabled after {@link #clearForceDisabled} was used.\n\t *\n\t * @param {String} id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the command.\n\t */\n\tforceDisabled( id ) {\n\t\tthis._disableStack.add( id );\n\n\t\tif ( this._disableStack.size == 1 ) {\n\t\t\tthis.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * Clears forced disable previously set through {@link #clearForceDisabled}. See {@link #clearForceDisabled}.\n\t *\n\t * @param {String} id Unique identifier, equal to the one passed in {@link #forceDisabled} call.\n\t */\n\tclearForceDisabled( id ) {\n\t\tthis._disableStack.delete( id );\n\n\t\tif ( this._disableStack.size == 0 ) {\n\t\t\tthis.off( 'set:isEnabled', forceDisable );\n\t\t\tthis.refresh();\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`}\n\t * to the command.\n\t *\n\t * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`).\n\t * This behavior is implemented by a high priority listener to the {@link #event:execute} event.\n\t *\n\t * In order to see how to disable a command from \"outside\" see the {@link #isEnabled} documentation.\n\t *\n\t * @fires execute\n\t */\n\texecute() {}\n\n\t/**\n\t * Destroys the command.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Event fired by the {@link #execute} method. The command action is a listener to this event so it's\n\t * possible to change/cancel the behavior of the command by listening to this event.\n\t *\n\t * See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples.\n\t *\n\t * **Note:** This event is fired even if command is disabled. However, it is automatically blocked\n\t * by a high priority listener in order to prevent command execution.\n\t *\n\t * @event execute\n\t */\n}\n\nmix( Command, ObservableMixin );\n\n// Helper function that forces command to be disabled.\nfunction forceDisable( evt ) {\n\tevt.return = false;\n\tevt.stop();\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module utils/first\n */\n\n/**\n * Returns first item of the given `iterable`.\n *\n * @param {Iterable.<*>} iterable\n * @returns {*}\n */\nexport default function first( iterable ) {\n\tconst iteratorItem = iterable.next();\n\n\tif ( iteratorItem.done ) {\n\t\treturn null;\n\t}\n\n\treturn iteratorItem.value;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module block-quote/blockquotecommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\n\nimport first from '@ckeditor/ckeditor5-utils/src/first';\n\n/**\n * The block quote command plugin.\n *\n * @extends module:core/command~Command\n */\nexport default class BlockQuoteCommand extends Command {\n\t/**\n\t * Whether the selection starts in a block quote.\n\t *\n\t * @observable\n\t * @readonly\n\t * @member {Boolean} #value\n\t */\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Executes the command. When the command {@link #value is on}, all top-most block quotes within\n\t * the selection will be removed. If it is off, all selected blocks will be wrapped with\n\t * a block quote.\n\t *\n\t * @fires execute\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\t\tconst selection = model.document.selection;\n\n\t\tconst blocks = Array.from( selection.getTopMostBlocks() );\n\n\t\tmodel.change( writer => {\n\t\t\tif ( this.value ) {\n\t\t\t\tthis._removeQuote( writer, blocks.filter( findQuote ) );\n\t\t\t} else {\n\t\t\t\tconst blocksToQuote = blocks.filter( block => {\n\t\t\t\t\t// Already quoted blocks needs to be considered while quoting too\n\t\t\t\t\t// in order to reuse their <bQ> elements.\n\t\t\t\t\treturn findQuote( block ) || checkCanBeQuoted( schema, block );\n\t\t\t\t} );\n\n\t\t\t\tthis._applyQuote( writer, blocksToQuote );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {Boolean} The current value.\n\t */\n\t_getValue() {\n\t\tconst selection = this.editor.model.document.selection;\n\n\t\tconst firstBlock = first( selection.getTopMostBlocks() );\n\n\t\t// In the current implementation, the block quote must be an immediate parent of a block element.\n\t\treturn !!( firstBlock && findQuote( firstBlock ) );\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\tif ( this.value ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst schema = this.editor.model.schema;\n\n\t\tconst firstBlock = first( selection.getSelectedBlocks() );\n\n\t\tif ( !firstBlock ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn checkCanBeQuoted( schema, firstBlock );\n\t}\n\n\t/**\n\t * Removes the quote from given blocks.\n\t *\n\t * If blocks which are supposed to be \"unquoted\" are in the middle of a quote,\n\t * start it or end it, then the quote will be split (if needed) and the blocks\n\t * will be moved out of it, so other quoted blocks remained quoted.\n\t *\n\t * @private\n\t * @param {module:engine/model/writer~Writer} writer\n\t * @param {Array.<module:engine/model/element~Element>} blocks\n\t */\n\t_removeQuote( writer, blocks ) {\n\t\t// Unquote all groups of block. Iterate in the reverse order to not break following ranges.\n\t\tgetRangesOfBlockGroups( writer, blocks ).reverse().forEach( groupRange => {\n\t\t\tif ( groupRange.start.isAtStart && groupRange.end.isAtEnd ) {\n\t\t\t\twriter.unwrap( groupRange.start.parent );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// The group of blocks are at the beginning of an <bQ> so let's move them left (out of the <bQ>).\n\t\t\tif ( groupRange.start.isAtStart ) {\n\t\t\t\tconst positionBefore = writer.createPositionBefore( groupRange.start.parent );\n\n\t\t\t\twriter.move( groupRange, positionBefore );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// The blocks are in the middle of an <bQ> so we need to split the <bQ> after the last block\n\t\t\t// so we move the items there.\n\t\t\tif ( !groupRange.end.isAtEnd ) {\n\t\t\t\twriter.split( groupRange.end );\n\t\t\t}\n\n\t\t\t// Now we are sure that groupRange.end.isAtEnd is true, so let's move the blocks right.\n\n\t\t\tconst positionAfter = writer.createPositionAfter( groupRange.end.parent );\n\n\t\t\twriter.move( groupRange, positionAfter );\n\t\t} );\n\t}\n\n\t/**\n\t * Applies the quote to given blocks.\n\t *\n\t * @private\n\t * @param {module:engine/model/writer~Writer} writer\n\t * @param {Array.<module:engine/model/element~Element>} blocks\n\t */\n\t_applyQuote( writer, blocks ) {\n\t\tconst quotesToMerge = [];\n\n\t\t// Quote all groups of block. Iterate in the reverse order to not break following ranges.\n\t\tgetRangesOfBlockGroups( writer, blocks ).reverse().forEach( groupRange => {\n\t\t\tlet quote = findQuote( groupRange.start );\n\n\t\t\tif ( !quote ) {\n\t\t\t\tquote = writer.createElement( 'blockQuote' );\n\n\t\t\t\twriter.wrap( groupRange, quote );\n\t\t\t}\n\n\t\t\tquotesToMerge.push( quote );\n\t\t} );\n\n\t\t// Merge subsequent <bQ> elements. Reverse the order again because this time we want to go through\n\t\t// the <bQ> elements in the source order (due to how merge works – it moves the right element's content\n\t\t// to the first element and removes the right one. Since we may need to merge a couple of subsequent `<bQ>` elements\n\t\t// we want to keep the reference to the first (furthest left) one.\n\t\tquotesToMerge.reverse().reduce( ( currentQuote, nextQuote ) => {\n\t\t\tif ( currentQuote.nextSibling == nextQuote ) {\n\t\t\t\twriter.merge( writer.createPositionAfter( currentQuote ) );\n\n\t\t\t\treturn currentQuote;\n\t\t\t}\n\n\t\t\treturn nextQuote;\n\t\t} );\n\t}\n}\n\nfunction findQuote( elementOrPosition ) {\n\treturn elementOrPosition.parent.name == 'blockQuote' ? elementOrPosition.parent : null;\n}\n\n// Returns a minimal array of ranges containing groups of subsequent blocks.\n//\n// content: abcdefgh\n// blocks: [ a, b, d , f, g, h ]\n// output ranges: [ab]c[d]e[fgh]\n//\n// @param {Array.<module:engine/model/element~Element>} blocks\n// @returns {Array.<module:engine/model/range~Range>}\nfunction getRangesOfBlockGroups( writer, blocks ) {\n\tlet startPosition;\n\tlet i = 0;\n\tconst ranges = [];\n\n\twhile ( i < blocks.length ) {\n\t\tconst block = blocks[ i ];\n\t\tconst nextBlock = blocks[ i + 1 ];\n\n\t\tif ( !startPosition ) {\n\t\t\tstartPosition = writer.createPositionBefore( block );\n\t\t}\n\n\t\tif ( !nextBlock || block.nextSibling != nextBlock ) {\n\t\t\tranges.push( writer.createRange( startPosition, writer.createPositionAfter( block ) ) );\n\t\t\tstartPosition = null;\n\t\t}\n\n\t\ti++;\n\t}\n\n\treturn ranges;\n}\n\n// Checks whether <bQ> can wrap the block.\nfunction checkCanBeQuoted( schema, block ) {\n\t// TMP will be replaced with schema.checkWrap().\n\tconst isBQAllowed = schema.checkChild( block.parent, 'blockQuote' );\n\tconst isBlockAllowedInBQ = schema.checkChild( [ '$root', 'blockQuote' ], block );\n\n\treturn isBQAllowed && isBlockAllowedInBQ;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module block-quote/blockquoteediting\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport BlockQuoteCommand from './blockquotecommand';\n\n/**\n * The block quote editing.\n *\n * Introduces the `'blockQuote'` command and the `'blockQuote'` model element.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class BlockQuoteEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\n\t\teditor.commands.add( 'blockQuote', new BlockQuoteCommand( editor ) );\n\n\t\tschema.register( 'blockQuote', {\n\t\t\tallowWhere: '$block',\n\t\t\tallowContentOf: '$root'\n\t\t} );\n\n\t\t// Disallow blockQuote in blockQuote.\n\t\tschema.addChildCheck( ( ctx, childDef ) => {\n\t\t\tif ( ctx.endsWith( 'blockQuote' ) && childDef.name == 'blockQuote' ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} );\n\n\t\teditor.conversion.elementToElement( { model: 'blockQuote', view: 'blockquote' } );\n\n\t\t// Postfixer which cleans incorrect model states connected with block quotes.\n\t\teditor.model.document.registerPostFixer( writer => {\n\t\t\tconst changes = editor.model.document.differ.getChanges();\n\n\t\t\tfor ( const entry of changes ) {\n\t\t\t\tif ( entry.type == 'insert' ) {\n\t\t\t\t\tconst element = entry.position.nodeAfter;\n\n\t\t\t\t\tif ( !element ) {\n\t\t\t\t\t\t// We are inside a text node.\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( element.is( 'blockQuote' ) && element.isEmpty ) {\n\t\t\t\t\t\t// Added an empty blockQuote - remove it.\n\t\t\t\t\t\twriter.remove( element );\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else if ( element.is( 'blockQuote' ) && !schema.checkChild( entry.position, element ) ) {\n\t\t\t\t\t\t// Added a blockQuote in incorrect place - most likely inside another blockQuote. Unwrap it\n\t\t\t\t\t\t// so the content inside is not lost.\n\t\t\t\t\t\twriter.unwrap( element );\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else if ( element.is( 'element' ) ) {\n\t\t\t\t\t\t// Just added an element. Check its children to see if there are no nested blockQuotes somewhere inside.\n\t\t\t\t\t\tconst range = writer.createRangeIn( element );\n\n\t\t\t\t\t\tfor ( const child of range.getItems() ) {\n\t\t\t\t\t\t\tif ( child.is( 'blockQuote' ) && !schema.checkChild( writer.createPositionBefore( child ), child ) ) {\n\t\t\t\t\t\t\t\twriter.unwrap( child );\n\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if ( entry.type == 'remove' ) {\n\t\t\t\t\tconst parent = entry.position.parent;\n\n\t\t\t\t\tif ( parent.is( 'blockQuote' ) && parent.isEmpty ) {\n\t\t\t\t\t\t// Something got removed and now blockQuote is empty. Remove the blockQuote as well.\n\t\t\t\t\t\twriter.remove( parent );\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tafterInit() {\n\t\tconst editor = this.editor;\n\t\tconst command = editor.commands.get( 'blockQuote' );\n\n\t\t// Overwrite default Enter key behavior.\n\t\t// If Enter key is pressed with selection collapsed in empty block inside a quote, break the quote.\n\t\t// This listener is added in afterInit in order to register it after list's feature listener.\n\t\t// We can't use a priority for this, because 'low' is already used by the enter feature, unless\n\t\t// we'd use numeric priority in this case.\n\t\tthis.listenTo( this.editor.editing.view.document, 'enter', ( evt, data ) => {\n\t\t\tconst doc = this.editor.model.document;\n\t\t\tconst positionParent = doc.selection.getLastPosition().parent;\n\n\t\t\tif ( doc.selection.isCollapsed && positionParent.isEmpty && command.value ) {\n\t\t\t\tthis.editor.execute( 'blockQuote' );\n\t\t\t\tthis.editor.editing.view.scrollToTheSelection();\n\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module block-quote/blockquoteui\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport quoteIcon from '@ckeditor/ckeditor5-core/theme/icons/quote.svg';\nimport '../theme/blockquote.css';\n/**\n * The block quote UI plugin.\n *\n * It introduces the `'blockQuote'` button.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class BlockQuoteUI extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const t = editor.t;\n editor.ui.componentFactory.add('blockQuote', locale => {\n const command = editor.commands.get('blockQuote');\n const buttonView = new ButtonView(locale);\n buttonView.set({\n label: t('e'),\n icon: quoteIcon,\n tooltip: true\n });\n // Bind button model to command.\n buttonView.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');\n // Execute command.\n this.listenTo(buttonView, 'execute', () => editor.execute('blockQuote'));\n return buttonView;\n });\n }\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor.data, 'ready', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n/**\n * Array of loaded plugins.\n *\n * @typedef {Array.<module:core/plugin~PluginInterface>} module:core/plugin~LoadedPlugins\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/command\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor commands.\n *\n * Commands are the main way to manipulate editor contents and state. They are mostly used by UI elements (or by other\n * commands) to make changes in the model. Commands are available in every part of code that has access to\n * the {@link module:core/editor/editor~Editor editor} instance.\n *\n * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n *\n * By default commands are disabled when the editor is in {@link module:core/editor/editor~Editor#isReadOnly read-only} mode.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Command {\n\t/**\n\t * Creates a new `Command` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor Editor on which this command will be used.\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor on which this command will be used.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * The value of the command. A concrete command class should define what it represents for it.\n\t\t *\n\t\t * For example, the `'bold'` command's value indicates whether the selection starts in a bolded text.\n\t\t * And the value of the `'link'` command may be an object with links details.\n\t\t *\n\t\t * It is possible for a command to have no value (e.g. for stateless actions such as `'imageUpload'`).\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member #value\n\t\t */\n\t\tthis.set( 'value', undefined );\n\n\t\t/**\n\t\t * Flag indicating whether a command is enabled or disabled.\n\t\t * A disabled command will do nothing when executed.\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * It is possible to disable a command from \"outside\". For instance, in your integration you may want to disable\n\t\t * a certain set of commands for the time being. To do that, you can use the fact that `isEnabled` is observable\n\t\t * and it fires the `set:isEnabled` event every time anyone tries to modify its value:\n\t\t *\n\t\t *\t\tfunction disableCommand( cmd ) {\n\t\t *\t\t\tcmd.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t *\n\t\t *\t\t\tcmd.isEnabled = false;\n\t\t *\n\t\t *\t\t\t// Make it possible to enable the command again.\n\t\t *\t\t\treturn () => {\n\t\t *\t\t\t\tcmd.off( 'set:isEnabled', forceDisable );\n\t\t *\t\t\t\tcmd.refresh();\n\t\t *\t\t\t};\n\t\t *\n\t\t *\t\t\tfunction forceDisable( evt ) {\n\t\t *\t\t\t\tevt.return = false;\n\t\t *\t\t\t\tevt.stop();\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\n\t\t *\t\t// Usage:\n\t\t *\n\t\t *\t\t// Disabling the command.\n\t\t *\t\tconst enableBold = disableCommand( editor.commands.get( 'bold' ) );\n\t\t *\n\t\t *\t\t// Enabling the command again.\n\t\t *\t\tenableBold();\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\t\tthis.set( 'isEnabled', false );\n\n\t\t/**\n\t\t * Holds identifiers for {@link #forceDisabled} mechanism.\n\t\t *\n\t\t * @type {Set.<String>}\n\t\t * @private\n\t\t */\n\t\tthis._disableStack = new Set();\n\n\t\tthis.decorate( 'execute' );\n\n\t\t// By default every command is refreshed when changes are applied to the model.\n\t\tthis.listenTo( this.editor.model.document, 'change', () => {\n\t\t\tthis.refresh();\n\t\t} );\n\n\t\tthis.on( 'execute', evt => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// By default commands are disabled when the editor is in read-only mode.\n\t\tthis.listenTo( editor, 'change:isReadOnly', ( evt, name, value ) => {\n\t\t\tif ( value ) {\n\t\t\t\tthis.forceDisabled( 'readOnlyMode' );\n\t\t\t} else {\n\t\t\t\tthis.clearForceDisabled( 'readOnlyMode' );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties\n\t * in this method.\n\t *\n\t * This method is automatically called when\n\t * {@link module:engine/model/document~Document#event:change any changes are applied to the document}.\n\t */\n\trefresh() {\n\t\tthis.isEnabled = true;\n\t}\n\n\t/**\n\t * Disables the command.\n\t *\n\t * Command may be disabled by multiple features or algorithms (at once). When disabling a command, unique id should be passed\n\t * (e.g. feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the command.\n\t * The command becomes enabled only after all features {@link #clearForceDisabled enabled it back}.\n\t *\n\t * Disabling and enabling a command:\n\t *\n\t *\t\tcommand.isEnabled; // -> true\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Command disabled by multiple features:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'OtherFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'OtherFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Multiple disabling with the same identifier is redundant:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * **Note:** some commands or algorithms may have more complex logic when it comes to enabling or disabling certain commands,\n\t * so the command might be still disabled after {@link #clearForceDisabled} was used.\n\t *\n\t * @param {String} id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the command.\n\t */\n\tforceDisabled( id ) {\n\t\tthis._disableStack.add( id );\n\n\t\tif ( this._disableStack.size == 1 ) {\n\t\t\tthis.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * Clears forced disable previously set through {@link #clearForceDisabled}. See {@link #clearForceDisabled}.\n\t *\n\t * @param {String} id Unique identifier, equal to the one passed in {@link #forceDisabled} call.\n\t */\n\tclearForceDisabled( id ) {\n\t\tthis._disableStack.delete( id );\n\n\t\tif ( this._disableStack.size == 0 ) {\n\t\t\tthis.off( 'set:isEnabled', forceDisable );\n\t\t\tthis.refresh();\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`}\n\t * to the command.\n\t *\n\t * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`).\n\t * This behavior is implemented by a high priority listener to the {@link #event:execute} event.\n\t *\n\t * In order to see how to disable a command from \"outside\" see the {@link #isEnabled} documentation.\n\t *\n\t * @fires execute\n\t */\n\texecute() {}\n\n\t/**\n\t * Destroys the command.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Event fired by the {@link #execute} method. The command action is a listener to this event so it's\n\t * possible to change/cancel the behavior of the command by listening to this event.\n\t *\n\t * See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples.\n\t *\n\t * **Note:** This event is fired even if command is disabled. However, it is automatically blocked\n\t * by a high priority listener in order to prevent command execution.\n\t *\n\t * @event execute\n\t */\n}\n\nmix( Command, ObservableMixin );\n\n// Helper function that forces command to be disabled.\nfunction forceDisable( evt ) {\n\tevt.return = false;\n\tevt.stop();\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module paragraph/paragraphcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport first from '@ckeditor/ckeditor5-utils/src/first';\n\n/**\n * The paragraph command.\n *\n * @extends module:core/command~Command\n */\nexport default class ParagraphCommand extends Command {\n\t/**\n\t * The value of the command. Indicates whether the selection start is placed in a paragraph.\n\t *\n\t * @readonly\n\t * @observable\n\t * @member {Boolean} #value\n\t */\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\t\tconst block = first( document.selection.getSelectedBlocks() );\n\n\t\tthis.value = !!block && block.is( 'paragraph' );\n\t\tthis.isEnabled = !!block && checkCanBecomeParagraph( block, model.schema );\n\t}\n\n\t/**\n\t * Executes the command. All the blocks (see {@link module:engine/model/schema~Schema}) in the selection\n\t * will be turned to paragraphs.\n\t *\n\t * @fires execute\n\t * @param {Object} [options] Options for the executed command.\n\t * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} [options.selection]\n\t * The selection that the command should be applied to.\n\t * By default, if not provided, the command is applied to the {@link module:engine/model/document~Document#selection}.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tmodel.change( writer => {\n\t\t\tconst blocks = ( options.selection || document.selection ).getSelectedBlocks();\n\n\t\t\tfor ( const block of blocks ) {\n\t\t\t\tif ( !block.is( 'paragraph' ) && checkCanBecomeParagraph( block, model.schema ) ) {\n\t\t\t\t\twriter.rename( block, 'paragraph' );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n\n// Checks whether the given block can be replaced by a paragraph.\n//\n// @private\n// @param {module:engine/model/element~Element} block A block to be tested.\n// @param {module:engine/model/schema~Schema} schema The schema of the document.\n// @returns {Boolean}\nfunction checkCanBecomeParagraph( block, schema ) {\n\treturn schema.checkChild( block.parent, 'paragraph' ) && !schema.isObject( block );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor.data, 'ready', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n/**\n * Array of loaded plugins.\n *\n * @typedef {Array.<module:core/plugin~PluginInterface>} module:core/plugin~LoadedPlugins\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module paragraph/paragraph\n */\n\nimport ParagraphCommand from './paragraphcommand';\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\n/**\n * The paragraph feature for the editor.\n *\n * It introduces the `<paragraph>` element in the model which renders as a `<p>` element in the DOM and data.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Paragraph extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Paragraph';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst data = editor.data;\n\n\t\teditor.commands.add( 'paragraph', new ParagraphCommand( editor ) );\n\n\t\t// Schema.\n\t\tmodel.schema.register( 'paragraph', { inheritAllFrom: '$block' } );\n\n\t\teditor.conversion.elementToElement( { model: 'paragraph', view: 'p' } );\n\n\t\t// Content autoparagraphing. --------------------------------------------------\n\n\t\t// Handles element which has not been converted by any plugin and checks if it would be converted if\n\t\t// we wrap it in a paragraph or change it to a paragraph.\n\t\teditor.conversion.for( 'upcast' ).elementToElement( {\n\t\t\tmodel: ( viewElement, modelWriter ) => {\n\t\t\t\tif ( !Paragraph.paragraphLikeElements.has( viewElement.name ) ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\t// Do not auto-paragraph empty elements.\n\t\t\t\tif ( viewElement.isEmpty ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\treturn modelWriter.createElement( 'paragraph' );\n\t\t\t},\n\t\t\tconverterPriority: 'low'\n\t\t} );\n\n\t\tdata.upcastDispatcher.on( 'element', ( evt, data, conversionApi ) => {\n\t\t\t// Do not try auto-paragraphing if the element was already converted.\n\t\t\tif ( !conversionApi.consumable.test( data.viewItem, { name: data.viewItem.name } ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If the element is not paragraph-like try wrapping it in a paragraph.\n\t\t\tif ( isParagraphable( data.viewItem, data.modelCursor, conversionApi.schema ) ) {\n\t\t\t\tObject.assign( data, wrapInParagraph( data.viewItem, data.modelCursor, conversionApi ) );\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\n\t\t// Handles not converted text nodes and checks if would be converted if we wraps then by a paragraph.\n\t\tdata.upcastDispatcher.on( 'text', ( evt, data, conversionApi ) => {\n\t\t\t// When node is already converted then do nothing.\n\t\t\tif ( data.modelRange ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isParagraphable( data.viewItem, data.modelCursor, conversionApi.schema ) ) {\n\t\t\t\tObject.assign( data, wrapInParagraph( data.viewItem, data.modelCursor, conversionApi ) );\n\t\t\t}\n\t\t}, { priority: 'lowest' } );\n\n\t\t// Empty roots autoparagraphing. -----------------------------------------------\n\n\t\t// Post-fixer which takes care of adding empty paragraph elements to empty roots.\n\t\t// Besides fixing content on #changesDone we also need to handle editor.data#ready event because\n\t\t// if initial data is empty or setData() wasn't even called there will be no #change fired.\n\t\tmodel.document.registerPostFixer( writer => this._autoparagraphEmptyRoots( writer ) );\n\n\t\teditor.data.on( 'ready', () => {\n\t\t\tmodel.enqueueChange( 'transparent', writer => this._autoparagraphEmptyRoots( writer ) );\n\t\t}, { priority: 'lowest' } );\n\t}\n\n\t/**\n\t * Fixes all empty roots.\n\t *\n\t * @private\n\t * @returns {Boolean} `true` if any change has been applied, `false` otherwise.\n\t */\n\t_autoparagraphEmptyRoots( writer ) {\n\t\tconst model = this.editor.model;\n\n\t\tfor ( const rootName of model.document.getRootNames() ) {\n\t\t\tconst root = model.document.getRoot( rootName );\n\n\t\t\tif ( root.isEmpty && root.rootName != '$graveyard' ) {\n\t\t\t\t// If paragraph element is allowed in the root, create paragraph element.\n\t\t\t\tif ( model.schema.checkChild( root, 'paragraph' ) ) {\n\t\t\t\t\twriter.insertElement( 'paragraph', root );\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * A list of element names which should be treated by the autoparagraphing algorithms as\n * paragraph-like. This means that e.g. the following content:\n *\n *\t\t<h1>Foo</h1>\n *\t\t<table>\n *\t\t\t<tr>\n *\t\t\t\t<td>X</td>\n *\t\t\t\t<td>\n *\t\t\t\t\t<ul>\n *\t\t\t\t\t\t<li>Y</li>\n *\t\t\t\t\t\t<li>Z</li>\n *\t\t\t\t\t</ul>\n *\t\t\t\t</td>\n *\t\t\t</tr>\n *\t\t</table>\n *\n * contains five paragraph-like elements: `<h1>`, two `<td>`s and two `<li>`s.\n * Hence, if none of the features is going to convert those elements the above content will be automatically handled\n * by the paragraph feature and converted to:\n *\n *\t\t<p>Foo</p>\n *\t\t<p>X</p>\n *\t\t<p>Y</p>\n *\t\t<p>Z</p>\n *\n * Note: The `<td>` containing two `<li>` elements was ignored as the innermost paragraph-like elements\n * have a priority upon conversion.\n *\n * @member {Set.<String>} module:paragraph/paragraph~Paragraph.paragraphLikeElements\n */\nParagraph.paragraphLikeElements = new Set( [\n\t'blockquote',\n\t'dd',\n\t'div',\n\t'dt',\n\t'h1',\n\t'h2',\n\t'h3',\n\t'h4',\n\t'h5',\n\t'h6',\n\t'li',\n\t'p',\n\t'td'\n] );\n\nfunction wrapInParagraph( input, position, conversionApi ) {\n\tconst paragraph = conversionApi.writer.createElement( 'paragraph' );\n\n\tconversionApi.writer.insert( paragraph, position );\n\treturn conversionApi.convertItem( input, conversionApi.writer.createPositionAt( paragraph, 0 ) );\n}\n\nfunction isParagraphable( node, position, schema ) {\n\tconst context = schema.createContext( position );\n\n\t// When paragraph is allowed in this context...\n\tif ( !schema.checkChild( context, 'paragraph' ) ) {\n\t\treturn false;\n\t}\n\n\t// And a node would be allowed in this paragraph...\n\tif ( !schema.checkChild( context.push( 'paragraph' ), node ) ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/command\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor commands.\n *\n * Commands are the main way to manipulate editor contents and state. They are mostly used by UI elements (or by other\n * commands) to make changes in the model. Commands are available in every part of code that has access to\n * the {@link module:core/editor/editor~Editor editor} instance.\n *\n * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n *\n * By default commands are disabled when the editor is in {@link module:core/editor/editor~Editor#isReadOnly read-only} mode.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Command {\n\t/**\n\t * Creates a new `Command` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor Editor on which this command will be used.\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor on which this command will be used.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * The value of the command. A concrete command class should define what it represents for it.\n\t\t *\n\t\t * For example, the `'bold'` command's value indicates whether the selection starts in a bolded text.\n\t\t * And the value of the `'link'` command may be an object with links details.\n\t\t *\n\t\t * It is possible for a command to have no value (e.g. for stateless actions such as `'imageUpload'`).\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member #value\n\t\t */\n\t\tthis.set( 'value', undefined );\n\n\t\t/**\n\t\t * Flag indicating whether a command is enabled or disabled.\n\t\t * A disabled command will do nothing when executed.\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * It is possible to disable a command from \"outside\". For instance, in your integration you may want to disable\n\t\t * a certain set of commands for the time being. To do that, you can use the fact that `isEnabled` is observable\n\t\t * and it fires the `set:isEnabled` event every time anyone tries to modify its value:\n\t\t *\n\t\t *\t\tfunction disableCommand( cmd ) {\n\t\t *\t\t\tcmd.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t *\n\t\t *\t\t\tcmd.isEnabled = false;\n\t\t *\n\t\t *\t\t\t// Make it possible to enable the command again.\n\t\t *\t\t\treturn () => {\n\t\t *\t\t\t\tcmd.off( 'set:isEnabled', forceDisable );\n\t\t *\t\t\t\tcmd.refresh();\n\t\t *\t\t\t};\n\t\t *\n\t\t *\t\t\tfunction forceDisable( evt ) {\n\t\t *\t\t\t\tevt.return = false;\n\t\t *\t\t\t\tevt.stop();\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\n\t\t *\t\t// Usage:\n\t\t *\n\t\t *\t\t// Disabling the command.\n\t\t *\t\tconst enableBold = disableCommand( editor.commands.get( 'bold' ) );\n\t\t *\n\t\t *\t\t// Enabling the command again.\n\t\t *\t\tenableBold();\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\t\tthis.set( 'isEnabled', false );\n\n\t\t/**\n\t\t * Holds identifiers for {@link #forceDisabled} mechanism.\n\t\t *\n\t\t * @type {Set.<String>}\n\t\t * @private\n\t\t */\n\t\tthis._disableStack = new Set();\n\n\t\tthis.decorate( 'execute' );\n\n\t\t// By default every command is refreshed when changes are applied to the model.\n\t\tthis.listenTo( this.editor.model.document, 'change', () => {\n\t\t\tthis.refresh();\n\t\t} );\n\n\t\tthis.on( 'execute', evt => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// By default commands are disabled when the editor is in read-only mode.\n\t\tthis.listenTo( editor, 'change:isReadOnly', ( evt, name, value ) => {\n\t\t\tif ( value ) {\n\t\t\t\tthis.forceDisabled( 'readOnlyMode' );\n\t\t\t} else {\n\t\t\t\tthis.clearForceDisabled( 'readOnlyMode' );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties\n\t * in this method.\n\t *\n\t * This method is automatically called when\n\t * {@link module:engine/model/document~Document#event:change any changes are applied to the document}.\n\t */\n\trefresh() {\n\t\tthis.isEnabled = true;\n\t}\n\n\t/**\n\t * Disables the command.\n\t *\n\t * Command may be disabled by multiple features or algorithms (at once). When disabling a command, unique id should be passed\n\t * (e.g. feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the command.\n\t * The command becomes enabled only after all features {@link #clearForceDisabled enabled it back}.\n\t *\n\t * Disabling and enabling a command:\n\t *\n\t *\t\tcommand.isEnabled; // -> true\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Command disabled by multiple features:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'OtherFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'OtherFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Multiple disabling with the same identifier is redundant:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * **Note:** some commands or algorithms may have more complex logic when it comes to enabling or disabling certain commands,\n\t * so the command might be still disabled after {@link #clearForceDisabled} was used.\n\t *\n\t * @param {String} id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the command.\n\t */\n\tforceDisabled( id ) {\n\t\tthis._disableStack.add( id );\n\n\t\tif ( this._disableStack.size == 1 ) {\n\t\t\tthis.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * Clears forced disable previously set through {@link #clearForceDisabled}. See {@link #clearForceDisabled}.\n\t *\n\t * @param {String} id Unique identifier, equal to the one passed in {@link #forceDisabled} call.\n\t */\n\tclearForceDisabled( id ) {\n\t\tthis._disableStack.delete( id );\n\n\t\tif ( this._disableStack.size == 0 ) {\n\t\t\tthis.off( 'set:isEnabled', forceDisable );\n\t\t\tthis.refresh();\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`}\n\t * to the command.\n\t *\n\t * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`).\n\t * This behavior is implemented by a high priority listener to the {@link #event:execute} event.\n\t *\n\t * In order to see how to disable a command from \"outside\" see the {@link #isEnabled} documentation.\n\t *\n\t * @fires execute\n\t */\n\texecute() {}\n\n\t/**\n\t * Destroys the command.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Event fired by the {@link #execute} method. The command action is a listener to this event so it's\n\t * possible to change/cancel the behavior of the command by listening to this event.\n\t *\n\t * See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples.\n\t *\n\t * **Note:** This event is fired even if command is disabled. However, it is automatically blocked\n\t * by a high priority listener in order to prevent command execution.\n\t *\n\t * @event execute\n\t */\n}\n\nmix( Command, ObservableMixin );\n\n// Helper function that forces command to be disabled.\nfunction forceDisable( evt ) {\n\tevt.return = false;\n\tevt.stop();\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module heading/headingcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport first from '@ckeditor/ckeditor5-utils/src/first';\n\n/**\n * The heading command. It is used by the {@link module:heading/heading~Heading heading feature} to apply headings.\n *\n * @extends module:core/command~Command\n */\nexport default class HeadingCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor Editor instance.\n\t * @param {Array.<String>} modelElements Names of the element which this command can apply in the model.\n\t */\n\tconstructor( editor, modelElements ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * If the selection starts in a heading (which {@link #modelElements is supported by this command})\n\t\t * the value is set to the name of that heading model element.\n\t\t * It is set to `false` otherwise.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean|String} #value\n\t\t */\n\n\t\t/**\n\t\t * Set of defined model's elements names that this command support.\n\t\t * See {@link module:heading/heading~HeadingOption}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Array.<String>}\n\t\t */\n\t\tthis.modelElements = modelElements;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst block = first( this.editor.model.document.selection.getSelectedBlocks() );\n\n\t\tthis.value = !!block && this.modelElements.includes( block.name ) && block.name;\n\t\tthis.isEnabled = !!block && this.modelElements.some( heading => checkCanBecomeHeading( block, heading, this.editor.model.schema ) );\n\t}\n\n\t/**\n\t * Executes the command. Applies the heading to the selected blocks or, if the first selected\n\t * block is a heading already, turns selected headings (of this level only) to paragraphs.\n\t *\n\t * @param {Object} options\n\t * @param {String} options.value Name of the element which this command will apply in the model.\n\t * @fires execute\n\t */\n\texecute( options ) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tconst modelElement = options.value;\n\n\t\tmodel.change( writer => {\n\t\t\tconst blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t\t.filter( block => {\n\t\t\t\t\treturn checkCanBecomeHeading( block, modelElement, model.schema );\n\t\t\t\t} );\n\n\t\t\tfor ( const block of blocks ) {\n\t\t\t\tif ( !block.is( modelElement ) ) {\n\t\t\t\t\twriter.rename( block, modelElement );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n\n// Checks whether the given block can be replaced by a specific heading.\n//\n// @private\n// @param {module:engine/model/element~Element} block A block to be tested.\n// @param {module:heading/headingcommand~HeadingCommand#modelElement} heading Command element name in the model.\n// @param {module:engine/model/schema~Schema} schema The schema of the document.\n// @returns {Boolean}\nfunction checkCanBecomeHeading( block, heading, schema ) {\n\treturn schema.checkChild( block.parent, heading ) && !schema.isObject( block );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module heading/headingediting\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';\nimport HeadingCommand from './headingcommand';\n\nimport priorities from '@ckeditor/ckeditor5-utils/src/priorities';\n\nconst defaultModelElement = 'paragraph';\n\n/**\n * The headings engine feature. It handles switching between block formats &ndash; headings and paragraph.\n * This class represents the engine part of the heading feature. See also {@link module:heading/heading~Heading}.\n * It introduces `heading1`-`headingN` commands which allow to convert paragraphs into headings.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class HeadingEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'heading', {\n\t\t\toptions: [\n\t\t\t\t{ model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },\n\t\t\t\t{ model: 'heading1', view: 'h2', title: 'Heading 1', class: 'ck-heading_heading1' },\n\t\t\t\t{ model: 'heading2', view: 'h3', title: 'Heading 2', class: 'ck-heading_heading2' },\n\t\t\t\t{ model: 'heading3', view: 'h4', title: 'Heading 3', class: 'ck-heading_heading3' }\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ Paragraph ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst options = editor.config.get( 'heading.options' );\n\n\t\tconst modelElements = [];\n\n\t\tfor ( const option of options ) {\n\t\t\t// Skip paragraph - it is defined in required Paragraph feature.\n\t\t\tif ( option.model !== defaultModelElement ) {\n\t\t\t\t// Schema.\n\t\t\t\teditor.model.schema.register( option.model, {\n\t\t\t\t\tinheritAllFrom: '$block'\n\t\t\t\t} );\n\n\t\t\t\teditor.conversion.elementToElement( option );\n\n\t\t\t\tmodelElements.push( option.model );\n\t\t\t}\n\t\t}\n\n\t\tthis._addDefaultH1Conversion( editor );\n\n\t\t// Register the heading command for this option.\n\t\teditor.commands.add( 'heading', new HeadingCommand( editor, modelElements ) );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tafterInit() {\n\t\t// If the enter command is added to the editor, alter its behavior.\n\t\t// Enter at the end of a heading element should create a paragraph.\n\t\tconst editor = this.editor;\n\t\tconst enterCommand = editor.commands.get( 'enter' );\n\t\tconst options = editor.config.get( 'heading.options' );\n\n\t\tif ( enterCommand ) {\n\t\t\tthis.listenTo( enterCommand, 'afterExecute', ( evt, data ) => {\n\t\t\t\tconst positionParent = editor.model.document.selection.getFirstPosition().parent;\n\t\t\t\tconst isHeading = options.some( option => positionParent.is( option.model ) );\n\n\t\t\t\tif ( isHeading && !positionParent.is( defaultModelElement ) && positionParent.childCount === 0 ) {\n\t\t\t\t\tdata.writer.rename( positionParent, defaultModelElement );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Adds default conversion for `h1` -> `heading1` with a low priority.\n\t *\n\t * @private\n\t * @param {module:core/editor/editor~Editor} editor Editor instance on which to add the `h1` conversion.\n\t */\n\t_addDefaultH1Conversion( editor ) {\n\t\teditor.conversion.for( 'upcast' ).elementToElement( {\n\t\t\tmodel: 'heading1',\n\t\t\tview: 'h1',\n\t\t\t// With a `low` priority, `paragraph` plugin autoparagraphing mechanism is executed. Make sure\n\t\t\t// this listener is called before it. If not, `h1` will be transformed into a paragraph.\n\t\t\tconverterPriority: priorities.get( 'low' ) + 1\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/model\n */\n\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport { extend } from 'lodash-es';\n\n/**\n * The base MVC model class.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Model {\n\t/**\n\t * Creates a new Model instance.\n\t *\n\t * @param {Object} [attributes] The model state attributes to be defined during the instance creation.\n\t * @param {Object} [properties] The (out of state) properties to be appended to the instance during creation.\n\t */\n\tconstructor( attributes, properties ) {\n\t\t// Extend this instance with the additional (out of state) properties.\n\t\tif ( properties ) {\n\t\t\textend( this, properties );\n\t\t}\n\n\t\t// Initialize the attributes.\n\t\tif ( attributes ) {\n\t\t\tthis.set( attributes );\n\t\t}\n\t}\n}\n\nmix( Model, ObservableMixin );\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/dropdown/dropdownpanelview\n */\n\nimport View from '../view';\n\n/**\n * The dropdown panel view class.\n *\n * See {@link module:ui/dropdown/dropdownview~DropdownView} to learn about the common usage.\n *\n * @extends module:ui/view~View\n */\nexport default class DropdownPanelView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * Controls whether the panel is visible.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isVisible\n\t\t */\n\t\tthis.set( 'isVisible', false );\n\n\t\t/**\n\t\t * The position of the panel, relative to the parent.\n\t\t *\n\t\t * This property is reflected in the CSS class set to {@link #element} that controls\n\t\t * the position of the panel.\n\t\t *\n\t\t * @observable\n\t\t * @default 'se'\n\t\t * @member {'se'|'sw'|'ne'|'nw'} #position\n\t\t */\n\t\tthis.set( 'position', 'se' );\n\n\t\t/**\n\t\t * Collection of the child views in this panel.\n\t\t *\n\t\t * A common child type is the {@link module:ui/list/listview~ListView} and {@link module:ui/toolbar/toolbarview~ToolbarView}.\n\t\t * See {@link module:ui/dropdown/utils~addListToDropdown} and\n\t\t * {@link module:ui/dropdown/utils~addToolbarToDropdown} to learn more about child views of dropdowns.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.children = this.createCollection();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-reset',\n\t\t\t\t\t'ck-dropdown__panel',\n\t\t\t\t\tbind.to( 'position', value => `ck-dropdown__panel_${ value }` ),\n\t\t\t\t\tbind.if( 'isVisible', 'ck-dropdown__panel-visible' )\n\t\t\t\t]\n\t\t\t},\n\n\t\t\tchildren: this.children,\n\n\t\t\ton: {\n\t\t\t\t// Drag and drop in the panel should not break the selection in the editor.\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/228\n\t\t\t\tselectstart: bind.to( evt => evt.preventDefault() )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Focuses the view element or first item in view collection on opening dropdown's panel.\n\t *\n\t * See also {@link module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable}.\n\t */\n\tfocus() {\n\t\tif ( this.children.length ) {\n\t\t\tthis.children.first.focus();\n\t\t}\n\t}\n\n\t/**\n\t * Focuses the view element or last item in view collection on opening dropdown's panel.\n\t *\n\t * See also {@link module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable}.\n\t */\n\tfocusLast() {\n\t\tif ( this.children.length ) {\n\t\t\tconst lastChild = this.children.last;\n\n\t\t\tif ( typeof lastChild.focusLast === 'function' ) {\n\t\t\t\tlastChild.focusLast();\n\t\t\t} else {\n\t\t\t\tlastChild.focus();\n\t\t\t}\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/dropdown/dropdownview\n */\n\nimport View from '../view';\nimport FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';\nimport KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';\n\nimport '../../theme/components/dropdown/dropdown.css';\n\nimport { getOptimalPosition } from '@ckeditor/ckeditor5-utils/src/dom/position';\n\n/**\n * The dropdown view class. It manages the dropdown button and dropdown panel.\n *\n * In most cases, the easiest way to create a dropdown is by using the {@link module:ui/dropdown/utils~createDropdown}\n * util:\n *\n *\t\tconst dropdown = createDropdown( locale );\n *\n *\t\t// Configure dropdown's button properties:\n *\t\tdropdown.buttonView.set( {\n *\t\t\tlabel: 'A dropdown',\n *\t\t\twithText: true\n *\t\t} );\n *\n *\t\tdropdown.render();\n *\n *\t\tdropdown.panelView.element.textContent = 'Content of the panel';\n *\n *\t\t// Will render a dropdown with a panel containing a \"Content of the panel\" text.\n *\t\tdocument.body.appendChild( dropdown.element );\n *\n * If you want to add a richer content to the dropdown panel, you can use the {@link module:ui/dropdown/utils~addListToDropdown}\n * and {@link module:ui/dropdown/utils~addToolbarToDropdown} helpers. See more examples in\n * {@link module:ui/dropdown/utils~createDropdown} documentation.\n *\n * If you want to create a completely custom dropdown, then you can compose it manually:\n *\n *\t\tconst button = new DropdownButtonView( locale );\n *\t\tconst panel = new DropdownPanelView( locale );\n *\t\tconst dropdown = new DropdownView( locale, button, panel );\n *\n *\t\tbutton.set( {\n *\t\t\tlabel: 'A dropdown',\n *\t\t\twithText: true\n *\t\t} );\n *\n *\t\tdropdown.render();\n *\n *\t\tpanel.element.textContent = 'Content of the panel';\n *\n *\t\t// Will render a dropdown with a panel containing a \"Content of the panel\" text.\n *\t\tdocument.body.appendChild( dropdown.element );\n *\n * However, dropdown created this way will contain little behavior. You will need to implement handlers for actions\n * such as {@link module:ui/bindings/clickoutsidehandler~clickOutsideHandler clicking outside an open dropdown}\n * (which should close it) and support for arrow keys inside the panel. Therefore, unless you really know what\n * you do and you really need to do it, it is recommended to use the {@link module:ui/dropdown/utils~createDropdown} helper.\n *\n * @extends module:ui/view~View\n */\nexport default class DropdownView extends View {\n\t/**\n\t * Creates an instance of the dropdown.\n\t *\n\t * Also see {@link #render}.\n\t *\n\t * @param {module:utils/locale~Locale} [locale] The localization services instance.\n\t * @param {module:ui/dropdown/button/dropdownbutton~DropdownButton} buttonView\n\t * @param {module:ui/dropdown/dropdownpanelview~DropdownPanelView} panelView\n\t */\n\tconstructor( locale, buttonView, panelView ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * Button of the dropdown view. Clicking the button opens the {@link #panelView}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/button/buttonview~ButtonView} #buttonView\n\t\t */\n\t\tthis.buttonView = buttonView;\n\n\t\t/**\n\t\t * Panel of the dropdown. It opens when the {@link #buttonView} is\n\t\t * {@link module:ui/button/buttonview~ButtonView#event:execute executed} (i.e. clicked).\n\t\t *\n\t\t * Child views can be added to the panel's `children` collection:\n\t\t *\n\t\t *\t\tdropdown.panelView.children.add( childView );\n\t\t *\n\t\t * See {@link module:ui/dropdown/dropdownpanelview~DropdownPanelView#children} and\n\t\t * {@link module:ui/viewcollection~ViewCollection#add}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/dropdown/dropdownpanelview~DropdownPanelView} #panelView\n\t\t */\n\t\tthis.panelView = panelView;\n\n\t\t/**\n\t\t * Controls whether the dropdown view is open, i.e. shows or hides the {@link #panelView panel}.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isOpen\n\t\t */\n\t\tthis.set( 'isOpen', false );\n\n\t\t/**\n\t\t * Controls whether the dropdown is enabled, i.e. it can be clicked and execute an action.\n\t\t *\n\t\t * See {@link module:ui/button/buttonview~ButtonView#isEnabled}.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\t\tthis.set( 'isEnabled', true );\n\n\t\t/**\n\t\t * (Optional) The additional CSS class set on the dropdown {@link #element}.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #class\n\t\t */\n\t\tthis.set( 'class' );\n\n\t\t/**\n\t\t * The position of the panel, relative to the dropdown.\n\t\t *\n\t\t * **Note**: When `'auto'`, the panel will use one of the remaining positions to stay\n\t\t * in the viewport, visible to the user. The positions correspond directly to\n\t\t * {@link module:ui/dropdown/dropdownview~DropdownView.defaultPanelPositions default panel positions}.\n\t\t *\n\t\t * **Note**: This value has an impact on the\n\t\t * {@link module:ui/dropdown/dropdownpanelview~DropdownPanelView#position} property\n\t\t * each time the panel becomes {@link #isOpen open}.\n\t\t *\n\t\t * @observable\n\t\t * @default 'auto'\n\t\t * @member {'auto'|'se'|'sw'|'ne'|'nw'} #panelPosition\n\t\t */\n\t\tthis.set( 'panelPosition', 'auto' );\n\n\t\t/**\n\t\t * Tracks information about DOM focus in the dropdown.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/focustracker~FocusTracker}\n\t\t */\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\t/**\n\t\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}. It manages\n\t\t * keystrokes of the dropdown:\n\t\t *\n\t\t * * <kbd>▼</kbd> opens the dropdown,\n\t\t * * <kbd>◀</kbd> and <kbd>Esc</kbd> closes the dropdown.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/keystrokehandler~KeystrokeHandler}\n\t\t */\n\t\tthis.keystrokes = new KeystrokeHandler();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-dropdown',\n\t\t\t\t\tbind.to( 'class' ),\n\t\t\t\t\tbind.if( 'isEnabled', 'ck-disabled', value => !value )\n\t\t\t\t]\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\tbuttonView,\n\t\t\t\tpanelView\n\t\t\t]\n\t\t} );\n\n\t\tbuttonView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-dropdown__button',\n\t\t\t\t]\n\t\t\t}\n\t\t} );\n\n\t\t/**\n\t\t * A child {@link module:ui/list/listview~ListView list view} of the dropdown located\n\t\t * in its {@link module:ui/dropdown/dropdownview~DropdownView#panelView panel}.\n\t\t *\n\t\t * **Note**: Only supported when dropdown has list view added using {@link module:ui/dropdown/utils~addListToDropdown}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/list/listview~ListView} #listView\n\t\t */\n\n\t\t/**\n\t\t * A child toolbar of the dropdown located in the\n\t\t * {@link module:ui/dropdown/dropdownview~DropdownView#panelView panel}.\n\t\t *\n\t\t * **Note**: Only supported when dropdown has list view added using {@link module:ui/dropdown/utils~addToolbarToDropdown}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/toolbar/toolbarview~ToolbarView} #toolbarView\n\t\t */\n\n\t\t/**\n\t\t * Fired when the toolbar button or list item is executed.\n\t\t *\n\t\t * For {@link #listView} It fires when a child of some {@link module:ui/list/listitemview~ListItemView}\n\t\t * fired `execute`.\n\t\t *\n\t\t * For {@link #toolbarView} It fires when one of the buttons has been\n\t\t * {@link module:ui/button/buttonview~ButtonView#event:execute executed}.\n\t\t *\n\t\t * **Note**: Only supported when dropdown has list view added using {@link module:ui/dropdown/utils~addListToDropdown}\n\t\t * or {@link module:ui/dropdown/utils~addToolbarToDropdown}.\n\t\t *\n\t\t * @event execute\n\t\t */\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\t// Toggle the dropdown when its button has been clicked.\n\t\tthis.listenTo( this.buttonView, 'open', () => {\n\t\t\tthis.isOpen = !this.isOpen;\n\t\t} );\n\n\t\t// Toggle the visibility of the panel when the dropdown becomes open.\n\t\tthis.panelView.bind( 'isVisible' ).to( this, 'isOpen' );\n\n\t\t// Let the dropdown control the position of the panel. The position must\n\t\t// be updated every time the dropdown is open.\n\t\tthis.on( 'change:isOpen', () => {\n\t\t\tif ( !this.isOpen ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If \"auto\", find the best position of the panel to fit into the viewport.\n\t\t\t// Otherwise, simply assign the static position.\n\t\t\tif ( this.panelPosition === 'auto' ) {\n\t\t\t\tconst defaultPanelPositions = DropdownView.defaultPanelPositions;\n\n\t\t\t\tthis.panelView.position = getOptimalPosition( {\n\t\t\t\t\telement: this.panelView.element,\n\t\t\t\t\ttarget: this.buttonView.element,\n\t\t\t\t\tfitInViewport: true,\n\t\t\t\t\tpositions: [\n\t\t\t\t\t\tdefaultPanelPositions.southEast,\n\t\t\t\t\t\tdefaultPanelPositions.southWest,\n\t\t\t\t\t\tdefaultPanelPositions.northEast,\n\t\t\t\t\t\tdefaultPanelPositions.northWest\n\t\t\t\t\t]\n\t\t\t\t} ).name;\n\t\t\t} else {\n\t\t\t\tthis.panelView.position = this.panelPosition;\n\t\t\t}\n\t\t} );\n\n\t\t// Listen for keystrokes coming from within #element.\n\t\tthis.keystrokes.listenTo( this.element );\n\n\t\t// Register #element in the focus tracker.\n\t\tthis.focusTracker.add( this.element );\n\n\t\tconst closeDropdown = ( data, cancel ) => {\n\t\t\tif ( this.isOpen ) {\n\t\t\t\tthis.buttonView.focus();\n\t\t\t\tthis.isOpen = false;\n\t\t\t\tcancel();\n\t\t\t}\n\t\t};\n\n\t\t// Open the dropdown panel using the arrow down key, just like with return or space.\n\t\tthis.keystrokes.set( 'arrowdown', ( data, cancel ) => {\n\t\t\t// Don't open if the dropdown is disabled or already open.\n\t\t\tif ( this.buttonView.isEnabled && !this.isOpen ) {\n\t\t\t\tthis.isOpen = true;\n\t\t\t\tcancel();\n\t\t\t}\n\t\t} );\n\n\t\t// Block the right arrow key (until nested dropdowns are implemented).\n\t\tthis.keystrokes.set( 'arrowright', ( data, cancel ) => {\n\t\t\tif ( this.isOpen ) {\n\t\t\t\tcancel();\n\t\t\t}\n\t\t} );\n\n\t\t// Close the dropdown using the arrow left/escape key.\n\t\tthis.keystrokes.set( 'arrowleft', closeDropdown );\n\t\tthis.keystrokes.set( 'esc', closeDropdown );\n\t}\n\n\t/**\n\t * Focuses the {@link #buttonView}.\n\t */\n\tfocus() {\n\t\tthis.buttonView.focus();\n\t}\n}\n\n/**\n * A set of positioning functions used by the dropdown view to determine\n * the optimal position (i.e. fitting into the browser viewport) of its\n * {@link module:ui/dropdown/dropdownview~DropdownView#panelView panel} when\n * {@link module:ui/dropdown/dropdownview~DropdownView#panelPosition} is set to 'auto'`.\n *\n * The available positioning functions are as follow:\n *\n * **South**\n *\n * * `southEast`\n *\n *\t\t[ Button ]\n *\t\t+-----------------+\n *\t\t| Panel |\n *\t\t+-----------------+\n *\n * * `southWest`\n *\n *\t\t [ Button ]\n *\t\t+-----------------+\n *\t\t| Panel |\n *\t\t+-----------------+\n *\n * **North**\n *\n * * `northEast`\n *\n *\t\t+-----------------+\n *\t\t| Panel |\n *\t\t+-----------------+\n *\t\t[ Button ]\n *\n * * `northWest`\n *\n *\t\t+-----------------+\n *\t\t| Panel |\n *\t\t+-----------------+\n *\t\t [ Button ]\n *\n * Positioning functions are compatible with {@link module:utils/dom/position~Position}.\n *\n * The name that position function returns will be reflected in dropdown panel's class that\n * controls its placement. See {@link module:ui/dropdown/dropdownview~DropdownView#panelPosition}\n * to learn more.\n *\n * @member {Object} module:ui/dropdown/dropdownview~DropdownView.defaultPanelPositions\n */\nDropdownView.defaultPanelPositions = {\n\tsouthEast: buttonRect => {\n\t\treturn {\n\t\t\ttop: buttonRect.bottom,\n\t\t\tleft: buttonRect.left,\n\t\t\tname: 'se'\n\t\t};\n\t},\n\tsouthWest: ( buttonRect, panelRect ) => {\n\t\treturn {\n\t\t\ttop: buttonRect.bottom,\n\t\t\tleft: buttonRect.left - panelRect.width + buttonRect.width,\n\t\t\tname: 'sw'\n\t\t};\n\t},\n\tnorthEast: ( buttonRect, panelRect ) => {\n\t\treturn {\n\t\t\ttop: buttonRect.top - panelRect.height,\n\t\t\tleft: buttonRect.left,\n\t\t\tname: 'ne'\n\t\t};\n\t},\n\tnorthWest: ( buttonRect, panelRect ) => {\n\t\treturn {\n\t\t\ttop: buttonRect.bottom - panelRect.height,\n\t\t\tleft: buttonRect.left - panelRect.width + buttonRect.width,\n\t\t\tname: 'nw'\n\t\t};\n\t}\n};\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/dropdown/button/dropdownbuttonview\n */\n\nimport ButtonView from '../../button/buttonview';\n\nimport dropdownArrowIcon from '../../../theme/icons/dropdown-arrow.svg';\nimport IconView from '../../icon/iconview';\n\n/**\n * The default dropdown button view class.\n *\n *\t\tconst view = new DropdownButtonView();\n *\n *\t\tview.set( {\n *\t\t\tlabel: 'A button',\n *\t\t\tkeystroke: 'Ctrl+B',\n *\t\t\ttooltip: true\n *\t\t} );\n *\n *\t\tview.render();\n *\n *\t\tdocument.body.append( view.element );\n *\n * Also see the {@link module:ui/dropdown/utils~createDropdown `createDropdown()` util}.\n *\n * @implements module:ui/dropdown/button/dropdownbutton~DropdownButton\n * @extends module:ui/button/buttonview~ButtonView\n */\nexport default class DropdownButtonView extends ButtonView {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\t/**\n\t\t * An icon that displays arrow to indicate a dropdown button.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/icon/iconview~IconView}\n\t\t */\n\t\tthis.arrowView = this._createArrowView();\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\t'aria-haspopup': true\n\t\t\t}\n\t\t} );\n\n\t\t// The DropdownButton interface expects the open event upon which will open the dropdown.\n\t\tthis.delegate( 'execute' ).to( this, 'open' );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\tthis.children.add( this.arrowView );\n\t}\n\n\t/**\n\t * Creates a {@link module:ui/icon/iconview~IconView} instance as {@link #arrowView}.\n\t *\n\t * @private\n\t * @returns {module:ui/icon/iconview~IconView}\n\t */\n\t_createArrowView() {\n\t\tconst arrowView = new IconView();\n\n\t\tarrowView.content = dropdownArrowIcon;\n\n\t\tarrowView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-dropdown__arrow'\n\t\t\t}\n\t\t} );\n\n\t\treturn arrowView;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/list/listview\n */\n\nimport View from '../view';\nimport FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';\nimport FocusCycler from '../focuscycler';\nimport KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';\n\nimport '../../theme/components/list/list.css';\n\n/**\n * The list view class.\n *\n * @extends module:ui/view~View\n * @implements module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable\n */\nexport default class ListView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * Collection of the child list views.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.items = this.createCollection();\n\n\t\t/**\n\t\t * Tracks information about DOM focus in the list.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/focustracker~FocusTracker}\n\t\t */\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\t/**\n\t\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/keystrokehandler~KeystrokeHandler}\n\t\t */\n\t\tthis.keystrokes = new KeystrokeHandler();\n\n\t\t/**\n\t\t * Helps cycling over focusable {@link #items} in the list.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/focuscycler~FocusCycler}\n\t\t */\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this.items,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate list items backwards using the arrowup key.\n\t\t\t\tfocusPrevious: 'arrowup',\n\n\t\t\t\t// Navigate toolbar items forwards using the arrowdown key.\n\t\t\t\tfocusNext: 'arrowdown',\n\t\t\t}\n\t\t} );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'ul',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-reset',\n\t\t\t\t\t'ck-list'\n\t\t\t\t]\n\t\t\t},\n\n\t\t\tchildren: this.items\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\t// Items added before rendering should be known to the #focusTracker.\n\t\tfor ( const item of this.items ) {\n\t\t\tthis.focusTracker.add( item.element );\n\t\t}\n\n\t\tthis.items.on( 'add', ( evt, item ) => {\n\t\t\tthis.focusTracker.add( item.element );\n\t\t} );\n\n\t\tthis.items.on( 'remove', ( evt, item ) => {\n\t\t\tthis.focusTracker.remove( item.element );\n\t\t} );\n\n\t\t// Start listening for the keystrokes coming from #element.\n\t\tthis.keystrokes.listenTo( this.element );\n\t}\n\n\t/**\n\t * Focuses the first focusable in {@link #items}.\n\t */\n\tfocus() {\n\t\tthis._focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * Focuses the last focusable in {@link #items}.\n\t */\n\tfocusLast() {\n\t\tthis._focusCycler.focusLast();\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/list/listitemview\n */\n\nimport View from '../view';\n\n/**\n * The list item view class.\n *\n * @extends module:ui/view~View\n */\nexport default class ListItemView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\t/**\n\t\t * Collection of the child views inside of the list item {@link #element}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.children = this.createCollection();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'li',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-list__item'\n\t\t\t\t]\n\t\t\t},\n\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n\n\t/**\n\t * Focuses the list item.\n\t */\n\tfocus() {\n\t\tthis.children.first.focus();\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/list/listseparatorview\n */\n\nimport View from '../view';\n\n/**\n * The list separator view class.\n *\n * @extends module:ui/view~View\n */\nexport default class ListSeparatorView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'li',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-list__separator'\n\t\t\t\t]\n\t\t\t}\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/button/switchbuttonview\n */\n\nimport View from '../view';\nimport ButtonView from './buttonview';\n\nimport '../../theme/components/button/switchbutton.css';\n\n/**\n * The switch button view class.\n *\n *\t\tconst view = new SwitchButtonView();\n *\n *\t\tview.set( {\n *\t\t\twithText: true,\n *\t\t\tlabel: 'Switch me!'\n *\t\t} );\n *\n *\t\tview.render();\n *\n *\t\tdocument.body.append( view.element );\n *\n * @extends module:ui/buttonview~ButtonView\n */\nexport default class SwitchButtonView extends ButtonView {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\t/**\n\t\t * The toggle switch of the button.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/view~View} #toggleSwitchView\n\t\t */\n\t\tthis.toggleSwitchView = this._createToggleView();\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-switchbutton'\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\tthis.children.add( this.toggleSwitchView );\n\t}\n\n\t/**\n\t * Creates a toggle child view.\n\t *\n\t * @private\n\t * @returns {module:ui/view~View}\n\t */\n\t_createToggleView() {\n\t\tconst toggleSwitchView = new View();\n\n\t\ttoggleSwitchView.setTemplate( {\n\t\t\ttag: 'span',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-button__toggle'\n\t\t\t\t],\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'span',\n\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [\n\t\t\t\t\t\t\t'ck',\n\t\t\t\t\t\t\t'ck-button__toggle__inner'\n\t\t\t\t\t\t],\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\n\t\treturn toggleSwitchView;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/bindings/clickoutsidehandler\n */\n\n/* global document */\n\n/**\n * Handles clicking **outside** of a specified set of elements, then fires an action.\n *\n * **Note**: Actually, the action is executed upon `mousedown`, not `click`. It prevents\n * certain issues when the user keeps holding the mouse button and the UI cannot react\n * properly.\n *\n * @param {Object} options Configuration options.\n * @param {module:utils/dom/emittermixin~Emitter} options.emitter The emitter to which this behavior\n * should be added.\n * @param {Function} options.activator Function returning a `Boolean`, to determine whether the handler is active.\n * @param {Array.<HTMLElement>} options.contextElements HTML elements that determine the scope of the\n * handler. Clicking any of them or their descendants will **not** fire the callback.\n * @param {Function} options.callback An action executed by the handler.\n */\nexport default function clickOutsideHandler( { emitter, activator, callback, contextElements } ) {\n\temitter.listenTo( document, 'mousedown', ( evt, { target } ) => {\n\t\tif ( !activator() ) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor ( const contextElement of contextElements ) {\n\t\t\tif ( contextElement.contains( target ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tcallback();\n\t} );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/dropdown/utils\n */\n\nimport DropdownPanelView from './dropdownpanelview';\nimport DropdownView from './dropdownview';\nimport DropdownButtonView from './button/dropdownbuttonview';\nimport ToolbarView from '../toolbar/toolbarview';\nimport ListView from '../list/listview';\nimport ListItemView from '../list/listitemview';\nimport ListSeparatorView from '../list/listseparatorview';\nimport ButtonView from '../button/buttonview';\nimport SwitchButtonView from '../button/switchbuttonview';\n\nimport clickOutsideHandler from '../bindings/clickoutsidehandler';\n\nimport '../../theme/components/dropdown/toolbardropdown.css';\nimport '../../theme/components/dropdown/listdropdown.css';\n\n/**\n * A helper for creating dropdowns. It creates an instance of a {@link module:ui/dropdown/dropdownview~DropdownView dropdown},\n * with a {@link module:ui/dropdown/button/dropdownbutton~DropdownButton button},\n * {@link module:ui/dropdown/dropdownpanelview~DropdownPanelView panel} and all standard dropdown's behaviors.\n *\n * # Creating dropdowns\n *\n * By default, the default {@link module:ui/dropdown/button/dropdownbuttonview~DropdownButtonView} class is used as\n * definition of the button:\n *\n *\t\tconst dropdown = createDropdown( model );\n *\n *\t\t// Configure dropdown's button properties:\n *\t\tdropdown.buttonView.set( {\n *\t\t\tlabel: 'A dropdown',\n *\t\t\twithText: true\n *\t\t} );\n *\n *\t\tdropdown.render();\n *\n *\t\t// Will render a dropdown labeled \"A dropdown\" with an empty panel.\n *\t\tdocument.body.appendChild( dropdown.element );\n *\n * You can also provide other button views (they need to implement the\n * {@link module:ui/dropdown/button/dropdownbutton~DropdownButton} interface). For instance, you can use\n * {@link module:ui/dropdown/button/splitbuttonview~SplitButtonView} to create a dropdown with a split button.\n *\n *\t\tconst dropdown = createDropdown( model, SplitButtonView );\n *\n *\t\t// Configure dropdown's button properties:\n *\t\tdropdown.buttonView.set( {\n *\t\t\tlabel: 'A dropdown',\n *\t\t\twithText: true\n *\t\t} );\n *\n *\t\tdropdown.buttonView.on( 'execute', () => {\n *\t\t\t// Add the behavior of the \"action part\" of the split button.\n *\t\t\t// Split button consists of the \"action part\" and \"arrow part\".\n *\t\t\t// The arrow opens the dropdown while the action part can have some other behavior.\n * \t\t} );\n *\n *\t\tdropdown.render();\n *\n *\t\t// Will render a dropdown labeled \"A dropdown\" with an empty panel.\n *\t\tdocument.body.appendChild( dropdown.element );\n *\n * # Adding content to the dropdown's panel\n *\n * The content of the panel can be inserted directly into the `dropdown.panelView.element`:\n *\n *\t\tdropdown.panelView.element.textContent = 'Content of the panel';\n *\n * However, most of the time you will want to add there either a {@link module:ui/list/listview~ListView list of options}\n * or a list of buttons (i.e. a {@link module:ui/toolbar/toolbarview~ToolbarView toolbar}).\n * To simplify the task, you can use, respectively, {@link module:ui/dropdown/utils~addListToDropdown} or\n * {@link module:ui/dropdown/utils~addToolbarToDropdown} utils.\n *\n * @param {module:utils/locale~Locale} locale The locale instance.\n * @param {Function} ButtonClass The dropdown button view class. Needs to implement the\n * {@link module:ui/dropdown/button/dropdownbutton~DropdownButton} interface.\n * @returns {module:ui/dropdown/dropdownview~DropdownView} The dropdown view instance.\n */\nexport function createDropdown( locale, ButtonClass = DropdownButtonView ) {\n\tconst buttonView = new ButtonClass( locale );\n\n\tconst panelView = new DropdownPanelView( locale );\n\tconst dropdownView = new DropdownView( locale, buttonView, panelView );\n\n\tbuttonView.bind( 'isEnabled' ).to( dropdownView );\n\n\tif ( buttonView instanceof DropdownButtonView ) {\n\t\tbuttonView.bind( 'isOn' ).to( dropdownView, 'isOpen' );\n\t} else {\n\t\tbuttonView.arrowView.bind( 'isOn' ).to( dropdownView, 'isOpen' );\n\t}\n\n\taddDefaultBehavior( dropdownView );\n\n\treturn dropdownView;\n}\n\n/**\n * Adds an instance of {@link module:ui/toolbar/toolbarview~ToolbarView} to a dropdown.\n *\n *\t\tconst buttons = [];\n *\n *\t\t// Either create a new ButtonView instance or create existing.\n *\t\tbuttons.push( new ButtonView() );\n *\t\tbuttons.push( editor.ui.componentFactory.get( 'someButton' ) );\n *\n *\t\tconst dropdown = createDropdown( locale );\n *\n *\t\taddToolbarToDropdown( dropdown, buttons );\n *\n *\t\tdropdown.toolbarView.isVertical = true;\n *\n *\t\t// Will render a vertical button dropdown labeled \"A button dropdown\"\n *\t\t// with a button group in the panel containing two buttons.\n *\t\tdropdown.render()\n *\t\tdocument.body.appendChild( dropdown.element );\n *\n * See {@link module:ui/dropdown/utils~createDropdown} and {@link module:ui/toolbar/toolbarview~ToolbarView}.\n *\n * @param {module:ui/dropdown/dropdownview~DropdownView} dropdownView A dropdown instance to which `ToolbarView` will be added.\n * @param {Iterable.<module:ui/button/buttonview~ButtonView>} buttons\n */\nexport function addToolbarToDropdown( dropdownView, buttons ) {\n\tconst toolbarView = dropdownView.toolbarView = new ToolbarView();\n\n\tdropdownView.extendTemplate( {\n\t\tattributes: {\n\t\t\tclass: [ 'ck-toolbar-dropdown' ]\n\t\t}\n\t} );\n\n\tbuttons.map( view => toolbarView.items.add( view ) );\n\n\tdropdownView.panelView.children.add( toolbarView );\n\ttoolbarView.items.delegate( 'execute' ).to( dropdownView );\n}\n\n/**\n * Adds an instance of {@link module:ui/list/listview~ListView} to a dropdown.\n *\n *\t\tconst items = new Collection();\n *\n *\t\titems.add( {\n *\t\t\ttype: 'button',\n *\t\t\tmodel: new Model( {\n *\t\t\t\twithText: true,\n *\t\t\t\tlabel: 'First item',\n *\t\t\t\tlabelStyle: 'color: red'\n *\t\t\t} )\n *\t\t} );\n *\n *\t\titems.add( {\n *\t\t\t type: 'button',\n *\t\t\t model: new Model( {\n *\t\t\t\twithText: true,\n *\t\t\t\tlabel: 'Second item',\n *\t\t\t\tlabelStyle: 'color: green',\n *\t\t\t\tclass: 'foo'\n *\t\t\t} )\n *\t\t} );\n *\n *\t\tconst dropdown = createDropdown( locale );\n *\n *\t\taddListToDropdown( dropdown, items );\n *\n *\t\t// Will render a dropdown with a list in the panel containing two items.\n *\t\tdropdown.render()\n *\t\tdocument.body.appendChild( dropdown.element );\n *\n * The `items` collection passed to this methods controls the presence and attributes of respective\n * {@link module:ui/list/listitemview~ListItemView list items}.\n *\n *\n * See {@link module:ui/dropdown/utils~createDropdown} and {@link module:list/list~List}.\n *\n * @param {module:ui/dropdown/dropdownview~DropdownView} dropdownView A dropdown instance to which `ListVIew` will be added.\n * @param {Iterable.<module:ui/dropdown/utils~ListDropdownItemDefinition>} items\n * A collection of the list item definitions to populate the list.\n */\nexport function addListToDropdown( dropdownView, items ) {\n\tconst locale = dropdownView.locale;\n\tconst listView = dropdownView.listView = new ListView( locale );\n\n\tlistView.items.bindTo( items ).using( ( { type, model } ) => {\n\t\tif ( type === 'separator' ) {\n\t\t\treturn new ListSeparatorView( locale );\n\t\t} else if ( type === 'button' || type === 'switchbutton' ) {\n\t\t\tconst listItemView = new ListItemView( locale );\n\t\t\tlet buttonView;\n\n\t\t\tif ( type === 'button' ) {\n\t\t\t\tbuttonView = new ButtonView( locale );\n\t\t\t} else {\n\t\t\t\tbuttonView = new SwitchButtonView( locale );\n\t\t\t}\n\n\t\t\t// Bind all model properties to the button view.\n\t\t\tbuttonView.bind( ...Object.keys( model ) ).to( model );\n\t\t\tbuttonView.delegate( 'execute' ).to( listItemView );\n\n\t\t\tlistItemView.children.add( buttonView );\n\n\t\t\treturn listItemView;\n\t\t}\n\t} );\n\n\tdropdownView.panelView.children.add( listView );\n\n\tlistView.items.delegate( 'execute' ).to( dropdownView );\n}\n\n// Add a set of default behaviors to dropdown view.\n//\n// @param {module:ui/dropdown/dropdownview~DropdownView} dropdownView\nfunction addDefaultBehavior( dropdownView ) {\n\tcloseDropdownOnBlur( dropdownView );\n\tcloseDropdownOnExecute( dropdownView );\n\tfocusDropdownContentsOnArrows( dropdownView );\n}\n\n// Adds a behavior to a dropdownView that closes opened dropdown when user clicks outside the dropdown.\n//\n// @param {module:ui/dropdown/dropdownview~DropdownView} dropdownView\nfunction closeDropdownOnBlur( dropdownView ) {\n\tdropdownView.on( 'render', () => {\n\t\tclickOutsideHandler( {\n\t\t\temitter: dropdownView,\n\t\t\tactivator: () => dropdownView.isOpen,\n\t\t\tcallback: () => {\n\t\t\t\tdropdownView.isOpen = false;\n\t\t\t},\n\t\t\tcontextElements: [ dropdownView.element ]\n\t\t} );\n\t} );\n}\n\n// Adds a behavior to a dropdownView that closes the dropdown view on \"execute\" event.\n//\n// @param {module:ui/dropdown/dropdownview~DropdownView} dropdownView\nfunction closeDropdownOnExecute( dropdownView ) {\n\t// Close the dropdown when one of the list items has been executed.\n\tdropdownView.on( 'execute', evt => {\n\t\t// Toggling a switch button view should not close the dropdown.\n\t\tif ( evt.source instanceof SwitchButtonView ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdropdownView.isOpen = false;\n\t} );\n}\n\n// Adds a behavior to a dropdownView that focuses the dropdown's panel view contents on keystrokes.\n//\n// @param {module:ui/dropdown/dropdownview~DropdownView} dropdownView\nfunction focusDropdownContentsOnArrows( dropdownView ) {\n\t// If the dropdown panel is already open, the arrow down key should focus the first child of the #panelView.\n\tdropdownView.keystrokes.set( 'arrowdown', ( data, cancel ) => {\n\t\tif ( dropdownView.isOpen ) {\n\t\t\tdropdownView.panelView.focus();\n\t\t\tcancel();\n\t\t}\n\t} );\n\n\t// If the dropdown panel is already open, the arrow up key should focus the last child of the #panelView.\n\tdropdownView.keystrokes.set( 'arrowup', ( data, cancel ) => {\n\t\tif ( dropdownView.isOpen ) {\n\t\t\tdropdownView.panelView.focusLast();\n\t\t\tcancel();\n\t\t}\n\t} );\n}\n\n/**\n * A definition of the list item used by the {@link module:ui/dropdown/utils~addListToDropdown}\n * utility.\n *\n * @typedef {Object} module:ui/dropdown/utils~ListDropdownItemDefinition\n *\n * @property {String} type Either `'separator'`, `'button'` or `'switchbutton'`.\n * @property {module:ui/model~Model} [model] Model of the item (when **not** `'separator'`).\n * Its properties fuel the newly created list item (or its children, depending on the `type`).\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module heading/headingui\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport Model from '@ckeditor/ckeditor5-ui/src/model';\nimport {\n createDropdown,\n addListToDropdown\n} from '@ckeditor/ckeditor5-ui/src/dropdown/utils';\nimport { getLocalizedOptions } from './utils';\nimport Collection from '@ckeditor/ckeditor5-utils/src/collection';\nimport '../theme/heading.css';\n/**\n * The headings UI feature. It introduces the `headings` dropdown.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class HeadingUI extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const t = editor.t;\n const options = getLocalizedOptions(editor);\n const defaultTitle = t('an');\n const dropdownTooltip = t('ao');\n // Register UI component.\n editor.ui.componentFactory.add('heading', locale => {\n const titles = {};\n const itemDefinitions = new Collection();\n const headingCommand = editor.commands.get('heading');\n const paragraphCommand = editor.commands.get('paragraph');\n const commands = [headingCommand];\n for (const option of options) {\n const def = {\n type: 'button',\n model: new Model({\n label: option.title,\n class: option.class,\n withText: true\n })\n };\n if (option.model === 'paragraph') {\n def.model.bind('isOn').to(paragraphCommand, 'value');\n def.model.set('commandName', 'paragraph');\n commands.push(paragraphCommand);\n } else {\n def.model.bind('isOn').to(headingCommand, 'value', value => value === option.model);\n def.model.set({\n commandName: 'heading',\n commandValue: option.model\n });\n }\n // Add the option to the collection.\n itemDefinitions.add(def);\n titles[option.model] = option.title;\n }\n const dropdownView = createDropdown(locale);\n addListToDropdown(dropdownView, itemDefinitions);\n dropdownView.buttonView.set({\n isOn: false,\n withText: true,\n tooltip: dropdownTooltip\n });\n dropdownView.extendTemplate({ attributes: { class: ['ck-heading-dropdown'] } });\n dropdownView.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled) => {\n return areEnabled.some(isEnabled => isEnabled);\n });\n dropdownView.buttonView.bind('label').to(headingCommand, 'value', paragraphCommand, 'value', (value, para) => {\n const whichModel = value || para && 'paragraph';\n // If none of the commands is active, display default title.\n return titles[whichModel] ? titles[whichModel] : defaultTitle;\n });\n // Execute command when an item from the dropdown is selected.\n this.listenTo(dropdownView, 'execute', evt => {\n editor.execute(evt.source.commandName, evt.source.commandValue ? { value: evt.source.commandValue } : undefined);\n editor.editing.view.focus();\n });\n return dropdownView;\n });\n }\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * Returns heading options as defined in `config.heading.options` but processed to consider\n * editor localization, i.e. to display {@link module:heading/heading~HeadingOption}\n * in the correct language.\n *\n * Note: The reason behind this method is that there's no way to use {@link module:utils/locale~Locale#t}\n * when the user config is defined because the editor does not exist yet.\n *\n * @param {module:core/editor/editor~Editor} editor\n * @returns {Array.<module:heading/heading~HeadingOption>}.\n */\nexport function getLocalizedOptions(editor) {\n const t = editor.t;\n const localizedTitles = {\n Paragraph: t('as'),\n 'Heading 1': t('at'),\n 'Heading 2': t('au'),\n 'Heading 3': t('av'),\n 'Heading 4': t('aw'),\n 'Heading 5': t('ax'),\n 'Heading 6': t('ay')\n };\n return editor.config.get('heading.options').map(option => {\n const title = localizedTitles[option.title];\n if (title && title != option.title) {\n option.title = title;\n }\n return option;\n });\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/image/imageloadobserver\n */\n\nimport Observer from '@ckeditor/ckeditor5-engine/src/view/observer/observer';\n\n/**\n * Observes all new images added to the {@link module:engine/view/document~Document},\n * fires {@link module:engine/view/document~Document#event:imageLoaded} and\n * {@link module:engine/view/document~Document#event:layoutChanged} event every time when the new image\n * has been loaded.\n *\n * **Note:** This event is not fired for images that has been added to the document and rendered as `complete` (already loaded).\n *\n * @extends module:engine/view/observer/observer~Observer\n */\nexport default class ImageLoadObserver extends Observer {\n\tconstructor( view ) {\n\t\tsuper( view );\n\n\t\t/**\n\t\t * List of img DOM elements that are observed by this observer.\n\t\t *\n\t\t * @private\n\t\t * @type {Set.<HTMLElement>}\n\t\t */\n\t\tthis._observedElements = new Set();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tobserve( domRoot, name ) {\n\t\tconst viewRoot = this.document.getRoot( name );\n\n\t\t// When there is a change in one of the view element\n\t\t// we need to check if there are any new `<img/>` elements to observe.\n\t\tviewRoot.on( 'change:children', ( evt, node ) => {\n\t\t\t// Wait for the render to be sure that `<img/>` elements are rendered in the DOM root.\n\t\t\tthis.view.once( 'render', () => this._updateObservedElements( domRoot, node ) );\n\t\t} );\n\t}\n\n\t/**\n\t * Updates the list of observed `<img/>` elements.\n\t *\n\t * @private\n\t * @param {HTMLElement} domRoot DOM root element.\n\t * @param {module:engine/view/element~Element} viewNode View element where children have changed.\n\t */\n\t_updateObservedElements( domRoot, viewNode ) {\n\t\tif ( !viewNode.is( 'element' ) || viewNode.is( 'attributeElement' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst domNode = this.view.domConverter.mapViewToDom( viewNode );\n\n\t\t// If there is no `domNode` it means that it was removed from the DOM in the meanwhile.\n\t\tif ( !domNode ) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor ( const domElement of domNode.querySelectorAll( 'img' ) ) {\n\t\t\tif ( !this._observedElements.has( domElement ) ) {\n\t\t\t\tthis.listenTo( domElement, 'load', ( evt, domEvt ) => this._fireEvents( domEvt ) );\n\t\t\t\tthis._observedElements.add( domElement );\n\t\t\t}\n\t\t}\n\n\t\t// Clean up the list of observed elements from elements that has been removed from the root.\n\t\tfor ( const domElement of this._observedElements ) {\n\t\t\tif ( !domRoot.contains( domElement ) ) {\n\t\t\t\tthis.stopListening( domElement );\n\t\t\t\tthis._observedElements.delete( domElement );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Fires {@link module:engine/view/document~Document#event:layoutChanged} and\n\t * {@link module:engine/view/document~Document#event:imageLoaded}\n\t * if observer {@link #isEnabled is enabled}.\n\t *\n\t * @protected\n\t * @param {Event} domEvent The DOM event.\n\t */\n\t_fireEvents( domEvent ) {\n\t\tif ( this.isEnabled ) {\n\t\t\tthis.document.fire( 'layoutChanged' );\n\t\t\tthis.document.fire( 'imageLoaded', domEvent );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis._observedElements.clear();\n\t\tsuper.destroy();\n\t}\n}\n\n/**\n * Fired when an <img/> DOM element has been loaded in the DOM root.\n *\n * Introduced by {@link module:image/image/imageloadobserver~ImageLoadObserver}.\n *\n * @see module:image/image/imageloadobserver~ImageLoadObserver\n * @event module:engine/view/document~Document#event:imageLoaded\n * @param {module:engine/view/observer/domeventdata~DomEventData} data Event data.\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/image/converters\n */\n\nimport first from '@ckeditor/ckeditor5-utils/src/first';\n\n/**\n * Returns a function that converts the image view representation:\n *\n *\t\t<figure class=\"image\"><img src=\"...\" alt=\"...\"></img></figure>\n *\n * to the model representation:\n *\n *\t\t<image src=\"...\" alt=\"...\"></image>\n *\n * The entire content of the `<figure>` element except the first `<img>` is being converted as children\n * of the `<image>` model element.\n *\n * @returns {Function}\n */\nexport function viewFigureToModel() {\n\treturn dispatcher => {\n\t\tdispatcher.on( 'element:figure', converter );\n\t};\n\n\tfunction converter( evt, data, conversionApi ) {\n\t\t// Do not convert if this is not an \"image figure\".\n\t\tif ( !conversionApi.consumable.test( data.viewItem, { name: true, classes: 'image' } ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Find an image element inside the figure element.\n\t\tconst viewImage = Array.from( data.viewItem.getChildren() ).find( viewChild => viewChild.is( 'img' ) );\n\n\t\t// Do not convert if image element is absent, is missing src attribute or was already converted.\n\t\tif ( !viewImage || !viewImage.hasAttribute( 'src' ) || !conversionApi.consumable.test( viewImage, { name: true } ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Convert view image to model image.\n\t\tconst conversionResult = conversionApi.convertItem( viewImage, data.modelCursor );\n\n\t\t// Get image element from conversion result.\n\t\tconst modelImage = first( conversionResult.modelRange.getItems() );\n\n\t\t// When image wasn't successfully converted then finish conversion.\n\t\tif ( !modelImage ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Convert rest of the figure element's children as an image children.\n\t\tconversionApi.convertChildren( data.viewItem, conversionApi.writer.createPositionAt( modelImage, 0 ) );\n\n\t\t// Set image range as conversion result.\n\t\tdata.modelRange = conversionResult.modelRange;\n\n\t\t// Continue conversion where image conversion ends.\n\t\tdata.modelCursor = conversionResult.modelCursor;\n\t}\n}\n\n/**\n * Converter used to convert the `srcset` model image attribute to the `srcset`, `sizes` and `width` attributes in the view.\n *\n * @returns {Function}\n */\nexport function srcsetAttributeConverter() {\n\treturn dispatcher => {\n\t\tdispatcher.on( 'attribute:srcset:image', converter );\n\t};\n\n\tfunction converter( evt, data, conversionApi ) {\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst writer = conversionApi.writer;\n\t\tconst figure = conversionApi.mapper.toViewElement( data.item );\n\t\tconst img = figure.getChild( 0 );\n\n\t\tif ( data.attributeNewValue === null ) {\n\t\t\tconst srcset = data.attributeOldValue;\n\n\t\t\tif ( srcset.data ) {\n\t\t\t\twriter.removeAttribute( 'srcset', img );\n\t\t\t\twriter.removeAttribute( 'sizes', img );\n\n\t\t\t\tif ( srcset.width ) {\n\t\t\t\t\twriter.removeAttribute( 'width', img );\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst srcset = data.attributeNewValue;\n\n\t\t\tif ( srcset.data ) {\n\t\t\t\twriter.setAttribute( 'srcset', srcset.data, img );\n\t\t\t\t// Always outputting `100vw`. See https://github.com/ckeditor/ckeditor5-image/issues/2.\n\t\t\t\twriter.setAttribute( 'sizes', '100vw', img );\n\n\t\t\t\tif ( srcset.width ) {\n\t\t\t\t\twriter.setAttribute( 'width', srcset.width, img );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport function modelToViewAttributeConverter( attributeKey ) {\n\treturn dispatcher => {\n\t\tdispatcher.on( `attribute:${ attributeKey }:image`, converter );\n\t};\n\n\tfunction converter( evt, data, conversionApi ) {\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst figure = conversionApi.mapper.toViewElement( data.item );\n\t\tconst img = figure.getChild( 0 );\n\n\t\tif ( data.attributeNewValue !== null ) {\n\t\t\tviewWriter.setAttribute( data.attributeKey, data.attributeNewValue, img );\n\t\t} else {\n\t\t\tviewWriter.removeAttribute( data.attributeKey, img );\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport { insertImage, isImageAllowed } from './utils';\n\n/**\n * @module image/image/imageinsertcommand\n */\n\n/**\n * Insert image command.\n *\n * The command is registered by the {@link module:image/image/imageediting~ImageEditing} plugin as `'imageInsert'`.\n *\n * In order to insert an image at the current selection position\n * (according to the {@link module:widget/utils~findOptimalInsertionPosition} algorithm),\n * execute the command and specify the image source:\n *\n *\t\teditor.execute( 'imageInsert', { source: 'http://url.to.the/image' } );\n *\n * It is also possible to insert multiple images at once:\n *\n *\t\teditor.execute( 'imageInsert', {\n *\t\t\tsource: [\n *\t\t\t\t'path/to/image.jpg',\n *\t\t\t\t'path/to/other-image.jpg'\n *\t\t\t]\n *\t\t} );\n *\n * @extends module:core/command~Command\n */\nexport default class ImageInsertCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.isEnabled = isImageAllowed( this.editor.model );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} options Options for the executed command.\n\t * @param {String|Array.<String>} options.source The image source or an array of image sources to insert.\n\t */\n\texecute( options ) {\n\t\tconst model = this.editor.model;\n\n\t\tmodel.change( writer => {\n\t\t\tconst sources = Array.isArray( options.source ) ? options.source : [ options.source ];\n\n\t\t\tfor ( const src of sources ) {\n\t\t\t\tinsertImage( writer, model, { src } );\n\t\t\t}\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module image/image/imageediting\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ImageLoadObserver from './imageloadobserver';\nimport {\n viewFigureToModel,\n modelToViewAttributeConverter,\n srcsetAttributeConverter\n} from './converters';\nimport { toImageWidget } from './utils';\nimport ImageInsertCommand from './imageinsertcommand';\n/**\n * The image engine plugin.\n *\n * It registers:\n *\n * * `<image>` as a block element in the document schema, and allows `alt`, `src` and `srcset` attributes.\n * * converters for editing and data pipelines.\n * * `'imageInsert'` command.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageEditing extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const schema = editor.model.schema;\n const t = editor.t;\n const conversion = editor.conversion;\n // See https://github.com/ckeditor/ckeditor5-image/issues/142.\n editor.editing.view.addObserver(ImageLoadObserver);\n // Configure schema.\n schema.register('image', {\n isObject: true,\n isBlock: true,\n allowWhere: '$block',\n allowAttributes: [\n 'alt',\n 'src',\n 'srcset'\n ]\n });\n conversion.for('dataDowncast').elementToElement({\n model: 'image',\n view: (modelElement, viewWriter) => createImageViewElement(viewWriter)\n });\n conversion.for('editingDowncast').elementToElement({\n model: 'image',\n view: (modelElement, viewWriter) => toImageWidget(createImageViewElement(viewWriter), viewWriter, t('aj'))\n });\n conversion.for('downcast').add(modelToViewAttributeConverter('src')).add(modelToViewAttributeConverter('alt')).add(srcsetAttributeConverter());\n conversion.for('upcast').elementToElement({\n view: {\n name: 'img',\n attributes: { src: true }\n },\n model: (viewImage, modelWriter) => modelWriter.createElement('image', { src: viewImage.getAttribute('src') })\n }).attributeToAttribute({\n view: {\n name: 'img',\n key: 'alt'\n },\n model: 'alt'\n }).attributeToAttribute({\n view: {\n name: 'img',\n key: 'srcset'\n },\n model: {\n key: 'srcset',\n value: viewImage => {\n const value = { data: viewImage.getAttribute('srcset') };\n if (viewImage.hasAttribute('width')) {\n value.width = viewImage.getAttribute('width');\n }\n return value;\n }\n }\n }).add(viewFigureToModel());\n // Register imageUpload command.\n editor.commands.add('imageInsert', new ImageInsertCommand(editor));\n }\n}\n// Creates a view element representing the image.\n//\n//\t\t<figure class=\"image\"><img></img></figure>\n//\n// Note that `alt` and `src` attributes are converted separately, so they are not included.\n//\n// @private\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\n// @returns {module:engine/view/containerelement~ContainerElement}\nexport function createImageViewElement(writer) {\n const emptyElement = writer.createEmptyElement('img');\n const figure = writer.createContainerElement('figure', { class: 'image' });\n writer.insert(writer.createPositionAt(figure, 0), emptyElement);\n return figure;\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imagetextalternative/imagetextalternativecommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport { isImage } from '../image/utils';\n\n/**\n * The image text alternative command. It is used to change the `alt` attribute of `<image>` elements.\n *\n * @extends module:core/command~Command\n */\nexport default class ImageTextAlternativeCommand extends Command {\n\t/**\n\t * The command value: `false` if there is no `alt` attribute, otherwise the value of the `alt` attribute.\n\t *\n\t * @readonly\n\t * @observable\n\t * @member {String|Boolean} #value\n\t */\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst element = this.editor.model.document.selection.getSelectedElement();\n\n\t\tthis.isEnabled = isImage( element );\n\n\t\tif ( isImage( element ) && element.hasAttribute( 'alt' ) ) {\n\t\t\tthis.value = element.getAttribute( 'alt' );\n\t\t} else {\n\t\t\tthis.value = false;\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} options\n\t * @param {String} options.newValue The new value of the `alt` attribute to set.\n\t */\n\texecute( options ) {\n\t\tconst model = this.editor.model;\n\t\tconst imageElement = model.document.selection.getSelectedElement();\n\n\t\tmodel.change( writer => {\n\t\t\twriter.setAttribute( 'alt', options.newValue, imageElement );\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imagetextalternative/imagetextalternativeediting\n */\n\nimport ImageTextAlternativeCommand from './imagetextalternativecommand';\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\n/**\n * The image text alternative editing plugin.\n *\n * Registers the `'imageTextAlternative'` command.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageTextAlternativeEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tthis.editor.commands.add( 'imageTextAlternative', new ImageTextAlternativeCommand( this.editor ) );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/labeledinput/labeledinputview\n */\n\nimport View from '../view';\nimport uid from '@ckeditor/ckeditor5-utils/src/uid';\nimport LabelView from '../label/labelview';\nimport '../../theme/components/labeledinput/labeledinput.css';\n\n/**\n * The labeled input view class.\n *\n * @extends module:ui/view~View\n */\nexport default class LabeledInputView extends View {\n\t/**\n\t * Creates an instance of the labeled input view class.\n\t *\n\t * @param {module:utils/locale~Locale} locale The locale instance.\n\t * @param {Function} InputView Constructor of the input view.\n\t */\n\tconstructor( locale, InputView ) {\n\t\tsuper( locale );\n\n\t\tconst inputUid = `ck-input-${ uid() }`;\n\t\tconst statusUid = `ck-status-${ uid() }`;\n\n\t\t/**\n\t\t * The text of the label.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #label\n\t\t */\n\t\tthis.set( 'label' );\n\n\t\t/**\n\t\t * The value of the input.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #value\n\t\t */\n\t\tthis.set( 'value' );\n\n\t\t/**\n\t\t * Controls whether the component is in read-only mode.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isReadOnly\n\t\t */\n\t\tthis.set( 'isReadOnly', false );\n\n\t\t/**\n\t\t * The validation error text. When set, it will be displayed\n\t\t * next to the {@link #inputView} as a typical validation error message.\n\t\t * Set it to `null` to hide the message.\n\t\t *\n\t\t * **Note:** Setting this property to anything but `null` will automatically\n\t\t * make the {@link module:ui/inputtext/inputtextview~InputTextView#hasError `hasError`}\n\t\t * of the {@link #inputView} `true`.\n\t\t *\n\t\t * **Note:** Typing in the {@link #inputView} which fires the\n\t\t * {@link module:ui/inputtext/inputtextview~InputTextView#event:input `input` event}\n\t\t * resets this property back to `null`, indicating that the input field can be re–validated.\n\t\t *\n\t\t * @observable\n\t\t * @member {String|null} #errorText\n\t\t */\n\t\tthis.set( 'errorText', null );\n\n\t\t/**\n\t\t * The additional information text displayed next to the {@link #inputView} which can\n\t\t * be used to inform the user about the purpose of the input, provide help or hints.\n\t\t *\n\t\t * Set it to `null` to hide the message.\n\t\t *\n\t\t * **Note:** This text will be displayed in the same place as {@link #errorText} but the\n\t\t * latter always takes precedence: if the {@link #errorText} is set, it replaces\n\t\t * {@link #errorText} for as long as the value of the input is invalid.\n\t\t *\n\t\t * @observable\n\t\t * @member {String|null} #infoText\n\t\t */\n\t\tthis.set( 'infoText', null );\n\n\t\t/**\n\t\t * The label view.\n\t\t *\n\t\t * @member {module:ui/label/labelview~LabelView} #labelView\n\t\t */\n\t\tthis.labelView = this._createLabelView( inputUid );\n\n\t\t/**\n\t\t * The input view.\n\t\t *\n\t\t * @member {module:ui/inputtext/inputtextview~InputTextView} #inputView\n\t\t */\n\t\tthis.inputView = this._createInputView( InputView, inputUid, statusUid );\n\n\t\t/**\n\t\t * The status view for the {@link #inputView}. It displays {@link #errorText} and\n\t\t * {@link #infoText}.\n\t\t *\n\t\t * @member {module:ui/view~View} #statusView\n\t\t */\n\t\tthis.statusView = this._createStatusView( statusUid );\n\n\t\t/**\n\t\t * The combined status text made of {@link #errorText} and {@link #infoText}.\n\t\t * Note that when present, {@link #errorText} always takes precedence in the\n\t\t * status.\n\t\t *\n\t\t * @see #errorText\n\t\t * @see #infoText\n\t\t * @see #statusView\n\t\t * @private\n\t\t * @observable\n\t\t * @member {String|null} #_statusText\n\t\t */\n\t\tthis.bind( '_statusText' ).to(\n\t\t\tthis, 'errorText',\n\t\t\tthis, 'infoText',\n\t\t\t( errorText, infoText ) => errorText || infoText\n\t\t);\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-labeled-input',\n\t\t\t\t\tbind.if( 'isReadOnly', 'ck-disabled' )\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\tthis.labelView,\n\t\t\t\tthis.inputView,\n\t\t\t\tthis.statusView\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * Creates label view class instance and bind with view.\n\t *\n\t * @private\n\t * @param {String} id Unique id to set as labelView#for attribute.\n\t * @returns {module:ui/label/labelview~LabelView}\n\t */\n\t_createLabelView( id ) {\n\t\tconst labelView = new LabelView( this.locale );\n\n\t\tlabelView.for = id;\n\t\tlabelView.bind( 'text' ).to( this, 'label' );\n\n\t\treturn labelView;\n\t}\n\n\t/**\n\t * Creates input view class instance and bind with view.\n\t *\n\t * @private\n\t * @param {Function} InputView Input view constructor.\n\t * @param {String} inputUid Unique id to set as inputView#id attribute.\n\t * @param {String} statusUid Unique id of the status for the input's `aria-describedby` attribute.\n\t * @returns {module:ui/inputtext/inputtextview~InputTextView}\n\t */\n\t_createInputView( InputView, inputUid, statusUid ) {\n\t\tconst inputView = new InputView( this.locale, statusUid );\n\n\t\tinputView.id = inputUid;\n\t\tinputView.ariaDesribedById = statusUid;\n\t\tinputView.bind( 'value' ).to( this );\n\t\tinputView.bind( 'isReadOnly' ).to( this );\n\t\tinputView.bind( 'hasError' ).to( this, 'errorText', value => !!value );\n\n\t\tinputView.on( 'input', () => {\n\t\t\t// UX: Make the error text disappear and disable the error indicator as the user\n\t\t\t// starts fixing the errors.\n\t\t\tthis.errorText = null;\n\t\t} );\n\n\t\treturn inputView;\n\t}\n\n\t/**\n\t * Creates the status view instance. It displays {@link #errorText} and {@link #infoText}\n\t * next to the {@link #inputView}. See {@link #_statusText}.\n\t *\n\t * @private\n\t * @param {String} statusUid Unique id of the status, shared with the input's `aria-describedby` attribute.\n\t * @returns {module:ui/view~View}\n\t */\n\t_createStatusView( statusUid ) {\n\t\tconst statusView = new View( this.locale );\n\t\tconst bind = this.bindTemplate;\n\n\t\tstatusView.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-labeled-input__status',\n\t\t\t\t\tbind.if( 'errorText', 'ck-labeled-input__status_error' ),\n\t\t\t\t\tbind.if( '_statusText', 'ck-hidden', value => !value )\n\t\t\t\t],\n\t\t\t\tid: statusUid\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttext: bind.to( '_statusText' )\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\n\t\treturn statusView;\n\t}\n\n\t/**\n\t * Moves the focus to the input and selects the value.\n\t */\n\tselect() {\n\t\tthis.inputView.select();\n\t}\n\n\t/**\n\t * Focuses the input.\n\t */\n\tfocus() {\n\t\tthis.inputView.focus();\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/inputtext/inputtextview\n */\n\nimport View from '../view';\nimport '../../theme/components/inputtext/inputtext.css';\n\n/**\n * The text input view class.\n *\n * @extends module:ui/view~View\n */\nexport default class InputTextView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\t/**\n\t\t * The value of the input.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #value\n\t\t */\n\t\tthis.set( 'value' );\n\n\t\t/**\n\t\t * The `id` attribute of the input (i.e. to pair with a `<label>` element).\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #id\n\t\t */\n\t\tthis.set( 'id' );\n\n\t\t/**\n\t\t * The `placeholder` attribute of the input.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #placeholder\n\t\t */\n\t\tthis.set( 'placeholder' );\n\n\t\t/**\n\t\t * Controls whether the input view is in read-only mode.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isReadOnly\n\t\t */\n\t\tthis.set( 'isReadOnly', false );\n\n\t\t/**\n\t\t * Set to `true` when the field has some error. Usually controlled via\n\t\t * {@link module:ui/labeledinput/labeledinputview~LabeledInputView#errorText}.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #hasError\n\t\t */\n\t\tthis.set( 'hasError', false );\n\n\t\t/**\n\t\t * The `id` of the element describing this field, e.g. when it has\n\t\t * some error, it helps screen readers read the error text.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #ariaDesribedById\n\t\t */\n\t\tthis.set( 'ariaDesribedById' );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'input',\n\t\t\tattributes: {\n\t\t\t\ttype: 'text',\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-input',\n\t\t\t\t\t'ck-input-text',\n\t\t\t\t\tbind.if( 'hasError', 'ck-error' )\n\t\t\t\t],\n\t\t\t\tid: bind.to( 'id' ),\n\t\t\t\tplaceholder: bind.to( 'placeholder' ),\n\t\t\t\treadonly: bind.to( 'isReadOnly' ),\n\t\t\t\t'aria-invalid': bind.if( 'hasError', true ),\n\t\t\t\t'aria-describedby': bind.to( 'ariaDesribedById' )\n\t\t\t},\n\t\t\ton: {\n\t\t\t\tinput: bind.to( 'input' )\n\t\t\t}\n\t\t} );\n\n\t\t/**\n\t\t * Fired when the user types in the input. Corresponds to the native\n\t\t * DOM `input` event.\n\t\t *\n\t\t * @event input\n\t\t */\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\tconst setValue = value => {\n\t\t\tthis.element.value = ( !value && value !== 0 ) ? '' : value;\n\t\t};\n\n\t\tsetValue( this.value );\n\n\t\t// Bind `this.value` to the DOM element's value.\n\t\t// We cannot use `value` DOM attribute because removing it on Edge does not clear the DOM element's value property.\n\t\tthis.on( 'change:value', ( evt, name, value ) => {\n\t\t\tsetValue( value );\n\t\t} );\n\t}\n\n\t/**\n\t * Moves the focus to the input and selects the value.\n\t */\n\tselect() {\n\t\tthis.element.select();\n\t}\n\n\t/**\n\t * Focuses the input.\n\t */\n\tfocus() {\n\t\tthis.element.focus();\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module ui/bindings/submithandler\n */\n\n/**\n * A handler useful for {@link module:ui/view~View views} working as HTML forms. It intercepts a native DOM\n * `submit` event, prevents the default web browser behavior (navigation and page reload) and\n * fires the `submit` event on a view instead. Such a custom event can be then used by any\n * {@link module:utils/dom/emittermixin~Emitter emitter}, e.g. to serialize the form data.\n *\n *\t\timport submitHandler from '@ckeditor/ckeditor5-ui/src/bindings/submithandler';\n *\n *\t\t// ...\n *\n *\t\tclass AnyFormView extends View {\n *\t\t\tconstructor() {\n *\t\t\t\tsuper();\n *\n *\t\t\t\t// ...\n *\n *\t\t\t\tsubmitHandler( {\n *\t\t\t\t\tview: this\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n *\t\t// ...\n *\n *\t\tconst view = new AnyFormView();\n *\n *\t\t// A sample listener attached by an emitter working with the view.\n *\t\tthis.listenTo( view, 'submit', () => {\n *\t\t\tsaveTheFormData();\n *\t\t\thideTheForm();\n *\t\t} );\n *\n * @param {Object} [options] Configuration options.\n * @param {module:ui/view~View} options.view The view which DOM `submit` events should be handled.\n */\nexport default function submitHandler( { view } ) {\n\tview.listenTo( view.element, 'submit', ( evt, domEvt ) => {\n\t\tdomEvt.preventDefault();\n\t\tview.fire( 'submit' );\n\t}, { useCapture: true } );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module image/imagetextalternative/ui/textalternativeformview\n */\nimport View from '@ckeditor/ckeditor5-ui/src/view';\nimport ViewCollection from '@ckeditor/ckeditor5-ui/src/viewcollection';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport LabeledInputView from '@ckeditor/ckeditor5-ui/src/labeledinput/labeledinputview';\nimport InputTextView from '@ckeditor/ckeditor5-ui/src/inputtext/inputtextview';\nimport submitHandler from '@ckeditor/ckeditor5-ui/src/bindings/submithandler';\nimport KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';\nimport FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';\nimport FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler';\nimport checkIcon from '@ckeditor/ckeditor5-core/theme/icons/check.svg';\nimport cancelIcon from '@ckeditor/ckeditor5-core/theme/icons/cancel.svg';\nimport '../../../theme/textalternativeform.css';\n/**\n * The TextAlternativeFormView class.\n *\n * @extends module:ui/view~View\n */\nexport default class TextAlternativeFormView extends View {\n /**\n\t * @inheritDoc\n\t */\n constructor(locale) {\n super(locale);\n const t = this.locale.t;\n /**\n\t\t * Tracks information about the DOM focus in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/focustracker~FocusTracker}\n\t\t */\n this.focusTracker = new FocusTracker();\n /**\n\t\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/keystrokehandler~KeystrokeHandler}\n\t\t */\n this.keystrokes = new KeystrokeHandler();\n /**\n\t\t * A textarea with a label.\n\t\t *\n\t\t * @member {module:ui/labeledinput/labeledinputview~LabeledInputView} #labeledTextarea\n\t\t */\n this.labeledInput = this._createLabeledInputView();\n /**\n\t\t * A button used to submit the form.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView} #saveButtonView\n\t\t */\n this.saveButtonView = this._createButton(t('az'), checkIcon, 'ck-button-save');\n this.saveButtonView.type = 'submit';\n /**\n\t\t * A button used to cancel the form.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView} #cancelButtonView\n\t\t */\n this.cancelButtonView = this._createButton(t('ba'), cancelIcon, 'ck-button-cancel', 'cancel');\n /**\n\t\t * A collection of views which can be focused in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n this._focusables = new ViewCollection();\n /**\n\t\t * Helps cycling over {@link #_focusables} in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/focuscycler~FocusCycler}\n\t\t */\n this._focusCycler = new FocusCycler({\n focusables: this._focusables,\n focusTracker: this.focusTracker,\n keystrokeHandler: this.keystrokes,\n actions: {\n // Navigate form fields backwards using the Shift + Tab keystroke.\n focusPrevious: 'shift + tab',\n // Navigate form fields forwards using the Tab key.\n focusNext: 'tab'\n }\n });\n this.setTemplate({\n tag: 'form',\n attributes: {\n class: [\n 'ck',\n 'ck-text-alternative-form'\n ],\n // https://github.com/ckeditor/ckeditor5-image/issues/40\n tabindex: '-1'\n },\n children: [\n this.labeledInput,\n this.saveButtonView,\n this.cancelButtonView\n ]\n });\n }\n /**\n\t * @inheritDoc\n\t */\n render() {\n super.render();\n this.keystrokes.listenTo(this.element);\n submitHandler({ view: this });\n [\n this.labeledInput,\n this.saveButtonView,\n this.cancelButtonView\n ].forEach(v => {\n // Register the view as focusable.\n this._focusables.add(v);\n // Register the view in the focus tracker.\n this.focusTracker.add(v.element);\n });\n }\n /**\n\t * Creates the button view.\n\t *\n\t * @private\n\t * @param {String} label The button label\n\t * @param {String} icon The button's icon.\n\t * @param {String} className The additional button CSS class name.\n\t * @param {String} [eventName] The event name that the ButtonView#execute event will be delegated to.\n\t * @returns {module:ui/button/buttonview~ButtonView} The button view instance.\n\t */\n _createButton(label, icon, className, eventName) {\n const button = new ButtonView(this.locale);\n button.set({\n label,\n icon,\n tooltip: true\n });\n button.extendTemplate({ attributes: { class: className } });\n if (eventName) {\n button.delegate('execute').to(this, eventName);\n }\n return button;\n }\n /**\n\t * Creates an input with a label.\n\t *\n\t * @private\n\t * @returns {module:ui/labeledinput/labeledinputview~LabeledInputView}\n\t */\n _createLabeledInputView() {\n const t = this.locale.t;\n const labeledInput = new LabeledInputView(this.locale, InputTextView);\n labeledInput.label = t('bg');\n labeledInput.inputView.placeholder = t('bg');\n return labeledInput;\n }\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/image/ui/utils\n */\n\nimport BalloonPanelView from '@ckeditor/ckeditor5-ui/src/panel/balloon/balloonpanelview';\nimport { getSelectedImageWidget } from '../utils';\n\n/**\n * A helper utility that positions the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} instance\n * with respect to the image in the editor content, if one is selected.\n *\n * @param {module:core/editor/editor~Editor} editor The editor instance.\n */\nexport function repositionContextualBalloon( editor ) {\n\tconst balloon = editor.plugins.get( 'ContextualBalloon' );\n\n\tif ( getSelectedImageWidget( editor.editing.view.document.selection ) ) {\n\t\tconst position = getBalloonPositionData( editor );\n\n\t\tballoon.updatePosition( position );\n\t}\n}\n\n/**\n * Returns the positioning options that control the geometry of the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} with respect\n * to the selected element in the editor content.\n *\n * @param {module:core/editor/editor~Editor} editor The editor instance.\n * @returns {module:utils/dom/position~Options}\n */\nexport function getBalloonPositionData( editor ) {\n\tconst editingView = editor.editing.view;\n\tconst defaultPositions = BalloonPanelView.defaultPositions;\n\n\treturn {\n\t\ttarget: editingView.domConverter.viewToDom( editingView.document.selection.getSelectedElement() ),\n\t\tpositions: [\n\t\t\tdefaultPositions.northArrowSouth,\n\t\t\tdefaultPositions.northArrowSouthWest,\n\t\t\tdefaultPositions.northArrowSouthEast,\n\t\t\tdefaultPositions.southArrowNorth,\n\t\t\tdefaultPositions.southArrowNorthWest,\n\t\t\tdefaultPositions.southArrowNorthEast\n\t\t]\n\t};\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module image/imagetextalternative/imagetextalternativeui\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport clickOutsideHandler from '@ckeditor/ckeditor5-ui/src/bindings/clickoutsidehandler';\nimport TextAlternativeFormView from './ui/textalternativeformview';\nimport ContextualBalloon from '@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon';\nimport textAlternativeIcon from '@ckeditor/ckeditor5-core/theme/icons/low-vision.svg';\nimport {\n repositionContextualBalloon,\n getBalloonPositionData\n} from '../image/ui/utils';\nimport { getSelectedImageWidget } from '../image/utils';\n/**\n * The image text alternative UI plugin.\n *\n * The plugin uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageTextAlternativeUI extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n static get requires() {\n return [ContextualBalloon];\n }\n /**\n\t * @inheritDoc\n\t */\n static get pluginName() {\n return 'ImageTextAlternativeUI';\n }\n /**\n\t * @inheritDoc\n\t */\n init() {\n this._createButton();\n this._createForm();\n }\n /**\n\t * @inheritDoc\n\t */\n destroy() {\n super.destroy();\n // Destroy created UI components as they are not automatically destroyed (see ckeditor5#1341).\n this._form.destroy();\n }\n /**\n\t * Creates a button showing the balloon panel for changing the image text alternative and\n\t * registers it in the editor {@link module:ui/componentfactory~ComponentFactory ComponentFactory}.\n\t *\n\t * @private\n\t */\n _createButton() {\n const editor = this.editor;\n const t = editor.t;\n editor.ui.componentFactory.add('imageTextAlternative', locale => {\n const command = editor.commands.get('imageTextAlternative');\n const view = new ButtonView(locale);\n view.set({\n label: t('ar'),\n icon: textAlternativeIcon,\n tooltip: true\n });\n view.bind('isEnabled').to(command, 'isEnabled');\n this.listenTo(view, 'execute', () => this._showForm());\n return view;\n });\n }\n /**\n\t * Creates the {@link module:image/imagetextalternative/ui/textalternativeformview~TextAlternativeFormView}\n\t * form.\n\t *\n\t * @private\n\t */\n _createForm() {\n const editor = this.editor;\n const view = editor.editing.view;\n const viewDocument = view.document;\n /**\n\t\t * The contextual balloon plugin instance.\n\t\t *\n\t\t * @private\n\t\t * @member {module:ui/panel/balloon/contextualballoon~ContextualBalloon}\n\t\t */\n this._balloon = this.editor.plugins.get('ContextualBalloon');\n /**\n\t\t * A form containing a textarea and buttons, used to change the `alt` text value.\n\t\t *\n\t\t * @member {module:image/imagetextalternative/ui/textalternativeformview~TextAlternativeFormView}\n\t\t */\n this._form = new TextAlternativeFormView(editor.locale);\n // Render the form so its #element is available for clickOutsideHandler.\n this._form.render();\n this.listenTo(this._form, 'submit', () => {\n editor.execute('imageTextAlternative', { newValue: this._form.labeledInput.inputView.element.value });\n this._hideForm(true);\n });\n this.listenTo(this._form, 'cancel', () => {\n this._hideForm(true);\n });\n // Close the form on Esc key press.\n this._form.keystrokes.set('Esc', (data, cancel) => {\n this._hideForm(true);\n cancel();\n });\n // Reposition the balloon or hide the form if an image widget is no longer selected.\n this.listenTo(editor.ui, 'update', () => {\n if (!getSelectedImageWidget(viewDocument.selection)) {\n this._hideForm(true);\n } else if (this._isVisible) {\n repositionContextualBalloon(editor);\n }\n });\n // Close on click outside of balloon panel element.\n clickOutsideHandler({\n emitter: this._form,\n activator: () => this._isVisible,\n contextElements: [this._form.element],\n callback: () => this._hideForm()\n });\n }\n /**\n\t * Shows the {@link #_form} in the {@link #_balloon}.\n\t *\n\t * @private\n\t */\n _showForm() {\n if (this._isVisible) {\n return;\n }\n const editor = this.editor;\n const command = editor.commands.get('imageTextAlternative');\n const labeledInput = this._form.labeledInput;\n if (!this._balloon.hasView(this._form)) {\n this._balloon.add({\n view: this._form,\n position: getBalloonPositionData(editor)\n });\n }\n // Make sure that each time the panel shows up, the field remains in sync with the value of\n // the command. If the user typed in the input, then canceled the balloon (`labeledInput#value`\n // stays unaltered) and re-opened it without changing the value of the command, they would see the\n // old value instead of the actual value of the command.\n // https://github.com/ckeditor/ckeditor5-image/issues/114\n labeledInput.value = labeledInput.inputView.element.value = command.value || '';\n this._form.labeledInput.select();\n }\n /**\n\t * Removes the {@link #_form} from the {@link #_balloon}.\n\t *\n\t * @param {Boolean} [focusEditable=false] Controls whether the editing view is focused afterwards.\n\t * @private\n\t */\n _hideForm(focusEditable) {\n if (!this._isVisible) {\n return;\n }\n // Blur the input element before removing it from DOM to prevent issues in some browsers.\n // See https://github.com/ckeditor/ckeditor5/issues/1501.\n this._form.saveButtonView.focus();\n this._balloon.remove(this._form);\n if (focusEditable) {\n this.editor.editing.view.focus();\n }\n }\n /**\n\t * Returns `true` when the {@link #_form} is the visible view in the {@link #_balloon}.\n\t *\n\t * @private\n\t * @type {Boolean}\n\t */\n get _isVisible() {\n return this._balloon.visibleView == this._form;\n }\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imagetextalternative\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ImageTextAlternativeEditing from './imagetextalternative/imagetextalternativeediting';\nimport ImageTextAlternativeUI from './imagetextalternative/imagetextalternativeui';\n\n/**\n * The image text alternative plugin.\n *\n * For a detailed overview, check the {@glink features/image#image-styles image styles} documentation.\n *\n * This is a \"glue\" plugin which loads the\n * {@link module:image/imagetextalternative/imagetextalternativeediting~ImageTextAlternativeEditing}\n * and {@link module:image/imagetextalternative/imagetextalternativeui~ImageTextAlternativeUI} plugins.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageTextAlternative extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ImageTextAlternativeEditing, ImageTextAlternativeUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageTextAlternative';\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imagecaption/utils\n */\n\nimport { enablePlaceholder } from '@ckeditor/ckeditor5-engine/src/view/placeholder';\nimport { toWidgetEditable } from '@ckeditor/ckeditor5-widget/src/utils';\n\n/**\n * Returns a function that creates a caption editable element for the given {@link module:engine/view/document~Document}.\n *\n * @param {module:engine/view/view~View} view\n * @param {String} placeholderText The text to be displayed when the caption is empty.\n * @returns {Function}\n */\nexport function captionElementCreator( view, placeholderText ) {\n\treturn writer => {\n\t\tconst editable = writer.createEditableElement( 'figcaption' );\n\t\twriter.setCustomProperty( 'imageCaption', true, editable );\n\n\t\tenablePlaceholder( {\n\t\t\tview,\n\t\t\telement: editable,\n\t\t\ttext: placeholderText\n\t\t} );\n\n\t\treturn toWidgetEditable( editable, writer );\n\t};\n}\n\n/**\n * Returns `true` if a given view element is the image caption editable.\n *\n * @param {module:engine/view/element~Element} viewElement\n * @returns {Boolean}\n */\nexport function isCaption( viewElement ) {\n\treturn !!viewElement.getCustomProperty( 'imageCaption' );\n}\n\n/**\n * Returns the caption model element from a given image element. Returns `null` if no caption is found.\n *\n * @param {module:engine/model/element~Element} imageModelElement\n * @returns {module:engine/model/element~Element|null}\n */\nexport function getCaptionFromImage( imageModelElement ) {\n\tfor ( const node of imageModelElement.getChildren() ) {\n\t\tif ( !!node && node.is( 'caption' ) ) {\n\t\t\treturn node;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * {@link module:engine/view/matcher~Matcher} pattern. Checks if a given element is a `<figcaption>` element that is placed\n * inside the image `<figure>` element.\n *\n * @param {module:engine/view/element~Element} element\n * @returns {Object|null} Returns the object accepted by {@link module:engine/view/matcher~Matcher} or `null` if the element\n * cannot be matched.\n */\nexport function matchImageCaption( element ) {\n\tconst parent = element.parent;\n\n\t// Convert only captions for images.\n\tif ( element.name == 'figcaption' && parent && parent.name == 'figure' && parent.hasClass( 'image' ) ) {\n\t\treturn { name: true };\n\t}\n\n\treturn null;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module image/imagecaption/imagecaptionediting\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport { isImage } from '../image/utils';\nimport {\n captionElementCreator,\n getCaptionFromImage,\n matchImageCaption\n} from './utils';\n/**\n * The image caption engine plugin.\n *\n * It registers proper converters. It takes care of adding a caption element if the image without it is inserted\n * to the model document.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageCaptionEditing extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const view = editor.editing.view;\n const schema = editor.model.schema;\n const data = editor.data;\n const editing = editor.editing;\n const t = editor.t;\n /**\n\t\t * The last selected caption editable.\n\t\t * It is used for hiding the editable when it is empty and the image widget is no longer selected.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/view/editableelement~EditableElement} #_lastSelectedCaption\n\t\t */\n // Schema configuration.\n schema.register('caption', {\n allowIn: 'image',\n allowContentOf: '$block',\n isLimit: true\n });\n // Add caption element to each image inserted without it.\n editor.model.document.registerPostFixer(writer => this._insertMissingModelCaptionElement(writer));\n // View to model converter for the data pipeline.\n editor.conversion.for('upcast').elementToElement({\n view: matchImageCaption,\n model: 'caption'\n });\n // Model to view converter for the data pipeline.\n const createCaptionForData = writer => writer.createContainerElement('figcaption');\n data.downcastDispatcher.on('insert:caption', captionModelToView(createCaptionForData, false));\n // Model to view converter for the editing pipeline.\n const createCaptionForEditing = captionElementCreator(view, t('ai'));\n editing.downcastDispatcher.on('insert:caption', captionModelToView(createCaptionForEditing));\n // Always show caption in view when something is inserted in model.\n editing.downcastDispatcher.on('insert', this._fixCaptionVisibility(data => data.item), { priority: 'high' });\n // Hide caption when everything is removed from it.\n editing.downcastDispatcher.on('remove', this._fixCaptionVisibility(data => data.position.parent), { priority: 'high' });\n // Update caption visibility on view in post fixer.\n view.document.registerPostFixer(writer => this._updateCaptionVisibility(writer));\n }\n /**\n\t * Updates the view before each rendering, making sure that empty captions (so unnecessary ones) are hidden\n\t * and then visible when the image is selected.\n\t *\n\t * @private\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} viewWriter\n\t * @returns {Boolean} Returns `true` when the view is updated.\n\t */\n _updateCaptionVisibility(viewWriter) {\n const mapper = this.editor.editing.mapper;\n const lastCaption = this._lastSelectedCaption;\n let viewCaption;\n // If whole image is selected.\n const modelSelection = this.editor.model.document.selection;\n const selectedElement = modelSelection.getSelectedElement();\n if (selectedElement && selectedElement.is('image')) {\n const modelCaption = getCaptionFromImage(selectedElement);\n viewCaption = mapper.toViewElement(modelCaption);\n }\n // If selection is placed inside caption.\n const position = modelSelection.getFirstPosition();\n const modelCaption = getParentCaption(position.parent);\n if (modelCaption) {\n viewCaption = mapper.toViewElement(modelCaption);\n }\n // Is currently any caption selected?\n if (viewCaption) {\n // Was any caption selected before?\n if (lastCaption) {\n // Same caption as before?\n if (lastCaption === viewCaption) {\n return showCaption(viewCaption, viewWriter);\n } else {\n hideCaptionIfEmpty(lastCaption, viewWriter);\n this._lastSelectedCaption = viewCaption;\n return showCaption(viewCaption, viewWriter);\n }\n } else {\n this._lastSelectedCaption = viewCaption;\n return showCaption(viewCaption, viewWriter);\n }\n } else {\n // Was any caption selected before?\n if (lastCaption) {\n const viewModified = hideCaptionIfEmpty(lastCaption, viewWriter);\n this._lastSelectedCaption = null;\n return viewModified;\n } else {\n return false;\n }\n }\n }\n /**\n\t * Returns a converter that fixes caption visibility during the model-to-view conversion.\n\t * Checks if the changed node is placed inside the caption element and fixes its visibility in the view.\n\t *\n\t * @private\n\t * @param {Function} nodeFinder\n\t * @returns {Function}\n\t */\n _fixCaptionVisibility(nodeFinder) {\n return (evt, data, conversionApi) => {\n const node = nodeFinder(data);\n const modelCaption = getParentCaption(node);\n const mapper = this.editor.editing.mapper;\n const viewWriter = conversionApi.writer;\n if (modelCaption) {\n const viewCaption = mapper.toViewElement(modelCaption);\n if (viewCaption) {\n if (modelCaption.childCount) {\n viewWriter.removeClass('ck-hidden', viewCaption);\n } else {\n viewWriter.addClass('ck-hidden', viewCaption);\n }\n }\n }\n };\n }\n /**\n\t * Checks whether the data inserted to the model document have an image element that has no caption element inside it.\n\t * If there is none, it adds it to the image element.\n\t *\n\t * @private\n\t * @param {module:engine/model/writer~Writer} writer The writer to make changes with.\n\t * @returns {Boolean} `true` if any change was applied, `false` otherwise.\n\t */\n _insertMissingModelCaptionElement(writer) {\n const model = this.editor.model;\n const changes = model.document.differ.getChanges();\n const imagesWithoutCaption = [];\n for (const entry of changes) {\n if (entry.type == 'insert' && entry.name != '$text') {\n const item = entry.position.nodeAfter;\n if (item.is('image') && !getCaptionFromImage(item)) {\n imagesWithoutCaption.push(item);\n }\n // Check elements with children for nested images.\n if (!item.is('image') && item.childCount) {\n for (const nestedItem of model.createRangeIn(item).getItems()) {\n if (nestedItem.is('image') && !getCaptionFromImage(nestedItem)) {\n imagesWithoutCaption.push(nestedItem);\n }\n }\n }\n }\n }\n for (const image of imagesWithoutCaption) {\n writer.appendElement('caption', image);\n }\n return !!imagesWithoutCaption.length;\n }\n}\n// Creates a converter that converts image caption model element to view element.\n//\n// @private\n// @param {Function} elementCreator\n// @param {Boolean} [hide=true] When set to `false` view element will not be inserted when it's empty.\n// @returns {Function}\nfunction captionModelToView(elementCreator, hide = true) {\n return (evt, data, conversionApi) => {\n const captionElement = data.item;\n // Return if element shouldn't be present when empty.\n if (!captionElement.childCount && !hide) {\n return;\n }\n if (isImage(captionElement.parent)) {\n if (!conversionApi.consumable.consume(data.item, 'insert')) {\n return;\n }\n const viewImage = conversionApi.mapper.toViewElement(data.range.start.parent);\n const viewCaption = elementCreator(conversionApi.writer);\n const viewWriter = conversionApi.writer;\n // Hide if empty.\n if (!captionElement.childCount) {\n viewWriter.addClass('ck-hidden', viewCaption);\n }\n insertViewCaptionAndBind(viewCaption, data.item, viewImage, conversionApi);\n }\n };\n}\n// Inserts `viewCaption` at the end of `viewImage` and binds it to `modelCaption`.\n//\n// @private\n// @param {module:engine/view/containerelement~ContainerElement} viewCaption\n// @param {module:engine/model/element~Element} modelCaption\n// @param {module:engine/view/containerelement~ContainerElement} viewImage\n// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\nfunction insertViewCaptionAndBind(viewCaption, modelCaption, viewImage, conversionApi) {\n const viewPosition = conversionApi.writer.createPositionAt(viewImage, 'end');\n conversionApi.writer.insert(viewPosition, viewCaption);\n conversionApi.mapper.bindElements(modelCaption, viewCaption);\n}\n// Checks if the provided node or one of its ancestors is a caption element, and returns it.\n//\n// @private\n// @param {module:engine/model/node~Node} node\n// @returns {module:engine/model/element~Element|null}\nfunction getParentCaption(node) {\n const ancestors = node.getAncestors({ includeSelf: true });\n const caption = ancestors.find(ancestor => ancestor.name == 'caption');\n if (caption && caption.parent && caption.parent.name == 'image') {\n return caption;\n }\n return null;\n}\n// Hides a given caption in the view if it is empty.\n//\n// @private\n// @param {module:engine/view/containerelement~ContainerElement} caption\n// @param {module:engine/view/downcastwriter~DowncastWriter} viewWriter\n// @returns {Boolean} Returns `true` if the view was modified.\nfunction hideCaptionIfEmpty(caption, viewWriter) {\n if (!caption.childCount && !caption.hasClass('ck-hidden')) {\n viewWriter.addClass('ck-hidden', caption);\n return true;\n }\n return false;\n}\n// Shows the caption.\n//\n// @private\n// @param {module:engine/view/containerelement~ContainerElement} caption\n// @param {module:engine/view/downcastwriter~DowncastWriter} viewWriter\n// @returns {Boolean} Returns `true` if the view was modified.\nfunction showCaption(caption, viewWriter) {\n if (caption.hasClass('ck-hidden')) {\n viewWriter.removeClass('ck-hidden', caption);\n return true;\n }\n return false;\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imagestyle/imagestylecommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport { isImage } from '../image/utils';\n\n/**\n * The image style command. It is used to apply different image styles.\n *\n * @extends module:core/command~Command\n */\nexport default class ImageStyleCommand extends Command {\n\t/**\n\t * Creates an instance of the image style command. Each command instance is handling one style.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {Array.<module:image/imagestyle/imagestyleediting~ImageStyleFormat>} styles The styles that this command supports.\n\t */\n\tconstructor( editor, styles ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The cached name of the default style if it is present. If there is no default style, it defaults to `false`.\n\t\t *\n\t\t * @type {Boolean|String}\n\t\t * @private\n\t\t */\n\t\tthis._defaultStyle = false;\n\n\t\t/**\n\t\t * A style handled by this command.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Array.<module:image/imagestyle/imagestyleediting~ImageStyleFormat>} #styles\n\t\t */\n\t\tthis.styles = styles.reduce( ( styles, style ) => {\n\t\t\tstyles[ style.name ] = style;\n\n\t\t\tif ( style.isDefault ) {\n\t\t\t\tthis._defaultStyle = style.name;\n\t\t\t}\n\n\t\t\treturn styles;\n\t\t}, {} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst element = this.editor.model.document.selection.getSelectedElement();\n\n\t\tthis.isEnabled = isImage( element );\n\n\t\tif ( !element ) {\n\t\t\tthis.value = false;\n\t\t} else if ( element.hasAttribute( 'imageStyle' ) ) {\n\t\t\tconst attributeValue = element.getAttribute( 'imageStyle' );\n\t\t\tthis.value = this.styles[ attributeValue ] ? attributeValue : false;\n\t\t} else {\n\t\t\tthis.value = this._defaultStyle;\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t *\t\teditor.execute( 'imageStyle', { value: 'side' } );\n\t *\n\t * @param {Object} options\n\t * @param {String} options.value The name of the style (based on the\n\t * {@link module:image/image~ImageConfig#styles `image.styles`} configuration option).\n\t * @fires execute\n\t */\n\texecute( options ) {\n\t\tconst styleName = options.value;\n\n\t\tconst model = this.editor.model;\n\t\tconst imageElement = model.document.selection.getSelectedElement();\n\n\t\tmodel.change( writer => {\n\t\t\t// Default style means that there is no `imageStyle` attribute in the model.\n\t\t\t// https://github.com/ckeditor/ckeditor5-image/issues/147\n\t\t\tif ( this.styles[ styleName ].isDefault ) {\n\t\t\t\twriter.removeAttribute( 'imageStyle', imageElement );\n\t\t\t} else {\n\t\t\t\twriter.setAttribute( 'imageStyle', styleName, imageElement );\n\t\t\t}\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\nimport first from '@ckeditor/ckeditor5-utils/src/first';\n\n/**\n * @module image/imagestyle/converters\n */\n\n/**\n * Returns a converter for the `imageStyle` attribute. It can be used for adding, changing and removing the attribute.\n *\n * @param {Object} styles An object containing available styles. See {@link module:image/imagestyle/imagestyleediting~ImageStyleFormat}\n * for more details.\n * @returns {Function} A model-to-view attribute converter.\n */\nexport function modelToViewStyleAttribute( styles ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if there is class name associated with given value.\n\t\tconst newStyle = getStyleByName( data.attributeNewValue, styles );\n\t\tconst oldStyle = getStyleByName( data.attributeOldValue, styles );\n\n\t\tconst viewElement = conversionApi.mapper.toViewElement( data.item );\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\tif ( oldStyle ) {\n\t\t\tviewWriter.removeClass( oldStyle.className, viewElement );\n\t\t}\n\n\t\tif ( newStyle ) {\n\t\t\tviewWriter.addClass( newStyle.className, viewElement );\n\t\t}\n\t};\n}\n\n/**\n * Returns a view-to-model converter converting image CSS classes to a proper value in the model.\n *\n * @param {Array.<module:image/imagestyle/imagestyleediting~ImageStyleFormat>} styles The styles for which the converter is created.\n * @returns {Function} A view-to-model converter.\n */\nexport function viewToModelStyleAttribute( styles ) {\n\t// Convert only non–default styles.\n\tconst filteredStyles = styles.filter( style => !style.isDefault );\n\n\treturn ( evt, data, conversionApi ) => {\n\t\tif ( !data.modelRange ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewFigureElement = data.viewItem;\n\t\tconst modelImageElement = first( data.modelRange.getItems() );\n\n\t\t// Check if `imageStyle` attribute is allowed for current element.\n\t\tif ( !conversionApi.schema.checkAttribute( modelImageElement, 'imageStyle' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Convert style one by one.\n\t\tfor ( const style of filteredStyles ) {\n\t\t\t// Try to consume class corresponding with style.\n\t\t\tif ( conversionApi.consumable.consume( viewFigureElement, { classes: style.className } ) ) {\n\t\t\t\t// And convert this style to model attribute.\n\t\t\t\tconversionApi.writer.setAttribute( 'imageStyle', style.name, modelImageElement );\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Returns the style with a given `name` from an array of styles.\n//\n// @param {String} name\n// @param {Array.<module:image/imagestyle/imagestyleediting~ImageStyleFormat> } styles\n// @returns {module:image/imagestyle/imagestyleediting~ImageStyleFormat|undefined}\nfunction getStyleByName( name, styles ) {\n\tfor ( const style of styles ) {\n\t\tif ( style.name === name ) {\n\t\t\treturn style;\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imagestyle/utils\n */\n\nimport log from '@ckeditor/ckeditor5-utils/src/log';\n\nimport fullWidthIcon from '@ckeditor/ckeditor5-core/theme/icons/object-full-width.svg';\nimport leftIcon from '@ckeditor/ckeditor5-core/theme/icons/object-left.svg';\nimport centerIcon from '@ckeditor/ckeditor5-core/theme/icons/object-center.svg';\nimport rightIcon from '@ckeditor/ckeditor5-core/theme/icons/object-right.svg';\n\n/**\n * Default image styles provided by the plugin that can be referred in the\n * {@link module:image/image~ImageConfig#styles} configuration.\n *\n * Among them, 2 default semantic content styles are available:\n *\n * * `full` is a full–width image without any CSS class,\n * * `side` is a side image styled with the `image-style-side` CSS class.\n *\n * There are also 3 styles focused on formatting:\n *\n * * `alignLeft` aligns the image to the left using the `image-style-align-left` class,\n * * `alignCenter` centers the image using the `image-style-align-center` class,\n * * `alignRight` aligns the image to the right using the `image-style-align-right` class,\n *\n * @member {Object.<String,Object>}\n */\nconst defaultStyles = {\n\t// This option is equal to the situation when no style is applied.\n\tfull: {\n\t\tname: 'full',\n\t\ttitle: 'Full size image',\n\t\ticon: fullWidthIcon,\n\t\tisDefault: true\n\t},\n\n\t// This represents a side image.\n\tside: {\n\t\tname: 'side',\n\t\ttitle: 'Side image',\n\t\ticon: rightIcon,\n\t\tclassName: 'image-style-side'\n\t},\n\n\t// This style represents an image aligned to the left.\n\talignLeft: {\n\t\tname: 'alignLeft',\n\t\ttitle: 'Left aligned image',\n\t\ticon: leftIcon,\n\t\tclassName: 'image-style-align-left'\n\t},\n\n\t// This style represents a centered image.\n\talignCenter: {\n\t\tname: 'alignCenter',\n\t\ttitle: 'Centered image',\n\t\ticon: centerIcon,\n\t\tclassName: 'image-style-align-center'\n\t},\n\n\t// This style represents an image aligned to the right.\n\talignRight: {\n\t\tname: 'alignRight',\n\t\ttitle: 'Right aligned image',\n\t\ticon: rightIcon,\n\t\tclassName: 'image-style-align-right'\n\t}\n};\n\n/**\n * Default image style icons provided by the plugin that can be referred in the\n * {@link module:image/image~ImageConfig#styles} configuration.\n *\n * There are 4 icons available: `'full'`, `'left'`, `'center'` and `'right'`.\n *\n * @member {Object.<String, String>}\n */\nconst defaultIcons = {\n\tfull: fullWidthIcon,\n\tleft: leftIcon,\n\tright: rightIcon,\n\tcenter: centerIcon\n};\n\n/**\n * Returns a {@link module:image/image~ImageConfig#styles} array with items normalized in the\n * {@link module:image/imagestyle/imagestyleediting~ImageStyleFormat} format and a complete `icon` markup for each style.\n *\n * @returns {Array.<module:image/imagestyle/imagestyleediting~ImageStyleFormat>}\n */\nexport function normalizeImageStyles( configuredStyles = [] ) {\n\treturn configuredStyles.map( _normalizeStyle );\n}\n\n// Normalizes an image style provided in the {@link module:image/image~ImageConfig#styles}\n// and returns it in a {@link module:image/imagestyle/imagestyleediting~ImageStyleFormat}.\n//\n// @param {Object} style\n// @returns {@link module:image/imagestyle/imagestyleediting~ImageStyleFormat}\nfunction _normalizeStyle( style ) {\n\t// Just the name of the style has been passed.\n\tif ( typeof style == 'string' ) {\n\t\tconst styleName = style;\n\n\t\t// If it's one of the defaults, just use it.\n\t\tif ( defaultStyles[ styleName ] ) {\n\t\t\t// Clone the style to avoid overriding defaults.\n\t\t\tstyle = Object.assign( {}, defaultStyles[ styleName ] );\n\t\t}\n\t\t// If it's just a name but none of the defaults, warn because probably it's a mistake.\n\t\telse {\n\t\t\tlog.warn(\n\t\t\t\t'image-style-not-found: There is no such image style of given name.',\n\t\t\t\t{ name: styleName }\n\t\t\t);\n\n\t\t\t// Normalize the style anyway to prevent errors.\n\t\t\tstyle = {\n\t\t\t\tname: styleName\n\t\t\t};\n\t\t}\n\t}\n\t// If an object style has been passed and if the name matches one of the defaults,\n\t// extend it with defaults – the user wants to customize a default style.\n\t// Note: Don't override the user–defined style object, clone it instead.\n\telse if ( defaultStyles[ style.name ] ) {\n\t\tconst defaultStyle = defaultStyles[ style.name ];\n\t\tconst extendedStyle = Object.assign( {}, style );\n\n\t\tfor ( const prop in defaultStyle ) {\n\t\t\tif ( !style.hasOwnProperty( prop ) ) {\n\t\t\t\textendedStyle[ prop ] = defaultStyle[ prop ];\n\t\t\t}\n\t\t}\n\n\t\tstyle = extendedStyle;\n\t}\n\n\t// If an icon is defined as a string and correspond with a name\n\t// in default icons, use the default icon provided by the plugin.\n\tif ( typeof style.icon == 'string' && defaultIcons[ style.icon ] ) {\n\t\tstyle.icon = defaultIcons[ style.icon ];\n\t}\n\n\treturn style;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imagestyle/imagestyleediting\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ImageStyleCommand from './imagestylecommand';\nimport { viewToModelStyleAttribute, modelToViewStyleAttribute } from './converters';\nimport { normalizeImageStyles } from './utils';\n\n/**\n * The image style engine plugin. It sets the default configuration, creates converters and registers\n * {@link module:image/imagestyle/imagestylecommand~ImageStyleCommand ImageStyleCommand}.\n *\n * @extends {module:core/plugin~Plugin}\n */\nexport default class ImageStyleEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageStyleEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\t\tconst data = editor.data;\n\t\tconst editing = editor.editing;\n\n\t\t// Define default configuration.\n\t\teditor.config.define( 'image.styles', [ 'full', 'side' ] );\n\n\t\t// Get configuration.\n\t\tconst styles = normalizeImageStyles( editor.config.get( 'image.styles' ) );\n\n\t\t// Allow imageStyle attribute in image.\n\t\t// We could call it 'style' but https://github.com/ckeditor/ckeditor5-engine/issues/559.\n\t\tschema.extend( 'image', { allowAttributes: 'imageStyle' } );\n\n\t\t// Converters for imageStyle attribute from model to view.\n\t\tconst modelToViewConverter = modelToViewStyleAttribute( styles );\n\t\tediting.downcastDispatcher.on( 'attribute:imageStyle:image', modelToViewConverter );\n\t\tdata.downcastDispatcher.on( 'attribute:imageStyle:image', modelToViewConverter );\n\n\t\t// Converter for figure element from view to model.\n\t\tdata.upcastDispatcher.on( 'element:figure', viewToModelStyleAttribute( styles ), { priority: 'low' } );\n\n\t\t// Register imageStyle command.\n\t\teditor.commands.add( 'imageStyle', new ImageStyleCommand( editor, styles ) );\n\t}\n}\n\n/**\n * The image style format descriptor.\n *\n *\t\timport fullSizeIcon from 'path/to/icon.svg';\n *\n *\t\tconst imageStyleFormat = {\n *\t\t\tname: 'fullSize',\n *\t\t\ticon: fullSizeIcon,\n *\t\t\ttitle: 'Full size image',\n *\t\t\tclassName: 'image-full-size'\n *\t\t}\n *\n * @typedef {Object} module:image/imagestyle/imagestyleediting~ImageStyleFormat\n *\n * @property {String} name The unique name of the style. It will be used to:\n *\n * * Store the chosen style in the model by setting the `imageStyle` attribute of the `<image>` element.\n * * As a value of the {@link module:image/imagestyle/imagestylecommand~ImageStyleCommand#execute `imageStyle` command},\n * * when registering a button for each of the styles (`'imageStyle:{name}'`) in the\n * {@link module:ui/componentfactory~ComponentFactory UI components factory} (this functionality is provided by the\n * {@link module:image/imagestyle/imagestyleui~ImageStyleUI} plugin).\n *\n * @property {Boolean} [isDefault] When set, the style will be used as the default one.\n * A default style does not apply any CSS class to the view element.\n *\n * @property {String} icon One of the following to be used when creating the style's button:\n *\n * * An SVG icon source (as an XML string).\n * * One of {@link module:image/imagestyle/utils~defaultIcons} to use a default icon provided by the plugin.\n *\n * @property {String} title The style's title.\n *\n * @property {String} className The CSS class used to represent the style in the view.\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module image/imagestyle/imagestyleui\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport { normalizeImageStyles } from './utils';\nimport '../../theme/imagestyle.css';\n/**\n * The image style UI plugin.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageStyleUI extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n static get pluginName() {\n return 'ImageStyleUI';\n }\n /**\n\t * Returns the default localized style titles provided by the plugin.\n\t *\n\t * The following localized titles corresponding with\n\t * {@link module:image/imagestyle/utils~defaultStyles} are available:\n\t *\n\t * * `'Full size image'`,\n\t * * `'Side image'`,\n\t * * `'Left aligned image'`,\n\t * * `'Centered image'`,\n\t * * `'Right aligned image'`\n\t *\n\t * @returns {Object.<String,String>}\n\t */\n get localizedDefaultStylesTitles() {\n const t = this.editor.t;\n return {\n 'Full size image': t('y'),\n 'Side image': t('z'),\n 'Left aligned image': t('aa'),\n 'Centered image': t('ab'),\n 'Right aligned image': t('ac')\n };\n }\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const configuredStyles = editor.config.get('image.styles');\n const translatedStyles = translateStyles(normalizeImageStyles(configuredStyles), this.localizedDefaultStylesTitles);\n for (const style of translatedStyles) {\n this._createButton(style);\n }\n }\n /**\n\t * Creates a button for each style and stores it in the editor {@link module:ui/componentfactory~ComponentFactory ComponentFactory}.\n\t *\n\t * @private\n\t * @param {module:image/imagestyle/imagestyleediting~ImageStyleFormat} style\n\t */\n _createButton(style) {\n const editor = this.editor;\n const componentName = `imageStyle:${ style.name }`;\n editor.ui.componentFactory.add(componentName, locale => {\n const command = editor.commands.get('imageStyle');\n const view = new ButtonView(locale);\n view.set({\n label: style.title,\n icon: style.icon,\n tooltip: true\n });\n view.bind('isEnabled').to(command, 'isEnabled');\n view.bind('isOn').to(command, 'value', value => value === style.name);\n this.listenTo(view, 'execute', () => editor.execute('imageStyle', { value: style.name }));\n return view;\n });\n }\n}\n/**\n * Returns the translated `title` from the passed styles array.\n *\n * @param {Array.<module:image/imagestyle/imagestyleediting~ImageStyleFormat>} styles\n * @param titles\n * @returns {Array.<module:image/imagestyle/imagestyleediting~ImageStyleFormat>}\n */\nfunction translateStyles(styles, titles) {\n for (const style of styles) {\n // Localize the titles of the styles, if a title corresponds with\n // a localized default provided by the plugin.\n if (titles[style.title]) {\n style.title = titles[style.title];\n }\n }\n return styles;\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module widget/widgettoolbarrepository\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ContextualBalloon from '@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon';\nimport ToolbarView from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview';\nimport BalloonPanelView from '@ckeditor/ckeditor5-ui/src/panel/balloon/balloonpanelview';\nimport { isWidget } from './utils';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Widget toolbar repository plugin. A central point for registering widget toolbars. This plugin handles the whole\n * toolbar rendering process and exposes a concise API.\n *\n * To add a toolbar for your widget use the {@link ~WidgetToolbarRepository#register `WidgetToolbarRepository#register()`} method.\n *\n * The following example comes from the {@link module:image/imagetoolbar~ImageToolbar} plugin:\n *\n * \t\tclass ImageToolbar extends Plugin {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ WidgetToolbarRepository ];\n *\t\t\t}\n *\n *\t\t\tafterInit() {\n *\t\t\t\tconst editor = this.editor;\n *\t\t\t\tconst widgetToolbarRepository = editor.plugins.get( WidgetToolbarRepository );\n *\n *\t\t\t\twidgetToolbarRepository.register( 'image', {\n *\t\t\t\t\titems: editor.config.get( 'image.toolbar' ),\n *\t\t\t\t\tgetRelatedElement: getSelectedImageWidget\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n */\nexport default class WidgetToolbarRepository extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ContextualBalloon ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'WidgetToolbarRepository';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\n\t\t// Disables the default balloon toolbar for all widgets.\n\t\tif ( editor.plugins.has( 'BalloonToolbar' ) ) {\n\t\t\tconst balloonToolbar = editor.plugins.get( 'BalloonToolbar' );\n\n\t\t\tthis.listenTo( balloonToolbar, 'show', evt => {\n\t\t\t\tif ( isWidgetSelected( editor.editing.view.document.selection ) ) {\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t}, { priority: 'high' } );\n\t\t}\n\n\t\t/**\n\t\t * A map of toolbar definitions.\n\t\t *\n\t\t * @protected\n\t\t * @member {Map.<String,module:widget/widgettoolbarrepository~WidgetRepositoryToolbarDefinition>} #_toolbarDefinitions\n\t\t */\n\t\tthis._toolbarDefinitions = new Map();\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tthis._balloon = this.editor.plugins.get( 'ContextualBalloon' );\n\n\t\tthis.listenTo( editor.ui, 'update', () => {\n\t\t\tthis._updateToolbarsVisibility();\n\t\t} );\n\n\t\t// UI#update is not fired after focus is back in editor, we need to check if balloon panel should be visible.\n\t\tthis.listenTo( editor.ui.focusTracker, 'change:isFocused', () => {\n\t\t\tthis._updateToolbarsVisibility();\n\t\t}, { priority: 'low' } );\n\t}\n\n\tdestroy() {\n\t\tsuper.destroy();\n\n\t\tfor ( const toolbarConfig of this._toolbarDefinitions.values() ) {\n\t\t\ttoolbarConfig.view.destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Registers toolbar in the WidgetToolbarRepository. It renders it in the `ContextualBalloon` based on the value of the invoked\n\t * `getRelatedElement` function. Toolbar items are gathered from `items` array.\n\t * The balloon's CSS class is by default `ck-toolbar-container` and may be override with the `balloonClassName` option.\n\t *\n\t * Note: This method should be called in the {@link module:core/plugin~PluginInterface#afterInit `Plugin#afterInit()`}\n\t * callback (or later) to make sure that the given toolbar items were already registered by other plugins.\n\t *\n\t * @param {String} toolbarId An id for the toolbar. Used to\n\t * @param {Object} options\n\t * @param {Array.<String>} options.items Array of toolbar items.\n\t * @param {Function} options.getRelatedElement Callback which returns an element the toolbar should be attached to.\n\t * @param {String} [options.balloonClassName='ck-toolbar-container'] CSS class for the widget balloon.\n\t */\n\tregister( toolbarId, { items, getRelatedElement, balloonClassName = 'ck-toolbar-container' } ) {\n\t\tconst editor = this.editor;\n\t\tconst toolbarView = new ToolbarView();\n\n\t\tif ( this._toolbarDefinitions.has( toolbarId ) ) {\n\t\t\t/**\n\t\t\t * Toolbar with the given id was already added.\n\t\t\t *\n\t\t\t * @error widget-toolbar-duplicated\n\t\t\t * @param toolbarId Toolbar id.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'widget-toolbar-duplicated: Toolbar with the given id was already added.', { toolbarId } );\n\t\t}\n\n\t\ttoolbarView.fillFromConfig( items, editor.ui.componentFactory );\n\n\t\tthis._toolbarDefinitions.set( toolbarId, {\n\t\t\tview: toolbarView,\n\t\t\tgetRelatedElement,\n\t\t\tballoonClassName,\n\t\t} );\n\t}\n\n\t/**\n\t * Iterates over stored toolbars and makes them visible or hidden.\n\t *\n\t * @private\n\t */\n\t_updateToolbarsVisibility() {\n\t\tlet maxRelatedElementDepth = 0;\n\t\tlet deepestRelatedElement = null;\n\t\tlet deepestToolbarDefinition = null;\n\n\t\tfor ( const definition of this._toolbarDefinitions.values() ) {\n\t\t\tconst relatedElement = definition.getRelatedElement( this.editor.editing.view.document.selection );\n\n\t\t\tif ( !this.editor.ui.focusTracker.isFocused || !relatedElement ) {\n\t\t\t\tthis._hideToolbar( definition );\n\t\t\t} else {\n\t\t\t\tconst relatedElementDepth = relatedElement.getAncestors().length;\n\n\t\t\t\t// Many toolbars can express willingness to be displayed but they do not know about\n\t\t\t\t// each other. Figure out which toolbar is deepest in the view tree to decide which\n\t\t\t\t// should be displayed. For instance, if a selected image is inside a table cell, display\n\t\t\t\t// the ImageToolbar rather than the TableToolbar (#60).\n\t\t\t\tif ( relatedElementDepth > maxRelatedElementDepth ) {\n\t\t\t\t\tmaxRelatedElementDepth = relatedElementDepth;\n\t\t\t\t\tdeepestRelatedElement = relatedElement;\n\t\t\t\t\tdeepestToolbarDefinition = definition;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( deepestToolbarDefinition ) {\n\t\t\tthis._showToolbar( deepestToolbarDefinition, deepestRelatedElement );\n\t\t}\n\t}\n\n\t/**\n\t * Hides the given toolbar.\n\t *\n\t * @private\n\t * @param {module:widget/widgettoolbarrepository~WidgetRepositoryToolbarDefinition} toolbarDefinition\n\t */\n\t_hideToolbar( toolbarDefinition ) {\n\t\tif ( !this._isToolbarVisible( toolbarDefinition ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._balloon.remove( toolbarDefinition.view );\n\t}\n\n\t/**\n\t * Shows up the toolbar if the toolbar is not visible.\n\t * Otherwise, repositions the toolbar's balloon when toolbar's view is the most top view in balloon stack.\n\t *\n\t * It might happen here that the toolbar's view is under another view. Then do nothing as the other toolbar view\n\t * should be still visible after the {@link module:core/editor/editorui~EditorUI#event:update}.\n\t *\n\t * @private\n\t * @param {module:widget/widgettoolbarrepository~WidgetRepositoryToolbarDefinition} toolbarDefinition\n\t * @param {module:engine/view/element~Element} relatedElement\n\t */\n\t_showToolbar( toolbarDefinition, relatedElement ) {\n\t\tif ( this._isToolbarVisible( toolbarDefinition ) ) {\n\t\t\trepositionContextualBalloon( this.editor, relatedElement );\n\t\t} else if ( !this._balloon.hasView( toolbarDefinition.view ) ) {\n\t\t\tthis._balloon.add( {\n\t\t\t\tview: toolbarDefinition.view,\n\t\t\t\tposition: getBalloonPositionData( this.editor, relatedElement ),\n\t\t\t\tballoonClassName: toolbarDefinition.balloonClassName,\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {Object} toolbar\n\t */\n\t_isToolbarVisible( toolbar ) {\n\t\treturn this._balloon.visibleView == toolbar.view;\n\t}\n}\n\nfunction repositionContextualBalloon( editor, relatedElement ) {\n\tconst balloon = editor.plugins.get( 'ContextualBalloon' );\n\tconst position = getBalloonPositionData( editor, relatedElement );\n\n\tballoon.updatePosition( position );\n}\n\nfunction getBalloonPositionData( editor, relatedElement ) {\n\tconst editingView = editor.editing.view;\n\tconst defaultPositions = BalloonPanelView.defaultPositions;\n\n\treturn {\n\t\ttarget: editingView.domConverter.viewToDom( relatedElement ),\n\t\tpositions: [\n\t\t\tdefaultPositions.northArrowSouth,\n\t\t\tdefaultPositions.northArrowSouthWest,\n\t\t\tdefaultPositions.northArrowSouthEast,\n\t\t\tdefaultPositions.southArrowNorth,\n\t\t\tdefaultPositions.southArrowNorthWest,\n\t\t\tdefaultPositions.southArrowNorthEast\n\t\t]\n\t};\n}\n\nfunction isWidgetSelected( selection ) {\n\tconst viewElement = selection.getSelectedElement();\n\n\treturn !!( viewElement && isWidget( viewElement ) );\n}\n\n/**\n * The toolbar definition object used by the toolbar repository to manage toolbars.\n * It contains information necessary to display the toolbar in the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} and\n * update it during its life (display) cycle.\n *\n * @typedef {Object} module:widget/widgettoolbarrepository~WidgetRepositoryToolbarDefinition\n *\n * @property {module:ui/view~View} view The UI view of the toolbar.\n * @property {Function} getRelatedElement A function that returns an engine {@link module:engine/view/view~View}\n * element the toolbar is to be attached to. For instance, an image widget or a table widget (or `null` when\n * there is no such element). The function accepts an instance of {@link module:engine/view/selection~Selection}.\n * @property {String} balloonClassName CSS class for the widget balloon when a toolbar is displayed.\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor.data, 'ready', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n/**\n * Array of loaded plugins.\n *\n * @typedef {Array.<module:core/plugin~PluginInterface>} module:core/plugin~LoadedPlugins\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/command\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor commands.\n *\n * Commands are the main way to manipulate editor contents and state. They are mostly used by UI elements (or by other\n * commands) to make changes in the model. Commands are available in every part of code that has access to\n * the {@link module:core/editor/editor~Editor editor} instance.\n *\n * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n *\n * By default commands are disabled when the editor is in {@link module:core/editor/editor~Editor#isReadOnly read-only} mode.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Command {\n\t/**\n\t * Creates a new `Command` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor Editor on which this command will be used.\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor on which this command will be used.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * The value of the command. A concrete command class should define what it represents for it.\n\t\t *\n\t\t * For example, the `'bold'` command's value indicates whether the selection starts in a bolded text.\n\t\t * And the value of the `'link'` command may be an object with links details.\n\t\t *\n\t\t * It is possible for a command to have no value (e.g. for stateless actions such as `'imageUpload'`).\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member #value\n\t\t */\n\t\tthis.set( 'value', undefined );\n\n\t\t/**\n\t\t * Flag indicating whether a command is enabled or disabled.\n\t\t * A disabled command will do nothing when executed.\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * It is possible to disable a command from \"outside\". For instance, in your integration you may want to disable\n\t\t * a certain set of commands for the time being. To do that, you can use the fact that `isEnabled` is observable\n\t\t * and it fires the `set:isEnabled` event every time anyone tries to modify its value:\n\t\t *\n\t\t *\t\tfunction disableCommand( cmd ) {\n\t\t *\t\t\tcmd.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t *\n\t\t *\t\t\tcmd.isEnabled = false;\n\t\t *\n\t\t *\t\t\t// Make it possible to enable the command again.\n\t\t *\t\t\treturn () => {\n\t\t *\t\t\t\tcmd.off( 'set:isEnabled', forceDisable );\n\t\t *\t\t\t\tcmd.refresh();\n\t\t *\t\t\t};\n\t\t *\n\t\t *\t\t\tfunction forceDisable( evt ) {\n\t\t *\t\t\t\tevt.return = false;\n\t\t *\t\t\t\tevt.stop();\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\n\t\t *\t\t// Usage:\n\t\t *\n\t\t *\t\t// Disabling the command.\n\t\t *\t\tconst enableBold = disableCommand( editor.commands.get( 'bold' ) );\n\t\t *\n\t\t *\t\t// Enabling the command again.\n\t\t *\t\tenableBold();\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\t\tthis.set( 'isEnabled', false );\n\n\t\t/**\n\t\t * Holds identifiers for {@link #forceDisabled} mechanism.\n\t\t *\n\t\t * @type {Set.<String>}\n\t\t * @private\n\t\t */\n\t\tthis._disableStack = new Set();\n\n\t\tthis.decorate( 'execute' );\n\n\t\t// By default every command is refreshed when changes are applied to the model.\n\t\tthis.listenTo( this.editor.model.document, 'change', () => {\n\t\t\tthis.refresh();\n\t\t} );\n\n\t\tthis.on( 'execute', evt => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// By default commands are disabled when the editor is in read-only mode.\n\t\tthis.listenTo( editor, 'change:isReadOnly', ( evt, name, value ) => {\n\t\t\tif ( value ) {\n\t\t\t\tthis.forceDisabled( 'readOnlyMode' );\n\t\t\t} else {\n\t\t\t\tthis.clearForceDisabled( 'readOnlyMode' );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties\n\t * in this method.\n\t *\n\t * This method is automatically called when\n\t * {@link module:engine/model/document~Document#event:change any changes are applied to the document}.\n\t */\n\trefresh() {\n\t\tthis.isEnabled = true;\n\t}\n\n\t/**\n\t * Disables the command.\n\t *\n\t * Command may be disabled by multiple features or algorithms (at once). When disabling a command, unique id should be passed\n\t * (e.g. feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the command.\n\t * The command becomes enabled only after all features {@link #clearForceDisabled enabled it back}.\n\t *\n\t * Disabling and enabling a command:\n\t *\n\t *\t\tcommand.isEnabled; // -> true\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Command disabled by multiple features:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'OtherFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'OtherFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Multiple disabling with the same identifier is redundant:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * **Note:** some commands or algorithms may have more complex logic when it comes to enabling or disabling certain commands,\n\t * so the command might be still disabled after {@link #clearForceDisabled} was used.\n\t *\n\t * @param {String} id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the command.\n\t */\n\tforceDisabled( id ) {\n\t\tthis._disableStack.add( id );\n\n\t\tif ( this._disableStack.size == 1 ) {\n\t\t\tthis.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * Clears forced disable previously set through {@link #clearForceDisabled}. See {@link #clearForceDisabled}.\n\t *\n\t * @param {String} id Unique identifier, equal to the one passed in {@link #forceDisabled} call.\n\t */\n\tclearForceDisabled( id ) {\n\t\tthis._disableStack.delete( id );\n\n\t\tif ( this._disableStack.size == 0 ) {\n\t\t\tthis.off( 'set:isEnabled', forceDisable );\n\t\t\tthis.refresh();\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`}\n\t * to the command.\n\t *\n\t * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`).\n\t * This behavior is implemented by a high priority listener to the {@link #event:execute} event.\n\t *\n\t * In order to see how to disable a command from \"outside\" see the {@link #isEnabled} documentation.\n\t *\n\t * @fires execute\n\t */\n\texecute() {}\n\n\t/**\n\t * Destroys the command.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Event fired by the {@link #execute} method. The command action is a listener to this event so it's\n\t * possible to change/cancel the behavior of the command by listening to this event.\n\t *\n\t * See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples.\n\t *\n\t * **Note:** This event is fired even if command is disabled. However, it is automatically blocked\n\t * by a high priority listener in order to prevent command execution.\n\t *\n\t * @event execute\n\t */\n}\n\nmix( Command, ObservableMixin );\n\n// Helper function that forces command to be disabled.\nfunction forceDisable( evt ) {\n\tevt.return = false;\n\tevt.stop();\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module link/findlinkrange\n */\n\n/**\n * Returns a range containing the entire link in which the given `position` is placed.\n *\n * It can be used e.g. to get the entire range on which the `linkHref` attribute needs to be changed when having a\n * selection inside a link.\n *\n * @param {module:engine/model/position~Position} position The start position.\n * @param {String} value The `linkHref` attribute value.\n * @returns {module:engine/model/range~Range} The link range.\n */\nexport default function findLinkRange( position, value, model ) {\n\treturn model.createRange( _findBound( position, value, true, model ), _findBound( position, value, false, model ) );\n}\n\n// Walks forward or backward (depends on the `lookBack` flag), node by node, as long as they have the same `linkHref` attribute value\n// and returns a position just before or after (depends on the `lookBack` flag) the last matched node.\n//\n// @param {module:engine/model/position~Position} position The start position.\n// @param {String} value The `linkHref` attribute value.\n// @param {Boolean} lookBack Whether the walk direction is forward (`false`) or backward (`true`).\n// @returns {module:engine/model/position~Position} The position just before the last matched node.\nfunction _findBound( position, value, lookBack, model ) {\n\t// Get node before or after position (depends on `lookBack` flag).\n\t// When position is inside text node then start searching from text node.\n\tlet node = position.textNode || ( lookBack ? position.nodeBefore : position.nodeAfter );\n\n\tlet lastNode = null;\n\n\twhile ( node && node.getAttribute( 'linkHref' ) == value ) {\n\t\tlastNode = node;\n\t\tnode = lookBack ? node.previousSibling : node.nextSibling;\n\t}\n\n\treturn lastNode ? model.createPositionAt( lastNode, lookBack ? 'before' : 'after' ) : position;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module link/linkcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport findLinkRange from './findlinkrange';\nimport toMap from '@ckeditor/ckeditor5-utils/src/tomap';\n\n/**\n * The link command. It is used by the {@link module:link/link~Link link feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class LinkCommand extends Command {\n\t/**\n\t * The value of the `'linkHref'` attribute if the start of the selection is located in a node with this attribute.\n\t *\n\t * @observable\n\t * @readonly\n\t * @member {Object|undefined} #value\n\t */\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\n\t\tthis.value = doc.selection.getAttribute( 'linkHref' );\n\t\tthis.isEnabled = model.schema.checkAttributeInSelection( doc.selection, 'linkHref' );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * When the selection is non-collapsed, the `linkHref` attribute will be applied to nodes inside the selection, but only to\n\t * those nodes where the `linkHref` attribute is allowed (disallowed nodes will be omitted).\n\t *\n\t * When the selection is collapsed and is not inside the text with the `linkHref` attribute, the\n\t * new {@link module:engine/model/text~Text Text node} with the `linkHref` attribute will be inserted in place of caret, but\n\t * only if such element is allowed in this place. The `_data` of the inserted text will equal the `href` parameter.\n\t * The selection will be updated to wrap the just inserted text node.\n\t *\n\t * When the selection is collapsed and inside the text with the `linkHref` attribute, the attribute value will be updated.\n\t *\n\t * @fires execute\n\t * @param {String} href Link destination.\n\t */\n\texecute( href ) {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\n\t\tmodel.change( writer => {\n\t\t\t// If selection is collapsed then update selected link or insert new one at the place of caret.\n\t\t\tif ( selection.isCollapsed ) {\n\t\t\t\tconst position = selection.getFirstPosition();\n\n\t\t\t\t// When selection is inside text with `linkHref` attribute.\n\t\t\t\tif ( selection.hasAttribute( 'linkHref' ) ) {\n\t\t\t\t\t// Then update `linkHref` value.\n\t\t\t\t\tconst linkRange = findLinkRange( selection.getFirstPosition(), selection.getAttribute( 'linkHref' ), model );\n\n\t\t\t\t\twriter.setAttribute( 'linkHref', href, linkRange );\n\n\t\t\t\t\t// Create new range wrapping changed link.\n\t\t\t\t\twriter.setSelection( linkRange );\n\t\t\t\t}\n\t\t\t\t// If not then insert text node with `linkHref` attribute in place of caret.\n\t\t\t\t// However, since selection in collapsed, attribute value will be used as data for text node.\n\t\t\t\t// So, if `href` is empty, do not create text node.\n\t\t\t\telse if ( href !== '' ) {\n\t\t\t\t\tconst attributes = toMap( selection.getAttributes() );\n\n\t\t\t\t\tattributes.set( 'linkHref', href );\n\n\t\t\t\t\tconst node = writer.createText( href, attributes );\n\n\t\t\t\t\twriter.insert( node, position );\n\n\t\t\t\t\t// Create new range wrapping created node.\n\t\t\t\t\twriter.setSelection( writer.createRangeOn( node ) );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If selection has non-collapsed ranges, we change attribute on nodes inside those ranges\n\t\t\t\t// omitting nodes where `linkHref` attribute is disallowed.\n\t\t\t\tconst ranges = model.schema.getValidRanges( selection.getRanges(), 'linkHref' );\n\n\t\t\t\tfor ( const range of ranges ) {\n\t\t\t\t\twriter.setAttribute( 'linkHref', href, range );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module link/unlinkcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport findLinkRange from './findlinkrange';\n\n/**\n * The unlink command. It is used by the {@link module:link/link~Link link plugin}.\n *\n * @extends module:core/command~Command\n */\nexport default class UnlinkCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.isEnabled = this.editor.model.document.selection.hasAttribute( 'linkHref' );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * When the selection is collapsed, removes the `linkHref` attribute from each node with the same `linkHref` attribute value.\n\t * When the selection is non-collapsed, removes the `linkHref` attribute from each node in selected ranges.\n\t *\n\t * @fires execute\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\n\t\tmodel.change( writer => {\n\t\t\t// Get ranges to unlink.\n\t\t\tconst rangesToUnlink = selection.isCollapsed ?\n\t\t\t\t[ findLinkRange( selection.getFirstPosition(), selection.getAttribute( 'linkHref' ), model ) ] : selection.getRanges();\n\n\t\t\t// Remove `linkHref` attribute from specified ranges.\n\t\t\tfor ( const range of rangesToUnlink ) {\n\t\t\t\twriter.removeAttribute( 'linkHref', range );\n\t\t\t}\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module link/utils\n */\n\nconst ATTRIBUTE_WHITESPACES = /[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205f\\u3000]/g; // eslint-disable-line no-control-regex\nconst SAFE_URL = /^(?:(?:https?|ftps?|mailto):|[^a-z]|[a-z+.-]+(?:[^a-z+.:-]|$))/i;\n\n/**\n * Returns `true` if a given view node is the link element.\n *\n * @param {module:engine/view/node~Node} node\n * @returns {Boolean}\n */\nexport function isLinkElement( node ) {\n\treturn node.is( 'attributeElement' ) && !!node.getCustomProperty( 'link' );\n}\n\n/**\n * Creates link {@link module:engine/view/attributeelement~AttributeElement} with provided `href` attribute.\n *\n * @param {String} href\n * @returns {module:engine/view/attributeelement~AttributeElement}\n */\nexport function createLinkElement( href, writer ) {\n\t// Priority 5 - https://github.com/ckeditor/ckeditor5-link/issues/121.\n\tconst linkElement = writer.createAttributeElement( 'a', { href }, { priority: 5 } );\n\twriter.setCustomProperty( 'link', true, linkElement );\n\n\treturn linkElement;\n}\n\n/**\n * Returns a safe URL based on a given value.\n *\n * An URL is considered safe if it is safe for the user (does not contain any malicious code).\n *\n * If URL is considered unsafe, a simple `\"#\"` is returned.\n *\n * @protected\n * @param {*} url\n * @returns {String} Safe URL.\n */\nexport function ensureSafeUrl( url ) {\n\turl = String( url );\n\n\treturn isSafeUrl( url ) ? url : '#';\n}\n\n// Checks whether the given URL is safe for the user (does not contain any malicious code).\n//\n// @param {String} url URL to check.\nfunction isSafeUrl( url ) {\n\tconst normalizedUrl = url.replace( ATTRIBUTE_WHITESPACES, '' );\n\n\treturn normalizedUrl.match( SAFE_URL );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/utils/bindtwostepcarettoattribute\n */\n\nimport { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';\nimport priorities from '@ckeditor/ckeditor5-utils/src/priorities';\n\n/**\n * This helper enabled the two-step caret (phantom) movement behavior for the given {@link module:engine/model/model~Model}\n * attribute on arrow right (<kbd>→</kbd>) and left (<kbd>←</kbd>) key press.\n *\n * Thanks to this (phantom) caret movement the user is able to type before/after as well as at the\n * beginning/end of an attribute.\n *\n * # Forward movement\n *\n * ## \"Entering\" an attribute:\n *\n * When this behavior is enabled for the `a` attribute and the selection is right before it\n * (at the attribute boundary), pressing the right arrow key will not move the selection but update its\n * attributes accordingly:\n *\n * * When enabled:\n *\n * \t\tfoo{}<$text a=\"true\">bar</$text>\n *\n * <kbd>→</kbd>\n *\n * \t\tfoo<$text a=\"true\">{}bar</$text>\n *\n * * When disabled:\n *\n * \t\tfoo{}<$text a=\"true\">bar</$text>\n *\n * <kbd>→</kbd>\n *\n * \t\tfoo<$text a=\"true\">b{}ar</$text>\n *\n *\n * ## \"Leaving\" an attribute:\n *\n * * When enabled:\n *\n * \t\t<$text a=\"true\">bar{}</$text>baz\n *\n * <kbd>→</kbd>\n *\n * \t\t<$text a=\"true\">bar</$text>{}baz\n *\n * * When disabled:\n *\n * \t\t<$text a=\"true\">bar{}</$text>baz\n *\n * <kbd>→</kbd>\n *\n * \t\t<$text a=\"true\">bar</$text>b{}az\n *\n * # Backward movement\n *\n * * When enabled:\n *\n * \t\t<$text a=\"true\">bar</$text>{}baz\n *\n * <kbd>←</kbd>\n *\n * \t\t<$text a=\"true\">bar{}</$text>baz\n *\n * * When disabled:\n *\n * \t\t<$text a=\"true\">bar</$text>{}baz\n *\n * <kbd>←</kbd>\n *\n * \t\t<$text a=\"true\">ba{}r</$text>b{}az\n *\n * @param {module:engine/view/view~View} view View controller instance.\n * @param {module:engine/model/model~Model} model Data model instance.\n * @param {module:utils/dom/emittermixin~Emitter} emitter The emitter to which this behavior should be added\n * (e.g. a plugin instance).\n * @param {String} attribute Attribute for which this behavior will be added.\n */\nexport default function bindTwoStepCaretToAttribute( view, model, emitter, attribute ) {\n\tconst twoStepCaretHandler = new TwoStepCaretHandler( model, emitter, attribute );\n\tconst modelSelection = model.document.selection;\n\n\t// Listen to keyboard events and handle the caret movement according to the 2-step caret logic.\n\t//\n\t// Note: This listener has the \"high+1\" priority:\n\t// * \"high\" because of the filler logic implemented in the renderer which also engages on #keydown.\n\t// When the gravity is overridden the attributes of the (model) selection attributes are reset.\n\t// It may end up with the filler kicking in and breaking the selection.\n\t// * \"+1\" because we would like to avoid collisions with other features (like Widgets), which\n\t// take over the keydown events with the \"high\" priority. Two-step caret movement takes precedence\n\t// over Widgets in that matter.\n\t//\n\t// Find out more in https://github.com/ckeditor/ckeditor5-engine/issues/1301.\n\temitter.listenTo( view.document, 'keydown', ( evt, data ) => {\n\t\t// This implementation works only for collapsed selection.\n\t\tif ( !modelSelection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// When user tries to expand the selection or jump over the whole word or to the beginning/end then\n\t\t// two-steps movement is not necessary.\n\t\tif ( data.shiftKey || data.altKey || data.ctrlKey ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst arrowRightPressed = data.keyCode == keyCodes.arrowright;\n\t\tconst arrowLeftPressed = data.keyCode == keyCodes.arrowleft;\n\n\t\t// When neither left or right arrow has been pressed then do noting.\n\t\tif ( !arrowRightPressed && !arrowLeftPressed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst position = modelSelection.getFirstPosition();\n\t\tlet isMovementHandled;\n\n\t\tif ( arrowRightPressed ) {\n\t\t\tisMovementHandled = twoStepCaretHandler.handleForwardMovement( position, data );\n\t\t} else {\n\t\t\tisMovementHandled = twoStepCaretHandler.handleBackwardMovement( position, data );\n\t\t}\n\n\t\t// Stop the keydown event if the two-step arent movement handled it. Avoid collisions\n\t\t// with other features which may also take over the caret movement (e.g. Widget).\n\t\tif ( isMovementHandled ) {\n\t\t\tevt.stop();\n\t\t}\n\t}, { priority: priorities.get( 'high' ) + 1 } );\n}\n\n/**\n * This is a private helper–class for {@link module:engine/utils/bindtwostepcarettoattribute}.\n * It handles the state of the 2-step caret movement for a single {@link module:engine/model/model~Model}\n * attribute upon the `keypress` in the {@link module:engine/view/view~View}.\n *\n * @private\n */\nclass TwoStepCaretHandler {\n\t/*\n\t * Creates two step handler instance.\n\t *\n\t * @param {module:engine/model/model~Model} model Data model instance.\n\t * @param {module:utils/dom/emittermixin~Emitter} emitter The emitter to which this behavior should be added\n\t * (e.g. a plugin instance).\n\t * @param {String} attribute Attribute for which the behavior will be added.\n\t */\n\tconstructor( model, emitter, attribute ) {\n\t\t/**\n\t\t * The model instance this class instance operates on.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/model~Model#schema}\n\t\t */\n\t\tthis.model = model;\n\n\t\t/**\n\t\t * The Attribute this class instance operates on.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.attribute = attribute;\n\n\t\t/**\n\t\t * A reference to the document selection.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/model/selection~Selection}\n\t\t */\n\t\tthis._modelSelection = model.document.selection;\n\n\t\t/**\n\t\t * The current UID of the overridden gravity, as returned by\n\t\t * {@link module:engine/model/writer~Writer#overrideSelectionGravity}.\n\t\t *\n\t\t * @private\n\t\t * @member {String}\n\t\t */\n\t\tthis._overrideUid = null;\n\n\t\t/**\n\t\t * A flag indicating that the automatic gravity restoration for this attribute\n\t\t * should not happen upon the next\n\t\t * {@link module:engine/model/selection~Selection#event:change:range} event.\n\t\t *\n\t\t * @private\n\t\t * @member {String}\n\t\t */\n\t\tthis._isNextGravityRestorationSkipped = false;\n\n\t\t// The automatic gravity restoration logic.\n\t\temitter.listenTo( this._modelSelection, 'change:range', ( evt, data ) => {\n\t\t\t// Skipping the automatic restoration is needed if the selection should change\n\t\t\t// but the gravity must remain overridden afterwards. See the #handleBackwardMovement\n\t\t\t// to learn more.\n\t\t\tif ( this._isNextGravityRestorationSkipped ) {\n\t\t\t\tthis._isNextGravityRestorationSkipped = false;\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Skip automatic restore when the gravity is not overridden — simply, there's nothing to restore\n\t\t\t// at this moment.\n\t\t\tif ( !this._isGravityOverridden ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Skip automatic restore when the change is indirect AND the selection is at the attribute boundary.\n\t\t\t// It means that e.g. if the change was external (collaboration) and the user had their\n\t\t\t// selection around the link, its gravity should remain intact in this change:range event.\n\t\t\tif ( !data.directChange && isAtBoundary( this._modelSelection.getFirstPosition(), attribute ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._restoreGravity();\n\t\t} );\n\t}\n\n\t/**\n\t * Updates the document selection and the view according to the two–step caret movement state\n\t * when moving **forwards**. Executed upon `keypress` in the {@link module:engine/view/view~View}.\n\t *\n\t * @param {module:engine/model/position~Position} position The model position at the moment of the key press.\n\t * @param {module:engine/view/observer/domeventdata~DomEventData} data Data of the key press.\n\t * @returns {Boolean} `true` when the handler prevented caret movement\n\t */\n\thandleForwardMovement( position, data ) {\n\t\tconst attribute = this.attribute;\n\n\t\t// DON'T ENGAGE 2-SCM if gravity is already overridden. It means that we just entered\n\t\t//\n\t\t// \t\t<paragraph>foo<$text attribute>{}bar</$text>baz</paragraph>\n\t\t//\n\t\t// or left the attribute\n\t\t//\n\t\t// \t\t<paragraph>foo<$text attribute>bar</$text>{}baz</paragraph>\n\t\t//\n\t\t// and the gravity will be restored automatically.\n\t\tif ( this._isGravityOverridden ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// DON'T ENGAGE 2-SCM when the selection is at the beginning of the block AND already has the\n\t\t// attribute:\n\t\t// * when the selection was initially set there using the mouse,\n\t\t// * when the editor has just started\n\t\t//\n\t\t//\t\t<paragraph><$text attribute>{}bar</$text>baz</paragraph>\n\t\t//\n\t\tif ( position.isAtStart && this._hasSelectionAttribute ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// ENGAGE 2-SCM when about to leave one attribute value and enter another:\n\t\t//\n\t\t// \t\t<paragraph><$text attribute=\"1\">foo{}</$text><$text attribute=\"2\">bar</$text></paragraph>\n\t\t//\n\t\t// but DON'T when already in between of them (no attribute selection):\n\t\t//\n\t\t// \t\t<paragraph><$text attribute=\"1\">foo</$text>{}<$text attribute=\"2\">bar</$text></paragraph>\n\t\t//\n\t\tif ( isBetweenDifferentValues( position, attribute ) && this._hasSelectionAttribute ) {\n\t\t\tthis._preventCaretMovement( data );\n\t\t\tthis._removeSelectionAttribute();\n\n\t\t\treturn true;\n\t\t}\n\n\t\t// ENGAGE 2-SCM when entering an attribute:\n\t\t//\n\t\t// \t\t<paragraph>foo{}<$text attribute>bar</$text>baz</paragraph>\n\t\t//\n\t\tif ( isAtStartBoundary( position, attribute ) ) {\n\t\t\tthis._preventCaretMovement( data );\n\t\t\tthis._overrideGravity();\n\n\t\t\treturn true;\n\t\t}\n\n\t\t// ENGAGE 2-SCM when leaving an attribute:\n\t\t//\n\t\t//\t\t<paragraph>foo<$text attribute>bar{}</$text>baz</paragraph>\n\t\t//\n\t\tif ( isAtEndBoundary( position, attribute ) && this._hasSelectionAttribute ) {\n\t\t\tthis._preventCaretMovement( data );\n\t\t\tthis._overrideGravity();\n\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t/**\n\t * Updates the document selection and the view according to the two–step caret movement state\n\t * when moving **backwards**. Executed upon `keypress` in the {@link module:engine/view/view~View}.\n\t *\n\t * @param {module:engine/model/position~Position} position The model position at the moment of the key press.\n\t * @param {module:engine/view/observer/domeventdata~DomEventData} data Data of the key press.\n\t * @returns {Boolean} `true` when the handler prevented caret movement\n\t */\n\thandleBackwardMovement( position, data ) {\n\t\tconst attribute = this.attribute;\n\n\t\t// When the gravity is already overridden...\n\t\tif ( this._isGravityOverridden ) {\n\t\t\t// ENGAGE 2-SCM & REMOVE SELECTION ATTRIBUTE\n\t\t\t// when about to leave one attribute value and enter another:\n\t\t\t//\n\t\t\t// \t\t<paragraph><$text attribute=\"1\">foo</$text><$text attribute=\"2\">{}bar</$text></paragraph>\n\t\t\t//\n\t\t\t// but DON'T when already in between of them (no attribute selection):\n\t\t\t//\n\t\t\t// \t\t<paragraph><$text attribute=\"1\">foo</$text>{}<$text attribute=\"2\">bar</$text></paragraph>\n\t\t\t//\n\t\t\tif ( isBetweenDifferentValues( position, attribute ) && this._hasSelectionAttribute ) {\n\t\t\t\tthis._preventCaretMovement( data );\n\t\t\t\tthis._restoreGravity();\n\t\t\t\tthis._removeSelectionAttribute();\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// ENGAGE 2-SCM when at any boundary of the attribute:\n\t\t\t//\n\t\t\t// \t\t<paragraph>foo<$text attribute>bar</$text>{}baz</paragraph>\n\t\t\t// \t\t<paragraph>foo<$text attribute>{}bar</$text>baz</paragraph>\n\t\t\t//\n\t\t\telse {\n\t\t\t\tthis._preventCaretMovement( data );\n\t\t\t\tthis._restoreGravity();\n\n\t\t\t\t// REMOVE SELECTION ATRIBUTE at the beginning of the block.\n\t\t\t\t// It's like restoring gravity but towards a non-existent content when\n\t\t\t\t// the gravity is overridden:\n\t\t\t\t//\n\t\t\t\t// \t\t<paragraph><$text attribute>{}bar</$text></paragraph>\n\t\t\t\t//\n\t\t\t\t// becomes:\n\t\t\t\t//\n\t\t\t\t// \t\t<paragraph>{}<$text attribute>bar</$text></paragraph>\n\t\t\t\t//\n\t\t\t\tif ( position.isAtStart ) {\n\t\t\t\t\tthis._removeSelectionAttribute();\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} else {\n\t\t\t// ENGAGE 2-SCM when between two different attribute values but selection has no attribute:\n\t\t\t//\n\t\t\t// \t\t<paragraph><$text attribute=\"1\">foo</$text>{}<$text attribute=\"2\">bar</$text></paragraph>\n\t\t\t//\n\t\t\tif ( isBetweenDifferentValues( position, attribute ) && !this._hasSelectionAttribute ) {\n\t\t\t\tthis._preventCaretMovement( data );\n\t\t\t\tthis._setSelectionAttributeFromTheNodeBefore( position );\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// End of block boundary cases:\n\t\t\t//\n\t\t\t// \t\t<paragraph><$text attribute>bar{}</$text></paragraph>\n\t\t\t// \t\t<paragraph><$text attribute>bar</$text>{}</paragraph>\n\t\t\t//\n\t\t\tif ( position.isAtEnd && isAtEndBoundary( position, attribute ) ) {\n\t\t\t\t// DON'T ENGAGE 2-SCM if the selection has the attribute already.\n\t\t\t\t// This is a common selection if set using the mouse.\n\t\t\t\t//\n\t\t\t\t// \t\t<paragraph><$text attribute>bar{}</$text></paragraph>\n\t\t\t\t//\n\t\t\t\tif ( this._hasSelectionAttribute ) {\n\t\t\t\t\t// DON'T ENGAGE 2-SCM if the attribute at the end of the block which has length == 1.\n\t\t\t\t\t// Make sure the selection will not the attribute after it moves backwards.\n\t\t\t\t\t//\n\t\t\t\t\t// \t\t<paragraph>foo<$text attribute>b{}</$text></paragraph>\n\t\t\t\t\t//\n\t\t\t\t\tif ( isStepAfterTheAttributeBoundary( position, attribute ) ) {\n\t\t\t\t\t\t// Skip the automatic gravity restore upon the next selection#change:range event.\n\t\t\t\t\t\t// If not skipped, it would automatically restore the gravity, which should remain\n\t\t\t\t\t\t// overridden.\n\t\t\t\t\t\tthis._skipNextAutomaticGravityRestoration();\n\t\t\t\t\t\tthis._overrideGravity();\n\n\t\t\t\t\t\t// Don't return \"true\" here because we didn't call _preventCaretMovement.\n\t\t\t\t\t\t// Returning here will destabilize the filler logic, which also listens to\n\t\t\t\t\t\t// keydown (and the event would be stopped).\n\t\t\t\t\t}\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// ENGAGE 2-SCM if the selection has no attribute. This may happen when the user\n\t\t\t\t// left the attribute using a FORWARD 2-SCM.\n\t\t\t\t//\n\t\t\t\t// \t\t<paragraph><$text attribute>bar</$text>{}</paragraph>\n\t\t\t\t//\n\t\t\t\telse {\n\t\t\t\t\tthis._preventCaretMovement( data );\n\t\t\t\t\tthis._setSelectionAttributeFromTheNodeBefore( position );\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// REMOVE SELECTION ATRIBUTE when restoring gravity towards a non-existent content at the\n\t\t\t// beginning of the block.\n\t\t\t//\n\t\t\t// \t\t<paragraph>{}<$text attribute>bar</$text></paragraph>\n\t\t\t//\n\t\t\tif ( position.isAtStart ) {\n\t\t\t\tif ( this._hasSelectionAttribute ) {\n\t\t\t\t\tthis._removeSelectionAttribute();\n\t\t\t\t\tthis._preventCaretMovement( data );\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// DON'T ENGAGE 2-SCM when about to enter of leave an attribute.\n\t\t\t// We need to check if the caret is a one position before the attribute boundary:\n\t\t\t//\n\t\t\t// \t\t<paragraph>foo<$text attribute>b{}ar</$text>baz</paragraph>\n\t\t\t// \t\t<paragraph>foo<$text attribute>bar</$text>b{}az</paragraph>\n\t\t\t//\n\t\t\tif ( isStepAfterTheAttributeBoundary( position, attribute ) ) {\n\t\t\t\t// Skip the automatic gravity restore upon the next selection#change:range event.\n\t\t\t\t// If not skipped, it would automatically restore the gravity, which should remain\n\t\t\t\t// overridden.\n\t\t\t\tthis._skipNextAutomaticGravityRestoration();\n\t\t\t\tthis._overrideGravity();\n\n\t\t\t\t// Don't return \"true\" here because we didn't call _preventCaretMovement.\n\t\t\t\t// Returning here will destabilize the filler logic, which also listens to\n\t\t\t\t// keydown (and the event would be stopped).\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * `true` when the gravity is overridden for the {@link #attribute}.\n\t *\n\t * @readonly\n\t * @private\n\t * @type {Boolean}\n\t */\n\tget _isGravityOverridden() {\n\t\treturn !!this._overrideUid;\n\t}\n\n\t/**\n\t * `true` when the {@link module:engine/model/selection~Selection} has the {@link #attribute}.\n\t *\n\t * @readonly\n\t * @private\n\t * @type {Boolean}\n\t */\n\tget _hasSelectionAttribute() {\n\t\treturn this._modelSelection.hasAttribute( this.attribute );\n\t}\n\n\t/**\n\t * Overrides the gravity using the {@link module:engine/model/writer~Writer model writer}\n\t * and stores the information about this fact in the {@link #_overrideUid}.\n\t *\n\t * A shorthand for {@link module:engine/model/writer~Writer#overrideSelectionGravity}.\n\t *\n\t * @private\n\t */\n\t_overrideGravity() {\n\t\tthis._overrideUid = this.model.change( writer => writer.overrideSelectionGravity() );\n\t}\n\n\t/**\n\t * Restores the gravity using the {@link module:engine/model/writer~Writer model writer}.\n\t *\n\t * A shorthand for {@link module:engine/model/writer~Writer#restoreSelectionGravity}.\n\t *\n\t * @private\n\t */\n\t_restoreGravity() {\n\t\tthis.model.change( writer => {\n\t\t\twriter.restoreSelectionGravity( this._overrideUid );\n\t\t\tthis._overrideUid = null;\n\t\t} );\n\t}\n\n\t/**\n\t * Prevents the caret movement in the view by calling `preventDefault` on the event data.\n\t *\n\t * @private\n\t */\n\t_preventCaretMovement( data ) {\n\t\tdata.preventDefault();\n\t}\n\n\t/**\n\t * Removes the {@link #attribute} from the selection using using the\n\t * {@link module:engine/model/writer~Writer model writer}.\n\t *\n\t * @private\n\t */\n\t_removeSelectionAttribute() {\n\t\tthis.model.change( writer => {\n\t\t\twriter.removeSelectionAttribute( this.attribute );\n\t\t} );\n\t}\n\n\t/**\n\t * Applies the {@link #attribute} to the current selection using using the\n\t * value from the node before the current position. Uses\n\t * the {@link module:engine/model/writer~Writer model writer}.\n\t *\n\t * @private\n\t * @param {module:engine/model/position~Position} position\n\t */\n\t_setSelectionAttributeFromTheNodeBefore( position ) {\n\t\tconst attribute = this.attribute;\n\n\t\tthis.model.change( writer => {\n\t\t\twriter.setSelectionAttribute( this.attribute, position.nodeBefore.getAttribute( attribute ) );\n\t\t} );\n\t}\n\n\t/**\n\t * Skips the next automatic selection gravity restoration upon the\n\t * {@link module:engine/model/selection~Selection#event:change:range} event.\n\t *\n\t * See {@link #_isNextGravityRestorationSkipped}.\n\t *\n\t * @private\n\t */\n\t_skipNextAutomaticGravityRestoration() {\n\t\tthis._isNextGravityRestorationSkipped = true;\n\t}\n}\n\n// @param {module:engine/model/position~Position} position\n// @param {String} attribute\n// @returns {Boolean} `true` when position between the nodes sticks to the bound of text with given attribute.\nfunction isAtBoundary( position, attribute ) {\n\treturn isAtStartBoundary( position, attribute ) || isAtEndBoundary( position, attribute );\n}\n\n// @param {module:engine/model/position~Position} position\n// @param {String} attribute\nfunction isAtStartBoundary( position, attribute ) {\n\tconst { nodeBefore, nodeAfter } = position;\n\tconst isAttrBefore = nodeBefore ? nodeBefore.hasAttribute( attribute ) : false;\n\tconst isAttrAfter = nodeAfter ? nodeAfter.hasAttribute( attribute ) : false;\n\n\treturn isAttrAfter && ( !isAttrBefore || nodeBefore.getAttribute( attribute ) !== nodeAfter.getAttribute( attribute ) );\n}\n\n// @param {module:engine/model/position~Position} position\n// @param {String} attribute\nfunction isAtEndBoundary( position, attribute ) {\n\tconst { nodeBefore, nodeAfter } = position;\n\tconst isAttrBefore = nodeBefore ? nodeBefore.hasAttribute( attribute ) : false;\n\tconst isAttrAfter = nodeAfter ? nodeAfter.hasAttribute( attribute ) : false;\n\n\treturn isAttrBefore && ( !isAttrAfter || nodeBefore.getAttribute( attribute ) !== nodeAfter.getAttribute( attribute ) );\n}\n\n// @param {module:engine/model/position~Position} position\n// @param {String} attribute\nfunction isBetweenDifferentValues( position, attribute ) {\n\tconst { nodeBefore, nodeAfter } = position;\n\tconst isAttrBefore = nodeBefore ? nodeBefore.hasAttribute( attribute ) : false;\n\tconst isAttrAfter = nodeAfter ? nodeAfter.hasAttribute( attribute ) : false;\n\n\tif ( !isAttrAfter || !isAttrBefore ) {\n\t\treturn;\n\t}\n\n\treturn nodeAfter.getAttribute( attribute ) !== nodeBefore.getAttribute( attribute );\n}\n\n// @param {module:engine/model/position~Position} position\n// @param {String} attribute\nfunction isStepAfterTheAttributeBoundary( position, attribute ) {\n\treturn isAtBoundary( position.getShiftedBy( -1 ), attribute );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module link/linkediting\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport LinkCommand from './linkcommand';\nimport UnlinkCommand from './unlinkcommand';\nimport { createLinkElement, ensureSafeUrl } from './utils';\nimport bindTwoStepCaretToAttribute from '@ckeditor/ckeditor5-engine/src/utils/bindtwostepcarettoattribute';\nimport findLinkRange from './findlinkrange';\nimport '../theme/link.css';\n\nconst HIGHLIGHT_CLASS = 'ck-link_selected';\n\n/**\n * The link engine feature.\n *\n * It introduces the `linkHref=\"url\"` attribute in the model which renders to the view as a `<a href=\"url\">` element\n * as well as `'link'` and `'unlink'` commands.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class LinkEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\n\t\t// Allow link attribute on all inline nodes.\n\t\teditor.model.schema.extend( '$text', { allowAttributes: 'linkHref' } );\n\n\t\teditor.conversion.for( 'dataDowncast' )\n\t\t\t.attributeToElement( { model: 'linkHref', view: createLinkElement } );\n\n\t\teditor.conversion.for( 'editingDowncast' )\n\t\t\t.attributeToElement( { model: 'linkHref', view: ( href, writer ) => {\n\t\t\t\treturn createLinkElement( ensureSafeUrl( href ), writer );\n\t\t\t} } );\n\n\t\teditor.conversion.for( 'upcast' )\n\t\t\t.elementToAttribute( {\n\t\t\t\tview: {\n\t\t\t\t\tname: 'a',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\thref: true\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tmodel: {\n\t\t\t\t\tkey: 'linkHref',\n\t\t\t\t\tvalue: viewElement => viewElement.getAttribute( 'href' )\n\t\t\t\t}\n\t\t\t} );\n\n\t\t// Create linking commands.\n\t\teditor.commands.add( 'link', new LinkCommand( editor ) );\n\t\teditor.commands.add( 'unlink', new UnlinkCommand( editor ) );\n\n\t\t// Enable two-step caret movement for `linkHref` attribute.\n\t\tbindTwoStepCaretToAttribute( editor.editing.view, editor.model, this, 'linkHref' );\n\n\t\t// Setup highlight over selected link.\n\t\tthis._setupLinkHighlight();\n\t}\n\n\t/**\n\t * Adds a visual highlight style to a link in which the selection is anchored.\n\t * Together with two-step caret movement, they indicate that the user is typing inside the link.\n\t *\n\t * Highlight is turned on by adding `.ck-link_selected` class to the link in the view:\n\t *\n\t * * the class is removed before conversion has started, as callbacks added with `'highest'` priority\n\t * to {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} events,\n\t * * the class is added in the view post fixer, after other changes in the model tree were converted to the view.\n\t *\n\t * This way, adding and removing highlight does not interfere with conversion.\n\t *\n\t * @private\n\t */\n\t_setupLinkHighlight() {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst highlightedLinks = new Set();\n\n\t\t// Adding the class.\n\t\tview.document.registerPostFixer( writer => {\n\t\t\tconst selection = editor.model.document.selection;\n\n\t\t\tif ( selection.hasAttribute( 'linkHref' ) ) {\n\t\t\t\tconst modelRange = findLinkRange( selection.getFirstPosition(), selection.getAttribute( 'linkHref' ), editor.model );\n\t\t\t\tconst viewRange = editor.editing.mapper.toViewRange( modelRange );\n\n\t\t\t\t// There might be multiple `a` elements in the `viewRange`, for example, when the `a` element is\n\t\t\t\t// broken by a UIElement.\n\t\t\t\tfor ( const item of viewRange.getItems() ) {\n\t\t\t\t\tif ( item.is( 'a' ) ) {\n\t\t\t\t\t\twriter.addClass( HIGHLIGHT_CLASS, item );\n\t\t\t\t\t\thighlightedLinks.add( item );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Removing the class.\n\t\teditor.conversion.for( 'editingDowncast' ).add( dispatcher => {\n\t\t\t// Make sure the highlight is removed on every possible event, before conversion is started.\n\t\t\tdispatcher.on( 'insert', removeHighlight, { priority: 'highest' } );\n\t\t\tdispatcher.on( 'remove', removeHighlight, { priority: 'highest' } );\n\t\t\tdispatcher.on( 'attribute', removeHighlight, { priority: 'highest' } );\n\t\t\tdispatcher.on( 'selection', removeHighlight, { priority: 'highest' } );\n\n\t\t\tfunction removeHighlight() {\n\t\t\t\tview.change( writer => {\n\t\t\t\t\tfor ( const item of highlightedLinks.values() ) {\n\t\t\t\t\t\twriter.removeClass( HIGHLIGHT_CLASS, item );\n\t\t\t\t\t\thighlightedLinks.delete( item );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t}\n}\n","\n/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module engine/view/observer/clickobserver\n */\n\nimport DomEventObserver from './domeventobserver';\n\n/**\n * {@link module:engine/view/document~Document#event:click Click} event observer.\n *\n * Note that this observer is not available by default. To make it available it needs to be added to\n * {@link module:engine/view/view~View view controller}\n * by a {@link module:engine/view/view~View#addObserver} method.\n *\n * @extends module:engine/view/observer/domeventobserver~DomEventObserver\n */\nexport default class ClickObserver extends DomEventObserver {\n\tconstructor( view ) {\n\t\tsuper( view );\n\n\t\tthis.domEventType = 'click';\n\t}\n\n\tonDomEvent( domEvent ) {\n\t\tthis.fire( domEvent.type, domEvent );\n\t}\n}\n\n/**\n * Fired when one of the editables has been clicked.\n *\n * Introduced by {@link module:engine/view/observer/clickobserver~ClickObserver}.\n *\n * Note that this event is not available by default. To make it available\n * {@link module:engine/view/observer/clickobserver~ClickObserver} needs to be added\n * to {@link module:engine/view/view~View} by a {@link module:engine/view/view~View#addObserver} method.\n *\n * @see module:engine/view/observer/clickobserver~ClickObserver\n * @event module:engine/view/document~Document#event:click\n * @param {module:engine/view/observer/domeventdata~DomEventData} data Event data.\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module link/ui/linkformview\n */\nimport View from '@ckeditor/ckeditor5-ui/src/view';\nimport ViewCollection from '@ckeditor/ckeditor5-ui/src/viewcollection';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport LabeledInputView from '@ckeditor/ckeditor5-ui/src/labeledinput/labeledinputview';\nimport InputTextView from '@ckeditor/ckeditor5-ui/src/inputtext/inputtextview';\nimport submitHandler from '@ckeditor/ckeditor5-ui/src/bindings/submithandler';\nimport FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';\nimport FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler';\nimport KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';\nimport checkIcon from '@ckeditor/ckeditor5-core/theme/icons/check.svg';\nimport cancelIcon from '@ckeditor/ckeditor5-core/theme/icons/cancel.svg';\nimport '../../theme/linkform.css';\n/**\n * The link form view controller class.\n *\n * See {@link module:link/ui/linkformview~LinkFormView}.\n *\n * @extends module:ui/view~View\n */\nexport default class LinkFormView extends View {\n /**\n\t * @inheritDoc\n\t */\n constructor(locale) {\n super(locale);\n const t = locale.t;\n /**\n\t\t * Tracks information about DOM focus in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/focustracker~FocusTracker}\n\t\t */\n this.focusTracker = new FocusTracker();\n /**\n\t\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/keystrokehandler~KeystrokeHandler}\n\t\t */\n this.keystrokes = new KeystrokeHandler();\n /**\n\t\t * The URL input view.\n\t\t *\n\t\t * @member {module:ui/labeledinput/labeledinputview~LabeledInputView}\n\t\t */\n this.urlInputView = this._createUrlInput();\n /**\n\t\t * The Save button view.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView}\n\t\t */\n this.saveButtonView = this._createButton(t('az'), checkIcon, 'ck-button-save');\n this.saveButtonView.type = 'submit';\n /**\n\t\t * The Cancel button view.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView}\n\t\t */\n this.cancelButtonView = this._createButton(t('ba'), cancelIcon, 'ck-button-cancel', 'cancel');\n /**\n\t\t * A collection of views which can be focused in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n this._focusables = new ViewCollection();\n /**\n\t\t * Helps cycling over {@link #_focusables} in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/focuscycler~FocusCycler}\n\t\t */\n this._focusCycler = new FocusCycler({\n focusables: this._focusables,\n focusTracker: this.focusTracker,\n keystrokeHandler: this.keystrokes,\n actions: {\n // Navigate form fields backwards using the Shift + Tab keystroke.\n focusPrevious: 'shift + tab',\n // Navigate form fields forwards using the Tab key.\n focusNext: 'tab'\n }\n });\n this.setTemplate({\n tag: 'form',\n attributes: {\n class: [\n 'ck',\n 'ck-link-form'\n ],\n // https://github.com/ckeditor/ckeditor5-link/issues/90\n tabindex: '-1'\n },\n children: [\n this.urlInputView,\n this.saveButtonView,\n this.cancelButtonView\n ]\n });\n }\n /**\n\t * @inheritDoc\n\t */\n render() {\n super.render();\n submitHandler({ view: this });\n const childViews = [\n this.urlInputView,\n this.saveButtonView,\n this.cancelButtonView\n ];\n childViews.forEach(v => {\n // Register the view as focusable.\n this._focusables.add(v);\n // Register the view in the focus tracker.\n this.focusTracker.add(v.element);\n });\n // Start listening for the keystrokes coming from #element.\n this.keystrokes.listenTo(this.element);\n }\n /**\n\t * Focuses the fist {@link #_focusables} in the form.\n\t */\n focus() {\n this._focusCycler.focusFirst();\n }\n /**\n\t * Creates a labeled input view.\n\t *\n\t * @private\n\t * @returns {module:ui/labeledinput/labeledinputview~LabeledInputView} Labeled input view instance.\n\t */\n _createUrlInput() {\n const t = this.locale.t;\n const labeledInput = new LabeledInputView(this.locale, InputTextView);\n labeledInput.label = t('bb');\n labeledInput.inputView.placeholder = 'https://example.com';\n return labeledInput;\n }\n /**\n\t * Creates a button view.\n\t *\n\t * @private\n\t * @param {String} label The button label.\n\t * @param {String} icon The button's icon.\n\t * @param {String} className The additional button CSS class name.\n\t * @param {String} [eventName] An event name that the `ButtonView#execute` event will be delegated to.\n\t * @returns {module:ui/button/buttonview~ButtonView} The button view instance.\n\t */\n _createButton(label, icon, className, eventName) {\n const button = new ButtonView(this.locale);\n button.set({\n label,\n icon,\n tooltip: true\n });\n button.extendTemplate({ attributes: { class: className } });\n if (eventName) {\n button.delegate('execute').to(this, eventName);\n }\n return button;\n }\n} /**\n * Fired when the form view is submitted (when one of the children triggered the submit event),\n * e.g. click on {@link #saveButtonView}.\n *\n * @event submit\n */\n /**\n * Fired when the form view is canceled, e.g. click on {@link #cancelButtonView}.\n *\n * @event cancel\n */","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module link/ui/linkactionsview\n */\nimport View from '@ckeditor/ckeditor5-ui/src/view';\nimport ViewCollection from '@ckeditor/ckeditor5-ui/src/viewcollection';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';\nimport FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler';\nimport KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';\nimport { ensureSafeUrl } from '../utils';\nimport unlinkIcon from '../../theme/icons/unlink.svg';\nimport pencilIcon from '@ckeditor/ckeditor5-core/theme/icons/pencil.svg';\nimport '../../theme/linkactions.css';\n/**\n * The link actions view class. This view displays link preview, allows\n * unlinking or editing the link.\n *\n * @extends module:ui/view~View\n */\nexport default class LinkActionsView extends View {\n /**\n\t * @inheritDoc\n\t */\n constructor(locale) {\n super(locale);\n const t = locale.t;\n /**\n\t\t * Tracks information about DOM focus in the actions.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/focustracker~FocusTracker}\n\t\t */\n this.focusTracker = new FocusTracker();\n /**\n\t\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/keystrokehandler~KeystrokeHandler}\n\t\t */\n this.keystrokes = new KeystrokeHandler();\n /**\n\t\t * The href preview view.\n\t\t *\n\t\t * @member {module:ui/view~View}\n\t\t */\n this.previewButtonView = this._createPreviewButton();\n /**\n\t\t * The unlink button view.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView}\n\t\t */\n this.unlinkButtonView = this._createButton(t('bc'), unlinkIcon, 'unlink');\n /**\n\t\t * The edit link button view.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView}\n\t\t */\n this.editButtonView = this._createButton(t('bd'), pencilIcon, 'edit');\n /**\n\t\t * Value of the \"href\" attribute of the link to use in the {@link #previewButtonView}.\n\t\t *\n\t\t * @observable\n\t\t * @member {String}\n\t\t */\n this.set('href');\n /**\n\t\t * A collection of views which can be focused in the view.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n this._focusables = new ViewCollection();\n /**\n\t\t * Helps cycling over {@link #_focusables} in the view.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/focuscycler~FocusCycler}\n\t\t */\n this._focusCycler = new FocusCycler({\n focusables: this._focusables,\n focusTracker: this.focusTracker,\n keystrokeHandler: this.keystrokes,\n actions: {\n // Navigate fields backwards using the Shift + Tab keystroke.\n focusPrevious: 'shift + tab',\n // Navigate fields forwards using the Tab key.\n focusNext: 'tab'\n }\n });\n this.setTemplate({\n tag: 'div',\n attributes: {\n class: [\n 'ck',\n 'ck-link-actions'\n ],\n // https://github.com/ckeditor/ckeditor5-link/issues/90\n tabindex: '-1'\n },\n children: [\n this.previewButtonView,\n this.editButtonView,\n this.unlinkButtonView\n ]\n });\n }\n /**\n\t * @inheritDoc\n\t */\n render() {\n super.render();\n const childViews = [\n this.previewButtonView,\n this.editButtonView,\n this.unlinkButtonView\n ];\n childViews.forEach(v => {\n // Register the view as focusable.\n this._focusables.add(v);\n // Register the view in the focus tracker.\n this.focusTracker.add(v.element);\n });\n // Start listening for the keystrokes coming from #element.\n this.keystrokes.listenTo(this.element);\n }\n /**\n\t * Focuses the fist {@link #_focusables} in the actions.\n\t */\n focus() {\n this._focusCycler.focusFirst();\n }\n /**\n\t * Creates a button view.\n\t *\n\t * @private\n\t * @param {String} label The button label.\n\t * @param {String} icon The button's icon.\n\t * @param {String} [eventName] An event name that the `ButtonView#execute` event will be delegated to.\n\t * @returns {module:ui/button/buttonview~ButtonView} The button view instance.\n\t */\n _createButton(label, icon, eventName) {\n const button = new ButtonView(this.locale);\n button.set({\n label,\n icon,\n tooltip: true\n });\n button.delegate('execute').to(this, eventName);\n return button;\n }\n /**\n\t * Creates a link href preview button.\n\t *\n\t * @private\n\t * @returns {module:ui/button/buttonview~ButtonView} The button view instance.\n\t */\n _createPreviewButton() {\n const button = new ButtonView(this.locale);\n const bind = this.bindTemplate;\n const t = this.t;\n button.set({\n withText: true,\n tooltip: t('be')\n });\n button.extendTemplate({\n attributes: {\n class: [\n 'ck',\n 'ck-link-actions__preview'\n ],\n href: bind.to('href', href => href && ensureSafeUrl(href)),\n target: '_blank'\n }\n });\n button.bind('label').to(this, 'href', href => {\n return href || t('bf');\n });\n button.bind('isEnabled').to(this, 'href', href => !!href);\n button.template.tag = 'a';\n button.template.eventListeners = {};\n return button;\n }\n} /**\n * Fired when the {@link #editButtonView} is clicked.\n *\n * @event edit\n */\n /**\n * Fired when the {@link #unlinkButtonView} is clicked.\n *\n * @event unlink\n */","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module link/linkui\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ClickObserver from '@ckeditor/ckeditor5-engine/src/view/observer/clickobserver';\nimport { isLinkElement } from './utils';\nimport ContextualBalloon from '@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon';\nimport clickOutsideHandler from '@ckeditor/ckeditor5-ui/src/bindings/clickoutsidehandler';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport LinkFormView from './ui/linkformview';\nimport LinkActionsView from './ui/linkactionsview';\nimport linkIcon from '../theme/icons/link.svg';\nconst linkKeystroke = 'Ctrl+K';\n/**\n * The link UI plugin. It introduces the `'link'` and `'unlink'` buttons and support for the <kbd>Ctrl+K</kbd> keystroke.\n *\n * It uses the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class LinkUI extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n static get requires() {\n return [ContextualBalloon];\n }\n /**\n\t * @inheritDoc\n\t */\n static get pluginName() {\n return 'LinkUI';\n }\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n editor.editing.view.addObserver(ClickObserver);\n /**\n\t\t * The actions view displayed inside of the balloon.\n\t\t *\n\t\t * @member {module:link/ui/linkactionsview~LinkActionsView}\n\t\t */\n this.actionsView = this._createActionsView();\n /**\n\t\t * The form view displayed inside the balloon.\n\t\t *\n\t\t * @member {module:link/ui/linkformview~LinkFormView}\n\t\t */\n this.formView = this._createFormView();\n /**\n\t\t * The contextual balloon plugin instance.\n\t\t *\n\t\t * @private\n\t\t * @member {module:ui/panel/balloon/contextualballoon~ContextualBalloon}\n\t\t */\n this._balloon = editor.plugins.get(ContextualBalloon);\n // Create toolbar buttons.\n this._createToolbarLinkButton();\n // Attach lifecycle actions to the the balloon.\n this._enableUserBalloonInteractions();\n }\n /**\n\t * @inheritDoc\n\t */\n destroy() {\n super.destroy();\n // Destroy created UI components as they are not automatically destroyed (see ckeditor5#1341).\n this.formView.destroy();\n }\n /**\n\t * Creates the {@link module:link/ui/linkactionsview~LinkActionsView} instance.\n\t *\n\t * @private\n\t * @returns {module:link/ui/linkactionsview~LinkActionsView} The link actions view instance.\n\t */\n _createActionsView() {\n const editor = this.editor;\n const actionsView = new LinkActionsView(editor.locale);\n const linkCommand = editor.commands.get('link');\n const unlinkCommand = editor.commands.get('unlink');\n actionsView.bind('href').to(linkCommand, 'value');\n actionsView.editButtonView.bind('isEnabled').to(linkCommand);\n actionsView.unlinkButtonView.bind('isEnabled').to(unlinkCommand);\n // Execute unlink command after clicking on the \"Edit\" button.\n this.listenTo(actionsView, 'edit', () => {\n this._addFormView();\n });\n // Execute unlink command after clicking on the \"Unlink\" button.\n this.listenTo(actionsView, 'unlink', () => {\n editor.execute('unlink');\n this._hideUI();\n });\n // Close the panel on esc key press when the **actions have focus**.\n actionsView.keystrokes.set('Esc', (data, cancel) => {\n this._hideUI();\n cancel();\n });\n // Open the form view on Ctrl+K when the **actions have focus**..\n actionsView.keystrokes.set(linkKeystroke, (data, cancel) => {\n this._addFormView();\n cancel();\n });\n return actionsView;\n }\n /**\n\t * Creates the {@link module:link/ui/linkformview~LinkFormView} instance.\n\t *\n\t * @private\n\t * @returns {module:link/ui/linkformview~LinkFormView} The link form instance.\n\t */\n _createFormView() {\n const editor = this.editor;\n const formView = new LinkFormView(editor.locale);\n const linkCommand = editor.commands.get('link');\n formView.urlInputView.bind('value').to(linkCommand, 'value');\n // Form elements should be read-only when corresponding commands are disabled.\n formView.urlInputView.bind('isReadOnly').to(linkCommand, 'isEnabled', value => !value);\n formView.saveButtonView.bind('isEnabled').to(linkCommand);\n // Execute link command after clicking the \"Save\" button.\n this.listenTo(formView, 'submit', () => {\n editor.execute('link', formView.urlInputView.inputView.element.value);\n this._removeFormView();\n });\n // Hide the panel after clicking the \"Cancel\" button.\n this.listenTo(formView, 'cancel', () => {\n this._removeFormView();\n });\n // Close the panel on esc key press when the **form has focus**.\n formView.keystrokes.set('Esc', (data, cancel) => {\n this._removeFormView();\n cancel();\n });\n return formView;\n }\n /**\n\t * Creates a toolbar Link button. Clicking this button will show\n\t * a {@link #_balloon} attached to the selection.\n\t *\n\t * @private\n\t */\n _createToolbarLinkButton() {\n const editor = this.editor;\n const linkCommand = editor.commands.get('link');\n const t = editor.t;\n // Handle the `Ctrl+K` keystroke and show the panel.\n editor.keystrokes.set(linkKeystroke, (keyEvtData, cancel) => {\n // Prevent focusing the search bar in FF and opening new tab in Edge. #153, #154.\n cancel();\n if (linkCommand.isEnabled) {\n this._showUI();\n }\n });\n editor.ui.componentFactory.add('link', locale => {\n const button = new ButtonView(locale);\n button.isEnabled = true;\n button.label = t('ak');\n button.icon = linkIcon;\n button.keystroke = linkKeystroke;\n button.tooltip = true;\n // Bind button to the command.\n button.bind('isOn', 'isEnabled').to(linkCommand, 'value', 'isEnabled');\n // Show the panel on button click.\n this.listenTo(button, 'execute', () => this._showUI());\n return button;\n });\n }\n /**\n\t * Attaches actions that control whether the balloon panel containing the\n\t * {@link #formView} is visible or not.\n\t *\n\t * @private\n\t */\n _enableUserBalloonInteractions() {\n const viewDocument = this.editor.editing.view.document;\n // Handle click on view document and show panel when selection is placed inside the link element.\n // Keep panel open until selection will be inside the same link element.\n this.listenTo(viewDocument, 'click', () => {\n const parentLink = this._getSelectedLinkElement();\n if (parentLink) {\n // Then show panel but keep focus inside editor editable.\n this._showUI();\n }\n });\n // Focus the form if the balloon is visible and the Tab key has been pressed.\n this.editor.keystrokes.set('Tab', (data, cancel) => {\n if (this._areActionsVisible && !this.actionsView.focusTracker.isFocused) {\n this.actionsView.focus();\n cancel();\n }\n }, {\n // Use the high priority because the link UI navigation is more important\n // than other feature's actions, e.g. list indentation.\n // https://github.com/ckeditor/ckeditor5-link/issues/146\n priority: 'high'\n });\n // Close the panel on the Esc key press when the editable has focus and the balloon is visible.\n this.editor.keystrokes.set('Esc', (data, cancel) => {\n if (this._isUIVisible) {\n this._hideUI();\n cancel();\n }\n });\n // Close on click outside of balloon panel element.\n clickOutsideHandler({\n emitter: this.formView,\n activator: () => this._isUIVisible,\n contextElements: [this._balloon.view.element],\n callback: () => this._hideUI()\n });\n }\n /**\n\t * Adds the {@link #actionsView} to the {@link #_balloon}.\n\t *\n\t * @protected\n\t */\n _addActionsView() {\n if (this._areActionsInPanel) {\n return;\n }\n this._balloon.add({\n view: this.actionsView,\n position: this._getBalloonPositionData()\n });\n }\n /**\n\t * Adds the {@link #formView} to the {@link #_balloon}.\n\t *\n\t * @protected\n\t */\n _addFormView() {\n if (this._isFormInPanel) {\n return;\n }\n const editor = this.editor;\n const linkCommand = editor.commands.get('link');\n this._balloon.add({\n view: this.formView,\n position: this._getBalloonPositionData()\n });\n this.formView.urlInputView.select();\n // Make sure that each time the panel shows up, the URL field remains in sync with the value of\n // the command. If the user typed in the input, then canceled the balloon (`urlInputView#value` stays\n // unaltered) and re-opened it without changing the value of the link command (e.g. because they\n // clicked the same link), they would see the old value instead of the actual value of the command.\n // https://github.com/ckeditor/ckeditor5-link/issues/78\n // https://github.com/ckeditor/ckeditor5-link/issues/123\n this.formView.urlInputView.inputView.element.value = linkCommand.value || '';\n }\n /**\n\t * Removes the {@link #formView} from the {@link #_balloon}.\n\t *\n\t * @protected\n\t */\n _removeFormView() {\n if (this._isFormInPanel) {\n // Blur the input element before removing it from DOM to prevent issues in some browsers.\n // See https://github.com/ckeditor/ckeditor5/issues/1501.\n this.formView.saveButtonView.focus();\n this._balloon.remove(this.formView);\n // Because the form has an input which has focus, the focus must be brought back\n // to the editor. Otherwise, it would be lost.\n this.editor.editing.view.focus();\n }\n }\n /**\n\t * Shows the right kind of the UI for current state of the command. It's either\n\t * {@link #formView} or {@link #actionsView}.\n\t *\n\t * @private\n\t */\n _showUI() {\n const editor = this.editor;\n const linkCommand = editor.commands.get('link');\n if (!linkCommand.isEnabled) {\n return;\n }\n // When there's no link under the selection, go straight to the editing UI.\n if (!this._getSelectedLinkElement()) {\n this._addActionsView();\n this._addFormView();\n } // If theres a link under the selection...\n else {\n // Go to the editing UI if actions are already visible.\n if (this._areActionsVisible) {\n this._addFormView();\n } // Otherwise display just the actions UI.\n else {\n this._addActionsView();\n }\n }\n // Begin responding to ui#update once the UI is added.\n this._startUpdatingUI();\n }\n /**\n\t * Removes the {@link #formView} from the {@link #_balloon}.\n\t *\n\t * See {@link #_addFormView}, {@link #_addActionsView}.\n\t *\n\t * @protected\n\t */\n _hideUI() {\n if (!this._isUIInPanel) {\n return;\n }\n const editor = this.editor;\n this.stopListening(editor.ui, 'update');\n // Make sure the focus always gets back to the editable _before_ removing the focused form view.\n // Doing otherwise causes issues in some browsers. See https://github.com/ckeditor/ckeditor5-link/issues/193.\n editor.editing.view.focus();\n // Remove form first because it's on top of the stack.\n this._removeFormView();\n // Then remove the actions view because it's beneath the form.\n this._balloon.remove(this.actionsView);\n }\n /**\n\t * Makes the UI react to the {@link module:core/editor/editorui~EditorUI#event:update} event to\n\t * reposition itself when the editor ui should be refreshed.\n\t *\n\t * See: {@link #_hideUI} to learn when the UI stops reacting to the `update` event.\n\t *\n\t * @protected\n\t */\n _startUpdatingUI() {\n const editor = this.editor;\n const viewDocument = editor.editing.view.document;\n let prevSelectedLink = this._getSelectedLinkElement();\n let prevSelectionParent = getSelectionParent();\n this.listenTo(editor.ui, 'update', () => {\n const selectedLink = this._getSelectedLinkElement();\n const selectionParent = getSelectionParent();\n // Hide the panel if:\n //\n // * the selection went out of the EXISTING link element. E.g. user moved the caret out\n // of the link,\n // * the selection went to a different parent when creating a NEW link. E.g. someone\n // else modified the document.\n // * the selection has expanded (e.g. displaying link actions then pressing SHIFT+Right arrow).\n //\n // Note: #_getSelectedLinkElement will return a link for a non-collapsed selection only\n // when fully selected.\n if (prevSelectedLink && !selectedLink || !prevSelectedLink && selectionParent !== prevSelectionParent) {\n this._hideUI();\n } // Update the position of the panel when:\n // * the selection remains in the original link element,\n // * there was no link element in the first place, i.e. creating a new link\n else {\n // If still in a link element, simply update the position of the balloon.\n // If there was no link (e.g. inserting one), the balloon must be moved\n // to the new position in the editing view (a new native DOM range).\n this._balloon.updatePosition(this._getBalloonPositionData());\n }\n prevSelectedLink = selectedLink;\n prevSelectionParent = selectionParent;\n });\n function getSelectionParent() {\n return viewDocument.selection.focus.getAncestors().reverse().find(node => node.is('element'));\n }\n }\n /**\n\t * Returns true when {@link #formView} is in the {@link #_balloon}.\n\t *\n\t * @readonly\n\t * @protected\n\t * @type {Boolean}\n\t */\n get _isFormInPanel() {\n return this._balloon.hasView(this.formView);\n }\n /**\n\t * Returns true when {@link #actionsView} is in the {@link #_balloon}.\n\t *\n\t * @readonly\n\t * @protected\n\t * @type {Boolean}\n\t */\n get _areActionsInPanel() {\n return this._balloon.hasView(this.actionsView);\n }\n /**\n\t * Returns true when {@link #actionsView} is in the {@link #_balloon} and it is\n\t * currently visible.\n\t *\n\t * @readonly\n\t * @protected\n\t * @type {Boolean}\n\t */\n get _areActionsVisible() {\n return this._balloon.visibleView === this.actionsView;\n }\n /**\n\t * Returns true when {@link #actionsView} or {@link #formView} is in the {@link #_balloon}.\n\t *\n\t * @readonly\n\t * @protected\n\t * @type {Boolean}\n\t */\n get _isUIInPanel() {\n return this._isFormInPanel || this._areActionsInPanel;\n }\n /**\n\t * Returns true when {@link #actionsView} or {@link #formView} is in the {@link #_balloon} and it is\n\t * currently visible.\n\t *\n\t * @readonly\n\t * @protected\n\t * @type {Boolean}\n\t */\n get _isUIVisible() {\n const visibleView = this._balloon.visibleView;\n return visibleView == this.formView || this._areActionsVisible;\n }\n /**\n\t * Returns positioning options for the {@link #_balloon}. They control the way the balloon is attached\n\t * to the target element or selection.\n\t *\n\t * If the selection is collapsed and inside a link element, the panel will be attached to the\n\t * entire link element. Otherwise, it will be attached to the selection.\n\t *\n\t * @private\n\t * @returns {module:utils/dom/position~Options}\n\t */\n _getBalloonPositionData() {\n const view = this.editor.editing.view;\n const viewDocument = view.document;\n const targetLink = this._getSelectedLinkElement();\n const target = targetLink ? // When selection is inside link element, then attach panel to this element.\n view.domConverter.mapViewToDom(targetLink) : // Otherwise attach panel to the selection.\n view.domConverter.viewRangeToDom(viewDocument.selection.getFirstRange());\n return { target };\n }\n /**\n\t * Returns the link {@link module:engine/view/attributeelement~AttributeElement} under\n\t * the {@link module:engine/view/document~Document editing view's} selection or `null`\n\t * if there is none.\n\t *\n\t * **Note**: For a non–collapsed selection the link element is only returned when **fully**\n\t * selected and the **only** element within the selection boundaries.\n\t *\n\t * @private\n\t * @returns {module:engine/view/attributeelement~AttributeElement|null}\n\t */\n _getSelectedLinkElement() {\n const view = this.editor.editing.view;\n const selection = view.document.selection;\n if (selection.isCollapsed) {\n return findLinkElementAncestor(selection.getFirstPosition());\n } else {\n // The range for fully selected link is usually anchored in adjacent text nodes.\n // Trim it to get closer to the actual link element.\n const range = selection.getFirstRange().getTrimmed();\n const startLink = findLinkElementAncestor(range.start);\n const endLink = findLinkElementAncestor(range.end);\n if (!startLink || startLink != endLink) {\n return null;\n }\n // Check if the link element is fully selected.\n if (view.createRangeIn(startLink).getTrimmed().isEqual(range)) {\n return startLink;\n } else {\n return null;\n }\n }\n }\n}\n// Returns a link element if there's one among the ancestors of the provided `Position`.\n//\n// @private\n// @param {module:engine/view/position~Position} View position to analyze.\n// @returns {module:engine/view/attributeelement~AttributeElement|null} Link element at the position or null.\nfunction findLinkElementAncestor(position) {\n return position.getAncestors().find(ancestor => isLinkElement(ancestor));\n}","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/command\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor commands.\n *\n * Commands are the main way to manipulate editor contents and state. They are mostly used by UI elements (or by other\n * commands) to make changes in the model. Commands are available in every part of code that has access to\n * the {@link module:core/editor/editor~Editor editor} instance.\n *\n * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n *\n * By default commands are disabled when the editor is in {@link module:core/editor/editor~Editor#isReadOnly read-only} mode.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Command {\n\t/**\n\t * Creates a new `Command` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor Editor on which this command will be used.\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor on which this command will be used.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * The value of the command. A concrete command class should define what it represents for it.\n\t\t *\n\t\t * For example, the `'bold'` command's value indicates whether the selection starts in a bolded text.\n\t\t * And the value of the `'link'` command may be an object with links details.\n\t\t *\n\t\t * It is possible for a command to have no value (e.g. for stateless actions such as `'imageUpload'`).\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member #value\n\t\t */\n\t\tthis.set( 'value', undefined );\n\n\t\t/**\n\t\t * Flag indicating whether a command is enabled or disabled.\n\t\t * A disabled command will do nothing when executed.\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * It is possible to disable a command from \"outside\". For instance, in your integration you may want to disable\n\t\t * a certain set of commands for the time being. To do that, you can use the fact that `isEnabled` is observable\n\t\t * and it fires the `set:isEnabled` event every time anyone tries to modify its value:\n\t\t *\n\t\t *\t\tfunction disableCommand( cmd ) {\n\t\t *\t\t\tcmd.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t *\n\t\t *\t\t\tcmd.isEnabled = false;\n\t\t *\n\t\t *\t\t\t// Make it possible to enable the command again.\n\t\t *\t\t\treturn () => {\n\t\t *\t\t\t\tcmd.off( 'set:isEnabled', forceDisable );\n\t\t *\t\t\t\tcmd.refresh();\n\t\t *\t\t\t};\n\t\t *\n\t\t *\t\t\tfunction forceDisable( evt ) {\n\t\t *\t\t\t\tevt.return = false;\n\t\t *\t\t\t\tevt.stop();\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\n\t\t *\t\t// Usage:\n\t\t *\n\t\t *\t\t// Disabling the command.\n\t\t *\t\tconst enableBold = disableCommand( editor.commands.get( 'bold' ) );\n\t\t *\n\t\t *\t\t// Enabling the command again.\n\t\t *\t\tenableBold();\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\t\tthis.set( 'isEnabled', false );\n\n\t\t/**\n\t\t * Holds identifiers for {@link #forceDisabled} mechanism.\n\t\t *\n\t\t * @type {Set.<String>}\n\t\t * @private\n\t\t */\n\t\tthis._disableStack = new Set();\n\n\t\tthis.decorate( 'execute' );\n\n\t\t// By default every command is refreshed when changes are applied to the model.\n\t\tthis.listenTo( this.editor.model.document, 'change', () => {\n\t\t\tthis.refresh();\n\t\t} );\n\n\t\tthis.on( 'execute', evt => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// By default commands are disabled when the editor is in read-only mode.\n\t\tthis.listenTo( editor, 'change:isReadOnly', ( evt, name, value ) => {\n\t\t\tif ( value ) {\n\t\t\t\tthis.forceDisabled( 'readOnlyMode' );\n\t\t\t} else {\n\t\t\t\tthis.clearForceDisabled( 'readOnlyMode' );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties\n\t * in this method.\n\t *\n\t * This method is automatically called when\n\t * {@link module:engine/model/document~Document#event:change any changes are applied to the document}.\n\t */\n\trefresh() {\n\t\tthis.isEnabled = true;\n\t}\n\n\t/**\n\t * Disables the command.\n\t *\n\t * Command may be disabled by multiple features or algorithms (at once). When disabling a command, unique id should be passed\n\t * (e.g. feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the command.\n\t * The command becomes enabled only after all features {@link #clearForceDisabled enabled it back}.\n\t *\n\t * Disabling and enabling a command:\n\t *\n\t *\t\tcommand.isEnabled; // -> true\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Command disabled by multiple features:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'OtherFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'OtherFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Multiple disabling with the same identifier is redundant:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * **Note:** some commands or algorithms may have more complex logic when it comes to enabling or disabling certain commands,\n\t * so the command might be still disabled after {@link #clearForceDisabled} was used.\n\t *\n\t * @param {String} id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the command.\n\t */\n\tforceDisabled( id ) {\n\t\tthis._disableStack.add( id );\n\n\t\tif ( this._disableStack.size == 1 ) {\n\t\t\tthis.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * Clears forced disable previously set through {@link #clearForceDisabled}. See {@link #clearForceDisabled}.\n\t *\n\t * @param {String} id Unique identifier, equal to the one passed in {@link #forceDisabled} call.\n\t */\n\tclearForceDisabled( id ) {\n\t\tthis._disableStack.delete( id );\n\n\t\tif ( this._disableStack.size == 0 ) {\n\t\t\tthis.off( 'set:isEnabled', forceDisable );\n\t\t\tthis.refresh();\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`}\n\t * to the command.\n\t *\n\t * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`).\n\t * This behavior is implemented by a high priority listener to the {@link #event:execute} event.\n\t *\n\t * In order to see how to disable a command from \"outside\" see the {@link #isEnabled} documentation.\n\t *\n\t * @fires execute\n\t */\n\texecute() {}\n\n\t/**\n\t * Destroys the command.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Event fired by the {@link #execute} method. The command action is a listener to this event so it's\n\t * possible to change/cancel the behavior of the command by listening to this event.\n\t *\n\t * See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples.\n\t *\n\t * **Note:** This event is fired even if command is disabled. However, it is automatically blocked\n\t * by a high priority listener in order to prevent command execution.\n\t *\n\t * @event execute\n\t */\n}\n\nmix( Command, ObservableMixin );\n\n// Helper function that forces command to be disabled.\nfunction forceDisable( evt ) {\n\tevt.return = false;\n\tevt.stop();\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module list/listcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport first from '@ckeditor/ckeditor5-utils/src/first';\n\n/**\n * The list command. It is used by the {@link module:list/list~List list feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class ListCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {'numbered'|'bulleted'} type List type that will be handled by this command.\n\t */\n\tconstructor( editor, type ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The type of the list created by the command.\n\t\t *\n\t\t * @readonly\n\t\t * @member {'numbered'|'bulleted'}\n\t\t */\n\t\tthis.type = type == 'bulleted' ? 'bulleted' : 'numbered';\n\n\t\t/**\n\t\t * A flag indicating whether the command is active, which means that the selection starts in a list of the same type.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #value\n\t\t */\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @protected\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\t\tconst blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t.filter( block => checkCanBecomeListItem( block, model.schema ) );\n\n\t\t// Whether we are turning off some items.\n\t\tconst turnOff = this.value === true;\n\t\t// If we are turning off items, we are going to rename them to paragraphs.\n\n\t\tmodel.change( writer => {\n\t\t\t// If part of a list got turned off, we need to handle (outdent) all of sub-items of the last turned-off item.\n\t\t\t// To be sure that model is all the time in a good state, we first fix items below turned-off item.\n\t\t\tif ( turnOff ) {\n\t\t\t\t// Start from the model item that is just after the last turned-off item.\n\t\t\t\tlet next = blocks[ blocks.length - 1 ].nextSibling;\n\t\t\t\tlet currentIndent = Number.POSITIVE_INFINITY;\n\t\t\t\tlet changes = [];\n\n\t\t\t\t// Correct indent of all items after the last turned off item.\n\t\t\t\t// Rules that should be followed:\n\t\t\t\t// 1. All direct sub-items of turned-off item should become indent 0, because the first item after it\n\t\t\t\t// will be the first item of a new list. Other items are at the same level, so should have same 0 index.\n\t\t\t\t// 2. All items with indent lower than indent of turned-off item should become indent 0, because they\n\t\t\t\t// should not end up as a child of any of list items that they were not children of before.\n\t\t\t\t// 3. All other items should have their indent changed relatively to it's parent.\n\t\t\t\t//\n\t\t\t\t// For example:\n\t\t\t\t// 1 * --------\n\t\t\t\t// 2 * --------\n\t\t\t\t// 3 * --------\t\t\t<-- this is turned off.\n\t\t\t\t// 4 * --------\t\t<-- this has to become indent = 0, because it will be first item on a new list.\n\t\t\t\t// 5 * --------\t<-- this should be still be a child of item above, so indent = 1.\n\t\t\t\t// 6 * --------\t\t\t<-- this has to become indent = 0, because it should not be a child of any of items above.\n\t\t\t\t// 7 * --------\t\t<-- this should be still be a child of item above, so indent = 1.\n\t\t\t\t// 8 * --------\t\t\t\t<-- this has to become indent = 0.\n\t\t\t\t// 9 * --------\t\t\t<-- this should still be a child of item above, so indent = 1.\n\t\t\t\t// 10 * --------\t\t<-- this should still be a child of item above, so indent = 2.\n\t\t\t\t// 11 * --------\t\t<-- this should still be at the same level as item above, so indent = 2.\n\t\t\t\t// 12 * --------\t\t\t\t<-- this and all below are left unchanged.\n\t\t\t\t// 13 * --------\n\t\t\t\t// 14 * --------\n\t\t\t\t//\n\t\t\t\t// After turning off 3 the list becomes:\n\t\t\t\t//\n\t\t\t\t// 1 * --------\n\t\t\t\t// 2 * --------\n\t\t\t\t//\n\t\t\t\t// 3 --------\n\t\t\t\t//\n\t\t\t\t// 4 * --------\n\t\t\t\t// 5 * --------\n\t\t\t\t// 6 * --------\n\t\t\t\t// 7 * --------\n\t\t\t\t// 8 * --------\n\t\t\t\t// 9 * --------\n\t\t\t\t// 10 * --------\n\t\t\t\t// 11 * --------\n\t\t\t\t// 12 * --------\n\t\t\t\t// 13 * --------\n\t\t\t\t// 14 * --------\n\t\t\t\t//\n\t\t\t\t// Thanks to this algorithm no lists are mismatched and no items get unexpected children/parent, while\n\t\t\t\t// those parent-child connection which are possible to maintain are still maintained. It's worth noting\n\t\t\t\t// that this is the same effect that we would be get by multiple use of outdent command. However doing\n\t\t\t\t// it like this is much more efficient because it's less operation (less memory usage, easier OT) and\n\t\t\t\t// less conversion (faster).\n\t\t\t\twhile ( next && next.name == 'listItem' && next.getAttribute( 'listIndent' ) !== 0 ) {\n\t\t\t\t\t// Check each next list item, as long as its indent is bigger than 0.\n\t\t\t\t\t// If the indent is 0 we are not going to change anything anyway.\n\t\t\t\t\tconst indent = next.getAttribute( 'listIndent' );\n\n\t\t\t\t\t// We check if that's item indent is lower as current relative indent.\n\t\t\t\t\tif ( indent < currentIndent ) {\n\t\t\t\t\t\t// If it is, current relative indent becomes that indent.\n\t\t\t\t\t\tcurrentIndent = indent;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fix indent relatively to current relative indent.\n\t\t\t\t\t// Note, that if we just changed the current relative indent, the newIndent will be equal to 0.\n\t\t\t\t\tconst newIndent = indent - currentIndent;\n\n\t\t\t\t\t// Save the entry in changes array. We do not apply it at the moment, because we will need to\n\t\t\t\t\t// reverse the changes so the last item is changed first.\n\t\t\t\t\t// This is to keep model in correct state all the time.\n\t\t\t\t\tchanges.push( { element: next, listIndent: newIndent } );\n\n\t\t\t\t\t// Find next item.\n\t\t\t\t\tnext = next.nextSibling;\n\t\t\t\t}\n\n\t\t\t\tchanges = changes.reverse();\n\n\t\t\t\tfor ( const item of changes ) {\n\t\t\t\t\twriter.setAttribute( 'listIndent', item.listIndent, item.element );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we are turning on, we might change some items that are already `listItem`s but with different type.\n\t\t\t// Changing one nested list item to other type should also trigger changing all its siblings so the\n\t\t\t// whole nested list is of the same type.\n\t\t\t// Example (assume changing to numbered list):\n\t\t\t// * ------\t\t\t\t<-- do not fix, top level item\n\t\t\t// * ------\t\t\t<-- fix, because latter list item of this item's list is changed\n\t\t\t// * ------\t\t<-- do not fix, item is not affected (different list)\n\t\t\t// * ------\t\t\t<-- fix, because latter list item of this item's list is changed\n\t\t\t// * ------\t\t<-- fix, because latter list item of this item's list is changed\n\t\t\t// * ---[--\t\t<-- already in selection\n\t\t\t// * ------\t\t\t<-- already in selection\n\t\t\t// * ------\t\t\t<-- already in selection\n\t\t\t// * ------\t\t\t\t<-- already in selection, but does not cause other list items to change because is top-level\n\t\t\t// * ---]--\t\t\t<-- already in selection\n\t\t\t// * ------\t\t\t<-- fix, because preceding list item of this item's list is changed\n\t\t\t// * ------\t\t<-- do not fix, item is not affected (different list)\n\t\t\t// * ------\t\t\t\t<-- do not fix, top level item\n\t\t\tif ( !turnOff ) {\n\t\t\t\t// Find lowest indent among selected items. This will be indicator what is the indent of\n\t\t\t\t// top-most list affected by the command.\n\t\t\t\tlet lowestIndent = Number.POSITIVE_INFINITY;\n\n\t\t\t\tfor ( const item of blocks ) {\n\t\t\t\t\tif ( item.is( 'listItem' ) && item.getAttribute( 'listIndent' ) < lowestIndent ) {\n\t\t\t\t\t\tlowestIndent = item.getAttribute( 'listIndent' );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Do not execute the fix for top-level lists.\n\t\t\t\tlowestIndent = lowestIndent === 0 ? 1 : lowestIndent;\n\n\t\t\t\t// Fix types of list items that are \"before\" the selected blocks.\n\t\t\t\t_fixType( blocks, true, lowestIndent );\n\n\t\t\t\t// Fix types of list items that are \"after\" the selected blocks.\n\t\t\t\t_fixType( blocks, false, lowestIndent );\n\t\t\t}\n\n\t\t\t// Phew! Now it will be easier :).\n\t\t\t// For each block element that was in the selection, we will either: turn it to list item,\n\t\t\t// turn it to paragraph, or change it's type. Or leave it as it is.\n\t\t\t// Do it in reverse as there might be multiple blocks (same as with changing indents).\n\t\t\tfor ( const element of blocks.reverse() ) {\n\t\t\t\tif ( turnOff && element.name == 'listItem' ) {\n\t\t\t\t\t// We are turning off and the element is a `listItem` - it should be converted to `paragraph`.\n\t\t\t\t\t// List item specific attributes are removed by post fixer.\n\t\t\t\t\twriter.rename( element, 'paragraph' );\n\t\t\t\t} else if ( !turnOff && element.name != 'listItem' ) {\n\t\t\t\t\t// We are turning on and the element is not a `listItem` - it should be converted to `listItem`.\n\t\t\t\t\t// The order of operations is important to keep model in correct state.\n\t\t\t\t\twriter.setAttributes( { listType: this.type, listIndent: 0 }, element );\n\t\t\t\t\twriter.rename( element, 'listItem' );\n\t\t\t\t} else if ( !turnOff && element.name == 'listItem' && element.getAttribute( 'listType' ) != this.type ) {\n\t\t\t\t\t// We are turning on and the element is a `listItem` but has different type - change it's type and\n\t\t\t\t\t// type of it's all siblings that have same indent.\n\t\t\t\t\twriter.setAttribute( 'listType', this.type, element );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {Boolean} The current value.\n\t */\n\t_getValue() {\n\t\t// Check whether closest `listItem` ancestor of the position has a correct type.\n\t\tconst listItem = first( this.editor.model.document.selection.getSelectedBlocks() );\n\n\t\treturn !!listItem && listItem.is( 'listItem' ) && listItem.getAttribute( 'listType' ) == this.type;\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\t// If command value is true it means that we are in list item, so the command should be enabled.\n\t\tif ( this.value ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst schema = this.editor.model.schema;\n\n\t\tconst firstBlock = first( selection.getSelectedBlocks() );\n\n\t\tif ( !firstBlock ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Otherwise, check if list item can be inserted at the position start.\n\t\treturn checkCanBecomeListItem( firstBlock, schema );\n\t}\n}\n\n// Helper function used when one or more list item have their type changed. Fixes type of other list items\n// that are affected by the change (are in same lists) but are not directly in selection. The function got extracted\n// not to duplicated code, as same fix has to be performed before and after selection.\n//\n// @param {Array.<module:engine/model/node~Node>} blocks Blocks that are in selection.\n// @param {Boolean} isBackward Specified whether fix will be applied for blocks before first selected block (`true`)\n// or blocks after last selected block (`false`).\n// @param {Number} lowestIndent Lowest indent among selected blocks.\nfunction _fixType( blocks, isBackward, lowestIndent ) {\n\t// We need to check previous sibling of first changed item and next siblings of last changed item.\n\tconst startingItem = isBackward ? blocks[ 0 ] : blocks[ blocks.length - 1 ];\n\n\tif ( startingItem.is( 'listItem' ) ) {\n\t\tlet item = startingItem[ isBackward ? 'previousSibling' : 'nextSibling' ];\n\t\t// During processing items, keeps the lowest indent of already processed items.\n\t\t// This saves us from changing too many items.\n\t\t// Following example is for going forward as it is easier to read, however same applies to going backward.\n\t\t// * ------\n\t\t// * ------\n\t\t// * --[---\n\t\t// * ------\t\t<-- `lowestIndent` should be 1\n\t\t// * --]---\t\t<-- `startingItem`, `currentIndent` = 2, `lowestIndent` == 1\n\t\t// * ------\t\t<-- should be fixed, `indent` == 2 == `currentIndent`\n\t\t// * ------\t\t<-- should be fixed, set `currentIndent` to 1, `indent` == 1 == `currentIndent`\n\t\t// * ------\t\t<-- should not be fixed, item is in different list, `indent` = 2, `indent` != `currentIndent`\n\t\t// * ------\t\t<-- should be fixed, `indent` == 1 == `currentIndent`\n\t\t// * ------\t\t\t<-- break loop (`indent` < `lowestIndent`)\n\t\tlet currentIndent = startingItem.getAttribute( 'listIndent' );\n\n\t\t// Look back until a list item with indent lower than reference `lowestIndent`.\n\t\t// That would be the parent of nested sublist which contains item having `lowestIndent`.\n\t\twhile ( item && item.is( 'listItem' ) && item.getAttribute( 'listIndent' ) >= lowestIndent ) {\n\t\t\tif ( currentIndent > item.getAttribute( 'listIndent' ) ) {\n\t\t\t\tcurrentIndent = item.getAttribute( 'listIndent' );\n\t\t\t}\n\n\t\t\t// Found an item that is in the same nested sublist.\n\t\t\tif ( item.getAttribute( 'listIndent' ) == currentIndent ) {\n\t\t\t\t// Just add the item to selected blocks like it was selected by the user.\n\t\t\t\tblocks[ isBackward ? 'unshift' : 'push' ]( item );\n\t\t\t}\n\n\t\t\titem = item[ isBackward ? 'previousSibling' : 'nextSibling' ];\n\t\t}\n\t}\n}\n\n// Checks whether the given block can be replaced by a listItem.\n//\n// @private\n// @param {module:engine/model/element~Element} block A block to be tested.\n// @param {module:engine/model/schema~Schema} schema The schema of the document.\n// @returns {Boolean}\nfunction checkCanBecomeListItem( block, schema ) {\n\treturn schema.checkChild( block.parent, 'listItem' ) && !schema.isObject( block );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module list/indentcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport first from '@ckeditor/ckeditor5-utils/src/first';\n\n/**\n * The list indent command. It is used by the {@link module:list/list~List list feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class IndentCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {'forward'|'backward'} indentDirection The direction of indent. If it is equal to `backward`, the command\n\t * will outdent a list item.\n\t */\n\tconstructor( editor, indentDirection ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * Determines by how much the command will change the list item's indent attribute.\n\t\t *\n\t\t * @readonly\n\t\t * @private\n\t\t * @member {Number}\n\t\t */\n\t\tthis._indentBy = indentDirection == 'forward' ? 1 : -1;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Indents or outdents (depends on the {@link #constructor}'s `indentDirection` parameter) selected list items.\n\t *\n\t * @fires execute\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tlet itemsToChange = Array.from( doc.selection.getSelectedBlocks() );\n\n\t\tmodel.change( writer => {\n\t\t\tconst lastItem = itemsToChange[ itemsToChange.length - 1 ];\n\n\t\t\t// Indenting a list item should also indent all the items that are already sub-items of indented item.\n\t\t\tlet next = lastItem.nextSibling;\n\n\t\t\t// Check all items after last indented item, as long as their indent is bigger than indent of that item.\n\t\t\twhile ( next && next.name == 'listItem' && next.getAttribute( 'listIndent' ) > lastItem.getAttribute( 'listIndent' ) ) {\n\t\t\t\titemsToChange.push( next );\n\n\t\t\t\tnext = next.nextSibling;\n\t\t\t}\n\n\t\t\t// We need to be sure to keep model in correct state after each small change, because converters\n\t\t\t// bases on that state and assumes that model is correct.\n\t\t\t// Because of that, if the command outdents items, we will outdent them starting from the last item, as\n\t\t\t// it is safer.\n\t\t\tif ( this._indentBy < 0 ) {\n\t\t\t\titemsToChange = itemsToChange.reverse();\n\t\t\t}\n\n\t\t\tfor ( const item of itemsToChange ) {\n\t\t\t\tconst indent = item.getAttribute( 'listIndent' ) + this._indentBy;\n\n\t\t\t\t// If indent is lower than 0, it means that the item got outdented when it was not indented.\n\t\t\t\t// This means that we need to convert that list item to paragraph.\n\t\t\t\tif ( indent < 0 ) {\n\t\t\t\t\t// To keep the model as correct as possible, first rename listItem, then remove attributes,\n\t\t\t\t\t// as listItem without attributes is very incorrect and will cause problems in converters.\n\t\t\t\t\t// No need to remove attributes, will be removed by post fixer.\n\t\t\t\t\twriter.rename( item, 'paragraph' );\n\t\t\t\t}\n\t\t\t\t// If indent is >= 0, change the attribute value.\n\t\t\t\telse {\n\t\t\t\t\twriter.setAttribute( 'listIndent', indent, item );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\t// Check whether any of position's ancestor is a list item.\n\t\tconst listItem = first( this.editor.model.document.selection.getSelectedBlocks() );\n\n\t\t// If selection is not in a list item, the command is disabled.\n\t\tif ( !listItem || !listItem.is( 'listItem' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this._indentBy > 0 ) {\n\t\t\t// Cannot indent first item in it's list. Check if before `listItem` is a list item that is in same list.\n\t\t\t// To be in the same list, the item has to have same attributes and cannot be \"split\" by an item with lower indent.\n\t\t\tconst indent = listItem.getAttribute( 'listIndent' );\n\t\t\tconst type = listItem.getAttribute( 'listType' );\n\n\t\t\tlet prev = listItem.previousSibling;\n\n\t\t\twhile ( prev && prev.is( 'listItem' ) && prev.getAttribute( 'listIndent' ) >= indent ) {\n\t\t\t\tif ( prev.getAttribute( 'listIndent' ) == indent ) {\n\t\t\t\t\t// The item is on the same level.\n\t\t\t\t\t// If it has same type, it means that we found a preceding sibling from the same list.\n\t\t\t\t\t// If it does not have same type, it means that `listItem` is on different list (this can happen only\n\t\t\t\t\t// on top level lists, though).\n\t\t\t\t\treturn prev.getAttribute( 'listType' ) == type;\n\t\t\t\t}\n\n\t\t\t\tprev = prev.previousSibling;\n\t\t\t}\n\n\t\t\t// Could not find similar list item, this means that `listItem` is first in its list.\n\t\t\treturn false;\n\t\t}\n\n\t\t// If we are outdenting it is enough to be in list item. Every list item can always be outdented.\n\t\treturn true;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor.data, 'ready', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n/**\n * Array of loaded plugins.\n *\n * @typedef {Array.<module:core/plugin~PluginInterface>} module:core/plugin~LoadedPlugins\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module list/utils\n */\n\nimport { getFillerOffset } from '@ckeditor/ckeditor5-engine/src/view/containerelement';\n\n/**\n * Creates list item {@link module:engine/view/containerelement~ContainerElement}.\n *\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer The writer instance.\n * @returns {module:engine/view/containerelement~ContainerElement}\n */\nexport function createViewListItemElement( writer ) {\n\tconst viewItem = writer.createContainerElement( 'li' );\n\tviewItem.getFillerOffset = getListItemFillerOffset;\n\n\treturn viewItem;\n}\n\n// Implementation of getFillerOffset for view list item element.\n//\n// @returns {Number|null} Block filler offset or `null` if block filler is not needed.\nfunction getListItemFillerOffset() {\n\tconst hasOnlyLists = !this.isEmpty && ( this.getChild( 0 ).name == 'ul' || this.getChild( 0 ).name == 'ol' );\n\n\tif ( this.isEmpty || hasOnlyLists ) {\n\t\treturn 0;\n\t}\n\n\treturn getFillerOffset.call( this );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module list/converters\n */\n\nimport { createViewListItemElement } from './utils';\nimport TreeWalker from '@ckeditor/ckeditor5-engine/src/model/treewalker';\n\n/**\n * A model-to-view converter for `listItem` model element insertion.\n *\n * It creates a `<ul><li></li><ul>` (or `<ol>`) view structure out of a `listItem` model element, inserts it at the correct\n * position, and merges the list with surrounding lists (if available).\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n * @param {module:engine/model/model~Model} model Model instance.\n * @returns {Function} Returns a conversion callback.\n */\nexport function modelViewInsertion( model ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst consumable = conversionApi.consumable;\n\n\t\tif ( !consumable.test( data.item, 'insert' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listType' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listIndent' )\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconsumable.consume( data.item, 'insert' );\n\t\tconsumable.consume( data.item, 'attribute:listType' );\n\t\tconsumable.consume( data.item, 'attribute:listIndent' );\n\n\t\tconst modelItem = data.item;\n\t\tconst viewItem = generateLiInUl( modelItem, conversionApi );\n\n\t\tinjectViewList( modelItem, viewItem, conversionApi, model );\n\t};\n}\n\n/**\n * A model-to-view converter for `listItem` model element removal.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:remove\n * @param {module:engine/model/model~Model} model Model instance.\n * @returns {Function} Returns a conversion callback.\n */\nexport function modelViewRemove( model ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst viewStart = conversionApi.mapper.toViewPosition( data.position ).getLastMatchingPosition( value => !value.item.is( 'li' ) );\n\t\tconst viewItem = viewStart.nodeAfter;\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\t// 1. Break the container after and before the list item.\n\t\t// This will create a view list with one view list item - the one to remove.\n\t\tviewWriter.breakContainer( viewWriter.createPositionBefore( viewItem ) );\n\t\tviewWriter.breakContainer( viewWriter.createPositionAfter( viewItem ) );\n\n\t\t// 2. Remove the list with the item to remove.\n\t\tconst viewList = viewItem.parent;\n\t\tconst viewListPrev = viewList.previousSibling;\n\t\tconst removeRange = viewWriter.createRangeOn( viewList );\n\t\tconst removed = viewWriter.remove( removeRange );\n\n\t\t// 3. Merge the whole created by breaking and removing the list.\n\t\tif ( viewListPrev && viewListPrev.nextSibling ) {\n\t\t\tmergeViewLists( viewWriter, viewListPrev, viewListPrev.nextSibling );\n\t\t}\n\n\t\t// 4. Bring back nested list that was in the removed <li>.\n\t\tconst modelItem = conversionApi.mapper.toModelElement( viewItem );\n\n\t\thoistNestedLists( modelItem.getAttribute( 'listIndent' ) + 1, data.position, removeRange.start, viewItem, conversionApi, model );\n\n\t\t// 5. Unbind removed view item and all children.\n\t\tfor ( const child of viewWriter.createRangeIn( removed ).getItems() ) {\n\t\t\tconversionApi.mapper.unbindViewElement( child );\n\t\t}\n\n\t\tevt.stop();\n\t};\n}\n\n/**\n * A model-to-view converter for `type` attribute change on `listItem` model element.\n *\n * This change means that `<li>` elements parent changes from `<ul>` to `<ol>` (or vice versa). This is accomplished\n * by breaking view elements, changing their name and merging them.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface.\n */\nexport function modelViewChangeType( evt, data, conversionApi ) {\n\tif ( !conversionApi.consumable.consume( data.item, 'attribute:listType' ) ) {\n\t\treturn;\n\t}\n\n\tconst viewItem = conversionApi.mapper.toViewElement( data.item );\n\tconst viewWriter = conversionApi.writer;\n\n\t// 1. Break the container after and before the list item.\n\t// This will create a view list with one view list item -- the one that changed type.\n\tviewWriter.breakContainer( viewWriter.createPositionBefore( viewItem ) );\n\tviewWriter.breakContainer( viewWriter.createPositionAfter( viewItem ) );\n\n\t// 2. Change name of the view list that holds the changed view item.\n\t// We cannot just change name property, because that would not render properly.\n\tlet viewList = viewItem.parent;\n\tconst listName = data.attributeNewValue == 'numbered' ? 'ol' : 'ul';\n\tviewList = viewWriter.rename( listName, viewList );\n\n\t// 3. Merge the changed view list with other lists, if possible.\n\tmergeViewLists( viewWriter, viewList, viewList.nextSibling );\n\tmergeViewLists( viewWriter, viewList.previousSibling, viewList );\n\n\t// 4. Consumable insertion of children inside the item. They are already handled by re-building the item in view.\n\tfor ( const child of data.item.getChildren() ) {\n\t\tconversionApi.consumable.consume( child, 'insert' );\n\t}\n}\n\n/**\n * A model-to-view converter for `listIndent` attribute change on `listItem` model element.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n * @param {module:engine/model/model~Model} model Model instance.\n * @returns {Function} Returns a conversion callback.\n */\nexport function modelViewChangeIndent( model ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tif ( !conversionApi.consumable.consume( data.item, 'attribute:listIndent' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewItem = conversionApi.mapper.toViewElement( data.item );\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\t// 1. Break the container after and before the list item.\n\t\t// This will create a view list with one view list item -- the one that changed type.\n\t\tviewWriter.breakContainer( viewWriter.createPositionBefore( viewItem ) );\n\t\tviewWriter.breakContainer( viewWriter.createPositionAfter( viewItem ) );\n\n\t\t// 2. Extract view list with changed view list item and merge \"hole\" possibly created by breaking and removing elements.\n\t\tconst viewList = viewItem.parent;\n\t\tconst viewListPrev = viewList.previousSibling;\n\t\tconst removeRange = viewWriter.createRangeOn( viewList );\n\t\tviewWriter.remove( removeRange );\n\n\t\tif ( viewListPrev && viewListPrev.nextSibling ) {\n\t\t\tmergeViewLists( viewWriter, viewListPrev, viewListPrev.nextSibling );\n\t\t}\n\n\t\t// 3. Bring back nested list that was in the removed <li>.\n\t\thoistNestedLists( data.attributeOldValue + 1, data.range.start, removeRange.start, viewItem, conversionApi, model );\n\n\t\t// 4. Inject view list like it is newly inserted.\n\t\tinjectViewList( data.item, viewItem, conversionApi, model );\n\n\t\t// 5. Consume insertion of children inside the item. They are already handled by re-building the item in view.\n\t\tfor ( const child of data.item.getChildren() ) {\n\t\t\tconversionApi.consumable.consume( child, 'insert' );\n\t\t}\n\t};\n}\n\n/**\n * A special model-to-view converter introduced by the {@link module:list/list~List list feature}. This converter is fired for\n * insert change of every model item, and should be fired before the actual converter. The converter checks whether the inserted\n * model item is a non-`listItem` element. If it is, and it is inserted inside a view list, the converter breaks the\n * list so the model element is inserted to the view parent element corresponding to its model parent element.\n *\n * The converter prevents such situations:\n *\n *\t\t// Model: // View:\n *\t\t<listItem>foo</listItem> <ul>\n *\t\t<listItem>bar</listItem> <li>foo</li>\n *\t\t <li>bar</li>\n *\t\t </ul>\n *\n *\t\t// After change: // Correct view guaranteed by this converter:\n *\t\t<listItem>foo</listItem> <ul><li>foo</li></ul><p>xxx</p><ul><li>bar</li></ul>\n *\t\t<paragraph>xxx</paragraph> // Instead of this wrong view state:\n *\t\t<listItem>bar</listItem> <ul><li>foo</li><p>xxx</p><li>bar</li></ul>\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface.\n */\nexport function modelViewSplitOnInsert( evt, data, conversionApi ) {\n\tif ( data.item.name != 'listItem' ) {\n\t\tlet viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst lists = [];\n\n\t\t// Break multiple ULs/OLs if there are.\n\t\t//\n\t\t// Imagine following list:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.1.1 --------\n\t\t// 1.1.2 --------\n\t\t// 1.1.3 --------\n\t\t// 1.1.3.1 --------\n\t\t// 1.2 --------\n\t\t// 1.2.1 --------\n\t\t// 2 --------\n\t\t//\n\t\t// Insert paragraph after item 1.1.1:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.1.1 --------\n\t\t//\n\t\t// Lorem ipsum.\n\t\t//\n\t\t// 1.1.2 --------\n\t\t// 1.1.3 --------\n\t\t// 1.1.3.1 --------\n\t\t// 1.2 --------\n\t\t// 1.2.1 --------\n\t\t// 2 --------\n\t\t//\n\t\t// In this case 1.1.2 has to become beginning of a new list.\n\t\t// We need to break list before 1.1.2 (obvious), then we need to break list also before 1.2.\n\t\t// Then we need to move those broken pieces one after another and merge:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.1.1 --------\n\t\t//\n\t\t// Lorem ipsum.\n\t\t//\n\t\t// 1.1.2 --------\n\t\t// 1.1.3 --------\n\t\t// 1.1.3.1 --------\n\t\t// 1.2 --------\n\t\t// 1.2.1 --------\n\t\t// 2 --------\n\t\t//\n\t\twhile ( viewPosition.parent.name == 'ul' || viewPosition.parent.name == 'ol' ) {\n\t\t\tviewPosition = viewWriter.breakContainer( viewPosition );\n\n\t\t\tif ( viewPosition.parent.name != 'li' ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Remove lists that are after inserted element.\n\t\t\t// They will be brought back later, below the inserted element.\n\t\t\tconst removeStart = viewPosition;\n\t\t\tconst removeEnd = viewWriter.createPositionAt( viewPosition.parent, 'end' );\n\n\t\t\t// Don't remove if there is nothing to remove.\n\t\t\tif ( !removeStart.isEqual( removeEnd ) ) {\n\t\t\t\tconst removed = viewWriter.remove( viewWriter.createRange( removeStart, removeEnd ) );\n\t\t\t\tlists.push( removed );\n\t\t\t}\n\n\t\t\tviewPosition = viewWriter.createPositionAfter( viewPosition.parent );\n\t\t}\n\n\t\t// Bring back removed lists.\n\t\tif ( lists.length > 0 ) {\n\t\t\tfor ( let i = 0; i < lists.length; i++ ) {\n\t\t\t\tconst previousList = viewPosition.nodeBefore;\n\t\t\t\tconst insertedRange = viewWriter.insert( viewPosition, lists[ i ] );\n\t\t\t\tviewPosition = insertedRange.end;\n\n\t\t\t\t// Don't merge first list! We want a split in that place (this is why this converter is introduced).\n\t\t\t\tif ( i > 0 ) {\n\t\t\t\t\tconst mergePos = mergeViewLists( viewWriter, previousList, previousList.nextSibling );\n\n\t\t\t\t\t// If `mergePos` is in `previousList` it means that the lists got merged.\n\t\t\t\t\t// In this case, we need to fix insert position.\n\t\t\t\t\tif ( mergePos && mergePos.parent == previousList ) {\n\t\t\t\t\t\tviewPosition.offset--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Merge last inserted list with element after it.\n\t\t\tmergeViewLists( viewWriter, viewPosition.nodeBefore, viewPosition.nodeAfter );\n\t\t}\n\t}\n}\n\n/**\n * A special model-to-view converter introduced by the {@link module:list/list~List list feature}. This converter takes care of\n * merging view lists after something is removed or moved from near them.\n *\n * Example:\n *\n *\t\t// Model: // View:\n *\t\t<listItem>foo</listItem> <ul><li>foo</li></ul>\n *\t\t<paragraph>xxx</paragraph> <p>xxx</p>\n *\t\t<listItem>bar</listItem> <ul><li>bar</li></ul>\n *\n *\t\t// After change: // Correct view guaranteed by this converter:\n *\t\t<listItem>foo</listItem> <ul>\n *\t\t<listItem>bar</listItem> <li>foo</li>\n *\t\t <li>bar</li>\n *\t\t </ul>\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:remove\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface.\n */\nexport function modelViewMergeAfter( evt, data, conversionApi ) {\n\tconst viewPosition = conversionApi.mapper.toViewPosition( data.position );\n\tconst viewItemPrev = viewPosition.nodeBefore;\n\tconst viewItemNext = viewPosition.nodeAfter;\n\n\t// Merge lists if something (remove, move) was done from inside of list.\n\t// Merging will be done only if both items are view lists of the same type.\n\t// The check is done inside the helper function.\n\tmergeViewLists( conversionApi.writer, viewItemPrev, viewItemNext );\n}\n\n/**\n * A view-to-model converter that converts `<li>` view elements into `listItem` model elements.\n *\n * To set correct values of the `listType` and `listIndent` attributes the converter:\n * * checks `<li>`'s parent,\n * * stores and increases the `conversionApi.store.indent` value when `<li>`'s sub-items are converted.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data An object containing conversion input and a placeholder for conversion output and possibly other values.\n * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface to be used by the callback.\n */\nexport function viewModelConverter( evt, data, conversionApi ) {\n\tif ( conversionApi.consumable.consume( data.viewItem, { name: true } ) ) {\n\t\tconst writer = conversionApi.writer;\n\t\tconst conversionStore = this.conversionApi.store;\n\n\t\t// 1. Create `listItem` model element.\n\t\tconst listItem = writer.createElement( 'listItem' );\n\n\t\t// 2. Handle `listItem` model element attributes.\n\t\tconversionStore.indent = conversionStore.indent || 0;\n\t\twriter.setAttribute( 'listIndent', conversionStore.indent, listItem );\n\n\t\t// Set 'bulleted' as default. If this item is pasted into a context,\n\t\tconst type = data.viewItem.parent && data.viewItem.parent.name == 'ol' ? 'numbered' : 'bulleted';\n\t\twriter.setAttribute( 'listType', type, listItem );\n\n\t\t// `listItem`s created recursively should have bigger indent.\n\t\tconversionStore.indent++;\n\n\t\t// Try to find allowed parent for list item.\n\t\tconst splitResult = conversionApi.splitToAllowedParent( listItem, data.modelCursor );\n\n\t\t// When there is no allowed parent it means that list item cannot be converted at current model position\n\t\t// and in any of position ancestors.\n\t\tif ( !splitResult ) {\n\t\t\treturn;\n\t\t}\n\n\t\twriter.insert( listItem, splitResult.position );\n\n\t\tconst nextPosition = viewToModelListItemChildrenConverter( listItem, data.viewItem.getChildren(), conversionApi );\n\n\t\tconversionStore.indent--;\n\n\t\t// Result range starts before the first item and ends after the last.\n\t\tdata.modelRange = writer.createRange( data.modelCursor, nextPosition );\n\n\t\t// When `data.modelCursor` parent had to be split to insert list item...\n\t\tif ( splitResult.cursorParent ) {\n\t\t\t// Continue conversion in the split element.\n\t\t\tdata.modelCursor = writer.createPositionAt( splitResult.cursorParent, 0 );\n\t\t} else {\n\t\t\t// Otherwise continue conversion after the last list item.\n\t\t\tdata.modelCursor = data.modelRange.end;\n\t\t}\n\t}\n}\n\n/**\n * A view-to-model converter for `<ul>` and `<ol>` view elements that cleans the input view of garbage.\n * This is mostly to clean whitespaces from between `<li>` view elements inside the view list element, however, also\n * incorrect data can be cleared if the view was incorrect.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data An object containing conversion input and a placeholder for conversion output and possibly other values.\n * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface to be used by the callback.\n */\nexport function cleanList( evt, data, conversionApi ) {\n\tif ( conversionApi.consumable.test( data.viewItem, { name: true } ) ) {\n\t\t// Caching children because when we start removing them iterating fails.\n\t\tconst children = Array.from( data.viewItem.getChildren() );\n\n\t\tfor ( const child of children ) {\n\t\t\tif ( !child.is( 'li' ) ) {\n\t\t\t\tchild._remove();\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * A view-to-model converter for `<li>` elements that cleans whitespace formatting from the input view.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data An object containing conversion input and a placeholder for conversion output and possibly other values.\n * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface to be used by the callback.\n */\nexport function cleanListItem( evt, data, conversionApi ) {\n\tif ( conversionApi.consumable.test( data.viewItem, { name: true } ) ) {\n\t\tif ( data.viewItem.childCount === 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst children = [ ...data.viewItem.getChildren() ];\n\n\t\tlet foundList = false;\n\t\tlet firstNode = true;\n\n\t\tfor ( const child of children ) {\n\t\t\tif ( foundList && !child.is( 'ul' ) && !child.is( 'ol' ) ) {\n\t\t\t\tchild._remove();\n\t\t\t}\n\n\t\t\tif ( child.is( 'text' ) ) {\n\t\t\t\t// If this is the first node and it's a text node, left-trim it.\n\t\t\t\tif ( firstNode ) {\n\t\t\t\t\tchild._data = child.data.replace( /^\\s+/, '' );\n\t\t\t\t}\n\n\t\t\t\t// If this is the last text node before <ul> or <ol>, right-trim it.\n\t\t\t\tif ( !child.nextSibling || ( child.nextSibling.is( 'ul' ) || child.nextSibling.is( 'ol' ) ) ) {\n\t\t\t\t\tchild._data = child.data.replace( /\\s+$/, '' );\n\t\t\t\t}\n\t\t\t} else if ( child.is( 'ul' ) || child.is( 'ol' ) ) {\n\t\t\t\t// If this is a <ul> or <ol>, do not process it, just mark that we already visited list element.\n\t\t\t\tfoundList = true;\n\t\t\t}\n\n\t\t\tfirstNode = false;\n\t\t}\n\t}\n}\n\n/**\n * Returns callback for model position to view position mapping for {@link module:engine/conversion/mapper~Mapper}. The callback fixes\n * positions between `listItem` elements that would be incorrectly mapped because of how list items are represented in model\n * and view.\n *\n * @see module:engine/conversion/mapper~Mapper#event:modelToViewPosition\n * @param {module:engine/view/view~View} view A view instance.\n * @returns {Function}\n */\nexport function modelToViewPosition( view ) {\n\treturn ( evt, data ) => {\n\t\tif ( data.isPhantom ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelItem = data.modelPosition.nodeBefore;\n\n\t\tif ( modelItem && modelItem.is( 'listItem' ) ) {\n\t\t\tconst viewItem = data.mapper.toViewElement( modelItem );\n\t\t\tconst topmostViewList = viewItem.getAncestors().find( element => element.is( 'ul' ) || element.is( 'ol' ) );\n\t\t\tconst walker = view.createPositionAt( viewItem, 0 ).getWalker();\n\n\t\t\tfor ( const value of walker ) {\n\t\t\t\tif ( value.type == 'elementStart' && value.item.is( 'li' ) ) {\n\t\t\t\t\tdata.viewPosition = value.previousPosition;\n\n\t\t\t\t\tbreak;\n\t\t\t\t} else if ( value.type == 'elementEnd' && value.item == topmostViewList ) {\n\t\t\t\t\tdata.viewPosition = value.nextPosition;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * The callback for view position to model position mapping for {@link module:engine/conversion/mapper~Mapper}. The callback fixes\n * positions between `<li>` elements that would be incorrectly mapped because of how list items are represented in model\n * and view.\n *\n * @see module:engine/conversion/mapper~Mapper#event:viewToModelPosition\n * @param {module:engine/model/model~Model} model Model instance.\n * @returns {Function} Returns a conversion callback.\n */\nexport function viewToModelPosition( model ) {\n\treturn ( evt, data ) => {\n\t\tconst viewPos = data.viewPosition;\n\t\tconst viewParent = viewPos.parent;\n\t\tconst mapper = data.mapper;\n\n\t\tif ( viewParent.name == 'ul' || viewParent.name == 'ol' ) {\n\t\t\t// Position is directly in <ul> or <ol>.\n\t\t\tif ( !viewPos.isAtEnd ) {\n\t\t\t\t// If position is not at the end, it must be before <li>.\n\t\t\t\t// Get that <li>, map it to `listItem` and set model position before that `listItem`.\n\t\t\t\tconst modelNode = mapper.toModelElement( viewPos.nodeAfter );\n\n\t\t\t\tdata.modelPosition = model.createPositionBefore( modelNode );\n\t\t\t} else {\n\t\t\t\t// Position is at the end of <ul> or <ol>, so there is no <li> after it to be mapped.\n\t\t\t\t// There is <li> before the position, but we cannot just map it to `listItem` and set model position after it,\n\t\t\t\t// because that <li> may contain nested items.\n\t\t\t\t// We will check \"model length\" of that <li>, in other words - how many `listItem`s are in that <li>.\n\t\t\t\tconst modelNode = mapper.toModelElement( viewPos.nodeBefore );\n\t\t\t\tconst modelLength = mapper.getModelLength( viewPos.nodeBefore );\n\n\t\t\t\t// Then we get model position before mapped `listItem` and shift it accordingly.\n\t\t\t\tdata.modelPosition = model.createPositionBefore( modelNode ).getShiftedBy( modelLength );\n\t\t\t}\n\n\t\t\tevt.stop();\n\t\t} else if (\n\t\t\tviewParent.name == 'li' &&\n\t\t\tviewPos.nodeBefore &&\n\t\t\t( viewPos.nodeBefore.name == 'ul' || viewPos.nodeBefore.name == 'ol' )\n\t\t) {\n\t\t\t// In most cases when view position is in <li> it is in text and this is a correct position.\n\t\t\t// However, if position is after <ul> or <ol> we have to fix it -- because in model <ul>/<ol> are not in the `listItem`.\n\t\t\tconst modelNode = mapper.toModelElement( viewParent );\n\n\t\t\t// Check all <ul>s and <ol>s that are in the <li> but before mapped position.\n\t\t\t// Get model length of those elements and then add it to the offset of `listItem` mapped to the original <li>.\n\t\t\tlet modelLength = 1; // Starts from 1 because the original <li> has to be counted in too.\n\t\t\tlet viewList = viewPos.nodeBefore;\n\n\t\t\twhile ( viewList && ( viewList.is( 'ul' ) || viewList.is( 'ol' ) ) ) {\n\t\t\t\tmodelLength += mapper.getModelLength( viewList );\n\n\t\t\t\tviewList = viewList.previousSibling;\n\t\t\t}\n\n\t\t\tdata.modelPosition = model.createPositionBefore( modelNode ).getShiftedBy( modelLength );\n\n\t\t\tevt.stop();\n\t\t}\n\t};\n}\n\n/**\n * Post-fixer that reacts to changes on document and fixes incorrect model states.\n *\n * In an example below, there is a correct list structure.\n * Then the middle element will be removed so the list structure will become incorrect:\n *\n *\t\t<listItem listType=\"bulleted\" listIndent=0>Item 1</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=1>Item 2</listItem> <--- this is removed.\n *\t\t<listItem listType=\"bulleted\" listIndent=2>Item 3</listItem>\n *\n * List structure after the middle element removed:\n *\n * \t\t<listItem listType=\"bulleted\" listIndent=0>Item 1</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=2>Item 3</listItem>\n *\n * Should become:\n *\n *\t\t<listItem listType=\"bulleted\" listIndent=0>Item 1</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=1>Item 3</listItem> <--- note that indent got post-fixed.\n *\n * @param {module:engine/model/model~Model} model The data model.\n * @param {module:engine/model/writer~Writer} writer The writer to do changes with.\n * @returns {Boolean} `true` if any change has been applied, `false` otherwise.\n */\nexport function modelChangePostFixer( model, writer ) {\n\tconst changes = model.document.differ.getChanges();\n\tconst itemToListHead = new Map();\n\n\tlet applied = false;\n\n\tfor ( const entry of changes ) {\n\t\tif ( entry.type == 'insert' && entry.name == 'listItem' ) {\n\t\t\t_addListToFix( entry.position );\n\t\t} else if ( entry.type == 'insert' && entry.name != 'listItem' ) {\n\t\t\tif ( entry.name != '$text' ) {\n\t\t\t\t// In case of renamed element.\n\t\t\t\tconst item = entry.position.nodeAfter;\n\n\t\t\t\tif ( item.hasAttribute( 'listIndent' ) ) {\n\t\t\t\t\twriter.removeAttribute( 'listIndent', item );\n\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\n\t\t\t\tif ( item.hasAttribute( 'listType' ) ) {\n\t\t\t\t\twriter.removeAttribute( 'listType', item );\n\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst posAfter = entry.position.getShiftedBy( entry.length );\n\n\t\t\t_addListToFix( posAfter );\n\t\t} else if ( entry.type == 'remove' && entry.name == 'listItem' ) {\n\t\t\t_addListToFix( entry.position );\n\t\t} else if ( entry.type == 'attribute' && entry.attributeKey == 'listIndent' ) {\n\t\t\t_addListToFix( entry.range.start );\n\t\t} else if ( entry.type == 'attribute' && entry.attributeKey == 'listType' ) {\n\t\t\t_addListToFix( entry.range.start );\n\t\t}\n\t}\n\n\tfor ( const listHead of itemToListHead.values() ) {\n\t\t_fixListIndents( listHead );\n\t\t_fixListTypes( listHead );\n\t}\n\n\treturn applied;\n\n\tfunction _addListToFix( position ) {\n\t\tconst prev = position.nodeBefore;\n\n\t\tif ( !prev || !prev.is( 'listItem' ) ) {\n\t\t\tconst item = position.nodeAfter;\n\n\t\t\tif ( item && item.is( 'listItem' ) ) {\n\t\t\t\titemToListHead.set( item, item );\n\t\t\t}\n\t\t} else {\n\t\t\tlet listHead = prev;\n\n\t\t\tif ( itemToListHead.has( listHead ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\twhile ( listHead.previousSibling && listHead.previousSibling.is( 'listItem' ) ) {\n\t\t\t\tlistHead = listHead.previousSibling;\n\n\t\t\t\tif ( itemToListHead.has( listHead ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\titemToListHead.set( position.nodeBefore, listHead );\n\t\t}\n\t}\n\n\tfunction _fixListIndents( item ) {\n\t\tlet maxIndent = 0;\n\t\tlet fixBy = null;\n\n\t\twhile ( item && item.is( 'listItem' ) ) {\n\t\t\tconst itemIndent = item.getAttribute( 'listIndent' );\n\n\t\t\tif ( itemIndent > maxIndent ) {\n\t\t\t\tlet newIndent;\n\n\t\t\t\tif ( fixBy === null ) {\n\t\t\t\t\tfixBy = itemIndent - maxIndent;\n\t\t\t\t\tnewIndent = maxIndent;\n\t\t\t\t} else {\n\t\t\t\t\tif ( fixBy > itemIndent ) {\n\t\t\t\t\t\tfixBy = itemIndent;\n\t\t\t\t\t}\n\n\t\t\t\t\tnewIndent = itemIndent - fixBy;\n\t\t\t\t}\n\n\t\t\t\twriter.setAttribute( 'listIndent', newIndent, item );\n\n\t\t\t\tapplied = true;\n\t\t\t} else {\n\t\t\t\tfixBy = null;\n\t\t\t\tmaxIndent = item.getAttribute( 'listIndent' ) + 1;\n\t\t\t}\n\n\t\t\titem = item.nextSibling;\n\t\t}\n\t}\n\n\tfunction _fixListTypes( item ) {\n\t\tlet typesStack = [];\n\t\tlet prev = null;\n\n\t\twhile ( item && item.is( 'listItem' ) ) {\n\t\t\tconst itemIndent = item.getAttribute( 'listIndent' );\n\n\t\t\tif ( prev && prev.getAttribute( 'listIndent' ) > itemIndent ) {\n\t\t\t\ttypesStack = typesStack.slice( 0, itemIndent + 1 );\n\t\t\t}\n\n\t\t\tif ( itemIndent != 0 ) {\n\t\t\t\tif ( typesStack[ itemIndent ] ) {\n\t\t\t\t\tconst type = typesStack[ itemIndent ];\n\n\t\t\t\t\tif ( item.getAttribute( 'listType' ) != type ) {\n\t\t\t\t\t\twriter.setAttribute( 'listType', type, item );\n\n\t\t\t\t\t\tapplied = true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttypesStack[ itemIndent ] = item.getAttribute( 'listType' );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tprev = item;\n\t\t\titem = item.nextSibling;\n\t\t}\n\t}\n}\n\n/**\n * A fixer for pasted content that includes list items.\n *\n * It fixes indentation of pasted list items so the pasted items match correctly to the context they are pasted into.\n *\n * Example:\n *\n *\t\t<listItem listType=\"bulleted\" listIndent=0>A</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=1>B^</listItem>\n *\t\t// At ^ paste: <listItem listType=\"bulleted\" listIndent=4>X</listItem>\n *\t\t// <listItem listType=\"bulleted\" listIndent=5>Y</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=2>C</listItem>\n *\n * Should become:\n *\n *\t\t<listItem listType=\"bulleted\" listIndent=0>A</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=1>BX</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=2>Y/listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=2>C</listItem>\n *\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Array} args Arguments of {@link module:engine/model/model~Model#insertContent}.\n */\nexport function modelIndentPasteFixer( evt, [ content, selectable ] ) {\n\t// Check whether inserted content starts from a `listItem`. If it does not, it means that there are some other\n\t// elements before it and there is no need to fix indents, because even if we insert that content into a list,\n\t// that list will be broken.\n\t// Note: we also need to handle singular elements because inserting item with indent 0 into 0,1,[],2\n\t// would create incorrect model.\n\tlet item = content.is( 'documentFragment' ) ? content.getChild( 0 ) : content;\n\n\tlet selection;\n\n\tif ( !selectable ) {\n\t\tselection = this.document.selection;\n\t} else {\n\t\tselection = this.createSelection( selectable );\n\t}\n\n\tif ( item && item.is( 'listItem' ) ) {\n\t\t// Get a reference list item. Inserted list items will be fixed according to that item.\n\t\tconst pos = selection.getFirstPosition();\n\t\tlet refItem = null;\n\n\t\tif ( pos.parent.is( 'listItem' ) ) {\n\t\t\trefItem = pos.parent;\n\t\t} else if ( pos.nodeBefore && pos.nodeBefore.is( 'listItem' ) ) {\n\t\t\trefItem = pos.nodeBefore;\n\t\t}\n\n\t\t// If there is `refItem` it means that we do insert list items into an existing list.\n\t\tif ( refItem ) {\n\t\t\t// First list item in `data` has indent equal to 0 (it is a first list item). It should have indent equal\n\t\t\t// to the indent of reference item. We have to fix the first item and all of it's children and following siblings.\n\t\t\t// Indent of all those items has to be adjusted to reference item.\n\t\t\tconst indentChange = refItem.getAttribute( 'listIndent' );\n\n\t\t\t// Fix only if there is anything to fix.\n\t\t\tif ( indentChange > 0 ) {\n\t\t\t\t// Adjust indent of all \"first\" list items in inserted data.\n\t\t\t\twhile ( item && item.is( 'listItem' ) ) {\n\t\t\t\t\titem._setAttribute( 'listIndent', item.getAttribute( 'listIndent' ) + indentChange );\n\n\t\t\t\t\titem = item.nextSibling;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Helper function that creates a `<ul><li></li></ul>` or (`<ol>`) structure out of given `modelItem` model `listItem` element.\n// Then, it binds created view list item (<li>) with model `listItem` element.\n// The function then returns created view list item (<li>).\nfunction generateLiInUl( modelItem, conversionApi ) {\n\tconst mapper = conversionApi.mapper;\n\tconst viewWriter = conversionApi.writer;\n\tconst listType = modelItem.getAttribute( 'listType' ) == 'numbered' ? 'ol' : 'ul';\n\tconst viewItem = createViewListItemElement( viewWriter );\n\n\tconst viewList = viewWriter.createContainerElement( listType, null );\n\tviewWriter.insert( viewWriter.createPositionAt( viewList, 0 ), viewItem );\n\n\tmapper.bindElements( modelItem, viewItem );\n\n\treturn viewItem;\n}\n\n// Helper function that converts children of a given `<li>` view element into corresponding model elements.\n// The function maintains proper order of elements if model `listItem` is split during the conversion\n// due to block children conversion.\n//\n// @param {module:engine/model/element~Element} listItemModel List item model element to which converted children will be inserted.\n// @param {Iterable.<module:engine/view/node~Node>} viewChildren View elements which will be converted.\n// @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface to be used by the callback.\n// @returns {module:engine/model/position~Position} Position on which next elements should be inserted after children conversion.\nfunction viewToModelListItemChildrenConverter( listItemModel, viewChildren, conversionApi ) {\n\tconst { writer, schema } = conversionApi;\n\n\t// A position after the last inserted `listItem`.\n\tlet nextPosition = writer.createPositionAfter( listItemModel );\n\n\t// Check all children of the converted `<li>`. At this point we assume there are no \"whitespace\" view text nodes\n\t// in view list, between view list items. This should be handled by `<ul>` and `<ol>` converters.\n\tfor ( const child of viewChildren ) {\n\t\tif ( child.name == 'ul' || child.name == 'ol' ) {\n\t\t\t// If the children is a list, we will insert its conversion result after currently handled `listItem`.\n\t\t\t// Then, next insertion position will be set after all the new list items (and maybe other elements if\n\t\t\t// something split list item).\n\t\t\t//\n\t\t\t// If this is a list, we expect that some `listItem`s and possibly other blocks will be inserted, however `.modelCursor`\n\t\t\t// should be set after last `listItem` (or block). This is why it feels safe to use it as `nextPosition`\n\t\t\tnextPosition = conversionApi.convertItem( child, nextPosition ).modelCursor;\n\t\t} else {\n\t\t\t// If this is not a list, try inserting content at the end of the currently handled `listItem`.\n\t\t\tconst result = conversionApi.convertItem( child, writer.createPositionAt( listItemModel, 'end' ) );\n\n\t\t\t// It may end up that the current `listItem` becomes split (if that content cannot be inside `listItem`). For example:\n\t\t\t//\n\t\t\t// <li><p>Foo</p></li>\n\t\t\t//\n\t\t\t// will be converted to:\n\t\t\t//\n\t\t\t// <listItem></listItem><paragraph>Foo</paragraph><listItem></listItem>\n\t\t\t//\n\t\t\tconst convertedChild = result.modelRange.start.nodeAfter;\n\t\t\tconst wasSplit = convertedChild && convertedChild.is( 'element' ) && !schema.checkChild( listItemModel, convertedChild.name );\n\n\t\t\tif ( wasSplit ) {\n\t\t\t\t// As `lastListItem` got split, we need to update it to the second part of the split `listItem` element.\n\t\t\t\t//\n\t\t\t\t// `modelCursor` should be set to a position where the conversion should continue. There are multiple possible scenarios\n\t\t\t\t// that may happen. Usually, `modelCursor` (marked as `#` below) would point to the second list item after conversion:\n\t\t\t\t//\n\t\t\t\t//\t\t`<li><p>Foo</p></li>` -> `<listItem></listItem><paragraph>Foo</paragraph><listItem>#</listItem>`\n\t\t\t\t//\n\t\t\t\t// However, in some cases, like auto-paragraphing, the position is placed at the end of the block element:\n\t\t\t\t//\n\t\t\t\t//\t\t`<li><div>Foo</div></li>` -> `<listItem></listItem><paragraph>Foo#</paragraph><listItem></listItem>`\n\t\t\t\t//\n\t\t\t\t// or after an element if another element broken auto-paragraphed element:\n\t\t\t\t//\n\t\t\t\t//\t\t`<li><div><h2>Foo</h2></div></li>` -> `<listItem></listItem><heading1>Foo</heading1>#<listItem></listItem>`\n\t\t\t\t//\n\t\t\t\t// We need to check for such cases and use proper list item and position based on it.\n\t\t\t\t//\n\t\t\t\tif ( result.modelCursor.parent.is( 'listItem' ) ) {\n\t\t\t\t\t// (1).\n\t\t\t\t\tlistItemModel = result.modelCursor.parent;\n\t\t\t\t} else {\n\t\t\t\t\t// (2), (3).\n\t\t\t\t\tlistItemModel = findNextListItem( result.modelCursor );\n\t\t\t\t}\n\n\t\t\t\tnextPosition = writer.createPositionAfter( listItemModel );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nextPosition;\n}\n\n// Helper function that seeks for a next list item starting from given `startPosition`.\nfunction findNextListItem( startPosition ) {\n\tconst treeWalker = new TreeWalker( { startPosition } );\n\n\tlet value;\n\n\tdo {\n\t\tvalue = treeWalker.next();\n\t} while ( !value.value.item.is( 'listItem' ) );\n\n\treturn value.value.item;\n}\n\n// Helper function that seeks for a previous list item sibling of given model item which meets given criteria.\n// `options` object may contain one or more of given values (by default they are `false`):\n// `options.sameIndent` - whether sought sibling should have same indent (default = no),\n// `options.smallerIndent` - whether sought sibling should have smaller indent (default = no).\n// `options.listIndent` - the reference indent.\n// Either `options.sameIndent` or `options.smallerIndent` should be set to `true`.\nfunction getSiblingListItem( modelItem, options ) {\n\tconst sameIndent = !!options.sameIndent;\n\tconst smallerIndent = !!options.smallerIndent;\n\tconst indent = options.listIndent;\n\n\tlet item = modelItem;\n\n\twhile ( item && item.name == 'listItem' ) {\n\t\tconst itemIndent = item.getAttribute( 'listIndent' );\n\n\t\tif ( ( sameIndent && indent == itemIndent ) || ( smallerIndent && indent > itemIndent ) ) {\n\t\t\treturn item;\n\t\t}\n\n\t\titem = item.previousSibling;\n\t}\n\n\treturn null;\n}\n\n// Helper function that takes two parameters, that are expected to be view list elements, and merges them.\n// The merge happen only if both parameters are UL or OL elements.\nfunction mergeViewLists( viewWriter, firstList, secondList ) {\n\tif ( firstList && secondList && ( firstList.name == 'ul' || firstList.name == 'ol' ) && firstList.name == secondList.name ) {\n\t\treturn viewWriter.mergeContainers( viewWriter.createPositionAfter( firstList ) );\n\t}\n\n\treturn null;\n}\n\n// Helper function that takes model list item element `modelItem`, corresponding view list item element `injectedItem`\n// that is not added to the view and is inside a view list element (`ul` or `ol`) and is that's list only child.\n// The list is inserted at correct position (element breaking may be needed) and then merged with it's siblings.\n// See comments below to better understand the algorithm.\nfunction injectViewList( modelItem, injectedItem, conversionApi, model ) {\n\tconst injectedList = injectedItem.parent;\n\tconst mapper = conversionApi.mapper;\n\tconst viewWriter = conversionApi.writer;\n\n\t// Position where view list will be inserted.\n\tlet insertPosition = mapper.toViewPosition( model.createPositionBefore( modelItem ) );\n\n\t// 1. Find previous list item that has same or smaller indent. Basically we are looking for a first model item\n\t// that is \"parent\" or \"sibling\" of injected model item.\n\t// If there is no such list item, it means that injected list item is the first item in \"its list\".\n\tconst refItem = getSiblingListItem( modelItem.previousSibling, {\n\t\tsameIndent: true,\n\t\tsmallerIndent: true,\n\t\tlistIndent: modelItem.getAttribute( 'listIndent' )\n\t} );\n\tconst prevItem = modelItem.previousSibling;\n\n\tif ( refItem && refItem.getAttribute( 'listIndent' ) == modelItem.getAttribute( 'listIndent' ) ) {\n\t\t// There is a list item with same indent - we found same-level sibling.\n\t\t// Break the list after it. Inserted view item will be inserted in the broken space.\n\t\tconst viewItem = mapper.toViewElement( refItem );\n\t\tinsertPosition = viewWriter.breakContainer( viewWriter.createPositionAfter( viewItem ) );\n\t} else {\n\t\t// There is no list item with same indent. Check previous model item.\n\t\tif ( prevItem && prevItem.name == 'listItem' ) {\n\t\t\t// If it is a list item, it has to have lower indent.\n\t\t\t// It means that inserted item should be added to it as its nested item.\n\t\t\tinsertPosition = mapper.toViewPosition( model.createPositionAt( prevItem, 'end' ) );\n\t\t} else {\n\t\t\t// Previous item is not a list item (or does not exist at all).\n\t\t\t// Just map the position and insert the view item at mapped position.\n\t\t\tinsertPosition = mapper.toViewPosition( model.createPositionBefore( modelItem ) );\n\t\t}\n\t}\n\n\tinsertPosition = positionAfterUiElements( insertPosition );\n\n\t// Insert the view item.\n\tviewWriter.insert( insertPosition, injectedList );\n\n\t// 2. Handle possible children of injected model item.\n\tif ( prevItem && prevItem.name == 'listItem' ) {\n\t\tconst prevView = mapper.toViewElement( prevItem );\n\n\t\tconst walkerBoundaries = viewWriter.createRange( viewWriter.createPositionAt( prevView, 0 ), insertPosition );\n\t\tconst walker = walkerBoundaries.getWalker( { ignoreElementEnd: true } );\n\n\t\tfor ( const value of walker ) {\n\t\t\tif ( value.item.is( 'li' ) ) {\n\t\t\t\tconst breakPosition = viewWriter.breakContainer( viewWriter.createPositionBefore( value.item ) );\n\t\t\t\tconst viewList = value.item.parent;\n\n\t\t\t\tconst targetPosition = viewWriter.createPositionAt( injectedItem, 'end' );\n\t\t\t\tmergeViewLists( viewWriter, targetPosition.nodeBefore, targetPosition.nodeAfter );\n\t\t\t\tviewWriter.move( viewWriter.createRangeOn( viewList ), targetPosition );\n\n\t\t\t\twalker.position = breakPosition;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tconst nextViewList = injectedList.nextSibling;\n\n\t\tif ( nextViewList && ( nextViewList.is( 'ul' ) || nextViewList.is( 'ol' ) ) ) {\n\t\t\tlet lastSubChild = null;\n\n\t\t\tfor ( const child of nextViewList.getChildren() ) {\n\t\t\t\tconst modelChild = mapper.toModelElement( child );\n\n\t\t\t\tif ( modelChild && modelChild.getAttribute( 'listIndent' ) > modelItem.getAttribute( 'listIndent' ) ) {\n\t\t\t\t\tlastSubChild = child;\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( lastSubChild ) {\n\t\t\t\tviewWriter.breakContainer( viewWriter.createPositionAfter( lastSubChild ) );\n\t\t\t\tviewWriter.move( viewWriter.createRangeOn( lastSubChild.parent ), viewWriter.createPositionAt( injectedItem, 'end' ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Merge inserted view list with its possible neighbour lists.\n\tmergeViewLists( viewWriter, injectedList, injectedList.nextSibling );\n\tmergeViewLists( viewWriter, injectedList.previousSibling, injectedList );\n}\n\n// Helper function that takes all children of given `viewRemovedItem` and moves them in a correct place, according\n// to other given parameters.\nfunction hoistNestedLists( nextIndent, modelRemoveStartPosition, viewRemoveStartPosition, viewRemovedItem, conversionApi, model ) {\n\t// Find correct previous model list item element.\n\t// The element has to have either same or smaller indent than given reference indent.\n\t// This will be the model element which will get nested items (if it has smaller indent) or sibling items (if it has same indent).\n\t// Keep in mind that such element might not be found, if removed item was the first item.\n\tconst prevModelItem = getSiblingListItem( modelRemoveStartPosition.nodeBefore, {\n\t\tsameIndent: true,\n\t\tsmallerIndent: true,\n\t\tlistIndent: nextIndent,\n\t\tfoo: 'b'\n\t} );\n\n\tconst mapper = conversionApi.mapper;\n\tconst viewWriter = conversionApi.writer;\n\n\t// Indent of found element or `null` if the element has not been found.\n\tconst prevIndent = prevModelItem ? prevModelItem.getAttribute( 'listIndent' ) : null;\n\n\tlet insertPosition;\n\n\tif ( !prevModelItem ) {\n\t\t// If element has not been found, simply insert lists at the position where the removed item was:\n\t\t//\n\t\t// Lorem ipsum.\n\t\t// 1 -------- <--- this is removed, no previous list item, put nested items in place of removed item.\n\t\t// 1.1 -------- <--- this is reference indent.\n\t\t// 1.1.1 --------\n\t\t// 1.1.2 --------\n\t\t// 1.2 --------\n\t\t//\n\t\t// Becomes:\n\t\t//\n\t\t// Lorem ipsum.\n\t\t// 1.1 --------\n\t\t// 1.1.1 --------\n\t\t// 1.1.2 --------\n\t\t// 1.2 --------\n\t\tinsertPosition = viewRemoveStartPosition;\n\t} else if ( prevIndent == nextIndent ) {\n\t\t// If element has been found and has same indent as reference indent it means that nested items should\n\t\t// become siblings of found element:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.2 -------- <--- this is `prevModelItem`.\n\t\t// 2 -------- <--- this is removed, previous list item has indent same as reference indent.\n\t\t// 2.1 -------- <--- this is reference indent, this and 2.2 should become siblings of 1.2.\n\t\t// 2.2 --------\n\t\t//\n\t\t// Becomes:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.2 --------\n\t\t// 2.1 --------\n\t\t// 2.2 --------\n\t\tconst prevViewList = mapper.toViewElement( prevModelItem ).parent;\n\t\tinsertPosition = viewWriter.createPositionAfter( prevViewList );\n\t} else {\n\t\t// If element has been found and has smaller indent as reference indent it means that nested items\n\t\t// should become nested items of found item:\n\t\t//\n\t\t// 1 -------- <--- this is `prevModelItem`.\n\t\t// 1.1 -------- <--- this is removed, previous list item has indent smaller than reference indent.\n\t\t// 1.1.1 -------- <--- this is reference indent, this and 1.1.1 should become nested items of 1.\n\t\t// 1.1.2 --------\n\t\t// 1.2 --------\n\t\t//\n\t\t// Becomes:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1.1 --------\n\t\t// 1.1.2 --------\n\t\t// 1.2 --------\n\t\t//\n\t\t// Note: in this case 1.1.1 have indent 2 while 1 have indent 0. In model that should not be possible,\n\t\t// because following item may have indent bigger only by one. But this is fixed by postfixer.\n\t\tconst modelPosition = model.createPositionAt( prevModelItem, 'end' );\n\t\tinsertPosition = mapper.toViewPosition( modelPosition );\n\t}\n\n\tinsertPosition = positionAfterUiElements( insertPosition );\n\n\t// Handle multiple lists. This happens if list item has nested numbered and bulleted lists. Following lists\n\t// are inserted after the first list (no need to recalculate insertion position for them).\n\tfor ( const child of [ ...viewRemovedItem.getChildren() ] ) {\n\t\tif ( child.is( 'ul' ) || child.is( 'ol' ) ) {\n\t\t\tinsertPosition = viewWriter.move( viewWriter.createRangeOn( child ), insertPosition ).end;\n\n\t\t\tmergeViewLists( viewWriter, child, child.nextSibling );\n\t\t\tmergeViewLists( viewWriter, child.previousSibling, child );\n\t\t}\n\t}\n}\n\n// Helper function that for given `view.Position`, returns a `view.Position` that is after all `view.UIElement`s that\n// are after given position.\n// For example:\n// <container:p>foo^<ui:span></ui:span><ui:span></ui:span>bar</contain:p>\n// For position ^, a position before \"bar\" will be returned.\nfunction positionAfterUiElements( viewPosition ) {\n\treturn viewPosition.getLastMatchingPosition( value => value.item.is( 'uiElement' ) );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module list/listediting\n */\n\nimport ListCommand from './listcommand';\nimport IndentCommand from './indentcommand';\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';\n\nimport {\n\tcleanList,\n\tcleanListItem,\n\tmodelViewInsertion,\n\tmodelViewChangeType,\n\tmodelViewMergeAfter,\n\tmodelViewRemove,\n\tmodelViewSplitOnInsert,\n\tmodelViewChangeIndent,\n\tmodelChangePostFixer,\n\tmodelIndentPasteFixer,\n\tviewModelConverter,\n\tmodelToViewPosition,\n\tviewToModelPosition\n} from './converters';\n\n/**\n * The engine of the list feature. It handles creating, editing and removing lists and list items.\n *\n * It registers the `'numberedList'`, `'bulletedList'`, `'indentList'` and `'outdentList'` commands.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ListEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ Paragraph ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\n\t\t// Schema.\n\t\t// Note: in case `$block` will ever be allowed in `listItem`, keep in mind that this feature\n\t\t// uses `Selection#getSelectedBlocks()` without any additional processing to obtain all selected list items.\n\t\t// If there are blocks allowed inside list item, algorithms using `getSelectedBlocks()` will have to be modified.\n\t\teditor.model.schema.register( 'listItem', {\n\t\t\tinheritAllFrom: '$block',\n\t\t\tallowAttributes: [ 'listType', 'listIndent' ]\n\t\t} );\n\n\t\t// Converters.\n\t\tconst data = editor.data;\n\t\tconst editing = editor.editing;\n\n\t\teditor.model.document.registerPostFixer( writer => modelChangePostFixer( editor.model, writer ) );\n\n\t\tediting.mapper.registerViewToModelLength( 'li', getViewListItemLength );\n\t\tdata.mapper.registerViewToModelLength( 'li', getViewListItemLength );\n\n\t\tediting.mapper.on( 'modelToViewPosition', modelToViewPosition( editing.view ) );\n\t\tediting.mapper.on( 'viewToModelPosition', viewToModelPosition( editor.model ) );\n\t\tdata.mapper.on( 'modelToViewPosition', modelToViewPosition( editing.view ) );\n\n\t\tediting.downcastDispatcher.on( 'insert', modelViewSplitOnInsert, { priority: 'high' } );\n\t\tediting.downcastDispatcher.on( 'insert:listItem', modelViewInsertion( editor.model ) );\n\t\tdata.downcastDispatcher.on( 'insert', modelViewSplitOnInsert, { priority: 'high' } );\n\t\tdata.downcastDispatcher.on( 'insert:listItem', modelViewInsertion( editor.model ) );\n\n\t\tediting.downcastDispatcher.on( 'attribute:listType:listItem', modelViewChangeType );\n\t\tdata.downcastDispatcher.on( 'attribute:listType:listItem', modelViewChangeType );\n\t\tediting.downcastDispatcher.on( 'attribute:listIndent:listItem', modelViewChangeIndent( editor.model ) );\n\t\tdata.downcastDispatcher.on( 'attribute:listIndent:listItem', modelViewChangeIndent( editor.model ) );\n\n\t\tediting.downcastDispatcher.on( 'remove:listItem', modelViewRemove( editor.model ) );\n\t\tediting.downcastDispatcher.on( 'remove', modelViewMergeAfter, { priority: 'low' } );\n\t\tdata.downcastDispatcher.on( 'remove:listItem', modelViewRemove( editor.model ) );\n\t\tdata.downcastDispatcher.on( 'remove', modelViewMergeAfter, { priority: 'low' } );\n\n\t\tdata.upcastDispatcher.on( 'element:ul', cleanList, { priority: 'high' } );\n\t\tdata.upcastDispatcher.on( 'element:ol', cleanList, { priority: 'high' } );\n\t\tdata.upcastDispatcher.on( 'element:li', cleanListItem, { priority: 'high' } );\n\t\tdata.upcastDispatcher.on( 'element:li', viewModelConverter );\n\n\t\t// Fix indentation of pasted items.\n\t\teditor.model.on( 'insertContent', modelIndentPasteFixer, { priority: 'high' } );\n\n\t\t// Register commands for numbered and bulleted list.\n\t\teditor.commands.add( 'numberedList', new ListCommand( editor, 'numbered' ) );\n\t\teditor.commands.add( 'bulletedList', new ListCommand( editor, 'bulleted' ) );\n\n\t\t// Register commands for indenting.\n\t\teditor.commands.add( 'indentList', new IndentCommand( editor, 'forward' ) );\n\t\teditor.commands.add( 'outdentList', new IndentCommand( editor, 'backward' ) );\n\n\t\tconst viewDocument = this.editor.editing.view.document;\n\n\t\t// Overwrite default Enter key behavior.\n\t\t// If Enter key is pressed with selection collapsed in empty list item, outdent it instead of breaking it.\n\t\tthis.listenTo( viewDocument, 'enter', ( evt, data ) => {\n\t\t\tconst doc = this.editor.model.document;\n\t\t\tconst positionParent = doc.selection.getLastPosition().parent;\n\n\t\t\tif ( doc.selection.isCollapsed && positionParent.name == 'listItem' && positionParent.isEmpty ) {\n\t\t\t\tthis.editor.execute( 'outdentList' );\n\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t} );\n\n\t\t// Overwrite default Backspace key behavior.\n\t\t// If Backspace key is pressed with selection collapsed on first position in first list item, outdent it. #83\n\t\tthis.listenTo( viewDocument, 'delete', ( evt, data ) => {\n\t\t\t// Check conditions from those that require less computations like those immediately available.\n\t\t\tif ( data.direction !== 'backward' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst selection = this.editor.model.document.selection;\n\n\t\t\tif ( !selection.isCollapsed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst firstPosition = selection.getFirstPosition();\n\n\t\t\tif ( !firstPosition.isAtStart ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst positionParent = firstPosition.parent;\n\n\t\t\tif ( positionParent.name !== 'listItem' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst previousIsAListItem = positionParent.previousSibling && positionParent.previousSibling.name === 'listItem';\n\n\t\t\tif ( previousIsAListItem ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.editor.execute( 'outdentList' );\n\n\t\t\tdata.preventDefault();\n\t\t\tevt.stop();\n\t\t}, { priority: 'high' } );\n\n\t\tconst getCommandExecuter = commandName => {\n\t\t\treturn ( data, cancel ) => {\n\t\t\t\tconst command = this.editor.commands.get( commandName );\n\n\t\t\t\tif ( command.isEnabled ) {\n\t\t\t\t\tthis.editor.execute( commandName );\n\t\t\t\t\tcancel();\n\t\t\t\t}\n\t\t\t};\n\t\t};\n\n\t\tthis.editor.keystrokes.set( 'Tab', getCommandExecuter( 'indentList' ) );\n\t\tthis.editor.keystrokes.set( 'Shift+Tab', getCommandExecuter( 'outdentList' ) );\n\t}\n}\n\nfunction getViewListItemLength( element ) {\n\tlet length = 1;\n\n\tfor ( const child of element.getChildren() ) {\n\t\tif ( child.name == 'ul' || child.name == 'ol' ) {\n\t\t\tfor ( const item of child.getChildren() ) {\n\t\t\t\tlength += getViewListItemLength( item );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn length;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module list/listui\n */\nimport numberedListIcon from '../theme/icons/numberedlist.svg';\nimport bulletedListIcon from '../theme/icons/bulletedlist.svg';\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\n/**\n * The list UI feature. It introduces the `'numberedList'` and `'bulletedList'` buttons that\n * allow to convert paragraphs to and from list items and indent or outdent them.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ListUI extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n init() {\n // Create two buttons and link them with numberedList and bulletedList commands.\n const t = this.editor.t;\n this._addButton('numberedList', t('al'), numberedListIcon);\n this._addButton('bulletedList', t('am'), bulletedListIcon);\n }\n /**\n\t * Helper method for initializing a button and linking it with an appropriate command.\n\t *\n\t * @private\n\t * @param {String} commandName The name of the command.\n\t * @param {Object} label The button label.\n\t * @param {String} icon The source of the icon.\n\t */\n _addButton(commandName, label, icon) {\n const editor = this.editor;\n editor.ui.componentFactory.add(commandName, locale => {\n const command = editor.commands.get(commandName);\n const buttonView = new ButtonView(locale);\n buttonView.set({\n label,\n icon,\n tooltip: true\n });\n // Bind button model to command.\n buttonView.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');\n // Execute command.\n this.listenTo(buttonView, 'execute', () => editor.execute(commandName));\n return buttonView;\n });\n }\n}","import ViewPosition from '@ckeditor/ckeditor5-engine/src/view/position';\nimport {toWidget, isWidget} from '@ckeditor/ckeditor5-widget/src/utils';\nimport {setContent} from './widget';\n\nconst codeBlockSymbol = Symbol( 'isOPCodeBlock' );\n\nexport function toCodeBlockWidget( viewElement, writer, label ) {\n\twriter.setCustomProperty( codeBlockSymbol, true, viewElement );\n\treturn toWidget( viewElement, writer, { label: label } );\n}\n\n\nexport function isCodeBlockWidget( viewElement ) {\n\treturn !!viewElement.getCustomProperty( codeBlockSymbol ) && isWidget( viewElement );\n}\n\n\nexport function isCodeBlockWidgetSelected( selection ) {\n\tconst viewElement = selection.getSelectedElement();\n\n\treturn !!( viewElement && isCodeBlockWidget( viewElement ) );\n}\n\nexport function createCodeBlockWidget( modelElement, writer, label ) {\n\tconst container = writer.createContainerElement(\n\t\t'div',\n\t\t{\n\t\t\tclass: 'op-ckeditor--code-block',\n\t\t\ttitle: window.I18n.t('js.editor.macro.toolbar_help')\n\t\t}\n\t);\n\trenderCodeBlockContent( writer, modelElement, container );\n\n\treturn toCodeBlockWidget( container, writer, label );\n}\n\nexport function renderCodeBlockContent( writer, modelElement, container ) {\n\t// Append language element\n\tconst languageClass = modelElement.getAttribute( 'opCodeblockLanguage' ) || 'language-text';\n\tconst language = languageClass.replace(/^language-/, '');\n\tconst langElement = writer.createContainerElement( 'div', { class: 'op-ckeditor--code-block-language' } );\n\tsetTextNode( writer, language, langElement, 'text' );\n\twriter.insert( writer.createPositionAt( container, 0 ), langElement );\n\n\t// Append code block content\n\tconst content = modelElement.getAttribute( 'opCodeblockContent' );\n\tsetTextNode( writer, content, container, '(empty)' );\n}\n\nexport function setTextNode( writer, content, container, empty_text ) {\n const placeholder = writer.createText( content || empty_text );\n writer.insert( writer.createPositionAt( container, 0 ), placeholder );\n}\n","import DomEventObserver from \"@ckeditor/ckeditor5-engine/src/view/observer/domeventobserver\";\n\nexport default class DoubleClickObserver extends DomEventObserver {\n\tconstructor( view ) {\n\t\tsuper( view );\n\n\t\tthis.domEventType = 'dblclick';\n\t}\n\n\tonDomEvent( domEvent ) {\n\t\tthis.fire( domEvent.type, domEvent );\n\t}\n}\n","import icon from '../../icons/code-block.svg';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport {modelCodeBlockToView, viewCodeBlockToModel, codeBlockContentToView} from './converters';\nimport {createCodeBlockWidget, isCodeBlockWidget} from './widget';\nimport DoubleClickObserver from './click-observer';\nimport { getPluginContext } from '../op-context/op-context';\n\nexport default class CodeBlockEditing extends Plugin {\n\n\tstatic get pluginName() {\n\t\treturn 'CodeBlockEditing';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\t\tconst conversion = editor.conversion;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\t\tconst pluginContext = getPluginContext(editor);\n\n\t\t// Configure schema.\n\t\tschema.register('codeblock', {\n\t\t\tisObject: true,\n\t\t\tisBlock: true,\n\t\t\tallowContentOf: '$block',\n\t\t\tallowWhere: ['$root', '$block'],\n\t\t\tallowIn: ['$root'],\n\t\t\tallowAttributes: ['opCodeblockLanguage', 'opCodeblockContent']\n\t\t});\n\n\t\tconversion.for( 'upcast' )\n\t\t\t.add(viewCodeBlockToModel());\n\n\t\tconversion.for( 'editingDowncast' )\n\t\t\t.elementToElement( {\n\t\t\t\tmodel: 'codeblock',\n\t\t\t\tview: (modelElement, viewWriter) => {\n\t\t\t\t\treturn createCodeBlockWidget( modelElement, viewWriter, 'Code block' );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.add ( codeBlockContentToView() );\n\n\t\tconversion\n\t\t\t.for('dataDowncast')\n\t\t\t.add(modelCodeBlockToView());\n\n\t\t// Register click handler to code block to edit it immediately\n\t\tview.addObserver( DoubleClickObserver );\n\t\tthis.listenTo( viewDocument, 'dblclick', ( eventInfo, domEventData ) => {\n\t\t\tlet element = domEventData.target;\n\t\t\tlet evt = domEventData.domEvent;\n\n\t\t\t// Avoid opening the widget with modifiers selected to allow selecting the widget\n\t\t\tif (evt.shiftKey || evt.altKey || evt.metaKey) {\n\t\t\t\treturn;\n\t\t\t}\n\n\n\t\t\t// If target is our widget\n\t\t\tif ( !isCodeBlockWidget( element ) ) {\n\t\t\t\telement = element.findAncestor( isCodeBlockWidget );\n\n\t\t\t\tif ( !element ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdomEventData.preventDefault();\n\t\t\tdomEventData.stopPropagation();\n\n\t\t\t// Create model selection over widget.\n\t\t\tconst modelElement = editor.editing.mapper.toModelElement( element );\n\n\t\t\tconst macroService = pluginContext.services.macros;\n\t\t\tconst language = modelElement.getAttribute( 'opCodeblockLanguage' );\n\t\t\tconst content = modelElement.getAttribute( 'opCodeblockContent' );\n\n\t\t\tmacroService\n\t\t\t\t.editCodeBlock( content, language )\n\t\t\t\t.then((update) => editor.model.change(writer => {\n\t\t\t\t\twriter.setAttribute( 'opCodeblockLanguage', update.languageClass, modelElement );\n\t\t\t\t\twriter.setAttribute( 'opCodeblockContent', update.content, modelElement );\n\t\t\t\t})\n\t\t\t);\n\n\t\t} );\n\n\t\t// Register toolbar button to create code block\n\t\teditor.ui.componentFactory.add( 'insertCodeBlock', locale => {\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\tlabel: window.I18n.t('js.editor.macro.code_block.button'),\n\t\t\t\ticon: icon,\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\t// Callback executed once the image is clicked.\n\t\t\tview.on( 'execute', () => {\n\t\t\t\tpluginContext.services.macros\n\t\t\t\t\t.editCodeBlock()\n\t\t\t\t\t.then((update) => editor.model.change(writer => {\n\n\t\t\t\t\t\tconst element = writer.createElement( 'codeblock' );\n\t\t\t\t\t\twriter.setAttribute( 'opCodeblockLanguage', update.languageClass, element );\n\t\t\t\t\t\twriter.setAttribute( 'opCodeblockContent', update.content, element );\n\t\t\t\t\t\teditor.model.insertContent( element, editor.model.document.selection );\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t} );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n}\n","import ModelPosition from '@ckeditor/ckeditor5-engine/src/model/position';\nimport ModelRange from '@ckeditor/ckeditor5-engine/src/model/range';\nimport ViewPosition from '@ckeditor/ckeditor5-engine/src/view/position';\nimport ViewRange from '@ckeditor/ckeditor5-engine/src/view/range';\nimport {renderCodeBlockContent} from './widget';\n\n\nexport function modelCodeBlockToView() {\n\treturn dispatcher => {\n\t\tdispatcher.on( 'insert:codeblock', converter, { priority: 'high' } );\n\t};\n\n\tfunction converter( evt, data, conversionApi ) {\n\t\tconst codeBlock = data.item;\n\t\tconst language = codeBlock.getAttribute('opCodeblockLanguage') || 'language-text';\n\t\tconst content = codeBlock.getAttribute('opCodeblockContent');\n\n\t\t// Consume the codeblock and text\n\t\tconversionApi.consumable.consume( codeBlock, 'insert' );\n\n\t\t// Wrap the element in a <pre> <code> block\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst preElement = viewWriter.createContainerElement( 'pre' );\n\t\tconst langElement = viewWriter.createContainerElement( 'div', { class: 'op-ckeditor--code-block-language' } );\n\t\tconst codeElement = viewWriter.createContainerElement( 'code', { class: language } );\n\t\tconst langContent = viewWriter.createText( language );\n\t\tconst contentElement = viewWriter.createText( content );\n\n\t\tviewWriter.insert( viewWriter.createPositionAt( codeElement, 0 ), contentElement );\n\t\tviewWriter.insert( viewWriter.createPositionAt( langElement, 0 ), langContent );\n\t\tviewWriter.insert( viewWriter.createPositionAt( preElement, 0 ), langElement );\n\t\tviewWriter.insert( viewWriter.createPositionAt( preElement, 0 ), codeElement );\n\n\t\tconversionApi.mapper.bindElements( codeBlock, codeElement );\n\t\tconversionApi.mapper.bindElements( codeBlock, preElement );\n\n\t\t// Insert at matching position\n\t\tconst insertPosition = conversionApi.mapper.toViewPosition( data.range.start );\n\t\tviewWriter.insert( insertPosition, preElement );\n\n\t\tevt.stop();\n\t}\n}\n\nexport function viewCodeBlockToModel() {\n\treturn dispatcher => {\n\t\tdispatcher.on( 'element:pre', converter, { priority: 'high' } );\n\t};\n\n\tfunction converter( evt, data, conversionApi ) {\n\t\t// Do not convert if this is not an \"image figure\".\n\t\tif ( !conversionApi.consumable.test( data.viewItem, { name: true } ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Find an code element inside the pre element.\n\t\tconst codeBlock = Array.from( data.viewItem.getChildren() ).find( viewChild => viewChild.is( 'code' ) );\n\n\t\t// Do not convert if code block is absent\n\t\tif ( !codeBlock || !conversionApi.consumable.consume( codeBlock, { name: true } ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Create the model element\n\t\tconst modelCodeBlock = conversionApi.writer.createElement( 'codeblock' );\n\t\tconversionApi.writer.setAttribute( 'opCodeblockLanguage', codeBlock.getAttribute('class'), modelCodeBlock );\n\n\t\t// Find allowed parent for paragraph that we are going to insert. If current parent does not allow\n\t\t// to insert paragraph but one of the ancestors does then split nodes to allowed parent.\n\t\tconst splitResult = conversionApi.splitToAllowedParent( modelCodeBlock, data.modelCursor );\n\n\t\t// When there is no split result it means that we can't insert paragraph in this position.\n\t\tif ( splitResult ) {\n\t\t\t// Insert codeblock in allowed position.\n\t\t\tconversionApi.writer.insert( modelCodeBlock, splitResult.position );\n\n\t\t\t// Convert text child of codeblock\n\t\t\tconst child = codeBlock.getChild(0);\n\t\t\tconversionApi.consumable.consume( child, { name: true } );\n\t\t\t// Replace last newline since that text is incorrectly mapped\n\t\t\t// Regression OP#28609\n\t\t\tconst content = child.data.replace(/\\n$/, \"\");\n\t\t\tconversionApi.writer.setAttribute( 'opCodeblockContent', content, modelCodeBlock );\n\n\t\t\t// Set as conversion result, attribute converters may use this property.\n\t\t\tdata.modelRange = new ModelRange(\n\t\t\t\tconversionApi.writer.createPositionBefore( modelCodeBlock ),\n\t\t\t\tconversionApi.writer.createPositionAfter( modelCodeBlock )\n\t\t\t);\n\n\t\t\t// Convert after pre element\n\t\t\tdata.modelCursor = data.modelRange.end;\n\t\t}\n\t}\n}\n\n\nexport function codeBlockContentToView() {\n\treturn dispatcher => {\n\t\tdispatcher.on( 'attribute:opCodeblockContent', converter );\n\t\tdispatcher.on( 'attribute:opCodeblockLanguage', converter );\n\t};\n\n\tfunction converter( evt, data, conversionApi ) {\n const modelElement = data.item;\n\n // Mark element as consumed by conversion.\n conversionApi.consumable.consume( data.item, evt.name );\n\n // Get mapped view element to update.\n const viewElement = conversionApi.mapper.toViewElement( modelElement );\n\n // Remove current <div> element contents.\n conversionApi.writer.remove( conversionApi.writer.createRangeOn( viewElement.getChild( 1 ) ) );\n conversionApi.writer.remove( conversionApi.writer.createRangeOn( viewElement.getChild( 0 ) ) );\n\n\t\t// Set current content\n\t\trenderCodeBlockContent( conversionApi.writer, modelElement, viewElement );\n\t}\n}\n","import Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ContextualBalloon from '@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon';\n\nimport {createToolbarEditButton} from '../../helpers/create-toolbar-edit-button';\nimport {createEditToolbar} from '../../helpers/create-toolbar';\nimport {isCodeBlockWidgetSelected} from './widget';\nimport {getPluginContext} from '../op-context/op-context';\n\nexport default class CodeBlockToolbar extends Plugin {\n\tstatic get requires() {\n\t\treturn [ ContextualBalloon ];\n\t}\n\n\tstatic get pluginName() {\n\t\treturn 'CodeBlockToolbar';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = this.editor.model;\n\t\tconst pluginContext = getPluginContext(editor);\n\n\t\t// Add editing button\n\t\tcreateToolbarEditButton( editor, 'opEditCodeBlock', widget => {\n\t\t\tconst macroService = pluginContext.services.macros;\n\t\t\tconst language = widget.getAttribute( 'opCodeblockLanguage' );\n\t\t\tconst content = widget.getAttribute( 'opCodeblockContent' );\n\n\t\t\tmacroService\n\t\t\t\t.editCodeBlock( content, language )\n\t\t\t\t.then((update) => model.change(writer => {\n\t\t\t\t\twriter.setAttribute( 'opCodeblockLanguage', update.languageClass, widget );\n\t\t\t\t\twriter.setAttribute( 'opCodeblockContent', update.content, widget );\n\t\t\t\t})\n\t\t\t);\n\t\t} );\n\t}\n\n\tafterInit() {\n\t\t// Add actual toolbar\n\t\tcreateEditToolbar(\n\t\t\tthis,\n\t\t\tthis.editor,\n\t\t\t'OPCodeBlock',\n\t\t\tisCodeBlockWidgetSelected\n\t\t);\n\t}\n}\n","import FileDialogButtonView from '@ckeditor/ckeditor5-upload/src/ui/filedialogbuttonview';\n\nexport function getToolbarItems(editor) {\n\teditor.__currentlyDisabled = editor.__currentlyDisabled || [];\n\n\tif (!editor.ui.view.toolbar) {\n\t\treturn [];\n\t}\n\n\treturn editor.ui.view.toolbar.items._items;\n}\n\nexport function disableItems(editor, except) {\n\tjQuery.each(getToolbarItems(editor), function(index, item) {\n\t\tlet toDisable = item;\n\n\t\tif (item instanceof FileDialogButtonView) {\n\t\t\ttoDisable = item.buttonView;\n\t\t} else if (item === except || !item.hasOwnProperty('isEnabled')) {\n\t\t\ttoDisable = null;\n\t\t}\n\n\t\tif (!toDisable) {\n\t\t\t// do nothing\n\t\t} else if (toDisable.isEnabled) {\n\t\t\ttoDisable.isEnabled = false;\n\t\t} else {\n\t\t\teditor.__currentlyDisabled.push(toDisable);\n\t\t}\n\t});\n}\n\nexport function enableItems(editor) {\n\tjQuery.each(getToolbarItems(editor), function(index, item) {\n\t\tlet toEnable = item;\n\n\t\tif (item instanceof FileDialogButtonView) {\n\t\t\ttoEnable = item.buttonView;\n\t\t}\n\n\t\tif (editor.__currentlyDisabled.indexOf(toEnable) < 0) {\n\t\t\ttoEnable.isEnabled = true\n\t\t}\n\t});\n\n\teditor.__currentlyDisabled = [];\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/plugin\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor plugin classes.\n *\n * @implements module:core/plugin~PluginInterface\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * Note that most editors implement the {@link module:core/editor/editorwithui~EditorWithUI} interface in addition\n\t\t * to the base {@link module:core/editor/editor~Editor} interface. However, editors with an external UI\n\t\t * (i.e. Bootstrap-based) or a headless editor may not implement the {@link module:core/editor/editorwithui~EditorWithUI}\n\t\t * interface.\n\t\t *\n\t\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t\t * - The \"editing\" part that only uses the {@link module:core/editor/editor~Editor} interface.\n\t\t * - The \"UI\" part that uses both the {@link module:core/editor/editor~Editor} interface and\n\t\t * the {@link module:core/editor/editorwithui~EditorWithUI} interface.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor} #editor\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n}\n\nmix( Plugin, ObservableMixin );\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form it can be a simple function (it will be used as a constructor) that accepts\n * {@link module:core/editor/editor~Editor the editor} as a parameter.\n * It can also implement a few methods which, when present, will be used to properly initialize and destroy the plugin.\n *\n *\t\t// A simple plugin that enables a data processor.\n *\t\tfunction MyPlugin( editor ) {\n *\t\t\teditor.data.processor = new MyDataProcessor();\n *\t\t}\n *\n * In most cases, however, you will want to inherit from the {@link module:core/plugin~Plugin} class which implements the\n * {@link module:utils/observablemixin~ObservableMixin} and is, therefore, more convenient:\n *\n *\t\tclass MyPlugin extends Plugin {\n *\t\t\tinit() {\n *\t\t\t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n *\t\t\t\t// By using `listenTo()` you will ensure that the listener is removed when\n *\t\t\t\t// the plugin is destroyed.\n *\t\t\t\tthis.listenTo( this.editor.data, 'ready', () => {\n *\t\t\t\t\t// Do something when the data is ready.\n *\t\t\t\t} );\n *\t\t\t}\n *\t\t}\n *\n * @interface PluginInterface\n */\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link #init} and {@link #afterInit}.\n *\n * A plugin is always instantiated after its {@link module:core/plugin~PluginInterface.requires dependencies} and the\n * {@link #init} and {@link #afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link #init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link #afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link module:core/plugin~PluginInterface.requires explicitly require} them).\n *\n * @method #constructor\n * @param {module:core/editor/editor~Editor} editor\n */\n\n/**\n * An array of plugins required by this plugin.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\timport Image from './image.js';\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get requires() {\n *\t\t\t\treturn [ Image ];\n *\t\t\t}\n *\t\t}\n *\n * @static\n * @readonly\n * @member {Array.<Function>|undefined} module:core/plugin~PluginInterface.requires\n */\n\n/**\n * An optional name of the plugin. If set, the plugin will be available in\n * {@link module:core/plugincollection~PluginCollection#get} by its\n * name and its constructor. If not, then only by its constructor.\n *\n * The name should reflect the constructor name.\n *\n * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n *\n *\t\texport default class ImageCaption {\n *\t\t\tstatic get pluginName() {\n *\t\t\t\treturn 'ImageCaption';\n *\t\t\t}\n *\t\t}\n *\n * Note: The native `Function.name` property could not be used to keep the plugin name because\n * it will be mangled during code minification.\n *\n * Naming a plugin is necessary to enable removing it through the\n * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n *\n * @static\n * @readonly\n * @member {String|undefined} module:core/plugin~PluginInterface.pluginName\n */\n\n/**\n * The second stage (after plugin {@link #constructor}) of plugin initialization.\n * Unlike the plugin constructor this method can be asynchronous.\n *\n * A plugin's `init()` method is called after its {@link module:core/plugin~PluginInterface.requires dependencies} are initialized,\n * so in the same order as constructors of these plugins.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #init\n * @returns {null|Promise}\n */\n\n/**\n * The third (and last) stage of plugin initialization. See also {@link #constructor} and {@link #init}.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #afterInit\n * @returns {null|Promise}\n */\n\n/**\n * Destroys the plugin.\n *\n * **Note:** This method is optional. A plugin instance does not need to have it defined.\n *\n * @method #destroy\n * @returns {null|Promise}\n */\n\n/**\n * Array of loaded plugins.\n *\n * @typedef {Array.<module:core/plugin~PluginInterface>} module:core/plugin~LoadedPlugins\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/commands/utils\n */\n\n/**\n * Returns the parent element of given name. Returns undefined if position is not inside desired parent.\n *\n * @param {String} parentName Name of parent element to find.\n * @param {module:engine/model/position~Position|module:engine/model/position~Position} position Position to start searching.\n * @returns {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment}\n */\nexport function findAncestor( parentName, position ) {\n\tlet parent = position.parent;\n\n\twhile ( parent ) {\n\t\tif ( parent.name === parentName ) {\n\t\t\treturn parent;\n\t\t}\n\n\t\tparent = parent.parent;\n\t}\n}\n\n/**\n * A common method to update the numeric value. If a value is the default one, it will be unset.\n *\n * @param {String} key Attribute key.\n * @param {*} value The new attribute value.\n * @param {module:engine/model/item~Item} item Model item on which the attribute will be set.\n * @param {module:engine/model/writer~Writer} writer\n * @param {*} defaultValue Default attribute value. If a value is lower or equal, it will be unset.\n */\nexport function updateNumericAttribute( key, value, item, writer, defaultValue = 1 ) {\n\tif ( value > defaultValue ) {\n\t\twriter.setAttribute( key, value, item );\n\t} else {\n\t\twriter.removeAttribute( key, item );\n\t}\n}\n\n/**\n * Common method to create empty table cell - it will create proper model structure as table cell must have at least one block inside.\n *\n * @param {module:engine/model/writer~Writer} writer Model writer.\n * @param {module:engine/model/position~Position} insertPosition Position at which table cell should be inserted.\n * @param {Object} attributes Element's attributes.\n */\nexport function createEmptyTableCell( writer, insertPosition, attributes = {} ) {\n\tconst tableCell = writer.createElement( 'tableCell', attributes );\n\twriter.insertElement( 'paragraph', tableCell );\n\twriter.insert( tableCell, insertPosition );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/converters/upcasttable\n */\n\nimport { createEmptyTableCell } from '../commands/utils';\n\n/**\n * View table element to model table element conversion helper.\n *\n * This conversion helper converts the table element as well as table rows.\n *\n * @returns {Function} Conversion helper.\n */\nexport default function upcastTable() {\n\treturn dispatcher => {\n\t\tdispatcher.on( 'element:table', ( evt, data, conversionApi ) => {\n\t\t\tconst viewTable = data.viewItem;\n\n\t\t\t// When element was already consumed then skip it.\n\t\t\tif ( !conversionApi.consumable.test( viewTable, { name: true } ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { rows, headingRows, headingColumns } = scanTable( viewTable );\n\n\t\t\t// Only set attributes if values is greater then 0.\n\t\t\tconst attributes = {};\n\n\t\t\tif ( headingColumns ) {\n\t\t\t\tattributes.headingColumns = headingColumns;\n\t\t\t}\n\n\t\t\tif ( headingRows ) {\n\t\t\t\tattributes.headingRows = headingRows;\n\t\t\t}\n\n\t\t\tconst table = conversionApi.writer.createElement( 'table', attributes );\n\n\t\t\t// Insert element on allowed position.\n\t\t\tconst splitResult = conversionApi.splitToAllowedParent( table, data.modelCursor );\n\n\t\t\t// When there is no split result it means that we can't insert element to model tree, so let's skip it.\n\t\t\tif ( !splitResult ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconversionApi.writer.insert( table, splitResult.position );\n\t\t\tconversionApi.consumable.consume( viewTable, { name: true } );\n\n\t\t\tif ( rows.length ) {\n\t\t\t\t// Upcast table rows in proper order (heading rows first).\n\t\t\t\trows.forEach( row => conversionApi.convertItem( row, conversionApi.writer.createPositionAt( table, 'end' ) ) );\n\t\t\t} else {\n\t\t\t\t// Create one row and one table cell for empty table.\n\t\t\t\tconst row = conversionApi.writer.createElement( 'tableRow' );\n\t\t\t\tconversionApi.writer.insert( row, conversionApi.writer.createPositionAt( table, 'end' ) );\n\n\t\t\t\tcreateEmptyTableCell( conversionApi.writer, conversionApi.writer.createPositionAt( row, 'end' ) );\n\t\t\t}\n\n\t\t\t// Set conversion result range.\n\t\t\tdata.modelRange = conversionApi.writer.createRange(\n\t\t\t\t// Range should start before inserted element\n\t\t\t\tconversionApi.writer.createPositionBefore( table ),\n\t\t\t\t// Should end after but we need to take into consideration that children could split our\n\t\t\t\t// element, so we need to move range after parent of the last converted child.\n\t\t\t\t// before: <allowed>[]</allowed>\n\t\t\t\t// after: <allowed>[<converted><child></child></converted><child></child><converted>]</converted></allowed>\n\t\t\t\tconversionApi.writer.createPositionAfter( table )\n\t\t\t);\n\n\t\t\t// Now we need to check where the modelCursor should be.\n\t\t\t// If we had to split parent to insert our element then we want to continue conversion inside split parent.\n\t\t\t//\n\t\t\t// before: <allowed><notAllowed>[]</notAllowed></allowed>\n\t\t\t// after: <allowed><notAllowed></notAllowed><converted></converted><notAllowed>[]</notAllowed></allowed>\n\t\t\tif ( splitResult.cursorParent ) {\n\t\t\t\tdata.modelCursor = conversionApi.writer.createPositionAt( splitResult.cursorParent, 0 );\n\n\t\t\t\t// Otherwise just continue after inserted element.\n\t\t\t} else {\n\t\t\t\tdata.modelCursor = data.modelRange.end;\n\t\t\t}\n\t\t} );\n\t};\n}\n\nexport function upcastTableCell( elementName ) {\n\treturn dispatcher => {\n\t\tdispatcher.on( `element:${ elementName }`, ( evt, data, conversionApi ) => {\n\t\t\tconst viewTableCell = data.viewItem;\n\n\t\t\t// When element was already consumed then skip it.\n\t\t\tif ( !conversionApi.consumable.test( viewTableCell, { name: true } ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst tableCell = conversionApi.writer.createElement( 'tableCell' );\n\n\t\t\t// Insert element on allowed position.\n\t\t\tconst splitResult = conversionApi.splitToAllowedParent( tableCell, data.modelCursor );\n\n\t\t\t// When there is no split result it means that we can't insert element to model tree, so let's skip it.\n\t\t\tif ( !splitResult ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconversionApi.writer.insert( tableCell, splitResult.position );\n\t\t\tconversionApi.consumable.consume( viewTableCell, { name: true } );\n\n\t\t\tconst modelCursor = conversionApi.writer.createPositionAt( tableCell, 0 );\n\t\t\tconversionApi.convertChildren( viewTableCell, modelCursor );\n\n\t\t\t// Ensure a paragraph in the model for empty table cells.\n\t\t\tif ( !tableCell.childCount ) {\n\t\t\t\tconversionApi.writer.insertElement( 'paragraph', modelCursor );\n\t\t\t}\n\n\t\t\t// Set conversion result range.\n\t\t\tdata.modelRange = conversionApi.writer.createRange(\n\t\t\t\t// Range should start before inserted element\n\t\t\t\tconversionApi.writer.createPositionBefore( tableCell ),\n\t\t\t\t// Should end after but we need to take into consideration that children could split our\n\t\t\t\t// element, so we need to move range after parent of the last converted child.\n\t\t\t\t// before: <allowed>[]</allowed>\n\t\t\t\t// after: <allowed>[<converted><child></child></converted><child></child><converted>]</converted></allowed>\n\t\t\t\tconversionApi.writer.createPositionAfter( tableCell )\n\t\t\t);\n\n\t\t\t// Continue after inserted element.\n\t\t\tdata.modelCursor = data.modelRange.end;\n\t\t} );\n\t};\n}\n\n// Scans table rows and extracts required metadata from the table:\n//\n// headingRows - the number of rows that goes as table header.\n// headingColumns - max number of row headings.\n// rows - sorted `<tr>`s as they should go into the model - ie. if `<thead>` is inserted after `<tbody>` in the view.\n//\n// @param {module:engine/view/element~Element} viewTable\n// @returns {{headingRows, headingColumns, rows}}\nfunction scanTable( viewTable ) {\n\tconst tableMeta = {\n\t\theadingRows: 0,\n\t\theadingColumns: 0\n\t};\n\n\t// The `<tbody>` and <thead> sections in the DOM do not have to be in order `<thead>` -> `<tbody>` and there might be more then one of\n\t// them.\n\t// As the model does not have those sections, rows from different sections must be sorted.\n\t// For example, below is a valid HTML table:\n\t//\n\t//\t\t<table>\n\t//\t\t\t<tbody><tr><td>2</td></tr></tbody>\n\t//\t\t\t<thead><tr><td>1</td></tr></thead>\n\t//\t\t\t<tbody><tr><td>3</td></tr></tbody>\n\t//\t\t</table>\n\t//\n\t// But browsers will render rows in order as: 1 as heading and 2 and 3 as (body).\n\tconst headRows = [];\n\tconst bodyRows = [];\n\n\t// Currently the editor does not support more then one <thead> section.\n\t// Only the first <thead> from the view will be used as heading rows and others will be converted to body rows.\n\tlet firstTheadElement;\n\n\tfor ( const tableChild of Array.from( viewTable.getChildren() ) ) {\n\t\t// Only <thead>, <tbody> & <tfoot> from allowed table children can have <tr>s.\n\t\t// The else is for future purposes (mainly <caption>).\n\t\tif ( tableChild.name === 'tbody' || tableChild.name === 'thead' || tableChild.name === 'tfoot' ) {\n\t\t\t// Save the first <thead> in the table as table header - all other ones will be converted to table body rows.\n\t\t\tif ( tableChild.name === 'thead' && !firstTheadElement ) {\n\t\t\t\tfirstTheadElement = tableChild;\n\t\t\t}\n\n\t\t\t// There might be some extra empty text nodes between the `tr`s.\n\t\t\t// Make sure further code operates on `tr`s only. (#145)\n\t\t\tconst trs = Array.from( tableChild.getChildren() ).filter( el => el.is( 'element', 'tr' ) );\n\n\t\t\tfor ( const tr of trs ) {\n\t\t\t\t// This <tr> is a child of a first <thead> element.\n\t\t\t\tif ( tr.parent.name === 'thead' && tr.parent === firstTheadElement ) {\n\t\t\t\t\ttableMeta.headingRows++;\n\t\t\t\t\theadRows.push( tr );\n\t\t\t\t} else {\n\t\t\t\t\tbodyRows.push( tr );\n\t\t\t\t\t// For other rows check how many column headings this row has.\n\n\t\t\t\t\tconst headingCols = scanRowForHeadingColumns( tr, tableMeta, firstTheadElement );\n\n\t\t\t\t\tif ( headingCols > tableMeta.headingColumns ) {\n\t\t\t\t\t\ttableMeta.headingColumns = headingCols;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\ttableMeta.rows = [ ...headRows, ...bodyRows ];\n\n\treturn tableMeta;\n}\n\n// Scans `<tr>` and its children for metadata:\n// - For heading row:\n// - either adds this row to heading or body rows.\n// - updates number of heading rows.\n// - For body rows:\n// - calculates the number of column headings.\n//\n// @param {module:engine/view/element~Element} tr\n// @returns {Number}\nfunction scanRowForHeadingColumns( tr ) {\n\tlet headingColumns = 0;\n\tlet index = 0;\n\n\t// Filter out empty text nodes from tr children.\n\tconst children = Array.from( tr.getChildren() )\n\t\t.filter( child => child.name === 'th' || child.name === 'td' );\n\n\t// Count starting adjacent <th> elements of a <tr>.\n\twhile ( index < children.length && children[ index ].name === 'th' ) {\n\t\tconst th = children[ index ];\n\n\t\t// Adjust columns calculation by the number of spanned columns.\n\t\tconst colspan = parseInt( th.getAttribute( 'colspan' ) || 1 );\n\n\t\theadingColumns = headingColumns + colspan;\n\t\tindex++;\n\t}\n\n\treturn headingColumns;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/tablewalker\n */\n\n/**\n * Table iterator class. It allows to iterate over table cells. For each cell the iterator yields\n * {@link module:table/tablewalker~TableWalkerValue} with proper table cell attributes.\n */\nexport default class TableWalker {\n\t/**\n\t * Creates an instance of the table walker.\n\t *\n\t *\n\t * The table walker iterates internally by traversing the table from row index = 0 and column index = 0.\n\t * It walks row by row and column by column in order to output values defined in the constructor.\n\t * By default it will output only those locations that are occupied by a cell. To include also spanned rows and columns,\n\t * pass the `includeSpanned` option to the constructor.\n\t *\n\t * The most important values of the iterator are column and row indexes of a cell.\n\t *\n\t * To iterate over a given row:\n\t *\n\t *\t\tconst tableWalker = new TableWalker( table, { startRow: 1, endRow: 2 } );\n\t *\n\t *\t\tfor ( const cellInfo of tableWalker ) {\n\t *\t\t\tconsole.log( 'A cell at row ' + cellInfo.row + ' and column ' + cellInfo.column );\n\t *\t\t}\n\t *\n\t * For instance the code above for the following table:\n\t *\n\t *\t\t+----+----+----+----+----+----+\n\t *\t\t| 00 | 02 | 03 | 04 | 05 |\n\t *\t\t| +----+----+----+----+\n\t *\t\t| | 12 | 14 | 15 |\n\t *\t\t| +----+----+----+ +\n\t *\t\t| | 22 | |\n\t *\t\t|----+----+----+----+----+ +\n\t *\t\t| 30 | 31 | 32 | 33 | 34 | |\n\t *\t\t+----+----+----+----+----+----+\n\t *\n\t * will log in the console:\n\t *\n\t *\t\t'A cell at row 1 and column 2'\n\t *\t\t'A cell at row 1 and column 4'\n\t *\t\t'A cell at row 1 and column 5'\n\t *\t\t'A cell at row 2 and column 2'\n\t *\n\t * To also iterate over spanned cells:\n\t *\n\t *\t\tconst tableWalker = new TableWalker( table, { startRow: 1, endRow: 1, includeSpanned: true } );\n\t *\n\t *\t\tfor ( const cellInfo of tableWalker ) {\n\t *\t\t\tconsole.log( 'Cell at ' + cellInfo.row + ' x ' + cellInfo.column + ' : ' + ( cellInfo.cell ? 'has data' : 'is spanned' ) );\n\t *\t\t}\n\t *\n\t * will log in the console for the table from previous example:\n\t *\n\t *\t\t'Cell at 1 x 0 : is spanned'\n\t *\t\t'Cell at 1 x 1 : is spanned'\n\t *\t\t'Cell at 1 x 2 : has data'\n\t *\t\t'Cell at 1 x 3 : is spanned'\n\t *\t\t'Cell at 1 x 4 : has data'\n\t *\t\t'Cell at 1 x 5 : has data'\n\t *\n\t * @constructor\n\t * @param {module:engine/model/element~Element} table A table over which the walker iterates.\n\t * @param {Object} [options={}] An object with configuration.\n\t * @param {Number} [options.column] A column index for which this iterator will output cells.\n\t * @param {Number} [options.startRow=0] A row index for which this iterator should start.\n\t * @param {Number} [options.endRow] A row index for which this iterator should end.\n\t * @param {Boolean} [options.includeSpanned] Also return values for spanned cells.\n\t */\n\tconstructor( table, options = {} ) {\n\t\t/**\n\t\t * The walker's table element.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/element~Element}\n\t\t */\n\t\tthis.table = table;\n\n\t\t/**\n\t\t * A row index on which this iterator will start.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t */\n\t\tthis.startRow = options.startRow || 0;\n\n\t\t/**\n\t\t * A row index on which this iterator will end.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t */\n\t\tthis.endRow = typeof options.endRow == 'number' ? options.endRow : undefined;\n\n\t\t/**\n\t\t * Enables output of spanned cells that are normally not yielded.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis.includeSpanned = !!options.includeSpanned;\n\n\t\t/**\n\t\t * If set, the table walker will only output cells of a given column or cells that overlap it.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t */\n\t\tthis.column = typeof options.column == 'number' ? options.column : undefined;\n\n\t\t/**\n\t\t * Row indexes to skip from the iteration.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Set<Number>}\n\t\t * @private\n\t\t */\n\t\tthis._skipRows = new Set();\n\n\t\t/**\n\t\t * The current row index.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t * @private\n\t\t */\n\t\tthis._row = 0;\n\n\t\t/**\n\t\t * The current column index.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t * @private\n\t\t */\n\t\tthis._column = 0;\n\n\t\t/**\n\t\t * The cell index in a parent row. For spanned cells when {@link #includeSpanned} is set to `true`,\n\t\t * this represents the index of the next table cell.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t * @private\n\t\t */\n\t\tthis._cell = 0;\n\n\t\t/**\n\t\t * Holds a map of spanned cells in a table.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Map<Number, Map.<Number, Number>>}\n\t\t * @private\n\t\t */\n\t\tthis._spannedCells = new Map();\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * @returns {Iterable.<module:table/tablewalker~TableWalkerValue>}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the next table walker's value.\n\t *\n\t * @returns {module:table/tablewalker~TableWalkerValue} The next table walker's value.\n\t */\n\tnext() {\n\t\tconst row = this.table.getChild( this._row );\n\n\t\t// Iterator is done when no row (table end) or the row is after #endRow.\n\t\tif ( !row || this._isOverEndRow() ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// Spanned cell location handling.\n\t\tif ( this._isSpanned( this._row, this._column ) ) {\n\t\t\t// Current column must be kept as it will be updated before returning current value.\n\t\t\tconst currentColumn = this._column;\n\t\t\tconst outValue = this._formatOutValue( undefined, currentColumn );\n\n\t\t\t// Advance to next column - always.\n\t\t\tthis._column++;\n\n\t\t\tconst skipCurrentValue = !this.includeSpanned || this._shouldSkipRow() || this._shouldSkipColumn( currentColumn, 1 );\n\n\t\t\t// The current value will be returned only if #includedSpanned=true and also current row and column are not skipped.\n\t\t\treturn skipCurrentValue ? this.next() : outValue;\n\t\t}\n\n\t\t// The cell location is not spanned by other cells.\n\t\tconst cell = row.getChild( this._cell );\n\n\t\tif ( !cell ) {\n\t\t\t// If there are no more cells left in row advance to next row.\n\t\t\tthis._row++;\n\t\t\t// And reset column & cell indexes.\n\t\t\tthis._column = 0;\n\t\t\tthis._cell = 0;\n\n\t\t\t// Return next value.\n\t\t\treturn this.next();\n\t\t}\n\n\t\t// Read table cell attributes.\n\t\tconst colspan = parseInt( cell.getAttribute( 'colspan' ) || 1 );\n\t\tconst rowspan = parseInt( cell.getAttribute( 'rowspan' ) || 1 );\n\n\t\t// Record this cell spans if it's not 1x1 cell.\n\t\tif ( colspan > 1 || rowspan > 1 ) {\n\t\t\tthis._recordSpans( this._row, this._column, rowspan, colspan );\n\t\t}\n\n\t\t// Current column must be kept as it will be updated before returning current value.\n\t\tconst currentColumn = this._column;\n\t\tconst outValue = this._formatOutValue( cell, currentColumn, rowspan, colspan );\n\n\t\t// Advance to next column before returning value.\n\t\tthis._column++;\n\n\t\t// Advance to next cell in a parent row before returning value.\n\t\tthis._cell++;\n\n\t\tconst skipCurrentValue = this._shouldSkipRow() || this._shouldSkipColumn( currentColumn, colspan );\n\n\t\t// The current value will be returned only if current row & column are not skipped.\n\t\treturn skipCurrentValue ? this.next() : outValue;\n\t}\n\n\t/**\n\t * Marks a row to skip in the next iteration. It will also skip cells from the current row if there are any cells from the current row\n\t * to output.\n\t *\n\t * @param {Number} row Row index to skip.\n\t */\n\tskipRow( row ) {\n\t\tthis._skipRows.add( row );\n\t}\n\n\t/**\n\t * Checks if the current row is over {@link #endRow}.\n\t *\n\t * @returns {Boolean}\n\t * @private\n\t */\n\t_isOverEndRow() {\n\t\t// If {@link #endRow) is defined skip all rows above it.\n\t\treturn this.endRow !== undefined && this._row > this.endRow;\n\t}\n\n\t/**\n\t * A common method for formatting the iterator's output value.\n\t *\n\t * @param {module:engine/model/element~Element|undefined} cell The table cell to output. It might be undefined for spanned cell\n\t * locations.\n\t * @param {Number} column Column index (use the cached value)\n\t * @param {Number} rowspan Rowspan of the current cell.\n\t * @param {Number} colspan Colspan of the current cell.\n\t * @returns {{done: boolean, value: {cell: *, row: Number, column: *, rowspan: *, colspan: *, cellIndex: Number}}}\n\t * @private\n\t */\n\t_formatOutValue( cell, column, rowspan = 1, colspan = 1 ) {\n\t\treturn {\n\t\t\tdone: false,\n\t\t\tvalue: {\n\t\t\t\tcell,\n\t\t\t\trow: this._row,\n\t\t\t\tcolumn,\n\t\t\t\trowspan,\n\t\t\t\tcolspan,\n\t\t\t\tcellIndex: this._cell\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Checks if the current row should be skipped.\n\t *\n\t * @returns {Boolean}\n\t * @private\n\t */\n\t_shouldSkipRow() {\n\t\tconst rowIsBelowStartRow = this._row < this.startRow;\n\t\tconst rowIsMarkedAsSkipped = this._skipRows.has( this._row );\n\n\t\treturn rowIsBelowStartRow || rowIsMarkedAsSkipped;\n\t}\n\n\t/**\n\t * Checks if the current column should be skipped.\n\t *\n\t * @param {Number} column\n\t * @param {Number} colspan\n\t * @returns {Boolean}\n\t * @private\n\t */\n\t_shouldSkipColumn( column, colspan ) {\n\t\tif ( this.column === undefined ) {\n\t\t\t// The {@link #column} is not defined so output all columns.\n\t\t\treturn false;\n\t\t}\n\n\t\t// When outputting cells from given column we skip:\n\t\t// - Cells that are not on that column.\n\t\tconst isCurrentColumn = column === this.column;\n\t\t// - CSells that are before given column and they overlaps given column.\n\t\tconst isPreviousThatOverlapsColumn = column < this.column && column + colspan > this.column;\n\n\t\treturn !isCurrentColumn && !isPreviousThatOverlapsColumn;\n\t}\n\n\t/**\n\t * Checks if the current cell location (row x column) is spanned by another cell.\n\t *\n\t * @param {Number} row Row index of a cell location to check.\n\t * @param {Number} column Column index of a cell location to check.\n\t * @returns {Boolean}\n\t * @private\n\t */\n\t_isSpanned( row, column ) {\n\t\tif ( !this._spannedCells.has( row ) ) {\n\t\t\t// No spans for given row.\n\t\t\treturn false;\n\t\t}\n\n\t\tconst rowSpans = this._spannedCells.get( row );\n\n\t\t// If spans for given rows has entry for column it means that this location if spanned by other cell.\n\t\treturn rowSpans.has( column );\n\t}\n\n\t/**\n\t * Updates spanned cells map relative to the current cell location and its span dimensions.\n\t *\n\t * @param {Number} row Row index of a cell.\n\t * @param {Number} column Column index of a cell.\n\t * @param {Number} rowspan Cell height.\n\t * @param {Number} colspan Cell width.\n\t * @private\n\t */\n\t_recordSpans( row, column, rowspan, colspan ) {\n\t\t// This will update all cell locations after current column - ie a cell has colspan set.\n\t\tfor ( let columnToUpdate = column + 1; columnToUpdate <= column + colspan - 1; columnToUpdate++ ) {\n\t\t\tthis._markSpannedCell( row, columnToUpdate );\n\t\t}\n\n\t\t// This will update all rows below current up to row's height.\n\t\tfor ( let rowToUpdate = row + 1; rowToUpdate < row + rowspan; rowToUpdate++ ) {\n\t\t\tfor ( let columnToUpdate = column; columnToUpdate <= column + colspan - 1; columnToUpdate++ ) {\n\t\t\t\tthis._markSpannedCell( rowToUpdate, columnToUpdate );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Marks the cell location as spanned by another cell.\n\t *\n\t * @param {Number} row Row index of the cell location.\n\t * @param {Number} column Column index of the cell location.\n\t * @private\n\t */\n\t_markSpannedCell( row, column ) {\n\t\tif ( !this._spannedCells.has( row ) ) {\n\t\t\tthis._spannedCells.set( row, new Map() );\n\t\t}\n\n\t\tconst rowSpans = this._spannedCells.get( row );\n\n\t\trowSpans.set( column, true );\n\t}\n}\n\n/**\n * An object returned by {@link module:table/tablewalker~TableWalker} when traversing table cells.\n *\n * @typedef {Object} module:table/tablewalker~TableWalkerValue\n * @property {module:engine/model/element~Element} [cell] The current table cell. Might be empty if\n * {@link module:table/tablewalker~TableWalker#includeSpanned} is set to `true`.\n * @property {Number} row The row index of a cell.\n * @property {Number} column The column index of a cell. Column index is adjusted to widths and heights of previous cells.\n * @property {Number} [colspan] The `colspan` attribute of a cell. It is always defined even if the model attribute is not present. Not\n * set if {@link module:table/tablewalker~TableWalker#includeSpanned} is set to `true`.\n * @property {Number} [rowspan] The `rowspan` attribute of a cell. It is always defined even if the model attribute is not present. Not\n * set if {@link module:table/tablewalker~TableWalker#includeSpanned} is set to `true`.\n * @property {Number} cellIndex The index of the current cell in a parent row. When using the `includeSpanned` option it will indicate the\n * next child index if #cell is empty (which indicates that the cell is spanned by another cell).\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/utils\n */\n\nimport { isWidget, toWidget } from '@ckeditor/ckeditor5-widget/src/utils';\nimport { findAncestor } from './commands/utils';\n\n/**\n * Converts a given {@link module:engine/view/element~Element} to a table widget:\n * * Adds a {@link module:engine/view/element~Element#_setCustomProperty custom property} allowing to recognize the table widget element.\n * * Calls the {@link module:widget/utils~toWidget} function with the proper element's label creator.\n *\n * @param {module:engine/view/element~Element} viewElement\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer An instance of the view writer.\n * @param {String} label The element's label. It will be concatenated with the table `alt` attribute if one is present.\n * @returns {module:engine/view/element~Element}\n */\nexport function toTableWidget( viewElement, writer ) {\n\twriter.setCustomProperty( 'table', true, viewElement );\n\n\treturn toWidget( viewElement, writer, { hasSelectionHandler: true } );\n}\n\n/**\n * Checks if a given view element is a table widget.\n *\n * @param {module:engine/view/element~Element} viewElement\n * @returns {Boolean}\n */\nexport function isTableWidget( viewElement ) {\n\treturn !!viewElement.getCustomProperty( 'table' ) && isWidget( viewElement );\n}\n\n/**\n * Returns a table widget editing view element if one is selected.\n *\n * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} selection\n * @returns {module:engine/view/element~Element|null}\n */\nexport function getSelectedTableWidget( selection ) {\n\tconst viewElement = selection.getSelectedElement();\n\n\tif ( viewElement && isTableWidget( viewElement ) ) {\n\t\treturn viewElement;\n\t}\n\n\treturn null;\n}\n\n/**\n * Returns a table widget editing view element if one is among selection's ancestors.\n *\n * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} selection\n * @returns {module:engine/view/element~Element|null}\n */\nexport function getTableWidgetAncestor( selection ) {\n\tconst parentTable = findAncestor( 'table', selection.getFirstPosition() );\n\n\tif ( parentTable && isTableWidget( parentTable.parent ) ) {\n\t\treturn parentTable.parent;\n\t}\n\n\treturn null;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/converters/downcast\n */\n\nimport TableWalker from './../tablewalker';\nimport { toWidgetEditable } from '@ckeditor/ckeditor5-widget/src/utils';\nimport { toTableWidget } from '../utils';\n\n/**\n * Model table element to view table element conversion helper.\n *\n * This conversion helper creates the whole table element with child elements.\n *\n * @param {Object} options\n * @param {Boolean} options.asWidget If set to `true`, the downcast conversion will produce a widget.\n * @returns {Function} Conversion helper.\n */\nexport function downcastInsertTable( options = {} ) {\n\treturn dispatcher => dispatcher.on( 'insert:table', ( evt, data, conversionApi ) => {\n\t\tconst table = data.item;\n\n\t\tif ( !conversionApi.consumable.consume( table, 'insert' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Consume attributes if present to not fire attribute change downcast\n\t\tconversionApi.consumable.consume( table, 'attribute:headingRows:table' );\n\t\tconversionApi.consumable.consume( table, 'attribute:headingColumns:table' );\n\n\t\tconst asWidget = options && options.asWidget;\n\n\t\tconst figureElement = conversionApi.writer.createContainerElement( 'figure', { class: 'table' } );\n\t\tconst tableElement = conversionApi.writer.createContainerElement( 'table' );\n\t\tconversionApi.writer.insert( conversionApi.writer.createPositionAt( figureElement, 0 ), tableElement );\n\n\t\tlet tableWidget;\n\n\t\tif ( asWidget ) {\n\t\t\ttableWidget = toTableWidget( figureElement, conversionApi.writer );\n\t\t}\n\n\t\tconst tableWalker = new TableWalker( table );\n\n\t\tconst tableAttributes = {\n\t\t\theadingRows: table.getAttribute( 'headingRows' ) || 0,\n\t\t\theadingColumns: table.getAttribute( 'headingColumns' ) || 0\n\t\t};\n\n\t\t// Cache for created table rows.\n\t\tconst viewRows = new Map();\n\n\t\tfor ( const tableWalkerValue of tableWalker ) {\n\t\t\tconst { row, cell } = tableWalkerValue;\n\n\t\t\tconst tableSection = getOrCreateTableSection( getSectionName( row, tableAttributes ), tableElement, conversionApi );\n\t\t\tconst tableRow = table.getChild( row );\n\n\t\t\tconst trElement = viewRows.get( row ) || createTr( tableRow, row, tableSection, conversionApi );\n\t\t\tviewRows.set( row, trElement );\n\n\t\t\t// Consume table cell - it will be always consumed as we convert whole table at once.\n\t\t\tconversionApi.consumable.consume( cell, 'insert' );\n\n\t\t\tconst insertPosition = conversionApi.writer.createPositionAt( trElement, 'end' );\n\n\t\t\tcreateViewTableCellElement( tableWalkerValue, tableAttributes, insertPosition, conversionApi, options );\n\t\t}\n\n\t\tconst viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n\n\t\tconversionApi.mapper.bindElements( table, asWidget ? tableWidget : figureElement );\n\t\tconversionApi.writer.insert( viewPosition, asWidget ? tableWidget : figureElement );\n\t} );\n}\n\n/**\n * Model row element to view `<tr>` element conversion helper.\n *\n * This conversion helper creates the whole `<tr>` element with child elements.\n *\n * @returns {Function} Conversion helper.\n */\nexport function downcastInsertRow( options = {} ) {\n\treturn dispatcher => dispatcher.on( 'insert:tableRow', ( evt, data, conversionApi ) => {\n\t\tconst tableRow = data.item;\n\n\t\tif ( !conversionApi.consumable.consume( tableRow, 'insert' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst table = tableRow.parent;\n\n\t\tconst figureElement = conversionApi.mapper.toViewElement( table );\n\t\tconst tableElement = getViewTable( figureElement );\n\n\t\tconst row = table.getChildIndex( tableRow );\n\n\t\tconst tableWalker = new TableWalker( table, { startRow: row, endRow: row } );\n\n\t\tconst tableAttributes = {\n\t\t\theadingRows: table.getAttribute( 'headingRows' ) || 0,\n\t\t\theadingColumns: table.getAttribute( 'headingColumns' ) || 0\n\t\t};\n\n\t\t// Cache for created table rows.\n\t\tconst viewRows = new Map();\n\n\t\tfor ( const tableWalkerValue of tableWalker ) {\n\t\t\tconst tableSection = getOrCreateTableSection( getSectionName( row, tableAttributes ), tableElement, conversionApi );\n\n\t\t\tconst trElement = viewRows.get( row ) || createTr( tableRow, row, tableSection, conversionApi );\n\t\t\tviewRows.set( row, trElement );\n\n\t\t\t// Consume table cell - it will be always consumed as we convert whole row at once.\n\t\t\tconversionApi.consumable.consume( tableWalkerValue.cell, 'insert' );\n\n\t\t\tconst insertPosition = conversionApi.writer.createPositionAt( trElement, 'end' );\n\n\t\t\tcreateViewTableCellElement( tableWalkerValue, tableAttributes, insertPosition, conversionApi, options );\n\t\t}\n\t} );\n}\n\n/**\n * Model table cell element to view `<td>` or `<th>` element conversion helper.\n *\n * This conversion helper will create proper `<th>` elements for table cells that are in the heading section (heading row or column)\n * and `<td>` otherwise.\n *\n * @returns {Function} Conversion helper.\n */\nexport function downcastInsertCell( options = {} ) {\n\treturn dispatcher => dispatcher.on( 'insert:tableCell', ( evt, data, conversionApi ) => {\n\t\tconst tableCell = data.item;\n\n\t\tif ( !conversionApi.consumable.consume( tableCell, 'insert' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst tableRow = tableCell.parent;\n\t\tconst table = tableRow.parent;\n\t\tconst rowIndex = table.getChildIndex( tableRow );\n\n\t\tconst tableWalker = new TableWalker( table, { startRow: rowIndex, endRow: rowIndex } );\n\n\t\tconst tableAttributes = {\n\t\t\theadingRows: table.getAttribute( 'headingRows' ) || 0,\n\t\t\theadingColumns: table.getAttribute( 'headingColumns' ) || 0\n\t\t};\n\n\t\t// We need to iterate over a table in order to get proper row & column values from a walker\n\t\tfor ( const tableWalkerValue of tableWalker ) {\n\t\t\tif ( tableWalkerValue.cell === tableCell ) {\n\t\t\t\tconst trElement = conversionApi.mapper.toViewElement( tableRow );\n\t\t\t\tconst insertPosition = conversionApi.writer.createPositionAt( trElement, tableRow.getChildIndex( tableCell ) );\n\n\t\t\t\tcreateViewTableCellElement( tableWalkerValue, tableAttributes, insertPosition, conversionApi, options );\n\n\t\t\t\t// No need to iterate further.\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t} );\n}\n\n/**\n * Conversion helper that acts on heading rows table attribute change.\n *\n * This converter will:\n *\n * * Rename `<td>` to `<th>` elements or vice versa depending on headings.\n * * Create `<thead>` or `<tbody>` elements if needed.\n * * Remove empty `<thead>` or `<tbody>` if needed.\n *\n * @returns {Function} Conversion helper.\n */\nexport function downcastTableHeadingRowsChange( options = {} ) {\n\tconst asWidget = !!options.asWidget;\n\n\treturn dispatcher => dispatcher.on( 'attribute:headingRows:table', ( evt, data, conversionApi ) => {\n\t\tconst table = data.item;\n\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst figureElement = conversionApi.mapper.toViewElement( table );\n\t\tconst viewTable = getViewTable( figureElement );\n\n\t\tconst oldRows = data.attributeOldValue;\n\t\tconst newRows = data.attributeNewValue;\n\n\t\t// The head section has grown so move rows from <tbody> to <thead>.\n\t\tif ( newRows > oldRows ) {\n\t\t\t// Filter out only those rows that are in wrong section.\n\t\t\tconst rowsToMove = Array.from( table.getChildren() ).filter( ( { index } ) => isBetween( index, oldRows - 1, newRows ) );\n\n\t\t\tconst viewTableHead = getOrCreateTableSection( 'thead', viewTable, conversionApi );\n\t\t\tmoveViewRowsToTableSection( rowsToMove, viewTableHead, conversionApi, 'end' );\n\n\t\t\t// Rename all table cells from moved rows to 'th' as they lands in <thead>.\n\t\t\tfor ( const tableRow of rowsToMove ) {\n\t\t\t\tfor ( const tableCell of tableRow.getChildren() ) {\n\t\t\t\t\trenameViewTableCell( tableCell, 'th', conversionApi, asWidget );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Cleanup: this will remove any empty section from the view which may happen when moving all rows from a table section.\n\t\t\tremoveTableSectionIfEmpty( 'tbody', viewTable, conversionApi );\n\t\t}\n\t\t// The head section has shrunk so move rows from <thead> to <tbody>.\n\t\telse {\n\t\t\t// Filter out only those rows that are in wrong section.\n\t\t\tconst rowsToMove = Array.from( table.getChildren() )\n\t\t\t\t.filter( ( { index } ) => isBetween( index, newRows - 1, oldRows ) )\n\t\t\t\t.reverse(); // The rows will be moved from <thead> to <tbody> in reverse order at the beginning of a <tbody>.\n\n\t\t\tconst viewTableBody = getOrCreateTableSection( 'tbody', viewTable, conversionApi );\n\t\t\tmoveViewRowsToTableSection( rowsToMove, viewTableBody, conversionApi, 0 );\n\n\t\t\t// Check if cells moved from <thead> to <tbody> requires renaming to <td> as this depends on current heading columns attribute.\n\t\t\tconst tableWalker = new TableWalker( table, { startRow: newRows ? newRows - 1 : newRows, endRow: oldRows - 1 } );\n\n\t\t\tconst tableAttributes = {\n\t\t\t\theadingRows: table.getAttribute( 'headingRows' ) || 0,\n\t\t\t\theadingColumns: table.getAttribute( 'headingColumns' ) || 0\n\t\t\t};\n\n\t\t\tfor ( const tableWalkerValue of tableWalker ) {\n\t\t\t\trenameViewTableCellIfRequired( tableWalkerValue, tableAttributes, conversionApi, asWidget );\n\t\t\t}\n\n\t\t\t// Cleanup: this will remove any empty section from the view which may happen when moving all rows from a table section.\n\t\t\tremoveTableSectionIfEmpty( 'thead', viewTable, conversionApi );\n\t\t}\n\n\t\tfunction isBetween( index, lower, upper ) {\n\t\t\treturn index > lower && index < upper;\n\t\t}\n\t} );\n}\n\n/**\n * Conversion helper that acts on heading columns table attribute change.\n *\n * Depending on changed attributes this converter will rename `<td` to `<th>` elements or vice versa depending of the cell column index.\n *\n * @returns {Function} Conversion helper.\n */\nexport function downcastTableHeadingColumnsChange( options = {} ) {\n\tconst asWidget = !!options.asWidget;\n\n\treturn dispatcher => dispatcher.on( 'attribute:headingColumns:table', ( evt, data, conversionApi ) => {\n\t\tconst table = data.item;\n\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst tableAttributes = {\n\t\t\theadingRows: table.getAttribute( 'headingRows' ) || 0,\n\t\t\theadingColumns: table.getAttribute( 'headingColumns' ) || 0\n\t\t};\n\n\t\tconst oldColumns = data.attributeOldValue;\n\t\tconst newColumns = data.attributeNewValue;\n\n\t\tconst lastColumnToCheck = ( oldColumns > newColumns ? oldColumns : newColumns ) - 1;\n\n\t\tfor ( const tableWalkerValue of new TableWalker( table ) ) {\n\t\t\t// Skip cells that were not in heading section before and after the change.\n\t\t\tif ( tableWalkerValue.column > lastColumnToCheck ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\trenameViewTableCellIfRequired( tableWalkerValue, tableAttributes, conversionApi, asWidget );\n\t\t}\n\t} );\n}\n\n/**\n * Conversion helper that acts on a removed row.\n *\n * @returns {Function} Conversion helper.\n */\nexport function downcastRemoveRow() {\n\treturn dispatcher => dispatcher.on( 'remove:tableRow', ( evt, data, conversionApi ) => {\n\t\t// Prevent default remove converter.\n\t\tevt.stop();\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst mapper = conversionApi.mapper;\n\n\t\tconst viewStart = mapper.toViewPosition( data.position ).getLastMatchingPosition( value => !value.item.is( 'tr' ) );\n\t\tconst viewItem = viewStart.nodeAfter;\n\t\tconst tableSection = viewItem.parent;\n\n\t\t// Remove associated <tr> from the view.\n\t\tconst removeRange = viewWriter.createRangeOn( viewItem );\n\t\tconst removed = viewWriter.remove( removeRange );\n\n\t\tfor ( const child of viewWriter.createRangeIn( removed ).getItems() ) {\n\t\t\tmapper.unbindViewElement( child );\n\t\t}\n\n\t\t// Check if table section has any children left - if not remove it from the view.\n\t\tif ( !tableSection.childCount ) {\n\t\t\t// No need to unbind anything as table section is not represented in the model.\n\t\t\tviewWriter.remove( viewWriter.createRangeOn( tableSection ) );\n\t\t}\n\t}, { priority: 'higher' } );\n}\n\n// Renames an existing table cell in the view to a given element name.\n//\n// **Note** This method will not do anything if a view table cell was not yet converted.\n//\n// @param {module:engine/model/element~Element} tableCell\n// @param {String} desiredCellElementName\n// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\n// @param {Boolean} asWidget\nfunction renameViewTableCell( tableCell, desiredCellElementName, conversionApi, asWidget ) {\n\tconst viewWriter = conversionApi.writer;\n\tconst viewCell = conversionApi.mapper.toViewElement( tableCell );\n\n\t// View cell might be not yet converted - skip it as it will be properly created by cell converter later on.\n\tif ( !viewCell ) {\n\t\treturn;\n\t}\n\n\tlet renamedCell;\n\n\tif ( asWidget ) {\n\t\tconst editable = viewWriter.createEditableElement( desiredCellElementName, viewCell.getAttributes() );\n\t\trenamedCell = toWidgetEditable( editable, viewWriter );\n\n\t\tviewWriter.insert( viewWriter.createPositionAfter( viewCell ), renamedCell );\n\t\tviewWriter.move( viewWriter.createRangeIn( viewCell ), viewWriter.createPositionAt( renamedCell, 0 ) );\n\t\tviewWriter.remove( viewWriter.createRangeOn( viewCell ) );\n\t} else {\n\t\trenamedCell = viewWriter.rename( desiredCellElementName, viewCell );\n\t}\n\n\tconversionApi.mapper.bindElements( tableCell, renamedCell );\n}\n\n// Renames a table cell element in the view according to its location in the table.\n//\n// @param {module:table/tablewalker~TableWalkerValue} tableWalkerValue\n// @param {{headingColumns, headingRows}} tableAttributes\n// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\n// @param {Boolean} asWidget\nfunction renameViewTableCellIfRequired( tableWalkerValue, tableAttributes, conversionApi, asWidget ) {\n\tconst { cell } = tableWalkerValue;\n\n\t// Check whether current columnIndex is overlapped by table cells from previous rows.\n\tconst desiredCellElementName = getCellElementName( tableWalkerValue, tableAttributes );\n\n\tconst viewCell = conversionApi.mapper.toViewElement( cell );\n\n\t// If in single change we're converting attribute changes and inserting cell the table cell might not be inserted into view\n\t// because of child conversion is done after parent.\n\tif ( viewCell && viewCell.name !== desiredCellElementName ) {\n\t\trenameViewTableCell( cell, desiredCellElementName, conversionApi, asWidget );\n\t}\n}\n\n// Creates a table cell element in the view.\n//\n// @param {module:table/tablewalker~TableWalkerValue} tableWalkerValue\n// @param {module:engine/view/position~Position} insertPosition\n// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\nfunction createViewTableCellElement( tableWalkerValue, tableAttributes, insertPosition, conversionApi, options ) {\n\tconst asWidget = options && options.asWidget;\n\tconst cellElementName = getCellElementName( tableWalkerValue, tableAttributes );\n\n\tconst cellElement = asWidget ?\n\t\ttoWidgetEditable( conversionApi.writer.createEditableElement( cellElementName ), conversionApi.writer ) :\n\t\tconversionApi.writer.createContainerElement( cellElementName );\n\n\tconst tableCell = tableWalkerValue.cell;\n\n\tconst firstChild = tableCell.getChild( 0 );\n\tconst isSingleParagraph = tableCell.childCount === 1 && firstChild.name === 'paragraph';\n\n\tconversionApi.writer.insert( insertPosition, cellElement );\n\n\tif ( isSingleParagraph && !hasAnyAttribute( firstChild ) ) {\n\t\tconst innerParagraph = tableCell.getChild( 0 );\n\t\tconst paragraphInsertPosition = conversionApi.writer.createPositionAt( cellElement, 'end' );\n\n\t\tconversionApi.consumable.consume( innerParagraph, 'insert' );\n\n\t\tif ( options.asWidget ) {\n\t\t\tconst fakeParagraph = conversionApi.writer.createContainerElement( 'span' );\n\n\t\t\tconversionApi.mapper.bindElements( innerParagraph, fakeParagraph );\n\t\t\tconversionApi.writer.insert( paragraphInsertPosition, fakeParagraph );\n\n\t\t\tconversionApi.mapper.bindElements( tableCell, cellElement );\n\t\t} else {\n\t\t\tconversionApi.mapper.bindElements( tableCell, cellElement );\n\t\t\tconversionApi.mapper.bindElements( innerParagraph, cellElement );\n\t\t}\n\t} else {\n\t\tconversionApi.mapper.bindElements( tableCell, cellElement );\n\t}\n}\n\n// Creates `<tr>` view element.\n//\n// @param {module:engine/view/element~Element} tableRow\n// @param {Number} rowIndex\n// @param {module:engine/view/element~Element} tableSection\n// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\n// @returns {module:engine/view/element~Element}\nfunction createTr( tableRow, rowIndex, tableSection, conversionApi ) {\n\t// Will always consume since we're converting <tableRow> element from a parent <table>.\n\tconversionApi.consumable.consume( tableRow, 'insert' );\n\n\tconst trElement = conversionApi.writer.createContainerElement( 'tr' );\n\tconversionApi.mapper.bindElements( tableRow, trElement );\n\n\tconst headingRows = tableRow.parent.getAttribute( 'headingRows' ) || 0;\n\tconst offset = headingRows > 0 && rowIndex >= headingRows ? rowIndex - headingRows : rowIndex;\n\n\tconst position = conversionApi.writer.createPositionAt( tableSection, offset );\n\tconversionApi.writer.insert( position, trElement );\n\n\treturn trElement;\n}\n\n// Returns `th` for heading cells and `td` for other cells for the current table walker value.\n//\n// @param {module:table/tablewalker~TableWalkerValue} tableWalkerValue\n// @param {{headingColumns, headingRows}} tableAttributes\n// @returns {String}\nfunction getCellElementName( tableWalkerValue, tableAttributes ) {\n\tconst { row, column } = tableWalkerValue;\n\tconst { headingColumns, headingRows } = tableAttributes;\n\n\t// Column heading are all tableCells in the first `columnHeading` rows.\n\tconst isColumnHeading = headingRows && headingRows > row;\n\n\t// So a whole row gets <th> element.\n\tif ( isColumnHeading ) {\n\t\treturn 'th';\n\t}\n\n\t// Row heading are tableCells which columnIndex is lower then headingColumns.\n\tconst isRowHeading = headingColumns && headingColumns > column;\n\n\treturn isRowHeading ? 'th' : 'td';\n}\n\n// Returns the table section name for the current table walker value.\n//\n// @param {Number} row\n// @param {{headingColumns, headingRows}} tableAttributes\n// @returns {String}\nfunction getSectionName( row, tableAttributes ) {\n\treturn row < tableAttributes.headingRows ? 'thead' : 'tbody';\n}\n\n// Creates or returns an existing `<tbody>` or `<thead>` element witch caching.\n//\n// @param {String} sectionName\n// @param {module:engine/view/element~Element} viewTable\n// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\n// @param {Object} cachedTableSection An object that stores cached elements.\n// @returns {module:engine/view/containerelement~ContainerElement}\nfunction getOrCreateTableSection( sectionName, viewTable, conversionApi ) {\n\tconst viewTableSection = getExistingTableSectionElement( sectionName, viewTable );\n\n\treturn viewTableSection ? viewTableSection : createTableSection( sectionName, viewTable, conversionApi );\n}\n\n// Finds an existing `<tbody>` or `<thead>` element or returns undefined.\n//\n// @param {String} sectionName\n// @param {module:engine/view/element~Element} tableElement\n// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\nfunction getExistingTableSectionElement( sectionName, tableElement ) {\n\tfor ( const tableSection of tableElement.getChildren() ) {\n\t\tif ( tableSection.name == sectionName ) {\n\t\t\treturn tableSection;\n\t\t}\n\t}\n}\n\n// Creates a table section at the end of the table.\n//\n// @param {String} sectionName\n// @param {module:engine/view/element~Element} tableElement\n// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\n// @returns {module:engine/view/containerelement~ContainerElement}\nfunction createTableSection( sectionName, tableElement, conversionApi ) {\n\tconst tableChildElement = conversionApi.writer.createContainerElement( sectionName );\n\n\tconst insertPosition = conversionApi.writer.createPositionAt( tableElement, sectionName == 'tbody' ? 'end' : 0 );\n\n\tconversionApi.writer.insert( insertPosition, tableChildElement );\n\n\treturn tableChildElement;\n}\n\n// Removes an existing `<tbody>` or `<thead>` element if it is empty.\n//\n// @param {String} sectionName\n// @param {module:engine/view/element~Element} tableElement\n// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\nfunction removeTableSectionIfEmpty( sectionName, tableElement, conversionApi ) {\n\tconst tableSection = getExistingTableSectionElement( sectionName, tableElement );\n\n\tif ( tableSection && tableSection.childCount === 0 ) {\n\t\tconversionApi.writer.remove( conversionApi.writer.createRangeOn( tableSection ) );\n\t}\n}\n\n// Moves view table rows associated with passed model rows to the provided table section element.\n//\n// **Note** This method will skip not converted table rows.\n//\n// @param {Array.<module:engine/model/element~Element>} rowsToMove\n// @param {module:engine/view/element~Element} viewTableSection\n// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\n// @param {Number|'end'|'before'|'after'} offset Offset or one of the flags.\nfunction moveViewRowsToTableSection( rowsToMove, viewTableSection, conversionApi, offset ) {\n\tfor ( const tableRow of rowsToMove ) {\n\t\tconst viewTableRow = conversionApi.mapper.toViewElement( tableRow );\n\n\t\t// View table row might be not yet converted - skip it as it will be properly created by cell converter later on.\n\t\tif ( viewTableRow ) {\n\t\t\tconversionApi.writer.move(\n\t\t\t\tconversionApi.writer.createRangeOn( viewTableRow ),\n\t\t\t\tconversionApi.writer.createPositionAt( viewTableSection, offset )\n\t\t\t);\n\t\t}\n\t}\n}\n\n// Properly finds '<table>' element inside `<figure>` widget.\n//\n// @param {module:engine/view/element~Element} viewFigure\nfunction getViewTable( viewFigure ) {\n\tfor ( const child of viewFigure.getChildren() ) {\n\t\tif ( child.name === 'table' ) {\n\t\t\treturn child;\n\t\t}\n\t}\n}\n\n// Checks if element has any attribute set.\n//\n// @param {module:engine/model/element~Element element\n// @returns {Boolean}\nfunction hasAnyAttribute( element ) {\n\treturn !![ ...element.getAttributeKeys() ].length;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/command\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor commands.\n *\n * Commands are the main way to manipulate editor contents and state. They are mostly used by UI elements (or by other\n * commands) to make changes in the model. Commands are available in every part of code that has access to\n * the {@link module:core/editor/editor~Editor editor} instance.\n *\n * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n *\n * By default commands are disabled when the editor is in {@link module:core/editor/editor~Editor#isReadOnly read-only} mode.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Command {\n\t/**\n\t * Creates a new `Command` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor Editor on which this command will be used.\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor on which this command will be used.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * The value of the command. A concrete command class should define what it represents for it.\n\t\t *\n\t\t * For example, the `'bold'` command's value indicates whether the selection starts in a bolded text.\n\t\t * And the value of the `'link'` command may be an object with links details.\n\t\t *\n\t\t * It is possible for a command to have no value (e.g. for stateless actions such as `'imageUpload'`).\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member #value\n\t\t */\n\t\tthis.set( 'value', undefined );\n\n\t\t/**\n\t\t * Flag indicating whether a command is enabled or disabled.\n\t\t * A disabled command will do nothing when executed.\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * It is possible to disable a command from \"outside\". For instance, in your integration you may want to disable\n\t\t * a certain set of commands for the time being. To do that, you can use the fact that `isEnabled` is observable\n\t\t * and it fires the `set:isEnabled` event every time anyone tries to modify its value:\n\t\t *\n\t\t *\t\tfunction disableCommand( cmd ) {\n\t\t *\t\t\tcmd.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t *\n\t\t *\t\t\tcmd.isEnabled = false;\n\t\t *\n\t\t *\t\t\t// Make it possible to enable the command again.\n\t\t *\t\t\treturn () => {\n\t\t *\t\t\t\tcmd.off( 'set:isEnabled', forceDisable );\n\t\t *\t\t\t\tcmd.refresh();\n\t\t *\t\t\t};\n\t\t *\n\t\t *\t\t\tfunction forceDisable( evt ) {\n\t\t *\t\t\t\tevt.return = false;\n\t\t *\t\t\t\tevt.stop();\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\n\t\t *\t\t// Usage:\n\t\t *\n\t\t *\t\t// Disabling the command.\n\t\t *\t\tconst enableBold = disableCommand( editor.commands.get( 'bold' ) );\n\t\t *\n\t\t *\t\t// Enabling the command again.\n\t\t *\t\tenableBold();\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\t\tthis.set( 'isEnabled', false );\n\n\t\t/**\n\t\t * Holds identifiers for {@link #forceDisabled} mechanism.\n\t\t *\n\t\t * @type {Set.<String>}\n\t\t * @private\n\t\t */\n\t\tthis._disableStack = new Set();\n\n\t\tthis.decorate( 'execute' );\n\n\t\t// By default every command is refreshed when changes are applied to the model.\n\t\tthis.listenTo( this.editor.model.document, 'change', () => {\n\t\t\tthis.refresh();\n\t\t} );\n\n\t\tthis.on( 'execute', evt => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// By default commands are disabled when the editor is in read-only mode.\n\t\tthis.listenTo( editor, 'change:isReadOnly', ( evt, name, value ) => {\n\t\t\tif ( value ) {\n\t\t\t\tthis.forceDisabled( 'readOnlyMode' );\n\t\t\t} else {\n\t\t\t\tthis.clearForceDisabled( 'readOnlyMode' );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties\n\t * in this method.\n\t *\n\t * This method is automatically called when\n\t * {@link module:engine/model/document~Document#event:change any changes are applied to the document}.\n\t */\n\trefresh() {\n\t\tthis.isEnabled = true;\n\t}\n\n\t/**\n\t * Disables the command.\n\t *\n\t * Command may be disabled by multiple features or algorithms (at once). When disabling a command, unique id should be passed\n\t * (e.g. feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the command.\n\t * The command becomes enabled only after all features {@link #clearForceDisabled enabled it back}.\n\t *\n\t * Disabling and enabling a command:\n\t *\n\t *\t\tcommand.isEnabled; // -> true\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Command disabled by multiple features:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'OtherFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'OtherFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Multiple disabling with the same identifier is redundant:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * **Note:** some commands or algorithms may have more complex logic when it comes to enabling or disabling certain commands,\n\t * so the command might be still disabled after {@link #clearForceDisabled} was used.\n\t *\n\t * @param {String} id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the command.\n\t */\n\tforceDisabled( id ) {\n\t\tthis._disableStack.add( id );\n\n\t\tif ( this._disableStack.size == 1 ) {\n\t\t\tthis.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * Clears forced disable previously set through {@link #clearForceDisabled}. See {@link #clearForceDisabled}.\n\t *\n\t * @param {String} id Unique identifier, equal to the one passed in {@link #forceDisabled} call.\n\t */\n\tclearForceDisabled( id ) {\n\t\tthis._disableStack.delete( id );\n\n\t\tif ( this._disableStack.size == 0 ) {\n\t\t\tthis.off( 'set:isEnabled', forceDisable );\n\t\t\tthis.refresh();\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`}\n\t * to the command.\n\t *\n\t * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`).\n\t * This behavior is implemented by a high priority listener to the {@link #event:execute} event.\n\t *\n\t * In order to see how to disable a command from \"outside\" see the {@link #isEnabled} documentation.\n\t *\n\t * @fires execute\n\t */\n\texecute() {}\n\n\t/**\n\t * Destroys the command.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Event fired by the {@link #execute} method. The command action is a listener to this event so it's\n\t * possible to change/cancel the behavior of the command by listening to this event.\n\t *\n\t * See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples.\n\t *\n\t * **Note:** This event is fired even if command is disabled. However, it is automatically blocked\n\t * by a high priority listener in order to prevent command execution.\n\t *\n\t * @event execute\n\t */\n}\n\nmix( Command, ObservableMixin );\n\n// Helper function that forces command to be disabled.\nfunction forceDisable( evt ) {\n\tevt.return = false;\n\tevt.stop();\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/commands/inserttablecommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport { findOptimalInsertionPosition } from '@ckeditor/ckeditor5-widget/src/utils';\n\n/**\n * The insert table command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as `'insertTable'` editor command.\n *\n * To insert a table at the current selection, execute the command and specify the dimensions:\n *\n *\t\teditor.execute( 'insertTable', { rows: 20, columns: 5 } );\n *\n * @extends module:core/command~Command\n */\nexport default class InsertTableCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst schema = model.schema;\n\n\t\tconst validParent = getInsertTableParent( selection.getFirstPosition() );\n\n\t\tthis.isEnabled = schema.checkChild( validParent, 'table' );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * Inserts a table with the given number of rows and columns into the editor.\n\t *\n\t * @param {Object} options\n\t * @param {Number} [options.rows=2] The number of rows to create in the inserted table.\n\t * @param {Number} [options.columns=2] The number of columns to create in the inserted table.\n\t * @fires execute\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst tableUtils = this.editor.plugins.get( 'TableUtils' );\n\n\t\tconst rows = parseInt( options.rows ) || 2;\n\t\tconst columns = parseInt( options.columns ) || 2;\n\n\t\tconst insertPosition = findOptimalInsertionPosition( selection, model );\n\n\t\tmodel.change( writer => {\n\t\t\tconst table = tableUtils.createTable( writer, rows, columns );\n\n\t\t\tmodel.insertContent( table, insertPosition );\n\n\t\t\twriter.setSelection( writer.createPositionAt( table.getNodeByPath( [ 0, 0, 0 ] ), 0 ) );\n\t\t} );\n\t}\n}\n\n// Returns valid parent to insert table\n//\n// @param {module:engine/model/position} position\nfunction getInsertTableParent( position ) {\n\tconst parent = position.parent;\n\n\treturn parent === parent.root ? parent : parent.parent;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/commands/insertrowcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport { findAncestor } from './utils';\n\n/**\n * The insert row command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as `'insertTableRowBelow'` and\n * `'insertTableRowAbove'` editor commands.\n *\n * To insert a row below the selected cell, execute the following command:\n *\n *\t\teditor.execute( 'insertTableRowBelow' );\n *\n * To insert a row above the selected cell, execute the following command:\n *\n *\t\teditor.execute( 'insertTableRowAbove' );\n *\n * @extends module:core/command~Command\n */\nexport default class InsertRowCommand extends Command {\n\t/**\n\t * Creates a new `InsertRowCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor on which this command will be used.\n\t * @param {Object} options\n\t * @param {String} [options.order=\"below\"] The order of insertion relative to the row in which the caret is located.\n\t * Possible values: `\"above\"` and `\"below\"`.\n\t */\n\tconstructor( editor, options = {} ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The order of insertion relative to the row in which the caret is located.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String} module:table/commands/insertrowcommand~InsertRowCommand#order\n\t\t */\n\t\tthis.order = options.order || 'below';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst selection = this.editor.model.document.selection;\n\n\t\tconst tableParent = findAncestor( 'table', selection.getFirstPosition() );\n\n\t\tthis.isEnabled = !!tableParent;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * Depending on the command's {@link #order} value, it inserts a row `'below'` or `'above'` the row in which selection is set.\n\t *\n\t * @fires execute\n\t */\n\texecute() {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\t\tconst tableUtils = editor.plugins.get( 'TableUtils' );\n\n\t\tconst tableCell = findAncestor( 'tableCell', selection.getFirstPosition() );\n\t\tconst tableRow = tableCell.parent;\n\t\tconst table = tableRow.parent;\n\n\t\tconst row = table.getChildIndex( tableRow );\n\t\tconst insertAt = this.order === 'below' ? row + 1 : row;\n\n\t\ttableUtils.insertRows( table, { rows: 1, at: insertAt } );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/commands/insertcolumncommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport { findAncestor } from './utils';\n\n/**\n * The insert column command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as `'insertTableColumnLeft'` and\n * `'insertTableColumnRight'` editor commands.\n *\n * To insert a column to the left of the selected cell, execute the following command:\n *\n *\t\teditor.execute( 'insertTableColumnLeft' );\n *\n * To insert a column to the right of the selected cell, execute the following command:\n *\n *\t\teditor.execute( 'insertTableColumnRight' );\n *\n * @extends module:core/command~Command\n */\nexport default class InsertColumnCommand extends Command {\n\t/**\n\t * Creates a new `InsertColumnCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor on which this command will be used.\n\t * @param {Object} options\n\t * @param {String} [options.order=\"right\"] The order of insertion relative to the column in which the caret is located.\n\t * Possible values: `\"left\"` and `\"right\"`.\n\t */\n\tconstructor( editor, options = {} ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The order of insertion relative to the column in which the caret is located.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String} module:table/commands/insertcolumncommand~InsertColumnCommand#order\n\t\t */\n\t\tthis.order = options.order || 'right';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst selection = this.editor.model.document.selection;\n\n\t\tconst tableParent = findAncestor( 'table', selection.getFirstPosition() );\n\n\t\tthis.isEnabled = !!tableParent;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * Depending on the command's {@link #order} value, it inserts a column to the `'left'` or `'right'` of the column\n\t * in which the selection is set.\n\t *\n\t * @fires execute\n\t */\n\texecute() {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\t\tconst tableUtils = editor.plugins.get( 'TableUtils' );\n\n\t\tconst firstPosition = selection.getFirstPosition();\n\n\t\tconst tableCell = findAncestor( 'tableCell', firstPosition );\n\t\tconst table = tableCell.parent.parent;\n\n\t\tconst { column } = tableUtils.getCellLocation( tableCell );\n\t\tconst insertAt = this.order === 'right' ? column + 1 : column;\n\n\t\ttableUtils.insertColumns( table, { columns: 1, at: insertAt } );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/commands/splitcellcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport { findAncestor } from './utils';\n\n/**\n * The split cell command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as `'splitTableCellVertically'`\n * and `'splitTableCellHorizontally'` editor commands.\n *\n * You can split any cell vertically or horizontally by executing this command. For example, to split the selected table cell vertically:\n *\n *\t\teditor.execute( 'splitTableCellVertically' );\n *\n * @extends module:core/command~Command\n */\nexport default class SplitCellCommand extends Command {\n\t/**\n\t * Creates a new `SplitCellCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor on which this command will be used.\n\t * @param {Object} options\n\t * @param {String} options.direction Indicates whether the command should split cells `'horizontally'` or `'vertically'`.\n\t */\n\tconstructor( editor, options = {} ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The direction that indicates which cell will be split.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String} #direction\n\t\t */\n\t\tthis.direction = options.direction || 'horizontally';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\n\t\tconst tableCell = findAncestor( 'tableCell', doc.selection.getFirstPosition() );\n\n\t\tthis.isEnabled = !!tableCell;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\t\tconst selection = document.selection;\n\n\t\tconst firstPosition = selection.getFirstPosition();\n\t\tconst tableCell = findAncestor( 'tableCell', firstPosition );\n\n\t\tconst isHorizontally = this.direction === 'horizontally';\n\n\t\tconst tableUtils = this.editor.plugins.get( 'TableUtils' );\n\n\t\tif ( isHorizontally ) {\n\t\t\ttableUtils.splitCellHorizontally( tableCell, 2 );\n\t\t} else {\n\t\t\ttableUtils.splitCellVertically( tableCell, 2 );\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/commands/mergecellcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport TableWalker from '../tablewalker';\nimport { findAncestor, updateNumericAttribute } from './utils';\n\n/**\n * The merge cell command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as `'mergeTableCellRight'`, `'mergeTableCellLeft'`,\n * `'mergeTableCellUp'` and `'mergeTableCellDown'` editor commands.\n *\n * To merge a table cell at the current selection with another cell, execute the command corresponding with the preferred direction.\n *\n * For example, to merge with a cell to the right:\n *\n *\t\teditor.execute( 'mergeTableCellRight' );\n *\n * **Note**: If a table cell has a different [`rowspan`](https://www.w3.org/TR/html50/tabular-data.html#attr-tdth-rowspan)\n * (for `'mergeTableCellRight'` and `'mergeTableCellLeft'`) or [`colspan`](https://www.w3.org/TR/html50/tabular-data.html#attr-tdth-colspan)\n * (for `'mergeTableCellUp'` and `'mergeTableCellDown'`), the command will be disabled.\n *\n * @extends module:core/command~Command\n */\nexport default class MergeCellCommand extends Command {\n\t/**\n\t * Creates a new `MergeCellCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor on which this command will be used.\n\t * @param {Object} options\n\t * @param {String} options.direction Indicates which cell to merge with the currently selected one.\n\t * Possible values are: `'left'`, `'right'`, `'up'` and `'down'`.\n\t */\n\tconstructor( editor, options ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The direction that indicates which cell will be merged with the currently selected one.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String} #direction\n\t\t */\n\t\tthis.direction = options.direction;\n\n\t\t/**\n\t\t * Whether the merge is horizontal (left/right) or vertical (up/down).\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} #isHorizontal\n\t\t */\n\t\tthis.isHorizontal = this.direction == 'right' || this.direction == 'left';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst cellToMerge = this._getMergeableCell();\n\n\t\tthis.isEnabled = !!cellToMerge;\n\t\t// In order to check if currently selected cell can be merged with one defined by #direction some computation are done beforehand.\n\t\t// As such we can cache it as a command's value.\n\t\tthis.value = cellToMerge;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * Depending on the command's {@link #direction} value, it will merge the cell that is to the `'left'`, `'right'`, `'up'` or `'down'`.\n\t *\n\t * @fires execute\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tconst tableCell = findAncestor( 'tableCell', doc.selection.getFirstPosition() );\n\t\tconst cellToMerge = this.value;\n\t\tconst direction = this.direction;\n\n\t\tmodel.change( writer => {\n\t\t\tconst isMergeNext = direction == 'right' || direction == 'down';\n\n\t\t\t// The merge mechanism is always the same so sort cells to be merged.\n\t\t\tconst cellToExpand = isMergeNext ? tableCell : cellToMerge;\n\t\t\tconst cellToRemove = isMergeNext ? cellToMerge : tableCell;\n\n\t\t\t// Cache the parent of cell to remove for later check.\n\t\t\tconst removedTableCellRow = cellToRemove.parent;\n\n\t\t\tmergeTableCells( cellToRemove, cellToExpand, writer );\n\n\t\t\tconst spanAttribute = this.isHorizontal ? 'colspan' : 'rowspan';\n\t\t\tconst cellSpan = parseInt( tableCell.getAttribute( spanAttribute ) || 1 );\n\t\t\tconst cellToMergeSpan = parseInt( cellToMerge.getAttribute( spanAttribute ) || 1 );\n\n\t\t\t// Update table cell span attribute and merge set selection on merged contents.\n\t\t\twriter.setAttribute( spanAttribute, cellSpan + cellToMergeSpan, cellToExpand );\n\t\t\twriter.setSelection( writer.createRangeIn( cellToExpand ) );\n\n\t\t\t// Remove empty row after merging.\n\t\t\tif ( !removedTableCellRow.childCount ) {\n\t\t\t\tremoveEmptyRow( removedTableCellRow, writer );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Returns a cell that can be merged with the current cell depending on the command's direction.\n\t *\n\t * @returns {module:engine/model/element|undefined}\n\t * @private\n\t */\n\t_getMergeableCell() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tconst tableCell = findAncestor( 'tableCell', doc.selection.getFirstPosition() );\n\n\t\tif ( !tableCell ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst tableUtils = this.editor.plugins.get( 'TableUtils' );\n\n\t\t// First get the cell on proper direction.\n\t\tconst cellToMerge = this.isHorizontal ?\n\t\t\tgetHorizontalCell( tableCell, this.direction, tableUtils ) :\n\t\t\tgetVerticalCell( tableCell, this.direction );\n\n\t\tif ( !cellToMerge ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If found check if the span perpendicular to merge direction is equal on both cells.\n\t\tconst spanAttribute = this.isHorizontal ? 'rowspan' : 'colspan';\n\t\tconst span = parseInt( tableCell.getAttribute( spanAttribute ) || 1 );\n\n\t\tconst cellToMergeSpan = parseInt( cellToMerge.getAttribute( spanAttribute ) || 1 );\n\n\t\tif ( cellToMergeSpan === span ) {\n\t\t\treturn cellToMerge;\n\t\t}\n\t}\n}\n\n// Returns the cell that can be merged horizontally.\n//\n// @param {module:engine/model/element~Element} tableCell\n// @param {String} direction\n// @returns {module:engine/model/node~Node|null}\nfunction getHorizontalCell( tableCell, direction, tableUtils ) {\n\tconst horizontalCell = direction == 'right' ? tableCell.nextSibling : tableCell.previousSibling;\n\n\tif ( !horizontalCell ) {\n\t\treturn;\n\t}\n\n\t// Sort cells:\n\tconst cellOnLeft = direction == 'right' ? tableCell : horizontalCell;\n\tconst cellOnRight = direction == 'right' ? horizontalCell : tableCell;\n\n\t// Get their column indexes:\n\tconst { column: leftCellColumn } = tableUtils.getCellLocation( cellOnLeft );\n\tconst { column: rightCellColumn } = tableUtils.getCellLocation( cellOnRight );\n\n\tconst leftCellSpan = parseInt( cellOnLeft.getAttribute( 'colspan' ) || 1 );\n\n\t// The cell on the right must have index that is distant to the cell on the left by the left cell's width (colspan).\n\tconst cellsAreTouching = leftCellColumn + leftCellSpan === rightCellColumn;\n\n\t// If the right cell's column index is different it means that there are rowspanned cells between them.\n\treturn cellsAreTouching ? horizontalCell : undefined;\n}\n\n// Returns the cell that can be merged vertically.\n//\n// @param {module:engine/model/element~Element} tableCell\n// @param {String} direction\n// @returns {module:engine/model/node~Node|null}\nfunction getVerticalCell( tableCell, direction ) {\n\tconst tableRow = tableCell.parent;\n\tconst table = tableRow.parent;\n\n\tconst rowIndex = table.getChildIndex( tableRow );\n\n\t// Don't search for mergeable cell if direction points out of the table.\n\tif ( ( direction == 'down' && rowIndex === table.childCount - 1 ) || ( direction == 'up' && rowIndex === 0 ) ) {\n\t\treturn;\n\t}\n\n\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );\n\tconst headingRows = table.getAttribute( 'headingRows' ) || 0;\n\n\tconst isMergeWithBodyCell = direction == 'down' && ( rowIndex + rowspan ) === headingRows;\n\tconst isMergeWithHeadCell = direction == 'up' && rowIndex === headingRows;\n\n\t// Don't search for mergeable cell if direction points out of the current table section.\n\tif ( headingRows && ( isMergeWithBodyCell || isMergeWithHeadCell ) ) {\n\t\treturn;\n\t}\n\n\tconst currentCellRowSpan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );\n\tconst rowOfCellToMerge = direction == 'down' ? rowIndex + currentCellRowSpan : rowIndex;\n\n\tconst tableMap = [ ...new TableWalker( table, { endRow: rowOfCellToMerge } ) ];\n\n\tconst currentCellData = tableMap.find( value => value.cell === tableCell );\n\tconst mergeColumn = currentCellData.column;\n\n\tconst cellToMergeData = tableMap.find( ( { row, rowspan, column } ) => {\n\t\tif ( column !== mergeColumn ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( direction == 'down' ) {\n\t\t\t// If merging a cell below the mergeRow is already calculated.\n\t\t\treturn row === rowOfCellToMerge;\n\t\t} else {\n\t\t\t// If merging a cell above calculate if it spans to mergeRow.\n\t\t\treturn rowOfCellToMerge === row + rowspan;\n\t\t}\n\t} );\n\n\treturn cellToMergeData && cellToMergeData.cell;\n}\n\n// Properly removes empty row from a table. Will update `rowspan` attribute of cells that overlaps removed row.\n//\n// @param {module:engine/model/element~Element} removedTableCellRow\n// @param {module:engine/model/writer~Writer} writer\nfunction removeEmptyRow( removedTableCellRow, writer ) {\n\tconst table = removedTableCellRow.parent;\n\n\tconst removedRowIndex = table.getChildIndex( removedTableCellRow );\n\n\tfor ( const { cell, row, rowspan } of new TableWalker( table, { endRow: removedRowIndex } ) ) {\n\t\tconst overlapsRemovedRow = row + rowspan - 1 >= removedRowIndex;\n\n\t\tif ( overlapsRemovedRow ) {\n\t\t\tupdateNumericAttribute( 'rowspan', rowspan - 1, cell, writer );\n\t\t}\n\t}\n\n\twriter.remove( removedTableCellRow );\n}\n\n// Merges two table cells - will ensure that after merging cells with empty paragraph the result table cell will only have one paragraph.\n// If one of the merged table cell is empty the merged table cell will have contents of the non-empty table cell.\n// If both are empty the merged table cell will have only one empty paragraph.\n//\n// @param {module:engine/model/element~Element} cellToRemove\n// @param {module:engine/model/element~Element} cellToExpand\n// @param {module:engine/model/writer~Writer} writer\nfunction mergeTableCells( cellToRemove, cellToExpand, writer ) {\n\tif ( !isEmpty( cellToRemove ) ) {\n\t\tif ( isEmpty( cellToExpand ) ) {\n\t\t\twriter.remove( writer.createRangeIn( cellToExpand ) );\n\t\t}\n\n\t\twriter.move( writer.createRangeIn( cellToRemove ), writer.createPositionAt( cellToExpand, 'end' ) );\n\t}\n\n\t// Remove merged table cell.\n\twriter.remove( cellToRemove );\n}\n\n// Checks if passed table cell contains empty paragraph.\n//\n// @param {module:engine/model/element~Element} tableCell\n// @returns {Boolean}\nfunction isEmpty( tableCell ) {\n\treturn tableCell.childCount == 1 && tableCell.getChild( 0 ).is( 'paragraph' ) && tableCell.getChild( 0 ).isEmpty;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/commands/removerowcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\n\nimport TableWalker from '../tablewalker';\nimport { findAncestor, updateNumericAttribute } from './utils';\n\n/**\n * The remove row command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as `'removeTableRow'` editor command.\n *\n * To remove the row containing the selected cell, execute the command:\n *\n *\t\teditor.execute( 'removeTableRow' );\n *\n * @extends module:core/command~Command\n */\nexport default class RemoveRowCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\n\t\tconst tableCell = findAncestor( 'tableCell', doc.selection.getFirstPosition() );\n\n\t\tthis.isEnabled = !!tableCell && tableCell.parent.parent.childCount > 1;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\n\t\tconst firstPosition = selection.getFirstPosition();\n\t\tconst tableCell = findAncestor( 'tableCell', firstPosition );\n\t\tconst tableRow = tableCell.parent;\n\t\tconst table = tableRow.parent;\n\n\t\tconst currentRow = table.getChildIndex( tableRow );\n\t\tconst headingRows = table.getAttribute( 'headingRows' ) || 0;\n\n\t\tmodel.change( writer => {\n\t\t\tif ( headingRows && currentRow <= headingRows ) {\n\t\t\t\tupdateNumericAttribute( 'headingRows', headingRows - 1, table, writer, 0 );\n\t\t\t}\n\n\t\t\tconst tableMap = [ ...new TableWalker( table, { endRow: currentRow } ) ];\n\n\t\t\tconst cellsToMove = new Map();\n\n\t\t\t// Get cells from removed row that are spanned over multiple rows.\n\t\t\ttableMap\n\t\t\t\t.filter( ( { row, rowspan } ) => row === currentRow && rowspan > 1 )\n\t\t\t\t.forEach( ( { column, cell, rowspan } ) => cellsToMove.set( column, { cell, rowspanToSet: rowspan - 1 } ) );\n\n\t\t\t// Reduce rowspan on cells that are above removed row and overlaps removed row.\n\t\t\ttableMap\n\t\t\t\t.filter( ( { row, rowspan } ) => row <= currentRow - 1 && row + rowspan > currentRow )\n\t\t\t\t.forEach( ( { cell, rowspan } ) => updateNumericAttribute( 'rowspan', rowspan - 1, cell, writer ) );\n\n\t\t\t// Move cells to another row.\n\t\t\tconst targetRow = currentRow + 1;\n\t\t\tconst tableWalker = new TableWalker( table, { includeSpanned: true, startRow: targetRow, endRow: targetRow } );\n\n\t\t\tlet previousCell;\n\n\t\t\tfor ( const { row, column, cell } of [ ...tableWalker ] ) {\n\t\t\t\tif ( cellsToMove.has( column ) ) {\n\t\t\t\t\tconst { cell: cellToMove, rowspanToSet } = cellsToMove.get( column );\n\t\t\t\t\tconst targetPosition = previousCell ?\n\t\t\t\t\t\twriter.createPositionAfter( previousCell ) :\n\t\t\t\t\t\twriter.createPositionAt( table.getChild( row ), 0 );\n\n\t\t\t\t\twriter.move( writer.createRangeOn( cellToMove ), targetPosition );\n\t\t\t\t\tupdateNumericAttribute( 'rowspan', rowspanToSet, cellToMove, writer );\n\n\t\t\t\t\tpreviousCell = cellToMove;\n\t\t\t\t} else {\n\t\t\t\t\tpreviousCell = cell;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\twriter.remove( tableRow );\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/commands/removecolumncommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\n\nimport TableWalker from '../tablewalker';\nimport { findAncestor, updateNumericAttribute } from './utils';\n\n/**\n * The remove column command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as `'removeTableColumn'` editor command.\n *\n * To remove the column containing the selected cell, execute the command:\n *\n *\t\teditor.execute( 'removeTableColumn' );\n *\n * @extends module:core/command~Command\n */\nexport default class RemoveColumnCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\t\tconst tableUtils = editor.plugins.get( 'TableUtils' );\n\n\t\tconst tableCell = findAncestor( 'tableCell', selection.getFirstPosition() );\n\n\t\tthis.isEnabled = !!tableCell && tableUtils.getColumns( tableCell.parent.parent ) > 1;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\n\t\tconst firstPosition = selection.getFirstPosition();\n\n\t\tconst tableCell = findAncestor( 'tableCell', firstPosition );\n\t\tconst tableRow = tableCell.parent;\n\t\tconst table = tableRow.parent;\n\n\t\tconst headingColumns = table.getAttribute( 'headingColumns' ) || 0;\n\t\tconst row = table.getChildIndex( tableRow );\n\n\t\t// Cache the table before removing or updating colspans.\n\t\tconst tableMap = [ ...new TableWalker( table ) ];\n\n\t\t// Get column index of removed column.\n\t\tconst cellData = tableMap.find( value => value.cell === tableCell );\n\t\tconst removedColumn = cellData.column;\n\n\t\tmodel.change( writer => {\n\t\t\t// Update heading columns attribute if removing a row from head section.\n\t\t\tif ( headingColumns && row <= headingColumns ) {\n\t\t\t\twriter.setAttribute( 'headingColumns', headingColumns - 1, table );\n\t\t\t}\n\n\t\t\tfor ( const { cell, column, colspan } of tableMap ) {\n\t\t\t\t// If colspaned cell overlaps removed column decrease it's span.\n\t\t\t\tif ( column <= removedColumn && colspan > 1 && column + colspan > removedColumn ) {\n\t\t\t\t\tupdateNumericAttribute( 'colspan', colspan - 1, cell, writer );\n\t\t\t\t} else if ( column === removedColumn ) {\n\t\t\t\t\t// The cell in removed column has colspan of 1.\n\t\t\t\t\twriter.remove( cell );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/commands/setheaderrowcommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\n\nimport { createEmptyTableCell, findAncestor, updateNumericAttribute } from './utils';\nimport TableWalker from '../tablewalker';\n\n/**\n * The header row command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as `'setTableColumnHeader'` editor command.\n *\n * You can make the row containing the selected cell a [header](https://www.w3.org/TR/html50/tabular-data.html#the-th-element) by executing:\n *\n *\t\teditor.execute( 'setTableRowHeader' );\n *\n * **Note:** All preceding rows will also become headers. If the current row is already a header, executing this command\n * will make it a regular row back again (including the following rows).\n *\n * @extends module:core/command~Command\n */\nexport default class SetHeaderRowCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tconst selection = doc.selection;\n\n\t\tconst position = selection.getFirstPosition();\n\t\tconst tableCell = findAncestor( 'tableCell', position );\n\t\tconst isInTable = !!tableCell;\n\n\t\tthis.isEnabled = isInTable;\n\n\t\t/**\n\t\t * Flag indicating whether the command is active. The command is active when the\n\t\t * {@link module:engine/model/selection~Selection} is in a header row.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #value\n\t\t */\n\t\tthis.value = isInTable && this._isInHeading( tableCell, tableCell.parent.parent );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * When the selection is in a non-header row, the command will set the `headingRows` table attribute to cover that row.\n\t *\n\t * When the selection is already in a header row, it will set `headingRows` so the heading section will end before that row.\n\t *\n\t * @fires execute\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tconst selection = doc.selection;\n\n\t\tconst position = selection.getFirstPosition();\n\t\tconst tableCell = findAncestor( 'tableCell', position );\n\t\tconst tableRow = tableCell.parent;\n\t\tconst table = tableRow.parent;\n\n\t\tconst currentHeadingRows = table.getAttribute( 'headingRows' ) || 0;\n\t\tconst selectionRow = tableRow.index;\n\n\t\tconst headingRowsToSet = currentHeadingRows > selectionRow ? selectionRow : selectionRow + 1;\n\n\t\tmodel.change( writer => {\n\t\t\tif ( headingRowsToSet ) {\n\t\t\t\t// Changing heading rows requires to check if any of a heading cell is overlapping vertically the table head.\n\t\t\t\t// Any table cell that has a rowspan attribute > 1 will not exceed the table head so we need to fix it in rows below.\n\t\t\t\tconst cellsToSplit = getOverlappingCells( table, headingRowsToSet, currentHeadingRows );\n\n\t\t\t\tfor ( const cell of cellsToSplit ) {\n\t\t\t\t\tsplitHorizontally( cell, headingRowsToSet, writer );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tupdateNumericAttribute( 'headingRows', headingRowsToSet, table, writer, 0 );\n\t\t} );\n\t}\n\n\t/**\n\t * Checks if a table cell is in the heading section.\n\t *\n\t * @param {module:engine/model/element~Element} tableCell\n\t * @param {module:engine/model/element~Element} table\n\t * @returns {Boolean}\n\t * @private\n\t */\n\t_isInHeading( tableCell, table ) {\n\t\tconst headingRows = parseInt( table.getAttribute( 'headingRows' ) || 0 );\n\n\t\treturn !!headingRows && tableCell.parent.index < headingRows;\n\t}\n}\n\n// Returns cells that span beyond the new heading section.\n//\n// @param {module:engine/model/element~Element} table The table to check.\n// @param {Number} headingRowsToSet New heading rows attribute.\n// @param {Number} currentHeadingRows Current heading rows attribute.\n// @returns {Array.<module:engine/model/element~Element>}\nfunction getOverlappingCells( table, headingRowsToSet, currentHeadingRows ) {\n\tconst cellsToSplit = [];\n\n\tconst startAnalysisRow = headingRowsToSet > currentHeadingRows ? currentHeadingRows : 0;\n\t// We're analyzing only when headingRowsToSet > 0.\n\tconst endAnalysisRow = headingRowsToSet - 1;\n\n\tconst tableWalker = new TableWalker( table, { startRow: startAnalysisRow, endRow: endAnalysisRow } );\n\n\tfor ( const { row, rowspan, cell } of tableWalker ) {\n\t\tif ( rowspan > 1 && row + rowspan > headingRowsToSet ) {\n\t\t\tcellsToSplit.push( cell );\n\t\t}\n\t}\n\n\treturn cellsToSplit;\n}\n\n// Splits the table cell horizontally.\n//\n// @param {module:engine/model/element~Element} tableCell\n// @param {Number} headingRows\n// @param {module:engine/model/writer~Writer} writer\nfunction splitHorizontally( tableCell, headingRows, writer ) {\n\tconst tableRow = tableCell.parent;\n\tconst table = tableRow.parent;\n\tconst rowIndex = tableRow.index;\n\n\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) );\n\tconst newRowspan = headingRows - rowIndex;\n\n\tconst attributes = {};\n\n\tconst spanToSet = rowspan - newRowspan;\n\n\tif ( spanToSet > 1 ) {\n\t\tattributes.rowspan = spanToSet;\n\t}\n\n\tconst startRow = table.getChildIndex( tableRow );\n\tconst endRow = startRow + newRowspan;\n\tconst tableMap = [ ...new TableWalker( table, { startRow, endRow, includeSpanned: true } ) ];\n\n\tlet columnIndex;\n\n\tfor ( const { row, column, cell, colspan, cellIndex } of tableMap ) {\n\t\tif ( cell === tableCell ) {\n\t\t\tcolumnIndex = column;\n\n\t\t\tif ( colspan > 1 ) {\n\t\t\t\tattributes.colspan = colspan;\n\t\t\t}\n\t\t}\n\n\t\tif ( columnIndex !== undefined && columnIndex === column && row === endRow ) {\n\t\t\tconst tableRow = table.getChild( row );\n\t\t\tconst tableCellPosition = writer.createPositionAt( tableRow, cellIndex );\n\n\t\t\tcreateEmptyTableCell( writer, tableCellPosition, attributes );\n\t\t}\n\t}\n\n\t// Update the rowspan attribute after updating table.\n\tupdateNumericAttribute( 'rowspan', newRowspan, tableCell, writer );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/commands/setheadercolumncommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\n\nimport { findAncestor, updateNumericAttribute } from './utils';\n\n/**\n * The header column command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as `'setTableColumnHeader'` editor command.\n *\n * You can make the column containing the selected cell a [header](https://www.w3.org/TR/html50/tabular-data.html#the-th-element)\n * by executing:\n *\n *\t\teditor.execute( 'setTableColumnHeader' );\n *\n * **Note:** All preceding columns will also become headers. If the current column is already a header, executing this command\n * will make it a regular column back again (including the following columns).\n *\n * @extends module:core/command~Command\n */\nexport default class SetHeaderColumnCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tconst selection = doc.selection;\n\n\t\tconst position = selection.getFirstPosition();\n\t\tconst tableCell = findAncestor( 'tableCell', position );\n\n\t\tconst isInTable = !!tableCell;\n\n\t\tthis.isEnabled = isInTable;\n\n\t\t/**\n\t\t * Flag indicating whether the command is active. The command is active when the\n\t\t * {@link module:engine/model/selection~Selection} is in a header column.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #value\n\t\t */\n\t\tthis.value = isInTable && this._isInHeading( tableCell, tableCell.parent.parent );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * When the selection is in a non-header column, the command will set the `headingColumns` table attribute to cover that column.\n\t *\n\t * When the selection is already in a header column, it will set `headingColumns` so the heading section will end before that column.\n\t *\n\t * @fires execute\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tconst selection = doc.selection;\n\t\tconst tableUtils = this.editor.plugins.get( 'TableUtils' );\n\n\t\tconst position = selection.getFirstPosition();\n\t\tconst tableCell = findAncestor( 'tableCell', position.parent );\n\t\tconst tableRow = tableCell.parent;\n\t\tconst table = tableRow.parent;\n\n\t\tconst currentHeadingColumns = parseInt( table.getAttribute( 'headingColumns' ) || 0 );\n\t\tconst { column: selectionColumn } = tableUtils.getCellLocation( tableCell );\n\n\t\tconst headingColumnsToSet = currentHeadingColumns > selectionColumn ? selectionColumn : selectionColumn + 1;\n\n\t\tmodel.change( writer => {\n\t\t\tupdateNumericAttribute( 'headingColumns', headingColumnsToSet, table, writer, 0 );\n\t\t} );\n\t}\n\n\t/**\n\t * Checks if a table cell is in the heading section.\n\t *\n\t * @param {module:engine/model/element~Element} tableCell\n\t * @param {module:engine/model/element~Element} table\n\t * @returns {Boolean}\n\t * @private\n\t */\n\t_isInHeading( tableCell, table ) {\n\t\tconst headingColumns = parseInt( table.getAttribute( 'headingColumns' ) || 0 );\n\n\t\tconst tableUtils = this.editor.plugins.get( 'TableUtils' );\n\n\t\tconst { column } = tableUtils.getCellLocation( tableCell );\n\n\t\treturn !!headingColumns && column < headingColumns;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/tableutils\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport TableWalker from './tablewalker';\nimport { createEmptyTableCell, updateNumericAttribute } from './commands/utils';\n\n/**\n * The table utilities plugin.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableUtils extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TableUtils';\n\t}\n\n\t/**\n\t * Returns the table cell location as an object with table row and table column indexes.\n\t *\n\t * For instance in the table below:\n\t *\n\t *\t\t 0 1 2 3\n\t *\t\t +---+---+---+---+\n\t *\t\t0 | a | b | c |\n\t *\t\t + + +---+\n\t *\t\t1 | | | d |\n\t *\t\t +---+---+ +---+\n\t *\t\t2 | e | | f |\n\t *\t\t +---+---+---+---+\n\t *\n\t * the method will return:\n\t *\n\t *\t\tconst cellA = table.getNodeByPath( [ 0, 0 ] );\n\t *\t\teditor.plugins.get( 'TableUtils' ).getCellLocation( cellA );\n\t *\t\t// will return { row: 0, column: 0 }\n\t *\n\t *\t\tconst cellD = table.getNodeByPath( [ 1, 0 ] );\n\t *\t\teditor.plugins.get( 'TableUtils' ).getCellLocation( cellD );\n\t *\t\t// will return { row: 1, column: 3 }\n\t *\n\t * @param {module:engine/model/element~Element} tableCell\n\t * @returns {Object} Returns a `{row, column}` object.\n\t */\n\tgetCellLocation( tableCell ) {\n\t\tconst tableRow = tableCell.parent;\n\t\tconst table = tableRow.parent;\n\n\t\tconst rowIndex = table.getChildIndex( tableRow );\n\n\t\tconst tableWalker = new TableWalker( table, { startRow: rowIndex, endRow: rowIndex } );\n\n\t\tfor ( const { cell, row, column } of tableWalker ) {\n\t\t\tif ( cell === tableCell ) {\n\t\t\t\treturn { row, column };\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Creates an empty table with proper structure. The table needs to be inserted into the model,\n\t * ie. using {@link module:engine/model/model~Model#insertContent} function.\n\t *\n\t *\t\tmodel.change( ( writer ) => {\n\t *\t\t\t// Create a table of 2 rows and 7 columns:\n\t *\t\t\tconst table = tableUtils.createTable( writer, 2, 7);\n\t *\n\t *\t\t\t// Insert table to the model at the best position taking current selection:\n\t *\t\t\tmodel.insertContent( table );\n\t *\t\t}\n\t *\n\t * @param {module:engine/model/writer~Writer} writer The model writer.\n\t * @param {Number} rows The number of rows to create.\n\t * @param {Number} columns The number of columns to create.\n\t * @returns {module:engine/model/element~Element} The created table element.\n\t */\n\tcreateTable( writer, rows, columns ) {\n\t\tconst table = writer.createElement( 'table' );\n\n\t\tcreateEmptyRows( writer, table, 0, rows, columns );\n\n\t\treturn table;\n\t}\n\n\t/**\n\t * Inserts rows into a table.\n\t *\n\t *\t\teditor.plugins.get( 'TableUtils' ).insertRows( table, { at: 1, rows: 2 } );\n\t *\n\t * Assuming the table on the left, the above code will transform it to the table on the right:\n\t *\n\t *\t\trow index\n\t *\t\t 0 +---+---+---+ `at` = 1, +---+---+---+ 0\n\t *\t\t | a | b | c | `rows` = 2, | a | b | c |\n\t *\t\t 1 + +---+---+ <-- insert here + +---+---+ 1\n\t *\t\t | | d | e | | | | |\n\t *\t\t 2 + +---+---+ will give: + +---+---+ 2\n\t *\t\t | | f | g | | | | |\n\t *\t\t 3 +---+---+---+ + +---+---+ 3\n\t *\t\t | | d | e |\n\t *\t\t +---+---+---+ 4\n\t *\t\t + + f | g |\n\t *\t\t +---+---+---+ 5\n\t *\n\t * @param {module:engine/model/element~Element} table The table model element where the rows will be inserted.\n\t * @param {Object} options\n\t * @param {Number} [options.at=0] Row index at which the rows will be inserted.\n\t * @param {Number} [options.rows=1] The number of rows to insert.\n\t */\n\tinsertRows( table, options = {} ) {\n\t\tconst model = this.editor.model;\n\n\t\tconst insertAt = options.at || 0;\n\t\tconst rowsToInsert = options.rows || 1;\n\n\t\tmodel.change( writer => {\n\t\t\tconst headingRows = table.getAttribute( 'headingRows' ) || 0;\n\n\t\t\t// Inserting rows inside heading section requires to update `headingRows` attribute as the heading section will grow.\n\t\t\tif ( headingRows > insertAt ) {\n\t\t\t\twriter.setAttribute( 'headingRows', headingRows + rowsToInsert, table );\n\t\t\t}\n\n\t\t\t// Inserting at the end and at the beginning of a table doesn't require to calculate anything special.\n\t\t\tif ( insertAt === 0 || insertAt === table.childCount ) {\n\t\t\t\tcreateEmptyRows( writer, table, insertAt, rowsToInsert, this.getColumns( table ) );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Iterate over all rows above inserted rows in order to check for rowspanned cells.\n\t\t\tconst tableIterator = new TableWalker( table, { endRow: insertAt } );\n\n\t\t\t// Will hold number of cells needed to insert in created rows.\n\t\t\t// The number might be different then table cell width when there are rowspanned cells.\n\t\t\tlet cellsToInsert = 0;\n\n\t\t\tfor ( const { row, rowspan, colspan, cell } of tableIterator ) {\n\t\t\t\tconst isBeforeInsertedRow = row < insertAt;\n\t\t\t\tconst overlapsInsertedRow = row + rowspan > insertAt;\n\n\t\t\t\tif ( isBeforeInsertedRow && overlapsInsertedRow ) {\n\t\t\t\t\t// This cell overlaps inserted rows so we need to expand it further.\n\t\t\t\t\twriter.setAttribute( 'rowspan', rowspan + rowsToInsert, cell );\n\t\t\t\t}\n\n\t\t\t\t// Calculate how many cells to insert based on the width of cells in a row at insert position.\n\t\t\t\t// It might be lower then table width as some cells might overlaps inserted row.\n\t\t\t\t// In the table above the cell 'a' overlaps inserted row so only two empty cells are need to be created.\n\t\t\t\tif ( row === insertAt ) {\n\t\t\t\t\tcellsToInsert += colspan;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcreateEmptyRows( writer, table, insertAt, rowsToInsert, cellsToInsert );\n\t\t} );\n\t}\n\n\t/**\n\t * Inserts columns into a table.\n\t *\n\t *\t\teditor.plugins.get( 'TableUtils' ).insertColumns( table, { at: 1, columns: 2 } );\n\t *\n\t * Assuming the table on the left, the above code will transform it to the table on the right:\n\t *\n\t *\t\t0 1 2 3 0 1 2 3 4 5\n\t *\t\t+---+---+---+ +---+---+---+---+---+\n\t *\t\t| a | b | | a | b |\n\t *\t\t+ +---+ + +---+\n\t *\t\t| | c | | | c |\n\t *\t\t+---+---+---+ will give: +---+---+---+---+---+\n\t *\t\t| d | e | f | | d | | | e | f |\n\t *\t\t+---+ +---+ +---+---+---+ +---+\n\t *\t\t| g | | h | | g | | | | h |\n\t *\t\t+---+---+---+ +---+---+---+---+---+\n\t *\t\t| i | | i |\n\t *\t\t+---+---+---+ +---+---+---+---+---+\n\t *\t\t ^---- insert here, `at` = 1, `columns` = 2\n\t *\n\t * @param {module:engine/model/element~Element} table The table model element where the columns will be inserted.\n\t * @param {Object} options\n\t * @param {Number} [options.at=0] Column index at which the columns will be inserted.\n\t * @param {Number} [options.columns=1] The number of columns to insert.\n\t */\n\tinsertColumns( table, options = {} ) {\n\t\tconst model = this.editor.model;\n\n\t\tconst insertAt = options.at || 0;\n\t\tconst columnsToInsert = options.columns || 1;\n\n\t\tmodel.change( writer => {\n\t\t\tconst headingColumns = table.getAttribute( 'headingColumns' );\n\n\t\t\t// Inserting columns inside heading section requires to update `headingColumns` attribute as the heading section will grow.\n\t\t\tif ( insertAt < headingColumns ) {\n\t\t\t\twriter.setAttribute( 'headingColumns', headingColumns + columnsToInsert, table );\n\t\t\t}\n\n\t\t\tconst tableColumns = this.getColumns( table );\n\n\t\t\t// Inserting at the end and at the beginning of a table doesn't require to calculate anything special.\n\t\t\tif ( insertAt === 0 || tableColumns === insertAt ) {\n\t\t\t\tfor ( const tableRow of table.getChildren() ) {\n\t\t\t\t\tcreateCells( columnsToInsert, writer, writer.createPositionAt( tableRow, insertAt ? 'end' : 0 ) );\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst tableWalker = new TableWalker( table, { column: insertAt, includeSpanned: true } );\n\n\t\t\tfor ( const { row, column, cell, colspan, rowspan, cellIndex } of tableWalker ) {\n\t\t\t\t// When iterating over column the table walker outputs either:\n\t\t\t\t// - cells at given column index (cell \"e\" from method docs),\n\t\t\t\t// - spanned columns (spanned cell from row between cells \"g\" and \"h\" - spanned by \"e\", only if `includeSpanned: true`),\n\t\t\t\t// - or a cell from the same row which spans over this column (cell \"a\").\n\n\t\t\t\tif ( column !== insertAt ) {\n\t\t\t\t\t// If column is different than `insertAt`, it is a cell that spans over an inserted column (cell \"a\" & \"i\").\n\t\t\t\t\t// For such cells expand them by a number of columns inserted.\n\t\t\t\t\twriter.setAttribute( 'colspan', colspan + columnsToInsert, cell );\n\n\t\t\t\t\t// The `includeSpanned` option will output the \"empty\"/spanned column so skip this row already.\n\t\t\t\t\ttableWalker.skipRow( row );\n\n\t\t\t\t\t// This cell will overlap cells in rows below so skip them also (because of `includeSpanned` option) - (cell \"a\")\n\t\t\t\t\tif ( rowspan > 1 ) {\n\t\t\t\t\t\tfor ( let i = row + 1; i < row + rowspan; i++ ) {\n\t\t\t\t\t\t\ttableWalker.skipRow( i );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// It's either cell at this column index or spanned cell by a rowspanned cell from row above.\n\t\t\t\t\t// In table above it's cell \"e\" and a spanned position from row below (empty cell between cells \"g\" and \"h\")\n\t\t\t\t\tconst insertPosition = writer.createPositionAt( table.getChild( row ), cellIndex );\n\n\t\t\t\t\tcreateCells( columnsToInsert, writer, insertPosition );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Divides a table cell vertically into several ones.\n\t *\n\t * The cell will be visually split into more cells by updating colspans of other cells in a column\n\t * and inserting cells (columns) after that cell.\n\t *\n\t * In the table below, if cell \"a\" is split to 3 cells:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a | b | c |\n\t *\t\t+---+---+---+\n\t *\t\t| d | e | f |\n\t *\t\t+---+---+---+\n\t *\n\t * it will result in the table below:\n\t *\n\t *\t\t+---+---+---+---+---+\n\t *\t\t| a | | | b | c |\n\t *\t\t+---+---+---+---+---+\n\t *\t\t| d | e | f |\n\t *\t\t+---+---+---+---+---+\n\t *\n\t * So cell \"d\" will get its `colspan` updated to `3` and 2 cells will be added (2 columns will be created).\n\t *\n\t * Splitting a cell that already has a `colspan` attribute set will distribute the cell `colspan` evenly and the remainder\n\t * will be left to the original cell:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a |\n\t *\t\t+---+---+---+\n\t *\t\t| b | c | d |\n\t *\t\t+---+---+---+\n\t *\n\t * Splitting cell \"a\" with `colspan=3` to 2 cells will create 1 cell with a `colspan=a` and cell \"a\" that will have `colspan=2`:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a | |\n\t *\t\t+---+---+---+\n\t *\t\t| b | c | d |\n\t *\t\t+---+---+---+\n\t *\n\t * @param {module:engine/model/element~Element} tableCell\n\t * @param {Number} numberOfCells\n\t */\n\tsplitCellVertically( tableCell, numberOfCells = 2 ) {\n\t\tconst model = this.editor.model;\n\t\tconst tableRow = tableCell.parent;\n\t\tconst table = tableRow.parent;\n\n\t\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );\n\t\tconst colspan = parseInt( tableCell.getAttribute( 'colspan' ) || 1 );\n\n\t\tmodel.change( writer => {\n\t\t\t// First check - the cell spans over multiple rows so before doing anything else just split this cell.\n\t\t\tif ( colspan > 1 ) {\n\t\t\t\t// Get spans of new (inserted) cells and span to update of split cell.\n\t\t\t\tconst { newCellsSpan, updatedSpan } = breakSpanEvenly( colspan, numberOfCells );\n\n\t\t\t\tupdateNumericAttribute( 'colspan', updatedSpan, tableCell, writer );\n\n\t\t\t\t// Each inserted cell will have the same attributes:\n\t\t\t\tconst newCellsAttributes = {};\n\n\t\t\t\t// Do not store default value in the model.\n\t\t\t\tif ( newCellsSpan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.colspan = newCellsSpan;\n\t\t\t\t}\n\n\t\t\t\t// Copy rowspan of split cell.\n\t\t\t\tif ( rowspan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.rowspan = rowspan;\n\t\t\t\t}\n\n\t\t\t\tconst cellsToInsert = colspan > numberOfCells ? numberOfCells - 1 : colspan - 1;\n\t\t\t\tcreateCells( cellsToInsert, writer, writer.createPositionAfter( tableCell ), newCellsAttributes );\n\t\t\t}\n\n\t\t\t// Second check - the cell has colspan of 1 or we need to create more cells then the currently one spans over.\n\t\t\tif ( colspan < numberOfCells ) {\n\t\t\t\tconst cellsToInsert = numberOfCells - colspan;\n\n\t\t\t\t// First step: expand cells on the same column as split cell.\n\t\t\t\tconst tableMap = [ ...new TableWalker( table ) ];\n\n\t\t\t\t// Get the column index of split cell.\n\t\t\t\tconst { column: splitCellColumn } = tableMap.find( ( { cell } ) => cell === tableCell );\n\n\t\t\t\t// Find cells which needs to be expanded vertically - those on the same column or those that spans over split cell's column.\n\t\t\t\tconst cellsToUpdate = tableMap.filter( ( { cell, colspan, column } ) => {\n\t\t\t\t\tconst isOnSameColumn = cell !== tableCell && column === splitCellColumn;\n\t\t\t\t\tconst spansOverColumn = ( column < splitCellColumn && column + colspan > splitCellColumn );\n\n\t\t\t\t\treturn isOnSameColumn || spansOverColumn;\n\t\t\t\t} );\n\n\t\t\t\t// Expand cells vertically.\n\t\t\t\tfor ( const { cell, colspan } of cellsToUpdate ) {\n\t\t\t\t\twriter.setAttribute( 'colspan', colspan + cellsToInsert, cell );\n\t\t\t\t}\n\n\t\t\t\t// Second step: create columns after split cell.\n\n\t\t\t\t// Each inserted cell will have the same attributes:\n\t\t\t\tconst newCellsAttributes = {};\n\n\t\t\t\t// Do not store default value in the model.\n\n\t\t\t\t// Copy rowspan of split cell.\n\t\t\t\tif ( rowspan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.rowspan = rowspan;\n\t\t\t\t}\n\n\t\t\t\tcreateCells( cellsToInsert, writer, writer.createPositionAfter( tableCell ), newCellsAttributes );\n\n\t\t\t\tconst headingColumns = table.getAttribute( 'headingColumns' ) || 0;\n\n\t\t\t\t// Update heading section if split cell is in heading section.\n\t\t\t\tif ( headingColumns > splitCellColumn ) {\n\t\t\t\t\tupdateNumericAttribute( 'headingColumns', headingColumns + cellsToInsert, table, writer );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Divides a table cell horizontally into several ones.\n\t *\n\t * The cell will be visually split into more cells by updating rowspans of other cells in the row and inserting rows with a single cell\n\t * below.\n\t *\n\t * If in the table below cell \"b\" is split to 3 cells:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a | b | c |\n\t *\t\t+---+---+---+\n\t *\t\t| d | e | f |\n\t *\t\t+---+---+---+\n\t *\n\t * It will result in the table below:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a | b | c |\n\t *\t\t+ +---+ +\n\t *\t\t| | | |\n\t *\t\t+ +---+ +\n\t *\t\t| | | |\n\t *\t\t+---+---+---+\n\t *\t\t| d | e | f |\n\t *\t\t+---+---+---+\n\t *\n\t * So cells \"a\" and \"b\" will get their `rowspan` updated to `3` and 2 rows with a single cell will be added.\n\t *\n\t * Splitting a cell that already has a `rowspan` attribute set will distribute the cell `rowspan` evenly and the remainder\n\t * will be left to the original cell:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a | b | c |\n\t *\t\t+ +---+---+\n\t *\t\t| | d | e |\n\t *\t\t+ +---+---+\n\t *\t\t| | f | g |\n\t *\t\t+ +---+---+\n\t *\t\t| | h | i |\n\t *\t\t+---+---+---+\n\t *\n\t * Splitting cell \"a\" with `rowspan=4` to 3 cells will create 2 cells with a `rowspan=1` and cell \"a\" will have `rowspan=2`:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a | b | c |\n\t *\t\t+ +---+---+\n\t *\t\t| | d | e |\n\t *\t\t+---+---+---+\n\t *\t\t| | f | g |\n\t *\t\t+---+---+---+\n\t *\t\t| | h | i |\n\t *\t\t+---+---+---+\n\t *\n\t * @param {module:engine/model/element~Element} tableCell\n\t * @param {Number} numberOfCells\n\t */\n\tsplitCellHorizontally( tableCell, numberOfCells = 2 ) {\n\t\tconst model = this.editor.model;\n\n\t\tconst tableRow = tableCell.parent;\n\t\tconst table = tableRow.parent;\n\t\tconst splitCellRow = table.getChildIndex( tableRow );\n\n\t\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );\n\t\tconst colspan = parseInt( tableCell.getAttribute( 'colspan' ) || 1 );\n\n\t\tmodel.change( writer => {\n\t\t\t// First check - the cell spans over multiple rows so before doing anything else just split this cell.\n\t\t\tif ( rowspan > 1 ) {\n\t\t\t\t// Cache table map before updating table.\n\t\t\t\tconst tableMap = [ ...new TableWalker( table, {\n\t\t\t\t\tstartRow: splitCellRow,\n\t\t\t\t\tendRow: splitCellRow + rowspan - 1,\n\t\t\t\t\tincludeSpanned: true\n\t\t\t\t} ) ];\n\n\t\t\t\t// Get spans of new (inserted) cells and span to update of split cell.\n\t\t\t\tconst { newCellsSpan, updatedSpan } = breakSpanEvenly( rowspan, numberOfCells );\n\n\t\t\t\tupdateNumericAttribute( 'rowspan', updatedSpan, tableCell, writer );\n\n\t\t\t\tconst { column: cellColumn } = tableMap.find( ( { cell } ) => cell === tableCell );\n\n\t\t\t\t// Each inserted cell will have the same attributes:\n\t\t\t\tconst newCellsAttributes = {};\n\n\t\t\t\t// Do not store default value in the model.\n\t\t\t\tif ( newCellsSpan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.rowspan = newCellsSpan;\n\t\t\t\t}\n\n\t\t\t\t// Copy colspan of split cell.\n\t\t\t\tif ( colspan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.colspan = colspan;\n\t\t\t\t}\n\n\t\t\t\tfor ( const { column, row, cellIndex } of tableMap ) {\n\t\t\t\t\t// As both newly created cells and the split cell might have rowspan,\n\t\t\t\t\t// the insertion of new cells must go to appropriate rows:\n\t\t\t\t\t//\n\t\t\t\t\t// 1. It's a row after split cell + it's height.\n\t\t\t\t\tconst isAfterSplitCell = row >= splitCellRow + updatedSpan;\n\t\t\t\t\t// 2. Is on the same column.\n\t\t\t\t\tconst isOnSameColumn = column === cellColumn;\n\t\t\t\t\t// 3. And it's row index is after previous cell height.\n\t\t\t\t\tconst isInEvenlySplitRow = ( row + splitCellRow + updatedSpan ) % newCellsSpan === 0;\n\n\t\t\t\t\tif ( isAfterSplitCell && isOnSameColumn && isInEvenlySplitRow ) {\n\t\t\t\t\t\tconst position = writer.createPositionAt( table.getChild( row ), cellIndex );\n\n\t\t\t\t\t\tcreateCells( 1, writer, position, newCellsAttributes );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Second check - the cell has rowspan of 1 or we need to create more cells than the current cell spans over.\n\t\t\tif ( rowspan < numberOfCells ) {\n\t\t\t\t// We already split the cell in check one so here we split to the remaining number of cells only.\n\t\t\t\tconst cellsToInsert = numberOfCells - rowspan;\n\n\t\t\t\t// This check is needed since we need to check if there are any cells from previous rows than spans over this cell's row.\n\t\t\t\tconst tableMap = [ ...new TableWalker( table, { startRow: 0, endRow: splitCellRow } ) ];\n\n\t\t\t\t// First step: expand cells.\n\t\t\t\tfor ( const { cell, rowspan, row } of tableMap ) {\n\t\t\t\t\t// Expand rowspan of cells that are either:\n\t\t\t\t\t// - on the same row as current cell,\n\t\t\t\t\t// - or are below split cell row and overlaps that row.\n\t\t\t\t\tif ( cell !== tableCell && row + rowspan > splitCellRow ) {\n\t\t\t\t\t\tconst rowspanToSet = rowspan + cellsToInsert;\n\n\t\t\t\t\t\twriter.setAttribute( 'rowspan', rowspanToSet, cell );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Second step: create rows with single cell below split cell.\n\t\t\t\tconst newCellsAttributes = {};\n\n\t\t\t\t// Copy colspan of split cell.\n\t\t\t\tif ( colspan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.colspan = colspan;\n\t\t\t\t}\n\n\t\t\t\tcreateEmptyRows( writer, table, splitCellRow + 1, cellsToInsert, 1, newCellsAttributes );\n\n\t\t\t\t// Update heading section if split cell is in heading section.\n\t\t\t\tconst headingRows = table.getAttribute( 'headingRows' ) || 0;\n\n\t\t\t\tif ( headingRows > splitCellRow ) {\n\t\t\t\t\tupdateNumericAttribute( 'headingRows', headingRows + cellsToInsert, table, writer );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Returns the number of columns for a given table.\n\t *\n\t *\t\teditor.plugins.get( 'TableUtils' ).getColumns( table );\n\t *\n\t * @param {module:engine/model/element~Element} table The table to analyze.\n\t * @returns {Number}\n\t */\n\tgetColumns( table ) {\n\t\t// Analyze first row only as all the rows should have the same width.\n\t\tconst row = table.getChild( 0 );\n\n\t\treturn [ ...row.getChildren() ].reduce( ( columns, row ) => {\n\t\t\tconst columnWidth = parseInt( row.getAttribute( 'colspan' ) || 1 );\n\n\t\t\treturn columns + columnWidth;\n\t\t}, 0 );\n\t}\n}\n\n// Creates empty rows at the given index in an existing table.\n//\n// @param {module:engine/model/writer~Writer} writer\n// @param {module:engine/model/element~Element} table\n// @param {Number} insertAt Row index of row insertion.\n// @param {Number} rows Number of rows to create.\n// @param {Number} tableCellToInsert Number of cells to insert in each row.\nfunction createEmptyRows( writer, table, insertAt, rows, tableCellToInsert, attributes = {} ) {\n\tfor ( let i = 0; i < rows; i++ ) {\n\t\tconst tableRow = writer.createElement( 'tableRow' );\n\n\t\twriter.insert( tableRow, table, insertAt );\n\n\t\tcreateCells( tableCellToInsert, writer, writer.createPositionAt( tableRow, 'end' ), attributes );\n\t}\n}\n\n// Creates cells at a given position.\n//\n// @param {Number} columns Number of columns to create\n// @param {module:engine/model/writer~Writer} writer\n// @param {module:engine/model/position~Position} insertPosition\nfunction createCells( cells, writer, insertPosition, attributes = {} ) {\n\tfor ( let i = 0; i < cells; i++ ) {\n\t\tcreateEmptyTableCell( writer, insertPosition, attributes );\n\t}\n}\n\n// Evenly distributes the span of a cell to a number of provided cells.\n// The resulting spans will always be integer values.\n//\n// For instance breaking a span of 7 into 3 cells will return:\n//\n//\t\t{ newCellsSpan: 2, updatedSpan: 3 }\n//\n// as two cells will have a span of 2 and the remainder will go the first cell so its span will change to 3.\n//\n// @param {Number} span Span value do break.\n// @param {Number} numberOfCells Number of resulting spans.\n// @returns {{newCellsSpan: Number, updatedSpan: Number}}\nfunction breakSpanEvenly( span, numberOfCells ) {\n\tif ( span < numberOfCells ) {\n\t\treturn { newCellsSpan: 1, updatedSpan: 1 };\n\t}\n\n\tconst newCellsSpan = Math.floor( span / numberOfCells );\n\tconst updatedSpan = ( span - newCellsSpan * numberOfCells ) + newCellsSpan;\n\n\treturn { newCellsSpan, updatedSpan };\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/converters/table-layout-post-fixer\n */\n\nimport { createEmptyTableCell, findAncestor, updateNumericAttribute } from './../commands/utils';\nimport TableWalker from './../tablewalker';\n\n/**\n * Injects a table layout post-fixer into the model.\n *\n * The role of the table layout post-fixer is to ensure that the table rows have the correct structure\n * after a {@link module:engine/model/model~Model#change `change()`} block was executed.\n *\n * The correct structure means that:\n *\n * * All table rows have the same size.\n * * None of a table cells that extend vertically beyond their section (either header or body).\n * * A table cell has always at least one element as child.\n *\n * If the table structure is not correct, the post-fixer will automatically correct it in two steps:\n *\n * 1. It will clip table cells that extends beyond it section.\n * 2. It will add empty table cells to those rows which are narrower then the widest table row.\n *\n * ## Clipping overlapping table cells\n *\n * Such situation may occur when pasting a table (or part of a table) to the editor from external sources.\n *\n * For example, see the following table which has the cell (FOO) with the rowspan attribute (2):\n *\n *\t\t<table headingRows=\"1\">\n *\t\t\t<tableRow>\n *\t\t\t\t<tableCell rowspan=\"2\"><paragraph>FOO</paragraph></tableCell>\n *\t\t\t\t<tableCell colspan=\"2\"><paragraph>BAR</paragraph></tableCell>\n *\t\t\t</tableRow>\n *\t\t\t<tableRow>\n *\t\t\t\t<tableCell><paragraph>BAZ</paragraph></tableCell>\n *\t\t\t\t<tableCell><paragraph>XYZ</paragraph></tableCell>\n *\t\t\t</tableRow>\n *\t\t</table>\n *\n * will be rendered in the view as:\n *\n *\t\t<table>\n *\t\t\t<thead>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td rowspan=\"2\">FOO</td>\n *\t\t\t\t\t<td colspan=\"2\">BAR</td>\n *\t\t\t\t</tr>\n *\t\t\t</thead>\n *\t\t\t<tbody>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>BAZ</td>\n *\t\t\t\t\t<td>XYZ</td>\n *\t\t\t\t</tr>\n *\t\t\t</tbody>\n *\t\t</table>\n *\n * In the above example the table will be rendered as a table with two rows - one in the header and second one in the body.\n * The table cell (FOO) cannot span over multiple rows as it would expand from the header to the body section.\n * The `rowspan` attribute must be changed to (1). The value (1) is a default value of the `rowspan` attribute\n * so the `rowspan` attribute will be removed from the model.\n *\n * The table cell with BAZ contents will be in the first column of the table.\n *\n * ## Adding missing table cells\n *\n * The table post-fixer will insert empty table cells to equalize table rows sizes (number of columns).\n * The size of a table row is calculated by counting column spans of table cells - both horizontal (from the same row) and\n * vertical (from rows above).\n *\n * In the above example, the table row in the body section of the table is narrower then the row from the header - it has two cells\n * with the default colspan (1). The header row has one cell with colspan (1) and second with colspan (2).\n * The table cell (FOO) does not expand beyond the head section (and as such will be fixed in the first step of this post-fixer).\n * The post-fixer will add a missing table cell to the row in the body section of the table.\n *\n * The table from the above example will be fixed and rendered to the view as below:\n *\n *\t\t<table>\n *\t\t\t<thead>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td rowspan=\"2\">FOO</td>\n *\t\t\t\t\t<td colspan=\"2\">BAR</td>\n *\t\t\t\t</tr>\n *\t\t\t</thead>\n *\t\t\t<tbody>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>BAZ</td>\n *\t\t\t\t\t<td>XYZ</td>\n *\t\t\t\t</tr>\n *\t\t\t</tbody>\n *\t\t</table>\n *\n * ## Collaboration & Undo - Expectations vs post-fixer results\n *\n * The table post-fixer only ensures proper structure without deeper analysis of the nature of a change. As such, it might lead\n * to a structure which was not intended by the user changes. In particular, it will also fix undo steps (in conjunction with collaboration)\n * in which editor content might not return to the original state.\n *\n * This will usually happen when one or more users changes size of the table.\n *\n * As en example see a table below:\n *\n *\t\t<table>\n *\t\t\t<tbody>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>11</td>\n *\t\t\t\t\t<td>12</td>\n *\t\t\t\t</tr>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>21</td>\n *\t\t\t\t\t<td>22</td>\n *\t\t\t\t</tr>\n *\t\t\t</tbody>\n *\t\t</table>\n *\n * and user actions:\n *\n * 1. Both user have table with two rows and two columns.\n * 2. User A adds a column at the end of the table - this will insert empty table cells to two rows.\n * 3. User B adds a row at the end of the table- this will insert a row with two empty table cells.\n * 4. Both users will have a table as below:\n *\n *\n *\t\t<table>\n *\t\t\t<tbody>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>11</td>\n *\t\t\t\t\t<td>12</td>\n *\t\t\t\t\t<td>(empty, inserted by A)</td>\n *\t\t\t\t</tr>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>21</td>\n *\t\t\t\t\t<td>22</td>\n *\t\t\t\t\t<td>(empty, inserted by A)</td>\n *\t\t\t\t</tr>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>(empty, inserted by B)</td>\n *\t\t\t\t\t<td>(empty, inserted by B)</td>\n *\t\t\t\t</tr>\n *\t\t\t</tbody>\n *\t\t</table>\n *\n * The last row is shorter then others so table post-fixer will add empty row to tha last row:\n *\n *\t\t<table>\n *\t\t\t<tbody>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>11</td>\n *\t\t\t\t\t<td>12</td>\n *\t\t\t\t\t<td>(empty, inserted by A)</td>\n *\t\t\t\t</tr>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>21</td>\n *\t\t\t\t\t<td>22</td>\n *\t\t\t\t\t<td>(empty, inserted by A)</td>\n *\t\t\t\t</tr>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>(empty, inserted by B)</td>\n *\t\t\t\t\t<td>(empty, inserted by B)</td>\n *\t\t\t\t\t<td>(empty, inserted by a post-fixer)</td>\n *\t\t\t\t</tr>\n *\t\t\t</tbody>\n *\t\t</table>\n *\n * Unfortunately undo doesn't know the nature of changes and depending which user will apply post-fixer changes undoing them might lead to\n * broken table. If User B will undo inserting column to a table the undo engine will undo only operations of\n * inserting empty cells to rows from initial table state (row 1 & 2) but the cell in post-fixed row will remain:\n *\n *\t\t<table>\n *\t\t\t<tbody>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>11</td>\n *\t\t\t\t\t<td>12</td>\n *\t\t\t\t</tr>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>21</td>\n *\t\t\t\t\t<td>22</td>\n *\t\t\t\t</tr>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>(empty, inserted by B)</td>\n *\t\t\t\t\t<td>(empty, inserted by B)</td>\n *\t\t\t\t\t<td>(empty, inserted by a post-fixer)</td>\n *\t\t\t\t</tr>\n *\t\t\t</tbody>\n *\t\t</table>\n *\n * After undo the table post-fixer will detect that two rows are shorter then other and will fix table to:\n *\n *\t\t<table>\n *\t\t\t<tbody>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>11</td>\n *\t\t\t\t\t<td>12</td>\n *\t\t\t\t\t<td>(empty, inserted by a post-fixer after undo)</td>\n *\t\t\t\t</tr>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>21</td>\n *\t\t\t\t\t<td>22</td>\n *\t\t\t\t\t<td>(empty, inserted by a post-fixer after undo)</td>\n *\t\t\t\t</tr>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>(empty, inserted by B)</td>\n *\t\t\t\t\t<td>(empty, inserted by B)</td>\n *\t\t\t\t\t<td>(empty, inserted by a post-fixer)</td>\n *\t\t\t\t</tr>\n *\t\t\t</tbody>\n *\t\t</table>\n * @param {module:engine/model/model~Model} model\n */\nexport default function injectTableLayoutPostFixer( model ) {\n\tmodel.document.registerPostFixer( writer => tableLayoutPostFixer( writer, model ) );\n}\n\n// The table layout post-fixer.\n//\n// @param {module:engine/model/writer~Writer} writer\n// @param {module:engine/model/model~Model} model\nfunction tableLayoutPostFixer( writer, model ) {\n\tconst changes = model.document.differ.getChanges();\n\n\tlet wasFixed = false;\n\n\t// Do not analyze the same table more then once - may happen for multiple changes in the same table.\n\tconst analyzedTables = new Set();\n\n\tfor ( const entry of changes ) {\n\t\tlet table;\n\n\t\tif ( entry.name == 'table' && entry.type == 'insert' ) {\n\t\t\ttable = entry.position.nodeAfter;\n\t\t}\n\n\t\t// Fix table on adding/removing table cells and rows.\n\t\tif ( entry.name == 'tableRow' || entry.name == 'tableCell' ) {\n\t\t\ttable = findAncestor( 'table', entry.position );\n\t\t}\n\n\t\t// Fix table on any table's attribute change - including attributes of table cells.\n\t\tif ( isTableAttributeEntry( entry ) ) {\n\t\t\ttable = findAncestor( 'table', entry.range.start );\n\t\t}\n\n\t\tif ( table && !analyzedTables.has( table ) ) {\n\t\t\t// Step 1: correct rowspans of table cells if necessary.\n\t\t\t// The wasFixed flag should be true if any of tables in batch was fixed - might be more then one.\n\t\t\twasFixed = fixTableCellsRowspan( table, writer ) || wasFixed;\n\t\t\t// Step 2: fix table rows sizes.\n\t\t\twasFixed = fixTableRowsSizes( table, writer ) || wasFixed;\n\n\t\t\tanalyzedTables.add( table );\n\t\t}\n\t}\n\n\treturn wasFixed;\n}\n\n// Fixes the invalid value of the rowspan attribute because a table cell cannot vertically extend beyond the table section it belongs to.\n//\n// @param {module:engine/model/element~Element} table\n// @param {module:engine/model/writer~Writer} writer\n// @returns {Boolean} Returns true if table was fixed.\nfunction fixTableCellsRowspan( table, writer ) {\n\tlet wasFixed = false;\n\n\tconst cellsToTrim = findCellsToTrim( table );\n\n\tif ( cellsToTrim.length ) {\n\t\twasFixed = true;\n\n\t\tfor ( const data of cellsToTrim ) {\n\t\t\tupdateNumericAttribute( 'rowspan', data.rowspan, data.cell, writer, 1 );\n\t\t}\n\t}\n\n\treturn wasFixed;\n}\n\n// Makes all table rows in a table the same size.\n//\n// @param {module:engine/model/element~Element} table\n// @param {module:engine/model/writer~Writer} writer\n// @returns {Boolean} Returns true if table was fixed.\nfunction fixTableRowsSizes( table, writer ) {\n\tlet wasFixed = false;\n\n\tconst rowsLengths = getRowsLengths( table );\n\tconst tableSize = rowsLengths[ 0 ];\n\n\tconst isValid = Object.values( rowsLengths ).every( length => length === tableSize );\n\n\tif ( !isValid ) {\n\t\tconst maxColumns = Object.values( rowsLengths ).reduce( ( prev, current ) => current > prev ? current : prev, 0 );\n\n\t\tfor ( const [ rowIndex, size ] of Object.entries( rowsLengths ) ) {\n\t\t\tconst columnsToInsert = maxColumns - size;\n\n\t\t\tif ( columnsToInsert ) {\n\t\t\t\tfor ( let i = 0; i < columnsToInsert; i++ ) {\n\t\t\t\t\tcreateEmptyTableCell( writer, writer.createPositionAt( table.getChild( rowIndex ), 'end' ) );\n\t\t\t\t}\n\n\t\t\t\twasFixed = true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn wasFixed;\n}\n\n// Searches for the table cells that extends beyond the table section to which they belong to. It will return an array of objects\n// that holds table cells to be trimmed and correct value of a rowspan attribute to set.\n//\n// @param {module:engine/model/element~Element} table\n// @returns {Array.<{{cell, rowspan}}>}\nfunction findCellsToTrim( table ) {\n\tconst headingRows = parseInt( table.getAttribute( 'headingRows' ) || 0 );\n\tconst maxRows = table.childCount;\n\n\tconst cellsToTrim = [];\n\n\tfor ( const { row, rowspan, cell } of new TableWalker( table ) ) {\n\t\t// Skip cells that do not expand over its row.\n\t\tif ( rowspan < 2 ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst isInHeader = row < headingRows;\n\n\t\t// Row limit is either end of header section or whole table as table body is after the header.\n\t\tconst rowLimit = isInHeader ? headingRows : maxRows;\n\n\t\t// If table cell expands over its limit reduce it height to proper value.\n\t\tif ( row + rowspan > rowLimit ) {\n\t\t\tconst newRowspan = rowLimit - row;\n\n\t\t\tcellsToTrim.push( { cell, rowspan: newRowspan } );\n\t\t}\n\t}\n\n\treturn cellsToTrim;\n}\n\n// Returns an object with lengths of rows assigned to the corresponding row index.\n//\n// @param {module:engine/model/element~Element} table\n// @returns {Object}\nfunction getRowsLengths( table ) {\n\tconst lengths = {};\n\n\tfor ( const { row } of new TableWalker( table, { includeSpanned: true } ) ) {\n\t\tif ( !lengths[ row ] ) {\n\t\t\tlengths[ row ] = 0;\n\t\t}\n\n\t\tlengths[ row ] += 1;\n\t}\n\n\treturn lengths;\n}\n\n// Checks if the differ entry for an attribute change is one of table's attributes.\n//\n// @param entry\n// @returns {Boolean}\nfunction isTableAttributeEntry( entry ) {\n\tconst isAttributeType = entry.type === 'attribute';\n\tconst key = entry.attributeKey;\n\n\treturn isAttributeType && ( key === 'headingRows' || key === 'colspan' || key === 'rowspan' );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/converters/table-cell-content-post-fixer\n */\n\n/**\n * Injects a table cell post-fixer into the model.\n *\n * The role of the table post-fixer is to ensure that the table cells have the correct content\n * after a {@link module:engine/model/model~Model#change `change()`} block was executed.\n *\n * A table cells must contains at least one block as a child. The empty table cell will have empty `<paragraph>` as a child.\n *\n * <table>\n * <tableRow>\n * <tableCell></tableCell>\n * </tableRow>\n * </table>\n *\n * Will be fixed to:\n *\n * <table>\n * <tableRow>\n * <tableCell><paragraph></paragraph></tableCell>\n * </tableRow>\n * </table>\n *\n * @param {module:engine/model/model~Model} model\n */\nexport default function injectTableCellContentPostFixer( model ) {\n\tmodel.document.registerPostFixer( writer => tableCellContentsPostFixer( writer, model ) );\n}\n\n// The table cell contents post-fixer.\n//\n// @param {module:engine/model/writer~Writer} writer\n// @param {module:engine/model/model~Model} model\nfunction tableCellContentsPostFixer( writer, model ) {\n\tconst changes = model.document.differ.getChanges();\n\n\tlet wasFixed = false;\n\n\tfor ( const entry of changes ) {\n\t\t// Enforce paragraph in tableCell even after other feature remove its contents.\n\t\tif ( entry.type == 'remove' && entry.position.parent.is( 'tableCell' ) ) {\n\t\t\twasFixed = fixTableCellContent( entry.position.parent, writer ) || wasFixed;\n\t\t}\n\n\t\t// Analyze table cells on insertion.\n\t\tif ( entry.type == 'insert' ) {\n\t\t\tif ( entry.name == 'table' ) {\n\t\t\t\twasFixed = fixTable( entry.position.nodeAfter, writer ) || wasFixed;\n\t\t\t}\n\n\t\t\tif ( entry.name == 'tableRow' ) {\n\t\t\t\twasFixed = fixTableRow( entry.position.nodeAfter, writer ) || wasFixed;\n\t\t\t}\n\n\t\t\tif ( entry.name == 'tableCell' ) {\n\t\t\t\twasFixed = fixTableCellContent( entry.position.nodeAfter, writer ) || wasFixed;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn wasFixed;\n}\n\n// Fixes all table cells in a table.\n//\n// @param {module:engine/model/element~Element} table\n// @param {module:engine/model/writer~Writer} writer\nfunction fixTable( table, writer ) {\n\tlet wasFixed = false;\n\n\tfor ( const row of table.getChildren() ) {\n\t\twasFixed = fixTableRow( row, writer ) || wasFixed;\n\t}\n\n\treturn wasFixed;\n}\n\n// Fixes all table cells in a table row.\n//\n// @param {module:engine/model/element~Element} tableRow\n// @param {module:engine/model/writer~Writer} writer\nfunction fixTableRow( tableRow, writer ) {\n\tlet wasFixed = false;\n\n\tfor ( const tableCell of tableRow.getChildren() ) {\n\t\twasFixed = fixTableCellContent( tableCell, writer ) || wasFixed;\n\t}\n\n\treturn wasFixed;\n}\n\n// Fixes all table cell content by:\n// - adding paragraph to a table cell without any child.\n// - wrapping direct $text in <paragraph>.\n//\n// @param {module:engine/model/element~Element} table\n// @param {module:engine/model/writer~Writer} writer\n// @returns {Boolean}\nfunction fixTableCellContent( tableCell, writer ) {\n\t// Insert paragraph to an empty table cell.\n\tif ( tableCell.childCount == 0 ) {\n\t\twriter.insertElement( 'paragraph', tableCell );\n\n\t\treturn true;\n\t}\n\n\t// Check table cell children for directly placed $text nodes.\n\t// Temporary solution. See https://github.com/ckeditor/ckeditor5/issues/1464.\n\tconst textNodes = Array.from( tableCell.getChildren() ).filter( child => child.is( 'text' ) );\n\n\tfor ( const child of textNodes ) {\n\t\twriter.wrap( writer.createRangeOn( child ), 'paragraph' );\n\t}\n\n\t// Return true when there were text nodes to fix.\n\treturn !!textNodes.length;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/converters/tablecell-post-fixer\n */\n\n/**\n * Injects a table cell post-fixer into the editing controller.\n *\n * The role of the table cell post-fixer is to ensure that the table cell contents in the editing view are properly converted.\n *\n * This post-fixer will ensure that after model changes in the editing view:\n * * single paragraphs are rendered as `<span>\n * * single paragraphs with one or more attributes are rendered as `<p>`\n * * single paragraphs in table cell with other block elements are rendered as `<p>`\n * * paragraphs in table cells with other block elements (including other paragraphs) are rendered as `<p>`.\n *\n * In the model each table cell has always at least one block element inside. If no other block was defined (empty table cell) the table\n * feature will insert empty `<paragraph>`. Similarly text nodes will be wrapped in paragraphs. Rendering in the data pipeline differs\n * from rendering in the editing pipeline - text nodes in single `<paragraph>` are rendered in the data pipeline as direct children\n * of the `<td>` or `<th>` elements. In other cases `<paragraph>` elements are rendered as `<p>` blocks.\n *\n * To ensure proper mappings between model and view elements and positions in the editing pipeline the table feature will always render\n * an element in the view: `<span>` for single or empty `<paragraph>` and `<p>` otherwise.\n *\n * Example:\n *\n *\t\t<table>\n *\t\t\t<tableRow>\n *\t\t\t\t<tableCell><paragraph></paragraph></tableCell>\n *\t\t\t\t<tableCell><paragraph>foo</paragraph></tableCell>\n *\t\t\t\t<tableCell><paragraph baz=\"bar\">foo</paragraph></tableCell>\n *\t\t\t\t<tableCell><heading2>bar</heading2><paragraph>baz</paragraph></tableCell>\n *\t\t\t</tableRow>\n *\t\t</table>\n *\n * The editor will render in the data pipeline:\n *\n *\t\t<figure>\n *\t\t\t<table>\n *\t\t\t\t<tbody>\n *\t\t\t\t\t<tr>\n *\t\t\t\t\t\t<td></td>\n *\t\t\t\t\t\t<td>foo</td>\n *\t\t\t\t\t\t<td><p baz=\"bar\">foo</p></td>\n *\t\t\t\t\t\t<td><h3>bar</h3><p>baz</p></td>\n *\t\t\t\t\t</tr>\n *\t\t\t\t</tbody>\n *\t\t\t</table>\n *\t\t</figure>\n *\n * and in the editing view (without widget markup):\n *\n *\t\t<figure>\n *\t\t\t<table>\n *\t\t\t\t<tbody>\n *\t\t\t\t\t<tr>\n *\t\t\t\t\t\t<td><span></span></td>\n *\t\t\t\t\t\t<td><span>foo</span></td>\n *\t\t\t\t\t\t<td><p baz=\"bar\">foo</p></td>\n *\t\t\t\t\t\t<td><h3>bar</h3><p>baz</p></td>\n *\t\t\t\t\t</tr>\n *\t\t\t\t</tbody>\n *\t\t\t</table>\n *\t\t</figure>\n *\n * @param {module:engine/model/model~Model} model\n * @param {module:engine/controller/editingcontroller~EditingController} editing\n */\nexport default function injectTableCellPostFixer( model, editing ) {\n\tediting.view.document.registerPostFixer( writer => tableCellPostFixer( writer, model, editing.mapper, editing.view ) );\n}\n\n// The table cell post-fixer.\n//\n// @param {module:engine/view/writer~Writer} writer\n// @param {module:engine/model/model~Model} model\n// @param {module:engine/conversion/mapper~Mapper} mapper\nfunction tableCellPostFixer( writer, model, mapper, view ) {\n\tlet wasFixed = false;\n\n\tconst elementsToCheck = getElementsToCheck( view );\n\n\tfor ( const element of elementsToCheck ) {\n\t\twasFixed = ensureProperElementName( element, mapper, writer ) || wasFixed;\n\t}\n\n\t// Selection in the view might not be updated to renamed elements. Happens mostly when other feature inserts paragraph to the table cell\n\t// (ie. when deleting table cell contents) and sets selection to it while table-post fixer changes view <p> to <span> element.\n\t// The view.selection would have outdated nodes.\n\tif ( wasFixed ) {\n\t\tupdateRangesInViewSelection( model.document.selection, mapper, writer );\n\t}\n\n\treturn wasFixed;\n}\n\n// Returns view elements changed in current view.change() block.\n//\n// **Note**: Currently it uses private property of the view: _renderer to get changed view elements to check.\n//\n// @param {module:engine/view/view~View} view\nfunction getElementsToCheck( view ) {\n\tconst elementsWithChangedAttributes = Array.from( view._renderer.markedAttributes )\n\t\t.filter( el => !!el.parent )\n\t\t.filter( isSpanOrP )\n\t\t.filter( el => isTdOrTh( el.parent ) );\n\n\tconst changedChildren = Array.from( view._renderer.markedChildren )\n\t\t.filter( el => !!el.parent )\n\t\t.filter( isTdOrTh )\n\t\t.reduce( ( prev, element ) => {\n\t\t\tconst childrenToCheck = Array.from( element.getChildren() ).filter( isSpanOrP );\n\n\t\t\treturn [ ...prev, ...childrenToCheck ];\n\t\t}, [] );\n\n\treturn [ ...elementsWithChangedAttributes, ...changedChildren ];\n}\n\n// This method checks if view element for model's <paragraph> was properly converter.\n// Paragraph should be either\n// - span: for single paragraph with no attributes.\n// - p : in other cases.\nfunction ensureProperElementName( currentViewElement, mapper, writer ) {\n\tconst modelParagraph = mapper.toModelElement( currentViewElement );\n\tconst expectedViewElementName = getExpectedElementName( modelParagraph.parent, modelParagraph );\n\n\tif ( currentViewElement.name !== expectedViewElementName ) {\n\t\t// Unbind current view element as it should be cleared from mapper.\n\t\tmapper.unbindViewElement( currentViewElement );\n\n\t\tconst renamedViewElement = writer.rename( expectedViewElementName, currentViewElement );\n\n\t\t// Bind paragraph inside table cell to the renamed view element.\n\t\tmapper.bindElements( modelParagraph, renamedViewElement );\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n// Expected view element name depends on model elements:\n// - <paragraph> with any attribute set should be rendered as <p>\n// - all <paragraphs> in <tableCell> that has more then one children should be rendered as <p>\n// - an only <paragraph> child with no attributes should be rendered as <span>\n//\n// @param {module:engine/model/element~Element} tableCell\n// @param {module:engine/model/element~Element} paragraph\n// @returns {String}\nfunction getExpectedElementName( tableCell, paragraph ) {\n\tconst isOnlyChild = tableCell.childCount > 1;\n\tconst hasAttributes = !![ ...paragraph.getAttributes() ].length;\n\n\treturn ( isOnlyChild || hasAttributes ) ? 'p' : 'span';\n}\n\n// Method to filter out <span> and <p> elements.\n//\n// @param {module:engine/view/element~Element} element\nfunction isSpanOrP( element ) {\n\treturn element.is( 'p' ) || element.is( 'span' );\n}\n\n// Method to filter out <td> and <th> elements.\n//\n// @param {module:engine/view/element~Element} element\nfunction isTdOrTh( element ) {\n\treturn element.is( 'td' ) || element.is( 'th' );\n}\n\n// Resets view selections based on model selection.\nfunction updateRangesInViewSelection( selection, mapper, writer ) {\n\tconst fixedRanges = Array.from( selection.getRanges() )\n\t\t.map( range => mapper.toViewRange( range ) );\n\n\twriter.setSelection( fixedRanges, { backward: selection.isBackward } );\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/tableediting\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport upcastTable, { upcastTableCell } from './converters/upcasttable';\nimport {\n\tdowncastInsertCell,\n\tdowncastInsertRow,\n\tdowncastInsertTable,\n\tdowncastRemoveRow,\n\tdowncastTableHeadingColumnsChange,\n\tdowncastTableHeadingRowsChange\n} from './converters/downcast';\n\nimport InsertTableCommand from './commands/inserttablecommand';\nimport InsertRowCommand from './commands/insertrowcommand';\nimport InsertColumnCommand from './commands/insertcolumncommand';\nimport SplitCellCommand from './commands/splitcellcommand';\nimport MergeCellCommand from './commands/mergecellcommand';\nimport RemoveRowCommand from './commands/removerowcommand';\nimport RemoveColumnCommand from './commands/removecolumncommand';\nimport SetHeaderRowCommand from './commands/setheaderrowcommand';\nimport SetHeaderColumnCommand from './commands/setheadercolumncommand';\nimport { findAncestor } from './commands/utils';\nimport TableUtils from '../src/tableutils';\n\nimport injectTableLayoutPostFixer from './converters/table-layout-post-fixer';\nimport injectTableCellContentsPostFixer from './converters/table-cell-content-post-fixer';\nimport injectTableCellPostFixer from './converters/tablecell-post-fixer';\n\nimport '../theme/tableediting.css';\n\n/**\n * The table editing feature.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst schema = model.schema;\n\t\tconst conversion = editor.conversion;\n\n\t\tschema.register( 'table', {\n\t\t\tallowWhere: '$block',\n\t\t\tallowAttributes: [ 'headingRows', 'headingColumns' ],\n\t\t\tisLimit: true,\n\t\t\tisObject: true,\n\t\t\tisBlock: true\n\t\t} );\n\n\t\tschema.register( 'tableRow', {\n\t\t\tallowIn: 'table',\n\t\t\tisLimit: true\n\t\t} );\n\n\t\tschema.register( 'tableCell', {\n\t\t\tallowIn: 'tableRow',\n\t\t\tallowAttributes: [ 'colspan', 'rowspan' ],\n\t\t\tisLimit: true\n\t\t} );\n\n\t\t// Allow all $block content inside table cell.\n\t\tschema.extend( '$block', { allowIn: 'tableCell' } );\n\n\t\t// Disallow table in table.\n\t\tschema.addChildCheck( ( context, childDefinition ) => {\n\t\t\tif ( childDefinition.name == 'table' && Array.from( context.getNames() ).includes( 'table' ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} );\n\n\t\t// Table conversion.\n\t\tconversion.for( 'upcast' ).add( upcastTable() );\n\n\t\tconversion.for( 'editingDowncast' ).add( downcastInsertTable( { asWidget: true } ) );\n\t\tconversion.for( 'dataDowncast' ).add( downcastInsertTable() );\n\n\t\t// Table row conversion.\n\t\tconversion.for( 'upcast' ).elementToElement( { model: 'tableRow', view: 'tr' } );\n\n\t\tconversion.for( 'editingDowncast' ).add( downcastInsertRow( { asWidget: true } ) );\n\t\tconversion.for( 'dataDowncast' ).add( downcastInsertRow() );\n\t\tconversion.for( 'downcast' ).add( downcastRemoveRow() );\n\n\t\t// Table cell conversion.\n\t\tconversion.for( 'upcast' ).add( upcastTableCell( 'td' ) );\n\t\tconversion.for( 'upcast' ).add( upcastTableCell( 'th' ) );\n\n\t\tconversion.for( 'editingDowncast' ).add( downcastInsertCell( { asWidget: true } ) );\n\t\tconversion.for( 'dataDowncast' ).add( downcastInsertCell() );\n\n\t\t// Table attributes conversion.\n\t\tconversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );\n\t\tconversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );\n\n\t\t// Table heading rows and cols conversion.\n\t\tconversion.for( 'editingDowncast' ).add( downcastTableHeadingColumnsChange( { asWidget: true } ) );\n\t\tconversion.for( 'dataDowncast' ).add( downcastTableHeadingColumnsChange() );\n\t\tconversion.for( 'editingDowncast' ).add( downcastTableHeadingRowsChange( { asWidget: true } ) );\n\t\tconversion.for( 'dataDowncast' ).add( downcastTableHeadingRowsChange() );\n\n\t\tinjectTableCellPostFixer( editor.model, editor.editing );\n\n\t\t// Define all the commands.\n\t\teditor.commands.add( 'insertTable', new InsertTableCommand( editor ) );\n\t\teditor.commands.add( 'insertTableRowAbove', new InsertRowCommand( editor, { order: 'above' } ) );\n\t\teditor.commands.add( 'insertTableRowBelow', new InsertRowCommand( editor, { order: 'below' } ) );\n\t\teditor.commands.add( 'insertTableColumnLeft', new InsertColumnCommand( editor, { order: 'left' } ) );\n\t\teditor.commands.add( 'insertTableColumnRight', new InsertColumnCommand( editor, { order: 'right' } ) );\n\n\t\teditor.commands.add( 'removeTableRow', new RemoveRowCommand( editor ) );\n\t\teditor.commands.add( 'removeTableColumn', new RemoveColumnCommand( editor ) );\n\n\t\teditor.commands.add( 'splitTableCellVertically', new SplitCellCommand( editor, { direction: 'vertically' } ) );\n\t\teditor.commands.add( 'splitTableCellHorizontally', new SplitCellCommand( editor, { direction: 'horizontally' } ) );\n\n\t\teditor.commands.add( 'mergeTableCellRight', new MergeCellCommand( editor, { direction: 'right' } ) );\n\t\teditor.commands.add( 'mergeTableCellLeft', new MergeCellCommand( editor, { direction: 'left' } ) );\n\t\teditor.commands.add( 'mergeTableCellDown', new MergeCellCommand( editor, { direction: 'down' } ) );\n\t\teditor.commands.add( 'mergeTableCellUp', new MergeCellCommand( editor, { direction: 'up' } ) );\n\n\t\teditor.commands.add( 'setTableColumnHeader', new SetHeaderColumnCommand( editor ) );\n\t\teditor.commands.add( 'setTableRowHeader', new SetHeaderRowCommand( editor ) );\n\n\t\tinjectTableLayoutPostFixer( model );\n\t\tinjectTableCellContentsPostFixer( model );\n\n\t\t// Handle tab key navigation.\n\t\tthis.editor.keystrokes.set( 'Tab', ( ...args ) => this._handleTabOnSelectedTable( ...args ), { priority: 'low' } );\n\t\tthis.editor.keystrokes.set( 'Tab', this._getTabHandler( true ), { priority: 'low' } );\n\t\tthis.editor.keystrokes.set( 'Shift+Tab', this._getTabHandler( false ), { priority: 'low' } );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ TableUtils ];\n\t}\n\n\t/**\n\t * Handles {@link module:engine/view/document~Document#event:keydown keydown} events for the <kbd>Tab</kbd> key executed\n\t * when the table widget is selected.\n\t *\n\t * @private\n\t * @param {module:utils/eventinfo~EventInfo} eventInfo\n\t * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData\n\t */\n\t_handleTabOnSelectedTable( domEventData, cancel ) {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\n\t\tif ( !selection.isCollapsed && selection.rangeCount === 1 && selection.getFirstRange().isFlat ) {\n\t\t\tconst selectedElement = selection.getSelectedElement();\n\n\t\t\tif ( !selectedElement || !selectedElement.is( 'table' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcancel();\n\n\t\t\teditor.model.change( writer => {\n\t\t\t\twriter.setSelection( writer.createRangeIn( selectedElement.getChild( 0 ).getChild( 0 ) ) );\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Returns a handler for {@link module:engine/view/document~Document#event:keydown keydown} events for the <kbd>Tab</kbd> key executed\n\t * inside table cell.\n\t *\n\t * @private\n\t * @param {Boolean} isForward Whether this handler will move selection to the next cell or previous.\n\t */\n\t_getTabHandler( isForward ) {\n\t\tconst editor = this.editor;\n\n\t\treturn ( domEventData, cancel ) => {\n\t\t\tconst selection = editor.model.document.selection;\n\n\t\t\tconst firstPosition = selection.getFirstPosition();\n\n\t\t\tconst tableCell = findAncestor( 'tableCell', firstPosition );\n\n\t\t\tif ( !tableCell ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcancel();\n\n\t\t\tconst tableRow = tableCell.parent;\n\t\t\tconst table = tableRow.parent;\n\n\t\t\tconst currentRowIndex = table.getChildIndex( tableRow );\n\t\t\tconst currentCellIndex = tableRow.getChildIndex( tableCell );\n\n\t\t\tconst isFirstCellInRow = currentCellIndex === 0;\n\n\t\t\tif ( !isForward && isFirstCellInRow && currentRowIndex === 0 ) {\n\t\t\t\t// It's the first cell of a table - don't do anything (stay in current position).\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst isLastCellInRow = currentCellIndex === tableRow.childCount - 1;\n\t\t\tconst isLastRow = currentRowIndex === table.childCount - 1;\n\n\t\t\tif ( isForward && isLastRow && isLastCellInRow ) {\n\t\t\t\teditor.plugins.get( 'TableUtils' ).insertRows( table, { at: table.childCount } );\n\t\t\t}\n\n\t\t\tlet cellToFocus;\n\n\t\t\t// Move to first cell in next row.\n\t\t\tif ( isForward && isLastCellInRow ) {\n\t\t\t\tconst nextRow = table.getChild( currentRowIndex + 1 );\n\n\t\t\t\tcellToFocus = nextRow.getChild( 0 );\n\t\t\t}\n\t\t\t// Move to last cell in a previous row.\n\t\t\telse if ( !isForward && isFirstCellInRow ) {\n\t\t\t\tconst previousRow = table.getChild( currentRowIndex - 1 );\n\n\t\t\t\tcellToFocus = previousRow.getChild( previousRow.childCount - 1 );\n\t\t\t}\n\t\t\t// Move to next/previous cell.\n\t\t\telse {\n\t\t\t\tcellToFocus = tableRow.getChild( currentCellIndex + ( isForward ? 1 : -1 ) );\n\t\t\t}\n\n\t\t\teditor.model.change( writer => {\n\t\t\t\twriter.setSelection( writer.createRangeIn( cellToFocus ) );\n\t\t\t} );\n\t\t};\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/ui/inserttableview\n */\n\nimport View from '@ckeditor/ckeditor5-ui/src/view';\n\nimport './../../theme/inserttable.css';\n\n/**\n * The table size view.\n *\n * It renders a 10x10 grid to choose the inserted table size.\n *\n * @extends module:ui/view~View\n * @implements module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable\n */\nexport default class InsertTableView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * A collection of table size box items.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.items = this.createCollection();\n\n\t\t/**\n\t\t * The currently selected number of rows of the new table.\n\t\t *\n\t\t * @observable\n\t\t * @member {Number} #rows\n\t\t */\n\t\tthis.set( 'rows', 0 );\n\n\t\t/**\n\t\t * The currently selected number of columns of the new table.\n\t\t *\n\t\t * @observable\n\t\t * @member {Number} #columns\n\t\t */\n\t\tthis.set( 'columns', 0 );\n\n\t\t/**\n\t\t * The label text displayed under the boxes.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #label\n\t\t */\n\t\tthis.bind( 'label' )\n\t\t\t.to( this, 'columns', this, 'rows', ( columns, rows ) => `${ rows } x ${ columns }` );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [ 'ck' ]\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'div',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [ 'ck-insert-table-dropdown__grid' ]\n\t\t\t\t\t},\n\t\t\t\t\tchildren: this.items\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttag: 'div',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [ 'ck-insert-table-dropdown__label' ]\n\t\t\t\t\t},\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttext: bind.to( 'label' )\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t],\n\n\t\t\ton: {\n\t\t\t\tmousedown: bind.to( evt => {\n\t\t\t\t\tevt.preventDefault();\n\t\t\t\t} ),\n\n\t\t\t\tclick: bind.to( () => {\n\t\t\t\t\tthis.fire( 'execute' );\n\t\t\t\t} )\n\t\t\t}\n\t\t} );\n\n\t\t// Add grid boxes to table selection view.\n\t\tfor ( let index = 0; index < 100; index++ ) {\n\t\t\tconst boxView = new TableSizeGridBoxView();\n\n\t\t\t// Listen to box view 'over' event which indicates that mouse is over this box.\n\t\t\tboxView.on( 'over', () => {\n\t\t\t\t// Translate box index to the row & column index.\n\t\t\t\tconst row = Math.floor( index / 10 );\n\t\t\t\tconst column = index % 10;\n\n\t\t\t\t// As row & column indexes are zero-based transform it to number of selected rows & columns.\n\t\t\t\tthis.set( 'rows', row + 1 );\n\t\t\t\tthis.set( 'columns', column + 1 );\n\t\t\t} );\n\n\t\t\tthis.items.add( boxView );\n\t\t}\n\n\t\tthis.on( 'change:columns', () => {\n\t\t\tthis._highlightGridBoxes();\n\t\t} );\n\n\t\tthis.on( 'change:rows', () => {\n\t\t\tthis._highlightGridBoxes();\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tfocus() {\n\t\t// The dropdown panel expects DropdownPanelFocusable interface on views passed to dropdown panel. See #30.\n\t\t// The method should be implemented while working on keyboard support for this view. See #22.\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tfocusLast() {\n\t\t// The dropdown panel expects DropdownPanelFocusable interface on views passed to dropdown panel. See #30.\n\t\t// The method should be implemented while working on keyboard support for this view. See #22.\n\t}\n\n\t/**\n\t * Highlights grid boxes depending on rows and columns selected.\n\t *\n\t * @private\n\t */\n\t_highlightGridBoxes() {\n\t\tconst rows = this.rows;\n\t\tconst columns = this.columns;\n\n\t\tthis.items.map( ( boxView, index ) => {\n\t\t\t// Translate box index to the row & column index.\n\t\t\tconst itemRow = Math.floor( index / 10 );\n\t\t\tconst itemColumn = index % 10;\n\n\t\t\t// Grid box is highlighted when its row & column index belongs to selected number of rows & columns.\n\t\t\tconst isOn = itemRow < rows && itemColumn < columns;\n\n\t\t\tboxView.set( 'isOn', isOn );\n\t\t} );\n\t}\n}\n\n/**\n * A single grid box view element.\n *\n * This class is used to render the table size selection grid in {@link module:table/ui/inserttableview~InsertTableView}.\n *\n * @private\n */\nclass TableSizeGridBoxView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * Controls whether the grid box view is \"on\".\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isOn\n\t\t */\n\t\tthis.set( 'isOn', false );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-insert-table-dropdown-grid-box',\n\t\t\t\t\tbind.if( 'isOn', 'ck-on' )\n\t\t\t\t]\n\t\t\t},\n\t\t\ton: {\n\t\t\t\tmouseover: bind.to( 'over' )\n\t\t\t}\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n/**\n * @module table/tableui\n */\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport {\n addListToDropdown,\n createDropdown\n} from '@ckeditor/ckeditor5-ui/src/dropdown/utils';\nimport Model from '@ckeditor/ckeditor5-ui/src/model';\nimport Collection from '@ckeditor/ckeditor5-utils/src/collection';\nimport InsertTableView from './ui/inserttableview';\nimport tableIcon from './../theme/icons/table.svg';\nimport tableColumnIcon from './../theme/icons/table-column.svg';\nimport tableRowIcon from './../theme/icons/table-row.svg';\nimport tableMergeCellIcon from './../theme/icons/table-merge-cell.svg';\n/**\n * The table UI plugin. It introduces:\n *\n * * The `'insertTable'` dropdown,\n * * The `'tableColumn'` dropdown,\n * * The `'tableRow'` dropdown,\n * * The `'mergeTableCells'` dropdown.\n *\n * The `'tableColumn'`, `'tableRow'`, `'mergeTableCells'` dropdowns work best with {@link module:table/tabletoolbar~TableToolbar}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableUI extends Plugin {\n /**\n\t * @inheritDoc\n\t */\n init() {\n const editor = this.editor;\n const t = this.editor.t;\n editor.ui.componentFactory.add('insertTable', locale => {\n const command = editor.commands.get('insertTable');\n const dropdownView = createDropdown(locale);\n dropdownView.bind('isEnabled').to(command);\n // Decorate dropdown's button.\n dropdownView.buttonView.set({\n icon: tableIcon,\n label: t('f'),\n tooltip: true\n });\n // Prepare custom view for dropdown's panel.\n const insertTableView = new InsertTableView(locale);\n dropdownView.panelView.children.add(insertTableView);\n insertTableView.delegate('execute').to(dropdownView);\n dropdownView.buttonView.on('open', () => {\n // Reset the chooser before showing it to the user.\n insertTableView.rows = 0;\n insertTableView.columns = 0;\n });\n dropdownView.on('execute', () => {\n editor.execute('insertTable', {\n rows: insertTableView.rows,\n columns: insertTableView.columns\n });\n editor.editing.view.focus();\n });\n return dropdownView;\n });\n editor.ui.componentFactory.add('tableColumn', locale => {\n const options = [\n {\n type: 'switchbutton',\n model: {\n commandName: 'setTableColumnHeader',\n label: t('g'),\n bindIsOn: true\n }\n },\n { type: 'separator' },\n {\n type: 'button',\n model: {\n commandName: 'insertTableColumnLeft',\n label: t('h')\n }\n },\n {\n type: 'button',\n model: {\n commandName: 'insertTableColumnRight',\n label: t('i')\n }\n },\n {\n type: 'button',\n model: {\n commandName: 'removeTableColumn',\n label: t('j')\n }\n }\n ];\n return this._prepareDropdown(t('k'), tableColumnIcon, options, locale);\n });\n editor.ui.componentFactory.add('tableRow', locale => {\n const options = [\n {\n type: 'switchbutton',\n model: {\n commandName: 'setTableRowHeader',\n label: t('l'),\n bindIsOn: true\n }\n },\n { type: 'separator' },\n {\n type: 'button',\n model: {\n commandName: 'insertTableRowBelow',\n label: t('m')\n }\n },\n {\n type: 'button',\n model: {\n commandName: 'insertTableRowAbove',\n label: t('n')\n }\n },\n {\n type: 'button',\n model: {\n commandName: 'removeTableRow',\n label: t('o')\n }\n }\n ];\n return this._prepareDropdown(t('p'), tableRowIcon, options, locale);\n });\n editor.ui.componentFactory.add('mergeTableCells', locale => {\n const options = [\n {\n type: 'button',\n model: {\n commandName: 'mergeTableCellUp',\n label: t('q')\n }\n },\n {\n type: 'button',\n model: {\n commandName: 'mergeTableCellRight',\n label: t('r')\n }\n },\n {\n type: 'button',\n model: {\n commandName: 'mergeTableCellDown',\n label: t('s')\n }\n },\n {\n type: 'button',\n model: {\n commandName: 'mergeTableCellLeft',\n label: t('t')\n }\n },\n { type: 'separator' },\n {\n type: 'button',\n model: {\n commandName: 'splitTableCellVertically',\n label: t('u')\n }\n },\n {\n type: 'button',\n model: {\n commandName: 'splitTableCellHorizontally',\n label: t('v')\n }\n }\n ];\n return this._prepareDropdown(t('w'), tableMergeCellIcon, options, locale);\n });\n }\n /**\n\t * Creates a dropdown view from the set of options.\n\t *\n\t * @private\n\t * @param {String} label The dropdown button label.\n\t * @param {String} icon An icon for the dropdown button.\n\t * @param {Array.<module:ui/dropdown/utils~ListDropdownItemDefinition>} options The list of options for the dropdown.\n\t * @param {module:utils/locale~Locale} locale\n\t * @returns {module:ui/dropdown/dropdownview~DropdownView}\n\t */\n _prepareDropdown(label, icon, options, locale) {\n const editor = this.editor;\n const dropdownView = createDropdown(locale);\n const commands = [];\n // Prepare dropdown list items for list dropdown.\n const itemDefinitions = new Collection();\n for (const option of options) {\n addListOption(option, editor, commands, itemDefinitions);\n }\n addListToDropdown(dropdownView, itemDefinitions);\n // Decorate dropdown's button.\n dropdownView.buttonView.set({\n label,\n icon,\n tooltip: true\n });\n // Make dropdown button disabled when all options are disabled.\n dropdownView.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled) => {\n return areEnabled.some(isEnabled => isEnabled);\n });\n this.listenTo(dropdownView, 'execute', evt => {\n editor.execute(evt.source.commandName);\n editor.editing.view.focus();\n });\n return dropdownView;\n }\n}\n// Adds an option to a list view.\n//\n// @param {module:table/tableui~DropdownOption} option Configuration option.\n// @param {module:core/editor/editor~Editor} editor\n// @param {Array.<module:core/command~Command>} commands List of commands to update.\n// @param {Iterable.<module:ui/dropdown/utils~ListDropdownItemDefinition>} itemDefinitions\n// Collection of dropdown items to update with given option.\nfunction addListOption(option, editor, commands, itemDefinitions) {\n const model = option.model = new Model(option.model);\n const {commandName, bindIsOn} = option.model;\n if (option.type !== 'separator') {\n const command = editor.commands.get(commandName);\n commands.push(command);\n model.set({ commandName });\n model.bind('isEnabled').to(command);\n if (bindIsOn) {\n model.bind('isOn').to(command, 'value');\n }\n }\n model.set({ withText: true });\n itemDefinitions.add(option);\n}","var highlightRegExp = /highlight-(?:text|source)-([a-z0-9]+)/;\n\nfunction highlightedCodeBlock (turndownService) {\n turndownService.addRule('highlightedCodeBlock', {\n filter: function (node) {\n var firstChild = node.firstChild;\n return (\n node.nodeName === 'DIV' &&\n highlightRegExp.test(node.className) &&\n firstChild &&\n firstChild.nodeName === 'PRE'\n )\n },\n replacement: function (content, node, options) {\n var className = node.className || '';\n var language = (className.match(highlightRegExp) || [null, ''])[1];\n\n return (\n '\\n\\n' + options.fence + language + '\\n' +\n node.firstChild.textContent +\n '\\n' + options.fence + '\\n\\n'\n )\n }\n });\n}\n\nfunction strikethrough (turndownService) {\n turndownService.addRule('strikethrough', {\n filter: ['del', 's', 'strike'],\n replacement: function (content) {\n return '~' + content + '~'\n }\n });\n}\n\nvar indexOf = Array.prototype.indexOf;\nvar every = Array.prototype.every;\nvar rules = {};\n\nrules.tableCell = {\n filter: ['th', 'td'],\n replacement: function (content, node) {\n return cell(content, node)\n }\n};\n\nrules.tableRow = {\n filter: 'tr',\n replacement: function (content, node) {\n var borderCells = '';\n var alignMap = { left: ':--', right: '--:', center: ':-:' };\n\n if (isHeadingRow(node)) {\n for (var i = 0; i < node.childNodes.length; i++) {\n var border = '---';\n var align = (\n node.childNodes[i].getAttribute('align') || ''\n ).toLowerCase();\n\n if (align) border = alignMap[align] || border;\n\n borderCells += cell(border, node.childNodes[i]);\n }\n }\n return '\\n' + content + (borderCells ? '\\n' + borderCells : '')\n }\n};\n\nrules.table = {\n // Only convert tables with a heading row.\n // Tables with no heading row are kept using `keep` (see below).\n filter: function (node) {\n return node.nodeName === 'TABLE' && isHeadingRow(node.rows[0])\n },\n\n replacement: function (content) {\n // Ensure there are no blank lines\n content = content.replace('\\n\\n', '\\n');\n return '\\n\\n' + content + '\\n\\n'\n }\n};\n\nrules.tableSection = {\n filter: ['thead', 'tbody', 'tfoot'],\n replacement: function (content) {\n return content\n }\n};\n\n// A tr is a heading row if:\n// - the parent is a THEAD\n// - or if its the first child of the TABLE or the first TBODY (possibly\n// following a blank THEAD)\n// - and every cell is a TH\nfunction isHeadingRow (tr) {\n var parentNode = tr.parentNode;\n return (\n parentNode.nodeName === 'THEAD' ||\n (\n parentNode.firstChild === tr &&\n (parentNode.nodeName === 'TABLE' || isFirstTbody(parentNode)) &&\n every.call(tr.childNodes, function (n) { return n.nodeName === 'TH' })\n )\n )\n}\n\nfunction isFirstTbody (element) {\n var previousSibling = element.previousSibling;\n return (\n element.nodeName === 'TBODY' && (\n !previousSibling ||\n (\n previousSibling.nodeName === 'THEAD' &&\n /^\\s*$/i.test(previousSibling.textContent)\n )\n )\n )\n}\n\nfunction cell (content, node) {\n var index = indexOf.call(node.parentNode.childNodes, node);\n var prefix = ' ';\n if (index === 0) prefix = '| ';\n return prefix + content + ' |'\n}\n\nfunction tables (turndownService) {\n turndownService.keep(function (node) {\n return node.nodeName === 'TABLE' && !isHeadingRow(node.rows[0])\n });\n for (var key in rules) turndownService.addRule(key, rules[key]);\n}\n\nfunction taskListItems (turndownService) {\n turndownService.addRule('taskListItems', {\n filter: function (node) {\n return node.type === 'checkbox' && node.parentNode.nodeName === 'LI'\n },\n replacement: function (content, node) {\n return (node.checked ? '[x]' : '[ ]') + ' '\n }\n });\n}\n\nfunction gfm (turndownService) {\n turndownService.use([\n highlightedCodeBlock,\n strikethrough,\n tables,\n taskListItems\n ]);\n}\n\nexport { gfm, highlightedCodeBlock, strikethrough, tables, taskListItems };\n","function extend (destination) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n for (var key in source) {\n if (source.hasOwnProperty(key)) destination[key] = source[key];\n }\n }\n return destination\n}\n\nfunction repeat (character, count) {\n return Array(count + 1).join(character)\n}\n\nvar blockElements = [\n 'address', 'article', 'aside', 'audio', 'blockquote', 'body', 'canvas',\n 'center', 'dd', 'dir', 'div', 'dl', 'dt', 'fieldset', 'figcaption',\n 'figure', 'footer', 'form', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\n 'header', 'hgroup', 'hr', 'html', 'isindex', 'li', 'main', 'menu', 'nav',\n 'noframes', 'noscript', 'ol', 'output', 'p', 'pre', 'section', 'table',\n 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'ul'\n];\n\nfunction isBlock (node) {\n return blockElements.indexOf(node.nodeName.toLowerCase()) !== -1\n}\n\nvar voidElements = [\n 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input',\n 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'\n];\n\nfunction isVoid (node) {\n return voidElements.indexOf(node.nodeName.toLowerCase()) !== -1\n}\n\nvar voidSelector = voidElements.join();\nfunction hasVoid (node) {\n return node.querySelector && node.querySelector(voidSelector)\n}\n\nvar rules = {};\n\nrules.paragraph = {\n filter: 'p',\n\n replacement: function (content) {\n return '\\n\\n' + content + '\\n\\n'\n }\n};\n\nrules.lineBreak = {\n filter: 'br',\n\n replacement: function (content, node, options) {\n return options.br + '\\n'\n }\n};\n\nrules.heading = {\n filter: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],\n\n replacement: function (content, node, options) {\n var hLevel = Number(node.nodeName.charAt(1));\n\n if (options.headingStyle === 'setext' && hLevel < 3) {\n var underline = repeat((hLevel === 1 ? '=' : '-'), content.length);\n return (\n '\\n\\n' + content + '\\n' + underline + '\\n\\n'\n )\n } else {\n return '\\n\\n' + repeat('#', hLevel) + ' ' + content + '\\n\\n'\n }\n }\n};\n\nrules.blockquote = {\n filter: 'blockquote',\n\n replacement: function (content) {\n content = content.replace(/^\\n+|\\n+$/g, '');\n content = content.replace(/^/gm, '> ');\n return '\\n\\n' + content + '\\n\\n'\n }\n};\n\nrules.list = {\n filter: ['ul', 'ol'],\n\n replacement: function (content, node) {\n var parent = node.parentNode;\n if (parent.nodeName === 'LI' && parent.lastElementChild === node) {\n return '\\n' + content\n } else {\n return '\\n\\n' + content + '\\n\\n'\n }\n }\n};\n\nrules.listItem = {\n filter: 'li',\n\n replacement: function (content, node, options) {\n content = content\n .replace(/^\\n+/, '') // remove leading newlines\n .replace(/\\n+$/, '\\n') // replace trailing newlines with just a single one\n .replace(/\\n/gm, '\\n '); // indent\n var prefix = options.bulletListMarker + ' ';\n var parent = node.parentNode;\n if (parent.nodeName === 'OL') {\n var start = parent.getAttribute('start');\n var index = Array.prototype.indexOf.call(parent.children, node);\n prefix = (start ? Number(start) + index : index + 1) + '. ';\n }\n return (\n prefix + content + (node.nextSibling && !/\\n$/.test(content) ? '\\n' : '')\n )\n }\n};\n\nrules.indentedCodeBlock = {\n filter: function (node, options) {\n return (\n options.codeBlockStyle === 'indented' &&\n node.nodeName === 'PRE' &&\n node.firstChild &&\n node.firstChild.nodeName === 'CODE'\n )\n },\n\n replacement: function (content, node, options) {\n return (\n '\\n\\n ' +\n node.firstChild.textContent.replace(/\\n/g, '\\n ') +\n '\\n\\n'\n )\n }\n};\n\nrules.fencedCodeBlock = {\n filter: function (node, options) {\n return (\n options.codeBlockStyle === 'fenced' &&\n node.nodeName === 'PRE' &&\n node.firstChild &&\n node.firstChild.nodeName === 'CODE'\n )\n },\n\n replacement: function (content, node, options) {\n var className = node.firstChild.className || '';\n var language = (className.match(/language-(\\S+)/) || [null, ''])[1];\n\n return (\n '\\n\\n' + options.fence + language + '\\n' +\n node.firstChild.textContent +\n '\\n' + options.fence + '\\n\\n'\n )\n }\n};\n\nrules.horizontalRule = {\n filter: 'hr',\n\n replacement: function (content, node, options) {\n return '\\n\\n' + options.hr + '\\n\\n'\n }\n};\n\nrules.inlineLink = {\n filter: function (node, options) {\n return (\n options.linkStyle === 'inlined' &&\n node.nodeName === 'A' &&\n node.getAttribute('href')\n )\n },\n\n replacement: function (content, node) {\n var href = node.getAttribute('href');\n var title = node.title ? ' \"' + node.title + '\"' : '';\n return '[' + content + '](' + href + title + ')'\n }\n};\n\nrules.referenceLink = {\n filter: function (node, options) {\n return (\n options.linkStyle === 'referenced' &&\n node.nodeName === 'A' &&\n node.getAttribute('href')\n )\n },\n\n replacement: function (content, node, options) {\n var href = node.getAttribute('href');\n var title = node.title ? ' \"' + node.title + '\"' : '';\n var replacement;\n var reference;\n\n switch (options.linkReferenceStyle) {\n case 'collapsed':\n replacement = '[' + content + '][]';\n reference = '[' + content + ']: ' + href + title;\n break\n case 'shortcut':\n replacement = '[' + content + ']';\n reference = '[' + content + ']: ' + href + title;\n break\n default:\n var id = this.references.length + 1;\n replacement = '[' + content + '][' + id + ']';\n reference = '[' + id + ']: ' + href + title;\n }\n\n this.references.push(reference);\n return replacement\n },\n\n references: [],\n\n append: function (options) {\n var references = '';\n if (this.references.length) {\n references = '\\n\\n' + this.references.join('\\n') + '\\n\\n';\n this.references = []; // Reset references\n }\n return references\n }\n};\n\nrules.emphasis = {\n filter: ['em', 'i'],\n\n replacement: function (content, node, options) {\n if (!content.trim()) return ''\n return options.emDelimiter + content + options.emDelimiter\n }\n};\n\nrules.strong = {\n filter: ['strong', 'b'],\n\n replacement: function (content, node, options) {\n if (!content.trim()) return ''\n return options.strongDelimiter + content + options.strongDelimiter\n }\n};\n\nrules.code = {\n filter: function (node) {\n var hasSiblings = node.previousSibling || node.nextSibling;\n var isCodeBlock = node.parentNode.nodeName === 'PRE' && !hasSiblings;\n\n return node.nodeName === 'CODE' && !isCodeBlock\n },\n\n replacement: function (content) {\n if (!content.trim()) return ''\n\n var delimiter = '`';\n var leadingSpace = '';\n var trailingSpace = '';\n var matches = content.match(/`+/gm);\n if (matches) {\n if (/^`/.test(content)) leadingSpace = ' ';\n if (/`$/.test(content)) trailingSpace = ' ';\n while (matches.indexOf(delimiter) !== -1) delimiter = delimiter + '`';\n }\n\n return delimiter + leadingSpace + content + trailingSpace + delimiter\n }\n};\n\nrules.image = {\n filter: 'img',\n\n replacement: function (content, node) {\n var alt = node.alt || '';\n var src = node.getAttribute('src') || '';\n var title = node.title || '';\n var titlePart = title ? ' \"' + title + '\"' : '';\n return src ? '![' + alt + ']' + '(' + src + titlePart + ')' : ''\n }\n};\n\n/**\n * Manages a collection of rules used to convert HTML to Markdown\n */\n\nfunction Rules (options) {\n this.options = options;\n this._keep = [];\n this._remove = [];\n\n this.blankRule = {\n replacement: options.blankReplacement\n };\n\n this.keepReplacement = options.keepReplacement;\n\n this.defaultRule = {\n replacement: options.defaultReplacement\n };\n\n this.array = [];\n for (var key in options.rules) this.array.push(options.rules[key]);\n}\n\nRules.prototype = {\n add: function (key, rule) {\n this.array.unshift(rule);\n },\n\n keep: function (filter) {\n this._keep.unshift({\n filter: filter,\n replacement: this.keepReplacement\n });\n },\n\n remove: function (filter) {\n this._remove.unshift({\n filter: filter,\n replacement: function () {\n return ''\n }\n });\n },\n\n forNode: function (node) {\n if (node.isBlank) return this.blankRule\n var rule;\n\n if ((rule = findRule(this.array, node, this.options))) return rule\n if ((rule = findRule(this._keep, node, this.options))) return rule\n if ((rule = findRule(this._remove, node, this.options))) return rule\n\n return this.defaultRule\n },\n\n forEach: function (fn) {\n for (var i = 0; i < this.array.length; i++) fn(this.array[i], i);\n }\n};\n\nfunction findRule (rules, node, options) {\n for (var i = 0; i < rules.length; i++) {\n var rule = rules[i];\n if (filterValue(rule, node, options)) return rule\n }\n return void 0\n}\n\nfunction filterValue (rule, node, options) {\n var filter = rule.filter;\n if (typeof filter === 'string') {\n if (filter === node.nodeName.toLowerCase()) return true\n } else if (Array.isArray(filter)) {\n if (filter.indexOf(node.nodeName.toLowerCase()) > -1) return true\n } else if (typeof filter === 'function') {\n if (filter.call(rule, node, options)) return true\n } else {\n throw new TypeError('`filter` needs to be a string, array, or function')\n }\n}\n\n/**\n * The collapseWhitespace function is adapted from collapse-whitespace\n * by Luc Thevenard.\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Luc Thevenard <lucthevenard@gmail.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n/**\n * collapseWhitespace(options) removes extraneous whitespace from an the given element.\n *\n * @param {Object} options\n */\nfunction collapseWhitespace (options) {\n var element = options.element;\n var isBlock = options.isBlock;\n var isVoid = options.isVoid;\n var isPre = options.isPre || function (node) {\n return node.nodeName === 'PRE'\n };\n\n if (!element.firstChild || isPre(element)) return\n\n var prevText = null;\n var prevVoid = false;\n\n var prev = null;\n var node = next(prev, element, isPre);\n\n while (node !== element) {\n if (node.nodeType === 3 || node.nodeType === 4) { // Node.TEXT_NODE or Node.CDATA_SECTION_NODE\n var text = node.data.replace(/[ \\r\\n\\t]+/g, ' ');\n\n if ((!prevText || / $/.test(prevText.data)) &&\n !prevVoid && text[0] === ' ') {\n text = text.substr(1);\n }\n\n // `text` might be empty at this point.\n if (!text) {\n node = remove(node);\n continue\n }\n\n node.data = text;\n\n prevText = node;\n } else if (node.nodeType === 1) { // Node.ELEMENT_NODE\n if (isBlock(node) || node.nodeName === 'BR') {\n if (prevText) {\n prevText.data = prevText.data.replace(/ $/, '');\n }\n\n prevText = null;\n prevVoid = false;\n } else if (isVoid(node)) {\n // Avoid trimming space around non-block, non-BR void elements.\n prevText = null;\n prevVoid = true;\n }\n } else {\n node = remove(node);\n continue\n }\n\n var nextNode = next(prev, node, isPre);\n prev = node;\n node = nextNode;\n }\n\n if (prevText) {\n prevText.data = prevText.data.replace(/ $/, '');\n if (!prevText.data) {\n remove(prevText);\n }\n }\n}\n\n/**\n * remove(node) removes the given node from the DOM and returns the\n * next node in the sequence.\n *\n * @param {Node} node\n * @return {Node} node\n */\nfunction remove (node) {\n var next = node.nextSibling || node.parentNode;\n\n node.parentNode.removeChild(node);\n\n return next\n}\n\n/**\n * next(prev, current, isPre) returns the next node in the sequence, given the\n * current and previous nodes.\n *\n * @param {Node} prev\n * @param {Node} current\n * @param {Function} isPre\n * @return {Node}\n */\nfunction next (prev, current, isPre) {\n if ((prev && prev.parentNode === current) || isPre(current)) {\n return current.nextSibling || current.parentNode\n }\n\n return current.firstChild || current.nextSibling || current.parentNode\n}\n\n/*\n * Set up window for Node.js\n */\n\nvar root = (typeof window !== 'undefined' ? window : {});\n\n/*\n * Parsing HTML strings\n */\n\nfunction canParseHTMLNatively () {\n var Parser = root.DOMParser;\n var canParse = false;\n\n // Adapted from https://gist.github.com/1129031\n // Firefox/Opera/IE throw errors on unsupported types\n try {\n // WebKit returns null on unsupported types\n if (new Parser().parseFromString('', 'text/html')) {\n canParse = true;\n }\n } catch (e) {}\n\n return canParse\n}\n\nfunction createHTMLParser () {\n var Parser = function () {};\n\n {\n var JSDOM = require('jsdom').JSDOM;\n Parser.prototype.parseFromString = function (string) {\n return new JSDOM(string).window.document\n };\n }\n return Parser\n}\n\nvar HTMLParser = canParseHTMLNatively() ? root.DOMParser : createHTMLParser();\n\nfunction RootNode (input) {\n var root;\n if (typeof input === 'string') {\n var doc = htmlParser().parseFromString(\n // DOM parsers arrange elements in the <head> and <body>.\n // Wrapping in a custom element ensures elements are reliably arranged in\n // a single element.\n '<x-turndown id=\"turndown-root\">' + input + '</x-turndown>',\n 'text/html'\n );\n root = doc.getElementById('turndown-root');\n } else {\n root = input.cloneNode(true);\n }\n collapseWhitespace({\n element: root,\n isBlock: isBlock,\n isVoid: isVoid\n });\n\n return root\n}\n\nvar _htmlParser;\nfunction htmlParser () {\n _htmlParser = _htmlParser || new HTMLParser();\n return _htmlParser\n}\n\nfunction Node (node) {\n node.isBlock = isBlock(node);\n node.isCode = node.nodeName.toLowerCase() === 'code' || node.parentNode.isCode;\n node.isBlank = isBlank(node);\n node.flankingWhitespace = flankingWhitespace(node);\n return node\n}\n\nfunction isBlank (node) {\n return (\n ['A', 'TH', 'TD', 'IFRAME', 'SCRIPT', 'AUDIO', 'VIDEO'].indexOf(node.nodeName) === -1 &&\n /^\\s*$/i.test(node.textContent) &&\n !isVoid(node) &&\n !hasVoid(node)\n )\n}\n\nfunction flankingWhitespace (node) {\n var leading = '';\n var trailing = '';\n\n if (!node.isBlock) {\n var hasLeading = /^[ \\r\\n\\t]/.test(node.textContent);\n var hasTrailing = /[ \\r\\n\\t]$/.test(node.textContent);\n\n if (hasLeading && !isFlankedByWhitespace('left', node)) {\n leading = ' ';\n }\n if (hasTrailing && !isFlankedByWhitespace('right', node)) {\n trailing = ' ';\n }\n }\n\n return { leading: leading, trailing: trailing }\n}\n\nfunction isFlankedByWhitespace (side, node) {\n var sibling;\n var regExp;\n var isFlanked;\n\n if (side === 'left') {\n sibling = node.previousSibling;\n regExp = / $/;\n } else {\n sibling = node.nextSibling;\n regExp = /^ /;\n }\n\n if (sibling) {\n if (sibling.nodeType === 3) {\n isFlanked = regExp.test(sibling.nodeValue);\n } else if (sibling.nodeType === 1 && !isBlock(sibling)) {\n isFlanked = regExp.test(sibling.textContent);\n }\n }\n return isFlanked\n}\n\nvar reduce = Array.prototype.reduce;\nvar leadingNewLinesRegExp = /^\\n*/;\nvar trailingNewLinesRegExp = /\\n*$/;\nvar escapes = [\n [/\\\\/g, '\\\\\\\\'],\n [/\\*/g, '\\\\*'],\n [/^-/g, '\\\\-'],\n [/^\\+ /g, '\\\\+ '],\n [/^(=+)/g, '\\\\$1'],\n [/^(#{1,6}) /g, '\\\\$1 '],\n [/`/g, '\\\\`'],\n [/^~~~/g, '\\\\~~~'],\n [/\\[/g, '\\\\['],\n [/\\]/g, '\\\\]'],\n [/^>/g, '\\\\>'],\n [/_/g, '\\\\_'],\n [/^(\\d+)\\. /g, '$1\\\\. ']\n];\n\nfunction TurndownService (options) {\n if (!(this instanceof TurndownService)) return new TurndownService(options)\n\n var defaults = {\n rules: rules,\n headingStyle: 'setext',\n hr: '* * *',\n bulletListMarker: '*',\n codeBlockStyle: 'indented',\n fence: '```',\n emDelimiter: '_',\n strongDelimiter: '**',\n linkStyle: 'inlined',\n linkReferenceStyle: 'full',\n br: ' ',\n blankReplacement: function (content, node) {\n return node.isBlock ? '\\n\\n' : ''\n },\n keepReplacement: function (content, node) {\n return node.isBlock ? '\\n\\n' + node.outerHTML + '\\n\\n' : node.outerHTML\n },\n defaultReplacement: function (content, node) {\n return node.isBlock ? '\\n\\n' + content + '\\n\\n' : content\n }\n };\n this.options = extend({}, defaults, options);\n this.rules = new Rules(this.options);\n}\n\nTurndownService.prototype = {\n /**\n * The entry point for converting a string or DOM node to Markdown\n * @public\n * @param {String|HTMLElement} input The string or DOM node to convert\n * @returns A Markdown representation of the input\n * @type String\n */\n\n turndown: function (input) {\n if (!canConvert(input)) {\n throw new TypeError(\n input + ' is not a string, or an element/document/fragment node.'\n )\n }\n\n if (input === '') return ''\n\n var output = process.call(this, new RootNode(input));\n return postProcess.call(this, output)\n },\n\n /**\n * Add one or more plugins\n * @public\n * @param {Function|Array} plugin The plugin or array of plugins to add\n * @returns The Turndown instance for chaining\n * @type Object\n */\n\n use: function (plugin) {\n if (Array.isArray(plugin)) {\n for (var i = 0; i < plugin.length; i++) this.use(plugin[i]);\n } else if (typeof plugin === 'function') {\n plugin(this);\n } else {\n throw new TypeError('plugin must be a Function or an Array of Functions')\n }\n return this\n },\n\n /**\n * Adds a rule\n * @public\n * @param {String} key The unique key of the rule\n * @param {Object} rule The rule\n * @returns The Turndown instance for chaining\n * @type Object\n */\n\n addRule: function (key, rule) {\n this.rules.add(key, rule);\n return this\n },\n\n /**\n * Keep a node (as HTML) that matches the filter\n * @public\n * @param {String|Array|Function} filter The unique key of the rule\n * @returns The Turndown instance for chaining\n * @type Object\n */\n\n keep: function (filter) {\n this.rules.keep(filter);\n return this\n },\n\n /**\n * Remove a node that matches the filter\n * @public\n * @param {String|Array|Function} filter The unique key of the rule\n * @returns The Turndown instance for chaining\n * @type Object\n */\n\n remove: function (filter) {\n this.rules.remove(filter);\n return this\n },\n\n /**\n * Escapes Markdown syntax\n * @public\n * @param {String} string The string to escape\n * @returns A string with Markdown syntax escaped\n * @type String\n */\n\n escape: function (string) {\n return escapes.reduce(function (accumulator, escape) {\n return accumulator.replace(escape[0], escape[1])\n }, string)\n }\n};\n\n/**\n * Reduces a DOM node down to its Markdown string equivalent\n * @private\n * @param {HTMLElement} parentNode The node to convert\n * @returns A Markdown representation of the node\n * @type String\n */\n\nfunction process (parentNode) {\n var self = this;\n return reduce.call(parentNode.childNodes, function (output, node) {\n node = new Node(node);\n\n var replacement = '';\n if (node.nodeType === 3) {\n replacement = node.isCode ? node.nodeValue : self.escape(node.nodeValue);\n } else if (node.nodeType === 1) {\n replacement = replacementForNode.call(self, node);\n }\n\n return join(output, replacement)\n }, '')\n}\n\n/**\n * Appends strings as each rule requires and trims the output\n * @private\n * @param {String} output The conversion output\n * @returns A trimmed version of the ouput\n * @type String\n */\n\nfunction postProcess (output) {\n var self = this;\n this.rules.forEach(function (rule) {\n if (typeof rule.append === 'function') {\n output = join(output, rule.append(self.options));\n }\n });\n\n return output.replace(/^[\\t\\r\\n]+/, '').replace(/[\\t\\r\\n\\s]+$/, '')\n}\n\n/**\n * Converts an element node to its Markdown equivalent\n * @private\n * @param {HTMLElement} node The node to convert\n * @returns A Markdown representation of the node\n * @type String\n */\n\nfunction replacementForNode (node) {\n var rule = this.rules.forNode(node);\n var content = process.call(this, node);\n var whitespace = node.flankingWhitespace;\n if (whitespace.leading || whitespace.trailing) content = content.trim();\n return (\n whitespace.leading +\n rule.replacement(content, node, this.options) +\n whitespace.trailing\n )\n}\n\n/**\n * Determines the new lines between the current output and the replacement\n * @private\n * @param {String} output The current conversion output\n * @param {String} replacement The string to append to the output\n * @returns The whitespace to separate the current output and the replacement\n * @type String\n */\n\nfunction separatingNewlines (output, replacement) {\n var newlines = [\n output.match(trailingNewLinesRegExp)[0],\n replacement.match(leadingNewLinesRegExp)[0]\n ].sort();\n var maxNewlines = newlines[newlines.length - 1];\n return maxNewlines.length < 2 ? maxNewlines : '\\n\\n'\n}\n\nfunction join (string1, string2) {\n var separator = separatingNewlines(string1, string2);\n\n // Remove trailing/leading newlines and replace with separator\n string1 = string1.replace(trailingNewLinesRegExp, '');\n string2 = string2.replace(leadingNewLinesRegExp, '');\n\n return string1 + separator + string2\n}\n\n/**\n * Determines whether an input can be converted\n * @private\n * @param {String|HTMLElement} input Describe this parameter\n * @returns Describe what it returns\n * @type String|Object|Array|Boolean|Number\n */\n\nfunction canConvert (input) {\n return (\n input != null && (\n typeof input === 'string' ||\n (input.nodeType && (\n input.nodeType === 1 || input.nodeType === 9 || input.nodeType === 11\n ))\n )\n )\n}\n\nexport default TurndownService;\n","\n/**\n * Replace whitespace of text nodes within the given parents in the given root element.\n * @param {*} root An HTMLElement to look for text nodes within\n * @param {*} allowed_whitespace_nodes String array of allowed text nodes ( ['STRONG', 'EM'] ... )\n * @param {*} allowed_raw_nodes String array of allowed raw text nodes ( ['PRE', 'CODE'] ... )\n */\nexport function textNodesPreprocessor(root, allowed_whitespace_nodes, allowed_raw_nodes) {\n\tallowed_whitespace_nodes = allowed_whitespace_nodes.map(el => el.toUpperCase());\n\tallowed_raw_nodes = allowed_raw_nodes.map(el => el.toUpperCase());\n\n\tlet walker = document.createNodeIterator(\n\t\troot,\n\t\t// Only consider text nodes\n\t\tNodeFilter.SHOW_TEXT,\n\t );\n\n\tlet node;\n\twhile(node = walker.nextNode()) {\n\t\t// Strip NBSP whitespace in given nodes\n\t\tif ( node.parentElement && allowed_whitespace_nodes.indexOf(node.parentElement.nodeName) >= 0) {\n\t\tnode.nodeValue = node.nodeValue\n\t\t\t.replace(/^[\\u00a0]+/g, ' ')\n\t\t\t.replace(/[\\u00a0]+$/g, ' ');\n\t\t}\n\n\t\t// Re-encode < and > that would otherwise be output as HTML by turndown\n\t\t// https://github.com/domchristie/turndown/issues/106\n\t\tif (!hasParentOfType(node, allowed_raw_nodes)) {\n\t\t\tnode.nodeValue = _.escape(node.nodeValue);\n\t\t}\n\t}\n}\n\n/**\n * Replace links of A elements with their computed .href attribute\n * https://community.ooject.com/wp/29742\n * @param {} root\n * @param {*} allowed_whitespace_nodes\n * @param {*} allowed_raw_nodes\n */\nexport function linkPreprocessor(root, allowed_whitespace_nodes, allowed_raw_nodes) {\n\tlet walker = document.createNodeIterator(\n\t\troot,\n\t\t// Only consider element nodes\n\t\tNodeFilter.SHOW_ELEMENT,\n\t\t// Accept only A tags\n\t\tfunction(node) {\n\t\t\treturn node.nodeName.toLowerCase() === 'a' ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;\n\t\t}\n\t );\n\n\tlet node;\n\twhile(node = walker.nextNode()) {\n\t\t// node.href is properly escaped, while the attribute is not\n\t\t// and turndown uses the getAttribute version\n\t\tnode.setAttribute('href', node.href);\n\t}\n}\n\n\nexport function hasParentOfType(node, tagNames) {\n\tlet parent = node.parentElement;\n\n\twhile (parent) {\n\t\tif (tagNames.indexOf(parent.tagName) >= 0) {\n\t\t\treturn true;\n\t\t}\n\n\t\tparent = parent.parentElement;\n\t}\n\n\treturn false;\n}\n","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module markdown-gfm/commonmarkdataprocessor\n */\n\n/* eslint-env browser */\n\nimport HtmlDataProcessor from '@ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor';\nimport DomConverter from '@ckeditor/ckeditor5-engine/src/view/domconverter';\nimport {highlightedCodeBlock, taskListItems} from 'turndown-plugin-gfm';\nimport TurndownService from 'turndown';\nimport {textNodesPreprocessor, linkPreprocessor} from './utils/preprocessor';\nimport {removeParagraphsInLists} from './utils/paragraph-in-lists';\n\nexport const originalSrcAttribute = 'data-original-src';\n\n/**\n * This data processor implementation uses CommonMark as input/output data.\n *\n * @implements module:engine/dataprocessor/dataprocessor~DataProcessor\n */\nexport default class CommonMarkDataProcessor {\n\tconstructor() {\n\t\tthis._htmlDP = new HtmlDataProcessor();\n\t\tthis._domConverter = new DomConverter();\n\t}\n\n\t/**\n\t * Converts the provided CommonMark string to view tree.\n\t *\n\t * @param {String} data A CommonMark string.\n\t * @returns {module:engine/view/documentfragment~DocumentFragment} The converted view element.\n\t */\n\ttoView( data ) {\n\t\tconst md = require( 'markdown-it' )( {\n\t\t\t// Output html\n\t\t\thtml: true,\n\t\t\t// Use GFM language fence prefix\n\t\t\tlangPrefix: 'language-',\n\t\t} );\n\t\tconst html = md.render( data );\n\n\t\t// Convert input HTML data to DOM DocumentFragment.\n\t\tconst domFragment = this._htmlDP._toDom( html );\n\n\t\t// Fix some CommonMark specifics\n\t\t// Paragraphs within list elements (https://community.openproject.com/work_packages/28765)\n\t\tremoveParagraphsInLists( domFragment );\n\n\t\t// Convert DOM DocumentFragment to view DocumentFragment.\n\t\treturn this._domConverter.domToView( domFragment );\n\t}\n\n\t/**\n\t * Converts the provided {@link module:engine/view/documentfragment~DocumentFragment} to data format &mdash; in this\n\t * case to a CommonMark string.\n\t *\n\t * @param {module:engine/view/documentfragment~DocumentFragment} viewFragment\n\t * @returns {String} CommonMark string.\n\t */\n\ttoData( viewFragment ) {\n\t\t// Convert view DocumentFragment to DOM DocumentFragment.\n\t\tconst domFragment = this._domConverter.viewToDom( viewFragment, document );\n\n\t\t// Replace leading and trailing nbsp at the end of strong and em tags\n\t\t// with single spaces\n\t\ttextNodesPreprocessor(\n\t\t\tdomFragment,\n\t\t\t['strong', 'em'],\n\t\t\t// Ensure tables are allowed to have HTML contents\n\t\t\t// OP#29457\n\t\t\t['pre', 'code', 'table']\n\t\t);\n\n\t\t// Replace link attributes with their computed href attribute\n\t\tlinkPreprocessor(domFragment);\n\n\t\t// Use Turndown to convert DOM fragment to markdown\n\t\tconst turndownService = new TurndownService( {\n\t\t\theadingStyle: 'atx',\n\t\t\tcodeBlockStyle: 'fenced'\n\t\t} );\n\n\t\tturndownService.use([\n\t\t\thighlightedCodeBlock,\n\t\t\ttaskListItems,\n\t\t]);\n\n\t\t// Replace images with appropriate source URLs derived from an attachment,\n\t\t// if any. Otherwise use the original src\n\t\tturndownService.addRule('img', {\n\t\t\tfilter: 'img',\n\n\t\t\treplacement: function (content, node) {\n\t\t\t var alt = node.alt || '';\n\t\t\t var src = node.getAttribute(originalSrcAttribute) || node.getAttribute('src') || '';\n\t\t\t var title = node.title || '';\n\t\t\t var titlePart = title ? ' \"' + title + '\"' : '';\n\n\t\t\t return src ? '![' + alt + ']' + '(' + src + titlePart + ')' : '';\n\t\t\t}\n\t\t});\n\n\t\t// Keep HTML tables and remove filler elements\n\t\tturndownService.addRule('htmlTables', {\n\t\t\tfilter: ['table'],\n\t\t\treplacement: function (_content, node) {\n\t\t\t\t// Remove filler nodes\n\t\t\t\tnode.querySelectorAll('td br[data-cke-filler]')\n\t\t\t\t\t.forEach((node) => node.remove());\n\n\t\t\t\treturn node.outerHTML;\n\t\t\t}\n\t\t});\n\n\t\tturndownService.addRule('strikethrough', {\n\t\t\tfilter: ['del', 's', 'strike'],\n\t\t\treplacement: function (content) {\n\t\t\t return '~~' + content + '~~'\n\t\t\t}\n\t\t});\n\n\t\tturndownService.addRule( 'openProjectMacros', {\n\t\t\tfilter: [ 'macro' ],\n\t\t\treplacement: ( _content, node ) => {\n\t\t\t\tnode.innerHTML = '';\n\t\t\t\tvar outer = node.outerHTML;\n\t\t\t\treturn outer.replace(\"</macro>\", \"\\n</macro>\")\n\t\t\t}\n\t\t});\n\n\t\treturn turndownService.turndown( domFragment );\n\t}\n}\n","\n/**\n * Remove paragraphs within lists since they will be stripped by CKEditor\n * https://community.openproject.com/work_packages/28765\n */\nexport function removeParagraphsInLists(root) {\n\tlet walker = document.createNodeIterator(\n\t\troot,\n\t\t// Only consider element nodes\n\t\tNodeFilter.SHOW_ELEMENT,\n\t\t// Only except text nodes whose parent is one of parents\n\t\t { acceptNode: function(node) {\n\t\t\tif ( node.tagName === 'P' && node.parentElement && node.parentElement.tagName === 'LI') {\n\t\t\t return NodeFilter.FILTER_ACCEPT;\n\t\t\t}\n\t\t }\n\t\t},\n\t\tfalse\n\t );\n\n\tlet node;\n\twhile(node = walker.nextNode()) {\n\t\tnode.outerHTML = node.innerHTML;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module core/command\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor commands.\n *\n * Commands are the main way to manipulate editor contents and state. They are mostly used by UI elements (or by other\n * commands) to make changes in the model. Commands are available in every part of code that has access to\n * the {@link module:core/editor/editor~Editor editor} instance.\n *\n * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n *\n * By default commands are disabled when the editor is in {@link module:core/editor/editor~Editor#isReadOnly read-only} mode.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Command {\n\t/**\n\t * Creates a new `Command` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor Editor on which this command will be used.\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor on which this command will be used.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * The value of the command. A concrete command class should define what it represents for it.\n\t\t *\n\t\t * For example, the `'bold'` command's value indicates whether the selection starts in a bolded text.\n\t\t * And the value of the `'link'` command may be an object with links details.\n\t\t *\n\t\t * It is possible for a command to have no value (e.g. for stateless actions such as `'imageUpload'`).\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member #value\n\t\t */\n\t\tthis.set( 'value', undefined );\n\n\t\t/**\n\t\t * Flag indicating whether a command is enabled or disabled.\n\t\t * A disabled command will do nothing when executed.\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * It is possible to disable a command from \"outside\". For instance, in your integration you may want to disable\n\t\t * a certain set of commands for the time being. To do that, you can use the fact that `isEnabled` is observable\n\t\t * and it fires the `set:isEnabled` event every time anyone tries to modify its value:\n\t\t *\n\t\t *\t\tfunction disableCommand( cmd ) {\n\t\t *\t\t\tcmd.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t *\n\t\t *\t\t\tcmd.isEnabled = false;\n\t\t *\n\t\t *\t\t\t// Make it possible to enable the command again.\n\t\t *\t\t\treturn () => {\n\t\t *\t\t\t\tcmd.off( 'set:isEnabled', forceDisable );\n\t\t *\t\t\t\tcmd.refresh();\n\t\t *\t\t\t};\n\t\t *\n\t\t *\t\t\tfunction forceDisable( evt ) {\n\t\t *\t\t\t\tevt.return = false;\n\t\t *\t\t\t\tevt.stop();\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\n\t\t *\t\t// Usage:\n\t\t *\n\t\t *\t\t// Disabling the command.\n\t\t *\t\tconst enableBold = disableCommand( editor.commands.get( 'bold' ) );\n\t\t *\n\t\t *\t\t// Enabling the command again.\n\t\t *\t\tenableBold();\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\t\tthis.set( 'isEnabled', false );\n\n\t\tthis.decorate( 'execute' );\n\n\t\t// By default every command is refreshed when changes are applied to the model.\n\t\tthis.listenTo( this.editor.model.document, 'change', () => {\n\t\t\tthis.refresh();\n\t\t} );\n\n\t\tthis.on( 'execute', evt => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// By default commands are disabled when the editor is in read-only mode.\n\t\tthis.listenTo( editor, 'change:isReadOnly', ( evt, name, value ) => {\n\t\t\tif ( value ) {\n\t\t\t\tthis.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t\t\tthis.isEnabled = false;\n\t\t\t} else {\n\t\t\t\tthis.off( 'set:isEnabled', forceDisable );\n\t\t\t\tthis.refresh();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties\n\t * in this method.\n\t *\n\t * This method is automatically called when\n\t * {@link module:engine/model/document~Document#event:change any changes are applied to the document}.\n\t */\n\trefresh() {\n\t\tthis.isEnabled = true;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`}\n\t * to the command.\n\t *\n\t * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`).\n\t * This behavior is implemented by a high priority listener to the {@link #event:execute} event.\n\t *\n\t * In order to see how to disable a command from \"outside\" see the {@link #isEnabled} documentation.\n\t *\n\t * @fires execute\n\t */\n\texecute() {}\n\n\t/**\n\t * Destroys the command.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Event fired by the {@link #execute} method. The command action is a listener to this event so it's\n\t * possible to change/cancel the behavior of the command by listening to this event.\n\t *\n\t * See {@link module:utils/observablemixin~ObservableMixin.decorate} for more information and samples.\n\t *\n\t * **Note:** This event is fired even if command is disabled. However, it is automatically blocked\n\t * by a high priority listener in order to prevent command execution.\n\t *\n\t * @event execute\n\t */\n}\n\nmix( Command, ObservableMixin );\n\n// Helper function that forces command to be disabled.\nfunction forceDisable( evt ) {\n\tevt.return = false;\n\tevt.stop();\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module mention/mentioncommand\n */\n\nimport Command from '@ckeditor/ckeditor5-core/src/command';\nimport toMap from '@ckeditor/ckeditor5-utils/src/tomap';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport { _addMentionAttributes } from './mentionediting';\n\n/**\n * The mention command.\n *\n * The command is registered by the {@link module:mention/mentionediting~MentionEditing} as `'mention'`.\n *\n * To insert a mention on a range, execute the command and specify a mention object and a range to replace:\n *\n *\t\tconst focus = editor.model.document.selection.focus;\n *\n *\t\t// It will replace one character before selection focus with '#1234' text\n *\t\t// with mention attribute filled with passed attributes.\n *\t\teditor.execute( 'mention', {\n *\t\t\tmarker: '#',\n *\t\t\tmention: {\n *\t\t\t\tid: '#1234',\n *\t\t\t\tname: 'Foo',\n *\t\t\t\ttitle: 'Big Foo'\n *\t\t\t},\n *\t\t\trange: model.createRange( focus, focus.getShiftedBy( -1 ) )\n *\t\t} );\n *\n *\t\t// It will replace one character before selection focus with 'Teh \"Big Foo\"' text\n *\t\t// with attribute filled with passed attributes.\n *\t\teditor.execute( 'mention', {\n *\t\t\tmarker: '#',\n *\t\t\tmention: {\n *\t\t\t\tid: '#1234',\n *\t\t\t\tname: 'Foo',\n *\t\t\t\ttitle: 'Big Foo'\n *\t\t\t},\n *\t\t\ttext: 'The \"Big Foo\"',\n *\t\t\trange: model.createRange( focus, focus.getShiftedBy( -1 ) )\n *\t\t} );\n *\n * @extends module:core/command~Command\n */\nexport default class MentionCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\n\t\tthis.isEnabled = model.schema.checkAttributeInSelection( doc.selection, 'mention' );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @param {Object} [options] Options for the executed command.\n\t * @param {Object|String} options.mention Mention object to insert. If passed a string it will be used to create a plain object with\n\t * name attribute equal to passed string.\n\t * @param {String} options.marker The marker character (e.g. `'@'`).\n\t * @param {String} [options.text] The text of inserted mention. Defaults to full mention string composed from `marker` and\n\t * `mention` string or `mention.id` if object is passed.\n\t * @param {String} [options.range] Range to replace. Note that replace range might be shorter then inserted text with mention attribute.\n\t * @fires execute\n\t */\n\texecute( options ) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\t\tconst selection = document.selection;\n\n\t\tconst mentionData = typeof options.mention == 'string' ? { id: options.mention } : options.mention;\n\t\tconst mentionID = mentionData.id;\n\n\t\tconst range = options.range || selection.getFirstRange();\n\n\t\tconst mentionText = options.text || mentionID;\n\n\t\tconst mention = _addMentionAttributes( { _text: mentionText, id: mentionID }, mentionData );\n\n\t\tif ( options.marker.length != 1 ) {\n\t\t\t/**\n\t\t\t * The marker must be a single character.\n\t\t\t *\n\t\t\t * Correct markers: `'@'`, `'#'`.\n\t\t\t *\n\t\t\t * Incorrect markers: `'$$'`, `'[@'`.\n\t\t\t *\n\t\t\t * See {@link module:mention/mention~MentionConfig}.\n\t\t\t *\n\t\t\t * @error mentioncommand-incorrect-marker\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'mentioncommand-incorrect-marker: The marker must be a single character.' );\n\t\t}\n\n\t\tif ( mentionID.charAt( 0 ) != options.marker ) {\n\t\t\t/**\n\t\t\t * The feed item id must start with the marker character.\n\t\t\t *\n\t\t\t * Correct mention feed setting:\n\t\t\t *\n\t\t\t *\t\tmentions: [\n\t\t\t *\t\t\t{\n\t\t\t *\t\t\t\tmarker: '@',\n\t\t\t *\t\t\t\tfeed: [ '@Ann', '@Barney', ... ]\n\t\t\t *\t\t\t}\n\t\t\t *\t\t]\n\t\t\t *\n\t\t\t * Incorrect mention feed setting:\n\t\t\t *\n\t\t\t *\t\tmentions: [\n\t\t\t *\t\t\t{\n\t\t\t *\t\t\t\tmarker: '@',\n\t\t\t *\t\t\t\tfeed: [ 'Ann', 'Barney', ... ]\n\t\t\t *\t\t\t}\n\t\t\t *\t\t]\n\t\t\t *\n\t\t\t * See {@link module:mention/mention~MentionConfig}.\n\t\t\t *\n\t\t\t * @error mentioncommand-incorrect-id\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'mentioncommand-incorrect-id: The item id must start with the marker character.' );\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\tconst currentAttributes = toMap( selection.getAttributes() );\n\t\t\tconst attributesWithMention = new Map( currentAttributes.entries() );\n\n\t\t\tattributesWithMention.set( 'mention', mention );\n\n\t\t\t// Replace range with a text with mention.\n\t\t\twriter.remove( range );\n\t\t\twriter.insertText( mentionText, attributesWithMention, range.start );\n\n\t\t\t// Insert space after a mention.\n\t\t\twriter.insertText( ' ', currentAttributes, model.document.selection.focus );\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module mention/mentionediting\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport uid from '@ckeditor/ckeditor5-utils/src/uid';\n\nimport MentionCommand from './mentioncommand';\n\n/**\n * The mention editing feature.\n *\n * It introduces the {@link module:mention/mentioncommand~MentionCommand command} and the `mention`\n * attribute in the {@link module:engine/model/model~Model model} which renders in the {@link module:engine/view/view view}\n * as a `<span class=\"mention\" data-mention=\"@mention\">`.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class MentionEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'MentionEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst doc = model.document;\n\n\t\t// Allow mention attribute on all text nodes.\n\t\tmodel.schema.extend( '$text', { allowAttributes: 'mention' } );\n\n\t\teditor.conversion.for( 'upcast' ).elementToAttribute( {\n\t\t\tview: {\n\t\t\t\tname: 'span',\n\t\t\t\tkey: 'data-mention',\n\t\t\t\tclasses: 'mention'\n\t\t\t},\n\t\t\tmodel: {\n\t\t\t\tkey: 'mention',\n\t\t\t\tvalue: _toMentionAttribute\n\t\t\t}\n\t\t} );\n\n\t\teditor.conversion.for( 'downcast' ).attributeToElement( {\n\t\t\tmodel: 'mention',\n\t\t\tview: createViewMentionElement\n\t\t} );\n\n\t\tdoc.registerPostFixer( writer => removePartialMentionPostFixer( writer, doc, model.schema ) );\n\t\tdoc.registerPostFixer( writer => extendAttributeOnMentionPostFixer( writer, doc ) );\n\t\tdoc.registerPostFixer( writer => selectionMentionAttributePostFixer( writer, doc ) );\n\n\t\teditor.commands.add( 'mention', new MentionCommand( editor ) );\n\t}\n}\n\nexport function _addMentionAttributes( baseMentionData, data ) {\n\treturn Object.assign( { _uid: uid() }, baseMentionData, data || {} );\n}\n\n/**\n * Creates mention attribute value from provided view element and optional data.\n *\n * This function is exposed as\n * {@link module:mention/mention~Mention#toMentionAttribute `editor.plugins.get( 'Mention' ).toMentionAttribute()`}.\n *\n * @protected\n * @param {module:engine/view/element~Element} viewElementOrMention\n * @param {String|Object} [data] Mention data to be extended.\n * @return {module:mention/mention~MentionAttribute}\n */\nexport function _toMentionAttribute( viewElementOrMention, data ) {\n\tconst dataMention = viewElementOrMention.getAttribute( 'data-mention' );\n\n\tconst textNode = viewElementOrMention.getChild( 0 );\n\n\t// Do not convert empty mentions.\n\tif ( !textNode ) {\n\t\treturn;\n\t}\n\n\tconst baseMentionData = {\n\t\tid: dataMention,\n\t\t_text: textNode.data\n\t};\n\n\treturn _addMentionAttributes( baseMentionData, data );\n}\n\n// Creates mention element from mention data.\n//\n// @param {Object} mention\n// @param {module:engine/view/downcastwriter~DowncastWriter} viewWriter\n// @returns {module:engine/view/attributeelement~AttributeElement}\nfunction createViewMentionElement( mention, viewWriter ) {\n\tif ( !mention ) {\n\t\treturn;\n\t}\n\n\tconst attributes = {\n\t\tclass: 'mention',\n\t\t'data-mention': mention.id\n\t};\n\n\tconst options = {\n\t\tid: mention._uid,\n\t\tpriority: 20\n\t};\n\n\treturn viewWriter.createAttributeElement( 'span', attributes, options );\n}\n\n// Model post-fixer that disallows typing with selection when selection is placed after the text node with mention attribute.\n//\n// @param {module:engine/model/writer~Writer} writer\n// @param {module:engine/model/document~Document} doc\n// @returns {Boolean} Returns true if selection was fixed.\nfunction selectionMentionAttributePostFixer( writer, doc ) {\n\tconst selection = doc.selection;\n\tconst focus = selection.focus;\n\n\tif ( selection.isCollapsed && selection.hasAttribute( 'mention' ) && isNodeBeforeAText( focus ) ) {\n\t\twriter.removeSelectionAttribute( 'mention' );\n\n\t\treturn true;\n\t}\n\n\tfunction isNodeBeforeAText( position ) {\n\t\treturn position.nodeBefore && position.nodeBefore.is( 'text' );\n\t}\n}\n\n// Model post-fixer that removes mention attribute from modified text node.\n//\n// @param {module:engine/model/writer~Writer} writer\n// @param {module:engine/model/document~Document} doc\n// @returns {Boolean} Returns true if selection was fixed.\nfunction removePartialMentionPostFixer( writer, doc, schema ) {\n\tconst changes = doc.differ.getChanges();\n\n\tlet wasChanged = false;\n\n\tfor ( const change of changes ) {\n\t\t// Check text node on current position;\n\t\tconst position = change.position;\n\n\t\tif ( change.name == '$text' ) {\n\t\t\tconst nodeAfterInsertedTextNode = position.textNode && position.textNode.nextSibling;\n\n\t\t\t// Check textNode where the change occurred.\n\t\t\twasChanged = checkAndFix( position.textNode, writer ) || wasChanged;\n\n\t\t\t// Occurs on paste occurs inside a text node with mention.\n\t\t\twasChanged = checkAndFix( nodeAfterInsertedTextNode, writer ) || wasChanged;\n\t\t\twasChanged = checkAndFix( position.nodeBefore, writer ) || wasChanged;\n\t\t\twasChanged = checkAndFix( position.nodeAfter, writer ) || wasChanged;\n\t\t}\n\n\t\t// Check text nodes in inserted elements (might occur when splitting paragraph or pasting content inside text with mention).\n\t\tif ( change.name != '$text' && change.type == 'insert' ) {\n\t\t\tconst insertedNode = position.nodeAfter;\n\n\t\t\tfor ( const item of writer.createRangeIn( insertedNode ).getItems() ) {\n\t\t\t\twasChanged = checkAndFix( item, writer ) || wasChanged;\n\t\t\t}\n\t\t}\n\n\t\t// Inserted inline elements might break mention.\n\t\tif ( change.type == 'insert' && schema.isInline( change.name ) ) {\n\t\t\tconst nodeAfterInserted = position.nodeAfter && position.nodeAfter.nextSibling;\n\n\t\t\twasChanged = checkAndFix( position.nodeBefore, writer ) || wasChanged;\n\t\t\twasChanged = checkAndFix( nodeAfterInserted, writer ) || wasChanged;\n\t\t}\n\t}\n\n\treturn wasChanged;\n}\n\n// This post-fixer will extend attribute applied on part of a mention so a whole text node of a mention will have added attribute.\n//\n// @param {module:engine/model/writer~Writer} writer\n// @param {module:engine/model/document~Document} doc\n// @returns {Boolean} Returns true if selection was fixed.\nfunction extendAttributeOnMentionPostFixer( writer, doc ) {\n\tconst changes = doc.differ.getChanges();\n\n\tlet wasChanged = false;\n\n\tfor ( const change of changes ) {\n\t\tif ( change.type === 'attribute' && change.attributeKey != 'mention' ) {\n\t\t\t// Check node at the left side of a range...\n\t\t\tconst nodeBefore = change.range.start.nodeBefore;\n\t\t\t// ... and on right side of range.\n\t\t\tconst nodeAfter = change.range.end.nodeAfter;\n\n\t\t\tfor ( const node of [ nodeBefore, nodeAfter ] ) {\n\t\t\t\tif ( isBrokenMentionNode( node ) && node.getAttribute( change.attributeKey ) != change.attributeNewValue ) {\n\t\t\t\t\twriter.setAttribute( change.attributeKey, change.attributeNewValue, node );\n\n\t\t\t\t\twasChanged = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn wasChanged;\n}\n\n// Checks if node has correct mention attribute if present.\n// Returns true if node is text and has a mention attribute which text does not match expected mention text.\n//\n// @param {module:engine/model/node~Node} node a node to check\n// @returns {Boolean}\nfunction isBrokenMentionNode( node ) {\n\tif ( !node || !( node.is( 'text' ) || node.is( 'textProxy' ) ) || !node.hasAttribute( 'mention' ) ) {\n\t\treturn false;\n\t}\n\n\tconst text = node.data;\n\tconst mention = node.getAttribute( 'mention' );\n\n\tconst expectedText = mention._text;\n\n\treturn text != expectedText;\n}\n\n// Fixes mention on text node it needs a fix.\n//\n// @param {module:engine/model/text~Text} textNode\n// @param {module:engine/model/writer~Writer} writer\n// @returns {Boolean}\nfunction checkAndFix( textNode, writer ) {\n\tif ( isBrokenMentionNode( textNode ) ) {\n\t\twriter.removeAttribute( 'mention', textNode );\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module mention/textwatcher\n */\n\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\n\n/**\n * Text watcher feature.\n *\n * Fires {@link module:mention/textwatcher~TextWatcher#event:matched matched} and\n * {@link module:mention/textwatcher~TextWatcher#event:unmatched unmatched} events on typing or selection changes.\n *\n * @private\n */\nexport default class TextWatcher {\n\t/**\n\t * Creates a text watcher instance.\n\t * @param {module:core/editor/editor~Editor} editor\n\t * @param {Function} testCallback Function used to match the text.\n\t * @param {Function} textMatcherCallback Function used to process matched text.\n\t */\n\tconstructor( editor, testCallback, textMatcherCallback ) {\n\t\tthis.editor = editor;\n\t\tthis.testCallback = testCallback;\n\t\tthis.textMatcher = textMatcherCallback;\n\t\tthis.debouncedMatcher = _.debounce(\n\t\t\t(text, matched) => this.fire( 'matched', { text, matched } ),\n\t\t\t100\n\t\t);\n\n\t\tthis.hasMatch = false;\n\n\t\tthis._startListening();\n\t}\n\n\t/**\n\t * Last matched text.\n\t *\n\t * @property {String}\n\t */\n\tget last() {\n\t\treturn this._getText();\n\t}\n\n\t/**\n\t * Starts listening the editor for typing & selection events.\n\t *\n\t * @private\n\t */\n\t_startListening() {\n\t\tconst editor = this.editor;\n\n\t\teditor.model.document.selection.on( 'change', ( evt, { directChange } ) => {\n\t\t\t// The indirect changes (ie on typing) are handled in document's change event.\n\t\t\tif ( !directChange ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._evaluateTextBeforeSelection();\n\t\t} );\n\n\t\teditor.model.document.on( 'change:data', ( evt, batch ) => {\n\t\t\tif ( batch.type == 'transparent' ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthis._evaluateTextBeforeSelection();\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the editor content for matched text.\n\t *\n\t * @fires matched\n\t * @fires unmatched\n\t *\n\t * @private\n\t */\n\t_evaluateTextBeforeSelection() {\n\t\tconst text = this._getText();\n\n\t\tconst textHasMatch = this.testCallback( text );\n\n\t\tif ( !textHasMatch && this.hasMatch ) {\n\t\t\t/**\n\t\t\t * Fired whenever text doesn't match anymore. Fired only when text matcher was matched.\n\t\t\t *\n\t\t\t * @event unmatched\n\t\t\t */\n\t\t\tthis.fire( 'unmatched' );\n\t\t}\n\n\t\tthis.hasMatch = textHasMatch;\n\n\t\tif ( textHasMatch ) {\n\t\t\tconst matched = this.textMatcher( text );\n\n\t\t\t/**\n\t\t\t * Fired whenever text matcher was matched.\n\t\t\t *\n\t\t\t * @event matched\n\t\t\t */\n\t\t\tthis.debouncedMatcher(text, matched);\n\t\t}\n\t}\n\n\t/**\n\t * Returns the text before the caret from the current selection block.\n\t *\n\t * @returns {String|undefined} Text from block or undefined if selection is not collapsed.\n\t * @private\n\t */\n\t_getText() {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\n\t\t// Do nothing if selection is not collapsed.\n\t\tif ( !selection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst block = selection.focus.parent;\n\n\t\treturn _getText( editor.model.createRangeIn( block ) ).slice( 0, selection.focus.offset );\n\t}\n}\n\n/**\n * Returns whole text from given range by adding all data from text nodes together.\n *\n * @protected\n * @param {module:engine/model/range~Range} range\n * @returns {String}\n */\nexport function _getText( range ) {\n\treturn Array.from( range.getItems() ).reduce( ( a, b ) => a + b.data, '' );\n}\n\nmix( TextWatcher, EmitterMixin );\n\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module mention/ui/mentionsview\n */\n\nimport ListView from '@ckeditor/ckeditor5-ui/src/list/listview';\nimport Rect from '@ckeditor/ckeditor5-utils/src/dom/rect';\n\nimport '../../theme/mentionui.css';\n\n/**\n * The mention ui view.\n *\n * @extends module:ui/list/listview~ListView\n */\nexport default class MentionsView extends ListView {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-mentions'\n\t\t\t\t],\n\n\t\t\t\ttabindex: '-1'\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * {@link #select Selects} the first item.\n\t */\n\tselectFirst() {\n\t\tthis.select( 0 );\n\t}\n\n\t/**\n\t * Selects next item to the currently {@link #select selected}.\n\t *\n\t * If the last item is already selected, it will select the first item.\n\t */\n\tselectNext() {\n\t\tconst item = this.selected;\n\t\tconst index = this.items.getIndex( item );\n\n\t\tthis.select( index + 1 );\n\t}\n\n\t/**\n\t * Selects previous item to the currently {@link #select selected}.\n\t *\n\t * If the first item is already selected, it will select the last item.\n\t */\n\tselectPrevious() {\n\t\tconst item = this.selected;\n\t\tconst index = this.items.getIndex( item );\n\n\t\tthis.select( index - 1 );\n\t}\n\n\t/**\n\t * Marks item at a given index as selected.\n\t *\n\t * Handles selection cycling when passed index is out of bounds:\n\t * - if the index is lower than 0, it will select the last item,\n\t * - if the index is higher than the last item index, it will select the first item.\n\t *\n\t * @param {Number} index Index of an item to be marked as selected.\n\t */\n\tselect( index ) {\n\t\tlet indexToGet = 0;\n\n\t\tif ( index > 0 && index < this.items.length ) {\n\t\t\tindexToGet = index;\n\t\t} else if ( index < 0 ) {\n\t\t\tindexToGet = this.items.length - 1;\n\t\t}\n\n\t\tconst item = this.items.get( indexToGet );\n\t\titem.highlight();\n\n\t\t// Scroll the mentions view to the selected element.\n\t\tif ( !this._isItemVisibleInScrolledArea( item ) ) {\n\t\t\tthis.element.scrollTop = item.element.offsetTop;\n\t\t}\n\n\t\tif ( this.selected ) {\n\t\t\tthis.selected.removeHighlight();\n\t\t}\n\n\t\tthis.selected = item;\n\t}\n\n\t/**\n\t * Triggers the `execute` event on the {@link #select selected} item.\n\t */\n\texecuteSelected() {\n\t\tthis.selected.fire( 'execute' );\n\t}\n\n\t// Checks if an item is visible in the scrollable area.\n\t//\n\t// The item is considered visible when:\n\t// - its top boundary is inside the scrollable rect\n\t// - its bottom boundary is inside the scrollable rect (the whole item must be visible)\n\t_isItemVisibleInScrolledArea( item ) {\n\t\treturn new Rect( this.element ).contains( new Rect( item.element ) );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module mention/ui/domwrapperview\n */\n\nimport View from '@ckeditor/ckeditor5-ui/src/view';\n\n/**\n * This class wraps DOM element as a CKEditor5 UI View.\n *\n * It allows to render any DOM element and use it in mentions list.\n */\nexport default class DomWrapperView extends View {\n\t/**\n\t * Creates an instance of {@link module:mention/ui/domwrapperview~DomWrapperView} class.\n\t *\n\t * Also see {@link #render}.\n\t *\n\t * @param {module:utils/locale~Locale} [locale] The localization services instance.\n\t * @param {Element} domElement\n\t */\n\tconstructor( locale, domElement ) {\n\t\tsuper( locale );\n\n\t\t// Disable template rendering on this view.\n\t\tthis.template = false;\n\n\t\t/**\n\t\t * The DOM element for which wrapper was created.\n\t\t *\n\t\t * @type {Element}\n\t\t */\n\t\tthis.domElement = domElement;\n\n\t\t// Render dom wrapper as a button.\n\t\tthis.domElement.classList.add( 'ck-button' );\n\n\t\t/**\n\t\t * Controls whether the dom wrapper view is \"on\". This is in line with {@link module:ui/button/button~Button#isOn} property.\n\t\t *\n\t\t * @observable\n\t\t * @default true\n\t\t * @member {Boolean} #isOn\n\t\t */\n\t\tthis.set( 'isOn', false );\n\n\t\t// Handle isOn state as in buttons.\n\t\tthis.on( 'change:isOn', ( evt, name, isOn ) => {\n\t\t\tif ( isOn ) {\n\t\t\t\tthis.domElement.classList.add( 'ck-on' );\n\t\t\t\tthis.domElement.classList.remove( 'ck-off' );\n\t\t\t} else {\n\t\t\t\tthis.domElement.classList.add( 'ck-off' );\n\t\t\t\tthis.domElement.classList.remove( 'ck-on' );\n\t\t\t}\n\t\t} );\n\n\t\t// Pass click event as execute event.\n\t\tthis.listenTo( this.domElement, 'click', () => {\n\t\t\tthis.fire( 'execute' );\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\tthis.element = this.domElement;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module mention/ui/mentionlistitemview\n */\n\nimport ListItemView from '@ckeditor/ckeditor5-ui/src/list/listitemview';\n\nexport default class MentionListItemView extends ListItemView {\n\thighlight() {\n\t\tconst child = this.children.first;\n\n\t\tchild.isOn = true;\n\t}\n\n\tremoveHighlight() {\n\t\tconst child = this.children.first;\n\n\t\tchild.isOn = false;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module mention/mentionui\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\nimport Collection from '@ckeditor/ckeditor5-utils/src/collection';\nimport BalloonPanelView from '@ckeditor/ckeditor5-ui/src/panel/balloon/balloonpanelview';\nimport clickOutsideHandler from '@ckeditor/ckeditor5-ui/src/bindings/clickoutsidehandler';\nimport { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';\nimport Rect from '@ckeditor/ckeditor5-utils/src/dom/rect';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\nimport TextWatcher from './textwatcher';\n\nimport MentionsView from './ui/mentionsview';\nimport DomWrapperView from './ui/domwrapperview';\nimport MentionListItemView from './ui/mentionlistitemview';\n\nconst VERTICAL_SPACING = 3;\n\n/**\n * The mention UI feature.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class MentionUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'MentionUI';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The balloon panel view, containing the mention view.\n\t\t *\n\t\t * @type {module:ui/panel/balloon/balloonpanelview~BalloonPanelView}\n\t\t */\n\t\tthis.panelView = this._creatPanelView();\n\n\t\t/**\n\t\t * The mentions view.\n\t\t *\n\t\t * @type {module:mention/ui/mentionsview~MentionsView}\n\t\t * @private\n\t\t */\n\t\tthis._mentionsView = this._createMentionView();\n\n\t\t/**\n\t\t * Stores mentions feeds configurations.\n\t\t *\n\t\t * @type {Map<String, Object>}\n\t\t * @private\n\t\t */\n\t\tthis._mentionsConfigurations = new Map();\n\n\t\teditor.config.define( 'mention', { feeds: [] } );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\t// Key listener that handles navigation in mention view.\n\t\tthis.editor.editing.view.document.on( 'keydown', ( evt, data ) => {\n\t\t\tif ( isHandledKey( data.keyCode ) && this.panelView.isVisible ) {\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop(); // Required for enter overriding.\n\n\t\t\t\tif ( data.keyCode == keyCodes.arrowdown ) {\n\t\t\t\t\tthis._mentionsView.selectNext();\n\t\t\t\t}\n\n\t\t\t\tif ( data.keyCode == keyCodes.arrowup ) {\n\t\t\t\t\tthis._mentionsView.selectPrevious();\n\t\t\t\t}\n\n\t\t\t\tif ( data.keyCode == keyCodes.enter || data.keyCode == keyCodes.tab || data.keyCode == keyCodes.space ) {\n\t\t\t\t\tthis._mentionsView.executeSelected();\n\t\t\t\t}\n\n\t\t\t\tif ( data.keyCode == keyCodes.esc ) {\n\t\t\t\t\tthis._hidePanelAndRemoveMarker();\n\t\t\t\t}\n\t\t\t}\n\t\t}, { priority: 'highest' } ); // Required to override enter.\n\n\t\t// Close the #panelView upon clicking outside of the plugin UI.\n\t\tclickOutsideHandler( {\n\t\t\temitter: this.panelView,\n\t\t\tcontextElements: [ this.panelView.element ],\n\t\t\tactivator: () => this.panelView.isVisible,\n\t\t\tcallback: () => this._hidePanelAndRemoveMarker()\n\t\t} );\n\n\t\tconst feeds = this.editor.config.get( 'mention.feeds' );\n\t\tthis.feeds = {};\n\n\t\tfor ( const mentionDescription of feeds ) {\n\t\t\tconst feed = mentionDescription.feed;\n\n\t\t\tconst marker = mentionDescription.marker;\n\n\t\t\tif ( !marker || marker.length != 1 ) {\n\t\t\t\t/**\n\t\t\t\t * The marker must be a single character.\n\t\t\t\t *\n\t\t\t\t * Correct markers: `'@'`, `'#'`.\n\t\t\t\t *\n\t\t\t\t * Incorrect markers: `'$$'`, `'[@'`.\n\t\t\t\t *\n\t\t\t\t * See {@link module:mention/mention~MentionConfig}.\n\t\t\t\t *\n\t\t\t\t * @error mentionconfig-incorrect-marker\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'mentionconfig-incorrect-marker: The marker must be provided and be a single character.' );\n\t\t\t}\n\n\t\t\tconst minimumCharacters = mentionDescription.minimumCharacters || 0;\n\t\t\tconst allowedPrefixes = mentionDescription.allowedPrefixes || [];\n\t\t\tconst feedCallback = typeof feed == 'function' ? feed.bind(this) : createFeedCallback( feed );\n\t\t\tconst watcher = this._setupTextWatcherForFeed( marker, allowedPrefixes, minimumCharacters );\n\t\t\tconst itemRenderer = mentionDescription.itemRenderer;\n\n\t\t\tconst definition = { watcher, marker, feedCallback, allowedPrefixes, itemRenderer };\n\n\t\t\tthis._mentionsConfigurations.set( marker, definition );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tsuper.destroy();\n\n\t\t// Destroy created UI components as they are not automatically destroyed (see ckeditor5#1341).\n\t\tthis.panelView.destroy();\n\t}\n\n\t/**\n\t * Creates the {@link #panelView}.\n\t *\n\t * @private\n\t * @returns {module:ui/panel/balloon/balloonpanelview~BalloonPanelView}\n\t */\n\t_creatPanelView() {\n\t\tconst panelView = new BalloonPanelView( this.editor.locale );\n\n\t\tpanelView.withArrow = false;\n\t\tpanelView.render();\n\n\t\tthis.editor.ui.view.body.add( panelView );\n\n\t\treturn panelView;\n\t}\n\n\t/**\n\t * Creates the {@link #_mentionsView}.\n\t *\n\t * @private\n\t * @returns {module:mention/ui/mentionsview~MentionsView}\n\t */\n\t_createMentionView() {\n\t\tconst locale = this.editor.locale;\n\n\t\tconst mentionsView = new MentionsView( locale );\n\n\t\tthis._items = new Collection();\n\n\t\tthis.panelView.content.add( mentionsView );\n\n\t\tmentionsView.items.bindTo( this._items ).using( data => {\n\t\t\tconst { item, marker } = data;\n\n\t\t\tconst listItemView = new MentionListItemView( locale );\n\n\t\t\tconst view = this._renderItem( item, marker );\n\t\t\tview.delegate( 'execute' ).to( listItemView );\n\n\t\t\tlistItemView.children.add( view );\n\t\t\tlistItemView.item = item;\n\t\t\tlistItemView.marker = marker;\n\n\t\t\tlistItemView.on( 'execute', () => {\n\t\t\t\tmentionsView.fire( 'execute', {\n\t\t\t\t\titem,\n\t\t\t\t\tmarker\n\t\t\t\t} );\n\t\t\t} );\n\n\t\t\treturn listItemView;\n\t\t} );\n\n\t\tmentionsView.on( 'execute', ( evt, data ) => {\n\t\t\tconst editor = this.editor;\n\t\t\tconst model = editor.model;\n\n\t\t\tconst item = data.item;\n\t\t\tconst marker = data.marker;\n\n\t\t\tconst watcher = this._getWatcher( marker );\n\n\t\t\tconst text = watcher.last;\n\n\t\t\tconst config = this._mentionsConfigurations.get(marker);\n\n\t\t\tconst textMatcher = createTextMatcher( marker, config.allowedPrefixes );\n\t\t\tconst matched = textMatcher( text );\n\n\t\t\t// Determine the text we want to insert\n\t\t\tconst insert = matched.prefix + item.text;\n\t\t\t// Determine length of text to remove\n\t\t\tconst totalLength = matched.total.length;\n\n\t\t\t// Create a range on matched text.\n\t\t\tconst end = model.createPositionAt( model.document.selection.focus );\n\t\t\tconst start = end.getShiftedBy( -totalLength );\n\t\t\tconst range = model.createRange( start, end );\n\n\t\t\tthis._hidePanelAndRemoveMarker();\n\n\t\t\teditor.execute( 'mention', {\n\t\t\t\tmention: item,\n\t\t\t\ttext: insert,\n\t\t\t\tmarker,\n\t\t\t\trange\n\t\t\t} );\n\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\treturn mentionsView;\n\t}\n\n\t/**\n\t * Returns item renderer for marker.\n\t *\n\t * @private\n\t * @param {String} marker\n\t * @returns {Function|null}\n\t */\n\t_getItemRenderer( marker ) {\n\t\tconst { itemRenderer } = this._mentionsConfigurations.get( marker );\n\n\t\treturn itemRenderer;\n\t}\n\n\t/**\n\t * Returns a promise that resolves with autocomplete items for given text.\n\t *\n\t * @param {String} marker\n\t * @param {String} feedText\n\t * @return {Promise<module:mention/mention~MentionFeedItem>}\n\t * @private\n\t */\n\t_getFeed( marker, feedText ) {\n\t\tconst { feedCallback } = this._mentionsConfigurations.get( marker );\n\n\t\treturn Promise.resolve().then( () => feedCallback( feedText ) );\n\t}\n\n\t/**\n\t * Registers a text watcher for marker.\n\t *\n\t * @private\n\t * @param {String} marker\n\t * @param {Number} minimumCharacters\n\t * @returns {module:mention/textwatcher~TextWatcher}\n\t */\n\t_setupTextWatcherForFeed( marker, allowedPrefixes, minimumCharacters ) {\n\t\tconst editor = this.editor;\n\n\t\tconst watcher = new TextWatcher( editor, createTestCallback( marker, allowedPrefixes, minimumCharacters ), createTextMatcher( marker, allowedPrefixes ) );\n\n\t\twatcher.on( 'matched', ( evt, data ) => {\n\t\t\tconst matched = data.matched;\n\n\t\t\tconst selection = editor.model.document.selection;\n\n\t\t\tconst hasMention = selection.hasAttribute( 'mention' );\n\t\t\tconst nodeBefore = selection.focus.nodeBefore;\n\n\t\t\tif ( hasMention || nodeBefore && nodeBefore.is( 'text' ) && nodeBefore.hasAttribute( 'mention' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { feedText, marker } = matched;\n\n\t\t\tconst matchedTextLength = marker.length + feedText.length;\n\n\t\t\t// create marker range\n\t\t\tconst start = selection.focus.getShiftedBy( -matchedTextLength );\n\t\t\tconst end = selection.focus.getShiftedBy( -feedText.length );\n\n\t\t\tconst markerRange = editor.model.createRange( start, end );\n\n\t\t\tlet mentionMarker;\n\n\t\t\tif ( editor.model.markers.has( 'mention' ) ) {\n\t\t\t\tmentionMarker = editor.model.markers.get( 'mention' );\n\t\t\t} else {\n\t\t\t\tmentionMarker = editor.model.change( writer => writer.addMarker( 'mention', {\n\t\t\t\t\trange: markerRange,\n\t\t\t\t\tusingOperation: false,\n\t\t\t\t\taffectsData: false\n\t\t\t\t} ) );\n\t\t\t}\n\n\t\t\tthis._getFeed( marker, feedText )\n\t\t\t\t.then( feed => {\n\t\t\t\t\tthis._items.clear();\n\n\t\t\t\t\tfor ( const feedItem of feed ) {\n\t\t\t\t\t\tconst item = typeof feedItem != 'object' ? { id: feedItem, text: feedItem } : feedItem;\n\n\t\t\t\t\t\tthis._items.add( { item, marker } );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( this._items.length ) {\n\t\t\t\t\t\tthis._showPanel( mentionMarker );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis._hidePanelAndRemoveMarker();\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t} );\n\n\t\twatcher.on( 'unmatched', () => {\n\t\t\tthis._hidePanelAndRemoveMarker();\n\t\t} );\n\n\t\treturn watcher;\n\t}\n\n\t/**\n\t * Returns registered text watcher for marker.\n\t *\n\t * @private\n\t * @param {String} marker\n\t * @returns {module:mention/textwatcher~TextWatcher}\n\t */\n\t_getWatcher( marker ) {\n\t\tconst { watcher } = this._mentionsConfigurations.get( marker );\n\n\t\treturn watcher;\n\t}\n\n\t/**\n\t * Shows the {@link #panelView}. If panel is already visible it will reposition it.\n\t *\n\t * @private\n\t */\n\t_showPanel( markerMarker ) {\n\t\tthis.panelView.pin( this._getBalloonPanelPositionData( markerMarker, this.panelView.position ) );\n\t\tthis.panelView.show();\n\t\tthis._mentionsView.selectFirst();\n\t}\n\n\t/**\n\t * Hides the {@link #panelView} and remove 'mention' marker from markers collection.\n\t *\n\t * @private\n\t */\n\t_hidePanelAndRemoveMarker() {\n\t\tif ( this.editor.model.markers.has( 'mention' ) ) {\n\t\t\tthis.editor.model.change( writer => writer.removeMarker( 'mention' ) );\n\t\t}\n\n\t\tthis.panelView.unpin();\n\t\t// Make last matched position on panel view undefined so the #_getBalloonPanelPositionData() will return all positions on next call.\n\t\tthis.panelView.position = undefined;\n\t\tthis.panelView.hide();\n\t}\n\n\t/**\n\t * Renders a single item in the autocomplete list.\n\t *\n\t * @private\n\t * @param {module:mention/mention~MentionFeedItem} item\n\t * @param {String} marker\n\t * @returns {module:ui/button/buttonview~ButtonView|module:mention/ui/domwrapperview~DomWrapperView}\n\t */\n\t_renderItem( item, marker ) {\n\t\tconst editor = this.editor;\n\n\t\tlet view;\n\t\tlet label = item.id;\n\n\t\tconst renderer = this._getItemRenderer( marker );\n\n\t\tif ( renderer ) {\n\t\t\tconst renderResult = renderer( item );\n\n\t\t\tif ( typeof renderResult != 'string' ) {\n\t\t\t\tview = new DomWrapperView( editor.locale, renderResult );\n\t\t\t} else {\n\t\t\t\tlabel = renderResult;\n\t\t\t}\n\t\t}\n\n\t\tif ( !view ) {\n\t\t\tconst buttonView = new ButtonView( editor.locale );\n\n\t\t\tbuttonView.label = label;\n\t\t\tbuttonView.withText = true;\n\n\t\t\tview = buttonView;\n\t\t}\n\n\t\treturn view;\n\t}\n\n\t/**\n\t * Creates position options object used to position the balloon panel.\n\t *\n\t * @param {module:engine/model/markercollection~Marker} mentionMarker\n\t * @param {String|undefined} positionName Name of last matched position name.\n\t * @returns {module:utils/dom/position~Options}\n\t * @private\n\t */\n\t_getBalloonPanelPositionData( mentionMarker, positionName ) {\n\t\tconst editing = this.editor.editing;\n\t\tconst domConverter = editing.view.domConverter;\n\t\tconst mapper = editing.mapper;\n\n\t\treturn {\n\t\t\ttarget: () => {\n\t\t\t\tconst viewRange = mapper.toViewRange( mentionMarker.getRange() );\n\n\t\t\t\tconst rangeRects = Rect.getDomRangeRects( domConverter.viewRangeToDom( viewRange ) );\n\n\t\t\t\treturn rangeRects.pop();\n\t\t\t},\n\t\t\tlimiter: () => {\n\t\t\t\tconst view = this.editor.editing.view;\n\t\t\t\tconst viewDocument = view.document;\n\t\t\t\tconst editableElement = viewDocument.selection.editableElement;\n\n\t\t\t\tif ( editableElement ) {\n\t\t\t\t\treturn view.domConverter.mapViewToDom( editableElement.root );\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\tpositions: getBalloonPanelPositions( positionName ),\n\t\t\tfitInViewport: true\n\t\t};\n\t}\n}\n\n// Returns balloon positions data callbacks.\n//\n// @returns {Array.<module:utils/dom/position~Position>}\nfunction getBalloonPanelPositions( positionName ) {\n\tconst positions = {\n\t\t// Positions panel to the south of caret rect.\n\t\t'caret_se': targetRect => {\n\t\t\treturn {\n\t\t\t\ttop: targetRect.bottom + VERTICAL_SPACING,\n\t\t\t\tleft: targetRect.right,\n\t\t\t\tname: 'caret_se'\n\t\t\t};\n\t\t},\n\n\t\t// Positions panel to the north of caret rect.\n\t\t'caret_ne': ( targetRect, balloonRect ) => {\n\t\t\treturn {\n\t\t\t\ttop: targetRect.top - balloonRect.height - VERTICAL_SPACING,\n\t\t\t\tleft: targetRect.right,\n\t\t\t\tname: 'caret_ne'\n\t\t\t};\n\t\t},\n\n\t\t// Positions panel to the south of caret rect.\n\t\t'caret_sw': ( targetRect, balloonRect ) => {\n\t\t\treturn {\n\t\t\t\ttop: targetRect.bottom + VERTICAL_SPACING,\n\t\t\t\tleft: targetRect.right - balloonRect.width,\n\t\t\t\tname: 'caret_sw'\n\t\t\t};\n\t\t},\n\n\t\t// Positions panel to the north of caret rect.\n\t\t'caret_nw': ( targetRect, balloonRect ) => {\n\t\t\treturn {\n\t\t\t\ttop: targetRect.top - balloonRect.height - VERTICAL_SPACING,\n\t\t\t\tleft: targetRect.right - balloonRect.width,\n\t\t\t\tname: 'caret_nw'\n\t\t\t};\n\t\t}\n\t};\n\n\t// Return only last position if it was matched to prevent panel from jumping after first match.\n\tif ( positions.hasOwnProperty( positionName ) ) {\n\t\treturn [\n\t\t\tpositions[ positionName ]\n\t\t];\n\t}\n\n\t// As default return all positions callbacks.\n\treturn [\n\t\tpositions.caret_se,\n\t\tpositions.caret_ne,\n\t\tpositions.caret_sw,\n\t\tpositions.caret_nw\n\t];\n}\n\n// Creates a regex pattern for marker.\n//\n// @param {String} marker\n// @param {Number} minimumCharacters\n// @returns {String}\nfunction createPattern( marker, allowedPrefixes, minimumCharacters ) {\n\tallowedPrefixes = allowedPrefixes || []\n\tallowedPrefixes.push('^');\n\tallowedPrefixes.push(' ');\n\tconst prefixes = (allowedPrefixes || []).join('|');\n\n\tconst numberOfCharacters = minimumCharacters == 0 ? '*' : `{${ minimumCharacters },}`;\n\n\treturn `(${prefixes})(\\\\${ marker })([_a-zA-Z0-9À-ž]${ numberOfCharacters }?)$`;\n}\n\n// Creates a test callback for marker to be used in text watcher instance.\n//\n// @param {String} marker\n// @param {Number} minimumCharacters\n// @returns {Function}\nfunction createTestCallback( marker, allowedPrefixes, minimumCharacters ) {\n\tconst regExp = new RegExp( createPattern( marker, allowedPrefixes, minimumCharacters ) );\n\n\treturn text => regExp.test( text );\n}\n\n// Creates a text watcher matcher for marker.\n//\n// @param {String} marker\n// @returns {Function}\nfunction createTextMatcher( marker, allowedPrefixes ) {\n\tconst regExp = new RegExp( createPattern( marker, allowedPrefixes, 0 ) );\n\n\treturn text => {\n\t\tconst match = text.match( regExp );\n\n\t\tconst marker = match[ 2 ];\n\t\tconst feedText = match[ 3 ];\n\t\tconst total = match[0];\n\t\tconst prefix = match[1];\n\n\t\treturn { marker, feedText, total, prefix };\n\t};\n}\n\n// Default feed callback\nfunction createFeedCallback( feedItems ) {\n\treturn feedText => {\n\t\tconst filteredItems = feedItems\n\t\t// Make default mention feed case-insensitive.\n\t\t\t.filter( item => {\n\t\t\t\t// Item might be defined as object.\n\t\t\t\tconst itemId = typeof item == 'string' ? item : String( item.id );\n\n\t\t\t\t// The default feed is case insensitive.\n\t\t\t\treturn itemId.toLowerCase().includes( feedText.toLowerCase() );\n\t\t\t} )\n\t\t\t// Do not return more than 10 items.\n\t\t\t.slice( 0, 10 );\n\n\t\treturn Promise.resolve( filteredItems );\n\t};\n}\n\n// Checks if given key code is handled by the mention ui.\n//\n// @param {Number}\n// @returns {Boolean}\nfunction isHandledKey( keyCode ) {\n\tconst handledKeyCodes = [\n\t\tkeyCodes.arrowup,\n\t\tkeyCodes.arrowdown,\n\t\tkeyCodes.enter,\n\t\tkeyCodes.tab,\n\t\tkeyCodes.space,\n\t\tkeyCodes.esc\n\t];\n\n\treturn handledKeyCodes.includes( keyCode );\n}\n","import OPMacroTocPlugin from './plugins/op-macro-toc-plugin';\nimport OPMacroEmbeddedTable from './plugins/op-macro-embedded-table/embedded-table-plugin';\nimport OPMacroWpButtonPlugin from './plugins/op-macro-wp-button/op-macro-wp-button-plugin';\nimport OPWikiIncludePagePlugin from './plugins/op-macro-wiki-include/op-macro-wiki-include-plugin';\nimport OpUploadPlugin from './plugins/op-upload-plugin';\nimport OPChildPagesPlugin from \"./plugins/op-macro-child-pages/op-macro-child-pages-plugin\";\nimport Essentials from \"@ckeditor/ckeditor5-essentials/src/essentials\";\nimport UploadAdapter from \"@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter\";\nimport AutoFormat from \"@ckeditor/ckeditor5-autoformat/src/autoformat\";\nimport Bold from \"@ckeditor/ckeditor5-basic-styles/src/bold\";\nimport Code from \"@ckeditor/ckeditor5-basic-styles/src/code\";\nimport Strikethrough from \"@ckeditor/ckeditor5-basic-styles/src/strikethrough\"\nimport Italic from \"@ckeditor/ckeditor5-basic-styles/src/italic\";\nimport BlockQuote from \"@ckeditor/ckeditor5-block-quote/src/blockquote\";\nimport Heading from \"@ckeditor/ckeditor5-heading/src/heading\";\nimport Image from \"@ckeditor/ckeditor5-image/src/image\";\nimport ImageCaption from \"@ckeditor/ckeditor5-image/src/imagecaption\";\nimport ImageStyle from \"@ckeditor/ckeditor5-image/src/imagestyle\";\nimport ImageToolbar from \"@ckeditor/ckeditor5-image/src/imagetoolbar\";\nimport Link from \"@ckeditor/ckeditor5-link/src/link\";\nimport List from \"@ckeditor/ckeditor5-list/src/list\";\nimport Paragraph from \"@ckeditor/ckeditor5-paragraph/src/paragraph\";\nimport Typing from \"@ckeditor/ckeditor5-typing/src/typing\";\nimport OPHelpLinkPlugin from \"./plugins/op-help-link-plugin/op-help-link-plugin\";\nimport CodeBlockPlugin from \"./plugins/code-block/code-block\";\nimport OPPreviewPlugin from \"./plugins/op-preview.plugin\";\nimport Table from \"@ckeditor/ckeditor5-table/src/table\";\nimport TableToolbar from \"@ckeditor/ckeditor5-table/src/tabletoolbar\";\nimport OPMacroListPlugin from \"./plugins/op-macro-list-plugin\";\nimport OPAttachmentListenerPlugin from './plugins/op-attachment-listener-plugin';\nimport OpImageAttachmentLookup from './plugins/op-image-attachment-lookup/op-image-attachment-lookup-plugin';\nimport CommonMark from './commonmark/commonmark';\nimport OPSourceCodePlugin from './plugins/op-source-code.plugin';\nimport Mention from \"../forked/ckeditor5-mention/src/mention\";\nimport {MentionCaster} from './mentions/mentions-caster';\n\n// We divide our plugins into separate concerns here\n// in order to enable / disable each group by configuration\nexport const opMacroPlugins = [\n\tOPMacroTocPlugin,\n\tOPMacroEmbeddedTable,\n\tOPMacroWpButtonPlugin,\n\tOPWikiIncludePagePlugin,\n\tOPChildPagesPlugin,\n];\n\nexport const opImageUploadPlugins = [\n\tOpUploadPlugin,\n\tOPAttachmentListenerPlugin\n];\n\nexport const builtinPlugins = [\n\tEssentials,\n\tUploadAdapter,\n\tAutoFormat,\n\tBold,\n\tCode,\n\tItalic,\n\tStrikethrough,\n\tBlockQuote,\n\tHeading,\n\tImage,\n\tImageCaption,\n\tImageStyle,\n\tImageToolbar,\n\tOpImageAttachmentLookup,\n\tLink,\n\tList,\n\tParagraph,\n\tTyping,\n\n\t// Built-in mentions\n\tMention,\n\tMentionCaster,\n\n\tOPHelpLinkPlugin,\n\tCodeBlockPlugin,\n\tOPPreviewPlugin,\n\tOPSourceCodePlugin,\n\n\tCommonMark,\n\tTable,\n\tTableToolbar,\n\n\tOPMacroListPlugin,\n\n].concat(\n\t// OpenProject Macro plugin group\n\topMacroPlugins,\n\n\t// OpenProject image upload plugins\n\topImageUploadPlugins,\n);\n","import EmbeddedTableEditing from './embedded-table-editing';\nimport Widget from '@ckeditor/ckeditor5-widget/src/widget';\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport EmbeddedTableToolbar from './embedded-table-toolbar';\n\nexport default class OPMacroEmbeddedTable extends Plugin {\n\tstatic get requires() {\n\t\treturn [ EmbeddedTableEditing, Widget, EmbeddedTableToolbar ];\n\t}\n\n\tstatic get pluginName() {\n\t\treturn 'OPMacroEmbeddedTable';\n\t}\n\n\tstatic get buttonName() {\n\t\treturn EmbeddedTableEditing.buttonName;\n\t}\n}\n","import Widget from '@ckeditor/ckeditor5-widget/src/widget';\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport OPMacroWpButtonEditing from './op-macro-wp-button-editing';\nimport OPMacroWpButtonToolbar from './op-macro-wp-button-toolbar';\n\nexport default class OPMacroWpButtonPlugin extends Plugin {\n\tstatic get requires() {\n\t\treturn [ OPMacroWpButtonEditing, Widget, OPMacroWpButtonToolbar ];\n\t}\n\n\tstatic get pluginName() {\n\t\treturn 'OPMacroWpButton';\n\t}\n\n\tstatic get buttonName() {\n\t\treturn OPMacroWpButtonEditing.buttonName;\n\t}\n}\n","import Widget from '@ckeditor/ckeditor5-widget/src/widget';\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport OPWikiIncludePageEditing from './op-macro-wiki-include-editing';\nimport OPWikiIncludePageToolbar from './op-macro-wiki-include-toolbar';\n\nexport default class OPWikiIncludePagePlugin extends Plugin {\n\tstatic get requires() {\n\t\treturn [ OPWikiIncludePageEditing, Widget, OPWikiIncludePageToolbar ];\n\t}\n\n\tstatic get pluginName() {\n\t\treturn 'OPWikiIncludePage';\n\t}\n\n\tstatic get buttonName() {\n\t\treturn OPWikiIncludePageEditing.buttonName;\n\t}\n}\n","import Widget from '@ckeditor/ckeditor5-widget/src/widget';\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport OPChildPagesEditing from './op-macro-child-pages-editing';\nimport OPChildPagesToolbar from './op-macro-child-pages-toolbar';\n\nexport default class OPChildPagesPlugin extends Plugin {\n\tstatic get requires() {\n\t\treturn [ OPChildPagesEditing, Widget, OPChildPagesToolbar ];\n\t}\n\n\tstatic get pluginName() {\n\t\treturn 'OPChildPages';\n\t}\n\n\tstatic get buttonName() {\n\t\treturn OPChildPagesEditing.buttonName;\n\t}\n}\n","import Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport FileRepository from '@ckeditor/ckeditor5-upload/src/filerepository';\nimport OpUploadResourceAdapter from './op-upload-resource-adapter';\nimport {getOPResource} from './op-context/op-context';\nimport ImageUpload from '@ckeditor/ckeditor5-image/src/imageupload';\n\nexport default class OpUploadPlugin extends Plugin {\n\n static get requires() {\n return [FileRepository, ImageUpload];\n }\n\n static get pluginName() {\n return 'OpUploadPlugin';\n }\n\n init() {\n this.editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {\n\t\t\tconst resource = getOPResource(this.editor);\n\t\t\treturn new OpUploadResourceAdapter(loader, resource, this.editor);\n\t\t}\n }\n}\n","import Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport Selection from '@ckeditor/ckeditor5-engine/src/model/selection';\n\nexport default class OPAttachmentListenerPlugin extends Plugin {\n\tstatic get pluginName() {\n\t\treturn 'OPAttachmentListener';\n\t}\n\n\tinit() {\n\t\tlet editor = this.editor;\n\n\t\teditor.model.on('op:attachment-removed', (_, urls) => {\n\t\t\tthis.removeDeletedImage(urls)\n\t\t});\n\t}\n\n\tremoveDeletedImage(urls) {\n\t\tlet root = this.editor.model.document.getRoot();\n\n\t\tfor (const child of Array.from(root.getChildren())) {\n\t\t\tif (child.name === 'image' && urls.indexOf(child.getAttribute('src')) > -1) {\n\t\t\t\tconst selection = new Selection( child, 'on' );\n\n\t\t\t\tthis.editor.model.deleteContent(selection);\n\t\t\t}\n\t\t}\n\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module essentials/essentials\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport Clipboard from '@ckeditor/ckeditor5-clipboard/src/clipboard';\nimport Enter from '@ckeditor/ckeditor5-enter/src/enter';\nimport ShiftEnter from '@ckeditor/ckeditor5-enter/src/shiftenter';\nimport Typing from '@ckeditor/ckeditor5-typing/src/typing';\nimport Undo from '@ckeditor/ckeditor5-undo/src/undo';\n\n/**\n * A plugin including all essential editing features. It represents a set of features that enables similar functionalities\n * to a `<textarea>` element.\n *\n * It includes:\n *\n * * {@link module:clipboard/clipboard~Clipboard},\n * * {@link module:enter/enter~Enter},\n * * {@link module:enter/shiftenter~ShiftEnter},\n * * {@link module:typing/typing~Typing},\n * * {@link module:undo/undo~Undo}.\n *\n * This plugin set does not define any block-level containers (such as {@link module:paragraph/paragraph~Paragraph}).\n * If your editor is supposed to handle block content, make sure to include it.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Essentials extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ Clipboard, Enter, ShiftEnter, Typing, Undo ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Essentials';\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module basic-styles/bold\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport BoldEditing from './bold/boldediting';\nimport BoldUI from './bold/boldui';\n\n/**\n * The bold feature.\n *\n * For a detailed overview check the {@glink features/basic-styles Basic styles feature documentation}\n * and the {@glink api/basic-styles package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:basic-styles/bold/boldediting~BoldEditing bold editing feature}\n * and {@link module:basic-styles/bold/boldui~BoldUI bold UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Bold extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ BoldEditing, BoldUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Bold';\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module basic-styles/code\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport CodeEditing from './code/codeediting';\nimport CodeUI from './code/codeui';\n\nimport '../theme/code.css';\n\n/**\n * The code feature.\n *\n * For a detailed overview check the {@glink features/basic-styles Basic styles feature documentation}\n * and the {@glink api/basic-styles package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:basic-styles/code/codeediting~CodeEditing code editing feature}\n * and {@link module:basic-styles/code/codeui~CodeUI code UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Code extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ CodeEditing, CodeUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Code';\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module basic-styles/italic\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ItalicEditing from './italic/italicediting';\nimport ItalicUI from './italic/italicui';\n\n/**\n * The italic feature.\n *\n * For a detailed overview check the {@glink features/basic-styles Basic styles feature documentation}\n * and the {@glink api/basic-styles package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:basic-styles/italic/italicediting~ItalicEditing} and\n * {@link module:basic-styles/italic/italicui~ItalicUI} plugins.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Italic extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ItalicEditing, ItalicUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Italic';\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module basic-styles/strikethrough\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport StrikethroughEditing from './strikethrough/strikethroughediting';\nimport StrikethroughUI from './strikethrough/strikethroughui';\n\n/**\n * The strikethrough feature.\n *\n * For a detailed overview check the {@glink features/basic-styles Basic styles feature documentation}\n * and the {@glink api/basic-styles package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:basic-styles/strikethrough/strikethroughediting~StrikethroughEditing} and\n * {@link module:basic-styles/strikethrough/strikethroughui~StrikethroughUI} plugins.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Strikethrough extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ StrikethroughEditing, StrikethroughUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Strikethrough';\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module block-quote/blockquote\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport BlockQuoteEditing from './blockquoteediting';\nimport BlockQuoteUI from './blockquoteui';\n\n/**\n * The block quote plugin.\n *\n * For more information about this feature check the {@glink api/block-quote package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:block-quote/blockquoteediting~BlockQuoteEditing block quote editing feature}\n * and {@link module:block-quote/blockquoteui~BlockQuoteUI block quote UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class BlockQuote extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ BlockQuoteEditing, BlockQuoteUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'BlockQuote';\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module heading/heading\n */\n\nimport HeadingEditing from './headingediting';\nimport HeadingUI from './headingui';\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport '../theme/heading.css';\n\n/**\n * The headings feature.\n *\n * For a detailed overview, check the {@glink features/headings Headings feature documentation}\n * and the {@glink api/heading package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:heading/headingediting~HeadingEditing heading editing feature}\n * and {@link module:heading/headingui~HeadingUI heading UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Heading extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ HeadingEditing, HeadingUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Heading';\n\t}\n}\n\n/**\n * The configuration of the heading feature. Introduced by the {@link module:heading/headingediting~HeadingEditing} feature.\n *\n * Read more in {@link module:heading/heading~HeadingConfig}.\n *\n * @member {module:heading/heading~HeadingConfig} module:core/editor/editorconfig~EditorConfig#heading\n */\n\n/**\n * The configuration of the heading feature.\n * The option is used by the {@link module:heading/headingediting~HeadingEditing} feature.\n *\n *\t\tClassicEditor\n *\t\t\t.create( {\n * \t\t\t\theading: ... // Heading feature config.\n *\t\t\t} )\n *\t\t\t.then( ... )\n *\t\t\t.catch( ... );\n *\n * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.\n *\n * @interface HeadingConfig\n */\n\n/**\n * The available heading options.\n *\n * The default value is:\n *\n *\t\tconst headingConfig = {\n *\t\t\toptions: [\n *\t\t\t\t{ model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },\n *\t\t\t\t{ model: 'heading1', view: 'h2', title: 'Heading 1', class: 'ck-heading_heading1' },\n *\t\t\t\t{ model: 'heading2', view: 'h3', title: 'Heading 2', class: 'ck-heading_heading2' },\n *\t\t\t\t{ model: 'heading3', view: 'h4', title: 'Heading 3', class: 'ck-heading_heading3' }\n *\t\t\t]\n *\t\t};\n *\n * It defines 3 levels of headings. In the editor model they will use `heading1`, `heading2`, and `heading3` elements.\n * Their respective view elements (so the elements output by the editor) will be: `h2`, `h3`, and `h4`. This means that\n * if you choose \"Heading 1\" in the headings dropdown the editor will turn the current block to `<heading1>` in the model\n * which will result in rendering (and outputting to data) the `<h2>` element.\n *\n * The `title` and `class` properties will be used by the `headings` dropdown to render available options.\n * Usually, the first option in the headings dropdown is the \"Paragraph\" option, hence it's also defined on the list.\n * However, you don't need to define its view representation because it's handled by\n * the {@link module:paragraph/paragraph~Paragraph} feature (which is required by\n * the {@link module:heading/headingediting~HeadingEditing} feature).\n *\n * You can **read more** about configuring heading levels and **see more examples** in\n * the {@glink features/headings Headings} guide.\n *\n * Note: In the model you should always start from `heading1`, regardless of how the headings are represented in the view.\n * That's assumption is used by features like {@link module:autoformat/autoformat~Autoformat} to know which element\n * they should use when applying the first level heading.\n *\n * The defined headings are also available as values passed to the `'heading'` command under their model names.\n * For example, the below code will apply `<heading1>` to the current selection:\n *\n *\t\teditor.execute( 'heading', { value: 'heading1' } );\n *\n * @member {Array.<module:heading/heading~HeadingOption>} module:heading/heading~HeadingConfig#options\n */\n\n/**\n * Heading option descriptor.\n *\n * @typedef {Object} module:heading/heading~HeadingOption\n * @property {String} model Name of the model element to convert.\n * @property {module:engine/view/elementdefinition~ElementDefinition} view Definition of a view element to convert from/to.\n * @property {String} title The user-readable title of the option.\n * @property {String} class The class which will be added to the dropdown item representing this option.\n * @property {String} [icon] Icon used by {@link module:heading/headingbuttonsui~HeadingButtonsUI}. It can be omitted when using\n * the default configuration.\n * @extends module:engine/conversion/conversion~ConverterDefinition\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/image\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ImageEditing from '../src/image/imageediting';\nimport Widget from '@ckeditor/ckeditor5-widget/src/widget';\nimport ImageTextAlternative from './imagetextalternative';\n\nimport '../theme/image.css';\n\n/**\n * The image plugin.\n *\n * For a detailed overview, check the {@glink features/image image feature} documentation.\n *\n * This is a \"glue\" plugin which loads the following plugins:\n *\n * * {@link module:image/image/imageediting~ImageEditing},\n * * {@link module:image/imagetextalternative~ImageTextAlternative}.\n *\n * Usually, it is used in conjuction with other plugins from this package. See the {@glink api/image package page}\n * for more information.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Image extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ImageEditing, Widget, ImageTextAlternative ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Image';\n\t}\n}\n\n/**\n * The configuration of the image features. Used by the image features in the `@ckeditor/ckeditor5-image` package.\n *\n * Read more in {@link module:image/image~ImageConfig}.\n *\n * @member {module:image/image~ImageConfig} module:core/editor/editorconfig~EditorConfig#image\n */\n\n/**\n * The configuration of the image features. Used by the image features in the `@ckeditor/ckeditor5-image` package.\n *\n *\t\tClassicEditor\n *\t\t\t.create( editorElement, {\n * \t\t\t\timage: ... // Image feature options.\n *\t\t\t} )\n *\t\t\t.then( ... )\n *\t\t\t.catch( ... );\n *\n * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.\n *\n * @interface ImageConfig\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imagecaption\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ImageCaptionEditing from './imagecaption/imagecaptionediting';\n\nimport '../theme/imagecaption.css';\n\n/**\n * The image caption plugin.\n *\n * For a detailed overview, check the {@glink features/image#image-captions image caption} documentation.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageCaption extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ImageCaptionEditing ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageCaption';\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imagestyle\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport ImageStyleEditing from './imagestyle/imagestyleediting';\nimport ImageStyleUI from './imagestyle/imagestyleui';\n\n/**\n * The image style plugin.\n *\n * For a detailed overview, check the {@glink features/image#image-styles image styles} documentation.\n *\n * This is a \"glue\" plugin which loads the {@link module:image/imagestyle/imagestyleediting~ImageStyleEditing}\n * and {@link module:image/imagestyle/imagestyleui~ImageStyleUI} plugins.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageStyle extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ImageStyleEditing, ImageStyleUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageStyle';\n\t}\n}\n\n/**\n * Available image styles.\n *\n * The default value is:\n *\n *\t\tconst imageConfig = {\n *\t\t\tstyles: [ 'full', 'side' ]\n *\t\t};\n *\n * which configures two default styles:\n *\n * * the \"full\" style which does not apply any class, e.g. for images styled to span 100% width of the content,\n * * the \"side\" style with the `.image-style-side` CSS class.\n *\n * See {@link module:image/imagestyle/utils~defaultStyles} to learn more about default\n * styles provided by the image feature.\n *\n * The {@link module:image/imagestyle/utils~defaultStyles default styles} can be customized,\n * e.g. to change the icon, title or CSS class of the style. The feature also provides several\n * {@link module:image/imagestyle/utils~defaultIcons default icons} to choose from.\n *\n *\t\timport customIcon from 'custom-icon.svg';\n *\n *\t\t// ...\n *\n *\t\tconst imageConfig = {\n *\t\t\tstyles: [\n *\t\t\t\t// This will only customize the icon of the \"full\" style.\n *\t\t\t\t// Note: 'right' is one of default icons provided by the feature.\n *\t\t\t\t{ name: 'full', icon: 'right' },\n *\n *\t\t\t\t// This will customize the icon, title and CSS class of the default \"side\" style.\n *\t\t\t\t{ name: 'side', icon: customIcon, title: 'My side style', className: 'custom-side-image' }\n *\t\t\t]\n *\t\t};\n *\n * If none of the default styles is good enough, it is possible to define independent custom styles, too:\n *\n *\t\timport fullSizeIcon from '@ckeditor/ckeditor5-core/theme/icons/object-center.svg';\n *\t\timport sideIcon from '@ckeditor/ckeditor5-core/theme/icons/object-right.svg';\n *\n *\t\t// ...\n *\n *\t\tconst imageConfig = {\n *\t\t\tstyles: [\n *\t\t\t\t// A completely custom full size style with no class, used as a default.\n *\t\t\t\t{ name: 'fullSize', title: 'Full size', icon: fullSizeIcon, isDefault: true },\n *\n *\t\t\t\t{ name: 'side', title: 'To the side', icon: sideIcon, className: 'side-image' }\n *\t\t\t]\n *\t\t};\n *\n * Note: Setting `title` to one of {@link module:image/imagestyle/imagestyleui~ImageStyleUI#localizedDefaultStylesTitles}\n * will automatically translate it to the language of the editor.\n *\n * Read more about styling images in the {@glink features/image#image-styles Image styles guide}.\n *\n * The feature creates commands based on defined styles, so you can change the style of a selected image by executing\n * the following command:\n *\n *\t\teditor.execute( 'imageStyle' { value: 'side' } );\n *\n * The feature also creates buttons that execute the commands. So, assuming that you use the\n * default image styles setting, you can {@link module:image/image~ImageConfig#toolbar configure the image toolbar}\n * (or any other toolbar) to contain these options:\n *\n *\t\tconst imageConfig = {\n *\t\t\ttoolbar: [ 'imageStyle:full', 'imageStyle:side' ]\n *\t\t};\n *\n * @member {Array.<module:image/imagestyle/imagestyleediting~ImageStyleFormat>} module:image/image~ImageConfig#styles\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module image/imagetoolbar\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport { getSelectedImageWidget } from './image/utils';\nimport WidgetToolbarRepository from '@ckeditor/ckeditor5-widget/src/widgettoolbarrepository';\n\n/**\n * The image toolbar plugin. It creates and manages the image toolbar (the toolbar displayed when an image is selected).\n *\n * For a detailed overview, check the {@glink features/image#image-contextual-toolbar image contextual toolbar} documentation.\n *\n * Instances of toolbar components (e.g. buttons) are created using the editor's\n * {@link module:ui/componentfactory~ComponentFactory component factory}\n * based on the {@link module:image/image~ImageConfig#toolbar `image.toolbar` configuration option}.\n *\n * The toolbar uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ImageToolbar extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ WidgetToolbarRepository ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ImageToolbar';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tafterInit() {\n\t\tconst editor = this.editor;\n\t\tconst widgetToolbarRepository = editor.plugins.get( WidgetToolbarRepository );\n\n\t\twidgetToolbarRepository.register( 'image', {\n\t\t\titems: editor.config.get( 'image.toolbar' ) || [],\n\t\t\tgetRelatedElement: getSelectedImageWidget,\n\t\t} );\n\t}\n}\n\n/**\n * Items to be placed in the image toolbar.\n * This option is used by the {@link module:image/imagetoolbar~ImageToolbar} feature.\n *\n * Assuming that you use the following features:\n *\n * * {@link module:image/imagestyle~ImageStyle} (with a default configuration),\n * * {@link module:image/imagetextalternative~ImageTextAlternative},\n *\n * three toolbar items will be available in {@link module:ui/componentfactory~ComponentFactory}:\n * `'imageStyle:full'`, `'imageStyle:side'`, and `'imageTextAlternative'` so you can configure the toolbar like this:\n *\n *\t\tconst imageConfig = {\n *\t\t\ttoolbar: [ 'imageStyle:full', 'imageStyle:side', '|', 'imageTextAlternative' ]\n *\t\t};\n *\n * Of course, the same buttons can also be used in the\n * {@link module:core/editor/editorconfig~EditorConfig#toolbar main editor toolbar}.\n *\n * Read more about configuring toolbar in {@link module:core/editor/editorconfig~EditorConfig#toolbar}.\n *\n * @member {Array.<String>} module:image/image~ImageConfig#toolbar\n */\n","import Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport {getOPResource} from '../op-context/op-context';\nimport {originalSrcAttribute} from '../../commonmark/commonmarkdataprocessor';\n\n\nexport function replaceImageAttachmentsByName(resource) {\n\treturn dispatcher => {\n\t\tdispatcher.on('attribute:src:image', converter, { priority: 'highest' } );\n\t};\n\n\tfunction converter( evt, data, conversionApi ) {\n\n\t\t// We do not consume the attribute since we want the regular attribute\n\t\t// converter to run as well.\n\t\tlet src = data.attributeNewValue;\n\n\t\t// If the resource is not attachable or src has been nulled, do nothing\n\t\tif (!(src && resource.lookupDownloadLocationByName)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst match = resource.lookupDownloadLocationByName(src);\n\t\tdata.attributeNewValue = match || src;\n\t}\n}\n\nexport function replaceNamedAttachmentWithUrl(resource) {\n\treturn dispatcher => {\n\t\tdispatcher.on('attribute:src:image', converter, { priority: 'highest' } );\n\t};\n\n\tfunction converter( evt, data, conversionApi ) {\n\n\t\t// We do not consume the attribute since we want the regular attribute\n\t\t// converter to run as well.\n\t\tlet src = data.attributeNewValue;\n\n\t\t// If the resource is not attachable or src has been nulled, do nothing\n\t\tif (!(src && resource.lookupDownloadLocationByName)) {\n\t\t\treturn;\n\t\t}\n\n\n\t\tconst match = resource.lookupDownloadLocationByName(src);\n\t\tdata.attributeNewValue = match || src;\n\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst figure = conversionApi.mapper.toViewElement( data.item );\n\t\tconst img = figure.getChild( 0 );\n\n\t\tif (match) {\n\t\t\tviewWriter.setAttribute(originalSrcAttribute, src, img );\n\t\t}\n\t}\n}\n\n\nexport default class OpImageAttachmentLookup extends Plugin {\n\tstatic get pluginName() {\n\t\treturn 'OpImageAttachmentLookup';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst conversion = editor.conversion;\n\t\tconst resource = getOPResource(editor);\n\n\t\tconversion\n\t\t\t.for('editingDowncast')\n\t\t\t.add(replaceImageAttachmentsByName(resource));\n\n\t\t// Temporarily replace the src attribute with data-src attribute to avoid loading\n\t\tconversion\n\t\t\t.for('dataDowncast')\n\t\t\t.add(replaceNamedAttachmentWithUrl(resource));\n\t}\n\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module link/link\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport LinkEditing from './linkediting';\nimport LinkUI from './linkui';\n\n/**\n * The link plugin.\n *\n * This is a \"glue\" plugin which loads the {@link module:link/linkediting~LinkEditing link editing feature}\n * and {@link module:link/linkui~LinkUI link UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Link extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ LinkEditing, LinkUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Link';\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module list/list\n */\n\nimport ListEditing from './listediting';\nimport ListUI from './listui';\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\n/**\n * The list feature.\n *\n * This is a \"glue\" plugin which loads the {@link module:list/listediting~ListEditing list editing feature}\n * and {@link module:list/listui~ListUI list UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class List extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ListEditing, ListUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'List';\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module mention/mention\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport MentionEditing, { _toMentionAttribute } from './mentionediting';\nimport MentionUI from './mentionui';\n\nimport '../theme/mention.css';\n\n/**\n * The mention plugin.\n *\n * For a detailed overview, check the {@glink features/mentions Mention feature documentation}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Mention extends Plugin {\n\t/**\n\t * Creates a mention attribute value from the provided view element and optional data.\n\t *\n\t *\t\teditor.plugins.get( 'Mention' ).toMentionAttribute( viewElement, { userId: '1234' } );\n\t *\n\t *\t\t// for a viewElement: <span data-mention=\"@joe\">@John Doe</span>\n\t *\t\t// it will return:\n\t *\t\t// { id: '@joe', userId: '1234', _uid: '7a7bc7...', _text: '@John Doe' }\n\t *\n\t * @param {module:engine/view/element~Element} viewElement\n\t * @param {String|Object} [data] Additional data to be stored in the mention attribute.\n\t * @returns {module:mention/mention~MentionAttribute}\n\t */\n\ttoMentionAttribute( viewElement, data ) {\n\t\treturn _toMentionAttribute( viewElement, data );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Mention';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ MentionEditing, MentionUI ];\n\t}\n}\n\n/**\n * The configuration of the {@link module:mention/mention~Mention} feature.\n *\n * Read more in {@link module:mention/mention~MentionConfig}.\n *\n * @member {module:mention/mention~MentionConfig} module:core/editor/editorconfig~EditorConfig#mention\n * @type {Array.<module/mention~MentionFeed>}\n */\n\n/**\n * The configuration of the mention feature.\n *\n * Read more about {@glink features/mentions#configuration configuring the mention feature}.\n *\n *\t\tClassicEditor\n *\t\t\t.create( editorElement, {\n *\t\t\t\tmention: ... // Media embed feature options.\n *\t\t\t} )\n *\t\t\t.then( ... )\n *\t\t\t.catch( ... );\n *\n * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.\n *\n * @interface MentionConfig\n */\n\n/**\n * The list of mention feeds supported by the editor.\n *\n *\t\tClassicEditor\n *\t\t\t.create( editorElement, {\n *\t\t\t\tplugins: [ Mention, ... ],\n *\t\t\t\tmention: {\n *\t\t\t\t\tfeeds: [\n *\t\t\t\t\t\t{\n *\t\t\t\t\t\t\tmarker: '@',\n *\t\t\t\t\t\t\tfeed: [ '@Barney', '@Lily', '@Marshall', '@Robin', '@Ted' ]\n *\t\t\t\t\t\t},\n *\t\t\t\t\t\t...\n * \t\t\t\t\t]\n *\t\t\t\t}\n *\t\t\t} )\n *\t\t\t.then( ... )\n *\t\t\t.catch( ... );\n *\n * You can provide as many mention feeds but they must use different `marker`s.\n * For example, you can use `'@'` to autocomplete people and `'#'` to autocomplete tags.\n *\n * @member {Array.<module:mention/mention~MentionFeed>} module:mention/mention~MentionConfig#feeds\n */\n\n/**\n * The mention feed descriptor. Used in {@link module:mention/mention~MentionConfig `config.mention`}.\n *\n * See {@link module:mention/mention~MentionConfig} to learn more.\n *\n *\t\t// Static configuration.\n *\t\tconst mentionFeedPeople = {\n *\t\t\tmarker: '@',\n *\t\t\tfeed: [ '@Alice', '@Bob', ... ],\n *\t\t\tminimumCharacters: 2\n *\t\t};\n *\n *\t\t// Simple, synchronous callback.\n *\t\tconst mentionFeedTags = {\n *\t\t\tmarker: '#',\n *\t\t\tfeed: searchString => {\n *\t\t\t\treturn tags\n *\t\t\t\t\t// Filter the tags list.\n *\t\t\t\t\t.filter( tag => {\n *\t\t\t\t\t\treturn tag.toLowerCase().includes( queryText.toLowerCase() );\n *\t\t\t\t\t} )\n *\t\t\t\t\t// Return 10 items max - needed for generic queries when the list may contain hundreds of elements.\n *\t\t\t\t\t.slice( 0, 10 );\n *\t\t\t}\n * \t\t};\n *\n *\t\tconst tags = [ 'wysiwyg', 'rte', 'rich-text-edior', 'collaboration', 'real-time', ... ];\n *\n *\t\t// Asynchronous callback.\n *\t\tconst mentionFeedPlaceholders = {\n *\t\t\tmarker: '$',\n *\t\t\tfeed: searchString => {\n *\t\t\t\treturn getMatchingPlaceholders( searchString );\n *\t\t\t}\n * \t\t};\n *\n *\t\tfunction getMatchingPlaceholders( searchString ) {\n *\t\t\treturn new Promise( resolve => {\n *\t\t\t\tdoSomeXHRQuery( result => {\n *\t\t\t\t\t// console.log( result );\n *\t\t\t\t\t// -> [ '$name', '$surname', '$postal', ... ]\n *\n *\t\t\t\t\tresolve( result );\n * \t\t\t\t} );\n *\t\t\t} );\n *\t\t}\n *\n * @typedef {Object} module:mention/mention~MentionFeed\n * @property {String} [marker] The character which triggers autocompletion for mention. It must be a single character.\n * @property {Array.<module:mention/mention~MentionFeedItem>|Function} feed The autocomplete items. Provide an array for\n * a static configuration (the mention feature will show matching items automatically) or a function which returns an array of\n * matching items (directly, or via a promise).\n * @property {Number} [minimumCharacters=0] Specifies after how many characters the autocomplete panel should be shown.\n * @property {Function} [itemRenderer] Function that renders a {@link module:mention/mention~MentionFeedItem}\n * to the autocomplete panel.\n */\n\n/**\n * The mention feed item. It may be defined as a string or a plain object.\n *\n * When defining a feed item as a plain object, the `id` property is obligatory. The additional properties\n * can be used when customizing the mention feature bahavior\n * (see {@glink features/mentions#customizing-the-autocomplete-list \"Customizing the autocomplete list\"}\n * and {@glink features/mentions#customizing-the-output \"Customizing the output\"} sections).\n *\n *\t\tClassicEditor\n *\t\t\t.create( editorElement, {\n *\t\t\t\tplugins: [ Mention, ... ],\n *\t\t\t\tmention: {\n *\t\t\t\t\tfeeds: [\n *\t\t\t\t\t\t// Feed items as objects.\n *\t\t\t\t\t\t{\n *\t\t\t\t\t\t\tmarker: '@',\n *\t\t\t\t\t\t\tfeed: [\n *\t\t\t\t\t\t\t\t{\n *\t\t\t\t\t\t\t\t\tid: '@Barney',\n *\t\t\t\t\t\t\t\t\tfullName: 'Barney Bloom'\n *\t\t\t\t\t\t\t\t},\n *\t\t\t\t\t\t\t\t{\n *\t\t\t\t\t\t\t\t\tid: '@Lily',\n *\t\t\t\t\t\t\t\t\tfullName: 'Lily Smith'\n *\t\t\t\t\t\t\t\t},\n *\t\t\t\t\t\t\t\t{\n *\t\t\t\t\t\t\t\t\tid: '@Marshall',\n *\t\t\t\t\t\t\t\t\tfullName: 'Marshall McDonald'\n *\t\t\t\t\t\t\t\t},\n *\t\t\t\t\t\t\t\t{\n *\t\t\t\t\t\t\t\t\tid: '@Robin',\n *\t\t\t\t\t\t\t\t\tfullName: 'Robin Hood'\n *\t\t\t\t\t\t\t\t},\n *\t\t\t\t\t\t\t\t{\n *\t\t\t\t\t\t\t\t\tid: '@Ted',\n *\t\t\t\t\t\t\t\t\tfullName: 'Ted Cruze'\n *\t\t\t\t\t\t\t\t},\n *\t\t\t\t\t\t\t\t// ...\n *\t\t\t\t\t\t\t]\n *\t\t\t\t\t\t},\n *\n *\t\t\t\t\t\t// Feed items as plain strings.\n *\t\t\t\t\t\t{\n *\t\t\t\t\t\t\tmarker: '#',\n *\t\t\t\t\t\t\tfeed: [ 'wysiwyg', 'rte', 'rich-text-edior', 'collaboration', 'real-time', ... ]\n *\t\t\t\t\t\t},\n * \t\t\t\t\t]\n *\t\t\t\t}\n *\t\t\t} )\n *\t\t\t.then( ... )\n *\t\t\t.catch( ... );\n *\n * @typedef {Object|String} module:mention/mention~MentionFeedItem\n * @property {String} id Unique id of the mention. It must start with the marker character.\n * @property {String} [text] Text inserted into the editor when creating a mention.\n */\n\n/**\n * Represents mention in the model.\n *\n * See {@link module:mention/mention~Mention#toMentionAttribute `Mention#toMentionAttribute()`}.\n *\n * @interface module:mention/mention~MentionAttribute\n * @property {String} id Id of a mention – identifies the mention item in mention feed.\n * @property {String} _uid Internal mention view item id. Should be passed as an `option.id` when using\n * {@link module:engine/view/downcastwriter~DowncastWriter#createAttributeElement writer.createAttributeElement()}.\n * @property {String} _text Helper property that holds text of inserted mention. Used for detecting broken mention in the editing area.\n */\n","export function MentionCaster( editor ) {\n // The upcast converter will convert <a class=\"mention\" href=\"\" data-user-id=\"\">\n // elements to the model 'mention' attribute.\n editor.conversion.for( 'upcast' ).elementToAttribute( {\n view: {\n name: 'a',\n key: 'data-mention',\n classes: 'mention',\n attributes: {\n href: true,\n 'data-user-id': true\n }\n },\n model: {\n key: 'mention',\n value: viewItem => {\n // The mention feature expects that the mention attribute value\n // in the model is a plain object with set of additional attributes.\n // In order to create proper object use `toMentionAttribute` helper method:\n const mentionAttribute = editor.plugins.get( 'Mention' ).toMentionAttribute( viewItem, {\n // Add any other properties that you need.\n link: viewItem.getAttribute( 'href' ),\n userId: viewItem.getAttribute( 'data-user-id' )\n } );\n\n return mentionAttribute;\n }\n },\n converterPriority: 'high'\n\t} );\n\n\t// editor.conversion\n\t// \t.for( 'editingDowncast' )\n\t// \t.attributeToElement( {\n\t// \t\tmodel: 'mention',\n\t// \t\tconverterPriority: 'high',\n\t// \t\tview: ( modelAttributeValue, viewWriter ) => {\n\t// \t\t\t// Do not convert empty attributes (lack of value means no mention).\n\t// \t\t\tif ( !modelAttributeValue ) {\n\t// \t\t\t\treturn;\n\t// \t\t\t}\n\n\t// \t\t\treturn viewWriter.createAttributeElement( 'a', {\n\t// \t\t\t\tclass: 'mention',\n\t// \t\t\t\t'data-type': modelAttributeValue.type,\n\t// \t\t\t\t'data-mention': modelAttributeValue.id,\n\t// \t\t\t\t'href': modelAttributeValue.link\n\t// \t\t\t} );\n\t// \t\t},\n\t// \t} );\n\n\teditor.conversion\n\t\t.for('downcast')\n\t\t.attributeToElement({\n\t\t\tmodel: 'mention',\n\t\t\tconverterPriority: 'high',\n\t\t\tview: (modelAttributeValue, writer) => {\n\t\t\t\t// Do not convert empty attributes (lack of value means no mention).\n\t\t\t\tif ( !modelAttributeValue ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst element = writer.createAttributeElement(\n\t\t\t\t\t'span',\n\t\t\t\t\t{\n\t\t\t\t\t\t'class': 'mention',\n\t\t\t\t\t\t'data-type': modelAttributeValue.type || '',\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\treturn element;\n\t\t\t}\n\t\t});\n}\n","// This SVG file import will be handled by webpack's raw-text loader.\n// This means that imageIcon will hold the source SVG.\nimport imageIcon from './../../icons/help.svg';\n\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nexport default class OPHelpLinkPlugin extends Plugin {\n\n\tstatic get pluginName() {\n\t\treturn 'OPHelpLinkPlugin';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst helpURL = editor.config.get('openProject.helpURL');\n\n\t\teditor.ui.componentFactory.add( 'openProjectShowFormattingHelp', locale => {\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\tlabel: window.I18n.t('js.inplace.link_formatting_help'),\n\t\t\t\ticon: imageIcon,\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\t// Callback executed once the image is clicked.\n\t\t\tview.on( 'execute', () => {\n\t\t\t\twindow.open(helpURL, '_blank');\n\t\t\t} );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n}\n","\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport CodeBlockEditing from './code-block-editing';\nimport CodeBlockToolbar from './code-block-toolbar';\n\nexport default class CodeBlockPlugin extends Plugin {\n\tstatic get pluginName() {\n\t\treturn 'CodeBlock';\n\t}\n\n\tstatic get requires() {\n\t\treturn [ CodeBlockEditing, CodeBlockToolbar ];\n\t}\n}\n","// This SVG file import will be handled by webpack's raw-text loader.\n// This means that imageIcon will hold the source SVG.\nimport imageIcon from '../icons/preview.svg';\n\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport {getOPPath, getOPPreviewContext, getOPService} from './op-context/op-context';\nimport {enableItems, disableItems} from '../helpers/button-disabler';\n\nexport default class OPPreviewPlugin extends Plugin {\n\n\tstatic get pluginName() {\n\t\treturn 'OPPreview';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tlet previewing = false;\n\t\tlet unregisterPreview = null;\n\n\t\teditor.ui.componentFactory.add( 'preview', locale => {\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\tlabel: this.label,\n\t\t\t\ticon: imageIcon,\n\t\t\t\ttooltip: true,\n\t\t\t} );\n\n\n\t\t\tlet showPreview = function(preview) {\n\t\t\t\tlet $editable = jQuery(editor.ui.element);\n\t\t\t\tlet $mainEditor = $editable.find('.ck-editor__main');\n\t\t\t\tlet $reference;\n\n\t\t\t\tif ($mainEditor.length) {\n\t\t\t\t\t$reference = $mainEditor;\n\t\t\t\t} else {\n\t\t\t\t\t$reference = $editable;\n\t\t\t\t}\n\n\t\t\t\tlet $previewWrapper = jQuery('<div class=\"ck-editor__preview\"></div>');\n\t\t\t\t$reference.siblings('.ck-editor__preview').remove();\n\n\t\t\t\tconst previewService = getOPService(editor, 'ckEditorPreview');\n\t\t\t\tunregisterPreview = previewService.render($previewWrapper[0], preview);\n\n\t\t\t\t$reference.hide();\n\t\t\t\t$reference.after($previewWrapper);\n\n\t\t\t\tdisableItems(editor, view);\n\t\t\t};\n\n\t\t\tlet getAndShowPreview = function() {\n\t\t\t\tlet link = getOPPreviewContext(editor);\n\t\t\t\tlet url = getOPPath(editor).api.v3.previewMarkup(link);\n\n\t\t\t\tjQuery\n\t\t\t\t\t.ajax({\n\t\t\t\t\t\tdata: editor.getData(),\n\t\t\t\t\t\turl: url,\n\t\t\t\t\t\tresponse_type: 'text',\n\t\t\t\t\t\tcontentType: 'text/plain; charset=UTF-8',\n\t\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\t}).done(showPreview);\n\t\t\t};\n\n\t\t\tlet disablePreviewing = function() {\n\t\t\t\tlet $editable = jQuery(editor.ui.element);\n\t\t\t\tlet $mainEditor = $editable.find('.ck-editor__main');\n\n\t\t\t\tunregisterPreview();\n\t\t\t\t$mainEditor.siblings('.ck-editor__preview').remove();\n\t\t\t\t$mainEditor.show();\n\n\t\t\t\tenableItems(editor);\n\t\t\t};\n\n\n\t\t\t// Callback executed once the image is clicked.\n\t\t\tview.on('execute', () => {\n\t\t\t\tif (previewing) {\n\t\t\t\t\tpreviewing = false;\n\n\t\t\t\t\tdisablePreviewing();\n\t\t\t\t} else {\n\t\t\t\t\tpreviewing = true;\n\n\t\t\t\t\tgetAndShowPreview();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn view;\n\t\t} );\n\t}\n\n\tget label() {\n\t\treturn window.I18n.t('js.editor.preview');\n\t}\n}\n","// This SVG file import will be handled by webpack's raw-text loader.\n// This means that imageIcon will hold the source SVG.\nimport sourceIcon from '../icons/source.svg';\nimport wysiwygIcon from '../icons/wysiwyg.svg';\n\nimport ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport {getOPPath, getOPPreviewContext, getOPService} from './op-context/op-context';\nimport {enableItems, disableItems} from '../helpers/button-disabler';\n\nexport default class OPSourceCodePlugin extends Plugin {\n\n\tstatic get pluginName() {\n\t\treturn 'OPSourceCode';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tlet inSourceMode = false;\n\t\tlet labels = {\n\t\t\tsource: window.I18n.t('js.editor.mode.manual'),\n\t\t\twysiwyg: window.I18n.t('js.editor.mode.wysiwyg'),\n\t\t}\n\n\n\t\teditor.ui.componentFactory.add( 'opShowSource', locale => {\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\tlabel: labels.source,\n\t\t\t\tclass: '',\n\t\t\t\ticon: sourceIcon,\n\t\t\t\ttooltip: true,\n\t\t\t} );\n\n\n\t\t\tlet showSource = function(preview) {\n\t\t\t\tlet $editable = jQuery(editor.ui.element);\n\t\t\t\tlet $mainEditor = $editable.find('.ck-editor__main');\n\t\t\t\tlet $reference;\n\n\t\t\t\tif ($mainEditor.length) {\n\t\t\t\t\t$reference = $mainEditor;\n\t\t\t\t} else {\n\t\t\t\t\t$reference = $editable;\n\t\t\t\t}\n\n\t\t\t\tlet $sourceWrapper = jQuery('<div class=\"ck-editor__source\"></div>');\n\t\t\t\t$reference.siblings('.ck-editor__source').remove();\n\n\t\t\t\t$reference.hide();\n\t\t\t\t$reference.after($sourceWrapper);\n\n\t\t\t\tdisableItems(editor, view);\n\n\t\t\t\teditor.fire('op:source-code-enabled');\n\n\t\t\t\tview.set( {\n\t\t\t\t\tlabel: labels.wysiwyg,\n\t\t\t\t\tclass: '-source-enabled',\n\t\t\t\t\ticon: wysiwygIcon,\n\t\t\t\t\ttooltip: true,\n\t\t\t\t} );\n\n\t\t\t};\n\n\t\t\tlet hideSource = function() {\n\t\t\t\tlet $editable = jQuery(editor.ui.element);\n\t\t\t\tlet $mainEditor = $editable.find('.ck-editor__main');\n\n\t\t\t\teditor.fire('op:source-code-disabled');\n\n\t\t\t\t$mainEditor.siblings('.ck-editor__source').remove();\n\t\t\t\t$mainEditor.show();\n\n\t\t\t\tenableItems(editor);\n\n\t\t\t\tview.set( {\n\t\t\t\t\tlabel: labels.source,\n\t\t\t\t\tclass: '',\n\t\t\t\t\ticon: sourceIcon,\n\t\t\t\t\ttooltip: true,\n\t\t\t\t} );\n\t\t\t};\n\n\n\t\t\t// Callback executed once the image is clicked.\n\t\t\tview.on('execute', () => {\n\t\t\t\tif (inSourceMode) {\n\t\t\t\t\tinSourceMode = false;\n\t\t\t\t\thideSource();\n\t\t\t\t} else {\n\t\t\t\t\tinSourceMode = true;\n\t\t\t\t\tshowSource();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn view;\n\t\t} );\n\t}\n\n}\n","/**\n * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\nimport CommonMarkDataProcessor from './commonmarkdataprocessor';\n\n// Simple plugin which loads the data processor.\n// eslint-disable-next-line no-unused-vars\nexport default function CommonMarkPlugin( editor ) {\n\teditor.data.processor = new CommonMarkDataProcessor();\n}\n\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/table\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport TableEditing from './tableediting';\nimport TableUI from './tableui';\nimport Widget from '@ckeditor/ckeditor5-widget/src/widget';\n\nimport '../theme/table.css';\n\n/**\n * The table plugin.\n *\n * For a detailed overview, check the {@glink features/table Table feature documentation}.\n *\n * This is a \"glue\" plugin which loads the {@link module:table/tableediting~TableEditing table editing feature}\n * and {@link module:table/tableui~TableUI table UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Table extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ TableEditing, TableUI, Widget ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Table';\n\t}\n}\n\n/**\n * The configuration of the table features. Used by the table features in the `@ckeditor/ckeditor5-table` package.\n *\n *\t\tClassicEditor\n *\t\t\t.create( editorElement, {\n * \t\t\t\ttable: ... // Table feature options.\n *\t\t\t} )\n *\t\t\t.then( ... )\n *\t\t\t.catch( ... );\n *\n * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.\n *\n * @interface TableConfig\n */\n","/**\n * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md.\n */\n\n/**\n * @module table/tabletoolbar\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport { getSelectedTableWidget, getTableWidgetAncestor } from './utils';\nimport WidgetToolbarRepository from '@ckeditor/ckeditor5-widget/src/widgettoolbarrepository';\n\n/**\n * The table toolbar class. It creates toolbars for the table feature and its content (for now only for a table cell content).\n *\n * Table toolbar shows up when a table widget is selected. Its components (e.g. buttons) are created based on the\n * {@link module:table/table~TableConfig#toolbar `table.tableToolbar` configuration option}.\n *\n * Table content toolbar shows up when the selection is inside the content of a table. It creates its component based on the\n * {@link module:table/table~TableConfig#contentToolbar `table.contentToolbar` configuration option}.\n *\n * Note that the old {@link module:table/table~TableConfig#toolbar `table.toolbar` configuration option} is deprecated\n * and will be removed in the next major release.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableToolbar extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ WidgetToolbarRepository ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TableToolbar';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tafterInit() {\n\t\tconst editor = this.editor;\n\t\tconst widgetToolbarRepository = editor.plugins.get( WidgetToolbarRepository );\n\n\t\tconst tableContentToolbarItems = editor.config.get( 'table.contentToolbar' );\n\t\tconst deprecatedTableContentToolbarItems = editor.config.get( 'table.toolbar' );\n\n\t\tconst tableToolbarItems = editor.config.get( 'table.tableToolbar' );\n\n\t\tif ( deprecatedTableContentToolbarItems ) {\n\t\t\t// eslint-disable-next-line\n\t\t\tconsole.warn(\n\t\t\t\t'`config.table.toolbar` is deprecated and will be removed in the next major release.' +\n\t\t\t\t' Use `config.table.contentToolbar` instead.'\n\t\t\t);\n\t\t}\n\n\t\tif ( tableContentToolbarItems || deprecatedTableContentToolbarItems ) {\n\t\t\twidgetToolbarRepository.register( 'tableContent', {\n\t\t\t\titems: tableContentToolbarItems || deprecatedTableContentToolbarItems,\n\t\t\t\tgetRelatedElement: getTableWidgetAncestor\n\t\t\t} );\n\t\t}\n\n\t\tif ( tableToolbarItems ) {\n\t\t\twidgetToolbarRepository.register( 'table', {\n\t\t\t\titems: tableToolbarItems,\n\t\t\t\tgetRelatedElement: getSelectedTableWidget\n\t\t\t} );\n\t\t}\n\t}\n}\n\n/**\n * Items to be placed in the table content toolbar.\n *\n * **Note:** This configuration option is deprecated! Use {@link module:table/table~TableConfig#contentToolbar} instead.\n *\n * Read more about configuring toolbar in {@link module:core/editor/editorconfig~EditorConfig#toolbar}.\n *\n * @deprecated\n * @member {Array.<String>} module:table/table~TableConfig#toolbar\n */\n\n/**\n * Items to be placed in the table content toolbar.\n * The {@link module:table/tabletoolbar~TableToolbar} plugin is required to make this toolbar working.\n *\n * Assuming that you use the {@link module:table/tableui~TableUI} feature, the following toolbar items will be available\n * in {@link module:ui/componentfactory~ComponentFactory}:\n *\n * * `'tableRow'`,\n * * `'tableColumn'`,\n * * `'mergeTableCells'`.\n *\n * You can thus configure the toolbar like this:\n *\n *\t\tconst tableConfig = {\n *\t\t\tcontentToolbar: [ 'tableRow', 'tableColumn', 'mergeTableCells' ]\n *\t\t};\n *\n * Of course, the same buttons can also be used in the\n * {@link module:core/editor/editorconfig~EditorConfig#toolbar main editor toolbar}.\n *\n * Read more about configuring toolbar in {@link module:core/editor/editorconfig~EditorConfig#toolbar}.\n *\n * @member {Array.<String>} module:table/table~TableConfig#contentToolbar\n */\n\n/**\n * Items to be placed in the table toolbar.\n * The {@link module:table/tabletoolbar~TableToolbar} plugin is required to make this toolbar working.\n *\n * You can thus configure the toolbar like this:\n *\n *\t\tconst tableConfig = {\n *\t\t\ttableToolbar: [ 'blockQuote' ]\n *\t\t};\n *\n * Of course, the same buttons can also be used in the\n * {@link module:core/editor/editorconfig~EditorConfig#toolbar main editor toolbar}.\n *\n * Read more about configuring toolbar in {@link module:core/editor/editorconfig~EditorConfig#toolbar}.\n *\n * @member {Array.<String>} module:table/table~TableConfig#tableToolbar\n */\n","import Plugin from '@ckeditor/ckeditor5-core/src/plugin';\n\nimport { createDropdown, addToolbarToDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils';\n\nimport {opMacroPlugins} from \"../op-plugins\";\n\n/**\n * Adding a drop down list of macros to the toolbar.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class OPMacroListPlugin extends Plugin {\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst disabledPluginNames = (editor.config.get('removePlugins') || []).map(p => p.pluginName);\n\t\tconst dropdownTooltip = window.I18n.t('js.editor.macro.dropdown.chose_macro');\n\n\t\t// Skip if we don't have any macros here\n\t\tif (editor.config.get('openProject.disableAllMacros') === true) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Register UI component.\n\t\teditor.ui.componentFactory.add( 'macroList', locale => {\n\t\t\tconst dropdownItems = [];\n\t\t\tfor ( const macroPlugin of opMacroPlugins ) {\n\t\t\t\tif (disabledPluginNames.indexOf(macroPlugin.pluginName) !== -1) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst listItem = editor.ui.componentFactory.create(macroPlugin.buttonName);\n\t\t\t\tdropdownItems.push(listItem);\n\t\t\t}\n\t\t\tconst dropdownView = createDropdown( locale );\n\n\t\t\taddToolbarToDropdown(dropdownView, dropdownItems);\n\t\t\tdropdownView.buttonView.set( {\n\t\t\t\tisOn: false,\n\t\t\t\twithText: true,\n\t\t\t\ttooltip: dropdownTooltip,\n\t\t\t\tlabel: window.I18n.t('js.editor.macro.dropdown.macros')\n\t\t\t} );\n\t\t\tdropdownView.toolbarView.isVertical = true;\n\t\t\tdropdownView.toolbarView.className = 'op-macro-list-button';\n\n\t\t\treturn dropdownView;\n\t\t} );\n\t}\n}\n","import {opImageUploadPlugins, opMacroPlugins} from './op-plugins';\n\nexport function configurationCustomizer(editorClass) {\n\treturn (wrapper, configuration) => {\n\t\tconst context = configuration.openProject.context;\n\n\t\t// We're going to remove some plugins from the default configuration\n\t\t// when we detect they are unsupported in the current context\n\t\tconfiguration.removePlugins = configuration.removePlugins || [];\n\n\t\t// Disable uploading if there is no resource with uploadAttachment\n\t\tconst resource = context.resource;\n\t\tif (!(resource && resource.canAddAttachments)) {\n\t\t\tconfiguration.removePlugins.push(...opImageUploadPlugins.map(el => el.pluginName))\n\t\t}\n\n\t\t// Disable macros entirely\n\t\tif (context.macros === false) {\n\t\t\tconfiguration.openProject.disableAllMacros = true;\n\t\t\tconfiguration.removePlugins.push(...opMacroPlugins.map(el => el.pluginName))\n\t\t}\n\n\t\t// Enable selective macros\n\t\tif (Array.isArray(context.macros)) {\n\t\t\tconst disabledMacros = opMacroPlugins.filter(plugin => context.macros.indexOf(plugin.pluginName) === -1);\n\t\t\tconfiguration.removePlugins.push(...disabledMacros);\n\t\t}\n\n\t\t// Return the original promise for instance creation\n\t\treturn editorClass.create(wrapper, configuration);\n\t};\n}\n","export function customItemRenderer( item ) {\n const itemElement = document.createElement( 'span' );\n\n\titemElement.classList.add( 'mention-list-item' );\n\titemElement.textContent = item.name;\n\n return itemElement;\n}\n","import { userMentions } from \"./mentions/user-mentions\";\nimport { workPackageMentions } from \"./mentions/work-package-mentions\";\nimport {customItemRenderer} from './mentions/mentions-item-renderer';\n\nexport const defaultConfig = {\n\theading: {\n\t\toptions: [\n\t\t\t{ model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },\n\t\t\t{ model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' },\n\t\t\t{ model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2' },\n\t\t\t{ model: 'heading3', view: 'h3', title: 'Heading 3', class: 'ck-heading_heading3' },\n\t\t\t{ model: 'heading4', view: 'h4', title: 'Heading 4', class: 'ck-heading_heading4' },\n\t\t\t{ model: 'heading5', view: 'h5', title: 'Heading 5', class: 'ck-heading_heading5' }\n\t\t]\n\t},\n\ttoolbar: {\n\t\t// Will be defined by each build\n\t},\n\tOPMacroEmbeddedTable: {\n\t\ttoolbar: [\n\t\t\t'opEditEmbeddedTableQuery',\n\t\t]\n\t},\n\tOPMacroWpButton: {\n\t\ttoolbar: [\n\t\t\t'opEditWpMacroButton',\n\t\t]\n\t},\n\tOPWikiIncludePage: {\n\t\ttoolbar: [\n\t\t\t'opEditWikiIncludeMacroButton',\n\t\t]\n\t},\n\tOPCodeBlock: {\n\t\ttoolbar: [\n\t\t\t'opEditCodeBlock',\n\t\t]\n\t},\n\tOPChildPages: {\n\t\ttoolbar: [\n\t\t\t'opEditChildPagesMacroButton',\n\t\t]\n\t},\n\timage: {\n\t\ttoolbar: [\n\t\t\t'imageStyle:full',\n\t\t\t'|',\n\t\t\t'imageTextAlternative'\n\t\t]\n\t},\n\ttable: {\n\t\ttoolbar: [ 'tableColumn', 'tableRow' ]\n\t},\n\n\tmention: {\n\t\tfeeds: [\n\t\t\t{\n\t\t\t\tmarker: '@',\n\t\t\t\tfeed: userMentions,\n\t\t\t\titemRenderer: customItemRenderer,\n\t\t\t\tminimumCharacters: 0\n\t\t\t},\n\t\t\t{\n\t\t\t\tmarker: '#',\n\t\t\t\t// Allow multi-hash WP references\n\t\t\t\tallowedPrefixes: ['#', '##'],\n\t\t\t\tfeed: workPackageMentions,\n\t\t\t\titemRenderer: customItemRenderer,\n\t\t\t\tminimumCharacters: 1\n\t\t\t},\n\t\t]\n\t},\n\n\tlanguage: 'en'\n};\n","import { getOPResource, getOPPath } from \"../plugins/op-context/op-context\";\n\nexport function userMentions(queryText) {\n\t let resource = getOPResource(this.editor);\n\n\t // Unsupported context does not allow mentioning\n\t if (!(resource && resource._type === 'WorkPackage')) {\n\t\treturn [];\n\t }\n\n\tconst project_id = resource.project.idFromLink;\n\tconst url = getOPPath(this.editor).api.v3.principals(project_id, queryText);\n\tlet base = window.OpenProject.urlRoot + `/users/`;\n\n\treturn new Promise((resolve, reject) => {\n\t\tjQuery\n\t\t\t.getJSON(url, collection => {\n\t\t\t\tresolve(collection._embedded.elements.map(user => {\n\t\t\t\t\tconst type = user._type.toLowerCase();\n\t\t\t\t\tconst displayText = `${type}#${user.id}`;\n\t\t\t\t\tconst id = `@${user.id}`;\n\t\t\t\t\treturn { type: 'user', id: id, text: displayText, name: user.name, link: base + user.id };\n\t\t\t\t}));\n\t\t\t});\n\t\t})\n}\n","import { getOPResource, getOPPath } from \"../plugins/op-context/op-context\";\n\nexport function workPackageMentions(query) {\n\tconst url = window.OpenProject.urlRoot + `/work_packages/auto_complete.json`;\n\tlet base = window.OpenProject.urlRoot + `/work_packages/`;\n\n\treturn new Promise((resolve, reject) => {\n\t\tjQuery\n\t\t\t.getJSON(url, {q: query, scope: 'all'}, collection => {\n\t\t\t\tresolve(collection.map(wp => {\n\t\t\t\t\tconst id = `#${wp.id}`;\n\t\t\t\t\treturn { type: 'work_package', id: id, text: id, name: wp.to_s, link: base + wp.id };\n\t\t\t\t}));\n\t\t\t});\n\t\t})\n}\n","import ClassicEditorBase from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';\nimport {configurationCustomizer} from './op-config-customizer';\nimport {builtinPlugins} from './op-plugins';\nimport {defaultConfig} from \"./op-ckeditor-config\";\n\nexport class ConstrainedEditor extends ClassicEditorBase {}\nexport class FullEditor extends ClassicEditorBase {}\n\n// Export the two common interfaces\nwindow.OPConstrainedEditor = ConstrainedEditor;\nwindow.OPClassicEditor = FullEditor;\n\nFullEditor.createCustomized = configurationCustomizer(FullEditor);\nFullEditor.builtinPlugins = builtinPlugins;\nFullEditor.defaultConfig = Object.assign({}, defaultConfig);\nFullEditor.defaultConfig.toolbar = {\n\t\titems: [\n\t\t\t'heading',\n\t\t\t'|',\n\t\t\t'bold',\n\t\t\t'italic',\n\t\t\t'strikethrough',\n\t\t\t'code',\n\t\t\t'insertCodeBlock',\n\t\t\t'link',\n\t\t\t'bulletedList',\n\t\t\t'numberedList',\n\t\t\t'imageUpload',\n\t\t\t'blockQuote',\n\t\t\t'|',\n\t\t\t'insertTable',\n\t\t\t'macroList',\n\t\t\t'|',\n\t\t\t'undo',\n\t\t\t'redo',\n\t\t\t'openProjectShowFormattingHelp',\n\t\t\t'|',\n\t\t\t'preview',\n\t\t\t'opShowSource'\n\t\t]\n};\n\nConstrainedEditor.createCustomized = configurationCustomizer(ConstrainedEditor);\nConstrainedEditor.builtinPlugins = builtinPlugins;\nConstrainedEditor.defaultConfig = Object.assign({}, defaultConfig);\nConstrainedEditor.defaultConfig.toolbar = {\n\titems: [\n\t\t'bold',\n\t\t'italic',\n\t\t'strikethrough',\n\t\t'code',\n\t\t'insertCodeBlock',\n\t\t'link',\n\t\t'bulletedList',\n\t\t'numberedList',\n\t\t'imageUpload',\n\t\t'blockQuote',\n\t\t'|',\n\t\t'openProjectShowFormattingHelp',\n\t\t'preview',\n\t\t'opShowSource'\n\t]\n};\n"],"sourceRoot":""}