{"version":3,"file":"tinymce-CRrQfLOK.js","sources":["../../lib/tinymce/tinymce.js","../../lib/tinymce/icons/default/icons.js","../../lib/tinymce/themes/silver/theme.js","../../lib/tinymce/plugins/advlist/plugin.js","../../lib/tinymce/plugins/code/plugin.js","../../lib/tinymce/plugins/emoticons/plugin.js","../../lib/tinymce/plugins/emoticons/js/emojis.js","../../lib/tinymce/plugins/link/plugin.js","../../lib/tinymce/plugins/lists/plugin.js","../../lib/tinymce/plugins/table/plugin.js","../../lib/tinymce/models/dom/model.js","../../lib/tinymce/editor.js","../../node_modules/react/cjs/react.production.min.js","../../node_modules/react/index.js","../../node_modules/prop-types/lib/ReactPropTypesSecret.js","../../node_modules/prop-types/factoryWithThrowingShims.js","../../node_modules/prop-types/index.js","../../node_modules/@tinymce/tinymce-react/lib/es2015/main/ts/components/EditorPropTypes.js","../../node_modules/@tinymce/tinymce-react/lib/es2015/main/ts/Utils.js","../../node_modules/@tinymce/tinymce-react/lib/es2015/main/ts/ScriptLoader2.js","../../node_modules/@tinymce/tinymce-react/lib/es2015/main/ts/TinyMCE.js","../../node_modules/@tinymce/tinymce-react/lib/es2015/main/ts/components/Editor.js"],"sourcesContent":["/**\r\n * TinyMCE version 6.4.1 (2023-03-29)\r\n */\r\n\r\n(function () {\r\n 'use strict';\r\n\r\n var typeOf$1 = function (x) {\r\n if (x === null) {\r\n return 'null';\r\n }\r\n if (x === undefined) {\r\n return 'undefined';\r\n }\r\n var t = typeof x;\r\n if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) {\r\n return 'array';\r\n }\r\n if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) {\r\n return 'string';\r\n }\r\n return t;\r\n };\r\n var isEquatableType = function (x) {\r\n return [\r\n 'undefined',\r\n 'boolean',\r\n 'number',\r\n 'string',\r\n 'function',\r\n 'xml',\r\n 'null'\r\n ].indexOf(x) !== -1;\r\n };\r\n\r\n var sort$1 = function (xs, compareFn) {\r\n var clone = Array.prototype.slice.call(xs);\r\n return clone.sort(compareFn);\r\n };\r\n\r\n var contramap = function (eqa, f) {\r\n return eq$2(function (x, y) {\r\n return eqa.eq(f(x), f(y));\r\n });\r\n };\r\n var eq$2 = function (f) {\r\n return { eq: f };\r\n };\r\n var tripleEq = eq$2(function (x, y) {\r\n return x === y;\r\n });\r\n var eqString = tripleEq;\r\n var eqArray = function (eqa) {\r\n return eq$2(function (x, y) {\r\n if (x.length !== y.length) {\r\n return false;\r\n }\r\n var len = x.length;\r\n for (var i = 0; i < len; i++) {\r\n if (!eqa.eq(x[i], y[i])) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n });\r\n };\r\n var eqSortedArray = function (eqa, compareFn) {\r\n return contramap(eqArray(eqa), function (xs) {\r\n return sort$1(xs, compareFn);\r\n });\r\n };\r\n var eqRecord = function (eqa) {\r\n return eq$2(function (x, y) {\r\n var kx = Object.keys(x);\r\n var ky = Object.keys(y);\r\n if (!eqSortedArray(eqString).eq(kx, ky)) {\r\n return false;\r\n }\r\n var len = kx.length;\r\n for (var i = 0; i < len; i++) {\r\n var q = kx[i];\r\n if (!eqa.eq(x[q], y[q])) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n });\r\n };\r\n var eqAny = eq$2(function (x, y) {\r\n if (x === y) {\r\n return true;\r\n }\r\n var tx = typeOf$1(x);\r\n var ty = typeOf$1(y);\r\n if (tx !== ty) {\r\n return false;\r\n }\r\n if (isEquatableType(tx)) {\r\n return x === y;\r\n } else if (tx === 'array') {\r\n return eqArray(eqAny).eq(x, y);\r\n } else if (tx === 'object') {\r\n return eqRecord(eqAny).eq(x, y);\r\n }\r\n return false;\r\n });\r\n\r\n const getPrototypeOf$2 = Object.getPrototypeOf;\r\n const hasProto = (v, constructor, predicate) => {\r\n var _a;\r\n if (predicate(v, constructor.prototype)) {\r\n return true;\r\n } else {\r\n return ((_a = v.constructor) === null || _a === void 0 ? void 0 : _a.name) === constructor.name;\r\n }\r\n };\r\n const typeOf = x => {\r\n const t = typeof x;\r\n if (x === null) {\r\n return 'null';\r\n } else if (t === 'object' && Array.isArray(x)) {\r\n return 'array';\r\n } else if (t === 'object' && hasProto(x, String, (o, proto) => proto.isPrototypeOf(o))) {\r\n return 'string';\r\n } else {\r\n return t;\r\n }\r\n };\r\n const isType$1 = type => value => typeOf(value) === type;\r\n const isSimpleType = type => value => typeof value === type;\r\n const eq$1 = t => a => t === a;\r\n const is$4 = (value, constructor) => isObject(value) && hasProto(value, constructor, (o, proto) => getPrototypeOf$2(o) === proto);\r\n const isString = isType$1('string');\r\n const isObject = isType$1('object');\r\n const isPlainObject = value => is$4(value, Object);\r\n const isArray$1 = isType$1('array');\r\n const isNull = eq$1(null);\r\n const isBoolean = isSimpleType('boolean');\r\n const isUndefined = eq$1(undefined);\r\n const isNullable = a => a === null || a === undefined;\r\n const isNonNullable = a => !isNullable(a);\r\n const isFunction = isSimpleType('function');\r\n const isNumber = isSimpleType('number');\r\n const isArrayOf = (value, pred) => {\r\n if (isArray$1(value)) {\r\n for (let i = 0, len = value.length; i < len; ++i) {\r\n if (!pred(value[i])) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n return false;\r\n };\r\n\r\n const noop = () => {\r\n };\r\n const compose = (fa, fb) => {\r\n return (...args) => {\r\n return fa(fb.apply(null, args));\r\n };\r\n };\r\n const compose1 = (fbc, fab) => a => fbc(fab(a));\r\n const constant = value => {\r\n return () => {\r\n return value;\r\n };\r\n };\r\n const identity = x => {\r\n return x;\r\n };\r\n const tripleEquals = (a, b) => {\r\n return a === b;\r\n };\r\n function curry(fn, ...initialArgs) {\r\n return (...restArgs) => {\r\n const all = initialArgs.concat(restArgs);\r\n return fn.apply(null, all);\r\n };\r\n }\r\n const not = f => t => !f(t);\r\n const die = msg => {\r\n return () => {\r\n throw new Error(msg);\r\n };\r\n };\r\n const apply$1 = f => {\r\n return f();\r\n };\r\n const call = f => {\r\n f();\r\n };\r\n const never = constant(false);\r\n const always = constant(true);\r\n\r\n class Optional {\r\n constructor(tag, value) {\r\n this.tag = tag;\r\n this.value = value;\r\n }\r\n static some(value) {\r\n return new Optional(true, value);\r\n }\r\n static none() {\r\n return Optional.singletonNone;\r\n }\r\n fold(onNone, onSome) {\r\n if (this.tag) {\r\n return onSome(this.value);\r\n } else {\r\n return onNone();\r\n }\r\n }\r\n isSome() {\r\n return this.tag;\r\n }\r\n isNone() {\r\n return !this.tag;\r\n }\r\n map(mapper) {\r\n if (this.tag) {\r\n return Optional.some(mapper(this.value));\r\n } else {\r\n return Optional.none();\r\n }\r\n }\r\n bind(binder) {\r\n if (this.tag) {\r\n return binder(this.value);\r\n } else {\r\n return Optional.none();\r\n }\r\n }\r\n exists(predicate) {\r\n return this.tag && predicate(this.value);\r\n }\r\n forall(predicate) {\r\n return !this.tag || predicate(this.value);\r\n }\r\n filter(predicate) {\r\n if (!this.tag || predicate(this.value)) {\r\n return this;\r\n } else {\r\n return Optional.none();\r\n }\r\n }\r\n getOr(replacement) {\r\n return this.tag ? this.value : replacement;\r\n }\r\n or(replacement) {\r\n return this.tag ? this : replacement;\r\n }\r\n getOrThunk(thunk) {\r\n return this.tag ? this.value : thunk();\r\n }\r\n orThunk(thunk) {\r\n return this.tag ? this : thunk();\r\n }\r\n getOrDie(message) {\r\n if (!this.tag) {\r\n throw new Error(message !== null && message !== void 0 ? message : 'Called getOrDie on None');\r\n } else {\r\n return this.value;\r\n }\r\n }\r\n static from(value) {\r\n return isNonNullable(value) ? Optional.some(value) : Optional.none();\r\n }\r\n getOrNull() {\r\n return this.tag ? this.value : null;\r\n }\r\n getOrUndefined() {\r\n return this.value;\r\n }\r\n each(worker) {\r\n if (this.tag) {\r\n worker(this.value);\r\n }\r\n }\r\n toArray() {\r\n return this.tag ? [this.value] : [];\r\n }\r\n toString() {\r\n return this.tag ? `some(${ this.value })` : 'none()';\r\n }\r\n }\r\n Optional.singletonNone = new Optional(false);\r\n\r\n const nativeSlice = Array.prototype.slice;\r\n const nativeIndexOf = Array.prototype.indexOf;\r\n const nativePush = Array.prototype.push;\r\n const rawIndexOf = (ts, t) => nativeIndexOf.call(ts, t);\r\n const indexOf$1 = (xs, x) => {\r\n const r = rawIndexOf(xs, x);\r\n return r === -1 ? Optional.none() : Optional.some(r);\r\n };\r\n const contains$2 = (xs, x) => rawIndexOf(xs, x) > -1;\r\n const exists = (xs, pred) => {\r\n for (let i = 0, len = xs.length; i < len; i++) {\r\n const x = xs[i];\r\n if (pred(x, i)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n };\r\n const map$3 = (xs, f) => {\r\n const len = xs.length;\r\n const r = new Array(len);\r\n for (let i = 0; i < len; i++) {\r\n const x = xs[i];\r\n r[i] = f(x, i);\r\n }\r\n return r;\r\n };\r\n const each$e = (xs, f) => {\r\n for (let i = 0, len = xs.length; i < len; i++) {\r\n const x = xs[i];\r\n f(x, i);\r\n }\r\n };\r\n const eachr = (xs, f) => {\r\n for (let i = xs.length - 1; i >= 0; i--) {\r\n const x = xs[i];\r\n f(x, i);\r\n }\r\n };\r\n const partition$2 = (xs, pred) => {\r\n const pass = [];\r\n const fail = [];\r\n for (let i = 0, len = xs.length; i < len; i++) {\r\n const x = xs[i];\r\n const arr = pred(x, i) ? pass : fail;\r\n arr.push(x);\r\n }\r\n return {\r\n pass,\r\n fail\r\n };\r\n };\r\n const filter$5 = (xs, pred) => {\r\n const r = [];\r\n for (let i = 0, len = xs.length; i < len; i++) {\r\n const x = xs[i];\r\n if (pred(x, i)) {\r\n r.push(x);\r\n }\r\n }\r\n return r;\r\n };\r\n const foldr = (xs, f, acc) => {\r\n eachr(xs, (x, i) => {\r\n acc = f(acc, x, i);\r\n });\r\n return acc;\r\n };\r\n const foldl = (xs, f, acc) => {\r\n each$e(xs, (x, i) => {\r\n acc = f(acc, x, i);\r\n });\r\n return acc;\r\n };\r\n const findUntil$1 = (xs, pred, until) => {\r\n for (let i = 0, len = xs.length; i < len; i++) {\r\n const x = xs[i];\r\n if (pred(x, i)) {\r\n return Optional.some(x);\r\n } else if (until(x, i)) {\r\n break;\r\n }\r\n }\r\n return Optional.none();\r\n };\r\n const find$2 = (xs, pred) => {\r\n return findUntil$1(xs, pred, never);\r\n };\r\n const findIndex$2 = (xs, pred) => {\r\n for (let i = 0, len = xs.length; i < len; i++) {\r\n const x = xs[i];\r\n if (pred(x, i)) {\r\n return Optional.some(i);\r\n }\r\n }\r\n return Optional.none();\r\n };\r\n const flatten = xs => {\r\n const r = [];\r\n for (let i = 0, len = xs.length; i < len; ++i) {\r\n if (!isArray$1(xs[i])) {\r\n throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);\r\n }\r\n nativePush.apply(r, xs[i]);\r\n }\r\n return r;\r\n };\r\n const bind$3 = (xs, f) => flatten(map$3(xs, f));\r\n const forall = (xs, pred) => {\r\n for (let i = 0, len = xs.length; i < len; ++i) {\r\n const x = xs[i];\r\n if (pred(x, i) !== true) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n };\r\n const reverse = xs => {\r\n const r = nativeSlice.call(xs, 0);\r\n r.reverse();\r\n return r;\r\n };\r\n const difference = (a1, a2) => filter$5(a1, x => !contains$2(a2, x));\r\n const mapToObject = (xs, f) => {\r\n const r = {};\r\n for (let i = 0, len = xs.length; i < len; i++) {\r\n const x = xs[i];\r\n r[String(x)] = f(x, i);\r\n }\r\n return r;\r\n };\r\n const sort = (xs, comparator) => {\r\n const copy = nativeSlice.call(xs, 0);\r\n copy.sort(comparator);\r\n return copy;\r\n };\r\n const get$b = (xs, i) => i >= 0 && i < xs.length ? Optional.some(xs[i]) : Optional.none();\r\n const head = xs => get$b(xs, 0);\r\n const last$3 = xs => get$b(xs, xs.length - 1);\r\n const from = isFunction(Array.from) ? Array.from : x => nativeSlice.call(x);\r\n const findMap = (arr, f) => {\r\n for (let i = 0; i < arr.length; i++) {\r\n const r = f(arr[i], i);\r\n if (r.isSome()) {\r\n return r;\r\n }\r\n }\r\n return Optional.none();\r\n };\r\n const unique$1 = (xs, comparator) => {\r\n const r = [];\r\n const isDuplicated = isFunction(comparator) ? x => exists(r, i => comparator(i, x)) : x => contains$2(r, x);\r\n for (let i = 0, len = xs.length; i < len; i++) {\r\n const x = xs[i];\r\n if (!isDuplicated(x)) {\r\n r.push(x);\r\n }\r\n }\r\n return r;\r\n };\r\n\r\n const keys = Object.keys;\r\n const hasOwnProperty$2 = Object.hasOwnProperty;\r\n const each$d = (obj, f) => {\r\n const props = keys(obj);\r\n for (let k = 0, len = props.length; k < len; k++) {\r\n const i = props[k];\r\n const x = obj[i];\r\n f(x, i);\r\n }\r\n };\r\n const map$2 = (obj, f) => {\r\n return tupleMap(obj, (x, i) => ({\r\n k: i,\r\n v: f(x, i)\r\n }));\r\n };\r\n const tupleMap = (obj, f) => {\r\n const r = {};\r\n each$d(obj, (x, i) => {\r\n const tuple = f(x, i);\r\n r[tuple.k] = tuple.v;\r\n });\r\n return r;\r\n };\r\n const objAcc = r => (x, i) => {\r\n r[i] = x;\r\n };\r\n const internalFilter = (obj, pred, onTrue, onFalse) => {\r\n each$d(obj, (x, i) => {\r\n (pred(x, i) ? onTrue : onFalse)(x, i);\r\n });\r\n };\r\n const bifilter = (obj, pred) => {\r\n const t = {};\r\n const f = {};\r\n internalFilter(obj, pred, objAcc(t), objAcc(f));\r\n return {\r\n t,\r\n f\r\n };\r\n };\r\n const filter$4 = (obj, pred) => {\r\n const t = {};\r\n internalFilter(obj, pred, objAcc(t), noop);\r\n return t;\r\n };\r\n const mapToArray = (obj, f) => {\r\n const r = [];\r\n each$d(obj, (value, name) => {\r\n r.push(f(value, name));\r\n });\r\n return r;\r\n };\r\n const values = obj => {\r\n return mapToArray(obj, identity);\r\n };\r\n const get$a = (obj, key) => {\r\n return has$2(obj, key) ? Optional.from(obj[key]) : Optional.none();\r\n };\r\n const has$2 = (obj, key) => hasOwnProperty$2.call(obj, key);\r\n const hasNonNullableKey = (obj, key) => has$2(obj, key) && obj[key] !== undefined && obj[key] !== null;\r\n const equal$1 = (a1, a2, eq = eqAny) => eqRecord(eq).eq(a1, a2);\r\n\r\n const stringArray = a => {\r\n const all = {};\r\n each$e(a, key => {\r\n all[key] = {};\r\n });\r\n return keys(all);\r\n };\r\n\r\n const isArrayLike = o => o.length !== undefined;\r\n const isArray = Array.isArray;\r\n const toArray$1 = obj => {\r\n if (!isArray(obj)) {\r\n const array = [];\r\n for (let i = 0, l = obj.length; i < l; i++) {\r\n array[i] = obj[i];\r\n }\r\n return array;\r\n } else {\r\n return obj;\r\n }\r\n };\r\n const each$c = (o, cb, s) => {\r\n if (!o) {\r\n return false;\r\n }\r\n s = s || o;\r\n if (isArrayLike(o)) {\r\n for (let n = 0, l = o.length; n < l; n++) {\r\n if (cb.call(s, o[n], n, o) === false) {\r\n return false;\r\n }\r\n }\r\n } else {\r\n for (const n in o) {\r\n if (has$2(o, n)) {\r\n if (cb.call(s, o[n], n, o) === false) {\r\n return false;\r\n }\r\n }\r\n }\r\n }\r\n return true;\r\n };\r\n const map$1 = (array, callback) => {\r\n const out = [];\r\n each$c(array, (item, index) => {\r\n out.push(callback(item, index, array));\r\n });\r\n return out;\r\n };\r\n const filter$3 = (a, f) => {\r\n const o = [];\r\n each$c(a, (v, index) => {\r\n if (!f || f(v, index, a)) {\r\n o.push(v);\r\n }\r\n });\r\n return o;\r\n };\r\n const indexOf = (a, v) => {\r\n if (a) {\r\n for (let i = 0, l = a.length; i < l; i++) {\r\n if (a[i] === v) {\r\n return i;\r\n }\r\n }\r\n }\r\n return -1;\r\n };\r\n const reduce = (collection, iteratee, accumulator, thisArg) => {\r\n let acc = isUndefined(accumulator) ? collection[0] : accumulator;\r\n for (let i = 0; i < collection.length; i++) {\r\n acc = iteratee.call(thisArg, acc, collection[i], i);\r\n }\r\n return acc;\r\n };\r\n const findIndex$1 = (array, predicate, thisArg) => {\r\n for (let i = 0, l = array.length; i < l; i++) {\r\n if (predicate.call(thisArg, array[i], i, array)) {\r\n return i;\r\n }\r\n }\r\n return -1;\r\n };\r\n const last$2 = collection => collection[collection.length - 1];\r\n\r\n const cached = f => {\r\n let called = false;\r\n let r;\r\n return (...args) => {\r\n if (!called) {\r\n called = true;\r\n r = f.apply(null, args);\r\n }\r\n return r;\r\n };\r\n };\r\n\r\n const DeviceType = (os, browser, userAgent, mediaMatch) => {\r\n const isiPad = os.isiOS() && /ipad/i.test(userAgent) === true;\r\n const isiPhone = os.isiOS() && !isiPad;\r\n const isMobile = os.isiOS() || os.isAndroid();\r\n const isTouch = isMobile || mediaMatch('(pointer:coarse)');\r\n const isTablet = isiPad || !isiPhone && isMobile && mediaMatch('(min-device-width:768px)');\r\n const isPhone = isiPhone || isMobile && !isTablet;\r\n const iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false;\r\n const isDesktop = !isPhone && !isTablet && !iOSwebview;\r\n return {\r\n isiPad: constant(isiPad),\r\n isiPhone: constant(isiPhone),\r\n isTablet: constant(isTablet),\r\n isPhone: constant(isPhone),\r\n isTouch: constant(isTouch),\r\n isAndroid: os.isAndroid,\r\n isiOS: os.isiOS,\r\n isWebView: constant(iOSwebview),\r\n isDesktop: constant(isDesktop)\r\n };\r\n };\r\n\r\n const firstMatch = (regexes, s) => {\r\n for (let i = 0; i < regexes.length; i++) {\r\n const x = regexes[i];\r\n if (x.test(s)) {\r\n return x;\r\n }\r\n }\r\n return undefined;\r\n };\r\n const find$1 = (regexes, agent) => {\r\n const r = firstMatch(regexes, agent);\r\n if (!r) {\r\n return {\r\n major: 0,\r\n minor: 0\r\n };\r\n }\r\n const group = i => {\r\n return Number(agent.replace(r, '$' + i));\r\n };\r\n return nu$3(group(1), group(2));\r\n };\r\n const detect$5 = (versionRegexes, agent) => {\r\n const cleanedAgent = String(agent).toLowerCase();\r\n if (versionRegexes.length === 0) {\r\n return unknown$2();\r\n }\r\n return find$1(versionRegexes, cleanedAgent);\r\n };\r\n const unknown$2 = () => {\r\n return nu$3(0, 0);\r\n };\r\n const nu$3 = (major, minor) => {\r\n return {\r\n major,\r\n minor\r\n };\r\n };\r\n const Version = {\r\n nu: nu$3,\r\n detect: detect$5,\r\n unknown: unknown$2\r\n };\r\n\r\n const detectBrowser$1 = (browsers, userAgentData) => {\r\n return findMap(userAgentData.brands, uaBrand => {\r\n const lcBrand = uaBrand.brand.toLowerCase();\r\n return find$2(browsers, browser => {\r\n var _a;\r\n return lcBrand === ((_a = browser.brand) === null || _a === void 0 ? void 0 : _a.toLowerCase());\r\n }).map(info => ({\r\n current: info.name,\r\n version: Version.nu(parseInt(uaBrand.version, 10), 0)\r\n }));\r\n });\r\n };\r\n\r\n const detect$4 = (candidates, userAgent) => {\r\n const agent = String(userAgent).toLowerCase();\r\n return find$2(candidates, candidate => {\r\n return candidate.search(agent);\r\n });\r\n };\r\n const detectBrowser = (browsers, userAgent) => {\r\n return detect$4(browsers, userAgent).map(browser => {\r\n const version = Version.detect(browser.versionRegexes, userAgent);\r\n return {\r\n current: browser.name,\r\n version\r\n };\r\n });\r\n };\r\n const detectOs = (oses, userAgent) => {\r\n return detect$4(oses, userAgent).map(os => {\r\n const version = Version.detect(os.versionRegexes, userAgent);\r\n return {\r\n current: os.name,\r\n version\r\n };\r\n });\r\n };\r\n\r\n const removeFromStart = (str, numChars) => {\r\n return str.substring(numChars);\r\n };\r\n\r\n const checkRange = (str, substr, start) => substr === '' || str.length >= substr.length && str.substr(start, start + substr.length) === substr;\r\n const removeLeading = (str, prefix) => {\r\n return startsWith(str, prefix) ? removeFromStart(str, prefix.length) : str;\r\n };\r\n const contains$1 = (str, substr, start = 0, end) => {\r\n const idx = str.indexOf(substr, start);\r\n if (idx !== -1) {\r\n return isUndefined(end) ? true : idx + substr.length <= end;\r\n } else {\r\n return false;\r\n }\r\n };\r\n const startsWith = (str, prefix) => {\r\n return checkRange(str, prefix, 0);\r\n };\r\n const endsWith = (str, suffix) => {\r\n return checkRange(str, suffix, str.length - suffix.length);\r\n };\r\n const blank = r => s => s.replace(r, '');\r\n const trim$3 = blank(/^\\s+|\\s+$/g);\r\n const lTrim = blank(/^\\s+/g);\r\n const rTrim = blank(/\\s+$/g);\r\n const isNotEmpty = s => s.length > 0;\r\n const isEmpty$3 = s => !isNotEmpty(s);\r\n const repeat = (s, count) => count <= 0 ? '' : new Array(count + 1).join(s);\r\n const toInt = (value, radix = 10) => {\r\n const num = parseInt(value, radix);\r\n return isNaN(num) ? Optional.none() : Optional.some(num);\r\n };\r\n\r\n const normalVersionRegex = /.*?version\\/\\ ?([0-9]+)\\.([0-9]+).*/;\r\n const checkContains = target => {\r\n return uastring => {\r\n return contains$1(uastring, target);\r\n };\r\n };\r\n const browsers = [\r\n {\r\n name: 'Edge',\r\n versionRegexes: [/.*?edge\\/ ?([0-9]+)\\.([0-9]+)$/],\r\n search: uastring => {\r\n return contains$1(uastring, 'edge/') && contains$1(uastring, 'chrome') && contains$1(uastring, 'safari') && contains$1(uastring, 'applewebkit');\r\n }\r\n },\r\n {\r\n name: 'Chromium',\r\n brand: 'Chromium',\r\n versionRegexes: [\r\n /.*?chrome\\/([0-9]+)\\.([0-9]+).*/,\r\n normalVersionRegex\r\n ],\r\n search: uastring => {\r\n return contains$1(uastring, 'chrome') && !contains$1(uastring, 'chromeframe');\r\n }\r\n },\r\n {\r\n name: 'IE',\r\n versionRegexes: [\r\n /.*?msie\\ ?([0-9]+)\\.([0-9]+).*/,\r\n /.*?rv:([0-9]+)\\.([0-9]+).*/\r\n ],\r\n search: uastring => {\r\n return contains$1(uastring, 'msie') || contains$1(uastring, 'trident');\r\n }\r\n },\r\n {\r\n name: 'Opera',\r\n versionRegexes: [\r\n normalVersionRegex,\r\n /.*?opera\\/([0-9]+)\\.([0-9]+).*/\r\n ],\r\n search: checkContains('opera')\r\n },\r\n {\r\n name: 'Firefox',\r\n versionRegexes: [/.*?firefox\\/\\ ?([0-9]+)\\.([0-9]+).*/],\r\n search: checkContains('firefox')\r\n },\r\n {\r\n name: 'Safari',\r\n versionRegexes: [\r\n normalVersionRegex,\r\n /.*?cpu os ([0-9]+)_([0-9]+).*/\r\n ],\r\n search: uastring => {\r\n return (contains$1(uastring, 'safari') || contains$1(uastring, 'mobile/')) && contains$1(uastring, 'applewebkit');\r\n }\r\n }\r\n ];\r\n const oses = [\r\n {\r\n name: 'Windows',\r\n search: checkContains('win'),\r\n versionRegexes: [/.*?windows\\ nt\\ ?([0-9]+)\\.([0-9]+).*/]\r\n },\r\n {\r\n name: 'iOS',\r\n search: uastring => {\r\n return contains$1(uastring, 'iphone') || contains$1(uastring, 'ipad');\r\n },\r\n versionRegexes: [\r\n /.*?version\\/\\ ?([0-9]+)\\.([0-9]+).*/,\r\n /.*cpu os ([0-9]+)_([0-9]+).*/,\r\n /.*cpu iphone os ([0-9]+)_([0-9]+).*/\r\n ]\r\n },\r\n {\r\n name: 'Android',\r\n search: checkContains('android'),\r\n versionRegexes: [/.*?android\\ ?([0-9]+)\\.([0-9]+).*/]\r\n },\r\n {\r\n name: 'macOS',\r\n search: checkContains('mac os x'),\r\n versionRegexes: [/.*?mac\\ os\\ x\\ ?([0-9]+)_([0-9]+).*/]\r\n },\r\n {\r\n name: 'Linux',\r\n search: checkContains('linux'),\r\n versionRegexes: []\r\n },\r\n {\r\n name: 'Solaris',\r\n search: checkContains('sunos'),\r\n versionRegexes: []\r\n },\r\n {\r\n name: 'FreeBSD',\r\n search: checkContains('freebsd'),\r\n versionRegexes: []\r\n },\r\n {\r\n name: 'ChromeOS',\r\n search: checkContains('cros'),\r\n versionRegexes: [/.*?chrome\\/([0-9]+)\\.([0-9]+).*/]\r\n }\r\n ];\r\n const PlatformInfo = {\r\n browsers: constant(browsers),\r\n oses: constant(oses)\r\n };\r\n\r\n const edge = 'Edge';\r\n const chromium = 'Chromium';\r\n const ie = 'IE';\r\n const opera = 'Opera';\r\n const firefox = 'Firefox';\r\n const safari = 'Safari';\r\n const unknown$1 = () => {\r\n return nu$2({\r\n current: undefined,\r\n version: Version.unknown()\r\n });\r\n };\r\n const nu$2 = info => {\r\n const current = info.current;\r\n const version = info.version;\r\n const isBrowser = name => () => current === name;\r\n return {\r\n current,\r\n version,\r\n isEdge: isBrowser(edge),\r\n isChromium: isBrowser(chromium),\r\n isIE: isBrowser(ie),\r\n isOpera: isBrowser(opera),\r\n isFirefox: isBrowser(firefox),\r\n isSafari: isBrowser(safari)\r\n };\r\n };\r\n const Browser = {\r\n unknown: unknown$1,\r\n nu: nu$2,\r\n edge: constant(edge),\r\n chromium: constant(chromium),\r\n ie: constant(ie),\r\n opera: constant(opera),\r\n firefox: constant(firefox),\r\n safari: constant(safari)\r\n };\r\n\r\n const windows = 'Windows';\r\n const ios = 'iOS';\r\n const android = 'Android';\r\n const linux = 'Linux';\r\n const macos = 'macOS';\r\n const solaris = 'Solaris';\r\n const freebsd = 'FreeBSD';\r\n const chromeos = 'ChromeOS';\r\n const unknown = () => {\r\n return nu$1({\r\n current: undefined,\r\n version: Version.unknown()\r\n });\r\n };\r\n const nu$1 = info => {\r\n const current = info.current;\r\n const version = info.version;\r\n const isOS = name => () => current === name;\r\n return {\r\n current,\r\n version,\r\n isWindows: isOS(windows),\r\n isiOS: isOS(ios),\r\n isAndroid: isOS(android),\r\n isMacOS: isOS(macos),\r\n isLinux: isOS(linux),\r\n isSolaris: isOS(solaris),\r\n isFreeBSD: isOS(freebsd),\r\n isChromeOS: isOS(chromeos)\r\n };\r\n };\r\n const OperatingSystem = {\r\n unknown,\r\n nu: nu$1,\r\n windows: constant(windows),\r\n ios: constant(ios),\r\n android: constant(android),\r\n linux: constant(linux),\r\n macos: constant(macos),\r\n solaris: constant(solaris),\r\n freebsd: constant(freebsd),\r\n chromeos: constant(chromeos)\r\n };\r\n\r\n const detect$3 = (userAgent, userAgentDataOpt, mediaMatch) => {\r\n const browsers = PlatformInfo.browsers();\r\n const oses = PlatformInfo.oses();\r\n const browser = userAgentDataOpt.bind(userAgentData => detectBrowser$1(browsers, userAgentData)).orThunk(() => detectBrowser(browsers, userAgent)).fold(Browser.unknown, Browser.nu);\r\n const os = detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu);\r\n const deviceType = DeviceType(os, browser, userAgent, mediaMatch);\r\n return {\r\n browser,\r\n os,\r\n deviceType\r\n };\r\n };\r\n const PlatformDetection = { detect: detect$3 };\r\n\r\n const mediaMatch = query => window.matchMedia(query).matches;\r\n let platform$2 = cached(() => PlatformDetection.detect(navigator.userAgent, Optional.from(navigator.userAgentData), mediaMatch));\r\n const detect$2 = () => platform$2();\r\n\r\n const userAgent = navigator.userAgent;\r\n const platform$1 = detect$2();\r\n const browser$1 = platform$1.browser;\r\n const os = platform$1.os;\r\n const deviceType = platform$1.deviceType;\r\n const windowsPhone = userAgent.indexOf('Windows Phone') !== -1;\r\n const Env = {\r\n transparentSrc: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',\r\n documentMode: browser$1.isIE() ? document.documentMode || 7 : 10,\r\n cacheSuffix: null,\r\n container: null,\r\n canHaveCSP: !browser$1.isIE(),\r\n windowsPhone,\r\n browser: {\r\n current: browser$1.current,\r\n version: browser$1.version,\r\n isChromium: browser$1.isChromium,\r\n isEdge: browser$1.isEdge,\r\n isFirefox: browser$1.isFirefox,\r\n isIE: browser$1.isIE,\r\n isOpera: browser$1.isOpera,\r\n isSafari: browser$1.isSafari\r\n },\r\n os: {\r\n current: os.current,\r\n version: os.version,\r\n isAndroid: os.isAndroid,\r\n isChromeOS: os.isChromeOS,\r\n isFreeBSD: os.isFreeBSD,\r\n isiOS: os.isiOS,\r\n isLinux: os.isLinux,\r\n isMacOS: os.isMacOS,\r\n isSolaris: os.isSolaris,\r\n isWindows: os.isWindows\r\n },\r\n deviceType: {\r\n isDesktop: deviceType.isDesktop,\r\n isiPad: deviceType.isiPad,\r\n isiPhone: deviceType.isiPhone,\r\n isPhone: deviceType.isPhone,\r\n isTablet: deviceType.isTablet,\r\n isTouch: deviceType.isTouch,\r\n isWebView: deviceType.isWebView\r\n }\r\n };\r\n\r\n const whiteSpaceRegExp$1 = /^\\s*|\\s*$/g;\r\n const trim$2 = str => {\r\n return isNullable(str) ? '' : ('' + str).replace(whiteSpaceRegExp$1, '');\r\n };\r\n const is$3 = (obj, type) => {\r\n if (!type) {\r\n return obj !== undefined;\r\n }\r\n if (type === 'array' && isArray(obj)) {\r\n return true;\r\n }\r\n return typeof obj === type;\r\n };\r\n const makeMap$4 = (items, delim, map = {}) => {\r\n const resolvedItems = isString(items) ? items.split(delim || ',') : items || [];\r\n let i = resolvedItems.length;\r\n while (i--) {\r\n map[resolvedItems[i]] = {};\r\n }\r\n return map;\r\n };\r\n const hasOwnProperty$1 = has$2;\r\n const extend$3 = (obj, ...exts) => {\r\n for (let i = 0; i < exts.length; i++) {\r\n const ext = exts[i];\r\n for (const name in ext) {\r\n if (has$2(ext, name)) {\r\n const value = ext[name];\r\n if (value !== undefined) {\r\n obj[name] = value;\r\n }\r\n }\r\n }\r\n }\r\n return obj;\r\n };\r\n const walk$4 = function (o, f, n, s) {\r\n s = s || this;\r\n if (o) {\r\n if (n) {\r\n o = o[n];\r\n }\r\n each$c(o, (o, i) => {\r\n if (f.call(s, o, i, n) === false) {\r\n return false;\r\n } else {\r\n walk$4(o, f, n, s);\r\n return true;\r\n }\r\n });\r\n }\r\n };\r\n const resolve$3 = (n, o = window) => {\r\n const path = n.split('.');\r\n for (let i = 0, l = path.length; i < l; i++) {\r\n o = o[path[i]];\r\n if (!o) {\r\n break;\r\n }\r\n }\r\n return o;\r\n };\r\n const explode$3 = (s, d) => {\r\n if (isArray$1(s)) {\r\n return s;\r\n } else if (s === '') {\r\n return [];\r\n } else {\r\n return map$1(s.split(d || ','), trim$2);\r\n }\r\n };\r\n const _addCacheSuffix = url => {\r\n const cacheSuffix = Env.cacheSuffix;\r\n if (cacheSuffix) {\r\n url += (url.indexOf('?') === -1 ? '?' : '&') + cacheSuffix;\r\n }\r\n return url;\r\n };\r\n const Tools = {\r\n trim: trim$2,\r\n isArray: isArray,\r\n is: is$3,\r\n toArray: toArray$1,\r\n makeMap: makeMap$4,\r\n each: each$c,\r\n map: map$1,\r\n grep: filter$3,\r\n inArray: indexOf,\r\n hasOwn: hasOwnProperty$1,\r\n extend: extend$3,\r\n walk: walk$4,\r\n resolve: resolve$3,\r\n explode: explode$3,\r\n _addCacheSuffix\r\n };\r\n\r\n const is$2 = (lhs, rhs, comparator = tripleEquals) => lhs.exists(left => comparator(left, rhs));\r\n const cat = arr => {\r\n const r = [];\r\n const push = x => {\r\n r.push(x);\r\n };\r\n for (let i = 0; i < arr.length; i++) {\r\n arr[i].each(push);\r\n }\r\n return r;\r\n };\r\n const lift2 = (oa, ob, f) => oa.isSome() && ob.isSome() ? Optional.some(f(oa.getOrDie(), ob.getOrDie())) : Optional.none();\r\n const lift3 = (oa, ob, oc, f) => oa.isSome() && ob.isSome() && oc.isSome() ? Optional.some(f(oa.getOrDie(), ob.getOrDie(), oc.getOrDie())) : Optional.none();\r\n const someIf = (b, a) => b ? Optional.some(a) : Optional.none();\r\n\r\n const Global = typeof window !== 'undefined' ? window : Function('return this;')();\r\n\r\n const path = (parts, scope) => {\r\n let o = scope !== undefined && scope !== null ? scope : Global;\r\n for (let i = 0; i < parts.length && o !== undefined && o !== null; ++i) {\r\n o = o[parts[i]];\r\n }\r\n return o;\r\n };\r\n const resolve$2 = (p, scope) => {\r\n const parts = p.split('.');\r\n return path(parts, scope);\r\n };\r\n\r\n const unsafe = (name, scope) => {\r\n return resolve$2(name, scope);\r\n };\r\n const getOrDie = (name, scope) => {\r\n const actual = unsafe(name, scope);\r\n if (actual === undefined || actual === null) {\r\n throw new Error(name + ' not available on this browser');\r\n }\r\n return actual;\r\n };\r\n\r\n const getPrototypeOf$1 = Object.getPrototypeOf;\r\n const sandHTMLElement = scope => {\r\n return getOrDie('HTMLElement', scope);\r\n };\r\n const isPrototypeOf = x => {\r\n const scope = resolve$2('ownerDocument.defaultView', x);\r\n return isObject(x) && (sandHTMLElement(scope).prototype.isPrototypeOf(x) || /^HTML\\w*Element$/.test(getPrototypeOf$1(x).constructor.name));\r\n };\r\n\r\n const COMMENT = 8;\r\n const DOCUMENT = 9;\r\n const DOCUMENT_FRAGMENT = 11;\r\n const ELEMENT = 1;\r\n const TEXT = 3;\r\n\r\n const name = element => {\r\n const r = element.dom.nodeName;\r\n return r.toLowerCase();\r\n };\r\n const type$1 = element => element.dom.nodeType;\r\n const isType = t => element => type$1(element) === t;\r\n const isComment$1 = element => type$1(element) === COMMENT || name(element) === '#comment';\r\n const isHTMLElement = element => isElement$7(element) && isPrototypeOf(element.dom);\r\n const isElement$7 = isType(ELEMENT);\r\n const isText$b = isType(TEXT);\r\n const isDocument$2 = isType(DOCUMENT);\r\n const isDocumentFragment$1 = isType(DOCUMENT_FRAGMENT);\r\n const isTag = tag => e => isElement$7(e) && name(e) === tag;\r\n\r\n const rawSet = (dom, key, value) => {\r\n if (isString(value) || isBoolean(value) || isNumber(value)) {\r\n dom.setAttribute(key, value + '');\r\n } else {\r\n console.error('Invalid call to Attribute.set. Key ', key, ':: Value ', value, ':: Element ', dom);\r\n throw new Error('Attribute value was not simple');\r\n }\r\n };\r\n const set$3 = (element, key, value) => {\r\n rawSet(element.dom, key, value);\r\n };\r\n const setAll$1 = (element, attrs) => {\r\n const dom = element.dom;\r\n each$d(attrs, (v, k) => {\r\n rawSet(dom, k, v);\r\n });\r\n };\r\n const get$9 = (element, key) => {\r\n const v = element.dom.getAttribute(key);\r\n return v === null ? undefined : v;\r\n };\r\n const getOpt = (element, key) => Optional.from(get$9(element, key));\r\n const has$1 = (element, key) => {\r\n const dom = element.dom;\r\n return dom && dom.hasAttribute ? dom.hasAttribute(key) : false;\r\n };\r\n const remove$b = (element, key) => {\r\n element.dom.removeAttribute(key);\r\n };\r\n const hasNone = element => {\r\n const attrs = element.dom.attributes;\r\n return attrs === undefined || attrs === null || attrs.length === 0;\r\n };\r\n const clone$4 = element => foldl(element.dom.attributes, (acc, attr) => {\r\n acc[attr.name] = attr.value;\r\n return acc;\r\n }, {});\r\n\r\n const read$4 = (element, attr) => {\r\n const value = get$9(element, attr);\r\n return value === undefined || value === '' ? [] : value.split(' ');\r\n };\r\n const add$4 = (element, attr, id) => {\r\n const old = read$4(element, attr);\r\n const nu = old.concat([id]);\r\n set$3(element, attr, nu.join(' '));\r\n return true;\r\n };\r\n const remove$a = (element, attr, id) => {\r\n const nu = filter$5(read$4(element, attr), v => v !== id);\r\n if (nu.length > 0) {\r\n set$3(element, attr, nu.join(' '));\r\n } else {\r\n remove$b(element, attr);\r\n }\r\n return false;\r\n };\r\n\r\n const supports = element => element.dom.classList !== undefined;\r\n const get$8 = element => read$4(element, 'class');\r\n const add$3 = (element, clazz) => add$4(element, 'class', clazz);\r\n const remove$9 = (element, clazz) => remove$a(element, 'class', clazz);\r\n const toggle$2 = (element, clazz) => {\r\n if (contains$2(get$8(element), clazz)) {\r\n return remove$9(element, clazz);\r\n } else {\r\n return add$3(element, clazz);\r\n }\r\n };\r\n\r\n const add$2 = (element, clazz) => {\r\n if (supports(element)) {\r\n element.dom.classList.add(clazz);\r\n } else {\r\n add$3(element, clazz);\r\n }\r\n };\r\n const cleanClass = element => {\r\n const classList = supports(element) ? element.dom.classList : get$8(element);\r\n if (classList.length === 0) {\r\n remove$b(element, 'class');\r\n }\r\n };\r\n const remove$8 = (element, clazz) => {\r\n if (supports(element)) {\r\n const classList = element.dom.classList;\r\n classList.remove(clazz);\r\n } else {\r\n remove$9(element, clazz);\r\n }\r\n cleanClass(element);\r\n };\r\n const toggle$1 = (element, clazz) => {\r\n const result = supports(element) ? element.dom.classList.toggle(clazz) : toggle$2(element, clazz);\r\n cleanClass(element);\r\n return result;\r\n };\r\n const has = (element, clazz) => supports(element) && element.dom.classList.contains(clazz);\r\n\r\n const fromHtml$1 = (html, scope) => {\r\n const doc = scope || document;\r\n const div = doc.createElement('div');\r\n div.innerHTML = html;\r\n if (!div.hasChildNodes() || div.childNodes.length > 1) {\r\n const message = 'HTML does not have a single root node';\r\n console.error(message, html);\r\n throw new Error(message);\r\n }\r\n return fromDom$2(div.childNodes[0]);\r\n };\r\n const fromTag = (tag, scope) => {\r\n const doc = scope || document;\r\n const node = doc.createElement(tag);\r\n return fromDom$2(node);\r\n };\r\n const fromText = (text, scope) => {\r\n const doc = scope || document;\r\n const node = doc.createTextNode(text);\r\n return fromDom$2(node);\r\n };\r\n const fromDom$2 = node => {\r\n if (node === null || node === undefined) {\r\n throw new Error('Node cannot be null or undefined');\r\n }\r\n return { dom: node };\r\n };\r\n const fromPoint$2 = (docElm, x, y) => Optional.from(docElm.dom.elementFromPoint(x, y)).map(fromDom$2);\r\n const SugarElement = {\r\n fromHtml: fromHtml$1,\r\n fromTag,\r\n fromText,\r\n fromDom: fromDom$2,\r\n fromPoint: fromPoint$2\r\n };\r\n\r\n const toArray = (target, f) => {\r\n const r = [];\r\n const recurse = e => {\r\n r.push(e);\r\n return f(e);\r\n };\r\n let cur = f(target);\r\n do {\r\n cur = cur.bind(recurse);\r\n } while (cur.isSome());\r\n return r;\r\n };\r\n\r\n const is$1 = (element, selector) => {\r\n const dom = element.dom;\r\n if (dom.nodeType !== ELEMENT) {\r\n return false;\r\n } else {\r\n const elem = dom;\r\n if (elem.matches !== undefined) {\r\n return elem.matches(selector);\r\n } else if (elem.msMatchesSelector !== undefined) {\r\n return elem.msMatchesSelector(selector);\r\n } else if (elem.webkitMatchesSelector !== undefined) {\r\n return elem.webkitMatchesSelector(selector);\r\n } else if (elem.mozMatchesSelector !== undefined) {\r\n return elem.mozMatchesSelector(selector);\r\n } else {\r\n throw new Error('Browser lacks native selectors');\r\n }\r\n }\r\n };\r\n const bypassSelector = dom => dom.nodeType !== ELEMENT && dom.nodeType !== DOCUMENT && dom.nodeType !== DOCUMENT_FRAGMENT || dom.childElementCount === 0;\r\n const all = (selector, scope) => {\r\n const base = scope === undefined ? document : scope.dom;\r\n return bypassSelector(base) ? [] : map$3(base.querySelectorAll(selector), SugarElement.fromDom);\r\n };\r\n const one = (selector, scope) => {\r\n const base = scope === undefined ? document : scope.dom;\r\n return bypassSelector(base) ? Optional.none() : Optional.from(base.querySelector(selector)).map(SugarElement.fromDom);\r\n };\r\n\r\n const eq = (e1, e2) => e1.dom === e2.dom;\r\n const contains = (e1, e2) => {\r\n const d1 = e1.dom;\r\n const d2 = e2.dom;\r\n return d1 === d2 ? false : d1.contains(d2);\r\n };\r\n\r\n const owner$1 = element => SugarElement.fromDom(element.dom.ownerDocument);\r\n const documentOrOwner = dos => isDocument$2(dos) ? dos : owner$1(dos);\r\n const documentElement = element => SugarElement.fromDom(documentOrOwner(element).dom.documentElement);\r\n const defaultView = element => SugarElement.fromDom(documentOrOwner(element).dom.defaultView);\r\n const parent = element => Optional.from(element.dom.parentNode).map(SugarElement.fromDom);\r\n const parentElement = element => Optional.from(element.dom.parentElement).map(SugarElement.fromDom);\r\n const parents$1 = (element, isRoot) => {\r\n const stop = isFunction(isRoot) ? isRoot : never;\r\n let dom = element.dom;\r\n const ret = [];\r\n while (dom.parentNode !== null && dom.parentNode !== undefined) {\r\n const rawParent = dom.parentNode;\r\n const p = SugarElement.fromDom(rawParent);\r\n ret.push(p);\r\n if (stop(p) === true) {\r\n break;\r\n } else {\r\n dom = rawParent;\r\n }\r\n }\r\n return ret;\r\n };\r\n const siblings = element => {\r\n const filterSelf = elements => filter$5(elements, x => !eq(element, x));\r\n return parent(element).map(children$1).map(filterSelf).getOr([]);\r\n };\r\n const prevSibling = element => Optional.from(element.dom.previousSibling).map(SugarElement.fromDom);\r\n const nextSibling = element => Optional.from(element.dom.nextSibling).map(SugarElement.fromDom);\r\n const prevSiblings = element => reverse(toArray(element, prevSibling));\r\n const nextSiblings = element => toArray(element, nextSibling);\r\n const children$1 = element => map$3(element.dom.childNodes, SugarElement.fromDom);\r\n const child$1 = (element, index) => {\r\n const cs = element.dom.childNodes;\r\n return Optional.from(cs[index]).map(SugarElement.fromDom);\r\n };\r\n const firstChild = element => child$1(element, 0);\r\n const lastChild = element => child$1(element, element.dom.childNodes.length - 1);\r\n const childNodesCount = element => element.dom.childNodes.length;\r\n\r\n const getHead = doc => {\r\n const b = doc.dom.head;\r\n if (b === null || b === undefined) {\r\n throw new Error('Head is not available yet');\r\n }\r\n return SugarElement.fromDom(b);\r\n };\r\n\r\n const isShadowRoot = dos => isDocumentFragment$1(dos) && isNonNullable(dos.dom.host);\r\n const supported = isFunction(Element.prototype.attachShadow) && isFunction(Node.prototype.getRootNode);\r\n const isSupported$1 = constant(supported);\r\n const getRootNode = supported ? e => SugarElement.fromDom(e.dom.getRootNode()) : documentOrOwner;\r\n const getStyleContainer = dos => isShadowRoot(dos) ? dos : getHead(documentOrOwner(dos));\r\n const getContentContainer = dos => isShadowRoot(dos) ? dos : SugarElement.fromDom(documentOrOwner(dos).dom.body);\r\n const getShadowRoot = e => {\r\n const r = getRootNode(e);\r\n return isShadowRoot(r) ? Optional.some(r) : Optional.none();\r\n };\r\n const getShadowHost = e => SugarElement.fromDom(e.dom.host);\r\n const getOriginalEventTarget = event => {\r\n if (isSupported$1() && isNonNullable(event.target)) {\r\n const el = SugarElement.fromDom(event.target);\r\n if (isElement$7(el) && isOpenShadowHost(el)) {\r\n if (event.composed && event.composedPath) {\r\n const composedPath = event.composedPath();\r\n if (composedPath) {\r\n return head(composedPath);\r\n }\r\n }\r\n }\r\n }\r\n return Optional.from(event.target);\r\n };\r\n const isOpenShadowHost = element => isNonNullable(element.dom.shadowRoot);\r\n\r\n const inBody = element => {\r\n const dom = isText$b(element) ? element.dom.parentNode : element.dom;\r\n if (dom === undefined || dom === null || dom.ownerDocument === null) {\r\n return false;\r\n }\r\n const doc = dom.ownerDocument;\r\n return getShadowRoot(SugarElement.fromDom(dom)).fold(() => doc.body.contains(dom), compose1(inBody, getShadowHost));\r\n };\r\n\r\n var ClosestOrAncestor = (is, ancestor, scope, a, isRoot) => {\r\n if (is(scope, a)) {\r\n return Optional.some(scope);\r\n } else if (isFunction(isRoot) && isRoot(scope)) {\r\n return Optional.none();\r\n } else {\r\n return ancestor(scope, a, isRoot);\r\n }\r\n };\r\n\r\n const ancestor$4 = (scope, predicate, isRoot) => {\r\n let element = scope.dom;\r\n const stop = isFunction(isRoot) ? isRoot : never;\r\n while (element.parentNode) {\r\n element = element.parentNode;\r\n const el = SugarElement.fromDom(element);\r\n if (predicate(el)) {\r\n return Optional.some(el);\r\n } else if (stop(el)) {\r\n break;\r\n }\r\n }\r\n return Optional.none();\r\n };\r\n const closest$4 = (scope, predicate, isRoot) => {\r\n const is = (s, test) => test(s);\r\n return ClosestOrAncestor(is, ancestor$4, scope, predicate, isRoot);\r\n };\r\n const sibling$1 = (scope, predicate) => {\r\n const element = scope.dom;\r\n if (!element.parentNode) {\r\n return Optional.none();\r\n }\r\n return child(SugarElement.fromDom(element.parentNode), x => !eq(scope, x) && predicate(x));\r\n };\r\n const child = (scope, predicate) => {\r\n const pred = node => predicate(SugarElement.fromDom(node));\r\n const result = find$2(scope.dom.childNodes, pred);\r\n return result.map(SugarElement.fromDom);\r\n };\r\n const descendant$1 = (scope, predicate) => {\r\n const descend = node => {\r\n for (let i = 0; i < node.childNodes.length; i++) {\r\n const child = SugarElement.fromDom(node.childNodes[i]);\r\n if (predicate(child)) {\r\n return Optional.some(child);\r\n }\r\n const res = descend(node.childNodes[i]);\r\n if (res.isSome()) {\r\n return res;\r\n }\r\n }\r\n return Optional.none();\r\n };\r\n return descend(scope.dom);\r\n };\r\n\r\n const ancestor$3 = (scope, selector, isRoot) => ancestor$4(scope, e => is$1(e, selector), isRoot);\r\n const descendant = (scope, selector) => one(selector, scope);\r\n const closest$3 = (scope, selector, isRoot) => {\r\n const is = (element, selector) => is$1(element, selector);\r\n return ClosestOrAncestor(is, ancestor$3, scope, selector, isRoot);\r\n };\r\n\r\n const closest$2 = target => closest$3(target, '[contenteditable]');\r\n const isEditable$3 = (element, assumeEditable = false) => {\r\n if (inBody(element)) {\r\n return element.dom.isContentEditable;\r\n } else {\r\n return closest$2(element).fold(constant(assumeEditable), editable => getRaw$1(editable) === 'true');\r\n }\r\n };\r\n const getRaw$1 = element => element.dom.contentEditable;\r\n\r\n const isSupported = dom => dom.style !== undefined && isFunction(dom.style.getPropertyValue);\r\n\r\n const internalSet = (dom, property, value) => {\r\n if (!isString(value)) {\r\n console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom);\r\n throw new Error('CSS value must be a string: ' + value);\r\n }\r\n if (isSupported(dom)) {\r\n dom.style.setProperty(property, value);\r\n }\r\n };\r\n const internalRemove = (dom, property) => {\r\n if (isSupported(dom)) {\r\n dom.style.removeProperty(property);\r\n }\r\n };\r\n const set$2 = (element, property, value) => {\r\n const dom = element.dom;\r\n internalSet(dom, property, value);\r\n };\r\n const setAll = (element, css) => {\r\n const dom = element.dom;\r\n each$d(css, (v, k) => {\r\n internalSet(dom, k, v);\r\n });\r\n };\r\n const get$7 = (element, property) => {\r\n const dom = element.dom;\r\n const styles = window.getComputedStyle(dom);\r\n const r = styles.getPropertyValue(property);\r\n return r === '' && !inBody(element) ? getUnsafeProperty(dom, property) : r;\r\n };\r\n const getUnsafeProperty = (dom, property) => isSupported(dom) ? dom.style.getPropertyValue(property) : '';\r\n const getRaw = (element, property) => {\r\n const dom = element.dom;\r\n const raw = getUnsafeProperty(dom, property);\r\n return Optional.from(raw).filter(r => r.length > 0);\r\n };\r\n const getAllRaw = element => {\r\n const css = {};\r\n const dom = element.dom;\r\n if (isSupported(dom)) {\r\n for (let i = 0; i < dom.style.length; i++) {\r\n const ruleName = dom.style.item(i);\r\n css[ruleName] = dom.style[ruleName];\r\n }\r\n }\r\n return css;\r\n };\r\n const remove$7 = (element, property) => {\r\n const dom = element.dom;\r\n internalRemove(dom, property);\r\n if (is$2(getOpt(element, 'style').map(trim$3), '')) {\r\n remove$b(element, 'style');\r\n }\r\n };\r\n const reflow = e => e.dom.offsetWidth;\r\n\r\n const before$3 = (marker, element) => {\r\n const parent$1 = parent(marker);\r\n parent$1.each(v => {\r\n v.dom.insertBefore(element.dom, marker.dom);\r\n });\r\n };\r\n const after$4 = (marker, element) => {\r\n const sibling = nextSibling(marker);\r\n sibling.fold(() => {\r\n const parent$1 = parent(marker);\r\n parent$1.each(v => {\r\n append$1(v, element);\r\n });\r\n }, v => {\r\n before$3(v, element);\r\n });\r\n };\r\n const prepend = (parent, element) => {\r\n const firstChild$1 = firstChild(parent);\r\n firstChild$1.fold(() => {\r\n append$1(parent, element);\r\n }, v => {\r\n parent.dom.insertBefore(element.dom, v.dom);\r\n });\r\n };\r\n const append$1 = (parent, element) => {\r\n parent.dom.appendChild(element.dom);\r\n };\r\n const wrap$2 = (element, wrapper) => {\r\n before$3(element, wrapper);\r\n append$1(wrapper, element);\r\n };\r\n\r\n const after$3 = (marker, elements) => {\r\n each$e(elements, (x, i) => {\r\n const e = i === 0 ? marker : elements[i - 1];\r\n after$4(e, x);\r\n });\r\n };\r\n const append = (parent, elements) => {\r\n each$e(elements, x => {\r\n append$1(parent, x);\r\n });\r\n };\r\n\r\n const empty = element => {\r\n element.dom.textContent = '';\r\n each$e(children$1(element), rogue => {\r\n remove$6(rogue);\r\n });\r\n };\r\n const remove$6 = element => {\r\n const dom = element.dom;\r\n if (dom.parentNode !== null) {\r\n dom.parentNode.removeChild(dom);\r\n }\r\n };\r\n const unwrap = wrapper => {\r\n const children = children$1(wrapper);\r\n if (children.length > 0) {\r\n after$3(wrapper, children);\r\n }\r\n remove$6(wrapper);\r\n };\r\n\r\n const fromHtml = (html, scope) => {\r\n const doc = scope || document;\r\n const div = doc.createElement('div');\r\n div.innerHTML = html;\r\n return children$1(SugarElement.fromDom(div));\r\n };\r\n const fromDom$1 = nodes => map$3(nodes, SugarElement.fromDom);\r\n\r\n const get$6 = element => element.dom.innerHTML;\r\n const set$1 = (element, content) => {\r\n const owner = owner$1(element);\r\n const docDom = owner.dom;\r\n const fragment = SugarElement.fromDom(docDom.createDocumentFragment());\r\n const contentElements = fromHtml(content, docDom);\r\n append(fragment, contentElements);\r\n empty(element);\r\n append$1(element, fragment);\r\n };\r\n const getOuter = element => {\r\n const container = SugarElement.fromTag('div');\r\n const clone = SugarElement.fromDom(element.dom.cloneNode(true));\r\n append$1(container, clone);\r\n return get$6(container);\r\n };\r\n\r\n const mkEvent = (target, x, y, stop, prevent, kill, raw) => ({\r\n target,\r\n x,\r\n y,\r\n stop,\r\n prevent,\r\n kill,\r\n raw\r\n });\r\n const fromRawEvent = rawEvent => {\r\n const target = SugarElement.fromDom(getOriginalEventTarget(rawEvent).getOr(rawEvent.target));\r\n const stop = () => rawEvent.stopPropagation();\r\n const prevent = () => rawEvent.preventDefault();\r\n const kill = compose(prevent, stop);\r\n return mkEvent(target, rawEvent.clientX, rawEvent.clientY, stop, prevent, kill, rawEvent);\r\n };\r\n const handle$1 = (filter, handler) => rawEvent => {\r\n if (filter(rawEvent)) {\r\n handler(fromRawEvent(rawEvent));\r\n }\r\n };\r\n const binder = (element, event, filter, handler, useCapture) => {\r\n const wrapped = handle$1(filter, handler);\r\n element.dom.addEventListener(event, wrapped, useCapture);\r\n return { unbind: curry(unbind, element, event, wrapped, useCapture) };\r\n };\r\n const bind$2 = (element, event, filter, handler) => binder(element, event, filter, handler, false);\r\n const unbind = (element, event, handler, useCapture) => {\r\n element.dom.removeEventListener(event, handler, useCapture);\r\n };\r\n\r\n const r = (left, top) => {\r\n const translate = (x, y) => r(left + x, top + y);\r\n return {\r\n left,\r\n top,\r\n translate\r\n };\r\n };\r\n const SugarPosition = r;\r\n\r\n const boxPosition = dom => {\r\n const box = dom.getBoundingClientRect();\r\n return SugarPosition(box.left, box.top);\r\n };\r\n const firstDefinedOrZero = (a, b) => {\r\n if (a !== undefined) {\r\n return a;\r\n } else {\r\n return b !== undefined ? b : 0;\r\n }\r\n };\r\n const absolute = element => {\r\n const doc = element.dom.ownerDocument;\r\n const body = doc.body;\r\n const win = doc.defaultView;\r\n const html = doc.documentElement;\r\n if (body === element.dom) {\r\n return SugarPosition(body.offsetLeft, body.offsetTop);\r\n }\r\n const scrollTop = firstDefinedOrZero(win === null || win === void 0 ? void 0 : win.pageYOffset, html.scrollTop);\r\n const scrollLeft = firstDefinedOrZero(win === null || win === void 0 ? void 0 : win.pageXOffset, html.scrollLeft);\r\n const clientTop = firstDefinedOrZero(html.clientTop, body.clientTop);\r\n const clientLeft = firstDefinedOrZero(html.clientLeft, body.clientLeft);\r\n return viewport(element).translate(scrollLeft - clientLeft, scrollTop - clientTop);\r\n };\r\n const viewport = element => {\r\n const dom = element.dom;\r\n const doc = dom.ownerDocument;\r\n const body = doc.body;\r\n if (body === dom) {\r\n return SugarPosition(body.offsetLeft, body.offsetTop);\r\n }\r\n if (!inBody(element)) {\r\n return SugarPosition(0, 0);\r\n }\r\n return boxPosition(dom);\r\n };\r\n\r\n const get$5 = _DOC => {\r\n const doc = _DOC !== undefined ? _DOC.dom : document;\r\n const x = doc.body.scrollLeft || doc.documentElement.scrollLeft;\r\n const y = doc.body.scrollTop || doc.documentElement.scrollTop;\r\n return SugarPosition(x, y);\r\n };\r\n const to = (x, y, _DOC) => {\r\n const doc = _DOC !== undefined ? _DOC.dom : document;\r\n const win = doc.defaultView;\r\n if (win) {\r\n win.scrollTo(x, y);\r\n }\r\n };\r\n const intoView = (element, alignToTop) => {\r\n const isSafari = detect$2().browser.isSafari();\r\n if (isSafari && isFunction(element.dom.scrollIntoViewIfNeeded)) {\r\n element.dom.scrollIntoViewIfNeeded(false);\r\n } else {\r\n element.dom.scrollIntoView(alignToTop);\r\n }\r\n };\r\n\r\n const get$4 = _win => {\r\n const win = _win === undefined ? window : _win;\r\n if (detect$2().browser.isFirefox()) {\r\n return Optional.none();\r\n } else {\r\n return Optional.from(win.visualViewport);\r\n }\r\n };\r\n const bounds = (x, y, width, height) => ({\r\n x,\r\n y,\r\n width,\r\n height,\r\n right: x + width,\r\n bottom: y + height\r\n });\r\n const getBounds = _win => {\r\n const win = _win === undefined ? window : _win;\r\n const doc = win.document;\r\n const scroll = get$5(SugarElement.fromDom(doc));\r\n return get$4(win).fold(() => {\r\n const html = win.document.documentElement;\r\n const width = html.clientWidth;\r\n const height = html.clientHeight;\r\n return bounds(scroll.left, scroll.top, width, height);\r\n }, visualViewport => bounds(Math.max(visualViewport.pageLeft, scroll.left), Math.max(visualViewport.pageTop, scroll.top), visualViewport.width, visualViewport.height));\r\n };\r\n\r\n const children = (scope, predicate) => filter$5(children$1(scope), predicate);\r\n const descendants$1 = (scope, predicate) => {\r\n let result = [];\r\n each$e(children$1(scope), x => {\r\n if (predicate(x)) {\r\n result = result.concat([x]);\r\n }\r\n result = result.concat(descendants$1(x, predicate));\r\n });\r\n return result;\r\n };\r\n\r\n const descendants = (scope, selector) => all(selector, scope);\r\n\r\n const ancestor$2 = (scope, selector, isRoot) => ancestor$3(scope, selector, isRoot).isSome();\r\n\r\n class DomTreeWalker {\r\n constructor(startNode, rootNode) {\r\n this.node = startNode;\r\n this.rootNode = rootNode;\r\n this.current = this.current.bind(this);\r\n this.next = this.next.bind(this);\r\n this.prev = this.prev.bind(this);\r\n this.prev2 = this.prev2.bind(this);\r\n }\r\n current() {\r\n return this.node;\r\n }\r\n next(shallow) {\r\n this.node = this.findSibling(this.node, 'firstChild', 'nextSibling', shallow);\r\n return this.node;\r\n }\r\n prev(shallow) {\r\n this.node = this.findSibling(this.node, 'lastChild', 'previousSibling', shallow);\r\n return this.node;\r\n }\r\n prev2(shallow) {\r\n this.node = this.findPreviousNode(this.node, shallow);\r\n return this.node;\r\n }\r\n findSibling(node, startName, siblingName, shallow) {\r\n if (node) {\r\n if (!shallow && node[startName]) {\r\n return node[startName];\r\n }\r\n if (node !== this.rootNode) {\r\n let sibling = node[siblingName];\r\n if (sibling) {\r\n return sibling;\r\n }\r\n for (let parent = node.parentNode; parent && parent !== this.rootNode; parent = parent.parentNode) {\r\n sibling = parent[siblingName];\r\n if (sibling) {\r\n return sibling;\r\n }\r\n }\r\n }\r\n }\r\n return undefined;\r\n }\r\n findPreviousNode(node, shallow) {\r\n if (node) {\r\n const sibling = node.previousSibling;\r\n if (this.rootNode && sibling === this.rootNode) {\r\n return;\r\n }\r\n if (sibling) {\r\n if (!shallow) {\r\n for (let child = sibling.lastChild; child; child = child.lastChild) {\r\n if (!child.lastChild) {\r\n return child;\r\n }\r\n }\r\n }\r\n return sibling;\r\n }\r\n const parent = node.parentNode;\r\n if (parent && parent !== this.rootNode) {\r\n return parent;\r\n }\r\n }\r\n return undefined;\r\n }\r\n }\r\n\r\n const isNodeType = type => {\r\n return node => {\r\n return !!node && node.nodeType === type;\r\n };\r\n };\r\n const isRestrictedNode = node => !!node && !Object.getPrototypeOf(node);\r\n const isElement$6 = isNodeType(1);\r\n const matchNodeName = name => {\r\n const lowerCasedName = name.toLowerCase();\r\n return node => isNonNullable(node) && node.nodeName.toLowerCase() === lowerCasedName;\r\n };\r\n const matchNodeNames = names => {\r\n const lowerCasedNames = names.map(s => s.toLowerCase());\r\n return node => {\r\n if (node && node.nodeName) {\r\n const nodeName = node.nodeName.toLowerCase();\r\n return contains$2(lowerCasedNames, nodeName);\r\n }\r\n return false;\r\n };\r\n };\r\n const matchStyleValues = (name, values) => {\r\n const items = values.toLowerCase().split(' ');\r\n return node => {\r\n if (isElement$6(node)) {\r\n const win = node.ownerDocument.defaultView;\r\n if (win) {\r\n for (let i = 0; i < items.length; i++) {\r\n const computed = win.getComputedStyle(node, null);\r\n const cssValue = computed ? computed.getPropertyValue(name) : null;\r\n if (cssValue === items[i]) {\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n return false;\r\n };\r\n };\r\n const hasAttribute = attrName => {\r\n return node => {\r\n return isElement$6(node) && node.hasAttribute(attrName);\r\n };\r\n };\r\n const hasAttributeValue = (attrName, attrValue) => {\r\n return node => {\r\n return isElement$6(node) && node.getAttribute(attrName) === attrValue;\r\n };\r\n };\r\n const isBogus$2 = node => isElement$6(node) && node.hasAttribute('data-mce-bogus');\r\n const isBogusAll$1 = node => isElement$6(node) && node.getAttribute('data-mce-bogus') === 'all';\r\n const isTable$2 = node => isElement$6(node) && node.tagName === 'TABLE';\r\n const hasContentEditableState = value => {\r\n return node => {\r\n if (isElement$6(node)) {\r\n if (node.contentEditable === value) {\r\n return true;\r\n }\r\n if (node.getAttribute('data-mce-contenteditable') === value) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n };\r\n };\r\n const isTextareaOrInput = matchNodeNames([\r\n 'textarea',\r\n 'input'\r\n ]);\r\n const isText$a = isNodeType(3);\r\n const isCData = isNodeType(4);\r\n const isPi = isNodeType(7);\r\n const isComment = isNodeType(8);\r\n const isDocument$1 = isNodeType(9);\r\n const isDocumentFragment = isNodeType(11);\r\n const isBr$6 = matchNodeName('br');\r\n const isImg = matchNodeName('img');\r\n const isContentEditableTrue$3 = hasContentEditableState('true');\r\n const isContentEditableFalse$b = hasContentEditableState('false');\r\n const isTableCell$3 = matchNodeNames([\r\n 'td',\r\n 'th'\r\n ]);\r\n const isTableCellOrCaption = matchNodeNames([\r\n 'td',\r\n 'th',\r\n 'caption'\r\n ]);\r\n const isMedia$2 = matchNodeNames([\r\n 'video',\r\n 'audio',\r\n 'object',\r\n 'embed'\r\n ]);\r\n const isListItem$2 = matchNodeName('li');\r\n\r\n const zeroWidth = '\\uFEFF';\r\n const nbsp = '\\xA0';\r\n const isZwsp$1 = char => char === zeroWidth;\r\n const removeZwsp = s => s.replace(/\\uFEFF/g, '');\r\n\r\n const NodeValue = (is, name) => {\r\n const get = element => {\r\n if (!is(element)) {\r\n throw new Error('Can only get ' + name + ' value of a ' + name + ' node');\r\n }\r\n return getOption(element).getOr('');\r\n };\r\n const getOption = element => is(element) ? Optional.from(element.dom.nodeValue) : Optional.none();\r\n const set = (element, value) => {\r\n if (!is(element)) {\r\n throw new Error('Can only set raw ' + name + ' value of a ' + name + ' node');\r\n }\r\n element.dom.nodeValue = value;\r\n };\r\n return {\r\n get,\r\n getOption,\r\n set\r\n };\r\n };\r\n\r\n const api$1 = NodeValue(isText$b, 'text');\r\n const get$3 = element => api$1.get(element);\r\n const getOption = element => api$1.getOption(element);\r\n const set = (element, value) => api$1.set(element, value);\r\n\r\n const blocks = [\r\n 'article',\r\n 'aside',\r\n 'details',\r\n 'div',\r\n 'dt',\r\n 'figcaption',\r\n 'footer',\r\n 'form',\r\n 'fieldset',\r\n 'header',\r\n 'hgroup',\r\n 'html',\r\n 'main',\r\n 'nav',\r\n 'section',\r\n 'summary',\r\n 'body',\r\n 'p',\r\n 'dl',\r\n 'multicol',\r\n 'dd',\r\n 'figure',\r\n 'address',\r\n 'center',\r\n 'blockquote',\r\n 'h1',\r\n 'h2',\r\n 'h3',\r\n 'h4',\r\n 'h5',\r\n 'h6',\r\n 'listing',\r\n 'xmp',\r\n 'pre',\r\n 'plaintext',\r\n 'menu',\r\n 'dir',\r\n 'ul',\r\n 'ol',\r\n 'li',\r\n 'hr',\r\n 'table',\r\n 'tbody',\r\n 'thead',\r\n 'tfoot',\r\n 'th',\r\n 'tr',\r\n 'td',\r\n 'caption'\r\n ];\r\n const tableCells = [\r\n 'td',\r\n 'th'\r\n ];\r\n const tableSections = [\r\n 'thead',\r\n 'tbody',\r\n 'tfoot'\r\n ];\r\n const textBlocks = [\r\n 'h1',\r\n 'h2',\r\n 'h3',\r\n 'h4',\r\n 'h5',\r\n 'h6',\r\n 'p',\r\n 'div',\r\n 'address',\r\n 'pre',\r\n 'form',\r\n 'blockquote',\r\n 'center',\r\n 'dir',\r\n 'fieldset',\r\n 'header',\r\n 'footer',\r\n 'article',\r\n 'section',\r\n 'hgroup',\r\n 'aside',\r\n 'nav',\r\n 'figure'\r\n ];\r\n const headings = [\r\n 'h1',\r\n 'h2',\r\n 'h3',\r\n 'h4',\r\n 'h5',\r\n 'h6'\r\n ];\r\n const listItems$1 = [\r\n 'li',\r\n 'dd',\r\n 'dt'\r\n ];\r\n const lists = [\r\n 'ul',\r\n 'ol',\r\n 'dl'\r\n ];\r\n const wsElements = [\r\n 'pre',\r\n 'script',\r\n 'textarea',\r\n 'style'\r\n ];\r\n const wrapBlockElements = ['pre'].concat(headings);\r\n const lazyLookup = items => {\r\n let lookup;\r\n return node => {\r\n lookup = lookup ? lookup : mapToObject(items, always);\r\n return has$2(lookup, name(node));\r\n };\r\n };\r\n const isBlock$2 = lazyLookup(blocks);\r\n const isTable$1 = node => name(node) === 'table';\r\n const isInline$1 = node => isElement$7(node) && !isBlock$2(node);\r\n const isBr$5 = node => isElement$7(node) && name(node) === 'br';\r\n const isTextBlock$2 = lazyLookup(textBlocks);\r\n const isList = lazyLookup(lists);\r\n const isListItem$1 = lazyLookup(listItems$1);\r\n const isTableSection = lazyLookup(tableSections);\r\n const isTableCell$2 = lazyLookup(tableCells);\r\n const isWsPreserveElement = lazyLookup(wsElements);\r\n const isWrapBlockElement = lazyLookup(wrapBlockElements);\r\n const isWrapElement = node => isWrapBlockElement(node) || isInline$1(node);\r\n\r\n const getLastChildren$1 = elm => {\r\n const children = [];\r\n let rawNode = elm.dom;\r\n while (rawNode) {\r\n children.push(SugarElement.fromDom(rawNode));\r\n rawNode = rawNode.lastChild;\r\n }\r\n return children;\r\n };\r\n const removeTrailingBr = elm => {\r\n const allBrs = descendants(elm, 'br');\r\n const brs = filter$5(getLastChildren$1(elm).slice(-1), isBr$5);\r\n if (allBrs.length === brs.length) {\r\n each$e(brs, remove$6);\r\n }\r\n };\r\n const createPaddingBr = () => {\r\n const br = SugarElement.fromTag('br');\r\n set$3(br, 'data-mce-bogus', '1');\r\n return br;\r\n };\r\n const fillWithPaddingBr = elm => {\r\n empty(elm);\r\n append$1(elm, createPaddingBr());\r\n };\r\n const trimBlockTrailingBr = elm => {\r\n lastChild(elm).each(lastChild => {\r\n prevSibling(lastChild).each(lastChildPrevSibling => {\r\n if (isBlock$2(elm) && isBr$5(lastChild) && isBlock$2(lastChildPrevSibling)) {\r\n remove$6(lastChild);\r\n }\r\n });\r\n });\r\n };\r\n\r\n const ZWSP$1 = zeroWidth;\r\n const isZwsp = isZwsp$1;\r\n const trim$1 = removeZwsp;\r\n\r\n const isElement$5 = isElement$6;\r\n const isText$9 = isText$a;\r\n const isCaretContainerBlock$1 = node => {\r\n if (isText$9(node)) {\r\n node = node.parentNode;\r\n }\r\n return isElement$5(node) && node.hasAttribute('data-mce-caret');\r\n };\r\n const isCaretContainerInline = node => isText$9(node) && isZwsp(node.data);\r\n const isCaretContainer$2 = node => isCaretContainerBlock$1(node) || isCaretContainerInline(node);\r\n const hasContent = node => node.firstChild !== node.lastChild || !isBr$6(node.firstChild);\r\n const insertInline$1 = (node, before) => {\r\n var _a;\r\n const doc = (_a = node.ownerDocument) !== null && _a !== void 0 ? _a : document;\r\n const textNode = doc.createTextNode(ZWSP$1);\r\n const parentNode = node.parentNode;\r\n if (!before) {\r\n const sibling = node.nextSibling;\r\n if (isText$9(sibling)) {\r\n if (isCaretContainer$2(sibling)) {\r\n return sibling;\r\n }\r\n if (startsWithCaretContainer$1(sibling)) {\r\n sibling.splitText(1);\r\n return sibling;\r\n }\r\n }\r\n if (node.nextSibling) {\r\n parentNode === null || parentNode === void 0 ? void 0 : parentNode.insertBefore(textNode, node.nextSibling);\r\n } else {\r\n parentNode === null || parentNode === void 0 ? void 0 : parentNode.appendChild(textNode);\r\n }\r\n } else {\r\n const sibling = node.previousSibling;\r\n if (isText$9(sibling)) {\r\n if (isCaretContainer$2(sibling)) {\r\n return sibling;\r\n }\r\n if (endsWithCaretContainer$1(sibling)) {\r\n return sibling.splitText(sibling.data.length - 1);\r\n }\r\n }\r\n parentNode === null || parentNode === void 0 ? void 0 : parentNode.insertBefore(textNode, node);\r\n }\r\n return textNode;\r\n };\r\n const isBeforeInline = pos => {\r\n const container = pos.container();\r\n if (!isText$a(container)) {\r\n return false;\r\n }\r\n return container.data.charAt(pos.offset()) === ZWSP$1 || pos.isAtStart() && isCaretContainerInline(container.previousSibling);\r\n };\r\n const isAfterInline = pos => {\r\n const container = pos.container();\r\n if (!isText$a(container)) {\r\n return false;\r\n }\r\n return container.data.charAt(pos.offset() - 1) === ZWSP$1 || pos.isAtEnd() && isCaretContainerInline(container.nextSibling);\r\n };\r\n const insertBlock = (blockName, node, before) => {\r\n var _a;\r\n const doc = (_a = node.ownerDocument) !== null && _a !== void 0 ? _a : document;\r\n const blockNode = doc.createElement(blockName);\r\n blockNode.setAttribute('data-mce-caret', before ? 'before' : 'after');\r\n blockNode.setAttribute('data-mce-bogus', 'all');\r\n blockNode.appendChild(createPaddingBr().dom);\r\n const parentNode = node.parentNode;\r\n if (!before) {\r\n if (node.nextSibling) {\r\n parentNode === null || parentNode === void 0 ? void 0 : parentNode.insertBefore(blockNode, node.nextSibling);\r\n } else {\r\n parentNode === null || parentNode === void 0 ? void 0 : parentNode.appendChild(blockNode);\r\n }\r\n } else {\r\n parentNode === null || parentNode === void 0 ? void 0 : parentNode.insertBefore(blockNode, node);\r\n }\r\n return blockNode;\r\n };\r\n const startsWithCaretContainer$1 = node => isText$9(node) && node.data[0] === ZWSP$1;\r\n const endsWithCaretContainer$1 = node => isText$9(node) && node.data[node.data.length - 1] === ZWSP$1;\r\n const trimBogusBr = elm => {\r\n var _a;\r\n const brs = elm.getElementsByTagName('br');\r\n const lastBr = brs[brs.length - 1];\r\n if (isBogus$2(lastBr)) {\r\n (_a = lastBr.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(lastBr);\r\n }\r\n };\r\n const showCaretContainerBlock = caretContainer => {\r\n if (caretContainer && caretContainer.hasAttribute('data-mce-caret')) {\r\n trimBogusBr(caretContainer);\r\n caretContainer.removeAttribute('data-mce-caret');\r\n caretContainer.removeAttribute('data-mce-bogus');\r\n caretContainer.removeAttribute('style');\r\n caretContainer.removeAttribute('data-mce-style');\r\n caretContainer.removeAttribute('_moz_abspos');\r\n return caretContainer;\r\n }\r\n return null;\r\n };\r\n const isRangeInCaretContainerBlock = range => isCaretContainerBlock$1(range.startContainer);\r\n\r\n const isContentEditableTrue$2 = isContentEditableTrue$3;\r\n const isContentEditableFalse$a = isContentEditableFalse$b;\r\n const isBr$4 = isBr$6;\r\n const isText$8 = isText$a;\r\n const isInvalidTextElement = matchNodeNames([\r\n 'script',\r\n 'style',\r\n 'textarea'\r\n ]);\r\n const isAtomicInline = matchNodeNames([\r\n 'img',\r\n 'input',\r\n 'textarea',\r\n 'hr',\r\n 'iframe',\r\n 'video',\r\n 'audio',\r\n 'object',\r\n 'embed'\r\n ]);\r\n const isTable = matchNodeNames(['table']);\r\n const isCaretContainer$1 = isCaretContainer$2;\r\n const isCaretCandidate$3 = node => {\r\n if (isCaretContainer$1(node)) {\r\n return false;\r\n }\r\n if (isText$8(node)) {\r\n return !isInvalidTextElement(node.parentNode);\r\n }\r\n return isAtomicInline(node) || isBr$4(node) || isTable(node) || isNonUiContentEditableFalse(node);\r\n };\r\n const isUnselectable = node => isElement$6(node) && node.getAttribute('unselectable') === 'true';\r\n const isNonUiContentEditableFalse = node => !isUnselectable(node) && isContentEditableFalse$a(node);\r\n const isInEditable = (node, root) => {\r\n for (let tempNode = node.parentNode; tempNode && tempNode !== root; tempNode = tempNode.parentNode) {\r\n if (isNonUiContentEditableFalse(tempNode)) {\r\n return false;\r\n }\r\n if (isContentEditableTrue$2(tempNode)) {\r\n return true;\r\n }\r\n }\r\n return true;\r\n };\r\n const isAtomicContentEditableFalse = node => {\r\n if (!isNonUiContentEditableFalse(node)) {\r\n return false;\r\n }\r\n return !foldl(from(node.getElementsByTagName('*')), (result, elm) => {\r\n return result || isContentEditableTrue$2(elm);\r\n }, false);\r\n };\r\n const isAtomic$1 = node => isAtomicInline(node) || isAtomicContentEditableFalse(node);\r\n const isEditableCaretCandidate$1 = (node, root) => isCaretCandidate$3(node) && isInEditable(node, root);\r\n\r\n const whiteSpaceRegExp = /^[ \\t\\r\\n]*$/;\r\n const isWhitespaceText = text => whiteSpaceRegExp.test(text);\r\n const isCollapsibleWhitespace$1 = c => ' \\f\\t\\x0B'.indexOf(c) !== -1;\r\n const isNewLineChar = c => c === '\\n' || c === '\\r';\r\n const isNewline = (text, idx) => idx < text.length && idx >= 0 ? isNewLineChar(text[idx]) : false;\r\n const normalize$4 = (text, tabSpaces = 4, isStartOfContent = true, isEndOfContent = true) => {\r\n const tabSpace = repeat(' ', tabSpaces);\r\n const normalizedText = text.replace(/\\t/g, tabSpace);\r\n const result = foldl(normalizedText, (acc, c) => {\r\n if (isCollapsibleWhitespace$1(c) || c === nbsp) {\r\n if (acc.pcIsSpace || acc.str === '' && isStartOfContent || acc.str.length === normalizedText.length - 1 && isEndOfContent || isNewline(normalizedText, acc.str.length + 1)) {\r\n return {\r\n pcIsSpace: false,\r\n str: acc.str + nbsp\r\n };\r\n } else {\r\n return {\r\n pcIsSpace: true,\r\n str: acc.str + ' '\r\n };\r\n }\r\n } else {\r\n return {\r\n pcIsSpace: isNewLineChar(c),\r\n str: acc.str + c\r\n };\r\n }\r\n }, {\r\n pcIsSpace: false,\r\n str: ''\r\n });\r\n return result.str;\r\n };\r\n\r\n const hasWhitespacePreserveParent = (node, rootNode) => {\r\n const rootElement = SugarElement.fromDom(rootNode);\r\n const startNode = SugarElement.fromDom(node);\r\n return ancestor$2(startNode, 'pre,code', curry(eq, rootElement));\r\n };\r\n const isWhitespace$1 = (node, rootNode) => {\r\n return isText$a(node) && isWhitespaceText(node.data) && !hasWhitespacePreserveParent(node, rootNode);\r\n };\r\n const isNamedAnchor = node => {\r\n return isElement$6(node) && node.nodeName === 'A' && !node.hasAttribute('href') && (node.hasAttribute('name') || node.hasAttribute('id'));\r\n };\r\n const isContent$1 = (node, rootNode) => {\r\n return isCaretCandidate$3(node) && !isWhitespace$1(node, rootNode) || isNamedAnchor(node) || isBookmark(node);\r\n };\r\n const isBookmark = hasAttribute('data-mce-bookmark');\r\n const isBogus$1 = hasAttribute('data-mce-bogus');\r\n const isBogusAll = hasAttributeValue('data-mce-bogus', 'all');\r\n const isEmptyNode = (targetNode, skipBogus) => {\r\n let brCount = 0;\r\n if (isContent$1(targetNode, targetNode)) {\r\n return false;\r\n } else {\r\n let node = targetNode.firstChild;\r\n if (!node) {\r\n return true;\r\n }\r\n const walker = new DomTreeWalker(node, targetNode);\r\n do {\r\n if (skipBogus) {\r\n if (isBogusAll(node)) {\r\n node = walker.next(true);\r\n continue;\r\n }\r\n if (isBogus$1(node)) {\r\n node = walker.next();\r\n continue;\r\n }\r\n }\r\n if (isBr$6(node)) {\r\n brCount++;\r\n node = walker.next();\r\n continue;\r\n }\r\n if (isContent$1(node, targetNode)) {\r\n return false;\r\n }\r\n node = walker.next();\r\n } while (node);\r\n return brCount <= 1;\r\n }\r\n };\r\n const isEmpty$2 = (elm, skipBogus = true) => isEmptyNode(elm.dom, skipBogus);\r\n\r\n const transparentBlockAttr = 'data-mce-block';\r\n const elementNames = map => filter$5(keys(map), key => !/[A-Z]/.test(key));\r\n const makeSelectorFromSchemaMap = map => elementNames(map).join(',');\r\n const updateTransparent = (blocksSelector, transparent) => {\r\n if (isNonNullable(transparent.querySelector(blocksSelector))) {\r\n transparent.setAttribute(transparentBlockAttr, 'true');\r\n if (transparent.getAttribute('data-mce-selected') === 'inline-boundary') {\r\n transparent.removeAttribute('data-mce-selected');\r\n }\r\n return true;\r\n } else {\r\n transparent.removeAttribute(transparentBlockAttr);\r\n return false;\r\n }\r\n };\r\n const updateBlockStateOnChildren = (schema, scope) => {\r\n const transparentSelector = makeSelectorFromSchemaMap(schema.getTransparentElements());\r\n const blocksSelector = makeSelectorFromSchemaMap(schema.getBlockElements());\r\n return filter$5(scope.querySelectorAll(transparentSelector), transparent => updateTransparent(blocksSelector, transparent));\r\n };\r\n const trimEdge = (el, leftSide) => {\r\n var _a;\r\n const childPropertyName = leftSide ? 'lastChild' : 'firstChild';\r\n for (let child = el[childPropertyName]; child; child = child[childPropertyName]) {\r\n if (isEmpty$2(SugarElement.fromDom(child))) {\r\n (_a = child.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(child);\r\n return;\r\n }\r\n }\r\n };\r\n const split$2 = (parentElm, splitElm) => {\r\n const range = document.createRange();\r\n const parentNode = parentElm.parentNode;\r\n if (parentNode) {\r\n range.setStartBefore(parentElm);\r\n range.setEndBefore(splitElm);\r\n const beforeFragment = range.extractContents();\r\n trimEdge(beforeFragment, true);\r\n range.setStartAfter(splitElm);\r\n range.setEndAfter(parentElm);\r\n const afterFragment = range.extractContents();\r\n trimEdge(afterFragment, false);\r\n if (!isEmpty$2(SugarElement.fromDom(beforeFragment))) {\r\n parentNode.insertBefore(beforeFragment, parentElm);\r\n }\r\n if (!isEmpty$2(SugarElement.fromDom(splitElm))) {\r\n parentNode.insertBefore(splitElm, parentElm);\r\n }\r\n if (!isEmpty$2(SugarElement.fromDom(afterFragment))) {\r\n parentNode.insertBefore(afterFragment, parentElm);\r\n }\r\n parentNode.removeChild(parentElm);\r\n }\r\n };\r\n const splitInvalidChildren = (schema, scope, transparentBlocks) => {\r\n const blocksElements = schema.getBlockElements();\r\n const rootNode = SugarElement.fromDom(scope);\r\n const isBlock = el => name(el) in blocksElements;\r\n const isRoot = el => eq(el, rootNode);\r\n each$e(fromDom$1(transparentBlocks), transparentBlock => {\r\n ancestor$4(transparentBlock, isBlock, isRoot).each(parentBlock => {\r\n const invalidChildren = children(transparentBlock, el => isBlock(el) && !schema.isValidChild(name(parentBlock), name(el)));\r\n if (invalidChildren.length > 0) {\r\n const stateScope = parentElement(parentBlock);\r\n each$e(invalidChildren, child => {\r\n ancestor$4(child, isBlock, isRoot).each(parentBlock => {\r\n split$2(parentBlock.dom, child.dom);\r\n });\r\n });\r\n stateScope.each(scope => updateBlockStateOnChildren(schema, scope.dom));\r\n }\r\n });\r\n });\r\n };\r\n const unwrapInvalidChildren = (schema, scope, transparentBlocks) => {\r\n each$e([\r\n ...transparentBlocks,\r\n ...isTransparentBlock(schema, scope) ? [scope] : []\r\n ], block => each$e(descendants(SugarElement.fromDom(block), block.nodeName.toLowerCase()), elm => {\r\n if (isTransparentInline(schema, elm.dom)) {\r\n unwrap(elm);\r\n }\r\n }));\r\n };\r\n const updateChildren = (schema, scope) => {\r\n const transparentBlocks = updateBlockStateOnChildren(schema, scope);\r\n splitInvalidChildren(schema, scope, transparentBlocks);\r\n unwrapInvalidChildren(schema, scope, transparentBlocks);\r\n };\r\n const updateElement = (schema, target) => {\r\n if (isTransparentElement(schema, target)) {\r\n const blocksSelector = makeSelectorFromSchemaMap(schema.getBlockElements());\r\n updateTransparent(blocksSelector, target);\r\n }\r\n };\r\n const updateCaret = (schema, root, caretParent) => {\r\n const isRoot = el => eq(el, SugarElement.fromDom(root));\r\n const parents = parents$1(SugarElement.fromDom(caretParent), isRoot);\r\n get$b(parents, parents.length - 2).filter(isElement$7).fold(() => updateChildren(schema, root), scope => updateChildren(schema, scope.dom));\r\n };\r\n const hasBlockAttr = el => el.hasAttribute(transparentBlockAttr);\r\n const isTransparentElementName = (schema, name) => has$2(schema.getTransparentElements(), name);\r\n const isTransparentElement = (schema, node) => isElement$6(node) && isTransparentElementName(schema, node.nodeName);\r\n const isTransparentBlock = (schema, node) => isTransparentElement(schema, node) && hasBlockAttr(node);\r\n const isTransparentInline = (schema, node) => isTransparentElement(schema, node) && !hasBlockAttr(node);\r\n const isTransparentAstBlock = (schema, node) => node.type === 1 && isTransparentElementName(schema, node.name) && isString(node.attr(transparentBlockAttr));\r\n const isTransparentAstInline = (schema, node) => node.type === 1 && isTransparentElementName(schema, node.name) && isUndefined(node.attr(transparentBlockAttr));\r\n\r\n const browser = detect$2().browser;\r\n const firstElement = nodes => find$2(nodes, isElement$7);\r\n const getTableCaptionDeltaY = elm => {\r\n if (browser.isFirefox() && name(elm) === 'table') {\r\n return firstElement(children$1(elm)).filter(elm => {\r\n return name(elm) === 'caption';\r\n }).bind(caption => {\r\n return firstElement(nextSiblings(caption)).map(body => {\r\n const bodyTop = body.dom.offsetTop;\r\n const captionTop = caption.dom.offsetTop;\r\n const captionHeight = caption.dom.offsetHeight;\r\n return bodyTop <= captionTop ? -captionHeight : 0;\r\n });\r\n }).getOr(0);\r\n } else {\r\n return 0;\r\n }\r\n };\r\n const hasChild = (elm, child) => elm.children && contains$2(elm.children, child);\r\n const getPos = (body, elm, rootElm) => {\r\n let x = 0, y = 0;\r\n const doc = body.ownerDocument;\r\n rootElm = rootElm ? rootElm : body;\r\n if (elm) {\r\n if (rootElm === body && elm.getBoundingClientRect && get$7(SugarElement.fromDom(body), 'position') === 'static') {\r\n const pos = elm.getBoundingClientRect();\r\n x = pos.left + (doc.documentElement.scrollLeft || body.scrollLeft) - doc.documentElement.clientLeft;\r\n y = pos.top + (doc.documentElement.scrollTop || body.scrollTop) - doc.documentElement.clientTop;\r\n return {\r\n x,\r\n y\r\n };\r\n }\r\n let offsetParent = elm;\r\n while (offsetParent && offsetParent !== rootElm && offsetParent.nodeType && !hasChild(offsetParent, rootElm)) {\r\n const castOffsetParent = offsetParent;\r\n x += castOffsetParent.offsetLeft || 0;\r\n y += castOffsetParent.offsetTop || 0;\r\n offsetParent = castOffsetParent.offsetParent;\r\n }\r\n offsetParent = elm.parentNode;\r\n while (offsetParent && offsetParent !== rootElm && offsetParent.nodeType && !hasChild(offsetParent, rootElm)) {\r\n x -= offsetParent.scrollLeft || 0;\r\n y -= offsetParent.scrollTop || 0;\r\n offsetParent = offsetParent.parentNode;\r\n }\r\n y += getTableCaptionDeltaY(SugarElement.fromDom(elm));\r\n }\r\n return {\r\n x,\r\n y\r\n };\r\n };\r\n\r\n const StyleSheetLoader = (documentOrShadowRoot, settings = {}) => {\r\n let idCount = 0;\r\n const loadedStates = {};\r\n const edos = SugarElement.fromDom(documentOrShadowRoot);\r\n const doc = documentOrOwner(edos);\r\n const _setReferrerPolicy = referrerPolicy => {\r\n settings.referrerPolicy = referrerPolicy;\r\n };\r\n const _setContentCssCors = contentCssCors => {\r\n settings.contentCssCors = contentCssCors;\r\n };\r\n const addStyle = element => {\r\n append$1(getStyleContainer(edos), element);\r\n };\r\n const removeStyle = id => {\r\n const styleContainer = getStyleContainer(edos);\r\n descendant(styleContainer, '#' + id).each(remove$6);\r\n };\r\n const getOrCreateState = url => get$a(loadedStates, url).getOrThunk(() => ({\r\n id: 'mce-u' + idCount++,\r\n passed: [],\r\n failed: [],\r\n count: 0\r\n }));\r\n const load = url => new Promise((success, failure) => {\r\n let link;\r\n const urlWithSuffix = Tools._addCacheSuffix(url);\r\n const state = getOrCreateState(urlWithSuffix);\r\n loadedStates[urlWithSuffix] = state;\r\n state.count++;\r\n const resolve = (callbacks, status) => {\r\n each$e(callbacks, call);\r\n state.status = status;\r\n state.passed = [];\r\n state.failed = [];\r\n if (link) {\r\n link.onload = null;\r\n link.onerror = null;\r\n link = null;\r\n }\r\n };\r\n const passed = () => resolve(state.passed, 2);\r\n const failed = () => resolve(state.failed, 3);\r\n if (success) {\r\n state.passed.push(success);\r\n }\r\n if (failure) {\r\n state.failed.push(failure);\r\n }\r\n if (state.status === 1) {\r\n return;\r\n }\r\n if (state.status === 2) {\r\n passed();\r\n return;\r\n }\r\n if (state.status === 3) {\r\n failed();\r\n return;\r\n }\r\n state.status = 1;\r\n const linkElem = SugarElement.fromTag('link', doc.dom);\r\n setAll$1(linkElem, {\r\n rel: 'stylesheet',\r\n type: 'text/css',\r\n id: state.id\r\n });\r\n if (settings.contentCssCors) {\r\n set$3(linkElem, 'crossOrigin', 'anonymous');\r\n }\r\n if (settings.referrerPolicy) {\r\n set$3(linkElem, 'referrerpolicy', settings.referrerPolicy);\r\n }\r\n link = linkElem.dom;\r\n link.onload = passed;\r\n link.onerror = failed;\r\n addStyle(linkElem);\r\n set$3(linkElem, 'href', urlWithSuffix);\r\n });\r\n const loadAll = urls => {\r\n const loadedUrls = Promise.allSettled(map$3(urls, url => load(url).then(constant(url))));\r\n return loadedUrls.then(results => {\r\n const parts = partition$2(results, r => r.status === 'fulfilled');\r\n if (parts.fail.length > 0) {\r\n return Promise.reject(map$3(parts.fail, result => result.reason));\r\n } else {\r\n return map$3(parts.pass, result => result.value);\r\n }\r\n });\r\n };\r\n const unload = url => {\r\n const urlWithSuffix = Tools._addCacheSuffix(url);\r\n get$a(loadedStates, urlWithSuffix).each(state => {\r\n const count = --state.count;\r\n if (count === 0) {\r\n delete loadedStates[urlWithSuffix];\r\n removeStyle(state.id);\r\n }\r\n });\r\n };\r\n const unloadAll = urls => {\r\n each$e(urls, url => {\r\n unload(url);\r\n });\r\n };\r\n return {\r\n load,\r\n loadAll,\r\n unload,\r\n unloadAll,\r\n _setReferrerPolicy,\r\n _setContentCssCors\r\n };\r\n };\r\n\r\n const create$d = () => {\r\n const map = new WeakMap();\r\n const forElement = (referenceElement, settings) => {\r\n const root = getRootNode(referenceElement);\r\n const rootDom = root.dom;\r\n return Optional.from(map.get(rootDom)).getOrThunk(() => {\r\n const sl = StyleSheetLoader(rootDom, settings);\r\n map.set(rootDom, sl);\r\n return sl;\r\n });\r\n };\r\n return { forElement };\r\n };\r\n const instance = create$d();\r\n\r\n const isSpan = node => node.nodeName.toLowerCase() === 'span';\r\n const isInlineContent = (node, root) => isNonNullable(node) && (isContent$1(node, root) || isInline$1(SugarElement.fromDom(node)));\r\n const surroundedByInlineContent = (node, root) => {\r\n const prev = new DomTreeWalker(node, root).prev(false);\r\n const next = new DomTreeWalker(node, root).next(false);\r\n const prevIsInline = isUndefined(prev) || isInlineContent(prev, root);\r\n const nextIsInline = isUndefined(next) || isInlineContent(next, root);\r\n return prevIsInline && nextIsInline;\r\n };\r\n const isBookmarkNode$2 = node => isSpan(node) && node.getAttribute('data-mce-type') === 'bookmark';\r\n const isKeepTextNode = (node, root) => isText$a(node) && node.data.length > 0 && surroundedByInlineContent(node, root);\r\n const isKeepElement = node => isElement$6(node) ? node.childNodes.length > 0 : false;\r\n const isDocument = node => isDocumentFragment(node) || isDocument$1(node);\r\n const trimNode = (dom, node, root) => {\r\n var _a;\r\n const rootNode = root || node;\r\n if (isElement$6(node) && isBookmarkNode$2(node)) {\r\n return node;\r\n }\r\n const children = node.childNodes;\r\n for (let i = children.length - 1; i >= 0; i--) {\r\n trimNode(dom, children[i], rootNode);\r\n }\r\n if (isElement$6(node)) {\r\n const currentChildren = node.childNodes;\r\n if (currentChildren.length === 1 && isBookmarkNode$2(currentChildren[0])) {\r\n (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(currentChildren[0], node);\r\n }\r\n }\r\n if (!isDocument(node) && !isContent$1(node, rootNode) && !isKeepElement(node) && !isKeepTextNode(node, rootNode)) {\r\n dom.remove(node);\r\n }\r\n return node;\r\n };\r\n\r\n const makeMap$3 = Tools.makeMap;\r\n const attrsCharsRegExp = /[&<>\\\"\\u0060\\u007E-\\uD7FF\\uE000-\\uFFEF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g;\r\n const textCharsRegExp = /[<>&\\u007E-\\uD7FF\\uE000-\\uFFEF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g;\r\n const rawCharsRegExp = /[<>&\\\"\\']/g;\r\n const entityRegExp = /&#([a-z0-9]+);?|&([a-z0-9]+);/gi;\r\n const asciiMap = {\r\n 128: '\\u20AC',\r\n 130: '\\u201A',\r\n 131: '\\u0192',\r\n 132: '\\u201E',\r\n 133: '\\u2026',\r\n 134: '\\u2020',\r\n 135: '\\u2021',\r\n 136: '\\u02c6',\r\n 137: '\\u2030',\r\n 138: '\\u0160',\r\n 139: '\\u2039',\r\n 140: '\\u0152',\r\n 142: '\\u017d',\r\n 145: '\\u2018',\r\n 146: '\\u2019',\r\n 147: '\\u201C',\r\n 148: '\\u201D',\r\n 149: '\\u2022',\r\n 150: '\\u2013',\r\n 151: '\\u2014',\r\n 152: '\\u02DC',\r\n 153: '\\u2122',\r\n 154: '\\u0161',\r\n 155: '\\u203A',\r\n 156: '\\u0153',\r\n 158: '\\u017e',\r\n 159: '\\u0178'\r\n };\r\n const baseEntities = {\r\n '\"': '"',\r\n '\\'': ''',\r\n '<': '<',\r\n '>': '>',\r\n '&': '&',\r\n '`': '`'\r\n };\r\n const reverseEntities = {\r\n '<': '<',\r\n '>': '>',\r\n '&': '&',\r\n '"': '\"',\r\n ''': `'`\r\n };\r\n const nativeDecode = text => {\r\n const elm = SugarElement.fromTag('div').dom;\r\n elm.innerHTML = text;\r\n return elm.textContent || elm.innerText || text;\r\n };\r\n const buildEntitiesLookup = (items, radix) => {\r\n const lookup = {};\r\n if (items) {\r\n const itemList = items.split(',');\r\n radix = radix || 10;\r\n for (let i = 0; i < itemList.length; i += 2) {\r\n const chr = String.fromCharCode(parseInt(itemList[i], radix));\r\n if (!baseEntities[chr]) {\r\n const entity = '&' + itemList[i + 1] + ';';\r\n lookup[chr] = entity;\r\n lookup[entity] = chr;\r\n }\r\n }\r\n return lookup;\r\n } else {\r\n return undefined;\r\n }\r\n };\r\n const namedEntities = buildEntitiesLookup('50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,' + '5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,' + '5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,' + '5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,' + '68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,' + '6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,' + '6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,' + '75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,' + '7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,' + '7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,' + 'sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,' + 'st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,' + 't9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,' + 'tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,' + 'u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,' + '81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,' + '8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,' + '8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,' + '8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,' + '8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,' + 'nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,' + 'rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,' + 'Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,' + '80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,' + '811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro', 32);\r\n const encodeRaw = (text, attr) => text.replace(attr ? attrsCharsRegExp : textCharsRegExp, chr => {\r\n return baseEntities[chr] || chr;\r\n });\r\n const encodeAllRaw = text => ('' + text).replace(rawCharsRegExp, chr => {\r\n return baseEntities[chr] || chr;\r\n });\r\n const encodeNumeric = (text, attr) => text.replace(attr ? attrsCharsRegExp : textCharsRegExp, chr => {\r\n if (chr.length > 1) {\r\n return '&#' + ((chr.charCodeAt(0) - 55296) * 1024 + (chr.charCodeAt(1) - 56320) + 65536) + ';';\r\n }\r\n return baseEntities[chr] || '&#' + chr.charCodeAt(0) + ';';\r\n });\r\n const encodeNamed = (text, attr, entities) => {\r\n const resolveEntities = entities || namedEntities;\r\n return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, chr => {\r\n return baseEntities[chr] || resolveEntities[chr] || chr;\r\n });\r\n };\r\n const getEncodeFunc = (name, entities) => {\r\n const entitiesMap = buildEntitiesLookup(entities) || namedEntities;\r\n const encodeNamedAndNumeric = (text, attr) => text.replace(attr ? attrsCharsRegExp : textCharsRegExp, chr => {\r\n if (baseEntities[chr] !== undefined) {\r\n return baseEntities[chr];\r\n }\r\n if (entitiesMap[chr] !== undefined) {\r\n return entitiesMap[chr];\r\n }\r\n if (chr.length > 1) {\r\n return '&#' + ((chr.charCodeAt(0) - 55296) * 1024 + (chr.charCodeAt(1) - 56320) + 65536) + ';';\r\n }\r\n return '&#' + chr.charCodeAt(0) + ';';\r\n });\r\n const encodeCustomNamed = (text, attr) => {\r\n return encodeNamed(text, attr, entitiesMap);\r\n };\r\n const nameMap = makeMap$3(name.replace(/\\+/g, ','));\r\n if (nameMap.named && nameMap.numeric) {\r\n return encodeNamedAndNumeric;\r\n }\r\n if (nameMap.named) {\r\n if (entities) {\r\n return encodeCustomNamed;\r\n }\r\n return encodeNamed;\r\n }\r\n if (nameMap.numeric) {\r\n return encodeNumeric;\r\n }\r\n return encodeRaw;\r\n };\r\n const decode = text => text.replace(entityRegExp, (all, numeric) => {\r\n if (numeric) {\r\n if (numeric.charAt(0).toLowerCase() === 'x') {\r\n numeric = parseInt(numeric.substr(1), 16);\r\n } else {\r\n numeric = parseInt(numeric, 10);\r\n }\r\n if (numeric > 65535) {\r\n numeric -= 65536;\r\n return String.fromCharCode(55296 + (numeric >> 10), 56320 + (numeric & 1023));\r\n }\r\n return asciiMap[numeric] || String.fromCharCode(numeric);\r\n }\r\n return reverseEntities[all] || namedEntities[all] || nativeDecode(all);\r\n });\r\n const Entities = {\r\n encodeRaw,\r\n encodeAllRaw,\r\n encodeNumeric,\r\n encodeNamed,\r\n getEncodeFunc,\r\n decode\r\n };\r\n\r\n const lookupCache = {};\r\n const mapCache = {};\r\n const dummyObj = {};\r\n const makeMap$2 = Tools.makeMap, each$b = Tools.each, extend$2 = Tools.extend, explode$2 = Tools.explode, inArray = Tools.inArray;\r\n const split$1 = (items, delim) => {\r\n items = Tools.trim(items);\r\n return items ? items.split(delim || ' ') : [];\r\n };\r\n const createMap = (defaultValue, extendWith = {}) => {\r\n const value = makeMap$2(defaultValue, ' ', makeMap$2(defaultValue.toUpperCase(), ' '));\r\n return extend$2(value, extendWith);\r\n };\r\n const getTextRootBlockElements = schema => createMap('td th li dt dd figcaption caption details summary', schema.getTextBlockElements());\r\n const compileSchema = type => {\r\n const schema = {};\r\n let globalAttributes, blockContent;\r\n let phrasingContent, flowContent;\r\n const add = (name, attributes = '', children = '') => {\r\n const childNames = split$1(children);\r\n const names = split$1(name);\r\n let ni = names.length;\r\n while (ni--) {\r\n const attributesOrder = split$1([\r\n globalAttributes,\r\n attributes\r\n ].join(' '));\r\n schema[names[ni]] = {\r\n attributes: mapToObject(attributesOrder, () => ({})),\r\n attributesOrder,\r\n children: mapToObject(childNames, constant(dummyObj))\r\n };\r\n }\r\n };\r\n const addAttrs = (name, attributes) => {\r\n const names = split$1(name);\r\n const attrs = split$1(attributes);\r\n let ni = names.length;\r\n while (ni--) {\r\n const schemaItem = schema[names[ni]];\r\n for (let i = 0, l = attrs.length; i < l; i++) {\r\n schemaItem.attributes[attrs[i]] = {};\r\n schemaItem.attributesOrder.push(attrs[i]);\r\n }\r\n }\r\n };\r\n if (lookupCache[type]) {\r\n return lookupCache[type];\r\n }\r\n globalAttributes = 'id accesskey class dir lang style tabindex title role';\r\n blockContent = 'address blockquote div dl fieldset form h1 h2 h3 h4 h5 h6 hr menu ol p pre table ul';\r\n phrasingContent = 'a abbr b bdo br button cite code del dfn em embed i iframe img input ins kbd ' + 'label map noscript object q s samp script select small span strong sub sup ' + 'textarea u var #text #comment';\r\n if (type !== 'html4') {\r\n const transparentContent = 'a ins del canvas map';\r\n globalAttributes += ' contenteditable contextmenu draggable dropzone ' + 'hidden spellcheck translate';\r\n blockContent += ' article aside details dialog figure main header footer hgroup section nav ' + transparentContent;\r\n phrasingContent += ' audio canvas command datalist mark meter output picture ' + 'progress time wbr video ruby bdi keygen';\r\n }\r\n if (type !== 'html5-strict') {\r\n globalAttributes += ' xml:lang';\r\n const html4PhrasingContent = 'acronym applet basefont big font strike tt';\r\n phrasingContent = [\r\n phrasingContent,\r\n html4PhrasingContent\r\n ].join(' ');\r\n each$b(split$1(html4PhrasingContent), name => {\r\n add(name, '', phrasingContent);\r\n });\r\n const html4BlockContent = 'center dir isindex noframes';\r\n blockContent = [\r\n blockContent,\r\n html4BlockContent\r\n ].join(' ');\r\n flowContent = [\r\n blockContent,\r\n phrasingContent\r\n ].join(' ');\r\n each$b(split$1(html4BlockContent), name => {\r\n add(name, '', flowContent);\r\n });\r\n }\r\n flowContent = flowContent || [\r\n blockContent,\r\n phrasingContent\r\n ].join(' ');\r\n add('html', 'manifest', 'head body');\r\n add('head', '', 'base command link meta noscript script style title');\r\n add('title hr noscript br');\r\n add('base', 'href target');\r\n add('link', 'href rel media hreflang type sizes hreflang');\r\n add('meta', 'name http-equiv content charset');\r\n add('style', 'media type scoped');\r\n add('script', 'src async defer type charset');\r\n add('body', 'onafterprint onbeforeprint onbeforeunload onblur onerror onfocus ' + 'onhashchange onload onmessage onoffline ononline onpagehide onpageshow ' + 'onpopstate onresize onscroll onstorage onunload', flowContent);\r\n add('address dt dd div caption', '', flowContent);\r\n add('h1 h2 h3 h4 h5 h6 pre p abbr code var samp kbd sub sup i b u bdo span legend em strong small s cite dfn', '', phrasingContent);\r\n add('blockquote', 'cite', flowContent);\r\n add('ol', 'reversed start type', 'li');\r\n add('ul', '', 'li');\r\n add('li', 'value', flowContent);\r\n add('dl', '', 'dt dd');\r\n add('a', 'href target rel media hreflang type', flowContent);\r\n add('q', 'cite', phrasingContent);\r\n add('ins del', 'cite datetime', flowContent);\r\n add('img', 'src sizes srcset alt usemap ismap width height');\r\n add('iframe', 'src name width height', flowContent);\r\n add('embed', 'src type width height');\r\n add('object', 'data type typemustmatch name usemap form width height', [\r\n flowContent,\r\n 'param'\r\n ].join(' '));\r\n add('param', 'name value');\r\n add('map', 'name', [\r\n flowContent,\r\n 'area'\r\n ].join(' '));\r\n add('area', 'alt coords shape href target rel media hreflang type');\r\n add('table', 'border', 'caption colgroup thead tfoot tbody tr' + (type === 'html4' ? ' col' : ''));\r\n add('colgroup', 'span', 'col');\r\n add('col', 'span');\r\n add('tbody thead tfoot', '', 'tr');\r\n add('tr', '', 'td th');\r\n add('td', 'colspan rowspan headers', flowContent);\r\n add('th', 'colspan rowspan headers scope abbr', flowContent);\r\n add('form', 'accept-charset action autocomplete enctype method name novalidate target', flowContent);\r\n add('fieldset', 'disabled form name', [\r\n flowContent,\r\n 'legend'\r\n ].join(' '));\r\n add('label', 'form for', phrasingContent);\r\n add('input', 'accept alt autocomplete checked dirname disabled form formaction formenctype formmethod formnovalidate ' + 'formtarget height list max maxlength min multiple name pattern readonly required size src step type value width');\r\n add('button', 'disabled form formaction formenctype formmethod formnovalidate formtarget name type value', type === 'html4' ? flowContent : phrasingContent);\r\n add('select', 'disabled form multiple name required size', 'option optgroup');\r\n add('optgroup', 'disabled label', 'option');\r\n add('option', 'disabled label selected value');\r\n add('textarea', 'cols dirname disabled form maxlength name readonly required rows wrap');\r\n add('menu', 'type label', [\r\n flowContent,\r\n 'li'\r\n ].join(' '));\r\n add('noscript', '', flowContent);\r\n if (type !== 'html4') {\r\n add('wbr');\r\n add('ruby', '', [\r\n phrasingContent,\r\n 'rt rp'\r\n ].join(' '));\r\n add('figcaption', '', flowContent);\r\n add('mark rt rp summary bdi', '', phrasingContent);\r\n add('canvas', 'width height', flowContent);\r\n add('video', 'src crossorigin poster preload autoplay mediagroup loop ' + 'muted controls width height buffered', [\r\n flowContent,\r\n 'track source'\r\n ].join(' '));\r\n add('audio', 'src crossorigin preload autoplay mediagroup loop muted controls ' + 'buffered volume', [\r\n flowContent,\r\n 'track source'\r\n ].join(' '));\r\n add('picture', '', 'img source');\r\n add('source', 'src srcset type media sizes');\r\n add('track', 'kind src srclang label default');\r\n add('datalist', '', [\r\n phrasingContent,\r\n 'option'\r\n ].join(' '));\r\n add('article section nav aside main header footer', '', flowContent);\r\n add('hgroup', '', 'h1 h2 h3 h4 h5 h6');\r\n add('figure', '', [\r\n flowContent,\r\n 'figcaption'\r\n ].join(' '));\r\n add('time', 'datetime', phrasingContent);\r\n add('dialog', 'open', flowContent);\r\n add('command', 'type label icon disabled checked radiogroup command');\r\n add('output', 'for form name', phrasingContent);\r\n add('progress', 'value max', phrasingContent);\r\n add('meter', 'value min max low high optimum', phrasingContent);\r\n add('details', 'open', [\r\n flowContent,\r\n 'summary'\r\n ].join(' '));\r\n add('keygen', 'autofocus challenge disabled form keytype name');\r\n }\r\n if (type !== 'html5-strict') {\r\n addAttrs('script', 'language xml:space');\r\n addAttrs('style', 'xml:space');\r\n addAttrs('object', 'declare classid code codebase codetype archive standby align border hspace vspace');\r\n addAttrs('embed', 'align name hspace vspace');\r\n addAttrs('param', 'valuetype type');\r\n addAttrs('a', 'charset name rev shape coords');\r\n addAttrs('br', 'clear');\r\n addAttrs('applet', 'codebase archive code object alt name width height align hspace vspace');\r\n addAttrs('img', 'name longdesc align border hspace vspace');\r\n addAttrs('iframe', 'longdesc frameborder marginwidth marginheight scrolling align');\r\n addAttrs('font basefont', 'size color face');\r\n addAttrs('input', 'usemap align');\r\n addAttrs('select');\r\n addAttrs('textarea');\r\n addAttrs('h1 h2 h3 h4 h5 h6 div p legend caption', 'align');\r\n addAttrs('ul', 'type compact');\r\n addAttrs('li', 'type');\r\n addAttrs('ol dl menu dir', 'compact');\r\n addAttrs('pre', 'width xml:space');\r\n addAttrs('hr', 'align noshade size width');\r\n addAttrs('isindex', 'prompt');\r\n addAttrs('table', 'summary width frame rules cellspacing cellpadding align bgcolor');\r\n addAttrs('col', 'width align char charoff valign');\r\n addAttrs('colgroup', 'width align char charoff valign');\r\n addAttrs('thead', 'align char charoff valign');\r\n addAttrs('tr', 'align char charoff valign bgcolor');\r\n addAttrs('th', 'axis align char charoff valign nowrap bgcolor width height');\r\n addAttrs('form', 'accept');\r\n addAttrs('td', 'abbr axis scope align char charoff valign nowrap bgcolor width height');\r\n addAttrs('tfoot', 'align char charoff valign');\r\n addAttrs('tbody', 'align char charoff valign');\r\n addAttrs('area', 'nohref');\r\n addAttrs('body', 'background bgcolor text link vlink alink');\r\n }\r\n if (type !== 'html4') {\r\n addAttrs('input button select textarea', 'autofocus');\r\n addAttrs('input textarea', 'placeholder');\r\n addAttrs('a', 'download');\r\n addAttrs('link script img', 'crossorigin');\r\n addAttrs('img', 'loading');\r\n addAttrs('iframe', 'sandbox seamless allow allowfullscreen loading');\r\n }\r\n if (type !== 'html4') {\r\n each$e([\r\n schema.video,\r\n schema.audio\r\n ], item => {\r\n delete item.children.audio;\r\n delete item.children.video;\r\n });\r\n }\r\n each$b(split$1('a form meter progress dfn'), name => {\r\n if (schema[name]) {\r\n delete schema[name].children[name];\r\n }\r\n });\r\n delete schema.caption.children.table;\r\n delete schema.script;\r\n lookupCache[type] = schema;\r\n return schema;\r\n };\r\n const compileElementMap = (value, mode) => {\r\n if (value) {\r\n const styles = {};\r\n if (isString(value)) {\r\n value = { '*': value };\r\n }\r\n each$b(value, (value, key) => {\r\n styles[key] = styles[key.toUpperCase()] = mode === 'map' ? makeMap$2(value, /[, ]/) : explode$2(value, /[, ]/);\r\n });\r\n return styles;\r\n } else {\r\n return undefined;\r\n }\r\n };\r\n const Schema = (settings = {}) => {\r\n var _a;\r\n const elements = {};\r\n const children = {};\r\n let patternElements = [];\r\n const customElementsMap = {};\r\n const specialElements = {};\r\n const createLookupTable = (option, defaultValue, extendWith) => {\r\n const value = settings[option];\r\n if (!value) {\r\n let newValue = mapCache[option];\r\n if (!newValue) {\r\n newValue = createMap(defaultValue, extendWith);\r\n mapCache[option] = newValue;\r\n }\r\n return newValue;\r\n } else {\r\n return makeMap$2(value, /[, ]/, makeMap$2(value.toUpperCase(), /[, ]/));\r\n }\r\n };\r\n const schemaType = (_a = settings.schema) !== null && _a !== void 0 ? _a : 'html5';\r\n const schemaItems = compileSchema(schemaType);\r\n if (settings.verify_html === false) {\r\n settings.valid_elements = '*[*]';\r\n }\r\n const validStyles = compileElementMap(settings.valid_styles);\r\n const invalidStyles = compileElementMap(settings.invalid_styles, 'map');\r\n const validClasses = compileElementMap(settings.valid_classes, 'map');\r\n const whitespaceElementsMap = createLookupTable('whitespace_elements', 'pre script noscript style textarea video audio iframe object code');\r\n const selfClosingElementsMap = createLookupTable('self_closing_elements', 'colgroup dd dt li option p td tfoot th thead tr');\r\n const voidElementsMap = createLookupTable('void_elements', 'area base basefont br col frame hr img input isindex link ' + 'meta param embed source wbr track');\r\n const boolAttrMap = createLookupTable('boolean_attributes', 'checked compact declare defer disabled ismap multiple nohref noresize ' + 'noshade nowrap readonly selected autoplay loop controls allowfullscreen');\r\n const nonEmptyOrMoveCaretBeforeOnEnter = 'td th iframe video audio object script code';\r\n const nonEmptyElementsMap = createLookupTable('non_empty_elements', nonEmptyOrMoveCaretBeforeOnEnter + ' pre', voidElementsMap);\r\n const moveCaretBeforeOnEnterElementsMap = createLookupTable('move_caret_before_on_enter_elements', nonEmptyOrMoveCaretBeforeOnEnter + ' table', voidElementsMap);\r\n const textBlockElementsMap = createLookupTable('text_block_elements', 'h1 h2 h3 h4 h5 h6 p div address pre form ' + 'blockquote center dir fieldset header footer article section hgroup aside main nav figure');\r\n const blockElementsMap = createLookupTable('block_elements', 'hr table tbody thead tfoot ' + 'th tr td li ol ul caption dl dt dd noscript menu isindex option ' + 'datalist select optgroup figcaption details summary', textBlockElementsMap);\r\n const textInlineElementsMap = createLookupTable('text_inline_elements', 'span strong b em i font s strike u var cite ' + 'dfn code mark q sup sub samp');\r\n const transparentElementsMap = createLookupTable('transparent_elements', 'a ins del canvas map');\r\n each$b('script noscript iframe noframes noembed title style textarea xmp plaintext'.split(' '), name => {\r\n specialElements[name] = new RegExp(']*>', 'gi');\r\n });\r\n const patternToRegExp = str => new RegExp('^' + str.replace(/([?+*])/g, '.$1') + '$');\r\n const addValidElements = validElements => {\r\n const elementRuleRegExp = /^([#+\\-])?([^\\[!\\/]+)(?:\\/([^\\[!]+))?(?:(!?)\\[([^\\]]+)])?$/;\r\n const attrRuleRegExp = /^([!\\-])?(\\w+[\\\\:]:\\w+|[^=~<]+)?(?:([=~<])(.*))?$/;\r\n const hasPatternsRegExp = /[*?+]/;\r\n if (validElements) {\r\n const validElementsArr = split$1(validElements, ',');\r\n let globalAttributes;\r\n let globalAttributesOrder;\r\n if (elements['@']) {\r\n globalAttributes = elements['@'].attributes;\r\n globalAttributesOrder = elements['@'].attributesOrder;\r\n }\r\n for (let ei = 0, el = validElementsArr.length; ei < el; ei++) {\r\n let matches = elementRuleRegExp.exec(validElementsArr[ei]);\r\n if (matches) {\r\n const prefix = matches[1];\r\n const elementName = matches[2];\r\n const outputName = matches[3];\r\n const attrData = matches[5];\r\n const attributes = {};\r\n const attributesOrder = [];\r\n const element = {\r\n attributes,\r\n attributesOrder\r\n };\r\n if (prefix === '#') {\r\n element.paddEmpty = true;\r\n }\r\n if (prefix === '-') {\r\n element.removeEmpty = true;\r\n }\r\n if (matches[4] === '!') {\r\n element.removeEmptyAttrs = true;\r\n }\r\n if (globalAttributes) {\r\n each$d(globalAttributes, (value, key) => {\r\n attributes[key] = value;\r\n });\r\n if (globalAttributesOrder) {\r\n attributesOrder.push(...globalAttributesOrder);\r\n }\r\n }\r\n if (attrData) {\r\n const attrDatas = split$1(attrData, '|');\r\n for (let ai = 0, al = attrDatas.length; ai < al; ai++) {\r\n matches = attrRuleRegExp.exec(attrDatas[ai]);\r\n if (matches) {\r\n const attr = {};\r\n const attrType = matches[1];\r\n const attrName = matches[2].replace(/[\\\\:]:/g, ':');\r\n const attrPrefix = matches[3];\r\n const value = matches[4];\r\n if (attrType === '!') {\r\n element.attributesRequired = element.attributesRequired || [];\r\n element.attributesRequired.push(attrName);\r\n attr.required = true;\r\n }\r\n if (attrType === '-') {\r\n delete attributes[attrName];\r\n attributesOrder.splice(inArray(attributesOrder, attrName), 1);\r\n continue;\r\n }\r\n if (attrPrefix) {\r\n if (attrPrefix === '=') {\r\n element.attributesDefault = element.attributesDefault || [];\r\n element.attributesDefault.push({\r\n name: attrName,\r\n value\r\n });\r\n attr.defaultValue = value;\r\n }\r\n if (attrPrefix === '~') {\r\n element.attributesForced = element.attributesForced || [];\r\n element.attributesForced.push({\r\n name: attrName,\r\n value\r\n });\r\n attr.forcedValue = value;\r\n }\r\n if (attrPrefix === '<') {\r\n attr.validValues = makeMap$2(value, '?');\r\n }\r\n }\r\n if (hasPatternsRegExp.test(attrName)) {\r\n const attrPattern = attr;\r\n element.attributePatterns = element.attributePatterns || [];\r\n attrPattern.pattern = patternToRegExp(attrName);\r\n element.attributePatterns.push(attrPattern);\r\n } else {\r\n if (!attributes[attrName]) {\r\n attributesOrder.push(attrName);\r\n }\r\n attributes[attrName] = attr;\r\n }\r\n }\r\n }\r\n }\r\n if (!globalAttributes && elementName === '@') {\r\n globalAttributes = attributes;\r\n globalAttributesOrder = attributesOrder;\r\n }\r\n if (outputName) {\r\n element.outputName = elementName;\r\n elements[outputName] = element;\r\n }\r\n if (hasPatternsRegExp.test(elementName)) {\r\n const patternElement = element;\r\n patternElement.pattern = patternToRegExp(elementName);\r\n patternElements.push(patternElement);\r\n } else {\r\n elements[elementName] = element;\r\n }\r\n }\r\n }\r\n }\r\n };\r\n const setValidElements = validElements => {\r\n patternElements = [];\r\n each$e(keys(elements), name => {\r\n delete elements[name];\r\n });\r\n addValidElements(validElements);\r\n each$b(schemaItems, (element, name) => {\r\n children[name] = element.children;\r\n });\r\n };\r\n const addCustomElements = customElements => {\r\n const customElementRegExp = /^(~)?(.+)$/;\r\n if (customElements) {\r\n delete mapCache.text_block_elements;\r\n delete mapCache.block_elements;\r\n each$b(split$1(customElements, ','), rule => {\r\n const matches = customElementRegExp.exec(rule);\r\n if (matches) {\r\n const inline = matches[1] === '~';\r\n const cloneName = inline ? 'span' : 'div';\r\n const name = matches[2];\r\n children[name] = children[cloneName];\r\n customElementsMap[name] = cloneName;\r\n nonEmptyElementsMap[name.toUpperCase()] = {};\r\n nonEmptyElementsMap[name] = {};\r\n if (!inline) {\r\n blockElementsMap[name.toUpperCase()] = {};\r\n blockElementsMap[name] = {};\r\n }\r\n if (!elements[name]) {\r\n let customRule = elements[cloneName];\r\n customRule = extend$2({}, customRule);\r\n delete customRule.removeEmptyAttrs;\r\n delete customRule.removeEmpty;\r\n elements[name] = customRule;\r\n }\r\n each$b(children, (element, elmName) => {\r\n if (element[cloneName]) {\r\n children[elmName] = element = extend$2({}, children[elmName]);\r\n element[name] = element[cloneName];\r\n }\r\n });\r\n }\r\n });\r\n }\r\n };\r\n const addValidChildren = validChildren => {\r\n const childRuleRegExp = /^([+\\-]?)([A-Za-z0-9_\\-.\\u00b7\\u00c0-\\u00d6\\u00d8-\\u00f6\\u00f8-\\u037d\\u037f-\\u1fff\\u200c-\\u200d\\u203f-\\u2040\\u2070-\\u218f\\u2c00-\\u2fef\\u3001-\\ud7ff\\uf900-\\ufdcf\\ufdf0-\\ufffd]+)\\[([^\\]]+)]$/;\r\n delete lookupCache[schemaType];\r\n if (validChildren) {\r\n each$b(split$1(validChildren, ','), rule => {\r\n const matches = childRuleRegExp.exec(rule);\r\n if (matches) {\r\n const prefix = matches[1];\r\n let parent;\r\n if (prefix) {\r\n parent = children[matches[2]];\r\n } else {\r\n parent = children[matches[2]] = { '#comment': {} };\r\n }\r\n parent = children[matches[2]];\r\n each$b(split$1(matches[3], '|'), child => {\r\n if (prefix === '-') {\r\n delete parent[child];\r\n } else {\r\n parent[child] = {};\r\n }\r\n });\r\n }\r\n });\r\n }\r\n };\r\n const getElementRule = name => {\r\n const element = elements[name];\r\n if (element) {\r\n return element;\r\n }\r\n let i = patternElements.length;\r\n while (i--) {\r\n const patternElement = patternElements[i];\r\n if (patternElement.pattern.test(name)) {\r\n return patternElement;\r\n }\r\n }\r\n return undefined;\r\n };\r\n if (!settings.valid_elements) {\r\n each$b(schemaItems, (element, name) => {\r\n elements[name] = {\r\n attributes: element.attributes,\r\n attributesOrder: element.attributesOrder\r\n };\r\n children[name] = element.children;\r\n });\r\n each$b(split$1('strong/b em/i'), item => {\r\n const items = split$1(item, '/');\r\n elements[items[1]].outputName = items[0];\r\n });\r\n each$b(textInlineElementsMap, (_val, name) => {\r\n if (elements[name]) {\r\n if (settings.padd_empty_block_inline_children) {\r\n elements[name].paddInEmptyBlock = true;\r\n }\r\n elements[name].removeEmpty = true;\r\n }\r\n });\r\n each$b(split$1('ol ul blockquote a table tbody'), name => {\r\n if (elements[name]) {\r\n elements[name].removeEmpty = true;\r\n }\r\n });\r\n each$b(split$1('p h1 h2 h3 h4 h5 h6 th td pre div address caption li'), name => {\r\n elements[name].paddEmpty = true;\r\n });\r\n each$b(split$1('span'), name => {\r\n elements[name].removeEmptyAttrs = true;\r\n });\r\n } else {\r\n setValidElements(settings.valid_elements);\r\n }\r\n addCustomElements(settings.custom_elements);\r\n addValidChildren(settings.valid_children);\r\n addValidElements(settings.extended_valid_elements);\r\n addValidChildren('+ol[ul|ol],+ul[ul|ol]');\r\n each$b({\r\n dd: 'dl',\r\n dt: 'dl',\r\n li: 'ul ol',\r\n td: 'tr',\r\n th: 'tr',\r\n tr: 'tbody thead tfoot',\r\n tbody: 'table',\r\n thead: 'table',\r\n tfoot: 'table',\r\n legend: 'fieldset',\r\n area: 'map',\r\n param: 'video audio object'\r\n }, (parents, item) => {\r\n if (elements[item]) {\r\n elements[item].parentsRequired = split$1(parents);\r\n }\r\n });\r\n if (settings.invalid_elements) {\r\n each$b(explode$2(settings.invalid_elements), item => {\r\n if (elements[item]) {\r\n delete elements[item];\r\n }\r\n });\r\n }\r\n if (!getElementRule('span')) {\r\n addValidElements('span[!data-mce-type|*]');\r\n }\r\n const getValidStyles = constant(validStyles);\r\n const getInvalidStyles = constant(invalidStyles);\r\n const getValidClasses = constant(validClasses);\r\n const getBoolAttrs = constant(boolAttrMap);\r\n const getBlockElements = constant(blockElementsMap);\r\n const getTextBlockElements = constant(textBlockElementsMap);\r\n const getTextInlineElements = constant(textInlineElementsMap);\r\n const getVoidElements = constant(Object.seal(voidElementsMap));\r\n const getSelfClosingElements = constant(selfClosingElementsMap);\r\n const getNonEmptyElements = constant(nonEmptyElementsMap);\r\n const getMoveCaretBeforeOnEnterElements = constant(moveCaretBeforeOnEnterElementsMap);\r\n const getWhitespaceElements = constant(whitespaceElementsMap);\r\n const getTransparentElements = constant(transparentElementsMap);\r\n const getSpecialElements = constant(Object.seal(specialElements));\r\n const isValidChild = (name, child) => {\r\n const parent = children[name.toLowerCase()];\r\n return !!(parent && parent[child.toLowerCase()]);\r\n };\r\n const isValid = (name, attr) => {\r\n const rule = getElementRule(name);\r\n if (rule) {\r\n if (attr) {\r\n if (rule.attributes[attr]) {\r\n return true;\r\n }\r\n const attrPatterns = rule.attributePatterns;\r\n if (attrPatterns) {\r\n let i = attrPatterns.length;\r\n while (i--) {\r\n if (attrPatterns[i].pattern.test(attr)) {\r\n return true;\r\n }\r\n }\r\n }\r\n } else {\r\n return true;\r\n }\r\n }\r\n return false;\r\n };\r\n const getCustomElements = constant(customElementsMap);\r\n return {\r\n type: schemaType,\r\n children,\r\n elements,\r\n getValidStyles,\r\n getValidClasses,\r\n getBlockElements,\r\n getInvalidStyles,\r\n getVoidElements,\r\n getTextBlockElements,\r\n getTextInlineElements,\r\n getBoolAttrs,\r\n getElementRule,\r\n getSelfClosingElements,\r\n getNonEmptyElements,\r\n getMoveCaretBeforeOnEnterElements,\r\n getWhitespaceElements,\r\n getTransparentElements,\r\n getSpecialElements,\r\n isValidChild,\r\n isValid,\r\n getCustomElements,\r\n addValidElements,\r\n setValidElements,\r\n addCustomElements,\r\n addValidChildren\r\n };\r\n };\r\n\r\n const Styles = (settings = {}, schema) => {\r\n const urlOrStrRegExp = /(?:url(?:(?:\\(\\s*\\\"([^\\\"]+)\\\"\\s*\\))|(?:\\(\\s*\\'([^\\']+)\\'\\s*\\))|(?:\\(\\s*([^)\\s]+)\\s*\\))))|(?:\\'([^\\']+)\\')|(?:\\\"([^\\\"]+)\\\")/gi;\r\n const styleRegExp = /\\s*([^:]+):\\s*([^;]+);?/g;\r\n const trimRightRegExp = /\\s+$/;\r\n const encodingLookup = {};\r\n let validStyles;\r\n let invalidStyles;\r\n const invisibleChar = zeroWidth;\r\n if (schema) {\r\n validStyles = schema.getValidStyles();\r\n invalidStyles = schema.getInvalidStyles();\r\n }\r\n const encodingItems = (`\\\\\" \\\\' \\\\; \\\\: ; : ` + invisibleChar).split(' ');\r\n for (let i = 0; i < encodingItems.length; i++) {\r\n encodingLookup[encodingItems[i]] = invisibleChar + i;\r\n encodingLookup[invisibleChar + i] = encodingItems[i];\r\n }\r\n const self = {\r\n parse: css => {\r\n const styles = {};\r\n let isEncoded = false;\r\n const urlConverter = settings.url_converter;\r\n const urlConverterScope = settings.url_converter_scope || self;\r\n const compress = (prefix, suffix, noJoin) => {\r\n const top = styles[prefix + '-top' + suffix];\r\n if (!top) {\r\n return;\r\n }\r\n const right = styles[prefix + '-right' + suffix];\r\n if (!right) {\r\n return;\r\n }\r\n const bottom = styles[prefix + '-bottom' + suffix];\r\n if (!bottom) {\r\n return;\r\n }\r\n const left = styles[prefix + '-left' + suffix];\r\n if (!left) {\r\n return;\r\n }\r\n const box = [\r\n top,\r\n right,\r\n bottom,\r\n left\r\n ];\r\n let i = box.length - 1;\r\n while (i--) {\r\n if (box[i] !== box[i + 1]) {\r\n break;\r\n }\r\n }\r\n if (i > -1 && noJoin) {\r\n return;\r\n }\r\n styles[prefix + suffix] = i === -1 ? box[0] : box.join(' ');\r\n delete styles[prefix + '-top' + suffix];\r\n delete styles[prefix + '-right' + suffix];\r\n delete styles[prefix + '-bottom' + suffix];\r\n delete styles[prefix + '-left' + suffix];\r\n };\r\n const canCompress = key => {\r\n const value = styles[key];\r\n if (!value) {\r\n return;\r\n }\r\n const values = value.split(' ');\r\n let i = values.length;\r\n while (i--) {\r\n if (values[i] !== values[0]) {\r\n return false;\r\n }\r\n }\r\n styles[key] = values[0];\r\n return true;\r\n };\r\n const compress2 = (target, a, b, c) => {\r\n if (!canCompress(a)) {\r\n return;\r\n }\r\n if (!canCompress(b)) {\r\n return;\r\n }\r\n if (!canCompress(c)) {\r\n return;\r\n }\r\n styles[target] = styles[a] + ' ' + styles[b] + ' ' + styles[c];\r\n delete styles[a];\r\n delete styles[b];\r\n delete styles[c];\r\n };\r\n const encode = str => {\r\n isEncoded = true;\r\n return encodingLookup[str];\r\n };\r\n const decode = (str, keepSlashes) => {\r\n if (isEncoded) {\r\n str = str.replace(/\\uFEFF[0-9]/g, str => {\r\n return encodingLookup[str];\r\n });\r\n }\r\n if (!keepSlashes) {\r\n str = str.replace(/\\\\([\\'\\\";:])/g, '$1');\r\n }\r\n return str;\r\n };\r\n const decodeSingleHexSequence = escSeq => {\r\n return String.fromCharCode(parseInt(escSeq.slice(1), 16));\r\n };\r\n const decodeHexSequences = value => {\r\n return value.replace(/\\\\[0-9a-f]+/gi, decodeSingleHexSequence);\r\n };\r\n const processUrl = (match, url, url2, url3, str, str2) => {\r\n str = str || str2;\r\n if (str) {\r\n str = decode(str);\r\n return `'` + str.replace(/\\'/g, `\\\\'`) + `'`;\r\n }\r\n url = decode(url || url2 || url3 || '');\r\n if (!settings.allow_script_urls) {\r\n const scriptUrl = url.replace(/[\\s\\r\\n]+/g, '');\r\n if (/(java|vb)script:/i.test(scriptUrl)) {\r\n return '';\r\n }\r\n if (!settings.allow_svg_data_urls && /^data:image\\/svg/i.test(scriptUrl)) {\r\n return '';\r\n }\r\n }\r\n if (urlConverter) {\r\n url = urlConverter.call(urlConverterScope, url, 'style');\r\n }\r\n return `url('` + url.replace(/\\'/g, `\\\\'`) + `')`;\r\n };\r\n if (css) {\r\n css = css.replace(/[\\u0000-\\u001F]/g, '');\r\n css = css.replace(/\\\\[\\\"\\';:\\uFEFF]/g, encode).replace(/\\\"[^\\\"]+\\\"|\\'[^\\']+\\'/g, str => {\r\n return str.replace(/[;:]/g, encode);\r\n });\r\n let matches;\r\n while (matches = styleRegExp.exec(css)) {\r\n styleRegExp.lastIndex = matches.index + matches[0].length;\r\n let name = matches[1].replace(trimRightRegExp, '').toLowerCase();\r\n let value = matches[2].replace(trimRightRegExp, '');\r\n if (name && value) {\r\n name = decodeHexSequences(name);\r\n value = decodeHexSequences(value);\r\n if (name.indexOf(invisibleChar) !== -1 || name.indexOf('\"') !== -1) {\r\n continue;\r\n }\r\n if (!settings.allow_script_urls && (name === 'behavior' || /expression\\s*\\(|\\/\\*|\\*\\//.test(value))) {\r\n continue;\r\n }\r\n if (name === 'font-weight' && value === '700') {\r\n value = 'bold';\r\n } else if (name === 'color' || name === 'background-color') {\r\n value = value.toLowerCase();\r\n }\r\n value = value.replace(urlOrStrRegExp, processUrl);\r\n styles[name] = isEncoded ? decode(value, true) : value;\r\n }\r\n }\r\n compress('border', '', true);\r\n compress('border', '-width');\r\n compress('border', '-color');\r\n compress('border', '-style');\r\n compress('padding', '');\r\n compress('margin', '');\r\n compress2('border', 'border-width', 'border-style', 'border-color');\r\n if (styles.border === 'medium none') {\r\n delete styles.border;\r\n }\r\n if (styles['border-image'] === 'none') {\r\n delete styles['border-image'];\r\n }\r\n }\r\n return styles;\r\n },\r\n serialize: (styles, elementName) => {\r\n let css = '';\r\n const serializeStyles = (elemName, validStyleList) => {\r\n const styleList = validStyleList[elemName];\r\n if (styleList) {\r\n for (let i = 0, l = styleList.length; i < l; i++) {\r\n const name = styleList[i];\r\n const value = styles[name];\r\n if (value) {\r\n css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';';\r\n }\r\n }\r\n }\r\n };\r\n const isValid = (name, elemName) => {\r\n if (!invalidStyles || !elemName) {\r\n return true;\r\n }\r\n let styleMap = invalidStyles['*'];\r\n if (styleMap && styleMap[name]) {\r\n return false;\r\n }\r\n styleMap = invalidStyles[elemName];\r\n return !(styleMap && styleMap[name]);\r\n };\r\n if (elementName && validStyles) {\r\n serializeStyles('*', validStyles);\r\n serializeStyles(elementName, validStyles);\r\n } else {\r\n each$d(styles, (value, name) => {\r\n if (value && isValid(name, elementName)) {\r\n css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';';\r\n }\r\n });\r\n }\r\n return css;\r\n }\r\n };\r\n return self;\r\n };\r\n\r\n const deprecated = {\r\n keyLocation: true,\r\n layerX: true,\r\n layerY: true,\r\n returnValue: true,\r\n webkitMovementX: true,\r\n webkitMovementY: true,\r\n keyIdentifier: true,\r\n mozPressure: true\r\n };\r\n const isNativeEvent = event => event instanceof Event || isFunction(event.initEvent);\r\n const hasIsDefaultPrevented = event => event.isDefaultPrevented === always || event.isDefaultPrevented === never;\r\n const needsNormalizing = event => isNullable(event.preventDefault) || isNativeEvent(event);\r\n const clone$3 = (originalEvent, data) => {\r\n const event = data !== null && data !== void 0 ? data : {};\r\n for (const name in originalEvent) {\r\n if (!has$2(deprecated, name)) {\r\n event[name] = originalEvent[name];\r\n }\r\n }\r\n if (isNonNullable(originalEvent.composedPath)) {\r\n event.composedPath = () => originalEvent.composedPath();\r\n }\r\n return event;\r\n };\r\n const normalize$3 = (type, originalEvent, fallbackTarget, data) => {\r\n var _a;\r\n const event = clone$3(originalEvent, data);\r\n event.type = type;\r\n if (isNullable(event.target)) {\r\n event.target = (_a = event.srcElement) !== null && _a !== void 0 ? _a : fallbackTarget;\r\n }\r\n if (needsNormalizing(originalEvent)) {\r\n event.preventDefault = () => {\r\n event.defaultPrevented = true;\r\n event.isDefaultPrevented = always;\r\n if (isFunction(originalEvent.preventDefault)) {\r\n originalEvent.preventDefault();\r\n }\r\n };\r\n event.stopPropagation = () => {\r\n event.cancelBubble = true;\r\n event.isPropagationStopped = always;\r\n if (isFunction(originalEvent.stopPropagation)) {\r\n originalEvent.stopPropagation();\r\n }\r\n };\r\n event.stopImmediatePropagation = () => {\r\n event.isImmediatePropagationStopped = always;\r\n event.stopPropagation();\r\n };\r\n if (!hasIsDefaultPrevented(event)) {\r\n event.isDefaultPrevented = event.defaultPrevented === true ? always : never;\r\n event.isPropagationStopped = event.cancelBubble === true ? always : never;\r\n event.isImmediatePropagationStopped = never;\r\n }\r\n }\r\n return event;\r\n };\r\n\r\n const eventExpandoPrefix = 'mce-data-';\r\n const mouseEventRe = /^(?:mouse|contextmenu)|click/;\r\n const addEvent = (target, name, callback, capture) => {\r\n target.addEventListener(name, callback, capture || false);\r\n };\r\n const removeEvent = (target, name, callback, capture) => {\r\n target.removeEventListener(name, callback, capture || false);\r\n };\r\n const isMouseEvent = event => isNonNullable(event) && mouseEventRe.test(event.type);\r\n const fix = (originalEvent, data) => {\r\n const event = normalize$3(originalEvent.type, originalEvent, document, data);\r\n if (isMouseEvent(originalEvent) && isUndefined(originalEvent.pageX) && !isUndefined(originalEvent.clientX)) {\r\n const eventDoc = event.target.ownerDocument || document;\r\n const doc = eventDoc.documentElement;\r\n const body = eventDoc.body;\r\n const mouseEvent = event;\r\n mouseEvent.pageX = originalEvent.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);\r\n mouseEvent.pageY = originalEvent.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);\r\n }\r\n return event;\r\n };\r\n const bindOnReady = (win, callback, eventUtils) => {\r\n const doc = win.document, event = { type: 'ready' };\r\n if (eventUtils.domLoaded) {\r\n callback(event);\r\n return;\r\n }\r\n const isDocReady = () => {\r\n return doc.readyState === 'complete' || doc.readyState === 'interactive' && doc.body;\r\n };\r\n const readyHandler = () => {\r\n removeEvent(win, 'DOMContentLoaded', readyHandler);\r\n removeEvent(win, 'load', readyHandler);\r\n if (!eventUtils.domLoaded) {\r\n eventUtils.domLoaded = true;\r\n callback(event);\r\n }\r\n win = null;\r\n };\r\n if (isDocReady()) {\r\n readyHandler();\r\n } else {\r\n addEvent(win, 'DOMContentLoaded', readyHandler);\r\n }\r\n if (!eventUtils.domLoaded) {\r\n addEvent(win, 'load', readyHandler);\r\n }\r\n };\r\n class EventUtils {\r\n constructor() {\r\n this.domLoaded = false;\r\n this.events = {};\r\n this.count = 1;\r\n this.expando = eventExpandoPrefix + (+new Date()).toString(32);\r\n this.hasFocusIn = 'onfocusin' in document.documentElement;\r\n this.count = 1;\r\n }\r\n bind(target, names, callback, scope) {\r\n const self = this;\r\n let callbackList;\r\n const win = window;\r\n const defaultNativeHandler = evt => {\r\n self.executeHandlers(fix(evt || win.event), id);\r\n };\r\n if (!target || isText$a(target) || isComment(target)) {\r\n return callback;\r\n }\r\n let id;\r\n if (!target[self.expando]) {\r\n id = self.count++;\r\n target[self.expando] = id;\r\n self.events[id] = {};\r\n } else {\r\n id = target[self.expando];\r\n }\r\n scope = scope || target;\r\n const namesList = names.split(' ');\r\n let i = namesList.length;\r\n while (i--) {\r\n let name = namesList[i];\r\n let nativeHandler = defaultNativeHandler;\r\n let capture = false;\r\n let fakeName = false;\r\n if (name === 'DOMContentLoaded') {\r\n name = 'ready';\r\n }\r\n if (self.domLoaded && name === 'ready' && target.readyState === 'complete') {\r\n callback.call(scope, fix({ type: name }));\r\n continue;\r\n }\r\n if (!self.hasFocusIn && (name === 'focusin' || name === 'focusout')) {\r\n capture = true;\r\n fakeName = name === 'focusin' ? 'focus' : 'blur';\r\n nativeHandler = evt => {\r\n const event = fix(evt || win.event);\r\n event.type = event.type === 'focus' ? 'focusin' : 'focusout';\r\n self.executeHandlers(event, id);\r\n };\r\n }\r\n callbackList = self.events[id][name];\r\n if (!callbackList) {\r\n self.events[id][name] = callbackList = [{\r\n func: callback,\r\n scope\r\n }];\r\n callbackList.fakeName = fakeName;\r\n callbackList.capture = capture;\r\n callbackList.nativeHandler = nativeHandler;\r\n if (name === 'ready') {\r\n bindOnReady(target, nativeHandler, self);\r\n } else {\r\n addEvent(target, fakeName || name, nativeHandler, capture);\r\n }\r\n } else {\r\n if (name === 'ready' && self.domLoaded) {\r\n callback(fix({ type: name }));\r\n } else {\r\n callbackList.push({\r\n func: callback,\r\n scope\r\n });\r\n }\r\n }\r\n }\r\n target = callbackList = null;\r\n return callback;\r\n }\r\n unbind(target, names, callback) {\r\n if (!target || isText$a(target) || isComment(target)) {\r\n return this;\r\n }\r\n const id = target[this.expando];\r\n if (id) {\r\n let eventMap = this.events[id];\r\n if (names) {\r\n const namesList = names.split(' ');\r\n let i = namesList.length;\r\n while (i--) {\r\n const name = namesList[i];\r\n const callbackList = eventMap[name];\r\n if (callbackList) {\r\n if (callback) {\r\n let ci = callbackList.length;\r\n while (ci--) {\r\n if (callbackList[ci].func === callback) {\r\n const nativeHandler = callbackList.nativeHandler;\r\n const fakeName = callbackList.fakeName, capture = callbackList.capture;\r\n const newCallbackList = callbackList.slice(0, ci).concat(callbackList.slice(ci + 1));\r\n newCallbackList.nativeHandler = nativeHandler;\r\n newCallbackList.fakeName = fakeName;\r\n newCallbackList.capture = capture;\r\n eventMap[name] = newCallbackList;\r\n }\r\n }\r\n }\r\n if (!callback || callbackList.length === 0) {\r\n delete eventMap[name];\r\n removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture);\r\n }\r\n }\r\n }\r\n } else {\r\n each$d(eventMap, (callbackList, name) => {\r\n removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture);\r\n });\r\n eventMap = {};\r\n }\r\n for (const name in eventMap) {\r\n if (has$2(eventMap, name)) {\r\n return this;\r\n }\r\n }\r\n delete this.events[id];\r\n try {\r\n delete target[this.expando];\r\n } catch (ex) {\r\n target[this.expando] = null;\r\n }\r\n }\r\n return this;\r\n }\r\n fire(target, name, args) {\r\n return this.dispatch(target, name, args);\r\n }\r\n dispatch(target, name, args) {\r\n if (!target || isText$a(target) || isComment(target)) {\r\n return this;\r\n }\r\n const event = fix({\r\n type: name,\r\n target\r\n }, args);\r\n do {\r\n const id = target[this.expando];\r\n if (id) {\r\n this.executeHandlers(event, id);\r\n }\r\n target = target.parentNode || target.ownerDocument || target.defaultView || target.parentWindow;\r\n } while (target && !event.isPropagationStopped());\r\n return this;\r\n }\r\n clean(target) {\r\n if (!target || isText$a(target) || isComment(target)) {\r\n return this;\r\n }\r\n if (target[this.expando]) {\r\n this.unbind(target);\r\n }\r\n if (!target.getElementsByTagName) {\r\n target = target.document;\r\n }\r\n if (target && target.getElementsByTagName) {\r\n this.unbind(target);\r\n const children = target.getElementsByTagName('*');\r\n let i = children.length;\r\n while (i--) {\r\n target = children[i];\r\n if (target[this.expando]) {\r\n this.unbind(target);\r\n }\r\n }\r\n }\r\n return this;\r\n }\r\n destroy() {\r\n this.events = {};\r\n }\r\n cancel(e) {\r\n if (e) {\r\n e.preventDefault();\r\n e.stopImmediatePropagation();\r\n }\r\n return false;\r\n }\r\n executeHandlers(evt, id) {\r\n const container = this.events[id];\r\n const callbackList = container && container[evt.type];\r\n if (callbackList) {\r\n for (let i = 0, l = callbackList.length; i < l; i++) {\r\n const callback = callbackList[i];\r\n if (callback && callback.func.call(callback.scope, evt) === false) {\r\n evt.preventDefault();\r\n }\r\n if (evt.isImmediatePropagationStopped()) {\r\n return;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n EventUtils.Event = new EventUtils();\r\n\r\n const each$a = Tools.each;\r\n const grep = Tools.grep;\r\n const internalStyleName = 'data-mce-style';\r\n const numericalCssMap = Tools.makeMap('fill-opacity font-weight line-height opacity orphans widows z-index zoom', ' ');\r\n const legacySetAttribute = (elm, name, value) => {\r\n if (isNullable(value) || value === '') {\r\n remove$b(elm, name);\r\n } else {\r\n set$3(elm, name, value);\r\n }\r\n };\r\n const camelCaseToHyphens = name => name.replace(/[A-Z]/g, v => '-' + v.toLowerCase());\r\n const findNodeIndex = (node, normalized) => {\r\n let idx = 0;\r\n if (node) {\r\n for (let lastNodeType = node.nodeType, tempNode = node.previousSibling; tempNode; tempNode = tempNode.previousSibling) {\r\n const nodeType = tempNode.nodeType;\r\n if (normalized && isText$a(tempNode)) {\r\n if (nodeType === lastNodeType || !tempNode.data.length) {\r\n continue;\r\n }\r\n }\r\n idx++;\r\n lastNodeType = nodeType;\r\n }\r\n }\r\n return idx;\r\n };\r\n const updateInternalStyleAttr = (styles, elm) => {\r\n const rawValue = get$9(elm, 'style');\r\n const value = styles.serialize(styles.parse(rawValue), name(elm));\r\n legacySetAttribute(elm, internalStyleName, value);\r\n };\r\n const convertStyleToString = (cssValue, cssName) => {\r\n if (isNumber(cssValue)) {\r\n return has$2(numericalCssMap, cssName) ? cssValue + '' : cssValue + 'px';\r\n } else {\r\n return cssValue;\r\n }\r\n };\r\n const applyStyle$1 = ($elm, cssName, cssValue) => {\r\n const normalizedName = camelCaseToHyphens(cssName);\r\n if (isNullable(cssValue) || cssValue === '') {\r\n remove$7($elm, normalizedName);\r\n } else {\r\n set$2($elm, normalizedName, convertStyleToString(cssValue, normalizedName));\r\n }\r\n };\r\n const setupAttrHooks = (styles, settings, getContext) => {\r\n const keepValues = settings.keep_values;\r\n const keepUrlHook = {\r\n set: (elm, value, name) => {\r\n const sugarElm = SugarElement.fromDom(elm);\r\n if (isFunction(settings.url_converter) && isNonNullable(value)) {\r\n value = settings.url_converter.call(settings.url_converter_scope || getContext(), String(value), name, elm);\r\n }\r\n const internalName = 'data-mce-' + name;\r\n legacySetAttribute(sugarElm, internalName, value);\r\n legacySetAttribute(sugarElm, name, value);\r\n },\r\n get: (elm, name) => {\r\n const sugarElm = SugarElement.fromDom(elm);\r\n return get$9(sugarElm, 'data-mce-' + name) || get$9(sugarElm, name);\r\n }\r\n };\r\n const attrHooks = {\r\n style: {\r\n set: (elm, value) => {\r\n const sugarElm = SugarElement.fromDom(elm);\r\n if (keepValues) {\r\n legacySetAttribute(sugarElm, internalStyleName, value);\r\n }\r\n remove$b(sugarElm, 'style');\r\n if (isString(value)) {\r\n setAll(sugarElm, styles.parse(value));\r\n }\r\n },\r\n get: elm => {\r\n const sugarElm = SugarElement.fromDom(elm);\r\n const value = get$9(sugarElm, internalStyleName) || get$9(sugarElm, 'style');\r\n return styles.serialize(styles.parse(value), name(sugarElm));\r\n }\r\n }\r\n };\r\n if (keepValues) {\r\n attrHooks.href = attrHooks.src = keepUrlHook;\r\n }\r\n return attrHooks;\r\n };\r\n const DOMUtils = (doc, settings = {}) => {\r\n const addedStyles = {};\r\n const win = window;\r\n const files = {};\r\n let counter = 0;\r\n const stdMode = true;\r\n const boxModel = true;\r\n const styleSheetLoader = instance.forElement(SugarElement.fromDom(doc), {\r\n contentCssCors: settings.contentCssCors,\r\n referrerPolicy: settings.referrerPolicy\r\n });\r\n const boundEvents = [];\r\n const schema = settings.schema ? settings.schema : Schema({});\r\n const styles = Styles({\r\n url_converter: settings.url_converter,\r\n url_converter_scope: settings.url_converter_scope\r\n }, settings.schema);\r\n const events = settings.ownEvents ? new EventUtils() : EventUtils.Event;\r\n const blockElementsMap = schema.getBlockElements();\r\n const isBlock = node => {\r\n if (isString(node)) {\r\n return has$2(blockElementsMap, node);\r\n } else {\r\n return isElement$6(node) && (has$2(blockElementsMap, node.nodeName) || isTransparentBlock(schema, node));\r\n }\r\n };\r\n const get = elm => elm && doc && isString(elm) ? doc.getElementById(elm) : elm;\r\n const _get = elm => {\r\n const value = get(elm);\r\n return isNonNullable(value) ? SugarElement.fromDom(value) : null;\r\n };\r\n const getAttrib = (elm, name, defaultVal = '') => {\r\n let value;\r\n const $elm = _get(elm);\r\n if (isNonNullable($elm) && isElement$7($elm)) {\r\n const hook = attrHooks[name];\r\n if (hook && hook.get) {\r\n value = hook.get($elm.dom, name);\r\n } else {\r\n value = get$9($elm, name);\r\n }\r\n }\r\n return isNonNullable(value) ? value : defaultVal;\r\n };\r\n const getAttribs = elm => {\r\n const node = get(elm);\r\n return isNullable(node) ? [] : node.attributes;\r\n };\r\n const setAttrib = (elm, name, value) => {\r\n run(elm, e => {\r\n if (isElement$6(e)) {\r\n const $elm = SugarElement.fromDom(e);\r\n const val = value === '' ? null : value;\r\n const originalValue = get$9($elm, name);\r\n const hook = attrHooks[name];\r\n if (hook && hook.set) {\r\n hook.set($elm.dom, val, name);\r\n } else {\r\n legacySetAttribute($elm, name, val);\r\n }\r\n if (originalValue !== val && settings.onSetAttrib) {\r\n settings.onSetAttrib({\r\n attrElm: $elm.dom,\r\n attrName: name,\r\n attrValue: val\r\n });\r\n }\r\n }\r\n });\r\n };\r\n const clone = (node, deep) => {\r\n return node.cloneNode(deep);\r\n };\r\n const getRoot = () => settings.root_element || doc.body;\r\n const getViewPort = argWin => {\r\n const vp = getBounds(argWin);\r\n return {\r\n x: vp.x,\r\n y: vp.y,\r\n w: vp.width,\r\n h: vp.height\r\n };\r\n };\r\n const getPos$1 = (elm, rootElm) => getPos(doc.body, get(elm), rootElm);\r\n const setStyle = (elm, name, value) => {\r\n run(elm, e => {\r\n const $elm = SugarElement.fromDom(e);\r\n applyStyle$1($elm, name, value);\r\n if (settings.update_styles) {\r\n updateInternalStyleAttr(styles, $elm);\r\n }\r\n });\r\n };\r\n const setStyles = (elm, stylesArg) => {\r\n run(elm, e => {\r\n const $elm = SugarElement.fromDom(e);\r\n each$d(stylesArg, (v, n) => {\r\n applyStyle$1($elm, n, v);\r\n });\r\n if (settings.update_styles) {\r\n updateInternalStyleAttr(styles, $elm);\r\n }\r\n });\r\n };\r\n const getStyle = (elm, name, computed) => {\r\n const $elm = get(elm);\r\n if (isNullable($elm) || !isElement$6($elm)) {\r\n return undefined;\r\n }\r\n if (computed) {\r\n return get$7(SugarElement.fromDom($elm), camelCaseToHyphens(name));\r\n } else {\r\n name = name.replace(/-(\\D)/g, (a, b) => b.toUpperCase());\r\n if (name === 'float') {\r\n name = 'cssFloat';\r\n }\r\n return $elm.style ? $elm.style[name] : undefined;\r\n }\r\n };\r\n const getSize = elm => {\r\n const $elm = get(elm);\r\n if (!$elm) {\r\n return {\r\n w: 0,\r\n h: 0\r\n };\r\n }\r\n let w = getStyle($elm, 'width');\r\n let h = getStyle($elm, 'height');\r\n if (!w || w.indexOf('px') === -1) {\r\n w = '0';\r\n }\r\n if (!h || h.indexOf('px') === -1) {\r\n h = '0';\r\n }\r\n return {\r\n w: parseInt(w, 10) || $elm.offsetWidth || $elm.clientWidth,\r\n h: parseInt(h, 10) || $elm.offsetHeight || $elm.clientHeight\r\n };\r\n };\r\n const getRect = elm => {\r\n const $elm = get(elm);\r\n const pos = getPos$1($elm);\r\n const size = getSize($elm);\r\n return {\r\n x: pos.x,\r\n y: pos.y,\r\n w: size.w,\r\n h: size.h\r\n };\r\n };\r\n const is = (elm, selector) => {\r\n if (!elm) {\r\n return false;\r\n }\r\n const elms = isArray$1(elm) ? elm : [elm];\r\n return exists(elms, e => {\r\n return is$1(SugarElement.fromDom(e), selector);\r\n });\r\n };\r\n const getParents = (elm, selector, root, collect) => {\r\n const result = [];\r\n let node = get(elm);\r\n collect = collect === undefined;\r\n const resolvedRoot = root || (getRoot().nodeName !== 'BODY' ? getRoot().parentNode : null);\r\n if (isString(selector)) {\r\n if (selector === '*') {\r\n selector = isElement$6;\r\n } else {\r\n const selectorVal = selector;\r\n selector = node => is(node, selectorVal);\r\n }\r\n }\r\n while (node) {\r\n if (node === resolvedRoot || isNullable(node.nodeType) || isDocument$1(node) || isDocumentFragment(node)) {\r\n break;\r\n }\r\n if (!selector || selector(node)) {\r\n if (collect) {\r\n result.push(node);\r\n } else {\r\n return [node];\r\n }\r\n }\r\n node = node.parentNode;\r\n }\r\n return collect ? result : null;\r\n };\r\n const getParent = (node, selector, root) => {\r\n const parents = getParents(node, selector, root, false);\r\n return parents && parents.length > 0 ? parents[0] : null;\r\n };\r\n const _findSib = (node, selector, name) => {\r\n let func = selector;\r\n if (node) {\r\n if (isString(selector)) {\r\n func = node => {\r\n return is(node, selector);\r\n };\r\n }\r\n for (let tempNode = node[name]; tempNode; tempNode = tempNode[name]) {\r\n if (isFunction(func) && func(tempNode)) {\r\n return tempNode;\r\n }\r\n }\r\n }\r\n return null;\r\n };\r\n const getNext = (node, selector) => _findSib(node, selector, 'nextSibling');\r\n const getPrev = (node, selector) => _findSib(node, selector, 'previousSibling');\r\n const isParentNode = node => isFunction(node.querySelectorAll);\r\n const select = (selector, scope) => {\r\n var _a, _b;\r\n const elm = (_b = (_a = get(scope)) !== null && _a !== void 0 ? _a : settings.root_element) !== null && _b !== void 0 ? _b : doc;\r\n return isParentNode(elm) ? from(elm.querySelectorAll(selector)) : [];\r\n };\r\n const run = function (elm, func, scope) {\r\n const context = scope !== null && scope !== void 0 ? scope : this;\r\n if (isArray$1(elm)) {\r\n const result = [];\r\n each$a(elm, (e, i) => {\r\n const node = get(e);\r\n if (node) {\r\n result.push(func.call(context, node, i));\r\n }\r\n });\r\n return result;\r\n } else {\r\n const node = get(elm);\r\n return !node ? false : func.call(context, node);\r\n }\r\n };\r\n const setAttribs = (elm, attrs) => {\r\n run(elm, $elm => {\r\n each$d(attrs, (value, name) => {\r\n setAttrib($elm, name, value);\r\n });\r\n });\r\n };\r\n const setHTML = (elm, html) => {\r\n run(elm, e => {\r\n const $elm = SugarElement.fromDom(e);\r\n set$1($elm, html);\r\n });\r\n };\r\n const add = (parentElm, name, attrs, html, create) => run(parentElm, parentElm => {\r\n const newElm = isString(name) ? doc.createElement(name) : name;\r\n if (isNonNullable(attrs)) {\r\n setAttribs(newElm, attrs);\r\n }\r\n if (html) {\r\n if (!isString(html) && html.nodeType) {\r\n newElm.appendChild(html);\r\n } else if (isString(html)) {\r\n setHTML(newElm, html);\r\n }\r\n }\r\n return !create ? parentElm.appendChild(newElm) : newElm;\r\n });\r\n const create = (name, attrs, html) => add(doc.createElement(name), name, attrs, html, true);\r\n const decode = Entities.decode;\r\n const encode = Entities.encodeAllRaw;\r\n const createHTML = (name, attrs, html = '') => {\r\n let outHtml = '<' + name;\r\n for (const key in attrs) {\r\n if (hasNonNullableKey(attrs, key)) {\r\n outHtml += ' ' + key + '=\"' + encode(attrs[key]) + '\"';\r\n }\r\n }\r\n if (isEmpty$3(html) && has$2(schema.getVoidElements(), name)) {\r\n return outHtml + ' />';\r\n } else {\r\n return outHtml + '>' + html + '';\r\n }\r\n };\r\n const createFragment = html => {\r\n const container = doc.createElement('div');\r\n const frag = doc.createDocumentFragment();\r\n frag.appendChild(container);\r\n if (html) {\r\n container.innerHTML = html;\r\n }\r\n let node;\r\n while (node = container.firstChild) {\r\n frag.appendChild(node);\r\n }\r\n frag.removeChild(container);\r\n return frag;\r\n };\r\n const remove = (node, keepChildren) => {\r\n return run(node, n => {\r\n const $node = SugarElement.fromDom(n);\r\n if (keepChildren) {\r\n each$e(children$1($node), child => {\r\n if (isText$b(child) && child.dom.length === 0) {\r\n remove$6(child);\r\n } else {\r\n before$3($node, child);\r\n }\r\n });\r\n }\r\n remove$6($node);\r\n return $node.dom;\r\n });\r\n };\r\n const removeAllAttribs = e => run(e, e => {\r\n const attrs = e.attributes;\r\n for (let i = attrs.length - 1; i >= 0; i--) {\r\n e.removeAttributeNode(attrs.item(i));\r\n }\r\n });\r\n const parseStyle = cssText => styles.parse(cssText);\r\n const serializeStyle = (stylesArg, name) => styles.serialize(stylesArg, name);\r\n const addStyle = cssText => {\r\n if (self !== DOMUtils.DOM && doc === document) {\r\n if (addedStyles[cssText]) {\r\n return;\r\n }\r\n addedStyles[cssText] = true;\r\n }\r\n let styleElm = doc.getElementById('mceDefaultStyles');\r\n if (!styleElm) {\r\n styleElm = doc.createElement('style');\r\n styleElm.id = 'mceDefaultStyles';\r\n styleElm.type = 'text/css';\r\n const head = doc.head;\r\n if (head.firstChild) {\r\n head.insertBefore(styleElm, head.firstChild);\r\n } else {\r\n head.appendChild(styleElm);\r\n }\r\n }\r\n if (styleElm.styleSheet) {\r\n styleElm.styleSheet.cssText += cssText;\r\n } else {\r\n styleElm.appendChild(doc.createTextNode(cssText));\r\n }\r\n };\r\n const loadCSS = urls => {\r\n if (!urls) {\r\n urls = '';\r\n }\r\n each$e(urls.split(','), url => {\r\n files[url] = true;\r\n styleSheetLoader.load(url).catch(noop);\r\n });\r\n };\r\n const toggleClass = (elm, cls, state) => {\r\n run(elm, e => {\r\n if (isElement$6(e)) {\r\n const $elm = SugarElement.fromDom(e);\r\n const classes = cls.split(' ');\r\n each$e(classes, c => {\r\n if (isNonNullable(state)) {\r\n const fn = state ? add$2 : remove$8;\r\n fn($elm, c);\r\n } else {\r\n toggle$1($elm, c);\r\n }\r\n });\r\n }\r\n });\r\n };\r\n const addClass = (elm, cls) => {\r\n toggleClass(elm, cls, true);\r\n };\r\n const removeClass = (elm, cls) => {\r\n toggleClass(elm, cls, false);\r\n };\r\n const hasClass = (elm, cls) => {\r\n const $elm = _get(elm);\r\n const classes = cls.split(' ');\r\n return isNonNullable($elm) && forall(classes, c => has($elm, c));\r\n };\r\n const show = elm => {\r\n run(elm, e => remove$7(SugarElement.fromDom(e), 'display'));\r\n };\r\n const hide = elm => {\r\n run(elm, e => set$2(SugarElement.fromDom(e), 'display', 'none'));\r\n };\r\n const isHidden = elm => {\r\n const $elm = _get(elm);\r\n return isNonNullable($elm) && is$2(getRaw($elm, 'display'), 'none');\r\n };\r\n const uniqueId = prefix => (!prefix ? 'mce_' : prefix) + counter++;\r\n const getOuterHTML = elm => {\r\n const $elm = _get(elm);\r\n if (isNonNullable($elm)) {\r\n return isElement$6($elm.dom) ? $elm.dom.outerHTML : getOuter($elm);\r\n } else {\r\n return '';\r\n }\r\n };\r\n const setOuterHTML = (elm, html) => {\r\n run(elm, $elm => {\r\n if (isElement$6($elm)) {\r\n $elm.outerHTML = html;\r\n }\r\n });\r\n };\r\n const insertAfter = (node, reference) => {\r\n const referenceNode = get(reference);\r\n return run(node, node => {\r\n const parent = referenceNode === null || referenceNode === void 0 ? void 0 : referenceNode.parentNode;\r\n const nextSibling = referenceNode === null || referenceNode === void 0 ? void 0 : referenceNode.nextSibling;\r\n if (parent) {\r\n if (nextSibling) {\r\n parent.insertBefore(node, nextSibling);\r\n } else {\r\n parent.appendChild(node);\r\n }\r\n }\r\n return node;\r\n });\r\n };\r\n const replace = (newElm, oldElm, keepChildren) => run(oldElm, elm => {\r\n var _a;\r\n const replacee = isArray$1(oldElm) ? newElm.cloneNode(true) : newElm;\r\n if (keepChildren) {\r\n each$a(grep(elm.childNodes), node => {\r\n replacee.appendChild(node);\r\n });\r\n }\r\n (_a = elm.parentNode) === null || _a === void 0 ? void 0 : _a.replaceChild(replacee, elm);\r\n return elm;\r\n });\r\n const rename = (elm, name) => {\r\n if (elm.nodeName !== name.toUpperCase()) {\r\n const newElm = create(name);\r\n each$a(getAttribs(elm), attrNode => {\r\n setAttrib(newElm, attrNode.nodeName, getAttrib(elm, attrNode.nodeName));\r\n });\r\n replace(newElm, elm, true);\r\n return newElm;\r\n } else {\r\n return elm;\r\n }\r\n };\r\n const findCommonAncestor = (a, b) => {\r\n let ps = a;\r\n while (ps) {\r\n let pe = b;\r\n while (pe && ps !== pe) {\r\n pe = pe.parentNode;\r\n }\r\n if (ps === pe) {\r\n break;\r\n }\r\n ps = ps.parentNode;\r\n }\r\n if (!ps && a.ownerDocument) {\r\n return a.ownerDocument.documentElement;\r\n } else {\r\n return ps;\r\n }\r\n };\r\n const isNonEmptyElement = node => {\r\n if (isElement$6(node)) {\r\n const isNamedAnchor = node.nodeName.toLowerCase() === 'a' && !getAttrib(node, 'href') && getAttrib(node, 'id');\r\n if (getAttrib(node, 'name') || getAttrib(node, 'data-mce-bookmark') || isNamedAnchor) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n };\r\n const isEmpty = (node, elements) => {\r\n let brCount = 0;\r\n if (isNonEmptyElement(node)) {\r\n return false;\r\n }\r\n const firstChild = node.firstChild;\r\n if (firstChild) {\r\n const walker = new DomTreeWalker(firstChild, node);\r\n const whitespaceElements = schema ? schema.getWhitespaceElements() : {};\r\n const nonEmptyElements = elements || (schema ? schema.getNonEmptyElements() : null);\r\n let tempNode = firstChild;\r\n do {\r\n if (isElement$6(tempNode)) {\r\n const bogusVal = tempNode.getAttribute('data-mce-bogus');\r\n if (bogusVal) {\r\n tempNode = walker.next(bogusVal === 'all');\r\n continue;\r\n }\r\n const name = tempNode.nodeName.toLowerCase();\r\n if (nonEmptyElements && nonEmptyElements[name]) {\r\n if (name === 'br') {\r\n brCount++;\r\n tempNode = walker.next();\r\n continue;\r\n }\r\n return false;\r\n }\r\n if (isNonEmptyElement(tempNode)) {\r\n return false;\r\n }\r\n }\r\n if (isComment(tempNode)) {\r\n return false;\r\n }\r\n if (isText$a(tempNode) && !isWhitespaceText(tempNode.data)) {\r\n return false;\r\n }\r\n if (isText$a(tempNode) && tempNode.parentNode && whitespaceElements[tempNode.parentNode.nodeName] && isWhitespaceText(tempNode.data)) {\r\n return false;\r\n }\r\n tempNode = walker.next();\r\n } while (tempNode);\r\n }\r\n return brCount <= 1;\r\n };\r\n const createRng = () => doc.createRange();\r\n const split = (parentElm, splitElm, replacementElm) => {\r\n let range = createRng();\r\n let beforeFragment;\r\n let afterFragment;\r\n if (parentElm && splitElm && parentElm.parentNode && splitElm.parentNode) {\r\n const parentNode = parentElm.parentNode;\r\n range.setStart(parentNode, findNodeIndex(parentElm));\r\n range.setEnd(splitElm.parentNode, findNodeIndex(splitElm));\r\n beforeFragment = range.extractContents();\r\n range = createRng();\r\n range.setStart(splitElm.parentNode, findNodeIndex(splitElm) + 1);\r\n range.setEnd(parentNode, findNodeIndex(parentElm) + 1);\r\n afterFragment = range.extractContents();\r\n parentNode.insertBefore(trimNode(self, beforeFragment), parentElm);\r\n if (replacementElm) {\r\n parentNode.insertBefore(replacementElm, parentElm);\r\n } else {\r\n parentNode.insertBefore(splitElm, parentElm);\r\n }\r\n parentNode.insertBefore(trimNode(self, afterFragment), parentElm);\r\n remove(parentElm);\r\n return replacementElm || splitElm;\r\n } else {\r\n return undefined;\r\n }\r\n };\r\n const bind = (target, name, func, scope) => {\r\n if (isArray$1(target)) {\r\n let i = target.length;\r\n const rv = [];\r\n while (i--) {\r\n rv[i] = bind(target[i], name, func, scope);\r\n }\r\n return rv;\r\n } else {\r\n if (settings.collect && (target === doc || target === win)) {\r\n boundEvents.push([\r\n target,\r\n name,\r\n func,\r\n scope\r\n ]);\r\n }\r\n return events.bind(target, name, func, scope || self);\r\n }\r\n };\r\n const unbind = (target, name, func) => {\r\n if (isArray$1(target)) {\r\n let i = target.length;\r\n const rv = [];\r\n while (i--) {\r\n rv[i] = unbind(target[i], name, func);\r\n }\r\n return rv;\r\n } else {\r\n if (boundEvents.length > 0 && (target === doc || target === win)) {\r\n let i = boundEvents.length;\r\n while (i--) {\r\n const [boundTarget, boundName, boundFunc] = boundEvents[i];\r\n if (target === boundTarget && (!name || name === boundName) && (!func || func === boundFunc)) {\r\n events.unbind(boundTarget, boundName, boundFunc);\r\n }\r\n }\r\n }\r\n return events.unbind(target, name, func);\r\n }\r\n };\r\n const dispatch = (target, name, evt) => events.dispatch(target, name, evt);\r\n const fire = (target, name, evt) => events.dispatch(target, name, evt);\r\n const getContentEditable = node => {\r\n if (node && isElement$6(node)) {\r\n const contentEditable = node.getAttribute('data-mce-contenteditable');\r\n if (contentEditable && contentEditable !== 'inherit') {\r\n return contentEditable;\r\n }\r\n return node.contentEditable !== 'inherit' ? node.contentEditable : null;\r\n } else {\r\n return null;\r\n }\r\n };\r\n const getContentEditableParent = node => {\r\n const root = getRoot();\r\n let state = null;\r\n for (let tempNode = node; tempNode && tempNode !== root; tempNode = tempNode.parentNode) {\r\n state = getContentEditable(tempNode);\r\n if (state !== null) {\r\n break;\r\n }\r\n }\r\n return state;\r\n };\r\n const isEditable = node => {\r\n if (isNonNullable(node)) {\r\n const scope = isElement$6(node) ? node : node.parentElement;\r\n const isRootEditable = getContentEditable(getRoot()) === 'true';\r\n return isNonNullable(scope) && isEditable$3(SugarElement.fromDom(scope), isRootEditable);\r\n } else {\r\n return false;\r\n }\r\n };\r\n const destroy = () => {\r\n if (boundEvents.length > 0) {\r\n let i = boundEvents.length;\r\n while (i--) {\r\n const [boundTarget, boundName, boundFunc] = boundEvents[i];\r\n events.unbind(boundTarget, boundName, boundFunc);\r\n }\r\n }\r\n each$d(files, (_, url) => {\r\n styleSheetLoader.unload(url);\r\n delete files[url];\r\n });\r\n };\r\n const isChildOf = (node, parent) => {\r\n return node === parent || parent.contains(node);\r\n };\r\n const dumpRng = r => 'startContainer: ' + r.startContainer.nodeName + ', startOffset: ' + r.startOffset + ', endContainer: ' + r.endContainer.nodeName + ', endOffset: ' + r.endOffset;\r\n const self = {\r\n doc,\r\n settings,\r\n win,\r\n files,\r\n stdMode,\r\n boxModel,\r\n styleSheetLoader,\r\n boundEvents,\r\n styles,\r\n schema,\r\n events,\r\n isBlock: isBlock,\r\n root: null,\r\n clone,\r\n getRoot,\r\n getViewPort,\r\n getRect,\r\n getSize,\r\n getParent,\r\n getParents: getParents,\r\n get,\r\n getNext,\r\n getPrev,\r\n select,\r\n is,\r\n add,\r\n create,\r\n createHTML,\r\n createFragment,\r\n remove,\r\n setStyle,\r\n getStyle: getStyle,\r\n setStyles,\r\n removeAllAttribs,\r\n setAttrib,\r\n setAttribs,\r\n getAttrib,\r\n getPos: getPos$1,\r\n parseStyle,\r\n serializeStyle,\r\n addStyle,\r\n loadCSS,\r\n addClass,\r\n removeClass,\r\n hasClass,\r\n toggleClass,\r\n show,\r\n hide,\r\n isHidden,\r\n uniqueId,\r\n setHTML,\r\n getOuterHTML,\r\n setOuterHTML,\r\n decode,\r\n encode,\r\n insertAfter,\r\n replace,\r\n rename,\r\n findCommonAncestor,\r\n run,\r\n getAttribs,\r\n isEmpty,\r\n createRng,\r\n nodeIndex: findNodeIndex,\r\n split,\r\n bind: bind,\r\n unbind: unbind,\r\n fire,\r\n dispatch,\r\n getContentEditable,\r\n getContentEditableParent,\r\n isEditable,\r\n destroy,\r\n isChildOf,\r\n dumpRng\r\n };\r\n const attrHooks = setupAttrHooks(styles, settings, constant(self));\r\n return self;\r\n };\r\n DOMUtils.DOM = DOMUtils(document);\r\n DOMUtils.nodeIndex = findNodeIndex;\r\n\r\n const DOM$b = DOMUtils.DOM;\r\n const QUEUED = 0;\r\n const LOADING = 1;\r\n const LOADED = 2;\r\n const FAILED = 3;\r\n class ScriptLoader {\r\n constructor(settings = {}) {\r\n this.states = {};\r\n this.queue = [];\r\n this.scriptLoadedCallbacks = {};\r\n this.queueLoadedCallbacks = [];\r\n this.loading = false;\r\n this.settings = settings;\r\n }\r\n _setReferrerPolicy(referrerPolicy) {\r\n this.settings.referrerPolicy = referrerPolicy;\r\n }\r\n loadScript(url) {\r\n return new Promise((resolve, reject) => {\r\n const dom = DOM$b;\r\n let elm;\r\n const cleanup = () => {\r\n dom.remove(id);\r\n if (elm) {\r\n elm.onerror = elm.onload = elm = null;\r\n }\r\n };\r\n const done = () => {\r\n cleanup();\r\n resolve();\r\n };\r\n const error = () => {\r\n cleanup();\r\n reject('Failed to load script: ' + url);\r\n };\r\n const id = dom.uniqueId();\r\n elm = document.createElement('script');\r\n elm.id = id;\r\n elm.type = 'text/javascript';\r\n elm.src = Tools._addCacheSuffix(url);\r\n if (this.settings.referrerPolicy) {\r\n dom.setAttrib(elm, 'referrerpolicy', this.settings.referrerPolicy);\r\n }\r\n elm.onload = done;\r\n elm.onerror = error;\r\n (document.getElementsByTagName('head')[0] || document.body).appendChild(elm);\r\n });\r\n }\r\n isDone(url) {\r\n return this.states[url] === LOADED;\r\n }\r\n markDone(url) {\r\n this.states[url] = LOADED;\r\n }\r\n add(url) {\r\n const self = this;\r\n self.queue.push(url);\r\n const state = self.states[url];\r\n if (state === undefined) {\r\n self.states[url] = QUEUED;\r\n }\r\n return new Promise((resolve, reject) => {\r\n if (!self.scriptLoadedCallbacks[url]) {\r\n self.scriptLoadedCallbacks[url] = [];\r\n }\r\n self.scriptLoadedCallbacks[url].push({\r\n resolve,\r\n reject\r\n });\r\n });\r\n }\r\n load(url) {\r\n return this.add(url);\r\n }\r\n remove(url) {\r\n delete this.states[url];\r\n delete this.scriptLoadedCallbacks[url];\r\n }\r\n loadQueue() {\r\n const queue = this.queue;\r\n this.queue = [];\r\n return this.loadScripts(queue);\r\n }\r\n loadScripts(scripts) {\r\n const self = this;\r\n const execCallbacks = (name, url) => {\r\n get$a(self.scriptLoadedCallbacks, url).each(callbacks => {\r\n each$e(callbacks, callback => callback[name](url));\r\n });\r\n delete self.scriptLoadedCallbacks[url];\r\n };\r\n const processResults = results => {\r\n const failures = filter$5(results, result => result.status === 'rejected');\r\n if (failures.length > 0) {\r\n return Promise.reject(bind$3(failures, ({reason}) => isArray$1(reason) ? reason : [reason]));\r\n } else {\r\n return Promise.resolve();\r\n }\r\n };\r\n const load = urls => Promise.allSettled(map$3(urls, url => {\r\n if (self.states[url] === LOADED) {\r\n execCallbacks('resolve', url);\r\n return Promise.resolve();\r\n } else if (self.states[url] === FAILED) {\r\n execCallbacks('reject', url);\r\n return Promise.reject(url);\r\n } else {\r\n self.states[url] = LOADING;\r\n return self.loadScript(url).then(() => {\r\n self.states[url] = LOADED;\r\n execCallbacks('resolve', url);\r\n const queue = self.queue;\r\n if (queue.length > 0) {\r\n self.queue = [];\r\n return load(queue).then(processResults);\r\n } else {\r\n return Promise.resolve();\r\n }\r\n }, () => {\r\n self.states[url] = FAILED;\r\n execCallbacks('reject', url);\r\n return Promise.reject(url);\r\n });\r\n }\r\n }));\r\n const processQueue = urls => {\r\n self.loading = true;\r\n return load(urls).then(results => {\r\n self.loading = false;\r\n const nextQueuedItem = self.queueLoadedCallbacks.shift();\r\n Optional.from(nextQueuedItem).each(call);\r\n return processResults(results);\r\n });\r\n };\r\n const uniqueScripts = stringArray(scripts);\r\n if (self.loading) {\r\n return new Promise((resolve, reject) => {\r\n self.queueLoadedCallbacks.push(() => processQueue(uniqueScripts).then(resolve, reject));\r\n });\r\n } else {\r\n return processQueue(uniqueScripts);\r\n }\r\n }\r\n }\r\n ScriptLoader.ScriptLoader = new ScriptLoader();\r\n\r\n const Cell = initial => {\r\n let value = initial;\r\n const get = () => {\r\n return value;\r\n };\r\n const set = v => {\r\n value = v;\r\n };\r\n return {\r\n get,\r\n set\r\n };\r\n };\r\n\r\n const isRaw = str => isObject(str) && has$2(str, 'raw');\r\n const isTokenised = str => isArray$1(str) && str.length > 1;\r\n const data = {};\r\n const currentCode = Cell('en');\r\n const getLanguageData = () => get$a(data, currentCode.get());\r\n const getData$1 = () => map$2(data, value => ({ ...value }));\r\n const setCode = newCode => {\r\n if (newCode) {\r\n currentCode.set(newCode);\r\n }\r\n };\r\n const getCode = () => currentCode.get();\r\n const add$1 = (code, items) => {\r\n let langData = data[code];\r\n if (!langData) {\r\n data[code] = langData = {};\r\n }\r\n each$d(items, (translation, name) => {\r\n langData[name.toLowerCase()] = translation;\r\n });\r\n };\r\n const translate = text => {\r\n const langData = getLanguageData().getOr({});\r\n const toString = obj => {\r\n if (isFunction(obj)) {\r\n return Object.prototype.toString.call(obj);\r\n }\r\n return !isEmpty(obj) ? '' + obj : '';\r\n };\r\n const isEmpty = text => text === '' || text === null || text === undefined;\r\n const getLangData = text => {\r\n const textstr = toString(text);\r\n return get$a(langData, textstr.toLowerCase()).map(toString).getOr(textstr);\r\n };\r\n const removeContext = str => str.replace(/{context:\\w+}$/, '');\r\n if (isEmpty(text)) {\r\n return '';\r\n }\r\n if (isRaw(text)) {\r\n return toString(text.raw);\r\n }\r\n if (isTokenised(text)) {\r\n const values = text.slice(1);\r\n const substitued = getLangData(text[0]).replace(/\\{([0-9]+)\\}/g, ($1, $2) => has$2(values, $2) ? toString(values[$2]) : $1);\r\n return removeContext(substitued);\r\n }\r\n return removeContext(getLangData(text));\r\n };\r\n const isRtl$1 = () => getLanguageData().bind(items => get$a(items, '_dir')).exists(dir => dir === 'rtl');\r\n const hasCode = code => has$2(data, code);\r\n const I18n = {\r\n getData: getData$1,\r\n setCode,\r\n getCode,\r\n add: add$1,\r\n translate,\r\n isRtl: isRtl$1,\r\n hasCode\r\n };\r\n\r\n const AddOnManager = () => {\r\n const items = [];\r\n const urls = {};\r\n const lookup = {};\r\n const _listeners = [];\r\n const runListeners = (name, state) => {\r\n const matchedListeners = filter$5(_listeners, listener => listener.name === name && listener.state === state);\r\n each$e(matchedListeners, listener => listener.resolve());\r\n };\r\n const isLoaded = name => has$2(urls, name);\r\n const isAdded = name => has$2(lookup, name);\r\n const get = name => {\r\n if (lookup[name]) {\r\n return lookup[name].instance;\r\n }\r\n return undefined;\r\n };\r\n const loadLanguagePack = (name, languages) => {\r\n const language = I18n.getCode();\r\n const wrappedLanguages = ',' + (languages || '') + ',';\r\n if (!language || languages && wrappedLanguages.indexOf(',' + language + ',') === -1) {\r\n return;\r\n }\r\n ScriptLoader.ScriptLoader.add(urls[name] + '/langs/' + language + '.js');\r\n };\r\n const requireLangPack = (name, languages) => {\r\n if (AddOnManager.languageLoad !== false) {\r\n if (isLoaded(name)) {\r\n loadLanguagePack(name, languages);\r\n } else {\r\n waitFor(name, 'loaded').then(() => loadLanguagePack(name, languages));\r\n }\r\n }\r\n };\r\n const add = (id, addOn) => {\r\n items.push(addOn);\r\n lookup[id] = { instance: addOn };\r\n runListeners(id, 'added');\r\n return addOn;\r\n };\r\n const remove = name => {\r\n delete urls[name];\r\n delete lookup[name];\r\n };\r\n const createUrl = (baseUrl, dep) => {\r\n if (isString(dep)) {\r\n return isString(baseUrl) ? {\r\n prefix: '',\r\n resource: dep,\r\n suffix: ''\r\n } : {\r\n prefix: baseUrl.prefix,\r\n resource: dep,\r\n suffix: baseUrl.suffix\r\n };\r\n } else {\r\n return dep;\r\n }\r\n };\r\n const load = (name, addOnUrl) => {\r\n if (urls[name]) {\r\n return Promise.resolve();\r\n }\r\n let urlString = isString(addOnUrl) ? addOnUrl : addOnUrl.prefix + addOnUrl.resource + addOnUrl.suffix;\r\n if (urlString.indexOf('/') !== 0 && urlString.indexOf('://') === -1) {\r\n urlString = AddOnManager.baseURL + '/' + urlString;\r\n }\r\n urls[name] = urlString.substring(0, urlString.lastIndexOf('/'));\r\n const done = () => {\r\n runListeners(name, 'loaded');\r\n return Promise.resolve();\r\n };\r\n if (lookup[name]) {\r\n return done();\r\n } else {\r\n return ScriptLoader.ScriptLoader.add(urlString).then(done);\r\n }\r\n };\r\n const waitFor = (name, state = 'added') => {\r\n if (state === 'added' && isAdded(name)) {\r\n return Promise.resolve();\r\n } else if (state === 'loaded' && isLoaded(name)) {\r\n return Promise.resolve();\r\n } else {\r\n return new Promise(resolve => {\r\n _listeners.push({\r\n name,\r\n state,\r\n resolve\r\n });\r\n });\r\n }\r\n };\r\n return {\r\n items,\r\n urls,\r\n lookup,\r\n get,\r\n requireLangPack,\r\n add,\r\n remove,\r\n createUrl,\r\n load,\r\n waitFor\r\n };\r\n };\r\n AddOnManager.languageLoad = true;\r\n AddOnManager.baseURL = '';\r\n AddOnManager.PluginManager = AddOnManager();\r\n AddOnManager.ThemeManager = AddOnManager();\r\n AddOnManager.ModelManager = AddOnManager();\r\n\r\n const singleton = doRevoke => {\r\n const subject = Cell(Optional.none());\r\n const revoke = () => subject.get().each(doRevoke);\r\n const clear = () => {\r\n revoke();\r\n subject.set(Optional.none());\r\n };\r\n const isSet = () => subject.get().isSome();\r\n const get = () => subject.get();\r\n const set = s => {\r\n revoke();\r\n subject.set(Optional.some(s));\r\n };\r\n return {\r\n clear,\r\n isSet,\r\n get,\r\n set\r\n };\r\n };\r\n const repeatable = delay => {\r\n const intervalId = Cell(Optional.none());\r\n const revoke = () => intervalId.get().each(id => clearInterval(id));\r\n const clear = () => {\r\n revoke();\r\n intervalId.set(Optional.none());\r\n };\r\n const isSet = () => intervalId.get().isSome();\r\n const get = () => intervalId.get();\r\n const set = functionToRepeat => {\r\n revoke();\r\n intervalId.set(Optional.some(setInterval(functionToRepeat, delay)));\r\n };\r\n return {\r\n clear,\r\n isSet,\r\n get,\r\n set\r\n };\r\n };\r\n const value$2 = () => {\r\n const subject = singleton(noop);\r\n const on = f => subject.get().each(f);\r\n return {\r\n ...subject,\r\n on\r\n };\r\n };\r\n\r\n const first$1 = (fn, rate) => {\r\n let timer = null;\r\n const cancel = () => {\r\n if (!isNull(timer)) {\r\n clearTimeout(timer);\r\n timer = null;\r\n }\r\n };\r\n const throttle = (...args) => {\r\n if (isNull(timer)) {\r\n timer = setTimeout(() => {\r\n timer = null;\r\n fn.apply(null, args);\r\n }, rate);\r\n }\r\n };\r\n return {\r\n cancel,\r\n throttle\r\n };\r\n };\r\n const last$1 = (fn, rate) => {\r\n let timer = null;\r\n const cancel = () => {\r\n if (!isNull(timer)) {\r\n clearTimeout(timer);\r\n timer = null;\r\n }\r\n };\r\n const throttle = (...args) => {\r\n cancel();\r\n timer = setTimeout(() => {\r\n timer = null;\r\n fn.apply(null, args);\r\n }, rate);\r\n };\r\n return {\r\n cancel,\r\n throttle\r\n };\r\n };\r\n\r\n const annotation = constant('mce-annotation');\r\n const dataAnnotation = constant('data-mce-annotation');\r\n const dataAnnotationId = constant('data-mce-annotation-uid');\r\n const dataAnnotationActive = constant('data-mce-annotation-active');\r\n const dataAnnotationClasses = constant('data-mce-annotation-classes');\r\n const dataAnnotationAttributes = constant('data-mce-annotation-attrs');\r\n\r\n const isRoot$1 = root => node => eq(node, root);\r\n const identify = (editor, annotationName) => {\r\n const rng = editor.selection.getRng();\r\n const start = SugarElement.fromDom(rng.startContainer);\r\n const root = SugarElement.fromDom(editor.getBody());\r\n const selector = annotationName.fold(() => '.' + annotation(), an => `[${ dataAnnotation() }=\"${ an }\"]`);\r\n const newStart = child$1(start, rng.startOffset).getOr(start);\r\n const closest = closest$3(newStart, selector, isRoot$1(root));\r\n return closest.bind(c => getOpt(c, `${ dataAnnotationId() }`).bind(uid => getOpt(c, `${ dataAnnotation() }`).map(name => {\r\n const elements = findMarkers(editor, uid);\r\n return {\r\n uid,\r\n name,\r\n elements\r\n };\r\n })));\r\n };\r\n const isAnnotation = elem => isElement$7(elem) && has(elem, annotation());\r\n const isBogusElement = (elem, root) => has$1(elem, 'data-mce-bogus') || ancestor$2(elem, '[data-mce-bogus=\"all\"]', isRoot$1(root));\r\n const findMarkers = (editor, uid) => {\r\n const body = SugarElement.fromDom(editor.getBody());\r\n const descendants$1 = descendants(body, `[${ dataAnnotationId() }=\"${ uid }\"]`);\r\n return filter$5(descendants$1, descendant => !isBogusElement(descendant, body));\r\n };\r\n const findAll = (editor, name) => {\r\n const body = SugarElement.fromDom(editor.getBody());\r\n const markers = descendants(body, `[${ dataAnnotation() }=\"${ name }\"]`);\r\n const directory = {};\r\n each$e(markers, m => {\r\n if (!isBogusElement(m, body)) {\r\n const uid = get$9(m, dataAnnotationId());\r\n const nodesAlready = get$a(directory, uid).getOr([]);\r\n directory[uid] = nodesAlready.concat([m]);\r\n }\r\n });\r\n return directory;\r\n };\r\n\r\n const setup$x = (editor, registry) => {\r\n const changeCallbacks = Cell({});\r\n const initData = () => ({\r\n listeners: [],\r\n previous: value$2()\r\n });\r\n const withCallbacks = (name, f) => {\r\n updateCallbacks(name, data => {\r\n f(data);\r\n return data;\r\n });\r\n };\r\n const updateCallbacks = (name, f) => {\r\n const callbackMap = changeCallbacks.get();\r\n const data = get$a(callbackMap, name).getOrThunk(initData);\r\n const outputData = f(data);\r\n callbackMap[name] = outputData;\r\n changeCallbacks.set(callbackMap);\r\n };\r\n const fireCallbacks = (name, uid, elements) => {\r\n withCallbacks(name, data => {\r\n each$e(data.listeners, f => f(true, name, {\r\n uid,\r\n nodes: map$3(elements, elem => elem.dom)\r\n }));\r\n });\r\n };\r\n const fireNoAnnotation = name => {\r\n withCallbacks(name, data => {\r\n each$e(data.listeners, f => f(false, name));\r\n });\r\n };\r\n const toggleActiveAttr = (uid, state) => {\r\n each$e(findMarkers(editor, uid), elem => {\r\n if (state) {\r\n set$3(elem, dataAnnotationActive(), 'true');\r\n } else {\r\n remove$b(elem, dataAnnotationActive());\r\n }\r\n });\r\n };\r\n const onNodeChange = last$1(() => {\r\n const annotations = sort(registry.getNames());\r\n each$e(annotations, name => {\r\n updateCallbacks(name, data => {\r\n const prev = data.previous.get();\r\n identify(editor, Optional.some(name)).fold(() => {\r\n prev.each(uid => {\r\n fireNoAnnotation(name);\r\n data.previous.clear();\r\n toggleActiveAttr(uid, false);\r\n });\r\n }, ({uid, name, elements}) => {\r\n if (!is$2(prev, uid)) {\r\n prev.each(uid => toggleActiveAttr(uid, false));\r\n fireCallbacks(name, uid, elements);\r\n data.previous.set(uid);\r\n toggleActiveAttr(uid, true);\r\n }\r\n });\r\n return {\r\n previous: data.previous,\r\n listeners: data.listeners\r\n };\r\n });\r\n });\r\n }, 30);\r\n editor.on('remove', () => {\r\n onNodeChange.cancel();\r\n });\r\n editor.on('NodeChange', () => {\r\n onNodeChange.throttle();\r\n });\r\n const addListener = (name, f) => {\r\n updateCallbacks(name, data => ({\r\n previous: data.previous,\r\n listeners: data.listeners.concat([f])\r\n }));\r\n };\r\n return { addListener };\r\n };\r\n\r\n const setup$w = (editor, registry) => {\r\n const dataAnnotation$1 = dataAnnotation();\r\n const identifyParserNode = node => Optional.from(node.attr(dataAnnotation$1)).bind(registry.lookup);\r\n const removeDirectAnnotation = node => {\r\n var _a, _b;\r\n node.attr(dataAnnotationId(), null);\r\n node.attr(dataAnnotation(), null);\r\n node.attr(dataAnnotationActive(), null);\r\n const customAttrNames = Optional.from(node.attr(dataAnnotationAttributes())).map(names => names.split(',')).getOr([]);\r\n const customClasses = Optional.from(node.attr(dataAnnotationClasses())).map(names => names.split(',')).getOr([]);\r\n each$e(customAttrNames, name => node.attr(name, null));\r\n const classList = (_b = (_a = node.attr('class')) === null || _a === void 0 ? void 0 : _a.split(' ')) !== null && _b !== void 0 ? _b : [];\r\n const newClassList = difference(classList, [annotation()].concat(customClasses));\r\n node.attr('class', newClassList.length > 0 ? newClassList.join(' ') : null);\r\n node.attr(dataAnnotationClasses(), null);\r\n node.attr(dataAnnotationAttributes(), null);\r\n };\r\n editor.serializer.addTempAttr(dataAnnotationActive());\r\n editor.serializer.addAttributeFilter(dataAnnotation$1, nodes => {\r\n for (const node of nodes) {\r\n identifyParserNode(node).each(settings => {\r\n if (settings.persistent === false) {\r\n if (node.name === 'span') {\r\n node.unwrap();\r\n } else {\r\n removeDirectAnnotation(node);\r\n }\r\n }\r\n });\r\n }\r\n });\r\n };\r\n\r\n const create$c = () => {\r\n const annotations = {};\r\n const register = (name, settings) => {\r\n annotations[name] = {\r\n name,\r\n settings\r\n };\r\n };\r\n const lookup = name => get$a(annotations, name).map(a => a.settings);\r\n const getNames = () => keys(annotations);\r\n return {\r\n register,\r\n lookup,\r\n getNames\r\n };\r\n };\r\n\r\n let unique = 0;\r\n const generate$1 = prefix => {\r\n const date = new Date();\r\n const time = date.getTime();\r\n const random = Math.floor(Math.random() * 1000000000);\r\n unique++;\r\n return prefix + '_' + random + unique + String(time);\r\n };\r\n\r\n const add = (element, classes) => {\r\n each$e(classes, x => {\r\n add$2(element, x);\r\n });\r\n };\r\n const remove$5 = (element, classes) => {\r\n each$e(classes, x => {\r\n remove$8(element, x);\r\n });\r\n };\r\n\r\n const clone$2 = (original, isDeep) => SugarElement.fromDom(original.dom.cloneNode(isDeep));\r\n const shallow$1 = original => clone$2(original, false);\r\n const deep$1 = original => clone$2(original, true);\r\n const shallowAs = (original, tag) => {\r\n const nu = SugarElement.fromTag(tag);\r\n const attributes = clone$4(original);\r\n setAll$1(nu, attributes);\r\n return nu;\r\n };\r\n const mutate = (original, tag) => {\r\n const nu = shallowAs(original, tag);\r\n after$4(original, nu);\r\n const children = children$1(original);\r\n append(nu, children);\r\n remove$6(original);\r\n return nu;\r\n };\r\n\r\n const TextWalker = (startNode, rootNode, isBoundary = never) => {\r\n const walker = new DomTreeWalker(startNode, rootNode);\r\n const walk = direction => {\r\n let next;\r\n do {\r\n next = walker[direction]();\r\n } while (next && !isText$a(next) && !isBoundary(next));\r\n return Optional.from(next).filter(isText$a);\r\n };\r\n return {\r\n current: () => Optional.from(walker.current()).filter(isText$a),\r\n next: () => walk('next'),\r\n prev: () => walk('prev'),\r\n prev2: () => walk('prev2')\r\n };\r\n };\r\n\r\n const TextSeeker = (dom, isBoundary) => {\r\n const isBlockBoundary = isBoundary ? isBoundary : node => dom.isBlock(node) || isBr$6(node) || isContentEditableFalse$b(node);\r\n const walk = (node, offset, walker, process) => {\r\n if (isText$a(node)) {\r\n const newOffset = process(node, offset, node.data);\r\n if (newOffset !== -1) {\r\n return Optional.some({\r\n container: node,\r\n offset: newOffset\r\n });\r\n }\r\n }\r\n return walker().bind(next => walk(next.container, next.offset, walker, process));\r\n };\r\n const backwards = (node, offset, process, root) => {\r\n const walker = TextWalker(node, root !== null && root !== void 0 ? root : dom.getRoot(), isBlockBoundary);\r\n return walk(node, offset, () => walker.prev().map(prev => ({\r\n container: prev,\r\n offset: prev.length\r\n })), process).getOrNull();\r\n };\r\n const forwards = (node, offset, process, root) => {\r\n const walker = TextWalker(node, root !== null && root !== void 0 ? root : dom.getRoot(), isBlockBoundary);\r\n return walk(node, offset, () => walker.next().map(next => ({\r\n container: next,\r\n offset: 0\r\n })), process).getOrNull();\r\n };\r\n return {\r\n backwards,\r\n forwards\r\n };\r\n };\r\n\r\n const round$2 = Math.round;\r\n const clone$1 = rect => {\r\n if (!rect) {\r\n return {\r\n left: 0,\r\n top: 0,\r\n bottom: 0,\r\n right: 0,\r\n width: 0,\r\n height: 0\r\n };\r\n }\r\n return {\r\n left: round$2(rect.left),\r\n top: round$2(rect.top),\r\n bottom: round$2(rect.bottom),\r\n right: round$2(rect.right),\r\n width: round$2(rect.width),\r\n height: round$2(rect.height)\r\n };\r\n };\r\n const collapse = (rect, toStart) => {\r\n rect = clone$1(rect);\r\n if (toStart) {\r\n rect.right = rect.left;\r\n } else {\r\n rect.left = rect.left + rect.width;\r\n rect.right = rect.left;\r\n }\r\n rect.width = 0;\r\n return rect;\r\n };\r\n const isEqual = (rect1, rect2) => rect1.left === rect2.left && rect1.top === rect2.top && rect1.bottom === rect2.bottom && rect1.right === rect2.right;\r\n const isValidOverflow = (overflowY, rect1, rect2) => overflowY >= 0 && overflowY <= Math.min(rect1.height, rect2.height) / 2;\r\n const isAbove$1 = (rect1, rect2) => {\r\n const halfHeight = Math.min(rect2.height / 2, rect1.height / 2);\r\n if (rect1.bottom - halfHeight < rect2.top) {\r\n return true;\r\n }\r\n if (rect1.top > rect2.bottom) {\r\n return false;\r\n }\r\n return isValidOverflow(rect2.top - rect1.bottom, rect1, rect2);\r\n };\r\n const isBelow$1 = (rect1, rect2) => {\r\n if (rect1.top > rect2.bottom) {\r\n return true;\r\n }\r\n if (rect1.bottom < rect2.top) {\r\n return false;\r\n }\r\n return isValidOverflow(rect2.bottom - rect1.top, rect1, rect2);\r\n };\r\n const containsXY = (rect, clientX, clientY) => clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;\r\n const boundingClientRectFromRects = rects => {\r\n return foldl(rects, (acc, rect) => {\r\n return acc.fold(() => Optional.some(rect), prevRect => {\r\n const left = Math.min(rect.left, prevRect.left);\r\n const top = Math.min(rect.top, prevRect.top);\r\n const right = Math.max(rect.right, prevRect.right);\r\n const bottom = Math.max(rect.bottom, prevRect.bottom);\r\n return Optional.some({\r\n top,\r\n right,\r\n bottom,\r\n left,\r\n width: right - left,\r\n height: bottom - top\r\n });\r\n });\r\n }, Optional.none());\r\n };\r\n const distanceToRectEdgeFromXY = (rect, x, y) => {\r\n const cx = Math.max(Math.min(x, rect.left + rect.width), rect.left);\r\n const cy = Math.max(Math.min(y, rect.top + rect.height), rect.top);\r\n return Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy));\r\n };\r\n const overlapY = (r1, r2) => Math.max(0, Math.min(r1.bottom, r2.bottom) - Math.max(r1.top, r2.top));\r\n\r\n const clamp$2 = (value, min, max) => Math.min(Math.max(value, min), max);\r\n\r\n const getSelectedNode = range => {\r\n const startContainer = range.startContainer, startOffset = range.startOffset;\r\n if (startContainer === range.endContainer && startContainer.hasChildNodes() && range.endOffset === startOffset + 1) {\r\n return startContainer.childNodes[startOffset];\r\n }\r\n return null;\r\n };\r\n const getNode$1 = (container, offset) => {\r\n if (isElement$6(container) && container.hasChildNodes()) {\r\n const childNodes = container.childNodes;\r\n const safeOffset = clamp$2(offset, 0, childNodes.length - 1);\r\n return childNodes[safeOffset];\r\n } else {\r\n return container;\r\n }\r\n };\r\n const getNodeUnsafe = (container, offset) => {\r\n if (offset < 0 && isElement$6(container) && container.hasChildNodes()) {\r\n return undefined;\r\n } else {\r\n return getNode$1(container, offset);\r\n }\r\n };\r\n\r\n const extendingChars = new RegExp('[\\u0300-\\u036f\\u0483-\\u0487\\u0488-\\u0489\\u0591-\\u05bd\\u05bf\\u05c1-\\u05c2\\u05c4-\\u05c5\\u05c7\\u0610-\\u061a' + '\\u064b-\\u065f\\u0670\\u06d6-\\u06dc\\u06df-\\u06e4\\u06e7-\\u06e8\\u06ea-\\u06ed\\u0711\\u0730-\\u074a\\u07a6-\\u07b0' + '\\u07eb-\\u07f3\\u0816-\\u0819\\u081b-\\u0823\\u0825-\\u0827\\u0829-\\u082d\\u0859-\\u085b\\u08e3-\\u0902\\u093a\\u093c' + '\\u0941-\\u0948\\u094d\\u0951-\\u0957\\u0962-\\u0963\\u0981\\u09bc\\u09be\\u09c1-\\u09c4\\u09cd\\u09d7\\u09e2-\\u09e3' + '\\u0a01-\\u0a02\\u0a3c\\u0a41-\\u0a42\\u0a47-\\u0a48\\u0a4b-\\u0a4d\\u0a51\\u0a70-\\u0a71\\u0a75\\u0a81-\\u0a82\\u0abc' + '\\u0ac1-\\u0ac5\\u0ac7-\\u0ac8\\u0acd\\u0ae2-\\u0ae3\\u0b01\\u0b3c\\u0b3e\\u0b3f\\u0b41-\\u0b44\\u0b4d\\u0b56\\u0b57' + '\\u0b62-\\u0b63\\u0b82\\u0bbe\\u0bc0\\u0bcd\\u0bd7\\u0c00\\u0c3e-\\u0c40\\u0c46-\\u0c48\\u0c4a-\\u0c4d\\u0c55-\\u0c56' + '\\u0c62-\\u0c63\\u0c81\\u0cbc\\u0cbf\\u0cc2\\u0cc6\\u0ccc-\\u0ccd\\u0cd5-\\u0cd6\\u0ce2-\\u0ce3\\u0d01\\u0d3e\\u0d41-\\u0d44' + '\\u0d4d\\u0d57\\u0d62-\\u0d63\\u0dca\\u0dcf\\u0dd2-\\u0dd4\\u0dd6\\u0ddf\\u0e31\\u0e34-\\u0e3a\\u0e47-\\u0e4e\\u0eb1\\u0eb4-\\u0eb9' + '\\u0ebb-\\u0ebc\\u0ec8-\\u0ecd\\u0f18-\\u0f19\\u0f35\\u0f37\\u0f39\\u0f71-\\u0f7e\\u0f80-\\u0f84\\u0f86-\\u0f87\\u0f8d-\\u0f97' + '\\u0f99-\\u0fbc\\u0fc6\\u102d-\\u1030\\u1032-\\u1037\\u1039-\\u103a\\u103d-\\u103e\\u1058-\\u1059\\u105e-\\u1060\\u1071-\\u1074' + '\\u1082\\u1085-\\u1086\\u108d\\u109d\\u135d-\\u135f\\u1712-\\u1714\\u1732-\\u1734\\u1752-\\u1753\\u1772-\\u1773\\u17b4-\\u17b5' + '\\u17b7-\\u17bd\\u17c6\\u17c9-\\u17d3\\u17dd\\u180b-\\u180d\\u18a9\\u1920-\\u1922\\u1927-\\u1928\\u1932\\u1939-\\u193b\\u1a17-\\u1a18' + '\\u1a1b\\u1a56\\u1a58-\\u1a5e\\u1a60\\u1a62\\u1a65-\\u1a6c\\u1a73-\\u1a7c\\u1a7f\\u1ab0-\\u1abd\\u1ABE\\u1b00-\\u1b03\\u1b34' + '\\u1b36-\\u1b3a\\u1b3c\\u1b42\\u1b6b-\\u1b73\\u1b80-\\u1b81\\u1ba2-\\u1ba5\\u1ba8-\\u1ba9\\u1bab-\\u1bad\\u1be6\\u1be8-\\u1be9' + '\\u1bed\\u1bef-\\u1bf1\\u1c2c-\\u1c33\\u1c36-\\u1c37\\u1cd0-\\u1cd2\\u1cd4-\\u1ce0\\u1ce2-\\u1ce8\\u1ced\\u1cf4\\u1cf8-\\u1cf9' + '\\u1dc0-\\u1df5\\u1dfc-\\u1dff\\u200c-\\u200d\\u20d0-\\u20dc\\u20DD-\\u20E0\\u20e1\\u20E2-\\u20E4\\u20e5-\\u20f0\\u2cef-\\u2cf1' + '\\u2d7f\\u2de0-\\u2dff\\u302a-\\u302d\\u302e-\\u302f\\u3099-\\u309a\\ua66f\\uA670-\\uA672\\ua674-\\ua67d\\ua69e-\\ua69f\\ua6f0-\\ua6f1' + '\\ua802\\ua806\\ua80b\\ua825-\\ua826\\ua8c4\\ua8e0-\\ua8f1\\ua926-\\ua92d\\ua947-\\ua951\\ua980-\\ua982\\ua9b3\\ua9b6-\\ua9b9\\ua9bc' + '\\ua9e5\\uaa29-\\uaa2e\\uaa31-\\uaa32\\uaa35-\\uaa36\\uaa43\\uaa4c\\uaa7c\\uaab0\\uaab2-\\uaab4\\uaab7-\\uaab8\\uaabe-\\uaabf\\uaac1' + '\\uaaec-\\uaaed\\uaaf6\\uabe5\\uabe8\\uabed\\ufb1e\\ufe00-\\ufe0f\\ufe20-\\ufe2f\\uff9e-\\uff9f]');\r\n const isExtendingChar = ch => isString(ch) && ch.charCodeAt(0) >= 768 && extendingChars.test(ch);\r\n\r\n const or = (...args) => {\r\n return x => {\r\n for (let i = 0; i < args.length; i++) {\r\n if (args[i](x)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n };\r\n };\r\n const and = (...args) => {\r\n return x => {\r\n for (let i = 0; i < args.length; i++) {\r\n if (!args[i](x)) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n };\r\n };\r\n\r\n const isElement$4 = isElement$6;\r\n const isCaretCandidate$2 = isCaretCandidate$3;\r\n const isBlock$1 = matchStyleValues('display', 'block table');\r\n const isFloated = matchStyleValues('float', 'left right');\r\n const isValidElementCaretCandidate = and(isElement$4, isCaretCandidate$2, not(isFloated));\r\n const isNotPre = not(matchStyleValues('white-space', 'pre pre-line pre-wrap'));\r\n const isText$7 = isText$a;\r\n const isBr$3 = isBr$6;\r\n const nodeIndex$1 = DOMUtils.nodeIndex;\r\n const resolveIndex$1 = getNodeUnsafe;\r\n const createRange$1 = doc => doc ? doc.createRange() : DOMUtils.DOM.createRng();\r\n const isWhiteSpace$1 = chr => isString(chr) && /[\\r\\n\\t ]/.test(chr);\r\n const isRange = rng => !!rng.setStart && !!rng.setEnd;\r\n const isHiddenWhiteSpaceRange = range => {\r\n const container = range.startContainer;\r\n const offset = range.startOffset;\r\n if (isWhiteSpace$1(range.toString()) && isNotPre(container.parentNode) && isText$a(container)) {\r\n const text = container.data;\r\n if (isWhiteSpace$1(text[offset - 1]) || isWhiteSpace$1(text[offset + 1])) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n };\r\n const getBrClientRect = brNode => {\r\n const doc = brNode.ownerDocument;\r\n const rng = createRange$1(doc);\r\n const nbsp$1 = doc.createTextNode(nbsp);\r\n const parentNode = brNode.parentNode;\r\n parentNode.insertBefore(nbsp$1, brNode);\r\n rng.setStart(nbsp$1, 0);\r\n rng.setEnd(nbsp$1, 1);\r\n const clientRect = clone$1(rng.getBoundingClientRect());\r\n parentNode.removeChild(nbsp$1);\r\n return clientRect;\r\n };\r\n const getBoundingClientRectWebKitText = rng => {\r\n const sc = rng.startContainer;\r\n const ec = rng.endContainer;\r\n const so = rng.startOffset;\r\n const eo = rng.endOffset;\r\n if (sc === ec && isText$a(ec) && so === 0 && eo === 1) {\r\n const newRng = rng.cloneRange();\r\n newRng.setEndAfter(ec);\r\n return getBoundingClientRect$1(newRng);\r\n } else {\r\n return null;\r\n }\r\n };\r\n const isZeroRect = r => r.left === 0 && r.right === 0 && r.top === 0 && r.bottom === 0;\r\n const getBoundingClientRect$1 = item => {\r\n var _a;\r\n let clientRect;\r\n const clientRects = item.getClientRects();\r\n if (clientRects.length > 0) {\r\n clientRect = clone$1(clientRects[0]);\r\n } else {\r\n clientRect = clone$1(item.getBoundingClientRect());\r\n }\r\n if (!isRange(item) && isBr$3(item) && isZeroRect(clientRect)) {\r\n return getBrClientRect(item);\r\n }\r\n if (isZeroRect(clientRect) && isRange(item)) {\r\n return (_a = getBoundingClientRectWebKitText(item)) !== null && _a !== void 0 ? _a : clientRect;\r\n }\r\n return clientRect;\r\n };\r\n const collapseAndInflateWidth = (clientRect, toStart) => {\r\n const newClientRect = collapse(clientRect, toStart);\r\n newClientRect.width = 1;\r\n newClientRect.right = newClientRect.left + 1;\r\n return newClientRect;\r\n };\r\n const getCaretPositionClientRects = caretPosition => {\r\n const clientRects = [];\r\n const addUniqueAndValidRect = clientRect => {\r\n if (clientRect.height === 0) {\r\n return;\r\n }\r\n if (clientRects.length > 0) {\r\n if (isEqual(clientRect, clientRects[clientRects.length - 1])) {\r\n return;\r\n }\r\n }\r\n clientRects.push(clientRect);\r\n };\r\n const addCharacterOffset = (container, offset) => {\r\n const range = createRange$1(container.ownerDocument);\r\n if (offset < container.data.length) {\r\n if (isExtendingChar(container.data[offset])) {\r\n return;\r\n }\r\n if (isExtendingChar(container.data[offset - 1])) {\r\n range.setStart(container, offset);\r\n range.setEnd(container, offset + 1);\r\n if (!isHiddenWhiteSpaceRange(range)) {\r\n addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect$1(range), false));\r\n return;\r\n }\r\n }\r\n }\r\n if (offset > 0) {\r\n range.setStart(container, offset - 1);\r\n range.setEnd(container, offset);\r\n if (!isHiddenWhiteSpaceRange(range)) {\r\n addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect$1(range), false));\r\n }\r\n }\r\n if (offset < container.data.length) {\r\n range.setStart(container, offset);\r\n range.setEnd(container, offset + 1);\r\n if (!isHiddenWhiteSpaceRange(range)) {\r\n addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect$1(range), true));\r\n }\r\n }\r\n };\r\n const container = caretPosition.container();\r\n const offset = caretPosition.offset();\r\n if (isText$7(container)) {\r\n addCharacterOffset(container, offset);\r\n return clientRects;\r\n }\r\n if (isElement$4(container)) {\r\n if (caretPosition.isAtEnd()) {\r\n const node = resolveIndex$1(container, offset);\r\n if (isText$7(node)) {\r\n addCharacterOffset(node, node.data.length);\r\n }\r\n if (isValidElementCaretCandidate(node) && !isBr$3(node)) {\r\n addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect$1(node), false));\r\n }\r\n } else {\r\n const node = resolveIndex$1(container, offset);\r\n if (isText$7(node)) {\r\n addCharacterOffset(node, 0);\r\n }\r\n if (isValidElementCaretCandidate(node) && caretPosition.isAtEnd()) {\r\n addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect$1(node), false));\r\n return clientRects;\r\n }\r\n const beforeNode = resolveIndex$1(caretPosition.container(), caretPosition.offset() - 1);\r\n if (isValidElementCaretCandidate(beforeNode) && !isBr$3(beforeNode)) {\r\n if (isBlock$1(beforeNode) || isBlock$1(node) || !isValidElementCaretCandidate(node)) {\r\n addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect$1(beforeNode), false));\r\n }\r\n }\r\n if (isValidElementCaretCandidate(node)) {\r\n addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect$1(node), true));\r\n }\r\n }\r\n }\r\n return clientRects;\r\n };\r\n const CaretPosition = (container, offset, clientRects) => {\r\n const isAtStart = () => {\r\n if (isText$7(container)) {\r\n return offset === 0;\r\n }\r\n return offset === 0;\r\n };\r\n const isAtEnd = () => {\r\n if (isText$7(container)) {\r\n return offset >= container.data.length;\r\n }\r\n return offset >= container.childNodes.length;\r\n };\r\n const toRange = () => {\r\n const range = createRange$1(container.ownerDocument);\r\n range.setStart(container, offset);\r\n range.setEnd(container, offset);\r\n return range;\r\n };\r\n const getClientRects = () => {\r\n if (!clientRects) {\r\n clientRects = getCaretPositionClientRects(CaretPosition(container, offset));\r\n }\r\n return clientRects;\r\n };\r\n const isVisible = () => getClientRects().length > 0;\r\n const isEqual = caretPosition => caretPosition && container === caretPosition.container() && offset === caretPosition.offset();\r\n const getNode = before => resolveIndex$1(container, before ? offset - 1 : offset);\r\n return {\r\n container: constant(container),\r\n offset: constant(offset),\r\n toRange,\r\n getClientRects,\r\n isVisible,\r\n isAtStart,\r\n isAtEnd,\r\n isEqual,\r\n getNode\r\n };\r\n };\r\n CaretPosition.fromRangeStart = range => CaretPosition(range.startContainer, range.startOffset);\r\n CaretPosition.fromRangeEnd = range => CaretPosition(range.endContainer, range.endOffset);\r\n CaretPosition.after = node => CaretPosition(node.parentNode, nodeIndex$1(node) + 1);\r\n CaretPosition.before = node => CaretPosition(node.parentNode, nodeIndex$1(node));\r\n CaretPosition.isAbove = (pos1, pos2) => lift2(head(pos2.getClientRects()), last$3(pos1.getClientRects()), isAbove$1).getOr(false);\r\n CaretPosition.isBelow = (pos1, pos2) => lift2(last$3(pos2.getClientRects()), head(pos1.getClientRects()), isBelow$1).getOr(false);\r\n CaretPosition.isAtStart = pos => pos ? pos.isAtStart() : false;\r\n CaretPosition.isAtEnd = pos => pos ? pos.isAtEnd() : false;\r\n CaretPosition.isTextPosition = pos => pos ? isText$a(pos.container()) : false;\r\n CaretPosition.isElementPosition = pos => !CaretPosition.isTextPosition(pos);\r\n\r\n const trimEmptyTextNode$1 = (dom, node) => {\r\n if (isText$a(node) && node.data.length === 0) {\r\n dom.remove(node);\r\n }\r\n };\r\n const insertNode = (dom, rng, node) => {\r\n rng.insertNode(node);\r\n trimEmptyTextNode$1(dom, node.previousSibling);\r\n trimEmptyTextNode$1(dom, node.nextSibling);\r\n };\r\n const insertFragment = (dom, rng, frag) => {\r\n const firstChild = Optional.from(frag.firstChild);\r\n const lastChild = Optional.from(frag.lastChild);\r\n rng.insertNode(frag);\r\n firstChild.each(child => trimEmptyTextNode$1(dom, child.previousSibling));\r\n lastChild.each(child => trimEmptyTextNode$1(dom, child.nextSibling));\r\n };\r\n const rangeInsertNode = (dom, rng, node) => {\r\n if (isDocumentFragment(node)) {\r\n insertFragment(dom, rng, node);\r\n } else {\r\n insertNode(dom, rng, node);\r\n }\r\n };\r\n\r\n const isText$6 = isText$a;\r\n const isBogus = isBogus$2;\r\n const nodeIndex = DOMUtils.nodeIndex;\r\n const normalizedParent = node => {\r\n const parentNode = node.parentNode;\r\n if (isBogus(parentNode)) {\r\n return normalizedParent(parentNode);\r\n }\r\n return parentNode;\r\n };\r\n const getChildNodes = node => {\r\n if (!node) {\r\n return [];\r\n }\r\n return reduce(node.childNodes, (result, node) => {\r\n if (isBogus(node) && node.nodeName !== 'BR') {\r\n result = result.concat(getChildNodes(node));\r\n } else {\r\n result.push(node);\r\n }\r\n return result;\r\n }, []);\r\n };\r\n const normalizedTextOffset = (node, offset) => {\r\n let tempNode = node;\r\n while (tempNode = tempNode.previousSibling) {\r\n if (!isText$6(tempNode)) {\r\n break;\r\n }\r\n offset += tempNode.data.length;\r\n }\r\n return offset;\r\n };\r\n const equal = a => b => a === b;\r\n const normalizedNodeIndex = node => {\r\n let nodes, index;\r\n nodes = getChildNodes(normalizedParent(node));\r\n index = findIndex$1(nodes, equal(node), node);\r\n nodes = nodes.slice(0, index + 1);\r\n const numTextFragments = reduce(nodes, (result, node, i) => {\r\n if (isText$6(node) && isText$6(nodes[i - 1])) {\r\n result++;\r\n }\r\n return result;\r\n }, 0);\r\n nodes = filter$3(nodes, matchNodeNames([node.nodeName]));\r\n index = findIndex$1(nodes, equal(node), node);\r\n return index - numTextFragments;\r\n };\r\n const createPathItem = node => {\r\n const name = isText$6(node) ? 'text()' : node.nodeName.toLowerCase();\r\n return name + '[' + normalizedNodeIndex(node) + ']';\r\n };\r\n const parentsUntil$1 = (root, node, predicate) => {\r\n const parents = [];\r\n for (let tempNode = node.parentNode; tempNode && tempNode !== root; tempNode = tempNode.parentNode) {\r\n if (predicate && predicate(tempNode)) {\r\n break;\r\n }\r\n parents.push(tempNode);\r\n }\r\n return parents;\r\n };\r\n const create$b = (root, caretPosition) => {\r\n let path = [];\r\n let container = caretPosition.container();\r\n let offset = caretPosition.offset();\r\n let outputOffset;\r\n if (isText$6(container)) {\r\n outputOffset = normalizedTextOffset(container, offset);\r\n } else {\r\n const childNodes = container.childNodes;\r\n if (offset >= childNodes.length) {\r\n outputOffset = 'after';\r\n offset = childNodes.length - 1;\r\n } else {\r\n outputOffset = 'before';\r\n }\r\n container = childNodes[offset];\r\n }\r\n path.push(createPathItem(container));\r\n let parents = parentsUntil$1(root, container);\r\n parents = filter$3(parents, not(isBogus$2));\r\n path = path.concat(map$1(parents, node => {\r\n return createPathItem(node);\r\n }));\r\n return path.reverse().join('/') + ',' + outputOffset;\r\n };\r\n const resolvePathItem = (node, name, index) => {\r\n let nodes = getChildNodes(node);\r\n nodes = filter$3(nodes, (node, index) => {\r\n return !isText$6(node) || !isText$6(nodes[index - 1]);\r\n });\r\n nodes = filter$3(nodes, matchNodeNames([name]));\r\n return nodes[index];\r\n };\r\n const findTextPosition = (container, offset) => {\r\n let node = container;\r\n let targetOffset = 0;\r\n while (isText$6(node)) {\r\n const dataLen = node.data.length;\r\n if (offset >= targetOffset && offset <= targetOffset + dataLen) {\r\n container = node;\r\n offset = offset - targetOffset;\r\n break;\r\n }\r\n if (!isText$6(node.nextSibling)) {\r\n container = node;\r\n offset = dataLen;\r\n break;\r\n }\r\n targetOffset += dataLen;\r\n node = node.nextSibling;\r\n }\r\n if (isText$6(container) && offset > container.data.length) {\r\n offset = container.data.length;\r\n }\r\n return CaretPosition(container, offset);\r\n };\r\n const resolve$1 = (root, path) => {\r\n if (!path) {\r\n return null;\r\n }\r\n const parts = path.split(',');\r\n const paths = parts[0].split('/');\r\n const offset = parts.length > 1 ? parts[1] : 'before';\r\n const container = reduce(paths, (result, value) => {\r\n const match = /([\\w\\-\\(\\)]+)\\[([0-9]+)\\]/.exec(value);\r\n if (!match) {\r\n return null;\r\n }\r\n if (match[1] === 'text()') {\r\n match[1] = '#text';\r\n }\r\n return resolvePathItem(result, match[1], parseInt(match[2], 10));\r\n }, root);\r\n if (!container) {\r\n return null;\r\n }\r\n if (!isText$6(container) && container.parentNode) {\r\n let nodeOffset;\r\n if (offset === 'after') {\r\n nodeOffset = nodeIndex(container) + 1;\r\n } else {\r\n nodeOffset = nodeIndex(container);\r\n }\r\n return CaretPosition(container.parentNode, nodeOffset);\r\n }\r\n return findTextPosition(container, parseInt(offset, 10));\r\n };\r\n\r\n const isContentEditableFalse$9 = isContentEditableFalse$b;\r\n const getNormalizedTextOffset$1 = (trim, container, offset) => {\r\n let trimmedOffset = trim(container.data.slice(0, offset)).length;\r\n for (let node = container.previousSibling; node && isText$a(node); node = node.previousSibling) {\r\n trimmedOffset += trim(node.data).length;\r\n }\r\n return trimmedOffset;\r\n };\r\n const getPoint = (dom, trim, normalized, rng, start) => {\r\n const container = start ? rng.startContainer : rng.endContainer;\r\n let offset = start ? rng.startOffset : rng.endOffset;\r\n const point = [];\r\n const root = dom.getRoot();\r\n if (isText$a(container)) {\r\n point.push(normalized ? getNormalizedTextOffset$1(trim, container, offset) : offset);\r\n } else {\r\n let after = 0;\r\n const childNodes = container.childNodes;\r\n if (offset >= childNodes.length && childNodes.length) {\r\n after = 1;\r\n offset = Math.max(0, childNodes.length - 1);\r\n }\r\n point.push(dom.nodeIndex(childNodes[offset], normalized) + after);\r\n }\r\n for (let node = container; node && node !== root; node = node.parentNode) {\r\n point.push(dom.nodeIndex(node, normalized));\r\n }\r\n return point;\r\n };\r\n const getLocation = (trim, selection, normalized, rng) => {\r\n const dom = selection.dom;\r\n const start = getPoint(dom, trim, normalized, rng, true);\r\n const forward = selection.isForward();\r\n const fakeCaret = isRangeInCaretContainerBlock(rng) ? { isFakeCaret: true } : {};\r\n if (!selection.isCollapsed()) {\r\n const end = getPoint(dom, trim, normalized, rng, false);\r\n return {\r\n start,\r\n end,\r\n forward,\r\n ...fakeCaret\r\n };\r\n } else {\r\n return {\r\n start,\r\n forward,\r\n ...fakeCaret\r\n };\r\n }\r\n };\r\n const findIndex = (dom, name, element) => {\r\n let count = 0;\r\n Tools.each(dom.select(name), node => {\r\n if (node.getAttribute('data-mce-bogus') === 'all') {\r\n return;\r\n } else if (node === element) {\r\n return false;\r\n } else {\r\n count++;\r\n return;\r\n }\r\n });\r\n return count;\r\n };\r\n const moveEndPoint$1 = (rng, start) => {\r\n let container = start ? rng.startContainer : rng.endContainer;\r\n let offset = start ? rng.startOffset : rng.endOffset;\r\n if (isElement$6(container) && container.nodeName === 'TR') {\r\n const childNodes = container.childNodes;\r\n container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)];\r\n if (container) {\r\n offset = start ? 0 : container.childNodes.length;\r\n if (start) {\r\n rng.setStart(container, offset);\r\n } else {\r\n rng.setEnd(container, offset);\r\n }\r\n }\r\n }\r\n };\r\n const normalizeTableCellSelection = rng => {\r\n moveEndPoint$1(rng, true);\r\n moveEndPoint$1(rng, false);\r\n return rng;\r\n };\r\n const findSibling = (node, offset) => {\r\n if (isElement$6(node)) {\r\n node = getNode$1(node, offset);\r\n if (isContentEditableFalse$9(node)) {\r\n return node;\r\n }\r\n }\r\n if (isCaretContainer$2(node)) {\r\n if (isText$a(node) && isCaretContainerBlock$1(node)) {\r\n node = node.parentNode;\r\n }\r\n let sibling = node.previousSibling;\r\n if (isContentEditableFalse$9(sibling)) {\r\n return sibling;\r\n }\r\n sibling = node.nextSibling;\r\n if (isContentEditableFalse$9(sibling)) {\r\n return sibling;\r\n }\r\n }\r\n return undefined;\r\n };\r\n const findAdjacentContentEditableFalseElm = rng => {\r\n return findSibling(rng.startContainer, rng.startOffset) || findSibling(rng.endContainer, rng.endOffset);\r\n };\r\n const getOffsetBookmark = (trim, normalized, selection) => {\r\n const element = selection.getNode();\r\n const rng = selection.getRng();\r\n if (element.nodeName === 'IMG' || isContentEditableFalse$9(element)) {\r\n const name = element.nodeName;\r\n return {\r\n name,\r\n index: findIndex(selection.dom, name, element)\r\n };\r\n }\r\n const sibling = findAdjacentContentEditableFalseElm(rng);\r\n if (sibling) {\r\n const name = sibling.tagName;\r\n return {\r\n name,\r\n index: findIndex(selection.dom, name, sibling)\r\n };\r\n }\r\n return getLocation(trim, selection, normalized, rng);\r\n };\r\n const getCaretBookmark = selection => {\r\n const rng = selection.getRng();\r\n return {\r\n start: create$b(selection.dom.getRoot(), CaretPosition.fromRangeStart(rng)),\r\n end: create$b(selection.dom.getRoot(), CaretPosition.fromRangeEnd(rng)),\r\n forward: selection.isForward()\r\n };\r\n };\r\n const getRangeBookmark = selection => {\r\n return {\r\n rng: selection.getRng(),\r\n forward: selection.isForward()\r\n };\r\n };\r\n const createBookmarkSpan = (dom, id, filled) => {\r\n const args = {\r\n 'data-mce-type': 'bookmark',\r\n id,\r\n 'style': 'overflow:hidden;line-height:0px'\r\n };\r\n return filled ? dom.create('span', args, '') : dom.create('span', args);\r\n };\r\n const getPersistentBookmark = (selection, filled) => {\r\n const dom = selection.dom;\r\n let rng = selection.getRng();\r\n const id = dom.uniqueId();\r\n const collapsed = selection.isCollapsed();\r\n const element = selection.getNode();\r\n const name = element.nodeName;\r\n const forward = selection.isForward();\r\n if (name === 'IMG') {\r\n return {\r\n name,\r\n index: findIndex(dom, name, element)\r\n };\r\n }\r\n const rng2 = normalizeTableCellSelection(rng.cloneRange());\r\n if (!collapsed) {\r\n rng2.collapse(false);\r\n const endBookmarkNode = createBookmarkSpan(dom, id + '_end', filled);\r\n rangeInsertNode(dom, rng2, endBookmarkNode);\r\n }\r\n rng = normalizeTableCellSelection(rng);\r\n rng.collapse(true);\r\n const startBookmarkNode = createBookmarkSpan(dom, id + '_start', filled);\r\n rangeInsertNode(dom, rng, startBookmarkNode);\r\n selection.moveToBookmark({\r\n id,\r\n keep: true,\r\n forward\r\n });\r\n return {\r\n id,\r\n forward\r\n };\r\n };\r\n const getBookmark$2 = (selection, type, normalized = false) => {\r\n if (type === 2) {\r\n return getOffsetBookmark(trim$1, normalized, selection);\r\n } else if (type === 3) {\r\n return getCaretBookmark(selection);\r\n } else if (type) {\r\n return getRangeBookmark(selection);\r\n } else {\r\n return getPersistentBookmark(selection, false);\r\n }\r\n };\r\n const getUndoBookmark = curry(getOffsetBookmark, identity, true);\r\n\r\n const value$1 = value => {\r\n const applyHelper = fn => fn(value);\r\n const constHelper = constant(value);\r\n const outputHelper = () => output;\r\n const output = {\r\n tag: true,\r\n inner: value,\r\n fold: (_onError, onValue) => onValue(value),\r\n isValue: always,\r\n isError: never,\r\n map: mapper => Result.value(mapper(value)),\r\n mapError: outputHelper,\r\n bind: applyHelper,\r\n exists: applyHelper,\r\n forall: applyHelper,\r\n getOr: constHelper,\r\n or: outputHelper,\r\n getOrThunk: constHelper,\r\n orThunk: outputHelper,\r\n getOrDie: constHelper,\r\n each: fn => {\r\n fn(value);\r\n },\r\n toOptional: () => Optional.some(value)\r\n };\r\n return output;\r\n };\r\n const error = error => {\r\n const outputHelper = () => output;\r\n const output = {\r\n tag: false,\r\n inner: error,\r\n fold: (onError, _onValue) => onError(error),\r\n isValue: never,\r\n isError: always,\r\n map: outputHelper,\r\n mapError: mapper => Result.error(mapper(error)),\r\n bind: outputHelper,\r\n exists: never,\r\n forall: always,\r\n getOr: identity,\r\n or: identity,\r\n getOrThunk: apply$1,\r\n orThunk: apply$1,\r\n getOrDie: die(String(error)),\r\n each: noop,\r\n toOptional: Optional.none\r\n };\r\n return output;\r\n };\r\n const fromOption = (optional, err) => optional.fold(() => error(err), value$1);\r\n const Result = {\r\n value: value$1,\r\n error,\r\n fromOption\r\n };\r\n\r\n const generate = cases => {\r\n if (!isArray$1(cases)) {\r\n throw new Error('cases must be an array');\r\n }\r\n if (cases.length === 0) {\r\n throw new Error('there must be at least one case');\r\n }\r\n const constructors = [];\r\n const adt = {};\r\n each$e(cases, (acase, count) => {\r\n const keys$1 = keys(acase);\r\n if (keys$1.length !== 1) {\r\n throw new Error('one and only one name per case');\r\n }\r\n const key = keys$1[0];\r\n const value = acase[key];\r\n if (adt[key] !== undefined) {\r\n throw new Error('duplicate key detected:' + key);\r\n } else if (key === 'cata') {\r\n throw new Error('cannot have a case named cata (sorry)');\r\n } else if (!isArray$1(value)) {\r\n throw new Error('case arguments must be an array');\r\n }\r\n constructors.push(key);\r\n adt[key] = (...args) => {\r\n const argLength = args.length;\r\n if (argLength !== value.length) {\r\n throw new Error('Wrong number of arguments to case ' + key + '. Expected ' + value.length + ' (' + value + '), got ' + argLength);\r\n }\r\n const match = branches => {\r\n const branchKeys = keys(branches);\r\n if (constructors.length !== branchKeys.length) {\r\n throw new Error('Wrong number of arguments to match. Expected: ' + constructors.join(',') + '\\nActual: ' + branchKeys.join(','));\r\n }\r\n const allReqd = forall(constructors, reqKey => {\r\n return contains$2(branchKeys, reqKey);\r\n });\r\n if (!allReqd) {\r\n throw new Error('Not all branches were specified when using match. Specified: ' + branchKeys.join(', ') + '\\nRequired: ' + constructors.join(', '));\r\n }\r\n return branches[key].apply(null, args);\r\n };\r\n return {\r\n fold: (...foldArgs) => {\r\n if (foldArgs.length !== cases.length) {\r\n throw new Error('Wrong number of arguments to fold. Expected ' + cases.length + ', got ' + foldArgs.length);\r\n }\r\n const target = foldArgs[count];\r\n return target.apply(null, args);\r\n },\r\n match,\r\n log: label => {\r\n console.log(label, {\r\n constructors,\r\n constructor: key,\r\n params: args\r\n });\r\n }\r\n };\r\n };\r\n });\r\n return adt;\r\n };\r\n const Adt = { generate };\r\n\r\n Adt.generate([\r\n {\r\n bothErrors: [\r\n 'error1',\r\n 'error2'\r\n ]\r\n },\r\n {\r\n firstError: [\r\n 'error1',\r\n 'value2'\r\n ]\r\n },\r\n {\r\n secondError: [\r\n 'value1',\r\n 'error2'\r\n ]\r\n },\r\n {\r\n bothValues: [\r\n 'value1',\r\n 'value2'\r\n ]\r\n }\r\n ]);\r\n const partition$1 = results => {\r\n const errors = [];\r\n const values = [];\r\n each$e(results, result => {\r\n result.fold(err => {\r\n errors.push(err);\r\n }, value => {\r\n values.push(value);\r\n });\r\n });\r\n return {\r\n errors,\r\n values\r\n };\r\n };\r\n\r\n const isInlinePattern = pattern => pattern.type === 'inline-command' || pattern.type === 'inline-format';\r\n const isBlockPattern = pattern => pattern.type === 'block-command' || pattern.type === 'block-format';\r\n const normalizePattern = pattern => {\r\n const err = message => Result.error({\r\n message,\r\n pattern\r\n });\r\n const formatOrCmd = (name, onFormat, onCommand) => {\r\n if (pattern.format !== undefined) {\r\n let formats;\r\n if (isArray$1(pattern.format)) {\r\n if (!forall(pattern.format, isString)) {\r\n return err(name + ' pattern has non-string items in the `format` array');\r\n }\r\n formats = pattern.format;\r\n } else if (isString(pattern.format)) {\r\n formats = [pattern.format];\r\n } else {\r\n return err(name + ' pattern has non-string `format` parameter');\r\n }\r\n return Result.value(onFormat(formats));\r\n } else if (pattern.cmd !== undefined) {\r\n if (!isString(pattern.cmd)) {\r\n return err(name + ' pattern has non-string `cmd` parameter');\r\n }\r\n return Result.value(onCommand(pattern.cmd, pattern.value));\r\n } else {\r\n return err(name + ' pattern is missing both `format` and `cmd` parameters');\r\n }\r\n };\r\n if (!isObject(pattern)) {\r\n return err('Raw pattern is not an object');\r\n }\r\n if (!isString(pattern.start)) {\r\n return err('Raw pattern is missing `start` parameter');\r\n }\r\n if (pattern.end !== undefined) {\r\n if (!isString(pattern.end)) {\r\n return err('Inline pattern has non-string `end` parameter');\r\n }\r\n if (pattern.start.length === 0 && pattern.end.length === 0) {\r\n return err('Inline pattern has empty `start` and `end` parameters');\r\n }\r\n let start = pattern.start;\r\n let end = pattern.end;\r\n if (end.length === 0) {\r\n end = start;\r\n start = '';\r\n }\r\n return formatOrCmd('Inline', format => ({\r\n type: 'inline-format',\r\n start,\r\n end,\r\n format\r\n }), (cmd, value) => ({\r\n type: 'inline-command',\r\n start,\r\n end,\r\n cmd,\r\n value\r\n }));\r\n } else if (pattern.replacement !== undefined) {\r\n if (!isString(pattern.replacement)) {\r\n return err('Replacement pattern has non-string `replacement` parameter');\r\n }\r\n if (pattern.start.length === 0) {\r\n return err('Replacement pattern has empty `start` parameter');\r\n }\r\n return Result.value({\r\n type: 'inline-command',\r\n start: '',\r\n end: pattern.start,\r\n cmd: 'mceInsertContent',\r\n value: pattern.replacement\r\n });\r\n } else {\r\n if (pattern.start.length === 0) {\r\n return err('Block pattern has empty `start` parameter');\r\n }\r\n return formatOrCmd('Block', formats => ({\r\n type: 'block-format',\r\n start: pattern.start,\r\n format: formats[0]\r\n }), (command, commandValue) => ({\r\n type: 'block-command',\r\n start: pattern.start,\r\n cmd: command,\r\n value: commandValue\r\n }));\r\n }\r\n };\r\n const getBlockPatterns = patterns => filter$5(patterns, isBlockPattern);\r\n const getInlinePatterns = patterns => filter$5(patterns, isInlinePattern);\r\n const createPatternSet = (patterns, dynamicPatternsLookup) => ({\r\n inlinePatterns: getInlinePatterns(patterns),\r\n blockPatterns: getBlockPatterns(patterns),\r\n dynamicPatternsLookup\r\n });\r\n const fromRawPatterns = patterns => {\r\n const normalized = partition$1(map$3(patterns, normalizePattern));\r\n each$e(normalized.errors, err => console.error(err.message, err.pattern));\r\n return normalized.values;\r\n };\r\n const fromRawPatternsLookup = lookupFn => {\r\n return ctx => {\r\n const rawPatterns = lookupFn(ctx);\r\n return fromRawPatterns(rawPatterns);\r\n };\r\n };\r\n\r\n const deviceDetection$1 = detect$2().deviceType;\r\n const isTouch = deviceDetection$1.isTouch();\r\n const DOM$a = DOMUtils.DOM;\r\n const getHash = value => {\r\n const items = value.indexOf('=') > 0 ? value.split(/[;,](?![^=;,]*(?:[;,]|$))/) : value.split(',');\r\n return foldl(items, (output, item) => {\r\n const arr = item.split('=');\r\n const key = arr[0];\r\n const val = arr.length > 1 ? arr[1] : key;\r\n output[trim$3(key)] = trim$3(val);\r\n return output;\r\n }, {});\r\n };\r\n const isRegExp = x => is$4(x, RegExp);\r\n const option = name => editor => editor.options.get(name);\r\n const stringOrObjectProcessor = value => isString(value) || isObject(value);\r\n const bodyOptionProcessor = (editor, defaultValue = '') => value => {\r\n const valid = isString(value);\r\n if (valid) {\r\n if (value.indexOf('=') !== -1) {\r\n const bodyObj = getHash(value);\r\n return {\r\n value: get$a(bodyObj, editor.id).getOr(defaultValue),\r\n valid\r\n };\r\n } else {\r\n return {\r\n value,\r\n valid\r\n };\r\n }\r\n } else {\r\n return {\r\n valid: false,\r\n message: 'Must be a string.'\r\n };\r\n }\r\n };\r\n const register$7 = editor => {\r\n const registerOption = editor.options.register;\r\n registerOption('id', {\r\n processor: 'string',\r\n default: editor.id\r\n });\r\n registerOption('selector', { processor: 'string' });\r\n registerOption('target', { processor: 'object' });\r\n registerOption('suffix', { processor: 'string' });\r\n registerOption('cache_suffix', { processor: 'string' });\r\n registerOption('base_url', { processor: 'string' });\r\n registerOption('referrer_policy', {\r\n processor: 'string',\r\n default: ''\r\n });\r\n registerOption('language_load', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('inline', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('iframe_attrs', {\r\n processor: 'object',\r\n default: {}\r\n });\r\n registerOption('doctype', {\r\n processor: 'string',\r\n default: ''\r\n });\r\n registerOption('document_base_url', {\r\n processor: 'string',\r\n default: editor.documentBaseUrl\r\n });\r\n registerOption('body_id', {\r\n processor: bodyOptionProcessor(editor, 'tinymce'),\r\n default: 'tinymce'\r\n });\r\n registerOption('body_class', {\r\n processor: bodyOptionProcessor(editor),\r\n default: ''\r\n });\r\n registerOption('content_security_policy', {\r\n processor: 'string',\r\n default: ''\r\n });\r\n registerOption('br_in_pre', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('forced_root_block', {\r\n processor: value => {\r\n const valid = isString(value) && isNotEmpty(value);\r\n if (valid) {\r\n return {\r\n value,\r\n valid\r\n };\r\n } else {\r\n return {\r\n valid: false,\r\n message: 'Must be a non-empty string.'\r\n };\r\n }\r\n },\r\n default: 'p'\r\n });\r\n registerOption('forced_root_block_attrs', {\r\n processor: 'object',\r\n default: {}\r\n });\r\n registerOption('newline_behavior', {\r\n processor: value => {\r\n const valid = contains$2([\r\n 'block',\r\n 'linebreak',\r\n 'invert',\r\n 'default'\r\n ], value);\r\n return valid ? {\r\n value,\r\n valid\r\n } : {\r\n valid: false,\r\n message: 'Must be one of: block, linebreak, invert or default.'\r\n };\r\n },\r\n default: 'default'\r\n });\r\n registerOption('br_newline_selector', {\r\n processor: 'string',\r\n default: '.mce-toc h2,figcaption,caption'\r\n });\r\n registerOption('no_newline_selector', {\r\n processor: 'string',\r\n default: ''\r\n });\r\n registerOption('keep_styles', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('end_container_on_empty_block', {\r\n processor: value => {\r\n if (isBoolean(value)) {\r\n return {\r\n valid: true,\r\n value\r\n };\r\n } else if (isString(value)) {\r\n return {\r\n valid: true,\r\n value\r\n };\r\n } else {\r\n return {\r\n valid: false,\r\n message: 'Must be boolean or a string'\r\n };\r\n }\r\n },\r\n default: 'blockquote'\r\n });\r\n registerOption('font_size_style_values', {\r\n processor: 'string',\r\n default: 'xx-small,x-small,small,medium,large,x-large,xx-large'\r\n });\r\n registerOption('font_size_legacy_values', {\r\n processor: 'string',\r\n default: 'xx-small,small,medium,large,x-large,xx-large,300%'\r\n });\r\n registerOption('font_size_classes', {\r\n processor: 'string',\r\n default: ''\r\n });\r\n registerOption('automatic_uploads', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('images_reuse_filename', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('images_replace_blob_uris', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('icons', {\r\n processor: 'string',\r\n default: ''\r\n });\r\n registerOption('icons_url', {\r\n processor: 'string',\r\n default: ''\r\n });\r\n registerOption('images_upload_url', {\r\n processor: 'string',\r\n default: ''\r\n });\r\n registerOption('images_upload_base_path', {\r\n processor: 'string',\r\n default: ''\r\n });\r\n registerOption('images_upload_credentials', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('images_upload_handler', { processor: 'function' });\r\n registerOption('language', {\r\n processor: 'string',\r\n default: 'en'\r\n });\r\n registerOption('language_url', {\r\n processor: 'string',\r\n default: ''\r\n });\r\n registerOption('entity_encoding', {\r\n processor: 'string',\r\n default: 'named'\r\n });\r\n registerOption('indent', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('indent_before', {\r\n processor: 'string',\r\n default: 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,' + 'tfoot,tbody,tr,section,summary,article,hgroup,aside,figure,figcaption,option,optgroup,datalist'\r\n });\r\n registerOption('indent_after', {\r\n processor: 'string',\r\n default: 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,' + 'tfoot,tbody,tr,section,summary,article,hgroup,aside,figure,figcaption,option,optgroup,datalist'\r\n });\r\n registerOption('indent_use_margin', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('indentation', {\r\n processor: 'string',\r\n default: '40px'\r\n });\r\n registerOption('content_css', {\r\n processor: value => {\r\n const valid = value === false || isString(value) || isArrayOf(value, isString);\r\n if (valid) {\r\n if (isString(value)) {\r\n return {\r\n value: map$3(value.split(','), trim$3),\r\n valid\r\n };\r\n } else if (isArray$1(value)) {\r\n return {\r\n value,\r\n valid\r\n };\r\n } else if (value === false) {\r\n return {\r\n value: [],\r\n valid\r\n };\r\n } else {\r\n return {\r\n value,\r\n valid\r\n };\r\n }\r\n } else {\r\n return {\r\n valid: false,\r\n message: 'Must be false, a string or an array of strings.'\r\n };\r\n }\r\n },\r\n default: isInline(editor) ? [] : ['default']\r\n });\r\n registerOption('content_style', { processor: 'string' });\r\n registerOption('content_css_cors', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('font_css', {\r\n processor: value => {\r\n const valid = isString(value) || isArrayOf(value, isString);\r\n if (valid) {\r\n const newValue = isArray$1(value) ? value : map$3(value.split(','), trim$3);\r\n return {\r\n value: newValue,\r\n valid\r\n };\r\n } else {\r\n return {\r\n valid: false,\r\n message: 'Must be a string or an array of strings.'\r\n };\r\n }\r\n },\r\n default: []\r\n });\r\n registerOption('inline_boundaries', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('inline_boundaries_selector', {\r\n processor: 'string',\r\n default: 'a[href],code,span.mce-annotation'\r\n });\r\n registerOption('object_resizing', {\r\n processor: value => {\r\n const valid = isBoolean(value) || isString(value);\r\n if (valid) {\r\n if (value === false || deviceDetection$1.isiPhone() || deviceDetection$1.isiPad()) {\r\n return {\r\n value: '',\r\n valid\r\n };\r\n } else {\r\n return {\r\n value: value === true ? 'table,img,figure.image,div,video,iframe' : value,\r\n valid\r\n };\r\n }\r\n } else {\r\n return {\r\n valid: false,\r\n message: 'Must be boolean or a string'\r\n };\r\n }\r\n },\r\n default: !isTouch\r\n });\r\n registerOption('resize_img_proportional', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('event_root', { processor: 'object' });\r\n registerOption('service_message', { processor: 'string' });\r\n registerOption('theme', {\r\n processor: value => value === false || isString(value) || isFunction(value),\r\n default: 'silver'\r\n });\r\n registerOption('theme_url', { processor: 'string' });\r\n registerOption('formats', { processor: 'object' });\r\n registerOption('format_empty_lines', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('format_noneditable_selector', {\r\n processor: 'string',\r\n default: ''\r\n });\r\n registerOption('preview_styles', {\r\n processor: value => {\r\n const valid = value === false || isString(value);\r\n if (valid) {\r\n return {\r\n value: value === false ? '' : value,\r\n valid\r\n };\r\n } else {\r\n return {\r\n valid: false,\r\n message: 'Must be false or a string'\r\n };\r\n }\r\n },\r\n default: 'font-family font-size font-weight font-style text-decoration text-transform color background-color border border-radius outline text-shadow'\r\n });\r\n registerOption('custom_ui_selector', {\r\n processor: 'string',\r\n default: ''\r\n });\r\n registerOption('hidden_input', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('submit_patch', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('encoding', { processor: 'string' });\r\n registerOption('add_form_submit_trigger', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('add_unload_trigger', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('custom_undo_redo_levels', {\r\n processor: 'number',\r\n default: 0\r\n });\r\n registerOption('disable_nodechange', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('readonly', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('plugins', {\r\n processor: 'string[]',\r\n default: []\r\n });\r\n registerOption('external_plugins', { processor: 'object' });\r\n registerOption('forced_plugins', { processor: 'string[]' });\r\n registerOption('model', {\r\n processor: 'string',\r\n default: editor.hasPlugin('rtc') ? 'plugin' : 'dom'\r\n });\r\n registerOption('model_url', { processor: 'string' });\r\n registerOption('block_unsupported_drop', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('visual', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('visual_table_class', {\r\n processor: 'string',\r\n default: 'mce-item-table'\r\n });\r\n registerOption('visual_anchor_class', {\r\n processor: 'string',\r\n default: 'mce-item-anchor'\r\n });\r\n registerOption('iframe_aria_text', {\r\n processor: 'string',\r\n default: 'Rich Text Area. Press ALT-0 for help.'\r\n });\r\n registerOption('setup', { processor: 'function' });\r\n registerOption('init_instance_callback', { processor: 'function' });\r\n registerOption('url_converter', {\r\n processor: 'function',\r\n default: editor.convertURL\r\n });\r\n registerOption('url_converter_scope', {\r\n processor: 'object',\r\n default: editor\r\n });\r\n registerOption('urlconverter_callback', { processor: 'function' });\r\n registerOption('allow_conditional_comments', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('allow_html_data_urls', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('allow_svg_data_urls', { processor: 'boolean' });\r\n registerOption('allow_html_in_named_anchor', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('allow_script_urls', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('allow_unsafe_link_target', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('convert_fonts_to_spans', {\r\n processor: 'boolean',\r\n default: true,\r\n deprecated: true\r\n });\r\n registerOption('fix_list_elements', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('preserve_cdata', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('remove_trailing_brs', { processor: 'boolean' });\r\n registerOption('inline_styles', {\r\n processor: 'boolean',\r\n default: true,\r\n deprecated: true\r\n });\r\n registerOption('element_format', {\r\n processor: 'string',\r\n default: 'html'\r\n });\r\n registerOption('entities', { processor: 'string' });\r\n registerOption('schema', {\r\n processor: 'string',\r\n default: 'html5'\r\n });\r\n registerOption('convert_urls', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('relative_urls', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('remove_script_host', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('custom_elements', { processor: 'string' });\r\n registerOption('extended_valid_elements', { processor: 'string' });\r\n registerOption('invalid_elements', { processor: 'string' });\r\n registerOption('invalid_styles', { processor: stringOrObjectProcessor });\r\n registerOption('valid_children', { processor: 'string' });\r\n registerOption('valid_classes', { processor: stringOrObjectProcessor });\r\n registerOption('valid_elements', { processor: 'string' });\r\n registerOption('valid_styles', { processor: stringOrObjectProcessor });\r\n registerOption('verify_html', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('auto_focus', { processor: value => isString(value) || value === true });\r\n registerOption('browser_spellcheck', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('protect', { processor: 'array' });\r\n registerOption('images_file_types', {\r\n processor: 'string',\r\n default: 'jpeg,jpg,jpe,jfi,jif,jfif,png,gif,bmp,webp'\r\n });\r\n registerOption('deprecation_warnings', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('a11y_advanced_options', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('api_key', { processor: 'string' });\r\n registerOption('paste_block_drop', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('paste_data_images', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('paste_preprocess', { processor: 'function' });\r\n registerOption('paste_postprocess', { processor: 'function' });\r\n registerOption('paste_webkit_styles', {\r\n processor: 'string',\r\n default: 'none'\r\n });\r\n registerOption('paste_remove_styles_if_webkit', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('paste_merge_formats', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('smart_paste', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('paste_as_text', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('paste_tab_spaces', {\r\n processor: 'number',\r\n default: 4\r\n });\r\n registerOption('text_patterns', {\r\n processor: value => {\r\n if (isArrayOf(value, isObject) || value === false) {\r\n const patterns = value === false ? [] : value;\r\n return {\r\n value: fromRawPatterns(patterns),\r\n valid: true\r\n };\r\n } else {\r\n return {\r\n valid: false,\r\n message: 'Must be an array of objects or false.'\r\n };\r\n }\r\n },\r\n default: [\r\n {\r\n start: '*',\r\n end: '*',\r\n format: 'italic'\r\n },\r\n {\r\n start: '**',\r\n end: '**',\r\n format: 'bold'\r\n },\r\n {\r\n start: '#',\r\n format: 'h1'\r\n },\r\n {\r\n start: '##',\r\n format: 'h2'\r\n },\r\n {\r\n start: '###',\r\n format: 'h3'\r\n },\r\n {\r\n start: '####',\r\n format: 'h4'\r\n },\r\n {\r\n start: '#####',\r\n format: 'h5'\r\n },\r\n {\r\n start: '######',\r\n format: 'h6'\r\n },\r\n {\r\n start: '1. ',\r\n cmd: 'InsertOrderedList'\r\n },\r\n {\r\n start: '* ',\r\n cmd: 'InsertUnorderedList'\r\n },\r\n {\r\n start: '- ',\r\n cmd: 'InsertUnorderedList'\r\n }\r\n ]\r\n });\r\n registerOption('text_patterns_lookup', {\r\n processor: value => {\r\n if (isFunction(value)) {\r\n return {\r\n value: fromRawPatternsLookup(value),\r\n valid: true\r\n };\r\n } else {\r\n return {\r\n valid: false,\r\n message: 'Must be a single function'\r\n };\r\n }\r\n },\r\n default: _ctx => []\r\n });\r\n registerOption('noneditable_class', {\r\n processor: 'string',\r\n default: 'mceNonEditable'\r\n });\r\n registerOption('editable_class', {\r\n processor: 'string',\r\n default: 'mceEditable'\r\n });\r\n registerOption('noneditable_regexp', {\r\n processor: value => {\r\n if (isArrayOf(value, isRegExp)) {\r\n return {\r\n value,\r\n valid: true\r\n };\r\n } else if (isRegExp(value)) {\r\n return {\r\n value: [value],\r\n valid: true\r\n };\r\n } else {\r\n return {\r\n valid: false,\r\n message: 'Must be a RegExp or an array of RegExp.'\r\n };\r\n }\r\n },\r\n default: []\r\n });\r\n registerOption('table_tab_navigation', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n registerOption('highlight_on_focus', {\r\n processor: 'boolean',\r\n default: false\r\n });\r\n registerOption('xss_sanitization', {\r\n processor: 'boolean',\r\n default: true\r\n });\r\n editor.on('ScriptsLoaded', () => {\r\n registerOption('directionality', {\r\n processor: 'string',\r\n default: I18n.isRtl() ? 'rtl' : undefined\r\n });\r\n registerOption('placeholder', {\r\n processor: 'string',\r\n default: DOM$a.getAttrib(editor.getElement(), 'placeholder')\r\n });\r\n });\r\n };\r\n const getIframeAttrs = option('iframe_attrs');\r\n const getDocType = option('doctype');\r\n const getDocumentBaseUrl = option('document_base_url');\r\n const getBodyId = option('body_id');\r\n const getBodyClass = option('body_class');\r\n const getContentSecurityPolicy = option('content_security_policy');\r\n const shouldPutBrInPre$1 = option('br_in_pre');\r\n const getForcedRootBlock = option('forced_root_block');\r\n const getForcedRootBlockAttrs = option('forced_root_block_attrs');\r\n const getNewlineBehavior = option('newline_behavior');\r\n const getBrNewLineSelector = option('br_newline_selector');\r\n const getNoNewLineSelector = option('no_newline_selector');\r\n const shouldKeepStyles = option('keep_styles');\r\n const shouldEndContainerOnEmptyBlock = option('end_container_on_empty_block');\r\n const isAutomaticUploadsEnabled = option('automatic_uploads');\r\n const shouldReuseFileName = option('images_reuse_filename');\r\n const shouldReplaceBlobUris = option('images_replace_blob_uris');\r\n const getIconPackName = option('icons');\r\n const getIconsUrl = option('icons_url');\r\n const getImageUploadUrl = option('images_upload_url');\r\n const getImageUploadBasePath = option('images_upload_base_path');\r\n const getImagesUploadCredentials = option('images_upload_credentials');\r\n const getImagesUploadHandler = option('images_upload_handler');\r\n const shouldUseContentCssCors = option('content_css_cors');\r\n const getReferrerPolicy = option('referrer_policy');\r\n const getLanguageCode = option('language');\r\n const getLanguageUrl = option('language_url');\r\n const shouldIndentUseMargin = option('indent_use_margin');\r\n const getIndentation = option('indentation');\r\n const getContentCss = option('content_css');\r\n const getContentStyle = option('content_style');\r\n const getFontCss = option('font_css');\r\n const getDirectionality = option('directionality');\r\n const getInlineBoundarySelector = option('inline_boundaries_selector');\r\n const getObjectResizing = option('object_resizing');\r\n const getResizeImgProportional = option('resize_img_proportional');\r\n const getPlaceholder = option('placeholder');\r\n const getEventRoot = option('event_root');\r\n const getServiceMessage = option('service_message');\r\n const getTheme = option('theme');\r\n const getThemeUrl = option('theme_url');\r\n const getModel = option('model');\r\n const getModelUrl = option('model_url');\r\n const isInlineBoundariesEnabled = option('inline_boundaries');\r\n const getFormats = option('formats');\r\n const getPreviewStyles = option('preview_styles');\r\n const canFormatEmptyLines = option('format_empty_lines');\r\n const getFormatNoneditableSelector = option('format_noneditable_selector');\r\n const getCustomUiSelector = option('custom_ui_selector');\r\n const isInline = option('inline');\r\n const hasHiddenInput = option('hidden_input');\r\n const shouldPatchSubmit = option('submit_patch');\r\n const shouldAddFormSubmitTrigger = option('add_form_submit_trigger');\r\n const shouldAddUnloadTrigger = option('add_unload_trigger');\r\n const getCustomUndoRedoLevels = option('custom_undo_redo_levels');\r\n const shouldDisableNodeChange = option('disable_nodechange');\r\n const isReadOnly$1 = option('readonly');\r\n const hasContentCssCors = option('content_css_cors');\r\n const getPlugins = option('plugins');\r\n const getExternalPlugins$1 = option('external_plugins');\r\n const shouldBlockUnsupportedDrop = option('block_unsupported_drop');\r\n const isVisualAidsEnabled = option('visual');\r\n const getVisualAidsTableClass = option('visual_table_class');\r\n const getVisualAidsAnchorClass = option('visual_anchor_class');\r\n const getIframeAriaText = option('iframe_aria_text');\r\n const getSetupCallback = option('setup');\r\n const getInitInstanceCallback = option('init_instance_callback');\r\n const getUrlConverterCallback = option('urlconverter_callback');\r\n const getAutoFocus = option('auto_focus');\r\n const shouldBrowserSpellcheck = option('browser_spellcheck');\r\n const getProtect = option('protect');\r\n const shouldPasteBlockDrop = option('paste_block_drop');\r\n const shouldPasteDataImages = option('paste_data_images');\r\n const getPastePreProcess = option('paste_preprocess');\r\n const getPastePostProcess = option('paste_postprocess');\r\n const getPasteWebkitStyles = option('paste_webkit_styles');\r\n const shouldPasteRemoveWebKitStyles = option('paste_remove_styles_if_webkit');\r\n const shouldPasteMergeFormats = option('paste_merge_formats');\r\n const isSmartPasteEnabled = option('smart_paste');\r\n const isPasteAsTextEnabled = option('paste_as_text');\r\n const getPasteTabSpaces = option('paste_tab_spaces');\r\n const shouldAllowHtmlDataUrls = option('allow_html_data_urls');\r\n const getTextPatterns = option('text_patterns');\r\n const getTextPatternsLookup = option('text_patterns_lookup');\r\n const getNonEditableClass = option('noneditable_class');\r\n const getEditableClass = option('editable_class');\r\n const getNonEditableRegExps = option('noneditable_regexp');\r\n const shouldPreserveCData = option('preserve_cdata');\r\n const shouldHighlightOnFocus = option('highlight_on_focus');\r\n const shouldSanitizeXss = option('xss_sanitization');\r\n const hasTextPatternsLookup = editor => editor.options.isSet('text_patterns_lookup');\r\n const getFontStyleValues = editor => Tools.explode(editor.options.get('font_size_style_values'));\r\n const getFontSizeClasses = editor => Tools.explode(editor.options.get('font_size_classes'));\r\n const isEncodingXml = editor => editor.options.get('encoding') === 'xml';\r\n const getAllowedImageFileTypes = editor => Tools.explode(editor.options.get('images_file_types'));\r\n const hasTableTabNavigation = option('table_tab_navigation');\r\n\r\n const isElement$3 = isElement$6;\r\n const isText$5 = isText$a;\r\n const removeNode$1 = node => {\r\n const parentNode = node.parentNode;\r\n if (parentNode) {\r\n parentNode.removeChild(node);\r\n }\r\n };\r\n const trimCount = text => {\r\n const trimmedText = trim$1(text);\r\n return {\r\n count: text.length - trimmedText.length,\r\n text: trimmedText\r\n };\r\n };\r\n const deleteZwspChars = caretContainer => {\r\n let idx;\r\n while ((idx = caretContainer.data.lastIndexOf(ZWSP$1)) !== -1) {\r\n caretContainer.deleteData(idx, 1);\r\n }\r\n };\r\n const removeUnchanged = (caretContainer, pos) => {\r\n remove$4(caretContainer);\r\n return pos;\r\n };\r\n const removeTextAndReposition = (caretContainer, pos) => {\r\n const before = trimCount(caretContainer.data.substr(0, pos.offset()));\r\n const after = trimCount(caretContainer.data.substr(pos.offset()));\r\n const text = before.text + after.text;\r\n if (text.length > 0) {\r\n deleteZwspChars(caretContainer);\r\n return CaretPosition(caretContainer, pos.offset() - before.count);\r\n } else {\r\n return pos;\r\n }\r\n };\r\n const removeElementAndReposition = (caretContainer, pos) => {\r\n const parentNode = pos.container();\r\n const newPosition = indexOf$1(from(parentNode.childNodes), caretContainer).map(index => {\r\n return index < pos.offset() ? CaretPosition(parentNode, pos.offset() - 1) : pos;\r\n }).getOr(pos);\r\n remove$4(caretContainer);\r\n return newPosition;\r\n };\r\n const removeTextCaretContainer = (caretContainer, pos) => isText$5(caretContainer) && pos.container() === caretContainer ? removeTextAndReposition(caretContainer, pos) : removeUnchanged(caretContainer, pos);\r\n const removeElementCaretContainer = (caretContainer, pos) => pos.container() === caretContainer.parentNode ? removeElementAndReposition(caretContainer, pos) : removeUnchanged(caretContainer, pos);\r\n const removeAndReposition = (container, pos) => CaretPosition.isTextPosition(pos) ? removeTextCaretContainer(container, pos) : removeElementCaretContainer(container, pos);\r\n const remove$4 = caretContainerNode => {\r\n if (isElement$3(caretContainerNode) && isCaretContainer$2(caretContainerNode)) {\r\n if (hasContent(caretContainerNode)) {\r\n caretContainerNode.removeAttribute('data-mce-caret');\r\n } else {\r\n removeNode$1(caretContainerNode);\r\n }\r\n }\r\n if (isText$5(caretContainerNode)) {\r\n deleteZwspChars(caretContainerNode);\r\n if (caretContainerNode.data.length === 0) {\r\n removeNode$1(caretContainerNode);\r\n }\r\n }\r\n };\r\n\r\n const isContentEditableFalse$8 = isContentEditableFalse$b;\r\n const isMedia$1 = isMedia$2;\r\n const isTableCell$1 = isTableCell$3;\r\n const inlineFakeCaretSelector = '*[contentEditable=false],video,audio,embed,object';\r\n const getAbsoluteClientRect = (root, element, before) => {\r\n const clientRect = collapse(element.getBoundingClientRect(), before);\r\n let scrollX;\r\n let scrollY;\r\n if (root.tagName === 'BODY') {\r\n const docElm = root.ownerDocument.documentElement;\r\n scrollX = root.scrollLeft || docElm.scrollLeft;\r\n scrollY = root.scrollTop || docElm.scrollTop;\r\n } else {\r\n const rootRect = root.getBoundingClientRect();\r\n scrollX = root.scrollLeft - rootRect.left;\r\n scrollY = root.scrollTop - rootRect.top;\r\n }\r\n clientRect.left += scrollX;\r\n clientRect.right += scrollX;\r\n clientRect.top += scrollY;\r\n clientRect.bottom += scrollY;\r\n clientRect.width = 1;\r\n let margin = element.offsetWidth - element.clientWidth;\r\n if (margin > 0) {\r\n if (before) {\r\n margin *= -1;\r\n }\r\n clientRect.left += margin;\r\n clientRect.right += margin;\r\n }\r\n return clientRect;\r\n };\r\n const trimInlineCaretContainers = root => {\r\n var _a, _b;\r\n const fakeCaretTargetNodes = descendants(SugarElement.fromDom(root), inlineFakeCaretSelector);\r\n for (let i = 0; i < fakeCaretTargetNodes.length; i++) {\r\n const node = fakeCaretTargetNodes[i].dom;\r\n let sibling = node.previousSibling;\r\n if (endsWithCaretContainer$1(sibling)) {\r\n const data = sibling.data;\r\n if (data.length === 1) {\r\n (_a = sibling.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(sibling);\r\n } else {\r\n sibling.deleteData(data.length - 1, 1);\r\n }\r\n }\r\n sibling = node.nextSibling;\r\n if (startsWithCaretContainer$1(sibling)) {\r\n const data = sibling.data;\r\n if (data.length === 1) {\r\n (_b = sibling.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(sibling);\r\n } else {\r\n sibling.deleteData(0, 1);\r\n }\r\n }\r\n }\r\n };\r\n const FakeCaret = (editor, root, isBlock, hasFocus) => {\r\n const lastVisualCaret = value$2();\r\n let cursorInterval;\r\n let caretContainerNode;\r\n const caretBlock = getForcedRootBlock(editor);\r\n const dom = editor.dom;\r\n const show = (before, element) => {\r\n let rng;\r\n hide();\r\n if (isTableCell$1(element)) {\r\n return null;\r\n }\r\n if (isBlock(element)) {\r\n const caretContainer = insertBlock(caretBlock, element, before);\r\n const clientRect = getAbsoluteClientRect(root, element, before);\r\n dom.setStyle(caretContainer, 'top', clientRect.top);\r\n caretContainerNode = caretContainer;\r\n const caret = dom.create('div', {\r\n 'class': 'mce-visual-caret',\r\n 'data-mce-bogus': 'all'\r\n });\r\n dom.setStyles(caret, { ...clientRect });\r\n dom.add(root, caret);\r\n lastVisualCaret.set({\r\n caret,\r\n element,\r\n before\r\n });\r\n if (before) {\r\n dom.addClass(caret, 'mce-visual-caret-before');\r\n }\r\n startBlink();\r\n rng = element.ownerDocument.createRange();\r\n rng.setStart(caretContainer, 0);\r\n rng.setEnd(caretContainer, 0);\r\n } else {\r\n caretContainerNode = insertInline$1(element, before);\r\n rng = element.ownerDocument.createRange();\r\n if (isInlineFakeCaretTarget(caretContainerNode.nextSibling)) {\r\n rng.setStart(caretContainerNode, 0);\r\n rng.setEnd(caretContainerNode, 0);\r\n } else {\r\n rng.setStart(caretContainerNode, 1);\r\n rng.setEnd(caretContainerNode, 1);\r\n }\r\n return rng;\r\n }\r\n return rng;\r\n };\r\n const hide = () => {\r\n trimInlineCaretContainers(root);\r\n if (caretContainerNode) {\r\n remove$4(caretContainerNode);\r\n caretContainerNode = null;\r\n }\r\n lastVisualCaret.on(caretState => {\r\n dom.remove(caretState.caret);\r\n lastVisualCaret.clear();\r\n });\r\n if (cursorInterval) {\r\n clearInterval(cursorInterval);\r\n cursorInterval = undefined;\r\n }\r\n };\r\n const startBlink = () => {\r\n cursorInterval = setInterval(() => {\r\n lastVisualCaret.on(caretState => {\r\n if (hasFocus()) {\r\n dom.toggleClass(caretState.caret, 'mce-visual-caret-hidden');\r\n } else {\r\n dom.addClass(caretState.caret, 'mce-visual-caret-hidden');\r\n }\r\n });\r\n }, 500);\r\n };\r\n const reposition = () => {\r\n lastVisualCaret.on(caretState => {\r\n const clientRect = getAbsoluteClientRect(root, caretState.element, caretState.before);\r\n dom.setStyles(caretState.caret, { ...clientRect });\r\n });\r\n };\r\n const destroy = () => clearInterval(cursorInterval);\r\n const getCss = () => '.mce-visual-caret {' + 'position: absolute;' + 'background-color: black;' + 'background-color: currentcolor;' + '}' + '.mce-visual-caret-hidden {' + 'display: none;' + '}' + '*[data-mce-caret] {' + 'position: absolute;' + 'left: -1000px;' + 'right: auto;' + 'top: 0;' + 'margin: 0;' + 'padding: 0;' + '}';\r\n return {\r\n show,\r\n hide,\r\n getCss,\r\n reposition,\r\n destroy\r\n };\r\n };\r\n const isFakeCaretTableBrowser = () => Env.browser.isFirefox();\r\n const isInlineFakeCaretTarget = node => isContentEditableFalse$8(node) || isMedia$1(node);\r\n const isFakeCaretTarget = node => {\r\n const isTarget = isInlineFakeCaretTarget(node) || isTable$2(node) && isFakeCaretTableBrowser();\r\n return isTarget && parentElement(SugarElement.fromDom(node)).exists(isEditable$3);\r\n };\r\n\r\n const isContentEditableTrue$1 = isContentEditableTrue$3;\r\n const isContentEditableFalse$7 = isContentEditableFalse$b;\r\n const isMedia = isMedia$2;\r\n const isBlockLike = matchStyleValues('display', 'block table table-cell table-caption list-item');\r\n const isCaretContainer = isCaretContainer$2;\r\n const isCaretContainerBlock = isCaretContainerBlock$1;\r\n const isElement$2 = isElement$6;\r\n const isText$4 = isText$a;\r\n const isCaretCandidate$1 = isCaretCandidate$3;\r\n const isForwards = direction => direction > 0;\r\n const isBackwards = direction => direction < 0;\r\n const skipCaretContainers = (walk, shallow) => {\r\n let node;\r\n while (node = walk(shallow)) {\r\n if (!isCaretContainerBlock(node)) {\r\n return node;\r\n }\r\n }\r\n return null;\r\n };\r\n const findNode = (node, direction, predicateFn, rootNode, shallow) => {\r\n const walker = new DomTreeWalker(node, rootNode);\r\n const isCefOrCaretContainer = isContentEditableFalse$7(node) || isCaretContainerBlock(node);\r\n let tempNode;\r\n if (isBackwards(direction)) {\r\n if (isCefOrCaretContainer) {\r\n tempNode = skipCaretContainers(walker.prev.bind(walker), true);\r\n if (predicateFn(tempNode)) {\r\n return tempNode;\r\n }\r\n }\r\n while (tempNode = skipCaretContainers(walker.prev.bind(walker), shallow)) {\r\n if (predicateFn(tempNode)) {\r\n return tempNode;\r\n }\r\n }\r\n }\r\n if (isForwards(direction)) {\r\n if (isCefOrCaretContainer) {\r\n tempNode = skipCaretContainers(walker.next.bind(walker), true);\r\n if (predicateFn(tempNode)) {\r\n return tempNode;\r\n }\r\n }\r\n while (tempNode = skipCaretContainers(walker.next.bind(walker), shallow)) {\r\n if (predicateFn(tempNode)) {\r\n return tempNode;\r\n }\r\n }\r\n }\r\n return null;\r\n };\r\n const getEditingHost = (node, rootNode) => {\r\n const isCETrue = node => isContentEditableTrue$1(node.dom);\r\n const isRoot = node => node.dom === rootNode;\r\n return ancestor$4(SugarElement.fromDom(node), isCETrue, isRoot).map(elm => elm.dom).getOr(rootNode);\r\n };\r\n const getParentBlock$3 = (node, rootNode) => {\r\n while (node && node !== rootNode) {\r\n if (isBlockLike(node)) {\r\n return node;\r\n }\r\n node = node.parentNode;\r\n }\r\n return null;\r\n };\r\n const isInSameBlock = (caretPosition1, caretPosition2, rootNode) => getParentBlock$3(caretPosition1.container(), rootNode) === getParentBlock$3(caretPosition2.container(), rootNode);\r\n const getChildNodeAtRelativeOffset = (relativeOffset, caretPosition) => {\r\n if (!caretPosition) {\r\n return Optional.none();\r\n }\r\n const container = caretPosition.container();\r\n const offset = caretPosition.offset();\r\n if (!isElement$2(container)) {\r\n return Optional.none();\r\n }\r\n return Optional.from(container.childNodes[offset + relativeOffset]);\r\n };\r\n const beforeAfter = (before, node) => {\r\n var _a;\r\n const doc = (_a = node.ownerDocument) !== null && _a !== void 0 ? _a : document;\r\n const range = doc.createRange();\r\n if (before) {\r\n range.setStartBefore(node);\r\n range.setEndBefore(node);\r\n } else {\r\n range.setStartAfter(node);\r\n range.setEndAfter(node);\r\n }\r\n return range;\r\n };\r\n const isNodesInSameBlock = (root, node1, node2) => getParentBlock$3(node1, root) === getParentBlock$3(node2, root);\r\n const lean = (left, root, node) => {\r\n const siblingName = left ? 'previousSibling' : 'nextSibling';\r\n let tempNode = node;\r\n while (tempNode && tempNode !== root) {\r\n let sibling = tempNode[siblingName];\r\n if (sibling && isCaretContainer(sibling)) {\r\n sibling = sibling[siblingName];\r\n }\r\n if (isContentEditableFalse$7(sibling) || isMedia(sibling)) {\r\n if (isNodesInSameBlock(root, sibling, tempNode)) {\r\n return sibling;\r\n }\r\n break;\r\n }\r\n if (isCaretCandidate$1(sibling)) {\r\n break;\r\n }\r\n tempNode = tempNode.parentNode;\r\n }\r\n return null;\r\n };\r\n const before$2 = curry(beforeAfter, true);\r\n const after$2 = curry(beforeAfter, false);\r\n const normalizeRange = (direction, root, range) => {\r\n let node;\r\n const leanLeft = curry(lean, true, root);\r\n const leanRight = curry(lean, false, root);\r\n const container = range.startContainer;\r\n const offset = range.startOffset;\r\n if (isCaretContainerBlock$1(container)) {\r\n const block = isText$4(container) ? container.parentNode : container;\r\n const location = block.getAttribute('data-mce-caret');\r\n if (location === 'before') {\r\n node = block.nextSibling;\r\n if (isFakeCaretTarget(node)) {\r\n return before$2(node);\r\n }\r\n }\r\n if (location === 'after') {\r\n node = block.previousSibling;\r\n if (isFakeCaretTarget(node)) {\r\n return after$2(node);\r\n }\r\n }\r\n }\r\n if (!range.collapsed) {\r\n return range;\r\n }\r\n if (isText$a(container)) {\r\n if (isCaretContainer(container)) {\r\n if (direction === 1) {\r\n node = leanRight(container);\r\n if (node) {\r\n return before$2(node);\r\n }\r\n node = leanLeft(container);\r\n if (node) {\r\n return after$2(node);\r\n }\r\n }\r\n if (direction === -1) {\r\n node = leanLeft(container);\r\n if (node) {\r\n return after$2(node);\r\n }\r\n node = leanRight(container);\r\n if (node) {\r\n return before$2(node);\r\n }\r\n }\r\n return range;\r\n }\r\n if (endsWithCaretContainer$1(container) && offset >= container.data.length - 1) {\r\n if (direction === 1) {\r\n node = leanRight(container);\r\n if (node) {\r\n return before$2(node);\r\n }\r\n }\r\n return range;\r\n }\r\n if (startsWithCaretContainer$1(container) && offset <= 1) {\r\n if (direction === -1) {\r\n node = leanLeft(container);\r\n if (node) {\r\n return after$2(node);\r\n }\r\n }\r\n return range;\r\n }\r\n if (offset === container.data.length) {\r\n node = leanRight(container);\r\n if (node) {\r\n return before$2(node);\r\n }\r\n return range;\r\n }\r\n if (offset === 0) {\r\n node = leanLeft(container);\r\n if (node) {\r\n return after$2(node);\r\n }\r\n return range;\r\n }\r\n }\r\n return range;\r\n };\r\n const getRelativeCefElm = (forward, caretPosition) => getChildNodeAtRelativeOffset(forward ? 0 : -1, caretPosition).filter(isContentEditableFalse$7);\r\n const getNormalizedRangeEndPoint = (direction, root, range) => {\r\n const normalizedRange = normalizeRange(direction, root, range);\r\n return direction === -1 ? CaretPosition.fromRangeStart(normalizedRange) : CaretPosition.fromRangeEnd(normalizedRange);\r\n };\r\n const getElementFromPosition = pos => Optional.from(pos.getNode()).map(SugarElement.fromDom);\r\n const getElementFromPrevPosition = pos => Optional.from(pos.getNode(true)).map(SugarElement.fromDom);\r\n const getVisualCaretPosition = (walkFn, caretPosition) => {\r\n let pos = caretPosition;\r\n while (pos = walkFn(pos)) {\r\n if (pos.isVisible()) {\r\n return pos;\r\n }\r\n }\r\n return pos;\r\n };\r\n const isMoveInsideSameBlock = (from, to) => {\r\n const inSameBlock = isInSameBlock(from, to);\r\n if (!inSameBlock && isBr$6(from.getNode())) {\r\n return true;\r\n }\r\n return inSameBlock;\r\n };\r\n\r\n var HDirection;\r\n (function (HDirection) {\r\n HDirection[HDirection['Backwards'] = -1] = 'Backwards';\r\n HDirection[HDirection['Forwards'] = 1] = 'Forwards';\r\n }(HDirection || (HDirection = {})));\r\n const isContentEditableFalse$6 = isContentEditableFalse$b;\r\n const isText$3 = isText$a;\r\n const isElement$1 = isElement$6;\r\n const isBr$2 = isBr$6;\r\n const isCaretCandidate = isCaretCandidate$3;\r\n const isAtomic = isAtomic$1;\r\n const isEditableCaretCandidate = isEditableCaretCandidate$1;\r\n const getParents$3 = (node, root) => {\r\n const parents = [];\r\n let tempNode = node;\r\n while (tempNode && tempNode !== root) {\r\n parents.push(tempNode);\r\n tempNode = tempNode.parentNode;\r\n }\r\n return parents;\r\n };\r\n const nodeAtIndex = (container, offset) => {\r\n if (container.hasChildNodes() && offset < container.childNodes.length) {\r\n return container.childNodes[offset];\r\n }\r\n return null;\r\n };\r\n const getCaretCandidatePosition = (direction, node) => {\r\n if (isForwards(direction)) {\r\n if (isCaretCandidate(node.previousSibling) && !isText$3(node.previousSibling)) {\r\n return CaretPosition.before(node);\r\n }\r\n if (isText$3(node)) {\r\n return CaretPosition(node, 0);\r\n }\r\n }\r\n if (isBackwards(direction)) {\r\n if (isCaretCandidate(node.nextSibling) && !isText$3(node.nextSibling)) {\r\n return CaretPosition.after(node);\r\n }\r\n if (isText$3(node)) {\r\n return CaretPosition(node, node.data.length);\r\n }\r\n }\r\n if (isBackwards(direction)) {\r\n if (isBr$2(node)) {\r\n return CaretPosition.before(node);\r\n }\r\n return CaretPosition.after(node);\r\n }\r\n return CaretPosition.before(node);\r\n };\r\n const moveForwardFromBr = (root, nextNode) => {\r\n const nextSibling = nextNode.nextSibling;\r\n if (nextSibling && isCaretCandidate(nextSibling)) {\r\n if (isText$3(nextSibling)) {\r\n return CaretPosition(nextSibling, 0);\r\n } else {\r\n return CaretPosition.before(nextSibling);\r\n }\r\n } else {\r\n return findCaretPosition$1(HDirection.Forwards, CaretPosition.after(nextNode), root);\r\n }\r\n };\r\n const findCaretPosition$1 = (direction, startPos, root) => {\r\n let node;\r\n let nextNode;\r\n let innerNode;\r\n let caretPosition;\r\n if (!isElement$1(root) || !startPos) {\r\n return null;\r\n }\r\n if (startPos.isEqual(CaretPosition.after(root)) && root.lastChild) {\r\n caretPosition = CaretPosition.after(root.lastChild);\r\n if (isBackwards(direction) && isCaretCandidate(root.lastChild) && isElement$1(root.lastChild)) {\r\n return isBr$2(root.lastChild) ? CaretPosition.before(root.lastChild) : caretPosition;\r\n }\r\n } else {\r\n caretPosition = startPos;\r\n }\r\n const container = caretPosition.container();\r\n let offset = caretPosition.offset();\r\n if (isText$3(container)) {\r\n if (isBackwards(direction) && offset > 0) {\r\n return CaretPosition(container, --offset);\r\n }\r\n if (isForwards(direction) && offset < container.length) {\r\n return CaretPosition(container, ++offset);\r\n }\r\n node = container;\r\n } else {\r\n if (isBackwards(direction) && offset > 0) {\r\n nextNode = nodeAtIndex(container, offset - 1);\r\n if (isCaretCandidate(nextNode)) {\r\n if (!isAtomic(nextNode)) {\r\n innerNode = findNode(nextNode, direction, isEditableCaretCandidate, nextNode);\r\n if (innerNode) {\r\n if (isText$3(innerNode)) {\r\n return CaretPosition(innerNode, innerNode.data.length);\r\n }\r\n return CaretPosition.after(innerNode);\r\n }\r\n }\r\n if (isText$3(nextNode)) {\r\n return CaretPosition(nextNode, nextNode.data.length);\r\n }\r\n return CaretPosition.before(nextNode);\r\n }\r\n }\r\n if (isForwards(direction) && offset < container.childNodes.length) {\r\n nextNode = nodeAtIndex(container, offset);\r\n if (isCaretCandidate(nextNode)) {\r\n if (isBr$2(nextNode)) {\r\n return moveForwardFromBr(root, nextNode);\r\n }\r\n if (!isAtomic(nextNode)) {\r\n innerNode = findNode(nextNode, direction, isEditableCaretCandidate, nextNode);\r\n if (innerNode) {\r\n if (isText$3(innerNode)) {\r\n return CaretPosition(innerNode, 0);\r\n }\r\n return CaretPosition.before(innerNode);\r\n }\r\n }\r\n if (isText$3(nextNode)) {\r\n return CaretPosition(nextNode, 0);\r\n }\r\n return CaretPosition.after(nextNode);\r\n }\r\n }\r\n node = nextNode ? nextNode : caretPosition.getNode();\r\n }\r\n if (node && (isForwards(direction) && caretPosition.isAtEnd() || isBackwards(direction) && caretPosition.isAtStart())) {\r\n node = findNode(node, direction, always, root, true);\r\n if (isEditableCaretCandidate(node, root)) {\r\n return getCaretCandidatePosition(direction, node);\r\n }\r\n }\r\n nextNode = node ? findNode(node, direction, isEditableCaretCandidate, root) : node;\r\n const rootContentEditableFalseElm = last$2(filter$5(getParents$3(container, root), isContentEditableFalse$6));\r\n if (rootContentEditableFalseElm && (!nextNode || !rootContentEditableFalseElm.contains(nextNode))) {\r\n if (isForwards(direction)) {\r\n caretPosition = CaretPosition.after(rootContentEditableFalseElm);\r\n } else {\r\n caretPosition = CaretPosition.before(rootContentEditableFalseElm);\r\n }\r\n return caretPosition;\r\n }\r\n if (nextNode) {\r\n return getCaretCandidatePosition(direction, nextNode);\r\n }\r\n return null;\r\n };\r\n const CaretWalker = root => ({\r\n next: caretPosition => {\r\n return findCaretPosition$1(HDirection.Forwards, caretPosition, root);\r\n },\r\n prev: caretPosition => {\r\n return findCaretPosition$1(HDirection.Backwards, caretPosition, root);\r\n }\r\n });\r\n\r\n const walkToPositionIn = (forward, root, start) => {\r\n const position = forward ? CaretPosition.before(start) : CaretPosition.after(start);\r\n return fromPosition(forward, root, position);\r\n };\r\n const afterElement = node => isBr$6(node) ? CaretPosition.before(node) : CaretPosition.after(node);\r\n const isBeforeOrStart = position => {\r\n if (CaretPosition.isTextPosition(position)) {\r\n return position.offset() === 0;\r\n } else {\r\n return isCaretCandidate$3(position.getNode());\r\n }\r\n };\r\n const isAfterOrEnd = position => {\r\n if (CaretPosition.isTextPosition(position)) {\r\n const container = position.container();\r\n return position.offset() === container.data.length;\r\n } else {\r\n return isCaretCandidate$3(position.getNode(true));\r\n }\r\n };\r\n const isBeforeAfterSameElement = (from, to) => !CaretPosition.isTextPosition(from) && !CaretPosition.isTextPosition(to) && from.getNode() === to.getNode(true);\r\n const isAtBr = position => !CaretPosition.isTextPosition(position) && isBr$6(position.getNode());\r\n const shouldSkipPosition = (forward, from, to) => {\r\n if (forward) {\r\n return !isBeforeAfterSameElement(from, to) && !isAtBr(from) && isAfterOrEnd(from) && isBeforeOrStart(to);\r\n } else {\r\n return !isBeforeAfterSameElement(to, from) && isBeforeOrStart(from) && isAfterOrEnd(to);\r\n }\r\n };\r\n const fromPosition = (forward, root, pos) => {\r\n const walker = CaretWalker(root);\r\n return Optional.from(forward ? walker.next(pos) : walker.prev(pos));\r\n };\r\n const navigate = (forward, root, from) => fromPosition(forward, root, from).bind(to => {\r\n if (isInSameBlock(from, to, root) && shouldSkipPosition(forward, from, to)) {\r\n return fromPosition(forward, root, to);\r\n } else {\r\n return Optional.some(to);\r\n }\r\n });\r\n const navigateIgnore = (forward, root, from, ignoreFilter) => navigate(forward, root, from).bind(pos => ignoreFilter(pos) ? navigateIgnore(forward, root, pos, ignoreFilter) : Optional.some(pos));\r\n const positionIn = (forward, element) => {\r\n const startNode = forward ? element.firstChild : element.lastChild;\r\n if (isText$a(startNode)) {\r\n return Optional.some(CaretPosition(startNode, forward ? 0 : startNode.data.length));\r\n } else if (startNode) {\r\n if (isCaretCandidate$3(startNode)) {\r\n return Optional.some(forward ? CaretPosition.before(startNode) : afterElement(startNode));\r\n } else {\r\n return walkToPositionIn(forward, element, startNode);\r\n }\r\n } else {\r\n return Optional.none();\r\n }\r\n };\r\n const nextPosition = curry(fromPosition, true);\r\n const prevPosition = curry(fromPosition, false);\r\n const firstPositionIn = curry(positionIn, true);\r\n const lastPositionIn = curry(positionIn, false);\r\n\r\n const CARET_ID = '_mce_caret';\r\n const isCaretNode = node => isElement$6(node) && node.id === CARET_ID;\r\n const getParentCaretContainer = (body, node) => {\r\n let currentNode = node;\r\n while (currentNode && currentNode !== body) {\r\n if (isCaretNode(currentNode)) {\r\n return currentNode;\r\n }\r\n currentNode = currentNode.parentNode;\r\n }\r\n return null;\r\n };\r\n\r\n const isStringPathBookmark = bookmark => isString(bookmark.start);\r\n const isRangeBookmark = bookmark => has$2(bookmark, 'rng');\r\n const isIdBookmark = bookmark => has$2(bookmark, 'id');\r\n const isIndexBookmark = bookmark => has$2(bookmark, 'name');\r\n const isPathBookmark = bookmark => Tools.isArray(bookmark.start);\r\n\r\n const isForwardBookmark = bookmark => !isIndexBookmark(bookmark) && isBoolean(bookmark.forward) ? bookmark.forward : true;\r\n const addBogus = (dom, node) => {\r\n if (isElement$6(node) && dom.isBlock(node) && !node.innerHTML) {\r\n node.innerHTML = '
';\r\n }\r\n return node;\r\n };\r\n const resolveCaretPositionBookmark = (dom, bookmark) => {\r\n const startPos = Optional.from(resolve$1(dom.getRoot(), bookmark.start));\r\n const endPos = Optional.from(resolve$1(dom.getRoot(), bookmark.end));\r\n return lift2(startPos, endPos, (start, end) => {\r\n const range = dom.createRng();\r\n range.setStart(start.container(), start.offset());\r\n range.setEnd(end.container(), end.offset());\r\n return {\r\n range,\r\n forward: isForwardBookmark(bookmark)\r\n };\r\n });\r\n };\r\n const insertZwsp = (node, rng) => {\r\n var _a;\r\n const doc = (_a = node.ownerDocument) !== null && _a !== void 0 ? _a : document;\r\n const textNode = doc.createTextNode(ZWSP$1);\r\n node.appendChild(textNode);\r\n rng.setStart(textNode, 0);\r\n rng.setEnd(textNode, 0);\r\n };\r\n const isEmpty$1 = node => !node.hasChildNodes();\r\n const tryFindRangePosition = (node, rng) => lastPositionIn(node).fold(never, pos => {\r\n rng.setStart(pos.container(), pos.offset());\r\n rng.setEnd(pos.container(), pos.offset());\r\n return true;\r\n });\r\n const padEmptyCaretContainer = (root, node, rng) => {\r\n if (isEmpty$1(node) && getParentCaretContainer(root, node)) {\r\n insertZwsp(node, rng);\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n };\r\n const setEndPoint = (dom, start, bookmark, rng) => {\r\n const point = bookmark[start ? 'start' : 'end'];\r\n const root = dom.getRoot();\r\n if (point) {\r\n let node = root;\r\n let offset = point[0];\r\n for (let i = point.length - 1; node && i >= 1; i--) {\r\n const children = node.childNodes;\r\n if (padEmptyCaretContainer(root, node, rng)) {\r\n return true;\r\n }\r\n if (point[i] > children.length - 1) {\r\n if (padEmptyCaretContainer(root, node, rng)) {\r\n return true;\r\n }\r\n return tryFindRangePosition(node, rng);\r\n }\r\n node = children[point[i]];\r\n }\r\n if (isText$a(node)) {\r\n offset = Math.min(point[0], node.data.length);\r\n }\r\n if (isElement$6(node)) {\r\n offset = Math.min(point[0], node.childNodes.length);\r\n }\r\n if (start) {\r\n rng.setStart(node, offset);\r\n } else {\r\n rng.setEnd(node, offset);\r\n }\r\n }\r\n return true;\r\n };\r\n const isValidTextNode = node => isText$a(node) && node.data.length > 0;\r\n const restoreEndPoint = (dom, suffix, bookmark) => {\r\n const marker = dom.get(bookmark.id + '_' + suffix);\r\n const markerParent = marker === null || marker === void 0 ? void 0 : marker.parentNode;\r\n const keep = bookmark.keep;\r\n if (marker && markerParent) {\r\n let container;\r\n let offset;\r\n if (suffix === 'start') {\r\n if (!keep) {\r\n container = markerParent;\r\n offset = dom.nodeIndex(marker);\r\n } else {\r\n if (marker.hasChildNodes()) {\r\n container = marker.firstChild;\r\n offset = 1;\r\n } else if (isValidTextNode(marker.nextSibling)) {\r\n container = marker.nextSibling;\r\n offset = 0;\r\n } else if (isValidTextNode(marker.previousSibling)) {\r\n container = marker.previousSibling;\r\n offset = marker.previousSibling.data.length;\r\n } else {\r\n container = markerParent;\r\n offset = dom.nodeIndex(marker) + 1;\r\n }\r\n }\r\n } else {\r\n if (!keep) {\r\n container = markerParent;\r\n offset = dom.nodeIndex(marker);\r\n } else {\r\n if (marker.hasChildNodes()) {\r\n container = marker.firstChild;\r\n offset = 1;\r\n } else if (isValidTextNode(marker.previousSibling)) {\r\n container = marker.previousSibling;\r\n offset = marker.previousSibling.data.length;\r\n } else {\r\n container = markerParent;\r\n offset = dom.nodeIndex(marker);\r\n }\r\n }\r\n }\r\n if (!keep) {\r\n const prev = marker.previousSibling;\r\n const next = marker.nextSibling;\r\n Tools.each(Tools.grep(marker.childNodes), node => {\r\n if (isText$a(node)) {\r\n node.data = node.data.replace(/\\uFEFF/g, '');\r\n }\r\n });\r\n let otherMarker;\r\n while (otherMarker = dom.get(bookmark.id + '_' + suffix)) {\r\n dom.remove(otherMarker, true);\r\n }\r\n if (isText$a(next) && isText$a(prev) && !Env.browser.isOpera()) {\r\n const idx = prev.data.length;\r\n prev.appendData(next.data);\r\n dom.remove(next);\r\n container = prev;\r\n offset = idx;\r\n }\r\n }\r\n return Optional.some(CaretPosition(container, offset));\r\n } else {\r\n return Optional.none();\r\n }\r\n };\r\n const resolvePaths = (dom, bookmark) => {\r\n const range = dom.createRng();\r\n if (setEndPoint(dom, true, bookmark, range) && setEndPoint(dom, false, bookmark, range)) {\r\n return Optional.some({\r\n range,\r\n forward: isForwardBookmark(bookmark)\r\n });\r\n } else {\r\n return Optional.none();\r\n }\r\n };\r\n const resolveId = (dom, bookmark) => {\r\n const startPos = restoreEndPoint(dom, 'start', bookmark);\r\n const endPos = restoreEndPoint(dom, 'end', bookmark);\r\n return lift2(startPos, endPos.or(startPos), (spos, epos) => {\r\n const range = dom.createRng();\r\n range.setStart(addBogus(dom, spos.container()), spos.offset());\r\n range.setEnd(addBogus(dom, epos.container()), epos.offset());\r\n return {\r\n range,\r\n forward: isForwardBookmark(bookmark)\r\n };\r\n });\r\n };\r\n const resolveIndex = (dom, bookmark) => Optional.from(dom.select(bookmark.name)[bookmark.index]).map(elm => {\r\n const range = dom.createRng();\r\n range.selectNode(elm);\r\n return {\r\n range,\r\n forward: true\r\n };\r\n });\r\n const resolve = (selection, bookmark) => {\r\n const dom = selection.dom;\r\n if (bookmark) {\r\n if (isPathBookmark(bookmark)) {\r\n return resolvePaths(dom, bookmark);\r\n } else if (isStringPathBookmark(bookmark)) {\r\n return resolveCaretPositionBookmark(dom, bookmark);\r\n } else if (isIdBookmark(bookmark)) {\r\n return resolveId(dom, bookmark);\r\n } else if (isIndexBookmark(bookmark)) {\r\n return resolveIndex(dom, bookmark);\r\n } else if (isRangeBookmark(bookmark)) {\r\n return Optional.some({\r\n range: bookmark.rng,\r\n forward: isForwardBookmark(bookmark)\r\n });\r\n }\r\n }\r\n return Optional.none();\r\n };\r\n\r\n const getBookmark$1 = (selection, type, normalized) => {\r\n return getBookmark$2(selection, type, normalized);\r\n };\r\n const moveToBookmark = (selection, bookmark) => {\r\n resolve(selection, bookmark).each(({range, forward}) => {\r\n selection.setRng(range, forward);\r\n });\r\n };\r\n const isBookmarkNode$1 = node => {\r\n return isElement$6(node) && node.tagName === 'SPAN' && node.getAttribute('data-mce-type') === 'bookmark';\r\n };\r\n\r\n const is = expected => actual => expected === actual;\r\n const isNbsp = is(nbsp);\r\n const isWhiteSpace = chr => chr !== '' && ' \\f\\n\\r\\t\\x0B'.indexOf(chr) !== -1;\r\n const isContent = chr => !isWhiteSpace(chr) && !isNbsp(chr) && !isZwsp$1(chr);\r\n\r\n const hexColour = value => ({ value: normalizeHex(value) });\r\n const normalizeHex = hex => removeLeading(hex, '#').toUpperCase();\r\n const toHex = component => {\r\n const hex = component.toString(16);\r\n return (hex.length === 1 ? '0' + hex : hex).toUpperCase();\r\n };\r\n const fromRgba = rgbaColour => {\r\n const value = toHex(rgbaColour.red) + toHex(rgbaColour.green) + toHex(rgbaColour.blue);\r\n return hexColour(value);\r\n };\r\n\r\n const rgbRegex = /^\\s*rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)\\s*$/i;\r\n const rgbaRegex = /^\\s*rgba\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d?(?:\\.\\d+)?)\\s*\\)\\s*$/i;\r\n const rgbaColour = (red, green, blue, alpha) => ({\r\n red,\r\n green,\r\n blue,\r\n alpha\r\n });\r\n const fromStringValues = (red, green, blue, alpha) => {\r\n const r = parseInt(red, 10);\r\n const g = parseInt(green, 10);\r\n const b = parseInt(blue, 10);\r\n const a = parseFloat(alpha);\r\n return rgbaColour(r, g, b, a);\r\n };\r\n const fromString = rgbaString => {\r\n if (rgbaString === 'transparent') {\r\n return Optional.some(rgbaColour(0, 0, 0, 0));\r\n }\r\n const rgbMatch = rgbRegex.exec(rgbaString);\r\n if (rgbMatch !== null) {\r\n return Optional.some(fromStringValues(rgbMatch[1], rgbMatch[2], rgbMatch[3], '1'));\r\n }\r\n const rgbaMatch = rgbaRegex.exec(rgbaString);\r\n if (rgbaMatch !== null) {\r\n return Optional.some(fromStringValues(rgbaMatch[1], rgbaMatch[2], rgbaMatch[3], rgbaMatch[4]));\r\n }\r\n return Optional.none();\r\n };\r\n\r\n const rgbaToHexString = color => fromString(color).map(fromRgba).map(h => '#' + h.value).getOr(color);\r\n\r\n const getRanges$1 = selection => {\r\n const ranges = [];\r\n if (selection) {\r\n for (let i = 0; i < selection.rangeCount; i++) {\r\n ranges.push(selection.getRangeAt(i));\r\n }\r\n }\r\n return ranges;\r\n };\r\n const getSelectedNodes = ranges => {\r\n return bind$3(ranges, range => {\r\n const node = getSelectedNode(range);\r\n return node ? [SugarElement.fromDom(node)] : [];\r\n });\r\n };\r\n const hasMultipleRanges = selection => {\r\n return getRanges$1(selection).length > 1;\r\n };\r\n\r\n const getCellsFromRanges = ranges => filter$5(getSelectedNodes(ranges), isTableCell$2);\r\n const getCellsFromElement = elm => descendants(elm, 'td[data-mce-selected],th[data-mce-selected]');\r\n const getCellsFromElementOrRanges = (ranges, element) => {\r\n const selectedCells = getCellsFromElement(element);\r\n return selectedCells.length > 0 ? selectedCells : getCellsFromRanges(ranges);\r\n };\r\n const getCellsFromEditor = editor => getCellsFromElementOrRanges(getRanges$1(editor.selection.getSel()), SugarElement.fromDom(editor.getBody()));\r\n const getClosestTable = (cell, isRoot) => ancestor$3(cell, 'table', isRoot);\r\n\r\n const getStartNode = rng => {\r\n const sc = rng.startContainer, so = rng.startOffset;\r\n if (isText$a(sc)) {\r\n return so === 0 ? Optional.some(SugarElement.fromDom(sc)) : Optional.none();\r\n } else {\r\n return Optional.from(sc.childNodes[so]).map(SugarElement.fromDom);\r\n }\r\n };\r\n const getEndNode = rng => {\r\n const ec = rng.endContainer, eo = rng.endOffset;\r\n if (isText$a(ec)) {\r\n return eo === ec.data.length ? Optional.some(SugarElement.fromDom(ec)) : Optional.none();\r\n } else {\r\n return Optional.from(ec.childNodes[eo - 1]).map(SugarElement.fromDom);\r\n }\r\n };\r\n const getFirstChildren = node => {\r\n return firstChild(node).fold(constant([node]), child => {\r\n return [node].concat(getFirstChildren(child));\r\n });\r\n };\r\n const getLastChildren = node => {\r\n return lastChild(node).fold(constant([node]), child => {\r\n if (name(child) === 'br') {\r\n return prevSibling(child).map(sibling => {\r\n return [node].concat(getLastChildren(sibling));\r\n }).getOr([]);\r\n } else {\r\n return [node].concat(getLastChildren(child));\r\n }\r\n });\r\n };\r\n const hasAllContentsSelected = (elm, rng) => {\r\n return lift2(getStartNode(rng), getEndNode(rng), (startNode, endNode) => {\r\n const start = find$2(getFirstChildren(elm), curry(eq, startNode));\r\n const end = find$2(getLastChildren(elm), curry(eq, endNode));\r\n return start.isSome() && end.isSome();\r\n }).getOr(false);\r\n };\r\n const moveEndPoint = (dom, rng, node, start) => {\r\n const root = node;\r\n const walker = new DomTreeWalker(node, root);\r\n const moveCaretBeforeOnEnterElementsMap = filter$4(dom.schema.getMoveCaretBeforeOnEnterElements(), (_, name) => !contains$2([\r\n 'td',\r\n 'th',\r\n 'table'\r\n ], name.toLowerCase()));\r\n let currentNode = node;\r\n do {\r\n if (isText$a(currentNode) && Tools.trim(currentNode.data).length !== 0) {\r\n if (start) {\r\n rng.setStart(currentNode, 0);\r\n } else {\r\n rng.setEnd(currentNode, currentNode.data.length);\r\n }\r\n return;\r\n }\r\n if (moveCaretBeforeOnEnterElementsMap[currentNode.nodeName]) {\r\n if (start) {\r\n rng.setStartBefore(currentNode);\r\n } else {\r\n if (currentNode.nodeName === 'BR') {\r\n rng.setEndBefore(currentNode);\r\n } else {\r\n rng.setEndAfter(currentNode);\r\n }\r\n }\r\n return;\r\n }\r\n } while (currentNode = start ? walker.next() : walker.prev());\r\n if (root.nodeName === 'BODY') {\r\n if (start) {\r\n rng.setStart(root, 0);\r\n } else {\r\n rng.setEnd(root, root.childNodes.length);\r\n }\r\n }\r\n };\r\n const hasAnyRanges = editor => {\r\n const sel = editor.selection.getSel();\r\n return isNonNullable(sel) && sel.rangeCount > 0;\r\n };\r\n const runOnRanges = (editor, executor) => {\r\n const fakeSelectionNodes = getCellsFromEditor(editor);\r\n if (fakeSelectionNodes.length > 0) {\r\n each$e(fakeSelectionNodes, elem => {\r\n const node = elem.dom;\r\n const fakeNodeRng = editor.dom.createRng();\r\n fakeNodeRng.setStartBefore(node);\r\n fakeNodeRng.setEndAfter(node);\r\n executor(fakeNodeRng, true);\r\n });\r\n } else {\r\n executor(editor.selection.getRng(), false);\r\n }\r\n };\r\n const preserve = (selection, fillBookmark, executor) => {\r\n const bookmark = getPersistentBookmark(selection, fillBookmark);\r\n executor(bookmark);\r\n selection.moveToBookmark(bookmark);\r\n };\r\n\r\n const isNode = node => isNumber(node === null || node === void 0 ? void 0 : node.nodeType);\r\n const isElementNode$1 = node => isElement$6(node) && !isBookmarkNode$1(node) && !isCaretNode(node) && !isBogus$2(node);\r\n const isElementDirectlySelected = (dom, node) => {\r\n if (isElementNode$1(node) && !/^(TD|TH)$/.test(node.nodeName)) {\r\n const selectedAttr = dom.getAttrib(node, 'data-mce-selected');\r\n const value = parseInt(selectedAttr, 10);\r\n return !isNaN(value) && value > 0;\r\n } else {\r\n return false;\r\n }\r\n };\r\n const isEditable$2 = elm => elm.isContentEditable === true;\r\n const preserveSelection = (editor, action, shouldMoveStart) => {\r\n const {selection, dom} = editor;\r\n const selectedNodeBeforeAction = selection.getNode();\r\n const isSelectedBeforeNodeNoneditable = isContentEditableFalse$b(selectedNodeBeforeAction);\r\n preserve(selection, true, () => {\r\n action();\r\n });\r\n const isBeforeNodeStillNoneditable = isSelectedBeforeNodeNoneditable && isContentEditableFalse$b(selectedNodeBeforeAction);\r\n if (isBeforeNodeStillNoneditable && dom.isChildOf(selectedNodeBeforeAction, editor.getBody())) {\r\n editor.selection.select(selectedNodeBeforeAction);\r\n } else if (shouldMoveStart(selection.getStart())) {\r\n moveStartToNearestText(dom, selection);\r\n }\r\n };\r\n const moveStartToNearestText = (dom, selection) => {\r\n var _a, _b;\r\n const rng = selection.getRng();\r\n const {startContainer, startOffset} = rng;\r\n const selectedNode = selection.getNode();\r\n if (isElementDirectlySelected(dom, selectedNode)) {\r\n return;\r\n }\r\n if (isElement$6(startContainer)) {\r\n const nodes = startContainer.childNodes;\r\n const root = dom.getRoot();\r\n let walker;\r\n if (startOffset < nodes.length) {\r\n const startNode = nodes[startOffset];\r\n walker = new DomTreeWalker(startNode, (_a = dom.getParent(startNode, dom.isBlock)) !== null && _a !== void 0 ? _a : root);\r\n } else {\r\n const startNode = nodes[nodes.length - 1];\r\n walker = new DomTreeWalker(startNode, (_b = dom.getParent(startNode, dom.isBlock)) !== null && _b !== void 0 ? _b : root);\r\n walker.next(true);\r\n }\r\n for (let node = walker.current(); node; node = walker.next()) {\r\n if (dom.getContentEditable(node) === 'false') {\r\n return;\r\n } else if (isText$a(node) && !isWhiteSpaceNode$1(node)) {\r\n rng.setStart(node, 0);\r\n selection.setRng(rng);\r\n return;\r\n }\r\n }\r\n }\r\n };\r\n const getNonWhiteSpaceSibling = (node, next, inc) => {\r\n if (node) {\r\n const nextName = next ? 'nextSibling' : 'previousSibling';\r\n for (node = inc ? node : node[nextName]; node; node = node[nextName]) {\r\n if (isElement$6(node) || !isWhiteSpaceNode$1(node)) {\r\n return node;\r\n }\r\n }\r\n }\r\n return undefined;\r\n };\r\n const isTextBlock$1 = (schema, node) => !!schema.getTextBlockElements()[node.nodeName.toLowerCase()] || isTransparentBlock(schema, node);\r\n const isValid = (ed, parent, child) => {\r\n return ed.schema.isValidChild(parent, child);\r\n };\r\n const isWhiteSpaceNode$1 = (node, allowSpaces = false) => {\r\n if (isNonNullable(node) && isText$a(node)) {\r\n const data = allowSpaces ? node.data.replace(/ /g, '\\xA0') : node.data;\r\n return isWhitespaceText(data);\r\n } else {\r\n return false;\r\n }\r\n };\r\n const isEmptyTextNode$1 = node => {\r\n return isNonNullable(node) && isText$a(node) && node.length === 0;\r\n };\r\n const isWrapNoneditableTarget = (editor, node) => {\r\n const baseDataSelector = '[data-mce-cef-wrappable]';\r\n const formatNoneditableSelector = getFormatNoneditableSelector(editor);\r\n const selector = isEmpty$3(formatNoneditableSelector) ? baseDataSelector : `${ baseDataSelector },${ formatNoneditableSelector }`;\r\n return is$1(SugarElement.fromDom(node), selector);\r\n };\r\n const isWrappableNoneditable = (editor, node) => {\r\n const dom = editor.dom;\r\n return isElementNode$1(node) && dom.getContentEditable(node) === 'false' && isWrapNoneditableTarget(editor, node) && dom.select('[contenteditable=\"true\"]', node).length === 0;\r\n };\r\n const replaceVars = (value, vars) => {\r\n if (isFunction(value)) {\r\n return value(vars);\r\n } else if (isNonNullable(vars)) {\r\n value = value.replace(/%(\\w+)/g, (str, name) => {\r\n return vars[name] || str;\r\n });\r\n }\r\n return value;\r\n };\r\n const isEq$5 = (str1, str2) => {\r\n str1 = str1 || '';\r\n str2 = str2 || '';\r\n str1 = '' + (str1.nodeName || str1);\r\n str2 = '' + (str2.nodeName || str2);\r\n return str1.toLowerCase() === str2.toLowerCase();\r\n };\r\n const normalizeStyleValue = (value, name) => {\r\n if (isNullable(value)) {\r\n return null;\r\n } else {\r\n let strValue = String(value);\r\n if (name === 'color' || name === 'backgroundColor') {\r\n strValue = rgbaToHexString(strValue);\r\n }\r\n if (name === 'fontWeight' && value === 700) {\r\n strValue = 'bold';\r\n }\r\n if (name === 'fontFamily') {\r\n strValue = strValue.replace(/[\\'\\\"]/g, '').replace(/,\\s+/g, ',');\r\n }\r\n return strValue;\r\n }\r\n };\r\n const getStyle = (dom, node, name) => {\r\n const style = dom.getStyle(node, name);\r\n return normalizeStyleValue(style, name);\r\n };\r\n const getTextDecoration = (dom, node) => {\r\n let decoration;\r\n dom.getParent(node, n => {\r\n if (isElement$6(n)) {\r\n decoration = dom.getStyle(n, 'text-decoration');\r\n return !!decoration && decoration !== 'none';\r\n } else {\r\n return false;\r\n }\r\n });\r\n return decoration;\r\n };\r\n const getParents$2 = (dom, node, selector) => {\r\n return dom.getParents(node, selector, dom.getRoot());\r\n };\r\n const isFormatPredicate = (editor, formatName, predicate) => {\r\n const formats = editor.formatter.get(formatName);\r\n return isNonNullable(formats) && exists(formats, predicate);\r\n };\r\n const isVariableFormatName = (editor, formatName) => {\r\n const hasVariableValues = format => {\r\n const isVariableValue = val => isFunction(val) || val.length > 1 && val.charAt(0) === '%';\r\n return exists([\r\n 'styles',\r\n 'attributes'\r\n ], key => get$a(format, key).exists(field => {\r\n const fieldValues = isArray$1(field) ? field : values(field);\r\n return exists(fieldValues, isVariableValue);\r\n }));\r\n };\r\n return isFormatPredicate(editor, formatName, hasVariableValues);\r\n };\r\n const areSimilarFormats = (editor, formatName, otherFormatName) => {\r\n const validKeys = [\r\n 'inline',\r\n 'block',\r\n 'selector',\r\n 'attributes',\r\n 'styles',\r\n 'classes'\r\n ];\r\n const filterObj = format => filter$4(format, (_, key) => exists(validKeys, validKey => validKey === key));\r\n return isFormatPredicate(editor, formatName, fmt1 => {\r\n const filteredFmt1 = filterObj(fmt1);\r\n return isFormatPredicate(editor, otherFormatName, fmt2 => {\r\n const filteredFmt2 = filterObj(fmt2);\r\n return equal$1(filteredFmt1, filteredFmt2);\r\n });\r\n });\r\n };\r\n const isBlockFormat = format => hasNonNullableKey(format, 'block');\r\n const isWrappingBlockFormat = format => isBlockFormat(format) && format.wrapper === true;\r\n const isNonWrappingBlockFormat = format => isBlockFormat(format) && format.wrapper !== true;\r\n const isSelectorFormat = format => hasNonNullableKey(format, 'selector');\r\n const isInlineFormat = format => hasNonNullableKey(format, 'inline');\r\n const isMixedFormat = format => isSelectorFormat(format) && isInlineFormat(format) && is$2(get$a(format, 'mixed'), true);\r\n const shouldExpandToSelector = format => isSelectorFormat(format) && format.expand !== false && !isInlineFormat(format);\r\n\r\n const isBookmarkNode = isBookmarkNode$1;\r\n const getParents$1 = getParents$2;\r\n const isWhiteSpaceNode = isWhiteSpaceNode$1;\r\n const isTextBlock = isTextBlock$1;\r\n const isBogusBr = node => {\r\n return isBr$6(node) && node.getAttribute('data-mce-bogus') && !node.nextSibling;\r\n };\r\n const findParentContentEditable = (dom, node) => {\r\n let parent = node;\r\n while (parent) {\r\n if (isElement$6(parent) && dom.getContentEditable(parent)) {\r\n return dom.getContentEditable(parent) === 'false' ? parent : node;\r\n }\r\n parent = parent.parentNode;\r\n }\r\n return node;\r\n };\r\n const walkText = (start, node, offset, predicate) => {\r\n const str = node.data;\r\n if (start) {\r\n for (let i = offset; i > 0; i--) {\r\n if (predicate(str.charAt(i - 1))) {\r\n return i;\r\n }\r\n }\r\n } else {\r\n for (let i = offset; i < str.length; i++) {\r\n if (predicate(str.charAt(i))) {\r\n return i;\r\n }\r\n }\r\n }\r\n return -1;\r\n };\r\n const findSpace = (start, node, offset) => walkText(start, node, offset, c => isNbsp(c) || isWhiteSpace(c));\r\n const findContent = (start, node, offset) => walkText(start, node, offset, isContent);\r\n const findWordEndPoint = (dom, body, container, offset, start, includeTrailingSpaces) => {\r\n let lastTextNode;\r\n const rootNode = dom.getParent(container, dom.isBlock) || body;\r\n const walk = (container, offset, pred) => {\r\n const textSeeker = TextSeeker(dom);\r\n const walker = start ? textSeeker.backwards : textSeeker.forwards;\r\n return Optional.from(walker(container, offset, (text, textOffset) => {\r\n if (isBookmarkNode(text.parentNode)) {\r\n return -1;\r\n } else {\r\n lastTextNode = text;\r\n return pred(start, text, textOffset);\r\n }\r\n }, rootNode));\r\n };\r\n const spaceResult = walk(container, offset, findSpace);\r\n return spaceResult.bind(result => includeTrailingSpaces ? walk(result.container, result.offset + (start ? -1 : 0), findContent) : Optional.some(result)).orThunk(() => lastTextNode ? Optional.some({\r\n container: lastTextNode,\r\n offset: start ? 0 : lastTextNode.length\r\n }) : Optional.none());\r\n };\r\n const findSelectorEndPoint = (dom, formatList, rng, container, siblingName) => {\r\n const sibling = container[siblingName];\r\n if (isText$a(container) && isEmpty$3(container.data) && sibling) {\r\n container = sibling;\r\n }\r\n const parents = getParents$1(dom, container);\r\n for (let i = 0; i < parents.length; i++) {\r\n for (let y = 0; y < formatList.length; y++) {\r\n const curFormat = formatList[y];\r\n if (isNonNullable(curFormat.collapsed) && curFormat.collapsed !== rng.collapsed) {\r\n continue;\r\n }\r\n if (isSelectorFormat(curFormat) && dom.is(parents[i], curFormat.selector)) {\r\n return parents[i];\r\n }\r\n }\r\n }\r\n return container;\r\n };\r\n const findBlockEndPoint = (dom, formatList, container, siblingName) => {\r\n var _a;\r\n let node = container;\r\n const root = dom.getRoot();\r\n const format = formatList[0];\r\n if (isBlockFormat(format)) {\r\n node = format.wrapper ? null : dom.getParent(container, format.block, root);\r\n }\r\n if (!node) {\r\n const scopeRoot = (_a = dom.getParent(container, 'LI,TD,TH')) !== null && _a !== void 0 ? _a : root;\r\n node = dom.getParent(isText$a(container) ? container.parentNode : container, node => node !== root && isTextBlock(dom.schema, node), scopeRoot);\r\n }\r\n if (node && isBlockFormat(format) && format.wrapper) {\r\n node = getParents$1(dom, node, 'ul,ol').reverse()[0] || node;\r\n }\r\n if (!node) {\r\n node = container;\r\n while (node && node[siblingName] && !dom.isBlock(node[siblingName])) {\r\n node = node[siblingName];\r\n if (isEq$5(node, 'br')) {\r\n break;\r\n }\r\n }\r\n }\r\n return node || container;\r\n };\r\n const isAtBlockBoundary$1 = (dom, root, container, siblingName) => {\r\n const parent = container.parentNode;\r\n if (isNonNullable(container[siblingName])) {\r\n return false;\r\n } else if (parent === root || isNullable(parent) || dom.isBlock(parent)) {\r\n return true;\r\n } else {\r\n return isAtBlockBoundary$1(dom, root, parent, siblingName);\r\n }\r\n };\r\n const findParentContainer = (dom, formatList, container, offset, start) => {\r\n let parent = container;\r\n const siblingName = start ? 'previousSibling' : 'nextSibling';\r\n const root = dom.getRoot();\r\n if (isText$a(container) && !isWhiteSpaceNode(container)) {\r\n if (start ? offset > 0 : offset < container.data.length) {\r\n return container;\r\n }\r\n }\r\n while (parent) {\r\n if (!formatList[0].block_expand && dom.isBlock(parent)) {\r\n return parent;\r\n }\r\n for (let sibling = parent[siblingName]; sibling; sibling = sibling[siblingName]) {\r\n const allowSpaces = isText$a(sibling) && !isAtBlockBoundary$1(dom, root, sibling, siblingName);\r\n if (!isBookmarkNode(sibling) && !isBogusBr(sibling) && !isWhiteSpaceNode(sibling, allowSpaces)) {\r\n return parent;\r\n }\r\n }\r\n if (parent === root || parent.parentNode === root) {\r\n container = parent;\r\n break;\r\n }\r\n parent = parent.parentNode;\r\n }\r\n return container;\r\n };\r\n const isSelfOrParentBookmark = container => isBookmarkNode(container.parentNode) || isBookmarkNode(container);\r\n const expandRng = (dom, rng, formatList, includeTrailingSpace = false) => {\r\n let {startContainer, startOffset, endContainer, endOffset} = rng;\r\n const format = formatList[0];\r\n if (isElement$6(startContainer) && startContainer.hasChildNodes()) {\r\n startContainer = getNode$1(startContainer, startOffset);\r\n if (isText$a(startContainer)) {\r\n startOffset = 0;\r\n }\r\n }\r\n if (isElement$6(endContainer) && endContainer.hasChildNodes()) {\r\n endContainer = getNode$1(endContainer, rng.collapsed ? endOffset : endOffset - 1);\r\n if (isText$a(endContainer)) {\r\n endOffset = endContainer.data.length;\r\n }\r\n }\r\n startContainer = findParentContentEditable(dom, startContainer);\r\n endContainer = findParentContentEditable(dom, endContainer);\r\n if (isSelfOrParentBookmark(startContainer)) {\r\n startContainer = isBookmarkNode(startContainer) ? startContainer : startContainer.parentNode;\r\n if (rng.collapsed) {\r\n startContainer = startContainer.previousSibling || startContainer;\r\n } else {\r\n startContainer = startContainer.nextSibling || startContainer;\r\n }\r\n if (isText$a(startContainer)) {\r\n startOffset = rng.collapsed ? startContainer.length : 0;\r\n }\r\n }\r\n if (isSelfOrParentBookmark(endContainer)) {\r\n endContainer = isBookmarkNode(endContainer) ? endContainer : endContainer.parentNode;\r\n if (rng.collapsed) {\r\n endContainer = endContainer.nextSibling || endContainer;\r\n } else {\r\n endContainer = endContainer.previousSibling || endContainer;\r\n }\r\n if (isText$a(endContainer)) {\r\n endOffset = rng.collapsed ? 0 : endContainer.length;\r\n }\r\n }\r\n if (rng.collapsed) {\r\n const startPoint = findWordEndPoint(dom, dom.getRoot(), startContainer, startOffset, true, includeTrailingSpace);\r\n startPoint.each(({container, offset}) => {\r\n startContainer = container;\r\n startOffset = offset;\r\n });\r\n const endPoint = findWordEndPoint(dom, dom.getRoot(), endContainer, endOffset, false, includeTrailingSpace);\r\n endPoint.each(({container, offset}) => {\r\n endContainer = container;\r\n endOffset = offset;\r\n });\r\n }\r\n if (isInlineFormat(format) || format.block_expand) {\r\n if (!isInlineFormat(format) || (!isText$a(startContainer) || startOffset === 0)) {\r\n startContainer = findParentContainer(dom, formatList, startContainer, startOffset, true);\r\n }\r\n if (!isInlineFormat(format) || (!isText$a(endContainer) || endOffset === endContainer.data.length)) {\r\n endContainer = findParentContainer(dom, formatList, endContainer, endOffset, false);\r\n }\r\n }\r\n if (shouldExpandToSelector(format)) {\r\n startContainer = findSelectorEndPoint(dom, formatList, rng, startContainer, 'previousSibling');\r\n endContainer = findSelectorEndPoint(dom, formatList, rng, endContainer, 'nextSibling');\r\n }\r\n if (isBlockFormat(format) || isSelectorFormat(format)) {\r\n startContainer = findBlockEndPoint(dom, formatList, startContainer, 'previousSibling');\r\n endContainer = findBlockEndPoint(dom, formatList, endContainer, 'nextSibling');\r\n if (isBlockFormat(format)) {\r\n if (!dom.isBlock(startContainer)) {\r\n startContainer = findParentContainer(dom, formatList, startContainer, startOffset, true);\r\n }\r\n if (!dom.isBlock(endContainer)) {\r\n endContainer = findParentContainer(dom, formatList, endContainer, endOffset, false);\r\n }\r\n }\r\n }\r\n if (isElement$6(startContainer) && startContainer.parentNode) {\r\n startOffset = dom.nodeIndex(startContainer);\r\n startContainer = startContainer.parentNode;\r\n }\r\n if (isElement$6(endContainer) && endContainer.parentNode) {\r\n endOffset = dom.nodeIndex(endContainer) + 1;\r\n endContainer = endContainer.parentNode;\r\n }\r\n return {\r\n startContainer,\r\n startOffset,\r\n endContainer,\r\n endOffset\r\n };\r\n };\r\n\r\n const walk$3 = (dom, rng, callback) => {\r\n var _a;\r\n const startOffset = rng.startOffset;\r\n const startContainer = getNode$1(rng.startContainer, startOffset);\r\n const endOffset = rng.endOffset;\r\n const endContainer = getNode$1(rng.endContainer, endOffset - 1);\r\n const exclude = nodes => {\r\n const firstNode = nodes[0];\r\n if (isText$a(firstNode) && firstNode === startContainer && startOffset >= firstNode.data.length) {\r\n nodes.splice(0, 1);\r\n }\r\n const lastNode = nodes[nodes.length - 1];\r\n if (endOffset === 0 && nodes.length > 0 && lastNode === endContainer && isText$a(lastNode)) {\r\n nodes.splice(nodes.length - 1, 1);\r\n }\r\n return nodes;\r\n };\r\n const collectSiblings = (node, name, endNode) => {\r\n const siblings = [];\r\n for (; node && node !== endNode; node = node[name]) {\r\n siblings.push(node);\r\n }\r\n return siblings;\r\n };\r\n const findEndPoint = (node, root) => dom.getParent(node, node => node.parentNode === root, root);\r\n const walkBoundary = (startNode, endNode, next) => {\r\n const siblingName = next ? 'nextSibling' : 'previousSibling';\r\n for (let node = startNode, parent = node.parentNode; node && node !== endNode; node = parent) {\r\n parent = node.parentNode;\r\n const siblings = collectSiblings(node === startNode ? node : node[siblingName], siblingName);\r\n if (siblings.length) {\r\n if (!next) {\r\n siblings.reverse();\r\n }\r\n callback(exclude(siblings));\r\n }\r\n }\r\n };\r\n if (startContainer === endContainer) {\r\n return callback(exclude([startContainer]));\r\n }\r\n const ancestor = (_a = dom.findCommonAncestor(startContainer, endContainer)) !== null && _a !== void 0 ? _a : dom.getRoot();\r\n if (dom.isChildOf(startContainer, endContainer)) {\r\n return walkBoundary(startContainer, ancestor, true);\r\n }\r\n if (dom.isChildOf(endContainer, startContainer)) {\r\n return walkBoundary(endContainer, ancestor);\r\n }\r\n const startPoint = findEndPoint(startContainer, ancestor) || startContainer;\r\n const endPoint = findEndPoint(endContainer, ancestor) || endContainer;\r\n walkBoundary(startContainer, startPoint, true);\r\n const siblings = collectSiblings(startPoint === startContainer ? startPoint : startPoint.nextSibling, 'nextSibling', endPoint === endContainer ? endPoint.nextSibling : endPoint);\r\n if (siblings.length) {\r\n callback(exclude(siblings));\r\n }\r\n walkBoundary(endContainer, endPoint);\r\n };\r\n\r\n const validBlocks = [\r\n 'pre[class*=language-][contenteditable=\"false\"]',\r\n 'figure.image',\r\n 'div[data-ephox-embed-iri]',\r\n 'div.tiny-pageembed',\r\n 'div.mce-toc',\r\n 'div[data-mce-toc]'\r\n ];\r\n const isZeroWidth = elem => isText$b(elem) && get$3(elem) === ZWSP$1;\r\n const context = (editor, elem, wrapName, nodeName) => parent(elem).fold(() => 'skipping', parent => {\r\n if (nodeName === 'br' || isZeroWidth(elem)) {\r\n return 'valid';\r\n } else if (isAnnotation(elem)) {\r\n return 'existing';\r\n } else if (isCaretNode(elem.dom)) {\r\n return 'caret';\r\n } else if (exists(validBlocks, selector => is$1(elem, selector))) {\r\n return 'valid-block';\r\n } else if (!isValid(editor, wrapName, nodeName) || !isValid(editor, name(parent), wrapName)) {\r\n return 'invalid-child';\r\n } else {\r\n return 'valid';\r\n }\r\n });\r\n\r\n const applyWordGrab = (editor, rng) => {\r\n const r = expandRng(editor.dom, rng, [{ inline: 'span' }]);\r\n rng.setStart(r.startContainer, r.startOffset);\r\n rng.setEnd(r.endContainer, r.endOffset);\r\n editor.selection.setRng(rng);\r\n };\r\n const applyAnnotation = (elem, masterUId, data, annotationName, decorate, directAnnotation) => {\r\n const {uid = masterUId, ...otherData} = data;\r\n add$2(elem, annotation());\r\n set$3(elem, `${ dataAnnotationId() }`, uid);\r\n set$3(elem, `${ dataAnnotation() }`, annotationName);\r\n const {attributes = {}, classes = []} = decorate(uid, otherData);\r\n setAll$1(elem, attributes);\r\n add(elem, classes);\r\n if (directAnnotation) {\r\n if (classes.length > 0) {\r\n set$3(elem, `${ dataAnnotationClasses() }`, classes.join(','));\r\n }\r\n const attributeNames = keys(attributes);\r\n if (attributeNames.length > 0) {\r\n set$3(elem, `${ dataAnnotationAttributes() }`, attributeNames.join(','));\r\n }\r\n }\r\n };\r\n const removeDirectAnnotation = elem => {\r\n remove$8(elem, annotation());\r\n remove$b(elem, `${ dataAnnotationId() }`);\r\n remove$b(elem, `${ dataAnnotation() }`);\r\n remove$b(elem, `${ dataAnnotationActive() }`);\r\n const customAttrNames = getOpt(elem, `${ dataAnnotationAttributes() }`).map(names => names.split(',')).getOr([]);\r\n const customClasses = getOpt(elem, `${ dataAnnotationClasses() }`).map(names => names.split(',')).getOr([]);\r\n each$e(customAttrNames, name => remove$b(elem, name));\r\n remove$5(elem, customClasses);\r\n remove$b(elem, `${ dataAnnotationClasses() }`);\r\n remove$b(elem, `${ dataAnnotationAttributes() }`);\r\n };\r\n const makeAnnotation = (eDoc, uid, data, annotationName, decorate) => {\r\n const master = SugarElement.fromTag('span', eDoc);\r\n applyAnnotation(master, uid, data, annotationName, decorate, false);\r\n return master;\r\n };\r\n const annotate = (editor, rng, uid, annotationName, decorate, data) => {\r\n const newWrappers = [];\r\n const master = makeAnnotation(editor.getDoc(), uid, data, annotationName, decorate);\r\n const wrapper = value$2();\r\n const finishWrapper = () => {\r\n wrapper.clear();\r\n };\r\n const getOrOpenWrapper = () => wrapper.get().getOrThunk(() => {\r\n const nu = shallow$1(master);\r\n newWrappers.push(nu);\r\n wrapper.set(nu);\r\n return nu;\r\n });\r\n const processElements = elems => {\r\n each$e(elems, processElement);\r\n };\r\n const processElement = elem => {\r\n const ctx = context(editor, elem, 'span', name(elem));\r\n switch (ctx) {\r\n case 'invalid-child': {\r\n finishWrapper();\r\n const children = children$1(elem);\r\n processElements(children);\r\n finishWrapper();\r\n break;\r\n }\r\n case 'valid-block': {\r\n finishWrapper();\r\n applyAnnotation(elem, uid, data, annotationName, decorate, true);\r\n break;\r\n }\r\n case 'valid': {\r\n const w = getOrOpenWrapper();\r\n wrap$2(elem, w);\r\n break;\r\n }\r\n }\r\n };\r\n const processNodes = nodes => {\r\n const elems = map$3(nodes, SugarElement.fromDom);\r\n processElements(elems);\r\n };\r\n walk$3(editor.dom, rng, nodes => {\r\n finishWrapper();\r\n processNodes(nodes);\r\n });\r\n return newWrappers;\r\n };\r\n const annotateWithBookmark = (editor, name, settings, data) => {\r\n editor.undoManager.transact(() => {\r\n const selection = editor.selection;\r\n const initialRng = selection.getRng();\r\n const hasFakeSelection = getCellsFromEditor(editor).length > 0;\r\n const masterUid = generate$1('mce-annotation');\r\n if (initialRng.collapsed && !hasFakeSelection) {\r\n applyWordGrab(editor, initialRng);\r\n }\r\n if (selection.getRng().collapsed && !hasFakeSelection) {\r\n const wrapper = makeAnnotation(editor.getDoc(), masterUid, data, name, settings.decorate);\r\n set$1(wrapper, nbsp);\r\n selection.getRng().insertNode(wrapper.dom);\r\n selection.select(wrapper.dom);\r\n } else {\r\n preserve(selection, false, () => {\r\n runOnRanges(editor, selectionRng => {\r\n annotate(editor, selectionRng, masterUid, name, settings.decorate, data);\r\n });\r\n });\r\n }\r\n });\r\n };\r\n\r\n const Annotator = editor => {\r\n const registry = create$c();\r\n setup$w(editor, registry);\r\n const changes = setup$x(editor, registry);\r\n const isSpan = isTag('span');\r\n const removeAnnotations = elements => {\r\n each$e(elements, element => {\r\n if (isSpan(element)) {\r\n unwrap(element);\r\n } else {\r\n removeDirectAnnotation(element);\r\n }\r\n });\r\n };\r\n return {\r\n register: (name, settings) => {\r\n registry.register(name, settings);\r\n },\r\n annotate: (name, data) => {\r\n registry.lookup(name).each(settings => {\r\n annotateWithBookmark(editor, name, settings, data);\r\n });\r\n },\r\n annotationChanged: (name, callback) => {\r\n changes.addListener(name, callback);\r\n },\r\n remove: name => {\r\n identify(editor, Optional.some(name)).each(({elements}) => {\r\n const bookmark = editor.selection.getBookmark();\r\n removeAnnotations(elements);\r\n editor.selection.moveToBookmark(bookmark);\r\n });\r\n },\r\n removeAll: name => {\r\n const bookmark = editor.selection.getBookmark();\r\n each$d(findAll(editor, name), (elements, _) => {\r\n removeAnnotations(elements);\r\n });\r\n editor.selection.moveToBookmark(bookmark);\r\n },\r\n getAll: name => {\r\n const directory = findAll(editor, name);\r\n return map$2(directory, elems => map$3(elems, elem => elem.dom));\r\n }\r\n };\r\n };\r\n\r\n const BookmarkManager = selection => {\r\n return {\r\n getBookmark: curry(getBookmark$1, selection),\r\n moveToBookmark: curry(moveToBookmark, selection)\r\n };\r\n };\r\n BookmarkManager.isBookmarkNode = isBookmarkNode$1;\r\n\r\n const isXYWithinRange = (clientX, clientY, range) => {\r\n if (range.collapsed) {\r\n return false;\r\n } else {\r\n return exists(range.getClientRects(), rect => containsXY(rect, clientX, clientY));\r\n }\r\n };\r\n\r\n const firePreProcess = (editor, args) => editor.dispatch('PreProcess', args);\r\n const firePostProcess = (editor, args) => editor.dispatch('PostProcess', args);\r\n const fireRemove = editor => {\r\n editor.dispatch('remove');\r\n };\r\n const fireDetach = editor => {\r\n editor.dispatch('detach');\r\n };\r\n const fireSwitchMode = (editor, mode) => {\r\n editor.dispatch('SwitchMode', { mode });\r\n };\r\n const fireObjectResizeStart = (editor, target, width, height, origin) => {\r\n editor.dispatch('ObjectResizeStart', {\r\n target,\r\n width,\r\n height,\r\n origin\r\n });\r\n };\r\n const fireObjectResized = (editor, target, width, height, origin) => {\r\n editor.dispatch('ObjectResized', {\r\n target,\r\n width,\r\n height,\r\n origin\r\n });\r\n };\r\n const firePreInit = editor => {\r\n editor.dispatch('PreInit');\r\n };\r\n const firePostRender = editor => {\r\n editor.dispatch('PostRender');\r\n };\r\n const fireInit = editor => {\r\n editor.dispatch('Init');\r\n };\r\n const firePlaceholderToggle = (editor, state) => {\r\n editor.dispatch('PlaceholderToggle', { state });\r\n };\r\n const fireError = (editor, errorType, error) => {\r\n editor.dispatch(errorType, error);\r\n };\r\n const fireFormatApply = (editor, format, node, vars) => {\r\n editor.dispatch('FormatApply', {\r\n format,\r\n node,\r\n vars\r\n });\r\n };\r\n const fireFormatRemove = (editor, format, node, vars) => {\r\n editor.dispatch('FormatRemove', {\r\n format,\r\n node,\r\n vars\r\n });\r\n };\r\n const fireBeforeSetContent = (editor, args) => editor.dispatch('BeforeSetContent', args);\r\n const fireSetContent = (editor, args) => editor.dispatch('SetContent', args);\r\n const fireBeforeGetContent = (editor, args) => editor.dispatch('BeforeGetContent', args);\r\n const fireGetContent = (editor, args) => editor.dispatch('GetContent', args);\r\n const fireAutocompleterStart = (editor, args) => {\r\n editor.dispatch('AutocompleterStart', args);\r\n };\r\n const fireAutocompleterUpdate = (editor, args) => {\r\n editor.dispatch('AutocompleterUpdate', args);\r\n };\r\n const fireAutocompleterEnd = editor => {\r\n editor.dispatch('AutocompleterEnd');\r\n };\r\n const firePastePreProcess = (editor, html, internal) => editor.dispatch('PastePreProcess', {\r\n content: html,\r\n internal\r\n });\r\n const firePastePostProcess = (editor, node, internal) => editor.dispatch('PastePostProcess', {\r\n node,\r\n internal\r\n });\r\n const firePastePlainTextToggle = (editor, state) => editor.dispatch('PastePlainTextToggle', { state });\r\n\r\n const VK = {\r\n BACKSPACE: 8,\r\n DELETE: 46,\r\n DOWN: 40,\r\n ENTER: 13,\r\n ESC: 27,\r\n LEFT: 37,\r\n RIGHT: 39,\r\n SPACEBAR: 32,\r\n TAB: 9,\r\n UP: 38,\r\n PAGE_UP: 33,\r\n PAGE_DOWN: 34,\r\n END: 35,\r\n HOME: 36,\r\n modifierPressed: e => {\r\n return e.shiftKey || e.ctrlKey || e.altKey || VK.metaKeyPressed(e);\r\n },\r\n metaKeyPressed: e => {\r\n return Env.os.isMacOS() || Env.os.isiOS() ? e.metaKey : e.ctrlKey && !e.altKey;\r\n }\r\n };\r\n\r\n const elementSelectionAttr = 'data-mce-selected';\r\n const controlElmSelector = 'table,img,figure.image,hr,video,span.mce-preview-object';\r\n const abs = Math.abs;\r\n const round$1 = Math.round;\r\n const resizeHandles = {\r\n nw: [\r\n 0,\r\n 0,\r\n -1,\r\n -1\r\n ],\r\n ne: [\r\n 1,\r\n 0,\r\n 1,\r\n -1\r\n ],\r\n se: [\r\n 1,\r\n 1,\r\n 1,\r\n 1\r\n ],\r\n sw: [\r\n 0,\r\n 1,\r\n -1,\r\n 1\r\n ]\r\n };\r\n const isTouchEvent = evt => evt.type === 'longpress' || evt.type.indexOf('touch') === 0;\r\n const ControlSelection = (selection, editor) => {\r\n const dom = editor.dom;\r\n const editableDoc = editor.getDoc();\r\n const rootDocument = document;\r\n const rootElement = editor.getBody();\r\n let selectedElm, selectedElmGhost, resizeHelper, selectedHandle, resizeBackdrop;\r\n let startX, startY, selectedElmX, selectedElmY, startW, startH, ratio, resizeStarted;\r\n let width;\r\n let height;\r\n let startScrollWidth;\r\n let startScrollHeight;\r\n const isImage = elm => isNonNullable(elm) && (isImg(elm) || dom.is(elm, 'figure.image'));\r\n const isMedia = elm => isMedia$2(elm) || dom.hasClass(elm, 'mce-preview-object');\r\n const isEventOnImageOutsideRange = (evt, range) => {\r\n if (isTouchEvent(evt)) {\r\n const touch = evt.touches[0];\r\n return isImage(evt.target) && !isXYWithinRange(touch.clientX, touch.clientY, range);\r\n } else {\r\n return isImage(evt.target) && !isXYWithinRange(evt.clientX, evt.clientY, range);\r\n }\r\n };\r\n const contextMenuSelectImage = evt => {\r\n const target = evt.target;\r\n if (isEventOnImageOutsideRange(evt, editor.selection.getRng()) && !evt.isDefaultPrevented()) {\r\n editor.selection.select(target);\r\n }\r\n };\r\n const getResizeTargets = elm => {\r\n if (dom.hasClass(elm, 'mce-preview-object') && isNonNullable(elm.firstElementChild)) {\r\n return [\r\n elm,\r\n elm.firstElementChild\r\n ];\r\n } else if (dom.is(elm, 'figure.image')) {\r\n return [elm.querySelector('img')];\r\n } else {\r\n return [elm];\r\n }\r\n };\r\n const isResizable = elm => {\r\n const selector = getObjectResizing(editor);\r\n if (!selector) {\r\n return false;\r\n }\r\n if (elm.getAttribute('data-mce-resize') === 'false') {\r\n return false;\r\n }\r\n if (elm === editor.getBody()) {\r\n return false;\r\n }\r\n if (dom.hasClass(elm, 'mce-preview-object') && isNonNullable(elm.firstElementChild)) {\r\n return is$1(SugarElement.fromDom(elm.firstElementChild), selector);\r\n } else {\r\n return is$1(SugarElement.fromDom(elm), selector);\r\n }\r\n };\r\n const createGhostElement = elm => {\r\n if (isMedia(elm)) {\r\n return dom.create('img', { src: Env.transparentSrc });\r\n } else {\r\n return elm.cloneNode(true);\r\n }\r\n };\r\n const setSizeProp = (element, name, value) => {\r\n if (isNonNullable(value)) {\r\n const targets = getResizeTargets(element);\r\n each$e(targets, target => {\r\n if (target.style[name] || !editor.schema.isValid(target.nodeName.toLowerCase(), name)) {\r\n dom.setStyle(target, name, value);\r\n } else {\r\n dom.setAttrib(target, name, '' + value);\r\n }\r\n });\r\n }\r\n };\r\n const setGhostElmSize = (ghostElm, width, height) => {\r\n setSizeProp(ghostElm, 'width', width);\r\n setSizeProp(ghostElm, 'height', height);\r\n };\r\n const resizeGhostElement = e => {\r\n let deltaX, deltaY, proportional;\r\n let resizeHelperX, resizeHelperY;\r\n deltaX = e.screenX - startX;\r\n deltaY = e.screenY - startY;\r\n width = deltaX * selectedHandle[2] + startW;\r\n height = deltaY * selectedHandle[3] + startH;\r\n width = width < 5 ? 5 : width;\r\n height = height < 5 ? 5 : height;\r\n if ((isImage(selectedElm) || isMedia(selectedElm)) && getResizeImgProportional(editor) !== false) {\r\n proportional = !VK.modifierPressed(e);\r\n } else {\r\n proportional = VK.modifierPressed(e);\r\n }\r\n if (proportional) {\r\n if (abs(deltaX) > abs(deltaY)) {\r\n height = round$1(width * ratio);\r\n width = round$1(height / ratio);\r\n } else {\r\n width = round$1(height / ratio);\r\n height = round$1(width * ratio);\r\n }\r\n }\r\n setGhostElmSize(selectedElmGhost, width, height);\r\n resizeHelperX = selectedHandle.startPos.x + deltaX;\r\n resizeHelperY = selectedHandle.startPos.y + deltaY;\r\n resizeHelperX = resizeHelperX > 0 ? resizeHelperX : 0;\r\n resizeHelperY = resizeHelperY > 0 ? resizeHelperY : 0;\r\n dom.setStyles(resizeHelper, {\r\n left: resizeHelperX,\r\n top: resizeHelperY,\r\n display: 'block'\r\n });\r\n resizeHelper.innerHTML = width + ' × ' + height;\r\n if (selectedHandle[2] < 0 && selectedElmGhost.clientWidth <= width) {\r\n dom.setStyle(selectedElmGhost, 'left', selectedElmX + (startW - width));\r\n }\r\n if (selectedHandle[3] < 0 && selectedElmGhost.clientHeight <= height) {\r\n dom.setStyle(selectedElmGhost, 'top', selectedElmY + (startH - height));\r\n }\r\n deltaX = rootElement.scrollWidth - startScrollWidth;\r\n deltaY = rootElement.scrollHeight - startScrollHeight;\r\n if (deltaX + deltaY !== 0) {\r\n dom.setStyles(resizeHelper, {\r\n left: resizeHelperX - deltaX,\r\n top: resizeHelperY - deltaY\r\n });\r\n }\r\n if (!resizeStarted) {\r\n fireObjectResizeStart(editor, selectedElm, startW, startH, 'corner-' + selectedHandle.name);\r\n resizeStarted = true;\r\n }\r\n };\r\n const endGhostResize = () => {\r\n const wasResizeStarted = resizeStarted;\r\n resizeStarted = false;\r\n if (wasResizeStarted) {\r\n setSizeProp(selectedElm, 'width', width);\r\n setSizeProp(selectedElm, 'height', height);\r\n }\r\n dom.unbind(editableDoc, 'mousemove', resizeGhostElement);\r\n dom.unbind(editableDoc, 'mouseup', endGhostResize);\r\n if (rootDocument !== editableDoc) {\r\n dom.unbind(rootDocument, 'mousemove', resizeGhostElement);\r\n dom.unbind(rootDocument, 'mouseup', endGhostResize);\r\n }\r\n dom.remove(selectedElmGhost);\r\n dom.remove(resizeHelper);\r\n dom.remove(resizeBackdrop);\r\n showResizeRect(selectedElm);\r\n if (wasResizeStarted) {\r\n fireObjectResized(editor, selectedElm, width, height, 'corner-' + selectedHandle.name);\r\n dom.setAttrib(selectedElm, 'style', dom.getAttrib(selectedElm, 'style'));\r\n }\r\n editor.nodeChanged();\r\n };\r\n const showResizeRect = targetElm => {\r\n unbindResizeHandleEvents();\r\n const position = dom.getPos(targetElm, rootElement);\r\n const selectedElmX = position.x;\r\n const selectedElmY = position.y;\r\n const rect = targetElm.getBoundingClientRect();\r\n const targetWidth = rect.width || rect.right - rect.left;\r\n const targetHeight = rect.height || rect.bottom - rect.top;\r\n if (selectedElm !== targetElm) {\r\n hideResizeRect();\r\n selectedElm = targetElm;\r\n width = height = 0;\r\n }\r\n const e = editor.dispatch('ObjectSelected', { target: targetElm });\r\n if (isResizable(targetElm) && !e.isDefaultPrevented()) {\r\n each$d(resizeHandles, (handle, name) => {\r\n const startDrag = e => {\r\n const target = getResizeTargets(selectedElm)[0];\r\n startX = e.screenX;\r\n startY = e.screenY;\r\n startW = target.clientWidth;\r\n startH = target.clientHeight;\r\n ratio = startH / startW;\r\n selectedHandle = handle;\r\n selectedHandle.name = name;\r\n selectedHandle.startPos = {\r\n x: targetWidth * handle[0] + selectedElmX,\r\n y: targetHeight * handle[1] + selectedElmY\r\n };\r\n startScrollWidth = rootElement.scrollWidth;\r\n startScrollHeight = rootElement.scrollHeight;\r\n resizeBackdrop = dom.add(rootElement, 'div', {\r\n 'class': 'mce-resize-backdrop',\r\n 'data-mce-bogus': 'all'\r\n });\r\n dom.setStyles(resizeBackdrop, {\r\n position: 'fixed',\r\n left: '0',\r\n top: '0',\r\n width: '100%',\r\n height: '100%'\r\n });\r\n selectedElmGhost = createGhostElement(selectedElm);\r\n dom.addClass(selectedElmGhost, 'mce-clonedresizable');\r\n dom.setAttrib(selectedElmGhost, 'data-mce-bogus', 'all');\r\n selectedElmGhost.contentEditable = 'false';\r\n dom.setStyles(selectedElmGhost, {\r\n left: selectedElmX,\r\n top: selectedElmY,\r\n margin: 0\r\n });\r\n setGhostElmSize(selectedElmGhost, targetWidth, targetHeight);\r\n selectedElmGhost.removeAttribute(elementSelectionAttr);\r\n rootElement.appendChild(selectedElmGhost);\r\n dom.bind(editableDoc, 'mousemove', resizeGhostElement);\r\n dom.bind(editableDoc, 'mouseup', endGhostResize);\r\n if (rootDocument !== editableDoc) {\r\n dom.bind(rootDocument, 'mousemove', resizeGhostElement);\r\n dom.bind(rootDocument, 'mouseup', endGhostResize);\r\n }\r\n resizeHelper = dom.add(rootElement, 'div', {\r\n 'class': 'mce-resize-helper',\r\n 'data-mce-bogus': 'all'\r\n }, startW + ' × ' + startH);\r\n };\r\n let handleElm = dom.get('mceResizeHandle' + name);\r\n if (handleElm) {\r\n dom.remove(handleElm);\r\n }\r\n handleElm = dom.add(rootElement, 'div', {\r\n 'id': 'mceResizeHandle' + name,\r\n 'data-mce-bogus': 'all',\r\n 'class': 'mce-resizehandle',\r\n 'unselectable': true,\r\n 'style': 'cursor:' + name + '-resize; margin:0; padding:0'\r\n });\r\n dom.bind(handleElm, 'mousedown', e => {\r\n e.stopImmediatePropagation();\r\n e.preventDefault();\r\n startDrag(e);\r\n });\r\n handle.elm = handleElm;\r\n dom.setStyles(handleElm, {\r\n left: targetWidth * handle[0] + selectedElmX - handleElm.offsetWidth / 2,\r\n top: targetHeight * handle[1] + selectedElmY - handleElm.offsetHeight / 2\r\n });\r\n });\r\n } else {\r\n hideResizeRect(false);\r\n }\r\n };\r\n const throttledShowResizeRect = first$1(showResizeRect, 0);\r\n const hideResizeRect = (removeSelected = true) => {\r\n throttledShowResizeRect.cancel();\r\n unbindResizeHandleEvents();\r\n if (selectedElm && removeSelected) {\r\n selectedElm.removeAttribute(elementSelectionAttr);\r\n }\r\n each$d(resizeHandles, (value, name) => {\r\n const handleElm = dom.get('mceResizeHandle' + name);\r\n if (handleElm) {\r\n dom.unbind(handleElm);\r\n dom.remove(handleElm);\r\n }\r\n });\r\n };\r\n const isChildOrEqual = (node, parent) => dom.isChildOf(node, parent);\r\n const updateResizeRect = e => {\r\n if (resizeStarted || editor.removed || editor.composing) {\r\n return;\r\n }\r\n const targetElm = e.type === 'mousedown' ? e.target : selection.getNode();\r\n const controlElm = closest$3(SugarElement.fromDom(targetElm), controlElmSelector).map(e => e.dom).filter(e => dom.isEditable(e.parentElement)).getOrUndefined();\r\n const selectedValue = isNonNullable(controlElm) ? dom.getAttrib(controlElm, elementSelectionAttr, '1') : '1';\r\n each$e(dom.select(`img[${ elementSelectionAttr }],hr[${ elementSelectionAttr }]`), img => {\r\n img.removeAttribute(elementSelectionAttr);\r\n });\r\n if (isNonNullable(controlElm) && isChildOrEqual(controlElm, rootElement)) {\r\n disableGeckoResize();\r\n const startElm = selection.getStart(true);\r\n if (isChildOrEqual(startElm, controlElm) && isChildOrEqual(selection.getEnd(true), controlElm)) {\r\n dom.setAttrib(controlElm, elementSelectionAttr, selectedValue);\r\n throttledShowResizeRect.throttle(controlElm);\r\n return;\r\n }\r\n }\r\n hideResizeRect();\r\n };\r\n const unbindResizeHandleEvents = () => {\r\n each$d(resizeHandles, handle => {\r\n if (handle.elm) {\r\n dom.unbind(handle.elm);\r\n delete handle.elm;\r\n }\r\n });\r\n };\r\n const disableGeckoResize = () => {\r\n try {\r\n editor.getDoc().execCommand('enableObjectResizing', false, 'false');\r\n } catch (ex) {\r\n }\r\n };\r\n editor.on('init', () => {\r\n disableGeckoResize();\r\n editor.on('NodeChange ResizeEditor ResizeWindow ResizeContent drop', updateResizeRect);\r\n editor.on('keyup compositionend', e => {\r\n if (selectedElm && selectedElm.nodeName === 'TABLE') {\r\n updateResizeRect(e);\r\n }\r\n });\r\n editor.on('hide blur', hideResizeRect);\r\n editor.on('contextmenu longpress', contextMenuSelectImage, true);\r\n });\r\n editor.on('remove', unbindResizeHandleEvents);\r\n const destroy = () => {\r\n throttledShowResizeRect.cancel();\r\n selectedElm = selectedElmGhost = resizeBackdrop = null;\r\n };\r\n return {\r\n isResizable,\r\n showResizeRect,\r\n hideResizeRect,\r\n updateResizeRect,\r\n destroy\r\n };\r\n };\r\n\r\n const setStart = (rng, situ) => {\r\n situ.fold(e => {\r\n rng.setStartBefore(e.dom);\r\n }, (e, o) => {\r\n rng.setStart(e.dom, o);\r\n }, e => {\r\n rng.setStartAfter(e.dom);\r\n });\r\n };\r\n const setFinish = (rng, situ) => {\r\n situ.fold(e => {\r\n rng.setEndBefore(e.dom);\r\n }, (e, o) => {\r\n rng.setEnd(e.dom, o);\r\n }, e => {\r\n rng.setEndAfter(e.dom);\r\n });\r\n };\r\n const relativeToNative = (win, startSitu, finishSitu) => {\r\n const range = win.document.createRange();\r\n setStart(range, startSitu);\r\n setFinish(range, finishSitu);\r\n return range;\r\n };\r\n const exactToNative = (win, start, soffset, finish, foffset) => {\r\n const rng = win.document.createRange();\r\n rng.setStart(start.dom, soffset);\r\n rng.setEnd(finish.dom, foffset);\r\n return rng;\r\n };\r\n\r\n const adt$3 = Adt.generate([\r\n {\r\n ltr: [\r\n 'start',\r\n 'soffset',\r\n 'finish',\r\n 'foffset'\r\n ]\r\n },\r\n {\r\n rtl: [\r\n 'start',\r\n 'soffset',\r\n 'finish',\r\n 'foffset'\r\n ]\r\n }\r\n ]);\r\n const fromRange = (win, type, range) => type(SugarElement.fromDom(range.startContainer), range.startOffset, SugarElement.fromDom(range.endContainer), range.endOffset);\r\n const getRanges = (win, selection) => selection.match({\r\n domRange: rng => {\r\n return {\r\n ltr: constant(rng),\r\n rtl: Optional.none\r\n };\r\n },\r\n relative: (startSitu, finishSitu) => {\r\n return {\r\n ltr: cached(() => relativeToNative(win, startSitu, finishSitu)),\r\n rtl: cached(() => Optional.some(relativeToNative(win, finishSitu, startSitu)))\r\n };\r\n },\r\n exact: (start, soffset, finish, foffset) => {\r\n return {\r\n ltr: cached(() => exactToNative(win, start, soffset, finish, foffset)),\r\n rtl: cached(() => Optional.some(exactToNative(win, finish, foffset, start, soffset)))\r\n };\r\n }\r\n });\r\n const doDiagnose = (win, ranges) => {\r\n const rng = ranges.ltr();\r\n if (rng.collapsed) {\r\n const reversed = ranges.rtl().filter(rev => rev.collapsed === false);\r\n return reversed.map(rev => adt$3.rtl(SugarElement.fromDom(rev.endContainer), rev.endOffset, SugarElement.fromDom(rev.startContainer), rev.startOffset)).getOrThunk(() => fromRange(win, adt$3.ltr, rng));\r\n } else {\r\n return fromRange(win, adt$3.ltr, rng);\r\n }\r\n };\r\n const diagnose = (win, selection) => {\r\n const ranges = getRanges(win, selection);\r\n return doDiagnose(win, ranges);\r\n };\r\n adt$3.ltr;\r\n adt$3.rtl;\r\n\r\n const create$a = (start, soffset, finish, foffset) => ({\r\n start,\r\n soffset,\r\n finish,\r\n foffset\r\n });\r\n const SimRange = { create: create$a };\r\n\r\n const caretPositionFromPoint = (doc, x, y) => {\r\n var _a, _b;\r\n return Optional.from((_b = (_a = doc.dom).caretPositionFromPoint) === null || _b === void 0 ? void 0 : _b.call(_a, x, y)).bind(pos => {\r\n if (pos.offsetNode === null) {\r\n return Optional.none();\r\n }\r\n const r = doc.dom.createRange();\r\n r.setStart(pos.offsetNode, pos.offset);\r\n r.collapse();\r\n return Optional.some(r);\r\n });\r\n };\r\n const caretRangeFromPoint = (doc, x, y) => {\r\n var _a, _b;\r\n return Optional.from((_b = (_a = doc.dom).caretRangeFromPoint) === null || _b === void 0 ? void 0 : _b.call(_a, x, y));\r\n };\r\n const availableSearch = (() => {\r\n if (document.caretPositionFromPoint) {\r\n return caretPositionFromPoint;\r\n } else if (document.caretRangeFromPoint) {\r\n return caretRangeFromPoint;\r\n } else {\r\n return Optional.none;\r\n }\r\n })();\r\n const fromPoint$1 = (win, x, y) => {\r\n const doc = SugarElement.fromDom(win.document);\r\n return availableSearch(doc, x, y).map(rng => SimRange.create(SugarElement.fromDom(rng.startContainer), rng.startOffset, SugarElement.fromDom(rng.endContainer), rng.endOffset));\r\n };\r\n\r\n const adt$2 = Adt.generate([\r\n { before: ['element'] },\r\n {\r\n on: [\r\n 'element',\r\n 'offset'\r\n ]\r\n },\r\n { after: ['element'] }\r\n ]);\r\n const cata = (subject, onBefore, onOn, onAfter) => subject.fold(onBefore, onOn, onAfter);\r\n const getStart$2 = situ => situ.fold(identity, identity, identity);\r\n const before$1 = adt$2.before;\r\n const on = adt$2.on;\r\n const after$1 = adt$2.after;\r\n const Situ = {\r\n before: before$1,\r\n on,\r\n after: after$1,\r\n cata,\r\n getStart: getStart$2\r\n };\r\n\r\n const adt$1 = Adt.generate([\r\n { domRange: ['rng'] },\r\n {\r\n relative: [\r\n 'startSitu',\r\n 'finishSitu'\r\n ]\r\n },\r\n {\r\n exact: [\r\n 'start',\r\n 'soffset',\r\n 'finish',\r\n 'foffset'\r\n ]\r\n }\r\n ]);\r\n const exactFromRange = simRange => adt$1.exact(simRange.start, simRange.soffset, simRange.finish, simRange.foffset);\r\n const getStart$1 = selection => selection.match({\r\n domRange: rng => SugarElement.fromDom(rng.startContainer),\r\n relative: (startSitu, _finishSitu) => Situ.getStart(startSitu),\r\n exact: (start, _soffset, _finish, _foffset) => start\r\n });\r\n const domRange = adt$1.domRange;\r\n const relative = adt$1.relative;\r\n const exact = adt$1.exact;\r\n const getWin = selection => {\r\n const start = getStart$1(selection);\r\n return defaultView(start);\r\n };\r\n const range = SimRange.create;\r\n const SimSelection = {\r\n domRange,\r\n relative,\r\n exact,\r\n exactFromRange,\r\n getWin,\r\n range\r\n };\r\n\r\n const beforeSpecial = (element, offset) => {\r\n const name$1 = name(element);\r\n if ('input' === name$1) {\r\n return Situ.after(element);\r\n } else if (!contains$2([\r\n 'br',\r\n 'img'\r\n ], name$1)) {\r\n return Situ.on(element, offset);\r\n } else {\r\n return offset === 0 ? Situ.before(element) : Situ.after(element);\r\n }\r\n };\r\n const preprocessRelative = (startSitu, finishSitu) => {\r\n const start = startSitu.fold(Situ.before, beforeSpecial, Situ.after);\r\n const finish = finishSitu.fold(Situ.before, beforeSpecial, Situ.after);\r\n return SimSelection.relative(start, finish);\r\n };\r\n const preprocessExact = (start, soffset, finish, foffset) => {\r\n const startSitu = beforeSpecial(start, soffset);\r\n const finishSitu = beforeSpecial(finish, foffset);\r\n return SimSelection.relative(startSitu, finishSitu);\r\n };\r\n const preprocess = selection => selection.match({\r\n domRange: rng => {\r\n const start = SugarElement.fromDom(rng.startContainer);\r\n const finish = SugarElement.fromDom(rng.endContainer);\r\n return preprocessExact(start, rng.startOffset, finish, rng.endOffset);\r\n },\r\n relative: preprocessRelative,\r\n exact: preprocessExact\r\n });\r\n\r\n const fromElements = (elements, scope) => {\r\n const doc = scope || document;\r\n const fragment = doc.createDocumentFragment();\r\n each$e(elements, element => {\r\n fragment.appendChild(element.dom);\r\n });\r\n return SugarElement.fromDom(fragment);\r\n };\r\n\r\n const toNative = selection => {\r\n const win = SimSelection.getWin(selection).dom;\r\n const getDomRange = (start, soffset, finish, foffset) => exactToNative(win, start, soffset, finish, foffset);\r\n const filtered = preprocess(selection);\r\n return diagnose(win, filtered).match({\r\n ltr: getDomRange,\r\n rtl: getDomRange\r\n });\r\n };\r\n const getAtPoint = (win, x, y) => fromPoint$1(win, x, y);\r\n\r\n const fromPoint = (clientX, clientY, doc) => {\r\n const win = defaultView(SugarElement.fromDom(doc));\r\n return getAtPoint(win.dom, clientX, clientY).map(simRange => {\r\n const rng = doc.createRange();\r\n rng.setStart(simRange.start.dom, simRange.soffset);\r\n rng.setEnd(simRange.finish.dom, simRange.foffset);\r\n return rng;\r\n }).getOrUndefined();\r\n };\r\n\r\n const isEq$4 = (rng1, rng2) => {\r\n return isNonNullable(rng1) && isNonNullable(rng2) && (rng1.startContainer === rng2.startContainer && rng1.startOffset === rng2.startOffset) && (rng1.endContainer === rng2.endContainer && rng1.endOffset === rng2.endOffset);\r\n };\r\n\r\n const findParent = (node, rootNode, predicate) => {\r\n let currentNode = node;\r\n while (currentNode && currentNode !== rootNode) {\r\n if (predicate(currentNode)) {\r\n return currentNode;\r\n }\r\n currentNode = currentNode.parentNode;\r\n }\r\n return null;\r\n };\r\n const hasParent$1 = (node, rootNode, predicate) => findParent(node, rootNode, predicate) !== null;\r\n const hasParentWithName = (node, rootNode, name) => hasParent$1(node, rootNode, node => node.nodeName === name);\r\n const isCeFalseCaretContainer = (node, rootNode) => isCaretContainer$2(node) && !hasParent$1(node, rootNode, isCaretNode);\r\n const hasBrBeforeAfter = (dom, node, left) => {\r\n const parentNode = node.parentNode;\r\n if (parentNode) {\r\n const walker = new DomTreeWalker(node, dom.getParent(parentNode, dom.isBlock) || dom.getRoot());\r\n let currentNode;\r\n while (currentNode = walker[left ? 'prev' : 'next']()) {\r\n if (isBr$6(currentNode)) {\r\n return true;\r\n }\r\n }\r\n }\r\n return false;\r\n };\r\n const isPrevNode = (node, name) => {\r\n var _a;\r\n return ((_a = node.previousSibling) === null || _a === void 0 ? void 0 : _a.nodeName) === name;\r\n };\r\n const hasContentEditableFalseParent = (root, node) => {\r\n let currentNode = node;\r\n while (currentNode && currentNode !== root) {\r\n if (isContentEditableFalse$b(currentNode)) {\r\n return true;\r\n }\r\n currentNode = currentNode.parentNode;\r\n }\r\n return false;\r\n };\r\n const findTextNodeRelative = (dom, isAfterNode, collapsed, left, startNode) => {\r\n const body = dom.getRoot();\r\n const nonEmptyElementsMap = dom.schema.getNonEmptyElements();\r\n const parentNode = startNode.parentNode;\r\n let lastInlineElement;\r\n let node;\r\n if (!parentNode) {\r\n return Optional.none();\r\n }\r\n const parentBlockContainer = dom.getParent(parentNode, dom.isBlock) || body;\r\n if (left && isBr$6(startNode) && isAfterNode && dom.isEmpty(parentBlockContainer)) {\r\n return Optional.some(CaretPosition(parentNode, dom.nodeIndex(startNode)));\r\n }\r\n const walker = new DomTreeWalker(startNode, parentBlockContainer);\r\n while (node = walker[left ? 'prev' : 'next']()) {\r\n if (dom.getContentEditableParent(node) === 'false' || isCeFalseCaretContainer(node, body)) {\r\n return Optional.none();\r\n }\r\n if (isText$a(node) && node.data.length > 0) {\r\n if (!hasParentWithName(node, body, 'A')) {\r\n return Optional.some(CaretPosition(node, left ? node.data.length : 0));\r\n }\r\n return Optional.none();\r\n }\r\n if (dom.isBlock(node) || nonEmptyElementsMap[node.nodeName.toLowerCase()]) {\r\n return Optional.none();\r\n }\r\n lastInlineElement = node;\r\n }\r\n if (isComment(lastInlineElement)) {\r\n return Optional.none();\r\n }\r\n if (collapsed && lastInlineElement) {\r\n return Optional.some(CaretPosition(lastInlineElement, 0));\r\n }\r\n return Optional.none();\r\n };\r\n const normalizeEndPoint = (dom, collapsed, start, rng) => {\r\n const body = dom.getRoot();\r\n let node;\r\n let normalized = false;\r\n let container = start ? rng.startContainer : rng.endContainer;\r\n let offset = start ? rng.startOffset : rng.endOffset;\r\n const isAfterNode = isElement$6(container) && offset === container.childNodes.length;\r\n const nonEmptyElementsMap = dom.schema.getNonEmptyElements();\r\n let directionLeft = start;\r\n if (isCaretContainer$2(container)) {\r\n return Optional.none();\r\n }\r\n if (isElement$6(container) && offset > container.childNodes.length - 1) {\r\n directionLeft = false;\r\n }\r\n if (isDocument$1(container)) {\r\n container = body;\r\n offset = 0;\r\n }\r\n if (container === body) {\r\n if (directionLeft) {\r\n node = container.childNodes[offset > 0 ? offset - 1 : 0];\r\n if (node) {\r\n if (isCaretContainer$2(node)) {\r\n return Optional.none();\r\n }\r\n if (nonEmptyElementsMap[node.nodeName] || isTable$2(node)) {\r\n return Optional.none();\r\n }\r\n }\r\n }\r\n if (container.hasChildNodes()) {\r\n offset = Math.min(!directionLeft && offset > 0 ? offset - 1 : offset, container.childNodes.length - 1);\r\n container = container.childNodes[offset];\r\n offset = isText$a(container) && isAfterNode ? container.data.length : 0;\r\n if (!collapsed && container === body.lastChild && isTable$2(container)) {\r\n return Optional.none();\r\n }\r\n if (hasContentEditableFalseParent(body, container) || isCaretContainer$2(container)) {\r\n return Optional.none();\r\n }\r\n if (container.hasChildNodes() && !isTable$2(container)) {\r\n node = container;\r\n const walker = new DomTreeWalker(container, body);\r\n do {\r\n if (isContentEditableFalse$b(node) || isCaretContainer$2(node)) {\r\n normalized = false;\r\n break;\r\n }\r\n if (isText$a(node) && node.data.length > 0) {\r\n offset = directionLeft ? 0 : node.data.length;\r\n container = node;\r\n normalized = true;\r\n break;\r\n }\r\n if (nonEmptyElementsMap[node.nodeName.toLowerCase()] && !isTableCellOrCaption(node)) {\r\n offset = dom.nodeIndex(node);\r\n container = node.parentNode;\r\n if (!directionLeft) {\r\n offset++;\r\n }\r\n normalized = true;\r\n break;\r\n }\r\n } while (node = directionLeft ? walker.next() : walker.prev());\r\n }\r\n }\r\n }\r\n if (collapsed) {\r\n if (isText$a(container) && offset === 0) {\r\n findTextNodeRelative(dom, isAfterNode, collapsed, true, container).each(pos => {\r\n container = pos.container();\r\n offset = pos.offset();\r\n normalized = true;\r\n });\r\n }\r\n if (isElement$6(container)) {\r\n node = container.childNodes[offset];\r\n if (!node) {\r\n node = container.childNodes[offset - 1];\r\n }\r\n if (node && isBr$6(node) && !isPrevNode(node, 'A') && !hasBrBeforeAfter(dom, node, false) && !hasBrBeforeAfter(dom, node, true)) {\r\n findTextNodeRelative(dom, isAfterNode, collapsed, true, node).each(pos => {\r\n container = pos.container();\r\n offset = pos.offset();\r\n normalized = true;\r\n });\r\n }\r\n }\r\n }\r\n if (directionLeft && !collapsed && isText$a(container) && offset === container.data.length) {\r\n findTextNodeRelative(dom, isAfterNode, collapsed, false, container).each(pos => {\r\n container = pos.container();\r\n offset = pos.offset();\r\n normalized = true;\r\n });\r\n }\r\n return normalized && container ? Optional.some(CaretPosition(container, offset)) : Optional.none();\r\n };\r\n const normalize$2 = (dom, rng) => {\r\n const collapsed = rng.collapsed, normRng = rng.cloneRange();\r\n const startPos = CaretPosition.fromRangeStart(rng);\r\n normalizeEndPoint(dom, collapsed, true, normRng).each(pos => {\r\n if (!collapsed || !CaretPosition.isAbove(startPos, pos)) {\r\n normRng.setStart(pos.container(), pos.offset());\r\n }\r\n });\r\n if (!collapsed) {\r\n normalizeEndPoint(dom, collapsed, false, normRng).each(pos => {\r\n normRng.setEnd(pos.container(), pos.offset());\r\n });\r\n }\r\n if (collapsed) {\r\n normRng.collapse(true);\r\n }\r\n return isEq$4(rng, normRng) ? Optional.none() : Optional.some(normRng);\r\n };\r\n\r\n const splitText = (node, offset) => {\r\n return node.splitText(offset);\r\n };\r\n const split = rng => {\r\n let startContainer = rng.startContainer, startOffset = rng.startOffset, endContainer = rng.endContainer, endOffset = rng.endOffset;\r\n if (startContainer === endContainer && isText$a(startContainer)) {\r\n if (startOffset > 0 && startOffset < startContainer.data.length) {\r\n endContainer = splitText(startContainer, startOffset);\r\n startContainer = endContainer.previousSibling;\r\n if (endOffset > startOffset) {\r\n endOffset = endOffset - startOffset;\r\n const newContainer = splitText(endContainer, endOffset).previousSibling;\r\n startContainer = endContainer = newContainer;\r\n endOffset = newContainer.data.length;\r\n startOffset = 0;\r\n } else {\r\n endOffset = 0;\r\n }\r\n }\r\n } else {\r\n if (isText$a(startContainer) && startOffset > 0 && startOffset < startContainer.data.length) {\r\n startContainer = splitText(startContainer, startOffset);\r\n startOffset = 0;\r\n }\r\n if (isText$a(endContainer) && endOffset > 0 && endOffset < endContainer.data.length) {\r\n const newContainer = splitText(endContainer, endOffset).previousSibling;\r\n endContainer = newContainer;\r\n endOffset = newContainer.data.length;\r\n }\r\n }\r\n return {\r\n startContainer,\r\n startOffset,\r\n endContainer,\r\n endOffset\r\n };\r\n };\r\n\r\n const RangeUtils = dom => {\r\n const walk = (rng, callback) => {\r\n return walk$3(dom, rng, callback);\r\n };\r\n const split$1 = split;\r\n const normalize = rng => {\r\n return normalize$2(dom, rng).fold(never, normalizedRng => {\r\n rng.setStart(normalizedRng.startContainer, normalizedRng.startOffset);\r\n rng.setEnd(normalizedRng.endContainer, normalizedRng.endOffset);\r\n return true;\r\n });\r\n };\r\n const expand = (rng, options = { type: 'word' }) => {\r\n if (options.type === 'word') {\r\n const rangeLike = expandRng(dom, rng, [{ inline: 'span' }]);\r\n const newRange = dom.createRng();\r\n newRange.setStart(rangeLike.startContainer, rangeLike.startOffset);\r\n newRange.setEnd(rangeLike.endContainer, rangeLike.endOffset);\r\n return newRange;\r\n }\r\n return rng;\r\n };\r\n return {\r\n walk,\r\n split: split$1,\r\n expand,\r\n normalize\r\n };\r\n };\r\n RangeUtils.compareRanges = isEq$4;\r\n RangeUtils.getCaretRangeFromPoint = fromPoint;\r\n RangeUtils.getSelectedNode = getSelectedNode;\r\n RangeUtils.getNode = getNode$1;\r\n\r\n const Dimension = (name, getOffset) => {\r\n const set = (element, h) => {\r\n if (!isNumber(h) && !h.match(/^[0-9]+$/)) {\r\n throw new Error(name + '.set accepts only positive integer values. Value was ' + h);\r\n }\r\n const dom = element.dom;\r\n if (isSupported(dom)) {\r\n dom.style[name] = h + 'px';\r\n }\r\n };\r\n const get = element => {\r\n const r = getOffset(element);\r\n if (r <= 0 || r === null) {\r\n const css = get$7(element, name);\r\n return parseFloat(css) || 0;\r\n }\r\n return r;\r\n };\r\n const getOuter = get;\r\n const aggregate = (element, properties) => foldl(properties, (acc, property) => {\r\n const val = get$7(element, property);\r\n const value = val === undefined ? 0 : parseInt(val, 10);\r\n return isNaN(value) ? acc : acc + value;\r\n }, 0);\r\n const max = (element, value, properties) => {\r\n const cumulativeInclusions = aggregate(element, properties);\r\n const absoluteMax = value > cumulativeInclusions ? value - cumulativeInclusions : 0;\r\n return absoluteMax;\r\n };\r\n return {\r\n set,\r\n get,\r\n getOuter,\r\n aggregate,\r\n max\r\n };\r\n };\r\n\r\n const api = Dimension('height', element => {\r\n const dom = element.dom;\r\n return inBody(element) ? dom.getBoundingClientRect().height : dom.offsetHeight;\r\n });\r\n const get$2 = element => api.get(element);\r\n\r\n const getDocument = () => SugarElement.fromDom(document);\r\n\r\n const walkUp = (navigation, doc) => {\r\n const frame = navigation.view(doc);\r\n return frame.fold(constant([]), f => {\r\n const parent = navigation.owner(f);\r\n const rest = walkUp(navigation, parent);\r\n return [f].concat(rest);\r\n });\r\n };\r\n const pathTo = (element, navigation) => {\r\n const d = navigation.owner(element);\r\n return walkUp(navigation, d);\r\n };\r\n\r\n const view = doc => {\r\n var _a;\r\n const element = doc.dom === document ? Optional.none() : Optional.from((_a = doc.dom.defaultView) === null || _a === void 0 ? void 0 : _a.frameElement);\r\n return element.map(SugarElement.fromDom);\r\n };\r\n const owner = element => documentOrOwner(element);\r\n\r\n var Navigation = /*#__PURE__*/Object.freeze({\r\n __proto__: null,\r\n view: view,\r\n owner: owner\r\n });\r\n\r\n const find = element => {\r\n const doc = getDocument();\r\n const scroll = get$5(doc);\r\n const frames = pathTo(element, Navigation);\r\n const offset = viewport(element);\r\n const r = foldr(frames, (b, a) => {\r\n const loc = viewport(a);\r\n return {\r\n left: b.left + loc.left,\r\n top: b.top + loc.top\r\n };\r\n }, {\r\n left: 0,\r\n top: 0\r\n });\r\n return SugarPosition(r.left + offset.left + scroll.left, r.top + offset.top + scroll.top);\r\n };\r\n\r\n const excludeFromDescend = element => name(element) === 'textarea';\r\n const fireScrollIntoViewEvent = (editor, data) => {\r\n const scrollEvent = editor.dispatch('ScrollIntoView', data);\r\n return scrollEvent.isDefaultPrevented();\r\n };\r\n const fireAfterScrollIntoViewEvent = (editor, data) => {\r\n editor.dispatch('AfterScrollIntoView', data);\r\n };\r\n const descend = (element, offset) => {\r\n const children = children$1(element);\r\n if (children.length === 0 || excludeFromDescend(element)) {\r\n return {\r\n element,\r\n offset\r\n };\r\n } else if (offset < children.length && !excludeFromDescend(children[offset])) {\r\n return {\r\n element: children[offset],\r\n offset: 0\r\n };\r\n } else {\r\n const last = children[children.length - 1];\r\n if (excludeFromDescend(last)) {\r\n return {\r\n element,\r\n offset\r\n };\r\n } else {\r\n if (name(last) === 'img') {\r\n return {\r\n element: last,\r\n offset: 1\r\n };\r\n } else if (isText$b(last)) {\r\n return {\r\n element: last,\r\n offset: get$3(last).length\r\n };\r\n } else {\r\n return {\r\n element: last,\r\n offset: children$1(last).length\r\n };\r\n }\r\n }\r\n }\r\n };\r\n const markerInfo = (element, cleanupFun) => {\r\n const pos = absolute(element);\r\n const height = get$2(element);\r\n return {\r\n element,\r\n bottom: pos.top + height,\r\n height,\r\n pos,\r\n cleanup: cleanupFun\r\n };\r\n };\r\n const createMarker$1 = (element, offset) => {\r\n const startPoint = descend(element, offset);\r\n const span = SugarElement.fromHtml('' + ZWSP$1 + '');\r\n before$3(startPoint.element, span);\r\n return markerInfo(span, () => remove$6(span));\r\n };\r\n const elementMarker = element => markerInfo(SugarElement.fromDom(element), noop);\r\n const withMarker = (editor, f, rng, alignToTop) => {\r\n preserveWith(editor, (_s, _e) => applyWithMarker(editor, f, rng, alignToTop), rng);\r\n };\r\n const withScrollEvents = (editor, doc, f, marker, alignToTop) => {\r\n const data = {\r\n elm: marker.element.dom,\r\n alignToTop\r\n };\r\n if (fireScrollIntoViewEvent(editor, data)) {\r\n return;\r\n }\r\n const scrollTop = get$5(doc).top;\r\n f(doc, scrollTop, marker, alignToTop);\r\n fireAfterScrollIntoViewEvent(editor, data);\r\n };\r\n const applyWithMarker = (editor, f, rng, alignToTop) => {\r\n const body = SugarElement.fromDom(editor.getBody());\r\n const doc = SugarElement.fromDom(editor.getDoc());\r\n reflow(body);\r\n const marker = createMarker$1(SugarElement.fromDom(rng.startContainer), rng.startOffset);\r\n withScrollEvents(editor, doc, f, marker, alignToTop);\r\n marker.cleanup();\r\n };\r\n const withElement = (editor, element, f, alignToTop) => {\r\n const doc = SugarElement.fromDom(editor.getDoc());\r\n withScrollEvents(editor, doc, f, elementMarker(element), alignToTop);\r\n };\r\n const preserveWith = (editor, f, rng) => {\r\n const startElement = rng.startContainer;\r\n const startOffset = rng.startOffset;\r\n const endElement = rng.endContainer;\r\n const endOffset = rng.endOffset;\r\n f(SugarElement.fromDom(startElement), SugarElement.fromDom(endElement));\r\n const newRng = editor.dom.createRng();\r\n newRng.setStart(startElement, startOffset);\r\n newRng.setEnd(endElement, endOffset);\r\n editor.selection.setRng(rng);\r\n };\r\n const scrollToMarker = (marker, viewHeight, alignToTop, doc) => {\r\n const pos = marker.pos;\r\n if (alignToTop) {\r\n to(pos.left, pos.top, doc);\r\n } else {\r\n const y = pos.top - viewHeight + marker.height;\r\n to(pos.left, y, doc);\r\n }\r\n };\r\n const intoWindowIfNeeded = (doc, scrollTop, viewHeight, marker, alignToTop) => {\r\n const viewportBottom = viewHeight + scrollTop;\r\n const markerTop = marker.pos.top;\r\n const markerBottom = marker.bottom;\r\n const largerThanViewport = markerBottom - markerTop >= viewHeight;\r\n if (markerTop < scrollTop) {\r\n scrollToMarker(marker, viewHeight, alignToTop !== false, doc);\r\n } else if (markerTop > viewportBottom) {\r\n const align = largerThanViewport ? alignToTop !== false : alignToTop === true;\r\n scrollToMarker(marker, viewHeight, align, doc);\r\n } else if (markerBottom > viewportBottom && !largerThanViewport) {\r\n scrollToMarker(marker, viewHeight, alignToTop === true, doc);\r\n }\r\n };\r\n const intoWindow = (doc, scrollTop, marker, alignToTop) => {\r\n const viewHeight = defaultView(doc).dom.innerHeight;\r\n intoWindowIfNeeded(doc, scrollTop, viewHeight, marker, alignToTop);\r\n };\r\n const intoFrame = (doc, scrollTop, marker, alignToTop) => {\r\n const frameViewHeight = defaultView(doc).dom.innerHeight;\r\n intoWindowIfNeeded(doc, scrollTop, frameViewHeight, marker, alignToTop);\r\n const op = find(marker.element);\r\n const viewportBounds = getBounds(window);\r\n if (op.top < viewportBounds.y) {\r\n intoView(marker.element, alignToTop !== false);\r\n } else if (op.top > viewportBounds.bottom) {\r\n intoView(marker.element, alignToTop === true);\r\n }\r\n };\r\n const rangeIntoWindow = (editor, rng, alignToTop) => withMarker(editor, intoWindow, rng, alignToTop);\r\n const elementIntoWindow = (editor, element, alignToTop) => withElement(editor, element, intoWindow, alignToTop);\r\n const rangeIntoFrame = (editor, rng, alignToTop) => withMarker(editor, intoFrame, rng, alignToTop);\r\n const elementIntoFrame = (editor, element, alignToTop) => withElement(editor, element, intoFrame, alignToTop);\r\n const scrollElementIntoView = (editor, element, alignToTop) => {\r\n const scroller = editor.inline ? elementIntoWindow : elementIntoFrame;\r\n scroller(editor, element, alignToTop);\r\n };\r\n const scrollRangeIntoView = (editor, rng, alignToTop) => {\r\n const scroller = editor.inline ? rangeIntoWindow : rangeIntoFrame;\r\n scroller(editor, rng, alignToTop);\r\n };\r\n\r\n const focus$1 = element => element.dom.focus();\r\n const hasFocus$1 = element => {\r\n const root = getRootNode(element).dom;\r\n return element.dom === root.activeElement;\r\n };\r\n const active$1 = (root = getDocument()) => Optional.from(root.dom.activeElement).map(SugarElement.fromDom);\r\n const search = element => active$1(getRootNode(element)).filter(e => element.dom.contains(e.dom));\r\n\r\n const clamp$1 = (offset, element) => {\r\n const max = isText$b(element) ? get$3(element).length : children$1(element).length + 1;\r\n if (offset > max) {\r\n return max;\r\n } else if (offset < 0) {\r\n return 0;\r\n }\r\n return offset;\r\n };\r\n const normalizeRng = rng => SimSelection.range(rng.start, clamp$1(rng.soffset, rng.start), rng.finish, clamp$1(rng.foffset, rng.finish));\r\n const isOrContains = (root, elm) => !isRestrictedNode(elm.dom) && (contains(root, elm) || eq(root, elm));\r\n const isRngInRoot = root => rng => isOrContains(root, rng.start) && isOrContains(root, rng.finish);\r\n const shouldStore = editor => editor.inline || Env.browser.isFirefox();\r\n const nativeRangeToSelectionRange = r => SimSelection.range(SugarElement.fromDom(r.startContainer), r.startOffset, SugarElement.fromDom(r.endContainer), r.endOffset);\r\n const readRange = win => {\r\n const selection = win.getSelection();\r\n const rng = !selection || selection.rangeCount === 0 ? Optional.none() : Optional.from(selection.getRangeAt(0));\r\n return rng.map(nativeRangeToSelectionRange);\r\n };\r\n const getBookmark = root => {\r\n const win = defaultView(root);\r\n return readRange(win.dom).filter(isRngInRoot(root));\r\n };\r\n const validate = (root, bookmark) => Optional.from(bookmark).filter(isRngInRoot(root)).map(normalizeRng);\r\n const bookmarkToNativeRng = bookmark => {\r\n const rng = document.createRange();\r\n try {\r\n rng.setStart(bookmark.start.dom, bookmark.soffset);\r\n rng.setEnd(bookmark.finish.dom, bookmark.foffset);\r\n return Optional.some(rng);\r\n } catch (_) {\r\n return Optional.none();\r\n }\r\n };\r\n const store = editor => {\r\n const newBookmark = shouldStore(editor) ? getBookmark(SugarElement.fromDom(editor.getBody())) : Optional.none();\r\n editor.bookmark = newBookmark.isSome() ? newBookmark : editor.bookmark;\r\n };\r\n const getRng = editor => {\r\n const bookmark = editor.bookmark ? editor.bookmark : Optional.none();\r\n return bookmark.bind(x => validate(SugarElement.fromDom(editor.getBody()), x)).bind(bookmarkToNativeRng);\r\n };\r\n const restore = editor => {\r\n getRng(editor).each(rng => editor.selection.setRng(rng));\r\n };\r\n\r\n const isEditorUIElement$1 = elm => {\r\n const className = elm.className.toString();\r\n return className.indexOf('tox-') !== -1 || className.indexOf('mce-') !== -1;\r\n };\r\n const FocusManager = { isEditorUIElement: isEditorUIElement$1 };\r\n\r\n const wrappedSetTimeout = (callback, time) => {\r\n if (!isNumber(time)) {\r\n time = 0;\r\n }\r\n return setTimeout(callback, time);\r\n };\r\n const wrappedSetInterval = (callback, time) => {\r\n if (!isNumber(time)) {\r\n time = 0;\r\n }\r\n return setInterval(callback, time);\r\n };\r\n const Delay = {\r\n setEditorTimeout: (editor, callback, time) => {\r\n return wrappedSetTimeout(() => {\r\n if (!editor.removed) {\r\n callback();\r\n }\r\n }, time);\r\n },\r\n setEditorInterval: (editor, callback, time) => {\r\n const timer = wrappedSetInterval(() => {\r\n if (!editor.removed) {\r\n callback();\r\n } else {\r\n clearInterval(timer);\r\n }\r\n }, time);\r\n return timer;\r\n }\r\n };\r\n\r\n const isManualNodeChange = e => {\r\n return e.type === 'nodechange' && e.selectionChange;\r\n };\r\n const registerPageMouseUp = (editor, throttledStore) => {\r\n const mouseUpPage = () => {\r\n throttledStore.throttle();\r\n };\r\n DOMUtils.DOM.bind(document, 'mouseup', mouseUpPage);\r\n editor.on('remove', () => {\r\n DOMUtils.DOM.unbind(document, 'mouseup', mouseUpPage);\r\n });\r\n };\r\n const registerMouseUp = (editor, throttledStore) => {\r\n editor.on('mouseup touchend', _e => {\r\n throttledStore.throttle();\r\n });\r\n };\r\n const registerEditorEvents = (editor, throttledStore) => {\r\n registerMouseUp(editor, throttledStore);\r\n editor.on('keyup NodeChange AfterSetSelectionRange', e => {\r\n if (!isManualNodeChange(e)) {\r\n store(editor);\r\n }\r\n });\r\n };\r\n const register$6 = editor => {\r\n const throttledStore = first$1(() => {\r\n store(editor);\r\n }, 0);\r\n editor.on('init', () => {\r\n if (editor.inline) {\r\n registerPageMouseUp(editor, throttledStore);\r\n }\r\n registerEditorEvents(editor, throttledStore);\r\n });\r\n editor.on('remove', () => {\r\n throttledStore.cancel();\r\n });\r\n };\r\n\r\n let documentFocusInHandler;\r\n const DOM$9 = DOMUtils.DOM;\r\n const isEditorUIElement = elm => {\r\n return isElement$6(elm) && FocusManager.isEditorUIElement(elm);\r\n };\r\n const isEditorContentAreaElement = elm => {\r\n const classList = elm.classList;\r\n if (classList !== undefined) {\r\n return classList.contains('tox-edit-area') || classList.contains('tox-edit-area__iframe') || classList.contains('mce-content-body');\r\n } else {\r\n return false;\r\n }\r\n };\r\n const isUIElement = (editor, elm) => {\r\n const customSelector = getCustomUiSelector(editor);\r\n const parent = DOM$9.getParent(elm, elm => {\r\n return isEditorUIElement(elm) || (customSelector ? editor.dom.is(elm, customSelector) : false);\r\n });\r\n return parent !== null;\r\n };\r\n const getActiveElement = editor => {\r\n try {\r\n const root = getRootNode(SugarElement.fromDom(editor.getElement()));\r\n return active$1(root).fold(() => document.body, x => x.dom);\r\n } catch (ex) {\r\n return document.body;\r\n }\r\n };\r\n const registerEvents$1 = (editorManager, e) => {\r\n const editor = e.editor;\r\n register$6(editor);\r\n const toggleContentAreaOnFocus = (editor, fn) => {\r\n if (shouldHighlightOnFocus(editor) && editor.inline !== true) {\r\n const contentArea = SugarElement.fromDom(editor.getContainer());\r\n fn(contentArea, 'tox-edit-focus');\r\n }\r\n };\r\n editor.on('focusin', () => {\r\n const focusedEditor = editorManager.focusedEditor;\r\n if (isEditorContentAreaElement(getActiveElement(editor))) {\r\n toggleContentAreaOnFocus(editor, add$2);\r\n }\r\n if (focusedEditor !== editor) {\r\n if (focusedEditor) {\r\n focusedEditor.dispatch('blur', { focusedEditor: editor });\r\n }\r\n editorManager.setActive(editor);\r\n editorManager.focusedEditor = editor;\r\n editor.dispatch('focus', { blurredEditor: focusedEditor });\r\n editor.focus(true);\r\n }\r\n });\r\n editor.on('focusout', () => {\r\n Delay.setEditorTimeout(editor, () => {\r\n const focusedEditor = editorManager.focusedEditor;\r\n if (!isEditorContentAreaElement(getActiveElement(editor)) || focusedEditor !== editor) {\r\n toggleContentAreaOnFocus(editor, remove$8);\r\n }\r\n if (!isUIElement(editor, getActiveElement(editor)) && focusedEditor === editor) {\r\n editor.dispatch('blur', { focusedEditor: null });\r\n editorManager.focusedEditor = null;\r\n }\r\n });\r\n });\r\n if (!documentFocusInHandler) {\r\n documentFocusInHandler = e => {\r\n const activeEditor = editorManager.activeEditor;\r\n if (activeEditor) {\r\n getOriginalEventTarget(e).each(target => {\r\n const elem = target;\r\n if (elem.ownerDocument === document) {\r\n if (elem !== document.body && !isUIElement(activeEditor, elem) && editorManager.focusedEditor === activeEditor) {\r\n activeEditor.dispatch('blur', { focusedEditor: null });\r\n editorManager.focusedEditor = null;\r\n }\r\n }\r\n });\r\n }\r\n };\r\n DOM$9.bind(document, 'focusin', documentFocusInHandler);\r\n }\r\n };\r\n const unregisterDocumentEvents = (editorManager, e) => {\r\n if (editorManager.focusedEditor === e.editor) {\r\n editorManager.focusedEditor = null;\r\n }\r\n if (!editorManager.activeEditor && documentFocusInHandler) {\r\n DOM$9.unbind(document, 'focusin', documentFocusInHandler);\r\n documentFocusInHandler = null;\r\n }\r\n };\r\n const setup$v = editorManager => {\r\n editorManager.on('AddEditor', curry(registerEvents$1, editorManager));\r\n editorManager.on('RemoveEditor', curry(unregisterDocumentEvents, editorManager));\r\n };\r\n\r\n const getContentEditableHost = (editor, node) => editor.dom.getParent(node, node => editor.dom.getContentEditable(node) === 'true');\r\n const getCollapsedNode = rng => rng.collapsed ? Optional.from(getNode$1(rng.startContainer, rng.startOffset)).map(SugarElement.fromDom) : Optional.none();\r\n const getFocusInElement = (root, rng) => getCollapsedNode(rng).bind(node => {\r\n if (isTableSection(node)) {\r\n return Optional.some(node);\r\n } else if (!contains(root, node)) {\r\n return Optional.some(root);\r\n } else {\r\n return Optional.none();\r\n }\r\n });\r\n const normalizeSelection = (editor, rng) => {\r\n getFocusInElement(SugarElement.fromDom(editor.getBody()), rng).bind(elm => {\r\n return firstPositionIn(elm.dom);\r\n }).fold(() => {\r\n editor.selection.normalize();\r\n }, caretPos => editor.selection.setRng(caretPos.toRange()));\r\n };\r\n const focusBody = body => {\r\n if (body.setActive) {\r\n try {\r\n body.setActive();\r\n } catch (ex) {\r\n body.focus();\r\n }\r\n } else {\r\n body.focus();\r\n }\r\n };\r\n const hasElementFocus = elm => hasFocus$1(elm) || search(elm).isSome();\r\n const hasIframeFocus = editor => isNonNullable(editor.iframeElement) && hasFocus$1(SugarElement.fromDom(editor.iframeElement));\r\n const hasInlineFocus = editor => {\r\n const rawBody = editor.getBody();\r\n return rawBody && hasElementFocus(SugarElement.fromDom(rawBody));\r\n };\r\n const hasUiFocus = editor => {\r\n const dos = getRootNode(SugarElement.fromDom(editor.getElement()));\r\n return active$1(dos).filter(elem => !isEditorContentAreaElement(elem.dom) && isUIElement(editor, elem.dom)).isSome();\r\n };\r\n const hasFocus = editor => editor.inline ? hasInlineFocus(editor) : hasIframeFocus(editor);\r\n const hasEditorOrUiFocus = editor => hasFocus(editor) || hasUiFocus(editor);\r\n const focusEditor = editor => {\r\n const selection = editor.selection;\r\n const body = editor.getBody();\r\n let rng = selection.getRng();\r\n editor.quirks.refreshContentEditable();\r\n if (isNonNullable(editor.bookmark) && !hasFocus(editor)) {\r\n getRng(editor).each(bookmarkRng => {\r\n editor.selection.setRng(bookmarkRng);\r\n rng = bookmarkRng;\r\n });\r\n }\r\n const contentEditableHost = getContentEditableHost(editor, selection.getNode());\r\n if (contentEditableHost && editor.dom.isChildOf(contentEditableHost, body)) {\r\n focusBody(contentEditableHost);\r\n normalizeSelection(editor, rng);\r\n activateEditor(editor);\r\n return;\r\n }\r\n if (!editor.inline) {\r\n if (!Env.browser.isOpera()) {\r\n focusBody(body);\r\n }\r\n editor.getWin().focus();\r\n }\r\n if (Env.browser.isFirefox() || editor.inline) {\r\n focusBody(body);\r\n normalizeSelection(editor, rng);\r\n }\r\n activateEditor(editor);\r\n };\r\n const activateEditor = editor => editor.editorManager.setActive(editor);\r\n const focus = (editor, skipFocus) => {\r\n if (editor.removed) {\r\n return;\r\n }\r\n if (skipFocus) {\r\n activateEditor(editor);\r\n } else {\r\n focusEditor(editor);\r\n }\r\n };\r\n\r\n const getEndpointElement = (root, rng, start, real, resolve) => {\r\n const container = start ? rng.startContainer : rng.endContainer;\r\n const offset = start ? rng.startOffset : rng.endOffset;\r\n return Optional.from(container).map(SugarElement.fromDom).map(elm => !real || !rng.collapsed ? child$1(elm, resolve(elm, offset)).getOr(elm) : elm).bind(elm => isElement$7(elm) ? Optional.some(elm) : parent(elm).filter(isElement$7)).map(elm => elm.dom).getOr(root);\r\n };\r\n const getStart = (root, rng, real = false) => getEndpointElement(root, rng, true, real, (elm, offset) => Math.min(childNodesCount(elm), offset));\r\n const getEnd$1 = (root, rng, real = false) => getEndpointElement(root, rng, false, real, (elm, offset) => offset > 0 ? offset - 1 : offset);\r\n const skipEmptyTextNodes = (node, forwards) => {\r\n const orig = node;\r\n while (node && isText$a(node) && node.length === 0) {\r\n node = forwards ? node.nextSibling : node.previousSibling;\r\n }\r\n return node || orig;\r\n };\r\n const getNode = (root, rng) => {\r\n if (!rng) {\r\n return root;\r\n }\r\n let startContainer = rng.startContainer;\r\n let endContainer = rng.endContainer;\r\n const startOffset = rng.startOffset;\r\n const endOffset = rng.endOffset;\r\n let node = rng.commonAncestorContainer;\r\n if (!rng.collapsed) {\r\n if (startContainer === endContainer) {\r\n if (endOffset - startOffset < 2) {\r\n if (startContainer.hasChildNodes()) {\r\n node = startContainer.childNodes[startOffset];\r\n }\r\n }\r\n }\r\n if (isText$a(startContainer) && isText$a(endContainer)) {\r\n if (startContainer.length === startOffset) {\r\n startContainer = skipEmptyTextNodes(startContainer.nextSibling, true);\r\n } else {\r\n startContainer = startContainer.parentNode;\r\n }\r\n if (endOffset === 0) {\r\n endContainer = skipEmptyTextNodes(endContainer.previousSibling, false);\r\n } else {\r\n endContainer = endContainer.parentNode;\r\n }\r\n if (startContainer && startContainer === endContainer) {\r\n node = startContainer;\r\n }\r\n }\r\n }\r\n const elm = isText$a(node) ? node.parentNode : node;\r\n return isElement$6(elm) ? elm : root;\r\n };\r\n const getSelectedBlocks = (dom, rng, startElm, endElm) => {\r\n const selectedBlocks = [];\r\n const root = dom.getRoot();\r\n const start = dom.getParent(startElm || getStart(root, rng, rng.collapsed), dom.isBlock);\r\n const end = dom.getParent(endElm || getEnd$1(root, rng, rng.collapsed), dom.isBlock);\r\n if (start && start !== root) {\r\n selectedBlocks.push(start);\r\n }\r\n if (start && end && start !== end) {\r\n let node;\r\n const walker = new DomTreeWalker(start, root);\r\n while ((node = walker.next()) && node !== end) {\r\n if (dom.isBlock(node)) {\r\n selectedBlocks.push(node);\r\n }\r\n }\r\n }\r\n if (end && start !== end && end !== root) {\r\n selectedBlocks.push(end);\r\n }\r\n return selectedBlocks;\r\n };\r\n const select = (dom, node, content) => Optional.from(node).bind(node => Optional.from(node.parentNode).map(parent => {\r\n const idx = dom.nodeIndex(node);\r\n const rng = dom.createRng();\r\n rng.setStart(parent, idx);\r\n rng.setEnd(parent, idx + 1);\r\n if (content) {\r\n moveEndPoint(dom, rng, node, true);\r\n moveEndPoint(dom, rng, node, false);\r\n }\r\n return rng;\r\n }));\r\n\r\n const processRanges = (editor, ranges) => map$3(ranges, range => {\r\n const evt = editor.dispatch('GetSelectionRange', { range });\r\n return evt.range !== range ? evt.range : range;\r\n });\r\n\r\n const getEnd = element => name(element) === 'img' ? 1 : getOption(element).fold(() => children$1(element).length, v => v.length);\r\n const isTextNodeWithCursorPosition = el => getOption(el).filter(text => text.trim().length !== 0 || text.indexOf(nbsp) > -1).isSome();\r\n const isContentEditableFalse$5 = elem => isHTMLElement(elem) && get$9(elem, 'contenteditable') === 'false';\r\n const elementsWithCursorPosition = [\r\n 'img',\r\n 'br'\r\n ];\r\n const isCursorPosition = elem => {\r\n const hasCursorPosition = isTextNodeWithCursorPosition(elem);\r\n return hasCursorPosition || contains$2(elementsWithCursorPosition, name(elem)) || isContentEditableFalse$5(elem);\r\n };\r\n\r\n const first = element => descendant$1(element, isCursorPosition);\r\n const last = element => descendantRtl(element, isCursorPosition);\r\n const descendantRtl = (scope, predicate) => {\r\n const descend = element => {\r\n const children = children$1(element);\r\n for (let i = children.length - 1; i >= 0; i--) {\r\n const child = children[i];\r\n if (predicate(child)) {\r\n return Optional.some(child);\r\n }\r\n const res = descend(child);\r\n if (res.isSome()) {\r\n return res;\r\n }\r\n }\r\n return Optional.none();\r\n };\r\n return descend(scope);\r\n };\r\n\r\n const autocompleteSelector = '[data-mce-autocompleter]';\r\n const create$9 = (editor, range) => {\r\n if (findIn(SugarElement.fromDom(editor.getBody())).isNone()) {\r\n const wrapper = SugarElement.fromHtml('', editor.getDoc());\r\n append$1(wrapper, SugarElement.fromDom(range.extractContents()));\r\n range.insertNode(wrapper.dom);\r\n parent(wrapper).each(elm => elm.dom.normalize());\r\n last(wrapper).map(last => {\r\n editor.selection.setCursorLocation(last.dom, getEnd(last));\r\n });\r\n }\r\n };\r\n const detect$1 = elm => closest$3(elm, autocompleteSelector);\r\n const findIn = elm => descendant(elm, autocompleteSelector);\r\n const remove$3 = (editor, elm) => findIn(elm).each(wrapper => {\r\n const bookmark = editor.selection.getBookmark();\r\n unwrap(wrapper);\r\n editor.selection.moveToBookmark(bookmark);\r\n });\r\n\r\n const typeLookup = {\r\n '#text': 3,\r\n '#comment': 8,\r\n '#cdata': 4,\r\n '#pi': 7,\r\n '#doctype': 10,\r\n '#document-fragment': 11\r\n };\r\n const walk$2 = (node, root, prev) => {\r\n const startName = prev ? 'lastChild' : 'firstChild';\r\n const siblingName = prev ? 'prev' : 'next';\r\n if (node[startName]) {\r\n return node[startName];\r\n }\r\n if (node !== root) {\r\n let sibling = node[siblingName];\r\n if (sibling) {\r\n return sibling;\r\n }\r\n for (let parent = node.parent; parent && parent !== root; parent = parent.parent) {\r\n sibling = parent[siblingName];\r\n if (sibling) {\r\n return sibling;\r\n }\r\n }\r\n }\r\n return undefined;\r\n };\r\n const isEmptyTextNode = node => {\r\n var _a;\r\n const text = (_a = node.value) !== null && _a !== void 0 ? _a : '';\r\n if (!isWhitespaceText(text)) {\r\n return false;\r\n }\r\n const parentNode = node.parent;\r\n if (parentNode && (parentNode.name !== 'span' || parentNode.attr('style')) && /^[ ]+$/.test(text)) {\r\n return false;\r\n }\r\n return true;\r\n };\r\n const isNonEmptyElement = node => {\r\n const isNamedAnchor = node.name === 'a' && !node.attr('href') && node.attr('id');\r\n return node.attr('name') || node.attr('id') && !node.firstChild || node.attr('data-mce-bookmark') || isNamedAnchor;\r\n };\r\n class AstNode {\r\n constructor(name, type) {\r\n this.name = name;\r\n this.type = type;\r\n if (type === 1) {\r\n this.attributes = [];\r\n this.attributes.map = {};\r\n }\r\n }\r\n static create(name, attrs) {\r\n const node = new AstNode(name, typeLookup[name] || 1);\r\n if (attrs) {\r\n each$d(attrs, (value, attrName) => {\r\n node.attr(attrName, value);\r\n });\r\n }\r\n return node;\r\n }\r\n replace(node) {\r\n const self = this;\r\n if (node.parent) {\r\n node.remove();\r\n }\r\n self.insert(node, self);\r\n self.remove();\r\n return self;\r\n }\r\n attr(name, value) {\r\n const self = this;\r\n if (!isString(name)) {\r\n if (isNonNullable(name)) {\r\n each$d(name, (value, key) => {\r\n self.attr(key, value);\r\n });\r\n }\r\n return self;\r\n }\r\n const attrs = self.attributes;\r\n if (attrs) {\r\n if (value !== undefined) {\r\n if (value === null) {\r\n if (name in attrs.map) {\r\n delete attrs.map[name];\r\n let i = attrs.length;\r\n while (i--) {\r\n if (attrs[i].name === name) {\r\n attrs.splice(i, 1);\r\n return self;\r\n }\r\n }\r\n }\r\n return self;\r\n }\r\n if (name in attrs.map) {\r\n let i = attrs.length;\r\n while (i--) {\r\n if (attrs[i].name === name) {\r\n attrs[i].value = value;\r\n break;\r\n }\r\n }\r\n } else {\r\n attrs.push({\r\n name,\r\n value\r\n });\r\n }\r\n attrs.map[name] = value;\r\n return self;\r\n }\r\n return attrs.map[name];\r\n }\r\n return undefined;\r\n }\r\n clone() {\r\n const self = this;\r\n const clone = new AstNode(self.name, self.type);\r\n const selfAttrs = self.attributes;\r\n if (selfAttrs) {\r\n const cloneAttrs = [];\r\n cloneAttrs.map = {};\r\n for (let i = 0, l = selfAttrs.length; i < l; i++) {\r\n const selfAttr = selfAttrs[i];\r\n if (selfAttr.name !== 'id') {\r\n cloneAttrs[cloneAttrs.length] = {\r\n name: selfAttr.name,\r\n value: selfAttr.value\r\n };\r\n cloneAttrs.map[selfAttr.name] = selfAttr.value;\r\n }\r\n }\r\n clone.attributes = cloneAttrs;\r\n }\r\n clone.value = self.value;\r\n return clone;\r\n }\r\n wrap(wrapper) {\r\n const self = this;\r\n if (self.parent) {\r\n self.parent.insert(wrapper, self);\r\n wrapper.append(self);\r\n }\r\n return self;\r\n }\r\n unwrap() {\r\n const self = this;\r\n for (let node = self.firstChild; node;) {\r\n const next = node.next;\r\n self.insert(node, self, true);\r\n node = next;\r\n }\r\n self.remove();\r\n }\r\n remove() {\r\n const self = this, parent = self.parent, next = self.next, prev = self.prev;\r\n if (parent) {\r\n if (parent.firstChild === self) {\r\n parent.firstChild = next;\r\n if (next) {\r\n next.prev = null;\r\n }\r\n } else if (prev) {\r\n prev.next = next;\r\n }\r\n if (parent.lastChild === self) {\r\n parent.lastChild = prev;\r\n if (prev) {\r\n prev.next = null;\r\n }\r\n } else if (next) {\r\n next.prev = prev;\r\n }\r\n self.parent = self.next = self.prev = null;\r\n }\r\n return self;\r\n }\r\n append(node) {\r\n const self = this;\r\n if (node.parent) {\r\n node.remove();\r\n }\r\n const last = self.lastChild;\r\n if (last) {\r\n last.next = node;\r\n node.prev = last;\r\n self.lastChild = node;\r\n } else {\r\n self.lastChild = self.firstChild = node;\r\n }\r\n node.parent = self;\r\n return node;\r\n }\r\n insert(node, refNode, before) {\r\n if (node.parent) {\r\n node.remove();\r\n }\r\n const parent = refNode.parent || this;\r\n if (before) {\r\n if (refNode === parent.firstChild) {\r\n parent.firstChild = node;\r\n } else if (refNode.prev) {\r\n refNode.prev.next = node;\r\n }\r\n node.prev = refNode.prev;\r\n node.next = refNode;\r\n refNode.prev = node;\r\n } else {\r\n if (refNode === parent.lastChild) {\r\n parent.lastChild = node;\r\n } else if (refNode.next) {\r\n refNode.next.prev = node;\r\n }\r\n node.next = refNode.next;\r\n node.prev = refNode;\r\n refNode.next = node;\r\n }\r\n node.parent = parent;\r\n return node;\r\n }\r\n getAll(name) {\r\n const self = this;\r\n const collection = [];\r\n for (let node = self.firstChild; node; node = walk$2(node, self)) {\r\n if (node.name === name) {\r\n collection.push(node);\r\n }\r\n }\r\n return collection;\r\n }\r\n children() {\r\n const self = this;\r\n const collection = [];\r\n for (let node = self.firstChild; node; node = node.next) {\r\n collection.push(node);\r\n }\r\n return collection;\r\n }\r\n empty() {\r\n const self = this;\r\n if (self.firstChild) {\r\n const nodes = [];\r\n for (let node = self.firstChild; node; node = walk$2(node, self)) {\r\n nodes.push(node);\r\n }\r\n let i = nodes.length;\r\n while (i--) {\r\n const node = nodes[i];\r\n node.parent = node.firstChild = node.lastChild = node.next = node.prev = null;\r\n }\r\n }\r\n self.firstChild = self.lastChild = null;\r\n return self;\r\n }\r\n isEmpty(elements, whitespace = {}, predicate) {\r\n var _a;\r\n const self = this;\r\n let node = self.firstChild;\r\n if (isNonEmptyElement(self)) {\r\n return false;\r\n }\r\n if (node) {\r\n do {\r\n if (node.type === 1) {\r\n if (node.attr('data-mce-bogus')) {\r\n continue;\r\n }\r\n if (elements[node.name]) {\r\n return false;\r\n }\r\n if (isNonEmptyElement(node)) {\r\n return false;\r\n }\r\n }\r\n if (node.type === 8) {\r\n return false;\r\n }\r\n if (node.type === 3 && !isEmptyTextNode(node)) {\r\n return false;\r\n }\r\n if (node.type === 3 && node.parent && whitespace[node.parent.name] && isWhitespaceText((_a = node.value) !== null && _a !== void 0 ? _a : '')) {\r\n return false;\r\n }\r\n if (predicate && predicate(node)) {\r\n return false;\r\n }\r\n } while (node = walk$2(node, self));\r\n }\r\n return true;\r\n }\r\n walk(prev) {\r\n return walk$2(this, null, prev);\r\n }\r\n }\r\n\r\n const isConditionalComment = (html, startIndex) => /^\\s*\\[if [\\w\\W]+\\]>.*/.test(html.substr(startIndex));\r\n const findCommentEndIndex = (html, isBogus, startIndex = 0) => {\r\n const lcHtml = html.toLowerCase();\r\n if (lcHtml.indexOf('[if ', startIndex) !== -1 && isConditionalComment(lcHtml, startIndex)) {\r\n const endIfIndex = lcHtml.indexOf('[endif]', startIndex);\r\n return lcHtml.indexOf('>', endIfIndex);\r\n } else {\r\n if (isBogus) {\r\n const endIndex = lcHtml.indexOf('>', startIndex);\r\n return endIndex !== -1 ? endIndex : lcHtml.length;\r\n } else {\r\n const endCommentRegexp = /--!?>/g;\r\n endCommentRegexp.lastIndex = startIndex;\r\n const match = endCommentRegexp.exec(html);\r\n return match ? match.index + match[0].length : lcHtml.length;\r\n }\r\n }\r\n };\r\n const findMatchingEndTagIndex = (schema, html, startIndex) => {\r\n const startTagRegExp = /<([!?\\/])?([A-Za-z0-9\\-_:.]+)/g;\r\n const endTagRegExp = /(?:\\s(?:[^'\">]+(?:\"[^\"]*\"|'[^']*'))*[^\"'>]*(?:\"[^\">]*|'[^'>]*)?|\\s*|\\/)>/g;\r\n const voidElements = schema.getVoidElements();\r\n let count = 1, index = startIndex;\r\n while (count !== 0) {\r\n startTagRegExp.lastIndex = index;\r\n while (true) {\r\n const startMatch = startTagRegExp.exec(html);\r\n if (startMatch === null) {\r\n return index;\r\n } else if (startMatch[1] === '!') {\r\n if (startsWith(startMatch[2], '--')) {\r\n index = findCommentEndIndex(html, false, startMatch.index + '!--'.length);\r\n } else {\r\n index = findCommentEndIndex(html, true, startMatch.index + 1);\r\n }\r\n break;\r\n } else {\r\n endTagRegExp.lastIndex = startTagRegExp.lastIndex;\r\n const endMatch = endTagRegExp.exec(html);\r\n if (isNull(endMatch) || endMatch.index !== startTagRegExp.lastIndex) {\r\n continue;\r\n }\r\n if (startMatch[1] === '/') {\r\n count -= 1;\r\n } else if (!has$2(voidElements, startMatch[2])) {\r\n count += 1;\r\n }\r\n index = startTagRegExp.lastIndex + endMatch[0].length;\r\n break;\r\n }\r\n }\r\n }\r\n return index;\r\n };\r\n const trimHtml$1 = (tempAttrs, html) => {\r\n const trimContentRegExp = new RegExp(['\\\\s?(' + tempAttrs.join('|') + ')=\"[^\"]+\"'].join('|'), 'gi');\r\n return html.replace(trimContentRegExp, '');\r\n };\r\n const trimInternal = (serializer, html) => {\r\n const bogusAllRegExp = /<(\\w+) [^>]*data-mce-bogus=\"all\"[^>]*>/g;\r\n const schema = serializer.schema;\r\n let content = trimHtml$1(serializer.getTempAttrs(), html);\r\n const voidElements = schema.getVoidElements();\r\n let matches;\r\n while (matches = bogusAllRegExp.exec(content)) {\r\n const index = bogusAllRegExp.lastIndex;\r\n const matchLength = matches[0].length;\r\n let endTagIndex;\r\n if (voidElements[matches[1]]) {\r\n endTagIndex = index;\r\n } else {\r\n endTagIndex = findMatchingEndTagIndex(schema, content, index);\r\n }\r\n content = content.substring(0, index - matchLength) + content.substring(endTagIndex);\r\n bogusAllRegExp.lastIndex = index - matchLength;\r\n }\r\n return trim$1(content);\r\n };\r\n const trimExternal = trimInternal;\r\n\r\n const cleanupBogusElements = parent => {\r\n const bogusElements = descendants(parent, '[data-mce-bogus]');\r\n each$e(bogusElements, elem => {\r\n const bogusValue = get$9(elem, 'data-mce-bogus');\r\n if (bogusValue === 'all') {\r\n remove$6(elem);\r\n } else if (isBr$5(elem)) {\r\n before$3(elem, SugarElement.fromText(zeroWidth));\r\n remove$6(elem);\r\n } else {\r\n unwrap(elem);\r\n }\r\n });\r\n };\r\n const cleanupInputNames = parent => {\r\n const inputs = descendants(parent, 'input');\r\n each$e(inputs, input => {\r\n remove$b(input, 'name');\r\n });\r\n };\r\n\r\n const trimEmptyContents = (editor, html) => {\r\n const blockName = getForcedRootBlock(editor);\r\n const emptyRegExp = new RegExp(`^(<${ blockName }[^>]*>( | |\\\\s|\\u00a0|
|)<\\\\/${ blockName }>[\\r\\n]*|
[\\r\\n]*)$`);\r\n return html.replace(emptyRegExp, '');\r\n };\r\n const getPlainTextContent = (editor, body) => {\r\n const doc = editor.getDoc();\r\n const dos = getRootNode(SugarElement.fromDom(editor.getBody()));\r\n const offscreenDiv = SugarElement.fromTag('div', doc);\r\n set$3(offscreenDiv, 'data-mce-bogus', 'all');\r\n setAll(offscreenDiv, {\r\n position: 'fixed',\r\n left: '-9999999px',\r\n top: '0'\r\n });\r\n set$1(offscreenDiv, body.innerHTML);\r\n cleanupBogusElements(offscreenDiv);\r\n cleanupInputNames(offscreenDiv);\r\n const root = getContentContainer(dos);\r\n append$1(root, offscreenDiv);\r\n const content = trim$1(offscreenDiv.dom.innerText);\r\n remove$6(offscreenDiv);\r\n return content;\r\n };\r\n const getContentFromBody = (editor, args, body) => {\r\n let content;\r\n if (args.format === 'raw') {\r\n content = Tools.trim(trimExternal(editor.serializer, body.innerHTML));\r\n } else if (args.format === 'text') {\r\n content = getPlainTextContent(editor, body);\r\n } else if (args.format === 'tree') {\r\n content = editor.serializer.serialize(body, args);\r\n } else {\r\n content = trimEmptyContents(editor, editor.serializer.serialize(body, args));\r\n }\r\n const shouldTrim = args.format !== 'text' && !isWsPreserveElement(SugarElement.fromDom(body));\r\n return shouldTrim && isString(content) ? Tools.trim(content) : content;\r\n };\r\n const getContentInternal = (editor, args) => Optional.from(editor.getBody()).fold(constant(args.format === 'tree' ? new AstNode('body', 11) : ''), body => getContentFromBody(editor, args, body));\r\n\r\n const makeMap$1 = Tools.makeMap;\r\n const Writer = settings => {\r\n const html = [];\r\n settings = settings || {};\r\n const indent = settings.indent;\r\n const indentBefore = makeMap$1(settings.indent_before || '');\r\n const indentAfter = makeMap$1(settings.indent_after || '');\r\n const encode = Entities.getEncodeFunc(settings.entity_encoding || 'raw', settings.entities);\r\n const htmlOutput = settings.element_format !== 'xhtml';\r\n return {\r\n start: (name, attrs, empty) => {\r\n if (indent && indentBefore[name] && html.length > 0) {\r\n const value = html[html.length - 1];\r\n if (value.length > 0 && value !== '\\n') {\r\n html.push('\\n');\r\n }\r\n }\r\n html.push('<', name);\r\n if (attrs) {\r\n for (let i = 0, l = attrs.length; i < l; i++) {\r\n const attr = attrs[i];\r\n html.push(' ', attr.name, '=\"', encode(attr.value, true), '\"');\r\n }\r\n }\r\n if (!empty || htmlOutput) {\r\n html[html.length] = '>';\r\n } else {\r\n html[html.length] = ' />';\r\n }\r\n if (empty && indent && indentAfter[name] && html.length > 0) {\r\n const value = html[html.length - 1];\r\n if (value.length > 0 && value !== '\\n') {\r\n html.push('\\n');\r\n }\r\n }\r\n },\r\n end: name => {\r\n let value;\r\n html.push('');\r\n if (indent && indentAfter[name] && html.length > 0) {\r\n value = html[html.length - 1];\r\n if (value.length > 0 && value !== '\\n') {\r\n html.push('\\n');\r\n }\r\n }\r\n },\r\n text: (text, raw) => {\r\n if (text.length > 0) {\r\n html[html.length] = raw ? text : encode(text);\r\n }\r\n },\r\n cdata: text => {\r\n html.push('');\r\n },\r\n comment: text => {\r\n html.push('');\r\n },\r\n pi: (name, text) => {\r\n if (text) {\r\n html.push('');\r\n } else {\r\n html.push('');\r\n }\r\n if (indent) {\r\n html.push('\\n');\r\n }\r\n },\r\n doctype: text => {\r\n html.push('', indent ? '\\n' : '');\r\n },\r\n reset: () => {\r\n html.length = 0;\r\n },\r\n getContent: () => {\r\n return html.join('').replace(/\\n$/, '');\r\n }\r\n };\r\n };\r\n\r\n const HtmlSerializer = (settings = {}, schema = Schema()) => {\r\n const writer = Writer(settings);\r\n settings.validate = 'validate' in settings ? settings.validate : true;\r\n const serialize = node => {\r\n const validate = settings.validate;\r\n const handlers = {\r\n 3: node => {\r\n var _a;\r\n writer.text((_a = node.value) !== null && _a !== void 0 ? _a : '', node.raw);\r\n },\r\n 8: node => {\r\n var _a;\r\n writer.comment((_a = node.value) !== null && _a !== void 0 ? _a : '');\r\n },\r\n 7: node => {\r\n writer.pi(node.name, node.value);\r\n },\r\n 10: node => {\r\n var _a;\r\n writer.doctype((_a = node.value) !== null && _a !== void 0 ? _a : '');\r\n },\r\n 4: node => {\r\n var _a;\r\n writer.cdata((_a = node.value) !== null && _a !== void 0 ? _a : '');\r\n },\r\n 11: node => {\r\n let tempNode = node;\r\n if (tempNode = tempNode.firstChild) {\r\n do {\r\n walk(tempNode);\r\n } while (tempNode = tempNode.next);\r\n }\r\n }\r\n };\r\n writer.reset();\r\n const walk = node => {\r\n var _a;\r\n const handler = handlers[node.type];\r\n if (!handler) {\r\n const name = node.name;\r\n const isEmpty = name in schema.getVoidElements();\r\n let attrs = node.attributes;\r\n if (validate && attrs && attrs.length > 1) {\r\n const sortedAttrs = [];\r\n sortedAttrs.map = {};\r\n const elementRule = schema.getElementRule(node.name);\r\n if (elementRule) {\r\n for (let i = 0, l = elementRule.attributesOrder.length; i < l; i++) {\r\n const attrName = elementRule.attributesOrder[i];\r\n if (attrName in attrs.map) {\r\n const attrValue = attrs.map[attrName];\r\n sortedAttrs.map[attrName] = attrValue;\r\n sortedAttrs.push({\r\n name: attrName,\r\n value: attrValue\r\n });\r\n }\r\n }\r\n for (let i = 0, l = attrs.length; i < l; i++) {\r\n const attrName = attrs[i].name;\r\n if (!(attrName in sortedAttrs.map)) {\r\n const attrValue = attrs.map[attrName];\r\n sortedAttrs.map[attrName] = attrValue;\r\n sortedAttrs.push({\r\n name: attrName,\r\n value: attrValue\r\n });\r\n }\r\n }\r\n attrs = sortedAttrs;\r\n }\r\n }\r\n writer.start(name, attrs, isEmpty);\r\n if (!isEmpty) {\r\n let child = node.firstChild;\r\n if (child) {\r\n if ((name === 'pre' || name === 'textarea') && child.type === 3 && ((_a = child.value) === null || _a === void 0 ? void 0 : _a[0]) === '\\n') {\r\n writer.text('\\n', true);\r\n }\r\n do {\r\n walk(child);\r\n } while (child = child.next);\r\n }\r\n writer.end(name);\r\n }\r\n } else {\r\n handler(node);\r\n }\r\n };\r\n if (node.type === 1 && !settings.inner) {\r\n walk(node);\r\n } else if (node.type === 3) {\r\n handlers[3](node);\r\n } else {\r\n handlers[11](node);\r\n }\r\n return writer.getContent();\r\n };\r\n return { serialize };\r\n };\r\n\r\n const nonInheritableStyles = new Set();\r\n (() => {\r\n const nonInheritableStylesArr = [\r\n 'margin',\r\n 'margin-left',\r\n 'margin-right',\r\n 'margin-top',\r\n 'margin-bottom',\r\n 'padding',\r\n 'padding-left',\r\n 'padding-right',\r\n 'padding-top',\r\n 'padding-bottom',\r\n 'border',\r\n 'border-width',\r\n 'border-style',\r\n 'border-color',\r\n 'background',\r\n 'background-attachment',\r\n 'background-clip',\r\n 'background-color',\r\n 'background-image',\r\n 'background-origin',\r\n 'background-position',\r\n 'background-repeat',\r\n 'background-size',\r\n 'float',\r\n 'position',\r\n 'left',\r\n 'right',\r\n 'top',\r\n 'bottom',\r\n 'z-index',\r\n 'display',\r\n 'transform',\r\n 'width',\r\n 'max-width',\r\n 'min-width',\r\n 'height',\r\n 'max-height',\r\n 'min-height',\r\n 'overflow',\r\n 'overflow-x',\r\n 'overflow-y',\r\n 'text-overflow',\r\n 'vertical-align',\r\n 'transition',\r\n 'transition-delay',\r\n 'transition-duration',\r\n 'transition-property',\r\n 'transition-timing-function'\r\n ];\r\n each$e(nonInheritableStylesArr, style => {\r\n nonInheritableStyles.add(style);\r\n });\r\n })();\r\n const shorthandStyleProps = [\r\n 'font',\r\n 'text-decoration',\r\n 'text-emphasis'\r\n ];\r\n const getStyleProps = (dom, node) => keys(dom.parseStyle(dom.getAttrib(node, 'style')));\r\n const isNonInheritableStyle = style => nonInheritableStyles.has(style);\r\n const hasInheritableStyles = (dom, node) => forall(getStyleProps(dom, node), style => !isNonInheritableStyle(style));\r\n const getLonghandStyleProps = styles => filter$5(styles, style => exists(shorthandStyleProps, prop => startsWith(style, prop)));\r\n const hasStyleConflict = (dom, node, parentNode) => {\r\n const nodeStyleProps = getStyleProps(dom, node);\r\n const parentNodeStyleProps = getStyleProps(dom, parentNode);\r\n const valueMismatch = prop => {\r\n var _a, _b;\r\n const nodeValue = (_a = dom.getStyle(node, prop)) !== null && _a !== void 0 ? _a : '';\r\n const parentValue = (_b = dom.getStyle(parentNode, prop)) !== null && _b !== void 0 ? _b : '';\r\n return isNotEmpty(nodeValue) && isNotEmpty(parentValue) && nodeValue !== parentValue;\r\n };\r\n return exists(nodeStyleProps, nodeStyleProp => {\r\n const propExists = props => exists(props, prop => prop === nodeStyleProp);\r\n if (!propExists(parentNodeStyleProps) && propExists(shorthandStyleProps)) {\r\n const longhandProps = getLonghandStyleProps(parentNodeStyleProps);\r\n return exists(longhandProps, valueMismatch);\r\n } else {\r\n return valueMismatch(nodeStyleProp);\r\n }\r\n });\r\n };\r\n\r\n const isChar = (forward, predicate, pos) => Optional.from(pos.container()).filter(isText$a).exists(text => {\r\n const delta = forward ? 0 : -1;\r\n return predicate(text.data.charAt(pos.offset() + delta));\r\n });\r\n const isBeforeSpace = curry(isChar, true, isWhiteSpace);\r\n const isAfterSpace = curry(isChar, false, isWhiteSpace);\r\n const isEmptyText = pos => {\r\n const container = pos.container();\r\n return isText$a(container) && (container.data.length === 0 || isZwsp(container.data) && BookmarkManager.isBookmarkNode(container.parentNode));\r\n };\r\n const matchesElementPosition = (before, predicate) => pos => getChildNodeAtRelativeOffset(before ? 0 : -1, pos).filter(predicate).isSome();\r\n const isImageBlock = node => isImg(node) && get$7(SugarElement.fromDom(node), 'display') === 'block';\r\n const isCefNode = node => isContentEditableFalse$b(node) && !isBogusAll$1(node);\r\n const isBeforeImageBlock = matchesElementPosition(true, isImageBlock);\r\n const isAfterImageBlock = matchesElementPosition(false, isImageBlock);\r\n const isBeforeMedia = matchesElementPosition(true, isMedia$2);\r\n const isAfterMedia = matchesElementPosition(false, isMedia$2);\r\n const isBeforeTable = matchesElementPosition(true, isTable$2);\r\n const isAfterTable = matchesElementPosition(false, isTable$2);\r\n const isBeforeContentEditableFalse = matchesElementPosition(true, isCefNode);\r\n const isAfterContentEditableFalse = matchesElementPosition(false, isCefNode);\r\n\r\n const dropLast = xs => xs.slice(0, -1);\r\n const parentsUntil = (start, root, predicate) => {\r\n if (contains(root, start)) {\r\n return dropLast(parents$1(start, elm => {\r\n return predicate(elm) || eq(elm, root);\r\n }));\r\n } else {\r\n return [];\r\n }\r\n };\r\n const parents = (start, root) => parentsUntil(start, root, never);\r\n const parentsAndSelf = (start, root) => [start].concat(parents(start, root));\r\n\r\n const navigateIgnoreEmptyTextNodes = (forward, root, from) => navigateIgnore(forward, root, from, isEmptyText);\r\n const getClosestBlock$1 = (root, pos) => find$2(parentsAndSelf(SugarElement.fromDom(pos.container()), root), isBlock$2);\r\n const isAtBeforeAfterBlockBoundary = (forward, root, pos) => navigateIgnoreEmptyTextNodes(forward, root.dom, pos).forall(newPos => getClosestBlock$1(root, pos).fold(() => !isInSameBlock(newPos, pos, root.dom), fromBlock => !isInSameBlock(newPos, pos, root.dom) && contains(fromBlock, SugarElement.fromDom(newPos.container()))));\r\n const isAtBlockBoundary = (forward, root, pos) => getClosestBlock$1(root, pos).fold(() => navigateIgnoreEmptyTextNodes(forward, root.dom, pos).forall(newPos => !isInSameBlock(newPos, pos, root.dom)), parent => navigateIgnoreEmptyTextNodes(forward, parent.dom, pos).isNone());\r\n const isAtStartOfBlock = curry(isAtBlockBoundary, false);\r\n const isAtEndOfBlock = curry(isAtBlockBoundary, true);\r\n const isBeforeBlock = curry(isAtBeforeAfterBlockBoundary, false);\r\n const isAfterBlock = curry(isAtBeforeAfterBlockBoundary, true);\r\n\r\n const isBr$1 = pos => getElementFromPosition(pos).exists(isBr$5);\r\n const findBr = (forward, root, pos) => {\r\n const parentBlocks = filter$5(parentsAndSelf(SugarElement.fromDom(pos.container()), root), isBlock$2);\r\n const scope = head(parentBlocks).getOr(root);\r\n return fromPosition(forward, scope.dom, pos).filter(isBr$1);\r\n };\r\n const isBeforeBr$1 = (root, pos) => getElementFromPosition(pos).exists(isBr$5) || findBr(true, root, pos).isSome();\r\n const isAfterBr = (root, pos) => getElementFromPrevPosition(pos).exists(isBr$5) || findBr(false, root, pos).isSome();\r\n const findPreviousBr = curry(findBr, false);\r\n const findNextBr = curry(findBr, true);\r\n\r\n const isInMiddleOfText = pos => CaretPosition.isTextPosition(pos) && !pos.isAtStart() && !pos.isAtEnd();\r\n const getClosestBlock = (root, pos) => {\r\n const parentBlocks = filter$5(parentsAndSelf(SugarElement.fromDom(pos.container()), root), isBlock$2);\r\n return head(parentBlocks).getOr(root);\r\n };\r\n const hasSpaceBefore = (root, pos) => {\r\n if (isInMiddleOfText(pos)) {\r\n return isAfterSpace(pos);\r\n } else {\r\n return isAfterSpace(pos) || prevPosition(getClosestBlock(root, pos).dom, pos).exists(isAfterSpace);\r\n }\r\n };\r\n const hasSpaceAfter = (root, pos) => {\r\n if (isInMiddleOfText(pos)) {\r\n return isBeforeSpace(pos);\r\n } else {\r\n return isBeforeSpace(pos) || nextPosition(getClosestBlock(root, pos).dom, pos).exists(isBeforeSpace);\r\n }\r\n };\r\n const isPreValue = value => contains$2([\r\n 'pre',\r\n 'pre-wrap'\r\n ], value);\r\n const isInPre = pos => getElementFromPosition(pos).bind(elm => closest$4(elm, isElement$7)).exists(elm => isPreValue(get$7(elm, 'white-space')));\r\n const isAtBeginningOfBody = (root, pos) => prevPosition(root.dom, pos).isNone();\r\n const isAtEndOfBody = (root, pos) => nextPosition(root.dom, pos).isNone();\r\n const isAtLineBoundary = (root, pos) => isAtBeginningOfBody(root, pos) || isAtEndOfBody(root, pos) || isAtStartOfBlock(root, pos) || isAtEndOfBlock(root, pos) || isAfterBr(root, pos) || isBeforeBr$1(root, pos);\r\n const isCefBlock = node => isNonNullable(node) && isContentEditableFalse$b(node) && isBlockLike(node);\r\n const isSiblingCefBlock = (root, direction) => container => {\r\n return isCefBlock(new DomTreeWalker(container, root)[direction]());\r\n };\r\n const isBeforeCefBlock = (root, pos) => {\r\n const nextPos = nextPosition(root.dom, pos).getOr(pos);\r\n const isNextCefBlock = isSiblingCefBlock(root.dom, 'next');\r\n return pos.isAtEnd() && (isNextCefBlock(pos.container()) || isNextCefBlock(nextPos.container()));\r\n };\r\n const isAfterCefBlock = (root, pos) => {\r\n const prevPos = prevPosition(root.dom, pos).getOr(pos);\r\n const isPrevCefBlock = isSiblingCefBlock(root.dom, 'prev');\r\n return pos.isAtStart() && (isPrevCefBlock(pos.container()) || isPrevCefBlock(prevPos.container()));\r\n };\r\n const needsToHaveNbsp = (root, pos) => {\r\n if (isInPre(pos)) {\r\n return false;\r\n } else {\r\n return isAtLineBoundary(root, pos) || hasSpaceBefore(root, pos) || hasSpaceAfter(root, pos);\r\n }\r\n };\r\n const needsToBeNbspLeft = (root, pos) => {\r\n if (isInPre(pos)) {\r\n return false;\r\n } else {\r\n return isAtStartOfBlock(root, pos) || isBeforeBlock(root, pos) || isAfterBr(root, pos) || hasSpaceBefore(root, pos) || isAfterCefBlock(root, pos);\r\n }\r\n };\r\n const leanRight = pos => {\r\n const container = pos.container();\r\n const offset = pos.offset();\r\n if (isText$a(container) && offset < container.data.length) {\r\n return CaretPosition(container, offset + 1);\r\n } else {\r\n return pos;\r\n }\r\n };\r\n const needsToBeNbspRight = (root, pos) => {\r\n if (isInPre(pos)) {\r\n return false;\r\n } else {\r\n return isAtEndOfBlock(root, pos) || isAfterBlock(root, pos) || isBeforeBr$1(root, pos) || hasSpaceAfter(root, pos) || isBeforeCefBlock(root, pos);\r\n }\r\n };\r\n const needsToBeNbsp = (root, pos) => needsToBeNbspLeft(root, pos) || needsToBeNbspRight(root, leanRight(pos));\r\n const isNbspAt = (text, offset) => isNbsp(text.charAt(offset));\r\n const isWhiteSpaceAt = (text, offset) => isWhiteSpace(text.charAt(offset));\r\n const hasNbsp = pos => {\r\n const container = pos.container();\r\n return isText$a(container) && contains$1(container.data, nbsp);\r\n };\r\n const normalizeNbspMiddle = text => {\r\n const chars = text.split('');\r\n return map$3(chars, (chr, i) => {\r\n if (isNbsp(chr) && i > 0 && i < chars.length - 1 && isContent(chars[i - 1]) && isContent(chars[i + 1])) {\r\n return ' ';\r\n } else {\r\n return chr;\r\n }\r\n }).join('');\r\n };\r\n const normalizeNbspAtStart = (root, node, makeNbsp) => {\r\n const text = node.data;\r\n const firstPos = CaretPosition(node, 0);\r\n if (!makeNbsp && isNbspAt(text, 0) && !needsToBeNbsp(root, firstPos)) {\r\n node.data = ' ' + text.slice(1);\r\n return true;\r\n } else if (makeNbsp && isWhiteSpaceAt(text, 0) && needsToBeNbspLeft(root, firstPos)) {\r\n node.data = nbsp + text.slice(1);\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n };\r\n const normalizeNbspInMiddleOfTextNode = node => {\r\n const text = node.data;\r\n const newText = normalizeNbspMiddle(text);\r\n if (newText !== text) {\r\n node.data = newText;\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n };\r\n const normalizeNbspAtEnd = (root, node, makeNbsp) => {\r\n const text = node.data;\r\n const lastPos = CaretPosition(node, text.length - 1);\r\n if (!makeNbsp && isNbspAt(text, text.length - 1) && !needsToBeNbsp(root, lastPos)) {\r\n node.data = text.slice(0, -1) + ' ';\r\n return true;\r\n } else if (makeNbsp && isWhiteSpaceAt(text, text.length - 1) && needsToBeNbspRight(root, lastPos)) {\r\n node.data = text.slice(0, -1) + nbsp;\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n };\r\n const normalizeNbsps = (root, pos) => {\r\n const container = pos.container();\r\n if (!isText$a(container)) {\r\n return Optional.none();\r\n }\r\n if (hasNbsp(pos)) {\r\n const normalized = normalizeNbspAtStart(root, container, false) || normalizeNbspInMiddleOfTextNode(container) || normalizeNbspAtEnd(root, container, false);\r\n return someIf(normalized, pos);\r\n } else if (needsToBeNbsp(root, pos)) {\r\n const normalized = normalizeNbspAtStart(root, container, true) || normalizeNbspAtEnd(root, container, true);\r\n return someIf(normalized, pos);\r\n } else {\r\n return Optional.none();\r\n }\r\n };\r\n const normalizeNbspsInEditor = editor => {\r\n const root = SugarElement.fromDom(editor.getBody());\r\n if (editor.selection.isCollapsed()) {\r\n normalizeNbsps(root, CaretPosition.fromRangeStart(editor.selection.getRng())).each(pos => {\r\n editor.selection.setRng(pos.toRange());\r\n });\r\n }\r\n };\r\n\r\n const normalize$1 = (node, offset, count) => {\r\n if (count === 0) {\r\n return;\r\n }\r\n const elm = SugarElement.fromDom(node);\r\n const root = ancestor$4(elm, isBlock$2).getOr(elm);\r\n const whitespace = node.data.slice(offset, offset + count);\r\n const isEndOfContent = offset + count >= node.data.length && needsToBeNbspRight(root, CaretPosition(node, node.data.length));\r\n const isStartOfContent = offset === 0 && needsToBeNbspLeft(root, CaretPosition(node, 0));\r\n node.replaceData(offset, count, normalize$4(whitespace, 4, isStartOfContent, isEndOfContent));\r\n };\r\n const normalizeWhitespaceAfter = (node, offset) => {\r\n const content = node.data.slice(offset);\r\n const whitespaceCount = content.length - lTrim(content).length;\r\n normalize$1(node, offset, whitespaceCount);\r\n };\r\n const normalizeWhitespaceBefore = (node, offset) => {\r\n const content = node.data.slice(0, offset);\r\n const whitespaceCount = content.length - rTrim(content).length;\r\n normalize$1(node, offset - whitespaceCount, whitespaceCount);\r\n };\r\n const mergeTextNodes = (prevNode, nextNode, normalizeWhitespace, mergeToPrev = true) => {\r\n const whitespaceOffset = rTrim(prevNode.data).length;\r\n const newNode = mergeToPrev ? prevNode : nextNode;\r\n const removeNode = mergeToPrev ? nextNode : prevNode;\r\n if (mergeToPrev) {\r\n newNode.appendData(removeNode.data);\r\n } else {\r\n newNode.insertData(0, removeNode.data);\r\n }\r\n remove$6(SugarElement.fromDom(removeNode));\r\n if (normalizeWhitespace) {\r\n normalizeWhitespaceAfter(newNode, whitespaceOffset);\r\n }\r\n return newNode;\r\n };\r\n\r\n const needsReposition = (pos, elm) => {\r\n const container = pos.container();\r\n const offset = pos.offset();\r\n return !CaretPosition.isTextPosition(pos) && container === elm.parentNode && offset > CaretPosition.before(elm).offset();\r\n };\r\n const reposition = (elm, pos) => needsReposition(pos, elm) ? CaretPosition(pos.container(), pos.offset() - 1) : pos;\r\n const beforeOrStartOf = node => isText$a(node) ? CaretPosition(node, 0) : CaretPosition.before(node);\r\n const afterOrEndOf = node => isText$a(node) ? CaretPosition(node, node.data.length) : CaretPosition.after(node);\r\n const getPreviousSiblingCaretPosition = elm => {\r\n if (isCaretCandidate$3(elm.previousSibling)) {\r\n return Optional.some(afterOrEndOf(elm.previousSibling));\r\n } else {\r\n return elm.previousSibling ? lastPositionIn(elm.previousSibling) : Optional.none();\r\n }\r\n };\r\n const getNextSiblingCaretPosition = elm => {\r\n if (isCaretCandidate$3(elm.nextSibling)) {\r\n return Optional.some(beforeOrStartOf(elm.nextSibling));\r\n } else {\r\n return elm.nextSibling ? firstPositionIn(elm.nextSibling) : Optional.none();\r\n }\r\n };\r\n const findCaretPositionBackwardsFromElm = (rootElement, elm) => {\r\n return Optional.from(elm.previousSibling ? elm.previousSibling : elm.parentNode).bind(node => prevPosition(rootElement, CaretPosition.before(node))).orThunk(() => nextPosition(rootElement, CaretPosition.after(elm)));\r\n };\r\n const findCaretPositionForwardsFromElm = (rootElement, elm) => nextPosition(rootElement, CaretPosition.after(elm)).orThunk(() => prevPosition(rootElement, CaretPosition.before(elm)));\r\n const findCaretPositionBackwards = (rootElement, elm) => getPreviousSiblingCaretPosition(elm).orThunk(() => getNextSiblingCaretPosition(elm)).orThunk(() => findCaretPositionBackwardsFromElm(rootElement, elm));\r\n const findCaretPositionForward = (rootElement, elm) => getNextSiblingCaretPosition(elm).orThunk(() => getPreviousSiblingCaretPosition(elm)).orThunk(() => findCaretPositionForwardsFromElm(rootElement, elm));\r\n const findCaretPosition = (forward, rootElement, elm) => forward ? findCaretPositionForward(rootElement, elm) : findCaretPositionBackwards(rootElement, elm);\r\n const findCaretPosOutsideElmAfterDelete = (forward, rootElement, elm) => findCaretPosition(forward, rootElement, elm).map(curry(reposition, elm));\r\n const setSelection$1 = (editor, forward, pos) => {\r\n pos.fold(() => {\r\n editor.focus();\r\n }, pos => {\r\n editor.selection.setRng(pos.toRange(), forward);\r\n });\r\n };\r\n const eqRawNode = rawNode => elm => elm.dom === rawNode;\r\n const isBlock = (editor, elm) => elm && has$2(editor.schema.getBlockElements(), name(elm));\r\n const paddEmptyBlock = elm => {\r\n if (isEmpty$2(elm)) {\r\n const br = SugarElement.fromHtml('
');\r\n empty(elm);\r\n append$1(elm, br);\r\n return Optional.some(CaretPosition.before(br.dom));\r\n } else {\r\n return Optional.none();\r\n }\r\n };\r\n const deleteNormalized = (elm, afterDeletePosOpt, normalizeWhitespace) => {\r\n const prevTextOpt = prevSibling(elm).filter(isText$b);\r\n const nextTextOpt = nextSibling(elm).filter(isText$b);\r\n remove$6(elm);\r\n return lift3(prevTextOpt, nextTextOpt, afterDeletePosOpt, (prev, next, pos) => {\r\n const prevNode = prev.dom, nextNode = next.dom;\r\n const offset = prevNode.data.length;\r\n mergeTextNodes(prevNode, nextNode, normalizeWhitespace);\r\n return pos.container() === nextNode ? CaretPosition(prevNode, offset) : pos;\r\n }).orThunk(() => {\r\n if (normalizeWhitespace) {\r\n prevTextOpt.each(elm => normalizeWhitespaceBefore(elm.dom, elm.dom.length));\r\n nextTextOpt.each(elm => normalizeWhitespaceAfter(elm.dom, 0));\r\n }\r\n return afterDeletePosOpt;\r\n });\r\n };\r\n const isInlineElement = (editor, element) => has$2(editor.schema.getTextInlineElements(), name(element));\r\n const deleteElement$2 = (editor, forward, elm, moveCaret = true) => {\r\n const afterDeletePos = findCaretPosOutsideElmAfterDelete(forward, editor.getBody(), elm.dom);\r\n const parentBlock = ancestor$4(elm, curry(isBlock, editor), eqRawNode(editor.getBody()));\r\n const normalizedAfterDeletePos = deleteNormalized(elm, afterDeletePos, isInlineElement(editor, elm));\r\n if (editor.dom.isEmpty(editor.getBody())) {\r\n editor.setContent('');\r\n editor.selection.setCursorLocation();\r\n } else {\r\n parentBlock.bind(paddEmptyBlock).fold(() => {\r\n if (moveCaret) {\r\n setSelection$1(editor, forward, normalizedAfterDeletePos);\r\n }\r\n }, paddPos => {\r\n if (moveCaret) {\r\n setSelection$1(editor, forward, Optional.some(paddPos));\r\n }\r\n });\r\n }\r\n };\r\n\r\n const strongRtl = /[\\u0591-\\u07FF\\uFB1D-\\uFDFF\\uFE70-\\uFEFC]/;\r\n const hasStrongRtl = text => strongRtl.test(text);\r\n\r\n const isInlineTarget = (editor, elm) => is$1(SugarElement.fromDom(elm), getInlineBoundarySelector(editor)) && !isTransparentBlock(editor.schema, elm) && editor.dom.isEditable(elm);\r\n const isRtl = element => {\r\n var _a;\r\n return DOMUtils.DOM.getStyle(element, 'direction', true) === 'rtl' || hasStrongRtl((_a = element.textContent) !== null && _a !== void 0 ? _a : '');\r\n };\r\n const findInlineParents = (isInlineTarget, rootNode, pos) => filter$5(DOMUtils.DOM.getParents(pos.container(), '*', rootNode), isInlineTarget);\r\n const findRootInline = (isInlineTarget, rootNode, pos) => {\r\n const parents = findInlineParents(isInlineTarget, rootNode, pos);\r\n return Optional.from(parents[parents.length - 1]);\r\n };\r\n const hasSameParentBlock = (rootNode, node1, node2) => {\r\n const block1 = getParentBlock$3(node1, rootNode);\r\n const block2 = getParentBlock$3(node2, rootNode);\r\n return isNonNullable(block1) && block1 === block2;\r\n };\r\n const isAtZwsp = pos => isBeforeInline(pos) || isAfterInline(pos);\r\n const normalizePosition = (forward, pos) => {\r\n const container = pos.container(), offset = pos.offset();\r\n if (forward) {\r\n if (isCaretContainerInline(container)) {\r\n if (isText$a(container.nextSibling)) {\r\n return CaretPosition(container.nextSibling, 0);\r\n } else {\r\n return CaretPosition.after(container);\r\n }\r\n } else {\r\n return isBeforeInline(pos) ? CaretPosition(container, offset + 1) : pos;\r\n }\r\n } else {\r\n if (isCaretContainerInline(container)) {\r\n if (isText$a(container.previousSibling)) {\r\n return CaretPosition(container.previousSibling, container.previousSibling.data.length);\r\n } else {\r\n return CaretPosition.before(container);\r\n }\r\n } else {\r\n return isAfterInline(pos) ? CaretPosition(container, offset - 1) : pos;\r\n }\r\n }\r\n };\r\n const normalizeForwards = curry(normalizePosition, true);\r\n const normalizeBackwards = curry(normalizePosition, false);\r\n\r\n const execCommandIgnoreInputEvents = (editor, command) => {\r\n const inputBlocker = e => e.stopImmediatePropagation();\r\n editor.on('beforeinput input', inputBlocker, true);\r\n editor.getDoc().execCommand(command);\r\n editor.off('beforeinput input', inputBlocker);\r\n };\r\n const execEditorDeleteCommand = editor => {\r\n editor.execCommand('delete');\r\n };\r\n const execNativeDeleteCommand = editor => execCommandIgnoreInputEvents(editor, 'Delete');\r\n const execNativeForwardDeleteCommand = editor => execCommandIgnoreInputEvents(editor, 'ForwardDelete');\r\n const isBeforeRoot = rootNode => elm => is$2(parent(elm), rootNode, eq);\r\n const isTextBlockOrListItem = element => isTextBlock$2(element) || isListItem$1(element);\r\n const getParentBlock$2 = (rootNode, elm) => {\r\n if (contains(rootNode, elm)) {\r\n return closest$4(elm, isTextBlockOrListItem, isBeforeRoot(rootNode));\r\n } else {\r\n return Optional.none();\r\n }\r\n };\r\n const paddEmptyBody = (editor, moveSelection = true) => {\r\n if (editor.dom.isEmpty(editor.getBody())) {\r\n editor.setContent('', { no_selection: !moveSelection });\r\n }\r\n };\r\n const willDeleteLastPositionInElement = (forward, fromPos, elm) => lift2(firstPositionIn(elm), lastPositionIn(elm), (firstPos, lastPos) => {\r\n const normalizedFirstPos = normalizePosition(true, firstPos);\r\n const normalizedLastPos = normalizePosition(false, lastPos);\r\n const normalizedFromPos = normalizePosition(false, fromPos);\r\n if (forward) {\r\n return nextPosition(elm, normalizedFromPos).exists(nextPos => nextPos.isEqual(normalizedLastPos) && fromPos.isEqual(normalizedFirstPos));\r\n } else {\r\n return prevPosition(elm, normalizedFromPos).exists(prevPos => prevPos.isEqual(normalizedFirstPos) && fromPos.isEqual(normalizedLastPos));\r\n }\r\n }).getOr(true);\r\n const freefallRtl = root => {\r\n const child = isComment$1(root) ? prevSibling(root) : lastChild(root);\r\n return child.bind(freefallRtl).orThunk(() => Optional.some(root));\r\n };\r\n const deleteRangeContents = (editor, rng, root, moveSelection = true) => {\r\n var _a;\r\n rng.deleteContents();\r\n const lastNode = freefallRtl(root).getOr(root);\r\n const lastBlock = SugarElement.fromDom((_a = editor.dom.getParent(lastNode.dom, editor.dom.isBlock)) !== null && _a !== void 0 ? _a : root.dom);\r\n if (lastBlock.dom === editor.getBody()) {\r\n paddEmptyBody(editor, moveSelection);\r\n } else if (isEmpty$2(lastBlock)) {\r\n fillWithPaddingBr(lastBlock);\r\n if (moveSelection) {\r\n editor.selection.setCursorLocation(lastBlock.dom, 0);\r\n }\r\n }\r\n if (!eq(root, lastBlock)) {\r\n const additionalCleanupNodes = is$2(parent(lastBlock), root) ? [] : siblings(lastBlock);\r\n each$e(additionalCleanupNodes.concat(children$1(root)), node => {\r\n if (!eq(node, lastBlock) && !contains(node, lastBlock) && isEmpty$2(node)) {\r\n remove$6(node);\r\n }\r\n });\r\n }\r\n };\r\n\r\n const isRootFromElement = root => cur => eq(root, cur);\r\n const getTableCells = table => descendants(table, 'td,th');\r\n const getTableDetailsFromRange = (rng, isRoot) => {\r\n const getTable = node => getClosestTable(SugarElement.fromDom(node), isRoot);\r\n const startTable = getTable(rng.startContainer);\r\n const endTable = getTable(rng.endContainer);\r\n const isStartInTable = startTable.isSome();\r\n const isEndInTable = endTable.isSome();\r\n const isSameTable = lift2(startTable, endTable, eq).getOr(false);\r\n const isMultiTable = !isSameTable && isStartInTable && isEndInTable;\r\n return {\r\n startTable,\r\n endTable,\r\n isStartInTable,\r\n isEndInTable,\r\n isSameTable,\r\n isMultiTable\r\n };\r\n };\r\n\r\n const tableCellRng = (start, end) => ({\r\n start,\r\n end\r\n });\r\n const tableSelection = (rng, table, cells) => ({\r\n rng,\r\n table,\r\n cells\r\n });\r\n const deleteAction = Adt.generate([\r\n {\r\n singleCellTable: [\r\n 'rng',\r\n 'cell'\r\n ]\r\n },\r\n { fullTable: ['table'] },\r\n {\r\n partialTable: [\r\n 'cells',\r\n 'outsideDetails'\r\n ]\r\n },\r\n {\r\n multiTable: [\r\n 'startTableCells',\r\n 'endTableCells',\r\n 'betweenRng'\r\n ]\r\n }\r\n ]);\r\n const getClosestCell$1 = (container, isRoot) => closest$3(SugarElement.fromDom(container), 'td,th', isRoot);\r\n const isExpandedCellRng = cellRng => !eq(cellRng.start, cellRng.end);\r\n const getTableFromCellRng = (cellRng, isRoot) => getClosestTable(cellRng.start, isRoot).bind(startParentTable => getClosestTable(cellRng.end, isRoot).bind(endParentTable => someIf(eq(startParentTable, endParentTable), startParentTable)));\r\n const isSingleCellTable = (cellRng, isRoot) => !isExpandedCellRng(cellRng) && getTableFromCellRng(cellRng, isRoot).exists(table => {\r\n const rows = table.dom.rows;\r\n return rows.length === 1 && rows[0].cells.length === 1;\r\n });\r\n const getCellRng = (rng, isRoot) => {\r\n const startCell = getClosestCell$1(rng.startContainer, isRoot);\r\n const endCell = getClosestCell$1(rng.endContainer, isRoot);\r\n return lift2(startCell, endCell, tableCellRng);\r\n };\r\n const getCellRangeFromStartTable = isRoot => startCell => getClosestTable(startCell, isRoot).bind(table => last$3(getTableCells(table)).map(endCell => tableCellRng(startCell, endCell)));\r\n const getCellRangeFromEndTable = isRoot => endCell => getClosestTable(endCell, isRoot).bind(table => head(getTableCells(table)).map(startCell => tableCellRng(startCell, endCell)));\r\n const getTableSelectionFromCellRng = isRoot => cellRng => getTableFromCellRng(cellRng, isRoot).map(table => tableSelection(cellRng, table, getTableCells(table)));\r\n const getTableSelections = (cellRng, selectionDetails, rng, isRoot) => {\r\n if (rng.collapsed || !cellRng.forall(isExpandedCellRng)) {\r\n return Optional.none();\r\n } else if (selectionDetails.isSameTable) {\r\n const sameTableSelection = cellRng.bind(getTableSelectionFromCellRng(isRoot));\r\n return Optional.some({\r\n start: sameTableSelection,\r\n end: sameTableSelection\r\n });\r\n } else {\r\n const startCell = getClosestCell$1(rng.startContainer, isRoot);\r\n const endCell = getClosestCell$1(rng.endContainer, isRoot);\r\n const startTableSelection = startCell.bind(getCellRangeFromStartTable(isRoot)).bind(getTableSelectionFromCellRng(isRoot));\r\n const endTableSelection = endCell.bind(getCellRangeFromEndTable(isRoot)).bind(getTableSelectionFromCellRng(isRoot));\r\n return Optional.some({\r\n start: startTableSelection,\r\n end: endTableSelection\r\n });\r\n }\r\n };\r\n const getCellIndex = (cells, cell) => findIndex$2(cells, x => eq(x, cell));\r\n const getSelectedCells = tableSelection => lift2(getCellIndex(tableSelection.cells, tableSelection.rng.start), getCellIndex(tableSelection.cells, tableSelection.rng.end), (startIndex, endIndex) => tableSelection.cells.slice(startIndex, endIndex + 1));\r\n const isSingleCellTableContentSelected = (optCellRng, rng, isRoot) => optCellRng.exists(cellRng => isSingleCellTable(cellRng, isRoot) && hasAllContentsSelected(cellRng.start, rng));\r\n const unselectCells = (rng, selectionDetails) => {\r\n const {startTable, endTable} = selectionDetails;\r\n const otherContentRng = rng.cloneRange();\r\n startTable.each(table => otherContentRng.setStartAfter(table.dom));\r\n endTable.each(table => otherContentRng.setEndBefore(table.dom));\r\n return otherContentRng;\r\n };\r\n const handleSingleTable = (cellRng, selectionDetails, rng, isRoot) => getTableSelections(cellRng, selectionDetails, rng, isRoot).bind(({start, end}) => start.or(end)).bind(tableSelection => {\r\n const {isSameTable} = selectionDetails;\r\n const selectedCells = getSelectedCells(tableSelection).getOr([]);\r\n if (isSameTable && tableSelection.cells.length === selectedCells.length) {\r\n return Optional.some(deleteAction.fullTable(tableSelection.table));\r\n } else if (selectedCells.length > 0) {\r\n if (isSameTable) {\r\n return Optional.some(deleteAction.partialTable(selectedCells, Optional.none()));\r\n } else {\r\n const otherContentRng = unselectCells(rng, selectionDetails);\r\n return Optional.some(deleteAction.partialTable(selectedCells, Optional.some({\r\n ...selectionDetails,\r\n rng: otherContentRng\r\n })));\r\n }\r\n } else {\r\n return Optional.none();\r\n }\r\n });\r\n const handleMultiTable = (cellRng, selectionDetails, rng, isRoot) => getTableSelections(cellRng, selectionDetails, rng, isRoot).bind(({start, end}) => {\r\n const startTableSelectedCells = start.bind(getSelectedCells).getOr([]);\r\n const endTableSelectedCells = end.bind(getSelectedCells).getOr([]);\r\n if (startTableSelectedCells.length > 0 && endTableSelectedCells.length > 0) {\r\n const otherContentRng = unselectCells(rng, selectionDetails);\r\n return Optional.some(deleteAction.multiTable(startTableSelectedCells, endTableSelectedCells, otherContentRng));\r\n } else {\r\n return Optional.none();\r\n }\r\n });\r\n const getActionFromRange = (root, rng) => {\r\n const isRoot = isRootFromElement(root);\r\n const optCellRng = getCellRng(rng, isRoot);\r\n const selectionDetails = getTableDetailsFromRange(rng, isRoot);\r\n if (isSingleCellTableContentSelected(optCellRng, rng, isRoot)) {\r\n return optCellRng.map(cellRng => deleteAction.singleCellTable(rng, cellRng.start));\r\n } else if (selectionDetails.isMultiTable) {\r\n return handleMultiTable(optCellRng, selectionDetails, rng, isRoot);\r\n } else {\r\n return handleSingleTable(optCellRng, selectionDetails, rng, isRoot);\r\n }\r\n };\r\n\r\n const cleanCells = cells => each$e(cells, cell => {\r\n remove$b(cell, 'contenteditable');\r\n fillWithPaddingBr(cell);\r\n });\r\n const getOutsideBlock = (editor, container) => Optional.from(editor.dom.getParent(container, editor.dom.isBlock)).map(SugarElement.fromDom);\r\n const handleEmptyBlock = (editor, startInTable, emptyBlock) => {\r\n emptyBlock.each(block => {\r\n if (startInTable) {\r\n remove$6(block);\r\n } else {\r\n fillWithPaddingBr(block);\r\n editor.selection.setCursorLocation(block.dom, 0);\r\n }\r\n });\r\n };\r\n const deleteContentInsideCell = (editor, cell, rng, isFirstCellInSelection) => {\r\n const insideTableRng = rng.cloneRange();\r\n if (isFirstCellInSelection) {\r\n insideTableRng.setStart(rng.startContainer, rng.startOffset);\r\n insideTableRng.setEndAfter(cell.dom.lastChild);\r\n } else {\r\n insideTableRng.setStartBefore(cell.dom.firstChild);\r\n insideTableRng.setEnd(rng.endContainer, rng.endOffset);\r\n }\r\n deleteCellContents(editor, insideTableRng, cell, false).each(action => action());\r\n };\r\n const collapseAndRestoreCellSelection = editor => {\r\n const selectedCells = getCellsFromEditor(editor);\r\n const selectedNode = SugarElement.fromDom(editor.selection.getNode());\r\n if (isTableCell$3(selectedNode.dom) && isEmpty$2(selectedNode)) {\r\n editor.selection.setCursorLocation(selectedNode.dom, 0);\r\n } else {\r\n editor.selection.collapse(true);\r\n }\r\n if (selectedCells.length > 1 && exists(selectedCells, cell => eq(cell, selectedNode))) {\r\n set$3(selectedNode, 'data-mce-selected', '1');\r\n }\r\n };\r\n const emptySingleTableCells = (editor, cells, outsideDetails) => Optional.some(() => {\r\n const editorRng = editor.selection.getRng();\r\n const cellsToClean = outsideDetails.bind(({rng, isStartInTable}) => {\r\n const outsideBlock = getOutsideBlock(editor, isStartInTable ? rng.endContainer : rng.startContainer);\r\n rng.deleteContents();\r\n handleEmptyBlock(editor, isStartInTable, outsideBlock.filter(isEmpty$2));\r\n const endPointCell = isStartInTable ? cells[0] : cells[cells.length - 1];\r\n deleteContentInsideCell(editor, endPointCell, editorRng, isStartInTable);\r\n if (!isEmpty$2(endPointCell)) {\r\n return Optional.some(isStartInTable ? cells.slice(1) : cells.slice(0, -1));\r\n } else {\r\n return Optional.none();\r\n }\r\n }).getOr(cells);\r\n cleanCells(cellsToClean);\r\n collapseAndRestoreCellSelection(editor);\r\n });\r\n const emptyMultiTableCells = (editor, startTableCells, endTableCells, betweenRng) => Optional.some(() => {\r\n const rng = editor.selection.getRng();\r\n const startCell = startTableCells[0];\r\n const endCell = endTableCells[endTableCells.length - 1];\r\n deleteContentInsideCell(editor, startCell, rng, true);\r\n deleteContentInsideCell(editor, endCell, rng, false);\r\n const startTableCellsToClean = isEmpty$2(startCell) ? startTableCells : startTableCells.slice(1);\r\n const endTableCellsToClean = isEmpty$2(endCell) ? endTableCells : endTableCells.slice(0, -1);\r\n cleanCells(startTableCellsToClean.concat(endTableCellsToClean));\r\n betweenRng.deleteContents();\r\n collapseAndRestoreCellSelection(editor);\r\n });\r\n const deleteCellContents = (editor, rng, cell, moveSelection = true) => Optional.some(() => {\r\n deleteRangeContents(editor, rng, cell, moveSelection);\r\n });\r\n const deleteTableElement = (editor, table) => Optional.some(() => deleteElement$2(editor, false, table));\r\n const deleteCellRange = (editor, rootElm, rng) => getActionFromRange(rootElm, rng).bind(action => action.fold(curry(deleteCellContents, editor), curry(deleteTableElement, editor), curry(emptySingleTableCells, editor), curry(emptyMultiTableCells, editor)));\r\n const deleteCaptionRange = (editor, caption) => emptyElement(editor, caption);\r\n const deleteTableRange = (editor, rootElm, rng, startElm) => getParentCaption(rootElm, startElm).fold(() => deleteCellRange(editor, rootElm, rng), caption => deleteCaptionRange(editor, caption));\r\n const deleteRange$3 = (editor, startElm, selectedCells) => {\r\n const rootNode = SugarElement.fromDom(editor.getBody());\r\n const rng = editor.selection.getRng();\r\n return selectedCells.length !== 0 ? emptySingleTableCells(editor, selectedCells, Optional.none()) : deleteTableRange(editor, rootNode, rng, startElm);\r\n };\r\n const getParentCell = (rootElm, elm) => find$2(parentsAndSelf(elm, rootElm), isTableCell$2);\r\n const getParentCaption = (rootElm, elm) => find$2(parentsAndSelf(elm, rootElm), isTag('caption'));\r\n const deleteBetweenCells = (editor, rootElm, forward, fromCell, from) => navigate(forward, editor.getBody(), from).bind(to => getParentCell(rootElm, SugarElement.fromDom(to.getNode())).bind(toCell => eq(toCell, fromCell) ? Optional.none() : Optional.some(noop)));\r\n const emptyElement = (editor, elm) => Optional.some(() => {\r\n fillWithPaddingBr(elm);\r\n editor.selection.setCursorLocation(elm.dom, 0);\r\n });\r\n const isDeleteOfLastCharPos = (fromCaption, forward, from, to) => firstPositionIn(fromCaption.dom).bind(first => lastPositionIn(fromCaption.dom).map(last => forward ? from.isEqual(first) && to.isEqual(last) : from.isEqual(last) && to.isEqual(first))).getOr(true);\r\n const emptyCaretCaption = (editor, elm) => emptyElement(editor, elm);\r\n const validateCaretCaption = (rootElm, fromCaption, to) => getParentCaption(rootElm, SugarElement.fromDom(to.getNode())).fold(() => Optional.some(noop), toCaption => someIf(!eq(toCaption, fromCaption), noop));\r\n const deleteCaretInsideCaption = (editor, rootElm, forward, fromCaption, from) => navigate(forward, editor.getBody(), from).fold(() => Optional.some(noop), to => isDeleteOfLastCharPos(fromCaption, forward, from, to) ? emptyCaretCaption(editor, fromCaption) : validateCaretCaption(rootElm, fromCaption, to));\r\n const deleteCaretCells = (editor, forward, rootElm, startElm) => {\r\n const from = CaretPosition.fromRangeStart(editor.selection.getRng());\r\n return getParentCell(rootElm, startElm).bind(fromCell => isEmpty$2(fromCell) ? emptyElement(editor, fromCell) : deleteBetweenCells(editor, rootElm, forward, fromCell, from));\r\n };\r\n const deleteCaretCaption = (editor, forward, rootElm, fromCaption) => {\r\n const from = CaretPosition.fromRangeStart(editor.selection.getRng());\r\n return isEmpty$2(fromCaption) ? emptyElement(editor, fromCaption) : deleteCaretInsideCaption(editor, rootElm, forward, fromCaption, from);\r\n };\r\n const isNearTable = (forward, pos) => forward ? isBeforeTable(pos) : isAfterTable(pos);\r\n const isBeforeOrAfterTable = (editor, forward) => {\r\n const fromPos = CaretPosition.fromRangeStart(editor.selection.getRng());\r\n return isNearTable(forward, fromPos) || fromPosition(forward, editor.getBody(), fromPos).exists(pos => isNearTable(forward, pos));\r\n };\r\n const deleteCaret$3 = (editor, forward, startElm) => {\r\n const rootElm = SugarElement.fromDom(editor.getBody());\r\n return getParentCaption(rootElm, startElm).fold(() => deleteCaretCells(editor, forward, rootElm, startElm).orThunk(() => someIf(isBeforeOrAfterTable(editor, forward), noop)), fromCaption => deleteCaretCaption(editor, forward, rootElm, fromCaption));\r\n };\r\n const backspaceDelete$9 = (editor, forward) => {\r\n const startElm = SugarElement.fromDom(editor.selection.getStart(true));\r\n const cells = getCellsFromEditor(editor);\r\n return editor.selection.isCollapsed() && cells.length === 0 ? deleteCaret$3(editor, forward, startElm) : deleteRange$3(editor, startElm, cells);\r\n };\r\n\r\n const getContentEditableRoot$1 = (root, node) => {\r\n let tempNode = node;\r\n while (tempNode && tempNode !== root) {\r\n if (isContentEditableTrue$3(tempNode) || isContentEditableFalse$b(tempNode)) {\r\n return tempNode;\r\n }\r\n tempNode = tempNode.parentNode;\r\n }\r\n return null;\r\n };\r\n\r\n const internalAttributesPrefixes = [\r\n 'data-ephox-',\r\n 'data-mce-',\r\n 'data-alloy-',\r\n 'data-snooker-',\r\n '_'\r\n ];\r\n const each$9 = Tools.each;\r\n const ElementUtils = editor => {\r\n const dom = editor.dom;\r\n const internalAttributes = new Set(editor.serializer.getTempAttrs());\r\n const compare = (node1, node2) => {\r\n if (node1.nodeName !== node2.nodeName || node1.nodeType !== node2.nodeType) {\r\n return false;\r\n }\r\n const getAttribs = node => {\r\n const attribs = {};\r\n each$9(dom.getAttribs(node), attr => {\r\n const name = attr.nodeName.toLowerCase();\r\n if (name !== 'style' && !isAttributeInternal(name)) {\r\n attribs[name] = dom.getAttrib(node, name);\r\n }\r\n });\r\n return attribs;\r\n };\r\n const compareObjects = (obj1, obj2) => {\r\n for (const name in obj1) {\r\n if (has$2(obj1, name)) {\r\n const value = obj2[name];\r\n if (isUndefined(value)) {\r\n return false;\r\n }\r\n if (obj1[name] !== value) {\r\n return false;\r\n }\r\n delete obj2[name];\r\n }\r\n }\r\n for (const name in obj2) {\r\n if (has$2(obj2, name)) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n };\r\n if (isElement$6(node1) && isElement$6(node2)) {\r\n if (!compareObjects(getAttribs(node1), getAttribs(node2))) {\r\n return false;\r\n }\r\n if (!compareObjects(dom.parseStyle(dom.getAttrib(node1, 'style')), dom.parseStyle(dom.getAttrib(node2, 'style')))) {\r\n return false;\r\n }\r\n }\r\n return !isBookmarkNode$1(node1) && !isBookmarkNode$1(node2);\r\n };\r\n const isAttributeInternal = attributeName => exists(internalAttributesPrefixes, value => startsWith(attributeName, value)) || internalAttributes.has(attributeName);\r\n return {\r\n compare,\r\n isAttributeInternal\r\n };\r\n };\r\n\r\n const traverse = (root, fn) => {\r\n let node = root;\r\n while (node = node.walk()) {\r\n fn(node);\r\n }\r\n };\r\n const matchNode$1 = (nodeFilters, attributeFilters, node, matches) => {\r\n const name = node.name;\r\n for (let ni = 0, nl = nodeFilters.length; ni < nl; ni++) {\r\n const filter = nodeFilters[ni];\r\n if (filter.name === name) {\r\n const match = matches.nodes[name];\r\n if (match) {\r\n match.nodes.push(node);\r\n } else {\r\n matches.nodes[name] = {\r\n filter,\r\n nodes: [node]\r\n };\r\n }\r\n }\r\n }\r\n if (node.attributes) {\r\n for (let ai = 0, al = attributeFilters.length; ai < al; ai++) {\r\n const filter = attributeFilters[ai];\r\n const attrName = filter.name;\r\n if (attrName in node.attributes.map) {\r\n const match = matches.attributes[attrName];\r\n if (match) {\r\n match.nodes.push(node);\r\n } else {\r\n matches.attributes[attrName] = {\r\n filter,\r\n nodes: [node]\r\n };\r\n }\r\n }\r\n }\r\n }\r\n };\r\n const findMatchingNodes = (nodeFilters, attributeFilters, node) => {\r\n const matches = {\r\n nodes: {},\r\n attributes: {}\r\n };\r\n if (node.firstChild) {\r\n traverse(node, childNode => {\r\n matchNode$1(nodeFilters, attributeFilters, childNode, matches);\r\n });\r\n }\r\n return matches;\r\n };\r\n const runFilters = (matches, args) => {\r\n const run = (matchRecord, filteringAttributes) => {\r\n each$d(matchRecord, match => {\r\n const nodes = from(match.nodes);\r\n each$e(match.filter.callbacks, callback => {\r\n for (let i = nodes.length - 1; i >= 0; i--) {\r\n const node = nodes[i];\r\n const valueMatches = filteringAttributes ? node.attr(match.filter.name) !== undefined : node.name === match.filter.name;\r\n if (!valueMatches || isNullable(node.parent)) {\r\n nodes.splice(i, 1);\r\n }\r\n }\r\n if (nodes.length > 0) {\r\n callback(nodes, match.filter.name, args);\r\n }\r\n });\r\n });\r\n };\r\n run(matches.nodes, false);\r\n run(matches.attributes, true);\r\n };\r\n const filter$2 = (nodeFilters, attributeFilters, node, args = {}) => {\r\n const matches = findMatchingNodes(nodeFilters, attributeFilters, node);\r\n runFilters(matches, args);\r\n };\r\n\r\n const paddEmptyNode = (args, isBlock, node) => {\r\n if (args.insert && isBlock(node)) {\r\n const astNode = new AstNode('br', 1);\r\n astNode.attr('data-mce-bogus', '1');\r\n node.empty().append(astNode);\r\n } else {\r\n node.empty().append(new AstNode('#text', 3)).value = nbsp;\r\n }\r\n };\r\n const isPaddedWithNbsp = node => {\r\n var _a;\r\n return hasOnlyChild(node, '#text') && ((_a = node === null || node === void 0 ? void 0 : node.firstChild) === null || _a === void 0 ? void 0 : _a.value) === nbsp;\r\n };\r\n const hasOnlyChild = (node, name) => {\r\n const firstChild = node === null || node === void 0 ? void 0 : node.firstChild;\r\n return isNonNullable(firstChild) && firstChild === node.lastChild && firstChild.name === name;\r\n };\r\n const isPadded = (schema, node) => {\r\n const rule = schema.getElementRule(node.name);\r\n return (rule === null || rule === void 0 ? void 0 : rule.paddEmpty) === true;\r\n };\r\n const isEmpty = (schema, nonEmptyElements, whitespaceElements, node) => node.isEmpty(nonEmptyElements, whitespaceElements, node => isPadded(schema, node));\r\n const isLineBreakNode = (node, isBlock) => isNonNullable(node) && (isBlock(node) || node.name === 'br');\r\n const findClosestEditingHost = scope => {\r\n let editableNode;\r\n for (let node = scope; node; node = node.parent) {\r\n const contentEditable = node.attr('contenteditable');\r\n if (contentEditable === 'false') {\r\n break;\r\n } else if (contentEditable === 'true') {\r\n editableNode = node;\r\n }\r\n }\r\n return Optional.from(editableNode);\r\n };\r\n\r\n const removeOrUnwrapInvalidNode = (node, schema, originalNodeParent = node.parent) => {\r\n if (schema.getSpecialElements()[node.name]) {\r\n node.empty().remove();\r\n } else {\r\n const children = node.children();\r\n for (const childNode of children) {\r\n if (originalNodeParent && !schema.isValidChild(originalNodeParent.name, childNode.name)) {\r\n removeOrUnwrapInvalidNode(childNode, schema, originalNodeParent);\r\n }\r\n }\r\n node.unwrap();\r\n }\r\n };\r\n const cleanInvalidNodes = (nodes, schema, rootNode, onCreate = noop) => {\r\n const textBlockElements = schema.getTextBlockElements();\r\n const nonEmptyElements = schema.getNonEmptyElements();\r\n const whitespaceElements = schema.getWhitespaceElements();\r\n const nonSplittableElements = Tools.makeMap('tr,td,th,tbody,thead,tfoot,table');\r\n const fixed = new Set();\r\n const isSplittableElement = node => node !== rootNode && !nonSplittableElements[node.name];\r\n for (let ni = 0; ni < nodes.length; ni++) {\r\n const node = nodes[ni];\r\n let parent;\r\n let newParent;\r\n let tempNode;\r\n if (!node.parent || fixed.has(node)) {\r\n continue;\r\n }\r\n if (textBlockElements[node.name] && node.parent.name === 'li') {\r\n let sibling = node.next;\r\n while (sibling) {\r\n if (textBlockElements[sibling.name]) {\r\n sibling.name = 'li';\r\n fixed.add(sibling);\r\n node.parent.insert(sibling, node.parent);\r\n } else {\r\n break;\r\n }\r\n sibling = sibling.next;\r\n }\r\n node.unwrap();\r\n continue;\r\n }\r\n const parents = [node];\r\n for (parent = node.parent; parent && !schema.isValidChild(parent.name, node.name) && isSplittableElement(parent); parent = parent.parent) {\r\n parents.push(parent);\r\n }\r\n if (parent && parents.length > 1) {\r\n if (schema.isValidChild(parent.name, node.name)) {\r\n parents.reverse();\r\n newParent = parents[0].clone();\r\n onCreate(newParent);\r\n let currentNode = newParent;\r\n for (let i = 0; i < parents.length - 1; i++) {\r\n if (schema.isValidChild(currentNode.name, parents[i].name) && i > 0) {\r\n tempNode = parents[i].clone();\r\n onCreate(tempNode);\r\n currentNode.append(tempNode);\r\n } else {\r\n tempNode = currentNode;\r\n }\r\n for (let childNode = parents[i].firstChild; childNode && childNode !== parents[i + 1];) {\r\n const nextNode = childNode.next;\r\n tempNode.append(childNode);\r\n childNode = nextNode;\r\n }\r\n currentNode = tempNode;\r\n }\r\n if (!isEmpty(schema, nonEmptyElements, whitespaceElements, newParent)) {\r\n parent.insert(newParent, parents[0], true);\r\n parent.insert(node, newParent);\r\n } else {\r\n parent.insert(node, parents[0], true);\r\n }\r\n parent = parents[0];\r\n if (isEmpty(schema, nonEmptyElements, whitespaceElements, parent) || hasOnlyChild(parent, 'br')) {\r\n parent.empty().remove();\r\n }\r\n } else {\r\n removeOrUnwrapInvalidNode(node, schema);\r\n }\r\n } else if (node.parent) {\r\n if (node.name === 'li') {\r\n let sibling = node.prev;\r\n if (sibling && (sibling.name === 'ul' || sibling.name === 'ol')) {\r\n sibling.append(node);\r\n continue;\r\n }\r\n sibling = node.next;\r\n if (sibling && (sibling.name === 'ul' || sibling.name === 'ol') && sibling.firstChild) {\r\n sibling.insert(node, sibling.firstChild, true);\r\n continue;\r\n }\r\n const wrapper = new AstNode('ul', 1);\r\n onCreate(wrapper);\r\n node.wrap(wrapper);\r\n continue;\r\n }\r\n if (schema.isValidChild(node.parent.name, 'div') && schema.isValidChild('div', node.name)) {\r\n const wrapper = new AstNode('div', 1);\r\n onCreate(wrapper);\r\n node.wrap(wrapper);\r\n } else {\r\n removeOrUnwrapInvalidNode(node, schema);\r\n }\r\n }\r\n }\r\n };\r\n const hasClosest = (node, parentName) => {\r\n let tempNode = node;\r\n while (tempNode) {\r\n if (tempNode.name === parentName) {\r\n return true;\r\n }\r\n tempNode = tempNode.parent;\r\n }\r\n return false;\r\n };\r\n const isInvalid = (schema, node, parent = node.parent) => {\r\n if (parent && schema.children[node.name] && !schema.isValidChild(parent.name, node.name)) {\r\n return true;\r\n } else if (parent && node.name === 'a' && hasClosest(parent, 'a')) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n };\r\n\r\n const createRange = (sc, so, ec, eo) => {\r\n const rng = document.createRange();\r\n rng.setStart(sc, so);\r\n rng.setEnd(ec, eo);\r\n return rng;\r\n };\r\n const normalizeBlockSelectionRange = rng => {\r\n const startPos = CaretPosition.fromRangeStart(rng);\r\n const endPos = CaretPosition.fromRangeEnd(rng);\r\n const rootNode = rng.commonAncestorContainer;\r\n return fromPosition(false, rootNode, endPos).map(newEndPos => {\r\n if (!isInSameBlock(startPos, endPos, rootNode) && isInSameBlock(startPos, newEndPos, rootNode)) {\r\n return createRange(startPos.container(), startPos.offset(), newEndPos.container(), newEndPos.offset());\r\n } else {\r\n return rng;\r\n }\r\n }).getOr(rng);\r\n };\r\n const normalize = rng => rng.collapsed ? rng : normalizeBlockSelectionRange(rng);\r\n\r\n const hasOnlyOneChild = node => {\r\n return isNonNullable(node.firstChild) && node.firstChild === node.lastChild;\r\n };\r\n const isPaddingNode = node => {\r\n return node.name === 'br' || node.value === nbsp;\r\n };\r\n const isPaddedEmptyBlock = (schema, node) => {\r\n const blockElements = schema.getBlockElements();\r\n return blockElements[node.name] && hasOnlyOneChild(node) && isPaddingNode(node.firstChild);\r\n };\r\n const isEmptyFragmentElement = (schema, node) => {\r\n const nonEmptyElements = schema.getNonEmptyElements();\r\n return isNonNullable(node) && (node.isEmpty(nonEmptyElements) || isPaddedEmptyBlock(schema, node));\r\n };\r\n const isListFragment = (schema, fragment) => {\r\n let firstChild = fragment.firstChild;\r\n let lastChild = fragment.lastChild;\r\n if (firstChild && firstChild.name === 'meta') {\r\n firstChild = firstChild.next;\r\n }\r\n if (lastChild && lastChild.attr('id') === 'mce_marker') {\r\n lastChild = lastChild.prev;\r\n }\r\n if (isEmptyFragmentElement(schema, lastChild)) {\r\n lastChild = lastChild === null || lastChild === void 0 ? void 0 : lastChild.prev;\r\n }\r\n if (!firstChild || firstChild !== lastChild) {\r\n return false;\r\n }\r\n return firstChild.name === 'ul' || firstChild.name === 'ol';\r\n };\r\n const cleanupDomFragment = domFragment => {\r\n var _a, _b;\r\n const firstChild = domFragment.firstChild;\r\n const lastChild = domFragment.lastChild;\r\n if (firstChild && firstChild.nodeName === 'META') {\r\n (_a = firstChild.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(firstChild);\r\n }\r\n if (lastChild && lastChild.id === 'mce_marker') {\r\n (_b = lastChild.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(lastChild);\r\n }\r\n return domFragment;\r\n };\r\n const toDomFragment = (dom, serializer, fragment) => {\r\n const html = serializer.serialize(fragment);\r\n const domFragment = dom.createFragment(html);\r\n return cleanupDomFragment(domFragment);\r\n };\r\n const listItems = elm => {\r\n var _a;\r\n return filter$5((_a = elm === null || elm === void 0 ? void 0 : elm.childNodes) !== null && _a !== void 0 ? _a : [], child => {\r\n return child.nodeName === 'LI';\r\n });\r\n };\r\n const isPadding = node => {\r\n return node.data === nbsp || isBr$6(node);\r\n };\r\n const isListItemPadded = node => {\r\n return isNonNullable(node === null || node === void 0 ? void 0 : node.firstChild) && node.firstChild === node.lastChild && isPadding(node.firstChild);\r\n };\r\n const isEmptyOrPadded = elm => {\r\n return !elm.firstChild || isListItemPadded(elm);\r\n };\r\n const trimListItems = elms => {\r\n return elms.length > 0 && isEmptyOrPadded(elms[elms.length - 1]) ? elms.slice(0, -1) : elms;\r\n };\r\n const getParentLi = (dom, node) => {\r\n const parentBlock = dom.getParent(node, dom.isBlock);\r\n return parentBlock && parentBlock.nodeName === 'LI' ? parentBlock : null;\r\n };\r\n const isParentBlockLi = (dom, node) => {\r\n return !!getParentLi(dom, node);\r\n };\r\n const getSplit = (parentNode, rng) => {\r\n const beforeRng = rng.cloneRange();\r\n const afterRng = rng.cloneRange();\r\n beforeRng.setStartBefore(parentNode);\r\n afterRng.setEndAfter(parentNode);\r\n return [\r\n beforeRng.cloneContents(),\r\n afterRng.cloneContents()\r\n ];\r\n };\r\n const findFirstIn = (node, rootNode) => {\r\n const caretPos = CaretPosition.before(node);\r\n const caretWalker = CaretWalker(rootNode);\r\n const newCaretPos = caretWalker.next(caretPos);\r\n return newCaretPos ? newCaretPos.toRange() : null;\r\n };\r\n const findLastOf = (node, rootNode) => {\r\n const caretPos = CaretPosition.after(node);\r\n const caretWalker = CaretWalker(rootNode);\r\n const newCaretPos = caretWalker.prev(caretPos);\r\n return newCaretPos ? newCaretPos.toRange() : null;\r\n };\r\n const insertMiddle = (target, elms, rootNode, rng) => {\r\n const parts = getSplit(target, rng);\r\n const parentElm = target.parentNode;\r\n if (parentElm) {\r\n parentElm.insertBefore(parts[0], target);\r\n Tools.each(elms, li => {\r\n parentElm.insertBefore(li, target);\r\n });\r\n parentElm.insertBefore(parts[1], target);\r\n parentElm.removeChild(target);\r\n }\r\n return findLastOf(elms[elms.length - 1], rootNode);\r\n };\r\n const insertBefore$1 = (target, elms, rootNode) => {\r\n const parentElm = target.parentNode;\r\n if (parentElm) {\r\n Tools.each(elms, elm => {\r\n parentElm.insertBefore(elm, target);\r\n });\r\n }\r\n return findFirstIn(target, rootNode);\r\n };\r\n const insertAfter$1 = (target, elms, rootNode, dom) => {\r\n dom.insertAfter(elms.reverse(), target);\r\n return findLastOf(elms[0], rootNode);\r\n };\r\n const insertAtCaret$1 = (serializer, dom, rng, fragment) => {\r\n const domFragment = toDomFragment(dom, serializer, fragment);\r\n const liTarget = getParentLi(dom, rng.startContainer);\r\n const liElms = trimListItems(listItems(domFragment.firstChild));\r\n const BEGINNING = 1, END = 2;\r\n const rootNode = dom.getRoot();\r\n const isAt = location => {\r\n const caretPos = CaretPosition.fromRangeStart(rng);\r\n const caretWalker = CaretWalker(dom.getRoot());\r\n const newPos = location === BEGINNING ? caretWalker.prev(caretPos) : caretWalker.next(caretPos);\r\n const newPosNode = newPos === null || newPos === void 0 ? void 0 : newPos.getNode();\r\n return newPosNode ? getParentLi(dom, newPosNode) !== liTarget : true;\r\n };\r\n if (!liTarget) {\r\n return null;\r\n } else if (isAt(BEGINNING)) {\r\n return insertBefore$1(liTarget, liElms, rootNode);\r\n } else if (isAt(END)) {\r\n return insertAfter$1(liTarget, liElms, rootNode, dom);\r\n } else {\r\n return insertMiddle(liTarget, liElms, rootNode, rng);\r\n }\r\n };\r\n\r\n const mergeableWrappedElements = ['pre'];\r\n const shouldPasteContentOnly = (dom, fragment, parentNode, root) => {\r\n var _a;\r\n const firstNode = fragment.firstChild;\r\n const lastNode = fragment.lastChild;\r\n const last = lastNode.attr('data-mce-type') === 'bookmark' ? lastNode.prev : lastNode;\r\n const isPastingSingleElement = firstNode === last;\r\n const isWrappedElement = contains$2(mergeableWrappedElements, firstNode.name);\r\n if (isPastingSingleElement && isWrappedElement) {\r\n const isContentEditable = firstNode.attr('contenteditable') !== 'false';\r\n const isPastingInTheSameBlockTag = ((_a = dom.getParent(parentNode, dom.isBlock)) === null || _a === void 0 ? void 0 : _a.nodeName.toLowerCase()) === firstNode.name;\r\n const isPastingInContentEditable = Optional.from(getContentEditableRoot$1(root, parentNode)).forall(isContentEditableTrue$3);\r\n return isContentEditable && isPastingInTheSameBlockTag && isPastingInContentEditable;\r\n } else {\r\n return false;\r\n }\r\n };\r\n const isTableCell = isTableCell$3;\r\n const isTableCellContentSelected = (dom, rng, cell) => {\r\n if (isNonNullable(cell)) {\r\n const endCell = dom.getParent(rng.endContainer, isTableCell);\r\n return cell === endCell && hasAllContentsSelected(SugarElement.fromDom(cell), rng);\r\n } else {\r\n return false;\r\n }\r\n };\r\n const validInsertion = (editor, value, parentNode) => {\r\n var _a;\r\n if (parentNode.getAttribute('data-mce-bogus') === 'all') {\r\n (_a = parentNode.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(editor.dom.createFragment(value), parentNode);\r\n } else {\r\n const node = parentNode.firstChild;\r\n const node2 = parentNode.lastChild;\r\n if (!node || node === node2 && node.nodeName === 'BR') {\r\n editor.dom.setHTML(parentNode, value);\r\n } else {\r\n editor.selection.setContent(value, { no_events: true });\r\n }\r\n }\r\n };\r\n const trimBrsFromTableCell = (dom, elm) => {\r\n Optional.from(dom.getParent(elm, 'td,th')).map(SugarElement.fromDom).each(trimBlockTrailingBr);\r\n };\r\n const reduceInlineTextElements = (editor, merge) => {\r\n const textInlineElements = editor.schema.getTextInlineElements();\r\n const dom = editor.dom;\r\n if (merge) {\r\n const root = editor.getBody();\r\n const elementUtils = ElementUtils(editor);\r\n Tools.each(dom.select('*[data-mce-fragment]'), node => {\r\n const isInline = isNonNullable(textInlineElements[node.nodeName.toLowerCase()]);\r\n if (isInline && hasInheritableStyles(dom, node)) {\r\n for (let parentNode = node.parentElement; isNonNullable(parentNode) && parentNode !== root; parentNode = parentNode.parentElement) {\r\n const styleConflict = hasStyleConflict(dom, node, parentNode);\r\n if (styleConflict) {\r\n break;\r\n }\r\n if (elementUtils.compare(parentNode, node)) {\r\n dom.remove(node, true);\r\n break;\r\n }\r\n }\r\n }\r\n });\r\n }\r\n };\r\n const markFragmentElements = fragment => {\r\n let node = fragment;\r\n while (node = node.walk()) {\r\n if (node.type === 1) {\r\n node.attr('data-mce-fragment', '1');\r\n }\r\n }\r\n };\r\n const unmarkFragmentElements = elm => {\r\n Tools.each(elm.getElementsByTagName('*'), elm => {\r\n elm.removeAttribute('data-mce-fragment');\r\n });\r\n };\r\n const isPartOfFragment = node => {\r\n return !!node.getAttribute('data-mce-fragment');\r\n };\r\n const canHaveChildren = (editor, node) => {\r\n return isNonNullable(node) && !editor.schema.getVoidElements()[node.nodeName];\r\n };\r\n const moveSelectionToMarker = (editor, marker) => {\r\n var _a, _b, _c;\r\n let nextRng;\r\n const dom = editor.dom;\r\n const selection = editor.selection;\r\n if (!marker) {\r\n return;\r\n }\r\n selection.scrollIntoView(marker);\r\n const parentEditableElm = getContentEditableRoot$1(editor.getBody(), marker);\r\n if (parentEditableElm && dom.getContentEditable(parentEditableElm) === 'false') {\r\n dom.remove(marker);\r\n selection.select(parentEditableElm);\r\n return;\r\n }\r\n let rng = dom.createRng();\r\n const node = marker.previousSibling;\r\n if (isText$a(node)) {\r\n rng.setStart(node, (_b = (_a = node.nodeValue) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0);\r\n const node2 = marker.nextSibling;\r\n if (isText$a(node2)) {\r\n node.appendData(node2.data);\r\n (_c = node2.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(node2);\r\n }\r\n } else {\r\n rng.setStartBefore(marker);\r\n rng.setEndBefore(marker);\r\n }\r\n const findNextCaretRng = rng => {\r\n let caretPos = CaretPosition.fromRangeStart(rng);\r\n const caretWalker = CaretWalker(editor.getBody());\r\n caretPos = caretWalker.next(caretPos);\r\n return caretPos === null || caretPos === void 0 ? void 0 : caretPos.toRange();\r\n };\r\n const parentBlock = dom.getParent(marker, dom.isBlock);\r\n dom.remove(marker);\r\n if (parentBlock && dom.isEmpty(parentBlock)) {\r\n empty(SugarElement.fromDom(parentBlock));\r\n rng.setStart(parentBlock, 0);\r\n rng.setEnd(parentBlock, 0);\r\n if (!isTableCell(parentBlock) && !isPartOfFragment(parentBlock) && (nextRng = findNextCaretRng(rng))) {\r\n rng = nextRng;\r\n dom.remove(parentBlock);\r\n } else {\r\n dom.add(parentBlock, dom.create('br', { 'data-mce-bogus': '1' }));\r\n }\r\n }\r\n selection.setRng(rng);\r\n };\r\n const deleteSelectedContent = editor => {\r\n const dom = editor.dom;\r\n const rng = normalize(editor.selection.getRng());\r\n editor.selection.setRng(rng);\r\n const startCell = dom.getParent(rng.startContainer, isTableCell);\r\n if (isTableCellContentSelected(dom, rng, startCell)) {\r\n deleteCellContents(editor, rng, SugarElement.fromDom(startCell));\r\n } else if (rng.startContainer === rng.endContainer && rng.endOffset - rng.startOffset === 1 && isText$a(rng.startContainer.childNodes[rng.startOffset])) {\r\n rng.deleteContents();\r\n } else {\r\n editor.getDoc().execCommand('Delete', false);\r\n }\r\n };\r\n const findMarkerNode = scope => {\r\n for (let markerNode = scope; markerNode; markerNode = markerNode.walk()) {\r\n if (markerNode.attr('id') === 'mce_marker') {\r\n return Optional.some(markerNode);\r\n }\r\n }\r\n return Optional.none();\r\n };\r\n const insertHtmlAtCaret = (editor, value, details) => {\r\n var _a, _b;\r\n const selection = editor.selection;\r\n const dom = editor.dom;\r\n const parser = editor.parser;\r\n const merge = details.merge;\r\n const serializer = HtmlSerializer({ validate: true }, editor.schema);\r\n const bookmarkHtml = '';\r\n if (value.indexOf('{$caret}') === -1) {\r\n value += '{$caret}';\r\n }\r\n value = value.replace(/\\{\\$caret\\}/, bookmarkHtml);\r\n let rng = selection.getRng();\r\n const caretElement = rng.startContainer;\r\n const body = editor.getBody();\r\n if (caretElement === body && selection.isCollapsed()) {\r\n if (dom.isBlock(body.firstChild) && canHaveChildren(editor, body.firstChild) && dom.isEmpty(body.firstChild)) {\r\n rng = dom.createRng();\r\n rng.setStart(body.firstChild, 0);\r\n rng.setEnd(body.firstChild, 0);\r\n selection.setRng(rng);\r\n }\r\n }\r\n if (!selection.isCollapsed()) {\r\n deleteSelectedContent(editor);\r\n }\r\n const parentNode = selection.getNode();\r\n const parserArgs = {\r\n context: parentNode.nodeName.toLowerCase(),\r\n data: details.data,\r\n insert: true\r\n };\r\n const fragment = parser.parse(value, parserArgs);\r\n if (details.paste === true && isListFragment(editor.schema, fragment) && isParentBlockLi(dom, parentNode)) {\r\n rng = insertAtCaret$1(serializer, dom, selection.getRng(), fragment);\r\n if (rng) {\r\n selection.setRng(rng);\r\n }\r\n return value;\r\n }\r\n if (details.paste === true && shouldPasteContentOnly(dom, fragment, parentNode, editor.getBody())) {\r\n (_a = fragment.firstChild) === null || _a === void 0 ? void 0 : _a.unwrap();\r\n }\r\n markFragmentElements(fragment);\r\n let node = fragment.lastChild;\r\n if (node && node.attr('id') === 'mce_marker') {\r\n const marker = node;\r\n for (node = node.prev; node; node = node.walk(true)) {\r\n if (node.type === 3 || !dom.isBlock(node.name)) {\r\n if (node.parent && editor.schema.isValidChild(node.parent.name, 'span')) {\r\n node.parent.insert(marker, node, node.name === 'br');\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n editor._selectionOverrides.showBlockCaretContainer(parentNode);\r\n if (!parserArgs.invalid) {\r\n value = serializer.serialize(fragment);\r\n validInsertion(editor, value, parentNode);\r\n } else {\r\n editor.selection.setContent(bookmarkHtml);\r\n let parentNode = selection.getNode();\r\n let tempNode;\r\n const rootNode = editor.getBody();\r\n if (isDocument$1(parentNode)) {\r\n parentNode = tempNode = rootNode;\r\n } else {\r\n tempNode = parentNode;\r\n }\r\n while (tempNode && tempNode !== rootNode) {\r\n parentNode = tempNode;\r\n tempNode = tempNode.parentNode;\r\n }\r\n value = parentNode === rootNode ? rootNode.innerHTML : dom.getOuterHTML(parentNode);\r\n const root = parser.parse(value);\r\n const markerNode = findMarkerNode(root);\r\n const editingHost = markerNode.bind(findClosestEditingHost).getOr(root);\r\n markerNode.each(marker => marker.replace(fragment));\r\n const toExtract = fragment.children();\r\n const parent = (_b = fragment.parent) !== null && _b !== void 0 ? _b : root;\r\n fragment.unwrap();\r\n const invalidChildren = filter$5(toExtract, node => isInvalid(editor.schema, node, parent));\r\n cleanInvalidNodes(invalidChildren, editor.schema, editingHost);\r\n filter$2(parser.getNodeFilters(), parser.getAttributeFilters(), root);\r\n value = serializer.serialize(root);\r\n if (parentNode === rootNode) {\r\n dom.setHTML(rootNode, value);\r\n } else {\r\n dom.setOuterHTML(parentNode, value);\r\n }\r\n }\r\n reduceInlineTextElements(editor, merge);\r\n moveSelectionToMarker(editor, dom.get('mce_marker'));\r\n unmarkFragmentElements(editor.getBody());\r\n trimBrsFromTableCell(dom, selection.getStart());\r\n updateCaret(editor.schema, editor.getBody(), selection.getStart());\r\n return value;\r\n };\r\n\r\n const isTreeNode = content => content instanceof AstNode;\r\n\r\n const moveSelection = editor => {\r\n if (hasFocus(editor)) {\r\n firstPositionIn(editor.getBody()).each(pos => {\r\n const node = pos.getNode();\r\n const caretPos = isTable$2(node) ? firstPositionIn(node).getOr(pos) : pos;\r\n editor.selection.setRng(caretPos.toRange());\r\n });\r\n }\r\n };\r\n const setEditorHtml = (editor, html, noSelection) => {\r\n editor.dom.setHTML(editor.getBody(), html);\r\n if (noSelection !== true) {\r\n moveSelection(editor);\r\n }\r\n };\r\n const setContentString = (editor, body, content, args) => {\r\n if (content.length === 0 || /^\\s+$/.test(content)) {\r\n const padd = '
';\r\n if (body.nodeName === 'TABLE') {\r\n content = '' + padd + '';\r\n } else if (/^(UL|OL)$/.test(body.nodeName)) {\r\n content = '
  • ' + padd + '
  • ';\r\n }\r\n const forcedRootBlockName = getForcedRootBlock(editor);\r\n if (editor.schema.isValidChild(body.nodeName.toLowerCase(), forcedRootBlockName.toLowerCase())) {\r\n content = padd;\r\n content = editor.dom.createHTML(forcedRootBlockName, getForcedRootBlockAttrs(editor), content);\r\n } else if (!content) {\r\n content = padd;\r\n }\r\n setEditorHtml(editor, content, args.no_selection);\r\n return {\r\n content,\r\n html: content\r\n };\r\n } else {\r\n if (args.format !== 'raw') {\r\n content = HtmlSerializer({ validate: false }, editor.schema).serialize(editor.parser.parse(content, {\r\n isRootContent: true,\r\n insert: true\r\n }));\r\n }\r\n const trimmedHtml = isWsPreserveElement(SugarElement.fromDom(body)) ? content : Tools.trim(content);\r\n setEditorHtml(editor, trimmedHtml, args.no_selection);\r\n return {\r\n content: trimmedHtml,\r\n html: trimmedHtml\r\n };\r\n }\r\n };\r\n const setContentTree = (editor, body, content, args) => {\r\n filter$2(editor.parser.getNodeFilters(), editor.parser.getAttributeFilters(), content);\r\n const html = HtmlSerializer({ validate: false }, editor.schema).serialize(content);\r\n const trimmedHtml = isWsPreserveElement(SugarElement.fromDom(body)) ? html : Tools.trim(html);\r\n setEditorHtml(editor, trimmedHtml, args.no_selection);\r\n return {\r\n content,\r\n html: trimmedHtml\r\n };\r\n };\r\n const setContentInternal = (editor, content, args) => {\r\n return Optional.from(editor.getBody()).map(body => {\r\n if (isTreeNode(content)) {\r\n return setContentTree(editor, body, content, args);\r\n } else {\r\n return setContentString(editor, body, content, args);\r\n }\r\n }).getOr({\r\n content,\r\n html: isTreeNode(args.content) ? '' : args.content\r\n });\r\n };\r\n\r\n const ancestor$1 = (scope, predicate, isRoot) => ancestor$4(scope, predicate, isRoot).isSome();\r\n const sibling = (scope, predicate) => sibling$1(scope, predicate).isSome();\r\n\r\n const ensureIsRoot = isRoot => isFunction(isRoot) ? isRoot : never;\r\n const ancestor = (scope, transform, isRoot) => {\r\n let element = scope.dom;\r\n const stop = ensureIsRoot(isRoot);\r\n while (element.parentNode) {\r\n element = element.parentNode;\r\n const el = SugarElement.fromDom(element);\r\n const transformed = transform(el);\r\n if (transformed.isSome()) {\r\n return transformed;\r\n } else if (stop(el)) {\r\n break;\r\n }\r\n }\r\n return Optional.none();\r\n };\r\n const closest$1 = (scope, transform, isRoot) => {\r\n const current = transform(scope);\r\n const stop = ensureIsRoot(isRoot);\r\n return current.orThunk(() => stop(scope) ? Optional.none() : ancestor(scope, transform, stop));\r\n };\r\n\r\n const isEq$3 = isEq$5;\r\n const matchesUnInheritedFormatSelector = (ed, node, name) => {\r\n const formatList = ed.formatter.get(name);\r\n if (formatList) {\r\n for (let i = 0; i < formatList.length; i++) {\r\n const format = formatList[i];\r\n if (isSelectorFormat(format) && format.inherit === false && ed.dom.is(node, format.selector)) {\r\n return true;\r\n }\r\n }\r\n }\r\n return false;\r\n };\r\n const matchParents = (editor, node, name, vars, similar) => {\r\n const root = editor.dom.getRoot();\r\n if (node === root) {\r\n return false;\r\n }\r\n const matchedNode = editor.dom.getParent(node, elm => {\r\n if (matchesUnInheritedFormatSelector(editor, elm, name)) {\r\n return true;\r\n }\r\n return elm.parentNode === root || !!matchNode(editor, elm, name, vars, true);\r\n });\r\n return !!matchNode(editor, matchedNode, name, vars, similar);\r\n };\r\n const matchName = (dom, node, format) => {\r\n if (isInlineFormat(format) && isEq$3(node, format.inline)) {\r\n return true;\r\n }\r\n if (isBlockFormat(format) && isEq$3(node, format.block)) {\r\n return true;\r\n }\r\n if (isSelectorFormat(format)) {\r\n return isElement$6(node) && dom.is(node, format.selector);\r\n }\r\n return false;\r\n };\r\n const matchItems = (dom, node, format, itemName, similar, vars) => {\r\n const items = format[itemName];\r\n const matchAttributes = itemName === 'attributes';\r\n if (isFunction(format.onmatch)) {\r\n return format.onmatch(node, format, itemName);\r\n }\r\n if (items) {\r\n if (!isArrayLike(items)) {\r\n for (const key in items) {\r\n if (has$2(items, key)) {\r\n const value = matchAttributes ? dom.getAttrib(node, key) : getStyle(dom, node, key);\r\n const expectedValue = replaceVars(items[key], vars);\r\n const isEmptyValue = isNullable(value) || isEmpty$3(value);\r\n if (isEmptyValue && isNullable(expectedValue)) {\r\n continue;\r\n }\r\n if (similar && isEmptyValue && !format.exact) {\r\n return false;\r\n }\r\n if ((!similar || format.exact) && !isEq$3(value, normalizeStyleValue(expectedValue, key))) {\r\n return false;\r\n }\r\n }\r\n }\r\n } else {\r\n for (let i = 0; i < items.length; i++) {\r\n if (matchAttributes ? dom.getAttrib(node, items[i]) : getStyle(dom, node, items[i])) {\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n return true;\r\n };\r\n const matchNode = (ed, node, name, vars, similar) => {\r\n const formatList = ed.formatter.get(name);\r\n const dom = ed.dom;\r\n if (formatList && isElement$6(node)) {\r\n for (let i = 0; i < formatList.length; i++) {\r\n const format = formatList[i];\r\n if (matchName(ed.dom, node, format) && matchItems(dom, node, format, 'attributes', similar, vars) && matchItems(dom, node, format, 'styles', similar, vars)) {\r\n const classes = format.classes;\r\n if (classes) {\r\n for (let x = 0; x < classes.length; x++) {\r\n if (!ed.dom.hasClass(node, replaceVars(classes[x], vars))) {\r\n return;\r\n }\r\n }\r\n }\r\n return format;\r\n }\r\n }\r\n }\r\n return undefined;\r\n };\r\n const match$2 = (editor, name, vars, node, similar) => {\r\n if (node) {\r\n return matchParents(editor, node, name, vars, similar);\r\n }\r\n node = editor.selection.getNode();\r\n if (matchParents(editor, node, name, vars, similar)) {\r\n return true;\r\n }\r\n const startNode = editor.selection.getStart();\r\n if (startNode !== node) {\r\n if (matchParents(editor, startNode, name, vars, similar)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n };\r\n const matchAll = (editor, names, vars) => {\r\n const matchedFormatNames = [];\r\n const checkedMap = {};\r\n const startElement = editor.selection.getStart();\r\n editor.dom.getParent(startElement, node => {\r\n for (let i = 0; i < names.length; i++) {\r\n const name = names[i];\r\n if (!checkedMap[name] && matchNode(editor, node, name, vars)) {\r\n checkedMap[name] = true;\r\n matchedFormatNames.push(name);\r\n }\r\n }\r\n }, editor.dom.getRoot());\r\n return matchedFormatNames;\r\n };\r\n const closest = (editor, names) => {\r\n const isRoot = elm => eq(elm, SugarElement.fromDom(editor.getBody()));\r\n const match = (elm, name) => matchNode(editor, elm.dom, name) ? Optional.some(name) : Optional.none();\r\n return Optional.from(editor.selection.getStart(true)).bind(rawElm => closest$1(SugarElement.fromDom(rawElm), elm => findMap(names, name => match(elm, name)), isRoot)).getOrNull();\r\n };\r\n const canApply = (editor, name) => {\r\n const formatList = editor.formatter.get(name);\r\n const dom = editor.dom;\r\n if (formatList) {\r\n const startNode = editor.selection.getStart();\r\n const parents = getParents$2(dom, startNode);\r\n for (let x = formatList.length - 1; x >= 0; x--) {\r\n const format = formatList[x];\r\n if (!isSelectorFormat(format)) {\r\n return true;\r\n }\r\n for (let i = parents.length - 1; i >= 0; i--) {\r\n if (dom.is(parents[i], format.selector)) {\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n return false;\r\n };\r\n const matchAllOnNode = (editor, node, formatNames) => foldl(formatNames, (acc, name) => {\r\n const matchSimilar = isVariableFormatName(editor, name);\r\n if (editor.formatter.matchNode(node, name, {}, matchSimilar)) {\r\n return acc.concat([name]);\r\n } else {\r\n return acc;\r\n }\r\n }, []);\r\n\r\n const ZWSP = ZWSP$1;\r\n const importNode = (ownerDocument, node) => {\r\n return ownerDocument.importNode(node, true);\r\n };\r\n const getEmptyCaretContainers = node => {\r\n const nodes = [];\r\n let tempNode = node;\r\n while (tempNode) {\r\n if (isText$a(tempNode) && tempNode.data !== ZWSP || tempNode.childNodes.length > 1) {\r\n return [];\r\n }\r\n if (isElement$6(tempNode)) {\r\n nodes.push(tempNode);\r\n }\r\n tempNode = tempNode.firstChild;\r\n }\r\n return nodes;\r\n };\r\n const isCaretContainerEmpty = node => {\r\n return getEmptyCaretContainers(node).length > 0;\r\n };\r\n const findFirstTextNode = node => {\r\n if (node) {\r\n const walker = new DomTreeWalker(node, node);\r\n for (let tempNode = walker.current(); tempNode; tempNode = walker.next()) {\r\n if (isText$a(tempNode)) {\r\n return tempNode;\r\n }\r\n }\r\n }\r\n return null;\r\n };\r\n const createCaretContainer = fill => {\r\n const caretContainer = SugarElement.fromTag('span');\r\n setAll$1(caretContainer, {\r\n 'id': CARET_ID,\r\n 'data-mce-bogus': '1',\r\n 'data-mce-type': 'format-caret'\r\n });\r\n if (fill) {\r\n append$1(caretContainer, SugarElement.fromText(ZWSP));\r\n }\r\n return caretContainer;\r\n };\r\n const trimZwspFromCaretContainer = caretContainerNode => {\r\n const textNode = findFirstTextNode(caretContainerNode);\r\n if (textNode && textNode.data.charAt(0) === ZWSP) {\r\n textNode.deleteData(0, 1);\r\n }\r\n return textNode;\r\n };\r\n const removeCaretContainerNode = (editor, node, moveCaret = true) => {\r\n const dom = editor.dom, selection = editor.selection;\r\n if (isCaretContainerEmpty(node)) {\r\n deleteElement$2(editor, false, SugarElement.fromDom(node), moveCaret);\r\n } else {\r\n const rng = selection.getRng();\r\n const block = dom.getParent(node, dom.isBlock);\r\n const startContainer = rng.startContainer;\r\n const startOffset = rng.startOffset;\r\n const endContainer = rng.endContainer;\r\n const endOffset = rng.endOffset;\r\n const textNode = trimZwspFromCaretContainer(node);\r\n dom.remove(node, true);\r\n if (startContainer === textNode && startOffset > 0) {\r\n rng.setStart(textNode, startOffset - 1);\r\n }\r\n if (endContainer === textNode && endOffset > 0) {\r\n rng.setEnd(textNode, endOffset - 1);\r\n }\r\n if (block && dom.isEmpty(block)) {\r\n fillWithPaddingBr(SugarElement.fromDom(block));\r\n }\r\n selection.setRng(rng);\r\n }\r\n };\r\n const removeCaretContainer = (editor, node, moveCaret = true) => {\r\n const dom = editor.dom, selection = editor.selection;\r\n if (!node) {\r\n node = getParentCaretContainer(editor.getBody(), selection.getStart());\r\n if (!node) {\r\n while (node = dom.get(CARET_ID)) {\r\n removeCaretContainerNode(editor, node, false);\r\n }\r\n }\r\n } else {\r\n removeCaretContainerNode(editor, node, moveCaret);\r\n }\r\n };\r\n const insertCaretContainerNode = (editor, caretContainer, formatNode) => {\r\n var _a, _b;\r\n const dom = editor.dom;\r\n const block = dom.getParent(formatNode, curry(isTextBlock$1, editor.schema));\r\n if (block && dom.isEmpty(block)) {\r\n (_a = formatNode.parentNode) === null || _a === void 0 ? void 0 : _a.replaceChild(caretContainer, formatNode);\r\n } else {\r\n removeTrailingBr(SugarElement.fromDom(formatNode));\r\n if (dom.isEmpty(formatNode)) {\r\n (_b = formatNode.parentNode) === null || _b === void 0 ? void 0 : _b.replaceChild(caretContainer, formatNode);\r\n } else {\r\n dom.insertAfter(caretContainer, formatNode);\r\n }\r\n }\r\n };\r\n const appendNode = (parentNode, node) => {\r\n parentNode.appendChild(node);\r\n return node;\r\n };\r\n const insertFormatNodesIntoCaretContainer = (formatNodes, caretContainer) => {\r\n var _a;\r\n const innerMostFormatNode = foldr(formatNodes, (parentNode, formatNode) => {\r\n return appendNode(parentNode, formatNode.cloneNode(false));\r\n }, caretContainer);\r\n const doc = (_a = innerMostFormatNode.ownerDocument) !== null && _a !== void 0 ? _a : document;\r\n return appendNode(innerMostFormatNode, doc.createTextNode(ZWSP));\r\n };\r\n const cleanFormatNode = (editor, caretContainer, formatNode, name, vars, similar) => {\r\n const formatter = editor.formatter;\r\n const dom = editor.dom;\r\n const validFormats = filter$5(keys(formatter.get()), formatName => formatName !== name && !contains$1(formatName, 'removeformat'));\r\n const matchedFormats = matchAllOnNode(editor, formatNode, validFormats);\r\n const uniqueFormats = filter$5(matchedFormats, fmtName => !areSimilarFormats(editor, fmtName, name));\r\n if (uniqueFormats.length > 0) {\r\n const clonedFormatNode = formatNode.cloneNode(false);\r\n dom.add(caretContainer, clonedFormatNode);\r\n formatter.remove(name, vars, clonedFormatNode, similar);\r\n dom.remove(clonedFormatNode);\r\n return Optional.some(clonedFormatNode);\r\n } else {\r\n return Optional.none();\r\n }\r\n };\r\n const applyCaretFormat = (editor, name, vars) => {\r\n let caretContainer;\r\n const selection = editor.selection;\r\n const formatList = editor.formatter.get(name);\r\n if (!formatList) {\r\n return;\r\n }\r\n const selectionRng = selection.getRng();\r\n let offset = selectionRng.startOffset;\r\n const container = selectionRng.startContainer;\r\n const text = container.nodeValue;\r\n caretContainer = getParentCaretContainer(editor.getBody(), selection.getStart());\r\n const wordcharRegex = /[^\\s\\u00a0\\u00ad\\u200b\\ufeff]/;\r\n if (text && offset > 0 && offset < text.length && wordcharRegex.test(text.charAt(offset)) && wordcharRegex.test(text.charAt(offset - 1))) {\r\n const bookmark = selection.getBookmark();\r\n selectionRng.collapse(true);\r\n let rng = expandRng(editor.dom, selectionRng, formatList);\r\n rng = split(rng);\r\n editor.formatter.apply(name, vars, rng);\r\n selection.moveToBookmark(bookmark);\r\n } else {\r\n let textNode = caretContainer ? findFirstTextNode(caretContainer) : null;\r\n if (!caretContainer || (textNode === null || textNode === void 0 ? void 0 : textNode.data) !== ZWSP) {\r\n caretContainer = importNode(editor.getDoc(), createCaretContainer(true).dom);\r\n textNode = caretContainer.firstChild;\r\n selectionRng.insertNode(caretContainer);\r\n offset = 1;\r\n editor.formatter.apply(name, vars, caretContainer);\r\n } else {\r\n editor.formatter.apply(name, vars, caretContainer);\r\n }\r\n selection.setCursorLocation(textNode, offset);\r\n }\r\n };\r\n const removeCaretFormat = (editor, name, vars, similar) => {\r\n const dom = editor.dom;\r\n const selection = editor.selection;\r\n let hasContentAfter = false;\r\n const formatList = editor.formatter.get(name);\r\n if (!formatList) {\r\n return;\r\n }\r\n const rng = selection.getRng();\r\n const container = rng.startContainer;\r\n const offset = rng.startOffset;\r\n let node = container;\r\n if (isText$a(container)) {\r\n if (offset !== container.data.length) {\r\n hasContentAfter = true;\r\n }\r\n node = node.parentNode;\r\n }\r\n const parents = [];\r\n let formatNode;\r\n while (node) {\r\n if (matchNode(editor, node, name, vars, similar)) {\r\n formatNode = node;\r\n break;\r\n }\r\n if (node.nextSibling) {\r\n hasContentAfter = true;\r\n }\r\n parents.push(node);\r\n node = node.parentNode;\r\n }\r\n if (!formatNode) {\r\n return;\r\n }\r\n if (hasContentAfter) {\r\n const bookmark = selection.getBookmark();\r\n rng.collapse(true);\r\n let expandedRng = expandRng(dom, rng, formatList, true);\r\n expandedRng = split(expandedRng);\r\n editor.formatter.remove(name, vars, expandedRng, similar);\r\n selection.moveToBookmark(bookmark);\r\n } else {\r\n const caretContainer = getParentCaretContainer(editor.getBody(), formatNode);\r\n const newCaretContainer = createCaretContainer(false).dom;\r\n insertCaretContainerNode(editor, newCaretContainer, caretContainer !== null && caretContainer !== void 0 ? caretContainer : formatNode);\r\n const cleanedFormatNode = cleanFormatNode(editor, newCaretContainer, formatNode, name, vars, similar);\r\n const caretTextNode = insertFormatNodesIntoCaretContainer(parents.concat(cleanedFormatNode.toArray()), newCaretContainer);\r\n if (caretContainer) {\r\n removeCaretContainerNode(editor, caretContainer, false);\r\n }\r\n selection.setCursorLocation(caretTextNode, 1);\r\n if (dom.isEmpty(formatNode)) {\r\n dom.remove(formatNode);\r\n }\r\n }\r\n };\r\n const disableCaretContainer = (editor, keyCode) => {\r\n const selection = editor.selection, body = editor.getBody();\r\n removeCaretContainer(editor, null, false);\r\n if ((keyCode === 8 || keyCode === 46) && selection.isCollapsed() && selection.getStart().innerHTML === ZWSP) {\r\n removeCaretContainer(editor, getParentCaretContainer(body, selection.getStart()));\r\n }\r\n if (keyCode === 37 || keyCode === 39) {\r\n removeCaretContainer(editor, getParentCaretContainer(body, selection.getStart()));\r\n }\r\n };\r\n const setup$u = editor => {\r\n editor.on('mouseup keydown', e => {\r\n disableCaretContainer(editor, e.keyCode);\r\n });\r\n };\r\n const createCaretFormat = formatNodes => {\r\n const caretContainer = createCaretContainer(false);\r\n const innerMost = insertFormatNodesIntoCaretContainer(formatNodes, caretContainer.dom);\r\n return {\r\n caretContainer,\r\n caretPosition: CaretPosition(innerMost, 0)\r\n };\r\n };\r\n const replaceWithCaretFormat = (targetNode, formatNodes) => {\r\n const {caretContainer, caretPosition} = createCaretFormat(formatNodes);\r\n before$3(SugarElement.fromDom(targetNode), caretContainer);\r\n remove$6(SugarElement.fromDom(targetNode));\r\n return caretPosition;\r\n };\r\n const createCaretFormatAtStart$1 = (editor, formatNodes) => {\r\n const {caretContainer, caretPosition} = createCaretFormat(formatNodes);\r\n editor.selection.getRng().insertNode(caretContainer.dom);\r\n return caretPosition;\r\n };\r\n const isFormatElement = (editor, element) => {\r\n const inlineElements = editor.schema.getTextInlineElements();\r\n return has$2(inlineElements, name(element)) && !isCaretNode(element.dom) && !isBogus$2(element.dom);\r\n };\r\n const isEmptyCaretFormatElement = element => {\r\n return isCaretNode(element.dom) && isCaretContainerEmpty(element.dom);\r\n };\r\n\r\n const postProcessHooks = {};\r\n const isPre = matchNodeNames(['pre']);\r\n const addPostProcessHook = (name, hook) => {\r\n const hooks = postProcessHooks[name];\r\n if (!hooks) {\r\n postProcessHooks[name] = [];\r\n }\r\n postProcessHooks[name].push(hook);\r\n };\r\n const postProcess$1 = (name, editor) => {\r\n if (has$2(postProcessHooks, name)) {\r\n each$e(postProcessHooks[name], hook => {\r\n hook(editor);\r\n });\r\n }\r\n };\r\n addPostProcessHook('pre', editor => {\r\n const rng = editor.selection.getRng();\r\n const hasPreSibling = blocks => pre => {\r\n const prev = pre.previousSibling;\r\n return isPre(prev) && contains$2(blocks, prev);\r\n };\r\n const joinPre = (pre1, pre2) => {\r\n const sPre2 = SugarElement.fromDom(pre2);\r\n const doc = documentOrOwner(sPre2).dom;\r\n remove$6(sPre2);\r\n append(SugarElement.fromDom(pre1), [\r\n SugarElement.fromTag('br', doc),\r\n SugarElement.fromTag('br', doc),\r\n ...children$1(sPre2)\r\n ]);\r\n };\r\n if (!rng.collapsed) {\r\n const blocks = editor.selection.getSelectedBlocks();\r\n const preBlocks = filter$5(filter$5(blocks, isPre), hasPreSibling(blocks));\r\n each$e(preBlocks, pre => {\r\n joinPre(pre.previousSibling, pre);\r\n });\r\n }\r\n });\r\n\r\n const listItemStyles = [\r\n 'fontWeight',\r\n 'fontStyle',\r\n 'color',\r\n 'fontSize',\r\n 'fontFamily'\r\n ];\r\n const hasListStyles = fmt => isObject(fmt.styles) && exists(keys(fmt.styles), name => contains$2(listItemStyles, name));\r\n const findExpandedListItemFormat = formats => find$2(formats, fmt => isInlineFormat(fmt) && fmt.inline === 'span' && hasListStyles(fmt));\r\n const getExpandedListItemFormat = (formatter, format) => {\r\n const formatList = formatter.get(format);\r\n return isArray$1(formatList) ? findExpandedListItemFormat(formatList) : Optional.none();\r\n };\r\n const isRngStartAtStartOfElement = (rng, elm) => prevPosition(elm, CaretPosition.fromRangeStart(rng)).isNone();\r\n const isRngEndAtEndOfElement = (rng, elm) => {\r\n return nextPosition(elm, CaretPosition.fromRangeEnd(rng)).exists(pos => !isBr$6(pos.getNode()) || nextPosition(elm, pos).isSome()) === false;\r\n };\r\n const isEditableListItem = dom => elm => isListItem$2(elm) && dom.isEditable(elm);\r\n const getFullySelectedBlocks = selection => {\r\n const blocks = selection.getSelectedBlocks();\r\n const rng = selection.getRng();\r\n if (selection.isCollapsed()) {\r\n return [];\r\n }\r\n if (blocks.length === 1) {\r\n return isRngStartAtStartOfElement(rng, blocks[0]) && isRngEndAtEndOfElement(rng, blocks[0]) ? blocks : [];\r\n } else {\r\n const first = head(blocks).filter(elm => isRngStartAtStartOfElement(rng, elm)).toArray();\r\n const last = last$3(blocks).filter(elm => isRngEndAtEndOfElement(rng, elm)).toArray();\r\n const middle = blocks.slice(1, -1);\r\n return first.concat(middle).concat(last);\r\n }\r\n };\r\n const getFullySelectedListItems = selection => filter$5(getFullySelectedBlocks(selection), isEditableListItem(selection.dom));\r\n const getPartiallySelectedListItems = selection => filter$5(selection.getSelectedBlocks(), isEditableListItem(selection.dom));\r\n\r\n const each$8 = Tools.each;\r\n const isElementNode = node => isElement$6(node) && !isBookmarkNode$1(node) && !isCaretNode(node) && !isBogus$2(node);\r\n const findElementSibling = (node, siblingName) => {\r\n for (let sibling = node; sibling; sibling = sibling[siblingName]) {\r\n if (isText$a(sibling) && isNotEmpty(sibling.data)) {\r\n return node;\r\n }\r\n if (isElement$6(sibling) && !isBookmarkNode$1(sibling)) {\r\n return sibling;\r\n }\r\n }\r\n return node;\r\n };\r\n const mergeSiblingsNodes = (editor, prev, next) => {\r\n const elementUtils = ElementUtils(editor);\r\n const isPrevEditable = isElement$6(prev) && isEditable$2(prev);\r\n const isNextEditable = isElement$6(next) && isEditable$2(next);\r\n if (isPrevEditable && isNextEditable) {\r\n const prevSibling = findElementSibling(prev, 'previousSibling');\r\n const nextSibling = findElementSibling(next, 'nextSibling');\r\n if (elementUtils.compare(prevSibling, nextSibling)) {\r\n for (let sibling = prevSibling.nextSibling; sibling && sibling !== nextSibling;) {\r\n const tmpSibling = sibling;\r\n sibling = sibling.nextSibling;\r\n prevSibling.appendChild(tmpSibling);\r\n }\r\n editor.dom.remove(nextSibling);\r\n Tools.each(Tools.grep(nextSibling.childNodes), node => {\r\n prevSibling.appendChild(node);\r\n });\r\n return prevSibling;\r\n }\r\n }\r\n return next;\r\n };\r\n const mergeSiblings = (editor, format, vars, node) => {\r\n var _a;\r\n if (node && format.merge_siblings !== false) {\r\n const newNode = (_a = mergeSiblingsNodes(editor, getNonWhiteSpaceSibling(node), node)) !== null && _a !== void 0 ? _a : node;\r\n mergeSiblingsNodes(editor, newNode, getNonWhiteSpaceSibling(newNode, true));\r\n }\r\n };\r\n const clearChildStyles = (dom, format, node) => {\r\n if (format.clear_child_styles) {\r\n const selector = format.links ? '*:not(a)' : '*';\r\n each$8(dom.select(selector, node), childNode => {\r\n if (isElementNode(childNode) && isEditable$2(childNode)) {\r\n each$8(format.styles, (_value, name) => {\r\n dom.setStyle(childNode, name, '');\r\n });\r\n }\r\n });\r\n }\r\n };\r\n const processChildElements = (node, filter, process) => {\r\n each$8(node.childNodes, node => {\r\n if (isElementNode(node)) {\r\n if (filter(node)) {\r\n process(node);\r\n }\r\n if (node.hasChildNodes()) {\r\n processChildElements(node, filter, process);\r\n }\r\n }\r\n });\r\n };\r\n const unwrapEmptySpan = (dom, node) => {\r\n if (node.nodeName === 'SPAN' && dom.getAttribs(node).length === 0) {\r\n dom.remove(node, true);\r\n }\r\n };\r\n const hasStyle = (dom, name) => node => !!(node && getStyle(dom, node, name));\r\n const applyStyle = (dom, name, value) => node => {\r\n dom.setStyle(node, name, value);\r\n if (node.getAttribute('style') === '') {\r\n node.removeAttribute('style');\r\n }\r\n unwrapEmptySpan(dom, node);\r\n };\r\n\r\n const removeResult = Adt.generate([\r\n { keep: [] },\r\n { rename: ['name'] },\r\n { removed: [] }\r\n ]);\r\n const MCE_ATTR_RE = /^(src|href|style)$/;\r\n const each$7 = Tools.each;\r\n const isEq$2 = isEq$5;\r\n const isTableCellOrRow = node => /^(TR|TH|TD)$/.test(node.nodeName);\r\n const isChildOfInlineParent = (dom, node, parent) => dom.isChildOf(node, parent) && node !== parent && !dom.isBlock(parent);\r\n const getContainer = (ed, rng, start) => {\r\n let container = rng[start ? 'startContainer' : 'endContainer'];\r\n let offset = rng[start ? 'startOffset' : 'endOffset'];\r\n if (isElement$6(container)) {\r\n const lastIdx = container.childNodes.length - 1;\r\n if (!start && offset) {\r\n offset--;\r\n }\r\n container = container.childNodes[offset > lastIdx ? lastIdx : offset];\r\n }\r\n if (isText$a(container) && start && offset >= container.data.length) {\r\n container = new DomTreeWalker(container, ed.getBody()).next() || container;\r\n }\r\n if (isText$a(container) && !start && offset === 0) {\r\n container = new DomTreeWalker(container, ed.getBody()).prev() || container;\r\n }\r\n return container;\r\n };\r\n const normalizeTableSelection = (node, start) => {\r\n const prop = start ? 'firstChild' : 'lastChild';\r\n const childNode = node[prop];\r\n if (isTableCellOrRow(node) && childNode) {\r\n if (node.nodeName === 'TR') {\r\n return childNode[prop] || childNode;\r\n } else {\r\n return childNode;\r\n }\r\n }\r\n return node;\r\n };\r\n const wrap$1 = (dom, node, name, attrs) => {\r\n var _a;\r\n const wrapper = dom.create(name, attrs);\r\n (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(wrapper, node);\r\n wrapper.appendChild(node);\r\n return wrapper;\r\n };\r\n const wrapWithSiblings = (dom, node, next, name, attrs) => {\r\n const start = SugarElement.fromDom(node);\r\n const wrapper = SugarElement.fromDom(dom.create(name, attrs));\r\n const siblings = next ? nextSiblings(start) : prevSiblings(start);\r\n append(wrapper, siblings);\r\n if (next) {\r\n before$3(start, wrapper);\r\n prepend(wrapper, start);\r\n } else {\r\n after$4(start, wrapper);\r\n append$1(wrapper, start);\r\n }\r\n return wrapper.dom;\r\n };\r\n const isColorFormatAndAnchor = (node, format) => format.links && node.nodeName === 'A';\r\n const removeNode = (ed, node, format) => {\r\n const parentNode = node.parentNode;\r\n let rootBlockElm;\r\n const dom = ed.dom;\r\n const forcedRootBlock = getForcedRootBlock(ed);\r\n if (isBlockFormat(format)) {\r\n if (parentNode === dom.getRoot()) {\r\n if (!format.list_block || !isEq$2(node, format.list_block)) {\r\n each$e(from(node.childNodes), node => {\r\n if (isValid(ed, forcedRootBlock, node.nodeName.toLowerCase())) {\r\n if (!rootBlockElm) {\r\n rootBlockElm = wrap$1(dom, node, forcedRootBlock);\r\n dom.setAttribs(rootBlockElm, getForcedRootBlockAttrs(ed));\r\n } else {\r\n rootBlockElm.appendChild(node);\r\n }\r\n } else {\r\n rootBlockElm = null;\r\n }\r\n });\r\n }\r\n }\r\n }\r\n if (isMixedFormat(format) && !isEq$2(format.inline, node)) {\r\n return;\r\n }\r\n dom.remove(node, true);\r\n };\r\n const processFormatAttrOrStyle = (name, value, vars) => {\r\n if (isNumber(name)) {\r\n return {\r\n name: value,\r\n value: null\r\n };\r\n } else {\r\n return {\r\n name,\r\n value: replaceVars(value, vars)\r\n };\r\n }\r\n };\r\n const removeEmptyStyleAttributeIfNeeded = (dom, elm) => {\r\n if (dom.getAttrib(elm, 'style') === '') {\r\n elm.removeAttribute('style');\r\n elm.removeAttribute('data-mce-style');\r\n }\r\n };\r\n const removeStyles = (dom, elm, format, vars, compareNode) => {\r\n let stylesModified = false;\r\n each$7(format.styles, (value, name) => {\r\n const {\r\n name: styleName,\r\n value: styleValue\r\n } = processFormatAttrOrStyle(name, value, vars);\r\n const normalizedStyleValue = normalizeStyleValue(styleValue, styleName);\r\n if (format.remove_similar || isNull(styleValue) || !isElement$6(compareNode) || isEq$2(getStyle(dom, compareNode, styleName), normalizedStyleValue)) {\r\n dom.setStyle(elm, styleName, '');\r\n }\r\n stylesModified = true;\r\n });\r\n if (stylesModified) {\r\n removeEmptyStyleAttributeIfNeeded(dom, elm);\r\n }\r\n };\r\n const removeListStyleFormats = (editor, name, vars) => {\r\n if (name === 'removeformat') {\r\n each$e(getPartiallySelectedListItems(editor.selection), li => {\r\n each$e(listItemStyles, name => editor.dom.setStyle(li, name, ''));\r\n removeEmptyStyleAttributeIfNeeded(editor.dom, li);\r\n });\r\n } else {\r\n getExpandedListItemFormat(editor.formatter, name).each(liFmt => {\r\n each$e(getPartiallySelectedListItems(editor.selection), li => removeStyles(editor.dom, li, liFmt, vars, null));\r\n });\r\n }\r\n };\r\n const removeFormatInternal = (ed, format, vars, node, compareNode) => {\r\n const dom = ed.dom;\r\n const elementUtils = ElementUtils(ed);\r\n const schema = ed.schema;\r\n if (isInlineFormat(format) && isTransparentElementName(schema, format.inline) && isTransparentBlock(schema, node) && node.parentElement === ed.getBody()) {\r\n removeNode(ed, node, format);\r\n return removeResult.removed();\r\n }\r\n if (!format.ceFalseOverride && node && dom.getContentEditableParent(node) === 'false') {\r\n return removeResult.keep();\r\n }\r\n if (node && !matchName(dom, node, format) && !isColorFormatAndAnchor(node, format)) {\r\n return removeResult.keep();\r\n }\r\n const elm = node;\r\n const preserveAttributes = format.preserve_attributes;\r\n if (isInlineFormat(format) && format.remove === 'all' && isArray$1(preserveAttributes)) {\r\n const attrsToPreserve = filter$5(dom.getAttribs(elm), attr => contains$2(preserveAttributes, attr.name.toLowerCase()));\r\n dom.removeAllAttribs(elm);\r\n each$e(attrsToPreserve, attr => dom.setAttrib(elm, attr.name, attr.value));\r\n if (attrsToPreserve.length > 0) {\r\n return removeResult.rename('span');\r\n }\r\n }\r\n if (format.remove !== 'all') {\r\n removeStyles(dom, elm, format, vars, compareNode);\r\n each$7(format.attributes, (value, name) => {\r\n const {\r\n name: attrName,\r\n value: attrValue\r\n } = processFormatAttrOrStyle(name, value, vars);\r\n if (format.remove_similar || isNull(attrValue) || !isElement$6(compareNode) || isEq$2(dom.getAttrib(compareNode, attrName), attrValue)) {\r\n if (attrName === 'class') {\r\n const currentValue = dom.getAttrib(elm, attrName);\r\n if (currentValue) {\r\n let valueOut = '';\r\n each$e(currentValue.split(/\\s+/), cls => {\r\n if (/mce\\-\\w+/.test(cls)) {\r\n valueOut += (valueOut ? ' ' : '') + cls;\r\n }\r\n });\r\n if (valueOut) {\r\n dom.setAttrib(elm, attrName, valueOut);\r\n return;\r\n }\r\n }\r\n }\r\n if (MCE_ATTR_RE.test(attrName)) {\r\n elm.removeAttribute('data-mce-' + attrName);\r\n }\r\n if (attrName === 'style' && matchNodeNames(['li'])(elm) && dom.getStyle(elm, 'list-style-type') === 'none') {\r\n elm.removeAttribute(attrName);\r\n dom.setStyle(elm, 'list-style-type', 'none');\r\n return;\r\n }\r\n if (attrName === 'class') {\r\n elm.removeAttribute('className');\r\n }\r\n elm.removeAttribute(attrName);\r\n }\r\n });\r\n each$7(format.classes, value => {\r\n value = replaceVars(value, vars);\r\n if (!isElement$6(compareNode) || dom.hasClass(compareNode, value)) {\r\n dom.removeClass(elm, value);\r\n }\r\n });\r\n const attrs = dom.getAttribs(elm);\r\n for (let i = 0; i < attrs.length; i++) {\r\n const attrName = attrs[i].nodeName;\r\n if (!elementUtils.isAttributeInternal(attrName)) {\r\n return removeResult.keep();\r\n }\r\n }\r\n }\r\n if (format.remove !== 'none') {\r\n removeNode(ed, elm, format);\r\n return removeResult.removed();\r\n }\r\n return removeResult.keep();\r\n };\r\n const removeFormat$1 = (ed, format, vars, node, compareNode) => removeFormatInternal(ed, format, vars, node, compareNode).fold(never, newName => {\r\n ed.dom.rename(node, newName);\r\n return true;\r\n }, always);\r\n const findFormatRoot = (editor, container, name, vars, similar) => {\r\n let formatRoot;\r\n if (container.parentNode) {\r\n each$e(getParents$2(editor.dom, container.parentNode).reverse(), parent => {\r\n if (!formatRoot && isElement$6(parent) && parent.id !== '_start' && parent.id !== '_end') {\r\n const format = matchNode(editor, parent, name, vars, similar);\r\n if (format && format.split !== false) {\r\n formatRoot = parent;\r\n }\r\n }\r\n });\r\n }\r\n return formatRoot;\r\n };\r\n const removeFormatFromClone = (editor, format, vars, clone) => removeFormatInternal(editor, format, vars, clone, clone).fold(constant(clone), newName => {\r\n const fragment = editor.dom.createFragment();\r\n fragment.appendChild(clone);\r\n return editor.dom.rename(clone, newName);\r\n }, constant(null));\r\n const wrapAndSplit = (editor, formatList, formatRoot, container, target, split, format, vars) => {\r\n var _a, _b;\r\n let lastClone;\r\n let firstClone;\r\n const dom = editor.dom;\r\n if (formatRoot) {\r\n const formatRootParent = formatRoot.parentNode;\r\n for (let parent = container.parentNode; parent && parent !== formatRootParent; parent = parent.parentNode) {\r\n let clone = dom.clone(parent, false);\r\n for (let i = 0; i < formatList.length; i++) {\r\n clone = removeFormatFromClone(editor, formatList[i], vars, clone);\r\n if (clone === null) {\r\n break;\r\n }\r\n }\r\n if (clone) {\r\n if (lastClone) {\r\n clone.appendChild(lastClone);\r\n }\r\n if (!firstClone) {\r\n firstClone = clone;\r\n }\r\n lastClone = clone;\r\n }\r\n }\r\n if (split && (!format.mixed || !dom.isBlock(formatRoot))) {\r\n container = (_a = dom.split(formatRoot, container)) !== null && _a !== void 0 ? _a : container;\r\n }\r\n if (lastClone && firstClone) {\r\n (_b = target.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(lastClone, target);\r\n firstClone.appendChild(target);\r\n if (isInlineFormat(format)) {\r\n mergeSiblings(editor, format, vars, lastClone);\r\n }\r\n }\r\n }\r\n return container;\r\n };\r\n const remove$2 = (ed, name, vars, node, similar) => {\r\n const formatList = ed.formatter.get(name);\r\n const format = formatList[0];\r\n const dom = ed.dom;\r\n const selection = ed.selection;\r\n const splitToFormatRoot = container => {\r\n const formatRoot = findFormatRoot(ed, container, name, vars, similar);\r\n return wrapAndSplit(ed, formatList, formatRoot, container, container, true, format, vars);\r\n };\r\n const isRemoveBookmarkNode = node => isBookmarkNode$1(node) && isElement$6(node) && (node.id === '_start' || node.id === '_end');\r\n const removeNodeFormat = node => exists(formatList, fmt => removeFormat$1(ed, fmt, vars, node, node));\r\n const process = node => {\r\n const children = from(node.childNodes);\r\n const removed = removeNodeFormat(node);\r\n const currentNodeMatches = removed || exists(formatList, f => matchName(dom, node, f));\r\n const parentNode = node.parentNode;\r\n if (!currentNodeMatches && isNonNullable(parentNode) && shouldExpandToSelector(format)) {\r\n removeNodeFormat(parentNode);\r\n }\r\n if (format.deep) {\r\n if (children.length) {\r\n for (let i = 0; i < children.length; i++) {\r\n process(children[i]);\r\n }\r\n }\r\n }\r\n const textDecorations = [\r\n 'underline',\r\n 'line-through',\r\n 'overline'\r\n ];\r\n each$e(textDecorations, decoration => {\r\n if (isElement$6(node) && ed.dom.getStyle(node, 'text-decoration') === decoration && node.parentNode && getTextDecoration(dom, node.parentNode) === decoration) {\r\n removeFormat$1(ed, {\r\n deep: false,\r\n exact: true,\r\n inline: 'span',\r\n styles: { textDecoration: decoration }\r\n }, undefined, node);\r\n }\r\n });\r\n };\r\n const unwrap = start => {\r\n const node = dom.get(start ? '_start' : '_end');\r\n if (node) {\r\n let out = node[start ? 'firstChild' : 'lastChild'];\r\n if (isRemoveBookmarkNode(out)) {\r\n out = out[start ? 'firstChild' : 'lastChild'];\r\n }\r\n if (isText$a(out) && out.data.length === 0) {\r\n out = start ? node.previousSibling || node.nextSibling : node.nextSibling || node.previousSibling;\r\n }\r\n dom.remove(node, true);\r\n return out;\r\n } else {\r\n return null;\r\n }\r\n };\r\n const removeRngStyle = rng => {\r\n let startContainer;\r\n let endContainer;\r\n let expandedRng = expandRng(dom, rng, formatList, rng.collapsed);\r\n if (format.split) {\r\n expandedRng = split(expandedRng);\r\n startContainer = getContainer(ed, expandedRng, true);\r\n endContainer = getContainer(ed, expandedRng);\r\n if (startContainer !== endContainer) {\r\n startContainer = normalizeTableSelection(startContainer, true);\r\n endContainer = normalizeTableSelection(endContainer, false);\r\n if (isChildOfInlineParent(dom, startContainer, endContainer)) {\r\n const marker = Optional.from(startContainer.firstChild).getOr(startContainer);\r\n splitToFormatRoot(wrapWithSiblings(dom, marker, true, 'span', {\r\n 'id': '_start',\r\n 'data-mce-type': 'bookmark'\r\n }));\r\n unwrap(true);\r\n return;\r\n }\r\n if (isChildOfInlineParent(dom, endContainer, startContainer)) {\r\n const marker = Optional.from(endContainer.lastChild).getOr(endContainer);\r\n splitToFormatRoot(wrapWithSiblings(dom, marker, false, 'span', {\r\n 'id': '_end',\r\n 'data-mce-type': 'bookmark'\r\n }));\r\n unwrap(false);\r\n return;\r\n }\r\n startContainer = wrap$1(dom, startContainer, 'span', {\r\n 'id': '_start',\r\n 'data-mce-type': 'bookmark'\r\n });\r\n endContainer = wrap$1(dom, endContainer, 'span', {\r\n 'id': '_end',\r\n 'data-mce-type': 'bookmark'\r\n });\r\n const newRng = dom.createRng();\r\n newRng.setStartAfter(startContainer);\r\n newRng.setEndBefore(endContainer);\r\n walk$3(dom, newRng, nodes => {\r\n each$e(nodes, n => {\r\n if (!isBookmarkNode$1(n) && !isBookmarkNode$1(n.parentNode)) {\r\n splitToFormatRoot(n);\r\n }\r\n });\r\n });\r\n splitToFormatRoot(startContainer);\r\n splitToFormatRoot(endContainer);\r\n startContainer = unwrap(true);\r\n endContainer = unwrap();\r\n } else {\r\n startContainer = endContainer = splitToFormatRoot(startContainer);\r\n }\r\n expandedRng.startContainer = startContainer.parentNode ? startContainer.parentNode : startContainer;\r\n expandedRng.startOffset = dom.nodeIndex(startContainer);\r\n expandedRng.endContainer = endContainer.parentNode ? endContainer.parentNode : endContainer;\r\n expandedRng.endOffset = dom.nodeIndex(endContainer) + 1;\r\n }\r\n walk$3(dom, expandedRng, nodes => {\r\n each$e(nodes, process);\r\n });\r\n };\r\n if (node) {\r\n if (isNode(node)) {\r\n const rng = dom.createRng();\r\n rng.setStartBefore(node);\r\n rng.setEndAfter(node);\r\n removeRngStyle(rng);\r\n } else {\r\n removeRngStyle(node);\r\n }\r\n fireFormatRemove(ed, name, node, vars);\r\n return;\r\n }\r\n if (!selection.isCollapsed() || !isInlineFormat(format) || getCellsFromEditor(ed).length) {\r\n preserveSelection(ed, () => runOnRanges(ed, removeRngStyle), startNode => isInlineFormat(format) && match$2(ed, name, vars, startNode));\r\n ed.nodeChanged();\r\n } else {\r\n removeCaretFormat(ed, name, vars, similar);\r\n }\r\n removeListStyleFormats(ed, name, vars);\r\n fireFormatRemove(ed, name, node, vars);\r\n };\r\n\r\n const each$6 = Tools.each;\r\n const mergeTextDecorationsAndColor = (dom, format, vars, node) => {\r\n const processTextDecorationsAndColor = n => {\r\n if (isElement$6(n) && isElement$6(n.parentNode) && isEditable$2(n)) {\r\n const parentTextDecoration = getTextDecoration(dom, n.parentNode);\r\n if (dom.getStyle(n, 'color') && parentTextDecoration) {\r\n dom.setStyle(n, 'text-decoration', parentTextDecoration);\r\n } else if (dom.getStyle(n, 'text-decoration') === parentTextDecoration) {\r\n dom.setStyle(n, 'text-decoration', null);\r\n }\r\n }\r\n };\r\n if (format.styles && (format.styles.color || format.styles.textDecoration)) {\r\n Tools.walk(node, processTextDecorationsAndColor, 'childNodes');\r\n processTextDecorationsAndColor(node);\r\n }\r\n };\r\n const mergeBackgroundColorAndFontSize = (dom, format, vars, node) => {\r\n if (format.styles && format.styles.backgroundColor) {\r\n const hasFontSize = hasStyle(dom, 'fontSize');\r\n processChildElements(node, elm => hasFontSize(elm) && isEditable$2(elm), applyStyle(dom, 'backgroundColor', replaceVars(format.styles.backgroundColor, vars)));\r\n }\r\n };\r\n const mergeSubSup = (dom, format, vars, node) => {\r\n if (isInlineFormat(format) && (format.inline === 'sub' || format.inline === 'sup')) {\r\n const hasFontSize = hasStyle(dom, 'fontSize');\r\n processChildElements(node, elm => hasFontSize(elm) && isEditable$2(elm), applyStyle(dom, 'fontSize', ''));\r\n const inverseTagDescendants = filter$5(dom.select(format.inline === 'sup' ? 'sub' : 'sup', node), isEditable$2);\r\n dom.remove(inverseTagDescendants, true);\r\n }\r\n };\r\n const mergeWithChildren = (editor, formatList, vars, node) => {\r\n each$6(formatList, format => {\r\n if (isInlineFormat(format)) {\r\n each$6(editor.dom.select(format.inline, node), child => {\r\n if (isElementNode(child)) {\r\n removeFormat$1(editor, format, vars, child, format.exact ? child : null);\r\n }\r\n });\r\n }\r\n clearChildStyles(editor.dom, format, node);\r\n });\r\n };\r\n const mergeWithParents = (editor, format, name, vars, node) => {\r\n const parentNode = node.parentNode;\r\n if (matchNode(editor, parentNode, name, vars)) {\r\n if (removeFormat$1(editor, format, vars, node)) {\r\n return;\r\n }\r\n }\r\n if (format.merge_with_parents && parentNode) {\r\n editor.dom.getParent(parentNode, parent => {\r\n if (matchNode(editor, parent, name, vars)) {\r\n removeFormat$1(editor, format, vars, node);\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n });\r\n }\r\n };\r\n\r\n const each$5 = Tools.each;\r\n const canFormatBR = (editor, format, node, parentName) => {\r\n if (canFormatEmptyLines(editor) && isInlineFormat(format) && node.parentNode) {\r\n const validBRParentElements = getTextRootBlockElements(editor.schema);\r\n const hasCaretNodeSibling = sibling(SugarElement.fromDom(node), sibling => isCaretNode(sibling.dom));\r\n return hasNonNullableKey(validBRParentElements, parentName) && isEmpty$2(SugarElement.fromDom(node.parentNode), false) && !hasCaretNodeSibling;\r\n } else {\r\n return false;\r\n }\r\n };\r\n const applyStyles = (dom, elm, format, vars) => {\r\n each$5(format.styles, (value, name) => {\r\n dom.setStyle(elm, name, replaceVars(value, vars));\r\n });\r\n if (format.styles) {\r\n const styleVal = dom.getAttrib(elm, 'style');\r\n if (styleVal) {\r\n dom.setAttrib(elm, 'data-mce-style', styleVal);\r\n }\r\n }\r\n };\r\n const applyFormat$1 = (ed, name, vars, node) => {\r\n const formatList = ed.formatter.get(name);\r\n const format = formatList[0];\r\n const isCollapsed = !node && ed.selection.isCollapsed();\r\n const dom = ed.dom;\r\n const selection = ed.selection;\r\n const setElementFormat = (elm, fmt = format) => {\r\n if (isFunction(fmt.onformat)) {\r\n fmt.onformat(elm, fmt, vars, node);\r\n }\r\n applyStyles(dom, elm, fmt, vars);\r\n each$5(fmt.attributes, (value, name) => {\r\n dom.setAttrib(elm, name, replaceVars(value, vars));\r\n });\r\n each$5(fmt.classes, value => {\r\n const newValue = replaceVars(value, vars);\r\n if (!dom.hasClass(elm, newValue)) {\r\n dom.addClass(elm, newValue);\r\n }\r\n });\r\n };\r\n const applyNodeStyle = (formatList, node) => {\r\n let found = false;\r\n each$5(formatList, format => {\r\n if (!isSelectorFormat(format)) {\r\n return false;\r\n }\r\n if (dom.getContentEditable(node) === 'false' && !format.ceFalseOverride) {\r\n return true;\r\n }\r\n if (isNonNullable(format.collapsed) && format.collapsed !== isCollapsed) {\r\n return true;\r\n }\r\n if (dom.is(node, format.selector) && !isCaretNode(node)) {\r\n setElementFormat(node, format);\r\n found = true;\r\n return false;\r\n }\r\n return true;\r\n });\r\n return found;\r\n };\r\n const createWrapElement = wrapName => {\r\n if (isString(wrapName)) {\r\n const wrapElm = dom.create(wrapName);\r\n setElementFormat(wrapElm);\r\n return wrapElm;\r\n } else {\r\n return null;\r\n }\r\n };\r\n const applyRngStyle = (dom, rng, nodeSpecific) => {\r\n const newWrappers = [];\r\n let contentEditable = true;\r\n const wrapName = format.inline || format.block;\r\n const wrapElm = createWrapElement(wrapName);\r\n const isMatchingWrappingBlock = node => isWrappingBlockFormat(format) && matchNode(ed, node, name, vars);\r\n const canRenameBlock = (node, parentName, isEditableDescendant) => {\r\n const isValidBlockFormatForNode = isNonWrappingBlockFormat(format) && isTextBlock$1(ed.schema, node) && isValid(ed, parentName, wrapName);\r\n return isEditableDescendant && isValidBlockFormatForNode;\r\n };\r\n const canWrapNode = (node, parentName, isEditableDescendant, isWrappableNoneditableElm) => {\r\n const nodeName = node.nodeName.toLowerCase();\r\n const isValidWrapNode = isValid(ed, wrapName, nodeName) && isValid(ed, parentName, wrapName);\r\n const isZwsp$1 = !nodeSpecific && isText$a(node) && isZwsp(node.data);\r\n const isCaret = isCaretNode(node);\r\n const isCorrectFormatForNode = !isInlineFormat(format) || !dom.isBlock(node);\r\n return (isEditableDescendant || isWrappableNoneditableElm) && isValidWrapNode && !isZwsp$1 && !isCaret && isCorrectFormatForNode;\r\n };\r\n walk$3(dom, rng, nodes => {\r\n let currentWrapElm;\r\n const process = node => {\r\n let hasContentEditableState = false;\r\n let lastContentEditable = contentEditable;\r\n let isWrappableNoneditableElm = false;\r\n const parentNode = node.parentNode;\r\n const parentName = parentNode.nodeName.toLowerCase();\r\n const contentEditableValue = dom.getContentEditable(node);\r\n if (isNonNullable(contentEditableValue)) {\r\n lastContentEditable = contentEditable;\r\n contentEditable = contentEditableValue === 'true';\r\n hasContentEditableState = true;\r\n isWrappableNoneditableElm = isWrappableNoneditable(ed, node);\r\n }\r\n const isEditableDescendant = contentEditable && !hasContentEditableState;\r\n if (isBr$6(node) && !canFormatBR(ed, format, node, parentName)) {\r\n currentWrapElm = null;\r\n if (isBlockFormat(format)) {\r\n dom.remove(node);\r\n }\r\n return;\r\n }\r\n if (isMatchingWrappingBlock(node)) {\r\n currentWrapElm = null;\r\n return;\r\n }\r\n if (canRenameBlock(node, parentName, isEditableDescendant)) {\r\n const elm = dom.rename(node, wrapName);\r\n setElementFormat(elm);\r\n newWrappers.push(elm);\r\n currentWrapElm = null;\r\n return;\r\n }\r\n if (isSelectorFormat(format)) {\r\n let found = applyNodeStyle(formatList, node);\r\n if (!found && isNonNullable(parentNode) && shouldExpandToSelector(format)) {\r\n found = applyNodeStyle(formatList, parentNode);\r\n }\r\n if (!isInlineFormat(format) || found) {\r\n currentWrapElm = null;\r\n return;\r\n }\r\n }\r\n if (isNonNullable(wrapElm) && canWrapNode(node, parentName, isEditableDescendant, isWrappableNoneditableElm)) {\r\n if (!currentWrapElm) {\r\n currentWrapElm = dom.clone(wrapElm, false);\r\n parentNode.insertBefore(currentWrapElm, node);\r\n newWrappers.push(currentWrapElm);\r\n }\r\n if (isWrappableNoneditableElm && hasContentEditableState) {\r\n contentEditable = lastContentEditable;\r\n }\r\n currentWrapElm.appendChild(node);\r\n } else {\r\n currentWrapElm = null;\r\n each$e(from(node.childNodes), process);\r\n if (hasContentEditableState) {\r\n contentEditable = lastContentEditable;\r\n }\r\n currentWrapElm = null;\r\n }\r\n };\r\n each$e(nodes, process);\r\n });\r\n if (format.links === true) {\r\n each$e(newWrappers, node => {\r\n const process = node => {\r\n if (node.nodeName === 'A') {\r\n setElementFormat(node, format);\r\n }\r\n each$e(from(node.childNodes), process);\r\n };\r\n process(node);\r\n });\r\n }\r\n each$e(newWrappers, node => {\r\n const getChildCount = node => {\r\n let count = 0;\r\n each$e(node.childNodes, node => {\r\n if (!isEmptyTextNode$1(node) && !isBookmarkNode$1(node)) {\r\n count++;\r\n }\r\n });\r\n return count;\r\n };\r\n const mergeStyles = node => {\r\n const childElement = find$2(node.childNodes, isElementNode$1).filter(child => dom.getContentEditable(child) !== 'false' && matchName(dom, child, format));\r\n return childElement.map(child => {\r\n const clone = dom.clone(child, false);\r\n setElementFormat(clone);\r\n dom.replace(clone, node, true);\r\n dom.remove(child, true);\r\n return clone;\r\n }).getOr(node);\r\n };\r\n const childCount = getChildCount(node);\r\n if ((newWrappers.length > 1 || !dom.isBlock(node)) && childCount === 0) {\r\n dom.remove(node, true);\r\n return;\r\n }\r\n if (isInlineFormat(format) || isBlockFormat(format) && format.wrapper) {\r\n if (!format.exact && childCount === 1) {\r\n node = mergeStyles(node);\r\n }\r\n mergeWithChildren(ed, formatList, vars, node);\r\n mergeWithParents(ed, format, name, vars, node);\r\n mergeBackgroundColorAndFontSize(dom, format, vars, node);\r\n mergeTextDecorationsAndColor(dom, format, vars, node);\r\n mergeSubSup(dom, format, vars, node);\r\n mergeSiblings(ed, format, vars, node);\r\n }\r\n });\r\n };\r\n const targetNode = isNode(node) ? node : selection.getNode();\r\n if (dom.getContentEditable(targetNode) === 'false' && !isWrappableNoneditable(ed, targetNode)) {\r\n node = targetNode;\r\n applyNodeStyle(formatList, node);\r\n fireFormatApply(ed, name, node, vars);\r\n return;\r\n }\r\n if (format) {\r\n if (node) {\r\n if (isNode(node)) {\r\n if (!applyNodeStyle(formatList, node)) {\r\n const rng = dom.createRng();\r\n rng.setStartBefore(node);\r\n rng.setEndAfter(node);\r\n applyRngStyle(dom, expandRng(dom, rng, formatList), true);\r\n }\r\n } else {\r\n applyRngStyle(dom, node, true);\r\n }\r\n } else {\r\n if (!isCollapsed || !isInlineFormat(format) || getCellsFromEditor(ed).length) {\r\n selection.setRng(normalize(selection.getRng()));\r\n preserveSelection(ed, () => {\r\n runOnRanges(ed, (selectionRng, fake) => {\r\n const expandedRng = fake ? selectionRng : expandRng(dom, selectionRng, formatList);\r\n applyRngStyle(dom, expandedRng, false);\r\n });\r\n }, always);\r\n ed.nodeChanged();\r\n } else {\r\n applyCaretFormat(ed, name, vars);\r\n }\r\n getExpandedListItemFormat(ed.formatter, name).each(liFmt => {\r\n each$e(getFullySelectedListItems(ed.selection), li => applyStyles(dom, li, liFmt, vars));\r\n });\r\n }\r\n postProcess$1(name, ed);\r\n }\r\n fireFormatApply(ed, name, node, vars);\r\n };\r\n\r\n const hasVars = value => has$2(value, 'vars');\r\n const setup$t = (registeredFormatListeners, editor) => {\r\n registeredFormatListeners.set({});\r\n editor.on('NodeChange', e => {\r\n updateAndFireChangeCallbacks(editor, e.element, registeredFormatListeners.get());\r\n });\r\n editor.on('FormatApply FormatRemove', e => {\r\n const element = Optional.from(e.node).map(nodeOrRange => isNode(nodeOrRange) ? nodeOrRange : nodeOrRange.startContainer).bind(node => isElement$6(node) ? Optional.some(node) : Optional.from(node.parentElement)).getOrThunk(() => fallbackElement(editor));\r\n updateAndFireChangeCallbacks(editor, element, registeredFormatListeners.get());\r\n });\r\n };\r\n const fallbackElement = editor => editor.selection.getStart();\r\n const matchingNode = (editor, parents, format, similar, vars) => {\r\n const isMatchingNode = node => {\r\n const matchingFormat = editor.formatter.matchNode(node, format, vars !== null && vars !== void 0 ? vars : {}, similar);\r\n return !isUndefined(matchingFormat);\r\n };\r\n const isUnableToMatch = node => {\r\n if (matchesUnInheritedFormatSelector(editor, node, format)) {\r\n return true;\r\n } else {\r\n if (!similar) {\r\n return isNonNullable(editor.formatter.matchNode(node, format, vars, true));\r\n } else {\r\n return false;\r\n }\r\n }\r\n };\r\n return findUntil$1(parents, isMatchingNode, isUnableToMatch);\r\n };\r\n const getParents = (editor, elm) => {\r\n const element = elm !== null && elm !== void 0 ? elm : fallbackElement(editor);\r\n return filter$5(getParents$2(editor.dom, element), node => isElement$6(node) && !isBogus$2(node));\r\n };\r\n const updateAndFireChangeCallbacks = (editor, elm, registeredCallbacks) => {\r\n const parents = getParents(editor, elm);\r\n each$d(registeredCallbacks, (data, format) => {\r\n const runIfChanged = spec => {\r\n const match = matchingNode(editor, parents, format, spec.similar, hasVars(spec) ? spec.vars : undefined);\r\n const isSet = match.isSome();\r\n if (spec.state.get() !== isSet) {\r\n spec.state.set(isSet);\r\n const node = match.getOr(elm);\r\n if (hasVars(spec)) {\r\n spec.callback(isSet, {\r\n node,\r\n format,\r\n parents\r\n });\r\n } else {\r\n each$e(spec.callbacks, callback => callback(isSet, {\r\n node,\r\n format,\r\n parents\r\n }));\r\n }\r\n }\r\n };\r\n each$e([\r\n data.withSimilar,\r\n data.withoutSimilar\r\n ], runIfChanged);\r\n each$e(data.withVars, runIfChanged);\r\n });\r\n };\r\n const addListeners = (editor, registeredFormatListeners, formats, callback, similar, vars) => {\r\n const formatChangeItems = registeredFormatListeners.get();\r\n each$e(formats.split(','), format => {\r\n const group = get$a(formatChangeItems, format).getOrThunk(() => {\r\n const base = {\r\n withSimilar: {\r\n state: Cell(false),\r\n similar: true,\r\n callbacks: []\r\n },\r\n withoutSimilar: {\r\n state: Cell(false),\r\n similar: false,\r\n callbacks: []\r\n },\r\n withVars: []\r\n };\r\n formatChangeItems[format] = base;\r\n return base;\r\n });\r\n const getCurrent = () => {\r\n const parents = getParents(editor);\r\n return matchingNode(editor, parents, format, similar, vars).isSome();\r\n };\r\n if (isUndefined(vars)) {\r\n const toAppendTo = similar ? group.withSimilar : group.withoutSimilar;\r\n toAppendTo.callbacks.push(callback);\r\n if (toAppendTo.callbacks.length === 1) {\r\n toAppendTo.state.set(getCurrent());\r\n }\r\n } else {\r\n group.withVars.push({\r\n state: Cell(getCurrent()),\r\n similar,\r\n vars,\r\n callback\r\n });\r\n }\r\n });\r\n registeredFormatListeners.set(formatChangeItems);\r\n };\r\n const removeListeners = (registeredFormatListeners, formats, callback) => {\r\n const formatChangeItems = registeredFormatListeners.get();\r\n each$e(formats.split(','), format => get$a(formatChangeItems, format).each(group => {\r\n formatChangeItems[format] = {\r\n withSimilar: {\r\n ...group.withSimilar,\r\n callbacks: filter$5(group.withSimilar.callbacks, cb => cb !== callback)\r\n },\r\n withoutSimilar: {\r\n ...group.withoutSimilar,\r\n callbacks: filter$5(group.withoutSimilar.callbacks, cb => cb !== callback)\r\n },\r\n withVars: filter$5(group.withVars, item => item.callback !== callback)\r\n };\r\n }));\r\n registeredFormatListeners.set(formatChangeItems);\r\n };\r\n const formatChangedInternal = (editor, registeredFormatListeners, formats, callback, similar, vars) => {\r\n addListeners(editor, registeredFormatListeners, formats, callback, similar, vars);\r\n return { unbind: () => removeListeners(registeredFormatListeners, formats, callback) };\r\n };\r\n\r\n const toggle = (editor, name, vars, node) => {\r\n const fmt = editor.formatter.get(name);\r\n if (fmt) {\r\n if (match$2(editor, name, vars, node) && (!('toggle' in fmt[0]) || fmt[0].toggle)) {\r\n remove$2(editor, name, vars, node);\r\n } else {\r\n applyFormat$1(editor, name, vars, node);\r\n }\r\n }\r\n };\r\n\r\n const explode$1 = Tools.explode;\r\n const create$8 = () => {\r\n const filters = {};\r\n const addFilter = (name, callback) => {\r\n each$e(explode$1(name), name => {\r\n if (!has$2(filters, name)) {\r\n filters[name] = {\r\n name,\r\n callbacks: []\r\n };\r\n }\r\n filters[name].callbacks.push(callback);\r\n });\r\n };\r\n const getFilters = () => values(filters);\r\n const removeFilter = (name, callback) => {\r\n each$e(explode$1(name), name => {\r\n if (has$2(filters, name)) {\r\n if (isNonNullable(callback)) {\r\n const filter = filters[name];\r\n const newCallbacks = filter$5(filter.callbacks, c => c !== callback);\r\n if (newCallbacks.length > 0) {\r\n filter.callbacks = newCallbacks;\r\n } else {\r\n delete filters[name];\r\n }\r\n } else {\r\n delete filters[name];\r\n }\r\n }\r\n });\r\n };\r\n return {\r\n addFilter,\r\n getFilters,\r\n removeFilter\r\n };\r\n };\r\n\r\n const removeAttrs = (node, names) => {\r\n each$e(names, name => {\r\n node.attr(name, null);\r\n });\r\n };\r\n const addFontToSpansFilter = (domParser, styles, fontSizes) => {\r\n domParser.addNodeFilter('font', nodes => {\r\n each$e(nodes, node => {\r\n const props = styles.parse(node.attr('style'));\r\n const color = node.attr('color');\r\n const face = node.attr('face');\r\n const size = node.attr('size');\r\n if (color) {\r\n props.color = color;\r\n }\r\n if (face) {\r\n props['font-family'] = face;\r\n }\r\n if (size) {\r\n toInt(size).each(num => {\r\n props['font-size'] = fontSizes[num - 1];\r\n });\r\n }\r\n node.name = 'span';\r\n node.attr('style', styles.serialize(props));\r\n removeAttrs(node, [\r\n 'color',\r\n 'face',\r\n 'size'\r\n ]);\r\n });\r\n });\r\n };\r\n const addStrikeFilter = (domParser, schema, styles) => {\r\n domParser.addNodeFilter('strike', nodes => {\r\n const convertToSTag = schema.type !== 'html4';\r\n each$e(nodes, node => {\r\n if (convertToSTag) {\r\n node.name = 's';\r\n } else {\r\n const props = styles.parse(node.attr('style'));\r\n props['text-decoration'] = 'line-through';\r\n node.name = 'span';\r\n node.attr('style', styles.serialize(props));\r\n }\r\n });\r\n });\r\n };\r\n const addFilters = (domParser, settings, schema) => {\r\n var _a;\r\n const styles = Styles();\r\n if (settings.convert_fonts_to_spans) {\r\n addFontToSpansFilter(domParser, styles, Tools.explode((_a = settings.font_size_legacy_values) !== null && _a !== void 0 ? _a : ''));\r\n }\r\n addStrikeFilter(domParser, schema, styles);\r\n };\r\n const register$5 = (domParser, settings, schema) => {\r\n if (settings.inline_styles) {\r\n addFilters(domParser, settings, schema);\r\n }\r\n };\r\n\r\n const blobUriToBlob = url => fetch(url).then(res => res.ok ? res.blob() : Promise.reject()).catch(() => Promise.reject(`Cannot convert ${ url } to Blob. Resource might not exist or is inaccessible.`));\r\n const extractBase64Data = data => {\r\n const matches = /([a-z0-9+\\/=\\s]+)/i.exec(data);\r\n return matches ? matches[1] : '';\r\n };\r\n const parseDataUri = uri => {\r\n const [type, ...rest] = uri.split(',');\r\n const data = rest.join(',');\r\n const matches = /data:([^/]+\\/[^;]+)(;.+)?/.exec(type);\r\n if (matches) {\r\n const base64Encoded = matches[2] === ';base64';\r\n const extractedData = base64Encoded ? extractBase64Data(data) : decodeURIComponent(data);\r\n return Optional.some({\r\n type: matches[1],\r\n data: extractedData,\r\n base64Encoded\r\n });\r\n } else {\r\n return Optional.none();\r\n }\r\n };\r\n const buildBlob = (type, data, base64Encoded = true) => {\r\n let str = data;\r\n if (base64Encoded) {\r\n try {\r\n str = atob(data);\r\n } catch (e) {\r\n return Optional.none();\r\n }\r\n }\r\n const arr = new Uint8Array(str.length);\r\n for (let i = 0; i < arr.length; i++) {\r\n arr[i] = str.charCodeAt(i);\r\n }\r\n return Optional.some(new Blob([arr], { type }));\r\n };\r\n const dataUriToBlob = uri => {\r\n return new Promise((resolve, reject) => {\r\n parseDataUri(uri).bind(({type, data, base64Encoded}) => buildBlob(type, data, base64Encoded)).fold(() => reject('Invalid data URI'), resolve);\r\n });\r\n };\r\n const uriToBlob = url => {\r\n if (startsWith(url, 'blob:')) {\r\n return blobUriToBlob(url);\r\n } else if (startsWith(url, 'data:')) {\r\n return dataUriToBlob(url);\r\n } else {\r\n return Promise.reject('Unknown URI format');\r\n }\r\n };\r\n const blobToDataUri = blob => {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n reader.onloadend = () => {\r\n resolve(reader.result);\r\n };\r\n reader.onerror = () => {\r\n var _a;\r\n reject((_a = reader.error) === null || _a === void 0 ? void 0 : _a.message);\r\n };\r\n reader.readAsDataURL(blob);\r\n });\r\n };\r\n\r\n let count$1 = 0;\r\n const uniqueId$1 = prefix => {\r\n return (prefix || 'blobid') + count$1++;\r\n };\r\n const processDataUri = (dataUri, base64Only, generateBlobInfo) => {\r\n return parseDataUri(dataUri).bind(({data, type, base64Encoded}) => {\r\n if (base64Only && !base64Encoded) {\r\n return Optional.none();\r\n } else {\r\n const base64 = base64Encoded ? data : btoa(data);\r\n return generateBlobInfo(base64, type);\r\n }\r\n });\r\n };\r\n const createBlobInfo$1 = (blobCache, blob, base64) => {\r\n const blobInfo = blobCache.create(uniqueId$1(), blob, base64);\r\n blobCache.add(blobInfo);\r\n return blobInfo;\r\n };\r\n const dataUriToBlobInfo = (blobCache, dataUri, base64Only = false) => {\r\n return processDataUri(dataUri, base64Only, (base64, type) => Optional.from(blobCache.getByData(base64, type)).orThunk(() => buildBlob(type, base64).map(blob => createBlobInfo$1(blobCache, blob, base64))));\r\n };\r\n const imageToBlobInfo = (blobCache, imageSrc) => {\r\n const invalidDataUri = () => Promise.reject('Invalid data URI');\r\n if (startsWith(imageSrc, 'blob:')) {\r\n const blobInfo = blobCache.getByUri(imageSrc);\r\n if (isNonNullable(blobInfo)) {\r\n return Promise.resolve(blobInfo);\r\n } else {\r\n return uriToBlob(imageSrc).then(blob => {\r\n return blobToDataUri(blob).then(dataUri => {\r\n return processDataUri(dataUri, false, base64 => {\r\n return Optional.some(createBlobInfo$1(blobCache, blob, base64));\r\n }).getOrThunk(invalidDataUri);\r\n });\r\n });\r\n }\r\n } else if (startsWith(imageSrc, 'data:')) {\r\n return dataUriToBlobInfo(blobCache, imageSrc).fold(invalidDataUri, blobInfo => Promise.resolve(blobInfo));\r\n } else {\r\n return Promise.reject('Unknown image data format');\r\n }\r\n };\r\n\r\n const isBogusImage = img => isNonNullable(img.attr('data-mce-bogus'));\r\n const isInternalImageSource = img => img.attr('src') === Env.transparentSrc || isNonNullable(img.attr('data-mce-placeholder'));\r\n const registerBase64ImageFilter = (parser, settings) => {\r\n const {blob_cache: blobCache} = settings;\r\n if (blobCache) {\r\n const processImage = img => {\r\n const inputSrc = img.attr('src');\r\n if (isInternalImageSource(img) || isBogusImage(img) || isNullable(inputSrc)) {\r\n return;\r\n }\r\n dataUriToBlobInfo(blobCache, inputSrc, true).each(blobInfo => {\r\n img.attr('src', blobInfo.blobUri());\r\n });\r\n };\r\n parser.addAttributeFilter('src', nodes => each$e(nodes, processImage));\r\n }\r\n };\r\n const register$4 = (parser, settings) => {\r\n const schema = parser.schema;\r\n if (settings.remove_trailing_brs) {\r\n parser.addNodeFilter('br', (nodes, _, args) => {\r\n const blockElements = Tools.extend({}, schema.getBlockElements());\r\n const nonEmptyElements = schema.getNonEmptyElements();\r\n const whitespaceElements = schema.getWhitespaceElements();\r\n blockElements.body = 1;\r\n const isBlock = node => node.name in blockElements && isTransparentAstInline(schema, node);\r\n for (let i = 0, l = nodes.length; i < l; i++) {\r\n let node = nodes[i];\r\n let parent = node.parent;\r\n if (parent && blockElements[parent.name] && node === parent.lastChild) {\r\n let prev = node.prev;\r\n while (prev) {\r\n const prevName = prev.name;\r\n if (prevName !== 'span' || prev.attr('data-mce-type') !== 'bookmark') {\r\n if (prevName === 'br') {\r\n node = null;\r\n }\r\n break;\r\n }\r\n prev = prev.prev;\r\n }\r\n if (node) {\r\n node.remove();\r\n if (isEmpty(schema, nonEmptyElements, whitespaceElements, parent)) {\r\n const elementRule = schema.getElementRule(parent.name);\r\n if (elementRule) {\r\n if (elementRule.removeEmpty) {\r\n parent.remove();\r\n } else if (elementRule.paddEmpty) {\r\n paddEmptyNode(args, isBlock, parent);\r\n }\r\n }\r\n }\r\n }\r\n } else {\r\n let lastParent = node;\r\n while (parent && parent.firstChild === lastParent && parent.lastChild === lastParent) {\r\n lastParent = parent;\r\n if (blockElements[parent.name]) {\r\n break;\r\n }\r\n parent = parent.parent;\r\n }\r\n if (lastParent === parent) {\r\n const textNode = new AstNode('#text', 3);\r\n textNode.value = nbsp;\r\n node.replace(textNode);\r\n }\r\n }\r\n }\r\n });\r\n }\r\n parser.addAttributeFilter('href', nodes => {\r\n let i = nodes.length;\r\n const appendRel = rel => {\r\n const parts = rel.split(' ').filter(p => p.length > 0);\r\n return parts.concat(['noopener']).sort().join(' ');\r\n };\r\n const addNoOpener = rel => {\r\n const newRel = rel ? Tools.trim(rel) : '';\r\n if (!/\\b(noopener)\\b/g.test(newRel)) {\r\n return appendRel(newRel);\r\n } else {\r\n return newRel;\r\n }\r\n };\r\n if (!settings.allow_unsafe_link_target) {\r\n while (i--) {\r\n const node = nodes[i];\r\n if (node.name === 'a' && node.attr('target') === '_blank') {\r\n node.attr('rel', addNoOpener(node.attr('rel')));\r\n }\r\n }\r\n }\r\n });\r\n if (!settings.allow_html_in_named_anchor) {\r\n parser.addAttributeFilter('id,name', nodes => {\r\n let i = nodes.length, sibling, prevSibling, parent, node;\r\n while (i--) {\r\n node = nodes[i];\r\n if (node.name === 'a' && node.firstChild && !node.attr('href')) {\r\n parent = node.parent;\r\n sibling = node.lastChild;\r\n while (sibling && parent) {\r\n prevSibling = sibling.prev;\r\n parent.insert(sibling, node);\r\n sibling = prevSibling;\r\n }\r\n }\r\n }\r\n });\r\n }\r\n if (settings.fix_list_elements) {\r\n parser.addNodeFilter('ul,ol', nodes => {\r\n let i = nodes.length, node, parentNode;\r\n while (i--) {\r\n node = nodes[i];\r\n parentNode = node.parent;\r\n if (parentNode && (parentNode.name === 'ul' || parentNode.name === 'ol')) {\r\n if (node.prev && node.prev.name === 'li') {\r\n node.prev.append(node);\r\n } else {\r\n const li = new AstNode('li', 1);\r\n li.attr('style', 'list-style-type: none');\r\n node.wrap(li);\r\n }\r\n }\r\n }\r\n });\r\n }\r\n const validClasses = schema.getValidClasses();\r\n if (settings.validate && validClasses) {\r\n parser.addAttributeFilter('class', nodes => {\r\n var _a;\r\n let i = nodes.length;\r\n while (i--) {\r\n const node = nodes[i];\r\n const clazz = (_a = node.attr('class')) !== null && _a !== void 0 ? _a : '';\r\n const classList = Tools.explode(clazz, ' ');\r\n let classValue = '';\r\n for (let ci = 0; ci < classList.length; ci++) {\r\n const className = classList[ci];\r\n let valid = false;\r\n let validClassesMap = validClasses['*'];\r\n if (validClassesMap && validClassesMap[className]) {\r\n valid = true;\r\n }\r\n validClassesMap = validClasses[node.name];\r\n if (!valid && validClassesMap && validClassesMap[className]) {\r\n valid = true;\r\n }\r\n if (valid) {\r\n if (classValue) {\r\n classValue += ' ';\r\n }\r\n classValue += className;\r\n }\r\n }\r\n if (!classValue.length) {\r\n classValue = null;\r\n }\r\n node.attr('class', classValue);\r\n }\r\n });\r\n }\r\n registerBase64ImageFilter(parser, settings);\r\n };\r\n\r\n function _typeof(obj) {\r\n '@babel/helpers - typeof';\r\n return _typeof = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function (obj) {\r\n return typeof obj;\r\n } : function (obj) {\r\n return obj && 'function' == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;\r\n }, _typeof(obj);\r\n }\r\n function _setPrototypeOf(o, p) {\r\n _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\r\n o.__proto__ = p;\r\n return o;\r\n };\r\n return _setPrototypeOf(o, p);\r\n }\r\n function _isNativeReflectConstruct() {\r\n if (typeof Reflect === 'undefined' || !Reflect.construct)\r\n return false;\r\n if (Reflect.construct.sham)\r\n return false;\r\n if (typeof Proxy === 'function')\r\n return true;\r\n try {\r\n Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {\r\n }));\r\n return true;\r\n } catch (e) {\r\n return false;\r\n }\r\n }\r\n function _construct(Parent, args, Class) {\r\n if (_isNativeReflectConstruct()) {\r\n _construct = Reflect.construct;\r\n } else {\r\n _construct = function _construct(Parent, args, Class) {\r\n var a = [null];\r\n a.push.apply(a, args);\r\n var Constructor = Function.bind.apply(Parent, a);\r\n var instance = new Constructor();\r\n if (Class)\r\n _setPrototypeOf(instance, Class.prototype);\r\n return instance;\r\n };\r\n }\r\n return _construct.apply(null, arguments);\r\n }\r\n function _toConsumableArray(arr) {\r\n return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();\r\n }\r\n function _arrayWithoutHoles(arr) {\r\n if (Array.isArray(arr))\r\n return _arrayLikeToArray(arr);\r\n }\r\n function _iterableToArray(iter) {\r\n if (typeof Symbol !== 'undefined' && iter[Symbol.iterator] != null || iter['@@iterator'] != null)\r\n return Array.from(iter);\r\n }\r\n function _unsupportedIterableToArray(o, minLen) {\r\n if (!o)\r\n return;\r\n if (typeof o === 'string')\r\n return _arrayLikeToArray(o, minLen);\r\n var n = Object.prototype.toString.call(o).slice(8, -1);\r\n if (n === 'Object' && o.constructor)\r\n n = o.constructor.name;\r\n if (n === 'Map' || n === 'Set')\r\n return Array.from(o);\r\n if (n === 'Arguments' || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))\r\n return _arrayLikeToArray(o, minLen);\r\n }\r\n function _arrayLikeToArray(arr, len) {\r\n if (len == null || len > arr.length)\r\n len = arr.length;\r\n for (var i = 0, arr2 = new Array(len); i < len; i++)\r\n arr2[i] = arr[i];\r\n return arr2;\r\n }\r\n function _nonIterableSpread() {\r\n throw new TypeError('Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.');\r\n }\r\n var hasOwnProperty = Object.hasOwnProperty, setPrototypeOf = Object.setPrototypeOf, isFrozen = Object.isFrozen, getPrototypeOf = Object.getPrototypeOf, getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\r\n var freeze = Object.freeze, seal = Object.seal, create$7 = Object.create;\r\n var _ref = typeof Reflect !== 'undefined' && Reflect, apply = _ref.apply, construct = _ref.construct;\r\n if (!apply) {\r\n apply = function apply(fun, thisValue, args) {\r\n return fun.apply(thisValue, args);\r\n };\r\n }\r\n if (!freeze) {\r\n freeze = function freeze(x) {\r\n return x;\r\n };\r\n }\r\n if (!seal) {\r\n seal = function seal(x) {\r\n return x;\r\n };\r\n }\r\n if (!construct) {\r\n construct = function construct(Func, args) {\r\n return _construct(Func, _toConsumableArray(args));\r\n };\r\n }\r\n var arrayForEach = unapply(Array.prototype.forEach);\r\n var arrayPop = unapply(Array.prototype.pop);\r\n var arrayPush = unapply(Array.prototype.push);\r\n var stringToLowerCase = unapply(String.prototype.toLowerCase);\r\n var stringMatch = unapply(String.prototype.match);\r\n var stringReplace = unapply(String.prototype.replace);\r\n var stringIndexOf = unapply(String.prototype.indexOf);\r\n var stringTrim = unapply(String.prototype.trim);\r\n var regExpTest = unapply(RegExp.prototype.test);\r\n var typeErrorCreate = unconstruct(TypeError);\r\n function unapply(func) {\r\n return function (thisArg) {\r\n for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\r\n args[_key - 1] = arguments[_key];\r\n }\r\n return apply(func, thisArg, args);\r\n };\r\n }\r\n function unconstruct(func) {\r\n return function () {\r\n for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\r\n args[_key2] = arguments[_key2];\r\n }\r\n return construct(func, args);\r\n };\r\n }\r\n function addToSet(set, array) {\r\n if (setPrototypeOf) {\r\n setPrototypeOf(set, null);\r\n }\r\n var l = array.length;\r\n while (l--) {\r\n var element = array[l];\r\n if (typeof element === 'string') {\r\n var lcElement = stringToLowerCase(element);\r\n if (lcElement !== element) {\r\n if (!isFrozen(array)) {\r\n array[l] = lcElement;\r\n }\r\n element = lcElement;\r\n }\r\n }\r\n set[element] = true;\r\n }\r\n return set;\r\n }\r\n function clone(object) {\r\n var newObject = create$7(null);\r\n var property;\r\n for (property in object) {\r\n if (apply(hasOwnProperty, object, [property])) {\r\n newObject[property] = object[property];\r\n }\r\n }\r\n return newObject;\r\n }\r\n function lookupGetter(object, prop) {\r\n while (object !== null) {\r\n var desc = getOwnPropertyDescriptor(object, prop);\r\n if (desc) {\r\n if (desc.get) {\r\n return unapply(desc.get);\r\n }\r\n if (typeof desc.value === 'function') {\r\n return unapply(desc.value);\r\n }\r\n }\r\n object = getPrototypeOf(object);\r\n }\r\n function fallbackValue(element) {\r\n console.warn('fallback value for', element);\r\n return null;\r\n }\r\n return fallbackValue;\r\n }\r\n var html$1 = freeze([\r\n 'a',\r\n 'abbr',\r\n 'acronym',\r\n 'address',\r\n 'area',\r\n 'article',\r\n 'aside',\r\n 'audio',\r\n 'b',\r\n 'bdi',\r\n 'bdo',\r\n 'big',\r\n 'blink',\r\n 'blockquote',\r\n 'body',\r\n 'br',\r\n 'button',\r\n 'canvas',\r\n 'caption',\r\n 'center',\r\n 'cite',\r\n 'code',\r\n 'col',\r\n 'colgroup',\r\n 'content',\r\n 'data',\r\n 'datalist',\r\n 'dd',\r\n 'decorator',\r\n 'del',\r\n 'details',\r\n 'dfn',\r\n 'dialog',\r\n 'dir',\r\n 'div',\r\n 'dl',\r\n 'dt',\r\n 'element',\r\n 'em',\r\n 'fieldset',\r\n 'figcaption',\r\n 'figure',\r\n 'font',\r\n 'footer',\r\n 'form',\r\n 'h1',\r\n 'h2',\r\n 'h3',\r\n 'h4',\r\n 'h5',\r\n 'h6',\r\n 'head',\r\n 'header',\r\n 'hgroup',\r\n 'hr',\r\n 'html',\r\n 'i',\r\n 'img',\r\n 'input',\r\n 'ins',\r\n 'kbd',\r\n 'label',\r\n 'legend',\r\n 'li',\r\n 'main',\r\n 'map',\r\n 'mark',\r\n 'marquee',\r\n 'menu',\r\n 'menuitem',\r\n 'meter',\r\n 'nav',\r\n 'nobr',\r\n 'ol',\r\n 'optgroup',\r\n 'option',\r\n 'output',\r\n 'p',\r\n 'picture',\r\n 'pre',\r\n 'progress',\r\n 'q',\r\n 'rp',\r\n 'rt',\r\n 'ruby',\r\n 's',\r\n 'samp',\r\n 'section',\r\n 'select',\r\n 'shadow',\r\n 'small',\r\n 'source',\r\n 'spacer',\r\n 'span',\r\n 'strike',\r\n 'strong',\r\n 'style',\r\n 'sub',\r\n 'summary',\r\n 'sup',\r\n 'table',\r\n 'tbody',\r\n 'td',\r\n 'template',\r\n 'textarea',\r\n 'tfoot',\r\n 'th',\r\n 'thead',\r\n 'time',\r\n 'tr',\r\n 'track',\r\n 'tt',\r\n 'u',\r\n 'ul',\r\n 'var',\r\n 'video',\r\n 'wbr'\r\n ]);\r\n var svg$1 = freeze([\r\n 'svg',\r\n 'a',\r\n 'altglyph',\r\n 'altglyphdef',\r\n 'altglyphitem',\r\n 'animatecolor',\r\n 'animatemotion',\r\n 'animatetransform',\r\n 'circle',\r\n 'clippath',\r\n 'defs',\r\n 'desc',\r\n 'ellipse',\r\n 'filter',\r\n 'font',\r\n 'g',\r\n 'glyph',\r\n 'glyphref',\r\n 'hkern',\r\n 'image',\r\n 'line',\r\n 'lineargradient',\r\n 'marker',\r\n 'mask',\r\n 'metadata',\r\n 'mpath',\r\n 'path',\r\n 'pattern',\r\n 'polygon',\r\n 'polyline',\r\n 'radialgradient',\r\n 'rect',\r\n 'stop',\r\n 'style',\r\n 'switch',\r\n 'symbol',\r\n 'text',\r\n 'textpath',\r\n 'title',\r\n 'tref',\r\n 'tspan',\r\n 'view',\r\n 'vkern'\r\n ]);\r\n var svgFilters = freeze([\r\n 'feBlend',\r\n 'feColorMatrix',\r\n 'feComponentTransfer',\r\n 'feComposite',\r\n 'feConvolveMatrix',\r\n 'feDiffuseLighting',\r\n 'feDisplacementMap',\r\n 'feDistantLight',\r\n 'feFlood',\r\n 'feFuncA',\r\n 'feFuncB',\r\n 'feFuncG',\r\n 'feFuncR',\r\n 'feGaussianBlur',\r\n 'feImage',\r\n 'feMerge',\r\n 'feMergeNode',\r\n 'feMorphology',\r\n 'feOffset',\r\n 'fePointLight',\r\n 'feSpecularLighting',\r\n 'feSpotLight',\r\n 'feTile',\r\n 'feTurbulence'\r\n ]);\r\n var svgDisallowed = freeze([\r\n 'animate',\r\n 'color-profile',\r\n 'cursor',\r\n 'discard',\r\n 'fedropshadow',\r\n 'font-face',\r\n 'font-face-format',\r\n 'font-face-name',\r\n 'font-face-src',\r\n 'font-face-uri',\r\n 'foreignobject',\r\n 'hatch',\r\n 'hatchpath',\r\n 'mesh',\r\n 'meshgradient',\r\n 'meshpatch',\r\n 'meshrow',\r\n 'missing-glyph',\r\n 'script',\r\n 'set',\r\n 'solidcolor',\r\n 'unknown',\r\n 'use'\r\n ]);\r\n var mathMl$1 = freeze([\r\n 'math',\r\n 'menclose',\r\n 'merror',\r\n 'mfenced',\r\n 'mfrac',\r\n 'mglyph',\r\n 'mi',\r\n 'mlabeledtr',\r\n 'mmultiscripts',\r\n 'mn',\r\n 'mo',\r\n 'mover',\r\n 'mpadded',\r\n 'mphantom',\r\n 'mroot',\r\n 'mrow',\r\n 'ms',\r\n 'mspace',\r\n 'msqrt',\r\n 'mstyle',\r\n 'msub',\r\n 'msup',\r\n 'msubsup',\r\n 'mtable',\r\n 'mtd',\r\n 'mtext',\r\n 'mtr',\r\n 'munder',\r\n 'munderover'\r\n ]);\r\n var mathMlDisallowed = freeze([\r\n 'maction',\r\n 'maligngroup',\r\n 'malignmark',\r\n 'mlongdiv',\r\n 'mscarries',\r\n 'mscarry',\r\n 'msgroup',\r\n 'mstack',\r\n 'msline',\r\n 'msrow',\r\n 'semantics',\r\n 'annotation',\r\n 'annotation-xml',\r\n 'mprescripts',\r\n 'none'\r\n ]);\r\n var text = freeze(['#text']);\r\n var html = freeze([\r\n 'accept',\r\n 'action',\r\n 'align',\r\n 'alt',\r\n 'autocapitalize',\r\n 'autocomplete',\r\n 'autopictureinpicture',\r\n 'autoplay',\r\n 'background',\r\n 'bgcolor',\r\n 'border',\r\n 'capture',\r\n 'cellpadding',\r\n 'cellspacing',\r\n 'checked',\r\n 'cite',\r\n 'class',\r\n 'clear',\r\n 'color',\r\n 'cols',\r\n 'colspan',\r\n 'controls',\r\n 'controlslist',\r\n 'coords',\r\n 'crossorigin',\r\n 'datetime',\r\n 'decoding',\r\n 'default',\r\n 'dir',\r\n 'disabled',\r\n 'disablepictureinpicture',\r\n 'disableremoteplayback',\r\n 'download',\r\n 'draggable',\r\n 'enctype',\r\n 'enterkeyhint',\r\n 'face',\r\n 'for',\r\n 'headers',\r\n 'height',\r\n 'hidden',\r\n 'high',\r\n 'href',\r\n 'hreflang',\r\n 'id',\r\n 'inputmode',\r\n 'integrity',\r\n 'ismap',\r\n 'kind',\r\n 'label',\r\n 'lang',\r\n 'list',\r\n 'loading',\r\n 'loop',\r\n 'low',\r\n 'max',\r\n 'maxlength',\r\n 'media',\r\n 'method',\r\n 'min',\r\n 'minlength',\r\n 'multiple',\r\n 'muted',\r\n 'name',\r\n 'nonce',\r\n 'noshade',\r\n 'novalidate',\r\n 'nowrap',\r\n 'open',\r\n 'optimum',\r\n 'pattern',\r\n 'placeholder',\r\n 'playsinline',\r\n 'poster',\r\n 'preload',\r\n 'pubdate',\r\n 'radiogroup',\r\n 'readonly',\r\n 'rel',\r\n 'required',\r\n 'rev',\r\n 'reversed',\r\n 'role',\r\n 'rows',\r\n 'rowspan',\r\n 'spellcheck',\r\n 'scope',\r\n 'selected',\r\n 'shape',\r\n 'size',\r\n 'sizes',\r\n 'span',\r\n 'srclang',\r\n 'start',\r\n 'src',\r\n 'srcset',\r\n 'step',\r\n 'style',\r\n 'summary',\r\n 'tabindex',\r\n 'title',\r\n 'translate',\r\n 'type',\r\n 'usemap',\r\n 'valign',\r\n 'value',\r\n 'width',\r\n 'xmlns',\r\n 'slot'\r\n ]);\r\n var svg = freeze([\r\n 'accent-height',\r\n 'accumulate',\r\n 'additive',\r\n 'alignment-baseline',\r\n 'ascent',\r\n 'attributename',\r\n 'attributetype',\r\n 'azimuth',\r\n 'basefrequency',\r\n 'baseline-shift',\r\n 'begin',\r\n 'bias',\r\n 'by',\r\n 'class',\r\n 'clip',\r\n 'clippathunits',\r\n 'clip-path',\r\n 'clip-rule',\r\n 'color',\r\n 'color-interpolation',\r\n 'color-interpolation-filters',\r\n 'color-profile',\r\n 'color-rendering',\r\n 'cx',\r\n 'cy',\r\n 'd',\r\n 'dx',\r\n 'dy',\r\n 'diffuseconstant',\r\n 'direction',\r\n 'display',\r\n 'divisor',\r\n 'dur',\r\n 'edgemode',\r\n 'elevation',\r\n 'end',\r\n 'fill',\r\n 'fill-opacity',\r\n 'fill-rule',\r\n 'filter',\r\n 'filterunits',\r\n 'flood-color',\r\n 'flood-opacity',\r\n 'font-family',\r\n 'font-size',\r\n 'font-size-adjust',\r\n 'font-stretch',\r\n 'font-style',\r\n 'font-variant',\r\n 'font-weight',\r\n 'fx',\r\n 'fy',\r\n 'g1',\r\n 'g2',\r\n 'glyph-name',\r\n 'glyphref',\r\n 'gradientunits',\r\n 'gradienttransform',\r\n 'height',\r\n 'href',\r\n 'id',\r\n 'image-rendering',\r\n 'in',\r\n 'in2',\r\n 'k',\r\n 'k1',\r\n 'k2',\r\n 'k3',\r\n 'k4',\r\n 'kerning',\r\n 'keypoints',\r\n 'keysplines',\r\n 'keytimes',\r\n 'lang',\r\n 'lengthadjust',\r\n 'letter-spacing',\r\n 'kernelmatrix',\r\n 'kernelunitlength',\r\n 'lighting-color',\r\n 'local',\r\n 'marker-end',\r\n 'marker-mid',\r\n 'marker-start',\r\n 'markerheight',\r\n 'markerunits',\r\n 'markerwidth',\r\n 'maskcontentunits',\r\n 'maskunits',\r\n 'max',\r\n 'mask',\r\n 'media',\r\n 'method',\r\n 'mode',\r\n 'min',\r\n 'name',\r\n 'numoctaves',\r\n 'offset',\r\n 'operator',\r\n 'opacity',\r\n 'order',\r\n 'orient',\r\n 'orientation',\r\n 'origin',\r\n 'overflow',\r\n 'paint-order',\r\n 'path',\r\n 'pathlength',\r\n 'patterncontentunits',\r\n 'patterntransform',\r\n 'patternunits',\r\n 'points',\r\n 'preservealpha',\r\n 'preserveaspectratio',\r\n 'primitiveunits',\r\n 'r',\r\n 'rx',\r\n 'ry',\r\n 'radius',\r\n 'refx',\r\n 'refy',\r\n 'repeatcount',\r\n 'repeatdur',\r\n 'restart',\r\n 'result',\r\n 'rotate',\r\n 'scale',\r\n 'seed',\r\n 'shape-rendering',\r\n 'specularconstant',\r\n 'specularexponent',\r\n 'spreadmethod',\r\n 'startoffset',\r\n 'stddeviation',\r\n 'stitchtiles',\r\n 'stop-color',\r\n 'stop-opacity',\r\n 'stroke-dasharray',\r\n 'stroke-dashoffset',\r\n 'stroke-linecap',\r\n 'stroke-linejoin',\r\n 'stroke-miterlimit',\r\n 'stroke-opacity',\r\n 'stroke',\r\n 'stroke-width',\r\n 'style',\r\n 'surfacescale',\r\n 'systemlanguage',\r\n 'tabindex',\r\n 'targetx',\r\n 'targety',\r\n 'transform',\r\n 'transform-origin',\r\n 'text-anchor',\r\n 'text-decoration',\r\n 'text-rendering',\r\n 'textlength',\r\n 'type',\r\n 'u1',\r\n 'u2',\r\n 'unicode',\r\n 'values',\r\n 'viewbox',\r\n 'visibility',\r\n 'version',\r\n 'vert-adv-y',\r\n 'vert-origin-x',\r\n 'vert-origin-y',\r\n 'width',\r\n 'word-spacing',\r\n 'wrap',\r\n 'writing-mode',\r\n 'xchannelselector',\r\n 'ychannelselector',\r\n 'x',\r\n 'x1',\r\n 'x2',\r\n 'xmlns',\r\n 'y',\r\n 'y1',\r\n 'y2',\r\n 'z',\r\n 'zoomandpan'\r\n ]);\r\n var mathMl = freeze([\r\n 'accent',\r\n 'accentunder',\r\n 'align',\r\n 'bevelled',\r\n 'close',\r\n 'columnsalign',\r\n 'columnlines',\r\n 'columnspan',\r\n 'denomalign',\r\n 'depth',\r\n 'dir',\r\n 'display',\r\n 'displaystyle',\r\n 'encoding',\r\n 'fence',\r\n 'frame',\r\n 'height',\r\n 'href',\r\n 'id',\r\n 'largeop',\r\n 'length',\r\n 'linethickness',\r\n 'lspace',\r\n 'lquote',\r\n 'mathbackground',\r\n 'mathcolor',\r\n 'mathsize',\r\n 'mathvariant',\r\n 'maxsize',\r\n 'minsize',\r\n 'movablelimits',\r\n 'notation',\r\n 'numalign',\r\n 'open',\r\n 'rowalign',\r\n 'rowlines',\r\n 'rowspacing',\r\n 'rowspan',\r\n 'rspace',\r\n 'rquote',\r\n 'scriptlevel',\r\n 'scriptminsize',\r\n 'scriptsizemultiplier',\r\n 'selection',\r\n 'separator',\r\n 'separators',\r\n 'stretchy',\r\n 'subscriptshift',\r\n 'supscriptshift',\r\n 'symmetric',\r\n 'voffset',\r\n 'width',\r\n 'xmlns'\r\n ]);\r\n var xml = freeze([\r\n 'xlink:href',\r\n 'xml:id',\r\n 'xlink:title',\r\n 'xml:space',\r\n 'xmlns:xlink'\r\n ]);\r\n var MUSTACHE_EXPR = seal(/\\{\\{[\\w\\W]*|[\\w\\W]*\\}\\}/gm);\r\n var ERB_EXPR = seal(/<%[\\w\\W]*|[\\w\\W]*%>/gm);\r\n var DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]/);\r\n var ARIA_ATTR = seal(/^aria-[\\-\\w]+$/);\r\n var IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i);\r\n var IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\r\n var ATTR_WHITESPACE = seal(/[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g);\r\n var DOCTYPE_NAME = seal(/^html$/i);\r\n var getGlobal = function getGlobal() {\r\n return typeof window === 'undefined' ? null : window;\r\n };\r\n var _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, document) {\r\n if (_typeof(trustedTypes) !== 'object' || typeof trustedTypes.createPolicy !== 'function') {\r\n return null;\r\n }\r\n var suffix = null;\r\n var ATTR_NAME = 'data-tt-policy-suffix';\r\n if (document.currentScript && document.currentScript.hasAttribute(ATTR_NAME)) {\r\n suffix = document.currentScript.getAttribute(ATTR_NAME);\r\n }\r\n var policyName = 'dompurify' + (suffix ? '#' + suffix : '');\r\n try {\r\n return trustedTypes.createPolicy(policyName, {\r\n createHTML: function createHTML(html) {\r\n return html;\r\n }\r\n });\r\n } catch (_) {\r\n console.warn('TrustedTypes policy ' + policyName + ' could not be created.');\r\n return null;\r\n }\r\n };\r\n function createDOMPurify() {\r\n var window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();\r\n var DOMPurify = function DOMPurify(root) {\r\n return createDOMPurify(root);\r\n };\r\n DOMPurify.version = '2.3.8';\r\n DOMPurify.removed = [];\r\n if (!window || !window.document || window.document.nodeType !== 9) {\r\n DOMPurify.isSupported = false;\r\n return DOMPurify;\r\n }\r\n var originalDocument = window.document;\r\n var document = window.document;\r\n var DocumentFragment = window.DocumentFragment, HTMLTemplateElement = window.HTMLTemplateElement, Node = window.Node, Element = window.Element, NodeFilter = window.NodeFilter, _window$NamedNodeMap = window.NamedNodeMap, NamedNodeMap = _window$NamedNodeMap === void 0 ? window.NamedNodeMap || window.MozNamedAttrMap : _window$NamedNodeMap, HTMLFormElement = window.HTMLFormElement, DOMParser = window.DOMParser, trustedTypes = window.trustedTypes;\r\n var ElementPrototype = Element.prototype;\r\n var cloneNode = lookupGetter(ElementPrototype, 'cloneNode');\r\n var getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');\r\n var getChildNodes = lookupGetter(ElementPrototype, 'childNodes');\r\n var getParentNode = lookupGetter(ElementPrototype, 'parentNode');\r\n if (typeof HTMLTemplateElement === 'function') {\r\n var template = document.createElement('template');\r\n if (template.content && template.content.ownerDocument) {\r\n document = template.content.ownerDocument;\r\n }\r\n }\r\n var trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, originalDocument);\r\n var emptyHTML = trustedTypesPolicy ? trustedTypesPolicy.createHTML('') : '';\r\n var _document = document, implementation = _document.implementation, createNodeIterator = _document.createNodeIterator, createDocumentFragment = _document.createDocumentFragment, getElementsByTagName = _document.getElementsByTagName;\r\n var importNode = originalDocument.importNode;\r\n var documentMode = {};\r\n try {\r\n documentMode = clone(document).documentMode ? document.documentMode : {};\r\n } catch (_) {\r\n }\r\n var hooks = {};\r\n DOMPurify.isSupported = typeof getParentNode === 'function' && implementation && typeof implementation.createHTMLDocument !== 'undefined' && documentMode !== 9;\r\n var MUSTACHE_EXPR$1 = MUSTACHE_EXPR, ERB_EXPR$1 = ERB_EXPR, DATA_ATTR$1 = DATA_ATTR, ARIA_ATTR$1 = ARIA_ATTR, IS_SCRIPT_OR_DATA$1 = IS_SCRIPT_OR_DATA, ATTR_WHITESPACE$1 = ATTR_WHITESPACE;\r\n var IS_ALLOWED_URI$1 = IS_ALLOWED_URI;\r\n var ALLOWED_TAGS = null;\r\n var DEFAULT_ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray(html$1), _toConsumableArray(svg$1), _toConsumableArray(svgFilters), _toConsumableArray(mathMl$1), _toConsumableArray(text)));\r\n var ALLOWED_ATTR = null;\r\n var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray(html), _toConsumableArray(svg), _toConsumableArray(mathMl), _toConsumableArray(xml)));\r\n var CUSTOM_ELEMENT_HANDLING = Object.seal(Object.create(null, {\r\n tagNameCheck: {\r\n writable: true,\r\n configurable: false,\r\n enumerable: true,\r\n value: null\r\n },\r\n attributeNameCheck: {\r\n writable: true,\r\n configurable: false,\r\n enumerable: true,\r\n value: null\r\n },\r\n allowCustomizedBuiltInElements: {\r\n writable: true,\r\n configurable: false,\r\n enumerable: true,\r\n value: false\r\n }\r\n }));\r\n var FORBID_TAGS = null;\r\n var FORBID_ATTR = null;\r\n var ALLOW_ARIA_ATTR = true;\r\n var ALLOW_DATA_ATTR = true;\r\n var ALLOW_UNKNOWN_PROTOCOLS = false;\r\n var SAFE_FOR_TEMPLATES = false;\r\n var WHOLE_DOCUMENT = false;\r\n var SET_CONFIG = false;\r\n var FORCE_BODY = false;\r\n var RETURN_DOM = false;\r\n var RETURN_DOM_FRAGMENT = false;\r\n var RETURN_TRUSTED_TYPE = false;\r\n var SANITIZE_DOM = true;\r\n var KEEP_CONTENT = true;\r\n var IN_PLACE = false;\r\n var USE_PROFILES = {};\r\n var FORBID_CONTENTS = null;\r\n var DEFAULT_FORBID_CONTENTS = addToSet({}, [\r\n 'annotation-xml',\r\n 'audio',\r\n 'colgroup',\r\n 'desc',\r\n 'foreignobject',\r\n 'head',\r\n 'iframe',\r\n 'math',\r\n 'mi',\r\n 'mn',\r\n 'mo',\r\n 'ms',\r\n 'mtext',\r\n 'noembed',\r\n 'noframes',\r\n 'noscript',\r\n 'plaintext',\r\n 'script',\r\n 'style',\r\n 'svg',\r\n 'template',\r\n 'thead',\r\n 'title',\r\n 'video',\r\n 'xmp'\r\n ]);\r\n var DATA_URI_TAGS = null;\r\n var DEFAULT_DATA_URI_TAGS = addToSet({}, [\r\n 'audio',\r\n 'video',\r\n 'img',\r\n 'source',\r\n 'image',\r\n 'track'\r\n ]);\r\n var URI_SAFE_ATTRIBUTES = null;\r\n var DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, [\r\n 'alt',\r\n 'class',\r\n 'for',\r\n 'id',\r\n 'label',\r\n 'name',\r\n 'pattern',\r\n 'placeholder',\r\n 'role',\r\n 'summary',\r\n 'title',\r\n 'value',\r\n 'style',\r\n 'xmlns'\r\n ]);\r\n var MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\r\n var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\r\n var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\r\n var NAMESPACE = HTML_NAMESPACE;\r\n var IS_EMPTY_INPUT = false;\r\n var PARSER_MEDIA_TYPE;\r\n var SUPPORTED_PARSER_MEDIA_TYPES = [\r\n 'application/xhtml+xml',\r\n 'text/html'\r\n ];\r\n var DEFAULT_PARSER_MEDIA_TYPE = 'text/html';\r\n var transformCaseFunc;\r\n var CONFIG = null;\r\n var formElement = document.createElement('form');\r\n var isRegexOrFunction = function isRegexOrFunction(testValue) {\r\n return testValue instanceof RegExp || testValue instanceof Function;\r\n };\r\n var _parseConfig = function _parseConfig(cfg) {\r\n if (CONFIG && CONFIG === cfg) {\r\n return;\r\n }\r\n if (!cfg || _typeof(cfg) !== 'object') {\r\n cfg = {};\r\n }\r\n cfg = clone(cfg);\r\n ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS) : DEFAULT_ALLOWED_TAGS;\r\n ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR) : DEFAULT_ALLOWED_ATTR;\r\n URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR) : DEFAULT_URI_SAFE_ATTRIBUTES;\r\n DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS) : DEFAULT_DATA_URI_TAGS;\r\n FORBID_CONTENTS = 'FORBID_CONTENTS' in cfg ? addToSet({}, cfg.FORBID_CONTENTS) : DEFAULT_FORBID_CONTENTS;\r\n FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS) : {};\r\n FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR) : {};\r\n USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;\r\n ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false;\r\n ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false;\r\n ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false;\r\n SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false;\r\n WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false;\r\n RETURN_DOM = cfg.RETURN_DOM || false;\r\n RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false;\r\n RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false;\r\n FORCE_BODY = cfg.FORCE_BODY || false;\r\n SANITIZE_DOM = cfg.SANITIZE_DOM !== false;\r\n KEEP_CONTENT = cfg.KEEP_CONTENT !== false;\r\n IN_PLACE = cfg.IN_PLACE || false;\r\n IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$1;\r\n NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;\r\n if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {\r\n CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;\r\n }\r\n if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) {\r\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;\r\n }\r\n if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') {\r\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;\r\n }\r\n PARSER_MEDIA_TYPE = SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE : PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE;\r\n transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? function (x) {\r\n return x;\r\n } : stringToLowerCase;\r\n if (SAFE_FOR_TEMPLATES) {\r\n ALLOW_DATA_ATTR = false;\r\n }\r\n if (RETURN_DOM_FRAGMENT) {\r\n RETURN_DOM = true;\r\n }\r\n if (USE_PROFILES) {\r\n ALLOWED_TAGS = addToSet({}, _toConsumableArray(text));\r\n ALLOWED_ATTR = [];\r\n if (USE_PROFILES.html === true) {\r\n addToSet(ALLOWED_TAGS, html$1);\r\n addToSet(ALLOWED_ATTR, html);\r\n }\r\n if (USE_PROFILES.svg === true) {\r\n addToSet(ALLOWED_TAGS, svg$1);\r\n addToSet(ALLOWED_ATTR, svg);\r\n addToSet(ALLOWED_ATTR, xml);\r\n }\r\n if (USE_PROFILES.svgFilters === true) {\r\n addToSet(ALLOWED_TAGS, svgFilters);\r\n addToSet(ALLOWED_ATTR, svg);\r\n addToSet(ALLOWED_ATTR, xml);\r\n }\r\n if (USE_PROFILES.mathMl === true) {\r\n addToSet(ALLOWED_TAGS, mathMl$1);\r\n addToSet(ALLOWED_ATTR, mathMl);\r\n addToSet(ALLOWED_ATTR, xml);\r\n }\r\n }\r\n if (cfg.ADD_TAGS) {\r\n if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {\r\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\r\n }\r\n addToSet(ALLOWED_TAGS, cfg.ADD_TAGS);\r\n }\r\n if (cfg.ADD_ATTR) {\r\n if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {\r\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\r\n }\r\n addToSet(ALLOWED_ATTR, cfg.ADD_ATTR);\r\n }\r\n if (cfg.ADD_URI_SAFE_ATTR) {\r\n addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR);\r\n }\r\n if (cfg.FORBID_CONTENTS) {\r\n if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\r\n FORBID_CONTENTS = clone(FORBID_CONTENTS);\r\n }\r\n addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS);\r\n }\r\n if (KEEP_CONTENT) {\r\n ALLOWED_TAGS['#text'] = true;\r\n }\r\n if (WHOLE_DOCUMENT) {\r\n addToSet(ALLOWED_TAGS, [\r\n 'html',\r\n 'head',\r\n 'body'\r\n ]);\r\n }\r\n if (ALLOWED_TAGS.table) {\r\n addToSet(ALLOWED_TAGS, ['tbody']);\r\n delete FORBID_TAGS.tbody;\r\n }\r\n if (freeze) {\r\n freeze(cfg);\r\n }\r\n CONFIG = cfg;\r\n };\r\n var MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, [\r\n 'mi',\r\n 'mo',\r\n 'mn',\r\n 'ms',\r\n 'mtext'\r\n ]);\r\n var HTML_INTEGRATION_POINTS = addToSet({}, [\r\n 'foreignobject',\r\n 'desc',\r\n 'title',\r\n 'annotation-xml'\r\n ]);\r\n var COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, [\r\n 'title',\r\n 'style',\r\n 'font',\r\n 'a',\r\n 'script'\r\n ]);\r\n var ALL_SVG_TAGS = addToSet({}, svg$1);\r\n addToSet(ALL_SVG_TAGS, svgFilters);\r\n addToSet(ALL_SVG_TAGS, svgDisallowed);\r\n var ALL_MATHML_TAGS = addToSet({}, mathMl$1);\r\n addToSet(ALL_MATHML_TAGS, mathMlDisallowed);\r\n var _checkValidNamespace = function _checkValidNamespace(element) {\r\n var parent = getParentNode(element);\r\n if (!parent || !parent.tagName) {\r\n parent = {\r\n namespaceURI: HTML_NAMESPACE,\r\n tagName: 'template'\r\n };\r\n }\r\n var tagName = stringToLowerCase(element.tagName);\r\n var parentTagName = stringToLowerCase(parent.tagName);\r\n if (element.namespaceURI === SVG_NAMESPACE) {\r\n if (parent.namespaceURI === HTML_NAMESPACE) {\r\n return tagName === 'svg';\r\n }\r\n if (parent.namespaceURI === MATHML_NAMESPACE) {\r\n return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);\r\n }\r\n return Boolean(ALL_SVG_TAGS[tagName]);\r\n }\r\n if (element.namespaceURI === MATHML_NAMESPACE) {\r\n if (parent.namespaceURI === HTML_NAMESPACE) {\r\n return tagName === 'math';\r\n }\r\n if (parent.namespaceURI === SVG_NAMESPACE) {\r\n return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];\r\n }\r\n return Boolean(ALL_MATHML_TAGS[tagName]);\r\n }\r\n if (element.namespaceURI === HTML_NAMESPACE) {\r\n if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {\r\n return false;\r\n }\r\n if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {\r\n return false;\r\n }\r\n return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);\r\n }\r\n return false;\r\n };\r\n var _forceRemove = function _forceRemove(node) {\r\n arrayPush(DOMPurify.removed, { element: node });\r\n try {\r\n node.parentNode.removeChild(node);\r\n } catch (_) {\r\n try {\r\n node.outerHTML = emptyHTML;\r\n } catch (_) {\r\n node.remove();\r\n }\r\n }\r\n };\r\n var _removeAttribute = function _removeAttribute(name, node) {\r\n try {\r\n arrayPush(DOMPurify.removed, {\r\n attribute: node.getAttributeNode(name),\r\n from: node\r\n });\r\n } catch (_) {\r\n arrayPush(DOMPurify.removed, {\r\n attribute: null,\r\n from: node\r\n });\r\n }\r\n node.removeAttribute(name);\r\n if (name === 'is' && !ALLOWED_ATTR[name]) {\r\n if (RETURN_DOM || RETURN_DOM_FRAGMENT) {\r\n try {\r\n _forceRemove(node);\r\n } catch (_) {\r\n }\r\n } else {\r\n try {\r\n node.setAttribute(name, '');\r\n } catch (_) {\r\n }\r\n }\r\n }\r\n };\r\n var _initDocument = function _initDocument(dirty) {\r\n var doc;\r\n var leadingWhitespace;\r\n if (FORCE_BODY) {\r\n dirty = '' + dirty;\r\n } else {\r\n var matches = stringMatch(dirty, /^[\\r\\n\\t ]+/);\r\n leadingWhitespace = matches && matches[0];\r\n }\r\n if (PARSER_MEDIA_TYPE === 'application/xhtml+xml') {\r\n dirty = '' + dirty + '';\r\n }\r\n var dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;\r\n if (NAMESPACE === HTML_NAMESPACE) {\r\n try {\r\n doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);\r\n } catch (_) {\r\n }\r\n }\r\n if (!doc || !doc.documentElement) {\r\n doc = implementation.createDocument(NAMESPACE, 'template', null);\r\n try {\r\n doc.documentElement.innerHTML = IS_EMPTY_INPUT ? '' : dirtyPayload;\r\n } catch (_) {\r\n }\r\n }\r\n var body = doc.body || doc.documentElement;\r\n if (dirty && leadingWhitespace) {\r\n body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);\r\n }\r\n if (NAMESPACE === HTML_NAMESPACE) {\r\n return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];\r\n }\r\n return WHOLE_DOCUMENT ? doc.documentElement : body;\r\n };\r\n var _createIterator = function _createIterator(root) {\r\n return createNodeIterator.call(root.ownerDocument || root, root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false);\r\n };\r\n var _isClobbered = function _isClobbered(elm) {\r\n return elm instanceof HTMLFormElement && (typeof elm.nodeName !== 'string' || typeof elm.textContent !== 'string' || typeof elm.removeChild !== 'function' || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== 'function' || typeof elm.setAttribute !== 'function' || typeof elm.namespaceURI !== 'string' || typeof elm.insertBefore !== 'function');\r\n };\r\n var _isNode = function _isNode(object) {\r\n return _typeof(Node) === 'object' ? object instanceof Node : object && _typeof(object) === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string';\r\n };\r\n var _executeHook = function _executeHook(entryPoint, currentNode, data) {\r\n if (!hooks[entryPoint]) {\r\n return;\r\n }\r\n arrayForEach(hooks[entryPoint], function (hook) {\r\n hook.call(DOMPurify, currentNode, data, CONFIG);\r\n });\r\n };\r\n var _sanitizeElements = function _sanitizeElements(currentNode) {\r\n var content;\r\n _executeHook('beforeSanitizeElements', currentNode, null);\r\n if (_isClobbered(currentNode)) {\r\n _forceRemove(currentNode);\r\n return true;\r\n }\r\n if (regExpTest(/[\\u0080-\\uFFFF]/, currentNode.nodeName)) {\r\n _forceRemove(currentNode);\r\n return true;\r\n }\r\n var tagName = transformCaseFunc(currentNode.nodeName);\r\n _executeHook('uponSanitizeElement', currentNode, {\r\n tagName: tagName,\r\n allowedTags: ALLOWED_TAGS\r\n });\r\n if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\\w]/g, currentNode.innerHTML) && regExpTest(/<[/\\w]/g, currentNode.textContent)) {\r\n _forceRemove(currentNode);\r\n return true;\r\n }\r\n if (tagName === 'select' && regExpTest(/