Your IP : 18.191.116.61


Current Path : /home/lentoinv/covisclubinternational.com/plugins/summernote/
Upload File :
Current File : //home/lentoinv/covisclubinternational.com/plugins/summernote/summernote-bs4.min.js.map

{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap","webpack:///external {\"root\":\"jQuery\",\"commonjs2\":\"jquery\",\"commonjs\":\"jquery\",\"amd\":\"jquery\"}","webpack:///./src/js/base/renderer.js","webpack:///(webpack)/buildin/amd-options.js","webpack:///./src/js/base/summernote-en-US.js","webpack:///./src/js/base/core/env.js","webpack:///./src/js/base/core/func.js","webpack:///./src/js/base/core/lists.js","webpack:///./src/js/base/core/dom.js","webpack:///./src/js/base/Context.js","webpack:///./src/js/base/core/range.js","webpack:///./src/js/summernote.js","webpack:///./src/js/base/core/key.js","webpack:///./src/js/base/editing/History.js","webpack:///./src/js/base/editing/Style.js","webpack:///./src/js/base/editing/Bullet.js","webpack:///./src/js/base/editing/Typing.js","webpack:///./src/js/base/editing/Table.js","webpack:///./src/js/base/module/Editor.js","webpack:///./src/js/base/core/async.js","webpack:///./src/js/base/module/Clipboard.js","webpack:///./src/js/base/module/Codeview.js","webpack:///./src/js/base/module/Dropzone.js","webpack:///./src/js/base/module/Statusbar.js","webpack:///./src/js/base/module/Fullscreen.js","webpack:///./src/js/base/module/Handle.js","webpack:///./src/js/base/module/AutoLink.js","webpack:///./src/js/base/module/AutoSync.js","webpack:///./src/js/base/module/AutoReplace.js","webpack:///./src/js/base/module/Placeholder.js","webpack:///./src/js/base/module/Buttons.js","webpack:///./src/js/base/module/Toolbar.js","webpack:///./src/js/base/module/LinkDialog.js","webpack:///./src/js/base/module/LinkPopover.js","webpack:///./src/js/base/module/ImageDialog.js","webpack:///./src/js/base/module/ImagePopover.js","webpack:///./src/js/base/module/TablePopover.js","webpack:///./src/js/base/module/VideoDialog.js","webpack:///./src/js/base/module/HelpDialog.js","webpack:///./src/js/base/module/AirPopover.js","webpack:///./src/js/base/module/HintPopover.js","webpack:///./src/js/base/settings.js","webpack:///./src/js/bs4/ui.js","webpack:///./src/js/bs4/settings.js"],"names":["root","factory","exports","module","require","define","amd","a","i","window","__WEBPACK_EXTERNAL_MODULE__0__","installedModules","__webpack_require__","moduleId","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","Renderer","markup","children","options","callback","this","$parent","$node","$","contents","html","className","addClass","data","each","k","v","attr","click","on","$container","find","forEach","child","render","length","append","arguments","Array","isArray","__webpack_amd_options__","summernote","lang","extend","font","bold","italic","underline","clear","height","strikethrough","subscript","superscript","size","sizeunit","image","insert","resizeFull","resizeHalf","resizeQuarter","resizeNone","floatLeft","floatRight","floatNone","shapeRounded","shapeCircle","shapeThumbnail","shapeNone","dragImageHere","dropImage","selectFromFiles","maximumFileSize","maximumFileSizeError","url","remove","original","video","videoLink","providers","link","unlink","edit","textToDisplay","openInNewWindow","useProtocol","table","addRowAbove","addRowBelow","addColLeft","addColRight","delRow","delCol","delTable","hr","style","blockquote","pre","h1","h2","h3","h4","h5","h6","lists","unordered","ordered","help","fullscreen","codeview","paragraph","outdent","indent","left","center","right","justify","color","recent","more","background","foreground","transparent","setTransparent","reset","resetToDefault","cpSelect","shortcut","shortcuts","close","textFormatting","action","paragraphFormatting","documentStyle","extraKeys","history","undo","redo","specialChar","select","output","noSelection","isSupportAmd","genericFontFamilies","validFontName","fontName","inArray","toLowerCase","browserVersion","userAgent","navigator","isMSIE","test","matches","exec","parseFloat","isEdge","hasCodeMirror","CodeMirror","isSupportTouch","MaxTouchPoints","msMaxTouchPoints","inputEventName","isMac","appVersion","indexOf","isFF","isPhantom","isWebkit","isChrome","isSafari","jqueryVersion","fn","jquery","isFontInstalled","testFontName","context","document","createElement","getContext","testSize","originalWidth","measureText","width","isW3CRangeSupport","createRange","idCounter","eq","itemA","itemB","eq2","peq2","propName","ok","fail","self","not","f","apply","and","fA","fB","item","invoke","obj","method","resetUniqueId","uniqueId","prefix","id","rect2bnd","rect","$document","top","scrollTop","scrollLeft","bottom","invertObject","inverted","namespaceToCamel","namespace","split","map","substring","toUpperCase","join","debounce","func","wait","immediate","timeout","args","later","callNow","clearTimeout","setTimeout","isValidUrl","head","array","last","tail","slice","contains","initial","prev","idx","next","pred","len","all","sum","reduce","memo","from","collection","result","isEmpty","clusterBy","aLast","compact","aResult","push","unique","results","NBSP_CHAR","String","fromCharCode","isEditable","node","hasClass","makePredByNodeName","nodeName","isText","nodeType","isVoid","isPara","isPre","isLi","isTable","isData","isInline","isBodyContainer","isList","isHr","isBlockquote","isCell","isAnchor","isBody","blankHTML","env","nodeLength","nodeValue","childNodes","innerHTML","paddingBlankHTML","ancestor","parentNode","listAncestor","ancestors","el","listNext","nodes","nextSibling","insertAfter","preceding","parent","insertBefore","appendChild","appendChildNodes","aChild","isLeftEdgePoint","point","offset","isRightEdgePoint","isEdgePoint","isLeftEdgeOf","position","isRightEdgeOf","previousSibling","hasChildren","prevPoint","isSkipInnerOffset","nextPoint","isSamePoint","pointA","pointB","splitNode","isSkipPaddingBlankHTML","isNotSplitEdgePoint","isDiscardEmptySplits","splitText","childNode","clone","cloneNode","splitTree","isRemoveChild","removeNode","removeChild","isTextarea","stripLinebreaks","val","replace","ZERO_WIDTH_NBSP_CHAR","blank","emptyPara","isControlSizing","isElement","isPurePara","isHeading","isBlock","isBodyInline","isParaInline","isDiv","isBR","isSpan","isB","isU","isS","isI","isImg","deepestChildIsEmpty","firstElementChild","isEmptyAnchor","isClosestSibling","nodeA","nodeB","withClosestSiblings","siblings","isLeftEdgePointOf","isRightEdgePointOf","isVisiblePoint","leftNode","rightNode","prevPointUntil","nextPointUntil","isCharPoint","ch","charAt","isSpacePoint","walkPoint","startPoint","endPoint","handler","singleChildAncestor","lastAncestor","filter","listPrev","listDescendant","descendants","fnWalk","current","commonAncestor","wrap","wrapperName","wrapper","makeOffsetPath","reverse","fromOffsetPath","offsets","splitPoint","splitRoot","container","topAncestor","pivot","createText","text","createTextNode","removeWhile","newNode","cssText","isNewlineOnBlock","match","endSlash","isEndOfInlineContainer","isBlockNode","trim","posFromPlaceholder","placeholder","$placeholder","pos","outerHeight","attachEvents","events","keys","detachEvents","off","isCustomStyleTag","classList","Context","$note","memos","layoutInfo","ui","ui_template","initialize","createLayout","_initialize","hide","_destroy","removeData","removeLayout","disabled","isDisabled","code","dom","disable","now","editor","buttons","plugins","initializeModule","removeModule","removeMemo","triggerEvent","isActivated","undefined","codable","editable","editing","callbacks","trigger","shouldInitialize","ModuleClass","withoutIntialize","destroy","event","createInvokeHandler","preventDefault","$target","target","closest","splits","hasSeparator","moduleName","methodName","textRangeToPoint","textRange","isStart","prevContainer","parentElement","tester","body","createTextRange","moveToElementText","compareEndPoints","textRangeStart","curTextNode","collapse","firstChild","pointTester","duplicate","setEndPoint","textCount","cont","pointToTextRange","info","textRangeInfo","isCollapseToStart","prevTextNodes","collapseToStart","moveStart","type","isExternalAPICalled","hasInitOptions","langInfo","icons","tooltip","note","first","focus","WrappedRange","sc","so","ec","eo","isOnEditable","makeIsOn","isOnList","isOnAnchor","isOnCell","isOnData","w3cRange","setStart","setEnd","Math","min","nativeRng","nativeRange","selection","getSelection","rangeCount","removeAllRanges","addRange","offsetTop","abs","getVisiblePoint","isLeftToRight","block","hasRightNode","hasLeftNode","getEndPoint","isCollapsed","getStartPoint","includeAncestor","fullyContains","leftEdgeNodes","startAncestor","endAncestor","boundaryPoints","getPoints","isSameContainer","rng","emptyParents","normalize","inlineSiblings","concat","para","wrapBodyInlineWithPara","deleteContents","contentsContainer","insertNode","toString","findAfter","isNotTextPoint","regex","index","path","e","paras","getClientRects","wrappedRange","createFromSelection","bodyElement","lastChild","createFromBodyElement","createFromNode","anchorNode","getRangeAt","startContainer","startOffset","endContainer","endOffset","textRangeEnd","isTextNode","createFromNodeBefore","createFromNodeAfter","createFromBookmark","bookmark","createFromParaBookmark","KEY_MAP","isEdit","keyCode","BACKSPACE","TAB","ENTER","SPACE","DELETE","isMove","LEFT","UP","RIGHT","DOWN","isNavigation","HOME","END","PAGEUP","PAGEDOWN","nameFromCode","History","stack","stackOffset","$editable","range","snapshot","recordUndo","applySnapshot","makeSnapshot","historyLimit","shift","Style","$obj","propertyNames","propertyName","css","styleInfo","jQueryCSS","fontSize","parseInt","expandClosestSibling","onlyPartialContains","nodesInRange","tails","elem","$cont","fromNode","queryCommandState","queryCommandValue","isUnordered","lineHeight","toFixed","anchor","Bullet","toggleList","clustereds","previousList","findList","wrapList","appendToPrevious","releaseList","listName","paraBookmark","wrappedParas","diffLists","listNode","prevList","nextList","isEscapseToBody","releasedParas","headList","parentItem","newList","findNextSiblings","lastList","middleList","rootLists","rootList","listNodes","Typing","bullet","tabsize","tab","nextPara","blockquoteBreakingLevel","emptyAnchors","scrollIntoView","TableResultAction","where","domTable","_startPoint","_virtualTable","_actionCellList","setVirtualTablePosition","rowIndex","cellIndex","baseRow","baseCell","isRowSpan","isColSpan","isVirtualCell","objPosition","getActionCell","virtualTableCellObj","resultAction","virtualRowPosition","virtualColPosition","recoverCellIndex","newCellIndex","addCellInfoToVirtual","row","cell","cellHasColspan","colSpan","cellHasRowspan","rowSpan","isThisSelectedCell","rowPos","colPos","rowspanNumber","attributes","rp","rowspanIndex","adjustStartPoint","colspanNumber","cp","cellspanIndex","isSelectedCell","getDeleteResultActionToCell","Column","SubtractSpanCount","Row","isVirtual","AddCell","RemoveCell","getAddResultActionToCell","SumSpanCount","Ignore","getActionList","fixedRow","fixedCol","actualPosition","canContinue","rowPosition","colPosition","requestAction","Add","Delete","tagName","rows","cells","createVirtualTable","Table","isShift","nextCell","currentTr","trAttributes","recoverAttributes","actions","idCell","currentCell","tdAttributes","newTd","removeAttr","setAttribute","before","lastTrIndex","after","actionIndex","resultStr","attrList","specified","cellPos","virtualPosition","virtualTable","hasRowspan","nextRow","cloneRow","removeAttribute","colCount","rowCount","tdHTML","tds","idxCol","trHTML","trs","idxRow","$table","tableClassName","Editor","$editor","lastRange","typing","untab","insertParagraph","insertOrderedList","insertUnorderedList","formatPara","insertHorizontalRule","commands","sCmd","beforeCommand","execCommand","afterCommand","wrapCommand","fontStyling","unit","currentStyle","fontSizeUnit","formatBlock","isLimited","getLastRange","setLastRange","insertText","textNode","pasteHTML","onApplyCustomStyle","onFormatBlock","hrNode","stylePara","createLink","linkInfo","linkUrl","linkText","isNewWindow","checkProtocol","additionalTextLength","isTextChanged","onCreateLink","defaultProtocol","anchors","styleNodes","colorInfo","foreColor","backColor","insertTable","dim","dimension","createTable","removeMedia","restoreTarget","detach","floatMe","toggleClass","resize","hasKeyShortCut","isDefaultPrevented","handleKeyMap","preventDefaultEditableShortCuts","recordEveryKeystroke","spellCheck","disableGrammar","airMode","overrideContextMenu","outerWidth","maxHeight","minHeight","keyMap","metaKey","ctrlKey","altKey","shiftKey","keyName","eventName","tabDisable","pad","maxTextLength","thenCollapse","commit","styleWithCSS","isPreventTrigger","normalizeContent","tabSize","insertTab","src","param","Deferred","deferred","$img","one","resolve","reject","display","appendTo","promise","then","$image","show","files","file","filename","maximumImageFileSize","FileReader","onload","dataURL","onerror","err","readAsDataURL","readFileAsDataURL","insertImage","onImageUpload","insertImagesAsDataURL","currentRange","spans","firstSpan","noteStatusOutput","expand","$anchor","addRow","addCol","deleteRow","deleteCol","deleteTable","bKeepRatio","imageSize","newRatio","y","x","ratio","is","hasFocus","Clipboard","pasteByEvent","clipboardData","originalEvent","items","kind","getAsFile","getData","Dropzone","$eventListener","documentEventHandlers","$dropzone","prependTo","disableDragAndDrop","onDrop","attachDragAndDropEvent","$dropzoneMessage","onDragenter","isCodeview","hasEditorSize","add","onDragleave","removeClass","dataTransfer","types","content","substr","CodeView","$codable","save","deactivate","activate","codeviewFilter","codeviewFilterRegex","codeviewIframeFilter","whitelist","codeviewIframeWhitelistSrc","codeviewIframeWhitelistSrcBase","tag","RegExp","prettifyHtml","cmEditor","fromTextArea","codemirror","tern","server","TernServer","ternServer","cm","updateArgHints","getValue","setSize","toTextArea","purify","isChange","Statusbar","$statusbar","statusbar","disableResizeEditor","stopPropagation","editableTop","onMouseMove","clientY","minheight","max","Fullscreen","$toolbar","toolbar","$window","$scrollbar","onResize","resizeTo","h","setsize","isFullscreen","Handle","$editingArea","editingArea","we","update","$handle","disableResizeImage","posStart","clientX","isImage","$selection","w","origImageObj","Image","sizingText","linkPattern","AutoLink","handleKeyup","handleKeydown","lastWordRange","keyword","urlText","linkTargetBlank","wordRange","getWordRange","AutoSync","AutoReplace","PERIOD","COMMA","SEMICOLON","SLASH","previousKeydownCode","lastWord","jQuery","Node","Placeholder","inheritPlaceholder","isShow","toggle","Buttons","invertedKeyMap","editorMethod","button","addToolbarButtons","addImagePopoverButtons","addLinkPopoverButtons","addTablePopoverButtons","fontInstalledMap","fontNamesIgnoreCheck","buttonGroup","icon","$button","currentTarget","$recentColor","colorButton","dropdownButtonContents","dropdown","$dropdown","$holder","palette","colors","colorsName","customColors","change","$chip","$picker","$palette","prepend","$color","$currentButton","magic","styleTags","title","template","styleIdx","styleLen","representShortcut","createInvokeHandlerAndUpdateState","eraser","addDefaultFonts","fontname","isFontDeservedToAdd","fontNames","dropdownCheck","checkClassName","menuCheck","fontSizes","fontSizeUnits","colorPalette","unorderedlist","orderedlist","justifyLeft","alignLeft","justifyCenter","alignCenter","justifyRight","alignRight","justifyFull","alignJustify","textHeight","lineHeights","insertTableMaxSize","col","mousedown","tableMoveHandler","picture","minus","arrowsAlt","question","rollback","trash","rowAbove","rowBelow","colBefore","colAfter","rowRemove","colRemove","groups","groupIdx","groupLen","group","groupName","$group","btn","updateBtnStates","$item","isChecked","infos","selector","toggleBtnActive","posOffset","$dimensionDisplay","$catcher","$highlighted","$unhighlighted","offsetX","posCatcher","pageX","pageY","offsetY","ceil","Toolbar","isFollowing","followScroll","toolbarContainer","changeContainer","followingToolbar","editorHeight","editorWidth","toolbarHeight","statusbarHeight","otherBarHeight","otherStaticBar","currentOffset","editorOffsetTop","activateOffset","deactivateOffsetBottom","marginTop","zIndex","isIncludeCodeview","$btn","toggleBtn","LinkDialog","$body","dialogsInBody","disableLinkTarget","checkbox","checked","footer","$dialog","dialog","fade","dialogsFade","hideDialog","$input","$linkBtn","$linkText","$linkUrl","$openInNewWindow","$useProtocol","onDialogShown","toggleLinkBtn","bindEnterKey","isNewWindowChecked","prop","useProtocolChecked","onDialogHidden","state","showDialog","showLinkDialog","LinkPopover","popover","$popover","$content","href","containerOffset","ImageDialog","imageLimitation","floor","log","readableSize","pow","showImageDialog","onImageLinkInsert","$imageInput","$imageUrl","$imageBtn","replaceWith","ImagePopover","popatmouse","TablePopover","VideoDialog","$video","ytMatch","igMatch","vMatch","vimMatch","dmMatch","youkuMatch","qqMatch","qqMatch2","mp4Match","oggMatch","webmMatch","fbMatch","youtubeId","start","ytMatchForStart","vid","encodeURIComponent","showVideoDialog","createVideoNode","$videoUrl","$videoBtn","HelpDialog","createShortcutList","command","$row","showHelpDialog","AirPopover","hidable","onContextmenu","air","forcelyOpen","HintPopover","hint","direction","hintDirection","hints","matchingWord","hideArrow","innerHeight","$current","$next","selectItem","$nextGroup","$prev","$prevGroup","nodeFromItem","rangeCompute","hintSelect","hintIdx","moveUp","moveDown","search","searchKeyword","createItemTemplates","hintMode","getWordsRange","getWordsMatchRange","empty","bnd","createGroup","version","Codeview","toolbarPosition","tabDisabled","textareaAutoSync","onBeforeCommand","onBlur","onBlurCodeview","onChange","onChangeCodeview","onEnter","onFocus","onImageUploadError","onInit","onKeydown","onKeyup","onMousedown","onMouseup","onPaste","onScroll","htmlMode","lineNumbers","pc","mac","renderer","airEditor","airEditable","option","iconClassName","editorOptions","rowSize","colSize","colorName","placement","isEnable","isActive","modal","interface"],"mappings":"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","file":"summernote-bs4.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"jquery\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"jquery\"], factory);\n\telse {\n\t\tvar a = typeof exports === 'object' ? factory(require(\"jquery\")) : factory(root[\"jQuery\"]);\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})(window, function(__WEBPACK_EXTERNAL_MODULE__0__) {\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 = 53);\n","module.exports = __WEBPACK_EXTERNAL_MODULE__0__;","import $ from 'jquery';\n\nclass Renderer {\n  constructor(markup, children, options, callback) {\n    this.markup = markup;\n    this.children = children;\n    this.options = options;\n    this.callback = callback;\n  }\n\n  render($parent) {\n    const $node = $(this.markup);\n\n    if (this.options && this.options.contents) {\n      $node.html(this.options.contents);\n    }\n\n    if (this.options && this.options.className) {\n      $node.addClass(this.options.className);\n    }\n\n    if (this.options && this.options.data) {\n      $.each(this.options.data, (k, v) => {\n        $node.attr('data-' + k, v);\n      });\n    }\n\n    if (this.options && this.options.click) {\n      $node.on('click', this.options.click);\n    }\n\n    if (this.children) {\n      const $container = $node.find('.note-children-container');\n      this.children.forEach((child) => {\n        child.render($container.length ? $container : $node);\n      });\n    }\n\n    if (this.callback) {\n      this.callback($node, this.options);\n    }\n\n    if (this.options && this.options.callback) {\n      this.options.callback($node);\n    }\n\n    if ($parent) {\n      $parent.append($node);\n    }\n\n    return $node;\n  }\n}\n\nexport default {\n  create: (markup, callback) => {\n    return function() {\n      const options = typeof arguments[1] === 'object' ? arguments[1] : arguments[0];\n      let children = Array.isArray(arguments[0]) ? arguments[0] : [];\n      if (options && options.children) {\n        children = options.children;\n      }\n      return new Renderer(markup, children, options, callback);\n    };\n  },\n};\n","/* globals __webpack_amd_options__ */\nmodule.exports = __webpack_amd_options__;\n","import $ from 'jquery';\n\n$.summernote = $.summernote || {\n  lang: {},\n};\n\n$.extend($.summernote.lang, {\n  'en-US': {\n    font: {\n      bold: 'Bold',\n      italic: 'Italic',\n      underline: 'Underline',\n      clear: 'Remove Font Style',\n      height: 'Line Height',\n      name: 'Font Family',\n      strikethrough: 'Strikethrough',\n      subscript: 'Subscript',\n      superscript: 'Superscript',\n      size: 'Font Size',\n      sizeunit: 'Font Size Unit',\n    },\n    image: {\n      image: 'Picture',\n      insert: 'Insert Image',\n      resizeFull: 'Resize full',\n      resizeHalf: 'Resize half',\n      resizeQuarter: 'Resize quarter',\n      resizeNone: 'Original size',\n      floatLeft: 'Float Left',\n      floatRight: 'Float Right',\n      floatNone: 'Remove float',\n      shapeRounded: 'Shape: Rounded',\n      shapeCircle: 'Shape: Circle',\n      shapeThumbnail: 'Shape: Thumbnail',\n      shapeNone: 'Shape: None',\n      dragImageHere: 'Drag image or text here',\n      dropImage: 'Drop image or Text',\n      selectFromFiles: 'Select from files',\n      maximumFileSize: 'Maximum file size',\n      maximumFileSizeError: 'Maximum file size exceeded.',\n      url: 'Image URL',\n      remove: 'Remove Image',\n      original: 'Original',\n    },\n    video: {\n      video: 'Video',\n      videoLink: 'Video Link',\n      insert: 'Insert Video',\n      url: 'Video URL',\n      providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion or Youku)',\n    },\n    link: {\n      link: 'Link',\n      insert: 'Insert Link',\n      unlink: 'Unlink',\n      edit: 'Edit',\n      textToDisplay: 'Text to display',\n      url: 'To what URL should this link go?',\n      openInNewWindow: 'Open in new window',\n      useProtocol: 'Use default protocol',\n    },\n    table: {\n      table: 'Table',\n      addRowAbove: 'Add row above',\n      addRowBelow: 'Add row below',\n      addColLeft: 'Add column left',\n      addColRight: 'Add column right',\n      delRow: 'Delete row',\n      delCol: 'Delete column',\n      delTable: 'Delete table',\n    },\n    hr: {\n      insert: 'Insert Horizontal Rule',\n    },\n    style: {\n      style: 'Style',\n      p: 'Normal',\n      blockquote: 'Quote',\n      pre: 'Code',\n      h1: 'Header 1',\n      h2: 'Header 2',\n      h3: 'Header 3',\n      h4: 'Header 4',\n      h5: 'Header 5',\n      h6: 'Header 6',\n    },\n    lists: {\n      unordered: 'Unordered list',\n      ordered: 'Ordered list',\n    },\n    options: {\n      help: 'Help',\n      fullscreen: 'Full Screen',\n      codeview: 'Code View',\n    },\n    paragraph: {\n      paragraph: 'Paragraph',\n      outdent: 'Outdent',\n      indent: 'Indent',\n      left: 'Align left',\n      center: 'Align center',\n      right: 'Align right',\n      justify: 'Justify full',\n    },\n    color: {\n      recent: 'Recent Color',\n      more: 'More Color',\n      background: 'Background Color',\n      foreground: 'Text Color',\n      transparent: 'Transparent',\n      setTransparent: 'Set transparent',\n      reset: 'Reset',\n      resetToDefault: 'Reset to default',\n      cpSelect: 'Select',\n    },\n    shortcut: {\n      shortcuts: 'Keyboard shortcuts',\n      close: 'Close',\n      textFormatting: 'Text formatting',\n      action: 'Action',\n      paragraphFormatting: 'Paragraph formatting',\n      documentStyle: 'Document Style',\n      extraKeys: 'Extra keys',\n    },\n    help: {\n      'insertParagraph': 'Insert Paragraph',\n      'undo': 'Undoes the last command',\n      'redo': 'Redoes the last command',\n      'tab': 'Tab',\n      'untab': 'Untab',\n      'bold': 'Set a bold style',\n      'italic': 'Set a italic style',\n      'underline': 'Set a underline style',\n      'strikethrough': 'Set a strikethrough style',\n      'removeFormat': 'Clean a style',\n      'justifyLeft': 'Set left align',\n      'justifyCenter': 'Set center align',\n      'justifyRight': 'Set right align',\n      'justifyFull': 'Set full align',\n      'insertUnorderedList': 'Toggle unordered list',\n      'insertOrderedList': 'Toggle ordered list',\n      'outdent': 'Outdent on current paragraph',\n      'indent': 'Indent on current paragraph',\n      'formatPara': 'Change current block\\'s format as a paragraph(P tag)',\n      'formatH1': 'Change current block\\'s format as H1',\n      'formatH2': 'Change current block\\'s format as H2',\n      'formatH3': 'Change current block\\'s format as H3',\n      'formatH4': 'Change current block\\'s format as H4',\n      'formatH5': 'Change current block\\'s format as H5',\n      'formatH6': 'Change current block\\'s format as H6',\n      'insertHorizontalRule': 'Insert horizontal rule',\n      'linkDialog.show': 'Show Link Dialog',\n    },\n    history: {\n      undo: 'Undo',\n      redo: 'Redo',\n    },\n    specialChar: {\n      specialChar: 'SPECIAL CHARACTERS',\n      select: 'Select Special characters',\n    },\n    output: {\n      noSelection: 'No Selection Made!',\n    },\n  },\n});\n","import $ from 'jquery';\nconst isSupportAmd = typeof define === 'function' && define.amd; // eslint-disable-line\n\n/**\n * returns whether font is installed or not.\n *\n * @param {String} fontName\n * @return {Boolean}\n */\nconst genericFontFamilies = ['sans-serif', 'serif', 'monospace', 'cursive', 'fantasy'];\n\nfunction validFontName(fontName) {\n  return ($.inArray(fontName.toLowerCase(), genericFontFamilies) === -1) ? `'${fontName}'` : fontName;\n}\n\nfunction isFontInstalled(fontName) {\n  const testFontName = fontName === 'Comic Sans MS' ? 'Courier New' : 'Comic Sans MS';\n  const testText = 'mmmmmmmmmmwwwww';\n  const testSize = '200px';\n\n  var canvas = document.createElement('canvas');\n  var context = canvas.getContext('2d');\n\n  context.font = testSize + \" '\" + testFontName + \"'\";\n  const originalWidth = context.measureText(testText).width;\n\n  context.font = testSize + ' ' + validFontName(fontName) + ', \"' + testFontName + '\"';\n  const width = context.measureText(testText).width;\n\n  return originalWidth !== width;\n}\n\nconst userAgent = navigator.userAgent;\nconst isMSIE = /MSIE|Trident/i.test(userAgent);\nlet browserVersion;\nif (isMSIE) {\n  let matches = /MSIE (\\d+[.]\\d+)/.exec(userAgent);\n  if (matches) {\n    browserVersion = parseFloat(matches[1]);\n  }\n  matches = /Trident\\/.*rv:([0-9]{1,}[.0-9]{0,})/.exec(userAgent);\n  if (matches) {\n    browserVersion = parseFloat(matches[1]);\n  }\n}\n\nconst isEdge = /Edge\\/\\d+/.test(userAgent);\n\nlet hasCodeMirror = !!window.CodeMirror;\n\nconst isSupportTouch =\n  (('ontouchstart' in window) ||\n   (navigator.MaxTouchPoints > 0) ||\n   (navigator.msMaxTouchPoints > 0));\n\n// [workaround] IE doesn't have input events for contentEditable\n// - see: https://goo.gl/4bfIvA\nconst inputEventName = (isMSIE) ? 'DOMCharacterDataModified DOMSubtreeModified DOMNodeInserted' : 'input';\n\n/**\n * @class core.env\n *\n * Object which check platform and agent\n *\n * @singleton\n * @alternateClassName env\n */\nexport default {\n  isMac: navigator.appVersion.indexOf('Mac') > -1,\n  isMSIE,\n  isEdge,\n  isFF: !isEdge && /firefox/i.test(userAgent),\n  isPhantom: /PhantomJS/i.test(userAgent),\n  isWebkit: !isEdge && /webkit/i.test(userAgent),\n  isChrome: !isEdge && /chrome/i.test(userAgent),\n  isSafari: !isEdge && /safari/i.test(userAgent) && (!/chrome/i.test(userAgent)),\n  browserVersion,\n  jqueryVersion: parseFloat($.fn.jquery),\n  isSupportAmd,\n  isSupportTouch,\n  hasCodeMirror,\n  isFontInstalled,\n  isW3CRangeSupport: !!document.createRange,\n  inputEventName,\n  genericFontFamilies,\n  validFontName,\n};\n","import $ from 'jquery';\n\n/**\n * @class core.func\n *\n * func utils (for high-order func's arg)\n *\n * @singleton\n * @alternateClassName func\n */\nfunction eq(itemA) {\n  return function(itemB) {\n    return itemA === itemB;\n  };\n}\n\nfunction eq2(itemA, itemB) {\n  return itemA === itemB;\n}\n\nfunction peq2(propName) {\n  return function(itemA, itemB) {\n    return itemA[propName] === itemB[propName];\n  };\n}\n\nfunction ok() {\n  return true;\n}\n\nfunction fail() {\n  return false;\n}\n\nfunction not(f) {\n  return function() {\n    return !f.apply(f, arguments);\n  };\n}\n\nfunction and(fA, fB) {\n  return function(item) {\n    return fA(item) && fB(item);\n  };\n}\n\nfunction self(a) {\n  return a;\n}\n\nfunction invoke(obj, method) {\n  return function() {\n    return obj[method].apply(obj, arguments);\n  };\n}\n\nlet idCounter = 0;\n\n/**\n * reset globally-unique id\n *\n */\nfunction resetUniqueId() {\n  idCounter = 0;\n}\n\n/**\n * generate a globally-unique id\n *\n * @param {String} [prefix]\n */\nfunction uniqueId(prefix) {\n  const id = ++idCounter + '';\n  return prefix ? prefix + id : id;\n}\n\n/**\n * returns bnd (bounds) from rect\n *\n * - IE Compatibility Issue: http://goo.gl/sRLOAo\n * - Scroll Issue: http://goo.gl/sNjUc\n *\n * @param {Rect} rect\n * @return {Object} bounds\n * @return {Number} bounds.top\n * @return {Number} bounds.left\n * @return {Number} bounds.width\n * @return {Number} bounds.height\n */\nfunction rect2bnd(rect) {\n  const $document = $(document);\n  return {\n    top: rect.top + $document.scrollTop(),\n    left: rect.left + $document.scrollLeft(),\n    width: rect.right - rect.left,\n    height: rect.bottom - rect.top,\n  };\n}\n\n/**\n * returns a copy of the object where the keys have become the values and the values the keys.\n * @param {Object} obj\n * @return {Object}\n */\nfunction invertObject(obj) {\n  const inverted = {};\n  for (const key in obj) {\n    if (Object.prototype.hasOwnProperty.call(obj, key)) {\n      inverted[obj[key]] = key;\n    }\n  }\n  return inverted;\n}\n\n/**\n * @param {String} namespace\n * @param {String} [prefix]\n * @return {String}\n */\nfunction namespaceToCamel(namespace, prefix) {\n  prefix = prefix || '';\n  return prefix + namespace.split('.').map(function(name) {\n    return name.substring(0, 1).toUpperCase() + name.substring(1);\n  }).join('');\n}\n\n/**\n * Returns a function, that, as long as it continues to be invoked, will not\n * be triggered. The function will be called after it stops being called for\n * N milliseconds. If `immediate` is passed, trigger the function on the\n * leading edge, instead of the trailing.\n * @param {Function} func\n * @param {Number} wait\n * @param {Boolean} immediate\n * @return {Function}\n */\nfunction debounce(func, wait, immediate) {\n  let timeout;\n  return function() {\n    const context = this;\n    const args = arguments;\n    const later = () => {\n      timeout = null;\n      if (!immediate) {\n        func.apply(context, args);\n      }\n    };\n    const callNow = immediate && !timeout;\n    clearTimeout(timeout);\n    timeout = setTimeout(later, wait);\n    if (callNow) {\n      func.apply(context, args);\n    }\n  };\n}\n\n/**\n *\n * @param {String} url\n * @return {Boolean}\n */\nfunction isValidUrl(url) {\n  const expression = /[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)/gi;\n  return expression.test(url);\n}\n\nexport default {\n  eq,\n  eq2,\n  peq2,\n  ok,\n  fail,\n  self,\n  not,\n  and,\n  invoke,\n  resetUniqueId,\n  uniqueId,\n  rect2bnd,\n  invertObject,\n  namespaceToCamel,\n  debounce,\n  isValidUrl,\n};\n","import func from './func';\n\n/**\n * returns the first item of an array.\n *\n * @param {Array} array\n */\nfunction head(array) {\n  return array[0];\n}\n\n/**\n * returns the last item of an array.\n *\n * @param {Array} array\n */\nfunction last(array) {\n  return array[array.length - 1];\n}\n\n/**\n * returns everything but the last entry of the array.\n *\n * @param {Array} array\n */\nfunction initial(array) {\n  return array.slice(0, array.length - 1);\n}\n\n/**\n * returns the rest of the items in an array.\n *\n * @param {Array} array\n */\nfunction tail(array) {\n  return array.slice(1);\n}\n\n/**\n * returns item of array\n */\nfunction find(array, pred) {\n  for (let idx = 0, len = array.length; idx < len; idx++) {\n    const item = array[idx];\n    if (pred(item)) {\n      return item;\n    }\n  }\n}\n\n/**\n * returns true if all of the values in the array pass the predicate truth test.\n */\nfunction all(array, pred) {\n  for (let idx = 0, len = array.length; idx < len; idx++) {\n    if (!pred(array[idx])) {\n      return false;\n    }\n  }\n  return true;\n}\n\n/**\n * returns true if the value is present in the list.\n */\nfunction contains(array, item) {\n  if (array && array.length && item) {\n    if (array.indexOf) {\n      return array.indexOf(item) !== -1;\n    } else if (array.contains) {\n      // `DOMTokenList` doesn't implement `.indexOf`, but it implements `.contains`\n      return array.contains(item);\n    }\n  }\n  return false;\n}\n\n/**\n * get sum from a list\n *\n * @param {Array} array - array\n * @param {Function} fn - iterator\n */\nfunction sum(array, fn) {\n  fn = fn || func.self;\n  return array.reduce(function(memo, v) {\n    return memo + fn(v);\n  }, 0);\n}\n\n/**\n * returns a copy of the collection with array type.\n * @param {Collection} collection - collection eg) node.childNodes, ...\n */\nfunction from(collection) {\n  const result = [];\n  const length = collection.length;\n  let idx = -1;\n  while (++idx < length) {\n    result[idx] = collection[idx];\n  }\n  return result;\n}\n\n/**\n * returns whether list is empty or not\n */\nfunction isEmpty(array) {\n  return !array || !array.length;\n}\n\n/**\n * cluster elements by predicate function.\n *\n * @param {Array} array - array\n * @param {Function} fn - predicate function for cluster rule\n * @param {Array[]}\n */\nfunction clusterBy(array, fn) {\n  if (!array.length) { return []; }\n  const aTail = tail(array);\n  return aTail.reduce(function(memo, v) {\n    const aLast = last(memo);\n    if (fn(last(aLast), v)) {\n      aLast[aLast.length] = v;\n    } else {\n      memo[memo.length] = [v];\n    }\n    return memo;\n  }, [[head(array)]]);\n}\n\n/**\n * returns a copy of the array with all false values removed\n *\n * @param {Array} array - array\n * @param {Function} fn - predicate function for cluster rule\n */\nfunction compact(array) {\n  const aResult = [];\n  for (let idx = 0, len = array.length; idx < len; idx++) {\n    if (array[idx]) { aResult.push(array[idx]); }\n  }\n  return aResult;\n}\n\n/**\n * produces a duplicate-free version of the array\n *\n * @param {Array} array\n */\nfunction unique(array) {\n  const results = [];\n\n  for (let idx = 0, len = array.length; idx < len; idx++) {\n    if (!contains(results, array[idx])) {\n      results.push(array[idx]);\n    }\n  }\n\n  return results;\n}\n\n/**\n * returns next item.\n * @param {Array} array\n */\nfunction next(array, item) {\n  if (array && array.length && item) {\n    const idx = array.indexOf(item);\n    return idx === -1 ? null : array[idx + 1];\n  }\n  return null;\n}\n\n/**\n * returns prev item.\n * @param {Array} array\n */\nfunction prev(array, item) {\n  if (array && array.length && item) {\n    const idx = array.indexOf(item);\n    return idx === -1 ? null : array[idx - 1];\n  }\n  return null;\n}\n\n/**\n * @class core.list\n *\n * list utils\n *\n * @singleton\n * @alternateClassName list\n */\nexport default {\n  head,\n  last,\n  initial,\n  tail,\n  prev,\n  next,\n  find,\n  contains,\n  all,\n  sum,\n  from,\n  isEmpty,\n  clusterBy,\n  compact,\n  unique,\n};\n","import $ from 'jquery';\nimport func from './func';\nimport lists from './lists';\nimport env from './env';\n\nconst NBSP_CHAR = String.fromCharCode(160);\nconst ZERO_WIDTH_NBSP_CHAR = '\\ufeff';\n\n/**\n * @method isEditable\n *\n * returns whether node is `note-editable` or not.\n *\n * @param {Node} node\n * @return {Boolean}\n */\nfunction isEditable(node) {\n  return node && $(node).hasClass('note-editable');\n}\n\n/**\n * @method isControlSizing\n *\n * returns whether node is `note-control-sizing` or not.\n *\n * @param {Node} node\n * @return {Boolean}\n */\nfunction isControlSizing(node) {\n  return node && $(node).hasClass('note-control-sizing');\n}\n\n/**\n * @method makePredByNodeName\n *\n * returns predicate which judge whether nodeName is same\n *\n * @param {String} nodeName\n * @return {Function}\n */\nfunction makePredByNodeName(nodeName) {\n  nodeName = nodeName.toUpperCase();\n  return function(node) {\n    return node && node.nodeName.toUpperCase() === nodeName;\n  };\n}\n\n/**\n * @method isText\n *\n *\n *\n * @param {Node} node\n * @return {Boolean} true if node's type is text(3)\n */\nfunction isText(node) {\n  return node && node.nodeType === 3;\n}\n\n/**\n * @method isElement\n *\n *\n *\n * @param {Node} node\n * @return {Boolean} true if node's type is element(1)\n */\nfunction isElement(node) {\n  return node && node.nodeType === 1;\n}\n\n/**\n * ex) br, col, embed, hr, img, input, ...\n * @see http://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements\n */\nfunction isVoid(node) {\n  return node && /^BR|^IMG|^HR|^IFRAME|^BUTTON|^INPUT|^AUDIO|^VIDEO|^EMBED/.test(node.nodeName.toUpperCase());\n}\n\nfunction isPara(node) {\n  if (isEditable(node)) {\n    return false;\n  }\n\n  // Chrome(v31.0), FF(v25.0.1) use DIV for paragraph\n  return node && /^DIV|^P|^LI|^H[1-7]/.test(node.nodeName.toUpperCase());\n}\n\nfunction isHeading(node) {\n  return node && /^H[1-7]/.test(node.nodeName.toUpperCase());\n}\n\nconst isPre = makePredByNodeName('PRE');\n\nconst isLi = makePredByNodeName('LI');\n\nfunction isPurePara(node) {\n  return isPara(node) && !isLi(node);\n}\n\nconst isTable = makePredByNodeName('TABLE');\n\nconst isData = makePredByNodeName('DATA');\n\nfunction isInline(node) {\n  return !isBodyContainer(node) &&\n         !isList(node) &&\n         !isHr(node) &&\n         !isPara(node) &&\n         !isTable(node) &&\n         !isBlockquote(node) &&\n         !isData(node);\n}\n\nfunction isList(node) {\n  return node && /^UL|^OL/.test(node.nodeName.toUpperCase());\n}\n\nconst isHr = makePredByNodeName('HR');\n\nfunction isCell(node) {\n  return node && /^TD|^TH/.test(node.nodeName.toUpperCase());\n}\n\nconst isBlockquote = makePredByNodeName('BLOCKQUOTE');\n\nfunction isBodyContainer(node) {\n  return isCell(node) || isBlockquote(node) || isEditable(node);\n}\n\nconst isAnchor = makePredByNodeName('A');\n\nfunction isParaInline(node) {\n  return isInline(node) && !!ancestor(node, isPara);\n}\n\nfunction isBodyInline(node) {\n  return isInline(node) && !ancestor(node, isPara);\n}\n\nconst isBody = makePredByNodeName('BODY');\n\n/**\n * returns whether nodeB is closest sibling of nodeA\n *\n * @param {Node} nodeA\n * @param {Node} nodeB\n * @return {Boolean}\n */\nfunction isClosestSibling(nodeA, nodeB) {\n  return nodeA.nextSibling === nodeB ||\n         nodeA.previousSibling === nodeB;\n}\n\n/**\n * returns array of closest siblings with node\n *\n * @param {Node} node\n * @param {function} [pred] - predicate function\n * @return {Node[]}\n */\nfunction withClosestSiblings(node, pred) {\n  pred = pred || func.ok;\n\n  const siblings = [];\n  if (node.previousSibling && pred(node.previousSibling)) {\n    siblings.push(node.previousSibling);\n  }\n  siblings.push(node);\n  if (node.nextSibling && pred(node.nextSibling)) {\n    siblings.push(node.nextSibling);\n  }\n  return siblings;\n}\n\n/**\n * blank HTML for cursor position\n * - [workaround] old IE only works with &nbsp;\n * - [workaround] IE11 and other browser works with bogus br\n */\nconst blankHTML = env.isMSIE && env.browserVersion < 11 ? '&nbsp;' : '<br>';\n\n/**\n * @method nodeLength\n *\n * returns #text's text size or element's childNodes size\n *\n * @param {Node} node\n */\nfunction nodeLength(node) {\n  if (isText(node)) {\n    return node.nodeValue.length;\n  }\n\n  if (node) {\n    return node.childNodes.length;\n  }\n\n  return 0;\n}\n\n/**\n * returns whether deepest child node is empty or not.\n *\n * @param {Node} node\n * @return {Boolean}\n */\nfunction deepestChildIsEmpty(node) {\n  do {\n    if (node.firstElementChild === null || node.firstElementChild.innerHTML === '') break;\n  } while ((node = node.firstElementChild));\n\n  return isEmpty(node);\n}\n\n/**\n * returns whether node is empty or not.\n *\n * @param {Node} node\n * @return {Boolean}\n */\nfunction isEmpty(node) {\n  const len = nodeLength(node);\n\n  if (len === 0) {\n    return true;\n  } else if (!isText(node) && len === 1 && node.innerHTML === blankHTML) {\n    // ex) <p><br></p>, <span><br></span>\n    return true;\n  } else if (lists.all(node.childNodes, isText) && node.innerHTML === '') {\n    // ex) <p></p>, <span></span>\n    return true;\n  }\n\n  return false;\n}\n\n/**\n * padding blankHTML if node is empty (for cursor position)\n */\nfunction paddingBlankHTML(node) {\n  if (!isVoid(node) && !nodeLength(node)) {\n    node.innerHTML = blankHTML;\n  }\n}\n\n/**\n * find nearest ancestor predicate hit\n *\n * @param {Node} node\n * @param {Function} pred - predicate function\n */\nfunction ancestor(node, pred) {\n  while (node) {\n    if (pred(node)) { return node; }\n    if (isEditable(node)) { break; }\n\n    node = node.parentNode;\n  }\n  return null;\n}\n\n/**\n * find nearest ancestor only single child blood line and predicate hit\n *\n * @param {Node} node\n * @param {Function} pred - predicate function\n */\nfunction singleChildAncestor(node, pred) {\n  node = node.parentNode;\n\n  while (node) {\n    if (nodeLength(node) !== 1) { break; }\n    if (pred(node)) { return node; }\n    if (isEditable(node)) { break; }\n\n    node = node.parentNode;\n  }\n  return null;\n}\n\n/**\n * returns new array of ancestor nodes (until predicate hit).\n *\n * @param {Node} node\n * @param {Function} [optional] pred - predicate function\n */\nfunction listAncestor(node, pred) {\n  pred = pred || func.fail;\n\n  const ancestors = [];\n  ancestor(node, function(el) {\n    if (!isEditable(el)) {\n      ancestors.push(el);\n    }\n\n    return pred(el);\n  });\n  return ancestors;\n}\n\n/**\n * find farthest ancestor predicate hit\n */\nfunction lastAncestor(node, pred) {\n  const ancestors = listAncestor(node);\n  return lists.last(ancestors.filter(pred));\n}\n\n/**\n * returns common ancestor node between two nodes.\n *\n * @param {Node} nodeA\n * @param {Node} nodeB\n */\nfunction commonAncestor(nodeA, nodeB) {\n  const ancestors = listAncestor(nodeA);\n  for (let n = nodeB; n; n = n.parentNode) {\n    if (ancestors.indexOf(n) > -1) return n;\n  }\n  return null; // difference document area\n}\n\n/**\n * listing all previous siblings (until predicate hit).\n *\n * @param {Node} node\n * @param {Function} [optional] pred - predicate function\n */\nfunction listPrev(node, pred) {\n  pred = pred || func.fail;\n\n  const nodes = [];\n  while (node) {\n    if (pred(node)) { break; }\n    nodes.push(node);\n    node = node.previousSibling;\n  }\n  return nodes;\n}\n\n/**\n * listing next siblings (until predicate hit).\n *\n * @param {Node} node\n * @param {Function} [pred] - predicate function\n */\nfunction listNext(node, pred) {\n  pred = pred || func.fail;\n\n  const nodes = [];\n  while (node) {\n    if (pred(node)) { break; }\n    nodes.push(node);\n    node = node.nextSibling;\n  }\n  return nodes;\n}\n\n/**\n * listing descendant nodes\n *\n * @param {Node} node\n * @param {Function} [pred] - predicate function\n */\nfunction listDescendant(node, pred) {\n  const descendants = [];\n  pred = pred || func.ok;\n\n  // start DFS(depth first search) with node\n  (function fnWalk(current) {\n    if (node !== current && pred(current)) {\n      descendants.push(current);\n    }\n    for (let idx = 0, len = current.childNodes.length; idx < len; idx++) {\n      fnWalk(current.childNodes[idx]);\n    }\n  })(node);\n\n  return descendants;\n}\n\n/**\n * wrap node with new tag.\n *\n * @param {Node} node\n * @param {Node} tagName of wrapper\n * @return {Node} - wrapper\n */\nfunction wrap(node, wrapperName) {\n  const parent = node.parentNode;\n  const wrapper = $('<' + wrapperName + '>')[0];\n\n  parent.insertBefore(wrapper, node);\n  wrapper.appendChild(node);\n\n  return wrapper;\n}\n\n/**\n * insert node after preceding\n *\n * @param {Node} node\n * @param {Node} preceding - predicate function\n */\nfunction insertAfter(node, preceding) {\n  const next = preceding.nextSibling;\n  let parent = preceding.parentNode;\n  if (next) {\n    parent.insertBefore(node, next);\n  } else {\n    parent.appendChild(node);\n  }\n  return node;\n}\n\n/**\n * append elements.\n *\n * @param {Node} node\n * @param {Collection} aChild\n */\nfunction appendChildNodes(node, aChild) {\n  $.each(aChild, function(idx, child) {\n    node.appendChild(child);\n  });\n  return node;\n}\n\n/**\n * returns whether boundaryPoint is left edge or not.\n *\n * @param {BoundaryPoint} point\n * @return {Boolean}\n */\nfunction isLeftEdgePoint(point) {\n  return point.offset === 0;\n}\n\n/**\n * returns whether boundaryPoint is right edge or not.\n *\n * @param {BoundaryPoint} point\n * @return {Boolean}\n */\nfunction isRightEdgePoint(point) {\n  return point.offset === nodeLength(point.node);\n}\n\n/**\n * returns whether boundaryPoint is edge or not.\n *\n * @param {BoundaryPoint} point\n * @return {Boolean}\n */\nfunction isEdgePoint(point) {\n  return isLeftEdgePoint(point) || isRightEdgePoint(point);\n}\n\n/**\n * returns whether node is left edge of ancestor or not.\n *\n * @param {Node} node\n * @param {Node} ancestor\n * @return {Boolean}\n */\nfunction isLeftEdgeOf(node, ancestor) {\n  while (node && node !== ancestor) {\n    if (position(node) !== 0) {\n      return false;\n    }\n    node = node.parentNode;\n  }\n\n  return true;\n}\n\n/**\n * returns whether node is right edge of ancestor or not.\n *\n * @param {Node} node\n * @param {Node} ancestor\n * @return {Boolean}\n */\nfunction isRightEdgeOf(node, ancestor) {\n  if (!ancestor) {\n    return false;\n  }\n  while (node && node !== ancestor) {\n    if (position(node) !== nodeLength(node.parentNode) - 1) {\n      return false;\n    }\n    node = node.parentNode;\n  }\n\n  return true;\n}\n\n/**\n * returns whether point is left edge of ancestor or not.\n * @param {BoundaryPoint} point\n * @param {Node} ancestor\n * @return {Boolean}\n */\nfunction isLeftEdgePointOf(point, ancestor) {\n  return isLeftEdgePoint(point) && isLeftEdgeOf(point.node, ancestor);\n}\n\n/**\n * returns whether point is right edge of ancestor or not.\n * @param {BoundaryPoint} point\n * @param {Node} ancestor\n * @return {Boolean}\n */\nfunction isRightEdgePointOf(point, ancestor) {\n  return isRightEdgePoint(point) && isRightEdgeOf(point.node, ancestor);\n}\n\n/**\n * returns offset from parent.\n *\n * @param {Node} node\n */\nfunction position(node) {\n  let offset = 0;\n  while ((node = node.previousSibling)) {\n    offset += 1;\n  }\n  return offset;\n}\n\nfunction hasChildren(node) {\n  return !!(node && node.childNodes && node.childNodes.length);\n}\n\n/**\n * returns previous boundaryPoint\n *\n * @param {BoundaryPoint} point\n * @param {Boolean} isSkipInnerOffset\n * @return {BoundaryPoint}\n */\nfunction prevPoint(point, isSkipInnerOffset) {\n  let node;\n  let offset;\n\n  if (point.offset === 0) {\n    if (isEditable(point.node)) {\n      return null;\n    }\n\n    node = point.node.parentNode;\n    offset = position(point.node);\n  } else if (hasChildren(point.node)) {\n    node = point.node.childNodes[point.offset - 1];\n    offset = nodeLength(node);\n  } else {\n    node = point.node;\n    offset = isSkipInnerOffset ? 0 : point.offset - 1;\n  }\n\n  return {\n    node: node,\n    offset: offset,\n  };\n}\n\n/**\n * returns next boundaryPoint\n *\n * @param {BoundaryPoint} point\n * @param {Boolean} isSkipInnerOffset\n * @return {BoundaryPoint}\n */\nfunction nextPoint(point, isSkipInnerOffset) {\n  let node, offset;\n\n  if (isEmpty(point.node)) {\n    return null;\n  }\n\n  if (nodeLength(point.node) === point.offset) {\n    if (isEditable(point.node)) {\n      return null;\n    }\n\n    node = point.node.parentNode;\n    offset = position(point.node) + 1;\n  } else if (hasChildren(point.node)) {\n    node = point.node.childNodes[point.offset];\n    offset = 0;\n    if (isEmpty(node)) {\n      return null;\n    }\n  } else {\n    node = point.node;\n    offset = isSkipInnerOffset ? nodeLength(point.node) : point.offset + 1;\n\n    if (isEmpty(node)) {\n      return null;\n    }\n  }\n\n  return {\n    node: node,\n    offset: offset,\n  };\n}\n\n/**\n * returns whether pointA and pointB is same or not.\n *\n * @param {BoundaryPoint} pointA\n * @param {BoundaryPoint} pointB\n * @return {Boolean}\n */\nfunction isSamePoint(pointA, pointB) {\n  return pointA.node === pointB.node && pointA.offset === pointB.offset;\n}\n\n/**\n * returns whether point is visible (can set cursor) or not.\n *\n * @param {BoundaryPoint} point\n * @return {Boolean}\n */\nfunction isVisiblePoint(point) {\n  if (isText(point.node) || !hasChildren(point.node) || isEmpty(point.node)) {\n    return true;\n  }\n\n  const leftNode = point.node.childNodes[point.offset - 1];\n  const rightNode = point.node.childNodes[point.offset];\n  if ((!leftNode || isVoid(leftNode)) && (!rightNode || isVoid(rightNode))) {\n    return true;\n  }\n\n  return false;\n}\n\n/**\n * @method prevPointUtil\n *\n * @param {BoundaryPoint} point\n * @param {Function} pred\n * @return {BoundaryPoint}\n */\nfunction prevPointUntil(point, pred) {\n  while (point) {\n    if (pred(point)) {\n      return point;\n    }\n\n    point = prevPoint(point);\n  }\n\n  return null;\n}\n\n/**\n * @method nextPointUntil\n *\n * @param {BoundaryPoint} point\n * @param {Function} pred\n * @return {BoundaryPoint}\n */\nfunction nextPointUntil(point, pred) {\n  while (point) {\n    if (pred(point)) {\n      return point;\n    }\n\n    point = nextPoint(point);\n  }\n\n  return null;\n}\n\n/**\n * returns whether point has character or not.\n *\n * @param {Point} point\n * @return {Boolean}\n */\nfunction isCharPoint(point) {\n  if (!isText(point.node)) {\n    return false;\n  }\n\n  const ch = point.node.nodeValue.charAt(point.offset - 1);\n  return ch && (ch !== ' ' && ch !== NBSP_CHAR);\n}\n\n/**\n * returns whether point has space or not.\n *\n * @param {Point} point\n * @return {Boolean}\n */\nfunction isSpacePoint(point) {\n  if (!isText(point.node)) {\n    return false;\n  }\n\n  const ch = point.node.nodeValue.charAt(point.offset - 1);\n  return ch === ' ' || ch === NBSP_CHAR;\n}\n\n/**\n * @method walkPoint\n *\n * @param {BoundaryPoint} startPoint\n * @param {BoundaryPoint} endPoint\n * @param {Function} handler\n * @param {Boolean} isSkipInnerOffset\n */\nfunction walkPoint(startPoint, endPoint, handler, isSkipInnerOffset) {\n  let point = startPoint;\n\n  while (point) {\n    handler(point);\n\n    if (isSamePoint(point, endPoint)) {\n      break;\n    }\n\n    const isSkipOffset = isSkipInnerOffset &&\n                       startPoint.node !== point.node &&\n                       endPoint.node !== point.node;\n    point = nextPoint(point, isSkipOffset);\n  }\n}\n\n/**\n * @method makeOffsetPath\n *\n * return offsetPath(array of offset) from ancestor\n *\n * @param {Node} ancestor - ancestor node\n * @param {Node} node\n */\nfunction makeOffsetPath(ancestor, node) {\n  const ancestors = listAncestor(node, func.eq(ancestor));\n  return ancestors.map(position).reverse();\n}\n\n/**\n * @method fromOffsetPath\n *\n * return element from offsetPath(array of offset)\n *\n * @param {Node} ancestor - ancestor node\n * @param {array} offsets - offsetPath\n */\nfunction fromOffsetPath(ancestor, offsets) {\n  let current = ancestor;\n  for (let i = 0, len = offsets.length; i < len; i++) {\n    if (current.childNodes.length <= offsets[i]) {\n      current = current.childNodes[current.childNodes.length - 1];\n    } else {\n      current = current.childNodes[offsets[i]];\n    }\n  }\n  return current;\n}\n\n/**\n * @method splitNode\n *\n * split element or #text\n *\n * @param {BoundaryPoint} point\n * @param {Object} [options]\n * @param {Boolean} [options.isSkipPaddingBlankHTML] - default: false\n * @param {Boolean} [options.isNotSplitEdgePoint] - default: false\n * @param {Boolean} [options.isDiscardEmptySplits] - default: false\n * @return {Node} right node of boundaryPoint\n */\nfunction splitNode(point, options) {\n  let isSkipPaddingBlankHTML = options && options.isSkipPaddingBlankHTML;\n  const isNotSplitEdgePoint = options && options.isNotSplitEdgePoint;\n  const isDiscardEmptySplits = options && options.isDiscardEmptySplits;\n\n  if (isDiscardEmptySplits) {\n    isSkipPaddingBlankHTML = true;\n  }\n\n  // edge case\n  if (isEdgePoint(point) && (isText(point.node) || isNotSplitEdgePoint)) {\n    if (isLeftEdgePoint(point)) {\n      return point.node;\n    } else if (isRightEdgePoint(point)) {\n      return point.node.nextSibling;\n    }\n  }\n\n  // split #text\n  if (isText(point.node)) {\n    return point.node.splitText(point.offset);\n  } else {\n    const childNode = point.node.childNodes[point.offset];\n    const clone = insertAfter(point.node.cloneNode(false), point.node);\n    appendChildNodes(clone, listNext(childNode));\n\n    if (!isSkipPaddingBlankHTML) {\n      paddingBlankHTML(point.node);\n      paddingBlankHTML(clone);\n    }\n\n    if (isDiscardEmptySplits) {\n      if (isEmpty(point.node)) {\n        remove(point.node);\n      }\n      if (isEmpty(clone)) {\n        remove(clone);\n        return point.node.nextSibling;\n      }\n    }\n\n    return clone;\n  }\n}\n\n/**\n * @method splitTree\n *\n * split tree by point\n *\n * @param {Node} root - split root\n * @param {BoundaryPoint} point\n * @param {Object} [options]\n * @param {Boolean} [options.isSkipPaddingBlankHTML] - default: false\n * @param {Boolean} [options.isNotSplitEdgePoint] - default: false\n * @return {Node} right node of boundaryPoint\n */\nfunction splitTree(root, point, options) {\n  // ex) [#text, <span>, <p>]\n  const ancestors = listAncestor(point.node, func.eq(root));\n\n  if (!ancestors.length) {\n    return null;\n  } else if (ancestors.length === 1) {\n    return splitNode(point, options);\n  }\n\n  return ancestors.reduce(function(node, parent) {\n    if (node === point.node) {\n      node = splitNode(point, options);\n    }\n\n    return splitNode({\n      node: parent,\n      offset: node ? position(node) : nodeLength(parent),\n    }, options);\n  });\n}\n\n/**\n * split point\n *\n * @param {Point} point\n * @param {Boolean} isInline\n * @return {Object}\n */\nfunction splitPoint(point, isInline) {\n  // find splitRoot, container\n  //  - inline: splitRoot is a child of paragraph\n  //  - block: splitRoot is a child of bodyContainer\n  const pred = isInline ? isPara : isBodyContainer;\n  const ancestors = listAncestor(point.node, pred);\n  const topAncestor = lists.last(ancestors) || point.node;\n\n  let splitRoot, container;\n  if (pred(topAncestor)) {\n    splitRoot = ancestors[ancestors.length - 2];\n    container = topAncestor;\n  } else {\n    splitRoot = topAncestor;\n    container = splitRoot.parentNode;\n  }\n\n  // if splitRoot is exists, split with splitTree\n  let pivot = splitRoot && splitTree(splitRoot, point, {\n    isSkipPaddingBlankHTML: isInline,\n    isNotSplitEdgePoint: isInline,\n  });\n\n  // if container is point.node, find pivot with point.offset\n  if (!pivot && container === point.node) {\n    pivot = point.node.childNodes[point.offset];\n  }\n\n  return {\n    rightNode: pivot,\n    container: container,\n  };\n}\n\nfunction create(nodeName) {\n  return document.createElement(nodeName);\n}\n\nfunction createText(text) {\n  return document.createTextNode(text);\n}\n\n/**\n * @method remove\n *\n * remove node, (isRemoveChild: remove child or not)\n *\n * @param {Node} node\n * @param {Boolean} isRemoveChild\n */\nfunction remove(node, isRemoveChild) {\n  if (!node || !node.parentNode) { return; }\n  if (node.removeNode) { return node.removeNode(isRemoveChild); }\n\n  const parent = node.parentNode;\n  if (!isRemoveChild) {\n    const nodes = [];\n    for (let i = 0, len = node.childNodes.length; i < len; i++) {\n      nodes.push(node.childNodes[i]);\n    }\n\n    for (let i = 0, len = nodes.length; i < len; i++) {\n      parent.insertBefore(nodes[i], node);\n    }\n  }\n\n  parent.removeChild(node);\n}\n\n/**\n * @method removeWhile\n *\n * @param {Node} node\n * @param {Function} pred\n */\nfunction removeWhile(node, pred) {\n  while (node) {\n    if (isEditable(node) || !pred(node)) {\n      break;\n    }\n\n    const parent = node.parentNode;\n    remove(node);\n    node = parent;\n  }\n}\n\n/**\n * @method replace\n *\n * replace node with provided nodeName\n *\n * @param {Node} node\n * @param {String} nodeName\n * @return {Node} - new node\n */\nfunction replace(node, nodeName) {\n  if (node.nodeName.toUpperCase() === nodeName.toUpperCase()) {\n    return node;\n  }\n\n  const newNode = create(nodeName);\n\n  if (node.style.cssText) {\n    newNode.style.cssText = node.style.cssText;\n  }\n\n  appendChildNodes(newNode, lists.from(node.childNodes));\n  insertAfter(newNode, node);\n  remove(node);\n\n  return newNode;\n}\n\nconst isTextarea = makePredByNodeName('TEXTAREA');\n\n/**\n * @param {jQuery} $node\n * @param {Boolean} [stripLinebreaks] - default: false\n */\nfunction value($node, stripLinebreaks) {\n  const val = isTextarea($node[0]) ? $node.val() : $node.html();\n  if (stripLinebreaks) {\n    return val.replace(/[\\n\\r]/g, '');\n  }\n  return val;\n}\n\n/**\n * @method html\n *\n * get the HTML contents of node\n *\n * @param {jQuery} $node\n * @param {Boolean} [isNewlineOnBlock]\n */\nfunction html($node, isNewlineOnBlock) {\n  let markup = value($node);\n\n  if (isNewlineOnBlock) {\n    const regexTag = /<(\\/?)(\\b(?!!)[^>\\s]*)(.*?)(\\s*\\/?>)/g;\n    markup = markup.replace(regexTag, function(match, endSlash, name) {\n      name = name.toUpperCase();\n      const isEndOfInlineContainer = /^DIV|^TD|^TH|^P|^LI|^H[1-7]/.test(name) &&\n                                   !!endSlash;\n      const isBlockNode = /^BLOCKQUOTE|^TABLE|^TBODY|^TR|^HR|^UL|^OL/.test(name);\n\n      return match + ((isEndOfInlineContainer || isBlockNode) ? '\\n' : '');\n    });\n    markup = markup.trim();\n  }\n\n  return markup;\n}\n\nfunction posFromPlaceholder(placeholder) {\n  const $placeholder = $(placeholder);\n  const pos = $placeholder.offset();\n  const height = $placeholder.outerHeight(true); // include margin\n\n  return {\n    left: pos.left,\n    top: pos.top + height,\n  };\n}\n\nfunction attachEvents($node, events) {\n  Object.keys(events).forEach(function(key) {\n    $node.on(key, events[key]);\n  });\n}\n\nfunction detachEvents($node, events) {\n  Object.keys(events).forEach(function(key) {\n    $node.off(key, events[key]);\n  });\n}\n\n/**\n * @method isCustomStyleTag\n *\n * assert if a node contains a \"note-styletag\" class,\n * which implies that's a custom-made style tag node\n *\n * @param {Node} an HTML DOM node\n */\nfunction isCustomStyleTag(node) {\n  return node && !isText(node) && lists.contains(node.classList, 'note-styletag');\n}\n\nexport default {\n  /** @property {String} NBSP_CHAR */\n  NBSP_CHAR,\n  /** @property {String} ZERO_WIDTH_NBSP_CHAR */\n  ZERO_WIDTH_NBSP_CHAR,\n  /** @property {String} blank */\n  blank: blankHTML,\n  /** @property {String} emptyPara */\n  emptyPara: `<p>${blankHTML}</p>`,\n  makePredByNodeName,\n  isEditable,\n  isControlSizing,\n  isText,\n  isElement,\n  isVoid,\n  isPara,\n  isPurePara,\n  isHeading,\n  isInline,\n  isBlock: func.not(isInline),\n  isBodyInline,\n  isBody,\n  isParaInline,\n  isPre,\n  isList,\n  isTable,\n  isData,\n  isCell,\n  isBlockquote,\n  isBodyContainer,\n  isAnchor,\n  isDiv: makePredByNodeName('DIV'),\n  isLi,\n  isBR: makePredByNodeName('BR'),\n  isSpan: makePredByNodeName('SPAN'),\n  isB: makePredByNodeName('B'),\n  isU: makePredByNodeName('U'),\n  isS: makePredByNodeName('S'),\n  isI: makePredByNodeName('I'),\n  isImg: makePredByNodeName('IMG'),\n  isTextarea,\n  deepestChildIsEmpty,\n  isEmpty,\n  isEmptyAnchor: func.and(isAnchor, isEmpty),\n  isClosestSibling,\n  withClosestSiblings,\n  nodeLength,\n  isLeftEdgePoint,\n  isRightEdgePoint,\n  isEdgePoint,\n  isLeftEdgeOf,\n  isRightEdgeOf,\n  isLeftEdgePointOf,\n  isRightEdgePointOf,\n  prevPoint,\n  nextPoint,\n  isSamePoint,\n  isVisiblePoint,\n  prevPointUntil,\n  nextPointUntil,\n  isCharPoint,\n  isSpacePoint,\n  walkPoint,\n  ancestor,\n  singleChildAncestor,\n  listAncestor,\n  lastAncestor,\n  listNext,\n  listPrev,\n  listDescendant,\n  commonAncestor,\n  wrap,\n  insertAfter,\n  appendChildNodes,\n  position,\n  hasChildren,\n  makeOffsetPath,\n  fromOffsetPath,\n  splitTree,\n  splitPoint,\n  create,\n  createText,\n  remove,\n  removeWhile,\n  replace,\n  html,\n  value,\n  posFromPlaceholder,\n  attachEvents,\n  detachEvents,\n  isCustomStyleTag,\n};\n","import $ from 'jquery';\nimport func from './core/func';\nimport lists from './core/lists';\nimport dom from './core/dom';\n\nexport default class Context {\n  /**\n   * @param {jQuery} $note\n   * @param {Object} options\n   */\n  constructor($note, options) {\n    this.$note = $note;\n\n    this.memos = {};\n    this.modules = {};\n    this.layoutInfo = {};\n    this.options = $.extend(true, {}, options);\n\n    // init ui with options\n    $.summernote.ui = $.summernote.ui_template(this.options);\n    this.ui = $.summernote.ui;\n\n    this.initialize();\n  }\n\n  /**\n   * create layout and initialize modules and other resources\n   */\n  initialize() {\n    this.layoutInfo = this.ui.createLayout(this.$note);\n    this._initialize();\n    this.$note.hide();\n    return this;\n  }\n\n  /**\n   * destroy modules and other resources and remove layout\n   */\n  destroy() {\n    this._destroy();\n    this.$note.removeData('summernote');\n    this.ui.removeLayout(this.$note, this.layoutInfo);\n  }\n\n  /**\n   * destory modules and other resources and initialize it again\n   */\n  reset() {\n    const disabled = this.isDisabled();\n    this.code(dom.emptyPara);\n    this._destroy();\n    this._initialize();\n\n    if (disabled) {\n      this.disable();\n    }\n  }\n\n  _initialize() {\n    // set own id\n    this.options.id = func.uniqueId($.now());\n    // set default container for tooltips, popovers, and dialogs\n    this.options.container = this.options.container || this.layoutInfo.editor;\n\n    // add optional buttons\n    const buttons = $.extend({}, this.options.buttons);\n    Object.keys(buttons).forEach((key) => {\n      this.memo('button.' + key, buttons[key]);\n    });\n\n    const modules = $.extend({}, this.options.modules, $.summernote.plugins || {});\n\n    // add and initialize modules\n    Object.keys(modules).forEach((key) => {\n      this.module(key, modules[key], true);\n    });\n\n    Object.keys(this.modules).forEach((key) => {\n      this.initializeModule(key);\n    });\n  }\n\n  _destroy() {\n    // destroy modules with reversed order\n    Object.keys(this.modules).reverse().forEach((key) => {\n      this.removeModule(key);\n    });\n\n    Object.keys(this.memos).forEach((key) => {\n      this.removeMemo(key);\n    });\n    // trigger custom onDestroy callback\n    this.triggerEvent('destroy', this);\n  }\n\n  code(html) {\n    const isActivated = this.invoke('codeview.isActivated');\n\n    if (html === undefined) {\n      this.invoke('codeview.sync');\n      return isActivated ? this.layoutInfo.codable.val() : this.layoutInfo.editable.html();\n    } else {\n      if (isActivated) {\n        this.layoutInfo.codable.val(html);\n      } else {\n        this.layoutInfo.editable.html(html);\n      }\n      this.$note.val(html);\n      this.triggerEvent('change', html, this.layoutInfo.editable);\n    }\n  }\n\n  isDisabled() {\n    return this.layoutInfo.editable.attr('contenteditable') === 'false';\n  }\n\n  enable() {\n    this.layoutInfo.editable.attr('contenteditable', true);\n    this.invoke('toolbar.activate', true);\n    this.triggerEvent('disable', false);\n    this.options.editing = true;\n  }\n\n  disable() {\n    // close codeview if codeview is opend\n    if (this.invoke('codeview.isActivated')) {\n      this.invoke('codeview.deactivate');\n    }\n    this.layoutInfo.editable.attr('contenteditable', false);\n    this.options.editing = false;\n    this.invoke('toolbar.deactivate', true);\n\n    this.triggerEvent('disable', true);\n  }\n\n  triggerEvent() {\n    const namespace = lists.head(arguments);\n    const args = lists.tail(lists.from(arguments));\n\n    const callback = this.options.callbacks[func.namespaceToCamel(namespace, 'on')];\n    if (callback) {\n      callback.apply(this.$note[0], args);\n    }\n    this.$note.trigger('summernote.' + namespace, args);\n  }\n\n  initializeModule(key) {\n    const module = this.modules[key];\n    module.shouldInitialize = module.shouldInitialize || func.ok;\n    if (!module.shouldInitialize()) {\n      return;\n    }\n\n    // initialize module\n    if (module.initialize) {\n      module.initialize();\n    }\n\n    // attach events\n    if (module.events) {\n      dom.attachEvents(this.$note, module.events);\n    }\n  }\n\n  module(key, ModuleClass, withoutIntialize) {\n    if (arguments.length === 1) {\n      return this.modules[key];\n    }\n\n    this.modules[key] = new ModuleClass(this);\n\n    if (!withoutIntialize) {\n      this.initializeModule(key);\n    }\n  }\n\n  removeModule(key) {\n    const module = this.modules[key];\n    if (module.shouldInitialize()) {\n      if (module.events) {\n        dom.detachEvents(this.$note, module.events);\n      }\n\n      if (module.destroy) {\n        module.destroy();\n      }\n    }\n\n    delete this.modules[key];\n  }\n\n  memo(key, obj) {\n    if (arguments.length === 1) {\n      return this.memos[key];\n    }\n    this.memos[key] = obj;\n  }\n\n  removeMemo(key) {\n    if (this.memos[key] && this.memos[key].destroy) {\n      this.memos[key].destroy();\n    }\n\n    delete this.memos[key];\n  }\n\n  /**\n   * Some buttons need to change their visual style immediately once they get pressed\n   */\n  createInvokeHandlerAndUpdateState(namespace, value) {\n    return (event) => {\n      this.createInvokeHandler(namespace, value)(event);\n      this.invoke('buttons.updateCurrentStyle');\n    };\n  }\n\n  createInvokeHandler(namespace, value) {\n    return (event) => {\n      event.preventDefault();\n      const $target = $(event.target);\n      this.invoke(namespace, value || $target.closest('[data-value]').data('value'), $target);\n    };\n  }\n\n  invoke() {\n    const namespace = lists.head(arguments);\n    const args = lists.tail(lists.from(arguments));\n\n    const splits = namespace.split('.');\n    const hasSeparator = splits.length > 1;\n    const moduleName = hasSeparator && lists.head(splits);\n    const methodName = hasSeparator ? lists.last(splits) : lists.head(splits);\n\n    const module = this.modules[moduleName || 'editor'];\n    if (!moduleName && this[methodName]) {\n      return this[methodName].apply(this, args);\n    } else if (module && module[methodName] && module.shouldInitialize()) {\n      return module[methodName].apply(module, args);\n    }\n  }\n}\n","import $ from 'jquery';\nimport env from './env';\nimport func from './func';\nimport lists from './lists';\nimport dom from './dom';\n\n/**\n * return boundaryPoint from TextRange, inspired by Andy Na's HuskyRange.js\n *\n * @param {TextRange} textRange\n * @param {Boolean} isStart\n * @return {BoundaryPoint}\n *\n * @see http://msdn.microsoft.com/en-us/library/ie/ms535872(v=vs.85).aspx\n */\nfunction textRangeToPoint(textRange, isStart) {\n  let container = textRange.parentElement();\n  let offset;\n\n  const tester = document.body.createTextRange();\n  let prevContainer;\n  const childNodes = lists.from(container.childNodes);\n  for (offset = 0; offset < childNodes.length; offset++) {\n    if (dom.isText(childNodes[offset])) {\n      continue;\n    }\n    tester.moveToElementText(childNodes[offset]);\n    if (tester.compareEndPoints('StartToStart', textRange) >= 0) {\n      break;\n    }\n    prevContainer = childNodes[offset];\n  }\n\n  if (offset !== 0 && dom.isText(childNodes[offset - 1])) {\n    const textRangeStart = document.body.createTextRange();\n    let curTextNode = null;\n    textRangeStart.moveToElementText(prevContainer || container);\n    textRangeStart.collapse(!prevContainer);\n    curTextNode = prevContainer ? prevContainer.nextSibling : container.firstChild;\n\n    const pointTester = textRange.duplicate();\n    pointTester.setEndPoint('StartToStart', textRangeStart);\n    let textCount = pointTester.text.replace(/[\\r\\n]/g, '').length;\n\n    while (textCount > curTextNode.nodeValue.length && curTextNode.nextSibling) {\n      textCount -= curTextNode.nodeValue.length;\n      curTextNode = curTextNode.nextSibling;\n    }\n\n    // [workaround] enforce IE to re-reference curTextNode, hack\n    const dummy = curTextNode.nodeValue; // eslint-disable-line\n\n    if (isStart && curTextNode.nextSibling && dom.isText(curTextNode.nextSibling) &&\n      textCount === curTextNode.nodeValue.length) {\n      textCount -= curTextNode.nodeValue.length;\n      curTextNode = curTextNode.nextSibling;\n    }\n\n    container = curTextNode;\n    offset = textCount;\n  }\n\n  return {\n    cont: container,\n    offset: offset,\n  };\n}\n\n/**\n * return TextRange from boundary point (inspired by google closure-library)\n * @param {BoundaryPoint} point\n * @return {TextRange}\n */\nfunction pointToTextRange(point) {\n  const textRangeInfo = function(container, offset) {\n    let node, isCollapseToStart;\n\n    if (dom.isText(container)) {\n      const prevTextNodes = dom.listPrev(container, func.not(dom.isText));\n      const prevContainer = lists.last(prevTextNodes).previousSibling;\n      node = prevContainer || container.parentNode;\n      offset += lists.sum(lists.tail(prevTextNodes), dom.nodeLength);\n      isCollapseToStart = !prevContainer;\n    } else {\n      node = container.childNodes[offset] || container;\n      if (dom.isText(node)) {\n        return textRangeInfo(node, 0);\n      }\n\n      offset = 0;\n      isCollapseToStart = false;\n    }\n\n    return {\n      node: node,\n      collapseToStart: isCollapseToStart,\n      offset: offset,\n    };\n  };\n\n  const textRange = document.body.createTextRange();\n  const info = textRangeInfo(point.node, point.offset);\n\n  textRange.moveToElementText(info.node);\n  textRange.collapse(info.collapseToStart);\n  textRange.moveStart('character', info.offset);\n  return textRange;\n}\n\n/**\n   * Wrapped Range\n   *\n   * @constructor\n   * @param {Node} sc - start container\n   * @param {Number} so - start offset\n   * @param {Node} ec - end container\n   * @param {Number} eo - end offset\n   */\nclass WrappedRange {\n  constructor(sc, so, ec, eo) {\n    this.sc = sc;\n    this.so = so;\n    this.ec = ec;\n    this.eo = eo;\n\n    // isOnEditable: judge whether range is on editable or not\n    this.isOnEditable = this.makeIsOn(dom.isEditable);\n    // isOnList: judge whether range is on list node or not\n    this.isOnList = this.makeIsOn(dom.isList);\n    // isOnAnchor: judge whether range is on anchor node or not\n    this.isOnAnchor = this.makeIsOn(dom.isAnchor);\n    // isOnCell: judge whether range is on cell node or not\n    this.isOnCell = this.makeIsOn(dom.isCell);\n    // isOnData: judge whether range is on data node or not\n    this.isOnData = this.makeIsOn(dom.isData);\n  }\n\n  // nativeRange: get nativeRange from sc, so, ec, eo\n  nativeRange() {\n    if (env.isW3CRangeSupport) {\n      const w3cRange = document.createRange();\n      w3cRange.setStart(this.sc, this.sc.data && this.so > this.sc.data.length ? 0 : this.so);\n      w3cRange.setEnd(this.ec, this.sc.data ? Math.min(this.eo, this.sc.data.length) : this.eo);\n\n      return w3cRange;\n    } else {\n      const textRange = pointToTextRange({\n        node: this.sc,\n        offset: this.so,\n      });\n\n      textRange.setEndPoint('EndToEnd', pointToTextRange({\n        node: this.ec,\n        offset: this.eo,\n      }));\n\n      return textRange;\n    }\n  }\n\n  getPoints() {\n    return {\n      sc: this.sc,\n      so: this.so,\n      ec: this.ec,\n      eo: this.eo,\n    };\n  }\n\n  getStartPoint() {\n    return {\n      node: this.sc,\n      offset: this.so,\n    };\n  }\n\n  getEndPoint() {\n    return {\n      node: this.ec,\n      offset: this.eo,\n    };\n  }\n\n  /**\n   * select update visible range\n   */\n  select() {\n    const nativeRng = this.nativeRange();\n    if (env.isW3CRangeSupport) {\n      const selection = document.getSelection();\n      if (selection.rangeCount > 0) {\n        selection.removeAllRanges();\n      }\n      selection.addRange(nativeRng);\n    } else {\n      nativeRng.select();\n    }\n\n    return this;\n  }\n\n  /**\n   * Moves the scrollbar to start container(sc) of current range\n   *\n   * @return {WrappedRange}\n   */\n  scrollIntoView(container) {\n    const height = $(container).height();\n    if (container.scrollTop + height < this.sc.offsetTop) {\n      container.scrollTop += Math.abs(container.scrollTop + height - this.sc.offsetTop);\n    }\n\n    return this;\n  }\n\n  /**\n   * @return {WrappedRange}\n   */\n  normalize() {\n    /**\n     * @param {BoundaryPoint} point\n     * @param {Boolean} isLeftToRight - true: prefer to choose right node\n     *                                - false: prefer to choose left node\n     * @return {BoundaryPoint}\n     */\n    const getVisiblePoint = function(point, isLeftToRight) {\n      if (!point) {\n        return point;\n      }\n\n      // Just use the given point [XXX:Adhoc]\n      //  - case 01. if the point is on the middle of the node\n      //  - case 02. if the point is on the right edge and prefer to choose left node\n      //  - case 03. if the point is on the left edge and prefer to choose right node\n      //  - case 04. if the point is on the right edge and prefer to choose right node but the node is void\n      //  - case 05. if the point is on the left edge and prefer to choose left node but the node is void\n      //  - case 06. if the point is on the block node and there is no children\n      if (dom.isVisiblePoint(point)) {\n        if (!dom.isEdgePoint(point) ||\n            (dom.isRightEdgePoint(point) && !isLeftToRight) ||\n            (dom.isLeftEdgePoint(point) && isLeftToRight) ||\n            (dom.isRightEdgePoint(point) && isLeftToRight && dom.isVoid(point.node.nextSibling)) ||\n            (dom.isLeftEdgePoint(point) && !isLeftToRight && dom.isVoid(point.node.previousSibling)) ||\n            (dom.isBlock(point.node) && dom.isEmpty(point.node))) {\n          return point;\n        }\n      }\n\n      // point on block's edge\n      const block = dom.ancestor(point.node, dom.isBlock);\n      let hasRightNode = false;\n\n      if (!hasRightNode) {\n        const prevPoint = dom.prevPoint(point) || { node: null };\n        hasRightNode = (dom.isLeftEdgePointOf(point, block) || dom.isVoid(prevPoint.node)) && !isLeftToRight;\n      }\n\n      let hasLeftNode = false;\n      if (!hasLeftNode) {\n        const nextPoint = dom.nextPoint(point) || { node: null };\n        hasLeftNode = (dom.isRightEdgePointOf(point, block) || dom.isVoid(nextPoint.node)) && isLeftToRight;\n      }\n\n      if (hasRightNode || hasLeftNode) {\n        // returns point already on visible point\n        if (dom.isVisiblePoint(point)) {\n          return point;\n        }\n        // reverse direction\n        isLeftToRight = !isLeftToRight;\n      }\n\n      const nextPoint = isLeftToRight ? dom.nextPointUntil(dom.nextPoint(point), dom.isVisiblePoint)\n        : dom.prevPointUntil(dom.prevPoint(point), dom.isVisiblePoint);\n      return nextPoint || point;\n    };\n\n    const endPoint = getVisiblePoint(this.getEndPoint(), false);\n    const startPoint = this.isCollapsed() ? endPoint : getVisiblePoint(this.getStartPoint(), true);\n\n    return new WrappedRange(\n      startPoint.node,\n      startPoint.offset,\n      endPoint.node,\n      endPoint.offset\n    );\n  }\n\n  /**\n   * returns matched nodes on range\n   *\n   * @param {Function} [pred] - predicate function\n   * @param {Object} [options]\n   * @param {Boolean} [options.includeAncestor]\n   * @param {Boolean} [options.fullyContains]\n   * @return {Node[]}\n   */\n  nodes(pred, options) {\n    pred = pred || func.ok;\n\n    const includeAncestor = options && options.includeAncestor;\n    const fullyContains = options && options.fullyContains;\n\n    // TODO compare points and sort\n    const startPoint = this.getStartPoint();\n    const endPoint = this.getEndPoint();\n\n    const nodes = [];\n    const leftEdgeNodes = [];\n\n    dom.walkPoint(startPoint, endPoint, function(point) {\n      if (dom.isEditable(point.node)) {\n        return;\n      }\n\n      let node;\n      if (fullyContains) {\n        if (dom.isLeftEdgePoint(point)) {\n          leftEdgeNodes.push(point.node);\n        }\n        if (dom.isRightEdgePoint(point) && lists.contains(leftEdgeNodes, point.node)) {\n          node = point.node;\n        }\n      } else if (includeAncestor) {\n        node = dom.ancestor(point.node, pred);\n      } else {\n        node = point.node;\n      }\n\n      if (node && pred(node)) {\n        nodes.push(node);\n      }\n    }, true);\n\n    return lists.unique(nodes);\n  }\n\n  /**\n   * returns commonAncestor of range\n   * @return {Element} - commonAncestor\n   */\n  commonAncestor() {\n    return dom.commonAncestor(this.sc, this.ec);\n  }\n\n  /**\n   * returns expanded range by pred\n   *\n   * @param {Function} pred - predicate function\n   * @return {WrappedRange}\n   */\n  expand(pred) {\n    const startAncestor = dom.ancestor(this.sc, pred);\n    const endAncestor = dom.ancestor(this.ec, pred);\n\n    if (!startAncestor && !endAncestor) {\n      return new WrappedRange(this.sc, this.so, this.ec, this.eo);\n    }\n\n    const boundaryPoints = this.getPoints();\n\n    if (startAncestor) {\n      boundaryPoints.sc = startAncestor;\n      boundaryPoints.so = 0;\n    }\n\n    if (endAncestor) {\n      boundaryPoints.ec = endAncestor;\n      boundaryPoints.eo = dom.nodeLength(endAncestor);\n    }\n\n    return new WrappedRange(\n      boundaryPoints.sc,\n      boundaryPoints.so,\n      boundaryPoints.ec,\n      boundaryPoints.eo\n    );\n  }\n\n  /**\n   * @param {Boolean} isCollapseToStart\n   * @return {WrappedRange}\n   */\n  collapse(isCollapseToStart) {\n    if (isCollapseToStart) {\n      return new WrappedRange(this.sc, this.so, this.sc, this.so);\n    } else {\n      return new WrappedRange(this.ec, this.eo, this.ec, this.eo);\n    }\n  }\n\n  /**\n   * splitText on range\n   */\n  splitText() {\n    const isSameContainer = this.sc === this.ec;\n    const boundaryPoints = this.getPoints();\n\n    if (dom.isText(this.ec) && !dom.isEdgePoint(this.getEndPoint())) {\n      this.ec.splitText(this.eo);\n    }\n\n    if (dom.isText(this.sc) && !dom.isEdgePoint(this.getStartPoint())) {\n      boundaryPoints.sc = this.sc.splitText(this.so);\n      boundaryPoints.so = 0;\n\n      if (isSameContainer) {\n        boundaryPoints.ec = boundaryPoints.sc;\n        boundaryPoints.eo = this.eo - this.so;\n      }\n    }\n\n    return new WrappedRange(\n      boundaryPoints.sc,\n      boundaryPoints.so,\n      boundaryPoints.ec,\n      boundaryPoints.eo\n    );\n  }\n\n  /**\n   * delete contents on range\n   * @return {WrappedRange}\n   */\n  deleteContents() {\n    if (this.isCollapsed()) {\n      return this;\n    }\n\n    const rng = this.splitText();\n    const nodes = rng.nodes(null, {\n      fullyContains: true,\n    });\n\n    // find new cursor point\n    const point = dom.prevPointUntil(rng.getStartPoint(), function(point) {\n      return !lists.contains(nodes, point.node);\n    });\n\n    const emptyParents = [];\n    $.each(nodes, function(idx, node) {\n      // find empty parents\n      const parent = node.parentNode;\n      if (point.node !== parent && dom.nodeLength(parent) === 1) {\n        emptyParents.push(parent);\n      }\n      dom.remove(node, false);\n    });\n\n    // remove empty parents\n    $.each(emptyParents, function(idx, node) {\n      dom.remove(node, false);\n    });\n\n    return new WrappedRange(\n      point.node,\n      point.offset,\n      point.node,\n      point.offset\n    ).normalize();\n  }\n\n  /**\n   * makeIsOn: return isOn(pred) function\n   */\n  makeIsOn(pred) {\n    return function() {\n      const ancestor = dom.ancestor(this.sc, pred);\n      return !!ancestor && (ancestor === dom.ancestor(this.ec, pred));\n    };\n  }\n\n  /**\n   * @param {Function} pred\n   * @return {Boolean}\n   */\n  isLeftEdgeOf(pred) {\n    if (!dom.isLeftEdgePoint(this.getStartPoint())) {\n      return false;\n    }\n\n    const node = dom.ancestor(this.sc, pred);\n    return node && dom.isLeftEdgeOf(this.sc, node);\n  }\n\n  /**\n   * returns whether range was collapsed or not\n   */\n  isCollapsed() {\n    return this.sc === this.ec && this.so === this.eo;\n  }\n\n  /**\n   * wrap inline nodes which children of body with paragraph\n   *\n   * @return {WrappedRange}\n   */\n  wrapBodyInlineWithPara() {\n    if (dom.isBodyContainer(this.sc) && dom.isEmpty(this.sc)) {\n      this.sc.innerHTML = dom.emptyPara;\n      return new WrappedRange(this.sc.firstChild, 0, this.sc.firstChild, 0);\n    }\n\n    /**\n     * [workaround] firefox often create range on not visible point. so normalize here.\n     *  - firefox: |<p>text</p>|\n     *  - chrome: <p>|text|</p>\n     */\n    const rng = this.normalize();\n    if (dom.isParaInline(this.sc) || dom.isPara(this.sc)) {\n      return rng;\n    }\n\n    // find inline top ancestor\n    let topAncestor;\n    if (dom.isInline(rng.sc)) {\n      const ancestors = dom.listAncestor(rng.sc, func.not(dom.isInline));\n      topAncestor = lists.last(ancestors);\n      if (!dom.isInline(topAncestor)) {\n        topAncestor = ancestors[ancestors.length - 2] || rng.sc.childNodes[rng.so];\n      }\n    } else {\n      topAncestor = rng.sc.childNodes[rng.so > 0 ? rng.so - 1 : 0];\n    }\n\n    if (topAncestor) {\n      // siblings not in paragraph\n      let inlineSiblings = dom.listPrev(topAncestor, dom.isParaInline).reverse();\n      inlineSiblings = inlineSiblings.concat(dom.listNext(topAncestor.nextSibling, dom.isParaInline));\n\n      // wrap with paragraph\n      if (inlineSiblings.length) {\n        const para = dom.wrap(lists.head(inlineSiblings), 'p');\n        dom.appendChildNodes(para, lists.tail(inlineSiblings));\n      }\n    }\n\n    return this.normalize();\n  }\n\n  /**\n   * insert node at current cursor\n   *\n   * @param {Node} node\n   * @return {Node}\n   */\n  insertNode(node) {\n    let rng = this;\n\n    if (dom.isText(node) || dom.isInline(node)) {\n      rng = this.wrapBodyInlineWithPara().deleteContents();\n    }\n\n    const info = dom.splitPoint(rng.getStartPoint(), dom.isInline(node));\n    if (info.rightNode) {\n      info.rightNode.parentNode.insertBefore(node, info.rightNode);\n    } else {\n      info.container.appendChild(node);\n    }\n\n    return node;\n  }\n\n  /**\n   * insert html at current cursor\n   */\n  pasteHTML(markup) {\n    markup = $.trim(markup);\n\n    const contentsContainer = $('<div></div>').html(markup)[0];\n    let childNodes = lists.from(contentsContainer.childNodes);\n\n    // const rng = this.wrapBodyInlineWithPara().deleteContents();\n    const rng = this;\n\n    if (rng.so >= 0) {\n      childNodes = childNodes.reverse();\n    }\n    childNodes = childNodes.map(function(childNode) {\n      return rng.insertNode(childNode);\n    });\n    if (rng.so > 0) {\n      childNodes = childNodes.reverse();\n    }\n    return childNodes;\n  }\n\n  /**\n   * returns text in range\n   *\n   * @return {String}\n   */\n  toString() {\n    const nativeRng = this.nativeRange();\n    return env.isW3CRangeSupport ? nativeRng.toString() : nativeRng.text;\n  }\n\n  /**\n   * returns range for word before cursor\n   *\n   * @param {Boolean} [findAfter] - find after cursor, default: false\n   * @return {WrappedRange}\n   */\n  getWordRange(findAfter) {\n    let endPoint = this.getEndPoint();\n\n    if (!dom.isCharPoint(endPoint)) {\n      return this;\n    }\n\n    const startPoint = dom.prevPointUntil(endPoint, function(point) {\n      return !dom.isCharPoint(point);\n    });\n\n    if (findAfter) {\n      endPoint = dom.nextPointUntil(endPoint, function(point) {\n        return !dom.isCharPoint(point);\n      });\n    }\n\n    return new WrappedRange(\n      startPoint.node,\n      startPoint.offset,\n      endPoint.node,\n      endPoint.offset\n    );\n  }\n\n  /**\n   * returns range for words before cursor\n   *\n   * @param {Boolean} [findAfter] - find after cursor, default: false\n   * @return {WrappedRange}\n   */\n  getWordsRange(findAfter) {\n    var endPoint = this.getEndPoint();\n\n    var isNotTextPoint = function(point) {\n      return !dom.isCharPoint(point) && !dom.isSpacePoint(point);\n    };\n\n    if (isNotTextPoint(endPoint)) {\n      return this;\n    }\n\n    var startPoint = dom.prevPointUntil(endPoint, isNotTextPoint);\n\n    if (findAfter) {\n      endPoint = dom.nextPointUntil(endPoint, isNotTextPoint);\n    }\n\n    return new WrappedRange(\n      startPoint.node,\n      startPoint.offset,\n      endPoint.node,\n      endPoint.offset\n    );\n  }\n\n  /**\n   * returns range for words before cursor that match with a Regex\n   *\n   * example:\n   *  range: 'hi @Peter Pan'\n   *  regex: '/@[a-z ]+/i'\n   *  return range: '@Peter Pan'\n   *\n   * @param {RegExp} [regex]\n   * @return {WrappedRange|null}\n   */\n  getWordsMatchRange(regex) {\n    var endPoint = this.getEndPoint();\n\n    var startPoint = dom.prevPointUntil(endPoint, function(point) {\n      if (!dom.isCharPoint(point) && !dom.isSpacePoint(point)) {\n        return true;\n      }\n      var rng = new WrappedRange(\n        point.node,\n        point.offset,\n        endPoint.node,\n        endPoint.offset\n      );\n      var result = regex.exec(rng.toString());\n      return result && result.index === 0;\n    });\n\n    var rng = new WrappedRange(\n      startPoint.node,\n      startPoint.offset,\n      endPoint.node,\n      endPoint.offset\n    );\n\n    var text = rng.toString();\n    var result = regex.exec(text);\n\n    if (result && result[0].length === text.length) {\n      return rng;\n    } else {\n      return null;\n    }\n  }\n\n  /**\n   * create offsetPath bookmark\n   *\n   * @param {Node} editable\n   */\n  bookmark(editable) {\n    return {\n      s: {\n        path: dom.makeOffsetPath(editable, this.sc),\n        offset: this.so,\n      },\n      e: {\n        path: dom.makeOffsetPath(editable, this.ec),\n        offset: this.eo,\n      },\n    };\n  }\n\n  /**\n   * create offsetPath bookmark base on paragraph\n   *\n   * @param {Node[]} paras\n   */\n  paraBookmark(paras) {\n    return {\n      s: {\n        path: lists.tail(dom.makeOffsetPath(lists.head(paras), this.sc)),\n        offset: this.so,\n      },\n      e: {\n        path: lists.tail(dom.makeOffsetPath(lists.last(paras), this.ec)),\n        offset: this.eo,\n      },\n    };\n  }\n\n  /**\n   * getClientRects\n   * @return {Rect[]}\n   */\n  getClientRects() {\n    const nativeRng = this.nativeRange();\n    return nativeRng.getClientRects();\n  }\n}\n\n/**\n * Data structure\n *  * BoundaryPoint: a point of dom tree\n *  * BoundaryPoints: two boundaryPoints corresponding to the start and the end of the Range\n *\n * See to http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Position\n */\nexport default {\n  /**\n   * create Range Object From arguments or Browser Selection\n   *\n   * @param {Node} sc - start container\n   * @param {Number} so - start offset\n   * @param {Node} ec - end container\n   * @param {Number} eo - end offset\n   * @return {WrappedRange}\n   */\n  create: function(sc, so, ec, eo) {\n    if (arguments.length === 4) {\n      return new WrappedRange(sc, so, ec, eo);\n    } else if (arguments.length === 2) { // collapsed\n      ec = sc;\n      eo = so;\n      return new WrappedRange(sc, so, ec, eo);\n    } else {\n      let wrappedRange = this.createFromSelection();\n\n      if (!wrappedRange && arguments.length === 1) {\n        let bodyElement = arguments[0];\n        if (dom.isEditable(bodyElement)) {\n          bodyElement = bodyElement.lastChild;\n        }\n        return this.createFromBodyElement(bodyElement, dom.emptyPara === arguments[0].innerHTML);\n      }\n      return wrappedRange;\n    }\n  },\n\n  createFromBodyElement: function(bodyElement, isCollapseToStart = false) {\n    var wrappedRange = this.createFromNode(bodyElement);\n    return wrappedRange.collapse(isCollapseToStart);\n  },\n\n  createFromSelection: function() {\n    let sc, so, ec, eo;\n    if (env.isW3CRangeSupport) {\n      const selection = document.getSelection();\n      if (!selection || selection.rangeCount === 0) {\n        return null;\n      } else if (dom.isBody(selection.anchorNode)) {\n        // Firefox: returns entire body as range on initialization.\n        // We won't never need it.\n        return null;\n      }\n\n      const nativeRng = selection.getRangeAt(0);\n      sc = nativeRng.startContainer;\n      so = nativeRng.startOffset;\n      ec = nativeRng.endContainer;\n      eo = nativeRng.endOffset;\n    } else { // IE8: TextRange\n      const textRange = document.selection.createRange();\n      const textRangeEnd = textRange.duplicate();\n      textRangeEnd.collapse(false);\n      const textRangeStart = textRange;\n      textRangeStart.collapse(true);\n\n      let startPoint = textRangeToPoint(textRangeStart, true);\n      let endPoint = textRangeToPoint(textRangeEnd, false);\n\n      // same visible point case: range was collapsed.\n      if (dom.isText(startPoint.node) && dom.isLeftEdgePoint(startPoint) &&\n        dom.isTextNode(endPoint.node) && dom.isRightEdgePoint(endPoint) &&\n        endPoint.node.nextSibling === startPoint.node) {\n        startPoint = endPoint;\n      }\n\n      sc = startPoint.cont;\n      so = startPoint.offset;\n      ec = endPoint.cont;\n      eo = endPoint.offset;\n    }\n\n    return new WrappedRange(sc, so, ec, eo);\n  },\n\n  /**\n   * @method\n   *\n   * create WrappedRange from node\n   *\n   * @param {Node} node\n   * @return {WrappedRange}\n   */\n  createFromNode: function(node) {\n    let sc = node;\n    let so = 0;\n    let ec = node;\n    let eo = dom.nodeLength(ec);\n\n    // browsers can't target a picture or void node\n    if (dom.isVoid(sc)) {\n      so = dom.listPrev(sc).length - 1;\n      sc = sc.parentNode;\n    }\n    if (dom.isBR(ec)) {\n      eo = dom.listPrev(ec).length - 1;\n      ec = ec.parentNode;\n    } else if (dom.isVoid(ec)) {\n      eo = dom.listPrev(ec).length;\n      ec = ec.parentNode;\n    }\n\n    return this.create(sc, so, ec, eo);\n  },\n\n  /**\n   * create WrappedRange from node after position\n   *\n   * @param {Node} node\n   * @return {WrappedRange}\n   */\n  createFromNodeBefore: function(node) {\n    return this.createFromNode(node).collapse(true);\n  },\n\n  /**\n   * create WrappedRange from node after position\n   *\n   * @param {Node} node\n   * @return {WrappedRange}\n   */\n  createFromNodeAfter: function(node) {\n    return this.createFromNode(node).collapse();\n  },\n\n  /**\n   * @method\n   *\n   * create WrappedRange from bookmark\n   *\n   * @param {Node} editable\n   * @param {Object} bookmark\n   * @return {WrappedRange}\n   */\n  createFromBookmark: function(editable, bookmark) {\n    const sc = dom.fromOffsetPath(editable, bookmark.s.path);\n    const so = bookmark.s.offset;\n    const ec = dom.fromOffsetPath(editable, bookmark.e.path);\n    const eo = bookmark.e.offset;\n    return new WrappedRange(sc, so, ec, eo);\n  },\n\n  /**\n   * @method\n   *\n   * create WrappedRange from paraBookmark\n   *\n   * @param {Object} bookmark\n   * @param {Node[]} paras\n   * @return {WrappedRange}\n   */\n  createFromParaBookmark: function(bookmark, paras) {\n    const so = bookmark.s.offset;\n    const eo = bookmark.e.offset;\n    const sc = dom.fromOffsetPath(lists.head(paras), bookmark.s.path);\n    const ec = dom.fromOffsetPath(lists.last(paras), bookmark.e.path);\n\n    return new WrappedRange(sc, so, ec, eo);\n  },\n};\n","import $ from 'jquery';\nimport env from './base/core/env';\nimport lists from './base/core/lists';\nimport Context from './base/Context';\n\n$.fn.extend({\n  /**\n   * Summernote API\n   *\n   * @param {Object|String}\n   * @return {this}\n   */\n  summernote: function() {\n    const type = $.type(lists.head(arguments));\n    const isExternalAPICalled = type === 'string';\n    const hasInitOptions = type === 'object';\n\n    const options = $.extend({}, $.summernote.options, hasInitOptions ? lists.head(arguments) : {});\n\n    // Update options\n    options.langInfo = $.extend(true, {}, $.summernote.lang['en-US'], $.summernote.lang[options.lang]);\n    options.icons = $.extend(true, {}, $.summernote.options.icons, options.icons);\n    options.tooltip = options.tooltip === 'auto' ? !env.isSupportTouch : options.tooltip;\n\n    this.each((idx, note) => {\n      const $note = $(note);\n      if (!$note.data('summernote')) {\n        const context = new Context($note, options);\n        $note.data('summernote', context);\n        $note.data('summernote').triggerEvent('init', context.layoutInfo);\n      }\n    });\n\n    const $note = this.first();\n    if ($note.length) {\n      const context = $note.data('summernote');\n      if (isExternalAPICalled) {\n        return context.invoke.apply(context, lists.from(arguments));\n      } else if (options.focus) {\n        context.invoke('editor.focus');\n      }\n    }\n\n    return this;\n  },\n});\n","import lists from './lists';\nimport func from './func';\n\nconst KEY_MAP = {\n  'BACKSPACE': 8,\n  'TAB': 9,\n  'ENTER': 13,\n  'SPACE': 32,\n  'DELETE': 46,\n\n  // Arrow\n  'LEFT': 37,\n  'UP': 38,\n  'RIGHT': 39,\n  'DOWN': 40,\n\n  // Number: 0-9\n  'NUM0': 48,\n  'NUM1': 49,\n  'NUM2': 50,\n  'NUM3': 51,\n  'NUM4': 52,\n  'NUM5': 53,\n  'NUM6': 54,\n  'NUM7': 55,\n  'NUM8': 56,\n\n  // Alphabet: a-z\n  'B': 66,\n  'E': 69,\n  'I': 73,\n  'J': 74,\n  'K': 75,\n  'L': 76,\n  'R': 82,\n  'S': 83,\n  'U': 85,\n  'V': 86,\n  'Y': 89,\n  'Z': 90,\n\n  'SLASH': 191,\n  'LEFTBRACKET': 219,\n  'BACKSLASH': 220,\n  'RIGHTBRACKET': 221,\n\n  // Navigation\n  'HOME': 36,\n  'END': 35,\n  'PAGEUP': 33,\n  'PAGEDOWN': 34,\n};\n\n/**\n * @class core.key\n *\n * Object for keycodes.\n *\n * @singleton\n * @alternateClassName key\n */\nexport default {\n  /**\n   * @method isEdit\n   *\n   * @param {Number} keyCode\n   * @return {Boolean}\n   */\n  isEdit: (keyCode) => {\n    return lists.contains([\n      KEY_MAP.BACKSPACE,\n      KEY_MAP.TAB,\n      KEY_MAP.ENTER,\n      KEY_MAP.SPACE,\n      KEY_MAP.DELETE,\n    ], keyCode);\n  },\n  /**\n   * @method isMove\n   *\n   * @param {Number} keyCode\n   * @return {Boolean}\n   */\n  isMove: (keyCode) => {\n    return lists.contains([\n      KEY_MAP.LEFT,\n      KEY_MAP.UP,\n      KEY_MAP.RIGHT,\n      KEY_MAP.DOWN,\n    ], keyCode);\n  },\n  /**\n   * @method isNavigation\n   *\n   * @param {Number} keyCode\n   * @return {Boolean}\n   */\n  isNavigation: (keyCode) => {\n    return lists.contains([\n      KEY_MAP.HOME,\n      KEY_MAP.END,\n      KEY_MAP.PAGEUP,\n      KEY_MAP.PAGEDOWN,\n    ], keyCode);\n  },\n  /**\n   * @property {Object} nameFromCode\n   * @property {String} nameFromCode.8 \"BACKSPACE\"\n   */\n  nameFromCode: func.invertObject(KEY_MAP),\n  code: KEY_MAP,\n};\n","import range from '../core/range';\n\nexport default class History {\n  constructor(context) {\n    this.stack = [];\n    this.stackOffset = -1;\n    this.context = context;\n    this.$editable = context.layoutInfo.editable;\n    this.editable = this.$editable[0];\n  }\n\n  makeSnapshot() {\n    const rng = range.create(this.editable);\n    const emptyBookmark = { s: { path: [], offset: 0 }, e: { path: [], offset: 0 } };\n\n    return {\n      contents: this.$editable.html(),\n      bookmark: ((rng && rng.isOnEditable()) ? rng.bookmark(this.editable) : emptyBookmark),\n    };\n  }\n\n  applySnapshot(snapshot) {\n    if (snapshot.contents !== null) {\n      this.$editable.html(snapshot.contents);\n    }\n    if (snapshot.bookmark !== null) {\n      range.createFromBookmark(this.editable, snapshot.bookmark).select();\n    }\n  }\n\n  /**\n  * @method rewind\n  * Rewinds the history stack back to the first snapshot taken.\n  * Leaves the stack intact, so that \"Redo\" can still be used.\n  */\n  rewind() {\n    // Create snap shot if not yet recorded\n    if (this.$editable.html() !== this.stack[this.stackOffset].contents) {\n      this.recordUndo();\n    }\n\n    // Return to the first available snapshot.\n    this.stackOffset = 0;\n\n    // Apply that snapshot.\n    this.applySnapshot(this.stack[this.stackOffset]);\n  }\n\n  /**\n  *  @method commit\n  *  Resets history stack, but keeps current editor's content.\n  */\n  commit() {\n    // Clear the stack.\n    this.stack = [];\n\n    // Restore stackOffset to its original value.\n    this.stackOffset = -1;\n\n    // Record our first snapshot (of nothing).\n    this.recordUndo();\n  }\n\n  /**\n  * @method reset\n  * Resets the history stack completely; reverting to an empty editor.\n  */\n  reset() {\n    // Clear the stack.\n    this.stack = [];\n\n    // Restore stackOffset to its original value.\n    this.stackOffset = -1;\n\n    // Clear the editable area.\n    this.$editable.html('');\n\n    // Record our first snapshot (of nothing).\n    this.recordUndo();\n  }\n\n  /**\n   * undo\n   */\n  undo() {\n    // Create snap shot if not yet recorded\n    if (this.$editable.html() !== this.stack[this.stackOffset].contents) {\n      this.recordUndo();\n    }\n\n    if (this.stackOffset > 0) {\n      this.stackOffset--;\n      this.applySnapshot(this.stack[this.stackOffset]);\n    }\n  }\n\n  /**\n   * redo\n   */\n  redo() {\n    if (this.stack.length - 1 > this.stackOffset) {\n      this.stackOffset++;\n      this.applySnapshot(this.stack[this.stackOffset]);\n    }\n  }\n\n  /**\n   * recorded undo\n   */\n  recordUndo() {\n    this.stackOffset++;\n\n    // Wash out stack after stackOffset\n    if (this.stack.length > this.stackOffset) {\n      this.stack = this.stack.slice(0, this.stackOffset);\n    }\n\n    // Create new snapshot and push it to the end\n    this.stack.push(this.makeSnapshot());\n\n    // If the stack size reachs to the limit, then slice it\n    if (this.stack.length > this.context.options.historyLimit) {\n      this.stack.shift();\n      this.stackOffset -= 1;\n    }\n  }\n}\n","import $ from 'jquery';\nimport env from '../core/env';\nimport func from '../core/func';\nimport lists from '../core/lists';\nimport dom from '../core/dom';\n\nexport default class Style {\n  /**\n   * @method jQueryCSS\n   *\n   * [workaround] for old jQuery\n   * passing an array of style properties to .css()\n   * will result in an object of property-value pairs.\n   * (compability with version < 1.9)\n   *\n   * @private\n   * @param  {jQuery} $obj\n   * @param  {Array} propertyNames - An array of one or more CSS properties.\n   * @return {Object}\n   */\n  jQueryCSS($obj, propertyNames) {\n    if (env.jqueryVersion < 1.9) {\n      const result = {};\n      $.each(propertyNames, (idx, propertyName) => {\n        result[propertyName] = $obj.css(propertyName);\n      });\n      return result;\n    }\n    return $obj.css(propertyNames);\n  }\n\n  /**\n   * returns style object from node\n   *\n   * @param {jQuery} $node\n   * @return {Object}\n   */\n  fromNode($node) {\n    const properties = ['font-family', 'font-size', 'text-align', 'list-style-type', 'line-height'];\n    const styleInfo = this.jQueryCSS($node, properties) || {};\n\n    const fontSize = $node[0].style.fontSize || styleInfo['font-size'];\n\n    styleInfo['font-size'] = parseInt(fontSize, 10);\n    styleInfo['font-size-unit'] = fontSize.match(/[a-z%]+$/);\n\n    return styleInfo;\n  }\n\n  /**\n   * paragraph level style\n   *\n   * @param {WrappedRange} rng\n   * @param {Object} styleInfo\n   */\n  stylePara(rng, styleInfo) {\n    $.each(rng.nodes(dom.isPara, {\n      includeAncestor: true,\n    }), (idx, para) => {\n      $(para).css(styleInfo);\n    });\n  }\n\n  /**\n   * insert and returns styleNodes on range.\n   *\n   * @param {WrappedRange} rng\n   * @param {Object} [options] - options for styleNodes\n   * @param {String} [options.nodeName] - default: `SPAN`\n   * @param {Boolean} [options.expandClosestSibling] - default: `false`\n   * @param {Boolean} [options.onlyPartialContains] - default: `false`\n   * @return {Node[]}\n   */\n  styleNodes(rng, options) {\n    rng = rng.splitText();\n\n    const nodeName = (options && options.nodeName) || 'SPAN';\n    const expandClosestSibling = !!(options && options.expandClosestSibling);\n    const onlyPartialContains = !!(options && options.onlyPartialContains);\n\n    if (rng.isCollapsed()) {\n      return [rng.insertNode(dom.create(nodeName))];\n    }\n\n    let pred = dom.makePredByNodeName(nodeName);\n    const nodes = rng.nodes(dom.isText, {\n      fullyContains: true,\n    }).map((text) => {\n      return dom.singleChildAncestor(text, pred) || dom.wrap(text, nodeName);\n    });\n\n    if (expandClosestSibling) {\n      if (onlyPartialContains) {\n        const nodesInRange = rng.nodes();\n        // compose with partial contains predication\n        pred = func.and(pred, (node) => {\n          return lists.contains(nodesInRange, node);\n        });\n      }\n\n      return nodes.map((node) => {\n        const siblings = dom.withClosestSiblings(node, pred);\n        const head = lists.head(siblings);\n        const tails = lists.tail(siblings);\n        $.each(tails, (idx, elem) => {\n          dom.appendChildNodes(head, elem.childNodes);\n          dom.remove(elem);\n        });\n        return lists.head(siblings);\n      });\n    } else {\n      return nodes;\n    }\n  }\n\n  /**\n   * get current style on cursor\n   *\n   * @param {WrappedRange} rng\n   * @return {Object} - object contains style properties.\n   */\n  current(rng) {\n    const $cont = $(!dom.isElement(rng.sc) ? rng.sc.parentNode : rng.sc);\n    let styleInfo = this.fromNode($cont);\n\n    // document.queryCommandState for toggle state\n    // [workaround] prevent Firefox nsresult: \"0x80004005 (NS_ERROR_FAILURE)\"\n    try {\n      styleInfo = $.extend(styleInfo, {\n        'font-bold': document.queryCommandState('bold') ? 'bold' : 'normal',\n        'font-italic': document.queryCommandState('italic') ? 'italic' : 'normal',\n        'font-underline': document.queryCommandState('underline') ? 'underline' : 'normal',\n        'font-subscript': document.queryCommandState('subscript') ? 'subscript' : 'normal',\n        'font-superscript': document.queryCommandState('superscript') ? 'superscript' : 'normal',\n        'font-strikethrough': document.queryCommandState('strikethrough') ? 'strikethrough' : 'normal',\n        'font-family': document.queryCommandValue('fontname') || styleInfo['font-family'],\n      });\n    } catch (e) {\n      // eslint-disable-next-line\n    }\n\n    // list-style-type to list-style(unordered, ordered)\n    if (!rng.isOnList()) {\n      styleInfo['list-style'] = 'none';\n    } else {\n      const orderedTypes = ['circle', 'disc', 'disc-leading-zero', 'square'];\n      const isUnordered = orderedTypes.indexOf(styleInfo['list-style-type']) > -1;\n      styleInfo['list-style'] = isUnordered ? 'unordered' : 'ordered';\n    }\n\n    const para = dom.ancestor(rng.sc, dom.isPara);\n    if (para && para.style['line-height']) {\n      styleInfo['line-height'] = para.style.lineHeight;\n    } else {\n      const lineHeight = parseInt(styleInfo['line-height'], 10) / parseInt(styleInfo['font-size'], 10);\n      styleInfo['line-height'] = lineHeight.toFixed(1);\n    }\n\n    styleInfo.anchor = rng.isOnAnchor() && dom.ancestor(rng.sc, dom.isAnchor);\n    styleInfo.ancestors = dom.listAncestor(rng.sc, dom.isEditable);\n    styleInfo.range = rng;\n\n    return styleInfo;\n  }\n}\n","import $ from 'jquery';\nimport lists from '../core/lists';\nimport func from '../core/func';\nimport dom from '../core/dom';\nimport range from '../core/range';\n\nexport default class Bullet {\n  /**\n   * toggle ordered list\n   */\n  insertOrderedList(editable) {\n    this.toggleList('OL', editable);\n  }\n\n  /**\n   * toggle unordered list\n   */\n  insertUnorderedList(editable) {\n    this.toggleList('UL', editable);\n  }\n\n  /**\n   * indent\n   */\n  indent(editable) {\n    const rng = range.create(editable).wrapBodyInlineWithPara();\n\n    const paras = rng.nodes(dom.isPara, { includeAncestor: true });\n    const clustereds = lists.clusterBy(paras, func.peq2('parentNode'));\n\n    $.each(clustereds, (idx, paras) => {\n      const head = lists.head(paras);\n      if (dom.isLi(head)) {\n        const previousList = this.findList(head.previousSibling);\n        if (previousList) {\n          paras\n            .map(para => previousList.appendChild(para));\n        } else {\n          this.wrapList(paras, head.parentNode.nodeName);\n          paras\n            .map((para) => para.parentNode)\n            .map((para) => this.appendToPrevious(para));\n        }\n      } else {\n        $.each(paras, (idx, para) => {\n          $(para).css('marginLeft', (idx, val) => {\n            return (parseInt(val, 10) || 0) + 25;\n          });\n        });\n      }\n    });\n\n    rng.select();\n  }\n\n  /**\n   * outdent\n   */\n  outdent(editable) {\n    const rng = range.create(editable).wrapBodyInlineWithPara();\n\n    const paras = rng.nodes(dom.isPara, { includeAncestor: true });\n    const clustereds = lists.clusterBy(paras, func.peq2('parentNode'));\n\n    $.each(clustereds, (idx, paras) => {\n      const head = lists.head(paras);\n      if (dom.isLi(head)) {\n        this.releaseList([paras]);\n      } else {\n        $.each(paras, (idx, para) => {\n          $(para).css('marginLeft', (idx, val) => {\n            val = (parseInt(val, 10) || 0);\n            return val > 25 ? val - 25 : '';\n          });\n        });\n      }\n    });\n\n    rng.select();\n  }\n\n  /**\n   * toggle list\n   *\n   * @param {String} listName - OL or UL\n   */\n  toggleList(listName, editable) {\n    const rng = range.create(editable).wrapBodyInlineWithPara();\n\n    let paras = rng.nodes(dom.isPara, { includeAncestor: true });\n    const bookmark = rng.paraBookmark(paras);\n    const clustereds = lists.clusterBy(paras, func.peq2('parentNode'));\n\n    // paragraph to list\n    if (lists.find(paras, dom.isPurePara)) {\n      let wrappedParas = [];\n      $.each(clustereds, (idx, paras) => {\n        wrappedParas = wrappedParas.concat(this.wrapList(paras, listName));\n      });\n      paras = wrappedParas;\n    // list to paragraph or change list style\n    } else {\n      const diffLists = rng.nodes(dom.isList, {\n        includeAncestor: true,\n      }).filter((listNode) => {\n        return !$.nodeName(listNode, listName);\n      });\n\n      if (diffLists.length) {\n        $.each(diffLists, (idx, listNode) => {\n          dom.replace(listNode, listName);\n        });\n      } else {\n        paras = this.releaseList(clustereds, true);\n      }\n    }\n\n    range.createFromParaBookmark(bookmark, paras).select();\n  }\n\n  /**\n   * @param {Node[]} paras\n   * @param {String} listName\n   * @return {Node[]}\n   */\n  wrapList(paras, listName) {\n    const head = lists.head(paras);\n    const last = lists.last(paras);\n\n    const prevList = dom.isList(head.previousSibling) && head.previousSibling;\n    const nextList = dom.isList(last.nextSibling) && last.nextSibling;\n\n    const listNode = prevList || dom.insertAfter(dom.create(listName || 'UL'), last);\n\n    // P to LI\n    paras = paras.map((para) => {\n      return dom.isPurePara(para) ? dom.replace(para, 'LI') : para;\n    });\n\n    // append to list(<ul>, <ol>)\n    dom.appendChildNodes(listNode, paras);\n\n    if (nextList) {\n      dom.appendChildNodes(listNode, lists.from(nextList.childNodes));\n      dom.remove(nextList);\n    }\n\n    return paras;\n  }\n\n  /**\n   * @method releaseList\n   *\n   * @param {Array[]} clustereds\n   * @param {Boolean} isEscapseToBody\n   * @return {Node[]}\n   */\n  releaseList(clustereds, isEscapseToBody) {\n    let releasedParas = [];\n\n    $.each(clustereds, (idx, paras) => {\n      const head = lists.head(paras);\n      const last = lists.last(paras);\n\n      const headList = isEscapseToBody ? dom.lastAncestor(head, dom.isList) : head.parentNode;\n      const parentItem = headList.parentNode;\n\n      if (headList.parentNode.nodeName === 'LI') {\n        paras.map(para => {\n          const newList = this.findNextSiblings(para);\n\n          if (parentItem.nextSibling) {\n            parentItem.parentNode.insertBefore(\n              para,\n              parentItem.nextSibling\n            );\n          } else {\n            parentItem.parentNode.appendChild(para);\n          }\n\n          if (newList.length) {\n            this.wrapList(newList, headList.nodeName);\n            para.appendChild(newList[0].parentNode);\n          }\n        });\n\n        if (headList.children.length === 0) {\n          parentItem.removeChild(headList);\n        }\n\n        if (parentItem.childNodes.length === 0) {\n          parentItem.parentNode.removeChild(parentItem);\n        }\n      } else {\n        const lastList = headList.childNodes.length > 1 ? dom.splitTree(headList, {\n          node: last.parentNode,\n          offset: dom.position(last) + 1,\n        }, {\n          isSkipPaddingBlankHTML: true,\n        }) : null;\n\n        const middleList = dom.splitTree(headList, {\n          node: head.parentNode,\n          offset: dom.position(head),\n        }, {\n          isSkipPaddingBlankHTML: true,\n        });\n\n        paras = isEscapseToBody ? dom.listDescendant(middleList, dom.isLi)\n          : lists.from(middleList.childNodes).filter(dom.isLi);\n\n        // LI to P\n        if (isEscapseToBody || !dom.isList(headList.parentNode)) {\n          paras = paras.map((para) => {\n            return dom.replace(para, 'P');\n          });\n        }\n\n        $.each(lists.from(paras).reverse(), (idx, para) => {\n          dom.insertAfter(para, headList);\n        });\n\n        // remove empty lists\n        const rootLists = lists.compact([headList, middleList, lastList]);\n        $.each(rootLists, (idx, rootList) => {\n          const listNodes = [rootList].concat(dom.listDescendant(rootList, dom.isList));\n          $.each(listNodes.reverse(), (idx, listNode) => {\n            if (!dom.nodeLength(listNode)) {\n              dom.remove(listNode, true);\n            }\n          });\n        });\n      }\n\n      releasedParas = releasedParas.concat(paras);\n    });\n\n    return releasedParas;\n  }\n\n  /**\n   * @method appendToPrevious\n   *\n   * Appends list to previous list item, if\n   * none exist it wraps the list in a new list item.\n   *\n   * @param {HTMLNode} ListItem\n   * @return {HTMLNode}\n   */\n  appendToPrevious(node) {\n    return node.previousSibling\n      ? dom.appendChildNodes(node.previousSibling, [node])\n      : this.wrapList([node], 'LI');\n  }\n\n  /**\n   * @method findList\n   *\n   * Finds an existing list in list item\n   *\n   * @param {HTMLNode} ListItem\n   * @return {Array[]}\n   */\n  findList(node) {\n    return node\n      ? lists.find(node.children, child => ['OL', 'UL'].indexOf(child.nodeName) > -1)\n      : null;\n  }\n\n  /**\n   * @method findNextSiblings\n   *\n   * Finds all list item siblings that follow it\n   *\n   * @param {HTMLNode} ListItem\n   * @return {HTMLNode}\n   */\n  findNextSiblings(node) {\n    const siblings = [];\n    while (node.nextSibling) {\n      siblings.push(node.nextSibling);\n      node = node.nextSibling;\n    }\n    return siblings;\n  }\n}\n","import $ from 'jquery';\nimport dom from '../core/dom';\nimport range from '../core/range';\nimport Bullet from '../editing/Bullet';\n\n/**\n * @class editing.Typing\n *\n * Typing\n *\n */\nexport default class Typing {\n  constructor(context) {\n    // a Bullet instance to toggle lists off\n    this.bullet = new Bullet();\n    this.options = context.options;\n  }\n\n  /**\n   * insert tab\n   *\n   * @param {WrappedRange} rng\n   * @param {Number} tabsize\n   */\n  insertTab(rng, tabsize) {\n    const tab = dom.createText(new Array(tabsize + 1).join(dom.NBSP_CHAR));\n    rng = rng.deleteContents();\n    rng.insertNode(tab, true);\n\n    rng = range.create(tab, tabsize);\n    rng.select();\n  }\n\n  /**\n   * insert paragraph\n   *\n   * @param {jQuery} $editable\n   * @param {WrappedRange} rng Can be used in unit tests to \"mock\" the range\n   *\n   * blockquoteBreakingLevel\n   *   0 - No break, the new paragraph remains inside the quote\n   *   1 - Break the first blockquote in the ancestors list\n   *   2 - Break all blockquotes, so that the new paragraph is not quoted (this is the default)\n   */\n  insertParagraph(editable, rng) {\n    rng = rng || range.create(editable);\n\n    // deleteContents on range.\n    rng = rng.deleteContents();\n\n    // Wrap range if it needs to be wrapped by paragraph\n    rng = rng.wrapBodyInlineWithPara();\n\n    // finding paragraph\n    const splitRoot = dom.ancestor(rng.sc, dom.isPara);\n\n    let nextPara;\n    // on paragraph: split paragraph\n    if (splitRoot) {\n      // if it is an empty line with li\n      if (dom.isLi(splitRoot) && (dom.isEmpty(splitRoot) || dom.deepestChildIsEmpty(splitRoot))) {\n        // toogle UL/OL and escape\n        this.bullet.toggleList(splitRoot.parentNode.nodeName);\n        return;\n      } else {\n        let blockquote = null;\n        if (this.options.blockquoteBreakingLevel === 1) {\n          blockquote = dom.ancestor(splitRoot, dom.isBlockquote);\n        } else if (this.options.blockquoteBreakingLevel === 2) {\n          blockquote = dom.lastAncestor(splitRoot, dom.isBlockquote);\n        }\n\n        if (blockquote) {\n          // We're inside a blockquote and options ask us to break it\n          nextPara = $(dom.emptyPara)[0];\n          // If the split is right before a <br>, remove it so that there's no \"empty line\"\n          // after the split in the new blockquote created\n          if (dom.isRightEdgePoint(rng.getStartPoint()) && dom.isBR(rng.sc.nextSibling)) {\n            $(rng.sc.nextSibling).remove();\n          }\n          const split = dom.splitTree(blockquote, rng.getStartPoint(), { isDiscardEmptySplits: true });\n          if (split) {\n            split.parentNode.insertBefore(nextPara, split);\n          } else {\n            dom.insertAfter(nextPara, blockquote); // There's no split if we were at the end of the blockquote\n          }\n        } else {\n          nextPara = dom.splitTree(splitRoot, rng.getStartPoint());\n\n          // not a blockquote, just insert the paragraph\n          let emptyAnchors = dom.listDescendant(splitRoot, dom.isEmptyAnchor);\n          emptyAnchors = emptyAnchors.concat(dom.listDescendant(nextPara, dom.isEmptyAnchor));\n\n          $.each(emptyAnchors, (idx, anchor) => {\n            dom.remove(anchor);\n          });\n\n          // replace empty heading, pre or custom-made styleTag with P tag\n          if ((dom.isHeading(nextPara) || dom.isPre(nextPara) || dom.isCustomStyleTag(nextPara)) && dom.isEmpty(nextPara)) {\n            nextPara = dom.replace(nextPara, 'p');\n          }\n        }\n      }\n    // no paragraph: insert empty paragraph\n    } else {\n      const next = rng.sc.childNodes[rng.so];\n      nextPara = $(dom.emptyPara)[0];\n      if (next) {\n        rng.sc.insertBefore(nextPara, next);\n      } else {\n        rng.sc.appendChild(nextPara);\n      }\n    }\n\n    range.create(nextPara, 0).normalize().select().scrollIntoView(editable);\n  }\n}\n","import $ from 'jquery';\nimport dom from '../core/dom';\nimport range from '../core/range';\nimport lists from '../core/lists';\n\n/**\n * @class Create a virtual table to create what actions to do in change.\n * @param {object} startPoint Cell selected to apply change.\n * @param {enum} where  Where change will be applied Row or Col. Use enum: TableResultAction.where\n * @param {enum} action Action to be applied. Use enum: TableResultAction.requestAction\n * @param {object} domTable Dom element of table to make changes.\n */\nconst TableResultAction = function(startPoint, where, action, domTable) {\n  const _startPoint = { 'colPos': 0, 'rowPos': 0 };\n  const _virtualTable = [];\n  const _actionCellList = [];\n\n  /// ///////////////////////////////////////////\n  // Private functions\n  /// ///////////////////////////////////////////\n\n  /**\n   * Set the startPoint of action.\n   */\n  function setStartPoint() {\n    if (!startPoint || !startPoint.tagName || (startPoint.tagName.toLowerCase() !== 'td' && startPoint.tagName.toLowerCase() !== 'th')) {\n      // Impossible to identify start Cell point\n      return;\n    }\n    _startPoint.colPos = startPoint.cellIndex;\n    if (!startPoint.parentElement || !startPoint.parentElement.tagName || startPoint.parentElement.tagName.toLowerCase() !== 'tr') {\n      // Impossible to identify start Row point\n      return;\n    }\n    _startPoint.rowPos = startPoint.parentElement.rowIndex;\n  }\n\n  /**\n   * Define virtual table position info object.\n   *\n   * @param {int} rowIndex Index position in line of virtual table.\n   * @param {int} cellIndex Index position in column of virtual table.\n   * @param {object} baseRow Row affected by this position.\n   * @param {object} baseCell Cell affected by this position.\n   * @param {bool} isSpan Inform if it is an span cell/row.\n   */\n  function setVirtualTablePosition(rowIndex, cellIndex, baseRow, baseCell, isRowSpan, isColSpan, isVirtualCell) {\n    const objPosition = {\n      'baseRow': baseRow,\n      'baseCell': baseCell,\n      'isRowSpan': isRowSpan,\n      'isColSpan': isColSpan,\n      'isVirtual': isVirtualCell,\n    };\n    if (!_virtualTable[rowIndex]) {\n      _virtualTable[rowIndex] = [];\n    }\n    _virtualTable[rowIndex][cellIndex] = objPosition;\n  }\n\n  /**\n   * Create action cell object.\n   *\n   * @param {object} virtualTableCellObj Object of specific position on virtual table.\n   * @param {enum} resultAction Action to be applied in that item.\n   */\n  function getActionCell(virtualTableCellObj, resultAction, virtualRowPosition, virtualColPosition) {\n    return {\n      'baseCell': virtualTableCellObj.baseCell,\n      'action': resultAction,\n      'virtualTable': {\n        'rowIndex': virtualRowPosition,\n        'cellIndex': virtualColPosition,\n      },\n    };\n  }\n\n  /**\n   * Recover free index of row to append Cell.\n   *\n   * @param {int} rowIndex Index of row to find free space.\n   * @param {int} cellIndex Index of cell to find free space in table.\n   */\n  function recoverCellIndex(rowIndex, cellIndex) {\n    if (!_virtualTable[rowIndex]) {\n      return cellIndex;\n    }\n    if (!_virtualTable[rowIndex][cellIndex]) {\n      return cellIndex;\n    }\n\n    let newCellIndex = cellIndex;\n    while (_virtualTable[rowIndex][newCellIndex]) {\n      newCellIndex++;\n      if (!_virtualTable[rowIndex][newCellIndex]) {\n        return newCellIndex;\n      }\n    }\n  }\n\n  /**\n   * Recover info about row and cell and add information to virtual table.\n   *\n   * @param {object} row Row to recover information.\n   * @param {object} cell Cell to recover information.\n   */\n  function addCellInfoToVirtual(row, cell) {\n    const cellIndex = recoverCellIndex(row.rowIndex, cell.cellIndex);\n    const cellHasColspan = (cell.colSpan > 1);\n    const cellHasRowspan = (cell.rowSpan > 1);\n    const isThisSelectedCell = (row.rowIndex === _startPoint.rowPos && cell.cellIndex === _startPoint.colPos);\n    setVirtualTablePosition(row.rowIndex, cellIndex, row, cell, cellHasRowspan, cellHasColspan, false);\n\n    // Add span rows to virtual Table.\n    const rowspanNumber = cell.attributes.rowSpan ? parseInt(cell.attributes.rowSpan.value, 10) : 0;\n    if (rowspanNumber > 1) {\n      for (let rp = 1; rp < rowspanNumber; rp++) {\n        const rowspanIndex = row.rowIndex + rp;\n        adjustStartPoint(rowspanIndex, cellIndex, cell, isThisSelectedCell);\n        setVirtualTablePosition(rowspanIndex, cellIndex, row, cell, true, cellHasColspan, true);\n      }\n    }\n\n    // Add span cols to virtual table.\n    const colspanNumber = cell.attributes.colSpan ? parseInt(cell.attributes.colSpan.value, 10) : 0;\n    if (colspanNumber > 1) {\n      for (let cp = 1; cp < colspanNumber; cp++) {\n        const cellspanIndex = recoverCellIndex(row.rowIndex, (cellIndex + cp));\n        adjustStartPoint(row.rowIndex, cellspanIndex, cell, isThisSelectedCell);\n        setVirtualTablePosition(row.rowIndex, cellspanIndex, row, cell, cellHasRowspan, true, true);\n      }\n    }\n  }\n\n  /**\n   * Process validation and adjust of start point if needed\n   *\n   * @param {int} rowIndex\n   * @param {int} cellIndex\n   * @param {object} cell\n   * @param {bool} isSelectedCell\n   */\n  function adjustStartPoint(rowIndex, cellIndex, cell, isSelectedCell) {\n    if (rowIndex === _startPoint.rowPos && _startPoint.colPos >= cell.cellIndex && cell.cellIndex <= cellIndex && !isSelectedCell) {\n      _startPoint.colPos++;\n    }\n  }\n\n  /**\n   * Create virtual table of cells with all cells, including span cells.\n   */\n  function createVirtualTable() {\n    const rows = domTable.rows;\n    for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {\n      const cells = rows[rowIndex].cells;\n      for (let cellIndex = 0; cellIndex < cells.length; cellIndex++) {\n        addCellInfoToVirtual(rows[rowIndex], cells[cellIndex]);\n      }\n    }\n  }\n\n  /**\n   * Get action to be applied on the cell.\n   *\n   * @param {object} cell virtual table cell to apply action\n   */\n  function getDeleteResultActionToCell(cell) {\n    switch (where) {\n      case TableResultAction.where.Column:\n        if (cell.isColSpan) {\n          return TableResultAction.resultAction.SubtractSpanCount;\n        }\n        break;\n      case TableResultAction.where.Row:\n        if (!cell.isVirtual && cell.isRowSpan) {\n          return TableResultAction.resultAction.AddCell;\n        } else if (cell.isRowSpan) {\n          return TableResultAction.resultAction.SubtractSpanCount;\n        }\n        break;\n    }\n    return TableResultAction.resultAction.RemoveCell;\n  }\n\n  /**\n   * Get action to be applied on the cell.\n   *\n   * @param {object} cell virtual table cell to apply action\n   */\n  function getAddResultActionToCell(cell) {\n    switch (where) {\n      case TableResultAction.where.Column:\n        if (cell.isColSpan) {\n          return TableResultAction.resultAction.SumSpanCount;\n        } else if (cell.isRowSpan && cell.isVirtual) {\n          return TableResultAction.resultAction.Ignore;\n        }\n        break;\n      case TableResultAction.where.Row:\n        if (cell.isRowSpan) {\n          return TableResultAction.resultAction.SumSpanCount;\n        } else if (cell.isColSpan && cell.isVirtual) {\n          return TableResultAction.resultAction.Ignore;\n        }\n        break;\n    }\n    return TableResultAction.resultAction.AddCell;\n  }\n\n  function init() {\n    setStartPoint();\n    createVirtualTable();\n  }\n\n  /// ///////////////////////////////////////////\n  // Public functions\n  /// ///////////////////////////////////////////\n\n  /**\n   * Recover array os what to do in table.\n   */\n  this.getActionList = function() {\n    const fixedRow = (where === TableResultAction.where.Row) ? _startPoint.rowPos : -1;\n    const fixedCol = (where === TableResultAction.where.Column) ? _startPoint.colPos : -1;\n\n    let actualPosition = 0;\n    let canContinue = true;\n    while (canContinue) {\n      const rowPosition = (fixedRow >= 0) ? fixedRow : actualPosition;\n      const colPosition = (fixedCol >= 0) ? fixedCol : actualPosition;\n      const row = _virtualTable[rowPosition];\n      if (!row) {\n        canContinue = false;\n        return _actionCellList;\n      }\n      const cell = row[colPosition];\n      if (!cell) {\n        canContinue = false;\n        return _actionCellList;\n      }\n\n      // Define action to be applied in this cell\n      let resultAction = TableResultAction.resultAction.Ignore;\n      switch (action) {\n        case TableResultAction.requestAction.Add:\n          resultAction = getAddResultActionToCell(cell);\n          break;\n        case TableResultAction.requestAction.Delete:\n          resultAction = getDeleteResultActionToCell(cell);\n          break;\n      }\n      _actionCellList.push(getActionCell(cell, resultAction, rowPosition, colPosition));\n      actualPosition++;\n    }\n\n    return _actionCellList;\n  };\n\n  init();\n};\n/**\n*\n* Where action occours enum.\n*/\nTableResultAction.where = { 'Row': 0, 'Column': 1 };\n/**\n*\n* Requested action to apply enum.\n*/\nTableResultAction.requestAction = { 'Add': 0, 'Delete': 1 };\n/**\n*\n* Result action to be executed enum.\n*/\nTableResultAction.resultAction = { 'Ignore': 0, 'SubtractSpanCount': 1, 'RemoveCell': 2, 'AddCell': 3, 'SumSpanCount': 4 };\n\n/**\n *\n * @class editing.Table\n *\n * Table\n *\n */\nexport default class Table {\n  /**\n   * handle tab key\n   *\n   * @param {WrappedRange} rng\n   * @param {Boolean} isShift\n   */\n  tab(rng, isShift) {\n    const cell = dom.ancestor(rng.commonAncestor(), dom.isCell);\n    const table = dom.ancestor(cell, dom.isTable);\n    const cells = dom.listDescendant(table, dom.isCell);\n\n    const nextCell = lists[isShift ? 'prev' : 'next'](cells, cell);\n    if (nextCell) {\n      range.create(nextCell, 0).select();\n    }\n  }\n\n  /**\n   * Add a new row\n   *\n   * @param {WrappedRange} rng\n   * @param {String} position (top/bottom)\n   * @return {Node}\n   */\n  addRow(rng, position) {\n    const cell = dom.ancestor(rng.commonAncestor(), dom.isCell);\n\n    const currentTr = $(cell).closest('tr');\n    const trAttributes = this.recoverAttributes(currentTr);\n    const html = $('<tr' + trAttributes + '></tr>');\n\n    const vTable = new TableResultAction(cell, TableResultAction.where.Row,\n      TableResultAction.requestAction.Add, $(currentTr).closest('table')[0]);\n    const actions = vTable.getActionList();\n\n    for (let idCell = 0; idCell < actions.length; idCell++) {\n      const currentCell = actions[idCell];\n      const tdAttributes = this.recoverAttributes(currentCell.baseCell);\n      switch (currentCell.action) {\n        case TableResultAction.resultAction.AddCell:\n          html.append('<td' + tdAttributes + '>' + dom.blank + '</td>');\n          break;\n        case TableResultAction.resultAction.SumSpanCount:\n          {\n            if (position === 'top') {\n              const baseCellTr = currentCell.baseCell.parent;\n              const isTopFromRowSpan = (!baseCellTr ? 0 : currentCell.baseCell.closest('tr').rowIndex) <= currentTr[0].rowIndex;\n              if (isTopFromRowSpan) {\n                const newTd = $('<div></div>').append($('<td' + tdAttributes + '>' + dom.blank + '</td>').removeAttr('rowspan')).html();\n                html.append(newTd);\n                break;\n              }\n            }\n            let rowspanNumber = parseInt(currentCell.baseCell.rowSpan, 10);\n            rowspanNumber++;\n            currentCell.baseCell.setAttribute('rowSpan', rowspanNumber);\n          }\n          break;\n      }\n    }\n\n    if (position === 'top') {\n      currentTr.before(html);\n    } else {\n      const cellHasRowspan = (cell.rowSpan > 1);\n      if (cellHasRowspan) {\n        const lastTrIndex = currentTr[0].rowIndex + (cell.rowSpan - 2);\n        $($(currentTr).parent().find('tr')[lastTrIndex]).after($(html));\n        return;\n      }\n      currentTr.after(html);\n    }\n  }\n\n  /**\n   * Add a new col\n   *\n   * @param {WrappedRange} rng\n   * @param {String} position (left/right)\n   * @return {Node}\n   */\n  addCol(rng, position) {\n    const cell = dom.ancestor(rng.commonAncestor(), dom.isCell);\n    const row = $(cell).closest('tr');\n    const rowsGroup = $(row).siblings();\n    rowsGroup.push(row);\n\n    const vTable = new TableResultAction(cell, TableResultAction.where.Column,\n      TableResultAction.requestAction.Add, $(row).closest('table')[0]);\n    const actions = vTable.getActionList();\n\n    for (let actionIndex = 0; actionIndex < actions.length; actionIndex++) {\n      const currentCell = actions[actionIndex];\n      const tdAttributes = this.recoverAttributes(currentCell.baseCell);\n      switch (currentCell.action) {\n        case TableResultAction.resultAction.AddCell:\n          if (position === 'right') {\n            $(currentCell.baseCell).after('<td' + tdAttributes + '>' + dom.blank + '</td>');\n          } else {\n            $(currentCell.baseCell).before('<td' + tdAttributes + '>' + dom.blank + '</td>');\n          }\n          break;\n        case TableResultAction.resultAction.SumSpanCount:\n          if (position === 'right') {\n            let colspanNumber = parseInt(currentCell.baseCell.colSpan, 10);\n            colspanNumber++;\n            currentCell.baseCell.setAttribute('colSpan', colspanNumber);\n          } else {\n            $(currentCell.baseCell).before('<td' + tdAttributes + '>' + dom.blank + '</td>');\n          }\n          break;\n      }\n    }\n  }\n\n  /*\n  * Copy attributes from element.\n  *\n  * @param {object} Element to recover attributes.\n  * @return {string} Copied string elements.\n  */\n  recoverAttributes(el) {\n    let resultStr = '';\n\n    if (!el) {\n      return resultStr;\n    }\n\n    const attrList = el.attributes || [];\n\n    for (let i = 0; i < attrList.length; i++) {\n      if (attrList[i].name.toLowerCase() === 'id') {\n        continue;\n      }\n\n      if (attrList[i].specified) {\n        resultStr += ' ' + attrList[i].name + '=\\'' + attrList[i].value + '\\'';\n      }\n    }\n\n    return resultStr;\n  }\n\n  /**\n   * Delete current row\n   *\n   * @param {WrappedRange} rng\n   * @return {Node}\n   */\n  deleteRow(rng) {\n    const cell = dom.ancestor(rng.commonAncestor(), dom.isCell);\n    const row = $(cell).closest('tr');\n    const cellPos = row.children('td, th').index($(cell));\n    const rowPos = row[0].rowIndex;\n\n    const vTable = new TableResultAction(cell, TableResultAction.where.Row,\n      TableResultAction.requestAction.Delete, $(row).closest('table')[0]);\n    const actions = vTable.getActionList();\n\n    for (let actionIndex = 0; actionIndex < actions.length; actionIndex++) {\n      if (!actions[actionIndex]) {\n        continue;\n      }\n\n      const baseCell = actions[actionIndex].baseCell;\n      const virtualPosition = actions[actionIndex].virtualTable;\n      const hasRowspan = (baseCell.rowSpan && baseCell.rowSpan > 1);\n      let rowspanNumber = (hasRowspan) ? parseInt(baseCell.rowSpan, 10) : 0;\n      switch (actions[actionIndex].action) {\n        case TableResultAction.resultAction.Ignore:\n          continue;\n        case TableResultAction.resultAction.AddCell:\n          {\n            const nextRow = row.next('tr')[0];\n            if (!nextRow) { continue; }\n            const cloneRow = row[0].cells[cellPos];\n            if (hasRowspan) {\n              if (rowspanNumber > 2) {\n                rowspanNumber--;\n                nextRow.insertBefore(cloneRow, nextRow.cells[cellPos]);\n                nextRow.cells[cellPos].setAttribute('rowSpan', rowspanNumber);\n                nextRow.cells[cellPos].innerHTML = '';\n              } else if (rowspanNumber === 2) {\n                nextRow.insertBefore(cloneRow, nextRow.cells[cellPos]);\n                nextRow.cells[cellPos].removeAttribute('rowSpan');\n                nextRow.cells[cellPos].innerHTML = '';\n              }\n            }\n          }\n          continue;\n        case TableResultAction.resultAction.SubtractSpanCount:\n          if (hasRowspan) {\n            if (rowspanNumber > 2) {\n              rowspanNumber--;\n              baseCell.setAttribute('rowSpan', rowspanNumber);\n              if (virtualPosition.rowIndex !== rowPos && baseCell.cellIndex === cellPos) { baseCell.innerHTML = ''; }\n            } else if (rowspanNumber === 2) {\n              baseCell.removeAttribute('rowSpan');\n              if (virtualPosition.rowIndex !== rowPos && baseCell.cellIndex === cellPos) { baseCell.innerHTML = ''; }\n            }\n          }\n          continue;\n        case TableResultAction.resultAction.RemoveCell:\n          // Do not need remove cell because row will be deleted.\n          continue;\n      }\n    }\n    row.remove();\n  }\n\n  /**\n   * Delete current col\n   *\n   * @param {WrappedRange} rng\n   * @return {Node}\n   */\n  deleteCol(rng) {\n    const cell = dom.ancestor(rng.commonAncestor(), dom.isCell);\n    const row = $(cell).closest('tr');\n    const cellPos = row.children('td, th').index($(cell));\n\n    const vTable = new TableResultAction(cell, TableResultAction.where.Column,\n      TableResultAction.requestAction.Delete, $(row).closest('table')[0]);\n    const actions = vTable.getActionList();\n\n    for (let actionIndex = 0; actionIndex < actions.length; actionIndex++) {\n      if (!actions[actionIndex]) {\n        continue;\n      }\n      switch (actions[actionIndex].action) {\n        case TableResultAction.resultAction.Ignore:\n          continue;\n        case TableResultAction.resultAction.SubtractSpanCount:\n          {\n            const baseCell = actions[actionIndex].baseCell;\n            const hasColspan = (baseCell.colSpan && baseCell.colSpan > 1);\n            if (hasColspan) {\n              let colspanNumber = (baseCell.colSpan) ? parseInt(baseCell.colSpan, 10) : 0;\n              if (colspanNumber > 2) {\n                colspanNumber--;\n                baseCell.setAttribute('colSpan', colspanNumber);\n                if (baseCell.cellIndex === cellPos) { baseCell.innerHTML = ''; }\n              } else if (colspanNumber === 2) {\n                baseCell.removeAttribute('colSpan');\n                if (baseCell.cellIndex === cellPos) { baseCell.innerHTML = ''; }\n              }\n            }\n          }\n          continue;\n        case TableResultAction.resultAction.RemoveCell:\n          dom.remove(actions[actionIndex].baseCell, true);\n          continue;\n      }\n    }\n  }\n\n  /**\n   * create empty table element\n   *\n   * @param {Number} rowCount\n   * @param {Number} colCount\n   * @return {Node}\n   */\n  createTable(colCount, rowCount, options) {\n    const tds = [];\n    let tdHTML;\n    for (let idxCol = 0; idxCol < colCount; idxCol++) {\n      tds.push('<td>' + dom.blank + '</td>');\n    }\n    tdHTML = tds.join('');\n\n    const trs = [];\n    let trHTML;\n    for (let idxRow = 0; idxRow < rowCount; idxRow++) {\n      trs.push('<tr>' + tdHTML + '</tr>');\n    }\n    trHTML = trs.join('');\n    const $table = $('<table>' + trHTML + '</table>');\n    if (options && options.tableClassName) {\n      $table.addClass(options.tableClassName);\n    }\n\n    return $table[0];\n  }\n\n  /**\n   * Delete current table\n   *\n   * @param {WrappedRange} rng\n   * @return {Node}\n   */\n  deleteTable(rng) {\n    const cell = dom.ancestor(rng.commonAncestor(), dom.isCell);\n    $(cell).closest('table').remove();\n  }\n}\n","import $ from 'jquery';\nimport env from '../core/env';\nimport key from '../core/key';\nimport func from '../core/func';\nimport lists from '../core/lists';\nimport dom from '../core/dom';\nimport range from '../core/range';\nimport { readFileAsDataURL, createImage } from '../core/async';\nimport History from '../editing/History';\nimport Style from '../editing/Style';\nimport Typing from '../editing/Typing';\nimport Table from '../editing/Table';\nimport Bullet from '../editing/Bullet';\n\nconst KEY_BOGUS = 'bogus';\n\n/**\n * @class Editor\n */\nexport default class Editor {\n  constructor(context) {\n    this.context = context;\n\n    this.$note = context.layoutInfo.note;\n    this.$editor = context.layoutInfo.editor;\n    this.$editable = context.layoutInfo.editable;\n    this.options = context.options;\n    this.lang = this.options.langInfo;\n\n    this.editable = this.$editable[0];\n    this.lastRange = null;\n    this.snapshot = null;\n\n    this.style = new Style();\n    this.table = new Table();\n    this.typing = new Typing(context);\n    this.bullet = new Bullet();\n    this.history = new History(context);\n\n    this.context.memo('help.undo', this.lang.help.undo);\n    this.context.memo('help.redo', this.lang.help.redo);\n    this.context.memo('help.tab', this.lang.help.tab);\n    this.context.memo('help.untab', this.lang.help.untab);\n    this.context.memo('help.insertParagraph', this.lang.help.insertParagraph);\n    this.context.memo('help.insertOrderedList', this.lang.help.insertOrderedList);\n    this.context.memo('help.insertUnorderedList', this.lang.help.insertUnorderedList);\n    this.context.memo('help.indent', this.lang.help.indent);\n    this.context.memo('help.outdent', this.lang.help.outdent);\n    this.context.memo('help.formatPara', this.lang.help.formatPara);\n    this.context.memo('help.insertHorizontalRule', this.lang.help.insertHorizontalRule);\n    this.context.memo('help.fontName', this.lang.help.fontName);\n\n    // native commands(with execCommand), generate function for execCommand\n    const commands = [\n      'bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript',\n      'justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull',\n      'formatBlock', 'removeFormat', 'backColor',\n    ];\n\n    for (let idx = 0, len = commands.length; idx < len; idx++) {\n      this[commands[idx]] = ((sCmd) => {\n        return (value) => {\n          this.beforeCommand();\n          document.execCommand(sCmd, false, value);\n          this.afterCommand(true);\n        };\n      })(commands[idx]);\n      this.context.memo('help.' + commands[idx], this.lang.help[commands[idx]]);\n    }\n\n    this.fontName = this.wrapCommand((value) => {\n      return this.fontStyling('font-family', env.validFontName(value));\n    });\n\n    this.fontSize = this.wrapCommand((value) => {\n      const unit = this.currentStyle()['font-size-unit'];\n      return this.fontStyling('font-size', value + unit);\n    });\n\n    this.fontSizeUnit = this.wrapCommand((value) => {\n      const size = this.currentStyle()['font-size'];\n      return this.fontStyling('font-size', size + value);\n    });\n\n    for (let idx = 1; idx <= 6; idx++) {\n      this['formatH' + idx] = ((idx) => {\n        return () => {\n          this.formatBlock('H' + idx);\n        };\n      })(idx);\n      this.context.memo('help.formatH' + idx, this.lang.help['formatH' + idx]);\n    }\n\n    this.insertParagraph = this.wrapCommand(() => {\n      this.typing.insertParagraph(this.editable);\n    });\n\n    this.insertOrderedList = this.wrapCommand(() => {\n      this.bullet.insertOrderedList(this.editable);\n    });\n\n    this.insertUnorderedList = this.wrapCommand(() => {\n      this.bullet.insertUnorderedList(this.editable);\n    });\n\n    this.indent = this.wrapCommand(() => {\n      this.bullet.indent(this.editable);\n    });\n\n    this.outdent = this.wrapCommand(() => {\n      this.bullet.outdent(this.editable);\n    });\n\n    /**\n     * insertNode\n     * insert node\n     * @param {Node} node\n     */\n    this.insertNode = this.wrapCommand((node) => {\n      if (this.isLimited($(node).text().length)) {\n        return;\n      }\n      const rng = this.getLastRange();\n      rng.insertNode(node);\n      this.setLastRange(range.createFromNodeAfter(node).select());\n    });\n\n    /**\n     * insert text\n     * @param {String} text\n     */\n    this.insertText = this.wrapCommand((text) => {\n      if (this.isLimited(text.length)) {\n        return;\n      }\n      const rng = this.getLastRange();\n      const textNode = rng.insertNode(dom.createText(text));\n      this.setLastRange(range.create(textNode, dom.nodeLength(textNode)).select());\n    });\n\n    /**\n     * paste HTML\n     * @param {String} markup\n     */\n    this.pasteHTML = this.wrapCommand((markup) => {\n      if (this.isLimited(markup.length)) {\n        return;\n      }\n      markup = this.context.invoke('codeview.purify', markup);\n      const contents = this.getLastRange().pasteHTML(markup);\n      this.setLastRange(range.createFromNodeAfter(lists.last(contents)).select());\n    });\n\n    /**\n     * formatBlock\n     *\n     * @param {String} tagName\n     */\n    this.formatBlock = this.wrapCommand((tagName, $target) => {\n      const onApplyCustomStyle = this.options.callbacks.onApplyCustomStyle;\n      if (onApplyCustomStyle) {\n        onApplyCustomStyle.call(this, $target, this.context, this.onFormatBlock);\n      } else {\n        this.onFormatBlock(tagName, $target);\n      }\n    });\n\n    /**\n     * insert horizontal rule\n     */\n    this.insertHorizontalRule = this.wrapCommand(() => {\n      const hrNode = this.getLastRange().insertNode(dom.create('HR'));\n      if (hrNode.nextSibling) {\n        this.setLastRange(range.create(hrNode.nextSibling, 0).normalize().select());\n      }\n    });\n\n    /**\n     * lineHeight\n     * @param {String} value\n     */\n    this.lineHeight = this.wrapCommand((value) => {\n      this.style.stylePara(this.getLastRange(), {\n        lineHeight: value,\n      });\n    });\n\n    /**\n     * create link (command)\n     *\n     * @param {Object} linkInfo\n     */\n    this.createLink = this.wrapCommand((linkInfo) => {\n      let linkUrl = linkInfo.url;\n      const linkText = linkInfo.text;\n      const isNewWindow = linkInfo.isNewWindow;\n      const checkProtocol = linkInfo.checkProtocol;\n      let rng = linkInfo.range || this.getLastRange();\n      const additionalTextLength = linkText.length - rng.toString().length;\n      if (additionalTextLength > 0 && this.isLimited(additionalTextLength)) {\n        return;\n      }\n      const isTextChanged = rng.toString() !== linkText;\n\n      // handle spaced urls from input\n      if (typeof linkUrl === 'string') {\n        linkUrl = linkUrl.trim();\n      }\n\n      if (this.options.onCreateLink) {\n        linkUrl = this.options.onCreateLink(linkUrl);\n      } else if (checkProtocol) {\n        // if url doesn't have any protocol and not even a relative or a label, use http:// as default\n        linkUrl = /^([A-Za-z][A-Za-z0-9+-.]*\\:|#|\\/)/.test(linkUrl)\n          ? linkUrl : this.options.defaultProtocol + linkUrl;\n      }\n\n      let anchors = [];\n      if (isTextChanged) {\n        rng = rng.deleteContents();\n        const anchor = rng.insertNode($('<A>' + linkText + '</A>')[0]);\n        anchors.push(anchor);\n      } else {\n        anchors = this.style.styleNodes(rng, {\n          nodeName: 'A',\n          expandClosestSibling: true,\n          onlyPartialContains: true,\n        });\n      }\n\n      $.each(anchors, (idx, anchor) => {\n        $(anchor).attr('href', linkUrl);\n        if (isNewWindow) {\n          $(anchor).attr('target', '_blank');\n        } else {\n          $(anchor).removeAttr('target');\n        }\n      });\n\n      const startRange = range.createFromNodeBefore(lists.head(anchors));\n      const startPoint = startRange.getStartPoint();\n      const endRange = range.createFromNodeAfter(lists.last(anchors));\n      const endPoint = endRange.getEndPoint();\n\n      this.setLastRange(\n        range.create(\n          startPoint.node,\n          startPoint.offset,\n          endPoint.node,\n          endPoint.offset\n        ).select()\n      );\n    });\n\n    /**\n     * setting color\n     *\n     * @param {Object} sObjColor  color code\n     * @param {String} sObjColor.foreColor foreground color\n     * @param {String} sObjColor.backColor background color\n     */\n    this.color = this.wrapCommand((colorInfo) => {\n      const foreColor = colorInfo.foreColor;\n      const backColor = colorInfo.backColor;\n\n      if (foreColor) { document.execCommand('foreColor', false, foreColor); }\n      if (backColor) { document.execCommand('backColor', false, backColor); }\n    });\n\n    /**\n     * Set foreground color\n     *\n     * @param {String} colorCode foreground color code\n     */\n    this.foreColor = this.wrapCommand((colorInfo) => {\n      document.execCommand('foreColor', false, colorInfo);\n    });\n\n    /**\n     * insert Table\n     *\n     * @param {String} dimension of table (ex : \"5x5\")\n     */\n    this.insertTable = this.wrapCommand((dim) => {\n      const dimension = dim.split('x');\n\n      const rng = this.getLastRange().deleteContents();\n      rng.insertNode(this.table.createTable(dimension[0], dimension[1], this.options));\n    });\n\n    /**\n     * remove media object and Figure Elements if media object is img with Figure.\n     */\n    this.removeMedia = this.wrapCommand(() => {\n      let $target = $(this.restoreTarget()).parent();\n      if ($target.closest('figure').length) {\n        $target.closest('figure').remove();\n      } else {\n        $target = $(this.restoreTarget()).detach();\n      }\n      this.context.triggerEvent('media.delete', $target, this.$editable);\n    });\n\n    /**\n     * float me\n     *\n     * @param {String} value\n     */\n    this.floatMe = this.wrapCommand((value) => {\n      const $target = $(this.restoreTarget());\n      $target.toggleClass('note-float-left', value === 'left');\n      $target.toggleClass('note-float-right', value === 'right');\n      $target.css('float', (value === 'none' ? '' : value));\n    });\n\n    /**\n     * resize overlay element\n     * @param {String} value\n     */\n    this.resize = this.wrapCommand((value) => {\n      const $target = $(this.restoreTarget());\n      value = parseFloat(value);\n      if (value === 0) {\n        $target.css('width', '');\n      } else {\n        $target.css({\n          width: value * 100 + '%',\n          height: '',\n        });\n      }\n    });\n  }\n\n  initialize() {\n    // bind custom events\n    this.$editable.on('keydown', (event) => {\n      if (event.keyCode === key.code.ENTER) {\n        this.context.triggerEvent('enter', event);\n      }\n      this.context.triggerEvent('keydown', event);\n\n      // keep a snapshot to limit text on input event\n      this.snapshot = this.history.makeSnapshot();\n      this.hasKeyShortCut = false;\n      if (!event.isDefaultPrevented()) {\n        if (this.options.shortcuts) {\n          this.hasKeyShortCut = this.handleKeyMap(event);\n        } else {\n          this.preventDefaultEditableShortCuts(event);\n        }\n      }\n      if (this.isLimited(1, event)) {\n        const lastRange = this.getLastRange();\n        if (lastRange.eo - lastRange.so === 0) {\n          return false;\n        }\n      }\n      this.setLastRange();\n\n      // record undo in the key event except keyMap.\n      if (this.options.recordEveryKeystroke) {\n        if (this.hasKeyShortCut === false) {\n          this.history.recordUndo();\n        }\n      }\n    }).on('keyup', (event) => {\n      this.setLastRange();\n      this.context.triggerEvent('keyup', event);\n    }).on('focus', (event) => {\n      this.setLastRange();\n      this.context.triggerEvent('focus', event);\n    }).on('blur', (event) => {\n      this.context.triggerEvent('blur', event);\n    }).on('mousedown', (event) => {\n      this.context.triggerEvent('mousedown', event);\n    }).on('mouseup', (event) => {\n      this.setLastRange();\n      this.history.recordUndo();\n      this.context.triggerEvent('mouseup', event);\n    }).on('scroll', (event) => {\n      this.context.triggerEvent('scroll', event);\n    }).on('paste', (event) => {\n      this.setLastRange();\n      this.context.triggerEvent('paste', event);\n    }).on('input', () => {\n      // To limit composition characters (e.g. Korean)\n      if (this.isLimited(0) && this.snapshot) {\n        this.history.applySnapshot(this.snapshot);\n      }\n    });\n\n    this.$editable.attr('spellcheck', this.options.spellCheck);\n\n    this.$editable.attr('autocorrect', this.options.spellCheck);\n\n    if (this.options.disableGrammar) {\n      this.$editable.attr('data-gramm', false);\n    }\n\n    // init content before set event\n    this.$editable.html(dom.html(this.$note) || dom.emptyPara);\n\n    this.$editable.on(env.inputEventName, func.debounce(() => {\n      this.context.triggerEvent('change', this.$editable.html(), this.$editable);\n    }, 10));\n\n    this.$editable.on('focusin', (event) => {\n      this.context.triggerEvent('focusin', event);\n    }).on('focusout', (event) => {\n      this.context.triggerEvent('focusout', event);\n    });\n\n    if (this.options.airMode) {\n      if (this.options.overrideContextMenu) {\n        this.$editor.on('contextmenu', (event) => {\n          this.context.triggerEvent('contextmenu', event);\n          return false;\n        });\n      }\n    } else {\n      if (this.options.width) {\n        this.$editor.outerWidth(this.options.width);\n      }\n      if (this.options.height) {\n        this.$editable.outerHeight(this.options.height);\n      }\n      if (this.options.maxHeight) {\n        this.$editable.css('max-height', this.options.maxHeight);\n      }\n      if (this.options.minHeight) {\n        this.$editable.css('min-height', this.options.minHeight);\n      }\n    }\n\n    this.history.recordUndo();\n    this.setLastRange();\n  }\n\n  destroy() {\n    this.$editable.off();\n  }\n\n  handleKeyMap(event) {\n    const keyMap = this.options.keyMap[env.isMac ? 'mac' : 'pc'];\n    const keys = [];\n\n    if (event.metaKey) { keys.push('CMD'); }\n    if (event.ctrlKey && !event.altKey) { keys.push('CTRL'); }\n    if (event.shiftKey) { keys.push('SHIFT'); }\n\n    const keyName = key.nameFromCode[event.keyCode];\n    if (keyName) {\n      keys.push(keyName);\n    }\n\n    const eventName = keyMap[keys.join('+')];\n\n    if (keyName === 'TAB' && !this.options.tabDisable) {\n      this.afterCommand();\n    } else if (eventName) {\n      if (this.context.invoke(eventName) !== false) {\n        event.preventDefault();\n        // if keyMap action was invoked\n        return true;\n      }\n    } else if (key.isEdit(event.keyCode)) {\n      this.afterCommand();\n    }\n    return false;\n  }\n\n  preventDefaultEditableShortCuts(event) {\n    // B(Bold, 66) / I(Italic, 73) / U(Underline, 85)\n    if ((event.ctrlKey || event.metaKey) &&\n      lists.contains([66, 73, 85], event.keyCode)) {\n      event.preventDefault();\n    }\n  }\n\n  isLimited(pad, event) {\n    pad = pad || 0;\n\n    if (typeof event !== 'undefined') {\n      if (key.isMove(event.keyCode) ||\n          key.isNavigation(event.keyCode) ||\n          (event.ctrlKey || event.metaKey) ||\n          lists.contains([key.code.BACKSPACE, key.code.DELETE], event.keyCode)) {\n        return false;\n      }\n    }\n\n    if (this.options.maxTextLength > 0) {\n      if ((this.$editable.text().length + pad) > this.options.maxTextLength) {\n        return true;\n      }\n    }\n    return false;\n  }\n  /**\n   * create range\n   * @return {WrappedRange}\n   */\n  createRange() {\n    this.focus();\n    this.setLastRange();\n    return this.getLastRange();\n  }\n\n  setLastRange(rng) {\n    if (rng) {\n      this.lastRange = rng;\n    } else {\n      this.lastRange = range.create(this.editable);\n\n      if ($(this.lastRange.sc).closest('.note-editable').length === 0) {\n        this.lastRange = range.createFromBodyElement(this.editable);\n      }\n    }\n  }\n\n  getLastRange() {\n    if (!this.lastRange) {\n      this.setLastRange();\n    }\n    return this.lastRange;\n  }\n\n  /**\n   * saveRange\n   *\n   * save current range\n   *\n   * @param {Boolean} [thenCollapse=false]\n   */\n  saveRange(thenCollapse) {\n    if (thenCollapse) {\n      this.getLastRange().collapse().select();\n    }\n  }\n\n  /**\n   * restoreRange\n   *\n   * restore lately range\n   */\n  restoreRange() {\n    if (this.lastRange) {\n      this.lastRange.select();\n      this.focus();\n    }\n  }\n\n  saveTarget(node) {\n    this.$editable.data('target', node);\n  }\n\n  clearTarget() {\n    this.$editable.removeData('target');\n  }\n\n  restoreTarget() {\n    return this.$editable.data('target');\n  }\n\n  /**\n   * currentStyle\n   *\n   * current style\n   * @return {Object|Boolean} unfocus\n   */\n  currentStyle() {\n    let rng = range.create();\n    if (rng) {\n      rng = rng.normalize();\n    }\n    return rng ? this.style.current(rng) : this.style.fromNode(this.$editable);\n  }\n\n  /**\n   * style from node\n   *\n   * @param {jQuery} $node\n   * @return {Object}\n   */\n  styleFromNode($node) {\n    return this.style.fromNode($node);\n  }\n\n  /**\n   * undo\n   */\n  undo() {\n    this.context.triggerEvent('before.command', this.$editable.html());\n    this.history.undo();\n    this.context.triggerEvent('change', this.$editable.html(), this.$editable);\n  }\n\n  /*\n  * commit\n  */\n  commit() {\n    this.context.triggerEvent('before.command', this.$editable.html());\n    this.history.commit();\n    this.context.triggerEvent('change', this.$editable.html(), this.$editable);\n  }\n\n  /**\n   * redo\n   */\n  redo() {\n    this.context.triggerEvent('before.command', this.$editable.html());\n    this.history.redo();\n    this.context.triggerEvent('change', this.$editable.html(), this.$editable);\n  }\n\n  /**\n   * before command\n   */\n  beforeCommand() {\n    this.context.triggerEvent('before.command', this.$editable.html());\n\n    // Set styleWithCSS before run a command\n    document.execCommand('styleWithCSS', false, this.options.styleWithCSS);\n\n    // keep focus on editable before command execution\n    this.focus();\n  }\n\n  /**\n   * after command\n   * @param {Boolean} isPreventTrigger\n   */\n  afterCommand(isPreventTrigger) {\n    this.normalizeContent();\n    this.history.recordUndo();\n    if (!isPreventTrigger) {\n      this.context.triggerEvent('change', this.$editable.html(), this.$editable);\n    }\n  }\n\n  /**\n   * handle tab key\n   */\n  tab() {\n    const rng = this.getLastRange();\n    if (rng.isCollapsed() && rng.isOnCell()) {\n      this.table.tab(rng);\n    } else {\n      if (this.options.tabSize === 0) {\n        return false;\n      }\n\n      if (!this.isLimited(this.options.tabSize)) {\n        this.beforeCommand();\n        this.typing.insertTab(rng, this.options.tabSize);\n        this.afterCommand();\n      }\n    }\n  }\n\n  /**\n   * handle shift+tab key\n   */\n  untab() {\n    const rng = this.getLastRange();\n    if (rng.isCollapsed() && rng.isOnCell()) {\n      this.table.tab(rng, true);\n    } else {\n      if (this.options.tabSize === 0) {\n        return false;\n      }\n    }\n  }\n\n  /**\n   * run given function between beforeCommand and afterCommand\n   */\n  wrapCommand(fn) {\n    return function() {\n      this.beforeCommand();\n      fn.apply(this, arguments);\n      this.afterCommand();\n    };\n  }\n\n  /**\n   * insert image\n   *\n   * @param {String} src\n   * @param {String|Function} param\n   * @return {Promise}\n   */\n  insertImage(src, param) {\n    return createImage(src, param).then(($image) => {\n      this.beforeCommand();\n\n      if (typeof param === 'function') {\n        param($image);\n      } else {\n        if (typeof param === 'string') {\n          $image.attr('data-filename', param);\n        }\n        $image.css('width', Math.min(this.$editable.width(), $image.width()));\n      }\n\n      $image.show();\n      this.getLastRange().insertNode($image[0]);\n      this.setLastRange(range.createFromNodeAfter($image[0]).select());\n      this.afterCommand();\n    }).fail((e) => {\n      this.context.triggerEvent('image.upload.error', e);\n    });\n  }\n\n  /**\n   * insertImages\n   * @param {File[]} files\n   */\n  insertImagesAsDataURL(files) {\n    $.each(files, (idx, file) => {\n      const filename = file.name;\n      if (this.options.maximumImageFileSize && this.options.maximumImageFileSize < file.size) {\n        this.context.triggerEvent('image.upload.error', this.lang.image.maximumFileSizeError);\n      } else {\n        readFileAsDataURL(file).then((dataURL) => {\n          return this.insertImage(dataURL, filename);\n        }).fail(() => {\n          this.context.triggerEvent('image.upload.error');\n        });\n      }\n    });\n  }\n\n  /**\n   * insertImagesOrCallback\n   * @param {File[]} files\n   */\n  insertImagesOrCallback(files) {\n    const callbacks = this.options.callbacks;\n    // If onImageUpload set,\n    if (callbacks.onImageUpload) {\n      this.context.triggerEvent('image.upload', files);\n      // else insert Image as dataURL\n    } else {\n      this.insertImagesAsDataURL(files);\n    }\n  }\n\n  /**\n   * return selected plain text\n   * @return {String} text\n   */\n  getSelectedText() {\n    let rng = this.getLastRange();\n\n    // if range on anchor, expand range with anchor\n    if (rng.isOnAnchor()) {\n      rng = range.createFromNode(dom.ancestor(rng.sc, dom.isAnchor));\n    }\n\n    return rng.toString();\n  }\n\n  onFormatBlock(tagName, $target) {\n    // [workaround] for MSIE, IE need `<`\n    document.execCommand('FormatBlock', false, env.isMSIE ? '<' + tagName + '>' : tagName);\n\n    // support custom class\n    if ($target && $target.length) {\n      // find the exact element has given tagName\n      if ($target[0].tagName.toUpperCase() !== tagName.toUpperCase()) {\n        $target = $target.find(tagName);\n      }\n\n      if ($target && $target.length) {\n        const className = $target[0].className || '';\n        if (className) {\n          const currentRange = this.createRange();\n\n          const $parent = $([currentRange.sc, currentRange.ec]).closest(tagName);\n          $parent.addClass(className);\n        }\n      }\n    }\n  }\n\n  formatPara() {\n    this.formatBlock('P');\n  }\n\n  fontStyling(target, value) {\n    const rng = this.getLastRange();\n\n    if (rng !== '') {\n      const spans = this.style.styleNodes(rng);\n      this.$editor.find('.note-status-output').html('');\n      $(spans).css(target, value);\n\n      // [workaround] added styled bogus span for style\n      //  - also bogus character needed for cursor position\n      if (rng.isCollapsed()) {\n        const firstSpan = lists.head(spans);\n        if (firstSpan && !dom.nodeLength(firstSpan)) {\n          firstSpan.innerHTML = dom.ZERO_WIDTH_NBSP_CHAR;\n          range.createFromNodeAfter(firstSpan.firstChild).select();\n          this.setLastRange();\n          this.$editable.data(KEY_BOGUS, firstSpan);\n        }\n      }\n    } else {\n      const noteStatusOutput = $.now();\n      this.$editor.find('.note-status-output').html('<div id=\"note-status-output-' + noteStatusOutput + '\" class=\"alert alert-info\">' + this.lang.output.noSelection + '</div>');\n      setTimeout(function() { $('#note-status-output-' + noteStatusOutput).remove(); }, 5000);\n    }\n  }\n\n  /**\n   * unlink\n   *\n   * @type command\n   */\n  unlink() {\n    let rng = this.getLastRange();\n    if (rng.isOnAnchor()) {\n      const anchor = dom.ancestor(rng.sc, dom.isAnchor);\n      rng = range.createFromNode(anchor);\n      rng.select();\n      this.setLastRange();\n\n      this.beforeCommand();\n      document.execCommand('unlink');\n      this.afterCommand();\n    }\n  }\n\n  /**\n   * returns link info\n   *\n   * @return {Object}\n   * @return {WrappedRange} return.range\n   * @return {String} return.text\n   * @return {Boolean} [return.isNewWindow=true]\n   * @return {String} [return.url=\"\"]\n   */\n  getLinkInfo() {\n    const rng = this.getLastRange().expand(dom.isAnchor);\n    // Get the first anchor on range(for edit).\n    const $anchor = $(lists.head(rng.nodes(dom.isAnchor)));\n    const linkInfo = {\n      range: rng,\n      text: rng.toString(),\n      url: $anchor.length ? $anchor.attr('href') : '',\n    };\n\n    // When anchor exists,\n    if ($anchor.length) {\n      // Set isNewWindow by checking its target.\n      linkInfo.isNewWindow = $anchor.attr('target') === '_blank';\n    }\n\n    return linkInfo;\n  }\n\n  addRow(position) {\n    const rng = this.getLastRange(this.$editable);\n    if (rng.isCollapsed() && rng.isOnCell()) {\n      this.beforeCommand();\n      this.table.addRow(rng, position);\n      this.afterCommand();\n    }\n  }\n\n  addCol(position) {\n    const rng = this.getLastRange(this.$editable);\n    if (rng.isCollapsed() && rng.isOnCell()) {\n      this.beforeCommand();\n      this.table.addCol(rng, position);\n      this.afterCommand();\n    }\n  }\n\n  deleteRow() {\n    const rng = this.getLastRange(this.$editable);\n    if (rng.isCollapsed() && rng.isOnCell()) {\n      this.beforeCommand();\n      this.table.deleteRow(rng);\n      this.afterCommand();\n    }\n  }\n\n  deleteCol() {\n    const rng = this.getLastRange(this.$editable);\n    if (rng.isCollapsed() && rng.isOnCell()) {\n      this.beforeCommand();\n      this.table.deleteCol(rng);\n      this.afterCommand();\n    }\n  }\n\n  deleteTable() {\n    const rng = this.getLastRange(this.$editable);\n    if (rng.isCollapsed() && rng.isOnCell()) {\n      this.beforeCommand();\n      this.table.deleteTable(rng);\n      this.afterCommand();\n    }\n  }\n\n  /**\n   * @param {Position} pos\n   * @param {jQuery} $target - target element\n   * @param {Boolean} [bKeepRatio] - keep ratio\n   */\n  resizeTo(pos, $target, bKeepRatio) {\n    let imageSize;\n    if (bKeepRatio) {\n      const newRatio = pos.y / pos.x;\n      const ratio = $target.data('ratio');\n      imageSize = {\n        width: ratio > newRatio ? pos.x : pos.y / ratio,\n        height: ratio > newRatio ? pos.x * ratio : pos.y,\n      };\n    } else {\n      imageSize = {\n        width: pos.x,\n        height: pos.y,\n      };\n    }\n\n    $target.css(imageSize);\n  }\n\n  /**\n   * returns whether editable area has focus or not.\n   */\n  hasFocus() {\n    return this.$editable.is(':focus');\n  }\n\n  /**\n   * set focus\n   */\n  focus() {\n    // [workaround] Screen will move when page is scolled in IE.\n    //  - do focus when not focused\n    if (!this.hasFocus()) {\n      this.$editable.focus();\n    }\n  }\n\n  /**\n   * returns whether contents is empty or not.\n   * @return {Boolean}\n   */\n  isEmpty() {\n    return dom.isEmpty(this.$editable[0]) || dom.emptyPara === this.$editable.html();\n  }\n\n  /**\n   * Removes all contents and restores the editable instance to an _emptyPara_.\n   */\n  empty() {\n    this.context.invoke('code', dom.emptyPara);\n  }\n\n  /**\n   * normalize content\n   */\n  normalizeContent() {\n    this.$editable[0].normalize();\n  }\n}\n","import $ from 'jquery';\n\n/**\n * @method readFileAsDataURL\n *\n * read contents of file as representing URL\n *\n * @param {File} file\n * @return {Promise} - then: dataUrl\n */\nexport function readFileAsDataURL(file) {\n  return $.Deferred((deferred) => {\n    $.extend(new FileReader(), {\n      onload: (e) => {\n        const dataURL = e.target.result;\n        deferred.resolve(dataURL);\n      },\n      onerror: (err) => {\n        deferred.reject(err);\n      },\n    }).readAsDataURL(file);\n  }).promise();\n}\n\n/**\n * @method createImage\n *\n * create `<image>` from url string\n *\n * @param {String} url\n * @return {Promise} - then: $image\n */\nexport function createImage(url) {\n  return $.Deferred((deferred) => {\n    const $img = $('<img>');\n\n    $img.one('load', () => {\n      $img.off('error abort');\n      deferred.resolve($img);\n    }).one('error abort', () => {\n      $img.off('load').detach();\n      deferred.reject($img);\n    }).css({\n      display: 'none',\n    }).appendTo(document.body).attr('src', url);\n  }).promise();\n}\n","import lists from '../core/lists';\n\nexport default class Clipboard {\n  constructor(context) {\n    this.context = context;\n    this.$editable = context.layoutInfo.editable;\n  }\n\n  initialize() {\n    this.$editable.on('paste', this.pasteByEvent.bind(this));\n  }\n\n  /**\n   * paste by clipboard event\n   *\n   * @param {Event} event\n   */\n  pasteByEvent(event) {\n    const clipboardData = event.originalEvent.clipboardData;\n\n    if (clipboardData && clipboardData.items && clipboardData.items.length) {\n      const item = clipboardData.items.length > 1 ? clipboardData.items[1] : lists.head(clipboardData.items);\n      if (item.kind === 'file' && item.type.indexOf('image/') !== -1) {\n        // paste img file\n        this.context.invoke('editor.insertImagesOrCallback', [item.getAsFile()]);\n        event.preventDefault();\n      } else if (item.kind === 'string') {\n        // paste text with maxTextLength check\n        if (this.context.invoke('editor.isLimited', clipboardData.getData('Text').length)) {\n          event.preventDefault();\n        }\n      }\n    } else if (window.clipboardData) {\n      // for IE\n      let text = window.clipboardData.getData('text');\n      if (this.context.invoke('editor.isLimited', text.length)) {\n        event.preventDefault();\n      }\n    }\n    // Call editor.afterCommand after proceeding default event handler\n    setTimeout(() => {\n      this.context.invoke('editor.afterCommand');\n    }, 10);\n  }\n}\n","import env from '../core/env';\nimport dom from '../core/dom';\n\nlet CodeMirror;\nif (env.hasCodeMirror) {\n  CodeMirror = window.CodeMirror;\n}\n\n/**\n * @class Codeview\n */\nexport default class CodeView {\n  constructor(context) {\n    this.context = context;\n    this.$editor = context.layoutInfo.editor;\n    this.$editable = context.layoutInfo.editable;\n    this.$codable = context.layoutInfo.codable;\n    this.options = context.options;\n  }\n\n  sync() {\n    const isCodeview = this.isActivated();\n    if (isCodeview && env.hasCodeMirror) {\n      this.$codable.data('cmEditor').save();\n    }\n  }\n\n  /**\n   * @return {Boolean}\n   */\n  isActivated() {\n    return this.$editor.hasClass('codeview');\n  }\n\n  /**\n   * toggle codeview\n   */\n  toggle() {\n    if (this.isActivated()) {\n      this.deactivate();\n    } else {\n      this.activate();\n    }\n    this.context.triggerEvent('codeview.toggled');\n  }\n\n  /**\n   * purify input value\n   * @param value\n   * @returns {*}\n   */\n  purify(value) {\n    if (this.options.codeviewFilter) {\n      // filter code view regex\n      value = value.replace(this.options.codeviewFilterRegex, '');\n      // allow specific iframe tag\n      if (this.options.codeviewIframeFilter) {\n        const whitelist = this.options.codeviewIframeWhitelistSrc.concat(this.options.codeviewIframeWhitelistSrcBase);\n        value = value.replace(/(<iframe.*?>.*?(?:<\\/iframe>)?)/gi, function(tag) {\n          // remove if src attribute is duplicated\n          if (/<.+src(?==?('|\"|\\s)?)[\\s\\S]+src(?=('|\"|\\s)?)[^>]*?>/i.test(tag)) {\n            return '';\n          }\n          for (const src of whitelist) {\n            // pass if src is trusted\n            if ((new RegExp('src=\"(https?:)?\\/\\/' + src.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&') + '\\/(.+)\"')).test(tag)) {\n              return tag;\n            }\n          }\n          return '';\n        });\n      }\n    }\n    return value;\n  }\n\n  /**\n   * activate code view\n   */\n  activate() {\n    this.$codable.val(dom.html(this.$editable, this.options.prettifyHtml));\n    this.$codable.height(this.$editable.height());\n\n    this.context.invoke('toolbar.updateCodeview', true);\n    this.$editor.addClass('codeview');\n    this.$codable.focus();\n\n    // activate CodeMirror as codable\n    if (env.hasCodeMirror) {\n      const cmEditor = CodeMirror.fromTextArea(this.$codable[0], this.options.codemirror);\n\n      // CodeMirror TernServer\n      if (this.options.codemirror.tern) {\n        const server = new CodeMirror.TernServer(this.options.codemirror.tern);\n        cmEditor.ternServer = server;\n        cmEditor.on('cursorActivity', (cm) => {\n          server.updateArgHints(cm);\n        });\n      }\n\n      cmEditor.on('blur', (event) => {\n        this.context.triggerEvent('blur.codeview', cmEditor.getValue(), event);\n      });\n      cmEditor.on('change', () => {\n        this.context.triggerEvent('change.codeview', cmEditor.getValue(), cmEditor);\n      });\n\n      // CodeMirror hasn't Padding.\n      cmEditor.setSize(null, this.$editable.outerHeight());\n      this.$codable.data('cmEditor', cmEditor);\n    } else {\n      this.$codable.on('blur', (event) => {\n        this.context.triggerEvent('blur.codeview', this.$codable.val(), event);\n      });\n      this.$codable.on('input', () => {\n        this.context.triggerEvent('change.codeview', this.$codable.val(), this.$codable);\n      });\n    }\n  }\n\n  /**\n   * deactivate code view\n   */\n  deactivate() {\n    // deactivate CodeMirror as codable\n    if (env.hasCodeMirror) {\n      const cmEditor = this.$codable.data('cmEditor');\n      this.$codable.val(cmEditor.getValue());\n      cmEditor.toTextArea();\n    }\n\n    const value = this.purify(dom.value(this.$codable, this.options.prettifyHtml) || dom.emptyPara);\n    const isChange = this.$editable.html() !== value;\n\n    this.$editable.html(value);\n    this.$editable.height(this.options.height ? this.$codable.height() : 'auto');\n    this.$editor.removeClass('codeview');\n\n    if (isChange) {\n      this.context.triggerEvent('change', this.$editable.html(), this.$editable);\n    }\n\n    this.$editable.focus();\n\n    this.context.invoke('toolbar.updateCodeview', false);\n  }\n\n  destroy() {\n    if (this.isActivated()) {\n      this.deactivate();\n    }\n  }\n}\n","import $ from 'jquery';\n\nexport default class Dropzone {\n  constructor(context) {\n    this.context = context;\n    this.$eventListener = $(document);\n    this.$editor = context.layoutInfo.editor;\n    this.$editable = context.layoutInfo.editable;\n    this.options = context.options;\n    this.lang = this.options.langInfo;\n    this.documentEventHandlers = {};\n\n    this.$dropzone = $([\n      '<div class=\"note-dropzone\">',\n        '<div class=\"note-dropzone-message\"/>',\n      '</div>',\n    ].join('')).prependTo(this.$editor);\n  }\n\n  /**\n   * attach Drag and Drop Events\n   */\n  initialize() {\n    if (this.options.disableDragAndDrop) {\n      // prevent default drop event\n      this.documentEventHandlers.onDrop = (e) => {\n        e.preventDefault();\n      };\n      // do not consider outside of dropzone\n      this.$eventListener = this.$dropzone;\n      this.$eventListener.on('drop', this.documentEventHandlers.onDrop);\n    } else {\n      this.attachDragAndDropEvent();\n    }\n  }\n\n  /**\n   * attach Drag and Drop Events\n   */\n  attachDragAndDropEvent() {\n    let collection = $();\n    const $dropzoneMessage = this.$dropzone.find('.note-dropzone-message');\n\n    this.documentEventHandlers.onDragenter = (e) => {\n      const isCodeview = this.context.invoke('codeview.isActivated');\n      const hasEditorSize = this.$editor.width() > 0 && this.$editor.height() > 0;\n      if (!isCodeview && !collection.length && hasEditorSize) {\n        this.$editor.addClass('dragover');\n        this.$dropzone.width(this.$editor.width());\n        this.$dropzone.height(this.$editor.height());\n        $dropzoneMessage.text(this.lang.image.dragImageHere);\n      }\n      collection = collection.add(e.target);\n    };\n\n    this.documentEventHandlers.onDragleave = (e) => {\n      collection = collection.not(e.target);\n\n      // If nodeName is BODY, then just make it over (fix for IE)\n      if (!collection.length || e.target.nodeName === 'BODY') {\n        collection = $();\n        this.$editor.removeClass('dragover');\n      }\n    };\n\n    this.documentEventHandlers.onDrop = () => {\n      collection = $();\n      this.$editor.removeClass('dragover');\n    };\n\n    // show dropzone on dragenter when dragging a object to document\n    // -but only if the editor is visible, i.e. has a positive width and height\n    this.$eventListener.on('dragenter', this.documentEventHandlers.onDragenter)\n      .on('dragleave', this.documentEventHandlers.onDragleave)\n      .on('drop', this.documentEventHandlers.onDrop);\n\n    // change dropzone's message on hover.\n    this.$dropzone.on('dragenter', () => {\n      this.$dropzone.addClass('hover');\n      $dropzoneMessage.text(this.lang.image.dropImage);\n    }).on('dragleave', () => {\n      this.$dropzone.removeClass('hover');\n      $dropzoneMessage.text(this.lang.image.dragImageHere);\n    });\n\n    // attach dropImage\n    this.$dropzone.on('drop', (event) => {\n      const dataTransfer = event.originalEvent.dataTransfer;\n\n      // stop the browser from opening the dropped content\n      event.preventDefault();\n\n      if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {\n        this.$editable.focus();\n        this.context.invoke('editor.insertImagesOrCallback', dataTransfer.files);\n      } else {\n        $.each(dataTransfer.types, (idx, type) => {\n          // skip moz-specific types\n          if (type.toLowerCase().indexOf('_moz_') > -1) {\n            return;\n          }\n          const content = dataTransfer.getData(type);\n\n          if (type.toLowerCase().indexOf('text') > -1) {\n            this.context.invoke('editor.pasteHTML', content);\n          } else {\n            $(content).each((idx, item) => {\n              this.context.invoke('editor.insertNode', item);\n            });\n          }\n        });\n      }\n    }).on('dragover', false); // prevent default dragover event\n  }\n\n  destroy() {\n    Object.keys(this.documentEventHandlers).forEach((key) => {\n      this.$eventListener.off(key.substr(2).toLowerCase(), this.documentEventHandlers[key]);\n    });\n    this.documentEventHandlers = {};\n  }\n}\n","import $ from 'jquery';\nconst EDITABLE_PADDING = 24;\n\nexport default class Statusbar {\n  constructor(context) {\n    this.$document = $(document);\n    this.$statusbar = context.layoutInfo.statusbar;\n    this.$editable = context.layoutInfo.editable;\n    this.options = context.options;\n  }\n\n  initialize() {\n    if (this.options.airMode || this.options.disableResizeEditor) {\n      this.destroy();\n      return;\n    }\n\n    this.$statusbar.on('mousedown', (event) => {\n      event.preventDefault();\n      event.stopPropagation();\n\n      const editableTop = this.$editable.offset().top - this.$document.scrollTop();\n      const onMouseMove = (event) => {\n        let height = event.clientY - (editableTop + EDITABLE_PADDING);\n\n        height = (this.options.minheight > 0) ? Math.max(height, this.options.minheight) : height;\n        height = (this.options.maxHeight > 0) ? Math.min(height, this.options.maxHeight) : height;\n\n        this.$editable.height(height);\n      };\n\n      this.$document.on('mousemove', onMouseMove).one('mouseup', () => {\n        this.$document.off('mousemove', onMouseMove);\n      });\n    });\n  }\n\n  destroy() {\n    this.$statusbar.off();\n    this.$statusbar.addClass('locked');\n  }\n}\n","import $ from 'jquery';\n\nexport default class Fullscreen {\n  constructor(context) {\n    this.context = context;\n\n    this.$editor = context.layoutInfo.editor;\n    this.$toolbar = context.layoutInfo.toolbar;\n    this.$editable = context.layoutInfo.editable;\n    this.$codable = context.layoutInfo.codable;\n\n    this.$window = $(window);\n    this.$scrollbar = $('html, body');\n\n    this.onResize = () => {\n      this.resizeTo({\n        h: this.$window.height() - this.$toolbar.outerHeight(),\n      });\n    };\n  }\n\n  resizeTo(size) {\n    this.$editable.css('height', size.h);\n    this.$codable.css('height', size.h);\n    if (this.$codable.data('cmeditor')) {\n      this.$codable.data('cmeditor').setsize(null, size.h);\n    }\n  }\n\n  /**\n   * toggle fullscreen\n   */\n  toggle() {\n    this.$editor.toggleClass('fullscreen');\n    if (this.isFullscreen()) {\n      this.$editable.data('orgHeight', this.$editable.css('height'));\n      this.$editable.data('orgMaxHeight', this.$editable.css('maxHeight'));\n      this.$editable.css('maxHeight', '');\n      this.$window.on('resize', this.onResize).trigger('resize');\n      this.$scrollbar.css('overflow', 'hidden');\n    } else {\n      this.$window.off('resize', this.onResize);\n      this.resizeTo({ h: this.$editable.data('orgHeight') });\n      this.$editable.css('maxHeight', this.$editable.css('orgMaxHeight'));\n      this.$scrollbar.css('overflow', 'visible');\n    }\n\n    this.context.invoke('toolbar.updateFullscreen', this.isFullscreen());\n  }\n\n  isFullscreen() {\n    return this.$editor.hasClass('fullscreen');\n  }\n}\n","import $ from 'jquery';\nimport dom from '../core/dom';\n\nexport default class Handle {\n  constructor(context) {\n    this.context = context;\n    this.$document = $(document);\n    this.$editingArea = context.layoutInfo.editingArea;\n    this.options = context.options;\n    this.lang = this.options.langInfo;\n\n    this.events = {\n      'summernote.mousedown': (we, e) => {\n        if (this.update(e.target, e)) {\n          e.preventDefault();\n        }\n      },\n      'summernote.keyup summernote.scroll summernote.change summernote.dialog.shown': () => {\n        this.update();\n      },\n      'summernote.disable summernote.blur': () => {\n        this.hide();\n      },\n      'summernote.codeview.toggled': () => {\n        this.update();\n      },\n    };\n  }\n\n  initialize() {\n    this.$handle = $([\n      '<div class=\"note-handle\">',\n        '<div class=\"note-control-selection\">',\n          '<div class=\"note-control-selection-bg\"></div>',\n          '<div class=\"note-control-holder note-control-nw\"></div>',\n          '<div class=\"note-control-holder note-control-ne\"></div>',\n          '<div class=\"note-control-holder note-control-sw\"></div>',\n          '<div class=\"',\n            (this.options.disableResizeImage ? 'note-control-holder' : 'note-control-sizing'),\n          ' note-control-se\"></div>',\n          (this.options.disableResizeImage ? '' : '<div class=\"note-control-selection-info\"></div>'),\n        '</div>',\n      '</div>',\n    ].join('')).prependTo(this.$editingArea);\n\n    this.$handle.on('mousedown', (event) => {\n      if (dom.isControlSizing(event.target)) {\n        event.preventDefault();\n        event.stopPropagation();\n\n        const $target = this.$handle.find('.note-control-selection').data('target');\n        const posStart = $target.offset();\n        const scrollTop = this.$document.scrollTop();\n\n        const onMouseMove = (event) => {\n          this.context.invoke('editor.resizeTo', {\n            x: event.clientX - posStart.left,\n            y: event.clientY - (posStart.top - scrollTop),\n          }, $target, !event.shiftKey);\n\n          this.update($target[0], event);\n        };\n\n        this.$document\n          .on('mousemove', onMouseMove)\n          .one('mouseup', (e) => {\n            e.preventDefault();\n            this.$document.off('mousemove', onMouseMove);\n            this.context.invoke('editor.afterCommand');\n          });\n\n        if (!$target.data('ratio')) { // original ratio.\n          $target.data('ratio', $target.height() / $target.width());\n        }\n      }\n    });\n\n    // Listen for scrolling on the handle overlay.\n    this.$handle.on('wheel', (e) => {\n      e.preventDefault();\n      this.update();\n    });\n  }\n\n  destroy() {\n    this.$handle.remove();\n  }\n\n  update(target, event) {\n    if (this.context.isDisabled()) {\n      return false;\n    }\n\n    const isImage = dom.isImg(target);\n    const $selection = this.$handle.find('.note-control-selection');\n\n    this.context.invoke('imagePopover.update', target, event);\n\n    if (isImage) {\n      const $image = $(target);\n      const position = $image.position();\n      const pos = {\n        left: position.left + parseInt($image.css('marginLeft'), 10),\n        top: position.top + parseInt($image.css('marginTop'), 10),\n      };\n\n      // exclude margin\n      const imageSize = {\n        w: $image.outerWidth(false),\n        h: $image.outerHeight(false),\n      };\n\n      $selection.css({\n        display: 'block',\n        left: pos.left,\n        top: pos.top,\n        width: imageSize.w,\n        height: imageSize.h,\n      }).data('target', $image); // save current image element.\n\n      const origImageObj = new Image();\n      origImageObj.src = $image.attr('src');\n\n      const sizingText = imageSize.w + 'x' + imageSize.h + ' (' + this.lang.image.original + ': ' + origImageObj.width + 'x' + origImageObj.height + ')';\n      $selection.find('.note-control-selection-info').text(sizingText);\n      this.context.invoke('editor.saveTarget', target);\n    } else {\n      this.hide();\n    }\n\n    return isImage;\n  }\n\n  /**\n   * hide\n   *\n   * @param {jQuery} $handle\n   */\n  hide() {\n    this.context.invoke('editor.clearTarget');\n    this.$handle.children().hide();\n  }\n}\n","import $ from 'jquery';\nimport lists from '../core/lists';\nimport key from '../core/key';\n\nconst defaultScheme = 'http://';\nconst linkPattern = /^([A-Za-z][A-Za-z0-9+-.]*\\:[\\/]{2}|tel:|mailto:[A-Z0-9._%+-]+@)?(www\\.)?(.+)$/i;\n\nexport default class AutoLink {\n  constructor(context) {\n    this.context = context;\n    this.events = {\n      'summernote.keyup': (we, e) => {\n        if (!e.isDefaultPrevented()) {\n          this.handleKeyup(e);\n        }\n      },\n      'summernote.keydown': (we, e) => {\n        this.handleKeydown(e);\n      },\n    };\n  }\n\n  initialize() {\n    this.lastWordRange = null;\n  }\n\n  destroy() {\n    this.lastWordRange = null;\n  }\n\n  replace() {\n    if (!this.lastWordRange) {\n      return;\n    }\n\n    const keyword = this.lastWordRange.toString();\n    const match = keyword.match(linkPattern);\n\n    if (match && (match[1] || match[2])) {\n      const link = match[1] ? keyword : defaultScheme + keyword;\n      const urlText = keyword.replace(/^(?:https?:\\/\\/)?(?:tel?:?)?(?:mailto?:?)?(?:www\\.)?/i, '').split('/')[0];\n      const node = $('<a />').html(urlText).attr('href', link)[0];\n      if (this.context.options.linkTargetBlank) {\n        $(node).attr('target', '_blank');\n      }\n\n      this.lastWordRange.insertNode(node);\n      this.lastWordRange = null;\n      this.context.invoke('editor.focus');\n    }\n  }\n\n  handleKeydown(e) {\n    if (lists.contains([key.code.ENTER, key.code.SPACE], e.keyCode)) {\n      const wordRange = this.context.invoke('editor.createRange').getWordRange();\n      this.lastWordRange = wordRange;\n    }\n  }\n\n  handleKeyup(e) {\n    if (lists.contains([key.code.ENTER, key.code.SPACE], e.keyCode)) {\n      this.replace();\n    }\n  }\n}\n","import dom from '../core/dom';\n\n/**\n * textarea auto sync.\n */\nexport default class AutoSync {\n  constructor(context) {\n    this.$note = context.layoutInfo.note;\n    this.events = {\n      'summernote.change': () => {\n        this.$note.val(context.invoke('code'));\n      },\n    };\n  }\n\n  shouldInitialize() {\n    return dom.isTextarea(this.$note[0]);\n  }\n}\n","import lists from '../core/lists';\nimport dom from '../core/dom';\nimport key from '../core/key';\n\nexport default class AutoReplace {\n  constructor(context) {\n    this.context = context;\n    this.options = context.options.replace || {};\n\n    this.keys = [key.code.ENTER, key.code.SPACE, key.code.PERIOD, key.code.COMMA, key.code.SEMICOLON, key.code.SLASH];\n    this.previousKeydownCode = null;\n\n    this.events = {\n      'summernote.keyup': (we, e) => {\n        if (!e.isDefaultPrevented()) {\n          this.handleKeyup(e);\n        }\n      },\n      'summernote.keydown': (we, e) => {\n        this.handleKeydown(e);\n      },\n    };\n  }\n\n  shouldInitialize() {\n    return !!this.options.match;\n  }\n\n  initialize() {\n    this.lastWord = null;\n  }\n\n  destroy() {\n    this.lastWord = null;\n  }\n\n  replace() {\n    if (!this.lastWord) {\n      return;\n    }\n\n    const self = this;\n    const keyword = this.lastWord.toString();\n    this.options.match(keyword, function(match) {\n      if (match) {\n        let node = '';\n\n        if (typeof match === 'string') {\n          node = dom.createText(match);\n        } else if (match instanceof jQuery) {\n          node = match[0];\n        } else if (match instanceof Node) {\n          node = match;\n        }\n\n        if (!node) return;\n        self.lastWord.insertNode(node);\n        self.lastWord = null;\n        self.context.invoke('editor.focus');\n      }\n    });\n  }\n\n  handleKeydown(e) {\n    // this forces it to remember the last whole word, even if multiple termination keys are pressed\n    // before the previous key is let go.\n    if (this.previousKeydownCode && lists.contains(this.keys, this.previousKeydownCode)) {\n      this.previousKeydownCode = e.keyCode;\n      return;\n    }\n\n    if (lists.contains(this.keys, e.keyCode)) {\n      const wordRange = this.context.invoke('editor.createRange').getWordRange();\n      this.lastWord = wordRange;\n    }\n    this.previousKeydownCode = e.keyCode;\n  }\n\n  handleKeyup(e) {\n    if (lists.contains(this.keys, e.keyCode)) {\n      this.replace();\n    }\n  }\n}\n","import $ from 'jquery';\nexport default class Placeholder {\n  constructor(context) {\n    this.context = context;\n\n    this.$editingArea = context.layoutInfo.editingArea;\n    this.options = context.options;\n\n    if (this.options.inheritPlaceholder === true) {\n      // get placeholder value from the original element\n      this.options.placeholder = this.context.$note.attr('placeholder') || this.options.placeholder;\n    }\n\n    this.events = {\n      'summernote.init summernote.change': () => {\n        this.update();\n      },\n      'summernote.codeview.toggled': () => {\n        this.update();\n      },\n    };\n  }\n\n  shouldInitialize() {\n    return !!this.options.placeholder;\n  }\n\n  initialize() {\n    this.$placeholder = $('<div class=\"note-placeholder\">');\n    this.$placeholder.on('click', () => {\n      this.context.invoke('focus');\n    }).html(this.options.placeholder).prependTo(this.$editingArea);\n\n    this.update();\n  }\n\n  destroy() {\n    this.$placeholder.remove();\n  }\n\n  update() {\n    const isShow = !this.context.invoke('codeview.isActivated') && this.context.invoke('editor.isEmpty');\n    this.$placeholder.toggle(isShow);\n  }\n}\n","import $ from 'jquery';\nimport func from '../core/func';\nimport lists from '../core/lists';\nimport env from '../core/env';\n\nexport default class Buttons {\n  constructor(context) {\n    this.ui = $.summernote.ui;\n    this.context = context;\n    this.$toolbar = context.layoutInfo.toolbar;\n    this.options = context.options;\n    this.lang = this.options.langInfo;\n    this.invertedKeyMap = func.invertObject(\n      this.options.keyMap[env.isMac ? 'mac' : 'pc']\n    );\n  }\n\n  representShortcut(editorMethod) {\n    let shortcut = this.invertedKeyMap[editorMethod];\n    if (!this.options.shortcuts || !shortcut) {\n      return '';\n    }\n\n    if (env.isMac) {\n      shortcut = shortcut.replace('CMD', '⌘').replace('SHIFT', '⇧');\n    }\n\n    shortcut = shortcut.replace('BACKSLASH', '\\\\')\n      .replace('SLASH', '/')\n      .replace('LEFTBRACKET', '[')\n      .replace('RIGHTBRACKET', ']');\n\n    return ' (' + shortcut + ')';\n  }\n\n  button(o) {\n    if (!this.options.tooltip && o.tooltip) {\n      delete o.tooltip;\n    }\n    o.container = this.options.container;\n    return this.ui.button(o);\n  }\n\n  initialize() {\n    this.addToolbarButtons();\n    this.addImagePopoverButtons();\n    this.addLinkPopoverButtons();\n    this.addTablePopoverButtons();\n    this.fontInstalledMap = {};\n  }\n\n  destroy() {\n    delete this.fontInstalledMap;\n  }\n\n  isFontInstalled(name) {\n    if (!Object.prototype.hasOwnProperty.call(this.fontInstalledMap, name)) {\n      this.fontInstalledMap[name] = env.isFontInstalled(name) ||\n        lists.contains(this.options.fontNamesIgnoreCheck, name);\n    }\n    return this.fontInstalledMap[name];\n  }\n\n  isFontDeservedToAdd(name) {\n    name = name.toLowerCase();\n    return (name !== '' && this.isFontInstalled(name) && env.genericFontFamilies.indexOf(name) === -1);\n  }\n\n  colorPalette(className, tooltip, backColor, foreColor) {\n    return this.ui.buttonGroup({\n      className: 'note-color ' + className,\n      children: [\n        this.button({\n          className: 'note-current-color-button',\n          contents: this.ui.icon(this.options.icons.font + ' note-recent-color'),\n          tooltip: tooltip,\n          click: (e) => {\n            const $button = $(e.currentTarget);\n            if (backColor && foreColor) {\n              this.context.invoke('editor.color', {\n                backColor: $button.attr('data-backColor'),\n                foreColor: $button.attr('data-foreColor'),\n              });\n            } else if (backColor) {\n              this.context.invoke('editor.color', {\n                backColor: $button.attr('data-backColor'),\n              });\n            } else if (foreColor) {\n              this.context.invoke('editor.color', {\n                foreColor: $button.attr('data-foreColor'),\n              });\n            }\n          },\n          callback: ($button) => {\n            const $recentColor = $button.find('.note-recent-color');\n            if (backColor) {\n              $recentColor.css('background-color', this.options.colorButton.backColor);\n              $button.attr('data-backColor', this.options.colorButton.backColor);\n            }\n            if (foreColor) {\n              $recentColor.css('color', this.options.colorButton.foreColor);\n              $button.attr('data-foreColor', this.options.colorButton.foreColor);\n            } else {\n              $recentColor.css('color', 'transparent');\n            }\n          },\n        }),\n        this.button({\n          className: 'dropdown-toggle',\n          contents: this.ui.dropdownButtonContents('', this.options),\n          tooltip: this.lang.color.more,\n          data: {\n            toggle: 'dropdown',\n          },\n        }),\n        this.ui.dropdown({\n          items: (backColor ? [\n            '<div class=\"note-palette\">',\n              '<div class=\"note-palette-title\">' + this.lang.color.background + '</div>',\n              '<div>',\n                '<button type=\"button\" class=\"note-color-reset btn btn-light\" data-event=\"backColor\" data-value=\"inherit\">',\n                  this.lang.color.transparent,\n                '</button>',\n              '</div>',\n              '<div class=\"note-holder\" data-event=\"backColor\"/>',\n              '<div>',\n                '<button type=\"button\" class=\"note-color-select btn btn-light\" data-event=\"openPalette\" data-value=\"backColorPicker\">',\n                  this.lang.color.cpSelect,\n                '</button>',\n                '<input type=\"color\" id=\"backColorPicker\" class=\"note-btn note-color-select-btn\" value=\"' + this.options.colorButton.backColor + '\" data-event=\"backColorPalette\">',\n              '</div>',\n              '<div class=\"note-holder-custom\" id=\"backColorPalette\" data-event=\"backColor\"/>',\n            '</div>',\n          ].join('') : '') +\n          (foreColor ? [\n            '<div class=\"note-palette\">',\n              '<div class=\"note-palette-title\">' + this.lang.color.foreground + '</div>',\n              '<div>',\n                '<button type=\"button\" class=\"note-color-reset btn btn-light\" data-event=\"removeFormat\" data-value=\"foreColor\">',\n                  this.lang.color.resetToDefault,\n                '</button>',\n              '</div>',\n              '<div class=\"note-holder\" data-event=\"foreColor\"/>',\n              '<div>',\n                '<button type=\"button\" class=\"note-color-select btn btn-light\" data-event=\"openPalette\" data-value=\"foreColorPicker\">',\n                  this.lang.color.cpSelect,\n                '</button>',\n                '<input type=\"color\" id=\"foreColorPicker\" class=\"note-btn note-color-select-btn\" value=\"' + this.options.colorButton.foreColor + '\" data-event=\"foreColorPalette\">',\n              '</div>', // Fix missing Div, Commented to find easily if it's wrong\n              '<div class=\"note-holder-custom\" id=\"foreColorPalette\" data-event=\"foreColor\"/>',\n            '</div>',\n          ].join('') : ''),\n          callback: ($dropdown) => {\n            $dropdown.find('.note-holder').each((idx, item) => {\n              const $holder = $(item);\n              $holder.append(this.ui.palette({\n                colors: this.options.colors,\n                colorsName: this.options.colorsName,\n                eventName: $holder.data('event'),\n                container: this.options.container,\n                tooltip: this.options.tooltip,\n              }).render());\n            });\n            /* TODO: do we have to record recent custom colors within cookies? */\n            var customColors = [\n              ['#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF'],\n            ];\n            $dropdown.find('.note-holder-custom').each((idx, item) => {\n              const $holder = $(item);\n              $holder.append(this.ui.palette({\n                colors: customColors,\n                colorsName: customColors,\n                eventName: $holder.data('event'),\n                container: this.options.container,\n                tooltip: this.options.tooltip,\n              }).render());\n            });\n            $dropdown.find('input[type=color]').each((idx, item) => {\n              $(item).change(function() {\n                const $chip = $dropdown.find('#' + $(this).data('event')).find('.note-color-btn').first();\n                const color = this.value.toUpperCase();\n                $chip.css('background-color', color)\n                  .attr('aria-label', color)\n                  .attr('data-value', color)\n                  .attr('data-original-title', color);\n                $chip.click();\n              });\n            });\n          },\n          click: (event) => {\n            event.stopPropagation();\n\n            const $parent = $('.' + className).find('.note-dropdown-menu');\n            const $button = $(event.target);\n            const eventName = $button.data('event');\n            const value = $button.attr('data-value');\n\n            if (eventName === 'openPalette') {\n              const $picker = $parent.find('#' + value);\n              const $palette = $($parent.find('#' + $picker.data('event')).find('.note-color-row')[0]);\n\n              // Shift palette chips\n              const $chip = $palette.find('.note-color-btn').last().detach();\n\n              // Set chip attributes\n              const color = $picker.val();\n              $chip.css('background-color', color)\n                .attr('aria-label', color)\n                .attr('data-value', color)\n                .attr('data-original-title', color);\n              $palette.prepend($chip);\n              $picker.click();\n            } else {\n              if (lists.contains(['backColor', 'foreColor'], eventName)) {\n                const key = eventName === 'backColor' ? 'background-color' : 'color';\n                const $color = $button.closest('.note-color').find('.note-recent-color');\n                const $currentButton = $button.closest('.note-color').find('.note-current-color-button');\n\n                $color.css(key, value);\n                $currentButton.attr('data-' + eventName, value);\n              }\n              this.context.invoke('editor.' + eventName, value);\n            }\n          },\n        }),\n      ],\n    }).render();\n  }\n\n  addToolbarButtons() {\n    this.context.memo('button.style', () => {\n      return this.ui.buttonGroup([\n        this.button({\n          className: 'dropdown-toggle',\n          contents: this.ui.dropdownButtonContents(\n            this.ui.icon(this.options.icons.magic), this.options\n          ),\n          tooltip: this.lang.style.style,\n          data: {\n            toggle: 'dropdown',\n          },\n        }),\n        this.ui.dropdown({\n          className: 'dropdown-style',\n          items: this.options.styleTags,\n          title: this.lang.style.style,\n          template: (item) => {\n            // TBD: need to be simplified\n            if (typeof item === 'string') {\n              item = {\n                tag: item,\n                title: (Object.prototype.hasOwnProperty.call(this.lang.style, item) ? this.lang.style[item] : item),\n              };\n            }\n\n            const tag = item.tag;\n            const title = item.title;\n            const style = item.style ? ' style=\"' + item.style + '\" ' : '';\n            const className = item.className ? ' class=\"' + item.className + '\"' : '';\n\n            return '<' + tag + style + className + '>' + title + '</' + tag + '>';\n          },\n          click: this.context.createInvokeHandler('editor.formatBlock'),\n        }),\n      ]).render();\n    });\n\n    for (let styleIdx = 0, styleLen = this.options.styleTags.length; styleIdx < styleLen; styleIdx++) {\n      const item = this.options.styleTags[styleIdx];\n\n      this.context.memo('button.style.' + item, () => {\n        return this.button({\n          className: 'note-btn-style-' + item,\n          contents: '<div data-value=\"' + item + '\">' + item.toUpperCase() + '</div>',\n          tooltip: this.lang.style[item],\n          click: this.context.createInvokeHandler('editor.formatBlock'),\n        }).render();\n      });\n    }\n\n    this.context.memo('button.bold', () => {\n      return this.button({\n        className: 'note-btn-bold',\n        contents: this.ui.icon(this.options.icons.bold),\n        tooltip: this.lang.font.bold + this.representShortcut('bold'),\n        click: this.context.createInvokeHandlerAndUpdateState('editor.bold'),\n      }).render();\n    });\n\n    this.context.memo('button.italic', () => {\n      return this.button({\n        className: 'note-btn-italic',\n        contents: this.ui.icon(this.options.icons.italic),\n        tooltip: this.lang.font.italic + this.representShortcut('italic'),\n        click: this.context.createInvokeHandlerAndUpdateState('editor.italic'),\n      }).render();\n    });\n\n    this.context.memo('button.underline', () => {\n      return this.button({\n        className: 'note-btn-underline',\n        contents: this.ui.icon(this.options.icons.underline),\n        tooltip: this.lang.font.underline + this.representShortcut('underline'),\n        click: this.context.createInvokeHandlerAndUpdateState('editor.underline'),\n      }).render();\n    });\n\n    this.context.memo('button.clear', () => {\n      return this.button({\n        contents: this.ui.icon(this.options.icons.eraser),\n        tooltip: this.lang.font.clear + this.representShortcut('removeFormat'),\n        click: this.context.createInvokeHandler('editor.removeFormat'),\n      }).render();\n    });\n\n    this.context.memo('button.strikethrough', () => {\n      return this.button({\n        className: 'note-btn-strikethrough',\n        contents: this.ui.icon(this.options.icons.strikethrough),\n        tooltip: this.lang.font.strikethrough + this.representShortcut('strikethrough'),\n        click: this.context.createInvokeHandlerAndUpdateState('editor.strikethrough'),\n      }).render();\n    });\n\n    this.context.memo('button.superscript', () => {\n      return this.button({\n        className: 'note-btn-superscript',\n        contents: this.ui.icon(this.options.icons.superscript),\n        tooltip: this.lang.font.superscript,\n        click: this.context.createInvokeHandlerAndUpdateState('editor.superscript'),\n      }).render();\n    });\n\n    this.context.memo('button.subscript', () => {\n      return this.button({\n        className: 'note-btn-subscript',\n        contents: this.ui.icon(this.options.icons.subscript),\n        tooltip: this.lang.font.subscript,\n        click: this.context.createInvokeHandlerAndUpdateState('editor.subscript'),\n      }).render();\n    });\n\n    this.context.memo('button.fontname', () => {\n      const styleInfo = this.context.invoke('editor.currentStyle');\n\n      if (this.options.addDefaultFonts) {\n        // Add 'default' fonts into the fontnames array if not exist\n        $.each(styleInfo['font-family'].split(','), (idx, fontname) => {\n          fontname = fontname.trim().replace(/['\"]+/g, '');\n          if (this.isFontDeservedToAdd(fontname)) {\n            if (this.options.fontNames.indexOf(fontname) === -1) {\n              this.options.fontNames.push(fontname);\n            }\n          }\n        });\n      }\n\n      return this.ui.buttonGroup([\n        this.button({\n          className: 'dropdown-toggle',\n          contents: this.ui.dropdownButtonContents(\n            '<span class=\"note-current-fontname\"/>', this.options\n          ),\n          tooltip: this.lang.font.name,\n          data: {\n            toggle: 'dropdown',\n          },\n        }),\n        this.ui.dropdownCheck({\n          className: 'dropdown-fontname',\n          checkClassName: this.options.icons.menuCheck,\n          items: this.options.fontNames.filter(this.isFontInstalled.bind(this)),\n          title: this.lang.font.name,\n          template: (item) => {\n            return '<span style=\"font-family: ' + env.validFontName(item) + '\">' + item + '</span>';\n          },\n          click: this.context.createInvokeHandlerAndUpdateState('editor.fontName'),\n        }),\n      ]).render();\n    });\n\n    this.context.memo('button.fontsize', () => {\n      return this.ui.buttonGroup([\n        this.button({\n          className: 'dropdown-toggle',\n          contents: this.ui.dropdownButtonContents('<span class=\"note-current-fontsize\"/>', this.options),\n          tooltip: this.lang.font.size,\n          data: {\n            toggle: 'dropdown',\n          },\n        }),\n        this.ui.dropdownCheck({\n          className: 'dropdown-fontsize',\n          checkClassName: this.options.icons.menuCheck,\n          items: this.options.fontSizes,\n          title: this.lang.font.size,\n          click: this.context.createInvokeHandlerAndUpdateState('editor.fontSize'),\n        }),\n      ]).render();\n    });\n\n    this.context.memo('button.fontsizeunit', () => {\n      return this.ui.buttonGroup([\n        this.button({\n          className: 'dropdown-toggle',\n          contents: this.ui.dropdownButtonContents('<span class=\"note-current-fontsizeunit\"/>', this.options),\n          tooltip: this.lang.font.sizeunit,\n          data: {\n            toggle: 'dropdown',\n          },\n        }),\n        this.ui.dropdownCheck({\n          className: 'dropdown-fontsizeunit',\n          checkClassName: this.options.icons.menuCheck,\n          items: this.options.fontSizeUnits,\n          title: this.lang.font.sizeunit,\n          click: this.context.createInvokeHandlerAndUpdateState('editor.fontSizeUnit'),\n        }),\n      ]).render();\n    });\n\n    this.context.memo('button.color', () => {\n      return this.colorPalette('note-color-all', this.lang.color.recent, true, true);\n    });\n\n    this.context.memo('button.forecolor', () => {\n      return this.colorPalette('note-color-fore', this.lang.color.foreground, false, true);\n    });\n\n    this.context.memo('button.backcolor', () => {\n      return this.colorPalette('note-color-back', this.lang.color.background, true, false);\n    });\n\n    this.context.memo('button.ul', () => {\n      return this.button({\n        contents: this.ui.icon(this.options.icons.unorderedlist),\n        tooltip: this.lang.lists.unordered + this.representShortcut('insertUnorderedList'),\n        click: this.context.createInvokeHandler('editor.insertUnorderedList'),\n      }).render();\n    });\n\n    this.context.memo('button.ol', () => {\n      return this.button({\n        contents: this.ui.icon(this.options.icons.orderedlist),\n        tooltip: this.lang.lists.ordered + this.representShortcut('insertOrderedList'),\n        click: this.context.createInvokeHandler('editor.insertOrderedList'),\n      }).render();\n    });\n\n    const justifyLeft = this.button({\n      contents: this.ui.icon(this.options.icons.alignLeft),\n      tooltip: this.lang.paragraph.left + this.representShortcut('justifyLeft'),\n      click: this.context.createInvokeHandler('editor.justifyLeft'),\n    });\n\n    const justifyCenter = this.button({\n      contents: this.ui.icon(this.options.icons.alignCenter),\n      tooltip: this.lang.paragraph.center + this.representShortcut('justifyCenter'),\n      click: this.context.createInvokeHandler('editor.justifyCenter'),\n    });\n\n    const justifyRight = this.button({\n      contents: this.ui.icon(this.options.icons.alignRight),\n      tooltip: this.lang.paragraph.right + this.representShortcut('justifyRight'),\n      click: this.context.createInvokeHandler('editor.justifyRight'),\n    });\n\n    const justifyFull = this.button({\n      contents: this.ui.icon(this.options.icons.alignJustify),\n      tooltip: this.lang.paragraph.justify + this.representShortcut('justifyFull'),\n      click: this.context.createInvokeHandler('editor.justifyFull'),\n    });\n\n    const outdent = this.button({\n      contents: this.ui.icon(this.options.icons.outdent),\n      tooltip: this.lang.paragraph.outdent + this.representShortcut('outdent'),\n      click: this.context.createInvokeHandler('editor.outdent'),\n    });\n\n    const indent = this.button({\n      contents: this.ui.icon(this.options.icons.indent),\n      tooltip: this.lang.paragraph.indent + this.representShortcut('indent'),\n      click: this.context.createInvokeHandler('editor.indent'),\n    });\n\n    this.context.memo('button.justifyLeft', func.invoke(justifyLeft, 'render'));\n    this.context.memo('button.justifyCenter', func.invoke(justifyCenter, 'render'));\n    this.context.memo('button.justifyRight', func.invoke(justifyRight, 'render'));\n    this.context.memo('button.justifyFull', func.invoke(justifyFull, 'render'));\n    this.context.memo('button.outdent', func.invoke(outdent, 'render'));\n    this.context.memo('button.indent', func.invoke(indent, 'render'));\n\n    this.context.memo('button.paragraph', () => {\n      return this.ui.buttonGroup([\n        this.button({\n          className: 'dropdown-toggle',\n          contents: this.ui.dropdownButtonContents(this.ui.icon(this.options.icons.alignLeft), this.options),\n          tooltip: this.lang.paragraph.paragraph,\n          data: {\n            toggle: 'dropdown',\n          },\n        }),\n        this.ui.dropdown([\n          this.ui.buttonGroup({\n            className: 'note-align',\n            children: [justifyLeft, justifyCenter, justifyRight, justifyFull],\n          }),\n          this.ui.buttonGroup({\n            className: 'note-list',\n            children: [outdent, indent],\n          }),\n        ]),\n      ]).render();\n    });\n\n    this.context.memo('button.height', () => {\n      return this.ui.buttonGroup([\n        this.button({\n          className: 'dropdown-toggle',\n          contents: this.ui.dropdownButtonContents(this.ui.icon(this.options.icons.textHeight), this.options),\n          tooltip: this.lang.font.height,\n          data: {\n            toggle: 'dropdown',\n          },\n        }),\n        this.ui.dropdownCheck({\n          items: this.options.lineHeights,\n          checkClassName: this.options.icons.menuCheck,\n          className: 'dropdown-line-height',\n          title: this.lang.font.height,\n          click: this.context.createInvokeHandler('editor.lineHeight'),\n        }),\n      ]).render();\n    });\n\n    this.context.memo('button.table', () => {\n      return this.ui.buttonGroup([\n        this.button({\n          className: 'dropdown-toggle',\n          contents: this.ui.dropdownButtonContents(this.ui.icon(this.options.icons.table), this.options),\n          tooltip: this.lang.table.table,\n          data: {\n            toggle: 'dropdown',\n          },\n        }),\n        this.ui.dropdown({\n          title: this.lang.table.table,\n          className: 'note-table',\n          items: [\n            '<div class=\"note-dimension-picker\">',\n              '<div class=\"note-dimension-picker-mousecatcher\" data-event=\"insertTable\" data-value=\"1x1\"/>',\n              '<div class=\"note-dimension-picker-highlighted\"/>',\n              '<div class=\"note-dimension-picker-unhighlighted\"/>',\n            '</div>',\n            '<div class=\"note-dimension-display\">1 x 1</div>',\n          ].join(''),\n        }),\n      ], {\n        callback: ($node) => {\n          const $catcher = $node.find('.note-dimension-picker-mousecatcher');\n          $catcher.css({\n            width: this.options.insertTableMaxSize.col + 'em',\n            height: this.options.insertTableMaxSize.row + 'em',\n          }).mousedown(this.context.createInvokeHandler('editor.insertTable'))\n            .on('mousemove', this.tableMoveHandler.bind(this));\n        },\n      }).render();\n    });\n\n    this.context.memo('button.link', () => {\n      return this.button({\n        contents: this.ui.icon(this.options.icons.link),\n        tooltip: this.lang.link.link + this.representShortcut('linkDialog.show'),\n        click: this.context.createInvokeHandler('linkDialog.show'),\n      }).render();\n    });\n\n    this.context.memo('button.picture', () => {\n      return this.button({\n        contents: this.ui.icon(this.options.icons.picture),\n        tooltip: this.lang.image.image,\n        click: this.context.createInvokeHandler('imageDialog.show'),\n      }).render();\n    });\n\n    this.context.memo('button.video', () => {\n      return this.button({\n        contents: this.ui.icon(this.options.icons.video),\n        tooltip: this.lang.video.video,\n        click: this.context.createInvokeHandler('videoDialog.show'),\n      }).render();\n    });\n\n    this.context.memo('button.hr', () => {\n      return this.button({\n        contents: this.ui.icon(this.options.icons.minus),\n        tooltip: this.lang.hr.insert + this.representShortcut('insertHorizontalRule'),\n        click: this.context.createInvokeHandler('editor.insertHorizontalRule'),\n      }).render();\n    });\n\n    this.context.memo('button.fullscreen', () => {\n      return this.button({\n        className: 'btn-fullscreen',\n        contents: this.ui.icon(this.options.icons.arrowsAlt),\n        tooltip: this.lang.options.fullscreen,\n        click: this.context.createInvokeHandler('fullscreen.toggle'),\n      }).render();\n    });\n\n    this.context.memo('button.codeview', () => {\n      return this.button({\n        className: 'btn-codeview',\n        contents: this.ui.icon(this.options.icons.code),\n        tooltip: this.lang.options.codeview,\n        click: this.context.createInvokeHandler('codeview.toggle'),\n      }).render();\n    });\n\n    this.context.memo('button.redo', () => {\n      return this.button({\n        contents: this.ui.icon(this.options.icons.redo),\n        tooltip: this.lang.history.redo + this.representShortcut('redo'),\n        click: this.context.createInvokeHandler('editor.redo'),\n      }).render();\n    });\n\n    this.context.memo('button.undo', () => {\n      return this.button({\n        contents: this.ui.icon(this.options.icons.undo),\n        tooltip: this.lang.history.undo + this.representShortcut('undo'),\n        click: this.context.createInvokeHandler('editor.undo'),\n      }).render();\n    });\n\n    this.context.memo('button.help', () => {\n      return this.button({\n        contents: this.ui.icon(this.options.icons.question),\n        tooltip: this.lang.options.help,\n        click: this.context.createInvokeHandler('helpDialog.show'),\n      }).render();\n    });\n  }\n\n  /**\n   * image: [\n   *   ['imageResize', ['resizeFull', 'resizeHalf', 'resizeQuarter', 'resizeNone']],\n   *   ['float', ['floatLeft', 'floatRight', 'floatNone']],\n   *   ['remove', ['removeMedia']],\n   * ],\n   */\n  addImagePopoverButtons() {\n    // Image Size Buttons\n    this.context.memo('button.resizeFull', () => {\n      return this.button({\n        contents: '<span class=\"note-fontsize-10\">100%</span>',\n        tooltip: this.lang.image.resizeFull,\n        click: this.context.createInvokeHandler('editor.resize', '1'),\n      }).render();\n    });\n    this.context.memo('button.resizeHalf', () => {\n      return this.button({\n        contents: '<span class=\"note-fontsize-10\">50%</span>',\n        tooltip: this.lang.image.resizeHalf,\n        click: this.context.createInvokeHandler('editor.resize', '0.5'),\n      }).render();\n    });\n    this.context.memo('button.resizeQuarter', () => {\n      return this.button({\n        contents: '<span class=\"note-fontsize-10\">25%</span>',\n        tooltip: this.lang.image.resizeQuarter,\n        click: this.context.createInvokeHandler('editor.resize', '0.25'),\n      }).render();\n    });\n    this.context.memo('button.resizeNone', () => {\n      return this.button({\n        contents: this.ui.icon(this.options.icons.rollback),\n        tooltip: this.lang.image.resizeNone,\n        click: this.context.createInvokeHandler('editor.resize', '0'),\n      }).render();\n    });\n\n    // Float Buttons\n    this.context.memo('button.floatLeft', () => {\n      return this.button({\n        contents: this.ui.icon(this.options.icons.floatLeft),\n        tooltip: this.lang.image.floatLeft,\n        click: this.context.createInvokeHandler('editor.floatMe', 'left'),\n      }).render();\n    });\n\n    this.context.memo('button.floatRight', () => {\n      return this.button({\n        contents: this.ui.icon(this.options.icons.floatRight),\n        tooltip: this.lang.image.floatRight,\n        click: this.context.createInvokeHandler('editor.floatMe', 'right'),\n      }).render();\n    });\n\n    this.context.memo('button.floatNone', () => {\n      return this.button({\n        contents: this.ui.icon(this.options.icons.rollback),\n        tooltip: this.lang.image.floatNone,\n        click: this.context.createInvokeHandler('editor.floatMe', 'none'),\n      }).render();\n    });\n\n    // Remove Buttons\n    this.context.memo('button.removeMedia', () => {\n      return this.button({\n        contents: this.ui.icon(this.options.icons.trash),\n        tooltip: this.lang.image.remove,\n        click: this.context.createInvokeHandler('editor.removeMedia'),\n      }).render();\n    });\n  }\n\n  addLinkPopoverButtons() {\n    this.context.memo('button.linkDialogShow', () => {\n      return this.button({\n        contents: this.ui.icon(this.options.icons.link),\n        tooltip: this.lang.link.edit,\n        click: this.context.createInvokeHandler('linkDialog.show'),\n      }).render();\n    });\n\n    this.context.memo('button.unlink', () => {\n      return this.button({\n        contents: this.ui.icon(this.options.icons.unlink),\n        tooltip: this.lang.link.unlink,\n        click: this.context.createInvokeHandler('editor.unlink'),\n      }).render();\n    });\n  }\n\n  /**\n   * table : [\n   *  ['add', ['addRowDown', 'addRowUp', 'addColLeft', 'addColRight']],\n   *  ['delete', ['deleteRow', 'deleteCol', 'deleteTable']]\n   * ],\n   */\n  addTablePopoverButtons() {\n    this.context.memo('button.addRowUp', () => {\n      return this.button({\n        className: 'btn-md',\n        contents: this.ui.icon(this.options.icons.rowAbove),\n        tooltip: this.lang.table.addRowAbove,\n        click: this.context.createInvokeHandler('editor.addRow', 'top'),\n      }).render();\n    });\n    this.context.memo('button.addRowDown', () => {\n      return this.button({\n        className: 'btn-md',\n        contents: this.ui.icon(this.options.icons.rowBelow),\n        tooltip: this.lang.table.addRowBelow,\n        click: this.context.createInvokeHandler('editor.addRow', 'bottom'),\n      }).render();\n    });\n    this.context.memo('button.addColLeft', () => {\n      return this.button({\n        className: 'btn-md',\n        contents: this.ui.icon(this.options.icons.colBefore),\n        tooltip: this.lang.table.addColLeft,\n        click: this.context.createInvokeHandler('editor.addCol', 'left'),\n      }).render();\n    });\n    this.context.memo('button.addColRight', () => {\n      return this.button({\n        className: 'btn-md',\n        contents: this.ui.icon(this.options.icons.colAfter),\n        tooltip: this.lang.table.addColRight,\n        click: this.context.createInvokeHandler('editor.addCol', 'right'),\n      }).render();\n    });\n    this.context.memo('button.deleteRow', () => {\n      return this.button({\n        className: 'btn-md',\n        contents: this.ui.icon(this.options.icons.rowRemove),\n        tooltip: this.lang.table.delRow,\n        click: this.context.createInvokeHandler('editor.deleteRow'),\n      }).render();\n    });\n    this.context.memo('button.deleteCol', () => {\n      return this.button({\n        className: 'btn-md',\n        contents: this.ui.icon(this.options.icons.colRemove),\n        tooltip: this.lang.table.delCol,\n        click: this.context.createInvokeHandler('editor.deleteCol'),\n      }).render();\n    });\n    this.context.memo('button.deleteTable', () => {\n      return this.button({\n        className: 'btn-md',\n        contents: this.ui.icon(this.options.icons.trash),\n        tooltip: this.lang.table.delTable,\n        click: this.context.createInvokeHandler('editor.deleteTable'),\n      }).render();\n    });\n  }\n\n  build($container, groups) {\n    for (let groupIdx = 0, groupLen = groups.length; groupIdx < groupLen; groupIdx++) {\n      const group = groups[groupIdx];\n      const groupName = Array.isArray(group) ? group[0] : group;\n      const buttons = Array.isArray(group) ? ((group.length === 1) ? [group[0]] : group[1]) : [group];\n\n      const $group = this.ui.buttonGroup({\n        className: 'note-' + groupName,\n      }).render();\n\n      for (let idx = 0, len = buttons.length; idx < len; idx++) {\n        const btn = this.context.memo('button.' + buttons[idx]);\n        if (btn) {\n          $group.append(typeof btn === 'function' ? btn(this.context) : btn);\n        }\n      }\n      $group.appendTo($container);\n    }\n  }\n\n  /**\n   * @param {jQuery} [$container]\n   */\n  updateCurrentStyle($container) {\n    const $cont = $container || this.$toolbar;\n\n    const styleInfo = this.context.invoke('editor.currentStyle');\n    this.updateBtnStates($cont, {\n      '.note-btn-bold': () => {\n        return styleInfo['font-bold'] === 'bold';\n      },\n      '.note-btn-italic': () => {\n        return styleInfo['font-italic'] === 'italic';\n      },\n      '.note-btn-underline': () => {\n        return styleInfo['font-underline'] === 'underline';\n      },\n      '.note-btn-subscript': () => {\n        return styleInfo['font-subscript'] === 'subscript';\n      },\n      '.note-btn-superscript': () => {\n        return styleInfo['font-superscript'] === 'superscript';\n      },\n      '.note-btn-strikethrough': () => {\n        return styleInfo['font-strikethrough'] === 'strikethrough';\n      },\n    });\n\n    if (styleInfo['font-family']) {\n      const fontNames = styleInfo['font-family'].split(',').map((name) => {\n        return name.replace(/[\\'\\\"]/g, '')\n          .replace(/\\s+$/, '')\n          .replace(/^\\s+/, '');\n      });\n      const fontName = lists.find(fontNames, this.isFontInstalled.bind(this));\n\n      $cont.find('.dropdown-fontname a').each((idx, item) => {\n        const $item = $(item);\n        // always compare string to avoid creating another func.\n        const isChecked = ($item.data('value') + '') === (fontName + '');\n        $item.toggleClass('checked', isChecked);\n      });\n      $cont.find('.note-current-fontname').text(fontName).css('font-family', fontName);\n    }\n\n    if (styleInfo['font-size']) {\n      const fontSize = styleInfo['font-size'];\n      $cont.find('.dropdown-fontsize a').each((idx, item) => {\n        const $item = $(item);\n        // always compare with string to avoid creating another func.\n        const isChecked = ($item.data('value') + '') === (fontSize + '');\n        $item.toggleClass('checked', isChecked);\n      });\n      $cont.find('.note-current-fontsize').text(fontSize);\n\n      const fontSizeUnit = styleInfo['font-size-unit'];\n      $cont.find('.dropdown-fontsizeunit a').each((idx, item) => {\n        const $item = $(item);\n        const isChecked = ($item.data('value') + '') === (fontSizeUnit + '');\n        $item.toggleClass('checked', isChecked);\n      });\n      $cont.find('.note-current-fontsizeunit').text(fontSizeUnit);\n    }\n\n    if (styleInfo['line-height']) {\n      const lineHeight = styleInfo['line-height'];\n      $cont.find('.dropdown-line-height li a').each((idx, item) => {\n        // always compare with string to avoid creating another func.\n        const isChecked = ($(item).data('value') + '') === (lineHeight + '');\n        this.className = isChecked ? 'checked' : '';\n      });\n    }\n  }\n\n  updateBtnStates($container, infos) {\n    $.each(infos, (selector, pred) => {\n      this.ui.toggleBtnActive($container.find(selector), pred());\n    });\n  }\n\n  tableMoveHandler(event) {\n    const PX_PER_EM = 18;\n    const $picker = $(event.target.parentNode); // target is mousecatcher\n    const $dimensionDisplay = $picker.next();\n    const $catcher = $picker.find('.note-dimension-picker-mousecatcher');\n    const $highlighted = $picker.find('.note-dimension-picker-highlighted');\n    const $unhighlighted = $picker.find('.note-dimension-picker-unhighlighted');\n\n    let posOffset;\n    // HTML5 with jQuery - e.offsetX is undefined in Firefox\n    if (event.offsetX === undefined) {\n      const posCatcher = $(event.target).offset();\n      posOffset = {\n        x: event.pageX - posCatcher.left,\n        y: event.pageY - posCatcher.top,\n      };\n    } else {\n      posOffset = {\n        x: event.offsetX,\n        y: event.offsetY,\n      };\n    }\n\n    const dim = {\n      c: Math.ceil(posOffset.x / PX_PER_EM) || 1,\n      r: Math.ceil(posOffset.y / PX_PER_EM) || 1,\n    };\n\n    $highlighted.css({ width: dim.c + 'em', height: dim.r + 'em' });\n    $catcher.data('value', dim.c + 'x' + dim.r);\n\n    if (dim.c > 3 && dim.c < this.options.insertTableMaxSize.col) {\n      $unhighlighted.css({ width: dim.c + 1 + 'em' });\n    }\n\n    if (dim.r > 3 && dim.r < this.options.insertTableMaxSize.row) {\n      $unhighlighted.css({ height: dim.r + 1 + 'em' });\n    }\n\n    $dimensionDisplay.html(dim.c + ' x ' + dim.r);\n  }\n}\n","import $ from 'jquery';\nexport default class Toolbar {\n  constructor(context) {\n    this.context = context;\n\n    this.$window = $(window);\n    this.$document = $(document);\n\n    this.ui = $.summernote.ui;\n    this.$note = context.layoutInfo.note;\n    this.$editor = context.layoutInfo.editor;\n    this.$toolbar = context.layoutInfo.toolbar;\n    this.$editable = context.layoutInfo.editable;\n    this.$statusbar = context.layoutInfo.statusbar;\n    this.options = context.options;\n\n    this.isFollowing = false;\n    this.followScroll = this.followScroll.bind(this);\n  }\n\n  shouldInitialize() {\n    return !this.options.airMode;\n  }\n\n  initialize() {\n    this.options.toolbar = this.options.toolbar || [];\n\n    if (!this.options.toolbar.length) {\n      this.$toolbar.hide();\n    } else {\n      this.context.invoke('buttons.build', this.$toolbar, this.options.toolbar);\n    }\n\n    if (this.options.toolbarContainer) {\n      this.$toolbar.appendTo(this.options.toolbarContainer);\n    }\n\n    this.changeContainer(false);\n\n    this.$note.on('summernote.keyup summernote.mouseup summernote.change', () => {\n      this.context.invoke('buttons.updateCurrentStyle');\n    });\n\n    this.context.invoke('buttons.updateCurrentStyle');\n    if (this.options.followingToolbar) {\n      this.$window.on('scroll resize', this.followScroll);\n    }\n  }\n\n  destroy() {\n    this.$toolbar.children().remove();\n\n    if (this.options.followingToolbar) {\n      this.$window.off('scroll resize', this.followScroll);\n    }\n  }\n\n  followScroll() {\n    if (this.$editor.hasClass('fullscreen')) {\n      return false;\n    }\n\n    const editorHeight = this.$editor.outerHeight();\n    const editorWidth = this.$editor.width();\n    const toolbarHeight = this.$toolbar.height();\n    const statusbarHeight = this.$statusbar.height();\n\n    // check if the web app is currently using another static bar\n    let otherBarHeight = 0;\n    if (this.options.otherStaticBar) {\n      otherBarHeight = $(this.options.otherStaticBar).outerHeight();\n    }\n\n    const currentOffset = this.$document.scrollTop();\n    const editorOffsetTop = this.$editor.offset().top;\n    const editorOffsetBottom = editorOffsetTop + editorHeight;\n    const activateOffset = editorOffsetTop - otherBarHeight;\n    const deactivateOffsetBottom = editorOffsetBottom - otherBarHeight - toolbarHeight - statusbarHeight;\n\n    if (!this.isFollowing &&\n      (currentOffset > activateOffset) && (currentOffset < deactivateOffsetBottom - toolbarHeight)) {\n      this.isFollowing = true;\n      this.$editable.css({\n        marginTop: this.$toolbar.outerHeight(),\n      });\n      this.$toolbar.css({\n        position: 'fixed',\n        top: otherBarHeight,\n        width: editorWidth,\n        zIndex: 1000,\n      });\n    } else if (this.isFollowing &&\n      ((currentOffset < activateOffset) || (currentOffset > deactivateOffsetBottom))) {\n      this.isFollowing = false;\n      this.$toolbar.css({\n        position: 'relative',\n        top: 0,\n        width: '100%',\n        zIndex: 'auto',\n      });\n      this.$editable.css({\n        marginTop: '',\n      });\n    }\n  }\n\n  changeContainer(isFullscreen) {\n    if (isFullscreen) {\n      this.$toolbar.prependTo(this.$editor);\n    } else {\n      if (this.options.toolbarContainer) {\n        this.$toolbar.appendTo(this.options.toolbarContainer);\n      }\n    }\n    if (this.options.followingToolbar) {\n      this.followScroll();\n    }\n  }\n\n  updateFullscreen(isFullscreen) {\n    this.ui.toggleBtnActive(this.$toolbar.find('.btn-fullscreen'), isFullscreen);\n\n    this.changeContainer(isFullscreen);\n  }\n\n  updateCodeview(isCodeview) {\n    this.ui.toggleBtnActive(this.$toolbar.find('.btn-codeview'), isCodeview);\n    if (isCodeview) {\n      this.deactivate();\n    } else {\n      this.activate();\n    }\n  }\n\n  activate(isIncludeCodeview) {\n    let $btn = this.$toolbar.find('button');\n    if (!isIncludeCodeview) {\n      $btn = $btn.not('.btn-codeview').not('.btn-fullscreen');\n    }\n    this.ui.toggleBtn($btn, true);\n  }\n\n  deactivate(isIncludeCodeview) {\n    let $btn = this.$toolbar.find('button');\n    if (!isIncludeCodeview) {\n      $btn = $btn.not('.btn-codeview').not('.btn-fullscreen');\n    }\n    this.ui.toggleBtn($btn, false);\n  }\n}\n","import $ from 'jquery';\nimport env from '../core/env';\nimport key from '../core/key';\nimport func from '../core/func';\n\nexport default class LinkDialog {\n  constructor(context) {\n    this.context = context;\n\n    this.ui = $.summernote.ui;\n    this.$body = $(document.body);\n    this.$editor = context.layoutInfo.editor;\n    this.options = context.options;\n    this.lang = this.options.langInfo;\n\n    context.memo('help.linkDialog.show', this.options.langInfo.help['linkDialog.show']);\n  }\n\n  initialize() {\n    const $container = this.options.dialogsInBody ? this.$body : this.options.container;\n    const body = [\n      '<div class=\"form-group note-form-group\">',\n        `<label for=\"note-dialog-link-txt-${this.options.id}\" class=\"note-form-label\">${this.lang.link.textToDisplay}</label>`,\n        `<input id=\"note-dialog-link-txt-${this.options.id}\" class=\"note-link-text form-control note-form-control note-input\" type=\"text\"/>`,\n      '</div>',\n      '<div class=\"form-group note-form-group\">',\n        `<label for=\"note-dialog-link-url-${this.options.id}\" class=\"note-form-label\">${this.lang.link.url}</label>`,\n        `<input id=\"note-dialog-link-url-${this.options.id}\" class=\"note-link-url form-control note-form-control note-input\" type=\"text\" value=\"http://\"/>`,\n      '</div>',\n      !this.options.disableLinkTarget\n        ? $('<div/>').append(this.ui.checkbox({\n          className: 'sn-checkbox-open-in-new-window',\n          text: this.lang.link.openInNewWindow,\n          checked: true,\n        }).render()).html()\n        : '',\n      $('<div/>').append(this.ui.checkbox({\n        className: 'sn-checkbox-use-protocol',\n        text: this.lang.link.useProtocol,\n        checked: true,\n      }).render()).html(),\n    ].join('');\n\n    const buttonClass = 'btn btn-primary note-btn note-btn-primary note-link-btn';\n    const footer = `<input type=\"button\" href=\"#\" class=\"${buttonClass}\" value=\"${this.lang.link.insert}\" disabled>`;\n\n    this.$dialog = this.ui.dialog({\n      className: 'link-dialog',\n      title: this.lang.link.insert,\n      fade: this.options.dialogsFade,\n      body: body,\n      footer: footer,\n    }).render().appendTo($container);\n  }\n\n  destroy() {\n    this.ui.hideDialog(this.$dialog);\n    this.$dialog.remove();\n  }\n\n  bindEnterKey($input, $btn) {\n    $input.on('keypress', (event) => {\n      if (event.keyCode === key.code.ENTER) {\n        event.preventDefault();\n        $btn.trigger('click');\n      }\n    });\n  }\n\n  /**\n   * toggle update button\n   */\n  toggleLinkBtn($linkBtn, $linkText, $linkUrl) {\n    this.ui.toggleBtn($linkBtn, $linkText.val() && $linkUrl.val());\n  }\n\n  /**\n   * Show link dialog and set event handlers on dialog controls.\n   *\n   * @param {Object} linkInfo\n   * @return {Promise}\n   */\n  showLinkDialog(linkInfo) {\n    return $.Deferred((deferred) => {\n      const $linkText = this.$dialog.find('.note-link-text');\n      const $linkUrl = this.$dialog.find('.note-link-url');\n      const $linkBtn = this.$dialog.find('.note-link-btn');\n      const $openInNewWindow = this.$dialog\n        .find('.sn-checkbox-open-in-new-window input[type=checkbox]');\n      const $useProtocol = this.$dialog\n        .find('.sn-checkbox-use-protocol input[type=checkbox]');\n\n      this.ui.onDialogShown(this.$dialog, () => {\n        this.context.triggerEvent('dialog.shown');\n\n        // If no url was given and given text is valid URL then copy that into URL Field\n        if (!linkInfo.url && func.isValidUrl(linkInfo.text)) {\n          linkInfo.url = linkInfo.text;\n        }\n\n        $linkText.on('input paste propertychange', () => {\n          // If linktext was modified by input events,\n          // cloning text from linkUrl will be stopped.\n          linkInfo.text = $linkText.val();\n          this.toggleLinkBtn($linkBtn, $linkText, $linkUrl);\n        }).val(linkInfo.text);\n\n        $linkUrl.on('input paste propertychange', () => {\n          // Display same text on `Text to display` as default\n          // when linktext has no text\n          if (!linkInfo.text) {\n            $linkText.val($linkUrl.val());\n          }\n          this.toggleLinkBtn($linkBtn, $linkText, $linkUrl);\n        }).val(linkInfo.url);\n\n        if (!env.isSupportTouch) {\n          $linkUrl.trigger('focus');\n        }\n\n        this.toggleLinkBtn($linkBtn, $linkText, $linkUrl);\n        this.bindEnterKey($linkUrl, $linkBtn);\n        this.bindEnterKey($linkText, $linkBtn);\n\n        const isNewWindowChecked = linkInfo.isNewWindow !== undefined\n          ? linkInfo.isNewWindow : this.context.options.linkTargetBlank;\n\n        $openInNewWindow.prop('checked', isNewWindowChecked);\n\n        const useProtocolChecked = linkInfo.url\n          ? false : this.context.options.useProtocol;\n\n        $useProtocol.prop('checked', useProtocolChecked);\n\n        $linkBtn.one('click', (event) => {\n          event.preventDefault();\n\n          deferred.resolve({\n            range: linkInfo.range,\n            url: $linkUrl.val(),\n            text: $linkText.val(),\n            isNewWindow: $openInNewWindow.is(':checked'),\n            checkProtocol: $useProtocol.is(':checked'),\n          });\n          this.ui.hideDialog(this.$dialog);\n        });\n      });\n\n      this.ui.onDialogHidden(this.$dialog, () => {\n        // detach events\n        $linkText.off();\n        $linkUrl.off();\n        $linkBtn.off();\n\n        if (deferred.state() === 'pending') {\n          deferred.reject();\n        }\n      });\n\n      this.ui.showDialog(this.$dialog);\n    }).promise();\n  }\n\n  /**\n   * @param {Object} layoutInfo\n   */\n  show() {\n    const linkInfo = this.context.invoke('editor.getLinkInfo');\n\n    this.context.invoke('editor.saveRange');\n    this.showLinkDialog(linkInfo).then((linkInfo) => {\n      this.context.invoke('editor.restoreRange');\n      this.context.invoke('editor.createLink', linkInfo);\n    }).fail(() => {\n      this.context.invoke('editor.restoreRange');\n    });\n  }\n}\n","import $ from 'jquery';\nimport lists from '../core/lists';\nimport dom from '../core/dom';\n\nexport default class LinkPopover {\n  constructor(context) {\n    this.context = context;\n\n    this.ui = $.summernote.ui;\n    this.options = context.options;\n    this.events = {\n      'summernote.keyup summernote.mouseup summernote.change summernote.scroll': () => {\n        this.update();\n      },\n      'summernote.disable summernote.dialog.shown summernote.blur': () => {\n        this.hide();\n      },\n    };\n  }\n\n  shouldInitialize() {\n    return !lists.isEmpty(this.options.popover.link);\n  }\n\n  initialize() {\n    this.$popover = this.ui.popover({\n      className: 'note-link-popover',\n      callback: ($node) => {\n        const $content = $node.find('.popover-content,.note-popover-content');\n        $content.prepend('<span><a target=\"_blank\"></a>&nbsp;</span>');\n      },\n    }).render().appendTo(this.options.container);\n    const $content = this.$popover.find('.popover-content,.note-popover-content');\n\n    this.context.invoke('buttons.build', $content, this.options.popover.link);\n\n    this.$popover.on('mousedown', (e) => { e.preventDefault(); });\n  }\n\n  destroy() {\n    this.$popover.remove();\n  }\n\n  update() {\n    // Prevent focusing on editable when invoke('code') is executed\n    if (!this.context.invoke('editor.hasFocus')) {\n      this.hide();\n      return;\n    }\n\n    const rng = this.context.invoke('editor.getLastRange');\n    if (rng.isCollapsed() && rng.isOnAnchor()) {\n      const anchor = dom.ancestor(rng.sc, dom.isAnchor);\n      const href = $(anchor).attr('href');\n      this.$popover.find('a').attr('href', href).text(href);\n\n      const pos = dom.posFromPlaceholder(anchor);\n      const containerOffset = $(this.options.container).offset();\n      pos.top -= containerOffset.top;\n      pos.left -= containerOffset.left;\n\n      this.$popover.css({\n        display: 'block',\n        left: pos.left,\n        top: pos.top,\n      });\n    } else {\n      this.hide();\n    }\n  }\n\n  hide() {\n    this.$popover.hide();\n  }\n}\n","import $ from 'jquery';\nimport env from '../core/env';\nimport key from '../core/key';\n\nexport default class ImageDialog {\n  constructor(context) {\n    this.context = context;\n    this.ui = $.summernote.ui;\n    this.$body = $(document.body);\n    this.$editor = context.layoutInfo.editor;\n    this.options = context.options;\n    this.lang = this.options.langInfo;\n  }\n\n  initialize() {\n    let imageLimitation = '';\n    if (this.options.maximumImageFileSize) {\n      const unit = Math.floor(Math.log(this.options.maximumImageFileSize) / Math.log(1024));\n      const readableSize = (this.options.maximumImageFileSize / Math.pow(1024, unit)).toFixed(2) * 1 +\n                         ' ' + ' KMGTP'[unit] + 'B';\n      imageLimitation = `<small>${this.lang.image.maximumFileSize + ' : ' + readableSize}</small>`;\n    }\n\n    const $container = this.options.dialogsInBody ? this.$body : this.options.container;\n    const body = [\n      '<div class=\"form-group note-form-group note-group-select-from-files\">',\n        '<label for=\"note-dialog-image-file-' + this.options.id + '\" class=\"note-form-label\">' + this.lang.image.selectFromFiles + '</label>',\n        '<input id=\"note-dialog-image-file-' + this.options.id + '\" class=\"note-image-input form-control-file note-form-control note-input\" ',\n        ' type=\"file\" name=\"files\" accept=\"image/*\" multiple=\"multiple\"/>',\n        imageLimitation,\n      '</div>',\n      '<div class=\"form-group note-group-image-url\">',\n        '<label for=\"note-dialog-image-url-' + this.options.id + '\" class=\"note-form-label\">' + this.lang.image.url + '</label>',\n        '<input id=\"note-dialog-image-url-' + this.options.id + '\" class=\"note-image-url form-control note-form-control note-input\" type=\"text\"/>',\n      '</div>',\n    ].join('');\n    const buttonClass = 'btn btn-primary note-btn note-btn-primary note-image-btn';\n    const footer = `<input type=\"button\" href=\"#\" class=\"${buttonClass}\" value=\"${this.lang.image.insert}\" disabled>`;\n\n    this.$dialog = this.ui.dialog({\n      title: this.lang.image.insert,\n      fade: this.options.dialogsFade,\n      body: body,\n      footer: footer,\n    }).render().appendTo($container);\n  }\n\n  destroy() {\n    this.ui.hideDialog(this.$dialog);\n    this.$dialog.remove();\n  }\n\n  bindEnterKey($input, $btn) {\n    $input.on('keypress', (event) => {\n      if (event.keyCode === key.code.ENTER) {\n        event.preventDefault();\n        $btn.trigger('click');\n      }\n    });\n  }\n\n  show() {\n    this.context.invoke('editor.saveRange');\n    this.showImageDialog().then((data) => {\n      // [workaround] hide dialog before restore range for IE range focus\n      this.ui.hideDialog(this.$dialog);\n      this.context.invoke('editor.restoreRange');\n\n      if (typeof data === 'string') { // image url\n        // If onImageLinkInsert set,\n        if (this.options.callbacks.onImageLinkInsert) {\n          this.context.triggerEvent('image.link.insert', data);\n        } else {\n          this.context.invoke('editor.insertImage', data);\n        }\n      } else { // array of files\n        this.context.invoke('editor.insertImagesOrCallback', data);\n      }\n    }).fail(() => {\n      this.context.invoke('editor.restoreRange');\n    });\n  }\n\n  /**\n   * show image dialog\n   *\n   * @param {jQuery} $dialog\n   * @return {Promise}\n   */\n  showImageDialog() {\n    return $.Deferred((deferred) => {\n      const $imageInput = this.$dialog.find('.note-image-input');\n      const $imageUrl = this.$dialog.find('.note-image-url');\n      const $imageBtn = this.$dialog.find('.note-image-btn');\n\n      this.ui.onDialogShown(this.$dialog, () => {\n        this.context.triggerEvent('dialog.shown');\n\n        // Cloning imageInput to clear element.\n        $imageInput.replaceWith($imageInput.clone().on('change', (event) => {\n          deferred.resolve(event.target.files || event.target.value);\n        }).val(''));\n\n        $imageUrl.on('input paste propertychange', () => {\n          this.ui.toggleBtn($imageBtn, $imageUrl.val());\n        }).val('');\n\n        if (!env.isSupportTouch) {\n          $imageUrl.trigger('focus');\n        }\n\n        $imageBtn.click((event) => {\n          event.preventDefault();\n          deferred.resolve($imageUrl.val());\n        });\n\n        this.bindEnterKey($imageUrl, $imageBtn);\n      });\n\n      this.ui.onDialogHidden(this.$dialog, () => {\n        $imageInput.off();\n        $imageUrl.off();\n        $imageBtn.off();\n\n        if (deferred.state() === 'pending') {\n          deferred.reject();\n        }\n      });\n\n      this.ui.showDialog(this.$dialog);\n    });\n  }\n}\n","import $ from 'jquery';\nimport lists from '../core/lists';\nimport dom from '../core/dom';\n\n/**\n * Image popover module\n *  mouse events that show/hide popover will be handled by Handle.js.\n *  Handle.js will receive the events and invoke 'imagePopover.update'.\n */\nexport default class ImagePopover {\n  constructor(context) {\n    this.context = context;\n    this.ui = $.summernote.ui;\n\n    this.editable = context.layoutInfo.editable[0];\n    this.options = context.options;\n\n    this.events = {\n      'summernote.disable summernote.blur': () => {\n        this.hide();\n      },\n    };\n  }\n\n  shouldInitialize() {\n    return !lists.isEmpty(this.options.popover.image);\n  }\n\n  initialize() {\n    this.$popover = this.ui.popover({\n      className: 'note-image-popover',\n    }).render().appendTo(this.options.container);\n    const $content = this.$popover.find('.popover-content,.note-popover-content');\n    this.context.invoke('buttons.build', $content, this.options.popover.image);\n\n    this.$popover.on('mousedown', (e) => { e.preventDefault(); });\n  }\n\n  destroy() {\n    this.$popover.remove();\n  }\n\n  update(target, event) {\n    if (dom.isImg(target)) {\n      const position = $(target).offset();\n      const containerOffset = $(this.options.container).offset();\n      let pos = {};\n      if (this.options.popatmouse) {\n        pos.left = event.pageX - 20;\n        pos.top = event.pageY;\n      } else {\n        pos = position;\n      }\n      pos.top -= containerOffset.top;\n      pos.left -= containerOffset.left;\n\n      this.$popover.css({\n        display: 'block',\n        left: pos.left,\n        top: pos.top,\n      });\n    } else {\n      this.hide();\n    }\n  }\n\n  hide() {\n    this.$popover.hide();\n  }\n}\n","import $ from 'jquery';\nimport env from '../core/env';\nimport lists from '../core/lists';\nimport dom from '../core/dom';\n\nexport default class TablePopover {\n  constructor(context) {\n    this.context = context;\n\n    this.ui = $.summernote.ui;\n    this.options = context.options;\n    this.events = {\n      'summernote.mousedown': (we, e) => {\n        this.update(e.target);\n      },\n      'summernote.keyup summernote.scroll summernote.change': () => {\n        this.update();\n      },\n      'summernote.disable summernote.blur': () => {\n        this.hide();\n      },\n    };\n  }\n\n  shouldInitialize() {\n    return !lists.isEmpty(this.options.popover.table);\n  }\n\n  initialize() {\n    this.$popover = this.ui.popover({\n      className: 'note-table-popover',\n    }).render().appendTo(this.options.container);\n    const $content = this.$popover.find('.popover-content,.note-popover-content');\n\n    this.context.invoke('buttons.build', $content, this.options.popover.table);\n\n    // [workaround] Disable Firefox's default table editor\n    if (env.isFF) {\n      document.execCommand('enableInlineTableEditing', false, false);\n    }\n\n    this.$popover.on('mousedown', (e) => { e.preventDefault(); });\n  }\n\n  destroy() {\n    this.$popover.remove();\n  }\n\n  update(target) {\n    if (this.context.isDisabled()) {\n      return false;\n    }\n\n    const isCell = dom.isCell(target);\n\n    if (isCell) {\n      const pos = dom.posFromPlaceholder(target);\n      const containerOffset = $(this.options.container).offset();\n      pos.top -= containerOffset.top;\n      pos.left -= containerOffset.left;\n\n      this.$popover.css({\n        display: 'block',\n        left: pos.left,\n        top: pos.top,\n      });\n    } else {\n      this.hide();\n    }\n\n    return isCell;\n  }\n\n  hide() {\n    this.$popover.hide();\n  }\n}\n","import $ from 'jquery';\nimport env from '../core/env';\nimport key from '../core/key';\n\nexport default class VideoDialog {\n  constructor(context) {\n    this.context = context;\n\n    this.ui = $.summernote.ui;\n    this.$body = $(document.body);\n    this.$editor = context.layoutInfo.editor;\n    this.options = context.options;\n    this.lang = this.options.langInfo;\n  }\n\n  initialize() {\n    const $container = this.options.dialogsInBody ? this.$body : this.options.container;\n    const body = [\n      '<div class=\"form-group note-form-group row-fluid\">',\n        `<label for=\"note-dialog-video-url-${this.options.id}\" class=\"note-form-label\">${this.lang.video.url} <small class=\"text-muted\">${this.lang.video.providers}</small></label>`,\n        `<input id=\"note-dialog-video-url-${this.options.id}\" class=\"note-video-url form-control note-form-control note-input\" type=\"text\"/>`,\n      '</div>',\n    ].join('');\n    const buttonClass = 'btn btn-primary note-btn note-btn-primary note-video-btn';\n    const footer = `<input type=\"button\" href=\"#\" class=\"${buttonClass}\" value=\"${this.lang.video.insert}\" disabled>`;\n\n    this.$dialog = this.ui.dialog({\n      title: this.lang.video.insert,\n      fade: this.options.dialogsFade,\n      body: body,\n      footer: footer,\n    }).render().appendTo($container);\n  }\n\n  destroy() {\n    this.ui.hideDialog(this.$dialog);\n    this.$dialog.remove();\n  }\n\n  bindEnterKey($input, $btn) {\n    $input.on('keypress', (event) => {\n      if (event.keyCode === key.code.ENTER) {\n        event.preventDefault();\n        $btn.trigger('click');\n      }\n    });\n  }\n\n  createVideoNode(url) {\n    // video url patterns(youtube, instagram, vimeo, dailymotion, youku, mp4, ogg, webm)\n    const ytRegExp = /\\/\\/(?:www\\.)?(?:youtu\\.be\\/|youtube\\.com\\/(?:embed\\/|v\\/|watch\\?v=|watch\\?.+&v=))([\\w|-]{11})(?:(?:[\\?&]t=)(\\S+))?$/;\n    const ytRegExpForStart = /^(?:(\\d+)h)?(?:(\\d+)m)?(?:(\\d+)s)?$/;\n    const ytMatch = url.match(ytRegExp);\n\n    const igRegExp = /(?:www\\.|\\/\\/)instagram\\.com\\/p\\/(.[a-zA-Z0-9_-]*)/;\n    const igMatch = url.match(igRegExp);\n\n    const vRegExp = /\\/\\/vine\\.co\\/v\\/([a-zA-Z0-9]+)/;\n    const vMatch = url.match(vRegExp);\n\n    const vimRegExp = /\\/\\/(player\\.)?vimeo\\.com\\/([a-z]*\\/)*(\\d+)[?]?.*/;\n    const vimMatch = url.match(vimRegExp);\n\n    const dmRegExp = /.+dailymotion.com\\/(video|hub)\\/([^_]+)[^#]*(#video=([^_&]+))?/;\n    const dmMatch = url.match(dmRegExp);\n\n    const youkuRegExp = /\\/\\/v\\.youku\\.com\\/v_show\\/id_(\\w+)=*\\.html/;\n    const youkuMatch = url.match(youkuRegExp);\n\n    const qqRegExp = /\\/\\/v\\.qq\\.com.*?vid=(.+)/;\n    const qqMatch = url.match(qqRegExp);\n\n    const qqRegExp2 = /\\/\\/v\\.qq\\.com\\/x?\\/?(page|cover).*?\\/([^\\/]+)\\.html\\??.*/;\n    const qqMatch2 = url.match(qqRegExp2);\n\n    const mp4RegExp = /^.+.(mp4|m4v)$/;\n    const mp4Match = url.match(mp4RegExp);\n\n    const oggRegExp = /^.+.(ogg|ogv)$/;\n    const oggMatch = url.match(oggRegExp);\n\n    const webmRegExp = /^.+.(webm)$/;\n    const webmMatch = url.match(webmRegExp);\n\n    const fbRegExp = /(?:www\\.|\\/\\/)facebook\\.com\\/([^\\/]+)\\/videos\\/([0-9]+)/;\n    const fbMatch = url.match(fbRegExp);\n\n    let $video;\n    if (ytMatch && ytMatch[1].length === 11) {\n      const youtubeId = ytMatch[1];\n      var start = 0;\n      if (typeof ytMatch[2] !== 'undefined') {\n        const ytMatchForStart = ytMatch[2].match(ytRegExpForStart);\n        if (ytMatchForStart) {\n          for (var n = [3600, 60, 1], i = 0, r = n.length; i < r; i++) {\n            start += (typeof ytMatchForStart[i + 1] !== 'undefined' ? n[i] * parseInt(ytMatchForStart[i + 1], 10) : 0);\n          }\n        }\n      }\n      $video = $('<iframe>')\n        .attr('frameborder', 0)\n        .attr('src', '//www.youtube.com/embed/' + youtubeId + (start > 0 ? '?start=' + start : ''))\n        .attr('width', '640').attr('height', '360');\n    } else if (igMatch && igMatch[0].length) {\n      $video = $('<iframe>')\n        .attr('frameborder', 0)\n        .attr('src', 'https://instagram.com/p/' + igMatch[1] + '/embed/')\n        .attr('width', '612').attr('height', '710')\n        .attr('scrolling', 'no')\n        .attr('allowtransparency', 'true');\n    } else if (vMatch && vMatch[0].length) {\n      $video = $('<iframe>')\n        .attr('frameborder', 0)\n        .attr('src', vMatch[0] + '/embed/simple')\n        .attr('width', '600').attr('height', '600')\n        .attr('class', 'vine-embed');\n    } else if (vimMatch && vimMatch[3].length) {\n      $video = $('<iframe webkitallowfullscreen mozallowfullscreen allowfullscreen>')\n        .attr('frameborder', 0)\n        .attr('src', '//player.vimeo.com/video/' + vimMatch[3])\n        .attr('width', '640').attr('height', '360');\n    } else if (dmMatch && dmMatch[2].length) {\n      $video = $('<iframe>')\n        .attr('frameborder', 0)\n        .attr('src', '//www.dailymotion.com/embed/video/' + dmMatch[2])\n        .attr('width', '640').attr('height', '360');\n    } else if (youkuMatch && youkuMatch[1].length) {\n      $video = $('<iframe webkitallowfullscreen mozallowfullscreen allowfullscreen>')\n        .attr('frameborder', 0)\n        .attr('height', '498')\n        .attr('width', '510')\n        .attr('src', '//player.youku.com/embed/' + youkuMatch[1]);\n    } else if ((qqMatch && qqMatch[1].length) || (qqMatch2 && qqMatch2[2].length)) {\n      const vid = ((qqMatch && qqMatch[1].length) ? qqMatch[1] : qqMatch2[2]);\n      $video = $('<iframe webkitallowfullscreen mozallowfullscreen allowfullscreen>')\n        .attr('frameborder', 0)\n        .attr('height', '310')\n        .attr('width', '500')\n        .attr('src', 'https://v.qq.com/iframe/player.html?vid=' + vid + '&amp;auto=0');\n    } else if (mp4Match || oggMatch || webmMatch) {\n      $video = $('<video controls>')\n        .attr('src', url)\n        .attr('width', '640').attr('height', '360');\n    } else if (fbMatch && fbMatch[0].length) {\n      $video = $('<iframe>')\n        .attr('frameborder', 0)\n        .attr('src', 'https://www.facebook.com/plugins/video.php?href=' + encodeURIComponent(fbMatch[0]) + '&show_text=0&width=560')\n        .attr('width', '560').attr('height', '301')\n        .attr('scrolling', 'no')\n        .attr('allowtransparency', 'true');\n    } else {\n      // this is not a known video link. Now what, Cat? Now what?\n      return false;\n    }\n\n    $video.addClass('note-video-clip');\n\n    return $video[0];\n  }\n\n  show() {\n    const text = this.context.invoke('editor.getSelectedText');\n    this.context.invoke('editor.saveRange');\n    this.showVideoDialog(text).then((url) => {\n      // [workaround] hide dialog before restore range for IE range focus\n      this.ui.hideDialog(this.$dialog);\n      this.context.invoke('editor.restoreRange');\n\n      // build node\n      const $node = this.createVideoNode(url);\n\n      if ($node) {\n        // insert video node\n        this.context.invoke('editor.insertNode', $node);\n      }\n    }).fail(() => {\n      this.context.invoke('editor.restoreRange');\n    });\n  }\n\n  /**\n   * show video dialog\n   *\n   * @param {jQuery} $dialog\n   * @return {Promise}\n   */\n  showVideoDialog(/* text */) {\n    return $.Deferred((deferred) => {\n      const $videoUrl = this.$dialog.find('.note-video-url');\n      const $videoBtn = this.$dialog.find('.note-video-btn');\n\n      this.ui.onDialogShown(this.$dialog, () => {\n        this.context.triggerEvent('dialog.shown');\n\n        $videoUrl.on('input paste propertychange', () => {\n          this.ui.toggleBtn($videoBtn, $videoUrl.val());\n        });\n\n        if (!env.isSupportTouch) {\n          $videoUrl.trigger('focus');\n        }\n\n        $videoBtn.click((event) => {\n          event.preventDefault();\n          deferred.resolve($videoUrl.val());\n        });\n\n        this.bindEnterKey($videoUrl, $videoBtn);\n      });\n\n      this.ui.onDialogHidden(this.$dialog, () => {\n        $videoUrl.off();\n        $videoBtn.off();\n\n        if (deferred.state() === 'pending') {\n          deferred.reject();\n        }\n      });\n\n      this.ui.showDialog(this.$dialog);\n    });\n  }\n}\n","import $ from 'jquery';\nimport env from '../core/env';\n\nexport default class HelpDialog {\n  constructor(context) {\n    this.context = context;\n\n    this.ui = $.summernote.ui;\n    this.$body = $(document.body);\n    this.$editor = context.layoutInfo.editor;\n    this.options = context.options;\n    this.lang = this.options.langInfo;\n  }\n\n  initialize() {\n    const $container = this.options.dialogsInBody ? this.$body : this.options.container;\n    const body = [\n      '<p class=\"text-center\">',\n        '<a href=\"http://summernote.org/\" target=\"_blank\">Summernote @@VERSION@@</a> · ',\n        '<a href=\"https://github.com/summernote/summernote\" target=\"_blank\">Project</a> · ',\n        '<a href=\"https://github.com/summernote/summernote/issues\" target=\"_blank\">Issues</a>',\n      '</p>',\n    ].join('');\n\n    this.$dialog = this.ui.dialog({\n      title: this.lang.options.help,\n      fade: this.options.dialogsFade,\n      body: this.createShortcutList(),\n      footer: body,\n      callback: ($node) => {\n        $node.find('.modal-body,.note-modal-body').css({\n          'max-height': 300,\n          'overflow': 'scroll',\n        });\n      },\n    }).render().appendTo($container);\n  }\n\n  destroy() {\n    this.ui.hideDialog(this.$dialog);\n    this.$dialog.remove();\n  }\n\n  createShortcutList() {\n    const keyMap = this.options.keyMap[env.isMac ? 'mac' : 'pc'];\n    return Object.keys(keyMap).map((key) => {\n      const command = keyMap[key];\n      const $row = $('<div><div class=\"help-list-item\"/></div>');\n      $row.append($('<label><kbd>' + key + '</kdb></label>').css({\n        'width': 180,\n        'margin-right': 10,\n      })).append($('<span/>').html(this.context.memo('help.' + command) || command));\n      return $row.html();\n    }).join('');\n  }\n\n  /**\n   * show help dialog\n   *\n   * @return {Promise}\n   */\n  showHelpDialog() {\n    return $.Deferred((deferred) => {\n      this.ui.onDialogShown(this.$dialog, () => {\n        this.context.triggerEvent('dialog.shown');\n        deferred.resolve();\n      });\n      this.ui.showDialog(this.$dialog);\n    }).promise();\n  }\n\n  show() {\n    this.context.invoke('editor.saveRange');\n    this.showHelpDialog().then(() => {\n      this.context.invoke('editor.restoreRange');\n    });\n  }\n}\n","import $ from 'jquery';\nimport lists from '../core/lists';\n\nconst AIRMODE_POPOVER_X_OFFSET = -5;\nconst AIRMODE_POPOVER_Y_OFFSET = 5;\n\nexport default class AirPopover {\n  constructor(context) {\n    this.context = context;\n    this.ui = $.summernote.ui;\n    this.options = context.options;\n\n    this.hidable = true;\n    this.onContextmenu = false;\n    this.pageX = null;\n    this.pageY = null;\n\n    this.events = {\n      'summernote.contextmenu': (e) => {\n        if (this.options.editing) {\n          e.preventDefault();\n          e.stopPropagation();\n          this.onContextmenu = true;\n          this.update(true);\n        }\n      },\n      'summernote.mousedown': (we, e) => {\n        this.pageX = e.pageX;\n        this.pageY = e.pageY;\n      },\n      'summernote.keyup summernote.mouseup summernote.scroll': (we, e) => {\n        if (this.options.editing && !this.onContextmenu) {\n          this.pageX = e.pageX;\n          this.pageY = e.pageY;\n          this.update();\n        }\n        this.onContextmenu = false;\n      },\n      'summernote.disable summernote.change summernote.dialog.shown summernote.blur': () => {\n        this.hide();\n      },\n      'summernote.focusout': () => {\n        if (!this.$popover.is(':active,:focus')) {\n          this.hide();\n        }\n      },\n    };\n  }\n\n  shouldInitialize() {\n    return this.options.airMode && !lists.isEmpty(this.options.popover.air);\n  }\n\n  initialize() {\n    this.$popover = this.ui.popover({\n      className: 'note-air-popover',\n    }).render().appendTo(this.options.container);\n    const $content = this.$popover.find('.popover-content');\n\n    this.context.invoke('buttons.build', $content, this.options.popover.air);\n\n    // disable hiding this popover preemptively by 'summernote.blur' event.\n    this.$popover.on('mousedown', () => { this.hidable = false; });\n    // (re-)enable hiding after 'summernote.blur' has been handled (aka. ignored).\n    this.$popover.on('mouseup', () => { this.hidable = true; });\n  }\n\n  destroy() {\n    this.$popover.remove();\n  }\n\n  update(forcelyOpen) {\n    const styleInfo = this.context.invoke('editor.currentStyle');\n    if (styleInfo.range && (!styleInfo.range.isCollapsed() || forcelyOpen)) {\n      let rect = {\n        left: this.pageX,\n        top: this.pageY,\n      };\n\n      const containerOffset = $(this.options.container).offset();\n      rect.top -= containerOffset.top;\n      rect.left -= containerOffset.left;\n\n      this.$popover.css({\n        display: 'block',\n        left: Math.max(rect.left, 0) + AIRMODE_POPOVER_X_OFFSET,\n        top: rect.top + AIRMODE_POPOVER_Y_OFFSET,\n      });\n      this.context.invoke('buttons.updateCurrentStyle', this.$popover);\n    } else {\n      this.hide();\n    }\n  }\n\n  hide() {\n    if (this.hidable) {\n      this.$popover.hide();\n    }\n  }\n}\n","import $ from 'jquery';\nimport func from '../core/func';\nimport lists from '../core/lists';\nimport dom from '../core/dom';\nimport range from '../core/range';\nimport key from '../core/key';\n\nconst POPOVER_DIST = 5;\n\nexport default class HintPopover {\n  constructor(context) {\n    this.context = context;\n\n    this.ui = $.summernote.ui;\n    this.$editable = context.layoutInfo.editable;\n    this.options = context.options;\n    this.hint = this.options.hint || [];\n    this.direction = this.options.hintDirection || 'bottom';\n    this.hints = Array.isArray(this.hint) ? this.hint : [this.hint];\n\n    this.events = {\n      'summernote.keyup': (we, e) => {\n        if (!e.isDefaultPrevented()) {\n          this.handleKeyup(e);\n        }\n      },\n      'summernote.keydown': (we, e) => {\n        this.handleKeydown(e);\n      },\n      'summernote.disable summernote.dialog.shown summernote.blur': () => {\n        this.hide();\n      },\n    };\n  }\n\n  shouldInitialize() {\n    return this.hints.length > 0;\n  }\n\n  initialize() {\n    this.lastWordRange = null;\n    this.matchingWord = null;\n    this.$popover = this.ui.popover({\n      className: 'note-hint-popover',\n      hideArrow: true,\n      direction: '',\n    }).render().appendTo(this.options.container);\n\n    this.$popover.hide();\n    this.$content = this.$popover.find('.popover-content,.note-popover-content');\n    this.$content.on('click', '.note-hint-item', (e) => {\n      this.$content.find('.active').removeClass('active');\n      $(e.currentTarget).addClass('active');\n      this.replace();\n    });\n\n    this.$popover.on('mousedown', (e) => { e.preventDefault(); });\n  }\n\n  destroy() {\n    this.$popover.remove();\n  }\n\n  selectItem($item) {\n    this.$content.find('.active').removeClass('active');\n    $item.addClass('active');\n\n    this.$content[0].scrollTop = $item[0].offsetTop - (this.$content.innerHeight() / 2);\n  }\n\n  moveDown() {\n    const $current = this.$content.find('.note-hint-item.active');\n    const $next = $current.next();\n\n    if ($next.length) {\n      this.selectItem($next);\n    } else {\n      let $nextGroup = $current.parent().next();\n\n      if (!$nextGroup.length) {\n        $nextGroup = this.$content.find('.note-hint-group').first();\n      }\n\n      this.selectItem($nextGroup.find('.note-hint-item').first());\n    }\n  }\n\n  moveUp() {\n    const $current = this.$content.find('.note-hint-item.active');\n    const $prev = $current.prev();\n\n    if ($prev.length) {\n      this.selectItem($prev);\n    } else {\n      let $prevGroup = $current.parent().prev();\n\n      if (!$prevGroup.length) {\n        $prevGroup = this.$content.find('.note-hint-group').last();\n      }\n\n      this.selectItem($prevGroup.find('.note-hint-item').last());\n    }\n  }\n\n  replace() {\n    const $item = this.$content.find('.note-hint-item.active');\n\n    if ($item.length) {\n      var node = this.nodeFromItem($item);\n      // If matchingWord length = 0 -> capture OK / open hint / but as mention capture \"\" (\\w*)\n      if (this.matchingWord !== null && this.matchingWord.length === 0) {\n        this.lastWordRange.so = this.lastWordRange.eo;\n      // Else si > 0 and normal case -> adjust range \"before\" for correct position of insertion\n      } else if (this.matchingWord !== null && this.matchingWord.length > 0 && !this.lastWordRange.isCollapsed()) {\n        let rangeCompute = this.lastWordRange.eo - this.lastWordRange.so - this.matchingWord.length;\n        if (rangeCompute > 0) {\n          this.lastWordRange.so += rangeCompute;\n        }\n      }\n      this.lastWordRange.insertNode(node);\n\n      if (this.options.hintSelect === 'next') {\n        var blank = document.createTextNode('');\n        $(node).after(blank);\n        range.createFromNodeBefore(blank).select();\n      } else {\n        range.createFromNodeAfter(node).select();\n      }\n\n      this.lastWordRange = null;\n      this.hide();\n      this.context.invoke('editor.focus');\n    }\n  }\n\n  nodeFromItem($item) {\n    const hint = this.hints[$item.data('index')];\n    const item = $item.data('item');\n    let node = hint.content ? hint.content(item) : item;\n    if (typeof node === 'string') {\n      node = dom.createText(node);\n    }\n    return node;\n  }\n\n  createItemTemplates(hintIdx, items) {\n    const hint = this.hints[hintIdx];\n    return items.map((item /*, idx */) => {\n      const $item = $('<div class=\"note-hint-item\"/>');\n      $item.append(hint.template ? hint.template(item) : item + '');\n      $item.data({\n        'index': hintIdx,\n        'item': item,\n      });\n      return $item;\n    });\n  }\n\n  handleKeydown(e) {\n    if (!this.$popover.is(':visible')) {\n      return;\n    }\n\n    if (e.keyCode === key.code.ENTER) {\n      e.preventDefault();\n      this.replace();\n    } else if (e.keyCode === key.code.UP) {\n      e.preventDefault();\n      this.moveUp();\n    } else if (e.keyCode === key.code.DOWN) {\n      e.preventDefault();\n      this.moveDown();\n    }\n  }\n\n  searchKeyword(index, keyword, callback) {\n    const hint = this.hints[index];\n    if (hint && hint.match.test(keyword) && hint.search) {\n      const matches = hint.match.exec(keyword);\n      this.matchingWord = matches[0];\n      hint.search(matches[1], callback);\n    } else {\n      callback();\n    }\n  }\n\n  createGroup(idx, keyword) {\n    const $group = $('<div class=\"note-hint-group note-hint-group-' + idx + '\"/>');\n    this.searchKeyword(idx, keyword, (items) => {\n      items = items || [];\n      if (items.length) {\n        $group.html(this.createItemTemplates(idx, items));\n        this.show();\n      }\n    });\n\n    return $group;\n  }\n\n  handleKeyup(e) {\n    if (!lists.contains([key.code.ENTER, key.code.UP, key.code.DOWN], e.keyCode)) {\n      let range = this.context.invoke('editor.getLastRange');\n      let wordRange, keyword;\n      if (this.options.hintMode === 'words') {\n        wordRange = range.getWordsRange(range);\n        keyword = wordRange.toString();\n\n        this.hints.forEach((hint) => {\n          if (hint.match.test(keyword)) {\n            wordRange = range.getWordsMatchRange(hint.match);\n            return false;\n          }\n        });\n\n        if (!wordRange) {\n          this.hide();\n          return;\n        }\n\n        keyword = wordRange.toString();\n      } else {\n        wordRange = range.getWordRange();\n        keyword = wordRange.toString();\n      }\n\n      if (this.hints.length && keyword) {\n        this.$content.empty();\n\n        const bnd = func.rect2bnd(lists.last(wordRange.getClientRects()));\n        const containerOffset = $(this.options.container).offset();\n        if (bnd) {\n          bnd.top -= containerOffset.top;\n          bnd.left -= containerOffset.left;\n\n          this.$popover.hide();\n          this.lastWordRange = wordRange;\n          this.hints.forEach((hint, idx) => {\n            if (hint.match.test(keyword)) {\n              this.createGroup(idx, keyword).appendTo(this.$content);\n            }\n          });\n          // select first .note-hint-item\n          this.$content.find('.note-hint-item:first').addClass('active');\n\n          // set position for popover after group is created\n          if (this.direction === 'top') {\n            this.$popover.css({\n              left: bnd.left,\n              top: bnd.top - this.$popover.outerHeight() - POPOVER_DIST,\n            });\n          } else {\n            this.$popover.css({\n              left: bnd.left,\n              top: bnd.top + bnd.height + POPOVER_DIST,\n            });\n          }\n        }\n      } else {\n        this.hide();\n      }\n    }\n  }\n\n  show() {\n    this.$popover.show();\n  }\n\n  hide() {\n    this.$popover.hide();\n  }\n}\n","import $ from 'jquery';\nimport './summernote-en-US';\nimport '../summernote';\nimport dom from './core/dom';\nimport range from './core/range';\nimport lists from './core/lists';\nimport Editor from './module/Editor';\nimport Clipboard from './module/Clipboard';\nimport Dropzone from './module/Dropzone';\nimport Codeview from './module/Codeview';\nimport Statusbar from './module/Statusbar';\nimport Fullscreen from './module/Fullscreen';\nimport Handle from './module/Handle';\nimport AutoLink from './module/AutoLink';\nimport AutoSync from './module/AutoSync';\nimport AutoReplace from './module/AutoReplace';\nimport Placeholder from './module/Placeholder';\nimport Buttons from './module/Buttons';\nimport Toolbar from './module/Toolbar';\nimport LinkDialog from './module/LinkDialog';\nimport LinkPopover from './module/LinkPopover';\nimport ImageDialog from './module/ImageDialog';\nimport ImagePopover from './module/ImagePopover';\nimport TablePopover from './module/TablePopover';\nimport VideoDialog from './module/VideoDialog';\nimport HelpDialog from './module/HelpDialog';\nimport AirPopover from './module/AirPopover';\nimport HintPopover from './module/HintPopover';\n\n$.summernote = $.extend($.summernote, {\n  version: '@@VERSION@@',\n  plugins: {},\n\n  dom: dom,\n  range: range,\n  lists: lists,\n\n  options: {\n    langInfo: $.summernote.lang['en-US'],\n    editing: true,\n    modules: {\n      'editor': Editor,\n      'clipboard': Clipboard,\n      'dropzone': Dropzone,\n      'codeview': Codeview,\n      'statusbar': Statusbar,\n      'fullscreen': Fullscreen,\n      'handle': Handle,\n      // FIXME: HintPopover must be front of autolink\n      //  - Script error about range when Enter key is pressed on hint popover\n      'hintPopover': HintPopover,\n      'autoLink': AutoLink,\n      'autoSync': AutoSync,\n      'autoReplace': AutoReplace,\n      'placeholder': Placeholder,\n      'buttons': Buttons,\n      'toolbar': Toolbar,\n      'linkDialog': LinkDialog,\n      'linkPopover': LinkPopover,\n      'imageDialog': ImageDialog,\n      'imagePopover': ImagePopover,\n      'tablePopover': TablePopover,\n      'videoDialog': VideoDialog,\n      'helpDialog': HelpDialog,\n      'airPopover': AirPopover,\n    },\n\n    buttons: {},\n\n    lang: 'en-US',\n\n    followingToolbar: false,\n    toolbarPosition: 'top',\n    otherStaticBar: '',\n\n    // toolbar\n    toolbar: [\n      ['style', ['style']],\n      ['font', ['bold', 'underline', 'clear']],\n      ['fontname', ['fontname']],\n      ['color', ['color']],\n      ['para', ['ul', 'ol', 'paragraph']],\n      ['table', ['table']],\n      ['insert', ['link', 'picture', 'video']],\n      ['view', ['fullscreen', 'codeview', 'help']],\n    ],\n\n    // popover\n    popatmouse: true,\n    popover: {\n      image: [\n        ['resize', ['resizeFull', 'resizeHalf', 'resizeQuarter', 'resizeNone']],\n        ['float', ['floatLeft', 'floatRight', 'floatNone']],\n        ['remove', ['removeMedia']],\n      ],\n      link: [\n        ['link', ['linkDialogShow', 'unlink']],\n      ],\n      table: [\n        ['add', ['addRowDown', 'addRowUp', 'addColLeft', 'addColRight']],\n        ['delete', ['deleteRow', 'deleteCol', 'deleteTable']],\n      ],\n      air: [\n        ['color', ['color']],\n        ['font', ['bold', 'underline', 'clear']],\n        ['para', ['ul', 'paragraph']],\n        ['table', ['table']],\n        ['insert', ['link', 'picture']],\n        ['view', ['fullscreen', 'codeview']],\n      ],\n    },\n\n    // air mode: inline editor\n    airMode: false,\n    overrideContextMenu: false, // TBD\n\n    width: null,\n    height: null,\n    linkTargetBlank: true,\n    useProtocol: true,\n    defaultProtocol: 'http://',\n\n    focus: false,\n    tabDisabled: false,\n    tabSize: 4,\n    styleWithCSS: false,\n    shortcuts: true,\n    textareaAutoSync: true,\n    tooltip: 'auto',\n    container: null,\n    maxTextLength: 0,\n    blockquoteBreakingLevel: 2,\n    spellCheck: true,\n    disableGrammar: false,\n    placeholder: null,\n    inheritPlaceholder: false,\n    // TODO: need to be documented\n    recordEveryKeystroke: false,\n    historyLimit: 200,\n\n    // TODO: need to be documented\n    hintMode: 'word',\n    hintSelect: 'after',\n    hintDirection: 'bottom',\n\n    styleTags: ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'],\n\n    fontNames: [\n      'Arial', 'Arial Black', 'Comic Sans MS', 'Courier New',\n      'Helvetica Neue', 'Helvetica', 'Impact', 'Lucida Grande',\n      'Tahoma', 'Times New Roman', 'Verdana',\n    ],\n    fontNamesIgnoreCheck: [],\n    addDefaultFonts: true,\n\n    fontSizes: ['8', '9', '10', '11', '12', '14', '18', '24', '36'],\n\n    fontSizeUnits: ['px', 'pt'],\n\n    // pallete colors(n x n)\n    colors: [\n      ['#000000', '#424242', '#636363', '#9C9C94', '#CEC6CE', '#EFEFEF', '#F7F7F7', '#FFFFFF'],\n      ['#FF0000', '#FF9C00', '#FFFF00', '#00FF00', '#00FFFF', '#0000FF', '#9C00FF', '#FF00FF'],\n      ['#F7C6CE', '#FFE7CE', '#FFEFC6', '#D6EFD6', '#CEDEE7', '#CEE7F7', '#D6D6E7', '#E7D6DE'],\n      ['#E79C9C', '#FFC69C', '#FFE79C', '#B5D6A5', '#A5C6CE', '#9CC6EF', '#B5A5D6', '#D6A5BD'],\n      ['#E76363', '#F7AD6B', '#FFD663', '#94BD7B', '#73A5AD', '#6BADDE', '#8C7BC6', '#C67BA5'],\n      ['#CE0000', '#E79439', '#EFC631', '#6BA54A', '#4A7B8C', '#3984C6', '#634AA5', '#A54A7B'],\n      ['#9C0000', '#B56308', '#BD9400', '#397B21', '#104A5A', '#085294', '#311873', '#731842'],\n      ['#630000', '#7B3900', '#846300', '#295218', '#083139', '#003163', '#21104A', '#4A1031'],\n    ],\n\n    // http://chir.ag/projects/name-that-color/\n    colorsName: [\n      ['Black', 'Tundora', 'Dove Gray', 'Star Dust', 'Pale Slate', 'Gallery', 'Alabaster', 'White'],\n      ['Red', 'Orange Peel', 'Yellow', 'Green', 'Cyan', 'Blue', 'Electric Violet', 'Magenta'],\n      ['Azalea', 'Karry', 'Egg White', 'Zanah', 'Botticelli', 'Tropical Blue', 'Mischka', 'Twilight'],\n      ['Tonys Pink', 'Peach Orange', 'Cream Brulee', 'Sprout', 'Casper', 'Perano', 'Cold Purple', 'Careys Pink'],\n      ['Mandy', 'Rajah', 'Dandelion', 'Olivine', 'Gulf Stream', 'Viking', 'Blue Marguerite', 'Puce'],\n      ['Guardsman Red', 'Fire Bush', 'Golden Dream', 'Chelsea Cucumber', 'Smalt Blue', 'Boston Blue', 'Butterfly Bush', 'Cadillac'],\n      ['Sangria', 'Mai Tai', 'Buddha Gold', 'Forest Green', 'Eden', 'Venice Blue', 'Meteorite', 'Claret'],\n      ['Rosewood', 'Cinnamon', 'Olive', 'Parsley', 'Tiber', 'Midnight Blue', 'Valentino', 'Loulou'],\n    ],\n\n    colorButton: {\n      foreColor: '#000000',\n      backColor: '#FFFF00',\n    },\n\n    lineHeights: ['1.0', '1.2', '1.4', '1.5', '1.6', '1.8', '2.0', '3.0'],\n\n    tableClassName: 'table table-bordered',\n\n    insertTableMaxSize: {\n      col: 10,\n      row: 10,\n    },\n\n    // By default, dialogs are attached in container.\n    dialogsInBody: false,\n    dialogsFade: false,\n\n    maximumImageFileSize: null,\n\n    callbacks: {\n      onBeforeCommand: null,\n      onBlur: null,\n      onBlurCodeview: null,\n      onChange: null,\n      onChangeCodeview: null,\n      onDialogShown: null,\n      onEnter: null,\n      onFocus: null,\n      onImageLinkInsert: null,\n      onImageUpload: null,\n      onImageUploadError: null,\n      onInit: null,\n      onKeydown: null,\n      onKeyup: null,\n      onMousedown: null,\n      onMouseup: null,\n      onPaste: null,\n      onScroll: null,\n    },\n\n    codemirror: {\n      mode: 'text/html',\n      htmlMode: true,\n      lineNumbers: true,\n    },\n\n    codeviewFilter: false,\n    codeviewFilterRegex: /<\\/*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|ilayer|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|t(?:itle|extarea)|xml)[^>]*?>/gi,\n    codeviewIframeFilter: true,\n    codeviewIframeWhitelistSrc: [],\n    codeviewIframeWhitelistSrcBase: [\n      'www.youtube.com',\n      'www.youtube-nocookie.com',\n      'www.facebook.com',\n      'vine.co',\n      'instagram.com',\n      'player.vimeo.com',\n      'www.dailymotion.com',\n      'player.youku.com',\n      'v.qq.com',\n    ],\n\n    keyMap: {\n      pc: {\n        'ENTER': 'insertParagraph',\n        'CTRL+Z': 'undo',\n        'CTRL+Y': 'redo',\n        'TAB': 'tab',\n        'SHIFT+TAB': 'untab',\n        'CTRL+B': 'bold',\n        'CTRL+I': 'italic',\n        'CTRL+U': 'underline',\n        'CTRL+SHIFT+S': 'strikethrough',\n        'CTRL+BACKSLASH': 'removeFormat',\n        'CTRL+SHIFT+L': 'justifyLeft',\n        'CTRL+SHIFT+E': 'justifyCenter',\n        'CTRL+SHIFT+R': 'justifyRight',\n        'CTRL+SHIFT+J': 'justifyFull',\n        'CTRL+SHIFT+NUM7': 'insertUnorderedList',\n        'CTRL+SHIFT+NUM8': 'insertOrderedList',\n        'CTRL+LEFTBRACKET': 'outdent',\n        'CTRL+RIGHTBRACKET': 'indent',\n        'CTRL+NUM0': 'formatPara',\n        'CTRL+NUM1': 'formatH1',\n        'CTRL+NUM2': 'formatH2',\n        'CTRL+NUM3': 'formatH3',\n        'CTRL+NUM4': 'formatH4',\n        'CTRL+NUM5': 'formatH5',\n        'CTRL+NUM6': 'formatH6',\n        'CTRL+ENTER': 'insertHorizontalRule',\n        'CTRL+K': 'linkDialog.show',\n      },\n\n      mac: {\n        'ENTER': 'insertParagraph',\n        'CMD+Z': 'undo',\n        'CMD+SHIFT+Z': 'redo',\n        'TAB': 'tab',\n        'SHIFT+TAB': 'untab',\n        'CMD+B': 'bold',\n        'CMD+I': 'italic',\n        'CMD+U': 'underline',\n        'CMD+SHIFT+S': 'strikethrough',\n        'CMD+BACKSLASH': 'removeFormat',\n        'CMD+SHIFT+L': 'justifyLeft',\n        'CMD+SHIFT+E': 'justifyCenter',\n        'CMD+SHIFT+R': 'justifyRight',\n        'CMD+SHIFT+J': 'justifyFull',\n        'CMD+SHIFT+NUM7': 'insertUnorderedList',\n        'CMD+SHIFT+NUM8': 'insertOrderedList',\n        'CMD+LEFTBRACKET': 'outdent',\n        'CMD+RIGHTBRACKET': 'indent',\n        'CMD+NUM0': 'formatPara',\n        'CMD+NUM1': 'formatH1',\n        'CMD+NUM2': 'formatH2',\n        'CMD+NUM3': 'formatH3',\n        'CMD+NUM4': 'formatH4',\n        'CMD+NUM5': 'formatH5',\n        'CMD+NUM6': 'formatH6',\n        'CMD+ENTER': 'insertHorizontalRule',\n        'CMD+K': 'linkDialog.show',\n      },\n    },\n    icons: {\n      'align': 'note-icon-align',\n      'alignCenter': 'note-icon-align-center',\n      'alignJustify': 'note-icon-align-justify',\n      'alignLeft': 'note-icon-align-left',\n      'alignRight': 'note-icon-align-right',\n      'rowBelow': 'note-icon-row-below',\n      'colBefore': 'note-icon-col-before',\n      'colAfter': 'note-icon-col-after',\n      'rowAbove': 'note-icon-row-above',\n      'rowRemove': 'note-icon-row-remove',\n      'colRemove': 'note-icon-col-remove',\n      'indent': 'note-icon-align-indent',\n      'outdent': 'note-icon-align-outdent',\n      'arrowsAlt': 'note-icon-arrows-alt',\n      'bold': 'note-icon-bold',\n      'caret': 'note-icon-caret',\n      'circle': 'note-icon-circle',\n      'close': 'note-icon-close',\n      'code': 'note-icon-code',\n      'eraser': 'note-icon-eraser',\n      'floatLeft': 'note-icon-float-left',\n      'floatRight': 'note-icon-float-right',\n      'font': 'note-icon-font',\n      'frame': 'note-icon-frame',\n      'italic': 'note-icon-italic',\n      'link': 'note-icon-link',\n      'unlink': 'note-icon-chain-broken',\n      'magic': 'note-icon-magic',\n      'menuCheck': 'note-icon-menu-check',\n      'minus': 'note-icon-minus',\n      'orderedlist': 'note-icon-orderedlist',\n      'pencil': 'note-icon-pencil',\n      'picture': 'note-icon-picture',\n      'question': 'note-icon-question',\n      'redo': 'note-icon-redo',\n      'rollback': 'note-icon-rollback',\n      'square': 'note-icon-square',\n      'strikethrough': 'note-icon-strikethrough',\n      'subscript': 'note-icon-subscript',\n      'superscript': 'note-icon-superscript',\n      'table': 'note-icon-table',\n      'textHeight': 'note-icon-text-height',\n      'trash': 'note-icon-trash',\n      'underline': 'note-icon-underline',\n      'undo': 'note-icon-undo',\n      'unorderedlist': 'note-icon-unorderedlist',\n      'video': 'note-icon-video',\n    },\n  },\n});\n","import $ from 'jquery';\nimport renderer from '../base/renderer';\n\nconst editor = renderer.create('<div class=\"note-editor note-frame card\"/>');\nconst toolbar = renderer.create('<div class=\"note-toolbar card-header\" role=\"toolbar\"></div>');\nconst editingArea = renderer.create('<div class=\"note-editing-area\"/>');\nconst codable = renderer.create('<textarea class=\"note-codable\" aria-multiline=\"true\"/>');\nconst editable = renderer.create('<div class=\"note-editable card-block\" contentEditable=\"true\" role=\"textbox\" aria-multiline=\"true\"/>');\nconst statusbar = renderer.create([\n  '<output class=\"note-status-output\" role=\"status\" aria-live=\"polite\"/>',\n  '<div class=\"note-statusbar\" role=\"status\">',\n    '<output class=\"note-status-output\" aria-live=\"polite\"></output>',\n    '<div class=\"note-resizebar\" aria-label=\"Resize\">',\n      '<div class=\"note-icon-bar\"/>',\n      '<div class=\"note-icon-bar\"/>',\n      '<div class=\"note-icon-bar\"/>',\n    '</div>',\n  '</div>',\n].join(''));\n\nconst airEditor = renderer.create('<div class=\"note-editor note-airframe\"/>');\nconst airEditable = renderer.create([\n  '<div class=\"note-editable\" contentEditable=\"true\" role=\"textbox\" aria-multiline=\"true\"/>',\n  '<output class=\"note-status-output\" role=\"status\" aria-live=\"polite\"/>',\n].join(''));\n\nconst buttonGroup = renderer.create('<div class=\"note-btn-group btn-group\">');\n\nconst dropdown = renderer.create('<div class=\"note-dropdown-menu dropdown-menu\" role=\"list\">', function($node, options) {\n  const markup = Array.isArray(options.items) ? options.items.map(function(item) {\n    const value = (typeof item === 'string') ? item : (item.value || '');\n    const content = options.template ? options.template(item) : item;\n    const option = (typeof item === 'object') ? item.option : undefined;\n\n    const dataValue = 'data-value=\"' + value + '\"';\n    const dataOption = (option !== undefined) ? ' data-option=\"' + option + '\"' : '';\n    return '<a class=\"dropdown-item\" href=\"#\" ' + (dataValue + dataOption) + ' role=\"listitem\" aria-label=\"' + value + '\">' + content + '</a>';\n  }).join('') : options.items;\n\n  $node.html(markup).attr({ 'aria-label': options.title });\n});\n\nconst dropdownButtonContents = function(contents) {\n  return contents;\n};\n\nconst dropdownCheck = renderer.create('<div class=\"note-dropdown-menu dropdown-menu note-check\" role=\"list\">', function($node, options) {\n  const markup = Array.isArray(options.items) ? options.items.map(function(item) {\n    const value = (typeof item === 'string') ? item : (item.value || '');\n    const content = options.template ? options.template(item) : item;\n    return '<a class=\"dropdown-item\" href=\"#\" data-value=\"' + value + '\" role=\"listitem\" aria-label=\"' + item + '\">' + icon(options.checkClassName) + ' ' + content + '</a>';\n  }).join('') : options.items;\n  $node.html(markup).attr({ 'aria-label': options.title });\n});\n\nconst dialog = renderer.create('<div class=\"modal note-modal\" aria-hidden=\"false\" tabindex=\"-1\" role=\"dialog\"/>', function($node, options) {\n  if (options.fade) {\n    $node.addClass('fade');\n  }\n  $node.attr({\n    'aria-label': options.title,\n  });\n  $node.html([\n    '<div class=\"modal-dialog\">',\n      '<div class=\"modal-content\">',\n        (options.title ? '<div class=\"modal-header\">' +\n          '<h4 class=\"modal-title\">' + options.title + '</h4>' +\n          '<button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\" aria-hidden=\"true\">&times;</button>' +\n        '</div>' : ''),\n        '<div class=\"modal-body\">' + options.body + '</div>',\n        (options.footer ? '<div class=\"modal-footer\">' + options.footer + '</div>' : ''),\n      '</div>',\n    '</div>',\n  ].join(''));\n});\n\nconst popover = renderer.create([\n  '<div class=\"note-popover popover in\">',\n    '<div class=\"arrow\"/>',\n    '<div class=\"popover-content note-children-container\"/>',\n  '</div>',\n].join(''), function($node, options) {\n  const direction = typeof options.direction !== 'undefined' ? options.direction : 'bottom';\n\n  $node.addClass(direction);\n\n  if (options.hideArrow) {\n    $node.find('.arrow').hide();\n  }\n});\n\nconst checkbox = renderer.create('<div class=\"form-check\"></div>', function($node, options) {\n  $node.html([\n    '<label class=\"form-check-label\"' + (options.id ? ' for=\"note-' + options.id + '\"' : '') + '>',\n      '<input type=\"checkbox\" class=\"form-check-input\"' + (options.id ? ' id=\"note-' + options.id + '\"' : ''),\n        (options.checked ? ' checked' : ''),\n        ' aria-label=\"' + (options.text ? options.text : '') + '\"',\n        ' aria-checked=\"' + (options.checked ? 'true' : 'false') + '\"/>',\n      ' ' + (options.text ? options.text : '') +\n    '</label>',\n  ].join(''));\n});\n\nconst icon = function(iconClassName, tagName) {\n  tagName = tagName || 'i';\n  return '<' + tagName + ' class=\"' + iconClassName + '\"/>';\n};\n\nconst ui = function(editorOptions) {\n  return {\n    editor: editor,\n    toolbar: toolbar,\n    editingArea: editingArea,\n    codable: codable,\n    editable: editable,\n    statusbar: statusbar,\n    airEditor: airEditor,\n    airEditable: airEditable,\n    buttonGroup: buttonGroup,\n    dropdown: dropdown,\n    dropdownButtonContents: dropdownButtonContents,\n    dropdownCheck: dropdownCheck,\n    dialog: dialog,\n    popover: popover,\n    icon: icon,\n    checkbox: checkbox,\n    options: editorOptions,\n\n    palette: function($node, options) {\n      return renderer.create('<div class=\"note-color-palette\"/>', function($node, options) {\n        const contents = [];\n        for (let row = 0, rowSize = options.colors.length; row < rowSize; row++) {\n          const eventName = options.eventName;\n          const colors = options.colors[row];\n          const colorsName = options.colorsName[row];\n          const buttons = [];\n          for (let col = 0, colSize = colors.length; col < colSize; col++) {\n            const color = colors[col];\n            const colorName = colorsName[col];\n            buttons.push([\n              '<button type=\"button\" class=\"note-color-btn\"',\n              'style=\"background-color:', color, '\" ',\n              'data-event=\"', eventName, '\" ',\n              'data-value=\"', color, '\" ',\n              'title=\"', colorName, '\" ',\n              'aria-label=\"', colorName, '\" ',\n              'data-toggle=\"button\" tabindex=\"-1\"></button>',\n            ].join(''));\n          }\n          contents.push('<div class=\"note-color-row\">' + buttons.join('') + '</div>');\n        }\n        $node.html(contents.join(''));\n\n        if (options.tooltip) {\n          $node.find('.note-color-btn').tooltip({\n            container: options.container || editorOptions.container,\n            trigger: 'hover',\n            placement: 'bottom',\n          });\n        }\n      })($node, options);\n    },\n\n    button: function($node, options) {\n      return renderer.create('<button type=\"button\" class=\"note-btn btn btn-light btn-sm\" tabindex=\"-1\">', function($node, options) {\n        if (options && options.tooltip) {\n          $node.attr({\n            title: options.tooltip,\n            'aria-label': options.tooltip,\n          }).tooltip({\n            container: options.container || editorOptions.container,\n            trigger: 'hover',\n            placement: 'bottom',\n          }).on('click', (e) => {\n            $(e.currentTarget).tooltip('hide');\n          });\n        }\n      })($node, options);\n    },\n\n    toggleBtn: function($btn, isEnable) {\n      $btn.toggleClass('disabled', !isEnable);\n      $btn.attr('disabled', !isEnable);\n    },\n\n    toggleBtnActive: function($btn, isActive) {\n      $btn.toggleClass('active', isActive);\n    },\n\n    onDialogShown: function($dialog, handler) {\n      $dialog.one('shown.bs.modal', handler);\n    },\n\n    onDialogHidden: function($dialog, handler) {\n      $dialog.one('hidden.bs.modal', handler);\n    },\n\n    showDialog: function($dialog) {\n      $dialog.modal('show');\n    },\n\n    hideDialog: function($dialog) {\n      $dialog.modal('hide');\n    },\n\n    createLayout: function($note) {\n      const $editor = (editorOptions.airMode ? airEditor([\n        editingArea([\n          codable(),\n          airEditable(),\n        ]),\n      ]) : (editorOptions.toolbarPosition === 'bottom'\n        ? editor([\n          editingArea([\n            codable(),\n            editable(),\n          ]),\n          toolbar(),\n          statusbar(),\n        ])\n        : editor([\n          toolbar(),\n          editingArea([\n            codable(),\n            editable(),\n          ]),\n          statusbar(),\n        ])\n      )).render();\n\n      $editor.insertAfter($note);\n\n      return {\n        note: $note,\n        editor: $editor,\n        toolbar: $editor.find('.note-toolbar'),\n        editingArea: $editor.find('.note-editing-area'),\n        editable: $editor.find('.note-editable'),\n        codable: $editor.find('.note-codable'),\n        statusbar: $editor.find('.note-statusbar'),\n      };\n    },\n\n    removeLayout: function($note, layoutInfo) {\n      $note.html(layoutInfo.editable.html());\n      layoutInfo.editor.remove();\n      $note.show();\n    },\n  };\n};\n\nexport default ui;\n","import $ from 'jquery';\nimport ui from './ui';\nimport '../base/settings.js';\n\nimport '../../styles/summernote-bs4.scss';\n\n$.summernote = $.extend($.summernote, {\n  ui_template: ui,\n  interface: 'bs4',\n});\n\n$.summernote.options.styleTags = [\n  'p',\n  { title: 'Blockquote', tag: 'blockquote', className: 'blockquote', value: 'blockquote' },\n  'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\n];\n"],"sourceRoot":""}

?>