/******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ "./node_modules/@editorjs/code/dist/bundle.js": /*!****************************************************!*\ !*** ./node_modules/@editorjs/code/dist/bundle.js ***! \****************************************************/ /***/ ((module) => { !function(e,t){ true?module.exports=t():0}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=4)}([function(e,t,n){var r=n(1),o=n(2);"string"==typeof(o=o.__esModule?o.default:o)&&(o=[[e.i,o,""]]);var a={insert:"head",singleton:!1};r(o,a);e.exports=o.locals||{}},function(e,t,n){"use strict";var r,o=function(){return void 0===r&&(r=Boolean(window&&document&&document.all&&!window.atob)),r},a=function(){var e={};return function(t){if(void 0===e[t]){var n=document.querySelector(t);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(e){n=null}e[t]=n}return e[t]}}(),i=[];function c(e){for(var t=-1,n=0;n0;)t-=1,n=e.substr(t,1);return"\n"===n&&(t+=1),t}(a,o);if(" "!==a.substr(i," ".length))return;n.value=a.substring(0,i)+a.substring(i+" ".length),t=o-" ".length}else t=o+" ".length,n.value=a.substring(0,o)+" "+a.substring(o);n.setSelectionRange(t,t)}},{key:"data",get:function(){return this._data},set:function(e){this._data=e,this.nodes.textarea&&(this.nodes.textarea.textContent=e.code)}}],[{key:"toolbox",get:function(){return{icon:'',title:"Code"}}},{key:"DEFAULT_PLACEHOLDER",get:function(){return"Enter a code"}},{key:"pasteConfig",get:function(){return{tags:["pre"]}}},{key:"sanitize",get:function(){return{code:!0}}}]),e}()}]).default})); /***/ }), /***/ "./node_modules/@editorjs/delimiter/dist/bundle.js": /*!*********************************************************!*\ !*** ./node_modules/@editorjs/delimiter/dist/bundle.js ***! \*********************************************************/ /***/ ((module) => { !function(e,t){ true?module.exports=t():0}(window,function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=5)}([function(e,t,n){var r=n(1);"string"==typeof r&&(r=[[e.i,r,""]]);var o={hmr:!0,transform:void 0,insertInto:void 0};n(3)(r,o);r.locals&&(e.exports=r.locals)},function(e,t,n){(e.exports=n(2)(!1)).push([e.i,'.ce-delimiter {\n line-height: 1.6em;\n width: 100%;\n text-align: center;\n}\n\n.ce-delimiter:before {\n display: inline-block;\n content: "***";\n font-size: 30px;\n line-height: 65px;\n height: 30px;\n letter-spacing: 0.2em;\n}',""])},function(e,t){e.exports=function(e){var t=[];return t.toString=function(){return this.map(function(t){var n=function(e,t){var n=e[1]||"",r=e[3];if(!r)return n;if(t&&"function"==typeof btoa){var o=(a=r,"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(a))))+" */"),i=r.sources.map(function(e){return"/*# sourceURL="+r.sourceRoot+e+" */"});return[n].concat(i).concat([o]).join("\n")}var a;return[n].join("\n")}(t,e);return t[2]?"@media "+t[2]+"{"+n+"}":n}).join("")},t.i=function(e,n){"string"==typeof e&&(e=[[null,e,""]]);for(var r={},o=0;o=0&&f.splice(t,1)}function b(e){var t=document.createElement("style");return void 0===e.attrs.type&&(e.attrs.type="text/css"),y(t,e.attrs),h(e,t),t}function y(e,t){Object.keys(t).forEach(function(n){e.setAttribute(n,t[n])})}function m(e,t){var n,r,o,i;if(t.transform&&e.css){if(!(i=t.transform(e.css)))return function(){};e.css=i}if(t.singleton){var a=c++;n=u||(u=b(t)),r=x.bind(null,n,a,!1),o=x.bind(null,n,a,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=function(e){var t=document.createElement("link");return void 0===e.attrs.type&&(e.attrs.type="text/css"),e.attrs.rel="stylesheet",y(t,e.attrs),h(e,t),t}(t),r=function(e,t,n){var r=n.css,o=n.sourceMap,i=void 0===t.convertToAbsoluteUrls&&o;(t.convertToAbsoluteUrls||i)&&(r=l(r));o&&(r+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(o))))+" */");var a=new Blob([r],{type:"text/css"}),s=e.href;e.href=URL.createObjectURL(a),s&&URL.revokeObjectURL(s)}.bind(null,n,t),o=function(){v(n),n.href&&URL.revokeObjectURL(n.href)}):(n=b(t),r=function(e,t){var n=t.css,r=t.media;r&&e.setAttribute("media",r);if(e.styleSheet)e.styleSheet.cssText=n;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(n))}}.bind(null,n),o=function(){v(n)});return r(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;r(e=t)}else o()}}e.exports=function(e,t){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(t=t||{}).attrs="object"==typeof t.attrs?t.attrs:{},t.singleton||"boolean"==typeof t.singleton||(t.singleton=a()),t.insertInto||(t.insertInto="head"),t.insertAt||(t.insertAt="bottom");var n=d(e,t);return p(n,t),function(e){for(var r=[],o=0;o',title:"Delimiter"}}}]),e}()}]).default}); /***/ }), /***/ "./node_modules/@editorjs/header/dist/bundle.js": /*!******************************************************!*\ !*** ./node_modules/@editorjs/header/dist/bundle.js ***! \******************************************************/ /***/ ((module) => { !function(e,t){ true?module.exports=t():0}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=5)}([function(e,t,n){var r=n(1);"string"==typeof r&&(r=[[e.i,r,""]]);var o={hmr:!0,transform:void 0,insertInto:void 0};n(3)(r,o);r.locals&&(e.exports=r.locals)},function(e,t,n){(e.exports=n(2)(!1)).push([e.i,"/**\n * Plugin styles\n */\n.ce-header {\n padding: 0.6em 0 3px;\n margin: 0;\n line-height: 1.25em;\n outline: none;\n}\n\n.ce-header p,\n.ce-header div{\n padding: 0 !important;\n margin: 0 !important;\n}\n\n/**\n * Styles for Plugin icon in Toolbar\n */\n.ce-header__icon {}\n\n.ce-header[contentEditable=true][data-placeholder]::before{\n position: absolute;\n content: attr(data-placeholder);\n color: #707684;\n font-weight: normal;\n display: none;\n cursor: text;\n}\n\n.ce-header[contentEditable=true][data-placeholder]:empty::before {\n display: block;\n}\n\n.ce-header[contentEditable=true][data-placeholder]:empty:focus::before {\n display: none;\n}\n",""])},function(e,t){e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n=function(e,t){var n=e[1]||"",r=e[3];if(!r)return n;if(t&&"function"==typeof btoa){var o=(a=r,"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(a))))+" */"),i=r.sources.map((function(e){return"/*# sourceURL="+r.sourceRoot+e+" */"}));return[n].concat(i).concat([o]).join("\n")}var a;return[n].join("\n")}(t,e);return t[2]?"@media "+t[2]+"{"+n+"}":n})).join("")},t.i=function(e,n){"string"==typeof e&&(e=[[null,e,""]]);for(var r={},o=0;o=0&&f.splice(t,1)}function b(e){var t=document.createElement("style");return void 0===e.attrs.type&&(e.attrs.type="text/css"),m(t,e.attrs),v(e,t),t}function m(e,t){Object.keys(t).forEach((function(n){e.setAttribute(n,t[n])}))}function y(e,t){var n,r,o,i;if(t.transform&&e.css){if(!(i=t.transform(e.css)))return function(){};e.css=i}if(t.singleton){var a=c++;n=u||(u=b(t)),r=L.bind(null,n,a,!1),o=L.bind(null,n,a,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=function(e){var t=document.createElement("link");return void 0===e.attrs.type&&(e.attrs.type="text/css"),e.attrs.rel="stylesheet",m(t,e.attrs),v(e,t),t}(t),r=x.bind(null,n,t),o=function(){g(n),n.href&&URL.revokeObjectURL(n.href)}):(n=b(t),r=M.bind(null,n),o=function(){g(n)});return r(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;r(e=t)}else o()}}e.exports=function(e,t){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(t=t||{}).attrs="object"==typeof t.attrs?t.attrs:{},t.singleton||"boolean"==typeof t.singleton||(t.singleton=a()),t.insertInto||(t.insertInto="head"),t.insertAt||(t.insertAt="bottom");var n=h(e,t);return p(n,t),function(e){for(var r=[],o=0;o',title:"Heading"}}}],(n=[{key:"normalizeData",value:function(e){var t={};return"object"!==r(e)&&(e={}),t.text=e.text||"",t.level=parseInt(e.level)||this.defaultLevel.number,t}},{key:"render",value:function(){return this._element}},{key:"renderSettings",value:function(){var e=this;return this.levels.map((function(t){return{icon:t.svg,label:e.api.i18n.t("Heading ".concat(t.number)),onActivate:function(){return e.setLevel(t.number)},closeOnActivate:!0,isActive:e.currentLevel.number===t.number}}))}},{key:"setLevel",value:function(e){this.data={level:e,text:this.data.text}}},{key:"merge",value:function(e){var t={text:this.data.text+e.text,level:this.data.level};this.data=t}},{key:"validate",value:function(e){return""!==e.text.trim()}},{key:"save",value:function(e){return{text:e.innerHTML,level:this.currentLevel.number}}},{key:"getTag",value:function(){var e=document.createElement(this.currentLevel.tag);return e.innerHTML=this._data.text||"",e.classList.add(this._CSS.wrapper),e.contentEditable=this.readOnly?"false":"true",e.dataset.placeholder=this.api.i18n.t(this._settings.placeholder||""),e}},{key:"onPaste",value:function(e){var t=e.detail.data,n=this.defaultLevel.number;switch(t.tagName){case"H1":n=1;break;case"H2":n=2;break;case"H3":n=3;break;case"H4":n=4;break;case"H5":n=5;break;case"H6":n=6}this._settings.levels&&(n=this._settings.levels.reduce((function(e,t){return Math.abs(t-n)'},{number:2,tag:"H2",svg:''},{number:3,tag:"H3",svg:''},{number:4,tag:"H4",svg:''},{number:5,tag:"H5",svg:''},{number:6,tag:"H6",svg:''}];return this._settings.levels?t.filter((function(t){return e._settings.levels.includes(t.number)})):t}}])&&o(t.prototype,n),i&&o(t,i),e}()}]).default})); /***/ }), /***/ "./node_modules/@editorjs/image/dist/bundle.js": /*!*****************************************************!*\ !*** ./node_modules/@editorjs/image/dist/bundle.js ***! \*****************************************************/ /***/ ((module) => { /*! * Image tool * * @version 2.8.1 * * @package https://github.com/editor-js/image * @licence MIT * @author CodeX */ !function(e,t){ true?module.exports=t():0}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=9)}([function(e,t){function n(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};if(e.url&&"string"!=typeof e.url)throw new Error("Url must be a string");if(e.url=e.url||"",e.method&&"string"!=typeof e.method)throw new Error("`method` must be a string or null");if(e.method=e.method?e.method.toUpperCase():"GET",e.headers&&"object"!==r(e.headers))throw new Error("`headers` must be an object or null");if(e.headers=e.headers||{},e.type&&("string"!=typeof e.type||!Object.values(o).includes(e.type)))throw new Error("`type` must be taken from module's «contentType» library");if(e.progress&&"function"!=typeof e.progress)throw new Error("`progress` must be a function or null");if(e.progress=e.progress||function(e){},e.beforeSend=e.beforeSend||function(e){},e.ratio&&"number"!=typeof e.ratio)throw new Error("`ratio` must be a number");if(e.ratio<0||e.ratio>100)throw new Error("`ratio` must be in a 0-100 interval");if(e.ratio=e.ratio||90,e.accept&&"string"!=typeof e.accept)throw new Error("`accept` must be a string with a list of allowed mime-types");if(e.accept=e.accept||"*/*",e.multiple&&"boolean"!=typeof e.multiple)throw new Error("`multiple` must be a true or false");if(e.multiple=e.multiple||!1,e.fieldName&&"string"!=typeof e.fieldName)throw new Error("`fieldName` must be a string");return e.fieldName=e.fieldName||"files",e},c=function(e){switch(e.method){case"GET":var t=s(e.data,o.URLENCODED);delete e.data,e.url=/\?/.test(e.url)?e.url+"&"+t:e.url+"?"+t;break;case"POST":case"PUT":case"DELETE":case"UPDATE":var n=function(){return(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}).type||o.JSON}(e);(d.isFormData(e.data)||d.isFormElement(e.data))&&(n=o.FORM),e.data=s(e.data,n),n!==f.contentType.FORM&&(e.headers["content-type"]=n)}return e},s=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};switch(arguments.length>1?arguments[1]:void 0){case o.URLENCODED:return d.urlEncode(e);case o.JSON:return d.jsonEncode(e);case o.FORM:return d.formEncode(e);default:return e}},l=function(e){return e>=200&&e<300},{contentType:o={URLENCODED:"application/x-www-form-urlencoded; charset=utf-8",FORM:"multipart/form-data",JSON:"application/json; charset=utf-8"},request:i,get:function(e){return e.method="GET",i(e)},post:a,transport:function(e){return e=u(e),d.selectFiles(e).then((function(t){for(var n=new FormData,r=0;r=0&&(e._idleTimeoutId=setTimeout((function(){e._onTimeout&&e._onTimeout()}),t))},n(6),t.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==e&&e.setImmediate||this&&this.setImmediate,t.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==e&&e.clearImmediate||this&&this.clearImmediate}).call(this,n(0))},function(e,t,n){(function(e,t){!function(e,n){"use strict";if(!e.setImmediate){var r,o,i,a,u,c=1,s={},l=!1,d=e.document,f=Object.getPrototypeOf&&Object.getPrototypeOf(e);f=f&&f.setTimeout?f:e,"[object process]"==={}.toString.call(e.process)?r=function(e){t.nextTick((function(){h(e)}))}:function(){if(e.postMessage&&!e.importScripts){var t=!0,n=e.onmessage;return e.onmessage=function(){t=!1},e.postMessage("","*"),e.onmessage=n,t}}()?(a="setImmediate$"+Math.random()+"$",u=function(t){t.source===e&&"string"==typeof t.data&&0===t.data.indexOf(a)&&h(+t.data.slice(a.length))},e.addEventListener?e.addEventListener("message",u,!1):e.attachEvent("onmessage",u),r=function(t){e.postMessage(a+t,"*")}):e.MessageChannel?((i=new MessageChannel).port1.onmessage=function(e){h(e.data)},r=function(e){i.port2.postMessage(e)}):d&&"onreadystatechange"in d.createElement("script")?(o=d.documentElement,r=function(e){var t=d.createElement("script");t.onreadystatechange=function(){h(e),t.onreadystatechange=null,o.removeChild(t),t=null},o.appendChild(t)}):r=function(e){setTimeout(h,0,e)},f.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),n=0;n1)for(var n=1;n HTMLElement")}},{key:"isObject",value:function(e){return"[object Object]"===Object.prototype.toString.call(e)}},{key:"isFormData",value:function(e){return e instanceof FormData}},{key:"isFormElement",value:function(e){return e instanceof HTMLFormElement}},{key:"selectFiles",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return new Promise((function(t,n){var r=document.createElement("INPUT");r.type="file",e.multiple&&r.setAttribute("multiple","multiple"),e.accept&&r.setAttribute("accept",e.accept),r.style.display="none",document.body.appendChild(r),r.addEventListener("change",(function(e){var n=e.target.files;t(n),document.body.removeChild(r)}),!1),r.click()}))}},{key:"parseHeaders",value:function(e){var t=e.trim().split(/[\r\n]+/),n={};return t.forEach((function(e){var t=e.split(": "),r=t.shift(),o=t.join(": ");r&&(n[r]=o)})),n}}])&&r(t,n),e}()},function(e,t){var n=function(e){return encodeURIComponent(e).replace(/[!'()*]/g,escape).replace(/%20/g,"+")},r=function(e,t,o,i){return t=t||null,o=o||"&",i=i||null,e?function(e){for(var t=new Array,n=0;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0;--o){var i=this.tryEntries[o],a=i.completion;if("root"===i.tryLoc)return r("end");if(i.tryLoc<=this.prev){var u=n.call(i,"catchLoc"),c=n.call(i,"finallyLoc");if(u&&c){if(this.prev=0;--r){var o=this.tryEntries[r];if(o.tryLoc<=this.prev&&n.call(o,"finallyLoc")&&this.prev=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),k(n),s}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var r=n.completion;if("throw"===r.type){var o=r.arg;k(n)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,n){return this.delegate={iterator:x(e),resultName:t,nextLoc:n},"next"===this.method&&(this.arg=void 0),s}},e}(e.exports);try{regeneratorRuntime=r}catch(e){Function("r","regeneratorRuntime = r")(r)}},function(e,t,n){var r=n(12),o=n(13);"string"==typeof(o=o.__esModule?o.default:o)&&(o=[[e.i,o,""]]);var i={insert:"head",singleton:!1},a=(r(o,i),o.locals?o.locals:{});e.exports=a},function(e,t,n){"use strict";var r,o=function(){return void 0===r&&(r=Boolean(window&&document&&document.all&&!window.atob)),r},i=function(){var e={};return function(t){if(void 0===e[t]){var n=document.querySelector(t);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(e){n=null}e[t]=n}return e[t]}}(),a=[];function u(e){for(var t=-1,n=0;n1&&void 0!==arguments[1]?arguments[1]:null,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=document.createElement(e);Array.isArray(n)?(t=o.classList).add.apply(t,p()(n)):n&&o.classList.add(n);for(var i in r)o[i]=r[i];return o}var m=function(){function e(t){var n=t.api,r=t.config,o=t.onSelectFile,i=t.readOnly;c()(this,e),this.api=n,this.config=r,this.onSelectFile=o,this.readOnly=i,this.nodes={wrapper:h("div",[this.CSS.baseClass,this.CSS.wrapper]),imageContainer:h("div",[this.CSS.imageContainer]),fileButton:this.createFileButton(),imageEl:void 0,imagePreloader:h("div",this.CSS.imagePreloader),caption:h("div",[this.CSS.input,this.CSS.caption],{contentEditable:!this.readOnly})},this.nodes.caption.dataset.placeholder=this.config.captionPlaceholder,this.nodes.imageContainer.appendChild(this.nodes.imagePreloader),this.nodes.wrapper.appendChild(this.nodes.imageContainer),this.nodes.wrapper.appendChild(this.nodes.caption),this.nodes.wrapper.appendChild(this.nodes.fileButton)}return l()(e,[{key:"render",value:function(t){return t.file&&0!==Object.keys(t.file).length?this.toggleStatus(e.status.UPLOADING):this.toggleStatus(e.status.EMPTY),this.nodes.wrapper}},{key:"createFileButton",value:function(){var e=this,t=h("div",[this.CSS.button]);return t.innerHTML=this.config.buttonContent||"".concat(d," ").concat(this.api.i18n.t("Select an Image")),t.addEventListener("click",(function(){e.onSelectFile()})),t}},{key:"showPreloader",value:function(t){this.nodes.imagePreloader.style.backgroundImage="url(".concat(t,")"),this.toggleStatus(e.status.UPLOADING)}},{key:"hidePreloader",value:function(){this.nodes.imagePreloader.style.backgroundImage="",this.toggleStatus(e.status.EMPTY)}},{key:"fillImage",value:function(t){var n=this,r=/\.mp4$/.test(t)?"VIDEO":"IMG",o={src:t},i="load";"VIDEO"===r&&(o.autoplay=!0,o.loop=!0,o.muted=!0,o.playsinline=!0,i="loadeddata"),this.nodes.imageEl=h(r,this.CSS.imageEl,o),this.nodes.imageEl.addEventListener(i,(function(){n.toggleStatus(e.status.FILLED),n.nodes.imagePreloader&&(n.nodes.imagePreloader.style.backgroundImage="")})),this.nodes.imageContainer.appendChild(this.nodes.imageEl)}},{key:"fillCaption",value:function(e){this.nodes.caption&&(this.nodes.caption.innerHTML=e)}},{key:"toggleStatus",value:function(t){for(var n in e.status)Object.prototype.hasOwnProperty.call(e.status,n)&&this.nodes.wrapper.classList.toggle("".concat(this.CSS.wrapper,"--").concat(e.status[n]),t===e.status[n])}},{key:"applyTune",value:function(e,t){this.nodes.wrapper.classList.toggle("".concat(this.CSS.wrapper,"--").concat(e),t)}},{key:"CSS",get:function(){return{baseClass:this.api.styles.block,loading:this.api.styles.loader,input:this.api.styles.input,button:this.api.styles.button,wrapper:"image-tool",imageContainer:"image-tool__image",imagePreloader:"image-tool__image-preloader",imageEl:"image-tool__image-picture",caption:"image-tool__caption"}}}],[{key:"status",get:function(){return{EMPTY:"empty",UPLOADING:"loading",FILLED:"filled"}}}]),e}(),g=n(8),y=n.n(g),v=n(1),b=n.n(v);function w(e){return e&&"function"==typeof e.then}var k=function(){function e(t){var n=t.config,r=t.onUpload,o=t.onError;c()(this,e),this.config=n,this.onUpload=r,this.onError=o}return l()(e,[{key:"uploadSelectedFile",value:function(e){var t=this,n=e.onPreview,r=function(e){var t=new FileReader;t.readAsDataURL(e),t.onload=function(e){n(e.target.result)}};(this.config.uploader&&"function"==typeof this.config.uploader.uploadByFile?b.a.selectFiles({accept:this.config.types}).then((function(e){r(e[0]);var n=t.config.uploader.uploadByFile(e[0]);return w(n)||console.warn("Custom uploader method uploadByFile should return a Promise"),n})):b.a.transport({url:this.config.endpoints.byFile,data:this.config.additionalRequestData,accept:this.config.types,headers:this.config.additionalRequestHeaders,beforeSend:function(e){r(e[0])},fieldName:this.config.field}).then((function(e){return e.body}))).then((function(e){t.onUpload(e)})).catch((function(e){t.onError(e)}))}},{key:"uploadByUrl",value:function(e){var t,n=this;this.config.uploader&&"function"==typeof this.config.uploader.uploadByUrl?w(t=this.config.uploader.uploadByUrl(e))||console.warn("Custom uploader method uploadByUrl should return a Promise"):t=b.a.post({url:this.config.endpoints.byUrl,data:Object.assign({url:e},this.config.additionalRequestData),type:b.a.contentType.JSON,headers:this.config.additionalRequestHeaders}).then((function(e){return e.body})),t.then((function(e){n.onUpload(e)})).catch((function(e){n.onError(e)}))}},{key:"uploadByFile",value:function(e,t){var n,r=this,o=t.onPreview,i=new FileReader;if(i.readAsDataURL(e),i.onload=function(e){o(e.target.result)},this.config.uploader&&"function"==typeof this.config.uploader.uploadByFile)w(n=this.config.uploader.uploadByFile(e))||console.warn("Custom uploader method uploadByFile should return a Promise");else{var a=new FormData;a.append(this.config.field,e),this.config.additionalRequestData&&Object.keys(this.config.additionalRequestData).length&&Object.entries(this.config.additionalRequestData).forEach((function(e){var t=y()(e,2),n=t[0],r=t[1];a.append(n,r)})),n=b.a.post({url:this.config.endpoints.byFile,data:a,type:b.a.contentType.JSON,headers:this.config.additionalRequestHeaders}).then((function(e){return e.body}))}n.then((function(e){r.onUpload(e)})).catch((function(e){r.onError(e)}))}}]),e}(),_=function(){function e(t){var n=this,r=t.data,o=t.config,i=t.api,a=t.readOnly;c()(this,e),this.api=i,this.readOnly=a,this.config={endpoints:o.endpoints||"",additionalRequestData:o.additionalRequestData||{},additionalRequestHeaders:o.additionalRequestHeaders||{},field:o.field||"image",types:o.types||"image/*",captionPlaceholder:this.api.i18n.t(o.captionPlaceholder||"Caption"),buttonContent:o.buttonContent||"",uploader:o.uploader||void 0,actions:o.actions||[]},this.uploader=new k({config:this.config,onUpload:function(e){return n.onUpload(e)},onError:function(e){return n.uploadingFailed(e)}}),this.ui=new m({api:i,config:this.config,onSelectFile:function(){n.uploader.uploadSelectedFile({onPreview:function(e){n.ui.showPreloader(e)}})},readOnly:a}),this._data={},this.data=r}var t;return l()(e,null,[{key:"isReadOnlySupported",get:function(){return!0}},{key:"toolbox",get:function(){return{icon:d,title:"Image"}}},{key:"tunes",get:function(){return[{name:"withBorder",icon:'',title:"With border",toggle:!0},{name:"stretched",icon:'',title:"Stretch image",toggle:!0},{name:"withBackground",icon:'',title:"With background",toggle:!0}]}}]),l()(e,[{key:"render",value:function(){return this.ui.render(this.data)}},{key:"validate",value:function(e){return e.file&&e.file.url}},{key:"save",value:function(){var e=this.ui.nodes.caption;return this._data.caption=e.innerHTML,this.data}},{key:"renderSettings",value:function(){var t=this;return e.tunes.concat(this.config.actions).map((function(e){return{icon:e.icon,label:t.api.i18n.t(e.title),name:e.name,toggle:e.toggle,isActive:t.data[e.name],onActivate:function(){"function"!=typeof e.action?t.tuneToggled(e.name):e.action(e.name)}}}))}},{key:"appendCallback",value:function(){this.ui.nodes.fileButton.click()}},{key:"onPaste",value:(t=a()(o.a.mark((function e(t){var n,r,i,a,u;return o.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:e.t0=t.type,e.next="tag"===e.t0?3:"pattern"===e.t0?15:"file"===e.t0?18:21;break;case 3:if(n=t.detail.data,!/^blob:/.test(n.src)){e.next=13;break}return e.next=7,fetch(n.src);case 7:return r=e.sent,e.next=10,r.blob();case 10:return i=e.sent,this.uploadFile(i),e.abrupt("break",21);case 13:return this.uploadUrl(n.src),e.abrupt("break",21);case 15:return a=t.detail.data,this.uploadUrl(a),e.abrupt("break",21);case 18:return u=t.detail.file,this.uploadFile(u),e.abrupt("break",21);case 21:case"end":return e.stop()}}),e,this)}))),function(e){return t.apply(this,arguments)})},{key:"onUpload",value:function(e){e.success&&e.file?this.image=e.file:this.uploadingFailed("incorrect response: "+JSON.stringify(e))}},{key:"uploadingFailed",value:function(e){console.log("Image Tool: uploading failed because of",e),this.api.notifier.show({message:this.api.i18n.t("Couldn’t upload image. Please try another."),style:"error"}),this.ui.hidePreloader()}},{key:"tuneToggled",value:function(e){this.setTune(e,!this._data[e])}},{key:"setTune",value:function(e,t){var n=this;this._data[e]=t,this.ui.applyTune(e,t),"stretched"===e&&Promise.resolve().then((function(){var e=n.api.blocks.getCurrentBlockIndex();n.api.blocks.stretchBlock(e,t)})).catch((function(e){console.error(e)}))}},{key:"uploadFile",value:function(e){var t=this;this.uploader.uploadByFile(e,{onPreview:function(e){t.ui.showPreloader(e)}})}},{key:"uploadUrl",value:function(e){this.ui.showPreloader(e),this.uploader.uploadByUrl(e)}},{key:"data",set:function(t){var n=this;this.image=t.file,this._data.caption=t.caption||"",this.ui.fillCaption(this._data.caption),e.tunes.forEach((function(e){var r=e.name,o=void 0!==t[r]&&(!0===t[r]||"true"===t[r]);n.setTune(r,o)}))},get:function(){return this._data}},{key:"image",set:function(e){this._data.file=e||{},e&&e.url&&this.ui.fillImage(e.url)}}],[{key:"pasteConfig",get:function(){return{tags:[{img:{src:!0}}],patterns:{image:/https?:\/\/\S+\.(gif|jpe?g|tiff|png|svg|webp)(\?[a-z0-9=]*)?$/i},files:{mimeTypes:["image/*"]}}}}]),e}(); /** * Image Tool for the Editor.js * * @author CodeX * @license MIT * @see {@link https://github.com/editor-js/image} * * To developers. * To simplify Tool structure, we split it to 4 parts: * 1) index.js — main Tool's interface, public API and methods for working with data * 2) uploader.js — module that has methods for sending files via AJAX: from device, by URL or File pasting * 3) ui.js — module for UI manipulations: render, showing preloader, etc * 4) tunes.js — working with Block Tunes: render buttons, handle clicks * * For debug purposes there is a testing server * that can save uploaded files and return a Response {@link UploadResponseFormat} * * $ node dev/server.js * * It will expose 8008 port, so you can pass http://localhost:8008 with the Tools config: * * image: { * class: ImageTool, * config: { * endpoints: { * byFile: 'http://localhost:8008/uploadFile', * byUrl: 'http://localhost:8008/fetchUrl', * } * }, * }, */}]).default})); /***/ }), /***/ "./node_modules/@editorjs/inline-code/dist/bundle.js": /*!***********************************************************!*\ !*** ./node_modules/@editorjs/inline-code/dist/bundle.js ***! \***********************************************************/ /***/ ((module) => { !function(t,e){ true?module.exports=e():0}(window,function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/",n(n.s=5)}([function(t,e,n){var r=n(1);"string"==typeof r&&(r=[[t.i,r,""]]);var o={hmr:!0,transform:void 0,insertInto:void 0};n(3)(r,o);r.locals&&(t.exports=r.locals)},function(t,e,n){(t.exports=n(2)(!1)).push([t.i,".inline-code {\n background: rgba(250, 239, 240, 0.78);\n color: #b44437;\n padding: 3px 4px;\n border-radius: 5px;\n margin: 0 1px;\n font-family: inherit;\n font-size: 0.86em;\n font-weight: 500;\n letter-spacing: 0.3px;\n}\n",""])},function(t,e){t.exports=function(t){var e=[];return e.toString=function(){return this.map(function(e){var n=function(t,e){var n=t[1]||"",r=t[3];if(!r)return n;if(e&&"function"==typeof btoa){var o=(s=r,"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(s))))+" */"),i=r.sources.map(function(t){return"/*# sourceURL="+r.sourceRoot+t+" */"});return[n].concat(i).concat([o]).join("\n")}var s;return[n].join("\n")}(e,t);return e[2]?"@media "+e[2]+"{"+n+"}":n}).join("")},e.i=function(t,n){"string"==typeof t&&(t=[[null,t,""]]);for(var r={},o=0;o=0&&f.splice(e,1)}function b(t){var e=document.createElement("style");return void 0===t.attrs.type&&(t.attrs.type="text/css"),y(e,t.attrs),h(t,e),e}function y(t,e){Object.keys(e).forEach(function(n){t.setAttribute(n,e[n])})}function g(t,e){var n,r,o,i;if(e.transform&&t.css){if(!(i=e.transform(t.css)))return function(){};t.css=i}if(e.singleton){var s=c++;n=u||(u=b(e)),r=x.bind(null,n,s,!1),o=x.bind(null,n,s,!0)}else t.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=function(t){var e=document.createElement("link");return void 0===t.attrs.type&&(t.attrs.type="text/css"),t.attrs.rel="stylesheet",y(e,t.attrs),h(t,e),e}(e),r=function(t,e,n){var r=n.css,o=n.sourceMap,i=void 0===e.convertToAbsoluteUrls&&o;(e.convertToAbsoluteUrls||i)&&(r=l(r));o&&(r+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(o))))+" */");var s=new Blob([r],{type:"text/css"}),a=t.href;t.href=URL.createObjectURL(s),a&&URL.revokeObjectURL(a)}.bind(null,n,e),o=function(){v(n),n.href&&URL.revokeObjectURL(n.href)}):(n=b(e),r=function(t,e){var n=e.css,r=e.media;r&&t.setAttribute("media",r);if(t.styleSheet)t.styleSheet.cssText=n;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(n))}}.bind(null,n),o=function(){v(n)});return r(t),function(e){if(e){if(e.css===t.css&&e.media===t.media&&e.sourceMap===t.sourceMap)return;r(t=e)}else o()}}t.exports=function(t,e){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(e=e||{}).attrs="object"==typeof e.attrs?e.attrs:{},e.singleton||"boolean"==typeof e.singleton||(e.singleton=s()),e.insertInto||(e.insertInto="head"),e.insertAt||(e.insertAt="bottom");var n=d(t,e);return p(n,e),function(t){for(var r=[],o=0;o'}}],[{key:"isInline",get:function(){return!0}},{key:"sanitize",get:function(){return{code:{class:t.CSS}}}}]),t}()}]).default}); /***/ }), /***/ "./node_modules/@editorjs/list/dist/bundle.js": /*!****************************************************!*\ !*** ./node_modules/@editorjs/list/dist/bundle.js ***! \****************************************************/ /***/ ((module) => { !function(e,t){ true?module.exports=t():0}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=4)}([function(e,t,n){var r=n(1),i=n(2);"string"==typeof(i=i.__esModule?i.default:i)&&(i=[[e.i,i,""]]);var o={insert:"head",singleton:!1};r(i,o);e.exports=i.locals||{}},function(e,t,n){"use strict";var r,i=function(){return void 0===r&&(r=Boolean(window&&document&&document.all&&!window.atob)),r},o=function(){var e={};return function(t){if(void 0===e[t]){var n=document.querySelector(t);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(e){n=null}e[t]=n}return e[t]}}(),a=[];function s(e){for(var t=-1,n=0;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n',default:"ordered"===i.defaultStyle||!0}],this._data={style:this.settings.find((function(e){return!0===e.default})).name,items:[]},this.data=n}return u(e,null,[{key:"isReadOnlySupported",get:function(){return!0}},{key:"enableLineBreaks",get:function(){return!0}},{key:"toolbox",get:function(){return{icon:r,title:"List"}}}]),u(e,[{key:"render",value:function(){var e=this;return this._elements.wrapper=this.makeMainTag(this._data.style),this._data.items.length?this._data.items.forEach((function(t){e._elements.wrapper.appendChild(e._make("li",e.CSS.item,{innerHTML:t}))})):this._elements.wrapper.appendChild(this._make("li",this.CSS.item)),this.readOnly||this._elements.wrapper.addEventListener("keydown",(function(t){switch(t.keyCode){case 13:e.getOutofList(t);break;case 8:e.backspace(t)}}),!1),this._elements.wrapper}},{key:"save",value:function(){return this.data}},{key:"renderSettings",value:function(){var e=this;return this.settings.map((function(t){return s(s({},t),{},{isActive:e._data.style===t.name,closeOnActivate:!0,onActivate:function(){return e.toggleTune(t.name)}})}))}},{key:"onPaste",value:function(e){var t=e.detail.data;this.data=this.pasteHandler(t)}},{key:"makeMainTag",value:function(e){var t="ordered"===e?this.CSS.wrapperOrdered:this.CSS.wrapperUnordered,n="ordered"===e?"ol":"ul";return this._make(n,[this.CSS.baseBlock,this.CSS.wrapper,t],{contentEditable:!this.readOnly})}},{key:"toggleTune",value:function(e){for(var t=this.makeMainTag(e);this._elements.wrapper.hasChildNodes();)t.appendChild(this._elements.wrapper.firstChild);this._elements.wrapper.replaceWith(t),this._elements.wrapper=t,this._data.style=e}},{key:"_make",value:function(e){var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=document.createElement(e);Array.isArray(n)?(t=o.classList).add.apply(t,i(n)):n&&o.classList.add(n);for(var a in r)o[a]=r[a];return o}},{key:"getOutofList",value:function(e){var t=this._elements.wrapper.querySelectorAll("."+this.CSS.item);if(!(t.length<2)){var n=t[t.length-1],r=this.currentItem;r!==n||n.textContent.trim().length||(r.parentElement.removeChild(r),this.api.blocks.insert(),this.api.caret.setToBlock(this.api.blocks.getCurrentBlockIndex()),e.preventDefault(),e.stopPropagation())}}},{key:"backspace",value:function(e){var t=this._elements.wrapper.querySelectorAll("."+this.CSS.item),n=t[0];n&&t.length<2&&!n.innerHTML.replace("
"," ").trim()&&e.preventDefault()}},{key:"selectItem",value:function(e){e.preventDefault();var t=window.getSelection(),n=t.anchorNode.parentNode.closest("."+this.CSS.item),r=new Range;r.selectNodeContents(n),t.removeAllRanges(),t.addRange(r)}},{key:"pasteHandler",value:function(e){var t,n=e.tagName;switch(n){case"OL":t="ordered";break;case"UL":case"LI":t="unordered"}var r={style:t,items:[]};if("LI"===n)r.items=[e.innerHTML];else{var i=Array.from(e.querySelectorAll("LI"));r.items=i.map((function(e){return e.innerHTML})).filter((function(e){return!!e.trim()}))}return r}},{key:"CSS",get:function(){return{baseBlock:this.api.styles.block,wrapper:"cdx-list",wrapperOrdered:"cdx-list--ordered",wrapperUnordered:"cdx-list--unordered",item:"cdx-list__item"}}},{key:"data",set:function(e){e||(e={}),this._data.style=e.style||this.settings.find((function(e){return!0===e.default})).name,this._data.items=e.items||[];var t=this._elements.wrapper;t&&t.parentNode.replaceChild(this.render(),t)},get:function(){this._data.items=[];for(var e=this._elements.wrapper.querySelectorAll(".".concat(this.CSS.item)),t=0;t"," ").trim()&&this._data.items.push(e[t].innerHTML)}return this._data}},{key:"currentItem",get:function(){var e=window.getSelection().anchorNode;return e.nodeType!==Node.ELEMENT_NODE&&(e=e.parentNode),e.closest(".".concat(this.CSS.item))}}],[{key:"conversionConfig",get:function(){return{export:function(e){return e.items.join(". ")},import:function(e){return{items:[e],style:"unordered"}}}}},{key:"sanitize",get:function(){return{style:{},items:{br:!0}}}},{key:"pasteConfig",get:function(){return{tags:["OL","UL","LI"]}}}]),e}()}]).default})); /***/ }), /***/ "./node_modules/@editorjs/quote/dist/bundle.js": /*!*****************************************************!*\ !*** ./node_modules/@editorjs/quote/dist/bundle.js ***! \*****************************************************/ /***/ ((module) => { !function(t,e){ true?module.exports=e():0}(window,function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/",n(n.s=5)}([function(t,e,n){var r=n(1);"string"==typeof r&&(r=[[t.i,r,""]]);var o={hmr:!0,transform:void 0,insertInto:void 0};n(3)(r,o);r.locals&&(t.exports=r.locals)},function(t,e,n){(t.exports=n(2)(!1)).push([t.i,".cdx-quote-icon svg {\n transform: rotate(180deg);\n}\n\n.cdx-quote {\n margin: 0;\n}\n\n.cdx-quote__text {\n min-height: 158px;\n margin-bottom: 10px;\n}\n\n.cdx-quote__caption {}\n\n.cdx-quote [contentEditable=true][data-placeholder]::before{\n position: absolute;\n content: attr(data-placeholder);\n color: #707684;\n font-weight: normal;\n opacity: 0;\n}\n\n.cdx-quote [contentEditable=true][data-placeholder]:empty::before {\n opacity: 1;\n}\n\n.cdx-quote [contentEditable=true][data-placeholder]:empty:focus::before {\n opacity: 0;\n}\n\n\n.cdx-quote-settings {\n display: flex;\n}\n\n.cdx-quote-settings .cdx-settings-button {\n width: 50%;\n}\n",""])},function(t,e){t.exports=function(t){var e=[];return e.toString=function(){return this.map(function(e){var n=function(t,e){var n=t[1]||"",r=t[3];if(!r)return n;if(e&&"function"==typeof btoa){var o=(a=r,"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(a))))+" */"),i=r.sources.map(function(t){return"/*# sourceURL="+r.sourceRoot+t+" */"});return[n].concat(i).concat([o]).join("\n")}var a;return[n].join("\n")}(e,t);return e[2]?"@media "+e[2]+"{"+n+"}":n}).join("")},e.i=function(t,n){"string"==typeof t&&(t=[[null,t,""]]);for(var r={},o=0;o=0&&l.splice(e,1)}function y(t){var e=document.createElement("style");return void 0===t.attrs.type&&(t.attrs.type="text/css"),g(e,t.attrs),h(t,e),e}function g(t,e){Object.keys(e).forEach(function(n){t.setAttribute(n,e[n])})}function b(t,e){var n,r,o,i;if(e.transform&&t.css){if(!(i=e.transform(t.css)))return function(){};t.css=i}if(e.singleton){var a=u++;n=c||(c=y(e)),r=x.bind(null,n,a,!1),o=x.bind(null,n,a,!0)}else t.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=function(t){var e=document.createElement("link");return void 0===t.attrs.type&&(t.attrs.type="text/css"),t.attrs.rel="stylesheet",g(e,t.attrs),h(t,e),e}(e),r=function(t,e,n){var r=n.css,o=n.sourceMap,i=void 0===e.convertToAbsoluteUrls&&o;(e.convertToAbsoluteUrls||i)&&(r=f(r));o&&(r+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(o))))+" */");var a=new Blob([r],{type:"text/css"}),s=t.href;t.href=URL.createObjectURL(a),s&&URL.revokeObjectURL(s)}.bind(null,n,e),o=function(){v(n),n.href&&URL.revokeObjectURL(n.href)}):(n=y(e),r=function(t,e){var n=e.css,r=e.media;r&&t.setAttribute("media",r);if(t.styleSheet)t.styleSheet.cssText=n;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(n))}}.bind(null,n),o=function(){v(n)});return r(t),function(e){if(e){if(e.css===t.css&&e.media===t.media&&e.sourceMap===t.sourceMap)return;r(t=e)}else o()}}t.exports=function(t,e){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(e=e||{}).attrs="object"==typeof e.attrs?e.attrs:{},e.singleton||"boolean"==typeof e.singleton||(e.singleton=a()),e.insertInto||(e.insertInto="head"),e.insertAt||(e.insertAt="bottom");var n=p(t,e);return d(n,e),function(t){for(var r=[],o=0;o'},{name:"center",icon:''}]}}],[{key:"isReadOnlySupported",get:function(){return!0}},{key:"toolbox",get:function(){return{icon:'',title:"Quote"}}},{key:"contentless",get:function(){return!0}},{key:"enableLineBreaks",get:function(){return!0}},{key:"DEFAULT_QUOTE_PLACEHOLDER",get:function(){return"Enter a quote"}},{key:"DEFAULT_CAPTION_PLACEHOLDER",get:function(){return"Enter a caption"}},{key:"ALIGNMENTS",get:function(){return{left:"left",center:"center"}}},{key:"DEFAULT_ALIGNMENT",get:function(){return t.ALIGNMENTS.left}},{key:"conversionConfig",get:function(){return{import:"text",export:function(t){return t.caption?"".concat(t.text," — ").concat(t.caption):t.text}}}}]),i(t,[{key:"render",value:function(){var t=this._make("blockquote",[this.CSS.baseClass,this.CSS.wrapper]),e=this._make("div",[this.CSS.input,this.CSS.text],{contentEditable:!this.readOnly,innerHTML:this.data.text}),n=this._make("div",[this.CSS.input,this.CSS.caption],{contentEditable:!this.readOnly,innerHTML:this.data.caption});return e.dataset.placeholder=this.quotePlaceholder,n.dataset.placeholder=this.captionPlaceholder,t.appendChild(e),t.appendChild(n),t}},{key:"save",value:function(t){var e=t.querySelector(".".concat(this.CSS.text)),n=t.querySelector(".".concat(this.CSS.caption));return Object.assign(this.data,{text:e.innerHTML,caption:n.innerHTML})}},{key:"renderSettings",value:function(){var t=this;return this.settings.map(function(e){return{icon:e.icon,label:t.api.i18n.t("Align ".concat((n=e.name,n[0].toUpperCase()+n.substr(1)))),onActivate:function(){return t._toggleTune(e.name)},isActive:t.data.alignment===e.name,closeOnActivate:!0};var n})}},{key:"_toggleTune",value:function(t){this.data.alignment=t}},{key:"_make",value:function(t){var e,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},i=document.createElement(t);Array.isArray(n)?(e=i.classList).add.apply(e,r(n)):n&&i.classList.add(n);for(var a in o)i[a]=o[a];return i}}],[{key:"sanitize",get:function(){return{text:{br:!0},caption:{br:!0},alignment:{}}}}]),t}()}]).default}); /***/ }), /***/ "./node_modules/@editorjs/raw/dist/bundle.js": /*!***************************************************!*\ !*** ./node_modules/@editorjs/raw/dist/bundle.js ***! \***************************************************/ /***/ ((module) => { !function(e,t){ true?module.exports=t():0}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=5)}([function(e,t,n){var r=n(1);"string"==typeof r&&(r=[[e.i,r,""]]);var o={hmr:!0,transform:void 0,insertInto:void 0};n(3)(r,o);r.locals&&(e.exports=r.locals)},function(e,t,n){(e.exports=n(2)(!1)).push([e.i,".ce-rawtool__textarea {\n min-height: 200px;\n resize: vertical;\n border-radius: 8px;\n border: 0;\n background-color: #1e2128;\n font-family: Menlo, Monaco, Consolas, Courier New, monospace;\n font-size: 12px;\n line-height: 1.6;\n letter-spacing: -0.2px;\n color: #a1a7b6;\n overscroll-behavior: contain;\n}\n",""])},function(e,t){e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n=function(e,t){var n=e[1]||"",r=e[3];if(!r)return n;if(t&&"function"==typeof btoa){var o=(a=r,"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(a))))+" */"),i=r.sources.map((function(e){return"/*# sourceURL="+r.sourceRoot+e+" */"}));return[n].concat(i).concat([o]).join("\n")}var a;return[n].join("\n")}(t,e);return t[2]?"@media "+t[2]+"{"+n+"}":n})).join("")},t.i=function(e,n){"string"==typeof e&&(e=[[null,e,""]]);for(var r={},o=0;o=0&&f.splice(t,1)}function y(e){var t=document.createElement("style");return void 0===e.attrs.type&&(e.attrs.type="text/css"),m(t,e.attrs),v(e,t),t}function m(e,t){Object.keys(t).forEach((function(n){e.setAttribute(n,t[n])}))}function g(e,t){var n,r,o,i;if(t.transform&&e.css){if(!(i=t.transform(e.css)))return function(){};e.css=i}if(t.singleton){var a=l++;n=c||(c=y(t)),r=L.bind(null,n,a,!1),o=L.bind(null,n,a,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=function(e){var t=document.createElement("link");return void 0===e.attrs.type&&(e.attrs.type="text/css"),e.attrs.rel="stylesheet",m(t,e.attrs),v(e,t),t}(t),r=j.bind(null,n,t),o=function(){b(n),n.href&&URL.revokeObjectURL(n.href)}):(n=y(t),r=C.bind(null,n),o=function(){b(n)});return r(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;r(e=t)}else o()}}e.exports=function(e,t){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(t=t||{}).attrs="object"==typeof t.attrs?t.attrs:{},t.singleton||"boolean"==typeof t.singleton||(t.singleton=a()),t.insertInto||(t.insertInto="head"),t.insertAt||(t.insertAt="bottom");var n=h(e,t);return d(n,t),function(e){for(var r=[],o=0;o',title:"Raw HTML"}}}]),o(e,[{key:"render",value:function(){var e=this,t=document.createElement("div");return this.textarea=document.createElement("textarea"),t.classList.add(this.CSS.baseClass,this.CSS.wrapper),this.textarea.classList.add(this.CSS.textarea,this.CSS.input),this.textarea.textContent=this.data.html,this.textarea.placeholder=this.placeholder,this.readOnly?this.textarea.disabled=!0:this.textarea.addEventListener("input",(function(){e.onInput()})),t.appendChild(this.textarea),setTimeout((function(){e.resize()}),100),t}},{key:"save",value:function(e){return{html:e.querySelector("textarea").value}}},{key:"onInput",value:function(){var e=this;this.resizeDebounce&&clearTimeout(this.resizeDebounce),this.resizeDebounce=setTimeout((function(){e.resize()}),200)}},{key:"resize",value:function(){this.textarea.style.height="auto",this.textarea.style.height=this.textarea.scrollHeight+"px"}}],[{key:"DEFAULT_PLACEHOLDER",get:function(){return"Enter HTML code"}},{key:"sanitize",get:function(){return{html:!0}}}]),e}()}]).default})); /***/ }), /***/ "./node_modules/@editorjs/table/dist/table.js": /*!****************************************************!*\ !*** ./node_modules/@editorjs/table/dist/table.js ***! \****************************************************/ /***/ ((module) => { !function(t,e){ true?module.exports=e():0}(window,(function(){return function(t){var e={};function o(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,o),i.l=!0,i.exports}return o.m=t,o.c=e,o.d=function(t,e,r){o.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},o.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(o.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)o.d(r,i,function(e){return t[e]}.bind(null,i));return r},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,"a",e),e},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o.p="/",o(o.s=6)}([function(t,e){t.exports=''},function(t,e,o){var r=o(2);"string"==typeof r&&(r=[[t.i,r,""]]);var i={hmr:!0,transform:void 0,insertInto:void 0};o(4)(r,i);r.locals&&(t.exports=r.locals)},function(t,e,o){(t.exports=o(3)(!1)).push([t.i,'.tc-wrap{--color-background:#f9f9fb;--color-text-secondary:#7b7e89;--color-border:#e8e8eb;--cell-size:34px;--toolbox-icon-size:18px;--toolbox-padding:6px;--toolbox-aiming-field-size:calc(var(--toolbox-icon-size) + var(--toolbox-padding)*2);border-left:0;position:relative;height:100%;width:100%;margin-top:var(--toolbox-icon-size);box-sizing:border-box;display:grid;grid-template-columns:calc(100% - var(--cell-size)) var(--cell-size);}.tc-wrap--readonly{grid-template-columns:100% var(--cell-size)}.tc-wrap svg{vertical-align:top}@media print{.tc-wrap{border-left-color:var(--color-border);border-left-style:solid;border-left-width:1px;grid-template-columns:100% var(--cell-size)}}@media print{.tc-wrap .tc-row:after{display:none}}.tc-table{position:relative;width:100%;height:100%;display:grid;font-size:14px;border-top:1px solid var(--color-border);line-height:1.4;}.tc-table:after{width:calc(var(--cell-size));height:100%;left:calc(var(--cell-size)*-1);top:0}.tc-table:after,.tc-table:before{position:absolute;content:""}.tc-table:before{width:100%;height:var(--toolbox-aiming-field-size);top:calc(var(--toolbox-aiming-field-size)*-1);left:0}.tc-table--heading .tc-row:first-child{font-weight:600;border-bottom:2px solid var(--color-border);}.tc-table--heading .tc-row:first-child [contenteditable]:empty:before{content:attr(heading);color:var(--color-text-secondary)}.tc-table--heading .tc-row:first-child:after{bottom:-2px;border-bottom:2px solid var(--color-border)}.tc-add-column,.tc-add-row{display:flex;color:var(--color-text-secondary)}@media print{.tc-add{display:none}}.tc-add-column{padding:4px 0;justify-content:center;border-top:1px solid var(--color-border);}@media print{.tc-add-column{display:none}}.tc-add-row{height:var(--cell-size);align-items:center;padding-left:4px;position:relative;}.tc-add-row:before{content:"";position:absolute;right:calc(var(--cell-size)*-1);width:var(--cell-size);height:100%}@media print{.tc-add-row{display:none}}.tc-add-column,.tc-add-row{transition:0s;cursor:pointer;will-change:background-color;}.tc-add-column:hover,.tc-add-row:hover{transition:background-color .1s ease;background-color:var(--color-background)}.tc-add-row{margin-top:1px;}.tc-add-row:hover:before{transition:.1s;background-color:var(--color-background)}.tc-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(10px,1fr));position:relative;border-bottom:1px solid var(--color-border);}.tc-row:after{content:"";pointer-events:none;position:absolute;width:var(--cell-size);height:100%;bottom:-1px;right:calc(var(--cell-size)*-1);border-bottom:1px solid var(--color-border)}.tc-row--selected{background:var(--color-background)}.tc-row--selected:after{background:var(--color-background)}.tc-cell{border-right:1px solid var(--color-border);padding:6px 12px;overflow:hidden;outline:none;line-break:normal;}.tc-cell--selected{background:var(--color-background)}.tc-wrap--readonly .tc-row:after{display:none}.tc-toolbox{--toolbox-padding:6px;--popover-margin:30px;--toggler-click-zone-size:30px;--toggler-dots-color:#7b7e89;--toggler-dots-color-hovered:#1d202b;position:absolute;cursor:pointer;z-index:1;opacity:0;transition:opacity .1s;will-change:left,opacity;}.tc-toolbox--column{top:calc(var(--toggler-click-zone-size)*-1);transform:translateX(calc(var(--toggler-click-zone-size)*-1/2));will-change:left,opacity}.tc-toolbox--row{left:calc(var(--popover-margin)*-1);transform:translateY(calc(var(--toggler-click-zone-size)*-1/2));margin-top:-1px;will-change:top,opacity}.tc-toolbox--showed{opacity:1}.tc-toolbox .tc-popover{position:absolute;top:0;left:var(--popover-margin)}.tc-toolbox__toggler{display:flex;align-items:center;justify-content:center;width:var(--toggler-click-zone-size);height:var(--toggler-click-zone-size);color:var(--toggler-dots-color);opacity:0;transition:opacity .15s ease;will-change:opacity;}.tc-toolbox__toggler:hover{color:var(--toggler-dots-color-hovered)}.tc-toolbox__toggler svg{fill:currentColor}.tc-wrap:hover .tc-toolbox__toggler{opacity:1}.tc-settings .cdx-settings-button{width:50%;margin:0}.tc-popover{--color-border:#eaeaea;--color-background:#fff;--color-background-hover:rgba(232,232,235,0.49);--color-background-confirm:#e24a4a;--color-background-confirm-hover:#d54040;--color-text-confirm:#fff;background:var(--color-background);border:1px solid var(--color-border);box-shadow:0 3px 15px -3px rgba(13,20,33,.13);border-radius:6px;padding:6px;display:none;will-change:opacity,transform;}.tc-popover--opened{display:block;animation:menuShowing .1s cubic-bezier(.215,.61,.355,1) forwards}.tc-popover__item{display:flex;align-items:center;padding:2px 14px 2px 2px;border-radius:5px;cursor:pointer;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;user-select:none;}.tc-popover__item:hover{background:var(--color-background-hover)}.tc-popover__item:not(:last-of-type){margin-bottom:2px}.tc-popover__item-icon{display:inline-flex;width:26px;height:26px;align-items:center;justify-content:center;background:var(--color-background);border-radius:5px;border:1px solid var(--color-border);margin-right:8px}.tc-popover__item-label{line-height:22px;font-size:14px;font-weight:500}.tc-popover__item--confirm{background:var(--color-background-confirm);color:var(--color-text-confirm);}.tc-popover__item--confirm:hover{background-color:var(--color-background-confirm-hover)}.tc-popover__item--confirm .tc-popover__item-icon{background:var(--color-background-confirm);border-color:rgba(0,0,0,.1);}.tc-popover__item--confirm .tc-popover__item-icon svg{transition:transform .2s ease-in;transform:rotate(90deg) scale(1.2)}.tc-popover__item--hidden{display:none}@keyframes menuShowing{0%{opacity:0;transform:translateY(-8px) scale(.9)}70%{opacity:1;transform:translateY(2px)}to{transform:translateY(0)}}',""])},function(t,e){t.exports=function(t){var e=[];return e.toString=function(){return this.map((function(e){var o=function(t,e){var o=t[1]||"",r=t[3];if(!r)return o;if(e&&"function"==typeof btoa){var i=(s=r,"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(s))))+" */"),n=r.sources.map((function(t){return"/*# sourceURL="+r.sourceRoot+t+" */"}));return[o].concat(n).concat([i]).join("\n")}var s;return[o].join("\n")}(e,t);return e[2]?"@media "+e[2]+"{"+o+"}":o})).join("")},e.i=function(t,o){"string"==typeof t&&(t=[[null,t,""]]);for(var r={},i=0;i=0&&h.splice(e,1)}function w(t){var e=document.createElement("style");if(void 0===t.attrs.type&&(t.attrs.type="text/css"),void 0===t.attrs.nonce){var r=function(){0;return o.nc}();r&&(t.attrs.nonce=r)}return b(e,t.attrs),g(t,e),e}function b(t,e){Object.keys(e).forEach((function(o){t.setAttribute(o,e[o])}))}function v(t,e){var o,r,i,n;if(e.transform&&t.css){if(!(n="function"==typeof e.transform?e.transform(t.css):e.transform.default(t.css)))return function(){};t.css=n}if(e.singleton){var s=d++;o=c||(c=w(e)),r=y.bind(null,o,s,!1),i=y.bind(null,o,s,!0)}else t.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(o=function(t){var e=document.createElement("link");return void 0===t.attrs.type&&(t.attrs.type="text/css"),t.attrs.rel="stylesheet",b(e,t.attrs),g(t,e),e}(e),r=R.bind(null,o,e),i=function(){m(o),o.href&&URL.revokeObjectURL(o.href)}):(o=w(e),r=k.bind(null,o),i=function(){m(o)});return r(t),function(e){if(e){if(e.css===t.css&&e.media===t.media&&e.sourceMap===t.sourceMap)return;r(t=e)}else i()}}t.exports=function(t,e){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(e=e||{}).attrs="object"==typeof e.attrs?e.attrs:{},e.singleton||"boolean"==typeof e.singleton||(e.singleton=s()),e.insertInto||(e.insertInto="head"),e.insertAt||(e.insertAt="bottom");var o=f(t,e);return u(o,e),function(t){for(var r=[],i=0;i{const o=r("div",a.CSS.item),i=r("div",a.CSS.itemIcon,{innerHTML:t.icon}),n=r("div",a.CSS.itemLabel,{textContent:t.label});o.dataset.index=e,o.appendChild(i),o.appendChild(n),this.wrapper.appendChild(o),this.itemEls.push(o)}),this.wrapper.addEventListener("click",t=>{this.popoverClicked(t)}),this.wrapper}popoverClicked(t){const e=t.target.closest("."+a.CSS.item);if(!e)return;const o=e.dataset.index,r=this.items[o];!r.confirmationRequired||this.hasConfirmationState(e)?r.onClick():this.setConfirmationState(e)}setConfirmationState(t){t.classList.add(a.CSS.itemConfirmState)}clearConfirmationState(t){t.classList.remove(a.CSS.itemConfirmState)}hasConfirmationState(t){return t.classList.contains(a.CSS.itemConfirmState)}get opened(){return this.wrapper.classList.contains(a.CSS.popoverOpened)}open(){this.items.forEach((t,e)=>{"function"==typeof t.hideIf&&this.itemEls[e].classList.toggle(a.CSS.itemHidden,t.hideIf())}),this.wrapper.classList.add(a.CSS.popoverOpened)}close(){this.wrapper.classList.remove(a.CSS.popoverOpened),this.itemEls.forEach(t=>{this.clearConfirmationState(t)})}}var c=o(0),d=o.n(c);class h{constructor({api:t,items:e,onOpen:o,onClose:r,cssModifier:i=""}){this.api=t,this.items=e,this.onOpen=o,this.onClose=r,this.cssModifier=i,this.popover=null,this.wrapper=this.createToolbox()}static get CSS(){return{toolbox:"tc-toolbox",toolboxShowed:"tc-toolbox--showed",toggler:"tc-toolbox__toggler"}}get element(){return this.wrapper}createToolbox(){const t=r("div",[h.CSS.toolbox,this.cssModifier?`${h.CSS.toolbox}--${this.cssModifier}`:""]);t.dataset.mutationFree="true";const e=this.createPopover(),o=this.createToggler();return t.appendChild(o),t.appendChild(e),t}createToggler(){const t=r("div",h.CSS.toggler,{innerHTML:d.a});return t.addEventListener("click",()=>{this.togglerClicked()}),t}createPopover(){return this.popover=new a({items:this.items}),this.popover.render()}togglerClicked(){this.popover.opened?(this.popover.close(),this.onClose()):(this.popover.open(),this.onOpen())}show(t){const e=t();Object.entries(e).forEach(([t,e])=>{this.wrapper.style[t]=e}),this.wrapper.classList.add(h.CSS.toolboxShowed)}hide(){this.popover.close(),this.wrapper.classList.remove(h.CSS.toolboxShowed)}}const p='',u='',f="tc-wrap",g="tc-wrap--readonly",m="tc-table",w="tc-row",b="tc-table--heading",v="tc-row--selected",x="tc-cell",C="tc-cell--selected",y="tc-add-row",k="tc-add-column";class R{constructor(t,e,o,r){this.readOnly=t,this.api=e,this.data=o,this.config=r,this.wrapper=null,this.table=null,this.toolboxColumn=this.createColumnToolbox(),this.toolboxRow=this.createRowToolbox(),this.createTableWrapper(),this.hoveredRow=0,this.hoveredColumn=0,this.selectedRow=0,this.selectedColumn=0,this.tunes={withHeadings:!1},this.resize(),this.fill(),this.focusedCell={row:0,column:0},this.documentClicked=t=>{const e=null!==t.target.closest("."+m),o=null===t.target.closest("."+f);(e||o)&&this.hideToolboxes();const r=t.target.closest("."+y),i=t.target.closest("."+k);r&&r.parentNode===this.wrapper?(this.addRow(void 0,!0),this.hideToolboxes()):i&&i.parentNode===this.wrapper&&(this.addColumn(void 0,!0),this.hideToolboxes())},this.readOnly||this.bindEvents()}getWrapper(){return this.wrapper}bindEvents(){document.addEventListener("click",this.documentClicked),this.table.addEventListener("mousemove",function(t,e){let o=0;return function(...r){const i=(new Date).getTime();if(!(i-othis.onMouseMoveInTable(t)),{passive:!0}),this.table.onkeypress=t=>this.onKeyPressListener(t),this.table.addEventListener("keydown",t=>this.onKeyDownListener(t)),this.table.addEventListener("focusin",t=>this.focusInTableListener(t))}createColumnToolbox(){return new h({api:this.api,cssModifier:"column",items:[{label:this.api.i18n.t("Add column to left"),icon:'',onClick:()=>{this.addColumn(this.selectedColumn,!0),this.hideToolboxes()}},{label:this.api.i18n.t("Add column to right"),icon:'',onClick:()=>{this.addColumn(this.selectedColumn+1,!0),this.hideToolboxes()}},{label:this.api.i18n.t("Delete column"),icon:p,hideIf:()=>1===this.numberOfColumns,confirmationRequired:!0,onClick:()=>{this.deleteColumn(this.selectedColumn),this.hideToolboxes()}}],onOpen:()=>{this.selectColumn(this.hoveredColumn),this.hideRowToolbox()},onClose:()=>{this.unselectColumn()}})}createRowToolbox(){return new h({api:this.api,cssModifier:"row",items:[{label:this.api.i18n.t("Add row above"),icon:'',onClick:()=>{this.addRow(this.selectedRow,!0),this.hideToolboxes()}},{label:this.api.i18n.t("Add row below"),icon:'',onClick:()=>{this.addRow(this.selectedRow+1,!0),this.hideToolboxes()}},{label:this.api.i18n.t("Delete row"),icon:p,hideIf:()=>1===this.numberOfRows,confirmationRequired:!0,onClick:()=>{this.deleteRow(this.selectedRow),this.hideToolboxes()}}],onOpen:()=>{this.selectRow(this.hoveredRow),this.hideColumnToolbox()},onClose:()=>{this.unselectRow()}})}moveCursorToNextRow(){this.focusedCell.row!==this.numberOfRows?(this.focusedCell.row+=1,this.focusCell(this.focusedCell)):(this.addRow(),this.focusedCell.row+=1,this.focusCell(this.focusedCell),this.updateToolboxesPosition(0,0))}getCell(t,e){return this.table.querySelectorAll(`.${w}:nth-child(${t}) .${x}`)[e-1]}getRow(t){return this.table.querySelector(`.${w}:nth-child(${t})`)}getRowByCell(t){return t.parentElement}getRowFirstCell(t){return t.querySelector(`.${x}:first-child`)}setCellContent(t,e,o){this.getCell(t,e).innerHTML=o}addColumn(t=-1,e=!1){let o=this.numberOfColumns;for(let r=1;r<=this.numberOfRows;r++){let i;const n=this.createCell();if(t>0&&t<=o?(i=this.getCell(r,t),s(n,i)):i=this.getRow(r).appendChild(n),1===r){const i=this.getCell(r,t>0?t:o+1);i&&e&&l(i)}}this.addHeadingAttrToFirstRow()}addRow(t=-1,e=!1){let o,i=r("div",w);this.tunes.withHeadings&&this.removeHeadingAttrFromFirstRow();let n=this.numberOfColumns;if(t>0&&t<=this.numberOfRows){o=s(i,this.getRow(t))}else o=this.table.appendChild(i);this.fillRow(o,n),this.tunes.withHeadings&&this.addHeadingAttrToFirstRow();const a=this.getRowFirstCell(o);return a&&e&&l(a),o}deleteColumn(t){for(let e=1;e<=this.numberOfRows;e++){const o=this.getCell(e,t);if(!o)return;o.remove()}}deleteRow(t){this.getRow(t).remove(),this.addHeadingAttrToFirstRow()}createTableWrapper(){if(this.wrapper=r("div",f),this.table=r("div",m),this.readOnly&&this.wrapper.classList.add(g),this.wrapper.appendChild(this.toolboxRow.element),this.wrapper.appendChild(this.toolboxColumn.element),this.wrapper.appendChild(this.table),!this.readOnly){const t=r("div",k,{innerHTML:u}),e=r("div",y,{innerHTML:u});this.wrapper.appendChild(t),this.wrapper.appendChild(e)}}computeInitialSize(){const t=this.data&&this.data.content,e=Array.isArray(t),o=!!e&&t.length,r=e?t.length:void 0,i=o?t[0].length:void 0,n=Number.parseInt(this.config&&this.config.rows),s=Number.parseInt(this.config&&this.config.cols),l=!isNaN(n)&&n>0?n:void 0,a=!isNaN(s)&&s>0?s:void 0;return{rows:r||l||2,cols:i||a||2}}resize(){const{rows:t,cols:e}=this.computeInitialSize();for(let e=0;e0&&e<=this.numberOfColumns&&this.toolboxColumn.show(()=>({left:`calc((100% - var(--cell-size)) / (${this.numberOfColumns} * 2) * (1 + (${e} - 1) * 2))`})),this.isRowMenuShowing||t>0&&t<=this.numberOfRows&&this.toolboxRow.show(()=>{const e=this.getRow(t),{fromTopBorder:o}=n(this.table,e),{height:r}=e.getBoundingClientRect();return{top:Math.ceil(o+r/2)+"px"}})}setHeadingsSetting(t){this.tunes.withHeadings=t,t?(this.table.classList.add(b),this.addHeadingAttrToFirstRow()):(this.table.classList.remove(b),this.removeHeadingAttrFromFirstRow())}addHeadingAttrToFirstRow(){for(let t=1;t<=this.numberOfColumns;t++){let e=this.getCell(1,t);e&&e.setAttribute("heading",this.api.i18n.t("Heading"))}}removeHeadingAttrFromFirstRow(){for(let t=1;t<=this.numberOfColumns;t++){let e=this.getCell(1,t);e&&e.removeAttribute("heading")}}selectRow(t){const e=this.getRow(t);e&&(this.selectedRow=t,e.classList.add(v))}unselectRow(){if(this.selectedRow<=0)return;const t=this.table.querySelector("."+v);t&&t.classList.remove(v),this.selectedRow=0}selectColumn(t){for(let e=1;e<=this.numberOfRows;e++){const o=this.getCell(e,t);o&&o.classList.add(C)}this.selectedColumn=t}unselectColumn(){if(this.selectedColumn<=0)return;let t=this.table.querySelectorAll("."+C);Array.from(t).forEach(t=>{t.classList.remove(C)}),this.selectedColumn=0}getHoveredCell(t){let e=this.hoveredRow,o=this.hoveredColumn;const{width:r,height:i,x:n,y:s}=function(t,e){const o=t.getBoundingClientRect(),{width:r,height:i,x:n,y:s}=o,{clientX:l,clientY:a}=e;return{width:r,height:i,x:l-n,y:a-s}}(this.table,t);return n>=0&&(o=this.binSearch(this.numberOfColumns,t=>this.getCell(1,t),({fromLeftBorder:t})=>nn>r-t)),s>=0&&(e=this.binSearch(this.numberOfRows,t=>this.getCell(t,1),({fromTopBorder:t})=>ss>i-t)),{row:e||this.hoveredRow,column:o||this.hoveredColumn}}binSearch(t,e,o,r){let i,s=0,l=t+1,a=0;for(;s!t.textContent.trim())||t.push(r.map(t=>t.innerHTML))}return t}destroy(){document.removeEventListener("click",this.documentClicked)}}o(1),e.default=class{static get isReadOnlySupported(){return!0}static get enableLineBreaks(){return!0}constructor({data:t,config:e,api:o,readOnly:r}){this.api=o,this.readOnly=r,this.config=e,this.data={withHeadings:this.getConfig("withHeadings",!1,t),content:t&&t.content?t.content:[]},this.table=null}static get toolbox(){return{icon:'',title:"Table"}}render(){return this.table=new R(this.readOnly,this.api,this.data,this.config),this.container=r("div",this.api.styles.block),this.container.appendChild(this.table.getWrapper()),this.table.setHeadingsSetting(this.data.withHeadings),this.container}renderSettings(){return[{label:this.api.i18n.t("With headings"),icon:'',isActive:this.data.withHeadings,closeOnActivate:!0,toggle:!0,onActivate:()=>{this.data.withHeadings=!0,this.table.setHeadingsSetting(this.data.withHeadings)}},{label:this.api.i18n.t("Without headings"),icon:'',isActive:!this.data.withHeadings,closeOnActivate:!0,toggle:!0,onActivate:()=>{this.data.withHeadings=!1,this.table.setHeadingsSetting(this.data.withHeadings)}}]}save(){const t=this.table.getData();return{withHeadings:this.data.withHeadings,content:t}}destroy(){this.table.destroy()}getConfig(t,e,o){const r=this.data||o;return r?r[t]?r[t]:e:this.config&&this.config[t]?this.config[t]:e}static get pasteConfig(){return{tags:["TABLE","TR","TH","TD"]}}onPaste(t){const e=t.detail.data,o=e.querySelector(":scope > thead, tr:first-of-type th"),r=Array.from(e.querySelectorAll("tr")).map(t=>Array.from(t.querySelectorAll("th, td")).map(t=>t.innerHTML));this.data={withHeadings:null!==o,content:r},this.table.wrapper&&this.table.wrapper.replaceWith(this.render())}}}]).default})); /***/ }), /***/ "./node_modules/@editorjs/underline/dist/bundle.js": /*!*********************************************************!*\ !*** ./node_modules/@editorjs/underline/dist/bundle.js ***! \*********************************************************/ /***/ ((module) => { !function(e,t){ true?module.exports=t():0}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=4)}([function(e,t,n){var r=n(1),o=n(2);"string"==typeof(o=o.__esModule?o.default:o)&&(o=[[e.i,o,""]]);var i={insert:"head",singleton:!1};r(o,i);e.exports=o.locals||{}},function(e,t,n){"use strict";var r,o=function(){return void 0===r&&(r=Boolean(window&&document&&document.all&&!window.atob)),r},i=function(){var e={};return function(t){if(void 0===e[t]){var n=document.querySelector(t);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(e){n=null}e[t]=n}return e[t]}}(),a=[];function u(e){for(var t=-1,n=0;n'}}])&&o(t.prototype,n),r&&o(t,r),Object.defineProperty(t,"prototype",{writable:!1}),e}()}]).default})); /***/ }), /***/ "./resources/js/editor.js": /*!********************************!*\ !*** ./resources/js/editor.js ***! \********************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var _editorjs_editorjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @editorjs/editorjs */ "./node_modules/@editorjs/editorjs/dist/editorjs.mjs"); /* harmony import */ var _editorjs_image__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @editorjs/image */ "./node_modules/@editorjs/image/dist/bundle.js"); /* harmony import */ var _editorjs_image__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_editorjs_image__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var _editorjs_list__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @editorjs/list */ "./node_modules/@editorjs/list/dist/bundle.js"); /* harmony import */ var _editorjs_list__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_editorjs_list__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var _editorjs_header__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @editorjs/header */ "./node_modules/@editorjs/header/dist/bundle.js"); /* harmony import */ var _editorjs_header__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_editorjs_header__WEBPACK_IMPORTED_MODULE_3__); /* harmony import */ var _editorjs_underline__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @editorjs/underline */ "./node_modules/@editorjs/underline/dist/bundle.js"); /* harmony import */ var _editorjs_underline__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_editorjs_underline__WEBPACK_IMPORTED_MODULE_4__); /* harmony import */ var _editorjs_code__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @editorjs/code */ "./node_modules/@editorjs/code/dist/bundle.js"); /* harmony import */ var _editorjs_code__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_editorjs_code__WEBPACK_IMPORTED_MODULE_5__); /* harmony import */ var _editorjs_inline_code__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @editorjs/inline-code */ "./node_modules/@editorjs/inline-code/dist/bundle.js"); /* harmony import */ var _editorjs_inline_code__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_editorjs_inline_code__WEBPACK_IMPORTED_MODULE_6__); /* harmony import */ var _editorjs_quote__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @editorjs/quote */ "./node_modules/@editorjs/quote/dist/bundle.js"); /* harmony import */ var _editorjs_quote__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(_editorjs_quote__WEBPACK_IMPORTED_MODULE_7__); /* harmony import */ var _editorjs_table__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @editorjs/table */ "./node_modules/@editorjs/table/dist/table.js"); /* harmony import */ var _editorjs_table__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(_editorjs_table__WEBPACK_IMPORTED_MODULE_8__); /* harmony import */ var _editorjs_raw__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @editorjs/raw */ "./node_modules/@editorjs/raw/dist/bundle.js"); /* harmony import */ var _editorjs_raw__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(_editorjs_raw__WEBPACK_IMPORTED_MODULE_9__); /* harmony import */ var _editorjs_delimiter__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @editorjs/delimiter */ "./node_modules/@editorjs/delimiter/dist/bundle.js"); /* harmony import */ var _editorjs_delimiter__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(_editorjs_delimiter__WEBPACK_IMPORTED_MODULE_10__); /* harmony import */ var editorjs_style__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! editorjs-style */ "./node_modules/editorjs-style/dist/index.js"); /* harmony import */ var editorjs_style__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(editorjs_style__WEBPACK_IMPORTED_MODULE_11__); /* harmony import */ var editorjs_drag_drop__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! editorjs-drag-drop */ "./node_modules/editorjs-drag-drop/dist/bundle.js"); /* harmony import */ var editorjs_drag_drop__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(editorjs_drag_drop__WEBPACK_IMPORTED_MODULE_12__); function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, defineProperty = Object.defineProperty || function (obj, key, desc) { obj[key] = desc.value; }, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return defineProperty(generator, "_invoke", { value: makeInvokeMethod(innerFn, self, context) }), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; defineProperty(this, "_invoke", { value: function value(method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return { value: void 0, done: !0 }; } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; } function maybeInvokeDelegate(delegate, context) { var methodName = context.method, method = delegate.iterator[methodName]; if (undefined === method) return context.delegate = null, "throw" === methodName && delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method) || "return" !== methodName && (context.method = "throw", context.arg = new TypeError("The iterator does not provide a '" + methodName + "' method")), ContinueSentinel; var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable || "" === iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; return next.value = undefined, next.done = !0, next; }; return next.next = next; } } throw new TypeError(_typeof(iterable) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, defineProperty(Gp, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), defineProperty(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (val) { var object = Object(val), keys = []; for (var key in object) keys.push(key); return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, "catch": function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; } function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } document.addEventListener("alpine:init", function () { Alpine.data("editorjs", function (_ref) { var state = _ref.state, statePath = _ref.statePath, placeholder = _ref.placeholder, readOnly = _ref.readOnly, tools = _ref.tools, minHeight = _ref.minHeight; return { instance: null, state: state, tools: tools, uploadImage: function uploadImage(blob) { var _this = this; return new Promise(function (resolve) { _this.$wire.upload("componentFileAttachments.".concat(statePath), blob, function (uploadedFilename) { _this.$wire.getComponentFileAttachmentUrl(statePath).then(function (url) { if (!url) { return resolve({ success: 0 }); } return resolve({ success: 1, file: { url: url } }); }); }); }); }, init: function init() { var _this2 = this; var enabledTools = {}; if (this.tools.includes("header")) { enabledTools.header = { "class": (_editorjs_header__WEBPACK_IMPORTED_MODULE_3___default()), inlineToolbar: true }; } if (this.tools.includes("image")) { enabledTools.image = { "class": (_editorjs_image__WEBPACK_IMPORTED_MODULE_1___default()), config: { uploader: { uploadByFile: function uploadByFile(file) { return _this2.uploadImage(file); }, uploadByUrl: function uploadByUrl(url) { return new Promise( /*#__PURE__*/function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(resolve) { return _regeneratorRuntime().wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: return _context.abrupt("return", fetch(url).then(function (res) { return res.blob(); }).then(function (blob) { return resolve(_this2.uploadImage(blob)); })); case 1: case "end": return _context.stop(); } }, _callee); })); return function (_x) { return _ref2.apply(this, arguments); }; }()); } } } }; } if (this.tools.includes("delimiter")) enabledTools.delimiter = (_editorjs_delimiter__WEBPACK_IMPORTED_MODULE_10___default()); if (this.tools.includes("list")) { enabledTools.list = { "class": (_editorjs_list__WEBPACK_IMPORTED_MODULE_2___default()), inlineToolbar: true }; } if (this.tools.includes("underline")) enabledTools.underline = (_editorjs_underline__WEBPACK_IMPORTED_MODULE_4___default()); if (this.tools.includes("quote")) { enabledTools.quote = { "class": (_editorjs_quote__WEBPACK_IMPORTED_MODULE_7___default()), inlineToolbar: true }; } if (this.tools.includes("table")) { enabledTools.table = { "class": (_editorjs_table__WEBPACK_IMPORTED_MODULE_8___default()), inlineToolbar: true }; } if (this.tools.includes("raw")) enabledTools.raw = (_editorjs_raw__WEBPACK_IMPORTED_MODULE_9___default()); if (this.tools.includes("code")) enabledTools.code = (_editorjs_code__WEBPACK_IMPORTED_MODULE_5___default()); if (this.tools.includes("inline-code")) enabledTools.inlineCode = (_editorjs_inline_code__WEBPACK_IMPORTED_MODULE_6___default()); if (this.tools.includes("style")) enabledTools.style = editorjs_style__WEBPACK_IMPORTED_MODULE_11__.StyleInlineTool; this.instance = new _editorjs_editorjs__WEBPACK_IMPORTED_MODULE_0__["default"]({ holder: this.$el, minHeight: minHeight, data: this.state, placeholder: placeholder, readOnly: readOnly, tools: enabledTools, onChange: function onChange() { _this2.instance.save().then(function (outputData) { _this2.state = outputData; }); }, onReady: function onReady() { new (editorjs_drag_drop__WEBPACK_IMPORTED_MODULE_12___default())(_this2.instance); } }); } }; }); }); /***/ }), /***/ "./node_modules/editorjs-drag-drop/dist/bundle.js": /*!********************************************************!*\ !*** ./node_modules/editorjs-drag-drop/dist/bundle.js ***! \********************************************************/ /***/ ((module) => { !function(e,t){ true?module.exports=t():0}(self,(function(){return(()=>{var e={424:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>s});var n=r(81),o=r.n(n),i=r(645),a=r.n(i)()(o());a.push([e.id,'.ce-block--drop-target .ce-block__content:before {\n content: "";\n position: absolute;\n top: 50%;\n left: -20px;\n margin-top: -1px;\n height: 8px;\n width: 8px;\n border: solid #a0a0a0;\n border-width: 1px 1px 0 0;\n -webkit-transform-origin: right;\n transform-origin: right;\n -webkit-transform: rotate(45deg);\n transform: rotate(45deg);\n}\n\n.ce-block--drop-target .ce-block__content:after {\n background: none;\n}',""]);const s=a},645:e=>{"use strict";e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var r="",n=void 0!==t[5];return t[4]&&(r+="@supports (".concat(t[4],") {")),t[2]&&(r+="@media ".concat(t[2]," {")),n&&(r+="@layer".concat(t[5].length>0?" ".concat(t[5]):""," {")),r+=e(t),n&&(r+="}"),t[2]&&(r+="}"),t[4]&&(r+="}"),r})).join("")},t.i=function(e,r,n,o,i){"string"==typeof e&&(e=[[null,e,void 0]]);var a={};if(n)for(var s=0;s0?" ".concat(u[5]):""," {").concat(u[1],"}")),u[5]=i),r&&(u[2]?(u[1]="@media ".concat(u[2]," {").concat(u[1],"}"),u[2]=r):u[2]=r),o&&(u[4]?(u[1]="@supports (".concat(u[4],") {").concat(u[1],"}"),u[4]=o):u[4]="".concat(o)),t.push(u))}},t}},81:e=>{"use strict";e.exports=function(e){return e[1]}},406:(e,t,r)=>{var n=r(424);"string"==typeof n&&(n=[[e.id,n,""]]);r(723)(n,{hmr:!0,transform:void 0,insertInto:void 0}),n.locals&&(e.exports=n.locals)},723:(e,t,r)=>{var n,o,i={},a=(n=function(){return window&&document&&document.all&&!window.atob},function(){return void 0===o&&(o=n.apply(this,arguments)),o}),s=function(e){return document.querySelector(e)},c=function(e){var t={};return function(e){if("function"==typeof e)return e();if(void 0===t[e]){var r=s.call(this,e);if(window.HTMLIFrameElement&&r instanceof window.HTMLIFrameElement)try{r=r.contentDocument.head}catch(e){r=null}t[e]=r}return t[e]}}(),l=null,u=0,f=[],d=r(947);function p(e,t){for(var r=0;r=0&&f.splice(t,1)}function y(e){var t=document.createElement("style");return void 0===e.attrs.type&&(e.attrs.type="text/css"),g(t,e.attrs),v(e,t),t}function g(e,t){Object.keys(t).forEach((function(r){e.setAttribute(r,t[r])}))}function m(e,t){var r,n,o,i;if(t.transform&&e.css){if(!(i=t.transform(e.css)))return function(){};e.css=i}if(t.singleton){var a=u++;r=l||(l=y(t)),n=x.bind(null,r,a,!1),o=x.bind(null,r,a,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(r=function(e){var t=document.createElement("link");return void 0===e.attrs.type&&(e.attrs.type="text/css"),e.attrs.rel="stylesheet",g(t,e.attrs),v(e,t),t}(t),n=O.bind(null,r,t),o=function(){b(r),r.href&&URL.revokeObjectURL(r.href)}):(r=y(t),n=B.bind(null,r),o=function(){b(r)});return n(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;n(e=t)}else o()}}e.exports=function(e,t){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(t=t||{}).attrs="object"==typeof t.attrs?t.attrs:{},t.singleton||"boolean"==typeof t.singleton||(t.singleton=a()),t.insertInto||(t.insertInto="head"),t.insertAt||(t.insertAt="bottom");var r=h(e,t);return p(r,t),function(e){for(var n=[],o=0;o{e.exports=function(e){var t="undefined"!=typeof window&&window.location;if(!t)throw new Error("fixUrls requires window.location");if(!e||"string"!=typeof e)return e;var r=t.protocol+"//"+t.host,n=r+t.pathname.replace(/\/[^\/]*$/,"/");return e.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi,(function(e,t){var o,i=t.trim().replace(/^"(.*)"$/,(function(e,t){return t})).replace(/^'(.*)'$/,(function(e,t){return t}));return/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/|\s*$)/i.test(i)?e:(o=0===i.indexOf("//")?i:0===i.indexOf("/")?r+i:n+i.replace(/^\.\//,""),"url("+JSON.stringify(o)+")")}))}}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var i=t[n]={id:n,exports:{}};return e[n](i,i.exports,r),i.exports}r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var n={};return(()=>{"use strict";function e(e,t){for(var r=0;rt}),r(406);var t=function(){function t(e,r){var n=e.configuration,o=e.blocks,i=e.toolbar,a=e.save;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),this.toolbar=i,this.borderStyle=r||"1px dashed #aaa",this.api=o,this.holder="string"==typeof n.holder?document.getElementById(n.holder):n.holder,this.readOnly=n.readOnly,this.startBlock=null,this.endBlock=null,this.save=a,this.setDragListener(),this.setDropListener()}var r,n,o;return r=t,o=[{key:"isReadOnlySupported",get:function(){return!0}}],(n=[{key:"setElementCursor",value:function(e){if(e){var t=document.createRange(),r=window.getSelection();t.setStart(e.childNodes[0],0),t.collapse(!0),r.removeAllRanges(),r.addRange(t),e.focus()}}},{key:"setDragListener",value:function(){var e=this;if(!this.readOnly){var t=this.holder.querySelector(".ce-toolbar__settings-btn");t.setAttribute("draggable","true"),t.addEventListener("dragstart",(function(){e.startBlock=e.api.getCurrentBlockIndex()})),t.addEventListener("drag",(function(){if(e.toolbar.close(),!e.isTheOnlyBlock()){var t=e.holder.querySelectorAll(".ce-block"),r=e.holder.querySelector(".ce-block--drop-target");e.setElementCursor(r),e.setBorderBlocks(t,r)}}))}}},{key:"setBorderBlocks",value:function(e,t){var r=this;Object.values(e).forEach((function(n){var o=n.querySelector(".ce-block__content");n!==t?(o.style.removeProperty("border-top"),o.style.removeProperty("border-bottom")):Object.keys(e).find((function(r){return e[r]===t}))>r.startBlock?o.style.borderBottom=r.borderStyle||borderStyle:o.style.borderTop=r.borderStyle}))}},{key:"setDropListener",value:function(){var e=this;document.addEventListener("drop",(function(t){var r=t.target;if(e.holder.contains(r)&&null!==e.startBlock){var n=e.getDropTarget(r);if(n){var o=n.querySelector(".ce-block__content");o.style.removeProperty("border-top"),o.style.removeProperty("border-bottom"),e.endBlock=e.getTargetPosition(n),e.moveBlocks()}}e.startBlock=null}))}},{key:"getDropTarget",value:function(e){return e.classList.contains("ce-block")?e:e.closest(".ce-block")}},{key:"getTargetPosition",value:function(e){return Array.from(e.parentNode.children).indexOf(e)}},{key:"isTheOnlyBlock",value:function(){return 1===this.api.getBlocksCount()}},{key:"moveBlocks",value:function(){this.isTheOnlyBlock()||this.api.move(this.endBlock,this.startBlock)}}])&&e(r.prototype,n),o&&e(r,o),Object.defineProperty(r,"prototype",{writable:!1}),t}()})(),n.default})()})); /***/ }), /***/ "./node_modules/editorjs-style/dist/index.js": /*!***************************************************!*\ !*** ./node_modules/editorjs-style/dist/index.js ***! \***************************************************/ /***/ ((module) => { !function(e,t){ true?module.exports=t():0}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";n.r(t),n.d(t,"StyleInlineTool",(function(){return c}));class r extends HTMLElement{}class i extends Error{constructor(...e){super(...e),this.name="EditorJSStyleError"}}var s,o,l=function(e,t,n,r,i){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!i)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!i:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?i.call(e,n):i?i.value=n:t.set(e,n),n},a=function(e,t,n,r){if("a"===n&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===n?r:"a"===n?r.call(e):r?r.value:t.get(e)};class c{constructor({api:e}){s.set(this,void 0),o.set(this,void 0),l(this,s,document.createElement("div"),"f"),l(this,o,e,"f")}static get isInline(){return!0}static get sanitize(){return{"editorjs-style":{class:!0,id:!0,style:!0}}}static get title(){return"Style"}static prepare(){customElements.get("editorjs-style")||customElements.define("editorjs-style",r)}get shortcut(){return"CMD+S"}checkState(){var e;a(this,s,"f").innerHTML="";const t=a(this,o,"f").selection.findParentTag("EDITORJS-STYLE");if(!t)return!1;a(this,s,"f").innerHTML=`\n
\n
\n
Style settings
\n\n \n
\n\n \n\n \n\n \n
\n `;const n=a(this,s,"f").querySelector(".delete-button"),r=a(this,s,"f").querySelector(".class-input"),l=a(this,s,"f").querySelector(".id-input"),c=a(this,s,"f").querySelector(".style-textarea");if(!(n&&r&&l&&c))throw new i;return n.addEventListener("click",()=>{const e=Array.from(t.childNodes).map(e=>e.cloneNode(!0));if(e.forEach(e=>{var n;return null===(n=t.parentNode)||void 0===n?void 0:n.insertBefore(e,t)}),t.remove(),0===e.length)return;const n=window.getSelection();if(!n)throw new i;n.removeAllRanges();const r=new Range;r.setStartBefore(e[0]),r.setEndAfter(e[e.length-1]),n.addRange(r),a(this,s,"f").innerHTML="",a(this,o,"f").tooltip.hide()}),a(this,o,"f").tooltip.onHover(n,"Delete style",{placement:"top"}),r.value=t.className,r.addEventListener("input",()=>t.setAttribute("class",r.value)),l.value=t.id,l.addEventListener("input",()=>t.id=l.value),c.value=null!==(e=t.getAttribute("style"))&&void 0!==e?e:"",c.addEventListener("keydown",e=>e.stopPropagation()),c.addEventListener("input",()=>t.setAttribute("style",c.value)),!0}clear(){a(this,s,"f").innerHTML=""}render(){const e=document.createElement("button");return e.classList.add(a(this,o,"f").styles.inlineToolButton),e.type="button",e.innerHTML='\n \n \n \n \n ',e}renderActions(){return a(this,s,"f")}surround(e){const t=new r;e.surroundContents(t),a(this,o,"f").selection.expandToTag(t)}}s=new WeakMap,o=new WeakMap}])})); /***/ }), /***/ "./resources/css/editor.css": /*!**********************************!*\ !*** ./resources/css/editor.css ***! \**********************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); // extracted by mini-css-extract-plugin /***/ }), /***/ "./node_modules/@editorjs/editorjs/dist/editorjs.mjs": /*!***********************************************************!*\ !*** ./node_modules/@editorjs/editorjs/dist/editorjs.mjs ***! \***********************************************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ fi) /* harmony export */ }); var Lt = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}; function xe(s) { return s && s.__esModule && Object.prototype.hasOwnProperty.call(s, "default") ? s.default : s; } function Be() { } Object.assign(Be, { default: Be, register: Be, revert: function() { }, __esModule: !0 }); Element.prototype.matches || (Element.prototype.matches = Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector || function(s) { const e = (this.document || this.ownerDocument).querySelectorAll(s); let t = e.length; for (; --t >= 0 && e.item(t) !== this; ) ; return t > -1; }); Element.prototype.closest || (Element.prototype.closest = function(s) { let e = this; if (!document.documentElement.contains(e)) return null; do { if (e.matches(s)) return e; e = e.parentElement || e.parentNode; } while (e !== null); return null; }); Element.prototype.prepend || (Element.prototype.prepend = function(e) { const t = document.createDocumentFragment(); Array.isArray(e) || (e = [e]), e.forEach((o) => { const i = o instanceof Node; t.appendChild(i ? o : document.createTextNode(o)); }), this.insertBefore(t, this.firstChild); }); Element.prototype.scrollIntoViewIfNeeded || (Element.prototype.scrollIntoViewIfNeeded = function(s) { s = arguments.length === 0 ? !0 : !!s; const e = this.parentNode, t = window.getComputedStyle(e, null), o = parseInt(t.getPropertyValue("border-top-width")), i = parseInt(t.getPropertyValue("border-left-width")), n = this.offsetTop - e.offsetTop < e.scrollTop, r = this.offsetTop - e.offsetTop + this.clientHeight - o > e.scrollTop + e.clientHeight, a = this.offsetLeft - e.offsetLeft < e.scrollLeft, l = this.offsetLeft - e.offsetLeft + this.clientWidth - i > e.scrollLeft + e.clientWidth, c = n && !r; (n || r) && s && (e.scrollTop = this.offsetTop - e.offsetTop - e.clientHeight / 2 - o + this.clientHeight / 2), (a || l) && s && (e.scrollLeft = this.offsetLeft - e.offsetLeft - e.clientWidth / 2 - i + this.clientWidth / 2), (n || r || a || l) && !s && this.scrollIntoView(c); }); let Ot = (s = 21) => crypto.getRandomValues(new Uint8Array(s)).reduce((e, t) => (t &= 63, t < 36 ? e += t.toString(36) : t < 62 ? e += (t - 26).toString(36).toUpperCase() : t > 62 ? e += "-" : e += "_", e), ""); var et = /* @__PURE__ */ ((s) => (s.VERBOSE = "VERBOSE", s.INFO = "INFO", s.WARN = "WARN", s.ERROR = "ERROR", s))(et || {}); const B = { BACKSPACE: 8, TAB: 9, ENTER: 13, SHIFT: 16, CTRL: 17, ALT: 18, ESC: 27, SPACE: 32, LEFT: 37, UP: 38, DOWN: 40, RIGHT: 39, DELETE: 46, META: 91 }, _t = { LEFT: 0, WHEEL: 1, RIGHT: 2, BACKWARD: 3, FORWARD: 4 }; function ge(s, e, t = "log", o, i = "color: inherit") { if (!("console" in window) || !window.console[t]) return; const n = ["info", "log", "warn", "error"].includes(t), r = []; switch (ge.logLevel) { case "ERROR": if (t !== "error") return; break; case "WARN": if (!["error", "warn"].includes(t)) return; break; case "INFO": if (!n || s) return; break; } o && r.push(o); const a = "Editor.js 2.27.2", l = `line-height: 1em; color: #006FEA; display: inline-block; font-size: 11px; line-height: 1em; background-color: #fff; padding: 4px 9px; border-radius: 30px; border: 1px solid rgba(56, 138, 229, 0.16); margin: 4px 5px 4px 0;`; s && (n ? (r.unshift(l, i), e = `%c${a}%c ${e}`) : e = `( ${a} )${e}`); try { n ? o ? console[t](`${e} %o`, ...r) : console[t](e, ...r) : console[t](e); } catch { } } ge.logLevel = "VERBOSE"; function At(s) { ge.logLevel = s; } const T = ge.bind(window, !1), K = ge.bind(window, !0); function te(s) { return Object.prototype.toString.call(s).match(/\s([a-zA-Z]+)/)[1].toLowerCase(); } function D(s) { return te(s) === "function" || te(s) === "asyncfunction"; } function j(s) { return te(s) === "object"; } function J(s) { return te(s) === "string"; } function Nt(s) { return te(s) === "boolean"; } function Ve(s) { return te(s) === "number"; } function Ze(s) { return te(s) === "undefined"; } function V(s) { return s ? Object.keys(s).length === 0 && s.constructor === Object : !0; } function tt(s) { return s > 47 && s < 58 || // number keys s === 32 || s === 13 || // Space bar & return key(s) s === 229 || // processing key input for certain languages — Chinese, Japanese, etc. s > 64 && s < 91 || // letter keys s > 95 && s < 112 || // Numpad keys s > 185 && s < 193 || // ;=,-./` (in order) s > 218 && s < 223; } async function ot(s, e = () => { }, t = () => { }) { async function o(i, n, r) { try { await i.function(i.data), await n(Ze(i.data) ? {} : i.data); } catch { r(Ze(i.data) ? {} : i.data); } } return s.reduce(async (i, n) => (await i, o(n, e, t)), Promise.resolve()); } function it(s) { return Array.prototype.slice.call(s); } function oe(s, e) { return function() { const t = this, o = arguments; window.setTimeout(() => s.apply(t, o), e); }; } function Rt(s) { return s.name.split(".").pop(); } function Dt(s) { return /^[-\w]+\/([-+\w]+|\*)$/.test(s); } function Pt(s, e, t) { let o; return (...i) => { const n = this, r = () => { o = null, t || s.apply(n, i); }, a = t && !o; window.clearTimeout(o), o = window.setTimeout(r, e), a && s.apply(n, i); }; } function Te(s, e, t = void 0) { let o, i, n, r = null, a = 0; t || (t = {}); const l = function() { a = t.leading === !1 ? 0 : Date.now(), r = null, n = s.apply(o, i), r || (o = i = null); }; return function() { const c = Date.now(); !a && t.leading === !1 && (a = c); const u = e - (c - a); return o = this, i = arguments, u <= 0 || u > e ? (r && (clearTimeout(r), r = null), a = c, n = s.apply(o, i), r || (o = i = null)) : !r && t.trailing !== !1 && (r = setTimeout(l, u)), n; }; } function Ft() { const s = { win: !1, mac: !1, x11: !1, linux: !1 }, e = Object.keys(s).find((t) => window.navigator.appVersion.toLowerCase().indexOf(t) !== -1); return e && (s[e] = !0), s; } function ke(s) { return s[0].toUpperCase() + s.slice(1); } function Se(s, ...e) { if (!e.length) return s; const t = e.shift(); if (j(s) && j(t)) for (const o in t) j(t[o]) ? (s[o] || Object.assign(s, { [o]: {} }), Se(s[o], t[o])) : Object.assign(s, { [o]: t[o] }); return Se(s, ...e); } function nt(s) { const e = Ft(); return s = s.replace(/shift/gi, "⇧").replace(/backspace/gi, "⌫").replace(/enter/gi, "⏎").replace(/up/gi, "↑").replace(/left/gi, "→").replace(/down/gi, "↓").replace(/right/gi, "←").replace(/escape/gi, "⎋").replace(/insert/gi, "Ins").replace(/delete/gi, "␡").replace(/\+/gi, " + "), e.mac ? s = s.replace(/ctrl|cmd/gi, "⌘").replace(/alt/gi, "⌥") : s = s.replace(/cmd/gi, "Ctrl").replace(/windows/gi, "WIN"), s; } function Ht(s) { try { return new URL(s).href; } catch { } return s.substring(0, 2) === "//" ? window.location.protocol + s : window.location.origin + s; } function zt() { return Ot(10); } function jt(s) { window.open(s, "_blank"); } function Ut(s = "") { return `${s}${Math.floor(Math.random() * 1e8).toString(16)}`; } function Ie(s, e, t) { const o = `«${e}» is deprecated and will be removed in the next major release. Please use the «${t}» instead.`; s && K(o, "warn"); } function ae(s, e, t) { const o = t.value ? "value" : "get", i = t[o], n = `#${e}Cache`; if (t[o] = function(...r) { return this[n] === void 0 && (this[n] = i.apply(this, ...r)), this[n]; }, o === "get" && t.set) { const r = t.set; t.set = function(a) { delete s[n], r.apply(this, a); }; } return t; } const st = 650; function ee() { return window.matchMedia(`(max-width: ${st}px)`).matches; } const Ge = typeof window < "u" && window.navigator && window.navigator.platform && (/iP(ad|hone|od)/.test(window.navigator.platform) || window.navigator.platform === "MacIntel" && window.navigator.maxTouchPoints > 1); function $t(s, e) { const t = Array.isArray(s) || j(s), o = Array.isArray(e) || j(e); return t || o ? JSON.stringify(s) === JSON.stringify(e) : s === e; } class d { /** * Check if passed tag has no closed tag * * @param {HTMLElement} tag - element to check * @returns {boolean} */ static isSingleTag(e) { return e.tagName && [ "AREA", "BASE", "BR", "COL", "COMMAND", "EMBED", "HR", "IMG", "INPUT", "KEYGEN", "LINK", "META", "PARAM", "SOURCE", "TRACK", "WBR" ].includes(e.tagName); } /** * Check if element is BR or WBR * * @param {HTMLElement} element - element to check * @returns {boolean} */ static isLineBreakTag(e) { return e && e.tagName && [ "BR", "WBR" ].includes(e.tagName); } /** * Helper for making Elements with class name and attributes * * @param {string} tagName - new Element tag name * @param {string[]|string} [classNames] - list or name of CSS class name(s) * @param {object} [attributes] - any attributes * @returns {HTMLElement} */ static make(e, t = null, o = {}) { const i = document.createElement(e); Array.isArray(t) ? i.classList.add(...t) : t && i.classList.add(t); for (const n in o) Object.prototype.hasOwnProperty.call(o, n) && (i[n] = o[n]); return i; } /** * Creates Text Node with the passed content * * @param {string} content - text content * @returns {Text} */ static text(e) { return document.createTextNode(e); } /** * Append one or several elements to the parent * * @param {Element|DocumentFragment} parent - where to append * @param {Element|Element[]|DocumentFragment|Text|Text[]} elements - element or elements list */ static append(e, t) { Array.isArray(t) ? t.forEach((o) => e.appendChild(o)) : e.appendChild(t); } /** * Append element or a couple to the beginning of the parent elements * * @param {Element} parent - where to append * @param {Element|Element[]} elements - element or elements list */ static prepend(e, t) { Array.isArray(t) ? (t = t.reverse(), t.forEach((o) => e.prepend(o))) : e.prepend(t); } /** * Swap two elements in parent * * @param {HTMLElement} el1 - from * @param {HTMLElement} el2 - to * @deprecated */ static swap(e, t) { const o = document.createElement("div"), i = e.parentNode; i.insertBefore(o, e), i.insertBefore(e, t), i.insertBefore(t, o), i.removeChild(o); } /** * Selector Decorator * * Returns first match * * @param {Element} el - element we searching inside. Default - DOM Document * @param {string} selector - searching string * @returns {Element} */ static find(e = document, t) { return e.querySelector(t); } /** * Get Element by Id * * @param {string} id - id to find * @returns {HTMLElement | null} */ static get(e) { return document.getElementById(e); } /** * Selector Decorator. * * Returns all matches * * @param {Element|Document} el - element we searching inside. Default - DOM Document * @param {string} selector - searching string * @returns {NodeList} */ static findAll(e = document, t) { return e.querySelectorAll(t); } /** * Returns CSS selector for all text inputs */ static get allInputsSelector() { return "[contenteditable=true], textarea, input:not([type]), " + ["text", "password", "email", "number", "search", "tel", "url"].map((t) => `input[type="${t}"]`).join(", "); } /** * Find all contenteditable, textarea and editable input elements passed holder contains * * @param holder - element where to find inputs */ static findAllInputs(e) { return it(e.querySelectorAll(d.allInputsSelector)).reduce((t, o) => d.isNativeInput(o) || d.containsOnlyInlineElements(o) ? [...t, o] : [...t, ...d.getDeepestBlockElements(o)], []); } /** * Search for deepest node which is Leaf. * Leaf is the vertex that doesn't have any child nodes * * @description Method recursively goes throw the all Node until it finds the Leaf * @param {Node} node - root Node. From this vertex we start Deep-first search * {@link https://en.wikipedia.org/wiki/Depth-first_search} * @param {boolean} [atLast] - find last text node * @returns {Node} - it can be text Node or Element Node, so that caret will able to work with it */ static getDeepestNode(e, t = !1) { const o = t ? "lastChild" : "firstChild", i = t ? "previousSibling" : "nextSibling"; if (e && e.nodeType === Node.ELEMENT_NODE && e[o]) { let n = e[o]; if (d.isSingleTag(n) && !d.isNativeInput(n) && !d.isLineBreakTag(n)) if (n[i]) n = n[i]; else if (n.parentNode[i]) n = n.parentNode[i]; else return n.parentNode; return this.getDeepestNode(n, t); } return e; } /** * Check if object is DOM node * * @param {*} node - object to check * @returns {boolean} */ // eslint-disable-next-line @typescript-eslint/no-explicit-any static isElement(e) { return Ve(e) ? !1 : e && e.nodeType && e.nodeType === Node.ELEMENT_NODE; } /** * Check if object is DocumentFragment node * * @param {object} node - object to check * @returns {boolean} */ // eslint-disable-next-line @typescript-eslint/no-explicit-any static isFragment(e) { return Ve(e) ? !1 : e && e.nodeType && e.nodeType === Node.DOCUMENT_FRAGMENT_NODE; } /** * Check if passed element is contenteditable * * @param {HTMLElement} element - html element to check * @returns {boolean} */ static isContentEditable(e) { return e.contentEditable === "true"; } /** * Checks target if it is native input * * @param {*} target - HTML element or string * @returns {boolean} */ // eslint-disable-next-line @typescript-eslint/no-explicit-any static isNativeInput(e) { const t = [ "INPUT", "TEXTAREA" ]; return e && e.tagName ? t.includes(e.tagName) : !1; } /** * Checks if we can set caret * * @param {HTMLElement} target - target to check * @returns {boolean} */ static canSetCaret(e) { let t = !0; if (d.isNativeInput(e)) switch (e.type) { case "file": case "checkbox": case "radio": case "hidden": case "submit": case "button": case "image": case "reset": t = !1; break; } else t = d.isContentEditable(e); return t; } /** * Checks node if it is empty * * @description Method checks simple Node without any childs for emptiness * If you have Node with 2 or more children id depth, you better use {@link Dom#isEmpty} method * @param {Node} node - node to check * @returns {boolean} true if it is empty */ static isNodeEmpty(e) { let t; return this.isSingleTag(e) && !this.isLineBreakTag(e) ? !1 : (this.isElement(e) && this.isNativeInput(e) ? t = e.value : t = e.textContent.replace("​", ""), t.trim().length === 0); } /** * checks node if it is doesn't have any child nodes * * @param {Node} node - node to check * @returns {boolean} */ static isLeaf(e) { return e ? e.childNodes.length === 0 : !1; } /** * breadth-first search (BFS) * {@link https://en.wikipedia.org/wiki/Breadth-first_search} * * @description Pushes to stack all DOM leafs and checks for emptiness * @param {Node} node - node to check * @returns {boolean} */ static isEmpty(e) { e.normalize(); const t = [e]; for (; t.length > 0; ) if (e = t.shift(), !!e) { if (this.isLeaf(e) && !this.isNodeEmpty(e)) return !1; e.childNodes && t.push(...Array.from(e.childNodes)); } return !0; } /** * Check if string contains html elements * * @param {string} str - string to check * @returns {boolean} */ static isHTMLString(e) { const t = d.make("div"); return t.innerHTML = e, t.childElementCount > 0; } /** * Return length of node`s text content * * @param {Node} node - node with content * @returns {number} */ static getContentLength(e) { return d.isNativeInput(e) ? e.value.length : e.nodeType === Node.TEXT_NODE ? e.length : e.textContent.length; } /** * Return array of names of block html elements * * @returns {string[]} */ static get blockElements() { return [ "address", "article", "aside", "blockquote", "canvas", "div", "dl", "dt", "fieldset", "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "header", "hgroup", "hr", "li", "main", "nav", "noscript", "ol", "output", "p", "pre", "ruby", "section", "table", "tbody", "thead", "tr", "tfoot", "ul", "video" ]; } /** * Check if passed content includes only inline elements * * @param {string|HTMLElement} data - element or html string * @returns {boolean} */ static containsOnlyInlineElements(e) { let t; J(e) ? (t = document.createElement("div"), t.innerHTML = e) : t = e; const o = (i) => !d.blockElements.includes(i.tagName.toLowerCase()) && Array.from(i.children).every(o); return Array.from(t.children).every(o); } /** * Find and return all block elements in the passed parent (including subtree) * * @param {HTMLElement} parent - root element * @returns {HTMLElement[]} */ static getDeepestBlockElements(e) { return d.containsOnlyInlineElements(e) ? [e] : Array.from(e.children).reduce((t, o) => [...t, ...d.getDeepestBlockElements(o)], []); } /** * Helper for get holder from {string} or return HTMLElement * * @param {string | HTMLElement} element - holder's id or holder's HTML Element * @returns {HTMLElement} */ static getHolder(e) { return J(e) ? document.getElementById(e) : e; } /** * Returns true if element is anchor (is A tag) * * @param {Element} element - element to check * @returns {boolean} */ static isAnchor(e) { return e.tagName.toLowerCase() === "a"; } /** * Return element's offset related to the document * * @todo handle case when editor initialized in scrollable popup * @param el - element to compute offset */ static offset(e) { const t = e.getBoundingClientRect(), o = window.pageXOffset || document.documentElement.scrollLeft, i = window.pageYOffset || document.documentElement.scrollTop, n = t.top + i, r = t.left + o; return { top: n, left: r, bottom: n + t.height, right: r + t.width }; } } const Wt = { blockTunes: { toggler: { "Click to tune": "", "or drag to move": "" } }, inlineToolbar: { converter: { "Convert to": "" } }, toolbar: { toolbox: { Add: "" } }, popover: { Filter: "", "Nothing found": "" } }, Yt = { Text: "", Link: "", Bold: "", Italic: "" }, Kt = { link: { "Add a link": "" }, stub: { "The block can not be displayed correctly.": "" } }, Xt = { delete: { Delete: "", "Click to delete": "" }, moveUp: { "Move up": "" }, moveDown: { "Move down": "" } }, rt = { ui: Wt, toolNames: Yt, tools: Kt, blockTunes: Xt }, ie = class { /** * Type-safe translation for internal UI texts: * Perform translation of the string by namespace and a key * * @example I18n.ui(I18nInternalNS.ui.blockTunes.toggler, 'Click to tune') * @param internalNamespace - path to translated string in dictionary * @param dictKey - dictionary key. Better to use default locale original text */ static ui(s, e) { return ie._t(s, e); } /** * Translate for external strings that is not presented in default dictionary. * For example, for user-specified tool names * * @param namespace - path to translated string in dictionary * @param dictKey - dictionary key. Better to use default locale original text */ static t(s, e) { return ie._t(s, e); } /** * Adjust module for using external dictionary * * @param dictionary - new messages list to override default */ static setDictionary(s) { ie.currentDictionary = s; } /** * Perform translation both for internal and external namespaces * If there is no translation found, returns passed key as a translated message * * @param namespace - path to translated string in dictionary * @param dictKey - dictionary key. Better to use default locale original text */ static _t(s, e) { const t = ie.getNamespace(s); return !t || !t[e] ? e : t[e]; } /** * Find messages section by namespace path * * @param namespace - path to section */ static getNamespace(s) { return s.split(".").reduce((t, o) => !t || !Object.keys(t).length ? {} : t[o], ie.currentDictionary); } }; let $ = ie; $.currentDictionary = rt; class at extends Error { } class we { constructor() { this.subscribers = {}; } /** * Subscribe any event on callback * * @param eventName - event name * @param callback - subscriber */ on(e, t) { e in this.subscribers || (this.subscribers[e] = []), this.subscribers[e].push(t); } /** * Subscribe any event on callback. Callback will be called once and be removed from subscribers array after call. * * @param eventName - event name * @param callback - subscriber */ once(e, t) { e in this.subscribers || (this.subscribers[e] = []); const o = (i) => { const n = t(i), r = this.subscribers[e].indexOf(o); return r !== -1 && this.subscribers[e].splice(r, 1), n; }; this.subscribers[e].push(o); } /** * Emit callbacks with passed data * * @param eventName - event name * @param data - subscribers get this data when they were fired */ emit(e, t) { V(this.subscribers) || !this.subscribers[e] || this.subscribers[e].reduce((o, i) => { const n = i(o); return n !== void 0 ? n : o; }, t); } /** * Unsubscribe callback from event * * @param eventName - event name * @param callback - event handler */ off(e, t) { for (let o = 0; o < this.subscribers[e].length; o++) if (this.subscribers[e][o] === t) { delete this.subscribers[e][o]; break; } } /** * Destroyer * clears subscribers list */ destroy() { this.subscribers = null; } } function he(s) { Object.setPrototypeOf(this, { /** * Block id * * @returns {string} */ get id() { return s.id; }, /** * Tool name * * @returns {string} */ get name() { return s.name; }, /** * Tool config passed on Editor's initialization * * @returns {ToolConfig} */ get config() { return s.config; }, /** * .ce-block element, that wraps plugin contents * * @returns {HTMLElement} */ get holder() { return s.holder; }, /** * True if Block content is empty * * @returns {boolean} */ get isEmpty() { return s.isEmpty; }, /** * True if Block is selected with Cross-Block selection * * @returns {boolean} */ get selected() { return s.selected; }, /** * Set Block's stretch state * * @param {boolean} state — state to set */ set stretched(t) { s.stretched = t; }, /** * True if Block is stretched * * @returns {boolean} */ get stretched() { return s.stretched; }, /** * Call Tool method with errors handler under-the-hood * * @param {string} methodName - method to call * @param {object} param - object with parameters * @returns {unknown} */ call(t, o) { return s.call(t, o); }, /** * Save Block content * * @returns {Promise} */ save() { return s.save(); }, /** * Validate Block data * * @param {BlockToolData} data - data to validate * @returns {Promise} */ validate(t) { return s.validate(t); }, /** * Allows to say Editor that Block was changed. Used to manually trigger Editor's 'onChange' callback * Can be useful for block changes invisible for editor core. */ dispatchChange() { s.dispatchChange(); } }); } class Re { constructor() { this.allListeners = []; } /** * Assigns event listener on element and returns unique identifier * * @param {EventTarget} element - DOM element that needs to be listened * @param {string} eventType - event type * @param {Function} handler - method that will be fired on event * @param {boolean|AddEventListenerOptions} options - useCapture or {capture, passive, once} */ on(e, t, o, i = !1) { const n = Ut("l"), r = { id: n, element: e, eventType: t, handler: o, options: i }; if (!this.findOne(e, t, o)) return this.allListeners.push(r), e.addEventListener(t, o, i), n; } /** * Removes event listener from element * * @param {EventTarget} element - DOM element that we removing listener * @param {string} eventType - event type * @param {Function} handler - remove handler, if element listens several handlers on the same event type * @param {boolean|AddEventListenerOptions} options - useCapture or {capture, passive, once} */ off(e, t, o, i) { const n = this.findAll(e, t, o); n.forEach((r, a) => { const l = this.allListeners.indexOf(n[a]); l > -1 && (this.allListeners.splice(l, 1), r.element.removeEventListener(r.eventType, r.handler, r.options)); }); } /** * Removes listener by id * * @param {string} id - listener identifier */ offById(e) { const t = this.findById(e); t && t.element.removeEventListener(t.eventType, t.handler, t.options); } /** * Finds and returns first listener by passed params * * @param {EventTarget} element - event target * @param {string} [eventType] - event type * @param {Function} [handler] - event handler * @returns {ListenerData|null} */ findOne(e, t, o) { const i = this.findAll(e, t, o); return i.length > 0 ? i[0] : null; } /** * Return all stored listeners by passed params * * @param {EventTarget} element - event target * @param {string} eventType - event type * @param {Function} handler - event handler * @returns {ListenerData[]} */ findAll(e, t, o) { let i; const n = e ? this.findByEventTarget(e) : []; return e && t && o ? i = n.filter((r) => r.eventType === t && r.handler === o) : e && t ? i = n.filter((r) => r.eventType === t) : i = n, i; } /** * Removes all listeners */ removeAll() { this.allListeners.map((e) => { e.element.removeEventListener(e.eventType, e.handler, e.options); }), this.allListeners = []; } /** * Module cleanup on destruction */ destroy() { this.removeAll(); } /** * Search method: looks for listener by passed element * * @param {EventTarget} element - searching element * @returns {Array} listeners that found on element */ findByEventTarget(e) { return this.allListeners.filter((t) => { if (t.element === e) return t; }); } /** * Search method: looks for listener by passed event type * * @param {string} eventType - event type * @returns {ListenerData[]} listeners that found on element */ findByType(e) { return this.allListeners.filter((t) => { if (t.eventType === e) return t; }); } /** * Search method: looks for listener by passed handler * * @param {Function} handler - event handler * @returns {ListenerData[]} listeners that found on element */ findByHandler(e) { return this.allListeners.filter((t) => { if (t.handler === e) return t; }); } /** * Returns listener data found by id * * @param {string} id - listener identifier * @returns {ListenerData} */ findById(e) { return this.allListeners.find((t) => t.id === e); } } class S { /** * @class * @param options - Module options * @param options.config - Module config * @param options.eventsDispatcher - Common event bus */ constructor({ config: e, eventsDispatcher: t }) { if (this.nodes = {}, this.listeners = new Re(), this.readOnlyMutableListeners = { /** * Assigns event listener on DOM element and pushes into special array that might be removed * * @param {EventTarget} element - DOM Element * @param {string} eventType - Event name * @param {Function} handler - Event handler * @param {boolean|AddEventListenerOptions} options - Listening options */ on: (o, i, n, r = !1) => { this.mutableListenerIds.push( this.listeners.on(o, i, n, r) ); }, /** * Clears all mutable listeners */ clearAll: () => { for (const o of this.mutableListenerIds) this.listeners.offById(o); this.mutableListenerIds = []; } }, this.mutableListenerIds = [], new.target === S) throw new TypeError("Constructors for abstract class Module are not allowed."); this.config = e, this.eventsDispatcher = t; } /** * Editor modules setter * * @param {EditorModules} Editor - Editor's Modules */ set state(e) { this.Editor = e; } /** * Remove memorized nodes */ removeAllNodes() { for (const e in this.nodes) { const t = this.nodes[e]; t instanceof HTMLElement && t.remove(); } } /** * Returns true if current direction is RTL (Right-To-Left) */ get isRtl() { return this.config.i18n.direction === "rtl"; } } class m { constructor() { this.instance = null, this.selection = null, this.savedSelectionRange = null, this.isFakeBackgroundEnabled = !1, this.commandBackground = "backColor", this.commandRemoveFormat = "removeFormat"; } /** * Editor styles * * @returns {{editorWrapper: string, editorZone: string}} */ static get CSS() { return { editorWrapper: "codex-editor", editorZone: "codex-editor__redactor" }; } /** * Returns selected anchor * {@link https://developer.mozilla.org/ru/docs/Web/API/Selection/anchorNode} * * @returns {Node|null} */ static get anchorNode() { const e = window.getSelection(); return e ? e.anchorNode : null; } /** * Returns selected anchor element * * @returns {Element|null} */ static get anchorElement() { const e = window.getSelection(); if (!e) return null; const t = e.anchorNode; return t ? d.isElement(t) ? t : t.parentElement : null; } /** * Returns selection offset according to the anchor node * {@link https://developer.mozilla.org/ru/docs/Web/API/Selection/anchorOffset} * * @returns {number|null} */ static get anchorOffset() { const e = window.getSelection(); return e ? e.anchorOffset : null; } /** * Is current selection range collapsed * * @returns {boolean|null} */ static get isCollapsed() { const e = window.getSelection(); return e ? e.isCollapsed : null; } /** * Check current selection if it is at Editor's zone * * @returns {boolean} */ static get isAtEditor() { return this.isSelectionAtEditor(m.get()); } /** * Check if passed selection is at Editor's zone * * @param selection - Selection object to check */ static isSelectionAtEditor(e) { if (!e) return !1; let t = e.anchorNode || e.focusNode; t && t.nodeType === Node.TEXT_NODE && (t = t.parentNode); let o = null; return t && t instanceof Element && (o = t.closest(`.${m.CSS.editorZone}`)), o ? o.nodeType === Node.ELEMENT_NODE : !1; } /** * Check if passed range at Editor zone * * @param range - range to check */ static isRangeAtEditor(e) { if (!e) return; let t = e.startContainer; t && t.nodeType === Node.TEXT_NODE && (t = t.parentNode); let o = null; return t && t instanceof Element && (o = t.closest(`.${m.CSS.editorZone}`)), o ? o.nodeType === Node.ELEMENT_NODE : !1; } /** * Methods return boolean that true if selection exists on the page */ static get isSelectionExists() { return !!m.get().anchorNode; } /** * Return first range * * @returns {Range|null} */ static get range() { return this.getRangeFromSelection(this.get()); } /** * Returns range from passed Selection object * * @param selection - Selection object to get Range from */ static getRangeFromSelection(e) { return e && e.rangeCount ? e.getRangeAt(0) : null; } /** * Calculates position and size of selected text * * @returns {DOMRect | ClientRect} */ static get rect() { let e = document.selection, t, o = { x: 0, y: 0, width: 0, height: 0 }; if (e && e.type !== "Control") return e = e, t = e.createRange(), o.x = t.boundingLeft, o.y = t.boundingTop, o.width = t.boundingWidth, o.height = t.boundingHeight, o; if (!window.getSelection) return T("Method window.getSelection is not supported", "warn"), o; if (e = window.getSelection(), e.rangeCount === null || isNaN(e.rangeCount)) return T("Method SelectionUtils.rangeCount is not supported", "warn"), o; if (e.rangeCount === 0) return o; if (t = e.getRangeAt(0).cloneRange(), t.getBoundingClientRect && (o = t.getBoundingClientRect()), o.x === 0 && o.y === 0) { const i = document.createElement("span"); if (i.getBoundingClientRect) { i.appendChild(document.createTextNode("​")), t.insertNode(i), o = i.getBoundingClientRect(); const n = i.parentNode; n.removeChild(i), n.normalize(); } } return o; } /** * Returns selected text as String * * @returns {string} */ static get text() { return window.getSelection ? window.getSelection().toString() : ""; } /** * Returns window SelectionUtils * {@link https://developer.mozilla.org/ru/docs/Web/API/Window/getSelection} * * @returns {Selection} */ static get() { return window.getSelection(); } /** * Set focus to contenteditable or native input element * * @param element - element where to set focus * @param offset - offset of cursor */ static setCursor(e, t = 0) { const o = document.createRange(), i = window.getSelection(); return d.isNativeInput(e) ? d.canSetCaret(e) ? (e.focus(), e.selectionStart = e.selectionEnd = t, e.getBoundingClientRect()) : void 0 : (o.setStart(e, t), o.setEnd(e, t), i.removeAllRanges(), i.addRange(o), o.getBoundingClientRect()); } /** * Check if current range exists and belongs to container * * @param container - where range should be */ static isRangeInsideContainer(e) { const t = m.range; return t === null ? !1 : e.contains(t.startContainer); } /** * Adds fake cursor to the current range */ static addFakeCursor() { const e = m.range; if (e === null) return; const t = d.make("span", "codex-editor__fake-cursor"); t.dataset.mutationFree = "true", e.collapse(), e.insertNode(t); } /** * Check if passed element contains a fake cursor * * @param el - where to check */ static isFakeCursorInsideContainer(e) { return d.find(e, ".codex-editor__fake-cursor") !== null; } /** * Removes fake cursor from a container * * @param container - container to look for */ static removeFakeCursor(e = document.body) { const t = d.find(e, ".codex-editor__fake-cursor"); t && t.remove(); } /** * Removes fake background */ removeFakeBackground() { this.isFakeBackgroundEnabled && (this.isFakeBackgroundEnabled = !1, document.execCommand(this.commandRemoveFormat)); } /** * Sets fake background */ setFakeBackground() { document.execCommand(this.commandBackground, !1, "#a8d6ff"), this.isFakeBackgroundEnabled = !0; } /** * Save SelectionUtils's range */ save() { this.savedSelectionRange = m.range; } /** * Restore saved SelectionUtils's range */ restore() { if (!this.savedSelectionRange) return; const e = window.getSelection(); e.removeAllRanges(), e.addRange(this.savedSelectionRange); } /** * Clears saved selection */ clearSaved() { this.savedSelectionRange = null; } /** * Collapse current selection */ collapseToEnd() { const e = window.getSelection(), t = document.createRange(); t.selectNodeContents(e.focusNode), t.collapse(!1), e.removeAllRanges(), e.addRange(t); } /** * Looks ahead to find passed tag from current selection * * @param {string} tagName - tag to found * @param {string} [className] - tag's class name * @param {number} [searchDepth] - count of tags that can be included. For better performance. * @returns {HTMLElement|null} */ findParentTag(e, t, o = 10) { const i = window.getSelection(); let n = null; return !i || !i.anchorNode || !i.focusNode ? null : ([ /** the Node in which the selection begins */ i.anchorNode, /** the Node in which the selection ends */ i.focusNode ].forEach((a) => { let l = o; for (; l > 0 && a.parentNode && !(a.tagName === e && (n = a, t && a.classList && !a.classList.contains(t) && (n = null), n)); ) a = a.parentNode, l--; }), n); } /** * Expands selection range to the passed parent node * * @param {HTMLElement} element - element which contents should be selected */ expandToTag(e) { const t = window.getSelection(); t.removeAllRanges(); const o = document.createRange(); o.selectNodeContents(e), t.addRange(o); } } function Vt(s, e) { const { type: t, target: o, addedNodes: i, removedNodes: n } = s; if (o === e) return !0; if (["characterData", "attributes"].includes(t)) { const l = o.nodeType === Node.TEXT_NODE ? o.parentNode : o; return e.contains(l); } const r = Array.from(i).some((l) => e.contains(l)), a = Array.from(n).some((l) => e.contains(l)); return r || a; } const Me = "redactor dom changed", lt = "block changed", ct = "fake cursor is about to be toggled", dt = "fake cursor have been set"; var q = /* @__PURE__ */ ((s) => (s.APPEND_CALLBACK = "appendCallback", s.RENDERED = "rendered", s.MOVED = "moved", s.UPDATED = "updated", s.REMOVED = "removed", s.ON_PASTE = "onPaste", s))(q || {}); class F extends we { /** * @param options - block constructor options * @param [options.id] - block's id. Will be generated if omitted. * @param options.data - Tool's initial data * @param options.tool — block's tool * @param options.api - Editor API module for pass it to the Block Tunes * @param options.readOnly - Read-Only flag * @param [eventBus] - Editor common event bus. Allows to subscribe on some Editor events. Could be omitted when "virtual" Block is created. See BlocksAPI@composeBlockData. */ constructor({ id: e = zt(), data: t, tool: o, api: i, readOnly: n, tunesData: r }, a) { super(), this.cachedInputs = [], this.toolRenderedElement = null, this.tunesInstances = /* @__PURE__ */ new Map(), this.defaultTunesInstances = /* @__PURE__ */ new Map(), this.unavailableTunesData = {}, this.inputIndex = 0, this.editorEventBus = null, this.handleFocus = () => { this.dropInputsCache(), this.updateCurrentInput(); }, this.didMutated = (l = void 0) => { const c = l === void 0, u = l instanceof InputEvent; !c && !u && this.detectToolRootChange(l); let h; c || u ? h = !0 : h = !(l.length > 0 && l.every((v) => { const { addedNodes: p, removedNodes: k, target: _ } = v; return [ ...Array.from(p), ...Array.from(k), _ ].some((A) => d.isElement(A) ? A.dataset.mutationFree === "true" : !1); })), h && (this.dropInputsCache(), this.updateCurrentInput(), this.call( "updated" /* UPDATED */ ), this.emit("didMutated", this)); }, this.name = o.name, this.id = e, this.settings = o.settings, this.config = o.settings.config || {}, this.api = i, this.editorEventBus = a || null, this.blockAPI = new he(this), this.tool = o, this.toolInstance = o.create(t, this.blockAPI, n), this.tunes = o.tunes, this.composeTunes(r), this.holder = this.compose(), this.watchBlockMutations(), this.addInputEvents(); } /** * CSS classes for the Block * * @returns {{wrapper: string, content: string}} */ static get CSS() { return { wrapper: "ce-block", wrapperStretched: "ce-block--stretched", content: "ce-block__content", focused: "ce-block--focused", selected: "ce-block--selected", dropTarget: "ce-block--drop-target" }; } /** * Find and return all editable elements (contenteditable and native inputs) in the Tool HTML * * @returns {HTMLElement[]} */ get inputs() { if (this.cachedInputs.length !== 0) return this.cachedInputs; const e = d.findAllInputs(this.holder); return this.inputIndex > e.length - 1 && (this.inputIndex = e.length - 1), this.cachedInputs = e, e; } /** * Return current Tool`s input * * @returns {HTMLElement} */ get currentInput() { return this.inputs[this.inputIndex]; } /** * Set input index to the passed element * * @param {HTMLElement | Node} element - HTML Element to set as current input */ set currentInput(e) { const t = this.inputs.findIndex((o) => o === e || o.contains(e)); t !== -1 && (this.inputIndex = t); } /** * Return first Tool`s input * * @returns {HTMLElement} */ get firstInput() { return this.inputs[0]; } /** * Return first Tool`s input * * @returns {HTMLElement} */ get lastInput() { const e = this.inputs; return e[e.length - 1]; } /** * Return next Tool`s input or undefined if it doesn't exist * * @returns {HTMLElement} */ get nextInput() { return this.inputs[this.inputIndex + 1]; } /** * Return previous Tool`s input or undefined if it doesn't exist * * @returns {HTMLElement} */ get previousInput() { return this.inputs[this.inputIndex - 1]; } /** * Get Block's JSON data * * @returns {object} */ get data() { return this.save().then((e) => e && !V(e.data) ? e.data : {}); } /** * Returns tool's sanitizer config * * @returns {object} */ get sanitize() { return this.tool.sanitizeConfig; } /** * is block mergeable * We plugin have merge function then we call it mergeable * * @returns {boolean} */ get mergeable() { return D(this.toolInstance.merge); } /** * Check block for emptiness * * @returns {boolean} */ get isEmpty() { const e = d.isEmpty(this.pluginsContent), t = !this.hasMedia; return e && t; } /** * Check if block has a media content such as images, iframe and other * * @returns {boolean} */ get hasMedia() { const e = [ "img", "iframe", "video", "audio", "source", "input", "textarea", "twitterwidget" ]; return !!this.holder.querySelector(e.join(",")); } /** * Set focused state * * @param {boolean} state - 'true' to select, 'false' to remove selection */ set focused(e) { this.holder.classList.toggle(F.CSS.focused, e); } /** * Get Block's focused state */ get focused() { return this.holder.classList.contains(F.CSS.focused); } /** * Set selected state * We don't need to mark Block as Selected when it is empty * * @param {boolean} state - 'true' to select, 'false' to remove selection */ set selected(e) { var i, n; this.holder.classList.toggle(F.CSS.selected, e); const t = e === !0 && m.isRangeInsideContainer(this.holder), o = e === !1 && m.isFakeCursorInsideContainer(this.holder); (t || o) && ((i = this.editorEventBus) == null || i.emit(ct, { state: e }), t ? m.addFakeCursor() : m.removeFakeCursor(this.holder), (n = this.editorEventBus) == null || n.emit(dt, { state: e })); } /** * Returns True if it is Selected * * @returns {boolean} */ get selected() { return this.holder.classList.contains(F.CSS.selected); } /** * Set stretched state * * @param {boolean} state - 'true' to enable, 'false' to disable stretched state */ set stretched(e) { this.holder.classList.toggle(F.CSS.wrapperStretched, e); } /** * Return Block's stretched state * * @returns {boolean} */ get stretched() { return this.holder.classList.contains(F.CSS.wrapperStretched); } /** * Toggle drop target state * * @param {boolean} state - 'true' if block is drop target, false otherwise */ set dropTarget(e) { this.holder.classList.toggle(F.CSS.dropTarget, e); } /** * Returns Plugins content * * @returns {HTMLElement} */ get pluginsContent() { return this.toolRenderedElement; } /** * Calls Tool's method * * Method checks tool property {MethodName}. Fires method with passes params If it is instance of Function * * @param {string} methodName - method to call * @param {object} params - method argument */ call(e, t) { if (D(this.toolInstance[e])) { e === "appendCallback" && T( "`appendCallback` hook is deprecated and will be removed in the next major release. Use `rendered` hook instead", "warn" ); try { this.toolInstance[e].call(this.toolInstance, t); } catch (o) { T(`Error during '${e}' call: ${o.message}`, "error"); } } } /** * Call plugins merge method * * @param {BlockToolData} data - data to merge */ async mergeWith(e) { await this.toolInstance.merge(e); } /** * Extracts data from Block * Groups Tool's save processing time * * @returns {object} */ async save() { const e = await this.toolInstance.save(this.pluginsContent), t = this.unavailableTunesData; [ ...this.tunesInstances.entries(), ...this.defaultTunesInstances.entries() ].forEach(([n, r]) => { if (D(r.save)) try { t[n] = r.save(); } catch (a) { T(`Tune ${r.constructor.name} save method throws an Error %o`, "warn", a); } }); const o = window.performance.now(); let i; return Promise.resolve(e).then((n) => (i = window.performance.now(), { id: this.id, tool: this.name, data: n, tunes: t, time: i - o })).catch((n) => { T(`Saving process for ${this.name} tool failed due to the ${n}`, "log", "red"); }); } /** * Uses Tool's validation method to check the correctness of output data * Tool's validation method is optional * * @description Method returns true|false whether data passed the validation or not * @param {BlockToolData} data - data to validate * @returns {Promise} valid */ async validate(e) { let t = !0; return this.toolInstance.validate instanceof Function && (t = await this.toolInstance.validate(e)), t; } /** * Returns data to render in tunes menu. * Splits block tunes settings into 2 groups: popover items and custom html. */ getTunes() { const e = document.createElement("div"), t = [], o = typeof this.toolInstance.renderSettings == "function" ? this.toolInstance.renderSettings() : [], i = [ ...this.tunesInstances.values(), ...this.defaultTunesInstances.values() ].map((n) => n.render()); return [o, i].flat().forEach((n) => { d.isElement(n) ? e.appendChild(n) : Array.isArray(n) ? t.push(...n) : t.push(n); }), [t, e]; } /** * Update current input index with selection anchor node */ updateCurrentInput() { this.currentInput = d.isNativeInput(document.activeElement) || !m.anchorNode ? document.activeElement : m.anchorNode; } /** * Allows to say Editor that Block was changed. Used to manually trigger Editor's 'onChange' callback * Can be useful for block changes invisible for editor core. */ dispatchChange() { this.didMutated(); } /** * Call Tool instance destroy method */ destroy() { this.unwatchBlockMutations(), this.removeInputEvents(), super.destroy(), D(this.toolInstance.destroy) && this.toolInstance.destroy(); } /** * Tool could specify several entries to be displayed at the Toolbox (for example, "Heading 1", "Heading 2", "Heading 3") * This method returns the entry that is related to the Block (depended on the Block data) */ async getActiveToolboxEntry() { const e = this.tool.toolbox; if (e.length === 1) return Promise.resolve(this.tool.toolbox[0]); const t = await this.data; return e.find((i) => Object.entries(i.data).some(([n, r]) => t[n] && $t(t[n], r))); } /** * Make default Block wrappers and put Tool`s content there * * @returns {HTMLDivElement} */ compose() { const e = d.make("div", F.CSS.wrapper), t = d.make("div", F.CSS.content), o = this.toolInstance.render(); this.toolRenderedElement = o, t.appendChild(this.toolRenderedElement); let i = t; return [...this.tunesInstances.values(), ...this.defaultTunesInstances.values()].forEach((n) => { if (D(n.wrap)) try { i = n.wrap(i); } catch (r) { T(`Tune ${n.constructor.name} wrap method throws an Error %o`, "warn", r); } }), e.appendChild(i), e; } /** * Instantiate Block Tunes * * @param tunesData - current Block tunes data * @private */ composeTunes(e) { Array.from(this.tunes.values()).forEach((t) => { (t.isInternal ? this.defaultTunesInstances : this.tunesInstances).set(t.name, t.create(e[t.name], this.blockAPI)); }), Object.entries(e).forEach(([t, o]) => { this.tunesInstances.has(t) || (this.unavailableTunesData[t] = o); }); } /** * Adds focus event listeners to all inputs and contenteditable */ addInputEvents() { this.inputs.forEach((e) => { e.addEventListener("focus", this.handleFocus), d.isNativeInput(e) && e.addEventListener("input", this.didMutated); }); } /** * removes focus event listeners from all inputs and contenteditable */ removeInputEvents() { this.inputs.forEach((e) => { e.removeEventListener("focus", this.handleFocus), d.isNativeInput(e) && e.removeEventListener("input", this.didMutated); }); } /** * Listen common editor Dom Changed event and detect mutations related to the Block */ watchBlockMutations() { var e; this.redactorDomChangedCallback = (t) => { const { mutations: o } = t; o.some((n) => Vt(n, this.toolRenderedElement)) && this.didMutated(o); }, (e = this.editorEventBus) == null || e.on(Me, this.redactorDomChangedCallback); } /** * Remove redactor dom change event listener */ unwatchBlockMutations() { var e; (e = this.editorEventBus) == null || e.off(Me, this.redactorDomChangedCallback); } /** * Sometimes Tool can replace own main element, for example H2 -> H4 or UL -> OL * We need to detect such changes and update a link to tools main element with the new one * * @param mutations - records of block content mutations */ detectToolRootChange(e) { e.forEach((t) => { if (Array.from(t.removedNodes).includes(this.toolRenderedElement)) { const i = t.addedNodes[t.addedNodes.length - 1]; this.toolRenderedElement = i; } }); } /** * Clears inputs cached value */ dropInputsCache() { this.cachedInputs = []; } } class Zt extends S { constructor() { super(...arguments), this.insert = (e = this.config.defaultBlock, t = {}, o = {}, i, n, r, a) => { const l = this.Editor.BlockManager.insert({ id: a, tool: e, data: t, index: i, needToFocus: n, replace: r }); return new he(l); }, this.composeBlockData = async (e) => { const t = this.Editor.Tools.blockTools.get(e); return new F({ tool: t, api: this.Editor.API, readOnly: !0, data: {}, tunesData: {} }).data; }, this.update = (e, t) => { const { BlockManager: o } = this.Editor, i = o.getBlockById(e); if (!i) { T("blocks.update(): Block with passed id was not found", "warn"); return; } const n = o.getBlockIndex(i); o.insert({ id: i.id, tool: i.name, data: t, index: n, replace: !0, tunes: i.tunes }); }; } /** * Available methods * * @returns {Blocks} */ get methods() { return { clear: () => this.clear(), render: (e) => this.render(e), renderFromHTML: (e) => this.renderFromHTML(e), delete: (e) => this.delete(e), swap: (e, t) => this.swap(e, t), move: (e, t) => this.move(e, t), getBlockByIndex: (e) => this.getBlockByIndex(e), getById: (e) => this.getById(e), getCurrentBlockIndex: () => this.getCurrentBlockIndex(), getBlockIndex: (e) => this.getBlockIndex(e), getBlocksCount: () => this.getBlocksCount(), stretchBlock: (e, t = !0) => this.stretchBlock(e, t), insertNewBlock: () => this.insertNewBlock(), insert: this.insert, update: this.update, composeBlockData: this.composeBlockData }; } /** * Returns Blocks count * * @returns {number} */ getBlocksCount() { return this.Editor.BlockManager.blocks.length; } /** * Returns current block index * * @returns {number} */ getCurrentBlockIndex() { return this.Editor.BlockManager.currentBlockIndex; } /** * Returns the index of Block by id; * * @param id - block id */ getBlockIndex(e) { const t = this.Editor.BlockManager.getBlockById(e); if (!t) { K("There is no block with id `" + e + "`", "warn"); return; } return this.Editor.BlockManager.getBlockIndex(t); } /** * Returns BlockAPI object by Block index * * @param {number} index - index to get */ getBlockByIndex(e) { const t = this.Editor.BlockManager.getBlockByIndex(e); if (t === void 0) { K("There is no block at index `" + e + "`", "warn"); return; } return new he(t); } /** * Returns BlockAPI object by Block id * * @param id - id of block to get */ getById(e) { const t = this.Editor.BlockManager.getBlockById(e); return t === void 0 ? (K("There is no block with id `" + e + "`", "warn"), null) : new he(t); } /** * Call Block Manager method that swap Blocks * * @param {number} fromIndex - position of first Block * @param {number} toIndex - position of second Block * @deprecated — use 'move' instead */ swap(e, t) { T( "`blocks.swap()` method is deprecated and will be removed in the next major release. Use `block.move()` method instead", "info" ), this.Editor.BlockManager.swap(e, t); } /** * Move block from one index to another * * @param {number} toIndex - index to move to * @param {number} fromIndex - index to move from */ move(e, t) { this.Editor.BlockManager.move(e, t); } /** * Deletes Block * * @param {number} blockIndex - index of Block to delete */ delete(e) { try { this.Editor.BlockManager.removeBlock(e); } catch (t) { K(t, "warn"); return; } this.Editor.BlockManager.blocks.length === 0 && this.Editor.BlockManager.insert(), this.Editor.BlockManager.currentBlock && this.Editor.Caret.setToBlock(this.Editor.BlockManager.currentBlock, this.Editor.Caret.positions.END), this.Editor.Toolbar.close(); } /** * Clear Editor's area */ clear() { this.Editor.BlockManager.clear(!0), this.Editor.InlineToolbar.close(); } /** * Fills Editor with Blocks data * * @param {OutputData} data — Saved Editor data */ render(e) { return this.Editor.BlockManager.clear(), this.Editor.Renderer.render(e.blocks); } /** * Render passed HTML string * * @param {string} data - HTML string to render * @returns {Promise} */ renderFromHTML(e) { return this.Editor.BlockManager.clear(), this.Editor.Paste.processText(e, !0); } /** * Stretch Block's content * * @param {number} index - index of Block to stretch * @param {boolean} status - true to enable, false to disable * @deprecated Use BlockAPI interface to stretch Blocks */ stretchBlock(e, t = !0) { Ie( !0, "blocks.stretchBlock()", "BlockAPI" ); const o = this.Editor.BlockManager.getBlockByIndex(e); o && (o.stretched = t); } /** * Insert new Block * After set caret to this Block * * @todo remove in 3.0.0 * @deprecated with insert() method */ insertNewBlock() { T("Method blocks.insertNewBlock() is deprecated and it will be removed in the next major release. Use blocks.insert() instead.", "warn"), this.insert(); } } class Gt extends S { constructor() { super(...arguments), this.setToFirstBlock = (e = this.Editor.Caret.positions.DEFAULT, t = 0) => this.Editor.BlockManager.firstBlock ? (this.Editor.Caret.setToBlock(this.Editor.BlockManager.firstBlock, e, t), !0) : !1, this.setToLastBlock = (e = this.Editor.Caret.positions.DEFAULT, t = 0) => this.Editor.BlockManager.lastBlock ? (this.Editor.Caret.setToBlock(this.Editor.BlockManager.lastBlock, e, t), !0) : !1, this.setToPreviousBlock = (e = this.Editor.Caret.positions.DEFAULT, t = 0) => this.Editor.BlockManager.previousBlock ? (this.Editor.Caret.setToBlock(this.Editor.BlockManager.previousBlock, e, t), !0) : !1, this.setToNextBlock = (e = this.Editor.Caret.positions.DEFAULT, t = 0) => this.Editor.BlockManager.nextBlock ? (this.Editor.Caret.setToBlock(this.Editor.BlockManager.nextBlock, e, t), !0) : !1, this.setToBlock = (e, t = this.Editor.Caret.positions.DEFAULT, o = 0) => this.Editor.BlockManager.blocks[e] ? (this.Editor.Caret.setToBlock(this.Editor.BlockManager.blocks[e], t, o), !0) : !1, this.focus = (e = !1) => e ? this.setToLastBlock(this.Editor.Caret.positions.END) : this.setToFirstBlock(this.Editor.Caret.positions.START); } /** * Available methods * * @returns {Caret} */ get methods() { return { setToFirstBlock: this.setToFirstBlock, setToLastBlock: this.setToLastBlock, setToPreviousBlock: this.setToPreviousBlock, setToNextBlock: this.setToNextBlock, setToBlock: this.setToBlock, focus: this.focus }; } } class qt extends S { /** * Available methods * * @returns {Events} */ get methods() { return { emit: (e, t) => this.emit(e, t), off: (e, t) => this.off(e, t), on: (e, t) => this.on(e, t) }; } /** * Subscribe on Posts * * @param {string} eventName - event name to subscribe * @param {Function} callback - event handler */ on(e, t) { this.eventsDispatcher.on(e, t); } /** * Emit event with data * * @param {string} eventName - event to emit * @param {object} data - event's data */ emit(e, t) { this.eventsDispatcher.emit(e, t); } /** * Unsubscribe from Event * * @param {string} eventName - event to unsubscribe * @param {Function} callback - event handler */ off(e, t) { this.eventsDispatcher.off(e, t); } } class De extends S { /** * Return namespace section for tool or block tune * * @param tool - tool object */ static getNamespace(e) { return e.isTune() ? `blockTunes.${e.name}` : `tools.${e.name}`; } /** * Return I18n API methods with global dictionary access */ get methods() { return { t: () => { K("I18n.t() method can be accessed only from Tools", "warn"); } }; } /** * Return I18n API methods with tool namespaced dictionary * * @param tool - Tool object */ getMethodsForTool(e) { return Object.assign( this.methods, { t: (t) => $.t(De.getNamespace(e), t) } ); } } class Jt extends S { /** * Editor.js Core API modules */ get methods() { return { blocks: this.Editor.BlocksAPI.methods, caret: this.Editor.CaretAPI.methods, events: this.Editor.EventsAPI.methods, listeners: this.Editor.ListenersAPI.methods, notifier: this.Editor.NotifierAPI.methods, sanitizer: this.Editor.SanitizerAPI.methods, saver: this.Editor.SaverAPI.methods, selection: this.Editor.SelectionAPI.methods, styles: this.Editor.StylesAPI.classes, toolbar: this.Editor.ToolbarAPI.methods, inlineToolbar: this.Editor.InlineToolbarAPI.methods, tooltip: this.Editor.TooltipAPI.methods, i18n: this.Editor.I18nAPI.methods, readOnly: this.Editor.ReadOnlyAPI.methods, ui: this.Editor.UiAPI.methods }; } /** * Returns Editor.js Core API methods for passed tool * * @param tool - tool object */ getMethodsForTool(e) { return Object.assign( this.methods, { i18n: this.Editor.I18nAPI.getMethodsForTool(e) } ); } } class Qt extends S { /** * Available methods * * @returns {InlineToolbar} */ get methods() { return { close: () => this.close(), open: () => this.open() }; } /** * Open Inline Toolbar */ open() { this.Editor.InlineToolbar.tryToShow(); } /** * Close Inline Toolbar */ close() { this.Editor.InlineToolbar.close(); } } class eo extends S { /** * Available methods * * @returns {Listeners} */ get methods() { return { on: (e, t, o, i) => this.on(e, t, o, i), off: (e, t, o, i) => this.off(e, t, o, i), offById: (e) => this.offById(e) }; } /** * Ads a DOM event listener. Return it's id. * * @param {HTMLElement} element - Element to set handler to * @param {string} eventType - event type * @param {() => void} handler - event handler * @param {boolean} useCapture - capture event or not */ on(e, t, o, i) { return this.listeners.on(e, t, o, i); } /** * Removes DOM listener from element * * @param {Element} element - Element to remove handler from * @param eventType - event type * @param handler - event handler * @param {boolean} useCapture - capture event or not */ off(e, t, o, i) { this.listeners.off(e, t, o, i); } /** * Removes DOM listener by the listener id * * @param id - id of the listener to remove */ offById(e) { this.listeners.offById(e); } } var Le = {}, to = { get exports() { return Le; }, set exports(s) { Le = s; } }; (function(s, e) { (function(t, o) { s.exports = o(); })(window, function() { return function(t) { var o = {}; function i(n) { if (o[n]) return o[n].exports; var r = o[n] = { i: n, l: !1, exports: {} }; return t[n].call(r.exports, r, r.exports, i), r.l = !0, r.exports; } return i.m = t, i.c = o, i.d = function(n, r, a) { i.o(n, r) || Object.defineProperty(n, r, { enumerable: !0, get: a }); }, i.r = function(n) { typeof Symbol < "u" && Symbol.toStringTag && Object.defineProperty(n, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(n, "__esModule", { value: !0 }); }, i.t = function(n, r) { if (1 & r && (n = i(n)), 8 & r || 4 & r && typeof n == "object" && n && n.__esModule) return n; var a = /* @__PURE__ */ Object.create(null); if (i.r(a), Object.defineProperty(a, "default", { enumerable: !0, value: n }), 2 & r && typeof n != "string") for (var l in n) i.d(a, l, function(c) { return n[c]; }.bind(null, l)); return a; }, i.n = function(n) { var r = n && n.__esModule ? function() { return n.default; } : function() { return n; }; return i.d(r, "a", r), r; }, i.o = function(n, r) { return Object.prototype.hasOwnProperty.call(n, r); }, i.p = "/", i(i.s = 0); }([function(t, o, i) { i(1), /*! * Codex JavaScript Notification module * https://github.com/codex-team/js-notifier */ t.exports = function() { var n = i(6), r = "cdx-notify--bounce-in", a = null; return { show: function(l) { if (l.message) { (function() { if (a) return !0; a = n.getWrapper(), document.body.appendChild(a); })(); var c = null, u = l.time || 8e3; switch (l.type) { case "confirm": c = n.confirm(l); break; case "prompt": c = n.prompt(l); break; default: c = n.alert(l), window.setTimeout(function() { c.remove(); }, u); } a.appendChild(c), c.classList.add(r); } } }; }(); }, function(t, o, i) { var n = i(2); typeof n == "string" && (n = [[t.i, n, ""]]); var r = { hmr: !0, transform: void 0, insertInto: void 0 }; i(4)(n, r), n.locals && (t.exports = n.locals); }, function(t, o, i) { (t.exports = i(3)(!1)).push([t.i, `.cdx-notify--error{background:#fffbfb!important}.cdx-notify--error::before{background:#fb5d5d!important}.cdx-notify__input{max-width:130px;padding:5px 10px;background:#f7f7f7;border:0;border-radius:3px;font-size:13px;color:#656b7c;outline:0}.cdx-notify__input:-ms-input-placeholder{color:#656b7c}.cdx-notify__input::placeholder{color:#656b7c}.cdx-notify__input:focus:-ms-input-placeholder{color:rgba(101,107,124,.3)}.cdx-notify__input:focus::placeholder{color:rgba(101,107,124,.3)}.cdx-notify__button{border:none;border-radius:3px;font-size:13px;padding:5px 10px;cursor:pointer}.cdx-notify__button:last-child{margin-left:10px}.cdx-notify__button--cancel{background:#f2f5f7;box-shadow:0 2px 1px 0 rgba(16,19,29,0);color:#656b7c}.cdx-notify__button--cancel:hover{background:#eee}.cdx-notify__button--confirm{background:#34c992;box-shadow:0 1px 1px 0 rgba(18,49,35,.05);color:#fff}.cdx-notify__button--confirm:hover{background:#33b082}.cdx-notify__btns-wrapper{display:-ms-flexbox;display:flex;-ms-flex-flow:row nowrap;flex-flow:row nowrap;margin-top:5px}.cdx-notify__cross{position:absolute;top:5px;right:5px;width:10px;height:10px;padding:5px;opacity:.54;cursor:pointer}.cdx-notify__cross::after,.cdx-notify__cross::before{content:'';position:absolute;left:9px;top:5px;height:12px;width:2px;background:#575d67}.cdx-notify__cross::before{transform:rotate(-45deg)}.cdx-notify__cross::after{transform:rotate(45deg)}.cdx-notify__cross:hover{opacity:1}.cdx-notifies{position:fixed;z-index:2;bottom:20px;left:20px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",sans-serif}.cdx-notify{position:relative;width:220px;margin-top:15px;padding:13px 16px;background:#fff;box-shadow:0 11px 17px 0 rgba(23,32,61,.13);border-radius:5px;font-size:14px;line-height:1.4em;word-wrap:break-word}.cdx-notify::before{content:'';position:absolute;display:block;top:0;left:0;width:3px;height:calc(100% - 6px);margin:3px;border-radius:5px;background:0 0}@keyframes bounceIn{0%{opacity:0;transform:scale(.3)}50%{opacity:1;transform:scale(1.05)}70%{transform:scale(.9)}100%{transform:scale(1)}}.cdx-notify--bounce-in{animation-name:bounceIn;animation-duration:.6s;animation-iteration-count:1}.cdx-notify--success{background:#fafffe!important}.cdx-notify--success::before{background:#41ffb1!important}`, ""]); }, function(t, o) { t.exports = function(i) { var n = []; return n.toString = function() { return this.map(function(r) { var a = function(l, c) { var u = l[1] || "", h = l[3]; if (!h) return u; if (c && typeof btoa == "function") { var f = (p = h, "/*# sourceMappingURL=data:application/json;charset=utf-8;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(p)))) + " */"), v = h.sources.map(function(k) { return "/*# sourceURL=" + h.sourceRoot + k + " */"; }); return [u].concat(v).concat([f]).join(` `); } var p; return [u].join(` `); }(r, i); return r[2] ? "@media " + r[2] + "{" + a + "}" : a; }).join(""); }, n.i = function(r, a) { typeof r == "string" && (r = [[null, r, ""]]); for (var l = {}, c = 0; c < this.length; c++) { var u = this[c][0]; typeof u == "number" && (l[u] = !0); } for (c = 0; c < r.length; c++) { var h = r[c]; typeof h[0] == "number" && l[h[0]] || (a && !h[2] ? h[2] = a : a && (h[2] = "(" + h[2] + ") and (" + a + ")"), n.push(h)); } }, n; }; }, function(t, o, i) { var n, r, a = {}, l = (n = function() { return window && document && document.all && !window.atob; }, function() { return r === void 0 && (r = n.apply(this, arguments)), r; }), c = function(b) { var g = {}; return function(E) { if (typeof E == "function") return E(); if (g[E] === void 0) { var C = function(O) { return document.querySelector(O); }.call(this, E); if (window.HTMLIFrameElement && C instanceof window.HTMLIFrameElement) try { C = C.contentDocument.head; } catch { C = null; } g[E] = C; } return g[E]; }; }(), u = null, h = 0, f = [], v = i(5); function p(b, g) { for (var E = 0; E < b.length; E++) { var C = b[E], O = a[C.id]; if (O) { O.refs++; for (var I = 0; I < O.parts.length; I++) O.parts[I](C.parts[I]); for (; I < C.parts.length; I++) O.parts.push(x(C.parts[I], g)); } else { var H = []; for (I = 0; I < C.parts.length; I++) H.push(x(C.parts[I], g)); a[C.id] = { id: C.id, refs: 1, parts: H }; } } } function k(b, g) { for (var E = [], C = {}, O = 0; O < b.length; O++) { var I = b[O], H = g.base ? I[0] + g.base : I[0], L = { css: I[1], media: I[2], sourceMap: I[3] }; C[H] ? C[H].parts.push(L) : E.push(C[H] = { id: H, parts: [L] }); } return E; } function _(b, g) { var E = c(b.insertInto); if (!E) throw new Error("Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid."); var C = f[f.length - 1]; if (b.insertAt === "top") C ? C.nextSibling ? E.insertBefore(g, C.nextSibling) : E.appendChild(g) : E.insertBefore(g, E.firstChild), f.push(g); else if (b.insertAt === "bottom") E.appendChild(g); else { if (typeof b.insertAt != "object" || !b.insertAt.before) throw new Error(`[Style Loader] Invalid value for parameter 'insertAt' ('options.insertAt') found. Must be 'top', 'bottom', or Object. (https://github.com/webpack-contrib/style-loader#insertat) `); var O = c(b.insertInto + " " + b.insertAt.before); E.insertBefore(g, O); } } function N(b) { if (b.parentNode === null) return !1; b.parentNode.removeChild(b); var g = f.indexOf(b); g >= 0 && f.splice(g, 1); } function A(b) { var g = document.createElement("style"); return b.attrs.type === void 0 && (b.attrs.type = "text/css"), y(g, b.attrs), _(b, g), g; } function y(b, g) { Object.keys(g).forEach(function(E) { b.setAttribute(E, g[E]); }); } function x(b, g) { var E, C, O, I; if (g.transform && b.css) { if (!(I = g.transform(b.css))) return function() { }; b.css = I; } if (g.singleton) { var H = h++; E = u || (u = A(g)), C = R.bind(null, E, H, !1), O = R.bind(null, E, H, !0); } else b.sourceMap && typeof URL == "function" && typeof URL.createObjectURL == "function" && typeof URL.revokeObjectURL == "function" && typeof Blob == "function" && typeof btoa == "function" ? (E = function(L) { var W = document.createElement("link"); return L.attrs.type === void 0 && (L.attrs.type = "text/css"), L.attrs.rel = "stylesheet", y(W, L.attrs), _(L, W), W; }(g), C = function(L, W, le) { var Q = le.css, Ee = le.sourceMap, It = W.convertToAbsoluteUrls === void 0 && Ee; (W.convertToAbsoluteUrls || It) && (Q = v(Q)), Ee && (Q += ` /*# sourceMappingURL=data:application/json;base64,` + btoa(unescape(encodeURIComponent(JSON.stringify(Ee)))) + " */"); var Mt = new Blob([Q], { type: "text/css" }), Xe = L.href; L.href = URL.createObjectURL(Mt), Xe && URL.revokeObjectURL(Xe); }.bind(null, E, g), O = function() { N(E), E.href && URL.revokeObjectURL(E.href); }) : (E = A(g), C = function(L, W) { var le = W.css, Q = W.media; if (Q && L.setAttribute("media", Q), L.styleSheet) L.styleSheet.cssText = le; else { for (; L.firstChild; ) L.removeChild(L.firstChild); L.appendChild(document.createTextNode(le)); } }.bind(null, E), O = function() { N(E); }); return C(b), function(L) { if (L) { if (L.css === b.css && L.media === b.media && L.sourceMap === b.sourceMap) return; C(b = L); } else O(); }; } t.exports = function(b, g) { if (typeof DEBUG < "u" && DEBUG && typeof document != "object") throw new Error("The style-loader cannot be used in a non-browser environment"); (g = g || {}).attrs = typeof g.attrs == "object" ? g.attrs : {}, g.singleton || typeof g.singleton == "boolean" || (g.singleton = l()), g.insertInto || (g.insertInto = "head"), g.insertAt || (g.insertAt = "bottom"); var E = k(b, g); return p(E, g), function(C) { for (var O = [], I = 0; I < E.length; I++) { var H = E[I]; (L = a[H.id]).refs--, O.push(L); } for (C && p(k(C, g), g), I = 0; I < O.length; I++) { var L; if ((L = O[I]).refs === 0) { for (var W = 0; W < L.parts.length; W++) L.parts[W](); delete a[L.id]; } } }; }; var w, M = (w = [], function(b, g) { return w[b] = g, w.filter(Boolean).join(` `); }); function R(b, g, E, C) { var O = E ? "" : C.css; if (b.styleSheet) b.styleSheet.cssText = M(g, O); else { var I = document.createTextNode(O), H = b.childNodes; H[g] && b.removeChild(H[g]), H.length ? b.insertBefore(I, H[g]) : b.appendChild(I); } } }, function(t, o) { t.exports = function(i) { var n = typeof window < "u" && window.location; if (!n) throw new Error("fixUrls requires window.location"); if (!i || typeof i != "string") return i; var r = n.protocol + "//" + n.host, a = r + n.pathname.replace(/\/[^\/]*$/, "/"); return i.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi, function(l, c) { var u, h = c.trim().replace(/^"(.*)"$/, function(f, v) { return v; }).replace(/^'(.*)'$/, function(f, v) { return v; }); return /^(#|data:|http:\/\/|https:\/\/|file:\/\/\/|\s*$)/i.test(h) ? l : (u = h.indexOf("//") === 0 ? h : h.indexOf("/") === 0 ? r + h : a + h.replace(/^\.\//, ""), "url(" + JSON.stringify(u) + ")"); }); }; }, function(t, o, i) { var n, r, a, l, c, u, h, f, v; t.exports = (n = "cdx-notifies", r = "cdx-notify", a = "cdx-notify__cross", l = "cdx-notify__button--confirm", c = "cdx-notify__button--cancel", u = "cdx-notify__input", h = "cdx-notify__button", f = "cdx-notify__btns-wrapper", { alert: v = function(p) { var k = document.createElement("DIV"), _ = document.createElement("DIV"), N = p.message, A = p.style; return k.classList.add(r), A && k.classList.add(r + "--" + A), k.innerHTML = N, _.classList.add(a), _.addEventListener("click", k.remove.bind(k)), k.appendChild(_), k; }, confirm: function(p) { var k = v(p), _ = document.createElement("div"), N = document.createElement("button"), A = document.createElement("button"), y = k.querySelector("." + a), x = p.cancelHandler, w = p.okHandler; return _.classList.add(f), N.innerHTML = p.okText || "Confirm", A.innerHTML = p.cancelText || "Cancel", N.classList.add(h), A.classList.add(h), N.classList.add(l), A.classList.add(c), x && typeof x == "function" && (A.addEventListener("click", x), y.addEventListener("click", x)), w && typeof w == "function" && N.addEventListener("click", w), N.addEventListener("click", k.remove.bind(k)), A.addEventListener("click", k.remove.bind(k)), _.appendChild(N), _.appendChild(A), k.appendChild(_), k; }, prompt: function(p) { var k = v(p), _ = document.createElement("div"), N = document.createElement("button"), A = document.createElement("input"), y = k.querySelector("." + a), x = p.cancelHandler, w = p.okHandler; return _.classList.add(f), N.innerHTML = p.okText || "Ok", N.classList.add(h), N.classList.add(l), A.classList.add(u), p.placeholder && A.setAttribute("placeholder", p.placeholder), p.default && (A.value = p.default), p.inputType && (A.type = p.inputType), x && typeof x == "function" && y.addEventListener("click", x), w && typeof w == "function" && N.addEventListener("click", function() { w(A.value); }), N.addEventListener("click", k.remove.bind(k)), _.appendChild(A), _.appendChild(N), k.appendChild(_), k; }, getWrapper: function() { var p = document.createElement("DIV"); return p.classList.add(n), p; } }); }]); }); })(to); const oo = /* @__PURE__ */ xe(Le); class io { /** * Show web notification * * @param {NotifierOptions | ConfirmNotifierOptions | PromptNotifierOptions} options - notification options */ show(e) { oo.show(e); } } class no extends S { /** * @param moduleConfiguration - Module Configuration * @param moduleConfiguration.config - Editor's config * @param moduleConfiguration.eventsDispatcher - Editor's event dispatcher */ constructor({ config: e, eventsDispatcher: t }) { super({ config: e, eventsDispatcher: t }), this.notifier = new io(); } /** * Available methods */ get methods() { return { show: (e) => this.show(e) }; } /** * Show notification * * @param {NotifierOptions} options - message option */ show(e) { return this.notifier.show(e); } } class so extends S { /** * Available methods */ get methods() { const e = () => this.isEnabled; return { toggle: (t) => this.toggle(t), get isEnabled() { return e(); } }; } /** * Set or toggle read-only state * * @param {boolean|undefined} state - set or toggle state * @returns {boolean} current value */ toggle(e) { return this.Editor.ReadOnly.toggle(e); } /** * Returns current read-only state */ get isEnabled() { return this.Editor.ReadOnly.isEnabled; } } var Oe = {}, ro = { get exports() { return Oe; }, set exports(s) { Oe = s; } }; (function(s, e) { (function(t, o) { s.exports = o(); })(Lt, function() { function t(h) { var f = h.tags, v = Object.keys(f), p = v.map(function(k) { return typeof f[k]; }).every(function(k) { return k === "object" || k === "boolean" || k === "function"; }); if (!p) throw new Error("The configuration was invalid"); this.config = h; } var o = ["P", "LI", "TD", "TH", "DIV", "H1", "H2", "H3", "H4", "H5", "H6", "PRE"]; function i(h) { return o.indexOf(h.nodeName) !== -1; } var n = ["A", "B", "STRONG", "I", "EM", "SUB", "SUP", "U", "STRIKE"]; function r(h) { return n.indexOf(h.nodeName) !== -1; } t.prototype.clean = function(h) { const f = document.implementation.createHTMLDocument(), v = f.createElement("div"); return v.innerHTML = h, this._sanitize(f, v), v.innerHTML; }, t.prototype._sanitize = function(h, f) { var v = a(h, f), p = v.firstChild(); if (p) do { if (p.nodeType === Node.TEXT_NODE) if (p.data.trim() === "" && (p.previousElementSibling && i(p.previousElementSibling) || p.nextElementSibling && i(p.nextElementSibling))) { f.removeChild(p), this._sanitize(h, f); break; } else continue; if (p.nodeType === Node.COMMENT_NODE) { f.removeChild(p), this._sanitize(h, f); break; } var k = r(p), _; k && (_ = Array.prototype.some.call(p.childNodes, i)); var N = !!f.parentNode, A = i(f) && i(p) && N, y = p.nodeName.toLowerCase(), x = l(this.config, y, p), w = k && _; if (w || c(p, x) || !this.config.keepNestedBlockElements && A) { if (!(p.nodeName === "SCRIPT" || p.nodeName === "STYLE")) for (; p.childNodes.length > 0; ) f.insertBefore(p.childNodes[0], p); f.removeChild(p), this._sanitize(h, f); break; } for (var M = 0; M < p.attributes.length; M += 1) { var R = p.attributes[M]; u(R, x, p) && (p.removeAttribute(R.name), M = M - 1); } this._sanitize(h, p); } while (p = v.nextSibling()); }; function a(h, f) { return h.createTreeWalker( f, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT, null, !1 ); } function l(h, f, v) { return typeof h.tags[f] == "function" ? h.tags[f](v) : h.tags[f]; } function c(h, f) { return typeof f > "u" ? !0 : typeof f == "boolean" ? !f : !1; } function u(h, f, v) { var p = h.name.toLowerCase(); return f === !0 ? !1 : typeof f[p] == "function" ? !f[p](h.value, v) : typeof f[p] > "u" || f[p] === !1 ? !0 : typeof f[p] == "string" ? f[p] !== h.value : !1; } return t; }); })(ro); const ao = Oe; function ht(s, e) { return s.map((t) => { const o = D(e) ? e(t.tool) : e; return V(o) || (t.data = Pe(t.data, o)), t; }); } function Z(s, e = {}) { const t = { tags: e }; return new ao(t).clean(s); } function Pe(s, e) { return Array.isArray(s) ? lo(s, e) : j(s) ? co(s, e) : J(s) ? ho(s, e) : s; } function lo(s, e) { return s.map((t) => Pe(t, e)); } function co(s, e) { const t = {}; for (const o in s) { if (!Object.prototype.hasOwnProperty.call(s, o)) continue; const i = s[o], n = uo(e[o]) ? e[o] : e; t[o] = Pe(i, n); } return t; } function ho(s, e) { return j(e) ? Z(s, e) : e === !1 ? Z(s, {}) : s; } function uo(s) { return j(s) || Nt(s) || D(s); } class po extends S { /** * Available methods * * @returns {SanitizerConfig} */ get methods() { return { clean: (e, t) => this.clean(e, t) }; } /** * Perform sanitizing of a string * * @param {string} taintString - what to sanitize * @param {SanitizerConfig} config - sanitizer config * @returns {string} */ clean(e, t) { return Z(e, t); } } class fo extends S { /** * Available methods * * @returns {Saver} */ get methods() { return { save: () => this.save() }; } /** * Return Editor's data * * @returns {OutputData} */ save() { const e = "Editor's content can not be saved in read-only mode"; return this.Editor.ReadOnly.isEnabled ? (K(e, "warn"), Promise.reject(new Error(e))) : this.Editor.Saver.save(); } } class go extends S { /** * Available methods * * @returns {SelectionAPIInterface} */ get methods() { return { findParentTag: (e, t) => this.findParentTag(e, t), expandToTag: (e) => this.expandToTag(e) }; } /** * Looks ahead from selection and find passed tag with class name * * @param {string} tagName - tag to find * @param {string} className - tag's class name * @returns {HTMLElement|null} */ findParentTag(e, t) { return new m().findParentTag(e, t); } /** * Expand selection to passed tag * * @param {HTMLElement} node - tag that should contain selection */ expandToTag(e) { new m().expandToTag(e); } } class bo extends S { /** * Exported classes */ get classes() { return { /** * Base Block styles */ block: "cdx-block", /** * Inline Tools styles */ inlineToolButton: "ce-inline-tool", inlineToolButtonActive: "ce-inline-tool--active", /** * UI elements */ input: "cdx-input", loader: "cdx-loader", button: "cdx-button", /** * Settings styles */ settingsButton: "cdx-settings-button", settingsButtonActive: "cdx-settings-button--active" }; } } class mo extends S { /** * Available methods * * @returns {Toolbar} */ get methods() { return { close: () => this.close(), open: () => this.open(), toggleBlockSettings: (e) => this.toggleBlockSettings(e), toggleToolbox: (e) => this.toggleToolbox(e) }; } /** * Open toolbar */ open() { this.Editor.Toolbar.moveAndOpen(); } /** * Close toolbar and all included elements */ close() { this.Editor.Toolbar.close(); } /** * Toggles Block Setting of the current block * * @param {boolean} openingState — opening state of Block Setting */ toggleBlockSettings(e) { if (this.Editor.BlockManager.currentBlockIndex === -1) { K("Could't toggle the Toolbar because there is no block selected ", "warn"); return; } e ?? !this.Editor.BlockSettings.opened ? (this.Editor.Toolbar.moveAndOpen(), this.Editor.BlockSettings.open()) : this.Editor.BlockSettings.close(); } /** * Open toolbox * * @param {boolean} openingState - Opening state of toolbox */ toggleToolbox(e) { if (this.Editor.BlockManager.currentBlockIndex === -1) { K("Could't toggle the Toolbox because there is no block selected ", "warn"); return; } e ?? !this.Editor.Toolbar.toolbox.opened ? (this.Editor.Toolbar.moveAndOpen(), this.Editor.Toolbar.toolbox.open()) : this.Editor.Toolbar.toolbox.close(); } } var _e = {}, ko = { get exports() { return _e; }, set exports(s) { _e = s; } }; /*! * CodeX.Tooltips * * @version 1.0.5 * * @licence MIT * @author CodeX * * */ (function(s, e) { (function(t, o) { s.exports = o(); })(window, function() { return function(t) { var o = {}; function i(n) { if (o[n]) return o[n].exports; var r = o[n] = { i: n, l: !1, exports: {} }; return t[n].call(r.exports, r, r.exports, i), r.l = !0, r.exports; } return i.m = t, i.c = o, i.d = function(n, r, a) { i.o(n, r) || Object.defineProperty(n, r, { enumerable: !0, get: a }); }, i.r = function(n) { typeof Symbol < "u" && Symbol.toStringTag && Object.defineProperty(n, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(n, "__esModule", { value: !0 }); }, i.t = function(n, r) { if (1 & r && (n = i(n)), 8 & r || 4 & r && typeof n == "object" && n && n.__esModule) return n; var a = /* @__PURE__ */ Object.create(null); if (i.r(a), Object.defineProperty(a, "default", { enumerable: !0, value: n }), 2 & r && typeof n != "string") for (var l in n) i.d(a, l, function(c) { return n[c]; }.bind(null, l)); return a; }, i.n = function(n) { var r = n && n.__esModule ? function() { return n.default; } : function() { return n; }; return i.d(r, "a", r), r; }, i.o = function(n, r) { return Object.prototype.hasOwnProperty.call(n, r); }, i.p = "", i(i.s = 0); }([function(t, o, i) { t.exports = i(1); }, function(t, o, i) { i.r(o), i.d(o, "default", function() { return n; }); class n { constructor() { this.nodes = { wrapper: null, content: null }, this.showed = !1, this.offsetTop = 10, this.offsetLeft = 10, this.offsetRight = 10, this.hidingDelay = 0, this.handleWindowScroll = () => { this.showed && this.hide(!0); }, this.loadStyles(), this.prepare(), window.addEventListener("scroll", this.handleWindowScroll, { passive: !0 }); } get CSS() { return { tooltip: "ct", tooltipContent: "ct__content", tooltipShown: "ct--shown", placement: { left: "ct--left", bottom: "ct--bottom", right: "ct--right", top: "ct--top" } }; } show(a, l, c) { this.nodes.wrapper || this.prepare(), this.hidingTimeout && clearTimeout(this.hidingTimeout); const u = Object.assign({ placement: "bottom", marginTop: 0, marginLeft: 0, marginRight: 0, marginBottom: 0, delay: 70, hidingDelay: 0 }, c); if (u.hidingDelay && (this.hidingDelay = u.hidingDelay), this.nodes.content.innerHTML = "", typeof l == "string") this.nodes.content.appendChild(document.createTextNode(l)); else { if (!(l instanceof Node)) throw Error("[CodeX Tooltip] Wrong type of «content» passed. It should be an instance of Node or String. But " + typeof l + " given."); this.nodes.content.appendChild(l); } switch (this.nodes.wrapper.classList.remove(...Object.values(this.CSS.placement)), u.placement) { case "top": this.placeTop(a, u); break; case "left": this.placeLeft(a, u); break; case "right": this.placeRight(a, u); break; case "bottom": default: this.placeBottom(a, u); } u && u.delay ? this.showingTimeout = setTimeout(() => { this.nodes.wrapper.classList.add(this.CSS.tooltipShown), this.showed = !0; }, u.delay) : (this.nodes.wrapper.classList.add(this.CSS.tooltipShown), this.showed = !0); } hide(a = !1) { if (this.hidingDelay && !a) return this.hidingTimeout && clearTimeout(this.hidingTimeout), void (this.hidingTimeout = setTimeout(() => { this.hide(!0); }, this.hidingDelay)); this.nodes.wrapper.classList.remove(this.CSS.tooltipShown), this.showed = !1, this.showingTimeout && clearTimeout(this.showingTimeout); } onHover(a, l, c) { a.addEventListener("mouseenter", () => { this.show(a, l, c); }), a.addEventListener("mouseleave", () => { this.hide(); }); } destroy() { this.nodes.wrapper.remove(), window.removeEventListener("scroll", this.handleWindowScroll); } prepare() { this.nodes.wrapper = this.make("div", this.CSS.tooltip), this.nodes.content = this.make("div", this.CSS.tooltipContent), this.append(this.nodes.wrapper, this.nodes.content), this.append(document.body, this.nodes.wrapper); } loadStyles() { const a = "codex-tooltips-style"; if (document.getElementById(a)) return; const l = i(2), c = this.make("style", null, { textContent: l.toString(), id: a }); this.prepend(document.head, c); } placeBottom(a, l) { const c = a.getBoundingClientRect(), u = c.left + a.clientWidth / 2 - this.nodes.wrapper.offsetWidth / 2, h = c.bottom + window.pageYOffset + this.offsetTop + l.marginTop; this.applyPlacement("bottom", u, h); } placeTop(a, l) { const c = a.getBoundingClientRect(), u = c.left + a.clientWidth / 2 - this.nodes.wrapper.offsetWidth / 2, h = c.top + window.pageYOffset - this.nodes.wrapper.clientHeight - this.offsetTop; this.applyPlacement("top", u, h); } placeLeft(a, l) { const c = a.getBoundingClientRect(), u = c.left - this.nodes.wrapper.offsetWidth - this.offsetLeft - l.marginLeft, h = c.top + window.pageYOffset + a.clientHeight / 2 - this.nodes.wrapper.offsetHeight / 2; this.applyPlacement("left", u, h); } placeRight(a, l) { const c = a.getBoundingClientRect(), u = c.right + this.offsetRight + l.marginRight, h = c.top + window.pageYOffset + a.clientHeight / 2 - this.nodes.wrapper.offsetHeight / 2; this.applyPlacement("right", u, h); } applyPlacement(a, l, c) { this.nodes.wrapper.classList.add(this.CSS.placement[a]), this.nodes.wrapper.style.left = l + "px", this.nodes.wrapper.style.top = c + "px"; } make(a, l = null, c = {}) { const u = document.createElement(a); Array.isArray(l) ? u.classList.add(...l) : l && u.classList.add(l); for (const h in c) c.hasOwnProperty(h) && (u[h] = c[h]); return u; } append(a, l) { Array.isArray(l) ? l.forEach((c) => a.appendChild(c)) : a.appendChild(l); } prepend(a, l) { Array.isArray(l) ? (l = l.reverse()).forEach((c) => a.prepend(c)) : a.prepend(l); } } }, function(t, o) { t.exports = `.ct{z-index:999;opacity:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none;-webkit-transition:opacity 50ms ease-in,-webkit-transform 70ms cubic-bezier(.215,.61,.355,1);transition:opacity 50ms ease-in,-webkit-transform 70ms cubic-bezier(.215,.61,.355,1);transition:opacity 50ms ease-in,transform 70ms cubic-bezier(.215,.61,.355,1);transition:opacity 50ms ease-in,transform 70ms cubic-bezier(.215,.61,.355,1),-webkit-transform 70ms cubic-bezier(.215,.61,.355,1);will-change:opacity,top,left;-webkit-box-shadow:0 8px 12px 0 rgba(29,32,43,.17),0 4px 5px -3px rgba(5,6,12,.49);box-shadow:0 8px 12px 0 rgba(29,32,43,.17),0 4px 5px -3px rgba(5,6,12,.49);border-radius:9px}.ct,.ct:before{position:absolute;top:0;left:0}.ct:before{content:"";bottom:0;right:0;background-color:#1d202b;z-index:-1;border-radius:4px}@supports(-webkit-mask-box-image:url("")){.ct:before{border-radius:0;-webkit-mask-box-image:url('data:image/svg+xml;charset=utf-8,') 48% 41% 37.9% 53.3%}}@media (--mobile){.ct{display:none}}.ct__content{padding:6px 10px;color:#cdd1e0;font-size:12px;text-align:center;letter-spacing:.02em;line-height:1em}.ct:after{content:"";width:8px;height:8px;position:absolute;background-color:#1d202b;z-index:-1}.ct--bottom{-webkit-transform:translateY(5px);transform:translateY(5px)}.ct--bottom:after{top:-3px;left:50%;-webkit-transform:translateX(-50%) rotate(-45deg);transform:translateX(-50%) rotate(-45deg)}.ct--top{-webkit-transform:translateY(-5px);transform:translateY(-5px)}.ct--top:after{top:auto;bottom:-3px;left:50%;-webkit-transform:translateX(-50%) rotate(-45deg);transform:translateX(-50%) rotate(-45deg)}.ct--left{-webkit-transform:translateX(-5px);transform:translateX(-5px)}.ct--left:after{top:50%;left:auto;right:0;-webkit-transform:translate(41.6%,-50%) rotate(-45deg);transform:translate(41.6%,-50%) rotate(-45deg)}.ct--right{-webkit-transform:translateX(5px);transform:translateX(5px)}.ct--right:after{top:50%;left:0;-webkit-transform:translate(-41.6%,-50%) rotate(-45deg);transform:translate(-41.6%,-50%) rotate(-45deg)}.ct--shown{opacity:1;-webkit-transform:none;transform:none}`; }]).default; }); })(ko); const vo = /* @__PURE__ */ xe(_e); class Fe { constructor() { this.lib = new vo(); } /** * Release the library */ destroy() { this.lib.destroy(); } /** * Shows tooltip on element with passed HTML content * * @param {HTMLElement} element - any HTML element in DOM * @param content - tooltip's content * @param options - showing settings */ show(e, t, o) { this.lib.show(e, t, o); } /** * Hides tooltip * * @param skipHidingDelay — pass true to immediately hide the tooltip */ hide(e = !1) { this.lib.hide(e); } /** * Binds 'mouseenter' and 'mouseleave' events that shows/hides the Tooltip * * @param {HTMLElement} element - any HTML element in DOM * @param content - tooltip's content * @param options - showing settings */ onHover(e, t, o) { this.lib.onHover(e, t, o); } } class xo extends S { /** * @class * @param moduleConfiguration - Module Configuration * @param moduleConfiguration.config - Editor's config * @param moduleConfiguration.eventsDispatcher - Editor's event dispatcher */ constructor({ config: e, eventsDispatcher: t }) { super({ config: e, eventsDispatcher: t }), this.tooltip = new Fe(); } /** * Destroy Module */ destroy() { this.tooltip.destroy(); } /** * Available methods */ get methods() { return { show: (e, t, o) => this.show(e, t, o), hide: () => this.hide(), onHover: (e, t, o) => this.onHover(e, t, o) }; } /** * Method show tooltip on element with passed HTML content * * @param {HTMLElement} element - element on which tooltip should be shown * @param {TooltipContent} content - tooltip content * @param {TooltipOptions} options - tooltip options */ show(e, t, o) { this.tooltip.show(e, t, o); } /** * Method hides tooltip on HTML page */ hide() { this.tooltip.hide(); } /** * Decorator for showing Tooltip by mouseenter/mouseleave * * @param {HTMLElement} element - element on which tooltip should be shown * @param {TooltipContent} content - tooltip content * @param {TooltipOptions} options - tooltip options */ onHover(e, t, o) { this.tooltip.onHover(e, t, o); } } class wo extends S { /** * Available methods / getters */ get methods() { return { nodes: this.editorNodes /** * There can be added some UI methods, like toggleThinMode() etc */ }; } /** * Exported classes */ get editorNodes() { return { /** * Top-level editor instance wrapper */ wrapper: this.Editor.UI.nodes.wrapper, /** * Element that holds all the Blocks */ redactor: this.Editor.UI.nodes.redactor }; } } function ut(s, e) { const t = {}; return Object.entries(s).forEach(([o, i]) => { if (j(i)) { const n = e ? `${e}.${o}` : o; Object.values(i).every((a) => J(a)) ? t[o] = n : t[o] = ut(i, n); return; } t[o] = i; }), t; } const X = ut(rt); function yo(s, e) { const t = {}; return Object.keys(s).forEach((o) => { const i = e[o]; i !== void 0 ? t[i] = s[o] : t[o] = s[o]; }), t; } const Eo = '', pt = '', Bo = '', Co = '', To = '', So = '', qe = '', Io = '', Mo = '', Lo = '', Oo = ''; class P { /** * Constructs popover item instance * * @param params - popover item construction params */ constructor(e) { this.nodes = { root: null, icon: null }, this.confirmationState = null, this.removeSpecialFocusBehavior = () => { this.nodes.root.classList.remove(P.CSS.noFocus); }, this.removeSpecialHoverBehavior = () => { this.nodes.root.classList.remove(P.CSS.noHover); }, this.onErrorAnimationEnd = () => { this.nodes.icon.classList.remove(P.CSS.wobbleAnimation), this.nodes.icon.removeEventListener("animationend", this.onErrorAnimationEnd); }, this.params = e, this.nodes.root = this.make(e); } /** * True if item is disabled and hence not clickable */ get isDisabled() { return this.params.isDisabled; } /** * Exposes popover item toggle parameter */ get toggle() { return this.params.toggle; } /** * Item title */ get title() { return this.params.title; } /** * True if popover should close once item is activated */ get closeOnActivate() { return this.params.closeOnActivate; } /** * True if confirmation state is enabled for popover item */ get isConfirmationStateEnabled() { return this.confirmationState !== null; } /** * True if item is focused in keyboard navigation process */ get isFocused() { return this.nodes.root.classList.contains(P.CSS.focused); } /** * Popover item CSS classes */ static get CSS() { return { container: "ce-popover-item", title: "ce-popover-item__title", secondaryTitle: "ce-popover-item__secondary-title", icon: "ce-popover-item__icon", active: "ce-popover-item--active", disabled: "ce-popover-item--disabled", focused: "ce-popover-item--focused", hidden: "ce-popover-item--hidden", confirmationState: "ce-popover-item--confirmation", noHover: "ce-popover-item--no-hover", noFocus: "ce-popover-item--no-focus", wobbleAnimation: "wobble" }; } /** * Returns popover item root element */ getElement() { return this.nodes.root; } /** * Called on popover item click */ handleClick() { if (this.isConfirmationStateEnabled) { this.activateOrEnableConfirmationMode(this.confirmationState); return; } this.activateOrEnableConfirmationMode(this.params); } /** * Toggles item active state * * @param isActive - true if item should strictly should become active */ toggleActive(e) { this.nodes.root.classList.toggle(P.CSS.active, e); } /** * Toggles item hidden state * * @param isHidden - true if item should be hidden */ toggleHidden(e) { this.nodes.root.classList.toggle(P.CSS.hidden, e); } /** * Resets popover item to its original state */ reset() { this.isConfirmationStateEnabled && this.disableConfirmationMode(); } /** * Method called once item becomes focused during keyboard navigation */ onFocus() { this.disableSpecialHoverAndFocusBehavior(); } /** * Constructs HTML element corresponding to popover item params * * @param params - item construction params */ make(e) { const t = d.make("div", P.CSS.container); return e.name && (t.dataset.itemName = e.name), this.nodes.icon = d.make("div", P.CSS.icon, { innerHTML: e.icon || To }), t.appendChild(this.nodes.icon), t.appendChild(d.make("div", P.CSS.title, { innerHTML: e.title || "" })), e.secondaryLabel && t.appendChild(d.make("div", P.CSS.secondaryTitle, { textContent: e.secondaryLabel })), e.isActive && t.classList.add(P.CSS.active), e.isDisabled && t.classList.add(P.CSS.disabled), t; } /** * Activates confirmation mode for the item. * * @param newState - new popover item params that should be applied */ enableConfirmationMode(e) { const t = { ...this.params, ...e, confirmation: e.confirmation }, o = this.make(t); this.nodes.root.innerHTML = o.innerHTML, this.nodes.root.classList.add(P.CSS.confirmationState), this.confirmationState = e, this.enableSpecialHoverAndFocusBehavior(); } /** * Returns item to its original state */ disableConfirmationMode() { const e = this.make(this.params); this.nodes.root.innerHTML = e.innerHTML, this.nodes.root.classList.remove(P.CSS.confirmationState), this.confirmationState = null, this.disableSpecialHoverAndFocusBehavior(); } /** * Enables special focus and hover behavior for item in confirmation state. * This is needed to prevent item from being highlighted as hovered/focused just after click. */ enableSpecialHoverAndFocusBehavior() { this.nodes.root.classList.add(P.CSS.noHover), this.nodes.root.classList.add(P.CSS.noFocus), this.nodes.root.addEventListener("mouseleave", this.removeSpecialHoverBehavior, { once: !0 }); } /** * Disables special focus and hover behavior */ disableSpecialHoverAndFocusBehavior() { this.removeSpecialFocusBehavior(), this.removeSpecialHoverBehavior(), this.nodes.root.removeEventListener("mouseleave", this.removeSpecialHoverBehavior); } /** * Executes item's onActivate callback if the item has no confirmation configured * * @param item - item to activate or bring to confirmation mode */ activateOrEnableConfirmationMode(e) { if (e.confirmation === void 0) try { e.onActivate(e), this.disableConfirmationMode(); } catch { this.animateError(); } else this.enableConfirmationMode(e.confirmation); } /** * Animates item which symbolizes that error occured while executing 'onActivate()' callback */ animateError() { this.nodes.icon.classList.contains(P.CSS.wobbleAnimation) || (this.nodes.icon.classList.add(P.CSS.wobbleAnimation), this.nodes.icon.addEventListener("animationend", this.onErrorAnimationEnd)); } } const ce = class { /** * @param {HTMLElement[]} nodeList — the list of iterable HTML-items * @param {string} focusedCssClass - user-provided CSS-class that will be set in flipping process */ constructor(s, e) { this.cursor = -1, this.items = [], this.items = s || [], this.focusedCssClass = e; } /** * Returns Focused button Node * * @returns {HTMLElement} */ get currentItem() { return this.cursor === -1 ? null : this.items[this.cursor]; } /** * Sets cursor to specified position * * @param cursorPosition - new cursor position */ setCursor(s) { s < this.items.length && s >= -1 && (this.dropCursor(), this.cursor = s, this.items[this.cursor].classList.add(this.focusedCssClass)); } /** * Sets items. Can be used when iterable items changed dynamically * * @param {HTMLElement[]} nodeList - nodes to iterate */ setItems(s) { this.items = s; } /** * Sets cursor next to the current */ next() { this.cursor = this.leafNodesAndReturnIndex(ce.directions.RIGHT); } /** * Sets cursor before current */ previous() { this.cursor = this.leafNodesAndReturnIndex(ce.directions.LEFT); } /** * Sets cursor to the default position and removes CSS-class from previously focused item */ dropCursor() { this.cursor !== -1 && (this.items[this.cursor].classList.remove(this.focusedCssClass), this.cursor = -1); } /** * Leafs nodes inside the target list from active element * * @param {string} direction - leaf direction. Can be 'left' or 'right' * @returns {number} index of focused node */ leafNodesAndReturnIndex(s) { if (this.items.length === 0) return this.cursor; let e = this.cursor; return e === -1 ? e = s === ce.directions.RIGHT ? -1 : 0 : this.items[e].classList.remove(this.focusedCssClass), s === ce.directions.RIGHT ? e = (e + 1) % this.items.length : e = (this.items.length + e - 1) % this.items.length, d.canSetCaret(this.items[e]) && oe(() => m.setCursor(this.items[e]), 50)(), this.items[e].classList.add(this.focusedCssClass), e; } }; let ne = ce; ne.directions = { RIGHT: "right", LEFT: "left" }; class G { /** * @param {FlipperOptions} options - different constructing settings */ constructor(e) { this.iterator = null, this.activated = !1, this.flipCallbacks = [], this.onKeyDown = (t) => { if (this.isEventReadyForHandling(t)) switch (G.usedKeys.includes(t.keyCode) && t.preventDefault(), t.keyCode) { case B.TAB: this.handleTabPress(t); break; case B.LEFT: case B.UP: this.flipLeft(); break; case B.RIGHT: case B.DOWN: this.flipRight(); break; case B.ENTER: this.handleEnterPress(t); break; } }, this.iterator = new ne(e.items, e.focusedItemClass), this.activateCallback = e.activateCallback, this.allowedKeys = e.allowedKeys || G.usedKeys; } /** * True if flipper is currently activated */ get isActivated() { return this.activated; } /** * Array of keys (codes) that is handled by Flipper * Used to: * - preventDefault only for this keys, not all keydowns (@see constructor) * - to skip external behaviours only for these keys, when filler is activated (@see BlockEvents@arrowRightAndDown) */ static get usedKeys() { return [ B.TAB, B.LEFT, B.RIGHT, B.ENTER, B.UP, B.DOWN ]; } /** * Active tab/arrows handling by flipper * * @param items - Some modules (like, InlineToolbar, BlockSettings) might refresh buttons dynamically * @param cursorPosition - index of the item that should be focused once flipper is activated */ activate(e, t) { this.activated = !0, e && this.iterator.setItems(e), t !== void 0 && this.iterator.setCursor(t), document.addEventListener("keydown", this.onKeyDown, !0); } /** * Disable tab/arrows handling by flipper */ deactivate() { this.activated = !1, this.dropCursor(), document.removeEventListener("keydown", this.onKeyDown); } /** * Focus first item */ focusFirst() { this.dropCursor(), this.flipRight(); } /** * Focuses previous flipper iterator item */ flipLeft() { this.iterator.previous(), this.flipCallback(); } /** * Focuses next flipper iterator item */ flipRight() { this.iterator.next(), this.flipCallback(); } /** * Return true if some button is focused */ hasFocus() { return !!this.iterator.currentItem; } /** * Registeres function that should be executed on each navigation action * * @param cb - function to execute */ onFlip(e) { this.flipCallbacks.push(e); } /** * Unregisteres function that is executed on each navigation action * * @param cb - function to stop executing */ removeOnFlip(e) { this.flipCallbacks = this.flipCallbacks.filter((t) => t !== e); } /** * Drops flipper's iterator cursor * * @see DomIterator#dropCursor */ dropCursor() { this.iterator.dropCursor(); } /** * This function is fired before handling flipper keycodes * The result of this function defines if it is need to be handled or not * * @param {KeyboardEvent} event - keydown keyboard event * @returns {boolean} */ isEventReadyForHandling(e) { return this.activated && this.allowedKeys.includes(e.keyCode); } /** * When flipper is activated tab press will leaf the items * * @param {KeyboardEvent} event - tab keydown event */ handleTabPress(e) { switch (e.shiftKey ? ne.directions.LEFT : ne.directions.RIGHT) { case ne.directions.RIGHT: this.flipRight(); break; case ne.directions.LEFT: this.flipLeft(); break; } } /** * Enter press will click current item if flipper is activated * * @param {KeyboardEvent} event - enter keydown event */ handleEnterPress(e) { this.activated && (this.iterator.currentItem && (e.stopPropagation(), e.preventDefault(), this.iterator.currentItem.click()), D(this.activateCallback) && this.activateCallback(this.iterator.currentItem)); } /** * Fired after flipping in any direction */ flipCallback() { this.iterator.currentItem && this.iterator.currentItem.scrollIntoViewIfNeeded(), this.flipCallbacks.forEach((e) => e()); } } class ue { /** * Styles */ static get CSS() { return { wrapper: "cdx-search-field", icon: "cdx-search-field__icon", input: "cdx-search-field__input" }; } /** * @param options - available config * @param options.items - searchable items list * @param options.onSearch - search callback * @param options.placeholder - input placeholder */ constructor({ items: e, onSearch: t, placeholder: o }) { this.listeners = new Re(), this.items = e, this.onSearch = t, this.render(o); } /** * Returns search field element */ getElement() { return this.wrapper; } /** * Sets focus to the input */ focus() { this.input.focus(); } /** * Clears search query and results */ clear() { this.input.value = "", this.searchQuery = "", this.onSearch("", this.foundItems); } /** * Clears memory */ destroy() { this.listeners.removeAll(); } /** * Creates the search field * * @param placeholder - input placeholder */ render(e) { this.wrapper = d.make("div", ue.CSS.wrapper); const t = d.make("div", ue.CSS.icon, { innerHTML: Lo }); this.input = d.make("input", ue.CSS.input, { placeholder: e }), this.wrapper.appendChild(t), this.wrapper.appendChild(this.input), this.listeners.on(this.input, "input", () => { this.searchQuery = this.input.value, this.onSearch(this.searchQuery, this.foundItems); }); } /** * Returns list of found items for the current search query */ get foundItems() { return this.items.filter((e) => this.checkItem(e)); } /** * Contains logic for checking whether passed item conforms the search query * * @param item - item to be checked */ checkItem(e) { var i; const t = ((i = e.title) == null ? void 0 : i.toLowerCase()) || "", o = this.searchQuery.toLowerCase(); return t.includes(o); } } const de = class { /** * Locks body element scroll */ lock() { Ge ? this.lockHard() : document.body.classList.add(de.CSS.scrollLocked); } /** * Unlocks body element scroll */ unlock() { Ge ? this.unlockHard() : document.body.classList.remove(de.CSS.scrollLocked); } /** * Locks scroll in a hard way (via setting fixed position to body element) */ lockHard() { this.scrollPosition = window.pageYOffset, document.documentElement.style.setProperty( "--window-scroll-offset", `${this.scrollPosition}px` ), document.body.classList.add(de.CSS.scrollLockedHard); } /** * Unlocks hard scroll lock */ unlockHard() { document.body.classList.remove(de.CSS.scrollLockedHard), this.scrollPosition !== null && window.scrollTo(0, this.scrollPosition), this.scrollPosition = null; } }; let ft = de; ft.CSS = { scrollLocked: "ce-scroll-locked", scrollLockedHard: "ce-scroll-locked--hard" }; var _o = Object.defineProperty, Ao = Object.getOwnPropertyDescriptor, No = (s, e, t, o) => { for (var i = o > 1 ? void 0 : o ? Ao(e, t) : e, n = s.length - 1, r; n >= 0; n--) (r = s[n]) && (i = (o ? r(e, t, i) : r(i)) || i); return o && i && _o(e, t, i), i; }, fe = /* @__PURE__ */ ((s) => (s.Close = "close", s))(fe || {}); const z = class extends we { /** * Constructs the instance * * @param params - popover construction params */ constructor(s) { super(), this.scopeElement = document.body, this.listeners = new Re(), this.scrollLocker = new ft(), this.nodes = { wrapper: null, popover: null, nothingFoundMessage: null, customContent: null, items: null, overlay: null }, this.messages = { nothingFound: "Nothing found", search: "Search" }, this.onFlip = () => { this.items.find((t) => t.isFocused).onFocus(); }, this.items = s.items.map((e) => new P(e)), s.scopeElement !== void 0 && (this.scopeElement = s.scopeElement), s.messages && (this.messages = { ...this.messages, ...s.messages }), s.customContentFlippableItems && (this.customContentFlippableItems = s.customContentFlippableItems), this.make(), s.customContent && this.addCustomContent(s.customContent), s.searchable && this.addSearch(), this.initializeFlipper(); } /** * Popover CSS classes */ static get CSS() { return { popover: "ce-popover", popoverOpenTop: "ce-popover--open-top", popoverOpened: "ce-popover--opened", search: "ce-popover__search", nothingFoundMessage: "ce-popover__nothing-found-message", nothingFoundMessageDisplayed: "ce-popover__nothing-found-message--displayed", customContent: "ce-popover__custom-content", customContentHidden: "ce-popover__custom-content--hidden", items: "ce-popover__items", overlay: "ce-popover__overlay", overlayHidden: "ce-popover__overlay--hidden" }; } /** * Returns HTML element corresponding to the popover */ getElement() { return this.nodes.wrapper; } /** * Returns true if some item inside popover is focused */ hasFocus() { return this.flipper.hasFocus(); } /** * Open popover */ show() { this.shouldOpenBottom || (this.nodes.popover.style.setProperty("--popover-height", this.height + "px"), this.nodes.popover.classList.add(z.CSS.popoverOpenTop)), this.nodes.overlay.classList.remove(z.CSS.overlayHidden), this.nodes.popover.classList.add(z.CSS.popoverOpened), this.flipper.activate(this.flippableElements), this.search !== void 0 && setTimeout(() => { this.search.focus(); }, 100), ee() && this.scrollLocker.lock(); } /** * Closes popover */ hide() { this.nodes.popover.classList.remove(z.CSS.popoverOpened), this.nodes.popover.classList.remove(z.CSS.popoverOpenTop), this.nodes.overlay.classList.add(z.CSS.overlayHidden), this.flipper.deactivate(), this.items.forEach((s) => s.reset()), this.search !== void 0 && this.search.clear(), ee() && this.scrollLocker.unlock(), this.emit( "close" /* Close */ ); } /** * Clears memory */ destroy() { this.flipper.deactivate(), this.listeners.removeAll(), ee() && this.scrollLocker.unlock(); } /** * Constructs HTML element corresponding to popover */ make() { this.nodes.popover = d.make("div", [z.CSS.popover]), this.nodes.nothingFoundMessage = d.make("div", [z.CSS.nothingFoundMessage], { textContent: this.messages.nothingFound }), this.nodes.popover.appendChild(this.nodes.nothingFoundMessage), this.nodes.items = d.make("div", [z.CSS.items]), this.items.forEach((s) => { this.nodes.items.appendChild(s.getElement()); }), this.nodes.popover.appendChild(this.nodes.items), this.listeners.on(this.nodes.popover, "click", (s) => { const e = this.getTargetItem(s); e !== void 0 && this.handleItemClick(e); }), this.nodes.wrapper = d.make("div"), this.nodes.overlay = d.make("div", [z.CSS.overlay, z.CSS.overlayHidden]), this.listeners.on(this.nodes.overlay, "click", () => { this.hide(); }), this.nodes.wrapper.appendChild(this.nodes.overlay), this.nodes.wrapper.appendChild(this.nodes.popover); } /** * Adds search to the popover */ addSearch() { this.search = new ue({ items: this.items, placeholder: this.messages.search, onSearch: (e, t) => { this.items.forEach((i) => { const n = !t.includes(i); i.toggleHidden(n); }), this.toggleNothingFoundMessage(t.length === 0), this.toggleCustomContent(e !== ""); const o = e === "" ? this.flippableElements : t.map((i) => i.getElement()); this.flipper.isActivated && (this.flipper.deactivate(), this.flipper.activate(o)); } }); const s = this.search.getElement(); s.classList.add(z.CSS.search), this.nodes.popover.insertBefore(s, this.nodes.popover.firstChild); } /** * Adds custom html content to the popover * * @param content - html content to append */ addCustomContent(s) { this.nodes.customContent = s, this.nodes.customContent.classList.add(z.CSS.customContent), this.nodes.popover.insertBefore(s, this.nodes.popover.firstChild); } /** * Retrieves popover item that is the target of the specified event * * @param event - event to retrieve popover item from */ getTargetItem(s) { return this.items.find((e) => s.composedPath().includes(e.getElement())); } /** * Handles item clicks * * @param item - item to handle click of */ handleItemClick(s) { s.isDisabled || (this.items.filter((e) => e !== s).forEach((e) => e.reset()), s.handleClick(), this.toggleItemActivenessIfNeeded(s), s.closeOnActivate && this.hide()); } /** * Creates Flipper instance which allows to navigate between popover items via keyboard */ initializeFlipper() { this.flipper = new G({ items: this.flippableElements, focusedItemClass: P.CSS.focused, allowedKeys: [ B.TAB, B.UP, B.DOWN, B.ENTER ] }), this.flipper.onFlip(this.onFlip); } /** * Returns list of elements available for keyboard navigation. * Contains both usual popover items elements and custom html content. */ get flippableElements() { const s = this.items.map((t) => t.getElement()); return (this.customContentFlippableItems || []).concat(s); } get height() { let s = 0; if (this.nodes.popover === null) return s; const e = this.nodes.popover.cloneNode(!0); return e.style.visibility = "hidden", e.style.position = "absolute", e.style.top = "-1000px", e.classList.add(z.CSS.popoverOpened), document.body.appendChild(e), s = e.offsetHeight, e.remove(), s; } /** * Checks if popover should be opened bottom. * It should happen when there is enough space below or not enough space above */ get shouldOpenBottom() { const s = this.nodes.popover.getBoundingClientRect(), e = this.scopeElement.getBoundingClientRect(), t = this.height, o = s.top + t, i = s.top - t, n = Math.min(window.innerHeight, e.bottom); return i < e.top || o <= n; } /** * Toggles nothing found message visibility * * @param isDisplayed - true if the message should be displayed */ toggleNothingFoundMessage(s) { this.nodes.nothingFoundMessage.classList.toggle(z.CSS.nothingFoundMessageDisplayed, s); } /** * Toggles custom content visibility * * @param isDisplayed - true if custom content should be displayed */ toggleCustomContent(s) { var e; (e = this.nodes.customContent) == null || e.classList.toggle(z.CSS.customContentHidden, s); } /** * - Toggles item active state, if clicked popover item has property 'toggle' set to true. * * - Performs radiobutton-like behavior if the item has property 'toggle' set to string key. * (All the other items with the same key get inactive, and the item gets active) * * @param clickedItem - popover item that was clicked */ toggleItemActivenessIfNeeded(s) { if (s.toggle === !0 && s.toggleActive(), typeof s.toggle == "string") { const e = this.items.filter((t) => t.toggle === s.toggle); if (e.length === 1) { s.toggleActive(); return; } e.forEach((t) => { t.toggleActive(t === s); }); } } }; let He = z; No([ ae ], He.prototype, "height", 1); class Ro extends S { constructor() { super(...arguments), this.opened = !1, this.selection = new m(), this.onPopoverClose = () => { this.close(); }; } /** * Module Posts * * @returns {{opened: string, closed: string}} */ get events() { return { opened: "block-settings-opened", closed: "block-settings-closed" }; } /** * Block Settings CSS */ get CSS() { return { settings: "ce-settings" }; } /** * Getter for inner popover's flipper instance * * @todo remove once BlockSettings becomes standalone non-module class */ get flipper() { var e; return (e = this.popover) == null ? void 0 : e.flipper; } /** * Panel with block settings with 2 sections: * - Tool's Settings * - Default Settings [Move, Remove, etc] */ make() { this.nodes.wrapper = d.make("div", [this.CSS.settings]); } /** * Destroys module */ destroy() { this.removeAllNodes(); } /** * Open Block Settings pane * * @param targetBlock - near which Block we should open BlockSettings */ open(e = this.Editor.BlockManager.currentBlock) { this.opened = !0, this.selection.save(), e.selected = !0, this.Editor.BlockSelection.clearCache(); const [t, o] = e.getTunes(); this.eventsDispatcher.emit(this.events.opened), this.popover = new He({ searchable: !0, items: t.map((i) => this.resolveTuneAliases(i)), customContent: o, customContentFlippableItems: this.getControls(o), scopeElement: this.Editor.API.methods.ui.nodes.redactor, messages: { nothingFound: $.ui(X.ui.popover, "Nothing found"), search: $.ui(X.ui.popover, "Filter") } }), this.popover.on(fe.Close, this.onPopoverClose), this.nodes.wrapper.append(this.popover.getElement()), this.popover.show(); } /** * Returns root block settings element */ getElement() { return this.nodes.wrapper; } /** * Close Block Settings pane */ close() { this.opened = !1, m.isAtEditor || this.selection.restore(), this.selection.clearSaved(), !this.Editor.CrossBlockSelection.isCrossBlockSelectionStarted && this.Editor.BlockManager.currentBlock && (this.Editor.BlockManager.currentBlock.selected = !1), this.eventsDispatcher.emit(this.events.closed), this.popover && (this.popover.off(fe.Close, this.onPopoverClose), this.popover.destroy(), this.popover.getElement().remove(), this.popover = null); } /** * Returns list of buttons and inputs inside specified container * * @param container - container to query controls inside of */ getControls(e) { const { StylesAPI: t } = this.Editor, o = e.querySelectorAll( `.${t.classes.settingsButton}, ${d.allInputsSelector}` ); return Array.from(o); } /** * Resolves aliases in tunes menu items * * @param item - item with resolved aliases */ resolveTuneAliases(e) { const t = yo(e, { label: "title" }); return e.confirmation && (t.confirmation = this.resolveTuneAliases(e.confirmation)), t; } } class Y extends S { constructor() { super(...arguments), this.opened = !1, this.tools = [], this.flipper = null, this.togglingCallback = null; } /** * CSS getter */ static get CSS() { return { conversionToolbarWrapper: "ce-conversion-toolbar", conversionToolbarShowed: "ce-conversion-toolbar--showed", conversionToolbarTools: "ce-conversion-toolbar__tools", conversionToolbarLabel: "ce-conversion-toolbar__label", conversionTool: "ce-conversion-tool", conversionToolHidden: "ce-conversion-tool--hidden", conversionToolIcon: "ce-conversion-tool__icon", conversionToolFocused: "ce-conversion-tool--focused", conversionToolActive: "ce-conversion-tool--active" }; } /** * Create UI of Conversion Toolbar */ make() { this.nodes.wrapper = d.make("div", [ Y.CSS.conversionToolbarWrapper, ...this.isRtl ? [this.Editor.UI.CSS.editorRtlFix] : [] ]), this.nodes.tools = d.make("div", Y.CSS.conversionToolbarTools); const e = d.make("div", Y.CSS.conversionToolbarLabel, { textContent: $.ui(X.ui.inlineToolbar.converter, "Convert to") }); return this.addTools(), this.enableFlipper(), d.append(this.nodes.wrapper, e), d.append(this.nodes.wrapper, this.nodes.tools), this.nodes.wrapper; } /** * Deactivates flipper and removes all nodes */ destroy() { this.flipper && (this.flipper.deactivate(), this.flipper = null), this.removeAllNodes(); } /** * Toggle conversion dropdown visibility * * @param {Function} [togglingCallback] — callback that will accept opening state */ toggle(e) { this.opened ? this.close() : this.open(), D(e) && (this.togglingCallback = e); } /** * Shows Conversion Toolbar */ open() { this.filterTools(), this.opened = !0, this.nodes.wrapper.classList.add(Y.CSS.conversionToolbarShowed), window.requestAnimationFrame(() => { this.flipper.activate(this.tools.map((e) => e.button).filter((e) => !e.classList.contains(Y.CSS.conversionToolHidden))), this.flipper.focusFirst(), D(this.togglingCallback) && this.togglingCallback(!0); }); } /** * Closes Conversion Toolbar */ close() { this.opened = !1, this.flipper.deactivate(), this.nodes.wrapper.classList.remove(Y.CSS.conversionToolbarShowed), D(this.togglingCallback) && this.togglingCallback(!1); } /** * Returns true if it has more than one tool available for convert in */ hasTools() { return this.tools.length === 1 ? this.tools[0].name !== this.config.defaultBlock : !0; } /** * Replaces one Block with another * For that Tools must provide import/export methods * * @param {string} replacingToolName - name of Tool which replaces current * @param blockDataOverrides - Block data overrides. Could be passed in case if Multiple Toolbox items specified */ async replaceWithBlock(e, t) { const o = this.Editor.BlockManager.currentBlock.tool, n = (await this.Editor.BlockManager.currentBlock.save()).data, r = this.Editor.Tools.blockTools.get(e); let a = ""; const l = o.conversionConfig.export; if (D(l)) a = l(n); else if (J(l)) a = n[l]; else { T("Conversion «export» property must be a string or function. String means key of saved data object to export. Function should export processed string to export."); return; } const c = Z( a, r.sanitizeConfig ); let u = {}; const h = r.conversionConfig.import; if (D(h)) u = h(c); else if (J(h)) u[h] = c; else { T("Conversion «import» property must be a string or function. String means key of tool data to import. Function accepts a imported string and return composed tool data."); return; } t && (u = Object.assign(u, t)), this.Editor.BlockManager.replace({ tool: e, data: u }), this.Editor.BlockSelection.clearSelection(), this.close(), this.Editor.InlineToolbar.close(), oe(() => { this.Editor.Caret.setToBlock(this.Editor.BlockManager.currentBlock); }, 10)(); } /** * Iterates existing Tools and inserts to the ConversionToolbar * if tools have ability to import */ addTools() { const e = this.Editor.Tools.blockTools; Array.from(e.entries()).forEach(([t, o]) => { const i = o.conversionConfig; !i || !i.import || o.toolbox.forEach( (n) => this.addToolIfValid(t, n) ); }); } /** * Inserts a tool to the ConversionToolbar if the tool's toolbox config is valid * * @param name - tool's name * @param toolboxSettings - tool's single toolbox setting */ addToolIfValid(e, t) { V(t) || !t.icon || this.addTool(e, t); } /** * Add tool to the Conversion Toolbar * * @param toolName - name of Tool to add * @param toolboxItem - tool's toolbox item data */ addTool(e, t) { const o = d.make("div", [Y.CSS.conversionTool]), i = d.make("div", [Y.CSS.conversionToolIcon]); o.dataset.tool = e, i.innerHTML = t.icon, d.append(o, i), d.append(o, d.text($.t(X.toolNames, t.title || ke(e)))), d.append(this.nodes.tools, o), this.tools.push({ name: e, button: o, toolboxItem: t }), this.listeners.on(o, "click", async () => { await this.replaceWithBlock(e, t.data); }); } /** * Hide current Tool and show others */ async filterTools() { const { currentBlock: e } = this.Editor.BlockManager, t = await e.getActiveToolboxEntry(); function o(i, n) { return i.icon === n.icon && i.title === n.title; } this.tools.forEach((i) => { let n = !1; if (t) { const r = o(t, i.toolboxItem); n = i.button.dataset.tool === e.name && r; } i.button.hidden = n, i.button.classList.toggle(Y.CSS.conversionToolHidden, n); }); } /** * Prepare Flipper to be able to leaf tools by arrows/tab */ enableFlipper() { this.flipper = new G({ focusedItemClass: Y.CSS.conversionToolFocused }); } } var Ae = {}, Do = { get exports() { return Ae; }, set exports(s) { Ae = s; } }; /*! * Library for handling keyboard shortcuts * @copyright CodeX (https://codex.so) * @license MIT * @author CodeX (https://codex.so) * @version 1.2.0 */ (function(s, e) { (function(t, o) { s.exports = o(); })(window, function() { return function(t) { var o = {}; function i(n) { if (o[n]) return o[n].exports; var r = o[n] = { i: n, l: !1, exports: {} }; return t[n].call(r.exports, r, r.exports, i), r.l = !0, r.exports; } return i.m = t, i.c = o, i.d = function(n, r, a) { i.o(n, r) || Object.defineProperty(n, r, { enumerable: !0, get: a }); }, i.r = function(n) { typeof Symbol < "u" && Symbol.toStringTag && Object.defineProperty(n, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(n, "__esModule", { value: !0 }); }, i.t = function(n, r) { if (1 & r && (n = i(n)), 8 & r || 4 & r && typeof n == "object" && n && n.__esModule) return n; var a = /* @__PURE__ */ Object.create(null); if (i.r(a), Object.defineProperty(a, "default", { enumerable: !0, value: n }), 2 & r && typeof n != "string") for (var l in n) i.d(a, l, function(c) { return n[c]; }.bind(null, l)); return a; }, i.n = function(n) { var r = n && n.__esModule ? function() { return n.default; } : function() { return n; }; return i.d(r, "a", r), r; }, i.o = function(n, r) { return Object.prototype.hasOwnProperty.call(n, r); }, i.p = "", i(i.s = 0); }([function(t, o, i) { function n(l, c) { for (var u = 0; u < c.length; u++) { var h = c[u]; h.enumerable = h.enumerable || !1, h.configurable = !0, "value" in h && (h.writable = !0), Object.defineProperty(l, h.key, h); } } function r(l, c, u) { return c && n(l.prototype, c), u && n(l, u), l; } i.r(o); var a = function() { function l(c) { var u = this; (function(h, f) { if (!(h instanceof f)) throw new TypeError("Cannot call a class as a function"); })(this, l), this.commands = {}, this.keys = {}, this.name = c.name, this.parseShortcutName(c.name), this.element = c.on, this.callback = c.callback, this.executeShortcut = function(h) { u.execute(h); }, this.element.addEventListener("keydown", this.executeShortcut, !1); } return r(l, null, [{ key: "supportedCommands", get: function() { return { SHIFT: ["SHIFT"], CMD: ["CMD", "CONTROL", "COMMAND", "WINDOWS", "CTRL"], ALT: ["ALT", "OPTION"] }; } }, { key: "keyCodes", get: function() { return { 0: 48, 1: 49, 2: 50, 3: 51, 4: 52, 5: 53, 6: 54, 7: 55, 8: 56, 9: 57, A: 65, B: 66, C: 67, D: 68, E: 69, F: 70, G: 71, H: 72, I: 73, J: 74, K: 75, L: 76, M: 77, N: 78, O: 79, P: 80, Q: 81, R: 82, S: 83, T: 84, U: 85, V: 86, W: 87, X: 88, Y: 89, Z: 90, BACKSPACE: 8, ENTER: 13, ESCAPE: 27, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, INSERT: 45, DELETE: 46, ".": 190 }; } }]), r(l, [{ key: "parseShortcutName", value: function(c) { c = c.split("+"); for (var u = 0; u < c.length; u++) { c[u] = c[u].toUpperCase(); var h = !1; for (var f in l.supportedCommands) if (l.supportedCommands[f].includes(c[u])) { h = this.commands[f] = !0; break; } h || (this.keys[c[u]] = !0); } for (var v in l.supportedCommands) this.commands[v] || (this.commands[v] = !1); } }, { key: "execute", value: function(c) { var u, h = { CMD: c.ctrlKey || c.metaKey, SHIFT: c.shiftKey, ALT: c.altKey }, f = !0; for (u in this.commands) this.commands[u] !== h[u] && (f = !1); var v, p = !0; for (v in this.keys) p = p && c.keyCode === l.keyCodes[v]; f && p && this.callback(c); } }, { key: "remove", value: function() { this.element.removeEventListener("keydown", this.executeShortcut); } }]), l; }(); o.default = a; }]).default; }); })(Do); const Po = /* @__PURE__ */ xe(Ae); class Fo { constructor() { this.registeredShortcuts = /* @__PURE__ */ new Map(); } /** * Register shortcut * * @param shortcut - shortcut options */ add(e) { if (this.findShortcut(e.on, e.name)) throw Error( `Shortcut ${e.name} is already registered for ${e.on}. Please remove it before add a new handler.` ); const o = new Po({ name: e.name, on: e.on, callback: e.handler }), i = this.registeredShortcuts.get(e.on) || []; this.registeredShortcuts.set(e.on, [...i, o]); } /** * Remove shortcut * * @param element - Element shortcut is set for * @param name - shortcut name */ remove(e, t) { const o = this.findShortcut(e, t); if (!o) return; o.remove(); const i = this.registeredShortcuts.get(e); this.registeredShortcuts.set(e, i.filter((n) => n !== o)); } /** * Get Shortcut instance if exist * * @param element - Element shorcut is set for * @param shortcut - shortcut name * @returns {number} index - shortcut index if exist */ findShortcut(e, t) { return (this.registeredShortcuts.get(e) || []).find(({ name: i }) => i === t); } } const re = new Fo(); var Ho = Object.defineProperty, zo = Object.getOwnPropertyDescriptor, gt = (s, e, t, o) => { for (var i = o > 1 ? void 0 : o ? zo(e, t) : e, n = s.length - 1, r; n >= 0; n--) (r = s[n]) && (i = (o ? r(e, t, i) : r(i)) || i); return o && i && Ho(e, t, i), i; }, be = /* @__PURE__ */ ((s) => (s.Opened = "toolbox-opened", s.Closed = "toolbox-closed", s.BlockAdded = "toolbox-block-added", s))(be || {}); const bt = class extends we { /** * Toolbox constructor * * @param options - available parameters * @param options.api - Editor API methods * @param options.tools - Tools available to check whether some of them should be displayed at the Toolbox or not */ constructor({ api: s, tools: e, i18nLabels: t }) { super(), this.opened = !1, this.nodes = { toolbox: null }, this.onPopoverClose = () => { this.opened = !1, this.emit( "toolbox-closed" /* Closed */ ); }, this.api = s, this.tools = e, this.i18nLabels = t; } /** * Returns True if Toolbox is Empty and nothing to show * * @returns {boolean} */ get isEmpty() { return this.toolsToBeDisplayed.length === 0; } /** * CSS styles * * @returns {Object} */ static get CSS() { return { toolbox: "ce-toolbox" }; } /** * Makes the Toolbox */ make() { return this.popover = new He({ scopeElement: this.api.ui.nodes.redactor, searchable: !0, messages: { nothingFound: this.i18nLabels.nothingFound, search: this.i18nLabels.filter }, items: this.toolboxItemsToBeDisplayed }), this.popover.on(fe.Close, this.onPopoverClose), this.enableShortcuts(), this.nodes.toolbox = this.popover.getElement(), this.nodes.toolbox.classList.add(bt.CSS.toolbox), this.nodes.toolbox; } /** * Returns true if the Toolbox has the Flipper activated and the Flipper has selected button */ hasFocus() { var s; return (s = this.popover) == null ? void 0 : s.hasFocus(); } /** * Destroy Module */ destroy() { var s; super.destroy(), this.nodes && this.nodes.toolbox && (this.nodes.toolbox.remove(), this.nodes.toolbox = null), this.removeAllShortcuts(), (s = this.popover) == null || s.off(fe.Close, this.onPopoverClose); } /** * Toolbox Tool's button click handler * * @param toolName - tool type to be activated * @param blockDataOverrides - Block data predefined by the activated Toolbox item */ toolButtonActivated(s, e) { this.insertNewBlock(s, e); } /** * Open Toolbox with Tools */ open() { var s; this.isEmpty || ((s = this.popover) == null || s.show(), this.opened = !0, this.emit( "toolbox-opened" /* Opened */ )); } /** * Close Toolbox */ close() { var s; (s = this.popover) == null || s.hide(), this.opened = !1, this.emit( "toolbox-closed" /* Closed */ ); } /** * Close Toolbox */ toggle() { this.opened ? this.close() : this.open(); } get toolsToBeDisplayed() { const s = []; return this.tools.forEach((e) => { e.toolbox && s.push(e); }), s; } get toolboxItemsToBeDisplayed() { const s = (e, t) => ({ icon: e.icon, title: $.t(X.toolNames, e.title || ke(t.name)), name: t.name, onActivate: () => { this.toolButtonActivated(t.name, e.data); }, secondaryLabel: t.shortcut ? nt(t.shortcut) : "" }); return this.toolsToBeDisplayed.reduce((e, t) => (Array.isArray(t.toolbox) ? t.toolbox.forEach((o) => { e.push(s(o, t)); }) : t.toolbox !== void 0 && e.push(s(t.toolbox, t)), e), []); } /** * Iterate all tools and enable theirs shortcuts if specified */ enableShortcuts() { this.toolsToBeDisplayed.forEach((s) => { const e = s.shortcut; e && this.enableShortcutForTool(s.name, e); }); } /** * Enable shortcut Block Tool implemented shortcut * * @param {string} toolName - Tool name * @param {string} shortcut - shortcut according to the ShortcutData Module format */ enableShortcutForTool(s, e) { re.add({ name: e, on: this.api.ui.nodes.redactor, handler: (t) => { t.preventDefault(), this.insertNewBlock(s); } }); } /** * Removes all added shortcuts * Fired when the Read-Only mode is activated */ removeAllShortcuts() { this.toolsToBeDisplayed.forEach((s) => { const e = s.shortcut; e && re.remove(this.api.ui.nodes.redactor, e); }); } /** * Inserts new block * Can be called when button clicked on Toolbox or by ShortcutData * * @param {string} toolName - Tool name * @param blockDataOverrides - predefined Block data */ async insertNewBlock(s, e) { const t = this.api.blocks.getCurrentBlockIndex(), o = this.api.blocks.getBlockByIndex(t); if (!o) return; const i = o.isEmpty ? t : t + 1; let n; if (e) { const a = await this.api.blocks.composeBlockData(s); n = Object.assign(a, e); } const r = this.api.blocks.insert( s, n, void 0, i, void 0, o.isEmpty ); r.call(q.APPEND_CALLBACK), this.api.caret.setToBlock(i), this.emit("toolbox-block-added", { block: r }), this.api.toolbar.close(); } }; let ze = bt; gt([ ae ], ze.prototype, "toolsToBeDisplayed", 1); gt([ ae ], ze.prototype, "toolboxItemsToBeDisplayed", 1); const mt = "block hovered"; class jo extends S { /** * @class * @param moduleConfiguration - Module Configuration * @param moduleConfiguration.config - Editor's config * @param moduleConfiguration.eventsDispatcher - Editor's event dispatcher */ constructor({ config: e, eventsDispatcher: t }) { super({ config: e, eventsDispatcher: t }), this.tooltip = new Fe(); } /** * CSS styles * * @returns {object} */ get CSS() { return { toolbar: "ce-toolbar", content: "ce-toolbar__content", actions: "ce-toolbar__actions", actionsOpened: "ce-toolbar__actions--opened", toolbarOpened: "ce-toolbar--opened", openedToolboxHolderModifier: "codex-editor--toolbox-opened", plusButton: "ce-toolbar__plus", plusButtonShortcut: "ce-toolbar__plus-shortcut", settingsToggler: "ce-toolbar__settings-btn", settingsTogglerHidden: "ce-toolbar__settings-btn--hidden" }; } /** * Returns the Toolbar opening state * * @returns {boolean} */ get opened() { return this.nodes.wrapper.classList.contains(this.CSS.toolbarOpened); } /** * Public interface for accessing the Toolbox */ get toolbox() { return { opened: this.toolboxInstance.opened, close: () => { this.toolboxInstance.close(); }, open: () => { this.Editor.BlockManager.currentBlock = this.hoveredBlock, this.toolboxInstance.open(); }, toggle: () => this.toolboxInstance.toggle(), hasFocus: () => this.toolboxInstance.hasFocus() }; } /** * Block actions appearance manipulations */ get blockActions() { return { hide: () => { this.nodes.actions.classList.remove(this.CSS.actionsOpened); }, show: () => { this.nodes.actions.classList.add(this.CSS.actionsOpened); } }; } /** * Methods for working with Block Tunes toggler */ get blockTunesToggler() { return { hide: () => this.nodes.settingsToggler.classList.add(this.CSS.settingsTogglerHidden), show: () => this.nodes.settingsToggler.classList.remove(this.CSS.settingsTogglerHidden) }; } /** * Toggles read-only mode * * @param {boolean} readOnlyEnabled - read-only mode */ toggleReadOnly(e) { e ? (this.destroy(), this.Editor.BlockSettings.destroy(), this.disableModuleBindings()) : (this.drawUI(), this.enableModuleBindings()); } /** * Move Toolbar to the passed (or current) Block * * @param block - block to move Toolbar near it */ moveAndOpen(e = this.Editor.BlockManager.currentBlock) { if (this.toolboxInstance.opened && this.toolboxInstance.close(), this.Editor.BlockSettings.opened && this.Editor.BlockSettings.close(), !e) return; this.hoveredBlock = e; const t = e.holder, { isMobile: o } = this.Editor.UI, i = e.pluginsContent, n = window.getComputedStyle(i), r = parseInt(n.paddingTop, 10), a = t.offsetHeight; let l; o ? l = t.offsetTop + a : l = t.offsetTop + r, this.nodes.wrapper.style.top = `${Math.floor(l)}px`, this.Editor.BlockManager.blocks.length === 1 && e.isEmpty ? this.blockTunesToggler.hide() : this.blockTunesToggler.show(), this.open(); } /** * Close the Toolbar */ close() { this.Editor.ReadOnly.isEnabled || (this.nodes.wrapper.classList.remove(this.CSS.toolbarOpened), this.blockActions.hide(), this.toolboxInstance.close(), this.Editor.BlockSettings.close()); } /** * Open Toolbar with Plus Button and Actions * * @param {boolean} withBlockActions - by default, Toolbar opens with Block Actions. * This flag allows to open Toolbar without Actions. */ open(e = !0) { oe(() => { this.nodes.wrapper.classList.add(this.CSS.toolbarOpened), e ? this.blockActions.show() : this.blockActions.hide(); }, 50)(); } /** * Draws Toolbar elements */ make() { this.nodes.wrapper = d.make("div", this.CSS.toolbar), ["content", "actions"].forEach((t) => { this.nodes[t] = d.make("div", this.CSS[t]); }), d.append(this.nodes.wrapper, this.nodes.content), d.append(this.nodes.content, this.nodes.actions), this.nodes.plusButton = d.make("div", this.CSS.plusButton, { innerHTML: Mo }), d.append(this.nodes.actions, this.nodes.plusButton), this.readOnlyMutableListeners.on(this.nodes.plusButton, "click", () => { this.tooltip.hide(!0), this.plusButtonClicked(); }, !1); const e = d.make("div"); e.appendChild(document.createTextNode($.ui(X.ui.toolbar.toolbox, "Add"))), e.appendChild(d.make("div", this.CSS.plusButtonShortcut, { textContent: "⇥ Tab" })), this.tooltip.onHover(this.nodes.plusButton, e, { hidingDelay: 400 }), this.nodes.settingsToggler = d.make("span", this.CSS.settingsToggler, { innerHTML: Io }), d.append(this.nodes.actions, this.nodes.settingsToggler), this.tooltip.onHover( this.nodes.settingsToggler, $.ui(X.ui.blockTunes.toggler, "Click to tune"), { hidingDelay: 400 } ), d.append(this.nodes.actions, this.makeToolbox()), d.append(this.nodes.actions, this.Editor.BlockSettings.getElement()), d.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper); } /** * Creates the Toolbox instance and return it's rendered element */ makeToolbox() { return this.toolboxInstance = new ze({ api: this.Editor.API.methods, tools: this.Editor.Tools.blockTools, i18nLabels: { filter: $.ui(X.ui.popover, "Filter"), nothingFound: $.ui(X.ui.popover, "Nothing found") } }), this.toolboxInstance.on(be.Opened, () => { this.Editor.UI.nodes.wrapper.classList.add(this.CSS.openedToolboxHolderModifier); }), this.toolboxInstance.on(be.Closed, () => { this.Editor.UI.nodes.wrapper.classList.remove(this.CSS.openedToolboxHolderModifier); }), this.toolboxInstance.on(be.BlockAdded, ({ block: e }) => { const { BlockManager: t, Caret: o } = this.Editor, i = t.getBlockById(e.id); i.inputs.length === 0 && (i === t.lastBlock ? (t.insertAtEnd(), o.setToBlock(t.lastBlock)) : o.setToBlock(t.nextBlock)); }), this.toolboxInstance.make(); } /** * Handler for Plus Button */ plusButtonClicked() { this.Editor.BlockManager.currentBlock = this.hoveredBlock, this.toolboxInstance.toggle(); } /** * Enable bindings */ enableModuleBindings() { this.readOnlyMutableListeners.on(this.nodes.settingsToggler, "mousedown", (e) => { e.stopPropagation(), this.settingsTogglerClicked(), this.toolboxInstance.opened && this.toolboxInstance.close(), this.tooltip.hide(!0); }, !0), ee() || this.eventsDispatcher.on(mt, (e) => { this.Editor.BlockSettings.opened || this.toolboxInstance.opened || this.moveAndOpen(e.block); }); } /** * Disable bindings */ disableModuleBindings() { this.readOnlyMutableListeners.clearAll(); } /** * Clicks on the Block Settings toggler */ settingsTogglerClicked() { this.Editor.BlockManager.currentBlock = this.hoveredBlock, this.Editor.BlockSettings.opened ? this.Editor.BlockSettings.close() : this.Editor.BlockSettings.open(this.hoveredBlock); } /** * Draws Toolbar UI * * Toolbar contains BlockSettings and Toolbox. * That's why at first we draw its components and then Toolbar itself * * Steps: * - Make Toolbar dependent components like BlockSettings, Toolbox and so on * - Make itself and append dependent nodes to itself * */ drawUI() { this.Editor.BlockSettings.make(), this.make(); } /** * Removes all created and saved HTMLElements * It is used in Read-Only mode */ destroy() { this.removeAllNodes(), this.toolboxInstance && this.toolboxInstance.destroy(), this.tooltip.destroy(); } } var ye = /* @__PURE__ */ ((s) => (s[s.Block = 0] = "Block", s[s.Inline = 1] = "Inline", s[s.Tune = 2] = "Tune", s))(ye || {}), me = /* @__PURE__ */ ((s) => (s.Shortcut = "shortcut", s.Toolbox = "toolbox", s.EnabledInlineTools = "inlineToolbar", s.EnabledBlockTunes = "tunes", s.Config = "config", s))(me || {}), kt = /* @__PURE__ */ ((s) => (s.Shortcut = "shortcut", s.SanitizeConfig = "sanitize", s))(kt || {}), se = /* @__PURE__ */ ((s) => (s.IsEnabledLineBreaks = "enableLineBreaks", s.Toolbox = "toolbox", s.ConversionConfig = "conversionConfig", s.IsReadOnlySupported = "isReadOnlySupported", s.PasteConfig = "pasteConfig", s))(se || {}), je = /* @__PURE__ */ ((s) => (s.IsInline = "isInline", s.Title = "title", s))(je || {}), vt = /* @__PURE__ */ ((s) => (s.IsTune = "isTune", s))(vt || {}); class Ue { /** * @class * @param {ConstructorOptions} options - Constructor options */ constructor({ name: e, constructable: t, config: o, api: i, isDefault: n, isInternal: r = !1, defaultPlaceholder: a }) { this.api = i, this.name = e, this.constructable = t, this.config = o, this.isDefault = n, this.isInternal = r, this.defaultPlaceholder = a; } /** * Returns Tool user configuration */ get settings() { const e = this.config.config || {}; return this.isDefault && !("placeholder" in e) && this.defaultPlaceholder && (e.placeholder = this.defaultPlaceholder), e; } /** * Calls Tool's reset method */ reset() { if (D(this.constructable.reset)) return this.constructable.reset(); } /** * Calls Tool's prepare method */ prepare() { if (D(this.constructable.prepare)) return this.constructable.prepare({ toolName: this.name, config: this.settings }); } /** * Returns shortcut for Tool (internal or specified by user) */ get shortcut() { const e = this.constructable.shortcut; return this.config.shortcut || e; } /** * Returns Tool's sanitizer configuration */ get sanitizeConfig() { return this.constructable.sanitize || {}; } /** * Returns true if Tools is inline */ isInline() { return this.type === 1; } /** * Returns true if Tools is block */ isBlock() { return this.type === 0; } /** * Returns true if Tools is tune */ isTune() { return this.type === 2; } } class Uo extends S { /** * @class * @param moduleConfiguration - Module Configuration * @param moduleConfiguration.config - Editor's config * @param moduleConfiguration.eventsDispatcher - Editor's event dispatcher */ constructor({ config: e, eventsDispatcher: t }) { super({ config: e, eventsDispatcher: t }), this.CSS = { inlineToolbar: "ce-inline-toolbar", inlineToolbarShowed: "ce-inline-toolbar--showed", inlineToolbarLeftOriented: "ce-inline-toolbar--left-oriented", inlineToolbarRightOriented: "ce-inline-toolbar--right-oriented", inlineToolbarShortcut: "ce-inline-toolbar__shortcut", buttonsWrapper: "ce-inline-toolbar__buttons", actionsWrapper: "ce-inline-toolbar__actions", inlineToolButton: "ce-inline-tool", inputField: "cdx-input", focusedButton: "ce-inline-tool--focused", conversionToggler: "ce-inline-toolbar__dropdown", conversionTogglerArrow: "ce-inline-toolbar__dropdown-arrow", conversionTogglerHidden: "ce-inline-toolbar__dropdown--hidden", conversionTogglerContent: "ce-inline-toolbar__dropdown-content", togglerAndButtonsWrapper: "ce-inline-toolbar__toggler-and-button-wrapper" }, this.opened = !1, this.toolbarVerticalMargin = ee() ? 20 : 6, this.buttonsList = null, this.width = 0, this.flipper = null, this.tooltip = new Fe(); } /** * Toggles read-only mode * * @param {boolean} readOnlyEnabled - read-only mode */ toggleReadOnly(e) { e ? (this.destroy(), this.Editor.ConversionToolbar.destroy()) : this.make(); } /** * Moving / appearance * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /** * Shows Inline Toolbar if something is selected * * @param [needToClose] - pass true to close toolbar if it is not allowed. * Avoid to use it just for closing IT, better call .close() clearly. * @param [needToShowConversionToolbar] - pass false to not to show Conversion Toolbar */ tryToShow(e = !1, t = !0) { if (!this.allowedToShow()) { e && this.close(); return; } this.move(), this.open(t), this.Editor.Toolbar.close(); } /** * Move Toolbar to the selected text */ move() { const e = m.rect, t = this.Editor.UI.nodes.wrapper.getBoundingClientRect(), o = { x: e.x - t.left, y: e.y + e.height - // + window.scrollY t.top + this.toolbarVerticalMargin }; e.width && (o.x += Math.floor(e.width / 2)); const i = o.x - this.width / 2, n = o.x + this.width / 2; this.nodes.wrapper.classList.toggle( this.CSS.inlineToolbarLeftOriented, i < this.Editor.UI.contentRect.left ), this.nodes.wrapper.classList.toggle( this.CSS.inlineToolbarRightOriented, n > this.Editor.UI.contentRect.right ), this.nodes.wrapper.style.left = Math.floor(o.x) + "px", this.nodes.wrapper.style.top = Math.floor(o.y) + "px"; } /** * Hides Inline Toolbar */ close() { this.opened && (this.Editor.ReadOnly.isEnabled || (this.nodes.wrapper.classList.remove(this.CSS.inlineToolbarShowed), Array.from(this.toolsInstances.entries()).forEach(([e, t]) => { const o = this.getToolShortcut(e); o && re.remove(this.Editor.UI.nodes.redactor, o), D(t.clear) && t.clear(); }), this.opened = !1, this.flipper.deactivate(), this.Editor.ConversionToolbar.close())); } /** * Shows Inline Toolbar * * @param [needToShowConversionToolbar] - pass false to not to show Conversion Toolbar */ open(e = !0) { if (this.opened) return; this.addToolsFiltered(), this.nodes.wrapper.classList.add(this.CSS.inlineToolbarShowed), this.buttonsList = this.nodes.buttons.querySelectorAll(`.${this.CSS.inlineToolButton}`), this.opened = !0, e && this.Editor.ConversionToolbar.hasTools() ? this.setConversionTogglerContent() : this.nodes.conversionToggler.hidden = !0; let t = Array.from(this.buttonsList); t.unshift(this.nodes.conversionToggler), t = t.filter((o) => !o.hidden), this.flipper.activate(t); } /** * Check if node is contained by Inline Toolbar * * @param {Node} node — node to check */ containsNode(e) { return this.nodes.wrapper.contains(e); } /** * Removes UI and its components */ destroy() { this.flipper && (this.flipper.deactivate(), this.flipper = null), this.removeAllNodes(), this.tooltip.destroy(); } /** * Making DOM */ make() { this.nodes.wrapper = d.make("div", [ this.CSS.inlineToolbar, ...this.isRtl ? [this.Editor.UI.CSS.editorRtlFix] : [] ]), this.nodes.togglerAndButtonsWrapper = d.make("div", this.CSS.togglerAndButtonsWrapper), this.nodes.buttons = d.make("div", this.CSS.buttonsWrapper), this.nodes.actions = d.make("div", this.CSS.actionsWrapper), this.listeners.on(this.nodes.wrapper, "mousedown", (e) => { e.target.closest(`.${this.CSS.actionsWrapper}`) || e.preventDefault(); }), d.append(this.nodes.wrapper, [this.nodes.togglerAndButtonsWrapper, this.nodes.actions]), d.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper), this.addConversionToggler(), d.append(this.nodes.togglerAndButtonsWrapper, this.nodes.buttons), this.prepareConversionToolbar(), this.recalculateWidth(), this.enableFlipper(); } /** * Need to show Inline Toolbar or not */ allowedToShow() { const e = ["IMG", "INPUT"], t = m.get(), o = m.text; if (!t || !t.anchorNode || t.isCollapsed || o.length < 1) return !1; const i = d.isElement(t.anchorNode) ? t.anchorNode : t.anchorNode.parentElement; if (t && e.includes(i.tagName) || i.closest('[contenteditable="true"]') === null) return !1; const r = this.Editor.BlockManager.getBlock(t.anchorNode); return r ? r.tool.inlineTools.size !== 0 : !1; } /** * Recalculate inline toolbar width */ recalculateWidth() { this.width = this.nodes.wrapper.offsetWidth; } /** * Create a toggler for Conversion Dropdown * and prepend it to the buttons list */ addConversionToggler() { this.nodes.conversionToggler = d.make("div", this.CSS.conversionToggler), this.nodes.conversionTogglerContent = d.make("div", this.CSS.conversionTogglerContent); const e = d.make("div", this.CSS.conversionTogglerArrow, { innerHTML: pt }); this.nodes.conversionToggler.appendChild(this.nodes.conversionTogglerContent), this.nodes.conversionToggler.appendChild(e), this.nodes.togglerAndButtonsWrapper.appendChild(this.nodes.conversionToggler), this.listeners.on(this.nodes.conversionToggler, "click", () => { this.Editor.ConversionToolbar.toggle((t) => { !t && this.opened ? this.flipper.activate() : this.opened && this.flipper.deactivate(); }); }), ee() === !1 && this.tooltip.onHover(this.nodes.conversionToggler, $.ui(X.ui.inlineToolbar.converter, "Convert to"), { placement: "top", hidingDelay: 100 }); } /** * Changes Conversion Dropdown content for current block's Tool */ async setConversionTogglerContent() { const { BlockManager: e } = this.Editor, { currentBlock: t } = e, o = t.name, i = t.tool.conversionConfig, n = i && i.export; this.nodes.conversionToggler.hidden = !n, this.nodes.conversionToggler.classList.toggle(this.CSS.conversionTogglerHidden, !n); const r = await t.getActiveToolboxEntry() || {}; this.nodes.conversionTogglerContent.innerHTML = r.icon || r.title || ke(o); } /** * Makes the Conversion Dropdown */ prepareConversionToolbar() { const e = this.Editor.ConversionToolbar.make(); d.append(this.nodes.wrapper, e); } /** * Working with Tools * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /** * Append only allowed Tools */ addToolsFiltered() { const e = m.get(), t = this.Editor.BlockManager.getBlock(e.anchorNode); this.nodes.buttons.innerHTML = "", this.nodes.actions.innerHTML = "", this.toolsInstances = /* @__PURE__ */ new Map(), Array.from(t.tool.inlineTools.values()).forEach((o) => { this.addTool(o); }), this.recalculateWidth(); } /** * Add tool button and activate clicks * * @param {InlineTool} tool - InlineTool object */ addTool(e) { const t = e.create(), o = t.render(); if (!o) { T("Render method must return an instance of Node", "warn", e.name); return; } if (o.dataset.tool = e.name, this.nodes.buttons.appendChild(o), this.toolsInstances.set(e.name, t), D(t.renderActions)) { const a = t.renderActions(); this.nodes.actions.appendChild(a); } this.listeners.on(o, "click", (a) => { this.toolClicked(t), a.preventDefault(); }); const i = this.getToolShortcut(e.name); if (i) try { this.enableShortcuts(t, i); } catch { } const n = d.make("div"), r = $.t( X.toolNames, e.title || ke(e.name) ); n.appendChild(d.text(r)), i && n.appendChild(d.make("div", this.CSS.inlineToolbarShortcut, { textContent: nt(i) })), ee() === !1 && this.tooltip.onHover(o, n, { placement: "top", hidingDelay: 100 }), t.checkState(m.get()); } /** * Get shortcut name for tool * * @param toolName — Tool name */ getToolShortcut(e) { const { Tools: t } = this.Editor, o = t.inlineTools.get(e), i = t.internal.inlineTools; return Array.from(i.keys()).includes(e) ? this.inlineTools[e][kt.Shortcut] : o.shortcut; } /** * Enable Tool shortcut with Editor Shortcuts Module * * @param {InlineTool} tool - Tool instance * @param {string} shortcut - shortcut according to the ShortcutData Module format */ enableShortcuts(e, t) { re.add({ name: t, handler: (o) => { const { currentBlock: i } = this.Editor.BlockManager; i && i.tool.enabledInlineTools && (o.preventDefault(), this.toolClicked(e)); }, on: this.Editor.UI.nodes.redactor }); } /** * Inline Tool button clicks * * @param {InlineTool} tool - Tool's instance */ toolClicked(e) { const t = m.range; e.surround(t), this.checkToolsState(), e.renderActions !== void 0 && this.flipper.deactivate(); } /** * Check Tools` state by selection */ checkToolsState() { this.toolsInstances.forEach((e) => { e.checkState(m.get()); }); } /** * Get inline tools tools * Tools that has isInline is true */ get inlineTools() { const e = {}; return Array.from(this.Editor.Tools.inlineTools.entries()).forEach(([t, o]) => { e[t] = o.create(); }), e; } /** * Allow to leaf buttons by arrows / tab * Buttons will be filled on opening */ enableFlipper() { this.flipper = new G({ focusedItemClass: this.CSS.focusedButton, allowedKeys: [ B.ENTER, B.TAB ] }); } } class $o extends S { /** * All keydowns on Block * * @param {KeyboardEvent} event - keydown */ keydown(e) { switch (this.beforeKeydownProcessing(e), e.keyCode) { case B.BACKSPACE: this.backspace(e); break; case B.ENTER: this.enter(e); break; case B.DOWN: case B.RIGHT: this.arrowRightAndDown(e); break; case B.UP: case B.LEFT: this.arrowLeftAndUp(e); break; case B.TAB: this.tabPressed(e); break; } } /** * Fires on keydown before event processing * * @param {KeyboardEvent} event - keydown */ beforeKeydownProcessing(e) { this.needToolbarClosing(e) && tt(e.keyCode) && (this.Editor.Toolbar.close(), this.Editor.ConversionToolbar.close(), e.ctrlKey || e.metaKey || e.altKey || e.shiftKey || (this.Editor.BlockManager.clearFocused(), this.Editor.BlockSelection.clearSelection(e))); } /** * Key up on Block: * - shows Inline Toolbar if something selected * - shows conversion toolbar with 85% of block selection * * @param {KeyboardEvent} event - keyup event */ keyup(e) { e.shiftKey || this.Editor.UI.checkEmptiness(); } /** * Open Toolbox to leaf Tools * * @param {KeyboardEvent} event - tab keydown event */ tabPressed(e) { this.Editor.BlockSelection.clearSelection(e); const { BlockManager: t, InlineToolbar: o, ConversionToolbar: i } = this.Editor, n = t.currentBlock; if (!n) return; const r = n.isEmpty, a = n.tool.isDefault && r, l = !r && i.opened, c = !r && !m.isCollapsed && o.opened; a ? this.activateToolbox() : !l && !c && this.activateBlockSettings(); } /** * Add drop target styles * * @param {DragEvent} event - drag over event */ dragOver(e) { const t = this.Editor.BlockManager.getBlockByChildNode(e.target); t.dropTarget = !0; } /** * Remove drop target style * * @param {DragEvent} event - drag leave event */ dragLeave(e) { const t = this.Editor.BlockManager.getBlockByChildNode(e.target); t.dropTarget = !1; } /** * Copying selected blocks * Before putting to the clipboard we sanitize all blocks and then copy to the clipboard * * @param {ClipboardEvent} event - clipboard event */ handleCommandC(e) { const { BlockSelection: t } = this.Editor; t.anyBlockSelected && t.copySelectedBlocks(e); } /** * Copy and Delete selected Blocks * * @param {ClipboardEvent} event - clipboard event */ handleCommandX(e) { const { BlockSelection: t, BlockManager: o, Caret: i } = this.Editor; t.anyBlockSelected && t.copySelectedBlocks(e).then(() => { const n = o.removeSelectedBlocks(), r = o.insertDefaultBlockAtIndex(n, !0); i.setToBlock(r, i.positions.START), t.clearSelection(e); }); } /** * ENTER pressed on block * * @param {KeyboardEvent} event - keydown */ enter(e) { const { BlockManager: t, UI: o } = this.Editor; if (t.currentBlock.tool.isLineBreaksEnabled || o.someToolbarOpened && o.someFlipperButtonFocused || e.shiftKey) return; let n = this.Editor.BlockManager.currentBlock; this.Editor.Caret.isAtStart && !this.Editor.BlockManager.currentBlock.hasMedia ? this.Editor.BlockManager.insertDefaultBlockAtIndex(this.Editor.BlockManager.currentBlockIndex) : this.Editor.Caret.isAtEnd ? n = this.Editor.BlockManager.insertDefaultBlockAtIndex(this.Editor.BlockManager.currentBlockIndex + 1) : n = this.Editor.BlockManager.split(), this.Editor.Caret.setToBlock(n), this.Editor.Toolbar.moveAndOpen(n), e.preventDefault(); } /** * Handle backspace keydown on Block * * @param {KeyboardEvent} event - keydown */ backspace(e) { const { BlockManager: t, BlockSelection: o, Caret: i } = this.Editor, n = t.currentBlock, r = n.tool; if (n.selected || n.isEmpty && n.currentInput === n.firstInput) { e.preventDefault(); const c = t.currentBlockIndex; t.previousBlock && t.previousBlock.inputs.length === 0 ? t.removeBlock(c - 1) : t.removeBlock(), i.setToBlock( t.currentBlock, c ? i.positions.END : i.positions.START ), this.Editor.Toolbar.close(), o.clearSelection(e); return; } if (r.isLineBreaksEnabled && !i.isAtStart) return; const a = t.currentBlockIndex === 0; i.isAtStart && m.isCollapsed && n.currentInput === n.firstInput && !a && (e.preventDefault(), this.mergeBlocks()); } /** * Merge current and previous Blocks if they have the same type */ mergeBlocks() { const { BlockManager: e, Caret: t, Toolbar: o } = this.Editor, i = e.previousBlock, n = e.currentBlock; if (n.name !== i.name || !i.mergeable) { if (i.inputs.length === 0 || i.isEmpty) { e.removeBlock(e.currentBlockIndex - 1), t.setToBlock(e.currentBlock), o.close(); return; } t.navigatePrevious() && o.close(); return; } t.createShadow(i.pluginsContent), e.mergeBlocks(i, n).then(() => { t.restoreCaret(i.pluginsContent), i.pluginsContent.normalize(), o.close(); }); } /** * Handle right and down keyboard keys * * @param {KeyboardEvent} event - keyboard event */ arrowRightAndDown(e) { const t = G.usedKeys.includes(e.keyCode) && (!e.shiftKey || e.keyCode === B.TAB); if (this.Editor.UI.someToolbarOpened && t) return; this.Editor.BlockManager.clearFocused(), this.Editor.Toolbar.close(); const o = this.Editor.Caret.isAtEnd || this.Editor.BlockSelection.anyBlockSelected; if (e.shiftKey && e.keyCode === B.DOWN && o) { this.Editor.CrossBlockSelection.toggleBlockSelectedState(); return; } (e.keyCode === B.DOWN || e.keyCode === B.RIGHT && !this.isRtl ? this.Editor.Caret.navigateNext() : this.Editor.Caret.navigatePrevious()) ? e.preventDefault() : oe(() => { this.Editor.BlockManager.currentBlock && this.Editor.BlockManager.currentBlock.updateCurrentInput(); }, 20)(), this.Editor.BlockSelection.clearSelection(e); } /** * Handle left and up keyboard keys * * @param {KeyboardEvent} event - keyboard event */ arrowLeftAndUp(e) { if (this.Editor.UI.someToolbarOpened) { if (G.usedKeys.includes(e.keyCode) && (!e.shiftKey || e.keyCode === B.TAB)) return; this.Editor.UI.closeAllToolbars(); } this.Editor.BlockManager.clearFocused(), this.Editor.Toolbar.close(); const t = this.Editor.Caret.isAtStart || this.Editor.BlockSelection.anyBlockSelected; if (e.shiftKey && e.keyCode === B.UP && t) { this.Editor.CrossBlockSelection.toggleBlockSelectedState(!1); return; } (e.keyCode === B.UP || e.keyCode === B.LEFT && !this.isRtl ? this.Editor.Caret.navigatePrevious() : this.Editor.Caret.navigateNext()) ? e.preventDefault() : oe(() => { this.Editor.BlockManager.currentBlock && this.Editor.BlockManager.currentBlock.updateCurrentInput(); }, 20)(), this.Editor.BlockSelection.clearSelection(e); } /** * Cases when we need to close Toolbar * * @param {KeyboardEvent} event - keyboard event */ needToolbarClosing(e) { const t = e.keyCode === B.ENTER && this.Editor.Toolbar.toolbox.opened, o = e.keyCode === B.ENTER && this.Editor.BlockSettings.opened, i = e.keyCode === B.ENTER && this.Editor.InlineToolbar.opened, n = e.keyCode === B.ENTER && this.Editor.ConversionToolbar.opened, r = e.keyCode === B.TAB; return !(e.shiftKey || r || t || o || i || n); } /** * If Toolbox is not open, then just open it and show plus button */ activateToolbox() { this.Editor.Toolbar.opened || this.Editor.Toolbar.moveAndOpen(), this.Editor.Toolbar.toolbox.open(); } /** * Open Toolbar and show BlockSettings before flipping Tools */ activateBlockSettings() { this.Editor.Toolbar.opened || (this.Editor.BlockManager.currentBlock.focused = !0, this.Editor.Toolbar.moveAndOpen()), this.Editor.BlockSettings.opened || this.Editor.BlockSettings.open(); } } class Ce { /** * @class * @param {HTMLElement} workingArea — editor`s working node */ constructor(e) { this.blocks = [], this.workingArea = e; } /** * Get length of Block instances array * * @returns {number} */ get length() { return this.blocks.length; } /** * Get Block instances array * * @returns {Block[]} */ get array() { return this.blocks; } /** * Get blocks html elements array * * @returns {HTMLElement[]} */ get nodes() { return it(this.workingArea.children); } /** * Proxy trap to implement array-like setter * * @example * blocks[0] = new Block(...) * @param {Blocks} instance — Blocks instance * @param {PropertyKey} property — block index or any Blocks class property key to set * @param {Block} value — value to set * @returns {boolean} */ static set(e, t, o) { return isNaN(Number(t)) ? (Reflect.set(e, t, o), !0) : (e.insert(+t, o), !0); } /** * Proxy trap to implement array-like getter * * @param {Blocks} instance — Blocks instance * @param {PropertyKey} property — Blocks class property key * @returns {Block|*} */ static get(e, t) { return isNaN(Number(t)) ? Reflect.get(e, t) : e.get(+t); } /** * Push new Block to the blocks array and append it to working area * * @param {Block} block - Block to add */ push(e) { this.blocks.push(e), this.insertToDOM(e); } /** * Swaps blocks with indexes first and second * * @param {number} first - first block index * @param {number} second - second block index * @deprecated — use 'move' instead */ swap(e, t) { const o = this.blocks[t]; d.swap(this.blocks[e].holder, o.holder), this.blocks[t] = this.blocks[e], this.blocks[e] = o; } /** * Move a block from one to another index * * @param {number} toIndex - new index of the block * @param {number} fromIndex - block to move */ move(e, t) { const o = this.blocks.splice(t, 1)[0], i = e - 1, n = Math.max(0, i), r = this.blocks[n]; e > 0 ? this.insertToDOM(o, "afterend", r) : this.insertToDOM(o, "beforebegin", r), this.blocks.splice(e, 0, o); const a = this.composeBlockEvent("move", { fromIndex: t, toIndex: e }); o.call(q.MOVED, a); } /** * Insert new Block at passed index * * @param {number} index — index to insert Block * @param {Block} block — Block to insert * @param {boolean} replace — it true, replace block on given index */ insert(e, t, o = !1) { if (!this.length) { this.push(t); return; } e > this.length && (e = this.length), o && (this.blocks[e].holder.remove(), this.blocks[e].call(q.REMOVED)); const i = o ? 1 : 0; if (this.blocks.splice(e, i, t), e > 0) { const n = this.blocks[e - 1]; this.insertToDOM(t, "afterend", n); } else { const n = this.blocks[e + 1]; n ? this.insertToDOM(t, "beforebegin", n) : this.insertToDOM(t); } } /** * Remove block * * @param {number} index - index of Block to remove */ remove(e) { isNaN(e) && (e = this.length - 1), this.blocks[e].holder.remove(), this.blocks[e].call(q.REMOVED), this.blocks.splice(e, 1); } /** * Remove all blocks */ removeAll() { this.workingArea.innerHTML = "", this.blocks.forEach((e) => e.call(q.REMOVED)), this.blocks.length = 0; } /** * Insert Block after passed target * * @todo decide if this method is necessary * @param {Block} targetBlock — target after which Block should be inserted * @param {Block} newBlock — Block to insert */ insertAfter(e, t) { const o = this.blocks.indexOf(e); this.insert(o + 1, t); } /** * Get Block by index * * @param {number} index — Block index * @returns {Block} */ get(e) { return this.blocks[e]; } /** * Return index of passed Block * * @param {Block} block - Block to find * @returns {number} */ indexOf(e) { return this.blocks.indexOf(e); } /** * Insert new Block into DOM * * @param {Block} block - Block to insert * @param {InsertPosition} position — insert position (if set, will use insertAdjacentElement) * @param {Block} target — Block related to position */ insertToDOM(e, t, o) { t ? o.holder.insertAdjacentElement(t, e.holder) : this.workingArea.appendChild(e.holder), e.call(q.RENDERED); } /** * Composes Block event with passed type and details * * @param {string} type - event type * @param {object} detail - event detail */ composeBlockEvent(e, t) { return new CustomEvent(e, { detail: t }); } } const Je = "block-removed", Qe = "block-added", Wo = "block-moved", Yo = "block-changed"; class Ko extends S { constructor() { super(...arguments), this._currentBlockIndex = -1, this._blocks = null; } /** * Returns current Block index * * @returns {number} */ get currentBlockIndex() { return this._currentBlockIndex; } /** * Set current Block index and fire Block lifecycle callbacks * * @param {number} newIndex - index of Block to set as current */ set currentBlockIndex(e) { this._currentBlockIndex = e; } /** * returns first Block * * @returns {Block} */ get firstBlock() { return this._blocks[0]; } /** * returns last Block * * @returns {Block} */ get lastBlock() { return this._blocks[this._blocks.length - 1]; } /** * Get current Block instance * * @returns {Block} */ get currentBlock() { return this._blocks[this.currentBlockIndex]; } /** * Set passed Block as a current * * @param block - block to set as a current */ set currentBlock(e) { this.currentBlockIndex = this.getBlockIndex(e); } /** * Returns next Block instance * * @returns {Block|null} */ get nextBlock() { return this.currentBlockIndex === this._blocks.length - 1 ? null : this._blocks[this.currentBlockIndex + 1]; } /** * Return first Block with inputs after current Block * * @returns {Block | undefined} */ get nextContentfulBlock() { return this.blocks.slice(this.currentBlockIndex + 1).find((t) => !!t.inputs.length); } /** * Return first Block with inputs before current Block * * @returns {Block | undefined} */ get previousContentfulBlock() { return this.blocks.slice(0, this.currentBlockIndex).reverse().find((t) => !!t.inputs.length); } /** * Returns previous Block instance * * @returns {Block|null} */ get previousBlock() { return this.currentBlockIndex === 0 ? null : this._blocks[this.currentBlockIndex - 1]; } /** * Get array of Block instances * * @returns {Block[]} {@link Blocks#array} */ get blocks() { return this._blocks.array; } /** * Check if each Block is empty * * @returns {boolean} */ get isEditorEmpty() { return this.blocks.every((e) => e.isEmpty); } /** * Should be called after Editor.UI preparation * Define this._blocks property */ prepare() { const e = new Ce(this.Editor.UI.nodes.redactor); this._blocks = new Proxy(e, { set: Ce.set, get: Ce.get }), this.listeners.on( document, "copy", (t) => this.Editor.BlockEvents.handleCommandC(t) ); } /** * Toggle read-only state * * If readOnly is true: * - Unbind event handlers from created Blocks * * if readOnly is false: * - Bind event handlers to all existing Blocks * * @param {boolean} readOnlyEnabled - "read only" state */ toggleReadOnly(e) { e ? this.disableModuleBindings() : this.enableModuleBindings(); } /** * Creates Block instance by tool name * * @param {object} options - block creation options * @param {string} options.tool - tools passed in editor config {@link EditorConfig#tools} * @param {string} [options.id] - unique id for this block * @param {BlockToolData} [options.data] - constructor params * @returns {Block} */ composeBlock({ tool: e, data: t = {}, id: o = void 0, tunes: i = {} }) { const n = this.Editor.ReadOnly.isEnabled, r = this.Editor.Tools.blockTools.get(e), a = new F({ id: o, data: t, tool: r, api: this.Editor.API, readOnly: n, tunesData: i }, this.eventsDispatcher); return n || this.bindBlockEvents(a), a; } /** * Insert new block into _blocks * * @param {object} options - insert options * @param {string} [options.id] - block's unique id * @param {string} [options.tool] - plugin name, by default method inserts the default block type * @param {object} [options.data] - plugin data * @param {number} [options.index] - index where to insert new Block * @param {boolean} [options.needToFocus] - flag shows if needed to update current Block index * @param {boolean} [options.replace] - flag shows if block by passed index should be replaced with inserted one * @returns {Block} */ insert({ id: e = void 0, tool: t = this.config.defaultBlock, data: o = {}, index: i, needToFocus: n = !0, replace: r = !1, tunes: a = {} } = {}) { let l = i; l === void 0 && (l = this.currentBlockIndex + (r ? 0 : 1)); const c = this.composeBlock({ id: e, tool: t, data: o, tunes: a }); return r && this.blockDidMutated(Je, this.getBlockByIndex(l), { index: l }), this._blocks.insert(l, c, r), this.blockDidMutated(Qe, c, { index: l }), n ? this.currentBlockIndex = l : l <= this.currentBlockIndex && this.currentBlockIndex++, c; } /** * Replace current working block * * @param {object} options - replace options * @param {string} options.tool — plugin name * @param {BlockToolData} options.data — plugin data * @returns {Block} */ replace({ tool: e = this.config.defaultBlock, data: t = {} }) { return this.insert({ tool: e, data: t, index: this.currentBlockIndex, replace: !0 }); } /** * Insert pasted content. Call onPaste callback after insert. * * @param {string} toolName - name of Tool to insert * @param {PasteEvent} pasteEvent - pasted data * @param {boolean} replace - should replace current block */ paste(e, t, o = !1) { const i = this.insert({ tool: e, replace: o }); try { i.call(q.ON_PASTE, t); } catch (n) { T(`${e}: onPaste callback call is failed`, "error", n); } return i; } /** * Insert new default block at passed index * * @param {number} index - index where Block should be inserted * @param {boolean} needToFocus - if true, updates current Block index * * TODO: Remove method and use insert() with index instead (?) * @returns {Block} inserted Block */ insertDefaultBlockAtIndex(e, t = !1) { const o = this.composeBlock({ tool: this.config.defaultBlock }); return this._blocks[e] = o, this.blockDidMutated(Qe, o, { index: e }), t ? this.currentBlockIndex = e : e <= this.currentBlockIndex && this.currentBlockIndex++, o; } /** * Always inserts at the end * * @returns {Block} */ insertAtEnd() { return this.currentBlockIndex = this.blocks.length - 1, this.insert(); } /** * Merge two blocks * * @param {Block} targetBlock - previous block will be append to this block * @param {Block} blockToMerge - block that will be merged with target block * @returns {Promise} - the sequence that can be continued */ async mergeBlocks(e, t) { const o = this._blocks.indexOf(t); if (t.isEmpty) return; const i = await t.data; V(i) || await e.mergeWith(i), this.removeBlock(o), this.currentBlockIndex = this._blocks.indexOf(e); } /** * Remove block with passed index or remove last * * @param {number|null} index - index of Block to remove * @throws {Error} if Block to remove is not found */ removeBlock(e = this.currentBlockIndex) { if (!this.validateIndex(e)) throw new Error("Can't find a Block to remove"); const t = this._blocks[e]; t.destroy(), this._blocks.remove(e), this.blockDidMutated(Je, t, { index: e }), this.currentBlockIndex >= e && this.currentBlockIndex--, this.blocks.length ? e === 0 && (this.currentBlockIndex = 0) : (this.currentBlockIndex = -1, this.insert()); } /** * Remove only selected Blocks * and returns first Block index where started removing... * * @returns {number|undefined} */ removeSelectedBlocks() { let e; for (let t = this.blocks.length - 1; t >= 0; t--) this.blocks[t].selected && (this.removeBlock(t), e = t); return e; } /** * Attention! * After removing insert the new default typed Block and focus on it * Removes all blocks */ removeAllBlocks() { for (let e = this.blocks.length - 1; e >= 0; e--) this._blocks.remove(e); this.currentBlockIndex = -1, this.insert(), this.currentBlock.firstInput.focus(); } /** * Split current Block * 1. Extract content from Caret position to the Block`s end * 2. Insert a new Block below current one with extracted content * * @returns {Block} */ split() { const e = this.Editor.Caret.extractFragmentFromCaretPosition(), t = d.make("div"); t.appendChild(e); const o = { text: d.isEmpty(t) ? "" : t.innerHTML }; return this.insert({ data: o }); } /** * Returns Block by passed index * * @param {number} index - index to get. -1 to get last * @returns {Block} */ getBlockByIndex(e) { return e === -1 && (e = this._blocks.length - 1), this._blocks[e]; } /** * Returns an index for passed Block * * @param block - block to find index */ getBlockIndex(e) { return this._blocks.indexOf(e); } /** * Returns the Block by passed id * * @param id - id of block to get * @returns {Block} */ getBlockById(e) { return this._blocks.array.find((t) => t.id === e); } /** * Get Block instance by html element * * @param {Node} element - html element to get Block by */ getBlock(e) { d.isElement(e) || (e = e.parentNode); const t = this._blocks.nodes, o = e.closest(`.${F.CSS.wrapper}`), i = t.indexOf(o); if (i >= 0) return this._blocks[i]; } /** * Remove selection from all Blocks then highlight only Current Block */ highlightCurrentNode() { this.clearFocused(), this.currentBlock.focused = !0; } /** * Remove selection from all Blocks */ clearFocused() { this.blocks.forEach((e) => { e.focused = !1; }); } /** * 1) Find first-level Block from passed child Node * 2) Mark it as current * * @param {Node} childNode - look ahead from this node. * @returns {Block | undefined} can return undefined in case when the passed child note is not a part of the current editor instance */ setCurrentBlockByChildNode(e) { d.isElement(e) || (e = e.parentNode); const t = e.closest(`.${F.CSS.wrapper}`); if (!t) return; const o = t.closest(`.${this.Editor.UI.CSS.editorWrapper}`); if (o != null && o.isEqualNode(this.Editor.UI.nodes.wrapper)) return this.currentBlockIndex = this._blocks.nodes.indexOf(t), this.currentBlock.updateCurrentInput(), this.currentBlock; } /** * Return block which contents passed node * * @param {Node} childNode - node to get Block by * @returns {Block} */ getBlockByChildNode(e) { d.isElement(e) || (e = e.parentNode); const t = e.closest(`.${F.CSS.wrapper}`); return this.blocks.find((o) => o.holder === t); } /** * Swap Blocks Position * * @param {number} fromIndex - index of first block * @param {number} toIndex - index of second block * @deprecated — use 'move' instead */ swap(e, t) { this._blocks.swap(e, t), this.currentBlockIndex = t; } /** * Move a block to a new index * * @param {number} toIndex - index where to move Block * @param {number} fromIndex - index of Block to move */ move(e, t = this.currentBlockIndex) { if (isNaN(e) || isNaN(t)) { T("Warning during 'move' call: incorrect indices provided.", "warn"); return; } if (!this.validateIndex(e) || !this.validateIndex(t)) { T("Warning during 'move' call: indices cannot be lower than 0 or greater than the amount of blocks.", "warn"); return; } this._blocks.move(e, t), this.currentBlockIndex = e, this.blockDidMutated(Wo, this.currentBlock, { fromIndex: t, toIndex: e }); } /** * Sets current Block Index -1 which means unknown * and clear highlights */ dropPointer() { this.currentBlockIndex = -1, this.clearFocused(); } /** * Clears Editor * * @param {boolean} needToAddDefaultBlock - 1) in internal calls (for example, in api.blocks.render) * we don't need to add an empty default block * 2) in api.blocks.clear we should add empty block */ clear(e = !1) { this._blocks.removeAll(), this.dropPointer(), e && this.insert(), this.Editor.UI.checkEmptiness(); } /** * Cleans up all the block tools' resources * This is called when editor is destroyed */ async destroy() { await Promise.all(this.blocks.map((e) => e.destroy())); } /** * Bind Block events * * @param {Block} block - Block to which event should be bound */ bindBlockEvents(e) { const { BlockEvents: t } = this.Editor; this.readOnlyMutableListeners.on(e.holder, "keydown", (o) => { t.keydown(o); }), this.readOnlyMutableListeners.on(e.holder, "keyup", (o) => { t.keyup(o); }), this.readOnlyMutableListeners.on(e.holder, "dragover", (o) => { t.dragOver(o); }), this.readOnlyMutableListeners.on(e.holder, "dragleave", (o) => { t.dragLeave(o); }), e.on("didMutated", (o) => this.blockDidMutated(Yo, o, { index: this.getBlockIndex(o) })); } /** * Disable mutable handlers and bindings */ disableModuleBindings() { this.readOnlyMutableListeners.clearAll(); } /** * Enables all module handlers and bindings for all Blocks */ enableModuleBindings() { this.readOnlyMutableListeners.on( document, "cut", (e) => this.Editor.BlockEvents.handleCommandX(e) ), this.blocks.forEach((e) => { this.bindBlockEvents(e); }); } /** * Validates that the given index is not lower than 0 or higher than the amount of blocks * * @param {number} index - index of blocks array to validate * @returns {boolean} */ validateIndex(e) { return !(e < 0 || e >= this._blocks.length); } /** * Block mutation callback * * @param mutationType - what happened with block * @param block - mutated block * @param detailData - additional data to pass with change event */ blockDidMutated(e, t, o) { const i = new CustomEvent(e, { detail: { target: new he(t), ...o } }); return this.eventsDispatcher.emit(lt, { event: i }), t; } } class Xo extends S { constructor() { super(...arguments), this.anyBlockSelectedCache = null, this.needToSelectAll = !1, this.nativeInputSelected = !1, this.readyToBlockSelection = !1; } /** * Sanitizer Config * * @returns {SanitizerConfig} */ get sanitizerConfig() { return { p: {}, h1: {}, h2: {}, h3: {}, h4: {}, h5: {}, h6: {}, ol: {}, ul: {}, li: {}, br: !0, img: { src: !0, width: !0, height: !0 }, a: { href: !0 }, b: {}, i: {}, u: {} }; } /** * Flag that identifies all Blocks selection * * @returns {boolean} */ get allBlocksSelected() { const { BlockManager: e } = this.Editor; return e.blocks.every((t) => t.selected === !0); } /** * Set selected all blocks * * @param {boolean} state - state to set */ set allBlocksSelected(e) { const { BlockManager: t } = this.Editor; t.blocks.forEach((o) => { o.selected = e; }), this.clearCache(); } /** * Flag that identifies any Block selection * * @returns {boolean} */ get anyBlockSelected() { const { BlockManager: e } = this.Editor; return this.anyBlockSelectedCache === null && (this.anyBlockSelectedCache = e.blocks.some((t) => t.selected === !0)), this.anyBlockSelectedCache; } /** * Return selected Blocks array * * @returns {Block[]} */ get selectedBlocks() { return this.Editor.BlockManager.blocks.filter((e) => e.selected); } /** * Module Preparation * Registers Shortcuts CMD+A and CMD+C * to select all and copy them */ prepare() { this.selection = new m(), re.add({ name: "CMD+A", handler: (e) => { const { BlockManager: t, ReadOnly: o } = this.Editor; if (o.isEnabled) { e.preventDefault(), this.selectAllBlocks(); return; } t.currentBlock && this.handleCommandA(e); }, on: this.Editor.UI.nodes.redactor }); } /** * Toggle read-only state * * - Remove all ranges * - Unselect all Blocks */ toggleReadOnly() { m.get().removeAllRanges(), this.allBlocksSelected = !1; } /** * Remove selection of Block * * @param {number?} index - Block index according to the BlockManager's indexes */ unSelectBlockByIndex(e) { const { BlockManager: t } = this.Editor; let o; isNaN(e) ? o = t.currentBlock : o = t.getBlockByIndex(e), o.selected = !1, this.clearCache(); } /** * Clear selection from Blocks * * @param {Event} reason - event caused clear of selection * @param {boolean} restoreSelection - if true, restore saved selection */ clearSelection(e, t = !1) { const { BlockManager: o, Caret: i, RectangleSelection: n } = this.Editor; this.needToSelectAll = !1, this.nativeInputSelected = !1, this.readyToBlockSelection = !1; const r = e && e instanceof KeyboardEvent, a = r && tt(e.keyCode); if (this.anyBlockSelected && r && a && !m.isSelectionExists) { const l = o.removeSelectedBlocks(); o.insertDefaultBlockAtIndex(l, !0), i.setToBlock(o.currentBlock), oe(() => { const c = e.key; i.insertContentAtCaretPosition(c.length > 1 ? "" : c); }, 20)(); } if (this.Editor.CrossBlockSelection.clear(e), !this.anyBlockSelected || n.isRectActivated()) { this.Editor.RectangleSelection.clearSelection(); return; } t && this.selection.restore(), this.allBlocksSelected = !1; } /** * Reduce each Block and copy its content * * @param {ClipboardEvent} e - copy/cut event * @returns {Promise} */ copySelectedBlocks(e) { e.preventDefault(); const t = d.make("div"); this.selectedBlocks.forEach((n) => { const r = Z(n.holder.innerHTML, this.sanitizerConfig), a = d.make("p"); a.innerHTML = r, t.appendChild(a); }); const o = Array.from(t.childNodes).map((n) => n.textContent).join(` `), i = t.innerHTML; return e.clipboardData.setData("text/plain", o), e.clipboardData.setData("text/html", i), Promise.all(this.selectedBlocks.map((n) => n.save())).then((n) => { try { e.clipboardData.setData(this.Editor.Paste.MIME_TYPE, JSON.stringify(n)); } catch { } }); } /** * select Block * * @param {number?} index - Block index according to the BlockManager's indexes */ selectBlockByIndex(e) { const { BlockManager: t } = this.Editor; t.clearFocused(); let o; isNaN(e) ? o = t.currentBlock : o = t.getBlockByIndex(e), this.selection.save(), m.get().removeAllRanges(), o.selected = !0, this.clearCache(), this.Editor.InlineToolbar.close(); } /** * Clear anyBlockSelected cache */ clearCache() { this.anyBlockSelectedCache = null; } /** * Module destruction * De-registers Shortcut CMD+A */ destroy() { re.remove(this.Editor.UI.nodes.redactor, "CMD+A"); } /** * First CMD+A selects all input content by native behaviour, * next CMD+A keypress selects all blocks * * @param {KeyboardEvent} event - keyboard event */ handleCommandA(e) { if (this.Editor.RectangleSelection.clearSelection(), d.isNativeInput(e.target) && !this.readyToBlockSelection) { this.readyToBlockSelection = !0; return; } const o = this.Editor.BlockManager.getBlock(e.target).inputs; if (o.length > 1 && !this.readyToBlockSelection) { this.readyToBlockSelection = !0; return; } if (o.length === 1 && !this.needToSelectAll) { this.needToSelectAll = !0; return; } this.needToSelectAll ? (e.preventDefault(), this.selectAllBlocks(), this.needToSelectAll = !1, this.readyToBlockSelection = !1, this.Editor.ConversionToolbar.close()) : this.readyToBlockSelection && (e.preventDefault(), this.selectBlockByIndex(), this.needToSelectAll = !0); } /** * Select All Blocks * Each Block has selected setter that makes Block copyable */ selectAllBlocks() { this.selection.save(), m.get().removeAllRanges(), this.allBlocksSelected = !0, this.Editor.InlineToolbar.close(); } } class ve extends S { /** * Allowed caret positions in input * * @static * @returns {{START: string, END: string, DEFAULT: string}} */ get positions() { return { START: "start", END: "end", DEFAULT: "default" }; } /** * Elements styles that can be useful for Caret Module */ static get CSS() { return { shadowCaret: "cdx-shadow-caret" }; } /** * Get's deepest first node and checks if offset is zero * * @returns {boolean} */ get isAtStart() { const e = m.get(), t = d.getDeepestNode(this.Editor.BlockManager.currentBlock.currentInput); let o = e.focusNode; if (d.isNativeInput(t)) return t.selectionEnd === 0; if (!e.anchorNode) return !1; let i = o.textContent.search(/\S/); i === -1 && (i = 0); let n = e.focusOffset; return o.nodeType !== Node.TEXT_NODE && o.childNodes.length && (o.childNodes[n] ? (o = o.childNodes[n], n = 0) : (o = o.childNodes[n - 1], n = o.textContent.length)), (d.isLineBreakTag(t) || d.isEmpty(t)) && this.getHigherLevelSiblings(o, "left").every((l) => { const c = d.isLineBreakTag(l), u = l.children.length === 1 && d.isLineBreakTag(l.children[0]), h = c || u; return d.isEmpty(l) && !h; }) && n === i ? !0 : t === null || o === t && n <= i; } /** * Get's deepest last node and checks if offset is last node text length * * @returns {boolean} */ get isAtEnd() { const e = m.get(); let t = e.focusNode; const o = d.getDeepestNode(this.Editor.BlockManager.currentBlock.currentInput, !0); if (d.isNativeInput(o)) return o.selectionEnd === o.value.length; if (!e.focusNode) return !1; let i = e.focusOffset; if (t.nodeType !== Node.TEXT_NODE && t.childNodes.length && (t.childNodes[i - 1] ? (t = t.childNodes[i - 1], i = t.textContent.length) : (t = t.childNodes[0], i = 0)), d.isLineBreakTag(o) || d.isEmpty(o)) { const r = this.getHigherLevelSiblings(t, "right"); if (r.every((l, c) => c === r.length - 1 && d.isLineBreakTag(l) || d.isEmpty(l) && !d.isLineBreakTag(l)) && i === t.textContent.length) return !0; } const n = o.textContent.replace(/\s+$/, ""); return t === o && i >= n.length; } /** * Method gets Block instance and puts caret to the text node with offset * There two ways that method applies caret position: * - first found text node: sets at the beginning, but you can pass an offset * - last found text node: sets at the end of the node. Also, you can customize the behaviour * * @param {Block} block - Block class * @param {string} position - position where to set caret. * If default - leave default behaviour and apply offset if it's passed * @param {number} offset - caret offset regarding to the text node */ setToBlock(e, t = this.positions.DEFAULT, o = 0) { const { BlockManager: i } = this.Editor; let n; switch (t) { case this.positions.START: n = e.firstInput; break; case this.positions.END: n = e.lastInput; break; default: n = e.currentInput; } if (!n) return; const r = d.getDeepestNode(n, t === this.positions.END), a = d.getContentLength(r); switch (!0) { case t === this.positions.START: o = 0; break; case t === this.positions.END: case o > a: o = a; break; } oe(() => { this.set(r, o); }, 20)(), i.setCurrentBlockByChildNode(e.holder), i.currentBlock.currentInput = n; } /** * Set caret to the current input of current Block. * * @param {HTMLElement} input - input where caret should be set * @param {string} position - position of the caret. * If default - leave default behaviour and apply offset if it's passed * @param {number} offset - caret offset regarding to the text node */ setToInput(e, t = this.positions.DEFAULT, o = 0) { const { currentBlock: i } = this.Editor.BlockManager, n = d.getDeepestNode(e); switch (t) { case this.positions.START: this.set(n, 0); break; case this.positions.END: this.set(n, d.getContentLength(n)); break; default: o && this.set(n, o); } i.currentInput = e; } /** * Creates Document Range and sets caret to the element with offset * * @param {HTMLElement} element - target node. * @param {number} offset - offset */ set(e, t = 0) { const { top: o, bottom: i } = m.setCursor(e, t), { innerHeight: n } = window; o < 0 && window.scrollBy(0, o), i > n && window.scrollBy(0, i - n); } /** * Set Caret to the last Block * If last block is not empty, append another empty block */ setToTheLastBlock() { const e = this.Editor.BlockManager.lastBlock; if (e) if (e.tool.isDefault && e.isEmpty) this.setToBlock(e); else { const t = this.Editor.BlockManager.insertAtEnd(); this.setToBlock(t); } } /** * Extract content fragment of current Block from Caret position to the end of the Block */ extractFragmentFromCaretPosition() { const e = m.get(); if (e.rangeCount) { const t = e.getRangeAt(0), o = this.Editor.BlockManager.currentBlock.currentInput; if (t.deleteContents(), o) if (d.isNativeInput(o)) { const i = o, n = document.createDocumentFragment(), r = i.value.substring(0, i.selectionStart), a = i.value.substring(i.selectionStart); return n.textContent = a, i.value = r, n; } else { const i = t.cloneRange(); return i.selectNodeContents(o), i.setStart(t.endContainer, t.endOffset), i.extractContents(); } } } /** * Set's caret to the next Block or Tool`s input * Before moving caret, we should check if caret position is at the end of Plugins node * Using {@link Dom#getDeepestNode} to get a last node and match with current selection * * @returns {boolean} */ navigateNext() { const { BlockManager: e } = this.Editor, { currentBlock: t, nextContentfulBlock: o } = e, { nextInput: i } = t, n = this.isAtEnd; let r = o; if (!r && !i) { if (t.tool.isDefault || !n) return !1; r = e.insertAtEnd(); } return n ? (i ? this.setToInput(i, this.positions.START) : this.setToBlock(r, this.positions.START), !0) : !1; } /** * Set's caret to the previous Tool`s input or Block * Before moving caret, we should check if caret position is start of the Plugins node * Using {@link Dom#getDeepestNode} to get a last node and match with current selection * * @returns {boolean} */ navigatePrevious() { const { currentBlock: e, previousContentfulBlock: t } = this.Editor.BlockManager; if (!e) return !1; const { previousInput: o } = e; return !t && !o ? !1 : this.isAtStart ? (o ? this.setToInput(o, this.positions.END) : this.setToBlock(t, this.positions.END), !0) : !1; } /** * Inserts shadow element after passed element where caret can be placed * * @param {Element} element - element after which shadow caret should be inserted */ createShadow(e) { const t = document.createElement("span"); t.classList.add(ve.CSS.shadowCaret), e.insertAdjacentElement("beforeend", t); } /** * Restores caret position * * @param {HTMLElement} element - element where caret should be restored */ restoreCaret(e) { const t = e.querySelector(`.${ve.CSS.shadowCaret}`); if (!t) return; new m().expandToTag(t), setTimeout(() => { const i = document.createRange(); i.selectNode(t), i.extractContents(); }, 50); } /** * Inserts passed content at caret position * * @param {string} content - content to insert */ insertContentAtCaretPosition(e) { const t = document.createDocumentFragment(), o = document.createElement("div"), i = m.get(), n = m.range; o.innerHTML = e, Array.from(o.childNodes).forEach((l) => t.appendChild(l)), t.childNodes.length === 0 && t.appendChild(new Text()); const r = t.lastChild; n.deleteContents(), n.insertNode(t); const a = document.createRange(); a.setStart(r, r.textContent.length), i.removeAllRanges(), i.addRange(a); } /** * Get all first-level (first child of [contenteditable]) siblings from passed node * Then you can check it for emptiness * * @example * * @param {HTMLElement} from - element from which siblings should be searched * @param {'left' | 'right'} direction - direction of search * @returns {HTMLElement[]} */ getHigherLevelSiblings(e, t) { let o = e; const i = []; for (; o.parentNode && o.parentNode.contentEditable !== "true"; ) o = o.parentNode; const n = t === "left" ? "previousSibling" : "nextSibling"; for (; o[n]; ) o = o[n], i.push(o); return i; } } class Vo extends S { constructor() { super(...arguments), this.onMouseUp = () => { this.listeners.off(document, "mouseover", this.onMouseOver), this.listeners.off(document, "mouseup", this.onMouseUp); }, this.onMouseOver = (e) => { const { BlockManager: t, BlockSelection: o } = this.Editor, i = t.getBlockByChildNode(e.relatedTarget) || this.lastSelectedBlock, n = t.getBlockByChildNode(e.target); if (!(!i || !n) && n !== i) { if (i === this.firstSelectedBlock) { m.get().removeAllRanges(), i.selected = !0, n.selected = !0, o.clearCache(); return; } if (n === this.firstSelectedBlock) { i.selected = !1, n.selected = !1, o.clearCache(); return; } this.Editor.InlineToolbar.close(), this.toggleBlocksSelectedState(i, n), this.lastSelectedBlock = n; } }; } /** * Module preparation * * @returns {Promise} */ async prepare() { this.listeners.on(document, "mousedown", (e) => { this.enableCrossBlockSelection(e); }); } /** * Sets up listeners * * @param {MouseEvent} event - mouse down event */ watchSelection(e) { if (e.button !== _t.LEFT) return; const { BlockManager: t } = this.Editor; this.firstSelectedBlock = t.getBlock(e.target), this.lastSelectedBlock = this.firstSelectedBlock, this.listeners.on(document, "mouseover", this.onMouseOver), this.listeners.on(document, "mouseup", this.onMouseUp); } /** * return boolean is cross block selection started */ get isCrossBlockSelectionStarted() { return !!this.firstSelectedBlock && !!this.lastSelectedBlock; } /** * Change selection state of the next Block * Used for CBS via Shift + arrow keys * * @param {boolean} next - if true, toggle next block. Previous otherwise */ toggleBlockSelectedState(e = !0) { const { BlockManager: t, BlockSelection: o } = this.Editor; this.lastSelectedBlock || (this.lastSelectedBlock = this.firstSelectedBlock = t.currentBlock), this.firstSelectedBlock === this.lastSelectedBlock && (this.firstSelectedBlock.selected = !0, o.clearCache(), m.get().removeAllRanges()); const i = t.blocks.indexOf(this.lastSelectedBlock) + (e ? 1 : -1), n = t.blocks[i]; n && (this.lastSelectedBlock.selected !== n.selected ? (n.selected = !0, o.clearCache()) : (this.lastSelectedBlock.selected = !1, o.clearCache()), this.lastSelectedBlock = n, this.Editor.InlineToolbar.close(), n.holder.scrollIntoView({ block: "nearest" })); } /** * Clear saved state * * @param {Event} reason - event caused clear of selection */ clear(e) { const { BlockManager: t, BlockSelection: o, Caret: i } = this.Editor, n = t.blocks.indexOf(this.firstSelectedBlock), r = t.blocks.indexOf(this.lastSelectedBlock); if (o.anyBlockSelected && n > -1 && r > -1) if (e && e instanceof KeyboardEvent) switch (e.keyCode) { case B.DOWN: case B.RIGHT: i.setToBlock(t.blocks[Math.max(n, r)], i.positions.END); break; case B.UP: case B.LEFT: i.setToBlock(t.blocks[Math.min(n, r)], i.positions.START); break; default: i.setToBlock(t.blocks[Math.max(n, r)], i.positions.END); } else i.setToBlock(t.blocks[Math.max(n, r)], i.positions.END); this.firstSelectedBlock = this.lastSelectedBlock = null; } /** * Enables Cross Block Selection * * @param {MouseEvent} event - mouse down event */ enableCrossBlockSelection(e) { const { UI: t } = this.Editor; m.isCollapsed || this.Editor.BlockSelection.clearSelection(e), t.nodes.redactor.contains(e.target) ? this.watchSelection(e) : this.Editor.BlockSelection.clearSelection(e); } /** * Change blocks selection state between passed two blocks. * * @param {Block} firstBlock - first block in range * @param {Block} lastBlock - last block in range */ toggleBlocksSelectedState(e, t) { const { BlockManager: o, BlockSelection: i } = this.Editor, n = o.blocks.indexOf(e), r = o.blocks.indexOf(t), a = e.selected !== t.selected; for (let l = Math.min(n, r); l <= Math.max(n, r); l++) { const c = o.blocks[l]; c !== this.firstSelectedBlock && c !== (a ? e : t) && (o.blocks[l].selected = !o.blocks[l].selected, i.clearCache()); } } } class Zo extends S { constructor() { super(...arguments), this.isStartedAtEditor = !1; } /** * Toggle read-only state * * if state is true: * - disable all drag-n-drop event handlers * * if state is false: * - restore drag-n-drop event handlers * * @param {boolean} readOnlyEnabled - "read only" state */ toggleReadOnly(e) { e ? this.disableModuleBindings() : this.enableModuleBindings(); } /** * Add drag events listeners to editor zone */ enableModuleBindings() { const { UI: e } = this.Editor; this.readOnlyMutableListeners.on(e.nodes.holder, "drop", async (t) => { await this.processDrop(t); }, !0), this.readOnlyMutableListeners.on(e.nodes.holder, "dragstart", () => { this.processDragStart(); }), this.readOnlyMutableListeners.on(e.nodes.holder, "dragover", (t) => { this.processDragOver(t); }, !0); } /** * Unbind drag-n-drop event handlers */ disableModuleBindings() { this.readOnlyMutableListeners.clearAll(); } /** * Handle drop event * * @param {DragEvent} dropEvent - drop event */ async processDrop(e) { const { BlockManager: t, Caret: o, Paste: i } = this.Editor; e.preventDefault(), t.blocks.forEach((r) => { r.dropTarget = !1; }), m.isAtEditor && !m.isCollapsed && this.isStartedAtEditor && document.execCommand("delete"), this.isStartedAtEditor = !1; const n = t.setCurrentBlockByChildNode(e.target); if (n) this.Editor.Caret.setToBlock(n, o.positions.END); else { const r = t.setCurrentBlockByChildNode(t.lastBlock.holder); this.Editor.Caret.setToBlock(r, o.positions.END); } await i.processDataTransfer(e.dataTransfer, !0); } /** * Handle drag start event */ processDragStart() { m.isAtEditor && !m.isCollapsed && (this.isStartedAtEditor = !0), this.Editor.InlineToolbar.close(); } /** * @param {DragEvent} dragEvent - drag event */ processDragOver(e) { e.preventDefault(); } } class Go extends S { /** * Prepare the module * * @param options - options used by the modification observer module * @param options.config - Editor configuration object * @param options.eventsDispatcher - common Editor event bus */ constructor({ config: e, eventsDispatcher: t }) { super({ config: e, eventsDispatcher: t }), this.disabled = !1, this.batchingTimeout = null, this.batchingOnChangeQueue = /* @__PURE__ */ new Map(), this.batchTime = 400, this.mutationObserver = new MutationObserver((o) => { this.redactorChanged(o); }), this.eventsDispatcher.on(lt, (o) => { this.particularBlockChanged(o.event); }), this.eventsDispatcher.on(ct, () => { this.disable(); }), this.eventsDispatcher.on(dt, () => { this.enable(); }); } /** * Enables onChange event */ enable() { this.mutationObserver.observe( this.Editor.UI.nodes.redactor, { childList: !0, subtree: !0, characterData: !0, attributes: !0 } ), this.disabled = !1; } /** * Disables onChange event */ disable() { this.mutationObserver.disconnect(), this.disabled = !0; } /** * Call onChange event passed to Editor.js configuration * * @param event - some of our custom change events */ particularBlockChanged(e) { this.disabled || !D(this.config.onChange) || (this.batchingOnChangeQueue.set(`block:${e.detail.target.id}:event:${e.type}`, e), this.batchingTimeout && clearTimeout(this.batchingTimeout), this.batchingTimeout = setTimeout(() => { let t; this.batchingOnChangeQueue.size === 1 ? t = this.batchingOnChangeQueue.values().next().value : t = Array.from(this.batchingOnChangeQueue.values()), this.config.onChange && this.config.onChange(this.Editor.API.methods, t), this.batchingOnChangeQueue.clear(); }, this.batchTime)); } /** * Fired on every blocks wrapper dom change * * @param mutations - mutations happened */ redactorChanged(e) { this.eventsDispatcher.emit(Me, { mutations: e }); } } const xt = class extends S { constructor() { super(...arguments), this.MIME_TYPE = "application/x-editor-js", this.toolsTags = {}, this.tagsByTool = {}, this.toolsPatterns = [], this.toolsFiles = {}, this.exceptionList = [], this.processTool = (s) => { try { const e = s.create({}, {}, !1); if (s.pasteConfig === !1) { this.exceptionList.push(s.name); return; } if (!D(e.onPaste)) return; this.getTagsConfig(s), this.getFilesConfig(s), this.getPatternsConfig(s); } catch (e) { T( `Paste handling for «${s.name}» Tool hasn't been set up because of the error`, "warn", e ); } }, this.handlePasteEvent = async (s) => { const { BlockManager: e, Toolbar: t } = this.Editor; !e.currentBlock || this.isNativeBehaviour(s.target) && !s.clipboardData.types.includes("Files") || e.currentBlock && this.exceptionList.includes(e.currentBlock.name) || (s.preventDefault(), this.processDataTransfer(s.clipboardData), e.clearFocused(), t.close()); }; } /** * Set onPaste callback and collect tools` paste configurations */ async prepare() { this.processTools(); } /** * Set read-only state * * @param {boolean} readOnlyEnabled - read only flag value */ toggleReadOnly(s) { s ? this.unsetCallback() : this.setCallback(); } /** * Handle pasted or dropped data transfer object * * @param {DataTransfer} dataTransfer - pasted or dropped data transfer object * @param {boolean} isDragNDrop - true if data transfer comes from drag'n'drop events */ async processDataTransfer(s, e = !1) { const { Tools: t } = this.Editor, o = s.types; if ((o.includes ? o.includes("Files") : o.contains("Files")) && !V(this.toolsFiles)) { await this.processFiles(s.files); return; } const n = s.getData(this.MIME_TYPE), r = s.getData("text/plain"); let a = s.getData("text/html"); if (n) try { this.insertEditorJSData(JSON.parse(n)); return; } catch { } e && r.trim() && a.trim() && (a = "

" + (a.trim() ? a : r) + "

"); const l = Object.keys(this.toolsTags).reduce((h, f) => (h[f.toLowerCase()] = this.toolsTags[f].sanitizationConfig ?? {}, h), {}), c = Object.assign({}, l, t.getAllInlineToolsSanitizeConfig(), { br: {} }), u = Z(a, c); !u.trim() || u.trim() === r || !d.isHTMLString(u) ? await this.processText(r) : await this.processText(u, !0); } /** * Process pasted text and divide them into Blocks * * @param {string} data - text to process. Can be HTML or plain. * @param {boolean} isHTML - if passed string is HTML, this parameter should be true */ async processText(s, e = !1) { const { Caret: t, BlockManager: o } = this.Editor, i = e ? this.processHTML(s) : this.processPlain(s); if (!i.length) return; if (i.length === 1) { i[0].isBlock ? this.processSingleBlock(i.pop()) : this.processInlinePaste(i.pop()); return; } const r = o.currentBlock && o.currentBlock.tool.isDefault && o.currentBlock.isEmpty; i.map( async (a, l) => this.insertBlock(a, l === 0 && r) ), o.currentBlock && t.setToBlock(o.currentBlock, t.positions.END); } /** * Set onPaste callback handler */ setCallback() { this.listeners.on(this.Editor.UI.nodes.holder, "paste", this.handlePasteEvent); } /** * Unset onPaste callback handler */ unsetCallback() { this.listeners.off(this.Editor.UI.nodes.holder, "paste", this.handlePasteEvent); } /** * Get and process tool`s paste configs */ processTools() { const s = this.Editor.Tools.blockTools; Array.from(s.values()).forEach(this.processTool); } /** * Get tags name list from either tag name or sanitization config. * * @param {string | object} tagOrSanitizeConfig - tag name or sanitize config object. * @returns {string[]} array of tags. */ collectTagNames(s) { return J(s) ? [s] : j(s) ? Object.keys(s) : []; } /** * Get tags to substitute by Tool * * @param tool - BlockTool object */ getTagsConfig(s) { if (s.pasteConfig === !1) return; const e = s.pasteConfig.tags || [], t = []; e.forEach((o) => { const i = this.collectTagNames(o); t.push(...i), i.forEach((n) => { if (Object.prototype.hasOwnProperty.call(this.toolsTags, n)) { T( `Paste handler for «${s.name}» Tool on «${n}» tag is skipped because it is already used by «${this.toolsTags[n].tool.name}» Tool.`, "warn" ); return; } const r = j(o) ? o[n] : null; this.toolsTags[n.toUpperCase()] = { tool: s, sanitizationConfig: r }; }); }), this.tagsByTool[s.name] = t.map((o) => o.toUpperCase()); } /** * Get files` types and extensions to substitute by Tool * * @param tool - BlockTool object */ getFilesConfig(s) { if (s.pasteConfig === !1) return; const { files: e = {} } = s.pasteConfig; let { extensions: t, mimeTypes: o } = e; !t && !o || (t && !Array.isArray(t) && (T(`«extensions» property of the onDrop config for «${s.name}» Tool should be an array`), t = []), o && !Array.isArray(o) && (T(`«mimeTypes» property of the onDrop config for «${s.name}» Tool should be an array`), o = []), o && (o = o.filter((i) => Dt(i) ? !0 : (T(`MIME type value «${i}» for the «${s.name}» Tool is not a valid MIME type`, "warn"), !1))), this.toolsFiles[s.name] = { extensions: t || [], mimeTypes: o || [] }); } /** * Get RegExp patterns to substitute by Tool * * @param tool - BlockTool object */ getPatternsConfig(s) { s.pasteConfig === !1 || !s.pasteConfig.patterns || V(s.pasteConfig.patterns) || Object.entries(s.pasteConfig.patterns).forEach(([e, t]) => { t instanceof RegExp || T( `Pattern ${t} for «${s.name}» Tool is skipped because it should be a Regexp instance.`, "warn" ), this.toolsPatterns.push({ key: e, pattern: t, tool: s }); }); } /** * Check if browser behavior suits better * * @param {EventTarget} element - element where content has been pasted * @returns {boolean} */ isNativeBehaviour(s) { return d.isNativeInput(s); } /** * Get files from data transfer object and insert related Tools * * @param {FileList} items - pasted or dropped items */ async processFiles(s) { const { BlockManager: e } = this.Editor; let t; t = await Promise.all( Array.from(s).map((n) => this.processFile(n)) ), t = t.filter((n) => !!n); const i = e.currentBlock.tool.isDefault && e.currentBlock.isEmpty; t.forEach( (n, r) => { e.paste(n.type, n.event, r === 0 && i); } ); } /** * Get information about file and find Tool to handle it * * @param {File} file - file to process */ async processFile(s) { const e = Rt(s), t = Object.entries(this.toolsFiles).find(([n, { mimeTypes: r, extensions: a }]) => { const [l, c] = s.type.split("/"), u = a.find((f) => f.toLowerCase() === e.toLowerCase()), h = r.find((f) => { const [v, p] = f.split("/"); return v === l && (p === c || p === "*"); }); return !!u || !!h; }); if (!t) return; const [o] = t; return { event: this.composePasteEvent("file", { file: s }), type: o }; } /** * Split HTML string to blocks and return it as array of Block data * * @param {string} innerHTML - html string to process * @returns {PasteData[]} */ processHTML(s) { const { Tools: e } = this.Editor, t = d.make("DIV"); return t.innerHTML = s, this.getNodes(t).map((i) => { let n, r = e.defaultTool, a = !1; switch (i.nodeType) { case Node.DOCUMENT_FRAGMENT_NODE: n = d.make("div"), n.appendChild(i); break; case Node.ELEMENT_NODE: n = i, a = !0, this.toolsTags[n.tagName] && (r = this.toolsTags[n.tagName].tool); break; } const { tags: l } = r.pasteConfig || { tags: [] }, c = l.reduce((f, v) => (this.collectTagNames(v).forEach((k) => { const _ = j(v) ? v[k] : null; f[k.toLowerCase()] = _ || {}; }), f), {}), u = Object.assign({}, c, r.baseSanitizeConfig); if (n.tagName.toLowerCase() === "table") { const f = Z(n.outerHTML, u); n = d.make("div", void 0, { innerHTML: f }).firstChild; } else n.innerHTML = Z(n.innerHTML, u); const h = this.composePasteEvent("tag", { data: n }); return { content: n, isBlock: a, tool: r.name, event: h }; }).filter((i) => { const n = d.isEmpty(i.content), r = d.isSingleTag(i.content); return !n || r; }); } /** * Split plain text by new line symbols and return it as array of Block data * * @param {string} plain - string to process * @returns {PasteData[]} */ processPlain(s) { const { defaultBlock: e } = this.config; if (!s) return []; const t = e; return s.split(/\r?\n/).filter((o) => o.trim()).map((o) => { const i = d.make("div"); i.textContent = o; const n = this.composePasteEvent("tag", { data: i }); return { content: i, tool: t, isBlock: !1, event: n }; }); } /** * Process paste of single Block tool content * * @param {PasteData} dataToInsert - data of Block to insert */ async processSingleBlock(s) { const { Caret: e, BlockManager: t } = this.Editor, { currentBlock: o } = t; if (!o || s.tool !== o.name || !d.containsOnlyInlineElements(s.content.innerHTML)) { this.insertBlock(s, (o == null ? void 0 : o.tool.isDefault) && o.isEmpty); return; } e.insertContentAtCaretPosition(s.content.innerHTML); } /** * Process paste to single Block: * 1. Find patterns` matches * 2. Insert new block if it is not the same type as current one * 3. Just insert text if there is no substitutions * * @param {PasteData} dataToInsert - data of Block to insert */ async processInlinePaste(s) { const { BlockManager: e, Caret: t } = this.Editor, { content: o } = s; if (e.currentBlock && e.currentBlock.tool.isDefault && o.textContent.length < xt.PATTERN_PROCESSING_MAX_LENGTH) { const n = await this.processPattern(o.textContent); if (n) { const r = e.currentBlock && e.currentBlock.tool.isDefault && e.currentBlock.isEmpty, a = e.paste(n.tool, n.event, r); t.setToBlock(a, t.positions.END); return; } } if (e.currentBlock && e.currentBlock.currentInput) { const n = e.currentBlock.tool.baseSanitizeConfig; document.execCommand( "insertHTML", !1, Z(o.innerHTML, n) ); } else this.insertBlock(s); } /** * Get patterns` matches * * @param {string} text - text to process * @returns {Promise<{event: PasteEvent, tool: string}>} */ async processPattern(s) { const e = this.toolsPatterns.find((o) => { const i = o.pattern.exec(s); return i ? s === i.shift() : !1; }); return e ? { event: this.composePasteEvent("pattern", { key: e.key, data: s }), tool: e.tool.name } : void 0; } /** * Insert pasted Block content to Editor * * @param {PasteData} data - data to insert * @param {boolean} canReplaceCurrentBlock - if true and is current Block is empty, will replace current Block * @returns {void} */ insertBlock(s, e = !1) { const { BlockManager: t, Caret: o } = this.Editor, { currentBlock: i } = t; let n; if (e && i && i.isEmpty) { n = t.paste(s.tool, s.event, !0), o.setToBlock(n, o.positions.END); return; } n = t.paste(s.tool, s.event), o.setToBlock(n, o.positions.END); } /** * Insert data passed as application/x-editor-js JSON * * @param {Array} blocks — Blocks' data to insert * @returns {void} */ insertEditorJSData(s) { const { BlockManager: e, Caret: t, Tools: o } = this.Editor; ht( s, (n) => o.blockTools.get(n).sanitizeConfig ).forEach(({ tool: n, data: r }, a) => { let l = !1; a === 0 && (l = e.currentBlock && e.currentBlock.tool.isDefault && e.currentBlock.isEmpty); const c = e.insert({ tool: n, data: r, replace: l }); t.setToBlock(c, t.positions.END); }); } /** * Fetch nodes from Element node * * @param {Node} node - current node * @param {Node[]} nodes - processed nodes * @param {Node} destNode - destination node */ processElementNode(s, e, t) { const o = Object.keys(this.toolsTags), i = s, { tool: n } = this.toolsTags[i.tagName] || {}, r = this.tagsByTool[n == null ? void 0 : n.name] || [], a = o.includes(i.tagName), l = d.blockElements.includes(i.tagName.toLowerCase()), c = Array.from(i.children).some( ({ tagName: h }) => o.includes(h) && !r.includes(h) ), u = Array.from(i.children).some( ({ tagName: h }) => d.blockElements.includes(h.toLowerCase()) ); if (!l && !a && !c) return t.appendChild(i), [...e, t]; if (a && !c || l && !u && !c) return [...e, t, i]; } /** * Recursively divide HTML string to two types of nodes: * 1. Block element * 2. Document Fragments contained text and markup tags like a, b, i etc. * * @param {Node} wrapper - wrapper of paster HTML content * @returns {Node[]} */ getNodes(s) { const e = Array.from(s.childNodes); let t; const o = (i, n) => { if (d.isEmpty(n) && !d.isSingleTag(n)) return i; const r = i[i.length - 1]; let a = new DocumentFragment(); switch (r && d.isFragment(r) && (a = i.pop()), n.nodeType) { case Node.ELEMENT_NODE: if (t = this.processElementNode(n, i, a), t) return t; break; case Node.TEXT_NODE: return a.appendChild(n), [...i, a]; default: return [...i, a]; } return [...i, ...Array.from(n.childNodes).reduce(o, [])]; }; return e.reduce(o, []); } /** * Compose paste event with passed type and detail * * @param {string} type - event type * @param {PasteEventDetail} detail - event detail */ composePasteEvent(s, e) { return new CustomEvent(s, { detail: e }); } }; let wt = xt; wt.PATTERN_PROCESSING_MAX_LENGTH = 450; class qo extends S { constructor() { super(...arguments), this.toolsDontSupportReadOnly = [], this.readOnlyEnabled = !1; } /** * Returns state of read only mode */ get isEnabled() { return this.readOnlyEnabled; } /** * Set initial state */ async prepare() { const { Tools: e } = this.Editor, { blockTools: t } = e, o = []; Array.from(t.entries()).forEach(([i, n]) => { n.isReadOnlySupported || o.push(i); }), this.toolsDontSupportReadOnly = o, this.config.readOnly && o.length > 0 && this.throwCriticalError(), this.toggle(this.config.readOnly); } /** * Set read-only mode or toggle current state * Call all Modules `toggleReadOnly` method and re-render Editor * * @param {boolean} state - (optional) read-only state or toggle */ async toggle(e = !this.readOnlyEnabled) { e && this.toolsDontSupportReadOnly.length > 0 && this.throwCriticalError(); const t = this.readOnlyEnabled; this.readOnlyEnabled = e; for (const i in this.Editor) this.Editor[i].toggleReadOnly && this.Editor[i].toggleReadOnly(e); if (t === e) return this.readOnlyEnabled; const o = await this.Editor.Saver.save(); return await this.Editor.BlockManager.clear(), await this.Editor.Renderer.render(o.blocks), this.readOnlyEnabled; } /** * Throws an error about tools which don't support read-only mode */ throwCriticalError() { throw new at( `To enable read-only mode all connected tools should support it. Tools ${this.toolsDontSupportReadOnly.join(", ")} don't support read-only mode.` ); } } class pe extends S { constructor() { super(...arguments), this.isRectSelectionActivated = !1, this.SCROLL_SPEED = 3, this.HEIGHT_OF_SCROLL_ZONE = 40, this.BOTTOM_SCROLL_ZONE = 1, this.TOP_SCROLL_ZONE = 2, this.MAIN_MOUSE_BUTTON = 0, this.mousedown = !1, this.isScrolling = !1, this.inScrollZone = null, this.startX = 0, this.startY = 0, this.mouseX = 0, this.mouseY = 0, this.stackOfSelected = [], this.listenerIds = []; } /** * CSS classes for the Block * * @returns {{wrapper: string, content: string}} */ static get CSS() { return { overlay: "codex-editor-overlay", overlayContainer: "codex-editor-overlay__container", rect: "codex-editor-overlay__rectangle", topScrollZone: "codex-editor-overlay__scroll-zone--top", bottomScrollZone: "codex-editor-overlay__scroll-zone--bottom" }; } /** * Module Preparation * Creating rect and hang handlers */ prepare() { this.enableModuleBindings(); } /** * Init rect params * * @param {number} pageX - X coord of mouse * @param {number} pageY - Y coord of mouse */ startSelection(e, t) { const o = document.elementFromPoint(e - window.pageXOffset, t - window.pageYOffset); o.closest(`.${this.Editor.Toolbar.CSS.toolbar}`) || (this.Editor.BlockSelection.allBlocksSelected = !1, this.clearSelection(), this.stackOfSelected = []); const n = [ `.${F.CSS.content}`, `.${this.Editor.Toolbar.CSS.toolbar}`, `.${this.Editor.InlineToolbar.CSS.inlineToolbar}` ], r = o.closest("." + this.Editor.UI.CSS.editorWrapper), a = n.some((l) => !!o.closest(l)); !r || a || (this.mousedown = !0, this.startX = e, this.startY = t); } /** * Clear all params to end selection */ endSelection() { this.mousedown = !1, this.startX = 0, this.startY = 0, this.overlayRectangle.style.display = "none"; } /** * is RectSelection Activated */ isRectActivated() { return this.isRectSelectionActivated; } /** * Mark that selection is end */ clearSelection() { this.isRectSelectionActivated = !1; } /** * Sets Module necessary event handlers */ enableModuleBindings() { const { container: e } = this.genHTML(); this.listeners.on(e, "mousedown", (t) => { this.processMouseDown(t); }, !1), this.listeners.on(document.body, "mousemove", Te((t) => { this.processMouseMove(t); }, 10), { passive: !0 }), this.listeners.on(document.body, "mouseleave", () => { this.processMouseLeave(); }), this.listeners.on(window, "scroll", Te((t) => { this.processScroll(t); }, 10), { passive: !0 }), this.listeners.on(document.body, "mouseup", () => { this.processMouseUp(); }, !1); } /** * Handle mouse down events * * @param {MouseEvent} mouseEvent - mouse event payload */ processMouseDown(e) { if (e.button !== this.MAIN_MOUSE_BUTTON) return; e.target.closest(d.allInputsSelector) !== null || this.startSelection(e.pageX, e.pageY); } /** * Handle mouse move events * * @param {MouseEvent} mouseEvent - mouse event payload */ processMouseMove(e) { this.changingRectangle(e), this.scrollByZones(e.clientY); } /** * Handle mouse leave */ processMouseLeave() { this.clearSelection(), this.endSelection(); } /** * @param {MouseEvent} mouseEvent - mouse event payload */ processScroll(e) { this.changingRectangle(e); } /** * Handle mouse up */ processMouseUp() { this.clearSelection(), this.endSelection(); } /** * Scroll If mouse in scroll zone * * @param {number} clientY - Y coord of mouse */ scrollByZones(e) { if (this.inScrollZone = null, e <= this.HEIGHT_OF_SCROLL_ZONE && (this.inScrollZone = this.TOP_SCROLL_ZONE), document.documentElement.clientHeight - e <= this.HEIGHT_OF_SCROLL_ZONE && (this.inScrollZone = this.BOTTOM_SCROLL_ZONE), !this.inScrollZone) { this.isScrolling = !1; return; } this.isScrolling || (this.scrollVertical(this.inScrollZone === this.TOP_SCROLL_ZONE ? -this.SCROLL_SPEED : this.SCROLL_SPEED), this.isScrolling = !0); } /** * Generates required HTML elements * * @returns {Object} */ genHTML() { const { UI: e } = this.Editor, t = e.nodes.holder.querySelector("." + e.CSS.editorWrapper), o = d.make("div", pe.CSS.overlay, {}), i = d.make("div", pe.CSS.overlayContainer, {}), n = d.make("div", pe.CSS.rect, {}); return i.appendChild(n), o.appendChild(i), t.appendChild(o), this.overlayRectangle = n, { container: t, overlay: o }; } /** * Activates scrolling if blockSelection is active and mouse is in scroll zone * * @param {number} speed - speed of scrolling */ scrollVertical(e) { if (!(this.inScrollZone && this.mousedown)) return; const t = window.pageYOffset; window.scrollBy(0, e), this.mouseY += window.pageYOffset - t, setTimeout(() => { this.scrollVertical(e); }, 0); } /** * Handles the change in the rectangle and its effect * * @param {MouseEvent} event - mouse event */ changingRectangle(e) { if (!this.mousedown) return; e.pageY !== void 0 && (this.mouseX = e.pageX, this.mouseY = e.pageY); const { rightPos: t, leftPos: o, index: i } = this.genInfoForMouseSelection(), n = this.startX > t && this.mouseX > t, r = this.startX < o && this.mouseX < o; this.rectCrossesBlocks = !(n || r), this.isRectSelectionActivated || (this.rectCrossesBlocks = !1, this.isRectSelectionActivated = !0, this.shrinkRectangleToPoint(), this.overlayRectangle.style.display = "block"), this.updateRectangleSize(), this.Editor.Toolbar.close(), i !== void 0 && (this.trySelectNextBlock(i), this.inverseSelection(), m.get().removeAllRanges()); } /** * Shrink rect to singular point */ shrinkRectangleToPoint() { this.overlayRectangle.style.left = `${this.startX - window.pageXOffset}px`, this.overlayRectangle.style.top = `${this.startY - window.pageYOffset}px`, this.overlayRectangle.style.bottom = `calc(100% - ${this.startY - window.pageYOffset}px`, this.overlayRectangle.style.right = `calc(100% - ${this.startX - window.pageXOffset}px`; } /** * Select or unselect all of blocks in array if rect is out or in selectable area */ inverseSelection() { const t = this.Editor.BlockManager.getBlockByIndex(this.stackOfSelected[0]).selected; if (this.rectCrossesBlocks && !t) for (const o of this.stackOfSelected) this.Editor.BlockSelection.selectBlockByIndex(o); if (!this.rectCrossesBlocks && t) for (const o of this.stackOfSelected) this.Editor.BlockSelection.unSelectBlockByIndex(o); } /** * Updates size of rectangle */ updateRectangleSize() { this.mouseY >= this.startY ? (this.overlayRectangle.style.top = `${this.startY - window.pageYOffset}px`, this.overlayRectangle.style.bottom = `calc(100% - ${this.mouseY - window.pageYOffset}px`) : (this.overlayRectangle.style.bottom = `calc(100% - ${this.startY - window.pageYOffset}px`, this.overlayRectangle.style.top = `${this.mouseY - window.pageYOffset}px`), this.mouseX >= this.startX ? (this.overlayRectangle.style.left = `${this.startX - window.pageXOffset}px`, this.overlayRectangle.style.right = `calc(100% - ${this.mouseX - window.pageXOffset}px`) : (this.overlayRectangle.style.right = `calc(100% - ${this.startX - window.pageXOffset}px`, this.overlayRectangle.style.left = `${this.mouseX - window.pageXOffset}px`); } /** * Collects information needed to determine the behavior of the rectangle * * @returns {object} index - index next Block, leftPos - start of left border of Block, rightPos - right border */ genInfoForMouseSelection() { const t = document.body.offsetWidth / 2, o = this.mouseY - window.pageYOffset, i = document.elementFromPoint(t, o), n = this.Editor.BlockManager.getBlockByChildNode(i); let r; n !== void 0 && (r = this.Editor.BlockManager.blocks.findIndex((h) => h.holder === n.holder)); const a = this.Editor.BlockManager.lastBlock.holder.querySelector("." + F.CSS.content), l = Number.parseInt(window.getComputedStyle(a).width, 10) / 2, c = t - l, u = t + l; return { index: r, leftPos: c, rightPos: u }; } /** * Select block with index index * * @param index - index of block in redactor */ addBlockInSelection(e) { this.rectCrossesBlocks && this.Editor.BlockSelection.selectBlockByIndex(e), this.stackOfSelected.push(e); } /** * Adds a block to the selection and determines which blocks should be selected * * @param {object} index - index of new block in the reactor */ trySelectNextBlock(e) { const t = this.stackOfSelected[this.stackOfSelected.length - 1] === e, o = this.stackOfSelected.length, i = 1, n = -1, r = 0; if (t) return; const a = this.stackOfSelected[o - 1] - this.stackOfSelected[o - 2] > 0; let l = r; o > 1 && (l = a ? i : n); const c = e > this.stackOfSelected[o - 1] && l === i, u = e < this.stackOfSelected[o - 1] && l === n, f = !(c || u || l === r); if (!f && (e > this.stackOfSelected[o - 1] || this.stackOfSelected[o - 1] === void 0)) { let k = this.stackOfSelected[o - 1] + 1 || e; for (k; k <= e; k++) this.addBlockInSelection(k); return; } if (!f && e < this.stackOfSelected[o - 1]) { for (let k = this.stackOfSelected[o - 1] - 1; k >= e; k--) this.addBlockInSelection(k); return; } if (!f) return; let v = o - 1, p; for (e > this.stackOfSelected[o - 1] ? p = () => e > this.stackOfSelected[v] : p = () => e < this.stackOfSelected[v]; p(); ) this.rectCrossesBlocks && this.Editor.BlockSelection.unSelectBlockByIndex(this.stackOfSelected[v]), this.stackOfSelected.pop(), v--; } } class Jo extends S { /** * @typedef {object} RendererBlocks * @property {string} type - tool name * @property {object} data - tool data */ /** * @example * * blocks: [ * { * id : 'oDe-EVrGWA', * type : 'paragraph', * data : { * text : 'Hello from Codex!' * } * }, * { * id : 'Ld5BJjJCHs', * type : 'paragraph', * data : { * text : 'Leave feedback if you like it!' * } * }, * ] */ /** * Make plugin blocks from array of plugin`s data * * @param {OutputBlockData[]} blocks - blocks to render */ async render(e) { const t = e.map((i) => ({ function: () => this.insertBlock(i) })); this.Editor.ModificationsObserver.disable(); const o = await ot(t); return this.Editor.ModificationsObserver.enable(), this.Editor.UI.checkEmptiness(), o; } /** * Get plugin instance * Add plugin instance to BlockManager * Insert block to working zone * * @param {object} item - Block data to insert * @returns {Promise} */ async insertBlock(e) { var l; const { Tools: t, BlockManager: o } = this.Editor, { type: i, data: n, tunes: r, id: a } = e; if (t.available.has(i)) try { o.insert({ id: a, tool: i, data: n, tunes: r }); } catch (c) { throw T(`Block «${i}» skipped because of plugins error`, "warn", { data: n, error: c }), Error(c); } else { const c = { savedData: { id: a, type: i, data: n }, title: i }; if (t.unavailable.has(i)) { const f = (l = t.unavailable.get(i).toolbox[0]) == null ? void 0 : l.title; c.title = f || c.title; } const u = o.insert({ id: a, tool: t.stubTool, data: c }); u.stretched = !0, T(`Tool «${i}» is not found. Check 'tools' property at your initial Editor.js config.`, "warn"); } } } class Qo extends S { /** * Composes new chain of Promises to fire them alternatelly * * @returns {OutputData} */ async save() { const { BlockManager: e, Tools: t } = this.Editor, o = e.blocks, i = []; try { o.forEach((a) => { i.push(this.getSavedData(a)); }); const n = await Promise.all(i), r = await ht(n, (a) => t.blockTools.get(a).sanitizeConfig); return this.makeOutput(r); } catch (n) { K("Saving failed due to the Error %o", "error", n); } } /** * Saves and validates * * @param {Block} block - Editor's Tool * @returns {ValidatedData} - Tool's validated data */ async getSavedData(e) { const t = await e.save(), o = t && await e.validate(t.data); return { ...t, isValid: o }; } /** * Creates output object with saved data, time and version of editor * * @param {ValidatedData} allExtractedData - data extracted from Blocks * @returns {OutputData} */ makeOutput(e) { let t = 0; const o = []; return T("[Editor.js saving]:", "groupCollapsed"), e.forEach(({ id: i, tool: n, data: r, tunes: a, time: l, isValid: c }) => { if (t += l, T(`${n.charAt(0).toUpperCase() + n.slice(1)}`, "group"), c) T(r), T(void 0, "groupEnd"); else { T(`Block «${n}» skipped because saved data is invalid`), T(void 0, "groupEnd"); return; } if (n === this.Editor.Tools.stubTool) { o.push(r); return; } const u = { id: i, type: n, data: r, ...!V(a) && { tunes: a } }; o.push(u); }), T("Total", "log", t), T(void 0, "groupEnd"), { time: +/* @__PURE__ */ new Date(), blocks: o, version: "2.27.2" }; } } var Ne = {}, ei = { get exports() { return Ne; }, set exports(s) { Ne = s; } }; (function(s, e) { (function(t, o) { s.exports = o(); })(window, function() { return function(t) { var o = {}; function i(n) { if (o[n]) return o[n].exports; var r = o[n] = { i: n, l: !1, exports: {} }; return t[n].call(r.exports, r, r.exports, i), r.l = !0, r.exports; } return i.m = t, i.c = o, i.d = function(n, r, a) { i.o(n, r) || Object.defineProperty(n, r, { enumerable: !0, get: a }); }, i.r = function(n) { typeof Symbol < "u" && Symbol.toStringTag && Object.defineProperty(n, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(n, "__esModule", { value: !0 }); }, i.t = function(n, r) { if (1 & r && (n = i(n)), 8 & r || 4 & r && typeof n == "object" && n && n.__esModule) return n; var a = /* @__PURE__ */ Object.create(null); if (i.r(a), Object.defineProperty(a, "default", { enumerable: !0, value: n }), 2 & r && typeof n != "string") for (var l in n) i.d(a, l, function(c) { return n[c]; }.bind(null, l)); return a; }, i.n = function(n) { var r = n && n.__esModule ? function() { return n.default; } : function() { return n; }; return i.d(r, "a", r), r; }, i.o = function(n, r) { return Object.prototype.hasOwnProperty.call(n, r); }, i.p = "/", i(i.s = 4); }([function(t, o, i) { var n = i(1), r = i(2); typeof (r = r.__esModule ? r.default : r) == "string" && (r = [[t.i, r, ""]]); var a = { insert: "head", singleton: !1 }; n(r, a), t.exports = r.locals || {}; }, function(t, o, i) { var n, r = function() { return n === void 0 && (n = !!(window && document && document.all && !window.atob)), n; }, a = function() { var y = {}; return function(x) { if (y[x] === void 0) { var w = document.querySelector(x); if (window.HTMLIFrameElement && w instanceof window.HTMLIFrameElement) try { w = w.contentDocument.head; } catch { w = null; } y[x] = w; } return y[x]; }; }(), l = []; function c(y) { for (var x = -1, w = 0; w < l.length; w++) if (l[w].identifier === y) { x = w; break; } return x; } function u(y, x) { for (var w = {}, M = [], R = 0; R < y.length; R++) { var b = y[R], g = x.base ? b[0] + x.base : b[0], E = w[g] || 0, C = "".concat(g, " ").concat(E); w[g] = E + 1; var O = c(C), I = { css: b[1], media: b[2], sourceMap: b[3] }; O !== -1 ? (l[O].references++, l[O].updater(I)) : l.push({ identifier: C, updater: A(I, x), references: 1 }), M.push(C); } return M; } function h(y) { var x = document.createElement("style"), w = y.attributes || {}; if (w.nonce === void 0) { var M = i.nc; M && (w.nonce = M); } if (Object.keys(w).forEach(function(b) { x.setAttribute(b, w[b]); }), typeof y.insert == "function") y.insert(x); else { var R = a(y.insert || "head"); if (!R) throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid."); R.appendChild(x); } return x; } var f, v = (f = [], function(y, x) { return f[y] = x, f.filter(Boolean).join(` `); }); function p(y, x, w, M) { var R = w ? "" : M.media ? "@media ".concat(M.media, " {").concat(M.css, "}") : M.css; if (y.styleSheet) y.styleSheet.cssText = v(x, R); else { var b = document.createTextNode(R), g = y.childNodes; g[x] && y.removeChild(g[x]), g.length ? y.insertBefore(b, g[x]) : y.appendChild(b); } } function k(y, x, w) { var M = w.css, R = w.media, b = w.sourceMap; if (R ? y.setAttribute("media", R) : y.removeAttribute("media"), b && btoa && (M += ` /*# sourceMappingURL=data:application/json;base64,`.concat(btoa(unescape(encodeURIComponent(JSON.stringify(b)))), " */")), y.styleSheet) y.styleSheet.cssText = M; else { for (; y.firstChild; ) y.removeChild(y.firstChild); y.appendChild(document.createTextNode(M)); } } var _ = null, N = 0; function A(y, x) { var w, M, R; if (x.singleton) { var b = N++; w = _ || (_ = h(x)), M = p.bind(null, w, b, !1), R = p.bind(null, w, b, !0); } else w = h(x), M = k.bind(null, w, x), R = function() { (function(g) { if (g.parentNode === null) return !1; g.parentNode.removeChild(g); })(w); }; return M(y), function(g) { if (g) { if (g.css === y.css && g.media === y.media && g.sourceMap === y.sourceMap) return; M(y = g); } else R(); }; } t.exports = function(y, x) { (x = x || {}).singleton || typeof x.singleton == "boolean" || (x.singleton = r()); var w = u(y = y || [], x); return function(M) { if (M = M || [], Object.prototype.toString.call(M) === "[object Array]") { for (var R = 0; R < w.length; R++) { var b = c(w[R]); l[b].references--; } for (var g = u(M, x), E = 0; E < w.length; E++) { var C = c(w[E]); l[C].references === 0 && (l[C].updater(), l.splice(C, 1)); } w = g; } }; }; }, function(t, o, i) { (o = i(3)(!1)).push([t.i, `.ce-paragraph { line-height: 1.6em; outline: none; } .ce-paragraph[data-placeholder]:empty::before{ content: attr(data-placeholder); color: #707684; font-weight: normal; opacity: 0; } /** Show placeholder at the first paragraph if Editor is empty */ .codex-editor--empty .ce-block:first-child .ce-paragraph[data-placeholder]:empty::before { opacity: 1; } .codex-editor--toolbox-opened .ce-block:first-child .ce-paragraph[data-placeholder]:empty::before, .codex-editor--empty .ce-block:first-child .ce-paragraph[data-placeholder]:empty:focus::before { opacity: 0; } .ce-paragraph p:first-of-type{ margin-top: 0; } .ce-paragraph p:last-of-type{ margin-bottom: 0; } `, ""]), t.exports = o; }, function(t, o, i) { t.exports = function(n) { var r = []; return r.toString = function() { return this.map(function(a) { var l = function(c, u) { var h = c[1] || "", f = c[3]; if (!f) return h; if (u && typeof btoa == "function") { var v = (k = f, _ = btoa(unescape(encodeURIComponent(JSON.stringify(k)))), N = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(_), "/*# ".concat(N, " */")), p = f.sources.map(function(A) { return "/*# sourceURL=".concat(f.sourceRoot || "").concat(A, " */"); }); return [h].concat(p).concat([v]).join(` `); } var k, _, N; return [h].join(` `); }(a, n); return a[2] ? "@media ".concat(a[2], " {").concat(l, "}") : l; }).join(""); }, r.i = function(a, l, c) { typeof a == "string" && (a = [[null, a, ""]]); var u = {}; if (c) for (var h = 0; h < this.length; h++) { var f = this[h][0]; f != null && (u[f] = !0); } for (var v = 0; v < a.length; v++) { var p = [].concat(a[v]); c && u[p[0]] || (l && (p[2] ? p[2] = "".concat(l, " and ").concat(p[2]) : p[2] = l), r.push(p)); } }, r; }; }, function(t, o, i) { i.r(o), i.d(o, "default", function() { return a; }), i(0); function n(l, c) { for (var u = 0; u < c.length; u++) { var h = c[u]; h.enumerable = h.enumerable || !1, h.configurable = !0, "value" in h && (h.writable = !0), Object.defineProperty(l, h.key, h); } } function r(l, c, u) { return c && n(l.prototype, c), u && n(l, u), l; } /** * Base Paragraph Block for the Editor.js. * Represents simple paragraph * * @author CodeX (team@codex.so) * @copyright CodeX 2018 * @license The MIT License (MIT) */ var a = function() { function l(c) { var u = c.data, h = c.config, f = c.api, v = c.readOnly; (function(p, k) { if (!(p instanceof k)) throw new TypeError("Cannot call a class as a function"); })(this, l), this.api = f, this.readOnly = v, this._CSS = { block: this.api.styles.block, wrapper: "ce-paragraph" }, this.readOnly || (this.onKeyUp = this.onKeyUp.bind(this)), this._placeholder = h.placeholder ? h.placeholder : l.DEFAULT_PLACEHOLDER, this._data = {}, this._element = this.drawView(), this._preserveBlank = h.preserveBlank !== void 0 && h.preserveBlank, this.data = u; } return r(l, null, [{ key: "DEFAULT_PLACEHOLDER", get: function() { return ""; } }]), r(l, [{ key: "onKeyUp", value: function(c) { c.code !== "Backspace" && c.code !== "Delete" || this._element.textContent === "" && (this._element.innerHTML = ""); } }, { key: "drawView", value: function() { var c = document.createElement("DIV"); return c.classList.add(this._CSS.wrapper, this._CSS.block), c.contentEditable = !1, c.dataset.placeholder = this.api.i18n.t(this._placeholder), this.readOnly || (c.contentEditable = !0, c.addEventListener("keyup", this.onKeyUp)), c; } }, { key: "render", value: function() { return this._element; } }, { key: "merge", value: function(c) { var u = { text: this.data.text + c.text }; this.data = u; } }, { key: "validate", value: function(c) { return !(c.text.trim() === "" && !this._preserveBlank); } }, { key: "save", value: function(c) { return { text: c.innerHTML }; } }, { key: "onPaste", value: function(c) { var u = { text: c.detail.data.innerHTML }; this.data = u; } }, { key: "data", get: function() { var c = this._element.innerHTML; return this._data.text = c, this._data; }, set: function(c) { this._data = c || {}, this._element.innerHTML = this._data.text || ""; } }], [{ key: "conversionConfig", get: function() { return { export: "text", import: "text" }; } }, { key: "sanitize", get: function() { return { text: { br: !0 } }; } }, { key: "isReadOnlySupported", get: function() { return !0; } }, { key: "pasteConfig", get: function() { return { tags: ["P"] }; } }, { key: "toolbox", get: function() { return { icon: '', title: "Text" }; } }]), l; }(); }]).default; }); })(ei); const ti = /* @__PURE__ */ xe(Ne); class $e { constructor() { this.commandName = "bold", this.CSS = { button: "ce-inline-tool", buttonActive: "ce-inline-tool--active", buttonModifier: "ce-inline-tool--bold" }, this.nodes = { button: void 0 }; } /** * Sanitizer Rule * Leave tags * * @returns {object} */ static get sanitize() { return { b: {} }; } /** * Create button for Inline Toolbar */ render() { return this.nodes.button = document.createElement("button"), this.nodes.button.type = "button", this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier), this.nodes.button.innerHTML = Eo, this.nodes.button; } /** * Wrap range with tag */ surround() { document.execCommand(this.commandName); } /** * Check selection and set activated state to button if there are tag * * @returns {boolean} */ checkState() { const e = document.queryCommandState(this.commandName); return this.nodes.button.classList.toggle(this.CSS.buttonActive, e), e; } /** * Set a shortcut * * @returns {boolean} */ get shortcut() { return "CMD+B"; } } $e.isInline = !0; $e.title = "Bold"; class We { constructor() { this.commandName = "italic", this.CSS = { button: "ce-inline-tool", buttonActive: "ce-inline-tool--active", buttonModifier: "ce-inline-tool--italic" }, this.nodes = { button: null }; } /** * Sanitizer Rule * Leave tags * * @returns {object} */ static get sanitize() { return { i: {} }; } /** * Create button for Inline Toolbar */ render() { return this.nodes.button = document.createElement("button"), this.nodes.button.type = "button", this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier), this.nodes.button.innerHTML = So, this.nodes.button; } /** * Wrap range with tag */ surround() { document.execCommand(this.commandName); } /** * Check selection and set activated state to button if there are tag */ checkState() { const e = document.queryCommandState(this.commandName); return this.nodes.button.classList.toggle(this.CSS.buttonActive, e), e; } /** * Set a shortcut */ get shortcut() { return "CMD+I"; } } We.isInline = !0; We.title = "Italic"; class Ye { /** * @param api - Editor.js API */ constructor({ api: e }) { this.commandLink = "createLink", this.commandUnlink = "unlink", this.ENTER_KEY = 13, this.CSS = { button: "ce-inline-tool", buttonActive: "ce-inline-tool--active", buttonModifier: "ce-inline-tool--link", buttonUnlink: "ce-inline-tool--unlink", input: "ce-inline-tool-input", inputShowed: "ce-inline-tool-input--showed" }, this.nodes = { button: null, input: null }, this.inputOpened = !1, this.toolbar = e.toolbar, this.inlineToolbar = e.inlineToolbar, this.notifier = e.notifier, this.i18n = e.i18n, this.selection = new m(); } /** * Sanitizer Rule * Leave
tags * * @returns {object} */ static get sanitize() { return { a: { href: !0, target: "_blank", rel: "nofollow" } }; } /** * Create button for Inline Toolbar */ render() { return this.nodes.button = document.createElement("button"), this.nodes.button.type = "button", this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier), this.nodes.button.innerHTML = qe, this.nodes.button; } /** * Input for the link */ renderActions() { return this.nodes.input = document.createElement("input"), this.nodes.input.placeholder = this.i18n.t("Add a link"), this.nodes.input.classList.add(this.CSS.input), this.nodes.input.addEventListener("keydown", (e) => { e.keyCode === this.ENTER_KEY && this.enterPressed(e); }), this.nodes.input; } /** * Handle clicks on the Inline Toolbar icon * * @param {Range} range - range to wrap with link */ surround(e) { if (e) { this.inputOpened ? (this.selection.restore(), this.selection.removeFakeBackground()) : (this.selection.setFakeBackground(), this.selection.save()); const t = this.selection.findParentTag("A"); if (t) { this.selection.expandToTag(t), this.unlink(), this.closeActions(), this.checkState(), this.toolbar.close(); return; } } this.toggleActions(); } /** * Check selection and set activated state to button if there are tag */ checkState() { const e = this.selection.findParentTag("A"); if (e) { this.nodes.button.innerHTML = Oo, this.nodes.button.classList.add(this.CSS.buttonUnlink), this.nodes.button.classList.add(this.CSS.buttonActive), this.openActions(); const t = e.getAttribute("href"); this.nodes.input.value = t !== "null" ? t : "", this.selection.save(); } else this.nodes.button.innerHTML = qe, this.nodes.button.classList.remove(this.CSS.buttonUnlink), this.nodes.button.classList.remove(this.CSS.buttonActive); return !!e; } /** * Function called with Inline Toolbar closing */ clear() { this.closeActions(); } /** * Set a shortcut */ get shortcut() { return "CMD+K"; } /** * Show/close link input */ toggleActions() { this.inputOpened ? this.closeActions(!1) : this.openActions(!0); } /** * @param {boolean} needFocus - on link creation we need to focus input. On editing - nope. */ openActions(e = !1) { this.nodes.input.classList.add(this.CSS.inputShowed), e && this.nodes.input.focus(), this.inputOpened = !0; } /** * Close input * * @param {boolean} clearSavedSelection — we don't need to clear saved selection * on toggle-clicks on the icon of opened Toolbar */ closeActions(e = !0) { if (this.selection.isFakeBackgroundEnabled) { const t = new m(); t.save(), this.selection.restore(), this.selection.removeFakeBackground(), t.restore(); } this.nodes.input.classList.remove(this.CSS.inputShowed), this.nodes.input.value = "", e && this.selection.clearSaved(), this.inputOpened = !1; } /** * Enter pressed on input * * @param {KeyboardEvent} event - enter keydown event */ enterPressed(e) { let t = this.nodes.input.value || ""; if (!t.trim()) { this.selection.restore(), this.unlink(), e.preventDefault(), this.closeActions(); return; } if (!this.validateURL(t)) { this.notifier.show({ message: "Pasted link is not valid.", style: "error" }), T("Incorrect Link pasted", "warn", t); return; } t = this.prepareLink(t), this.selection.restore(), this.selection.removeFakeBackground(), this.insertLink(t), e.preventDefault(), e.stopPropagation(), e.stopImmediatePropagation(), this.selection.collapseToEnd(), this.inlineToolbar.close(); } /** * Detects if passed string is URL * * @param {string} str - string to validate * @returns {boolean} */ validateURL(e) { return !/\s/.test(e); } /** * Process link before injection * - sanitize * - add protocol for links like 'google.com' * * @param {string} link - raw user input */ prepareLink(e) { return e = e.trim(), e = this.addProtocol(e), e; } /** * Add 'http' protocol to the links like 'vc.ru', 'google.com' * * @param {string} link - string to process */ addProtocol(e) { if (/^(\w+):(\/\/)?/.test(e)) return e; const t = /^\/[^/\s]/.test(e), o = e.substring(0, 1) === "#", i = /^\/\/[^/\s]/.test(e); return !t && !o && !i && (e = "http://" + e), e; } /** * Inserts tag with "href" * * @param {string} link - "href" value */ insertLink(e) { const t = this.selection.findParentTag("A"); t && this.selection.expandToTag(t), document.execCommand(this.commandLink, !1, e); } /** * Removes tag */ unlink() { document.execCommand(this.commandUnlink); } } Ye.isInline = !0; Ye.title = "Link"; class yt { /** * @param options - constructor options * @param options.data - stub tool data * @param options.api - Editor.js API */ constructor({ data: e, api: t }) { this.CSS = { wrapper: "ce-stub", info: "ce-stub__info", title: "ce-stub__title", subtitle: "ce-stub__subtitle" }, this.api = t, this.title = e.title || this.api.i18n.t("Error"), this.subtitle = this.api.i18n.t("The block can not be displayed correctly."), this.savedData = e.savedData, this.wrapper = this.make(); } /** * Returns stub holder * * @returns {HTMLElement} */ render() { return this.wrapper; } /** * Return original Tool data * * @returns {BlockToolData} */ save() { return this.savedData; } /** * Create Tool html markup * * @returns {HTMLElement} */ make() { const e = d.make("div", this.CSS.wrapper), t = '', o = d.make("div", this.CSS.info), i = d.make("div", this.CSS.title, { textContent: this.title }), n = d.make("div", this.CSS.subtitle, { textContent: this.subtitle }); return e.innerHTML = t, o.appendChild(i), o.appendChild(n), e.appendChild(o), e; } } yt.isReadOnlySupported = !0; class oi extends Ue { constructor() { super(...arguments), this.type = ye.Inline; } /** * Returns title for Inline Tool if specified by user */ get title() { return this.constructable[je.Title]; } /** * Constructs new InlineTool instance from constructable */ create() { return new this.constructable({ api: this.api.getMethodsForTool(this), config: this.settings }); } } class ii extends Ue { constructor() { super(...arguments), this.type = ye.Tune; } /** * Constructs new BlockTune instance from constructable * * @param data - Tune data * @param block - Block API object */ create(e, t) { return new this.constructable({ api: this.api.getMethodsForTool(this), config: this.settings, block: t, data: e }); } } class U extends Map { /** * Returns Block Tools collection */ get blockTools() { const e = Array.from(this.entries()).filter(([, t]) => t.isBlock()); return new U(e); } /** * Returns Inline Tools collection */ get inlineTools() { const e = Array.from(this.entries()).filter(([, t]) => t.isInline()); return new U(e); } /** * Returns Block Tunes collection */ get blockTunes() { const e = Array.from(this.entries()).filter(([, t]) => t.isTune()); return new U(e); } /** * Returns internal Tools collection */ get internalTools() { const e = Array.from(this.entries()).filter(([, t]) => t.isInternal); return new U(e); } /** * Returns Tools collection provided by user */ get externalTools() { const e = Array.from(this.entries()).filter(([, t]) => !t.isInternal); return new U(e); } } var ni = Object.defineProperty, si = Object.getOwnPropertyDescriptor, Et = (s, e, t, o) => { for (var i = o > 1 ? void 0 : o ? si(e, t) : e, n = s.length - 1, r; n >= 0; n--) (r = s[n]) && (i = (o ? r(e, t, i) : r(i)) || i); return o && i && ni(e, t, i), i; }; class Ke extends Ue { constructor() { super(...arguments), this.type = ye.Block, this.inlineTools = new U(), this.tunes = new U(); } /** * Creates new Tool instance * * @param data - Tool data * @param block - BlockAPI for current Block * @param readOnly - True if Editor is in read-only mode */ create(e, t, o) { return new this.constructable({ data: e, block: t, readOnly: o, api: this.api.getMethodsForTool(this), config: this.settings }); } /** * Returns true if read-only mode is supported by Tool */ get isReadOnlySupported() { return this.constructable[se.IsReadOnlySupported] === !0; } /** * Returns true if Tool supports linebreaks */ get isLineBreaksEnabled() { return this.constructable[se.IsEnabledLineBreaks]; } /** * Returns Tool toolbox configuration (internal or user-specified). * * Merges internal and user-defined toolbox configs based on the following rules: * * - If both internal and user-defined toolbox configs are arrays their items are merged. * Length of the second one is kept. * * - If both are objects their properties are merged. * * - If one is an object and another is an array than internal config is replaced with user-defined * config. This is made to allow user to override default tool's toolbox representation (single/multiple entries) */ get toolbox() { const e = this.constructable[se.Toolbox], t = this.config[me.Toolbox]; if (!V(e) && t !== !1) return t ? Array.isArray(e) ? Array.isArray(t) ? t.map((o, i) => { const n = e[i]; return n ? { ...n, ...o } : o; }) : [t] : Array.isArray(t) ? t : [ { ...e, ...t } ] : Array.isArray(e) ? e : [e]; } /** * Returns Tool conversion configuration */ get conversionConfig() { return this.constructable[se.ConversionConfig]; } /** * Returns enabled inline tools for Tool */ get enabledInlineTools() { return this.config[me.EnabledInlineTools] || !1; } /** * Returns enabled tunes for Tool */ get enabledBlockTunes() { return this.config[me.EnabledBlockTunes]; } /** * Returns Tool paste configuration */ get pasteConfig() { return this.constructable[se.PasteConfig] ?? {}; } get sanitizeConfig() { const e = super.sanitizeConfig, t = this.baseSanitizeConfig; if (V(e)) return t; const o = {}; for (const i in e) if (Object.prototype.hasOwnProperty.call(e, i)) { const n = e[i]; j(n) ? o[i] = Object.assign({}, t, n) : o[i] = n; } return o; } get baseSanitizeConfig() { const e = {}; return Array.from(this.inlineTools.values()).forEach((t) => Object.assign(e, t.sanitizeConfig)), Array.from(this.tunes.values()).forEach((t) => Object.assign(e, t.sanitizeConfig)), e; } } Et([ ae ], Ke.prototype, "sanitizeConfig", 1); Et([ ae ], Ke.prototype, "baseSanitizeConfig", 1); class ri { /** * @class * @param config - tools config * @param editorConfig - EditorJS config * @param api - EditorJS API module */ constructor(e, t, o) { this.api = o, this.config = e, this.editorConfig = t; } /** * Returns Tool object based on it's type * * @param name - tool name */ get(e) { const { class: t, isInternal: o = !1, ...i } = this.config[e], n = this.getConstructor(t); return new n({ name: e, constructable: t, config: i, api: this.api, isDefault: e === this.editorConfig.defaultBlock, defaultPlaceholder: this.editorConfig.placeholder, isInternal: o }); } /** * Find appropriate Tool object constructor for Tool constructable * * @param constructable - Tools constructable */ getConstructor(e) { switch (!0) { case e[je.IsInline]: return oi; case e[vt.IsTune]: return ii; default: return Ke; } } } class Bt { /** * MoveDownTune constructor * * @param {API} api — Editor's API */ constructor({ api: e }) { this.CSS = { animation: "wobble" }, this.api = e; } /** * Tune's appearance in block settings menu */ render() { return { icon: pt, title: this.api.i18n.t("Move down"), onActivate: () => this.handleClick(), name: "move-down" }; } /** * Handle clicks on 'move down' button */ handleClick() { const e = this.api.blocks.getCurrentBlockIndex(), t = this.api.blocks.getBlockByIndex(e + 1); if (!t) throw new Error("Unable to move Block down since it is already the last"); const o = t.holder, i = o.getBoundingClientRect(); let n = Math.abs(window.innerHeight - o.offsetHeight); i.top < window.innerHeight && (n = window.scrollY + o.offsetHeight), window.scrollTo(0, n), this.api.blocks.move(e + 1), this.api.toolbar.toggleBlockSettings(!0); } } Bt.isTune = !0; class Ct { /** * DeleteTune constructor * * @param {API} api - Editor's API */ constructor({ api: e }) { this.api = e; } /** * Tune's appearance in block settings menu */ render() { return { icon: Co, title: this.api.i18n.t("Delete"), name: "delete", confirmation: { title: this.api.i18n.t("Click to delete"), onActivate: () => this.handleClick() } }; } /** * Delete block conditions passed */ handleClick() { this.api.blocks.delete(); } } Ct.isTune = !0; class Tt { /** * MoveUpTune constructor * * @param {API} api - Editor's API */ constructor({ api: e }) { this.CSS = { animation: "wobble" }, this.api = e; } /** * Tune's appearance in block settings menu */ render() { return { icon: Bo, title: this.api.i18n.t("Move up"), onActivate: () => this.handleClick(), name: "move-up" }; } /** * Move current block up */ handleClick() { const e = this.api.blocks.getCurrentBlockIndex(), t = this.api.blocks.getBlockByIndex(e), o = this.api.blocks.getBlockByIndex(e - 1); if (e === 0 || !t || !o) throw new Error("Unable to move Block up since it is already the first"); const i = t.holder, n = o.holder, r = i.getBoundingClientRect(), a = n.getBoundingClientRect(); let l; a.top > 0 ? l = Math.abs(r.top) - Math.abs(a.top) : l = Math.abs(r.top) + a.height, window.scrollBy(0, -1 * l), this.api.blocks.move(e - 1), this.api.toolbar.toggleBlockSettings(!0); } } Tt.isTune = !0; var ai = Object.defineProperty, li = Object.getOwnPropertyDescriptor, ci = (s, e, t, o) => { for (var i = o > 1 ? void 0 : o ? li(e, t) : e, n = s.length - 1, r; n >= 0; n--) (r = s[n]) && (i = (o ? r(e, t, i) : r(i)) || i); return o && i && ai(e, t, i), i; }; class St extends S { constructor() { super(...arguments), this.stubTool = "stub", this.toolsAvailable = new U(), this.toolsUnavailable = new U(); } /** * Returns available Tools */ get available() { return this.toolsAvailable; } /** * Returns unavailable Tools */ get unavailable() { return this.toolsUnavailable; } /** * Return Tools for the Inline Toolbar */ get inlineTools() { return this.available.inlineTools; } /** * Return editor block tools */ get blockTools() { return this.available.blockTools; } /** * Return available Block Tunes * * @returns {object} - object of Inline Tool's classes */ get blockTunes() { return this.available.blockTunes; } /** * Returns default Tool object */ get defaultTool() { return this.blockTools.get(this.config.defaultBlock); } /** * Returns internal tools */ get internal() { return this.available.internalTools; } /** * Creates instances via passed or default configuration * * @returns {Promise} */ async prepare() { if (this.validateTools(), this.config.tools = Se({}, this.internalTools, this.config.tools), !Object.prototype.hasOwnProperty.call(this.config, "tools") || Object.keys(this.config.tools).length === 0) throw Error("Can't start without tools"); const e = this.prepareConfig(); this.factory = new ri(e, this.config, this.Editor.API); const t = this.getListOfPrepareFunctions(e); if (t.length === 0) return Promise.resolve(); await ot(t, (o) => { this.toolPrepareMethodSuccess(o); }, (o) => { this.toolPrepareMethodFallback(o); }), this.prepareBlockTools(); } getAllInlineToolsSanitizeConfig() { const e = {}; return Array.from(this.inlineTools.values()).forEach((t) => { Object.assign(e, t.sanitizeConfig); }), e; } /** * Calls each Tool reset method to clean up anything set by Tool */ destroy() { Object.values(this.available).forEach(async (e) => { D(e.reset) && await e.reset(); }); } /** * Returns internal tools * Includes Bold, Italic, Link and Paragraph */ get internalTools() { return { bold: { class: $e, isInternal: !0 }, italic: { class: We, isInternal: !0 }, link: { class: Ye, isInternal: !0 }, paragraph: { class: ti, inlineToolbar: !0, isInternal: !0 }, stub: { class: yt, isInternal: !0 }, moveUp: { class: Tt, isInternal: !0 }, delete: { class: Ct, isInternal: !0 }, moveDown: { class: Bt, isInternal: !0 } }; } /** * Tool prepare method success callback * * @param {object} data - append tool to available list */ toolPrepareMethodSuccess(e) { const t = this.factory.get(e.toolName); if (t.isInline()) { const i = ["render", "surround", "checkState"].filter((n) => !t.create()[n]); if (i.length) { T( `Incorrect Inline Tool: ${t.name}. Some of required methods is not implemented %o`, "warn", i ), this.toolsUnavailable.set(t.name, t); return; } } this.toolsAvailable.set(t.name, t); } /** * Tool prepare method fail callback * * @param {object} data - append tool to unavailable list */ toolPrepareMethodFallback(e) { this.toolsUnavailable.set(e.toolName, this.factory.get(e.toolName)); } /** * Binds prepare function of plugins with user or default config * * @returns {Array} list of functions that needs to be fired sequentially * @param config - tools config */ getListOfPrepareFunctions(e) { const t = []; return Object.entries(e).forEach(([o, i]) => { t.push({ // eslint-disable-next-line @typescript-eslint/no-empty-function function: D(i.class.prepare) ? i.class.prepare : () => { }, data: { toolName: o, config: i.config } }); }), t; } /** * Assign enabled Inline Tools and Block Tunes for Block Tool */ prepareBlockTools() { Array.from(this.blockTools.values()).forEach((e) => { this.assignInlineToolsToBlockTool(e), this.assignBlockTunesToBlockTool(e); }); } /** * Assign enabled Inline Tools for Block Tool * * @param tool - Block Tool */ assignInlineToolsToBlockTool(e) { if (this.config.inlineToolbar !== !1) { if (e.enabledInlineTools === !0) { e.inlineTools = new U( Array.isArray(this.config.inlineToolbar) ? this.config.inlineToolbar.map((t) => [t, this.inlineTools.get(t)]) : Array.from(this.inlineTools.entries()) ); return; } Array.isArray(e.enabledInlineTools) && (e.inlineTools = new U( e.enabledInlineTools.map((t) => [t, this.inlineTools.get(t)]) )); } } /** * Assign enabled Block Tunes for Block Tool * * @param tool — Block Tool */ assignBlockTunesToBlockTool(e) { if (e.enabledBlockTunes !== !1) { if (Array.isArray(e.enabledBlockTunes)) { const t = new U( e.enabledBlockTunes.map((o) => [o, this.blockTunes.get(o)]) ); e.tunes = new U([...t, ...this.blockTunes.internalTools]); return; } if (Array.isArray(this.config.tunes)) { const t = new U( this.config.tunes.map((o) => [o, this.blockTunes.get(o)]) ); e.tunes = new U([...t, ...this.blockTunes.internalTools]); return; } e.tunes = this.blockTunes.internalTools; } } /** * Validate Tools configuration objects and throw Error for user if it is invalid */ validateTools() { for (const e in this.config.tools) if (Object.prototype.hasOwnProperty.call(this.config.tools, e)) { if (e in this.internalTools) return; const t = this.config.tools[e]; if (!D(t) && !D(t.class)) throw Error( `Tool «${e}» must be a constructor function or an object with function in the «class» property` ); } } /** * Unify tools config */ prepareConfig() { const e = {}; for (const t in this.config.tools) j(this.config.tools[t]) ? e[t] = this.config.tools[t] : e[t] = { class: this.config.tools[t] }; return e; } } ci([ ae ], St.prototype, "getAllInlineToolsSanitizeConfig", 1); const di = `:root{--selectionColor: #e1f2ff;--inlineSelectionColor: #d4ecff;--bg-light: #eff2f5;--grayText: #707684;--color-dark: #1D202B;--color-active-icon: #388AE5;--color-gray-border: rgba(201, 201, 204, .48);--content-width: 650px;--narrow-mode-right-padding: 50px;--toolbox-buttons-size: 26px;--toolbox-buttons-size--mobile: 36px;--icon-size: 20px;--icon-size--mobile: 28px;--block-padding-vertical: .4em;--color-line-gray: #EFF0F1 }.codex-editor{position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;z-index:1}.codex-editor .hide,.codex-editor__redactor--hidden{display:none}.codex-editor__redactor [contenteditable]:empty:after{content:"\\feff"}@media (min-width: 651px){.codex-editor--narrow .codex-editor__redactor{margin-right:50px}}@media (min-width: 651px){.codex-editor--narrow.codex-editor--rtl .codex-editor__redactor{margin-left:50px;margin-right:0}}@media (min-width: 651px){.codex-editor--narrow .ce-toolbar__actions{right:-5px}}.codex-editor__loader{position:relative;height:30vh}.codex-editor__loader:before{content:"";position:absolute;left:50%;top:50%;width:30px;height:30px;margin-top:-15px;margin-left:-15px;border-radius:50%;border:2px solid rgba(201,201,204,.48);border-top-color:transparent;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-animation:editor-loader-spin .8s infinite linear;animation:editor-loader-spin .8s infinite linear;will-change:transform}.codex-editor-copyable{position:absolute;height:1px;width:1px;top:-400%;opacity:.001}.codex-editor-overlay{position:fixed;top:0px;left:0px;right:0px;bottom:0px;z-index:999;pointer-events:none;overflow:hidden}.codex-editor-overlay__container{position:relative;pointer-events:auto;z-index:0}.codex-editor-overlay__rectangle{position:absolute;pointer-events:none;background-color:#2eaadc33;border:1px solid transparent}.codex-editor svg{max-height:100%}.codex-editor path{stroke:currentColor}::-moz-selection{background-color:#d4ecff}::selection{background-color:#d4ecff}.codex-editor--toolbox-opened [contentEditable=true][data-placeholder]:focus:before{opacity:0!important}@-webkit-keyframes editor-loader-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes editor-loader-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.ce-scroll-locked{overflow:hidden}.ce-scroll-locked--hard{overflow:hidden;top:calc(-1 * var(--window-scroll-offset));position:fixed;width:100%}.ce-toolbar{position:absolute;left:0;right:0;top:0;-webkit-transition:opacity .1s ease;transition:opacity .1s ease;will-change:opacity,top;display:none}.ce-toolbar--opened{display:block}.ce-toolbar__content{max-width:650px;margin:0 auto;position:relative}.ce-toolbar__plus{color:#1d202b;cursor:pointer;width:26px;height:26px;border-radius:7px;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-ms-flex-negative:0;flex-shrink:0}@media (max-width: 650px){.ce-toolbar__plus{width:36px;height:36px}}@media (hover: hover){.ce-toolbar__plus:hover{background-color:#eff2f5}}.ce-toolbar__plus--active{background-color:#eff2f5;-webkit-animation:bounceIn .75s 1;animation:bounceIn .75s 1;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.ce-toolbar__plus-shortcut{opacity:.6;word-spacing:-2px;margin-top:5px}@media (max-width: 650px){.ce-toolbar__plus{position:absolute;background-color:#fff;border:1px solid #E8E8EB;-webkit-box-shadow:0 3px 15px -3px rgba(13,20,33,.13);box-shadow:0 3px 15px -3px #0d142121;border-radius:6px;z-index:2;position:static}.ce-toolbar__plus--left-oriented:before{left:15px;margin-left:0}.ce-toolbar__plus--right-oriented:before{left:auto;right:15px;margin-left:0}}.ce-toolbar__actions{position:absolute;right:100%;opacity:0;display:-webkit-box;display:-ms-flexbox;display:flex;padding-right:5px}.ce-toolbar__actions--opened{opacity:1}@media (max-width: 650px){.ce-toolbar__actions{right:auto}}.ce-toolbar__settings-btn{color:#1d202b;width:26px;height:26px;border-radius:7px;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;margin-left:3px;cursor:pointer;user-select:none}@media (max-width: 650px){.ce-toolbar__settings-btn{width:36px;height:36px}}@media (hover: hover){.ce-toolbar__settings-btn:hover{background-color:#eff2f5}}.ce-toolbar__settings-btn--active{background-color:#eff2f5;-webkit-animation:bounceIn .75s 1;animation:bounceIn .75s 1;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}@media (min-width: 651px){.ce-toolbar__settings-btn{width:24px}}.ce-toolbar__settings-btn--hidden{display:none}@media (max-width: 650px){.ce-toolbar__settings-btn{position:absolute;background-color:#fff;border:1px solid #E8E8EB;-webkit-box-shadow:0 3px 15px -3px rgba(13,20,33,.13);box-shadow:0 3px 15px -3px #0d142121;border-radius:6px;z-index:2;position:static}.ce-toolbar__settings-btn--left-oriented:before{left:15px;margin-left:0}.ce-toolbar__settings-btn--right-oriented:before{left:auto;right:15px;margin-left:0}}.ce-toolbar__plus svg,.ce-toolbar__settings-btn svg{width:24px;height:24px}@media (min-width: 651px){.codex-editor--narrow .ce-toolbar__plus{left:5px}}@media (min-width: 651px){.codex-editor--narrow .ce-toolbox .ce-popover{right:0;left:auto;left:initial}}.ce-inline-toolbar{--y-offset: 8px;position:absolute;background-color:#fff;border:1px solid #E8E8EB;-webkit-box-shadow:0 3px 15px -3px rgba(13,20,33,.13);box-shadow:0 3px 15px -3px #0d142121;border-radius:6px;z-index:2;-webkit-transform:translateX(-50%) translateY(8px) scale(.94);transform:translate(-50%) translateY(8px) scale(.94);opacity:0;visibility:hidden;-webkit-transition:opacity .25s ease,-webkit-transform .15s ease;transition:opacity .25s ease,-webkit-transform .15s ease;transition:transform .15s ease,opacity .25s ease;transition:transform .15s ease,opacity .25s ease,-webkit-transform .15s ease;will-change:transform,opacity;top:0;left:0;z-index:3}.ce-inline-toolbar--left-oriented:before{left:15px;margin-left:0}.ce-inline-toolbar--right-oriented:before{left:auto;right:15px;margin-left:0}.ce-inline-toolbar--showed{opacity:1;visibility:visible;-webkit-transform:translateX(-50%);transform:translate(-50%)}.ce-inline-toolbar--left-oriented{-webkit-transform:translateX(-23px) translateY(8px) scale(.94);transform:translate(-23px) translateY(8px) scale(.94)}.ce-inline-toolbar--left-oriented.ce-inline-toolbar--showed{-webkit-transform:translateX(-23px);transform:translate(-23px)}.ce-inline-toolbar--right-oriented{-webkit-transform:translateX(-100%) translateY(8px) scale(.94);transform:translate(-100%) translateY(8px) scale(.94);margin-left:23px}.ce-inline-toolbar--right-oriented.ce-inline-toolbar--showed{-webkit-transform:translateX(-100%);transform:translate(-100%)}.ce-inline-toolbar [hidden]{display:none!important}.ce-inline-toolbar__toggler-and-button-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;padding:0 6px}.ce-inline-toolbar__buttons{display:-webkit-box;display:-ms-flexbox;display:flex}.ce-inline-toolbar__dropdown{display:-webkit-box;display:-ms-flexbox;display:flex;padding:6px;margin:0 6px 0 -6px;-webkit-box-align:center;-ms-flex-align:center;align-items:center;cursor:pointer;border-right:1px solid rgba(201,201,204,.48);-webkit-box-sizing:border-box;box-sizing:border-box}@media (hover: hover){.ce-inline-toolbar__dropdown:hover{background:#eff2f5}}.ce-inline-toolbar__dropdown--hidden{display:none}.ce-inline-toolbar__dropdown-content,.ce-inline-toolbar__dropdown-arrow{display:-webkit-box;display:-ms-flexbox;display:flex}.ce-inline-toolbar__dropdown-content svg,.ce-inline-toolbar__dropdown-arrow svg{width:20px;height:20px}.ce-inline-toolbar__shortcut{opacity:.6;word-spacing:-3px;margin-top:3px}.ce-inline-tool{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding:6px 1px;cursor:pointer;border:0;outline:none;background-color:transparent;vertical-align:bottom;color:inherit;margin:0;border-radius:0;line-height:normal}.ce-inline-tool svg{width:20px;height:20px}@media (max-width: 650px){.ce-inline-tool svg{width:28px;height:28px}}@media (hover: hover){.ce-inline-tool:hover{background-color:#eff2f5}}.ce-inline-tool--active{color:#388ae5}.ce-inline-tool--focused{background:rgba(34,186,255,.08)!important}.ce-inline-tool--focused{-webkit-box-shadow:inset 0 0 0px 1px rgba(7,161,227,.08);box-shadow:inset 0 0 0 1px #07a1e314}.ce-inline-tool--focused-animated{-webkit-animation-name:buttonClicked;animation-name:buttonClicked;-webkit-animation-duration:.25s;animation-duration:.25s}.ce-inline-tool--link .icon--unlink,.ce-inline-tool--unlink .icon--link{display:none}.ce-inline-tool--unlink .icon--unlink{display:inline-block;margin-bottom:-1px}.ce-inline-tool-input{outline:none;border:0;border-radius:0 0 4px 4px;margin:0;font-size:13px;padding:10px;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box;display:none;font-weight:500;border-top:1px solid rgba(201,201,204,.48);-webkit-appearance:none;font-family:inherit}@media (max-width: 650px){.ce-inline-tool-input{font-size:15px;font-weight:500}}.ce-inline-tool-input::-webkit-input-placeholder{color:#707684}.ce-inline-tool-input::-moz-placeholder{color:#707684}.ce-inline-tool-input:-ms-input-placeholder{color:#707684}.ce-inline-tool-input::-ms-input-placeholder{color:#707684}.ce-inline-tool-input::placeholder{color:#707684}.ce-inline-tool-input--showed{display:block}.ce-conversion-toolbar{position:absolute;background-color:#fff;border:1px solid #E8E8EB;-webkit-box-shadow:0 3px 15px -3px rgba(13,20,33,.13);box-shadow:0 3px 15px -3px #0d142121;border-radius:6px;z-index:2;opacity:0;visibility:hidden;will-change:transform,opacity;-webkit-transition:opacity .1s ease,-webkit-transform .1s ease;transition:opacity .1s ease,-webkit-transform .1s ease;transition:transform .1s ease,opacity .1s ease;transition:transform .1s ease,opacity .1s ease,-webkit-transform .1s ease;-webkit-transform:translateY(-8px);transform:translateY(-8px);left:-1px;width:150px;margin-top:5px;-webkit-box-sizing:content-box;box-sizing:content-box}.ce-conversion-toolbar--left-oriented:before{left:15px;margin-left:0}.ce-conversion-toolbar--right-oriented:before{left:auto;right:15px;margin-left:0}.ce-conversion-toolbar--showed{opacity:1;visibility:visible;-webkit-transform:none;transform:none}.ce-conversion-toolbar [hidden]{display:none!important}.ce-conversion-toolbar__buttons{display:-webkit-box;display:-ms-flexbox;display:flex}.ce-conversion-toolbar__label{color:#707684;font-size:11px;font-weight:500;letter-spacing:.33px;padding:10px 10px 5px;text-transform:uppercase}.ce-conversion-tool{display:-webkit-box;display:-ms-flexbox;display:flex;padding:5px 10px;font-size:14px;line-height:20px;font-weight:500;cursor:pointer;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ce-conversion-tool--hidden{display:none}.ce-conversion-tool--focused{background:rgba(34,186,255,.08)!important}.ce-conversion-tool--focused{-webkit-box-shadow:inset 0 0 0px 1px rgba(7,161,227,.08);box-shadow:inset 0 0 0 1px #07a1e314}.ce-conversion-tool--focused-animated{-webkit-animation-name:buttonClicked;animation-name:buttonClicked;-webkit-animation-duration:.25s;animation-duration:.25s}.ce-conversion-tool:hover{background:#eff2f5}.ce-conversion-tool__icon{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;width:26px;height:26px;-webkit-box-shadow:0 0 0 1px rgba(201,201,204,.48);box-shadow:0 0 0 1px #c9c9cc7a;border-radius:5px;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;background:#fff;-webkit-box-sizing:content-box;box-sizing:content-box;-ms-flex-negative:0;flex-shrink:0;margin-right:10px}.ce-conversion-tool__icon svg{width:20px;height:20px}@media (max-width: 650px){.ce-conversion-tool__icon{width:36px;height:36px;border-radius:8px}.ce-conversion-tool__icon svg{width:28px;height:28px}}.ce-conversion-tool--last{margin-right:0!important}.ce-conversion-tool--active{color:#388ae5!important}.ce-conversion-tool--active{-webkit-animation:bounceIn .75s 1;animation:bounceIn .75s 1;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.ce-settings__button{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding:6px 1px;border-radius:3px;cursor:pointer;border:0;outline:none;background-color:transparent;vertical-align:bottom;color:inherit;margin:0;line-height:32px}.ce-settings__button svg{width:20px;height:20px}@media (max-width: 650px){.ce-settings__button svg{width:28px;height:28px}}@media (hover: hover){.ce-settings__button:hover{background-color:#eff2f5}}.ce-settings__button--active{color:#388ae5}.ce-settings__button--focused{background:rgba(34,186,255,.08)!important}.ce-settings__button--focused{-webkit-box-shadow:inset 0 0 0px 1px rgba(7,161,227,.08);box-shadow:inset 0 0 0 1px #07a1e314}.ce-settings__button--focused-animated{-webkit-animation-name:buttonClicked;animation-name:buttonClicked;-webkit-animation-duration:.25s;animation-duration:.25s}.ce-settings__button:not(:nth-child(3n+3)){margin-right:3px}.ce-settings__button:nth-child(n+4){margin-top:3px}.ce-settings__button--disabled{cursor:not-allowed!important}.ce-settings__button--disabled{opacity:.3}.ce-settings__button--selected{color:#388ae5}@media (min-width: 651px){.codex-editor--narrow .ce-settings .ce-popover{right:0;left:auto;left:initial}}@-webkit-keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}.ce-block{-webkit-animation:fade-in .3s ease;animation:fade-in .3s ease;-webkit-animation-fill-mode:none;animation-fill-mode:none;-webkit-animation-fill-mode:initial;animation-fill-mode:initial}.ce-block:first-of-type{margin-top:0}.ce-block--selected .ce-block__content{background:#e1f2ff}.ce-block--selected .ce-block__content [contenteditable]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ce-block--selected .ce-block__content img,.ce-block--selected .ce-block__content .ce-stub{opacity:.55}.ce-block--stretched .ce-block__content{max-width:none}.ce-block__content{position:relative;max-width:650px;margin:0 auto;-webkit-transition:background-color .15s ease;transition:background-color .15s ease}.ce-block--drop-target .ce-block__content:before{content:"";position:absolute;top:100%;left:-20px;margin-top:-1px;height:8px;width:8px;border:solid #388AE5;border-width:1px 1px 0 0;-webkit-transform-origin:right;transform-origin:right;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.ce-block--drop-target .ce-block__content:after{content:"";position:absolute;top:100%;height:1px;width:100%;color:#388ae5;background:repeating-linear-gradient(90deg,#388AE5,#388AE5 1px,#fff 1px,#fff 6px)}.ce-block a{cursor:pointer;-webkit-text-decoration:underline;text-decoration:underline}.ce-block b{font-weight:700}.ce-block i{font-style:italic}@media (min-width: 651px){.codex-editor--narrow .ce-block--focused{margin-right:-50px;padding-right:50px}}@-webkit-keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}20%{-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}60%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}20%{-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}60%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@-webkit-keyframes selectionBounce{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}50%{-webkit-transform:scale3d(1.01,1.01,1.01);transform:scale3d(1.01,1.01,1.01)}70%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@keyframes selectionBounce{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}50%{-webkit-transform:scale3d(1.01,1.01,1.01);transform:scale3d(1.01,1.01,1.01)}70%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@-webkit-keyframes buttonClicked{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.95,.95,.95);transform:scale3d(.95,.95,.95)}60%{-webkit-transform:scale3d(1.02,1.02,1.02);transform:scale3d(1.02,1.02,1.02)}80%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@keyframes buttonClicked{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.95,.95,.95);transform:scale3d(.95,.95,.95)}60%{-webkit-transform:scale3d(1.02,1.02,1.02);transform:scale3d(1.02,1.02,1.02)}80%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}.cdx-block{padding:.4em 0}.cdx-block::-webkit-input-placeholder{line-height:normal!important}.cdx-input{border:1px solid rgba(201,201,204,.48);-webkit-box-shadow:inset 0 1px 2px 0 rgba(35,44,72,.06);box-shadow:inset 0 1px 2px #232c480f;border-radius:3px;padding:10px 12px;outline:none;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.cdx-input[data-placeholder]:before{position:static!important}.cdx-input[data-placeholder]:before{display:inline-block;width:0;white-space:nowrap;pointer-events:none}.cdx-settings-button{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding:6px 1px;border-radius:3px;cursor:pointer;border:0;outline:none;background-color:transparent;vertical-align:bottom;color:inherit;margin:0;min-width:26px;min-height:26px}.cdx-settings-button svg{width:20px;height:20px}@media (max-width: 650px){.cdx-settings-button svg{width:28px;height:28px}}@media (hover: hover){.cdx-settings-button:hover{background-color:#eff2f5}}.cdx-settings-button--focused{background:rgba(34,186,255,.08)!important}.cdx-settings-button--focused{-webkit-box-shadow:inset 0 0 0px 1px rgba(7,161,227,.08);box-shadow:inset 0 0 0 1px #07a1e314}.cdx-settings-button--focused-animated{-webkit-animation-name:buttonClicked;animation-name:buttonClicked;-webkit-animation-duration:.25s;animation-duration:.25s}.cdx-settings-button--active{color:#388ae5}.cdx-settings-button svg{width:auto;height:auto}@media (max-width: 650px){.cdx-settings-button{width:36px;height:36px;border-radius:8px}}.cdx-loader{position:relative;border:1px solid rgba(201,201,204,.48)}.cdx-loader:before{content:"";position:absolute;left:50%;top:50%;width:18px;height:18px;margin:-11px 0 0 -11px;border:2px solid rgba(201,201,204,.48);border-left-color:#388ae5;border-radius:50%;-webkit-animation:cdxRotation 1.2s infinite linear;animation:cdxRotation 1.2s infinite linear}@-webkit-keyframes cdxRotation{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes cdxRotation{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.cdx-button{padding:13px;border-radius:3px;border:1px solid rgba(201,201,204,.48);font-size:14.9px;background:#fff;-webkit-box-shadow:0 2px 2px 0 rgba(18,30,57,.04);box-shadow:0 2px 2px #121e390a;color:#707684;text-align:center;cursor:pointer}@media (hover: hover){.cdx-button:hover{background:#FBFCFE;-webkit-box-shadow:0 1px 3px 0 rgba(18,30,57,.08);box-shadow:0 1px 3px #121e3914}}.cdx-button svg{height:20px;margin-right:.2em;margin-top:-2px}.ce-stub{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:100%;padding:3.5em 0;margin:17px 0;border-radius:3px;background:#fcf7f7;color:#b46262}.ce-stub__info{margin-left:20px}.ce-stub__title{margin-bottom:3px;font-weight:600;font-size:18px;text-transform:capitalize}.ce-stub__subtitle{font-size:16px}.codex-editor.codex-editor--rtl{direction:rtl}.codex-editor.codex-editor--rtl .cdx-list{padding-left:0;padding-right:40px}.codex-editor.codex-editor--rtl .ce-toolbar__plus{right:-26px;left:auto}.codex-editor.codex-editor--rtl .ce-toolbar__actions{right:auto;left:-26px}@media (max-width: 650px){.codex-editor.codex-editor--rtl .ce-toolbar__actions{margin-left:0;margin-right:auto;padding-right:0;padding-left:10px}}.codex-editor.codex-editor--rtl .ce-settings{left:5px;right:auto}.codex-editor.codex-editor--rtl .ce-settings:before{right:auto;left:25px}.codex-editor.codex-editor--rtl .ce-settings__button:not(:nth-child(3n+3)){margin-left:3px;margin-right:0}.codex-editor.codex-editor--rtl .ce-conversion-tool__icon{margin-right:0;margin-left:10px}.codex-editor.codex-editor--rtl .ce-inline-toolbar__dropdown{border-right:0px solid transparent;border-left:1px solid rgba(201,201,204,.48);margin:0 -6px 0 6px}.codex-editor.codex-editor--rtl .ce-inline-toolbar__dropdown .icon--toggler-down{margin-left:0;margin-right:4px}@media (min-width: 651px){.codex-editor--narrow.codex-editor--rtl .ce-toolbar__plus{left:0px;right:5px}}@media (min-width: 651px){.codex-editor--narrow.codex-editor--rtl .ce-toolbar__actions{left:-5px}}.cdx-search-field{--icon-margin-right: 10px;background:rgba(232,232,235,.49);border:1px solid rgba(226,226,229,.2);border-radius:6px;padding:2px;display:grid;grid-template-columns:auto auto 1fr;grid-template-rows:auto}.cdx-search-field__icon{width:26px;height:26px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin-right:var(--icon-margin-right)}.cdx-search-field__icon svg{width:20px;height:20px;color:#707684}.cdx-search-field__input{font-size:14px;outline:none;font-weight:500;font-family:inherit;border:0;background:transparent;margin:0;padding:0;line-height:22px;min-width:calc(100% - 26px - var(--icon-margin-right))}.cdx-search-field__input::-webkit-input-placeholder{color:#707684;font-weight:500}.cdx-search-field__input::-moz-placeholder{color:#707684;font-weight:500}.cdx-search-field__input:-ms-input-placeholder{color:#707684;font-weight:500}.cdx-search-field__input::-ms-input-placeholder{color:#707684;font-weight:500}.cdx-search-field__input::placeholder{color:#707684;font-weight:500}.ce-popover{--border-radius: 6px;--width: 200px;--max-height: 270px;--padding: 6px;--offset-from-target: 8px;--color-border: #e8e8eb;--color-shadow: rgba(13,20,33,.13);--color-background: white;--color-text-primary: black;--color-text-secondary: #707684;--color-border-icon: rgba(201, 201, 204, .48);--color-border-icon-disabled: #EFF0F1;--color-text-icon-active: #388AE5;--color-background-icon-active: rgba(56, 138, 229, .1);--color-background-item-focus: rgba(34, 186, 255, .08);--color-shadow-item-focus: rgba(7, 161, 227, .08);--color-background-item-hover: #eff2f5;--color-background-item-confirm: #E24A4A;--color-background-item-confirm-hover: #CE4343;min-width:var(--width);width:var(--width);max-height:var(--max-height);border-radius:var(--border-radius);overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:0 3px 15px -3px var(--color-shadow);box-shadow:0 3px 15px -3px var(--color-shadow);position:absolute;left:0;top:calc(100% + var(--offset-from-target));background:var(--color-background);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;z-index:4;opacity:0;max-height:0;pointer-events:none;padding:0;border:none}.ce-popover--opened{opacity:1;padding:var(--padding);max-height:var(--max-height);pointer-events:auto;-webkit-animation:panelShowing .1s ease;animation:panelShowing .1s ease;border:1px solid var(--color-border)}@media (max-width: 650px){.ce-popover--opened{-webkit-animation:panelShowingMobile .25s ease;animation:panelShowingMobile .25s ease}}.ce-popover__items{overflow-y:auto;-ms-scroll-chaining:none;overscroll-behavior:contain}@media (max-width: 650px){.ce-popover__overlay{position:fixed;top:0;bottom:0;left:0;right:0;background:#1D202B;z-index:3;opacity:.5;-webkit-transition:opacity .12s ease-in;transition:opacity .12s ease-in;will-change:opacity;visibility:visible}}.ce-popover__overlay--hidden{display:none}.ce-popover--open-top{top:calc(-1 * (var(--offset-from-target) + var(--popover-height)))}@media (max-width: 650px){.ce-popover{--offset: 5px;position:fixed;max-width:none;min-width:calc(100% - var(--offset) * 2);left:var(--offset);right:var(--offset);bottom:calc(var(--offset) + env(safe-area-inset-bottom));top:auto;border-radius:10px}.ce-popover .ce-popover__search{display:none}}.ce-popover__search,.ce-popover__custom-content:not(:empty){margin-bottom:5px}.ce-popover__nothing-found-message{color:#707684;display:none;cursor:default;padding:3px;font-size:14px;line-height:20px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ce-popover__nothing-found-message--displayed{display:block}.ce-popover__custom-content:not(:empty){padding:4px}@media (min-width: 651px){.ce-popover__custom-content:not(:empty){padding:0}}.ce-popover__custom-content--hidden{display:none}.ce-popover-item{--border-radius: 6px;--icon-size: 20px;--icon-size-mobile: 28px;border-radius:var(--border-radius);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:3px;color:var(--color-text-primary);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}@media (max-width: 650px){.ce-popover-item{padding:4px}}.ce-popover-item:not(:last-of-type){margin-bottom:1px}.ce-popover-item__icon{border-radius:5px;width:26px;height:26px;-webkit-box-shadow:0 0 0 1px var(--color-border-icon);box-shadow:0 0 0 1px var(--color-border-icon);background:#fff;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin-right:10px}.ce-popover-item__icon svg{width:20px;height:20px}@media (max-width: 650px){.ce-popover-item__icon{width:36px;height:36px;border-radius:8px}.ce-popover-item__icon svg{width:var(--icon-size-mobile);height:var(--icon-size-mobile)}}.ce-popover-item__title{font-size:14px;line-height:20px;font-weight:500;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}@media (max-width: 650px){.ce-popover-item__title{font-size:16px}}.ce-popover-item__secondary-title{color:var(--color-text-secondary);font-size:12px;margin-left:auto;white-space:nowrap;letter-spacing:-.1em;padding-right:5px;margin-bottom:-2px;opacity:.6}@media (max-width: 650px){.ce-popover-item__secondary-title{display:none}}.ce-popover-item--active{background:var(--color-background-icon-active);color:var(--color-text-icon-active)}.ce-popover-item--active .ce-popover-item__icon{-webkit-box-shadow:none;box-shadow:none}.ce-popover-item--disabled{color:var(--color-text-secondary);cursor:default;pointer-events:none}.ce-popover-item--disabled .ce-popover-item__icon{-webkit-box-shadow:0 0 0 1px var(--color-border-icon-disabled);box-shadow:0 0 0 1px var(--color-border-icon-disabled)}.ce-popover-item--focused:not(.ce-popover-item--no-focus){background:var(--color-background-item-focus)!important}.ce-popover-item--focused:not(.ce-popover-item--no-focus){-webkit-box-shadow:inset 0 0 0px 1px var(--color-shadow-item-focus);box-shadow:inset 0 0 0 1px var(--color-shadow-item-focus)}.ce-popover-item--hidden{display:none}@media (hover: hover){.ce-popover-item:hover{cursor:pointer}.ce-popover-item:hover:not(.ce-popover-item--no-hover){background-color:var(--color-background-item-hover)}.ce-popover-item:hover .ce-popover-item__icon{-webkit-box-shadow:none;box-shadow:none}}.ce-popover-item--confirmation{background:var(--color-background-item-confirm)}.ce-popover-item--confirmation .ce-popover-item__icon{color:var(--color-background-item-confirm)}.ce-popover-item--confirmation .ce-popover-item__title{color:#fff}@media (hover: hover){.ce-popover-item--confirmation:not(.ce-popover-item--no-hover):hover{background:var(--color-background-item-confirm-hover)}}.ce-popover-item--confirmation:not(.ce-popover-item--no-focus).ce-popover-item--focused{background:var(--color-background-item-confirm-hover)!important}.ce-popover-item--confirmation .ce-popover-item__icon,.ce-popover-item--active .ce-popover-item__icon,.ce-popover-item--focused .ce-popover-item__icon{-webkit-box-shadow:none;box-shadow:none}@-webkit-keyframes panelShowing{0%{opacity:0;-webkit-transform:translateY(-8px) scale(.9);transform:translateY(-8px) scale(.9)}70%{opacity:1;-webkit-transform:translateY(2px);transform:translateY(2px)}to{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes panelShowing{0%{opacity:0;-webkit-transform:translateY(-8px) scale(.9);transform:translateY(-8px) scale(.9)}70%{opacity:1;-webkit-transform:translateY(2px);transform:translateY(2px)}to{-webkit-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes panelShowingMobile{0%{opacity:0;-webkit-transform:translateY(14px) scale(.98);transform:translateY(14px) scale(.98)}70%{opacity:1;-webkit-transform:translateY(-4px);transform:translateY(-4px)}to{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes panelShowingMobile{0%{opacity:0;-webkit-transform:translateY(14px) scale(.98);transform:translateY(14px) scale(.98)}70%{opacity:1;-webkit-transform:translateY(-4px);transform:translateY(-4px)}to{-webkit-transform:translateY(0);transform:translateY(0)}}.wobble{-webkit-animation-name:wobble;animation-name:wobble;-webkit-animation-duration:.4s;animation-duration:.4s}@-webkit-keyframes wobble{0%{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}15%{-webkit-transform:translate3d(-9%,0,0);transform:translate3d(-9%,0,0)}30%{-webkit-transform:translate3d(9%,0,0);transform:translate3d(9%,0,0)}45%{-webkit-transform:translate3d(-4%,0,0);transform:translate3d(-4%,0,0)}60%{-webkit-transform:translate3d(4%,0,0);transform:translate3d(4%,0,0)}75%{-webkit-transform:translate3d(-1%,0,0);transform:translate3d(-1%,0,0)}to{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}}@keyframes wobble{0%{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}15%{-webkit-transform:translate3d(-9%,0,0);transform:translate3d(-9%,0,0)}30%{-webkit-transform:translate3d(9%,0,0);transform:translate3d(9%,0,0)}45%{-webkit-transform:translate3d(-4%,0,0);transform:translate3d(-4%,0,0)}60%{-webkit-transform:translate3d(4%,0,0);transform:translate3d(4%,0,0)}75%{-webkit-transform:translate3d(-1%,0,0);transform:translate3d(-1%,0,0)}to{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}} `; class hi extends S { constructor() { super(...arguments), this.isMobile = !1, this.contentRectCache = void 0, this.resizeDebouncer = Pt(() => { this.windowResize(); }, 200); } /** * Editor.js UI CSS class names * * @returns {{editorWrapper: string, editorZone: string}} */ get CSS() { return { editorWrapper: "codex-editor", editorWrapperNarrow: "codex-editor--narrow", editorZone: "codex-editor__redactor", editorZoneHidden: "codex-editor__redactor--hidden", editorLoader: "codex-editor__loader", editorEmpty: "codex-editor--empty", editorRtlFix: "codex-editor--rtl" }; } /** * Return Width of center column of Editor * * @returns {DOMRect} */ get contentRect() { if (this.contentRectCache) return this.contentRectCache; const e = this.nodes.wrapper.querySelector(`.${F.CSS.content}`); return e ? (this.contentRectCache = e.getBoundingClientRect(), this.contentRectCache) : { width: 650, left: 0, right: 0 }; } /** * Adds loader to editor while content is not ready */ addLoader() { this.nodes.loader = d.make("div", this.CSS.editorLoader), this.nodes.wrapper.prepend(this.nodes.loader), this.nodes.redactor.classList.add(this.CSS.editorZoneHidden); } /** * Removes loader when content has loaded */ removeLoader() { this.nodes.loader.remove(), this.nodes.redactor.classList.remove(this.CSS.editorZoneHidden); } /** * Making main interface */ async prepare() { this.checkIsMobile(), this.make(), this.addLoader(), this.loadStyles(); } /** * Toggle read-only state * * If readOnly is true: * - removes all listeners from main UI module elements * * if readOnly is false: * - enables all listeners to UI module elements * * @param {boolean} readOnlyEnabled - "read only" state */ toggleReadOnly(e) { e ? this.disableModuleBindings() : this.enableModuleBindings(); } /** * Check if Editor is empty and set CSS class to wrapper */ checkEmptiness() { const { BlockManager: e } = this.Editor; this.nodes.wrapper.classList.toggle(this.CSS.editorEmpty, e.isEditorEmpty); } /** * Check if one of Toolbar is opened * Used to prevent global keydowns (for example, Enter) conflicts with Enter-on-toolbar * * @returns {boolean} */ get someToolbarOpened() { const { Toolbar: e, BlockSettings: t, InlineToolbar: o, ConversionToolbar: i } = this.Editor; return t.opened || o.opened || i.opened || e.toolbox.opened; } /** * Check for some Flipper-buttons is under focus */ get someFlipperButtonFocused() { return this.Editor.Toolbar.toolbox.hasFocus() ? !0 : Object.entries(this.Editor).filter(([e, t]) => t.flipper instanceof G).some(([e, t]) => t.flipper.hasFocus()); } /** * Clean editor`s UI */ destroy() { this.nodes.holder.innerHTML = ""; } /** * Close all Editor's toolbars */ closeAllToolbars() { const { Toolbar: e, BlockSettings: t, InlineToolbar: o, ConversionToolbar: i } = this.Editor; t.close(), o.close(), i.close(), e.toolbox.close(); } /** * Check for mobile mode and cache a result */ checkIsMobile() { this.isMobile = window.innerWidth < st; } /** * Makes Editor.js interface */ make() { this.nodes.holder = d.getHolder(this.config.holder), this.nodes.wrapper = d.make("div", [ this.CSS.editorWrapper, ...this.isRtl ? [this.CSS.editorRtlFix] : [] ]), this.nodes.redactor = d.make("div", this.CSS.editorZone), this.nodes.holder.offsetWidth < this.contentRect.width && this.nodes.wrapper.classList.add(this.CSS.editorWrapperNarrow), this.nodes.redactor.style.paddingBottom = this.config.minHeight + "px", this.nodes.wrapper.appendChild(this.nodes.redactor), this.nodes.holder.appendChild(this.nodes.wrapper); } /** * Appends CSS */ loadStyles() { const e = "editor-js-styles"; if (d.get(e)) return; const t = d.make("style", null, { id: e, textContent: di.toString() }); d.prepend(document.head, t); } /** * Bind events on the Editor.js interface */ enableModuleBindings() { this.readOnlyMutableListeners.on(this.nodes.redactor, "click", (e) => { this.redactorClicked(e); }, !1), this.readOnlyMutableListeners.on(this.nodes.redactor, "mousedown", (e) => { this.documentTouched(e); }, !0), this.readOnlyMutableListeners.on(this.nodes.redactor, "touchstart", (e) => { this.documentTouched(e); }, !0), this.readOnlyMutableListeners.on(document, "keydown", (e) => { this.documentKeydown(e); }, !0), this.readOnlyMutableListeners.on(document, "mousedown", (e) => { this.documentClicked(e); }, !0), this.readOnlyMutableListeners.on(document, "selectionchange", () => { this.selectionChanged(); }, !0), this.readOnlyMutableListeners.on(window, "resize", () => { this.resizeDebouncer(); }, { passive: !0 }), this.watchBlockHoveredEvents(); } /** * Listen redactor mousemove to emit 'block-hovered' event */ watchBlockHoveredEvents() { let e; this.readOnlyMutableListeners.on(this.nodes.redactor, "mousemove", Te((t) => { const o = t.target.closest(".ce-block"); this.Editor.BlockSelection.anyBlockSelected || o && e !== o && (e = o, this.eventsDispatcher.emit(mt, { block: this.Editor.BlockManager.getBlockByChildNode(o) })); }, 20), { passive: !0 }); } /** * Unbind events on the Editor.js interface */ disableModuleBindings() { this.readOnlyMutableListeners.clearAll(); } /** * Resize window handler */ windowResize() { this.contentRectCache = null, this.checkIsMobile(); } /** * All keydowns on document * * @param {KeyboardEvent} event - keyboard event */ documentKeydown(e) { switch (e.keyCode) { case B.ENTER: this.enterPressed(e); break; case B.BACKSPACE: this.backspacePressed(e); break; case B.ESC: this.escapePressed(e); break; default: this.defaultBehaviour(e); break; } } /** * Ignore all other document's keydown events * * @param {KeyboardEvent} event - keyboard event */ defaultBehaviour(e) { const { currentBlock: t } = this.Editor.BlockManager, o = e.target.closest(`.${this.CSS.editorWrapper}`), i = e.altKey || e.ctrlKey || e.metaKey || e.shiftKey; if (t !== void 0 && o === null) { this.Editor.BlockEvents.keydown(e); return; } o || t && i || (this.Editor.BlockManager.dropPointer(), this.Editor.Toolbar.close()); } /** * @param {KeyboardEvent} event - keyboard event */ backspacePressed(e) { const { BlockManager: t, BlockSelection: o, Caret: i } = this.Editor; if (o.anyBlockSelected && !m.isSelectionExists) { const n = t.removeSelectedBlocks(); i.setToBlock(t.insertDefaultBlockAtIndex(n, !0), i.positions.START), o.clearSelection(e), e.preventDefault(), e.stopPropagation(), e.stopImmediatePropagation(); } } /** * Escape pressed * If some of Toolbar components are opened, then close it otherwise close Toolbar * * @param {Event} event - escape keydown event */ escapePressed(e) { this.Editor.BlockSelection.clearSelection(e), this.Editor.Toolbar.toolbox.opened ? (this.Editor.Toolbar.toolbox.close(), this.Editor.Caret.setToBlock(this.Editor.BlockManager.currentBlock)) : this.Editor.BlockSettings.opened ? this.Editor.BlockSettings.close() : this.Editor.ConversionToolbar.opened ? this.Editor.ConversionToolbar.close() : this.Editor.InlineToolbar.opened ? this.Editor.InlineToolbar.close() : this.Editor.Toolbar.close(); } /** * Enter pressed on document * * @param {KeyboardEvent} event - keyboard event */ enterPressed(e) { const { BlockManager: t, BlockSelection: o } = this.Editor, i = t.currentBlockIndex >= 0; if (o.anyBlockSelected && !m.isSelectionExists) { o.clearSelection(e), e.preventDefault(), e.stopImmediatePropagation(), e.stopPropagation(); return; } if (!this.someToolbarOpened && i && e.target.tagName === "BODY") { const n = this.Editor.BlockManager.insert(); this.Editor.Caret.setToBlock(n), this.Editor.BlockManager.highlightCurrentNode(), this.Editor.Toolbar.moveAndOpen(n); } this.Editor.BlockSelection.clearSelection(e); } /** * All clicks on document * * @param {MouseEvent} event - Click event */ documentClicked(e) { if (!e.isTrusted) return; const t = e.target; this.nodes.holder.contains(t) || m.isAtEditor || (this.Editor.BlockManager.dropPointer(), this.Editor.Toolbar.close()); const i = this.Editor.BlockSettings.nodes.wrapper.contains(t), n = this.Editor.Toolbar.nodes.settingsToggler.contains(t), r = i || n; if (this.Editor.BlockSettings.opened && !r) { this.Editor.BlockSettings.close(); const a = this.Editor.BlockManager.getBlockByChildNode(t); this.Editor.Toolbar.moveAndOpen(a); } this.Editor.BlockSelection.clearSelection(e); } /** * First touch on editor * Fired before click * * Used to change current block — we need to do it before 'selectionChange' event. * Also: * - Move and show the Toolbar * - Set a Caret * * @param {MouseEvent | TouchEvent} event - touch or mouse event */ documentTouched(e) { let t = e.target; if (t === this.nodes.redactor) { const o = e instanceof MouseEvent ? e.clientX : e.touches[0].clientX, i = e instanceof MouseEvent ? e.clientY : e.touches[0].clientY; t = document.elementFromPoint(o, i); } try { this.Editor.BlockManager.setCurrentBlockByChildNode(t), this.Editor.BlockManager.highlightCurrentNode(); } catch { this.Editor.RectangleSelection.isRectActivated() || this.Editor.Caret.setToTheLastBlock(); } this.Editor.Toolbar.moveAndOpen(); } /** * All clicks on the redactor zone * * @param {MouseEvent} event - click event * @description * - By clicks on the Editor's bottom zone: * - if last Block is empty, set a Caret to this * - otherwise, add a new empty Block and set a Caret to that */ redactorClicked(e) { const { BlockSelection: t } = this.Editor; if (!m.isCollapsed) return; const o = () => { e.stopImmediatePropagation(), e.stopPropagation(); }, i = e.target, n = e.metaKey || e.ctrlKey; if (d.isAnchor(i) && n) { o(); const u = i.getAttribute("href"), h = Ht(u); jt(h); return; } const r = this.Editor.BlockManager.getBlockByIndex(-1), a = d.offset(r.holder).bottom, l = e.pageY; if (e.target instanceof Element && e.target.isEqualNode(this.nodes.redactor) && /** * If there is cross block selection started, target will be equal to redactor so we need additional check */ !t.anyBlockSelected && /** * Prevent caret jumping (to last block) when clicking between blocks */ a < l) { o(); const { BlockManager: u, Caret: h, Toolbar: f } = this.Editor; (!u.lastBlock.tool.isDefault || !u.lastBlock.isEmpty) && u.insertAtEnd(), h.setToTheLastBlock(), f.moveAndOpen(u.lastBlock); } } /** * Handle selection changes on mobile devices * Uses for showing the Inline Toolbar */ selectionChanged() { const { CrossBlockSelection: e, BlockSelection: t } = this.Editor, o = m.anchorElement; if (e.isCrossBlockSelectionStarted && t.anyBlockSelected && m.get().removeAllRanges(), !o) { m.range || this.Editor.InlineToolbar.close(); return; } const i = o.closest(`.${F.CSS.content}`) === null; if (i && (this.Editor.InlineToolbar.containsNode(o) || this.Editor.InlineToolbar.close(), !(o.dataset.inlineToolbar === "true"))) return; this.Editor.BlockManager.currentBlock || this.Editor.BlockManager.setCurrentBlockByChildNode(o); const n = i !== !0; this.Editor.InlineToolbar.tryToShow(!0, n); } } const ui = { // API Modules BlocksAPI: Zt, CaretAPI: Gt, EventsAPI: qt, I18nAPI: De, API: Jt, InlineToolbarAPI: Qt, ListenersAPI: eo, NotifierAPI: no, ReadOnlyAPI: so, SanitizerAPI: po, SaverAPI: fo, SelectionAPI: go, StylesAPI: bo, ToolbarAPI: mo, TooltipAPI: xo, UiAPI: wo, // Toolbar Modules BlockSettings: Ro, ConversionToolbar: Y, Toolbar: jo, InlineToolbar: Uo, // Modules BlockEvents: $o, BlockManager: Ko, BlockSelection: Xo, Caret: ve, CrossBlockSelection: Vo, DragNDrop: Zo, ModificationsObserver: Go, Paste: wt, ReadOnly: qo, RectangleSelection: pe, Renderer: Jo, Saver: Qo, Tools: St, UI: hi }; class pi { /** * @param {EditorConfig} config - user configuration */ constructor(e) { this.moduleInstances = {}, this.eventsDispatcher = new we(); let t, o; this.isReady = new Promise((i, n) => { t = i, o = n; }), Promise.resolve().then(async () => { this.configuration = e, await this.validate(), await this.init(), await this.start(), K("I'm ready! (ノ◕ヮ◕)ノ*:・゚✧", "log", "", "color: #E24A75"), setTimeout(async () => { if (await this.render(), this.configuration.autofocus) { const { BlockManager: i, Caret: n } = this.moduleInstances; n.setToBlock(i.blocks[0], n.positions.START), i.highlightCurrentNode(); } this.moduleInstances.UI.removeLoader(), t(); }, 500); }).catch((i) => { T(`Editor.js is not ready because of ${i}`, "error"), o(i); }); } /** * Setting for configuration * * @param {EditorConfig|string} config - Editor's config to set */ set configuration(e) { var o, i; j(e) ? this.config = { ...e } : this.config = { holder: e }, Ie(!!this.config.holderId, "config.holderId", "config.holder"), this.config.holderId && !this.config.holder && (this.config.holder = this.config.holderId, this.config.holderId = null), this.config.holder == null && (this.config.holder = "editorjs"), this.config.logLevel || (this.config.logLevel = et.VERBOSE), At(this.config.logLevel), Ie(!!this.config.initialBlock, "config.initialBlock", "config.defaultBlock"), this.config.defaultBlock = this.config.defaultBlock || this.config.initialBlock || "paragraph", this.config.minHeight = this.config.minHeight !== void 0 ? this.config.minHeight : 300; const t = { type: this.config.defaultBlock, data: {} }; this.config.placeholder = this.config.placeholder || !1, this.config.sanitizer = this.config.sanitizer || { p: !0, b: !0, a: !0 }, this.config.hideToolbar = this.config.hideToolbar ? this.config.hideToolbar : !1, this.config.tools = this.config.tools || {}, this.config.i18n = this.config.i18n || {}, this.config.data = this.config.data || { blocks: [] }, this.config.onReady = this.config.onReady || (() => { }), this.config.onChange = this.config.onChange || (() => { }), this.config.inlineToolbar = this.config.inlineToolbar !== void 0 ? this.config.inlineToolbar : !0, (V(this.config.data) || !this.config.data.blocks || this.config.data.blocks.length === 0) && (this.config.data = { blocks: [t] }), this.config.readOnly = this.config.readOnly || !1, (o = this.config.i18n) != null && o.messages && $.setDictionary(this.config.i18n.messages), this.config.i18n.direction = ((i = this.config.i18n) == null ? void 0 : i.direction) || "ltr"; } /** * Returns private property * * @returns {EditorConfig} */ get configuration() { return this.config; } /** * Checks for required fields in Editor's config * * @returns {Promise} */ async validate() { const { holderId: e, holder: t } = this.config; if (e && t) throw Error("«holderId» and «holder» param can't assign at the same time."); if (J(t) && !d.get(t)) throw Error(`element with ID «${t}» is missing. Pass correct holder's ID.`); if (t && j(t) && !d.isElement(t)) throw Error("«holder» value must be an Element node"); } /** * Initializes modules: * - make and save instances * - configure */ init() { this.constructModules(), this.configureModules(); } /** * Start Editor! * * Get list of modules that needs to be prepared and return a sequence (Promise) * * @returns {Promise} */ async start() { await [ "Tools", "UI", "BlockManager", "Paste", "BlockSelection", "RectangleSelection", "CrossBlockSelection", "ReadOnly" ].reduce( (t, o) => t.then(async () => { try { await this.moduleInstances[o].prepare(); } catch (i) { if (i instanceof at) throw new Error(i.message); T(`Module ${o} was skipped because of %o`, "warn", i); } }), Promise.resolve() ); } /** * Render initial data */ render() { return this.moduleInstances.Renderer.render(this.config.data.blocks); } /** * Make modules instances and save it to the @property this.moduleInstances */ constructModules() { Object.entries(ui).forEach(([e, t]) => { try { this.moduleInstances[e] = new t({ config: this.configuration, eventsDispatcher: this.eventsDispatcher }); } catch (o) { T("[constructModules]", `Module ${e} skipped because`, "error", o); } }); } /** * Modules instances configuration: * - pass other modules to the 'state' property * - ... */ configureModules() { for (const e in this.moduleInstances) Object.prototype.hasOwnProperty.call(this.moduleInstances, e) && (this.moduleInstances[e].state = this.getModulesDiff(e)); } /** * Return modules without passed name * * @param {string} name - module for witch modules difference should be calculated */ getModulesDiff(e) { const t = {}; for (const o in this.moduleInstances) o !== e && (t[o] = this.moduleInstances[o]); return t; } } /** * Editor.js * * @license Apache-2.0 * @see Editor.js * @author CodeX Team */ class fi { /** Editor version */ static get version() { return "2.27.2"; } /** * @param {EditorConfig|string|undefined} [configuration] - user configuration */ constructor(e) { let t = () => { }; j(e) && D(e.onReady) && (t = e.onReady); const o = new pi(e); this.isReady = o.isReady.then(() => { this.exportAPI(o), t(); }); } /** * Export external API methods * * @param {Core} editor — Editor's instance */ exportAPI(e) { const t = ["configuration"], o = () => { Object.values(e.moduleInstances).forEach((n) => { D(n.destroy) && n.destroy(), n.listeners.removeAll(); }), e = null; for (const n in this) Object.prototype.hasOwnProperty.call(this, n) && delete this[n]; Object.setPrototypeOf(this, null); }; t.forEach((n) => { this[n] = e[n]; }), this.destroy = o, Object.setPrototypeOf(this, e.moduleInstances.API.methods), delete this.exportAPI, Object.entries({ blocks: { clear: "clear", render: "render" }, caret: { focus: "focus" }, events: { on: "on", off: "off", emit: "emit" }, saver: { save: "save" } }).forEach(([n, r]) => { Object.entries(r).forEach(([a, l]) => { this[l] = e.moduleInstances.API.methods[n][a]; }); }); } } /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = __webpack_modules__; /******/ /************************************************************************/ /******/ /* webpack/runtime/chunk loaded */ /******/ (() => { /******/ var deferred = []; /******/ __webpack_require__.O = (result, chunkIds, fn, priority) => { /******/ if(chunkIds) { /******/ priority = priority || 0; /******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1]; /******/ deferred[i] = [chunkIds, fn, priority]; /******/ return; /******/ } /******/ var notFulfilled = Infinity; /******/ for (var i = 0; i < deferred.length; i++) { /******/ var [chunkIds, fn, priority] = deferred[i]; /******/ var fulfilled = true; /******/ for (var j = 0; j < chunkIds.length; j++) { /******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) { /******/ chunkIds.splice(j--, 1); /******/ } else { /******/ fulfilled = false; /******/ if(priority < notFulfilled) notFulfilled = priority; /******/ } /******/ } /******/ if(fulfilled) { /******/ deferred.splice(i--, 1) /******/ var r = fn(); /******/ if (r !== undefined) result = r; /******/ } /******/ } /******/ return result; /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/compat get default export */ /******/ (() => { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? /******/ () => (module['default']) : /******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ (() => { /******/ // define __esModule on exports /******/ __webpack_require__.r = (exports) => { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/jsonp chunk loading */ /******/ (() => { /******/ // no baseURI /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched /******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ "/resources/dist/js/editor": 0, /******/ "resources/dist/css/editor": 0 /******/ }; /******/ /******/ // no chunk on demand loading /******/ /******/ // no prefetching /******/ /******/ // no preloaded /******/ /******/ // no HMR /******/ /******/ // no HMR manifest /******/ /******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0); /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { /******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback /******/ var moduleId, chunkId, i = 0; /******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { /******/ for(moduleId in moreModules) { /******/ if(__webpack_require__.o(moreModules, moduleId)) { /******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; /******/ } /******/ } /******/ if(runtime) var result = runtime(__webpack_require__); /******/ } /******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { /******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } /******/ return __webpack_require__.O(result); /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); /******/ })(); /******/ /************************************************************************/ /******/ /******/ // startup /******/ // Load entry module and return exports /******/ // This entry module depends on other loaded chunks and execution need to be delayed /******/ __webpack_require__.O(undefined, ["resources/dist/css/editor"], () => (__webpack_require__("./resources/js/editor.js"))) /******/ var __webpack_exports__ = __webpack_require__.O(undefined, ["resources/dist/css/editor"], () => (__webpack_require__("./resources/css/editor.css"))) /******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__); /******/ /******/ })() ;