PageSourceSearch

https://www.hoinprinter.com/assets/plugins/tinymce/tinymce.js

js hoinprinter.com collected 2026-10-05 22:01:10 UTC 1,085,015 bytes, 30,142 lines download raw bytes

1/**
2 * Copyright (c) Tiny Technologies, Inc. All rights reserved.
3 * Licensed under the LGPL or a commercial license.
4 * For LGPL see License.txt in the project root for license information.
5 * For commercial licenses see https://www.tiny.cloud/
6 *
7 * Version: 5.10.9 (2023-11-15)
8 */
9(function () {
10    'use strict';
11
12    var typeOf$1 = function (x) {
13      if (x === null) {
14        return 'null';
15      }
16      if (x === undefined) {
17        return 'undefined';
18      }
19      var t = typeof x;
20      if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) {
21        return 'array';
22      }
23      if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) {
24        return 'string';
25      }
26      return t;
27    };
28    var isEquatableType = function (x) {
29      return [
30        'undefined',
31        'boolean',
32        'number',
33        'string',
34        'function',
35        'xml',
36        'null'
37      ].indexOf(x) !== -1;
38    };
39
40    var sort$1 = function (xs, compareFn) {
41      var clone = Array.prototype.slice.call(xs);
42      return clone.sort(compareFn);
43    };
44
45    var contramap = function (eqa, f) {
46      return eq$2(function (x, y) {
47        return eqa.eq(f(x), f(y));
48      });
49    };
50    var eq$2 = function (f) {
51      return { eq: f };
52    };
53    var tripleEq = eq$2(function (x, y) {
54      return x === y;
55    });
56    var eqString = tripleEq;
57    var eqArray = function (eqa) {
58      return eq$2(function (x, y) {
59        if (x.length !== y.length) {
60          return false;
61        }
62        var len = x.length;
63        for (var i = 0; i < len; i++) {
64          if (!eqa.eq(x[i], y[i])) {
65            return false;
66          }
67        }
68        return true;
69      });
70    };
71    var eqSortedArray = function (eqa, compareFn) {
72      return contramap(eqArray(eqa), function (xs) {
73        return sort$1(xs, compareFn);
74      });
75    };
76    var eqRecord = function (eqa) {
77      return eq$2(function (x, y) {
78        var kx = Object.keys(x);
79        var ky = Object.keys(y);
80        if (!eqSortedArray(eqString).eq(kx, ky)) {
81          return false;
82        }
83        var len = kx.length;
84        for (var i = 0; i < len; i++) {
85          var q = kx[i];
86          if (!eqa.eq(x[q], y[q])) {
87            return false;
88          }
89        }
90        return true;
91      });
92    };
93    var eqAny = eq$2(function (x, y) {
94      if (x === y) {
95        return true;
96      }
97      var tx = typeOf$1(x);
98      var ty = typeOf$1(y);
99      if (tx !== ty) {
100        return false;
101      }
102      if (isEquatableType(tx)) {
103        return x === y;
104      } else if (tx === 'array') {
105        return eqArray(eqAny).eq(x, y);
106      } else if (tx === 'object') {
107        return eqRecord(eqAny).eq(x, y);
108      }
109      return false;
110    });
111
112    var typeOf = function (x) {
113      var t = typeof x;
114      if (x === null) {
115        return 'null';
116      } else if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) {
117        return 'array';
118      } else if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) {
119        return 'string';
120      } else {
121        return t;
122      }
123    };
124    var isType$1 = function (type) {
125      return function (value) {
126        return typeOf(value) === type;
127      };
128    };
129    var isSimpleType = function (type) {
130      return function (value) {
131        return typeof value === type;
132      };
133    };
134    var eq$1 = function (t) {
135      return function (a) {
136        return t === a;
137      };
138    };
139    var isString$1 = isType$1('string');
140    var isObject = isType$1('object');
141    var isArray$1 = isType$1('array');
142    var isNull = eq$1(null);
143    var isBoolean = isSimpleType('boolean');
144    var isUndefined = eq$1(undefined);
145    var isNullable = function (a) {
146      return a === null || a === undefined;
147    };
148    var isNonNullable = function (a) {
149      return !isNullable(a);
150    };
151    var isFunction = isSimpleType('function');
152    var isNumber = isSimpleType('number');
153
154    var noop = function () {
155    };
156    var compose = function (fa, fb) {
157      return function () {
158        var args = [];
159        for (var _i = 0; _i < arguments.length; _i++) {
160          args[_i] = arguments[_i];
161        }
162        return fa(fb.apply(null, args));
163      };
164    };
165    var compose1 = function (fbc, fab) {
166      return function (a) {
167        return fbc(fab(a));
168      };
169    };
170    var constant = function (value) {
171      return function () {
172        return value;
173      };
174    };
175    var identity = function (x) {
176      return x;
177    };
178    var tripleEquals = function (a, b) {
179      return a === b;
180    };
181    function curry(fn) {
182      var initialArgs = [];
183      for (var _i = 1; _i < arguments.length; _i++) {
184        initialArgs[_i - 1] = arguments[_i];
185      }
186      return function () {
187        var restArgs = [];
188        for (var _i = 0; _i < arguments.length; _i++) {
189          restArgs[_i] = arguments[_i];
190        }
191        var all = initialArgs.concat(restArgs);
192        return fn.apply(null, all);
193      };
194    }
195    var not = function (f) {
196      return function (t) {
197        return !f(t);
198      };
199    };
200    var die = function (msg) {
201      return function () {
202        throw new Error(msg);
203      };
204    };
205    var apply = function (f) {
206      return f();
207    };
208    var call = function (f) {
209      f();
210    };
211    var never = constant(false);
212    var always = constant(true);
213
214    var none = function () {
215      return NONE;
216    };
217    var NONE = function () {
218      var call = function (thunk) {
219        return thunk();
220      };
221      var id = identity;
222      var me = {
223        fold: function (n, _s) {
224          return n();
225        },
226        isSome: never,
227        isNone: always,
228        getOr: id,
229        getOrThunk: call,
230        getOrDie: function (msg) {
231          throw new Error(msg || 'error: getOrDie called on none.');
232        },
233        getOrNull: constant(null),
234        getOrUndefined: constant(undefined),
235        or: id,
236        orThunk: call,
237        map: none,
238        each: noop,
239        bind: none,
240        exists: never,
241        forall: always,
242        filter: function () {
243          return none();
244        },
245        toArray: function () {
246          return [];
247        },
248        toString: constant('none()')
249      };
250      return me;
251    }();
252    var some = function (a) {
253      var constant_a = constant(a);
254      var self = function () {
255        return me;
256      };
257      var bind = function (f) {
258        return f(a);
259      };
260      var me = {
261        fold: function (n, s) {
262          return s(a);
263        },
264        isSome: always,
265        isNone: never,
266        getOr: constant_a,
267        getOrThunk: constant_a,
268        getOrDie: constant_a,
269        getOrNull: constant_a,
270        getOrUndefined: constant_a,
271        or: self,
272        orThunk: self,
273        map: function (f) {
274          return some(f(a));
275        },
276        each: function (f) {
277          f(a);
278        },
279        bind: bind,
280        exists: bind,
281        forall: bind,
282        filter: function (f) {
283          return f(a) ? me : NONE;
284        },
285        toArray: function () {
286          return [a];
287        },
288        toString: function () {
289          return 'some(' + a + ')';
290        }
291      };
292      return me;
293    };
294    var from$1 = function (value) {
295      return value === null || value === undefined ? NONE : some(value);
296    };
297    var Optional = {
298      some: some,
299      none: none,
300      from: from$1
301    };
302
303    var nativeSlice = Array.prototype.slice;
304    var nativeIndexOf = Array.prototype.indexOf;
305    var nativePush = Array.prototype.push;
306    var rawIndexOf = function (ts, t) {
307      return nativeIndexOf.call(ts, t);
308    };
309    var indexOf$2 = function (xs, x) {
310      var r = rawIndexOf(xs, x);
311      return r === -1 ? Optional.none() : Optional.some(r);
312    };
313    var contains$3 = function (xs, x) {
314      return rawIndexOf(xs, x) > -1;
315    };
316    var exists = function (xs, pred) {
317      for (var i = 0, len = xs.length; i < len; i++) {
318        var x = xs[i];
319        if (pred(x, i)) {
320          return true;
321        }
322      }
323      return false;
324    };
325    var map$3 = function (xs, f) {
326      var len = xs.length;
327      var r = new Array(len);
328      for (var i = 0; i < len; i++) {
329        var x = xs[i];
330        r[i] = f(x, i);
331      }
332      return r;
333    };
334    var each$k = function (xs, f) {
335      for (var i = 0, len = xs.length; i < len; i++) {
336        var x = xs[i];
337        f(x, i);
338      }
339    };
340    var eachr = function (xs, f) {
341      for (var i = xs.length - 1; i >= 0; i--) {
342        var x = xs[i];
343        f(x, i);
344      }
345    };
346    var partition = function (xs, pred) {
347      var pass = [];
348      var fail = [];
349      for (var i = 0, len = xs.length; i < len; i++) {
350        var x = xs[i];
351        var arr = pred(x, i) ? pass : fail;
352        arr.push(x);
353      }
354      return {
355        pass: pass,
356        fail: fail
357      };
358    };
359    var filter$4 = function (xs, pred) {
360      var r = [];
361      for (var i = 0, len = xs.length; i < len; i++) {
362        var x = xs[i];
363        if (pred(x, i)) {
364          r.push(x);
365        }
366      }
367      return r;
368    };
369    var foldr = function (xs, f, acc) {
370      eachr(xs, function (x, i) {
371        acc = f(acc, x, i);
372      });
373      return acc;
374    };
375    var foldl = function (xs, f, acc) {
376      each$k(xs, function (x, i) {
377        acc = f(acc, x, i);
378      });
379      return acc;
380    };
381    var findUntil$1 = function (xs, pred, until) {
382      for (var i = 0, len = xs.length; i < len; i++) {
383        var x = xs[i];
384        if (pred(x, i)) {
385          return Optional.some(x);
386        } else if (until(x, i)) {
387          break;
388        }
389      }
390      return Optional.none();
391    };
392    var find$3 = function (xs, pred) {
393      return findUntil$1(xs, pred, never);
394    };
395    var findIndex$2 = function (xs, pred) {
396      for (var i = 0, len = xs.length; i < len; i++) {
397        var x = xs[i];
398        if (pred(x, i)) {
399          return Optional.some(i);
400        }
401      }
402      return Optional.none();
403    };
404    var flatten = function (xs) {
405      var r = [];
406      for (var i = 0, len = xs.length; i < len; ++i) {
407        if (!isArray$1(xs[i])) {
408          throw new Error('Arr.flatten item ' + i + ' was not an array, input
408: ' + xs);
409        }
410        nativePush.apply(r, xs[i]);
411      }
412      return r;
413    };
414    var bind = function (xs, f) {
415      return flatten(map$3(xs, f));
416    };
417    var forall = function (xs, pred) {
418      for (var i = 0, len = xs.length; i < len; ++i) {
419        var x = xs[i];
420        if (pred(x, i) !== true) {
421          return false;
422        }
423      }
424      return true;
425    };
426    var reverse = function (xs) {
427      var r = nativeSlice.call(xs, 0);
428      r.reverse();
429      return r;
430    };
431    var difference = function (a1, a2) {
432      return filter$4(a1, function (x) {
433        return !contains$3(a2, x);
434      });
435    };
436    var mapToObject = function (xs, f) {
437      var r = {};
438      for (var i = 0, len = xs.length; i < len; i++) {
439        var x = xs[i];
440        r[String(x)] = f(x, i);
441      }
442      return r;
443    };
444    var sort = function (xs, comparator) {
445      var copy = nativeSlice.call(xs, 0);
446      copy.sort(comparator);
447      return copy;
448    };
449    var get$a = function (xs, i) {
450      return i >= 0 && i < xs.length ? Optional.some(xs[i]) : Optional.none();
451    };
452    var head = function (xs) {
453      return get$a(xs, 0);
454    };
455    var last$2 = function (xs) {
456      return get$a(xs, xs.length - 1);
457    };
458    var from = isFunction(Array.from) ? Array.from : function (x) {
459      return nativeSlice.call(x);
460    };
461    var findMap = function (arr, f) {
462      for (var i = 0; i < arr.length; i++) {
463        var r = f(arr[i], i);
464        if (r.isSome()) {
465          return r;
466        }
467      }
468      return Optional.none();
469    };
470
471    var keys = Object.keys;
472    var hasOwnProperty$1 = Object.hasOwnProperty;
473    var each$j = function (obj, f) {
474      var props = keys(obj);
475      for (var k = 0, len = props.length; k < len; k++) {
476        var i = props[k];
477        var x = obj[i];
478        f(x, i);
479      }
480    };
481    var map$2 = function (obj, f) {
482      return tupleMap(obj, function (x, i) {
483        return {
484          k: i,
485          v: f(x, i)
486        };
487      });
488    };
489    var tupleMap = function (obj, f) {
490      var r = {};
491      each$j(obj, function (x, i) {
492        var tuple = f(x, i);
493        r[tuple.k] = tuple.v;
494      });
495      return r;
496    };
497    var objAcc = function (r) {
498      return function (x, i) {
499        r[i] = x;
500      };
501    };
502    var internalFilter = function (obj, pred, onTrue, onFalse) {
503      var r = {};
504      each$j(obj, function (x, i) {
505        (pred(x, i) ? onTrue : onFalse)(x, i);
506      });
507      return r;
508    };
509    var bifilter = function (obj, pred) {
510      var t = {};
511      var f = {};
512      internalFilter(obj, pred, objAcc(t), objAcc(f));
513      return {
514        t: t,
515        f: f
516      };
517    };
518    var filter$3 = function (obj, pred) {
519      var t = {};
520      internalFilter(obj, pred, objAcc(t), noop);
521      return t;
522    };
523    var mapToArray = function (obj, f) {
524      var r = [];
525      each$j(obj, function (value, name) {
526        r.push(f(value, name));
527      });
528      return r;
529    };
530    var values = function (obj) {
531      return mapToArray(obj, identity);
532    };
533    var get$9 = function (obj, key) {
534      return has$2(obj, key) ? Optional.from(obj[key]) : Optional.none();
535    };
536    var has$2 = function (obj, key) {
537      return hasOwnProperty$1.call(obj, key);
538    };
539    var hasNonNullableKey = function (obj, key) {
540      return has$2(obj, key) && obj[key] !== undefined && obj[key] !== null;
541    };
542    var equal$1 = function (a1, a2, eq) {
543      if (eq === void 0) {
544        eq = eqAny;
545      }
546      return eqRecord(eq).eq(a1, a2);
547    };
548
549    var isArray = Array.isArray;
550    var toArray$1 = function (obj) {
551      if (!isArray(obj)) {
552        var array = [];
553        for (var i = 0, l = obj.length; i < l; i++) {
554          array[i] = obj[i];
555        }
556        return array;
557      } else {
558        return obj;
559      }
560    };
561    var each$i = function (o, cb, s) {
562      var n, l;
563      if (!o) {
564        return false;
565      }
566      s = s || o;
567      if (o.length !== undefined) {
568        for (n = 0, l = o.length; n < l; n++) {
569          if (cb.call(s, o[n], n, o) === false) {
570            return false;
571          }
572        }
573      } else {
574        for (n in o) {
575          if (has$2(o, n)) {
576            if (cb.call(s, o[n], n, o) === false) {
577              return false;
578            }
579          }
580        }
581      }
582      return true;
583    };
584    var map$1 = function (array, callback) {
585      var out = [];
586      each$i(array, function (item, index) {
587        out.push(callback(item, index, array));
588      });
589      return out;
590    };
591    var filter$2 = function (a, f) {
592      var o = [];
593      each$i(a, function (v, index) {
594        if (!f || f(v, index, a)) {
595          o.push(v);
596        }
597      });
598      return o;
599    };
600    var indexOf$1 = function (a, v) {
601      if (a) {
602        for (var i = 0, l = a.length; i < l; i++) {
603          if (a[i] === v) {
604            return i;
605          }
606        }
607      }
608      return -1;
609    };
610    var reduce = function (collection, iteratee, accumulator, thisArg) {
611      var acc = isUndefined(accumulator) ? collection[0] : accumulator;
612      for (var i = 0; i < collection.length; i++) {
613        acc = iteratee.call(thisArg, acc, collection[i], i);
614      }
615      return acc;
616    };
617    var findIndex$1 = function (array, predicate, thisArg) {
618      var i, l;
619      for (i = 0, l = array.length; i < l; i++) {
620        if (predicate.call(thisArg, array[i], i, array)) {
621          return i;
622        }
623      }
624      return -1;
625    };
626    var last$1 = function (collection) {
627      return collection[collection.length - 1];
628    };
629
630    var __assign = function () {
631      __assign = Object.assign || function __assign(t) {
632        for (var s, i = 1, n = arguments.length; i < n; i++) {
633          s = arguments[i];
634          for (var p in s)
635            if (Object.prototype.hasOwnProperty.call(s, p))
636              t[p] = s[p];
637        }
638        return t;
639      };
640      return __assign.apply(this, arguments);
641    };
642    function __rest(s, e) {
643      var t = {};
644      for (var p in s)
645        if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
646          t[p] = s[p];
647      if (s != null && typeof Object.getOwnPropertySymbols === 'function')
648        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
649          if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
650            t[p[i]] = s[p[i]];
651        }
652      return t;
653    }
654    function __spreadArray(to, from, pack) {
655      if (pack || arguments.length === 2)
656        for (var i = 0, l = from.length, ar; i < l; i++) {
657          if (ar || !(i in from)) {
658            if (!ar)
659              ar = Array.prototype.slice.call(from, 0, i);
660            ar[i] = from[i];
661          }
662        }
663      return to.concat(ar || Array.prototype.slice.call(from));
664    }
665
666    var cached = function (f) {
667      var called = false;
668      var r;
669      return function () {
670        var args = [];
671        for (var _i = 0; _i < arguments.length; _i++) {
672          args[_i] = arguments[_i];
673        }
674        if (!called) {
675          called = true;
676          r = f.apply(null, args);
677        }
678        return r;
679      };
680    };
681
682    var DeviceType = function (os, browser, userAgent, mediaMatch) {
683      var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true;
684      var isiPhone = os.isiOS() && !isiPad;
685      var isMobile = os.isiOS() || os.isAndroid();
686      var isTouch = isMobile || mediaMatch('(pointer:coarse)');
687      var isTablet = isiPad || !isiPhone && isMobile && mediaMatch('(min-device-width:768px)');
688      var isPhone = isiPhone || isMobile && !isTablet;
689      var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false;
690      var isDesktop = !isPhone && !isTablet && !iOSwebview;
691      return {
692        isiPad: constant(isiPad),
693        isiPhone: constant(isiPhone),
694        isTablet: constant(isTablet),
695        isPhone: constant(isPhone),
696        isTouch: constant(isTouch),
697        isAndroid: os.isAndroid,
698        isiOS: os.isiOS,
699        isWebView: constant(iOSwebview),
700        isDesktop: constant(isDesktop)
701      };
702    };
703
704    var firstMatch = function (regexes, s) {
705      for (var i = 0; i < regexes.length; i++) {
706        var x = regexes[i];
707        if (x.test(s)) {
708          return x;
709        }
710      }
711      return undefined;
712    };
713    var find$2 = function (regexes, agent) {
714      var r = firstMatch(regexes, agent);
715      if (!r) {
716        return {
717          major: 0,
718          minor: 0
719        };
720      }
721      var group = function (i) {
722        return Number(agent.replace(r, '$' + i));
723      };
724      return nu$4(group(1), group(2));
725    };
726    var detect$3 = function (versionRegexes, agent) {
727      var cleanedAgent = String(agent).toLowerCase();
728      if (versionRegexes.length === 0) {
729        return unknown$2();
730      }
731      return find$2(versionRegexes, cleanedAgent);
732    };
733    var unknown$2 = function () {
734      return nu$4(0, 0);
735    };
736    var nu$4 = function (major, minor) {
737      return {
738        major: major,
739        minor: minor
740      };
741    };
742    var Version = {
743      nu: nu$4,
744      detect: detect$3,
745      unknown: unknown$2
746    };
747
748    var detectBrowser$1 = function (browsers, userAgentData) {
749      return findMap(userAgentData.brands, function (uaBrand) {
750        var lcBrand = uaBrand.brand.toLowerCase();
751        return find$3(browsers, function (browser) {
752          var _a;
753          return lcBrand === ((_a = browser.brand) === null || _a === void 0 ? void 0 : _a.toLowerCase());
754        }).map(function (info) {
755          return {
756            current: info.name,
757            version: Version.nu(parseInt(uaBrand.version, 10), 0)
758          };
759        });
760      });
761    };
762
763    var detect$2 = function (candidates, userAgent) {
764      var agent = String(userAgent).toLowerCase();
765      return find$3(candidates, function (candidate) {
766        return candidate.search(agent);
767      });
768    };
769    var detectBrowser = function (browsers, userAgent) {
770      return detect$2(browsers, userAgent).map(function (browser) {
771        var version = Version.detect(browser.versionRegexes, userAgent);
772        return {
773          current: browser.name,
774          version: version
775        };
776      });
777    };
778    var detectOs = function (oses, userAgent) {
779      return detect$2(oses, userAgent).map(function (os) {
780        var version = Version.detect(os.versionRegexes, userAgent);
781        return {
782          current: os.name,
783          version: version
784        };
785      });
786    };
787
788    var removeFromStart = function (str, numChars) {
789      return str.substring(numChars);
790    };
791
792    var checkRange = function (str, substr, start) {
793      return substr === '' || str.length >= substr.length && str.substr(start, start + substr.length) === substr;
794    };
795    var removeLeading = function (str, prefix) {
796      return startsWith(str, prefix) ? removeFromStart(str, prefix.length) : str;
797    };
798    var contains$2 = function (str, substr) {
799      return str.indexOf(substr) !== -1;
800    };
801    var startsWith = function (str, prefix) {
802      return checkRange(str, prefix, 0);
803    };
804    var blank = function (r) {
805      return function (s) {
806        return s.replace(r, '');
807      };
808    };
809    var trim$5 = blank(/^\s+|\s+$/g);
810    var lTrim = blank(/^\s+/g);
811    var rTrim = blank(/\s+$/g);
812    var isNotEmpty = function (s) {
813      return s.length > 0;
814    };
815    var isEmpty$3 = function (s) {
816      return !isNotEmpty(s);
817    };
818
819    var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/;
820    var checkContains = function (target) {
821      return function (uastring) {
822        return contains$2(uastring, target);
823      };
824    };
825    var browsers = [
826      {
827        name: 'Edge',
828        versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/],
829        search: function (uastring) {
830          return contains$2(uastring, 'edge/') && contains$2(uastring, 'chrome') && contains$2(uastring, 'safari') && contains$2(uastring, 'applewebkit');
831        }
832      },
833      {
834        name: 'Chrome',
835        brand: 'Chromium',
836        versionRegexes: [
837          /.*?chrome\/([0-9]+)\.([0-9]+).*/,
838          normalVersionRegex
839        ],
840        search: function (uastring) {
841          return contains$2(uastring, 'chrome') && !contains$2(uastring, 'chromeframe');
842        }
843      },
844      {
845        name: 'IE',
846        versionRegexes: [
847          /.*?msie\ ?([0-9]+)\.([0-9]+).*/,
848          /.*?rv:([0-9]+)\.([0-9]+).*/
849        ],
850        search: function (uastring) {
851          return contains$2(uastring, 'msie') || contains$2(uastring, 'trident');
852        }
853      },
854      {
855        name: 'Opera',
856        versionRegexes: [
857          normalVersionRegex,
858          /.*?opera\/([0-9]+)\.([0-9]+).*/
859        ],
860        search: checkContains('opera')
861      },
862      {
863        name: 'Firefox',
864        versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/],
865        search: checkContains('firefox')
866      },
867      {
868        name: 'Safari',
869        versionRegexes: [
870          normalVersionRegex,
871          /.*?cpu os ([0-9]+)_([0-9]+).*/
872        ],
873        search: function (uastring) {
874          return (contains$2(uastring, 'safari') || contains$2(uastring, 'mobile/')) && contains$2(uastring, 'applewebkit');
875        }
876      }
877    ];
878    var oses = [
879      {
880        name: 'Windows',
881        search: checkContains('win'),
882        versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/]
883      },
884      {
885        name: 'iOS',
886        search: function (uastring) {
887          return contains$2(uastring, 'iphone') || contains$2(uastring, 'ipad');
888        },
889        versionRegexes: [
890          /.*?version\/\ ?([0-9]+)\.([0-9]+).*/,
891          /.*cpu os ([0-9]+)_([0-9]+).*/,
892          /.*cpu iphone os ([0-9]+)_([0-9]+).*/
893        ]
894      },
895      {
896        name: 'Android',
897        search: checkContains('android'),
898        versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/]
899      },
900      {
901        name: 'OSX',
902        search: checkContains('mac os x'),
903        versionRegexes: [/.*?mac\ os\ x\ ?([0-9]+)_([0-9]+).*/]
904      },
905      {
906        name: 'Linux',
907        search: checkContains('linux'),
908        versionRegexes: []
909      },
910      {
911        name: 'Solaris',
912        search: checkContains('sunos'),
913        versionRegexes: []
914      },
915      {
916        name: 'FreeBSD',
917        search: checkContains('freebsd'),
918        versionRegexes: []
919      },
920      {
921        name: 'ChromeOS',
922        search: checkContains('cros'),
923        versionRegexes: [/.*?chrome\/([0-9]+)\.([0-9]+).*/]
924      }
925    ];
926    var PlatformInfo = {
927      browsers: constant(browsers),
928      oses: constant(oses)
929    };
930
931    var edge = 'Edge';
932    var chrome = 'Chrome';
933    var ie$1 = 'IE';
934    var opera = 'Opera';
935    var firefox = 'Firefox';
936    var safari = 'Safari';
937    var unknown$1 = function () {
938      return nu$3({
939        current: undefined,
940        version: Version.unknown()
941      });
942    };
943    var nu$3 = function (info) {
944      var current = info.current;
945      var version = info.version;
946      var isBrowser = function (name) {
947        return function () {
948          return current === name;
949        };
950      };
951      return {
952        current: current,
953        version: version,
954        isEdge: isBrowser(edge),
955        isChrome: isBrowser(chrome),
956        isIE: isBrowser(ie$1),
957        isOpera: isBrowser(opera),
958        isFirefox: isBrowser(firefox),
959        isSafari: isBrowser(safari)
960      };
961    };
962    var Browser = {
963      unknown: unknown$1,
964      nu: nu$3,
965      edge: constant(edge),
966      chrome: constant(chrome),
967      ie: constant(ie$1),
968      opera: constant(opera),
969      firefox: constant(firefox),
970      safari: constant(safari)
971    };
972
973    var windows = 'Windows';
974    var ios = 'iOS';
975    var android = 'Android';
976    var linux = 'Linux';
977    var osx = 'OSX';
978    var solaris = 'Solaris';
979    var freebsd = 'FreeBSD';
980    var chromeos = 'ChromeOS';
981    var unknown = function () {
982      return nu$2({
983        current: undefined,
984        version: Version.unknown()
985      });
986    };
987    var nu$2 = function (info) {
988      var current = info.current;
989      var version = info.version;
990      var isOS = function (name) {
991        return function () {
992          return current === name;
993        };
994      };
995      return {
996        current: current,
997        version: version,
998        isWindows: isOS(windows),
999        isiOS: isOS(ios),
1000        isAndroid: isOS(android),
1001        isOSX: isOS(osx),
1002        isLinux: isOS(linux),
1003        isSolaris: isOS(solaris),
1004        isFreeBSD: isOS(freebsd),
1005        isChromeOS: isOS(chromeos)
1006      };
1007    };
1008    var OperatingSystem = {
1009      unknown: unknown,
1010      nu: nu$2,
1011      windows: constant(windows),
1012      ios: constant(ios),
1013      android: constant(android),
1014      linux: constant(linux),
1015      osx: constant(osx),
1016      solaris: constant(solaris),
1017      freebsd: constant(freebsd),
1018      chromeos: constant(chromeos)
1019    };
1020
1021    var detect$1 = function (userAgent, userAgentDataOpt, mediaMatch) {
1022      var browsers = PlatformInfo.browsers();
1023      var oses = PlatformInfo.oses();
1024      var browser = userAgentDataOpt.bind(function (userAgentData) {
1025        return detectBrowser$1(browsers, userAgentData);
1026      }).orThunk(function () {
1027        return detectBrowser(browsers, userAgent);
1028      }).fold(Browser.unknown, Browser.nu);
1029      var os = detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu);
1030      var deviceType = DeviceType(os, browser, userAgent, mediaMatch);
1031      return {
1032        browser: browser,
1033        os: os,
1034        deviceType: deviceType
1035      };
1036    };
1037    var PlatformDetection = { detect: detect$1 };
1038
1039    var mediaMatch = function (query) {
1040      return window.matchMedia(query).matches;
1041    };
1042    var platform$2 = cached(function () {
1043      return PlatformDetection.detect(navigator.userAgent, Optional.from(navigator.userAgentData), mediaMatch);
1044    });
1045    var detect = function () {
1046      return platform$2();
1047    };
1048
1049    var userAgent = navigator.userAgent;
1050    var platform$1 = detect();
1051    var browser$4 = platform$1.browser;
1052    var os = platform$1.os;
1053    var deviceType = platform$1.deviceType;
1054    var webkit = /WebKit/.test(userAgent) && !browser$4.isEdge();
1055    var fileApi = 'FormData' in window && 'FileReader' in window && 'URL' in window && !!URL.createObjectURL;
1056    var windowsPhone = userAgent.indexOf('Windows Phone') !== -1;
1057    var Env = {
1058      opera: browser$4.isOpera(),
1059      webkit: webkit,
1060      ie: browser$4.isIE() || browser$4.isEdge() ? browser$4.version.major : false,
1061      gecko: browser$4.isFirefox(),
1062      mac: os.isOSX() || os.isiOS(),
1063      iOS: deviceType.isiPad() || deviceType.isiPhone(),
1064      android: os.isAndroid(),
1065      contentEditable: true,
1066      transparentSrc: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
1067      caretAfter: true,
1068      range: window.getSelection && 'Range' in window,
1069      documentMode: browser$4.isIE() ? document.documentMode || 7 : 10,
1070      fileApi: fileApi,
1071      ceFalse: true,
1072      cacheSuffix: null,
1073      container: null,
1074      experimentalShadowDom: false,
1075      canHaveCSP: !browser$4.isIE(),
1076      desktop: deviceType.isDesktop(),
1077      windowsPhone: windowsPhone,
1078      browser: {
1079        current: browser$4.current,
1080        version: browser$4.version,
1081        isChrome: browser$4.isChrome,
1082        isEdge: browser$4.isEdge,
1083        isFirefox: browser$4.isFirefox,
1084        isIE: browser$4.isIE,
1085        isOpera: browser$4.isOpera,
1086        isSafari: browser$4.isSafari
1087      },
1088      os: {
1089        current: os.current,
1090        version: os.version,
1091        isAndroid: os.isAndroid,
1092        isChromeOS: os.isChromeOS,
1093        isFreeBSD: os.isFreeBSD,
1094        isiOS: os.isiOS,
1095        isLinux: os.isLinux,
1096        isOSX: os.isOSX,
1097        isSolaris: os.isSolaris,
1098        isWindows: os.isWindows
1099      },
1100      deviceType: {
1101        isDesktop: deviceType.isDesktop,
1102        isiPad: deviceType.isiPad,
1103        isiPhone: deviceType.isiPhone,
1104        isPhone: deviceType.isPhone,
1105        isTablet: deviceType.isTablet,
1106        isTouch: deviceType.isTouch,
1107        isWebView: deviceType.isWebView
1108      }
1109    };
1110
1111    var whiteSpaceRegExp$2 = /^\s*|\s*$/g;
1112    var trim$4 = function (str) {
1113      return str === null || str === undefined ? '' : ('' + str).replace(whiteSpaceRegExp$2, '');
1114    };
1115    var is$3 = function (obj, type) {
1116      if (!type) {
1117        return obj !== undefined;
1118      }
1119      if (type === 'array' && isArray(obj)) {
1120        return true;
1121      }
1122      return typeof obj === type;
1123    };
1124    var makeMap$4 = function (items, delim, map) {
1125      var i;
1126      items = items || [];
1127      delim = delim || ',';
1128      if (typeof items === 'string') {
1129        items = items.split(delim);
1130      }
1131      map = map || {};
1132      i = items.length;
1133      while (i--) {
1134        map[items[i]] = {};
1135      }
1136      return map;
1137    };
1138    var hasOwnProperty = has$2;
1139    var create$9 = function (s, p, root) {
1140      var self = this;
1141      var sp, scn, c, de = 0;
1142      s = /^((static) )?([\w.]+)(:([\w.]+))?/.exec(s);
1143      var cn = s[3].match(/(^|\.)(\w+)$/i)[2];
1144      var ns = self.createNS(s[3].replace(/\.\w+$/, ''), root);
1145      if (ns[cn]) {
1146        return;
1147      }
1148      if (s[2] === 'static') {
1149        ns[cn] = p;
1150        if (this.onCreate) {
1151          this.onCreate(s[2], s[3], ns[cn]);
1152        }
1153        return;
1154      }
1155      if (!p[cn]) {
1156        p[cn] = function () {
1157        };
1158        de = 1;
1159      }
1160      ns[cn] = p[cn];
1161      self.extend(ns[cn].prototype, p);
1162      if (s[5]) {
1163        sp = self.resolve(s[5]).prototype;
1164        scn = s[5].match(/\.(\w+)$/i)[1];
1165        c = ns[cn];
1166        if (de) {
1167          ns[cn] = function () {
1168            return sp[scn].apply(this, arguments);
1169          };
1170        } else {
1171          ns[cn] = function () {
1172            this.parent = sp[scn];
1173            return c.apply(this, arguments);
1174          };
1175        }
1176        ns[cn].prototype[cn] = ns[cn];
1177        self.each(sp, function (f, n) {
1178          ns[cn].prototype[n] = sp[n];
1179        });
1180        self.each(p, function (f, n) {
1181          if (sp[n]) {
1182            ns[cn].prototype[n] = function () {
1183              this.parent = sp[n];
1184              return f.apply(this, arguments);
1185            };
1186          } else {
1187            if (n !== cn) {
1188              ns[cn].prototype[n] = f;
1189            }
1190          }
1191        });
1192      }
1193      self.each(p.static, function (f, n) {
1194        ns[cn][n] = f;
1195      });
1196    };
1197    var extend$6 = function (obj) {
1198      var exts = [];
1199      for (var _i = 1; _i < arguments.length; _i++) {
1200        exts[_i - 1] = arguments[_i];
1201      }
1202      for (var i = 0; i < exts.length; i++) {
1203        var ext = exts[i];
1204        for (var name_1 in ext) {
1205          if (has$2(ext, name_1)) {
1206            var value = ext[name_1];
1207            if (value !== undefined) {
1208              obj[name_1] = value;
1209            }
1210          }
1211        }
1212      }
1213      return obj;
1214    };
1215    var walk$3 = function (o, f, n, s) {
1216      s = s || this;
1217      if (o) {
1218        if (n) {
1219          o = o[n];
1220        }
1221        each$i(o, function (o, i) {
1222          if (f.call(s, o, i, n) === false) {
1223            return false;
1224          }
1225          walk$3(o, f, n, s);
1226        });
1227      }
1228    };
1229    var createNS = function (n, o) {
1230      var i, v;
1231      o = o || window;
1232      n = n.split('.');
1233      for (i = 0; i < n.length; i++) {
1234        v = n[i];
1235        if (!o[v]) {
1236          o[v] = {};
1237        }
1238        o = o[v];
1239      }
1240      return o;
1241    };
1242    var resolve$3 = function (n, o) {
1243      var i, l;
1244      o = o || window;
1245      n = n.split('.');
1246      for (i = 0, l = n.length; i < l; i++) {
1247        o = o[n[i]];
1248        if (!o) {
1249          break;
1250        }
1251      }
1252      return o;
1253    };
1254    var explode$4 = function (s, d) {
1255      if (!s || is$3(s, 'array')) {
1256        return s;
1257      }
1258      return map$1(s.split(d || ','), trim$4);
1259    };
1260    var _addCacheSuffix = function (url) {
1261      var cacheSuffix = Env.cacheSuffix;
1262      if (cacheSuffix) {
1263        url += (url.indexOf('?') === -1 ? '?' : '&') + cacheSuffix;
1264      }
1265      return url;
1266    };
1267    var Tools = {
1268      trim: trim$4,
1269      isArray: isArray,
1270      is: is$3,
1271      toArray: toArray$1,
1272      makeMap: makeMap$4,
1273      each: each$i,
1274      map: map$1,
1275      grep: filter$2,
1276      inArray: indexOf$1,
1277      hasOwn: hasOwnProperty,
1278      extend: extend$6,
1279      create: create$9,
1280      walk: walk$3,
1281      createNS: createNS,
1282      resolve: resolve$3,
1283      explode: explode$4,
1284      _addCacheSuffix: _addCacheSuffix
1285    };
1286
1287    var fromHtml$1 = function (html, scope) {
1288      var doc = scope || document;
1289      var div = doc.createElement('div');
1290      div.innerHTML = html;
1291      if (!div.hasChildNodes() || div.childNodes.length > 1) {
1292        console.error('HTML does not have a single root node', html);
1293        throw new Error('HTML must have a single root node');
1294      }
1295      return fromDom$2(div.childNodes[0]);
1296    };
1297    var fromTag = function (tag, scope) {
1298      var doc = scope || document;
1299      var node = doc.createElement(tag);
1300      return fromDom$2(node);
1301    };
1302    var fromText = function (text, scope) {
1303      var doc = scope || document;
1304      var node = doc.createTextNode(text);
1305      return fromDom$2(node);
1306    };
1307    var fromDom$2 = function (node) {
1308      if (node === null || node === undefined) {
1309        throw new Error('Node cannot be null or undefined');
1310      }
1311      return { dom: node };
1312    };
1313    var fromPoint$1 = function (docElm, x, y) {
1314      return Optional.from(docElm.dom.elementFromPoint(x, y)).map(fromDom$2);
1315    };
1316    var SugarElement = {
1317      fromHtml: fromHtml$1,
1318      fromTag: fromTag,
1319      fromText: fromText,
1320      fromDom: fromDom$2,
1321      fromPoint: fromPoint$1
1322    };
1323
1324    var toArray = function (target, f) {
1325      var r = [];
1326      var recurse = function (e) {
1327        r.push(e);
1328        return f(e);
1329      };
1330      var cur = f(target);
1331      do {
1332        cur = cur.bind(recurse);
1333      } while (cur.isSome());
1334      return r;
1335    };
1336
1337    var compareDocumentPosition = function (a, b, match) {
1338      return (a.compareDocumentPosition(b) & match) !== 0;
1339    };
1340    var documentPositionContainedBy = function (a, b) {
1341      return compareDocumentPosition(a, b, Node.DOCUMENT_POSITION_CONTAINED_BY);
1342    };
1343
1344    var COMMENT = 8;
1345    var DOCUMENT = 9;
1346    var DOCUMENT_FRAGMENT = 11;
1347    var ELEMENT = 1;
1348    var TEXT = 3;
1349
1350    var is$2 = function (element, selector) {
1351      var dom = element.dom;
1352      if (dom.nodeType !== ELEMENT) {
1353        return false;
1354      } else {
1355        var elem = dom;
1356        if (elem.matches !== undefined) {
1357          return elem.matches(selector);
1358        } else if (elem.msMatchesSelector !== undefined) {
1359          return elem.msMatchesSelector(selector);
1360        } else if (elem.webkitMatchesSelector !== undefined) {
1361          return elem.webkitMatchesSelector(selector);
1362        } else if (elem.mozMatchesSelector !== undefined) {
1363          return elem.mozMatchesSelector(selector);
1364        } else {
1365          throw new Error('Browser lacks native selectors');
1366        }
1367      }
1368    };
1369    var bypassSelector = function (dom) {
1370      return dom.nodeType !== ELEMENT && dom.nodeType !== DOCUMENT && dom.nodeType !== DOCUMENT_FRAGMENT || dom.childElementCount === 0;
1371    };
1372    var all = function (selector, scope) {
1373      var base = scope === undefined ? document : scope.dom;
1374      return bypassSelector(base) ? [] : map$3(base.querySelectorAll(selector), SugarElement.fromDom);
1375    };
1376    var one = function (selector, scope) {
1377      var base = scope === undefined ? document : scope.dom;
1378      return bypassSelector(base) ? Optional.none() : Optional.from(base.querySelector(selector)).map(SugarElement.fromDom);
1379    };
1380
1381    var eq = function (e1, e2) {
1382      return e1.dom === e2.dom;
1383    };
1384    var regularContains = function (e1, e2) {
1385      var d1 = e1.dom;
1386      var d2 = e2.dom;
1387      return d1 === d2 ? false : d1.contains(d2);
1388    };
1389    var ieContains = function (e1, e2) {
1390      return documentPositionContainedBy(e1.dom, e2.dom);
1391    };
1392    var contains$1 = function (e1, e2) {
1393      return detect().browser.isIE() ? ieContains(e1, e2) : regularContains(e1, e2);
1394    };
1395
1396    typeof window !== 'undefined' ? window : Function('return this;')();
1397
1398    var name = function (element) {
1399      var r = element.dom.nodeName;
1400      return r.toLowerCase();
1401    };
1402    var type = function (element) {
1403      return element.dom.nodeType;
1404    };
1405    var isType = function (t) {
1406      return function (element) {
1407        return type(element) === t;
1408      };
1409    };
1410    var isComment$1 = function (element) {
1411      return type(element) === COMMENT || name(element) === '#comment';
1412    };
1413    var isElement$6 = isType(ELEMENT);
1414    var isText$8 = isType(TEXT);
1415    var isDocument$2 = isType(DOCUMENT);
1416    var isDocumentFragment$1 = isType(DOCUMENT_FRAGMENT);
1417    var isTag = function (tag) {
1418      return function (e) {
1419        return isElement$6(e) && name(e) === tag;
1420      };
1421    };
1422
1423    var owner$1 = function (element) {
1424      return SugarElement.fromDom(element.dom.ownerDocument);
1425    };
1426    var documentOrOwner = function (dos) {
1427      return isDocument$2(dos) ? dos : owner$1(dos);
1428    };
1429    var documentElement = function (element) {
1430      return SugarElement.fromDom(documentOrOwner(element).dom.documentElement);
1431    };
1432    var defaultView = function (element) {
1433      return SugarElement.fromDom(documentOrOwner(element).dom.defaultView);
1434    };
1435    var parent = function (element) {
1436      return Optional.from(element.dom.parentNode).map(SugarElement.fromDom);
1437    };
1438    var parents$1 = function (element, isRoot) {
1439      var stop = isFunction(isRoot) ? isRoot : never;
1440      var dom = element.dom;
1441      var ret = [];
1442      while (dom.parentNode !== null && dom.parentNode !== undefined) {
1443        var rawParent = dom.parentNode;
1444        var p = SugarElement.fromDom(rawParent);
1445        ret.push(p);
1446        if (stop(p) === true) {
1447          break;
1448        } else {
1449          dom = rawParent;
1450        }
1451      }
1452      return ret;
1453    };
1454    var siblings = function (element) {
1455      var filterSelf = function (elements) {
1456        return filter$4(elements, function (x) {
1457          return !eq(element, x);
1458        });
1459      };
1460      return parent(element).map(children).map(filterSelf).getOr([]);
1461    };
1462    var prevSibling = function (element) {
1463      return Optional.from(element.dom.previousSibling).map(SugarElement.fromDom);
1464    };
1465    var nextSibling = function (element) {
1466      return Optional.from(element.dom.nextSibling).map(SugarElement.fromDom);
1467    };
1468    var prevSiblings = function (element) {
1469      return reverse(toArray(element, prevSibling));
1470    };
1471    var nextSiblings = function (element) {
1472      return toArray(element, nextSibling);
1473    };
1474    var children = function (element) {
1475      return map$3(element.dom.childNodes, SugarElement.fromDom);
1476    };
1477    var child$1 = function (element, index) {
1478      var cs = element.dom.childNodes;
1479      return Optional.from(cs[index]).map(SugarElement.fromDom);
1480    };
1481    var firstChild = function (element) {
1482      return child$1(element, 0);
1483    };
1484    var lastChild = function (element) {
1485      return child$1(element, element.dom.childNodes.length - 1);
1486    };
1487    var childNodesCount = function (element) {
1488      return element.dom.childNodes.length;
1489    };
1490
1491    var getHead = function (doc) {
1492      var b = doc.dom.head;
1493      if (b === null || b === undefined) {
1494        throw new Error('Head is not available yet');
1495      }
1496      return SugarElement.fromDom(b);
1497    };
1498
1499    var isShadowRoot = function (dos) {
1500      return isDocumentFragment$1(dos) && isNonNullable(dos.dom.host);
1501    };
1502    var supported = isFunction(Element.prototype.attachShadow) && isFunction(Node.prototype.getRootNode);
1503    var isSupported$1 = constant(supported);
1504    var getRootNode = supported ? function (e) {
1505      return SugarElement.fromDom(e.dom.getRootNode());
1506    } : documentOrOwner;
1507    var getStyleContainer = function (dos) {
1508      return isShadowRoot(dos) ? dos : getHead(documentOrOwner(dos));
1509    };
1510    var getShadowRoot = function (e) {
1511      var r = getRootNode(e);
1512      return isShadowRoot(r) ? Optional.some(r) : Optional.none();
1513    };
1514    var getShadowHost = function (e) {
1515      return SugarElement.fromDom(e.dom.host);
1516    };
1517    var getOriginalEventTarget = function (event) {
1518      if (isSupported$1() && isNonNullable(event.target)) {
1519        var el = SugarElement.fromDom(event.target);
1520        if (isElement$6(el) && isOpenShadowHost(el)) {
1521          if (event.composed && event.composedPath) {
1522            var composedPath = event.composedPath();
1523            if (composedPath) {
1524              return head(composedPath);
1525            }
1526          }
1527        }
1528      }
1529      return Optional.from(event.target);
1530    };
1531    var isOpenShadowHost = function (element) {
1532      return isNonNullable(element.dom.shadowRoot);
1533    };
1534
1535    var before$4 = function (marker, element) {
1536      var parent$1 = parent(marker);
1537      parent$1.each(function (v) {
1538        v.dom.insertBefore(element.dom, marker.dom);
1539      });
1540    };
1541    var after$3 = function (marker, element) {
1542      var sibling = nextSibling(marker);
1543      sibling.fold(function () {
1544        var parent$1 = parent(marker);
1545        parent$1.each(function (v) {
1546          append$1(v, element);
1547        });
1548      }, function (v) {
1549        before$4(v, element);
1550      });
1551    };
1552    var prepend = function (parent, element) {
1553      var firstChild$1 = firstChild(parent);
1554      firstChild$1.fold(function () {
1555        append$1(parent, element);
1556      }, function (v) {
1557        parent.dom.insertBefore(element.dom, v.dom);
1558      });
1559    };
1560    var append$1 = function (parent, element) {
1561      parent.dom.appendChild(element.dom);
1562    };
1563    var wrap$3 = function (element, wrapper) {
1564      before$4(element, wrapper);
1565      append$1(wrapper, element);
1566    };
1567
1568    var before$3 = function (marker, elements) {
1569      each$k(elements, function (x) {
1570        before$4(marker, x);
1571      });
1572    };
1573    var append = function (parent, elements) {
1574      each$k(elements, function (x) {
1575        append$1(parent, x);
1576      });
1577    };
1578
1579    var empty = function (element) {
1580      element.dom.textContent = '';
1581      each$k(children(element), function (rogue) {
1582        remove$7(rogue);
1583      });
1584    };
1585    var remove$7 = function (element) {
1586      var dom = element.dom;
1587      if (dom.parentNode !== null) {
1588        dom.parentNode.removeChild(dom);
1589      }
1590    };
1591    var unwrap = function (wrapper) {
1592      var children$1 = children(wrapper);
1593      if (children$1.length > 0) {
1594        before$3(wrapper, children$1);
1595      }
1596      remove$7(wrapper);
1597    };
1598
1599    var inBody = function (element) {
1600      var dom = isText$8(element) ? element.dom.parentNode : element.dom;
1601      if (dom === undefined || dom === null || dom.ownerDocument === null) {
1602        return false;
1603      }
1604      var doc = dom.ownerDocument;
1605      return getShadowRoot(SugarElement.fromDom(dom)).fold(function () {
1606        return doc.body.contains(dom);
1607      }, compose1(inBody, getShadowHost));
1608    };
1609
1610    var r = function (left, top) {
1611      var translate = function (x, y) {
1612        return r(left + x, top + y);
1613      };
1614      return {
1615        left: left,
1616        top: top,
1617        translate: translate
1618      };
1619    };
1620    var SugarPosition = r;
1621
1622    var boxPosition = function (dom) {
1623      var box = dom.getBoundingClientRect();
1624      return SugarPosition(box.left, box.top);
1625    };
1626    var firstDefinedOrZero = function (a, b) {
1627      if (a !== undefined) {
1628        return a;
1629      } else {
1630        return b !== undefined ? b : 0;
1631      }
1632    };
1633    var absolute = function (element) {
1634      var doc = element.dom.ownerDocument;
1635      var body = doc.body;
1636      var win = doc.defaultView;
1637      var html = doc.documentElement;
1638      if (body === element.dom) {
1639        return SugarPosition(body.offsetLeft, body.offsetTop);
1640      }
1641      var scrollTop = firstDefinedOrZero(win === null || win === void 0 ? void 0 : win.pageYOffset, html.scrollTop);
1642      var scrollLeft = firstDefinedOrZero(win === null || win === void 0 ? void 0 : win.pageXOffset, html.scrollLeft);
1643      var clientTop = firstDefinedOrZero(html.clientTop, body.clientTop);
1644      var clientLeft = firstDefinedOrZero(html.clientLeft, body.clientLeft);
1645      return viewport(element).translate(scrollLeft - clientLeft, scrollTop - clientTop);
1646    };
1647    var viewport = function (element) {
1648      var dom = element.dom;
1649      var doc = dom.ownerDocument;
1650      var body = doc.body;
1651      if (body === dom) {
1652        return SugarPosition(body.offsetLeft, body.offsetTop);
1653      }
1654      if (!inBody(element)) {
1655        return SugarPosition(0, 0);
1656      }
1657      return boxPosition(dom);
1658    };
1659
1660    var get$8 = function (_DOC) {
1661      var doc = _DOC !== undefined ? _DOC.dom : document;
1662      var x = doc.body.scrollLeft || doc.documentElement.scrollLeft;
1663      var y = doc.body.scrollTop || doc.documentElement.scrollTop;
1664      return SugarPosition(x, y);
1665    };
1666    var to = function (x, y, _DOC) {
1667      var doc = _DOC !== undefined ? _DOC.dom : document;
1668      var win = doc.defaultView;
1669      if (win) {
1670        win.scrollTo(x, y);
1671      }
1672    };
1673    var intoView = function (element, alignToTop) {
1674      var isSafari = detect().browser.isSafari();
1675      if (isSafari && isFunction(element.dom.scrollIntoViewIfNeeded)) {
1676        element.dom.scrollIntoViewIfNeeded(false);
1677      } else {
1678        element.dom.scrollIntoView(alignToTop);
1679      }
1680    };
1681
1682    var get$7 = function (_win) {
1683      var win = _win === undefined ? window : _win;
1684      if (detect().browser.isFirefox()) {
1685        return Optional.none();
1686      } else {
1687        return Optional.from(win['visualViewport']);
1688      }
1689    };
1690    var bounds = function (x, y, width, height) {
1691      return {
1692        x: x,
1693        y: y,
1694        width: width,
1695        height: height,
1696        right: x + width,
1697        bottom: y + height
1698      };
1699    };
1700    var getBounds = function (_win) {
1701      var win = _win === undefined ? window : _win;
1702      var doc = win.document;
1703      var scroll = get$8(SugarElement.fromDom(doc));
1704      return get$7(win).fold(function () {
1705        var html = win.document.documentElement;
1706        var width = html.clientWidth;
1707        var height = html.clientHeight;
1708        return bounds(scroll.left, scroll.top, width, height);
1709      }, function (visualViewport) {
1710        return bounds(Math.max(visualViewport.pageLeft, scroll.left), Math.max(visualViewport.pageTop, scroll.top), visualViewport.width, visualViewport.height);
1711      });
1712    };
1713
1714    var isNodeType = function (type) {
1715      return function (node) {
1716        return !!node && node.nodeType === type;
1717      };
1718    };
1719    var isRestrictedNode = function (node) {
1720      return !!node && !Object.getPrototypeOf(node);
1721    };
1722    var isElement$5 = isNodeType(1);
1723    var matchNodeNames = function (names) {
1724      var lowercasedNames = names.map(function (s) {
1725        return s.toLowerCase();
1726      });
1727      return function (node) {
1728        if (node && node.nodeName) {
1729          var nodeName = node.nodeName.toLowerCase();
1730          return contains$3(lowercasedNames, nodeName);
1731        }
1732        return false;
1733      };
1734    };
1735    var matchStyleValues = function (name, values) {
1736      var items = values.toLowerCase().split(' ');
1737      return function (node) {
1738        if (isElement$5(node)) {
1739          for (var i = 0; i < items.length; i++) {
1740            var computed = node.ownerDocument.defaultView.getComputedStyle(node, null);
1741            var cssValue = computed ? computed.getPropertyValue(name) : null;
1742            if (cssValue === items[i]) {
1743              return true;
1744            }
1745          }
1746        }
1747        return false;
1748      };
1749    };
1750    var hasAttribute = function (attrName) {
1751      return function (node) {
1752        return isElement$5(node) && node.hasAttribute(attrName);
1753      };
1754    };
1755    var hasAttributeValue = function (attrName, attrValue) {
1756      return function (node) {
1757        return isElement$5(node) && node.getAttribute(attrName) === attrValue;
1758      };
1759    };
1760    var isBogus$2 = function (node) {
1761      return isElement$5(node) && node.hasAttribute('data-mce-bogus');
1762    };
1763    var isBogusAll$1 = function (node) {
1764      return isElement$5(node) && node.getAttribute('data-mce-bogus') === 'all';
1765    };
1766    var isTable$3 = function (node) {
1767      return isElement$5(node) && node.tagName === 'TABLE';
1768    };
1769    var hasContentEditableState = function (value) {
1770      return function (node) {
1771        if (isElement$5(node)) {
1772          if (node.contentEditable === value) {
1773            return true;
1774          }
1775          if (node.getAttribute('data-mce-contenteditable') === value) {
1776            return true;
1777          }
1778        }
1779        return false;
1780      };
1781    };
1782    var isTextareaOrInput = matchNodeNames([
1783      'textarea',
1784      'input'
1785    ]);
1786    var isText$7 = isNodeType(3);
1787    var isComment = isNodeType(8);
1788    var isDocument$1 = isNodeType(9);
1789    var isDocumentFragment = isNodeType(11);
1790    var isBr$5 = matchNodeNames(['br']);
1791    var isImg = matchNodeNames(['img']);
1792    var isContentEditableTrue$4 = hasContentEditableState('true');
1793    var isContentEditableFalse$b = hasContentEditableState('false');
1794    var isTableCell$5 = matchNodeNames([
1795      'td',
1796      'th'
1797    ]);
1798    var isMedia$2 = matchNodeNames([
1799      'video',
1800      'audio',
1801      'object',
1802      'embed'
1803    ]);
1804
1805    var is$1 = function (lhs, rhs, comparator) {
1806      if (comparator === void 0) {
1807        comparator = tripleEquals;
1808      }
1809      return lhs.exists(function (left) {
1810        return comparator(left, rhs);
1811      });
1812    };
1813    var cat = function (arr) {
1814      var r = [];
1815      var push = function (x) {
1816        r.push(x);
1817      };
1818      for (var i = 0; i < arr.length; i++) {
1819        arr[i].each(push);
1820      }
1821      return r;
1822    };
1823    var lift2 = function (oa, ob, f) {
1824      return oa.isSome() && ob.isSome() ? Optional.some(f(oa.getOrDie(), ob.getOrDie())) : Optional.none();
1825    };
1826    var lift3 = function (oa, ob, oc, f) {
1827      return oa.isSome() && ob.isSome() && oc.isSome() ? Optional.some(f(oa.getOrDie(), ob.getOrDie(), oc.getOrDie())) : Optional.none();
1828    };
1829    var someIf = function (b, a) {
1830      return b ? Optional.some(a) : Optional.none();
1831    };
1832
1833    var isSupported = function (dom) {
1834      return dom.style !== undefined && isFunction(dom.style.getPropertyValue);
1835    };
1836
1837    var rawSet = function (dom, key, value) {
1838      if (isString$1(value) || isBoolean(value) || isNumber(value)) {
1839        dom.setAttribute(key, value + '');
1840      } else {
1841        console.error('Invalid call to Attribute.set. Key ', key, ':: Value ', value, ':: Element ', dom);
1842        throw new Error('Attribute value was not simple');
1843      }
1844    };
1845    var set$1 = function (element, key, value) {
1846      rawSet(element.dom, key, value);
1847    };
1848    var setAll$1 = function (element, attrs) {
1849      var dom = element.dom;
1850      each$j(attrs, function (v, k) {
1851        rawSet(dom, k, v);
1852      });
1853    };
1854    var get$6 = function (element, key) {
1855      var v = element.dom.getAttribute(key);
1856      return v === null ? undefined : v;
1857    };
1858    var getOpt = function (element, key) {
1859      return Optional.from(get$6(element, key));
1860    };
1861    var has$1 = function (element, key) {
1862      var dom = element.dom;
1863      return dom && dom.hasAttribute ? dom.hasAttribute(key) : false;
1864    };
1865    var remove$6 = function (element, key) {
1866      element.dom.removeAttribute(key);
1867    };
1868    var clone$3 = function (element) {
1869      return foldl(element.dom.attributes, function (acc, attr) {
1870        acc[attr.name] = attr.value;
1871        return acc;
1872      }, {});
1873    };
1874
1875    var internalSet = function (dom, property, value) {
1876      if (!isString$1(value)) {
1877        console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom);
1878        throw new Error('CSS value must be a string: ' + value);
1879      }
1880      if (isSupported(dom)) {
1881        dom.style.setProperty(property, value);
1882      }
1883    };
1884    var setAll = function (element, css) {
1885      var dom = element.dom;
1886      each$j(css, function (v, k) {
1887        internalSet(dom, k, v);
1888      });
1889    };
1890    var get$5 = function (element, property) {
1891      var dom = element.dom;
1892      var styles = window.getComputedStyle(dom);
1893      var r = styles.getPropertyValue(property);
1894      return r === '' && !inBody(element) ? getUnsafeProperty(dom, property) : r;
1895    };
1896    var getUnsafeProperty = function (dom, property) {
1897      return isSupported(dom) ? dom.style.getPropertyValue(property) : '';
1898    };
1899    var getRaw = function (element, property) {
1900      var dom = element.dom;
1901      var raw = getUnsafeProperty(dom, property);
1902      return Optional.from(raw).filter(function (r) {
1903        return r.length > 0;
1904      });
1905    };
1906    var getAllRaw = function (element) {
1907      var css = {};
1908      var dom = element.dom;
1909      if (isSupported(dom)) {
1910        for (var i = 0; i < dom.style.length; i++) {
1911          var ruleName = dom.style.item(i);
1912          css[ruleName] = dom.style[ruleName];
1913        }
1914      }
1915      return css;
1916    };
1917    var reflow = function (e) {
1918      return e.dom.offsetWidth;
1919    };
1920
1921    var browser$3 = detect().browser;
1922    var firstElement = function (nodes) {
1923      return find$3(nodes, isElement$6);
1924    };
1925    var getTableCaptionDeltaY = function (elm) {
1926      if (browser$3.isFirefox() && name(elm) === 'table') {
1927        return firstElement(children(elm)).filter(function (elm) {
1928          return name(elm) === 'caption';
1929        }).bind(function (caption) {
1930          return firstElement(nextSiblings(caption)).map(function (body) {
1931            var bodyTop = body.dom.offsetTop;
1932            var captionTop = caption.dom.offsetTop;
1933            var captionHeight = caption.dom.offsetHeight;
1934            return bodyTop <= captionTop ? -captionHeight : 0;
1935          });
1936        }).getOr(0);
1937      } else {
1938        return 0;
1939      }
1940    };
1941    var hasChild = function (elm, child) {
1942      return elm.children && contains$3(elm.children, child);
1943    };
1944    var getPos = function (body, elm, rootElm) {
1945      var x = 0, y = 0;
1946      var doc = body.ownerDocument;
1947      rootElm = rootElm ? rootElm : body;
1948      if (elm) {
1949        if (rootElm === body && elm.getBoundingClientRect && get$5(SugarElement.fromDom(body), 'position') === 'static') {
1950          var pos = elm.getBoundingClientRect();
1951          x = pos.left + (doc.documentElement.scrollLeft || body.scrollLeft) - doc.documentElement.clientLeft;
1952          y = pos.top + (doc.documentElement.scrollTop || body.scrollTop) - doc.documentElement.clientTop;
1953          return {
1954            x: x,
1955            y: y
1956          };
1957        }
1958        var offsetParent = elm;
1959        while (offsetParent && offsetParent !== rootElm && offsetParent.nodeType && !hasChild(offsetParent, rootElm)) {
1960          var castOffsetParent = offsetParent;
1961          x += castOffsetParent.offsetLeft || 0;
1962          y += castOffsetParent.offsetTop || 0;
1963          offsetParent = castOffsetParent.offsetParent;
1964        }
1965        offsetParent = elm.parentNode;
1966        while (offsetParent && offsetParent !== rootElm && offsetParent.nodeType && !hasChild(offsetParent, rootElm)) {
1967          x -= offsetParent.scrollLeft || 0;
1968          y -= offsetParent.scrollTop || 0;
1969          offsetParent = offsetParent.parentNode;
1970        }
1971        y += getTableCaptionDeltaY(SugarElement.fromDom(elm));
1972      }
1973      return {
1974        x: x,
1975        y: y
1976      };
1977    };
1978
1979    var exports$1 = {}, module$1 = { exports: exports$1 };
1980    (function (define, exports, module, require) {
1981      (function (global, factory) {
1982        typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.EphoxContactWrapper = factory());
1983      }(this, function () {
1984        var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
1985        var promise = { exports: {} };
1986        (function (module) {
1987          (function (root) {
1988            var setTimeoutFunc = setTimeout;
1989            function noop() {
1990            }
1991            function bind(fn, thisArg) {
1992              return function () {
1993                fn.apply(thisArg, arguments);
1994              };
1995            }
1996            function Promise(fn) {
1997              if (typeof this !== 'object')
1998                throw new TypeError('Promises must be constructed via new');
1999              if (typeof fn !== 'function')
2000                throw new TypeError('not a function');
2001              this._state = 0;
2002              this._handled = false;
2003              this._value = undefined;
2004              this._deferreds = [];
2005              doResolve(fn, this);
2006            }
2007            function handle(self, deferred) {
2008              while (self._state === 3) {
2009                self = self._value;
2010              }
2011              if (self._state === 0) {
2012                self._deferreds.push(deferred);
2013                return;
2014              }
2015              self._handled = true;
2016              Promise._immediateFn(function () {
2017                var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
2018                if (cb === null) {
2019                  (self._state === 1 ? resolve : reject)(deferred.promise, self._value);
2020                  return;
2021                }
2022                var ret;
2023                try {
2024                  ret = cb(self._value);
2025                } catch (e) {
2026                  reject(deferred.promise, e);
2027                  return;
2028                }
2029                resolve(deferred.promise, ret);
2030              });
2031            }
2032            function resolve(self, newValue) {
2033              try {
2034                if (newValue === self)
2035                  throw new TypeError('A promise cannot be resolved with itself.');
2036                if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
2037                  var then = newValue.then;
2038                  if (newValue instanceof Promise) {
2039                    self._state = 3;
2040                    self._value = newValue;
2041                    finale(self);
2042                    return;
2043                  } else if (typeof then === 'function') {
2044                    doResolve(bind(then, newValue), self);
2045                    return;
2046                  }
2047                }
2048                self._state = 1;
2049                self._value = newValue;
2050                finale(self);
2051              } catch (e) {
2052                reject(self, e);
2053              }
2054            }
2055            function reject(self, newValue) {
2056              self._state = 2;
2057              self._value = newValue;
2058              finale(self);
2059            }
2060            function finale(self) {
2061              if (self._state === 2 && self._deferreds.length === 0) {
2062                Promise._immediateFn(function () {
2063                  if (!self._handled) {
2064                    Promise._unhandledRejectionFn(self._value);
2065                  }
2066                });
2067              }
2068              for (var i = 0, len = self._deferreds.length; i < len; i++) {
2069                handle(self, self._deferreds[i]);
2070              }
2071              self._deferreds = null;
2072            }
2073            function Handler(onFulfilled, onRejected, promise) {
2074              this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
2075              this.onRejected = typeof onRejected === 'function' ? onRejected : null;
2076              this.promise = promise;
2077            }
2078            function doResolve(fn, self) {
2079              var done = false;
2080              try {
2081                fn(function (value) {
2082                  if (done)
2083                    return;
2084                  done = true;
2085                  resolve(self, value);
2086                }, function (reason) {
2087                  if (done)
2088                    return;
2089                  done = true;
2090                  reject(self, reason);
2091                });
2092              } catch (ex) {
2093                if (done)
2094                  return;
2095                done = true;
2096                reject(self, ex);
2097              }
2098            }
2099            Promise.prototype['catch'] = function (onRejected) {
2100              return this.then(null, onRejected);
2101            };
2102            Promise.prototype.then = function (onFulfilled, onRejected) {
2103              var prom = new this.constructor(noop);
2104              handle(this, new Handler(onFulfilled, onRejected, prom));
2105              return prom;
2106            };
2107            Promise.all = function (arr) {
2108              var args = Array.prototype.slice.call(arr);
2109              return new Promise(function (resolve, reject) {
2110                if (args.length === 0)
2111                  return resolve([]);
2112                var remaining = args.length;
2113                function res(i, val) {
2114                  try {
2115                    if (val && (typeof val === 'object' || typeof val === 'function')) {
2116                      var then = val.then;
2117                      if (typeof then === 'function') {
2118                        then.call(val, function (val) {
2119                          res(i, val);
2120                        }, reject);
2121                        return;
2122                      }
2123                    }
2124                    args[i] = val;
2125                    if (--remaining === 0) {
2126                      resolve(args);
2127                    }
2128                  } catch (ex) {
2129                    reject(ex);
2130                  }
2131                }
2132                for (var i = 0; i < args.length; i++) {
2133                  res(i, args[i]);
2134                }
2135              });
2136            };
2137            Promise.resolve = function (value) {
2138              if (value && typeof value === 'object' && value.constructor === Promise) {
2139                return value;
2140              }
2141              return new Promise(function (resolve) {
2142                resolve(value);
2143              });
2144            };
2145            Promise.reject = function (value) {
2146              return new Promise(function (resolve, reject) {
2147                reject(value);
2148              });
2149            };
2150            Promise.race = function (values) {
2151              return new Promise(function (resolve, reject) {
2152                for (var i = 0, len = values.length; i < len; i++) {
2153                  values[i].then(resolve, reject);
2154                }
2155              });
2156            };
2157            Promise._immediateFn = typeof setImmediate === 'function' ? function (fn) {
2158              setImmediate(fn);
2159            } : function (fn) {
2160              setTimeoutFunc(fn, 0);
2161            };
2162            Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {
2163              if (typeof console !== 'undefined' && console) {
2164                console.warn('Possible Unhandled Promise Rejection:', err);
2165              }
2166            };
2167            Promise._setImmediateFn = function _setImmediateFn(fn) {
2168              Promise._immediateFn = fn;
2169            };
2170            Promise._setUnhandledRejectionFn = function _setUnhandledRejectionFn(fn) {
2171              Promise._unhandledRejectionFn = fn;
2172            };
2173            if (module.exports) {
2174              module.exports = Promise;
2175            } else if (!root.Promise) {
2176              root.Promise = Promise;
2177            }
2178          }(commonjsGlobal));
2179        }(promise));
2180        var promisePolyfill = promise.exports;
2181        var Global = function () {
2182          if (typeof window !== 'undefined') {
2183            return window;
2184          } else {
2185            return Function('return this;')();
2186          }
2187        }();
2188        var promisePolyfill_1 = { boltExport: Global.Promise || promisePolyfill };
2189        return promisePolyfill_1;
2190      }));
2191    }(undefined, exports$1, module$1));
2192    var Promise$1 = module$1.exports.boltExport;
2193
2194    var nu$1 = function (baseFn) {
2195      var data = Optional.none();
2196      var callbacks = [];
2197      var map = function (f) {
2198        return nu$1(function (nCallback) {
2199          get(function (data) {
2200            nCallback(f(data));
2201          });
2202        });
2203      };
2204      var get = function (nCallback) {
2205        if (isReady()) {
2206          call(nCallback);
2207        } else {
2208          callbacks.push(nCallback);
2209        }
2210      };
2211      var set = function (x) {
2212        if (!isReady()) {
2213          data = Optional.some(x);
2214          run(callbacks);
2215          callbacks = [];
2216        }
2217      };
2218      var isReady = function () {
2219        return data.isSome();
2220      };
2221      var run = function (cbs) {
2222        each$k(cbs, call);
2223      };
2224      var call = function (cb) {
2225        data.each(function (x) {
2226          setTimeout(function () {
2227            cb(x);
2228          }, 0);
2229        });
2230      };
2231      baseFn(set);
2232      return {
2233        get: get,
2234        map: map,
2235        isReady: isReady
2236      };
2237    };
2238    var pure$1 = function (a) {
2239      return nu$1(function (callback) {
2240        callback(a);
2241      });
2242    };
2243    var LazyValue = {
2244      nu: nu$1,
2245      pure: pure$1
2246    };
2247
2248    var errorReporter = function (err) {
2249      setTimeout(function () {
2250        throw err;
2251      }, 0);
2252    };
2253    var make = function (run) {
2254      var get = function (callback) {
2255        run().then(callback, errorReporter);
2256      };
2257      var map = function (fab) {
2258        return make(function () {
2259          return run().then(fab);
2260        });
2261      };
2262      var bind = function (aFutureB) {
2263        return make(function () {
2264          return run().then(function (v) {
2265            return aFutureB(v).toPromise();
2266          });
2267        });
2268      };
2269      var anonBind = function (futureB) {
2270        return make(function () {
2271          return run().then(function () {
2272            return futureB.toPromise();
2273          });
2274        });
2275      };
2276      var toLazy = function () {
2277        return LazyValue.nu(get);
2278      };
2279      var toCached = function () {
2280        var cache = null;
2281        return make(function () {
2282          if (cache === null) {
2283            cache = run();
2284          }
2285          return cache;
2286        });
2287      };
2288      var toPromise = run;
2289      return {
2290        map: map,
2291        bind: bind,
2292        anonBind: anonBind,
2293        toLazy: toLazy,
2294        toCached: toCached,
2295        toPromise: toPromise,
2296        get: get
2297      };
2298    };
2299    var nu = function (baseFn) {
2300      return make(function () {
2301        return new Promise$1(baseFn);
2302      });
2303    };
2304    var pure = function (a) {
2305      return make(function () {
2306        return Promise$1.resolve(a);
2307      });
2308    };
2309    var Future = {
2310      nu: nu,
2311      pure: pure
2312    };
2313
2314    var par$1 = function (asyncValues, nu) {
2315      return nu(function (callback) {
2316        var r = [];
2317        var count = 0;
2318        var cb = function (i) {
2319          return function (value) {
2320            r[i] = value;
2321            count++;
2322            if (count >= asyncValues.length) {
2323              callback(r);
2324            }
2325          };
2326        };
2327        if (asyncValues.length === 0) {
2328          callback([]);
2329        } else {
2330          each$k(asyncValues, function (asyncValue, i) {
2331            asyncValue.get(cb(i));
2332          });
2333        }
2334      });
2335    };
2336
2337    var par = function (futures) {
2338      return par$1(futures, Future.nu);
2339    };
2340
2341    var value$1 = function (o) {
2342      var or = function (_opt) {
2343        return value$1(o);
2344      };
2345      var orThunk = function (_f) {
2346        return value$1(o);
2347      };
2348      var map = function (f) {
2349        return value$1(f(o));
2350      };
2351      var mapError = function (_f) {
2352        return value$1(o);
2353      };
2354      var each = function (f) {
2355        f(o);
2356      };
2357      var bind = function (f) {
2358        return f(o);
2359      };
2360      var fold = function (_, onValue) {
2361        return onValue(o);
2362      };
2363      var exists = function (f) {
2364        return f(o);
2365      };
2366      var forall = function (f) {
2367        return f(o);
2368      };
2369      var toOptional = function () {
2370        return Optional.some(o);
2371      };
2372      return {
2373        isValue: always,
2374        isError: never,
2375        getOr: constant(o),
2376        getOrThunk: constant(o),
2377        getOrDie: constant(o),
2378        or: or,
2379        orThunk: orThunk,
2380        fold: fold,
2381        map: map,
2382        mapError: mapError,
2383        each: each,
2384        bind: bind,
2385        exists: exists,
2386        forall: forall,
2387        toOptional: toOptional
2388      };
2389    };
2390    var error = function (message) {
2391      var getOrThunk = function (f) {
2392        return f();
2393      };
2394      var getOrDie = function () {
2395        return die(String(message))();
2396      };
2397      var or = identity;
2398      var orThunk = function (f) {
2399        return f();
2400      };
2401      var map = function (_f) {
2402        return error(message);
2403      };
2404      var mapError = function (f) {
2405        return error(f(message));
2406      };
2407      var bind = function (_f) {
2408        return error(message);
2409      };
2410      var fold = function (onError, _) {
2411        return onError(message);
2412      };
2413      return {
2414        isValue: never,
2415        isError: always,
2416        getOr: identity,
2417        getOrThunk: getOrThunk,
2418        getOrDie: getOrDie,
2419        or: or,
2420        orThunk: orThunk,
2421        fold: fold,
2422        map: map,
2423        mapError: mapError,
2424        each: noop,
2425        bind: bind,
2426        exists: never,
2427        forall: always,
2428        toOptional: Optional.none
2429      };
2430    };
2431    var fromOption = function (opt, err) {
2432      return opt.fold(function () {
2433        return error(err);
2434      }, value$1);
2435    };
2436    var Result = {
2437      value: value$1,
2438      error: error,
2439      fromOption: fromOption
2440    };
2441
2442    var generate$1 = function (cases) {
2443      if (!isArray$1(cases)) {
2444        throw new Error('cases must be an array');
2445      }
2446      if (cases.length === 0) {
2447        throw new Error('there must be at least one case');
2448      }
2449      var constructors = [];
2450      var adt = {};
2451      each$k(cases, function (acase, count) {
2452        var keys$1 = keys(acase);
2453        if (keys$1.length !== 1) {
2454          throw new Error('one and only one name per case');
2455        }
2456        var key = keys$1[0];
2457        var value = acase[key];
2458        if (adt[key] !== undefined) {
2459          throw new Error('duplicate key detected:' + key);
2460        } else if (key === 'cata') {
2461          throw new Error('cannot have a case named cata (sorry)');
2462        } else if (!isArray$1(value)) {
2463          throw new Error('case arguments must be an array');
2464        }
2465        constructors.push(key);
2466        adt[key] = function () {
2467          var args = [];
2468          for (var _i = 0; _i < arguments.length; _i++) {
2469            args[_i] = arguments[_i];
2470          }
2471          var argLength = args.length;
2472          if (argLength !== value.length) {
2473            throw new Error('Wrong number of arguments to case ' + key + '. Expected ' + value.length + ' (' + value + '), got ' + argLength);
2474          }
2475          var match = function (branches) {
2476            var branchKeys = keys(branches);
2477            if (constructors.length !== branchKeys.length) {
2478              throw new Error('Wrong number of arguments to match. Expected: ' + constructors.join(',') + '\nActual: ' + branchKeys.join(','));
2479            }
2480            var allReqd = forall(constructors, function (reqKey) {
2481              return contains$3(branchKeys, reqKey);
2482            });
2483            if (!allReqd) {
2484              throw new Error('Not all branches were specified when using match. Specified: ' + branchKeys.join(', ') + '\nRequired: ' + constructors.join(', '));
2485            }
2486            return branches[key].apply(null, args);
2487          };
2488          return {
2489            fold: function () {
2490              var foldArgs = [];
2491              for (var _i = 0; _i < arguments.length; _i++) {
2492                foldArgs[_i] = arguments[_i];
2493              }
2494              if (foldArgs.length !== cases.length) {
2495                throw new Error('Wrong number of arguments to fold. Expected ' + cases.length + ', got ' + foldArgs.length);
2496              }
2497              var target = foldArgs[count];
2498              return target.apply(null, args);
2499            },
2500            match: match,
2501            log: function (label) {
2502              console.log(label, {
2503                constructors: constructors,
2504                constructor: key,
2505                params: args
2506              });
2507            }
2508          };
2509        };
2510      });
2511      return adt;
2512    };
2513    var Adt = { generate: generate$1 };
2514
2515    Adt.generate([
2516      {
2517        bothErrors: [
2518          'error1',
2519          'error2'
2520        ]
2521      },
2522      {
2523        firstError: [
2524          'error1',
2525          'value2'
2526        ]
2527      },
2528      {
2529        secondError: [
2530          'value1',
2531          'error2'
2532        ]
2533      },
2534      {
2535        bothValues: [
2536          'value1',
2537          'value2'
2538        ]
2539      }
2540    ]);
2541    var unite = function (result) {
2542      return result.fold(identity, identity);
2543    };
2544
2545    function ClosestOrAncestor (is, ancestor, scope, a, isRoot) {
2546      if (is(scope, a)) {
2547        return Optional.some(scope);
2548      } else if (isFunction(isRoot) && isRoot(scope)) {
2549        return Optional.none();
2550      } else {
2551        return ancestor(scope, a, isRoot);
2552      }
2553    }
2554
2555    var ancestor$3 = function (scope, predicate, isRoot) {
2556      var element = scope.dom;
2557      var stop = isFunction(isRoot) ? isRoot : never;
2558      while (element.parentNode) {
2559        element = element.parentNode;
2560        var el = SugarElement.fromDom(element);
2561        if (predicate(el)) {
2562          return Optional.some(el);
2563        } else if (stop(el)) {
2564          break;
2565        }
2566      }
2567      return Optional.none();
2568    };
2569    var closest$3 = function (scope, predicate, isRoot) {
2570      var is = function (s, test) {
2571        return test(s);
2572      };
2573      return ClosestOrAncestor(is, ancestor$3, scope, predicate, isRoot);
2574    };
2575    var sibling$2 = function (scope, predicate) {
2576      var element = scope.dom;
2577      if (!element.parentNode) {
2578        return Optional.none();
2579      }
2580      return child(SugarElement.fromDom(element.parentNode), function (x) {
2581        return !eq(scope, x) && predicate(x);
2582      });
2583    };
2584    var child = function (scope, predicate) {
2585      var pred = function (node) {
2586        return predicate(SugarElement.fromDom(node));
2587      };
2588      var result = find$3(scope.dom.childNodes, pred);
2589      return result.map(SugarElement.fromDom);
2590    };
2591
2592    var ancestor$2 = function (scope, selector, isRoot) {
2593      return ancestor$3(scope, function (e) {
2594        return is$2(e, selector);
2595      }, isRoot);
2596    };
2597    var descendant = function (scope, selector) {
2598      return one(selector, scope);
2599    };
2600    var closest$2 = function (scope, selector, isRoot) {
2601      var is = function (element, selector) {
2602        return is$2(element, selector);
2603      };
2604      return ClosestOrAncestor(is, ancestor$2, scope, selector, isRoot);
2605    };
2606
2607    var promiseObj = window.Promise ? window.Promise : Promise$1;
2608
2609    var requestAnimationFramePromise;
2610    var requestAnimationFrame = function (callback, element) {
2611      var requestAnimationFrameFunc = window.requestAnimationFrame;
2612      var vendors = [
2613        'ms',
2614        'moz',
2615        'webkit'
2616      ];
2617      var featurefill = function (cb) {
2618        window.setTimeout(cb, 0);
2619      };
2620      for (var i = 0; i < vendors.length && !requestAnimationFrameFunc; i++) {
2621        requestAnimationFrameFunc = window[vendors[i] + 'RequestAnimationFrame'];
2622      }
2623      if (!requestAnimationFrameFunc) {
2624        requestAnimationFrameFunc = featurefill;
2625      }
2626      requestAnimationFrameFunc(callback, element);
2627    };
2628    var wrappedSetTimeout = function (callback, time) {
2629      if (typeof time !== 'number') {
2630        time = 0;
2631      }
2632      return setTimeout(callback, time);
2633    };
2634    var wrappedSetInterval = function (callback, time) {
2635      if (typeof time !== 'number') {
2636        time = 1;
2637      }
2638      return setInterval(callback, time);
2639    };
2640    var wrappedClearTimeout = function (id) {
2641      return clearTimeout(id);
2642    };
2643    var wrappedClearInterval = function (id) {
2644      return clearInterval(id);
2645    };
2646    var debounce = function (callback, time) {
2647      var timer;
2648      var func = function () {
2649        var args = [];
2650        for (var _i = 0; _i < arguments.length; _i++) {
2651          args[_i] = arguments[_i];
2652        }
2653        clearTimeout(timer);
2654        timer = wrappedSetTimeout(function () {
2655          callback.apply(this, args);
2656        }, time);
2657      };
2658      func.stop = function () {
2659        clearTimeout(timer);
2660      };
2661      return func;
2662    };
2663    var Delay = {
2664      requestAnimationFrame: function (callback, element) {
2665        if (requestAnimationFramePromise) {
2666          requestAnimationFramePromise.then(callback);
2667          return;
2668        }
2669        requestAnimationFramePromise = new promiseObj(function (resolve) {
2670          if (!element) {
2671            element = document.body;
2672          }
2673          requestAnimationFrame(resolve, element);
2674        }).then(callback);
2675      },
2676      setTimeout: wrappedSetTimeout,
2677      setInterval: wrappedSetInterval,
2678      setEditorTimeout: function (editor, callback, time) {
2679        return wrappedSetTimeout(function () {
2680          if (!editor.removed) {
2681            callback();
2682          }
2683        }, time);
2684      },
2685      setEditorInterval: function (editor, callback, time) {
2686        var timer = wrappedSetInterval(function () {
2687          if (!editor.removed) {
2688            callback();
2689          } else {
2690            clearInterval(timer);
2691          }
2692        }, time);
2693        return timer;
2694      },
2695      debounce: debounce,
2696      throttle: debounce,
2697      clearInterval: wrappedClearInterval,
2698      clearTimeout: wrappedClearTimeout
2699    };
2700
2701    var StyleSheetLoader = function (documentOrShadowRoot, settings) {
2702      if (settings === void 0) {
2703        settings = {};
2704      }
2705      var idCount = 0;
2706      var loadedStates = {};
2707      var edos = SugarElement.fromDom(documentOrShadowRoot);
2708      var doc = documentOrOwner(edos);
2709      var maxLoadTime = settings.maxLoadTime || 5000;
2710      var _setReferrerPolicy = function (referrerPolicy) {
2711        settings.referrerPolicy = referrerPolicy;
2712      };
2713      var addStyle = function (element) {
2714        append$1(getStyleContainer(edos), element);
2715      };
2716      var removeStyle = function (id) {
2717        var styleContainer = getStyleContainer(edos);
2718        descendant(styleContainer, '#' + id).each(remove$7);
2719      };
2720      var getOrCreateState = function (url) {
2721        return get$9(loadedStates, url).getOrThunk(function () {
2722          return {
2723            id: 'mce-u' + idCount++,
2724            passed: [],
2725            failed: [],
2726            count: 0
2727          };
2728        });
2729      };
2730      var load = function (url, success, failure) {
2731        var link;
2732        var urlWithSuffix = Tools._addCacheSuffix(url);
2733        var state = getOrCreateState(urlWithSuffix);
2734        loadedStates[urlWithSuffix] = state;
2735        state.count++;
2736        var resolve = function (callbacks, status) {
2737          var i = callbacks.length;
2738          while (i--) {
2739            callbacks[i]();
2740          }
2741          state.status = status;
2742          state.passed = [];
2743          state.failed = [];
2744          if (link) {
2745            link.onload = null;
2746            link.onerror = null;
2747            link = null;
2748          }
2749        };
2750        var passed = function () {
2751          return resolve(state.passed, 2);
2752        };
2753        var failed = function () {
2754          return resolve(state.failed, 3);
2755        };
2756        var wait = function (testCallback, waitCallback) {
2757          if (!testCallback()) {
2758            if (Date.now() - startTime < maxLoadTime) {
2759              Delay.setTimeout(waitCallback);
2760            } else {
2761              failed();
2762            }
2763          }
2764        };
2765        var waitForWebKitLinkLoaded = function () {
2766          wait(function () {
2767            var styleSheets = documentOrShadowRoot.styleSheets;
2768            var i = styleSheets.length;
2769            while (i--) {
2770              var styleSheet = styleSheets[i];
2771              var owner = styleSheet.ownerNode;
2772              if (owner && owner.id === link.id) {
2773                passed();
2774                return true;
2775              }
2776            }
2777            return false;
2778          }, waitForWebKitLinkLoaded);
2779        };
2780        if (success) {
2781          state.passed.push(success);
2782        }
2783        if (failure) {
2784          state.failed.push(failure);
2785        }
2786        if (state.status === 1) {
2787          return;
2788        }
2789        if (state.status === 2) {
2790          passed();
2791          return;
2792        }
2793        if (state.status === 3) {
2794          failed();
2795          return;
2796        }
2797        state.status = 1;
2798        var linkElem = SugarElement.fromTag('link', doc.dom);
2799        setAll$1(linkElem, {
2800          rel: 'stylesheet',
2801          type: 'text/css',
2802          id: state.id
2803        });
2804        var startTime = Date.now();
2805        if (settings.contentCssCors) {
2806          set$1(linkElem, 'crossOrigin', 'anonymous');
2807        }
2808        if (settings.referrerPolicy) {
2809          set$1(linkElem, 'referrerpolicy', settings.referrerPolicy);
2810        }
2811        link = linkElem.dom;
2812        link.onload = waitForWebKitLinkLoaded;
2813        link.onerror = failed;
2814        addStyle(linkElem);
2815        set$1(linkElem, 'href', urlWithSuffix);
2816      };
2817      var loadF = function (url) {
2818        return Future.nu(function (resolve) {
2819          load(url, compose(resolve, constant(Result.value(url))), compose(resolve, constant(Result.error(url))));
2820        });
2821      };
2822      var loadAll = function (urls, success, failure) {
2823        par(map$3(urls, loadF)).get(function (result) {
2824          var parts = partition(result, function (r) {
2825            return r.isValue();
2826          });
2827          if (parts.fail.length > 0) {
2828            failure(parts.fail.map(unite));
2829          } else {
2830            success(parts.pass.map(unite));
2831          }
2832        });
2833      };
2834      var unload = function (url) {
2835        var urlWithSuffix = Tools._addCacheSuffix(url);
2836        get$9(loadedStates, urlWithSuffix).each(function (state) {
2837          var count = --state.count;
2838          if (count === 0) {
2839            delete loadedStates[urlWithSuffix];
2840            removeStyle(state.id);
2841          }
2842        });
2843      };
2844      var unloadAll = function (urls) {
2845        each$k(urls, function (url) {
2846          unload(url);
2847        });
2848      };
2849      return {
2850        load: load,
2851        loadAll: loadAll,
2852        unload: unload,
2853        unloadAll: unloadAll,
2854        _setReferrerPolicy: _setReferrerPolicy
2855      };
2856    };
2857
2858    var create$8 = function () {
2859      var map = new WeakMap();
2860      var forElement = function (referenceElement, settings) {
2861        var root = getRootNode(referenceElement);
2862        var rootDom = root.dom;
2863        return Optional.from(map.get(rootDom)).getOrThunk(function () {
2864          var sl = StyleSheetLoader(rootDom, settings);
2865          map.set(rootDom, sl);
2866          return sl;
2867        });
2868      };
2869      return { forElement: forElement };
2870    };
2871    var instance = create$8();
2872
2873    var DomTreeWalker = function () {
2874      function DomTreeWalker(startNode, rootNode) {
2875        this.node = startNode;
2876        this.rootNode = rootNode;
2877        this.current = this.current.bind(this);
2878        this.next = this.next.bind(this);
2879        this.prev = this.prev.bind(this);
2880        this.prev2 = this.prev2.bind(this);
2881      }
2882      DomTreeWalker.prototype.current = function () {
2883        return this.node;
2884      };
2885      DomTreeWalker.prototype.next = function (shallow) {
2886        this.node = this.findSibling(this.node, 'firstChild', 'nextSibling', shallow);
2887        return this.node;
2888      };
2889      DomTreeWalker.prototype.prev = function (shallow) {
2890        this.node = this.findSibling(this.node, 'lastChild', 'previousSibling', shallow);
2891        return this.node;
2892      };
2893      DomTreeWalker.prototype.prev2 = function (shallow) {
2894        this.node = this.findPreviousNode(this.node, 'lastChild', 'previousSibling', shallow);
2895        return this.node;
2896      };
2897      DomTreeWalker.prototype.findSibling = function (node, startName, siblingName, shallow) {
2898        var sibling, parent;
2899        if (node) {
2900          if (!shallow && node[startName]) {
2901            return node[startName];
2902          }
2903          if (node !== this.rootNode) {
2904            sibling = node[siblingName];
2905            if (sibling) {
2906              return sibling;
2907            }
2908            for (parent = node.parentNode; parent && parent !== this.rootNode; parent = parent.parentNode) {
2909              sibling = parent[siblingName];
2910              if (sibling) {
2911                return sibling;
2912              }
2913            }
2914          }
2915        }
2916      };
2917      DomTreeWalker.prototype.findPreviousNode = function (node, startName, siblingName, shallow) {
2918        var sibling, parent, child;
2919        if (node) {
2920          sibling = node[siblingName];
2921          if (this.rootNode && sibling === this.rootNode) {
2922            return;
2923          }
2924          if (sibling) {
2925            if (!shallow) {
2926              for (child = sibling[startName]; child; child = child[startName]) {
2927                if (!child[startName]) {
2928                  return child;
2929                }
2930              }
2931            }
2932            return sibling;
2933          }
2934          parent = node.parentNode;
2935          if (parent && parent !== this.rootNode) {
2936            return parent;
2937          }
2938        }
2939      };
2940      return DomTreeWalker;
2941    }();
2942
2943    var blocks = [
2944      'article',
2945      'aside',
2946      'details',
2947      'div',
2948      'dt',
2949      'figcaption',
2950      'footer',
2951      'form',
2952      'fieldset',
2953      'header',
2954      'hgroup',
2955      'html',
2956      'main',
2957      'nav',
2958      'section',
2959      'summary',
2960      'body',
2961      'p',
2962      'dl',
2963      'multicol',
2964      'dd',
2965      'figure',
2966      'address',
2967      'center',
2968      'blockquote',
2969      'h1',
2970      'h2',
2971      'h3',
2972      'h4',
2973      'h5',
2974      'h6',
2975      'listing',
2976      'xmp',
2977      'pre',
2978      'plaintext',
2979      'menu',
2980      'dir',
2981      'ul',
2982      'ol',
2983      'li',
2984      'hr',
2985      'table',
2986      'tbody',
2987      'thead',
2988      'tfoot',
2989      'th',
2990      'tr',
2991      'td',
2992      'caption'
2993    ];
2994    var tableCells = [
2995      'td',
2996      'th'
2997    ];
2998    var tableSections = [
2999      'thead',
3000      'tbody',
3001      'tfoot'
3002    ];
3003    var textBlocks = [
3004      'h1',
3005      'h2',
3006      'h3',
3007      'h4',
3008      'h5',
3009      'h6',
3010      'p',
3011      'div',
3012      'address',
3013      'pre',
3014      'form',
3015      'blockquote',
3016      'center',
3017      'dir',
3018      'fieldset',
3019      'header',
3020      'footer',
3021      'article',
3022      'section',
3023      'hgroup',
3024      'aside',
3025      'nav',
3026      'figure'
3027    ];
3028    var headings = [
3029      'h1',
3030      'h2',
3031      'h3',
3032      'h4',
3033      'h5',
3034      'h6'
3035    ];
3036    var listItems$1 = [
3037      'li',
3038      'dd',
3039      'dt'
3040    ];
3041    var lists = [
3042      'ul',
3043      'ol',
3044      'dl'
3045    ];
3046    var wsElements = [
3047      'pre',
3048      'script',
3049      'textarea',
3050      'style'
3051    ];
3052    var lazyLookup = function (items) {
3053      var lookup;
3054      return function (node) {
3055        lookup = lookup ? lookup : mapToObject(items, always);
3056        return has$2(lookup, name(node));
3057      };
3058    };
3059    var isHeading = lazyLookup(headings);
3060    var isBlock$2 = lazyLookup(blocks);
3061    var isTable$2 = function (node) {
3062      return name(node) === 'table';
3063    };
3064    var isInline$1 = function (node) {
3065      return isElement$6(node) && !isBlock$2(node);
3066    };
3067    var isBr$4 = function (node) {
3068      return isElement$6(node) && name(node) === 'br';
3069    };
3070    var isTextBlock$2 = lazyLookup(textBlocks);
3071    var isList = lazyLookup(lists);
3072    var isListItem = lazyLookup(listItems$1);
3073    var isTableSection = lazyLookup(tableSections);
3074    var isTableCell$4 = lazyLookup(tableCells);
3075    var isWsPreserveElement = lazyLookup(wsElements);
3076
3077    var ancestor$1 = function (scope, selector, isRoot) {
3078      return ancestor$2(scope, selector, isRoot).isSome();
3079    };
3080
3081    var zeroWidth = '\uFEFF';
3082    var nbsp = '\xA0';
3083    var isZwsp$1 = function (char) {
3084      return char === zeroWidth;
3085    };
3086    var removeZwsp = function (s) {
3087      return s.replace(/\uFEFF/g, '');
3088    };
3089
3090    var ZWSP$1 = zeroWidth;
3091    var isZwsp = isZwsp$1;
3092    var trim$3 = removeZwsp;
3093
3094    var isElement$4 = isElement$5;
3095    var isText$6 = isText$7;
3096    var isCaretContainerBlock$1 = function (node) {
3097      if (isText$6(node)) {
3098        node = node.parentNode;
3099      }
3100      return isElement$4(node) && node.hasAttribute('data-mce-caret');
3101    };
3102    var isCaretContainerInline = function (node) {
3103      return isText$6(node) && isZwsp(node.data);
3104    };
3105    var isCaretContainer$2 = function (node) {
3106      return isCaretContainerBlock$1(node) || isCaretContainerInline(node);
3107    };
3108    var hasContent = function (node) {
3109      return node.firstChild !== node.lastChild || !isBr$5(node.firstChild);
3110    };
3111    var insertInline$1 = function (node, before) {
3112      var doc = node.ownerDocument;
3113      var textNode = doc.createTextNode(ZWSP$1);
3114      var parentNode = node.parentNode;
3115      if (!before) {
3116        var sibling = node.nextSibling;
3117        if (isText$6(sibling)) {
3118          if (isCaretContainer$2(sibling)) {
3119            return sibling;
3120          }
3121          if (startsWithCaretContainer$1(sibling)) {
3122            sibling.splitText(1);
3123            return sibling;
3124          }
3125        }
3126        if (node.nextSibling) {
3127          parentNode.insertBefore(textNode, node.nextSibling);
3128        } else {
3129          parentNode.appendChild(textNode);
3130        }
3131      } else {
3132        var sibling = node.previousSibling;
3133        if (isText$6(sibling)) {
3134          if (isCaretContainer$2(sibling)) {
3135            return sibling;
3136          }
3137          if (endsWithCaretContainer$1(sibling)) {
3138            return sibling.splitText(sibling.data.length - 1);
3139          }
3140        }
3141        parentNode.insertBefore(textNode, node);
3142      }
3143      return textNode;
3144    };
3145    var isBeforeInline = function (pos) {
3146      var container = pos.container();
3147      if (!isText$7(container)) {
3148        return false;
3149      }
3150      return container.data.charAt(pos.offset()) === ZWSP$1 || pos.isAtStart() && isCaretContainerInline(container.previousSibling);
3151    };
3152    var isAfterInline = function (pos) {
3153      var container = pos.container();
3154      if (!isText$7(container)) {
3155        return false;
3156      }
3157      return container.data.charAt(pos.offset() - 1) === ZWSP$1 || pos.isAtEnd() && isCaretContainerInline(container.nextSibling);
3158    };
3159    var createBogusBr = function () {
3160      var br = document.createElement('br');
3161      br.setAttribute('data-mce-bogus', '1');
3162      return br;
3163    };
3164    var insertBlock$1 = function (blockName, node, before) {
3165      var doc = node.ownerDocument;
3166      var blockNode = doc.createElement(blockName);
3167      blockNode.setAttribute('data-mce-caret', before ? 'before' : 'after');
3168      blockNode.setAttribute('data-mce-bogus', 'all');
3169      blockNode.appendChild(createBogusBr());
3170      var parentNode = node.parentNode;
3171      if (!before) {
3172        if (node.nextSibling) {
3173          parentNode.insertBefore(blockNode, node.nextSibling);
3174        } else {
3175          parentNode.appendChild(blockNode);
3176        }
3177      } else {
3178        parentNode.insertBefore(blockNode, node);
3179      }
3180      return blockNode;
3181    };
3182    var startsWithCaretContainer$1 = function (node) {
3183      return isText$6(node) && node.data[0] === ZWSP$1;
3184    };
3185    var endsWithCaretContainer$1 = function (node) {
3186      return isText$6(node) && node.data[node.data.length - 1] === ZWSP$1;
3187    };
3188    var trimBogusBr = function (elm) {
3189      var brs = elm.getElementsByTagName('br');
3190      var lastBr = brs[brs.length - 1];
3191      if (isBogus$2(lastBr)) {
3192        lastBr.parentNode.removeChild(lastBr);
3193      }
3194    };
3195    var showCaretContainerBlock = function (caretContainer) {
3196      if (caretContainer && caretContainer.hasAttribute('data-mce-caret')) {
3197        trimBogusBr(caretContainer);
3198        caretContainer.removeAttribute('data-mce-caret');
3199        caretContainer.removeAttribute('data-mce-bogus');
3200        caretContainer.removeAttribute('style');
3201        caretContainer.removeAttribute('_moz_abspos');
3202        return caretContainer;
3203      }
3204      return null;
3205    };
3206    var isRangeInCaretContainerBlock = function (range) {
3207      return isCaretContainerBlock$1(range.startContainer);
3208    };
3209
3210    var isContentEditableTrue$3 = isContentEditableTrue$4;
3211    var isContentEditableFalse$a = isContentEditableFalse$b;
3212    var isBr$3 = isBr$5;
3213    var isText$5 = isText$7;
3214    var isInvalidTextElement = matchNodeNames([
3215      'script',
3216      'style',
3217      'textarea'
3218    ]);
3219    var isAtomicInline = matchNodeNames([
3220      'img',
3221      'input',
3222      'textarea',
3223      'hr',
3224      'iframe',
3225      'video',
3226      'audio',
3227      'object',
3228      'embed'
3229    ]);
3230    var isTable$1 = matchNodeNames(['table']);
3231    var isCaretContainer$1 = isCaretContainer$2;
3232    var isCaretCandidate$3 = function (node) {
3233      if (isCaretContainer$1(node)) {
3234        return false;
3235      }
3236      if (isText$5(node)) {
3237        return !isInvalidTextElement(node.parentNode);
3238      }
3239      return isAtomicInline(node) || isBr$3(node) || isTable$1(node) || isNonUiContentEditableFalse(node);
3240    };
3241    var isUnselectable = function (node) {
3242      return isElement$5(node) && node.getAttribute('unselectable') === 'true';
3243    };
3244    var isNonUiContentEditableFalse = function (node) {
3245      return isUnselectable(node) === false && isContentEditableFalse$a(node);
3246    };
3247    var isInEditable = function (node, root) {
3248      for (node = node.parentNode; node && node !== root; node = node.parentNode) {
3249        if (isNonUiContentEditableFalse(node)) {
3250          return false;
3251        }
3252        if (isContentEditableTrue$3(node)) {
3253          return true;
3254        }
3255      }
3256      return true;
3257    };
3258    var isAtomicContentEditableFalse = function (node) {
3259      if (!isNonUiContentEditableFalse(node)) {
3260        return false;
3261      }
3262      return foldl(from(node.getElementsByTagName('*')), function (result, elm) {
3263        return result || isContentEditableTrue$3(elm);
3264      }, false) !== true;
3265    };
3266    var isAtomic$1 = function (node) {
3267      return isAtomicInline(node) || isAtomicContentEditableFalse(node);
3268    };
3269    var isEditableCaretCandidate$1 = function (node, root) {
3270      return isCaretCandidate$3(node) && isInEditable(node, root);
3271    };
3272
3273    var whiteSpaceRegExp$1 = /^[ \t\r\n]*$/;
3274    var isWhitespaceText = function (text) {
3275      return whiteSpaceRegExp$1.test(text);
3276    };
3277
3278    var hasWhitespacePreserveParent = function (node, rootNode) {
3279      var rootElement = SugarElement.fromDom(rootNode);
3280      var startNode = SugarElement.fromDom(node);
3281      return ancestor$1(startNode, 'pre,code', curry(eq, rootElement));
3282    };
3283    var isWhitespace = function (node, rootNode) {
3284      return isText$7(node) && isWhitespaceText(node.data) && hasWhitespacePreserveParent(node, rootNode) === false;
3285    };
3286    var isNamedAnchor = function (node) {
3287      return isElement$5(node) && node.nodeName === 'A' && !node.hasAttribute('href') && (node.hasAttribute('name') || node.hasAttribute('id'));
3288    };
3289    var isContent$1 = function (node, rootNode) {
3290      return isCaretCandidate$3(node) && isWhitespace(node, rootNode) === false || isNamedAnchor(node) || isBookmark(node);
3291    };
3292    var isBookmark = hasAttribute('data-mce-bookmark');
3293    var isBogus$1 = hasAttribute('data-mce-bogus');
3294    var isBogusAll = hasAttributeValue('data-mce-bogus', 'all');
3295    var isEmptyNode = function (targetNode, skipBogus) {
3296      var brCount = 0;
3297      if (isContent$1(targetNode, targetNode)) {
3298        return false;
3299      } else {
3300        var node = targetNode.firstChild;
3301        if (!node) {
3302          return true;
3303        }
3304        var walker = new DomTreeWalker(node, targetNode);
3305        do {
3306          if (skipBogus) {
3307            if (isBogusAll(node)) {
3308              node = walker.next(true);
3309              continue;
3310            }
3311            if (isBogus$1(node)) {
3312              node = walker.next();
3313              continue;
3314            }
3315          }
3316          if (isBr$5(node)) {
3317            brCount++;
3318            node = walker.next();
3319            continue;
3320          }
3321          if (isContent$1(node, targetNode)) {
3322            return false;
3323          }
3324          node = walker.next();
3325        } while (node);
3326        return brCount <= 1;
3327      }
3328    };
3329    var isEmpty$2 = function (elm, skipBogus) {
3330      if (skipBogus === void 0) {
3331        skipBogus = true;
3332      }
3333      return isEmptyNode(elm.dom, skipBogus);
3334    };
3335
3336    var isSpan = function (node) {
3337      return node.nodeName.toLowerCase() === 'span';
3338    };
3339    var isInlineContent = function (node, root) {
3340      return isNonNullable(node) && (isContent$1(node, root) || isInline$1(SugarElement.fromDom(node)));
3341    };
3342    var surroundedByInlineContent = function (node, root) {
3343      var prev = new DomTreeWalker(node, root).prev(false);
3344      var next = new DomTreeWalker(node, root).next(false);
3345      var prevIsInline = isUndefined(prev) || isInlineContent(prev, root);
3346      var nextIsInline = isUndefined(next) || isInlineContent(next, root);
3347      return prevIsInline && nextIsInline;
3348    };
3349    var isBookmarkNode$2 = function (node) {
3350      return isSpan(node) && node.getAttribute('data-mce-type') === 'bookmark';
3351    };
3352    var isKeepTextNode = function (node, root) {
3353      return isText$7(node) && node.data.length > 0 && surroundedByInlineContent(node, root);
3354    };
3355    var isKeepElement = function (node) {
3356      return isElement$5(node) ? node.childNodes.length > 0 : false;
3357    };
3358    var isDocument = function (node) {
3359      return isDocumentFragment(node) || isDocument$1(node);
3360    };
3361    var trimNode = function (dom, node, root) {
3362      var rootNode = root || node;
3363      if (isElement$5(node) && isBookmarkNode$2(node)) {
3364        return node;
3365      }
3366      var children = node.childNodes;
3367      for (var i = children.length - 1; i >= 0; i--) {
3368        trimNode(dom, children[i], rootNode);
3369      }
3370      if (isElement$5(node)) {
3371        var currentChildren = node.childNodes;
3372        if (currentChildren.length === 1 && isBookmarkNode$2(currentChildren[0])) {
3373          node.parentNode.insertBefore(currentChildren[0], node);
3374        }
3375      }
3376      if (!isDocument(node) && !isContent$1(node, rootNode) && !isKeepElement(node) && !isKeepTextNode(node, rootNode)) {
3377        dom.remove(node);
3378      }
3379      return node;
3380    };
3381
3382    var makeMap$3 = Tools.makeMap;
3383    var attrsCharsRegExp = /[&<>\"\u0060\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
3384    var textCharsRegExp = /[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
3385    var rawCharsRegExp = /[<>&\"\']/g;
3386    var entityRegExp = /&#([a-z0-9]+);?|&([a-z0-9]+);/gi;
3387    var asciiMap = {
3388      128: '\u20AC',
3389      130: '\u201A',
3390      131: '\u0192',
3391      132: '\u201E',
3392      133: '\u2026',
3393      134: '\u2020',
3394      135: '\u2021',
3395      136: '\u02c6',
3396      137: '\u2030',
3397      138: '\u0160',
3398      139: '\u2039',
3399      140: '\u0152',
3400      142: '\u017d',
3401      145: '\u2018',
3402      146: '\u2019',
3403      147: '\u201C',
3404      148: '\u201D',
3405      149: '\u2022',
3406      150: '\u2013',
3407      151: '\u2014',
3408      152: '\u02DC',
3409      153: '\u2122',
3410      154: '\u0161',
3411      155: '\u203A',
3412      156: '\u0153',
3413      158: '\u017e',
3414      159: '\u0178'
3415    };
3416    var baseEntities = {
3417      '"': '&quot;',
3418      '\'': '&#39;',
3419      '<': '&lt;',
3420      '>': '&gt;',
3421      '&': '&amp;',
3422      '`': '&#96;'
3423    };
3424    var reverseEntities = {
3425      '&lt;': '<',
3426      '&gt;': '>',
3427      '&amp;': '&',
3428      '&quot;': '"',
3429      '&apos;': '\''
3430    };
3431    var nativeDecode = function (text) {
3432      var elm = SugarElement.fromTag('div').dom;
3433      elm.innerHTML = text;
3434      return elm.textContent || elm.innerText || text;
3435    };
3436    var buildEntitiesLookup = function (items, radix) {
3437      var i, chr, entity;
3438      var lookup = {};
3439      if (items) {
3440        items = items.split(',');
3441        radix = radix || 10;
3442        for (i = 0; i < items.length; i += 2) {
3443          chr = String.fromCharCode(parseInt(items[i], radix));
3444          if (!baseEntities[chr]) {
3445            entity = '&' + items[i + 1] + ';';
3446            lookup[chr] = entity;
3447            lookup[entity] = chr;
3448          }
3449        }
3450        return lookup;
3451      }
3452    };
3453    var 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,8
3453k4,' + '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);
3454    var encodeRaw = function (text, attr) {
3455      return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {
3456        return baseEntities[chr] || chr;
3457      });
3458    };
3459    var encodeAllRaw = function (text) {
3460      return ('' + text).replace(rawCharsRegExp, function (chr) {
3461        return baseEntities[chr] || chr;
3462      });
3463    };
3464    var encodeNumeric = function (text, attr) {
3465      return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {
3466        if (chr.length > 1) {
3467          return '&#' + ((chr.charCodeAt(0) - 55296) * 1024 + (chr.charCodeAt(1) - 56320) + 65536) + ';';
3468        }
3469        return baseEntities[chr] || '&#' + chr.charCodeAt(0) + ';';
3470      });
3471    };
3472    var encodeNamed = function (text, attr, entities) {
3473      entities = entities || namedEntities;
3474      return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {
3475        return baseEntities[chr] || entities[chr] || chr;
3476      });
3477    };
3478    var getEncodeFunc = function (name, entities) {
3479      var entitiesMap = buildEntitiesLookup(entities) || namedEntities;
3480      var encodeNamedAndNumeric = function (text, attr) {
3481        return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {
3482          if (baseEntities[chr] !== undefined) {
3483            return baseEntities[chr];
3484          }
3485          if (entitiesMap[chr] !== undefined) {
3486            return entitiesMap[chr];
3487          }
3488          if (chr.length > 1) {
3489            return '&#' + ((chr.charCodeAt(0) - 55296) * 1024 + (chr.charCodeAt(1) - 56320) + 65536) + ';';
3490          }
3491          return '&#' + chr.charCodeAt(0) + ';';
3492        });
3493      };
3494      var encodeCustomNamed = function (text, attr) {
3495        return encodeNamed(text, attr, entitiesMap);
3496      };
3497      var nameMap = makeMap$3(name.replace(/\+/g, ','));
3498      if (nameMap.named && nameMap.numeric) {
3499        return encodeNamedAndNumeric;
3500      }
3501      if (nameMap.named) {
3502        if (entities) {
3503          return encodeCustomNamed;
3504        }
3505        return encodeNamed;
3506      }
3507      if (nameMap.numeric) {
3508        return encodeNumeric;
3509      }
3510      return encodeRaw;
3511    };
3512    var decode = function (text) {
3513      return text.replace(entityRegExp, function (all, numeric) {
3514        if (numeric) {
3515          if (numeric.charAt(0).toLowerCase() === 'x') {
3516            numeric = parseInt(numeric.substr(1), 16);
3517          } else {
3518            numeric = parseInt(numeric, 10);
3519          }
3520          if (numeric > 65535) {
3521            numeric -= 65536;
3522            return String.fromCharCode(55296 + (numeric >> 10), 56320 + (numeric & 1023));
3523          }
3524          return asciiMap[numeric] || String.fromCharCode(numeric);
3525        }
3526        return reverseEntities[all] || namedEntities[all] || nativeDecode(all);
3527      });
3528    };
3529    var Entities = {
3530      encodeRaw: encodeRaw,
3531      encodeAllRaw: encodeAllRaw,
3532      encodeNumeric: encodeNumeric,
3533      encodeNamed: encodeNamed,
3534      getEncodeFunc: getEncodeFunc,
3535      decode: decode
3536    };
3537
3538    var mapCache = {}, dummyObj = {};
3539    var makeMap$2 = Tools.makeMap, each$h = Tools.each, extend$5 = Tools.extend, explode$3 = Tools.explode, inArray$2 = Tools.inArray;
3540    var split$1 = function (items, delim) {
3541      items = Tools.trim(items);
3542      return items ? items.split(delim || ' ') : [];
3543    };
3544    var createMap = function (defaultValue, extendWith) {
3545      var value = makeMap$2(defaultValue, ' ', makeMap$2(defaultValue.toUpperCase(), ' '));
3546      return extend$5(value, extendWith);
3547    };
3548    var getTextRootBlockElements = function (schema) {
3549      return createMap('td th li dt dd figcaption caption details summary', schema.getTextBlockElements());
3550    };
3551    var compileSchema = function (type) {
3552      var schema = {};
3553      var globalAttributes, blockContent;
3554      var phrasingContent, flowContent, html4BlockContent, html4PhrasingContent;
3555      var add = function (name, attributes, children) {
3556        var ni, attributesOrder, element;
3557        var arrayToMap = function (array, obj) {
3558          var map = {};
3559          var i, l;
3560          for (i = 0, l = array.length; i < l; i++) {
3561            map[array[i]] = obj || {};
3562          }
3563          return map;
3564        };
3565        children = children || [];
3566        attributes = attributes || '';
3567        if (typeof children === 'string') {
3568          children = split$1(children);
3569        }
3570        var names = split$1(name);
3571        ni = names.length;
3572        while (ni--) {
3573          attributesOrder = split$1([
3574            globalAttributes,
3575            attributes
3576          ].join(' '));
3577          element = {
3578            attributes: arrayToMap(attributesOrder),
3579            attributesOrder: attributesOrder,
3580            children: arrayToMap(children, dummyObj)
3581          };
3582          schema[names[ni]] = element;
3583        }
3584      };
3585      var addAttrs = function (name, attributes) {
3586        var ni, schemaItem, i, l;
3587        var names = split$1(name);
3588        ni = names.length;
3589        var attrs = split$1(attributes);
3590        while (ni--) {
3591          schemaItem = schema[names[ni]];
3592          for (i = 0, l = attrs.length; i < l; i++) {
3593            schemaItem.attributes[attrs[i]] = {};
3594            schemaItem.attributesOrder.push(attrs[i]);
3595          }
3596        }
3597      };
3598      if (mapCache[type]) {
3599        return mapCache[type];
3600      }
3601      globalAttributes = 'id accesskey class dir lang style tabindex title role';
3602      blockContent = 'address blockquote div dl fieldset form h1 h2 h3 h4 h5 h6 hr menu ol p pre table ul';
3603      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';
3604      if (type !== 'html4') {
3605        globalAttributes += ' contenteditable contextmenu draggable dropzone ' + 'hidden spellcheck translate';
3606        blockContent += ' article aside details dialog figure main header footer hgroup section nav';
3607        phrasingContent += ' audio canvas command datalist mark meter output picture ' + 'progress time wbr video ruby bdi keygen';
3608      }
3609      if (type !== 'html5-strict') {
3610        globalAttributes += ' xml:lang';
3611        html4PhrasingContent = 'acronym applet basefont big font strike tt';
3612        phrasingContent = [
3613          phrasingContent,
3614          html4PhrasingContent
3615        ].join(' ');
3616        each$h(split$1(html4PhrasingContent), function (name) {
3617          add(name, '', phrasingContent);
3618        });
3619        html4BlockContent = 'center dir isindex noframes';
3620        blockContent = [
3621          blockContent,
3622          html4BlockContent
3623        ].join(' ');
3624        flowContent = [
3625          blockContent,
3626          phrasingContent
3627        ].join(' ');
3628        each$h(split$1(html4BlockContent), function (name) {
3629          add(name, '', flowContent);
3630        });
3631      }
3632      flowContent = flowContent || [
3633        blockContent,
3634        phrasingContent
3635      ].join(' ');
3636      add('html', 'manifest', 'head body');
3637      add('head', '', 'base command link meta noscript script style title');
3638      add('title hr noscript br');
3639      add('base', 'href target');
3640      add('link', 'href rel media hreflang type sizes hreflang');
3641      add('meta', 'name http-equiv content charset');
3642      add('style', 'media type scoped');
3643      add('script', 'src async defer type charset');
3644      add('body', 'onafterprint onbeforeprint onbeforeunload onblur onerror onfocus ' + 'onhashchange onload onmessage onoffline ononline onpagehide onpageshow ' + 'onpopstate onresize onscroll onstorage onunload', flowContent);
3645      add('address dt dd div caption', '', flowContent);
3646      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);
3647      add('blockquote', 'cite', flowContent);
3648      add('ol', 'reversed start type', 'li');
3649      add('ul', '', 'li');
3650      add('li', 'value', flowContent);
3651      add('dl', '', 'dt dd');
3652      add('a', 'href target rel media hreflang type', phrasingContent);
3653      add('q', 'cite', phrasingContent);
3654      add('ins del', 'cite datetime', flowContent);
3655      add('img', 'src sizes srcset alt usemap ismap width height');
3656      add('iframe', 'src name width height', flowContent);
3657      add('embed', 'src type width height');
3658      add('object', 'data type typemustmatch name usemap form width height', [
3659        flowContent,
3660        'param'
3661      ].join(' '));
3662      add('param', 'name value');
3663      add('map', 'name', [
3664        flowContent,
3665        'area'
3666      ].join(' '));
3667      add('area', 'alt coords shape href target rel media hreflang type');
3668      add('table', 'border', 'caption colgroup thead tfoot tbody tr' + (type === 'html4' ? ' col' : ''));
3669      add('colgroup', 'span', 'col');
3670      add('col', 'span');
3671      add('tbody thead tfoot', '', 'tr');
3672      add('tr', '', 'td th');
3673      add('td', 'colspan rowspan headers', flowContent);
3674      add('th', 'colspan rowspan headers scope abbr', flowContent);
3675      add('form', 'accept-charset action autocomplete enctype method name novalidate target', flowContent);
3676      add('fieldset', 'disabled form name', [
3677        flowContent,
3678        'legend'
3679      ].join(' '));
3680      add('label', 'form for', phrasingContent);
3681      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');
3682      add('button', 'disabled form formaction formenctype formmethod formnovalidate formtarget name type value', type === 'html4' ? flowContent : phrasingContent);
3683      add('select', 'disabled form multiple name required size', 'option optgroup');
3684      add('optgroup', 'disabled label', 'option');
3685      add('option', 'disabled label selected value');
3686      add('textarea', 'cols dirname disabled form maxlength name readonly required rows wrap');
3687      add('menu', 'type label', [
3688        flowContent,
3689        'li'
3690      ].join(' '));
3691      add('noscript', '', flowContent);
3692      if (type !== 'html4') {
3693        add('wbr');
3694        add('ruby', '', [
3695          phrasingContent,
3696          'rt rp'
3697        ].join(' '));
3698        add('figcaption', '', flowContent);
3699        add('mark rt rp summary bdi', '', phrasingContent);
3700        add('canvas', 'width height', flowContent);
3701        add('video', 'src crossorigin poster preload autoplay mediagroup loop ' + 'muted controls width height buffered', [
3702          flowContent,
3703          'track source'
3704        ].join(' '));
3705        add('audio', 'src crossorigin preload autoplay mediagroup loop muted controls ' + 'buffered volume', [
3706          flowContent,
3707          'track source'
3708        ].join(' '));
3709        add('picture', '', 'img source');
3710        add('source', 'src srcset type media sizes');
3711        add('track', 'kind src srclang label default');
3712        add('datalist', '', [
3713          phrasingContent,
3714          'option'
3715        ].join(' '));
3716        add('article section nav aside main header footer', '', flowContent);
3717        add('hgroup', '', 'h1 h2 h3 h4 h5 h6');
3718        add('figure', '', [
3719          flowContent,
3720          'figcaption'
3721        ].join(' '));
3722        add('time', 'datetime', phrasingContent);
3723        add('dialog', 'open', flowContent);
3724        add('command', 'type label icon disabled checked radiogroup command');
3725        add('output', 'for form name', phrasingContent);
3726        add('progress', 'value max', phrasingContent);
3727        add('meter', 'value min max low high optimum', phrasingContent);
3728        add('details', 'open', [
3729          flowContent,
3730          'summary'
3731        ].join(' '));
3732        add('keygen', 'autofocus challenge disabled form keytype name');
3733      }
3734      if (type !== 'html5-strict') {
3735        addAttrs('script', 'language xml:space');
3736        addAttrs('style', 'xml:space');
3737        addAttrs('object', 'declare classid code codebase codetype archive standby align border hspace vspace');
3738        addAttrs('embed', 'align name hspace vspace');
3739        addAttrs('param', 'valuetype type');
3740        addAttrs('a', 'charset name rev shape coords');
3741        addAttrs('br', 'clear');
3742        addAttrs('applet', 'codebase archive code object alt name width height align hspace vspace');
3743        addAttrs('img', 'name longdesc align border hspace vspace');
3744        addAttrs('iframe', 'longdesc frameborder marginwidth marginheight scrolling align');
3745        addAttrs('font basefont', 'size color face');
3746        addAttrs('input', 'usemap align');
3747        addAttrs('select');
3748        addAttrs('textarea');
3749        addAttrs('h1 h2 h3 h4 h5 h6 div p legend caption', 'align');
3750        addAttrs('ul', 'type compact');
3751        addAttrs('li', 'type');
3752        addAttrs('ol dl menu dir', 'compact');
3753        addAttrs('pre', 'width xml:space');
3754        addAttrs('hr', 'align noshade size width');
3755        addAttrs('isindex', 'prompt');
3756        addAttrs('table', 'summary width frame rules cellspacing cellpadding align bgcolor');
3757        addAttrs('col', 'width align char charoff valign');
3758        addAttrs('colgroup', 'width align char charoff valign');
3759        addAttrs('thead', 'align char charoff valign');
3760        addAttrs('tr', 'align char charoff valign bgcolor');
3761        addAttrs('th', 'axis align char charoff valign nowrap bgcolor width height');
3762        addAttrs('form', 'accept');
3763        addAttrs('td', 'abbr axis scope align char charoff valign nowrap bgcolor width height');
3764        addAttrs('tfoot', 'align char charoff valign');
3765        addAttrs('tbody', 'align char charoff valign');
3766        addAttrs('area', 'nohref');
3767        addAttrs('body', 'background bgcolor text link vlink alink');
3768      }
3769      if (type !== 'html4') {
3770        addAttrs('input button select textarea', 'autofocus');
3771        addAttrs('input textarea', 'placeholder');
3772        addAttrs('a', 'download');
3773        addAttrs('link script img', 'crossorigin');
3774        addAttrs('img', 'loading');
3775        addAttrs('iframe', 'sandbox seamless allowfullscreen loading');
3776      }
3777      each$h(split$1('a form meter progress dfn'), function (name) {
3778        if (schema[name]) {
3779          delete schema[name].children[name];
3780        }
3781      });
3782      delete schema.caption.children.table;
3783      delete schema.script;
3784      mapCache[type] = schema;
3785      return schema;
3786    };
3787    var compileElementMap = function (value, mode) {
3788      var styles;
3789      if (value) {
3790        styles = {};
3791        if (typeof value === 'string') {
3792          value = { '*': value };
3793        }
3794        each$h(value, function (value, key) {
3795          styles[key] = styles[key.toUpperCase()] = mode === 'map' ? makeMap$2(value, /[, ]/) : explode$3(value, /[, ]/);
3796        });
3797      }
3798      return styles;
3799    };
3800    var Schema = function (settings) {
3801      var elements = {};
3802      var children = {};
3803      var patternElements = [];
3804      var customElementsMap = {}, specialElements = {};
3805      var createLookupTable = function (option, defaultValue, extendWith) {
3806        var value = settings[option];
3807        if (!value) {
3808          value = mapCache[option];
3809          if (!value) {
3810            value = createMap(defaultValue, extendWith);
3811            mapCache[option] = value;
3812          }
3813        } else {
3814          value = makeMap$2(value, /[, ]/, makeMap$2(value.toUpperCase(), /[, ]/));
3815        }
3816        return value;
3817      };
3818      settings = settings || {};
3819      var schemaItems = compileSchema(settings.schema);
3820      if (settings.verify_html === false) {
3821        settings.valid_elements = '*[*]';
3822      }
3823      var validStyles = compileElementMap(settings.valid_styles);
3824      var invalidStyles = compileElementMap(settings.invalid_styles, 'map');
3825      var validClasses = compileElementMap(settings.valid_classes, 'map');
3826      var whiteSpaceElementsMap = createLookupTable('whitespace_elements', 'pre script noscript style textarea video audio iframe object code');
3827      var selfClosingElementsMap = createLookupTable('self_closing_elements', 'colgroup dd dt li option p td tfoot th thead tr');
3828      var shortEndedElementsMap = createLookupTable('short_ended_elements', 'area base basefont br col frame hr img input isindex link ' + 'meta param embed source wbr track');
3829      var boolAttrMap = createLookupTable('boolean_attributes', 'checked compact declare defer disabled ismap multiple nohref noresize ' + 'noshade nowrap readonly selected autoplay loop controls');
3830      var nonEmptyOrMoveCaretBeforeOnEnter = 'td th iframe video audio object script code';
3831      var nonEmptyElementsMap = createLookupTable('non_empty_elements', nonEmptyOrMoveCaretBeforeOnEnter + ' pre', shortEndedElementsMap);
3832      var moveCaretBeforeOnEnterElementsMap = createLookupTable('move_caret_before_on_enter_elements', nonEmptyOrMoveCaretBeforeOnEnter + ' table', shortEndedElementsMap);
3833      var 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');
3834      var 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);
3835      var textInlineElementsMap = createLookupTable('text_inline_elements', 'span strong b em i font s strike u var cite ' + 'dfn code mark q sup sub samp');
3836      each$h((settings.special || 'script noscript iframe noframes noembed title style textarea xmp').split(' '), function (name) {
3837        specialElements[name] = new RegExp('</' + name + '[^>]*>', 'gi');
3838      });
3839      var patternToRegExp = function (str) {
3840        return new RegExp('^' + str.replace(/([?+*])/g, '.$1') + '$');
3841      };
3842      var addValidElements = function (validElements) {
3843        var ei, el, ai, al, matches, element, attr, attrData, elementName, attrName, attrType, attributes, attributesOrder, prefix, outputName, globalAttributes, globalAttributesOrder, value;
3844        var elementRuleRegExp = /^([#+\-])?([^\[!\/]+)(?:\/([^\[!]+))?(?:(!?)\[([^\]]+)])?$/, attrRuleRegExp = /^([!\-])?(\w+[\\:]:\w+|[^=:<]+)?(?:([=:<])(.*))?$/, hasPatternsRegExp = /[*?+]/;
3845        if (validElements) {
3846          var validElementsArr = split$1(validElements, ',');
3847          if (elements['@']) {
3848            globalAttributes = elements['@'].attributes;
3849            globalAttributesOrder = elements['@'].attributesOrder;
3850          }
3851          for (ei = 0, el = validElementsArr.length; ei < el; ei++) {
3852            matches = elementRuleRegExp.exec(validElementsArr[ei]);
3853            if (matches) {
3854              prefix = matches[1];
3855              elementName = matches[2];
3856              outputName = matches[3];
3857              attrData = matches[5];
3858              attributes = {};
3859              attributesOrder = [];
3860              element = {
3861                attributes: attributes,
3862                attributesOrder: attributesOrder
3863              };
3864              if (prefix === '#') {
3865                element.paddEmpty = true;
3866              }
3867              if (prefix === '-') {
3868                element.removeEmpty = true;
3869              }
3870              if (matches[4] === '!') {
3871                element.removeEmptyAttrs = true;
3872              }
3873              if (globalAttributes) {
3874                each$j(globalAttributes, function (value, key) {
3875                  attributes[key] = value;
3876                });
3877                attributesOrder.push.apply(attributesOrder, globalAttributesOrder);
3878              }
3879              if (attrData) {
3880                attrData = split$1(attrData, '|');
3881                for (ai = 0, al = attrData.length; ai < al; ai++) {
3882                  matches = attrRuleRegExp.exec(attrData[ai]);
3883                  if (matches) {
3884                    attr = {};
3885                    attrType = matches[1];
3886                    attrName = matches[2].replace(/[\\:]:/g, ':');
3887                    prefix = matches[3];
3888                    value = matches[4];
3889                    if (attrType === '!') {
3890                      element.attributesRequired = element.attributesRequired || [];
3891                      element.attributesRequired.push(attrName);
3892                      attr.required = true;
3893                    }
3894                    if (attrType === '-') {
3895                      delete attributes[attrName];
3896                      attributesOrder.splice(inArray$2(attributesOrder, attrName), 1);
3897                      continue;
3898                    }
3899                    if (prefix) {
3900                      if (prefix === '=') {
3901                        element.attributesDefault = element.attributesDefault || [];
3902                        element.attributesDefault.push({
3903                          name: attrName,
3904                          value: value
3905                        });
3906                        attr.defaultValue = value;
3907                      }
3908                      if (prefix === ':') {
3909                        element.attributesForced = element.attributesForced || [];
3910                        element.attributesForced.push({
3911                          name: attrName,
3912                          value: value
3913                        });
3914                        attr.forcedValue = value;
3915                      }
3916                      if (prefix === '<') {
3917                        attr.validValues = makeMap$2(value, '?');
3918                      }
3919                    }
3920                    if (hasPatternsRegExp.test(attrName)) {
3921                      element.attributePatterns = element.attributePatterns || [];
3922                      attr.pattern = patternToRegExp(attrName);
3923                      element.attributePatterns.push(attr);
3924                    } else {
3925                      if (!attributes[attrName]) {
3926                        attributesOrder.push(attrName);
3927                      }
3928                      attributes[attrName] = attr;
3929                    }
3930                  }
3931                }
3932              }
3933              if (!globalAttributes && elementName === '@') {
3934                globalAttributes = attributes;
3935                globalAttributesOrder = attributesOrder;
3936              }
3937              if (outputName) {
3938                element.outputName = elementName;
3939                elements[outputName] = element;
3940              }
3941              if (hasPatternsRegExp.test(elementName)) {
3942                element.pattern = patternToRegExp(elementName);
3943                patternElements.push(element);
3944              } else {
3945                elements[elementName] = element;
3946              }
3947            }
3948          }
3949        }
3950      };
3951      var setValidElements = function (validElements) {
3952        elements = {};
3953        patternElements = [];
3954        addValidElements(validElements);
3955        each$h(schemaItems, function (element, name) {
3956          children[name] = element.children;
3957        });
3958      };
3959      var addCustomElements = function (customElements) {
3960        var customElementRegExp = /^(~)?(.+)$/;
3961        if (customElements) {
3962          mapCache.text_block_elements = mapCache.block_elements = null;
3963          each$h(split$1(customElements, ','), function (rule) {
3964            var matches = customElementRegExp.exec(rule), inline = matches[1] === '~', cloneName = inline ? 'span' : 'div', name = matches[2];
3965            children[name] = children[cloneName];
3966            customElementsMap[name] = cloneName;
3967            if (!inline) {
3968              blockElementsMap[name.toUpperCase()] = {};
3969              blockElementsMap[name] = {};
3970            }
3971            if (!elements[name]) {
3972              var customRule = elements[cloneName];
3973              customRule = extend$5({}, customRule);
3974              delete customRule.removeEmptyAttrs;
3975              delete customRule.removeEmpty;
3976              elements[name] = customRule;
3977            }
3978            each$h(children, function (element, elmName) {
3979              if (element[cloneName]) {
3980                children[elmName] = element = extend$5({}, children[elmName]);
3981                element[name] = element[cloneName];
3982              }
3983            });
3984          });
3985        }
3986      };
3987      var addValidChildren = function (validChildren) {
3988        var 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]+)\[([^\]]+)]$/;
3989        mapCache[settings.schema] = null;
3990        if (validChildren) {
3991          each$h(split$1(validChildren, ','), function (rule) {
3992            var matches = childRuleRegExp.exec(rule);
3993            var parent, prefix;
3994            if (matches) {
3995              prefix = matches[1];
3996              if (prefix) {
3997                parent = children[matches[2]];
3998              } else {
3999                parent = children[matches[2]] = { '#comment': {} };
4000              }
4001              parent = children[matches[2]];
4002              each$h(split$1(matches[3], '|'), function (child) {
4003                if (prefix === '-') {
4004                  delete parent[child];
4005                } else {
4006                  parent[child] = {};
4007                }
4008              });
4009            }
4010          });
4011        }
4012      };
4013      var getElementRule = function (name) {
4014        var element = elements[name], i;
4015        if (element) {
4016          return element;
4017        }
4018        i = patternElements.length;
4019        while (i--) {
4020          element = patternElements[i];
4021          if (element.pattern.test(name)) {
4022            return element;
4023          }
4024        }
4025      };
4026      if (!settings.valid_elements) {
4027        each$h(schemaItems, function (element, name) {
4028          elements[name] = {
4029            attributes: element.attributes,
4030            attributesOrder: element.attributesOrder
4031          };
4032          children[name] = element.children;
4033        });
4034        if (settings.schema !== 'html5') {
4035          each$h(split$1('strong/b em/i'), function (item) {
4036            var items = split$1(item, '/');
4037            elements[items[1]].outputName = items[0];
4038          });
4039        }
4040        each$h(textInlineElementsMap, function (_val, name) {
4041          if (elements[name]) {
4042            if (settings.padd_empty_block_inline_children) {
4043              elements[name].paddInEmptyBlock = true;
4044            }
4045            elements[name].removeEmpty = true;
4046          }
4047        });
4048        each$h(split$1('ol ul blockquote a table tbody'), function (name) {
4049          if (elements[name]) {
4050            elements[name].removeEmpty = true;
4051          }
4052        });
4053        each$h(split$1('p h1 h2 h3 h4 h5 h6 th td pre div address caption li'), function (name) {
4054          elements[name].paddEmpty = true;
4055        });
4056        each$h(split$1('span'), function (name) {
4057          elements[name].removeEmptyAttrs = true;
4058        });
4059      } else {
4060        setValidElements(settings.valid_elements);
4061      }
4062      addCustomElements(settings.custom_elements);
4063      addValidChildren(settings.valid_children);
4064      addValidElements(settings.extended_valid_elements);
4065      addValidChildren('+ol[ul|ol],+ul[ul|ol]');
4066      each$h({
4067        dd: 'dl',
4068        dt: 'dl',
4069        li: 'ul ol',
4070        td: 'tr',
4071        th: 'tr',
4072        tr: 'tbody thead tfoot',
4073        tbody: 'table',
4074        thead: 'table',
4075        tfoot: 'table',
4076        legend: 'fieldset',
4077        area: 'map',
4078        param: 'video audio object'
4079      }, function (parents, item) {
4080        if (elements[item]) {
4081          elements[item].parentsRequired = split$1(parents);
4082        }
4083      });
4084      if (settings.invalid_elements) {
4085        each$h(explode$3(settings.invalid_elements), function (item) {
4086          if (elements[item]) {
4087            delete elements[item];
4088          }
4089        });
4090      }
4091      if (!getElementRule('span')) {
4092        addValidElements('span[!data-mce-type|*]');
4093      }
4094      var getValidStyles = constant(validStyles);
4095      var getInvalidStyles = constant(invalidStyles);
4096      var getValidClasses = constant(validClasses);
4097      var getBoolAttrs = constant(boolAttrMap);
4098      var getBlockElements = constant(blockElementsMap);
4099      var getTextBlockElements = constant(textBlockElementsMap);
4100      var getTextInlineElements = constant(textInlineElementsMap);
4101      var getShortEndedElements = constant(shortEndedElementsMap);
4102      var getSelfClosingElements = constant(selfClosingElementsMap);
4103      var getNonEmptyElements = constant(nonEmptyElementsMap);
4104      var getMoveCaretBeforeOnEnterElements = constant(moveCaretBeforeOnEnterElementsMap);
4105      var getWhiteSpaceElements = constant(whiteSpaceElementsMap);
4106      var getSpecialElements = constant(specialElements);
4107      var isValidChild = function (name, child) {
4108        var parent = children[name.toLowerCase()];
4109        return !!(parent && parent[child.toLowerCase()]);
4110      };
4111      var isValid = function (name, attr) {
4112        var attrPatterns, i;
4113        var rule = getElementRule(name);
4114        if (rule) {
4115          if (attr) {
4116            if (rule.attributes[attr]) {
4117              return true;
4118            }
4119            attrPatterns = rule.attributePatterns;
4120            if (attrPatterns) {
4121              i = attrPatterns.length;
4122              while (i--) {
4123                if (attrPatterns[i].pattern.test(name)) {
4124                  return true;
4125                }
4126              }
4127            }
4128          } else {
4129            return true;
4130          }
4131        }
4132        return false;
4133      };
4134      var getCustomElements = constant(customElementsMap);
4135      return {
4136        children: children,
4137        elements: elements,
4138        getValidStyles: getValidStyles,
4139        getValidClasses: getValidClasses,
4140        getBlockElements: getBlockElements,
4141        getInvalidStyles: getInvalidStyles,
4142        getShortEndedElements: getShortEndedElements,
4143        getTextBlockElements: getTextBlockElements,
4144        getTextInlineElements: getTextInlineElements,
4145        getBoolAttrs: getBoolAttrs,
4146        getElementRule: getElementRule,
4147        getSelfClosingElements: getSelfClosingElements,
4148        getNonEmptyElements: getNonEmptyElements,
4149        getMoveCaretBeforeOnEnterElements: getMoveCaretBeforeOnEnterElements,
4150        getWhiteSpaceElements: getWhiteSpaceElements,
4151        getSpecialElements: getSpecialElements,
4152        isValidChild: isValidChild,
4153        isValid: isValid,
4154        getCustomElements: getCustomElements,
4155        addValidElements: addValidElements,
4156        setValidElements: setValidElements,
4157        addCustomElements: addCustomElements,
4158        addValidChildren: addValidChildren
4159      };
4160    };
4161
4162    var toHex = function (match, r, g, b) {
4163      var hex = function (val) {
4164        val = parseInt(val, 10).toString(16);
4165        return val.length > 1 ? val : '0' + val;
4166      };
4167      return '#' + hex(r) + hex(g) + hex(b);
4168    };
4169    var Styles = function (settings, schema) {
4170      var _this = this;
4171      var rgbRegExp = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi;
4172      var urlOrStrRegExp = /(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi;
4173      var styleRegExp = /\s*([^:]+):\s*([^;]+);?/g;
4174      var trimRightRegExp = /\s+$/;
4175      var i;
4176      var encodingLookup = {};
4177      var validStyles;
4178      var invalidStyles;
4179      var invisibleChar = zeroWidth;
4180      settings = settings || {};
4181      if (schema) {
4182        validStyles = schema.getValidStyles();
4183        invalidStyles = schema.getInvalidStyles();
4184      }
4185      var encodingItems = ('\\" \\\' \\; \\: ; : ' + invisibleChar).split(' ');
4186      for (i = 0; i < encodingItems.length; i++) {
4187        encodingLookup[encodingItems[i]] = invisibleChar + i;
4188        encodingLookup[invisibleChar + i] = encodingItems[i];
4189      }
4190      return {
4191        toHex: function (color) {
4192          return color.replace(rgbRegExp, toHex);
4193        },
4194        parse: function (css) {
4195          var styles = {};
4196          var matches, name, value, isEncoded;
4197          var urlConverter = settings.url_converter;
4198          var urlConverterScope = settings.url_converter_scope || _this;
4199          var compress = function (prefix, suffix, noJoin) {
4200            var top = styles[prefix + '-top' + suffix];
4201            if (!top) {
4202              return;
4203            }
4204            var right = styles[prefix + '-right' + suffix];
4205            if (!right) {
4206              return;
4207            }
4208            var bottom = styles[prefix + '-bottom' + suffix];
4209            if (!bottom) {
4210              return;
4211            }
4212            var left = styles[prefix + '-left' + suffix];
4213            if (!left) {
4214              return;
4215            }
4216            var box = [
4217              top,
4218              right,
4219              bottom,
4220              left
4221            ];
4222            i = box.length - 1;
4223            while (i--) {
4224              if (box[i] !== box[i + 1]) {
4225                break;
4226              }
4227            }
4228            if (i > -1 && noJoin) {
4229              return;
4230            }
4231            styles[prefix + suffix] = i === -1 ? box[0] : box.join(' ');
4232            delete styles[prefix + '-top' + suffix];
4233            delete styles[prefix + '-right' + suffix];
4234            delete styles[prefix + '-bottom' + suffix];
4235            delete styles[prefix + '-left' + suffix];
4236          };
4237          var canCompress = function (key) {
4238            var value = styles[key], i;
4239            if (!value) {
4240              return;
4241            }
4242            value = value.split(' ');
4243            i = value.length;
4244            while (i--) {
4245              if (value[i] !== value[0]) {
4246                return false;
4247              }
4248            }
4249            styles[key] = value[0];
4250            return true;
4251          };
4252          var compress2 = function (target, a, b, c) {
4253            if (!canCompress(a)) {
4254              return;
4255            }
4256            if (!canCompress(b)) {
4257              return;
4258            }
4259            if (!canCompress(c)) {
4260              return;
4261            }
4262            styles[target] = styles[a] + ' ' + styles[b] + ' ' + styles[c];
4263            delete styles[a];
4264            delete styles[b];
4265            delete styles[c];
4266          };
4267          var encode = function (str) {
4268            isEncoded = true;
4269            return encodingLookup[str];
4270          };
4271          var decode = function (str, keepSlashes) {
4272            if (isEncoded) {
4273              str = str.replace(/\uFEFF[0-9]/g, function (str) {
4274                return encodingLookup[str];
4275              });
4276            }
4277            if (!keepSlashes) {
4278              str = str.replace(/\\([\'\";:])/g, '$1');
4279            }
4280            return str;
4281          };
4282          var decodeSingleHexSequence = function (escSeq) {
4283            return String.fromCharCode(parseInt(escSeq.slice(1), 16));
4284          };
4285          var decodeHexSequences = function (value) {
4286            return value.replace(/\\[0-9a-f]+/gi, decodeSingleHexSequence);
4287          };
4288          var processUrl = function (match, url, url2, url3, str, str2) {
4289            str = str || str2;
4290            if (str) {
4291              str = decode(str);
4292              return '\'' + str.replace(/\'/g, '\\\'') + '\'';
4293            }
4294            url = decode(url || url2 || url3);
4295            if (!settings.allow_script_urls) {
4296              var scriptUrl = url.replace(/[\s\r\n]+/g, '');
4297              if (/(java|vb)script:/i.test(scriptUrl)) {
4298                return '';
4299              }
4300              if (!settings.allow_svg_data_urls && /^data:image\/svg/i.test(scriptUrl)) {
4301                return '';
4302              }
4303            }
4304            if (urlConverter) {
4305              url = urlConverter.call(urlConverterScope, url, 'style');
4306            }
4307            return 'url(\'' + url.replace(/\'/g, '\\\'') + '\')';
4308          };
4309          if (css) {
4310            css = css.replace(/[\u0000-\u001F]/g, '');
4311            css = css.replace(/\\[\"\';:\uFEFF]/g, encode).replace(/\"[^\"]+\"|\'[^\']+\'/g, function (str) {
4312              return str.replace(/[;:]/g, encode);
4313            });
4314            while (matches = styleRegExp.exec(css)) {
4315              styleRegExp.lastIndex = matches.index + matches[0].length;
4316              name = matches[1].replace(trimRightRegExp, '').toLowerCase();
4317              value = matches[2].replace(trimRightRegExp, '');
4318              if (name && value) {
4319                name = decodeHexSequences(name);
4320                value = decodeHexSequences(value);
4321                if (name.indexOf(invisibleChar) !== -1 || name.indexOf('"') !== -1) {
4322                  continue;
4323                }
4324                if (!settings.allow_script_urls && (name === 'behavior' || /expression\s*\(|\/\*|\*\//.test(value))) {
4325                  continue;
4326                }
4327                if (name === 'font-weight' && value === '700') {
4328                  value = 'bold';
4329                } else if (name === 'color' || name === 'background-color') {
4330                  value = value.toLowerCase();
4331                }
4332                value = value.replace(rgbRegExp, toHex);
4333                value = value.replace(urlOrStrRegExp, processUrl);
4334                styles[name] = isEncoded ? decode(value, true) : value;
4335              }
4336            }
4337            compress('border', '', true);
4338            compress('border', '-width');
4339            compress('border', '-color');
4340            compress('border', '-style');
4341            compress('padding', '');
4342            compress('margin', '');
4343            compress2('border', 'border-width', 'border-style', 'border-color');
4344            if (styles.border === 'medium none') {
4345              delete styles.border;
4346            }
4347            if (styles['border-image'] === 'none') {
4348              delete styles['border-image'];
4349            }
4350          }
4351          return styles;
4352        },
4353        serialize: function (styles, elementName) {
4354          var css = '';
4355          var serializeStyles = function (name) {
4356            var value;
4357            var styleList = validStyles[name];
4358            if (styleList) {
4359              for (var i_1 = 0, l = styleList.length; i_1 < l; i_1++) {
4360                name = styleList[i_1];
4361                value = styles[name];
4362                if (value) {
4363                  css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';';
4364                }
4365              }
4366            }
4367          };
4368          var isValid = function (name, elementName) {
4369            var styleMap = invalidStyles['*'];
4370            if (styleMap && styleMap[name]) {
4371              return false;
4372            }
4373            styleMap = invalidStyles[elementName];
4374            return !(styleMap && styleMap[name]);
4375          };
4376          if (elementName && validStyles) {
4377            serializeStyles('*');
4378            serializeStyles(elementName);
4379          } else {
4380            each$j(styles, function (value, name) {
4381              if (value && (!invalidStyles || isValid(name, elementName))) {
4382                css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';';
4383              }
4384            });
4385          }
4386          return css;
4387        }
4388      };
4389    };
4390
4391    var deprecated = {
4392      keyLocation: true,
4393      layerX: true,
4394      layerY: true,
4395      returnValue: true,
4396      webkitMovementX: true,
4397      webkitMovementY: true,
4398      keyIdentifier: true,
4399      mozPressure: true
4400    };
4401    var isNativeEvent = function (event) {
4402      return event instanceof Event || isFunction(event.initEvent);
4403    };
4404    var hasIsDefaultPrevented = function (event) {
4405      return event.isDefaultPrevented === always || event.isDefaultPrevented === never;
4406    };
4407    var needsNormalizing = function (event) {
4408      return isNullable(event.preventDefault) || isNativeEvent(event);
4409    };
4410    var clone$2 = function (originalEvent, data) {
4411      var event = data !== null && data !== void 0 ? data : {};
4412      for (var name_1 in originalEvent) {
4413        if (!has$2(deprecated, name_1)) {
4414          event[name_1] = originalEvent[name_1];
4415        }
4416      }
4417      if (isNonNullable(event.composedPath)) {
4418        event.composedPath = function () {
4419          return originalEvent.composedPath();
4420        };
4421      }
4422      return event;
4423    };
4424    var normalize$3 = function (type, originalEvent, fallbackTarget, data) {
4425      var _a;
4426      var event = clone$2(originalEvent, data);
4427      event.type = type;
4428      if (isNullable(event.target)) {
4429        event.target = (_a = event.srcElement) !== null && _a !== void 0 ? _a : fallbackTarget;
4430      }
4431      if (needsNormalizing(originalEvent)) {
4432        event.preventDefault = function () {
4433          event.defaultPrevented = true;
4434          event.isDefaultPrevented = always;
4435          if (isFunction(originalEvent.preventDefault)) {
4436            originalEvent.preventDefault();
4437          } else if (isNativeEvent(originalEvent)) {
4438            originalEvent.returnValue = false;
4439          }
4440        };
4441        event.stopPropagation = function () {
4442          event.cancelBubble = true;
4443          event.isPropagationStopped = always;
4444          if (isFunction(originalEvent.stopPropagation)) {
4445            originalEvent.stopPropagation();
4446          } else if (isNativeEvent(originalEvent)) {
4447            originalEvent.cancelBubble = true;
4448          }
4449        };
4450        event.stopImmediatePropagation = function () {
4451          event.isImmediatePropagationStopped = always;
4452          event.stopPropagation();
4453        };
4454        if (!hasIsDefaultPrevented(event)) {
4455          event.isDefaultPrevented = event.defaultPrevented === true ? always : never;
4456          event.isPropagationStopped = event.cancelBubble === true ? always : never;
4457          event.isImmediatePropagationStopped = never;
4458        }
4459      }
4460      return event;
4461    };
4462
4463    var eventExpandoPrefix = 'mce-data-';
4464    var mouseEventRe = /^(?:mouse|contextmenu)|click/;
4465    var addEvent = function (target, name, callback, capture) {
4466      if (target.addEventListener) {
4467        target.addEventListener(name, callback, capture || false);
4468      } else if (target.attachEvent) {
4469        target.attachEvent('on' + name, callback);
4470      }
4471    };
4472    var removeEvent = function (target, name, callback, capture) {
4473      if (target.removeEventListener) {
4474        target.removeEventListener(name, callback, capture || false);
4475      } else if (target.detachEvent) {
4476        target.detachEvent('on' + name, callback);
4477      }
4478    };
4479    var isMouseEvent = function (event) {
4480      return isNonNullable(event) && mouseEventRe.test(event.type);
4481    };
4482    var fix = function (originalEvent, data) {
4483      var event = normalize$3(originalEvent.type, originalEvent, document, data);
4484      if (isMouseEvent(originalEvent) && isUndefined(originalEvent.pageX) && !isUndefined(originalEvent.clientX)) {
4485        var eventDoc = event.target.ownerDocument || document;
4486        var doc = eventDoc.documentElement;
4487        var body = eventDoc.body;
4488        var mouseEvent = event;
4489        mouseEvent.pageX = originalEvent.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
4490        mouseEvent.pageY = originalEvent.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
4491      }
4492      if (isUndefined(event.metaKey)) {
4493        event.metaKey = false;
4494      }
4495      return event;
4496    };
4497    var bindOnReady = function (win, callback, eventUtils) {
4498      var doc = win.document, event = { type: 'ready' };
4499      if (eventUtils.domLoaded) {
4500        callback(event);
4501        return;
4502      }
4503      var isDocReady = function () {
4504        return doc.readyState === 'complete' || doc.readyState === 'interactive' && doc.body;
4505      };
4506      var readyHandler = function () {
4507        removeEvent(win, 'DOMContentLoaded', readyHandler);
4508        removeEvent(win, 'load', readyHandler);
4509        if (!eventUtils.domLoaded) {
4510          eventUtils.domLoaded = true;
4511          callback(event);
4512        }
4513        win = null;
4514      };
4515      if (isDocReady()) {
4516        readyHandler();
4517      } else {
4518        addEvent(win, 'DOMContentLoaded', readyHandler);
4519      }
4520      if (!eventUtils.domLoaded) {
4521        addEvent(win, 'load', readyHandler);
4522      }
4523    };
4524    var EventUtils = function () {
4525      function EventUtils() {
4526        this.domLoaded = false;
4527        this.events = {};
4528        this.count = 1;
4529        this.expando = eventExpandoPrefix + (+new Date()).toString(32);
4530        this.hasMouseEnterLeave = 'onmouseenter' in document.documentElement;
4531        this.hasFocusIn = 'onfocusin' in document.documentElement;
4532        this.count = 1;
4533      }
4534      EventUtils.prototype.bind = function (target, names, callback, scope) {
4535        var self = this;
4536        var id, callbackList, i, name, fakeName, nativeHandler, capture;
4537        var win = window;
4538        var defaultNativeHandler = function (evt) {
4539          self.executeHandlers(fix(evt || win.event), id);
4540        };
4541        if (!target || target.nodeType === 3 || target.nodeType === 8) {
4542          return;
4543        }
4544        if (!target[self.expando]) {
4545          id = self.count++;
4546          target[self.expando] = id;
4547          self.events[id] = {};
4548        } else {
4549          id = target[self.expando];
4550        }
4551        scope = scope || target;
4552        var namesList = names.split(' ');
4553        i = namesList.length;
4554        while (i--) {
4555          name = namesList[i];
4556          nativeHandler = defaultNativeHandler;
4557          fakeName = capture = false;
4558          if (name === 'DOMContentLoaded') {
4559            name = 'ready';
4560          }
4561          if (self.domLoaded && name === 'ready' && target.readyState === 'complete') {
4562            callback.call(scope, fix({ type: name }));
4563            continue;
4564          }
4565          if (!self.hasMouseEnterLeave) {
4566            fakeName = self.mouseEnterLeave[name];
4567            if (fakeName) {
4568              nativeHandler = function (evt) {
4569                var current = evt.currentTarget;
4570                var related = evt.relatedTarget;
4571                if (related && current.contains) {
4572                  related = current.contains(related);
4573                } else {
4574                  while (related && related !== current) {
4575                    related = related.parentNode;
4576                  }
4577                }
4578                if (!related) {
4579                  evt = fix(evt || win.event);
4580                  evt.type = evt.type === 'mouseout' ? 'mouseleave' : 'mouseenter';
4581                  evt.target = current;
4582                  self.executeHandlers(evt, id);
4583                }
4584              };
4585            }
4586          }
4587          if (!self.hasFocusIn && (name === 'focusin' || name === 'focusout')) {
4588            capture = true;
4589            fakeName = name === 'focusin' ? 'focus' : 'blur';
4590            nativeHandler = function (evt) {
4591              evt = fix(evt || win.event);
4592              evt.type = evt.type === 'focus' ? 'focusin' : 'focusout';
4593              self.executeHandlers(evt, id);
4594            };
4595          }
4596          callbackList = self.events[id][name];
4597          if (!callbackList) {
4598            self.events[id][name] = callbackList = [{
4599                func: callback,
4600                scope: scope
4601              }];
4602            callbackList.fakeName = fakeName;
4603            callbackList.capture = capture;
4604            callbackList.nativeHandler = nativeHandler;
4605            if (name === 'ready') {
4606              bindOnReady(target, nativeHandler, self);
4607            } else {
4608              addEvent(target, fakeName || name, nativeHandler, capture);
4609            }
4610          } else {
4611            if (name === 'ready' && self.domLoaded) {
4612              callback(fix({ type: name }));
4613            } else {
4614              callbackList.push({
4615                func: callback,
4616                scope: scope
4617              });
4618            }
4619          }
4620        }
4621        target = callbackList = null;
4622        return callback;
4623      };
4624      EventUtils.prototype.unbind = function (target, names, callback) {
4625        var callbackList, i, ci, name, eventMap;
4626        if (!target || target.nodeType === 3 || target.nodeType === 8) {
4627          return this;
4628        }
4629        var id = target[this.expando];
4630        if (id) {
4631          eventMap = this.events[id];
4632          if (names) {
4633            var namesList = names.split(' ');
4634            i = namesList.length;
4635            while (i--) {
4636              name = namesList[i];
4637              callbackList = eventMap[name];
4638              if (callbackList) {
4639                if (callback) {
4640                  ci = callbackList.length;
4641                  while (ci--) {
4642                    if (callbackList[ci].func === callback) {
4643                      var nativeHandler = callbackList.nativeHandler;
4644                      var fakeName = callbackList.fakeName, capture = callbackList.capture;
4645                      callbackList = callbackList.slice(0, ci).concat(callbackList.slice(ci + 1));
4646                      callbackList.nativeHandler = nativeHandler;
4647                      callbackList.fakeName = fakeName;
4648                      callbackList.capture = capture;
4649                      eventMap[name] = callbackList;
4650                    }
4651                  }
4652                }
4653                if (!callback || callbackList.length === 0) {
4654                  delete eventMap[name];
4655                  removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture);
4656                }
4657              }
4658            }
4659          } else {
4660            each$j(eventMap, function (callbackList, name) {
4661              removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture);
4662            });
4663            eventMap = {};
4664          }
4665          for (name in eventMap) {
4666            if (has$2(eventMap, name)) {
4667              return this;
4668            }
4669          }
4670          delete this.events[id];
4671          try {
4672            delete target[this.expando];
4673          } catch (ex) {
4674            target[this.expando] = null;
4675          }
4676        }
4677        return this;
4678      };
4679      EventUtils.prototype.fire = function (target, name, args) {
4680        var id;
4681        if (!target || target.nodeType === 3 || target.nodeType === 8) {
4682          return this;
4683        }
4684        var event = fix({
4685          type: name,
4686          target: target
4687        }, args);
4688        do {
4689          id = target[this.expando];
4690          if (id) {
4691            this.executeHandlers(event, id);
4692          }
4693          target = target.parentNode || target.ownerDocument || target.defaultView || target.parentWindow;
4694        } while (target && !event.isPropagationStopped());
4695        return this;
4696      };
4697      EventUtils.prototype.clean = function (target) {
4698        var i, children;
4699        if (!target || target.nodeType === 3 || target.nodeType === 8) {
4700          return this;
4701        }
4702        if (target[this.expando]) {
4703          this.unbind(target);
4704        }
4705        if (!target.getElementsByTagName) {
4706          target = target.document;
4707        }
4708        if (target && target.getElementsByTagName) {
4709          this.unbind(target);
4710          children = target.getElementsByTagName('*');
4711          i = children.length;
4712          while (i--) {
4713            target = children[i];
4714            if (target[this.expando]) {
4715              this.unbind(target);
4716            }
4717          }
4718        }
4719        return this;
4720      };
4721      EventUtils.prototype.destroy = function () {
4722        this.events = {};
4723      };
4724      EventUtils.prototype.cancel = function (e) {
4725        if (e) {
4726          e.preventDefault();
4727          e.stopImmediatePropagation();
4728        }
4729        return false;
4730      };
4731      EventUtils.prototype.executeHandlers = function (evt, id) {
4732        var container = this.events[id];
4733        var callbackList = container && container[evt.type];
4734        if (callbackList) {
4735          for (var i = 0, l = callbackList.length; i < l; i++) {
4736            var callback = callbackList[i];
4737            if (callback && callback.func.call(callback.scope, evt) === false) {
4738              evt.preventDefault();
4739            }
4740            if (evt.isImmediatePropagationStopped()) {
4741              return;
4742            }
4743          }
4744        }
4745      };
4746      EventUtils.Event = new EventUtils();
4747      return EventUtils;
4748    }();
4749
4750    var support, Expr, getText, isXML, tokenize, compile, select$1, outermostContext, sortInput, hasDuplicate, setDocument, document$1, docElem, documentIsHTML, rbuggyQSA, rbuggyMatches, matches, contains, expando = 'sizzle' + -new Date(), preferredDoc = window.document, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), sortOrder = function (a, b) {
4751        if (a === b) {
4752          hasDuplicate = true;
4753        }
4754        return 0;
4755      }, strundefined = typeof undefined, MAX_NEGATIVE = 1 << 31, hasOwn = {}.hasOwnProperty, arr = [], pop = arr.pop, push_native = arr.push, push$1 = arr.push, slice$1 = arr.slice, indexOf = arr.indexOf || function (elem) {
4756        var i = 0, len = this.length;
4757        for (; i < len; i++) {
4758          if (this[i] === elem) {
4759            return i;
4760          }
4761        }
4762        return -1;
4763      }, booleans = 'checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped', whitespace = '[\\x20\\t\\r\\n\\f]', identifier = '(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+', attributes = '\\[' + whitespace + '*(' + identifier + ')(?:' + whitespace + '*([*^$|!~]?=)' + whitespace + '*(?:\'((?:\\\\.|[^\\\\\'])*)\'|"((?:\\\\.|[^\\\\"])*)"|(' + identifier + '))|)' + whitespace + '*\\]', pseudos = ':(' + identifier + ')(?:\\((' + '(\'((?:\\\\.|[^\\\\\'])*)\'|"((?:\\\\.|[^\\\\"])*)")|' + '((?:\\\\.|[^\\\\()[\\]]|' + attributes + ')*)|' + '.*' + ')\\)|)', rtrim = new RegExp('^' + whitespace + '+|((?:^|[^\\\\])(?:\\\\.)*)' + whitespace + '+$', 'g'), rcomma = new RegExp('^' + whitespace + '*,' + whitespace + '*'), rcombinators = new RegExp('^' + whitespace + '*([>+~]|' + whitespace + ')' + whitespace + '*'), rattributeQuotes = new RegExp('=' + whitespace + '*([^\\]\'"]*?)' + whitespace + '*\\]', 'g'), rpseudo = new RegExp(pseudos), ridentifier = new RegExp('^' + identifier + '$'), matchExpr = {
4764        ID: new RegExp('^#(' + identifier + ')'),
4765        CLASS: new RegExp('^\\.(' + identifier + ')'),
4766        TAG: new RegExp('^(' + identifier + '|[*])'),
4767        ATTR: new RegExp('^' + attributes),
4768        PSEUDO: new RegExp('^' + pseudos),
4769        CHILD: new RegExp('^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(' + whitespace + '*(even|odd|(([+-]|)(\\d*)n|)' + whitespace + '*(?:([+-]|)' + whitespace + '*(\\d+)|))' + whitespace + '*\\)|)', 'i'),
4770        bool: new RegExp('^(?:' + booleans + ')$', 'i'),
4771        needsContext: new RegExp('^' + whitespace + '*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(' + whitespace + '*((?:-\\d)?\\d*)' + whitespace + '*\\)|)(?=[^-]|$)', 'i')
4772      }, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rnative = /^[^{]+\{\s*\[native \w/, rquickExpr$1 = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rsibling = /[+~]/, rescape = /'|\\/g, runescape = new RegExp('\\\\([\\da-f]{1,6}' + whitespace + '?|(' + whitespace + ')|.)', 'ig'), funescape = function (_, escaped, escapedWhitespace) {
4773        var high = '0x' + escaped - 65536;
4774        return high !== high || escapedWhitespace ? escaped : high < 0 ? String.fromCharCode(high + 65536) : String.fromCharCode(high >> 10 | 55296, high & 1023 | 56320);
4775      };
4776    try {
4777      push$1.apply(arr = slice$1.call(preferredDoc.childNodes), preferredDoc.childNodes);
4778      arr[preferredDoc.childNodes.length].nodeType;
4779    } catch (e) {
4780      push$1 = {
4781        apply: arr.length ? function (target, els) {
4782          push_native.apply(target, slice$1.call(els));
4783        } : function (target, els) {
4784          var j = target.length, i = 0;
4785          while (target[j++] = els[i++]) {
4786          }
4787          target.length = j - 1;
4788        }
4789      };
4790    }
4791    var Sizzle = function (selector, context, results, seed) {
4792      var match, elem, m, nodeType, i, groups, old, nid, newContext, newSelector;
4793      if ((context ? context.ownerDocument || context : preferredDoc) !== document$1) {
4794        setDocument(context);
4795      }
4796      context = context || document$1;
4797      results = results || [];
4798      if (!selector || typeof selector !== 'string') {
4799        return results;
4800      }
4801      if ((nodeType = context.nodeType) !== 1 && nodeType !== 9) {
4802        return [];
4803      }
4804      if (documentIsHTML && !seed) {
4805        if (match = rquickExpr$1.exec(selector)) {
4806          if (m = match[1]) {
4807            if (nodeType === 9) {
4808              elem = context.getElementById(m);
4809              if (elem && elem.parentNode) {
4810                if (elem.id === m) {
4811                  results.push(elem);
4812                  return results;
4813                }
4814              } else {
4815                return results;
4816              }
4817            } else {
4818              if (context.ownerDocument && (elem = context.ownerDocument.getElementById(m)) && contains(context, elem) && elem.id === m) {
4819                results.push(elem);
4820                return results;
4821              }
4822            }
4823          } else if (match[2]) {
4824            push$1.apply(results, context.getElementsByTagName(selector));
4825            return results;
4826          } else if ((m = match[3]) && support.getElementsByClassName) {
4827            push$1.apply(results, context.getElementsByClassName(m));
4828            return results;
4829          }
4830        }
4831        if (support.qsa && (!rbuggyQSA || !rbuggyQSA.test(selector))) {
4832          nid = old = expando;
4833          newContext = context;
4834          newSelector = nodeType === 9 && selector;
4835          if (nodeType === 1 && context.nodeName.toLowerCase() !== 'object') {
4836            groups = tokenize(selector);
4837            if (old = context.getAttribute('id')) {
4838              nid = old.replace(rescape, '\\$&');
4839            } else {
4840              context.setAttribute('id', nid);
4841            }
4842            nid = '[id=\'' + nid + '\'] ';
4843            i = groups.length;
4844            while (i--) {
4845              groups[i] = nid + toSelector(groups[i]);
4846            }
4847            newContext = rsibling.test(selector) && testContext(context.parentNode) || context;
4848            newSelector = groups.join(',');
4849          }
4850          if (newSelector) {
4851            try {
4852              push$1.apply(results, newContext.querySelectorAll(newSelector));
4853              return results;
4854            } catch (qsaError) {
4855            } finally {
4856              if (!old) {
4857                context.removeAttribute('id');
4858              }
4859            }
4860          }
4861        }
4862      }
4863      return select$1(selector.replace(rtrim, '$1'), context, results, seed);
4864    };
4865    function createCache() {
4866      var keys = [];
4867      function cache(key, value) {
4868        if (keys.push(key + ' ') > Expr.cacheLength) {
4869          delete cache[keys.shift()];
4870        }
4871        return cache[key + ' '] = value;
4872      }
4873      return cache;
4874    }
4875    function markFunction(fn) {
4876      fn[expando] = true;
4877      return fn;
4878    }
4879    function siblingCheck(a, b) {
4880      var cur = b && a, diff = cur && a.nodeType === 1 && b.nodeType === 1 && (~b.sourceIndex || MAX_NEGATIVE) - (~a.sourceIndex || MAX_NEGATIVE);
4881      if (diff) {
4882        return diff;
4883      }
4884      if (cur) {
4885        while (cur = cur.nextSibling) {
4886          if (cur === b) {
4887            return -1;
4888          }
4889        }
4890      }
4891      return a ? 1 : -1;
4892    }
4893    function createInputPseudo(type) {
4894      return function (elem) {
4895        var name = elem.nodeName.toLowerCase();
4896        return name === 'input' && elem.type === type;
4897      };
4898    }
4899    function createButtonPseudo(type) {
4900      return function (elem) {
4901        var name = elem.nodeName.toLowerCase();
4902        return (name === 'input' || name === 'button') && elem.type === type;
4903      };
4904    }
4905    function createPositionalPseudo(fn) {
4906      return markFunction(function (argument) {
4907        argument = +argument;
4908        return markFunction(function (seed, matches) {
4909          var j, matchIndexes = fn([], seed.length, argument), i = matchIndexes.length;
4910          while (i--) {
4911            if (seed[j = matchIndexes[i]]) {
4912              seed[j] = !(matches[j] = seed[j]);
4913            }
4914          }
4915        });
4916      });
4917    }
4918    function testContext(context) {
4919      return context && typeof context.getElementsByTagName !== strundefined && context;
4920    }
4921    support = Sizzle.support = {};
4922    isXML = Sizzle.isXML = function (elem) {
4923      var documentElement = elem && (elem.ownerDocument || elem).documentElement;
4924      return documentElement ? documentElement.nodeName !== 'HTML' : false;
4925    };
4926    setDocument = Sizzle.setDocument = function (node) {
4927      var hasCompare, doc = node ? node.ownerDocument || node : preferredDoc, parent = doc.defaultView;
4928      function getTop(win) {
4929        try {
4930          return win.top;
4931        } catch (ex) {
4932        }
4933        return null;
4934      }
4935      if (doc === document$1 || doc.nodeType !== 9 || !doc.documentElement) {
4936        return document$1;
4937      }
4938      document$1 = doc;
4939      docElem = doc.documentElement;
4940      documentIsHTML = !isXML(doc);
4941      if (parent && parent !== getTop(parent)) {
4942        if (parent.addEventListener) {
4943          parent.addEventListener('unload', function () {
4944            setDocument();
4945          }, false);
4946        } else if (parent.attachEvent) {
4947          parent.attachEvent('onunload', function () {
4948            setDocument();
4949          });
4950        }
4951      }
4952      support.attributes = true;
4953      support.getElementsByTagName = true;
4954      support.getElementsByClassName = rnative.test(doc.getElementsByClassName);
4955      support.getById = true;
4956      Expr.find.ID = function (id, context) {
4957        if (typeof context.getElementById !== strundefined && documentIsHTML) {
4958          var m = context.getElementById(id);
4959          return m && m.parentNode ? [m] : [];
4960        }
4961      };
4962      Expr.filter.ID = function (id) {
4963        var attrId = id.replace(runescape, funescape);
4964        return function (elem) {
4965          return elem.getAttribute('id') === attrId;
4966        };
4967      };
4968      Expr.find.TAG = support.getElementsByTagName ? function (tag, context) {
4969        if (typeof context.getElementsByTagName !== strundefined) {
4970          return context.getElementsByTagName(tag);
4971        }
4972      } : function (tag, context) {
4973        var elem, tmp = [], i = 0, results = context.getElementsByTagName(tag);
4974        if (tag === '*') {
4975          while (elem = results[i++]) {
4976            if (elem.nodeType === 1) {
4977              tmp.push(elem);
4978            }
4979          }
4980          return tmp;
4981        }
4982        return results;
4983      };
4984      Expr.find.CLASS = support.getElementsByClassName && function (className, context) {
4985        if (documentIsHTML) {
4986          return context.getElementsByClassName(className);
4987        }
4988      };
4989      rbuggyMatches = [];
4990      rbuggyQSA = [];
4991      support.disconnectedMatch = true;
vendor: 8,594 bytes, lines 4992-5205
4992      rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join('|'));
4993      rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join('|'));
4994      hasCompare = rnative.test(docElem.compareDocumentPosition);
4995      contains = hasCompare || rnative.test(docElem.contains) ? function (a, b) {
4996        var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode;
4997        return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16));
4998      } : function (a, b) {
4999        if (b) {
5000          while (b = b.parentNode) {
5001            if (b === a) {
5002              return true;
5003            }
5004          }
5005        }
5006        return false;
5007      };
5008      sortOrder = hasCompare ? function (a, b) {
5009        if (a === b) {
5010          hasDuplicate = true;
5011          return 0;
5012        }
5013        var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
5014        if (compare) {
5015          return compare;
5016        }
5017        compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1;
5018        if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) {
5019          if (a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a)) {
5020            return -1;
5021          }
5022          if (b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b)) {
5023            return 1;
5024          }
5025          return sortInput ? indexOf.call(sortInput, a) - indexOf.call(sortInput, b) : 0;
5026        }
5027        return compare & 4 ? -1 : 1;
5028      } : function (a, b) {
5029        if (a === b) {
5030          hasDuplicate = true;
5031          return 0;
5032        }
5033        var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [a], bp = [b];
5034        if (!aup || !bup) {
5035          return a === doc ? -1 : b === doc ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf.call(sortInput, a) - indexOf.call(sortInput, b) : 0;
5036        } else if (aup === bup) {
5037          return siblingCheck(a, b);
5038        }
5039        cur = a;
5040        while (cur = cur.parentNode) {
5041          ap.unshift(cur);
5042        }
5043        cur = b;
5044        while (cur = cur.parentNode) {
5045          bp.unshift(cur);
5046        }
5047        while (ap[i] === bp[i]) {
5048          i++;
5049        }
5050        return i ? siblingCheck(ap[i], bp[i]) : ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0;
5051      };
5052      return doc;
5053    };
5054    Sizzle.matches = function (expr, elements) {
5055      return Sizzle(expr, null, null, elements);
5056    };
5057    Sizzle.matchesSelector = function (elem, expr) {
5058      if ((elem.ownerDocument || elem) !== document$1) {
5059        setDocument(elem);
5060      }
5061      expr = expr.replace(rattributeQuotes, '=\'$1\']');
5062      if (support.matchesSelector && documentIsHTML && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) {
5063        try {
5064          var ret = matches.call(elem, expr);
5065          if (ret || support.disconnectedMatch || elem.document && elem.document.nodeType !== 11) {
5066            return ret;
5067          }
5068        } catch (e) {
5069        }
5070      }
5071      return Sizzle(expr, document$1, null, [elem]).length > 0;
5072    };
5073    Sizzle.contains = function (context, elem) {
5074      if ((context.ownerDocument || context) !== document$1) {
5075        setDocument(context);
5076      }
5077      return contains(context, elem);
5078    };
5079    Sizzle.attr = function (elem, name) {
5080      if ((elem.ownerDocument || elem) !== document$1) {
5081        setDocument(elem);
5082      }
5083      var fn = Expr.attrHandle[name.toLowerCase()], val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined;
5084      return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null;
5085    };
5086    Sizzle.error = function (msg) {
5087      throw new Error('Syntax error, unrecognized expression: ' + msg);
5088    };
5089    Sizzle.uniqueSort = function (results) {
5090      var elem, duplicates = [], j = 0, i = 0;
5091      hasDuplicate = !support.detectDuplicates;
5092      sortInput = !support.sortStable && results.slice(0);
5093      results.sort(sortOrder);
5094      if (hasDuplicate) {
5095        while (elem = results[i++]) {
5096          if (elem === results[i]) {
5097            j = duplicates.push(i);
5098          }
5099        }
5100        while (j--) {
5101          results.splice(duplicates[j], 1);
5102        }
5103      }
5104      sortInput = null;
5105      return results;
5106    };
5107    getText = Sizzle.getText = function (elem) {
5108      var node, ret = '', i = 0, nodeType = elem.nodeType;
5109      if (!nodeType) {
5110        while (node = elem[i++]) {
5111          ret += getText(node);
5112        }
5113      } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {
5114        if (typeof elem.textContent === 'string') {
5115          return elem.textContent;
5116        } else {
5117          for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
5118            ret += getText(elem);
5119          }
5120        }
5121      } else if (nodeType === 3 || nodeType === 4) {
5122        return elem.nodeValue;
5123      }
5124      return ret;
5125    };
5126    Expr = Sizzle.selectors = {
5127      cacheLength: 50,
5128      createPseudo: markFunction,
5129      match: matchExpr,
5130      attrHandle: {},
5131      find: {},
5132      relative: {
5133        '>': {
5134          dir: 'parentNode',
5135          first: true
5136        },
5137        ' ': { dir: 'parentNode' },
5138        '+': {
5139          dir: 'previousSibling',
5140          first: true
5141        },
5142        '~': { dir: 'previousSibling' }
5143      },
5144      preFilter: {
5145        ATTR: function (match) {
5146          match[1] = match[1].replace(runescape, funescape);
5147          match[3] = (match[3] || match[4] || match[5] || '').replace(runescape, funescape);
5148          if (match[2] === '~=') {
5149            match[3] = ' ' + match[3] + ' ';
5150          }
5151          return match.slice(0, 4);
5152        },
5153        CHILD: function (match) {
5154          match[1] = match[1].toLowerCase();
5155          if (match[1].slice(0, 3) === 'nth') {
5156            if (!match[3]) {
5157              Sizzle.error(match[0]);
5158            }
5159            match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === 'even' || match[3] === 'odd'));
5160            match[5] = +(match[7] + match[8] || match[3] === 'odd');
5161          } else if (match[3]) {
5162            Sizzle.error(match[0]);
5163          }
5164          return match;
5165        },
5166        PSEUDO: function (match) {
5167          var excess, unquoted = !match[6] && match[2];
5168          if (matchExpr.CHILD.test(match[0])) {
5169            return null;
5170          }
5171          if (match[3]) {
5172            match[2] = match[4] || match[5] || '';
5173          } else if (unquoted && rpseudo.test(unquoted) && (excess = tokenize(unquoted, true)) && (excess = unquoted.indexOf(')', unquoted.length - excess) - unquoted.length)) {
5174            match[0] = match[0].slice(0, excess);
5175            match[2] = unquoted.slice(0, excess);
5176          }
5177          return match.slice(0, 3);
5178        }
5179      },
5180      filter: {
5181        TAG: function (nodeNameSelector) {
5182          var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();
5183          return nodeNameSelector === '*' ? function () {
5184            return true;
5185          } : function (elem) {
5186            return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
5187          };
5188        },
5189        CLASS: function (className) {
5190          var pattern = classCache[className + ' '];
5191          return pattern || (pattern = new RegExp('(^|' + whitespace + ')' + className + '(' + whitespace + '|$)')) && classCache(className, function (elem) {
5192            return pattern.test(typeof elem.className === 'string' && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute('class') || '');
5193          });
5194        },
5195        ATTR: function (name, operator, check) {
5196          return function (elem) {
5197            var result = Sizzle.attr(elem, name);
5198            if (result == null) {
5199              return operator === '!=';
5200            }
5201            if (!operator) {
5202              return true;
5203            }
5204            result += '';
5205            return operator === '=' ? result === check : operator === '!=' ? result !== check : operator === '^=' ? check && result.indexOf(check) === 0 : operator === '*=' ? check && result.indexOf(check) > -1 : operator === '$=' ? check && result.slice(-check.length) === check : operator === '~=' ? (' ' + result + ' ').indexOf(check) > -1 : operator === '|=' ? result === check || result.slice(0, check.length + 1) === check + '-' : false;
5206          };
5207        },
5208        CHILD: function (type, what, argument, first, last) {
5209          var simple = type.slice(0, 3) !== 'nth', forward = type.slice(-4) !== 'last', ofType = what === 'of-type';
5210          return first === 1 && last === 0 ? function (elem) {
5211            return !!elem.parentNode;
5212          } : function (elem, context, xml) {
5213            var cache, outerCache, node, diff, nodeIndex, start, dir = simple !== forward ? 'nextSibling' : 'previousSibling', parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType;
5214            if (parent) {
5215              if (simple) {
5216                while (dir) {
5217                  node = elem;
5218                  while (node = node[dir]) {
5219                    if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) {
5220                      return false;
5221                    }
5222                  }
5223                  start = dir = type === 'only' && !start && 'nextSibling';
5224                }
5225                return true;
5226              }
5227              start = [forward ? parent.firstChild : parent.lastChild];
5228              if (forward && useCache) {
5229                outerCache = parent[expando] || (parent[expando] = {});
5230                cache = outerCache[type] || [];
5231                nodeIndex = cache[0] === dirruns && cache[1];
5232                diff = cache[0] === dirruns && cache[2];
5233                node = nodeIndex && parent.childNodes[nodeIndex];
5234                while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {
5235                  if (node.nodeType === 1 && ++diff && node === elem) {
5236                    outerCache[type] = [
5237                      dirruns,
5238                      nodeIndex,
5239                      diff
5240                    ];
5241                    break;
5242                  }
5243                }
5244              } else if (useCache && (cache = (elem[expando] || (elem[expando] = {}))[type]) && cache[0] === dirruns) {
5245                diff = cache[1];
5246              } else {
5247                while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {
5248                  if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) {
5249                    if (useCache) {
5250                      (node[expando] || (node[expando] = {}))[type] = [
5251                        dirruns,
5252                        diff
5253                      ];
5254                    }
5255                    if (node === elem) {
5256                      break;
5257                    }
5258                  }
5259                }
5260              }
5261              diff -= last;
5262              return diff === first || diff % first === 0 && diff / first >= 0;
5263            }
5264          };
5265        },
5266        PSEUDO: function (pseudo, argument) {
5267          var args, fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error('unsupported pseudo: ' + pseudo);
5268          if (fn[expando]) {
5269            return fn(argument);
5270          }
5271          if (fn.length > 1) {
5272            args = [
5273              pseudo,
5274              pseudo,
5275              '',
5276              argument
5277            ];
5278            return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) {
5279              var idx, matched = fn(seed, argument), i = matched.length;
5280              while (i--) {
5281                idx = indexOf.call(seed, matched[i]);
5282                seed[idx] = !(matches[idx] = matched[i]);
5283              }
5284            }) : function (elem) {
5285              return fn(elem, 0, args);
5286            };
5287          }
5288          return fn;
5289        }
5290      },
5291      pseudos: {
5292        not: markFunction(function (selector) {
5293          var input = [], results = [], matcher = compile(selector.replace(rtrim, '$1'));
5294          return matcher[expando] ? markFunction(function (seed, matches, context, xml) {
5295            var elem, unmatched = matcher(seed, null, xml, []), i = seed.length;
5296            while (i--) {
5297              if (elem = unmatched[i]) {
5298                seed[i] = !(matches[i] = elem);
5299              }
5300            }
5301          }) : function (elem, context, xml) {
5302            input[0] = elem;
5303            matcher(input, null, xml, results);
5304            input[0] = null;
5305            return !results.pop();
5306          };
5307        }),
5308        has: markFunction(function (selector) {
5309          return function (elem) {
5310            return Sizzle(selector, elem).length > 0;
5311          };
5312        }),
5313        contains: markFunction(function (text) {
5314          text = text.replace(runescape, funescape);
5315          return function (elem) {
5316            return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1;
5317          };
5318        }),
5319        lang: markFunction(function (lang) {
5320          if (!ridentifier.test(lang || '')) {
5321            Sizzle.error('unsupported lang: ' + lang);
5322          }
5323          lang = lang.replace(runescape, funescape).toLowerCase();
5324          return function (elem) {
5325            var elemLang;
5326            do {
5327              if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute('xml:lang') || elem.getAttribute('lang')) {
5328                elemLang = elemLang.toLowerCase();
5329                return elemLang === lang || elemLang.indexOf(lang + '-') === 0;
5330              }
5331            } while ((elem = elem.parentNode) && elem.nodeType === 1);
5332            return false;
5333          };
5334        }),
5335        target: function (elem) {
5336          var hash = window.location && window.location.hash;
5337          return hash && hash.slice(1) === elem.id;
5338        },
5339        root: function (elem) {
5340          return elem === docElem;
5341        },
5342        focus: function (elem) {
5343          return elem === document$1.activeElement && (!document$1.hasFocus || document$1.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
5344        },
5345        enabled: function (elem) {
5346          return elem.disabled === false;
5347        },
5348        disabled: function (elem) {
5349          return elem.disabled === true;
5350        },
5351        checked: function (elem) {
5352          var nodeName = elem.nodeName.toLowerCase();
5353          return nodeName === 'input' && !!elem.checked || nodeName === 'option' && !!elem.selected;
5354        },
5355        selected: function (elem) {
5356          if (elem.parentNode) {
5357            elem.parentNode.selectedIndex;
5358          }
5359          return elem.selected === true;
5360        },
5361        empty: function (elem) {
5362          for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
5363            if (elem.nodeType < 6) {
5364              return false;
5365            }
5366          }
5367          return true;
5368        },
5369        parent: function (elem) {
5370          return !Expr.pseudos.empty(elem);
5371        },
5372        header: function (elem) {
5373          return rheader.test(elem.nodeName);
5374        },
5375        input: function (elem) {
5376          return rinputs.test(elem.nodeName);
5377        },
5378        button: function (elem) {
5379          var name = elem.nodeName.toLowerCase();
5380          return name === 'input' && elem.type === 'button' || name === 'button';
5381        },
5382        text: function (elem) {
5383          var attr;
5384          return elem.nodeName.toLowerCase() === 'input' && elem.type === 'text' && ((attr = elem.getAttribute('type')) == null || attr.toLowerCase() === 'text');
5385        },
5386        first: createPositionalPseudo(function () {
5387          return [0];
5388        }),
5389        last: createPositionalPseudo(function (matchIndexes, length) {
5390          return [length - 1];
5391        }),
5392        eq: createPositionalPseudo(function (matchIndexes, length, argument) {
5393          return [argument < 0 ? argument + length : argument];
5394        }),
5395        even: createPositionalPseudo(function (matchIndexes, length) {
5396          var i = 0;
5397          for (; i < length; i += 2) {
5398            matchIndexes.push(i);
5399          }
5400          return matchIndexes;
5401        }),
5402        odd: createPositionalPseudo(function (matchIndexes, length) {
5403          var i = 1;
5404          for (; i < length; i += 2) {
5405            matchIndexes.push(i);
5406          }
5407          return matchIndexes;
5408        }),
5409        lt: createPositionalPseudo(function (matchIndexes, length, argument) {
5410          var i = argument < 0 ? argument + length : argument;
5411          for (; --i >= 0;) {
5412            matchIndexes.push(i);
5413          }
5414          return matchIndexes;
5415        }),
5416        gt: createPositionalPseudo(function (matchIndexes, length, argument) {
5417          var i = argument < 0 ? argument + length : argument;
5418          for (; ++i < length;) {
5419            matchIndexes.push(i);
5420          }
5421          return matchIndexes;
5422        })
5423      }
5424    };
5425    Expr.pseudos.nth = Expr.pseudos.eq;
5426    each$k([
5427      'radio',
5428      'checkbox',
5429      'file',
5430      'password',
5431      'image'
5432    ], function (i) {
5433      Expr.pseudos[i] = createInputPseudo(i);
5434    });
5435    each$k([
5436      'submit',
5437      'reset'
5438    ], function (i) {
5439      Expr.pseudos[i] = createButtonPseudo(i);
5440    });
5441    function setFilters() {
5442    }
5443    setFilters.prototype = Expr.filters = Expr.pseudos;
5444    Expr.setFilters = new setFilters();
5445    tokenize = Sizzle.tokenize = function (selector, parseOnly) {
5446      var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[selector + ' '];
5447      if (cached) {
5448        return parseOnly ? 0 : cached.slice(0);
5449      }
5450      soFar = selector;
5451      groups = [];
5452      preFilters = Expr.preFilter;
5453      while (soFar) {
5454        if (!matched || (match = rcomma.exec(soFar))) {
5455          if (match) {
5456            soFar = soFar.slice(match[0].length) || soFar;
5457          }
5458          groups.push(tokens = []);
5459        }
5460        matched = false;
5461        if (match = rcombinators.exec(soFar)) {
5462          matched = match.shift();
5463          tokens.push({
5464            value: matched,
5465            type: match[0].replace(rtrim, ' ')
5466          });
5467          soFar = soFar.slice(matched.length);
5468        }
5469        for (type in Expr.filter) {
5470          if (!Expr.filter.hasOwnProperty(type)) {
5471            continue;
5472          }
5473          if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) {
5474            matched = match.shift();
5475            tokens.push({
5476              value: matched,
5477              type: type,
5478              matches: match
5479            });
5480            soFar = soFar.slice(matched.length);
5481          }
5482        }
5483        if (!matched) {
5484          break;
5485        }
5486      }
5487      return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) : tokenCache(selector, groups).slice(0);
5488    };
5489    function toSelector(tokens) {
5490      var i = 0, len = tokens.length, selector = '';
5491      for (; i < len; i++) {
5492        selector += tokens[i].value;
5493      }
5494      return selector;
5495    }
5496    function addCombinator(matcher, combinator, base) {
5497      var dir = combinator.dir, checkNonElements = base && dir === 'parentNode', doneName = done++;
5498      return combinator.first ? function (elem, context, xml) {
5499        while (elem = elem[dir]) {
5500          if (elem.nodeType === 1 || checkNonElements) {
5501            return matcher(elem, context, xml);
5502          }
5503        }
5504      } : function (elem, context, xml) {
5505        var oldCache, outerCache, newCache = [
5506            dirruns,
5507            doneName
5508          ];
5509        if (xml) {
5510          while (elem = elem[dir]) {
5511            if (elem.nodeType === 1 || checkNonElements) {
5512              if (matcher(elem, context, xml)) {
5513                return true;
5514              }
5515            }
5516          }
5517        } else {
5518          while (elem = elem[dir]) {
5519            if (elem.nodeType === 1 || checkNonElements) {
5520              outerCache = elem[expando] || (elem[expando] = {});
5521              if ((oldCache = outerCache[dir]) && oldCache[0] === dirruns && oldCache[1] === doneName) {
5522                return newCache[2] = oldCache[2];
5523              } else {
5524                outerCache[dir] = newCache;
5525                if (newCache[2] = matcher(elem, context, xml)) {
5526                  return true;
5527                }
5528              }
5529            }
5530          }
5531        }
5532      };
5533    }
5534    function elementMatcher(matchers) {
5535      return matchers.length > 1 ? function (elem, context, xml) {
5536        var i = matchers.length;
5537        while (i--) {
5538          if (!matchers[i](elem, context, xml)) {
5539            return false;
5540          }
5541        }
5542        return true;
5543      } : matchers[0];
5544    }
5545    function multipleContexts(selector, contexts, results) {
5546      var i = 0, len = contexts.length;
5547      for (; i < len; i++) {
5548        Sizzle(selector, contexts[i], results);
5549      }
5550      return results;
5551    }
5552    function condense(unmatched, map, filter, context, xml) {
5553      var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null;
5554      for (; i < len; i++) {
5555        if (elem = unmatched[i]) {
5556          if (!filter || filter(elem, context, xml)) {
5557            newUnmatched.push(elem);
5558            if (mapped) {
5559              map.push(i);
5560            }
5561          }
5562        }
5563      }
5564      return newUnmatched;
5565    }
5566    function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {
5567      if (postFilter && !postFilter[expando]) {
5568        postFilter = setMatcher(postFilter);
5569      }
5570      if (postFinder && !postFinder[expando]) {
5571        postFinder = setMatcher(postFinder, postSelector);
5572      }
5573      return markFunction(function (seed, results, context, xml) {
5574        var temp, i, elem, preMap = [], postMap = [], preexisting = results.length, elems = seed || multipleContexts(selector || '*', context.nodeType ? [context] : context, []), matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems, matcherOut = matcher ? postFinder || (seed ? preFilter : preexisting || postFilter) ? [] : results : matcherIn;
5575        if (matcher) {
5576          matcher(matcherIn, matcherOut, context, xml);
5577        }
5578        if (postFilter) {
5579          temp = condense(matcherOut, postMap);
5580          postFilter(temp, [], context, xml);
5581          i = temp.length;
5582          while (i--) {
5583            if (elem = temp[i]) {
5584              matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);
5585            }
5586          }
5587        }
5588        if (seed) {
5589          if (postFinder || preFilter) {
5590            if (postFinder) {
5591              temp = [];
5592              i = matcherOut.length;
5593              while (i--) {
5594                if (elem = matcherOut[i]) {
5595                  temp.push(matcherIn[i] = elem);
5596                }
5597              }
5598              postFinder(null, matcherOut = [], temp, xml);
5599            }
5600            i = matcherOut.length;
5601            while (i--) {
5602              if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf.call(seed, elem) : preMap[i]) > -1) {
5603                seed[temp] = !(results[temp] = elem);
5604              }
5605            }
5606          }
5607        } else {
5608          matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut);
5609          if (postFinder) {
5610            postFinder(null, results, matcherOut, xml);
5611          } else {
5612            push$1.apply(results, matcherOut);
5613          }
5614        }
5615      });
5616    }
5617    function matcherFromTokens(tokens) {
5618      var checkContext, matcher, j, len = tokens.length, leadingRelative = Expr.relative[tokens[0].type], implicitRelative = leadingRelative || Expr.relative[' '], i = leadingRelative ? 1 : 0, matchContext = addCombinator(function (elem) {
5619          return elem === checkContext;
5620        }, implicitRelative, true), matchAnyContext = addCombinator(function (elem) {
5621          return indexOf.call(checkContext, elem) > -1;
5622        }, implicitRelative, true), matchers = [function (elem, context, xml) {
5623            var ret = !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml));
5624            checkContext = null;
5625            return ret;
5626          }];
5627      for (; i < len; i++) {
5628        if (matcher = Expr.relative[tokens[i].type]) {
5629          matchers = [addCombinator(elementMatcher(matchers), matcher)];
5630        } else {
5631          matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);
5632          if (matcher[expando]) {
5633            j = ++i;
5634            for (; j < len; j++) {
5635              if (Expr.relative[tokens[j].type]) {
5636                break;
5637              }
5638            }
5639            return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector(tokens.slice(0, i - 1).concat({ value: tokens[i - 2].type === ' ' ? '*' : '' })).replace(rtrim, '$1'), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens));
5640          }
5641          matchers.push(matcher);
5642        }
5643      }
5644      return elementMatcher(matchers);
5645    }
5646    function matcherFromGroupMatchers(elementMatchers, setMatchers) {
5647      var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function (seed, context, xml, results, outermost) {
5648          var elem, j, matcher, matchedCount = 0, i = '0', unmatched = seed && [], setMatched = [], contextBackup = outermostContext, elems = seed || byElement && Expr.find.TAG('*', outermost), dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1, len = elems.length;
5649          if (outermost) {
5650            outermostContext = context !== document$1 && context;
5651          }
5652          for (; i !== len && (elem = elems[i]) != null; i++) {
5653            if (byElement && elem) {
5654              j = 0;
5655              while (matcher = elementMatchers[j++]) {
5656                if (matcher(elem, context, xml)) {
5657                  results.push(elem);
5658                  break;
5659                }
5660              }
5661              if (outermost) {
5662                dirruns = dirrunsUnique;
5663              }
5664            }
5665            if (bySet) {
5666              if (elem = !matcher && elem) {
5667                matchedCount--;
5668              }
5669              if (seed) {
5670                unmatched.push(elem);
5671              }
5672            }
5673          }
5674          matchedCount += i;
5675          if (bySet && i !== matchedCount) {
5676            j = 0;
5677            while (matcher = setMatchers[j++]) {
5678              matcher(unmatched, setMatched, context, xml);
5679            }
5680            if (seed) {
5681              if (matchedCount > 0) {
5682                while (i--) {
5683                  if (!(unmatched[i] || setMatched[i])) {
5684                    setMatched[i] = pop.call(results);
5685                  }
5686                }
5687              }
5688              setMatched = condense(setMatched);
5689            }
5690            push$1.apply(results, setMatched);
5691            if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) {
5692              Sizzle.uniqueSort(results);
5693            }
5694          }
5695          if (outermost) {
5696            dirruns = dirrunsUnique;
5697            outermostContext = contextBackup;
5698          }
5699          return unmatched;
5700        };
5701      return bySet ? markFunction(superMatcher) : superMatcher;
5702    }
5703    compile = Sizzle.compile = function (selector, match) {
5704      var i, setMatchers = [], elementMatchers = [], cached = compilerCache[selector + ' '];
5705      if (!cached) {
5706        if (!match) {
5707          match = tokenize(selector);
5708        }
5709        i = match.length;
5710        while (i--) {
5711          cached = matcherFromTokens(match[i]);
5712          if (cached[expando]) {
5713            setMatchers.push(cached);
5714          } else {
5715            elementMatchers.push(cached);
5716          }
5717        }
5718        cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers));
5719        cached.selector = selector;
5720      }
5721      return cached;
5722    };
5723    select$1 = Sizzle.select = function (selector, context, results, seed) {
5724      var i, tokens, token, type, find, compiled = typeof selector === 'function' && selector, match = !seed && tokenize(selector = compiled.selector || selector);
5725      results = results || [];
5726      if (match.length === 1) {
5727        tokens = match[0] = match[0].slice(0);
5728        if (tokens.length > 2 && (token = tokens[0]).type === 'ID' && support.getById && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) {
5729          context = (Expr.find.ID(token.matches[0].replace(runescape, funescape), context) || [])[0];
5730          if (!context) {
5731            return results;
5732          } else if (compiled) {
5733            context = context.parentNode;
5734          }
5735          selector = selector.slice(tokens.shift().value.length);
5736        }
5737        i = matchExpr.needsContext.test(selector) ? 0 : tokens.length;
5738        while (i--) {
5739          token = tokens[i];
5740          if (Expr.relative[type = token.type]) {
5741            break;
5742          }
5743          if (find = Expr.find[type]) {
5744            if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testC
5744ontext(context.parentNode) || context)) {
5745              tokens.splice(i, 1);
5746              selector = seed.length && toSelector(tokens);
5747              if (!selector) {
5748                push$1.apply(results, seed);
5749                return results;
5750              }
5751              break;
5752            }
5753          }
5754        }
5755      }
5756      (compiled || compile(selector, match))(seed, context, !documentIsHTML, results, rsibling.test(selector) && testContext(context.parentNode) || context);
5757      return results;
5758    };
5759    support.sortStable = expando.split('').sort(sortOrder).join('') === expando;
5760    support.detectDuplicates = !!hasDuplicate;
5761    setDocument();
5762    support.sortDetached = true;
5763
5764    var doc = document;
5765    var push = Array.prototype.push;
5766    var slice = Array.prototype.slice;
5767    var rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/;
5768    var Event$1 = EventUtils.Event;
5769    var skipUniques = Tools.makeMap('children,contents,next,prev');
5770    var isDefined = function (obj) {
5771      return typeof obj !== 'undefined';
5772    };
5773    var isString = function (obj) {
5774      return typeof obj === 'string';
5775    };
5776    var isWindow = function (obj) {
5777      return obj && obj === obj.window;
5778    };
5779    var createFragment$1 = function (html, fragDoc) {
5780      fragDoc = fragDoc || doc;
5781      var container = fragDoc.createElement('div');
5782      var frag = fragDoc.createDocumentFragment();
5783      container.innerHTML = html;
5784      var node;
5785      while (node = container.firstChild) {
5786        frag.appendChild(node);
5787      }
5788      return frag;
5789    };
5790    var domManipulate = function (targetNodes, sourceItem, callback, reverse) {
5791      var i;
5792      if (isString(sourceItem)) {
5793        sourceItem = createFragment$1(sourceItem, getElementDocument(targetNodes[0]));
5794      } else if (sourceItem.length && !sourceItem.nodeType) {
5795        sourceItem = DomQuery.makeArray(sourceItem);
5796        if (reverse) {
5797          for (i = sourceItem.length - 1; i >= 0; i--) {
5798            domManipulate(targetNodes, sourceItem[i], callback, reverse);
5799          }
5800        } else {
5801          for (i = 0; i < sourceItem.length; i++) {
5802            domManipulate(targetNodes, sourceItem[i], callback, reverse);
5803          }
5804        }
5805        return targetNodes;
5806      }
5807      if (sourceItem.nodeType) {
5808        i = targetNodes.length;
5809        while (i--) {
5810          callback.call(targetNodes[i], sourceItem);
5811        }
5812      }
5813      return targetNodes;
5814    };
5815    var hasClass = function (node, className) {
5816      return node && className && (' ' + node.className + ' ').indexOf(' ' + className + ' ') !== -1;
5817    };
5818    var wrap$2 = function (elements, wrapper, all) {
5819      var lastParent, newWrapper;
5820      wrapper = DomQuery(wrapper)[0];
5821      elements.each(function () {
5822        var self = this;
5823        if (!all || lastParent !== self.parentNode) {
5824          lastParent = self.parentNode;
5825          newWrapper = wrapper.cloneNode(false);
5826          self.parentNode.insertBefore(newWrapper, self);
5827          newWrapper.appendChild(self);
5828        } else {
5829          newWrapper.appendChild(self);
5830        }
5831      });
5832      return elements;
5833    };
5834    var numericCssMap = Tools.makeMap('fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom', ' ');
5835    var booleanMap = Tools.makeMap('checked compact declare defer disabled ismap multiple nohref noshade nowrap readonly selected', ' ');
5836    var propFix = {
5837      for: 'htmlFor',
5838      class: 'className',
5839      readonly: 'readOnly'
5840    };
5841    var cssFix = { float: 'cssFloat' };
5842    var attrHooks = {}, cssHooks = {};
5843    var DomQueryConstructor = function (selector, context) {
5844      return new DomQuery.fn.init(selector, context);
5845    };
5846    var inArray$1 = function (item, array) {
5847      var i;
5848      if (array.indexOf) {
5849        return array.indexOf(item);
5850      }
5851      i = array.length;
5852      while (i--) {
5853        if (array[i] === item) {
5854          return i;
5855        }
5856      }
5857      return -1;
5858    };
5859    var whiteSpaceRegExp = /^\s*|\s*$/g;
5860    var trim$2 = function (str) {
5861      return str === null || str === undefined ? '' : ('' + str).replace(whiteSpaceRegExp, '');
5862    };
5863    var each$g = function (obj, callback) {
5864      var length, key, i, value;
5865      if (obj) {
5866        length = obj.length;
5867        if (length === undefined) {
5868          for (key in obj) {
5869            if (obj.hasOwnProperty(key)) {
5870              value = obj[key];
5871              if (callback.call(value, key, value) === false) {
5872                break;
5873              }
5874            }
5875          }
5876        } else {
5877          for (i = 0; i < length; i++) {
5878            value = obj[i];
5879            if (callback.call(value, i, value) === false) {
5880              break;
5881            }
5882          }
5883        }
5884      }
5885      return obj;
5886    };
5887    var grep$2 = function (array, callback) {
5888      var out = [];
5889      each$g(array, function (i, item) {
5890        if (callback(item, i)) {
5891          out.push(item);
5892        }
5893      });
5894      return out;
5895    };
5896    var getElementDocument = function (element) {
5897      if (!element) {
5898        return doc;
5899      }
5900      if (element.nodeType === 9) {
5901        return element;
5902      }
5903      return element.ownerDocument;
5904    };
5905    DomQueryConstructor.fn = DomQueryConstructor.prototype = {
5906      constructor: DomQueryConstructor,
5907      selector: '',
5908      context: null,
5909      length: 0,
5910      init: function (selector, context) {
5911        var self = this;
5912        var match, node;
5913        if (!selector) {
5914          return self;
5915        }
5916        if (selector.nodeType) {
5917          self.context = self[0] = selector;
5918          self.length = 1;
5919          return self;
5920        }
5921        if (context && context.nodeType) {
5922          self.context = context;
5923        } else {
5924          if (context) {
5925            return DomQuery(selector).attr(context);
5926          }
5927          self.context = context = document;
5928        }
5929        if (isString(selector)) {
5930          self.selector = selector;
5931          if (selector.charAt(0) === '<' && selector.charAt(selector.length - 1) === '>' && selector.length >= 3) {
5932            match = [
5933              null,
5934              selector,
5935              null
5936            ];
5937          } else {
5938            match = rquickExpr.exec(selector);
5939          }
5940          if (match) {
5941            if (match[1]) {
5942              node = createFragment$1(selector, getElementDocument(context)).firstChild;
5943              while (node) {
5944                push.call(self, node);
5945                node = node.nextSibling;
5946              }
5947            } else {
5948              node = getElementDocument(context).getElementById(match[2]);
5949              if (!node) {
5950                return self;
5951              }
5952              if (node.id !== match[2]) {
5953                return self.find(selector);
5954              }
5955              self.length = 1;
5956              self[0] = node;
5957            }
5958          } else {
5959            return DomQuery(context).find(selector);
5960          }
5961        } else {
5962          this.add(selector, false);
5963        }
5964        return self;
5965      },
5966      toArray: function () {
5967        return Tools.toArray(this);
5968      },
5969      add: function (items, sort) {
5970        var self = this;
5971        var nodes, i;
5972        if (isString(items)) {
5973          return self.add(DomQuery(items));
5974        }
5975        if (sort !== false) {
5976          nodes = DomQuery.unique(self.toArray().concat(DomQuery.makeArray(items)));
5977          self.length = nodes.length;
5978          for (i = 0; i < nodes.length; i++) {
5979            self[i] = nodes[i];
5980          }
5981        } else {
5982          push.apply(self, DomQuery.makeArray(items));
5983        }
5984        return self;
5985      },
5986      attr: function (name, value) {
5987        var self = this;
5988        var hook;
5989        if (typeof name === 'object') {
5990          each$g(name, function (name, value) {
5991            self.attr(name, value);
5992          });
5993        } else if (isDefined(value)) {
5994          this.each(function () {
5995            var hook;
5996            if (this.nodeType === 1) {
5997              hook = attrHooks[name];
5998              if (hook && hook.set) {
5999                hook.set(this, value);
6000                return;
6001              }
6002              if (value === null) {
6003                this.removeAttribute(name, 2);
6004              } else {
6005                this.setAttribute(name, value, 2);
6006              }
6007            }
6008          });
6009        } else {
6010          if (self[0] && self[0].nodeType === 1) {
6011            hook = attrHooks[name];
6012            if (hook && hook.get) {
6013              return hook.get(self[0], name);
6014            }
6015            if (booleanMap[name]) {
6016              return self.prop(name) ? name : undefined;
6017            }
6018            value = self[0].getAttribute(name, 2);
6019            if (value === null) {
6020              value = undefined;
6021            }
6022          }
6023          return value;
6024        }
6025        return self;
6026      },
6027      removeAttr: function (name) {
6028        return this.attr(name, null);
6029      },
6030      prop: function (name, value) {
6031        var self = this;
6032        name = propFix[name] || name;
6033        if (typeof name === 'object') {
6034          each$g(name, function (name, value) {
6035            self.prop(name, value);
6036          });
6037        } else if (isDefined(value)) {
6038          this.each(function () {
6039            if (this.nodeType === 1) {
6040              this[name] = value;
6041            }
6042          });
6043        } else {
6044          if (self[0] && self[0].nodeType && name in self[0]) {
6045            return self[0][name];
6046          }
6047          return value;
6048        }
6049        return self;
6050      },
6051      css: function (name, value) {
6052        var self = this;
6053        var elm, hook;
6054        var camel = function (name) {
6055          return name.replace(/-(\D)/g, function (a, b) {
6056            return b.toUpperCase();
6057          });
6058        };
6059        var dashed = function (name) {
6060          return name.replace(/[A-Z]/g, function (a) {
6061            return '-' + a;
6062          });
6063        };
6064        if (typeof name === 'object') {
6065          each$g(name, function (name, value) {
6066            self.css(name, value);
6067          });
6068        } else {
6069          if (isDefined(value)) {
6070            name = camel(name);
6071            if (typeof value === 'number' && !numericCssMap[name]) {
6072              value = value.toString() + 'px';
6073            }
6074            self.each(function () {
6075              var style = this.style;
6076              hook = cssHooks[name];
6077              if (hook && hook.set) {
6078                hook.set(this, value);
6079                return;
6080              }
6081              try {
6082                this.style[cssFix[name] || name] = value;
6083              } catch (ex) {
6084              }
6085              if (value === null || value === '') {
6086                if (style.removeProperty) {
6087                  style.removeProperty(dashed(name));
6088                } else {
6089                  style.removeAttribute(name);
6090                }
6091              }
6092            });
6093          } else {
6094            elm = self[0];
6095            hook = cssHooks[name];
6096            if (hook && hook.get) {
6097              return hook.get(elm);
6098            }
6099            if (elm.ownerDocument.defaultView) {
6100              try {
6101                return elm.ownerDocument.defaultView.getComputedStyle(elm, null).getPropertyValue(dashed(name));
6102              } catch (ex) {
6103                return undefined;
6104              }
6105            } else if (elm.currentStyle) {
6106              return elm.currentStyle[camel(name)];
6107            } else {
6108              return '';
6109            }
6110          }
6111        }
6112        return self;
6113      },
6114      remove: function () {
6115        var self = this;
6116        var node, i = this.length;
6117        while (i--) {
6118          node = self[i];
6119          Event$1.clean(node);
6120          if (node.parentNode) {
6121            node.parentNode.removeChild(node);
6122          }
6123        }
6124        return this;
6125      },
6126      empty: function () {
6127        var self = this;
6128        var node, i = this.length;
6129        while (i--) {
6130          node = self[i];
6131          while (node.firstChild) {
6132            node.removeChild(node.firstChild);
6133          }
6134        }
6135        return this;
6136      },
6137      html: function (value) {
6138        var self = this;
6139        var i;
6140        if (isDefined(value)) {
6141          i = self.length;
6142          try {
6143            while (i--) {
6144              self[i].innerHTML = value;
6145            }
6146          } catch (ex) {
6147            DomQuery(self[i]).empty().append(value);
6148          }
6149          return self;
6150        }
6151        return self[0] ? self[0].innerHTML : '';
6152      },
6153      text: function (value) {
6154        var self = this;
6155        var i;
6156        if (isDefined(value)) {
6157          i = self.length;
6158          while (i--) {
6159            if ('innerText' in self[i]) {
6160              self[i].innerText = value;
6161            } else {
6162              self[0].textContent = value;
6163            }
6164          }
6165          return self;
6166        }
6167        return self[0] ? self[0].innerText || self[0].textContent : '';
6168      },
6169      append: function () {
6170        return domManipulate(this, arguments, function (node) {
6171          if (this.nodeType === 1 || this.host && this.host.nodeType === 1) {
6172            this.appendChild(node);
6173          }
6174        });
6175      },
6176      prepend: function () {
6177        return domManipulate(this, arguments, function (node) {
6178          if (this.nodeType === 1 || this.host && this.host.nodeType === 1) {
6179            this.insertBefore(node, this.firstChild);
6180          }
6181        }, true);
6182      },
6183      before: function () {
6184        var self = this;
6185        if (self[0] && self[0].parentNode) {
6186          return domManipulate(self, arguments, function (node) {
6187            this.parentNode.insertBefore(node, this);
6188          });
6189        }
6190        return self;
6191      },
6192      after: function () {
6193        var self = this;
6194        if (self[0] && self[0].parentNode) {
6195          return domManipulate(self, arguments, function (node) {
6196            this.parentNode.insertBefore(node, this.nextSibling);
6197          }, true);
6198        }
6199        return self;
6200      },
6201      appendTo: function (val) {
6202        DomQuery(val).append(this);
6203        return this;
6204      },
6205      prependTo: function (val) {
6206        DomQuery(val).prepend(this);
6207        return this;
6208      },
6209      replaceWith: function (content) {
6210        return this.before(content).remove();
6211      },
6212      wrap: function (content) {
6213        return wrap$2(this, content);
6214      },
6215      wrapAll: function (content) {
6216        return wrap$2(this, content, true);
6217      },
6218      wrapInner: function (content) {
6219        this.each(function () {
6220          DomQuery(this).contents().wrapAll(content);
6221        });
6222        return this;
6223      },
6224      unwrap: function () {
6225        return this.parent().each(function () {
6226          DomQuery(this).replaceWith(this.childNodes);
6227        });
6228      },
6229      clone: function () {
6230        var result = [];
6231        this.each(function () {
6232          result.push(this.cloneNode(true));
6233        });
6234        return DomQuery(result);
6235      },
6236      addClass: function (className) {
6237        return this.toggleClass(className, true);
6238      },
6239      removeClass: function (className) {
6240        return this.toggleClass(className, false);
6241      },
6242      toggleClass: function (className, state) {
6243        var self = this;
6244        if (typeof className !== 'string') {
6245          return self;
6246        }
6247        if (className.indexOf(' ') !== -1) {
6248          each$g(className.split(' '), function () {
6249            self.toggleClass(this, state);
6250          });
6251        } else {
6252          self.each(function (index, node) {
6253            var classState = hasClass(node, className);
6254            if (classState !== state) {
6255              var existingClassName = node.className;
6256              if (classState) {
6257                node.className = trim$2((' ' + existingClassName + ' ').replace(' ' + className + ' ', ' '));
6258              } else {
6259                node.className += existingClassName ? ' ' + className : className;
6260              }
6261            }
6262          });
6263        }
6264        return self;
6265      },
6266      hasClass: function (className) {
6267        return hasClass(this[0], className);
6268      },
6269      each: function (callback) {
6270        return each$g(this, callback);
6271      },
6272      on: function (name, callback) {
6273        return this.each(function () {
6274          Event$1.bind(this, name, callback);
6275        });
6276      },
6277      off: function (name, callback) {
6278        return this.each(function () {
6279          Event$1.unbind(this, name, callback);
6280        });
6281      },
6282      trigger: function (name) {
6283        return this.each(function () {
6284          if (typeof name === 'object') {
6285            Event$1.fire(this, name.type, name);
6286          } else {
6287            Event$1.fire(this, name);
6288          }
6289        });
6290      },
6291      show: function () {
6292        return this.css('display', '');
6293      },
6294      hide: function () {
6295        return this.css('display', 'none');
6296      },
6297      slice: function () {
6298        return DomQuery(slice.apply(this, arguments));
6299      },
6300      eq: function (index) {
6301        return index === -1 ? this.slice(index) : this.slice(index, +index + 1);
6302      },
6303      first: function () {
6304        return this.eq(0);
6305      },
6306      last: function () {
6307        return this.eq(-1);
6308      },
6309      find: function (selector) {
6310        var i, l;
6311        var ret = [];
6312        for (i = 0, l = this.length; i < l; i++) {
6313          DomQuery.find(selector, this[i], ret);
6314        }
6315        return DomQuery(ret);
6316      },
6317      filter: function (selector) {
6318        if (typeof selector === 'function') {
6319          return DomQuery(grep$2(this.toArray(), function (item, i) {
6320            return selector(i, item);
6321          }));
6322        }
6323        return DomQuery(DomQuery.filter(selector, this.toArray()));
6324      },
6325      closest: function (selector) {
6326        var result = [];
6327        if (selector instanceof DomQuery) {
6328          selector = selector[0];
6329        }
6330        this.each(function (i, node) {
6331          while (node) {
6332            if (typeof selector === 'string' && DomQuery(node).is(selector)) {
6333              result.push(node);
6334              break;
6335            } else if (node === selector) {
6336              result.push(node);
6337              break;
6338            }
6339            node = node.parentNode;
6340          }
6341        });
6342        return DomQuery(result);
6343      },
6344      offset: function (offset) {
6345        var elm, doc, docElm;
6346        var x = 0, y = 0, pos;
6347        if (!offset) {
6348          elm = this[0];
6349          if (elm) {
6350            doc = elm.ownerDocument;
6351            docElm = doc.documentElement;
6352            if (elm.getBoundingClientRect) {
6353              pos = elm.getBoundingClientRect();
6354              x = pos.left + (docElm.scrollLeft || doc.body.scrollLeft) - docElm.clientLeft;
6355              y = pos.top + (docElm.scrollTop || doc.body.scrollTop) - docElm.clientTop;
6356            }
6357          }
6358          return {
6359            left: x,
6360            top: y
6361          };
6362        }
6363        return this.css(offset);
6364      },
6365      push: push,
6366      sort: Array.prototype.sort,
6367      splice: Array.prototype.splice
6368    };
6369    Tools.extend(DomQueryConstructor, {
6370      extend: Tools.extend,
6371      makeArray: function (object) {
6372        if (isWindow(object) || object.nodeType) {
6373          return [object];
6374        }
6375        return Tools.toArray(object);
6376      },
6377      inArray: inArray$1,
6378      isArray: Tools.isArray,
6379      each: each$g,
6380      trim: trim$2,
6381      grep: grep$2,
6382      find: Sizzle,
6383      expr: Sizzle.selectors,
6384      unique: Sizzle.uniqueSort,
6385      text: Sizzle.getText,
6386      contains: Sizzle.contains,
6387      filter: function (expr, elems, not) {
6388        var i = elems.length;
6389        if (not) {
6390          expr = ':not(' + expr + ')';
6391        }
6392        while (i--) {
6393          if (elems[i].nodeType !== 1) {
6394            elems.splice(i, 1);
6395          }
6396        }
6397        if (elems.length === 1) {
6398          elems = DomQuery.find.matchesSelector(elems[0], expr) ? [elems[0]] : [];
6399        } else {
6400          elems = DomQuery.find.matches(expr, elems);
6401        }
6402        return elems;
6403      }
6404    });
6405    var dir = function (el, prop, until) {
6406      var matched = [];
6407      var cur = el[prop];
6408      if (typeof until !== 'string' && until instanceof DomQuery) {
6409        until = until[0];
6410      }
6411      while (cur && cur.nodeType !== 9) {
6412        if (until !== undefined) {
6413          if (cur === until) {
6414            break;
6415          }
6416          if (typeof until === 'string' && DomQuery(cur).is(until)) {
6417            break;
6418          }
6419        }
6420        if (cur.nodeType === 1) {
6421          matched.push(cur);
6422        }
6423        cur = cur[prop];
6424      }
6425      return matched;
6426    };
6427    var sibling$1 = function (node, siblingName, nodeType, until) {
6428      var result = [];
6429      if (until instanceof DomQuery) {
6430        until = until[0];
6431      }
6432      for (; node; node = node[siblingName]) {
6433        if (nodeType && node.nodeType !== nodeType) {
6434          continue;
6435        }
6436        if (until !== undefined) {
6437          if (node === until) {
6438            break;
6439          }
6440          if (typeof until === 'string' && DomQuery(node).is(until)) {
6441            break;
6442          }
6443        }
6444        result.push(node);
6445      }
6446      return result;
6447    };
6448    var firstSibling = function (node, siblingName, nodeType) {
6449      for (node = node[siblingName]; node; node = node[siblingName]) {
6450        if (node.nodeType === nodeType) {
6451          return node;
6452        }
6453      }
6454      return null;
6455    };
6456    each$g({
6457      parent: function (node) {
6458        var parent = node.parentNode;
6459        return parent && parent.nodeType !== 11 ? parent : null;
6460      },
6461      parents: function (node) {
6462        return dir(node, 'parentNode');
6463      },
6464      next: function (node) {
6465        return firstSibling(node, 'nextSibling', 1);
6466      },
6467      prev: function (node) {
6468        return firstSibling(node, 'previousSibling', 1);
6469      },
6470      children: function (node) {
6471        return sibling$1(node.firstChild, 'nextSibling', 1);
6472      },
6473      contents: function (node) {
6474        return Tools.toArray((node.nodeName === 'iframe' ? node.contentDocument || node.contentWindow.document : node).childNodes);
6475      }
6476    }, function (name, fn) {
6477      DomQueryConstructor.fn[name] = function (selector) {
6478        var self = this;
6479        var result = [];
6480        self.each(function () {
6481          var nodes = fn.call(result, this, selector, result);
6482          if (nodes) {
6483            if (DomQuery.isArray(nodes)) {
6484              result.push.apply(result, nodes);
6485            } else {
6486              result.push(nodes);
6487            }
6488          }
6489        });
6490        if (this.length > 1) {
6491          if (!skipUniques[name]) {
6492            result = DomQuery.unique(result);
6493          }
6494          if (name.indexOf('parents') === 0) {
6495            result = result.reverse();
6496          }
6497        }
6498        var wrappedResult = DomQuery(result);
6499        if (selector) {
6500          return wrappedResult.filter(selector);
6501        }
6502        return wrappedResult;
6503      };
6504    });
6505    each$g({
6506      parentsUntil: function (node, until) {
6507        return dir(node, 'parentNode', until);
6508      },
6509      nextUntil: function (node, until) {
6510        return sibling$1(node, 'nextSibling', 1, until).slice(1);
6511      },
6512      prevUntil: function (node, until) {
6513        return sibling$1(node, 'previousSibling', 1, until).slice(1);
6514      }
6515    }, function (name, fn) {
6516      DomQueryConstructor.fn[name] = function (selector, filter) {
6517        var self = this;
6518        var result = [];
6519        self.each(function () {
6520          var nodes = fn.call(result, this, selector, result);
6521          if (nodes) {
6522            if (DomQuery.isArray(nodes)) {
6523              result.push.apply(result, nodes);
6524            } else {
6525              result.push(nodes);
6526            }
6527          }
6528        });
6529        if (this.length > 1) {
6530          result = DomQuery.unique(result);
6531          if (name.indexOf('parents') === 0 || name === 'prevUntil') {
6532            result = result.reverse();
6533          }
6534        }
6535        var wrappedResult = DomQuery(result);
6536        if (filter) {
6537          return wrappedResult.filter(filter);
6538        }
6539        return wrappedResult;
6540      };
6541    });
6542    DomQueryConstructor.fn.is = function (selector) {
6543      return !!selector && this.filter(selector).length > 0;
6544    };
6545    DomQueryConstructor.fn.init.prototype = DomQueryConstructor.fn;
6546    DomQueryConstructor.overrideDefaults = function (callback) {
6547      var defaults;
6548      var sub = function (selector, context) {
6549        defaults = defaults || callback();
6550        if (arguments.length === 0) {
6551          selector = defaults.element;
6552        }
6553        if (!context) {
6554          context = defaults.context;
6555        }
6556        return new sub.fn.init(selector, context);
6557      };
6558      DomQuery.extend(sub, this);
6559      return sub;
6560    };
6561    DomQueryConstructor.attrHooks = attrHooks;
6562    DomQueryConstructor.cssHooks = cssHooks;
6563    var DomQuery = DomQueryConstructor;
6564
6565    var each$f = Tools.each;
6566    var grep$1 = Tools.grep;
6567    var isIE = Env.ie;
6568    var simpleSelectorRe = /^([a-z0-9],?)+$/i;
6569    var setupAttrHooks = function (styles, settings, getContext) {
6570      var keepValues = settings.keep_values;
6571      var keepUrlHook = {
6572        set: function ($elm, value, name) {
6573          if (settings.url_converter && value !== null) {
6574            value = settings.url_converter.call(settings.url_converter_scope || getContext(), value, name, $elm[0]);
6575          }
6576          $elm.attr('data-mce-' + name, value).attr(name, value);
6577        },
6578        get: function ($elm, name) {
6579          return $elm.attr('data-mce-' + name) || $elm.attr(name);
6580        }
6581      };
6582      var attrHooks = {
6583        style: {
6584          set: function ($elm, value) {
6585            if (value !== null && typeof value === 'object') {
6586              $elm.css(value);
6587              return;
6588            }
6589            if (keepValues) {
6590              $elm.attr('data-mce-style', value);
6591            }
6592            if (value !== null && typeof value === 'string') {
6593              $elm.removeAttr('style');
6594              $elm.css(styles.parse(value));
6595            } else {
6596              $elm.attr('style', value);
6597            }
6598          },
6599          get: function ($elm) {
6600            var value = $elm.attr('data-mce-style') || $elm.attr('style');
6601            value = styles.serialize(styles.parse(value), $elm[0].nodeName);
6602            return value;
6603          }
6604        }
6605      };
6606      if (keepValues) {
6607        attrHooks.href = attrHooks.src = keepUrlHook;
6608      }
6609      return attrHooks;
6610    };
6611    var updateInternalStyleAttr = function (styles, $elm) {
6612      var rawValue = $elm.attr('style');
6613      var value = styles.serialize(styles.parse(rawValue), $elm[0].nodeName);
6614      if (!value) {
6615        value = null;
6616      }
6617      $elm.attr('data-mce-style', value);
6618    };
6619    var findNodeIndex = function (node, normalized) {
6620      var idx = 0, lastNodeType, nodeType;
6621      if (node) {
6622        for (lastNodeType = node.nodeType, node = node.previousSibling; node; node = node.previousSibling) {
6623          nodeType = node.nodeType;
6624          if (normalized && nodeType === 3) {
6625            if (nodeType === lastNodeType || !node.nodeValue.length) {
6626              continue;
6627            }
6628          }
6629          idx++;
6630          lastNodeType = nodeType;
6631        }
6632      }
6633      return idx;
6634    };
6635    var DOMUtils = function (doc, settings) {
6636      if (settings === void 0) {
6637        settings = {};
6638      }
6639      var addedStyles = {};
6640      var win = window;
6641      var files = {};
6642      var counter = 0;
6643      var stdMode = true;
6644      var boxModel = true;
6645      var styleSheetLoader = instance.forElement(SugarElement.fromDom(doc), {
6646        contentCssCors: settings.contentCssCors,
6647        referrerPolicy: settings.referrerPolicy
6648      });
6649      var boundEvents = [];
6650      var schema = settings.schema ? settings.schema : Schema({});
6651      var styles = Styles({
6652        url_converter: settings.url_converter,
6653        url_converter_scope: settings.url_converter_scope
6654      }, settings.schema);
6655      var events = settings.ownEvents ? new EventUtils() : EventUtils.Event;
6656      var blockElementsMap = schema.getBlockElements();
6657      var $ = DomQuery.overrideDefaults(function () {
6658        return {
6659          context: doc,
6660          element: self.getRoot()
6661        };
6662      });
6663      var isBlock = function (node) {
6664        if (typeof node === 'string') {
6665          return !!blockElementsMap[node];
6666        } else if (node) {
6667          var type = node.nodeType;
6668          if (type) {
6669            return !!(type === 1 && blockElementsMap[node.nodeName]);
6670          }
6671        }
6672        return false;
6673      };
6674      var get = function (elm) {
6675        return elm && doc && isString$1(elm) ? doc.getElementById(elm) : elm;
6676      };
6677      var $$ = function (elm) {
6678        return $(typeof elm === 'string' ? get(elm) : elm);
6679      };
6680      var getAttrib = function (elm, name, defaultVal) {
6681        var hook, value;
6682        var $elm = $$(elm);
6683        if ($elm.length) {
6684          hook = attrHooks[name];
6685          if (hook && hook.get) {
6686            value = hook.get($elm, name);
6687          } else {
6688            value = $elm.attr(name);
6689          }
6690        }
6691        if (typeof value === 'undefined') {
6692          value = defaultVal || '';
6693        }
6694        return value;
6695      };
6696      var getAttribs = function (elm) {
6697        var node = get(elm);
6698        if (!node) {
6699          return [];
6700        }
6701        return node.attributes;
6702      };
6703      var setAttrib = function (elm, name, value) {
6704        if (value === '') {
6705          value = null;
6706        }
6707        var $elm = $$(elm);
6708        var originalValue = $elm.attr(name);
6709        if (!$elm.length) {
6710          return;
6711        }
6712        var hook = attrHooks[name];
6713        if (hook && hook.set) {
6714          hook.set($elm, value, name);
6715        } else {
6716          $elm.attr(name, value);
6717        }
6718        if (originalValue !== value && settings.onSetAttrib) {
6719          settings.onSetAttrib({
6720            attrElm: $elm,
6721            attrName: name,
6722            attrValue: value
6723          });
6724        }
6725      };
6726      var clone = function (node, deep) {
6727        if (!isIE || node.nodeType !== 1 || deep) {
6728          return node.cloneNode(deep);
6729        } else {
6730          var clone_1 = doc.createElement(node.nodeName);
6731          each$f(getAttribs(node), function (attr) {
6732            setAttrib(clone_1, attr.nodeName, getAttrib(node, attr.nodeName));
6733          });
6734          return clone_1;
6735        }
6736      };
6737      var getRoot = function () {
6738        return settings.root_element || doc.body;
6739      };
6740      var getViewPort = function (argWin) {
6741        var vp = getBounds(argWin);
6742        return {
6743          x: vp.x,
6744          y: vp.y,
6745          w: vp.width,
6746          h: vp.height
6747        };
6748      };
6749      var getPos$1 = function (elm, rootElm) {
6750        return getPos(doc.body, get(elm), rootElm);
6751      };
6752      var setStyle = function (elm, name, value) {
6753        var $elm = isString$1(name) ? $$(elm).css(name, value) : $$(elm).css(name);
6754        if (settings.update_styles) {
6755          updateInternalStyleAttr(styles, $elm);
6756        }
6757      };
6758      var setStyles = function (elm, stylesArg) {
6759        var $elm = $$(elm).css(stylesArg);
6760        if (settings.update_styles) {
6761          updateInternalStyleAttr(styles, $elm);
6762        }
6763      };
6764      var getStyle = function (elm, name, computed) {
6765        var $elm = $$(elm);
6766        if (computed) {
6767          return $elm.css(name);
6768        }
6769        name = name.replace(/-(\D)/g, function (a, b) {
6770          return b.toUpperCase();
6771        });
6772        if (name === 'float') {
6773          name = Env.browser.isIE() ? 'styleFloat' : 'cssFloat';
6774        }
6775        return $elm[0] && $elm[0].style ? $elm[0].style[name] : undefined;
6776      };
6777      var getSize = function (elm) {
6778        var w, h;
6779        elm = get(elm);
6780        w = getStyle(elm, 'width');
6781        h = getStyle(elm, 'height');
6782        if (w.indexOf('px') === -1) {
6783          w = 0;
6784        }
6785        if (h.indexOf('px') === -1) {
6786          h = 0;
6787        }
6788        return {
6789          w: parseInt(w, 10) || elm.offsetWidth || elm.clientWidth,
6790          h: parseInt(h, 10) || elm.offsetHeight || elm.clientHeight
6791        };
6792      };
6793      var getRect = function (elm) {
6794        elm = get(elm);
6795        var pos = getPos$1(elm);
6796        var size = getSize(elm);
6797        return {
6798          x: pos.x,
6799          y: pos.y,
6800          w: size.w,
6801          h: size.h
6802        };
6803      };
6804      var is = function (elm, selector) {
6805        var i;
6806        if (!elm) {
6807          return false;
6808        }
6809        if (!Array.isArray(elm)) {
6810          if (selector === '*') {
6811            return elm.nodeType === 1;
6812          }
6813          if (simpleSelectorRe.test(selector)) {
6814            var selectors = selector.toLowerCase().split(/,/);
6815            var elmName = elm.nodeName.toLowerCase();
6816            for (i = selectors.length - 1; i >= 0; i--) {
6817              if (selectors[i] === elmName) {
6818                return true;
6819              }
6820            }
6821            return false;
6822          }
6823          if (elm.nodeType && elm.nodeType !== 1) {
6824            return false;
6825          }
6826        }
6827        var elms = !Array.isArray(elm) ? [elm] : elm;
6828        return Sizzle(selector, elms[0].ownerDocument || elms[0], null, elms).length > 0;
6829      };
6830      var getParents = function (elm, selector, root, collect) {
6831        var result = [];
6832        var selectorVal;
6833        var node = get(elm);
6834        collect = collect === undefined;
6835        root = root || (getRoot().nodeName !== 'BODY' ? getRoot().parentNode : null);
6836        if (Tools.is(selector, 'string')) {
6837          selectorVal = selector;
6838          if (selector === '*') {
6839            selector = function (node) {
6840              return node.nodeType === 1;
6841            };
6842          } else {
6843            selector = function (node) {
6844              return is(node, selectorVal);
6845            };
6846          }
6847        }
6848        while (node) {
6849          if (node === root || isNullable(node.nodeType) || isDocument$1(node) || isDocumentFragment(node)) {
6850            break;
6851          }
6852          if (!selector || typeof selector === 'function' && selector(node)) {
6853            if (collect) {
6854              result.push(node);
6855            } else {
6856              return [node];
6857            }
6858          }
6859          node = node.parentNode;
6860        }
6861        return collect ? result : null;
6862      };
6863      var getParent = function (node, selector, root) {
6864        var parents = getParents(node, selector, root, false);
6865        return parents && parents.length > 0 ? parents[0] : null;
6866      };
6867      var _findSib = function (node, selector, name) {
6868        var func = selector;
6869        if (node) {
6870          if (typeof selector === 'string') {
6871            func = function (node) {
6872              return is(node, selector);
6873            };
6874          }
6875          for (node = node[name]; node; node = node[name]) {
6876            if (typeof func === 'function' && func(node)) {
6877              return node;
6878            }
6879          }
6880        }
6881        return null;
6882      };
6883      var getNext = function (node, selector) {
6884        return _findSib(node, selector, 'nextSibling');
6885      };
6886      var getPrev = function (node, selector) {
6887        return _findSib(node, selector, 'previousSibling');
6888      };
6889      var select = function (selector, scope) {
6890        return Sizzle(selector, get(scope) || settings.root_element || doc, []);
6891      };
6892      var run = function (elm, func, scope) {
6893        var result;
6894        var node = typeof elm === 'string' ? get(elm) : elm;
6895        if (!node) {
6896          return false;
6897        }
6898        if (Tools.isArray(node) && (node.length || node.length === 0)) {
6899          result = [];
6900          each$f(node, function (elm, i) {
6901            if (elm) {
6902              result.push(func.call(scope, typeof elm === 'string' ? get(elm) : elm, i));
6903            }
6904          });
6905          return result;
6906        }
6907        var context = scope ? scope : this;
6908        return func.call(context, node);
6909      };
6910      var setAttribs = function (elm, attrs) {
6911        $$(elm).each(function (i, node) {
6912          each$f(attrs, function (value, name) {
6913            setAttrib(node, name, value);
6914          });
6915        });
6916      };
6917      var setHTML = function (elm, html) {
6918        var $elm = $$(elm);
6919        if (isIE) {
6920          $elm.each(function (i, target) {
6921            if (target.canHaveHTML === false) {
6922              return;
6923            }
6924            while (target.firstChild) {
6925              target.removeChild(target.firstChild);
6926            }
6927            try {
6928              target.innerHTML = '<br>' + html;
6929              target.removeChild(target.firstChild);
6930            } catch (ex) {
6931              DomQuery('<div></div>').html('<br>' + html).contents().slice(1).appendTo(target);
6932            }
6933            return html;
6934          });
6935        } else {
6936          $elm.html(html);
6937        }
6938      };
6939      var add = function (parentElm, name, attrs, html, create) {
6940        return run(parentElm, function (parentElm) {
6941          var newElm = typeof name === 'string' ? doc.createElement(name) : name;
6942          setAttribs(newElm, attrs);
6943          if (html) {
6944            if (typeof html !== 'string' && html.nodeType) {
6945              newElm.appendChild(html);
6946            } else if (typeof html === 'string') {
6947              setHTML(newElm, html);
6948            }
6949          }
6950          return !create ? parentElm.appendChild(newElm) : newElm;
6951        });
6952      };
6953      var create = function (name, attrs, html) {
6954        return add(doc.createElement(name), name, attrs, html, true);
6955      };
6956      var decode = Entities.decode;
6957      var encode = Entities.encodeAllRaw;
6958      var createHTML = function (name, attrs, html) {
6959        var outHtml = '', key;
6960        outHtml += '<' + name;
6961        for (key in attrs) {
6962          if (hasNonNullableKey(attrs, key)) {
6963            outHtml += ' ' + key + '="' + encode(attrs[key]) + '"';
6964          }
6965        }
6966        if (typeof html !== 'undefined') {
6967          return outHtml + '>' + html + '</' + name + '>';
6968        }
6969        return outHtml + ' />';
6970      };
6971      var createFragment = function (html) {
6972        var node;
6973        var container = doc.createElement('div');
6974        var frag = doc.createDocumentFragment();
6975        frag.appendChild(container);
6976        if (html) {
6977          container.innerHTML = html;
6978        }
6979        while (node = container.firstChild) {
6980          frag.appendChild(node);
6981        }
6982        frag.removeChild(container);
6983        return frag;
6984      };
6985      var remove = function (node, keepChildren) {
6986        var $node = $$(node);
6987        if (keepChildren) {
6988          $node.each(function () {
6989            var child;
6990            while (child = this.firstChild) {
6991              if (child.nodeType === 3 && child.data.length === 0) {
6992                this.removeChild(child);
6993              } else {
6994                this.parentNode.insertBefore(child, this);
6995              }
6996            }
6997          }).remove();
6998        } else {
6999          $node.remove();
7000        }
7001        return $node.length >
7001 1 ? $node.toArray() : $node[0];
7002      };
7003      var removeAllAttribs = function (e) {
7004        return run(e, function (e) {
7005          var i;
7006          var attrs = e.attributes;
7007          for (i = attrs.length - 1; i >= 0; i--) {
7008            e.removeAttributeNode(attrs.item(i));
7009          }
7010        });
7011      };
7012      var parseStyle = function (cssText) {
7013        return styles.parse(cssText);
7014      };
7015      var serializeStyle = function (stylesArg, name) {
7016        return styles.serialize(stylesArg, name);
7017      };
7018      var addStyle = function (cssText) {
7019        var head, styleElm;
7020        if (self !== DOMUtils.DOM && doc === document) {
7021          if (addedStyles[cssText]) {
7022            return;
7023          }
7024          addedStyles[cssText] = true;
7025        }
7026        styleElm = doc.getElementById('mceDefaultStyles');
7027        if (!styleElm) {
7028          styleElm = doc.createElement('style');
7029          styleElm.id = 'mceDefaultStyles';
7030          styleElm.type = 'text/css';
7031          head = doc.getElementsByTagName('head')[0];
7032          if (head.firstChild) {
7033            head.insertBefore(styleElm, head.firstChild);
7034          } else {
7035            head.appendChild(styleElm);
7036          }
7037        }
7038        if (styleElm.styleSheet) {
7039          styleElm.styleSheet.cssText += cssText;
7040        } else {
7041          styleElm.appendChild(doc.createTextNode(cssText));
7042        }
7043      };
7044      var loadCSS = function (urls) {
7045        if (!urls) {
7046          urls = '';
7047        }
7048        each$k(urls.split(','), function (url) {
7049          files[url] = true;
7050          styleSheetLoader.load(url, noop);
7051        });
7052      };
7053      var toggleClass = function (elm, cls, state) {
7054        $$(elm).toggleClass(cls, state).each(function () {
7055          if (this.className === '') {
7056            DomQuery(this).attr('class', null);
7057          }
7058        });
7059      };
7060      var addClass = function (elm, cls) {
7061        $$(elm).addClass(cls);
7062      };
7063      var removeClass = function (elm, cls) {
7064        toggleClass(elm, cls, false);
7065      };
7066      var hasClass = function (elm, cls) {
7067        return $$(elm).hasClass(cls);
7068      };
7069      var show = function (elm) {
7070        $$(elm).show();
7071      };
7072      var hide = function (elm) {
7073        $$(elm).hide();
7074      };
7075      var isHidden = function (elm) {
7076        return $$(elm).css('display') === 'none';
7077      };
7078      var uniqueId = function (prefix) {
7079        return (!prefix ? 'mce_' : prefix) + counter++;
7080      };
7081      var getOuterHTML = function (elm) {
7082        var node = typeof elm === 'string' ? get(elm) : elm;
7083        return isElement$5(node) ? node.outerHTML : DomQuery('<div></div>').append(DomQuery(node).clone()).html();
7084      };
7085      var setOuterHTML = function (elm, html) {
7086        $$(elm).each(function () {
7087          try {
7088            if ('outerHTML' in this) {
7089              this.outerHTML = html;
7090              return;
7091            }
7092          } catch (ex) {
7093          }
7094          remove(DomQuery(this).html(html), true);
7095        });
7096      };
7097      var insertAfter = function (node, reference) {
7098        var referenceNode = get(reference);
7099        return run(node, function (node) {
7100          var parent = referenceNode.parentNode;
7101          var nextSibling = referenceNode.nextSibling;
7102          if (nextSibling) {
7103            parent.insertBefore(node, nextSibling);
7104          } else {
7105            parent.appendChild(node);
7106          }
7107          return node;
7108        });
7109      };
7110      var replace = function (newElm, oldElm, keepChildren) {
7111        return run(oldElm, function (oldElm) {
7112          if (Tools.is(oldElm, 'array')) {
7113            newElm = newElm.cloneNode(true);
7114          }
7115          if (keepChildren) {
7116            each$f(grep$1(oldElm.childNodes), function (node) {
7117              newElm.appendChild(node);
7118            });
7119          }
7120          return oldElm.parentNode.replaceChild(newElm, oldElm);
7121        });
7122      };
7123      var rename = function (elm, name) {
7124        var newElm;
7125        if (elm.nodeName !== name.toUpperCase()) {
7126          newElm = create(name);
7127          each$f(getAttribs(elm), function (attrNode) {
7128            setAttrib(newElm, attrNode.nodeName, getAttrib(elm, attrNode.nodeName));
7129          });
7130          replace(newElm, elm, true);
7131        }
7132        return newElm || elm;
7133      };
7134      var findCommonAncestor = function (a, b) {
7135        var ps = a, pe;
7136        while (ps) {
7137          pe = b;
7138          while (pe && ps !== pe) {
7139            pe = pe.parentNode;
7140          }
7141          if (ps === pe) {
7142            break;
7143          }
7144          ps = ps.parentNode;
7145        }
7146        if (!ps && a.ownerDocument) {
7147          return a.ownerDocument.documentElement;
7148        }
7149        return ps;
7150      };
7151      var toHex = function (rgbVal) {
7152        return styles.toHex(Tools.trim(rgbVal));
7153      };
7154      var isNonEmptyElement = function (node) {
7155        if (isElement$5(node)) {
7156          var isNamedAnchor = node.nodeName.toLowerCase() === 'a' && !getAttrib(node, 'href') && getAttrib(node, 'id');
7157          if (getAttrib(node, 'name') || getAttrib(node, 'data-mce-bookmark') || isNamedAnchor) {
7158            return true;
7159          }
7160        }
7161        return false;
7162      };
7163      var isEmpty = function (node, elements) {
7164        var type, name, brCount = 0;
7165        if (isNonEmptyElement(node)) {
7166          return false;
7167        }
7168        node = node.firstChild;
7169        if (node) {
7170          var walker = new DomTreeWalker(node, node.parentNode);
7171          var whitespace = schema ? schema.getWhiteSpaceElements() : {};
7172          elements = elements || (schema ? schema.getNonEmptyElements() : null);
7173          do {
7174            type = node.nodeType;
7175            if (isElement$5(node)) {
7176              var bogusVal = node.getAttribute('data-mce-bogus');
7177              if (bogusVal) {
7178                node = walker.next(bogusVal === 'all');
7179                continue;
7180              }
7181              name = node.nodeName.toLowerCase();
7182              if (elements && elements[name]) {
7183                if (name === 'br') {
7184                  brCount++;
7185                  node = walker.next();
7186                  continue;
7187                }
7188                return false;
7189              }
7190              if (isNonEmptyElement(node)) {
7191                return false;
7192              }
7193            }
7194            if (type === 8) {
7195              return false;
7196            }
7197            if (type === 3 && !isWhitespaceText(node.nodeValue)) {
7198              return false;
7199            }
7200            if (type === 3 && node.parentNode && whitespace[node.parentNode.nodeName] && isWhitespaceText(node.nodeValue)) {
7201              return false;
7202            }
7203            node = walker.next();
7204          } while (node);
7205        }
7206        return brCount <= 1;
7207      };
7208      var createRng = function () {
7209        return doc.createRange();
7210      };
7211      var split = function (parentElm, splitElm, replacementElm) {
7212        var range = createRng();
7213        var beforeFragment;
7214        var afterFragment;
7215        var parentNode;
7216        if (parentElm && splitElm) {
7217          range.setStart(parentElm.parentNode, findNodeIndex(parentElm));
7218          range.setEnd(splitElm.parentNode, findNodeIndex(splitElm));
7219          beforeFragment = range.extractContents();
7220          range = createRng();
7221          range.setStart(splitElm.parentNode, findNodeIndex(splitElm) + 1);
7222          range.setEnd(parentElm.parentNode, findNodeIndex(parentElm) + 1);
7223          afterFragment = range.extractContents();
7224          parentNode = parentElm.parentNode;
7225          parentNode.insertBefore(trimNode(self, beforeFragment), parentElm);
7226          if (replacementElm) {
7227            parentNode.insertBefore(replacementElm, parentElm);
7228          } else {
7229            parentNode.insertBefore(splitElm, parentElm);
7230          }
7231          parentNode.insertBefore(trimNode(self, afterFragment), parentElm);
7232          remove(parentElm);
7233          return replacementElm || splitElm;
7234        }
7235      };
7236      var bind = function (target, name, func, scope) {
7237        if (Tools.isArray(target)) {
7238          var i = target.length;
7239          var rv = [];
7240          while (i--) {
7241            rv[i] = bind(target[i], name, func, scope);
7242          }
7243          return rv;
7244        }
7245        if (settings.collect && (target === doc || target === win)) {
7246          boundEvents.push([
7247            target,
7248            name,
7249            func,
7250            scope
7251          ]);
7252        }
7253        var output = events.bind(target, name, func, scope || self);
7254        return output;
7255      };
7256      var unbind = function (target, name, func) {
7257        if (Tools.isArray(target)) {
7258          var i = target.length;
7259          var rv = [];
7260          while (i--) {
7261            rv[i] = unbind(target[i], name, func);
7262          }
7263          return rv;
7264        } else {
7265          if (boundEvents.length > 0 && (target === doc || target === win)) {
7266            var i = boundEvents.length;
7267            while (i--) {
7268              var item = boundEvents[i];
7269              if (target === item[0] && (!name || name === item[1]) && (!func || func === item[2])) {
7270                events.unbind(item[0], item[1], item[2]);
7271              }
7272            }
7273          }
7274          return events.unbind(target, name, func);
7275        }
7276      };
7277      var fire = function (target, name, evt) {
7278        return events.fire(target, name, evt);
7279      };
7280      var getContentEditable = function (node) {
7281        if (node && isElement$5(node)) {
7282          var contentEditable = node.getAttribute('data-mce-contenteditable');
7283          if (contentEditable && contentEditable !== 'inherit') {
7284            return contentEditable;
7285          }
7286          return node.contentEditable !== 'inherit' ? node.contentEditable : null;
7287        } else {
7288          return null;
7289        }
7290      };
7291      var getContentEditableParent = function (node) {
7292        var root = getRoot();
7293        var state = null;
7294        for (; node && node !== root; node = node.parentNode) {
7295          state = getContentEditable(node);
7296          if (state !== null) {
7297            break;
7298          }
7299        }
7300        return state;
7301      };
7302      var destroy = function () {
7303        if (boundEvents.length > 0) {
7304          var i = boundEvents.length;
7305          while (i--) {
7306            var item = boundEvents[i];
7307            events.unbind(item[0], item[1], item[2]);
7308          }
7309        }
7310        each$j(files, function (_, url) {
7311          styleSheetLoader.unload(url);
7312          delete files[url];
7313        });
7314        if (Sizzle.setDocument) {
7315          Sizzle.setDocument();
7316        }
7317      };
7318      var isChildOf = function (node, parent) {
7319        if (!isIE) {
7320          return node === parent || parent.contains(node);
7321        } else {
7322          while (node) {
7323            if (parent === node) {
7324              return true;
7325            }
7326            node = node.parentNode;
7327          }
7328          return false;
7329        }
7330      };
7331      var dumpRng = function (r) {
7332        return 'startContainer: ' + r.startContainer.nodeName + ', startOffset: ' + r.startOffset + ', endContainer: ' + r.endContainer.nodeName + ', endOffset: ' + r.endOffset;
7333      };
7334      var self = {
7335        doc: doc,
7336        settings: settings,
7337        win: win,
7338        files: files,
7339        stdMode: stdMode,
7340        boxModel: boxModel,
7341        styleSheetLoader: styleSheetLoader,
7342        boundEvents: boundEvents,
7343        styles: styles,
7344        schema: schema,
7345        events: events,
7346        isBlock: isBlock,
7347        $: $,
7348        $$: $$,
7349        root: null,
7350        clone: clone,
7351        getRoot: getRoot,
7352        getViewPort: getViewPort,
7353        getRect: getRect,
7354        getSize: getSize,
7355        getParent: getParent,
7356        getParents: getParents,
7357        get: get,
7358        getNext: getNext,
7359        getPrev: getPrev,
7360        select: select,
7361        is: is,
7362        add: add,
7363        create: create,
7364        createHTML: createHTML,
7365        createFragment: createFragment,
7366        remove: remove,
7367        setStyle: setStyle,
7368        getStyle: getStyle,
7369        setStyles: setStyles,
7370        removeAllAttribs: removeAllAttribs,
7371        setAttrib: setAttrib,
7372        setAttribs: setAttribs,
7373        getAttrib: getAttrib,
7374        getPos: getPos$1,
7375        parseStyle: parseStyle,
7376        serializeStyle: serializeStyle,
7377        addStyle: addStyle,
7378        loadCSS: loadCSS,
7379        addClass: addClass,
7380        removeClass: removeClass,
7381        hasClass: hasClass,
7382        toggleClass: toggleClass,
7383        show: show,
7384        hide: hide,
7385        isHidden: isHidden,
7386        uniqueId: uniqueId,
7387        setHTML: setHTML,
7388        getOuterHTML: getOuterHTML,
7389        setOuterHTML: setOuterHTML,
7390        decode: decode,
7391        encode: encode,
7392        insertAfter: insertAfter,
7393        replace: replace,
7394        rename: rename,
7395        findCommonAncestor: findCommonAncestor,
7396        toHex: toHex,
7397        run: run,
7398        getAttribs: getAttribs,
7399        isEmpty: isEmpty,
7400        createRng: createRng,
7401        nodeIndex: findNodeIndex,
7402        split: split,
7403        bind: bind,
7404        unbind: unbind,
7405        fire: fire,
7406        getContentEditable: getContentEditable,
7407        getContentEditableParent: getContentEditableParent,
7408        destroy: destroy,
7409        isChildOf: isChildOf,
7410        dumpRng: dumpRng
7411      };
7412      var attrHooks = setupAttrHooks(styles, settings, constant(self));
7413      return self;
7414    };
7415    DOMUtils.DOM = DOMUtils(document);
7416    DOMUtils.nodeIndex = findNodeIndex;
7417
7418    var DOM$a = DOMUtils.DOM;
7419    var each$e = Tools.each, grep = Tools.grep;
7420    var QUEUED = 0;
7421    var LOADING = 1;
7422    var LOADED = 2;
7423    var FAILED = 3;
7424    var ScriptLoader = function () {
7425      function ScriptLoader(settings) {
7426        if (settings === void 0) {
7427          settings = {};
7428        }
7429        this.states = {};
7430        this.queue = [];
7431        this.scriptLoadedCallbacks = {};
7432        this.queueLoadedCallbacks = [];
7433        this.loading = 0;
7434        this.settings = settings;
7435      }
7436      ScriptLoader.prototype._setReferrerPolicy = function (referrerPolicy) {
7437        this.settings.referrerPolicy = referrerPolicy;
7438      };
7439      ScriptLoader.prototype.loadScript = function (url, success, failure) {
7440        var dom = DOM$a;
7441        var elm;
7442        var cleanup = function () {
7443          dom.remove(id);
7444          if (elm) {
7445            elm.onerror = elm.onload = elm = null;
7446          }
7447        };
7448        var done = function () {
7449          cleanup();
7450          success();
7451        };
7452        var error = function () {
7453          cleanup();
7454          if (isFunction(failure)) {
7455            failure();
7456          } else {
7457            if (typeof console !== 'undefined' && console.log) {
7458              console.log('Failed to load script: ' + url);
7459            }
7460          }
7461        };
7462        var id = dom.uniqueId();
7463        elm = document.createElement('script');
7464        elm.id = id;
7465        elm.type = 'text/javascript';
7466        elm.src = Tools._addCacheSuffix(url);
7467        if (this.settings.referrerPolicy) {
7468          dom.setAttrib(elm, 'referrerpolicy', this.settings.referrerPolicy);
7469        }
7470        elm.onload = done;
7471        elm.onerror = error;
7472        (document.getElementsByTagName('head')[0] || document.body).appendChild(elm);
7473      };
7474      ScriptLoader.prototype.isDone = function (url) {
7475        return this.states[url] === LOADED;
7476      };
7477      ScriptLoader.prototype.markDone = function (url) {
7478        this.states[url] = LOADED;
7479      };
7480      ScriptLoader.prototype.add = function (url, success, scope, failure) {
7481        var state = this.states[url];
7482        this.queue.push(url);
7483        if (state === undefined) {
7484          this.states[url] = QUEUED;
7485        }
7486        if (success) {
7487          if (!this.scriptLoadedCallbacks[url]) {
7488            this.scriptLoadedCallbacks[url] = [];
7489          }
7490          this.scriptLoadedCallbacks[url].push({
7491            success: success,
7492            failure: failure,
7493            scope: scope || this
7494          });
7495        }
7496      };
7497      ScriptLoader.prototype.load = function (url, success, scope, failure) {
7498        return this.add(url, success, scope, failure);
7499      };
7500      ScriptLoader.prototype.remove = function (url) {
7501        delete this.states[url];
7502        delete this.scriptLoadedCallbacks[url];
7503      };
7504      ScriptLoader.prototype.loadQueue = function (success, scope, failure) {
7505        this.loadScripts(this.queue, success, scope, failure);
7506      };
7507      ScriptLoader.prototype.loadScripts = function (scripts, success, scope, failure) {
7508        var self = this;
7509        var failures = [];
7510        var execCallbacks = function (name, url) {
7511          each$e(self.scriptLoadedCallbacks[url], function (callback) {
7512            if (isFunction(callback[name])) {
7513              callback[name].call(callback.scope);
7514            }
7515          });
7516          self.scriptLoadedCallbacks[url] = undefined;
7517        };
7518        self.queueLoadedCallbacks.push({
7519          success: success,
7520          failure: failure,
7521          scope: scope || this
7522        });
7523        var loadScripts = function () {
7524          var loadingScripts = grep(scripts);
7525          scripts.length = 0;
7526          each$e(loadingScripts, function (url) {
7527            if (self.states[url] === LOADED) {
7528              execCallbacks('success', url);
7529              return;
7530            }
7531            if (self.states[url] === FAILED) {
7532              execCallbacks('failure', url);
7533              return;
7534            }
7535            if (self.states[url] !== LOADING) {
7536              self.states[url] = LOADING;
7537              self.loading++;
7538              self.loadScript(url, function () {
7539                self.states[url] = LOADED;
7540                self.loading--;
7541                execCallbacks('success', url);
7542                loadScripts();
7543              }, function () {
7544                self.states[url] = FAILED;
7545                self.loading--;
7546                failures.push(url);
7547                execCallbacks('failure', url);
7548                loadScripts();
7549              });
7550            }
7551          });
7552          if (!self.loading) {
7553            var notifyCallbacks = self.queueLoadedCallbacks.slice(0);
7554            self.queueLoadedCallbacks.length = 0;
7555            each$e(notifyCallbacks, function (callback) {
7556              if (failures.length === 0) {
7557                if (isFunction(callback.success)) {
7558                  callback.success.call(callback.scope);
7559                }
7560              } else {
7561                if (isFunction(callback.failure)) {
7562                  callback.failure.call(callback.scope, failures);
7563                }
7564              }
7565            });
7566          }
7567        };
7568        loadScripts();
7569      };
7570      ScriptLoader.ScriptLoader = new ScriptLoader();
7571      return ScriptLoader;
7572    }();
7573
7574    var Cell = function (initial) {
7575      var value = initial;
7576      var get = function () {
7577        return value;
7578      };
7579      var set = function (v) {
7580        value = v;
7581      };
7582      return {
7583        get: get,
7584        set: set
7585      };
7586    };
7587
7588    var isRaw = function (str) {
7589      return isObject(str) && has$2(str, 'raw');
7590    };
7591    var isTokenised = function (str) {
7592      return isArray$1(str) && str.length > 1;
7593    };
7594    var data = {};
7595    var currentCode = Cell('en');
7596    var getLanguageData = function () {
7597      return get$9(data, currentCode.get());
7598    };
7599    var getData = function () {
7600      return map$2(data, function (value) {
7601        return __assign({}, value);
7602      });
7603    };
7604    var setCode = function (newCode) {
7605      if (newCode) {
7606        currentCode.set(newCode);
7607      }
7608    };
7609    var getCode = function () {
7610      return currentCode.get();
7611    };
7612    var add$4 = function (code, items) {
7613      var langData = data[code];
7614      if (!langData) {
7615        data[code] = langData = {};
7616      }
7617      each$j(items, function (translation, name) {
7618        langData[name.toLowerCase()] = translation;
7619      });
7620    };
7621    var translate = function (text) {
7622      var langData = getLanguageData().getOr({});
7623      var toString = function (obj) {
7624        if (isFunction(obj)) {
7625          return Object.prototype.toString.call(obj);
7626        }
7627        return !isEmpty(obj) ? '' + obj : '';
7628      };
7629      var isEmpty = function (text) {
7630        return text === '' || text === null || text === undefined;
7631      };
7632      var getLangData = function (text) {
7633        var textstr = toString(text);
7634        return get$9(langData, textstr.toLowerCase()).map(toString).getOr(textstr);
7635      };
7636      var removeContext = function (str) {
7637        return str.replace(/{context:\w+}$/, '');
7638      };
7639      if (isEmpty(text)) {
7640        return '';
7641      }
7642      if (isRaw(text)) {
7643        return toString(text.raw);
7644      }
7645      if (isTokenised(text)) {
7646        var values_1 = text.slice(1);
7647        var substitued = getLangData(text[0]).replace(/\{([0-9]+)\}/g, function ($1, $2) {
7648          return has$2(values_1, $2) ? toString(values_1[$2]) : $1;
7649        });
7650        return removeContext(substitued);
7651      }
7652      return removeContext(getLangData(text));
7653    };
7654    var isRtl$1 = function () {
7655      return getLanguageData().bind(function (items) {
7656        return get$9(items, '_dir');
7657      }).exists(function (dir) {
7658        return dir === 'rtl';
7659      });
7660    };
7661    var hasCode = function (code) {
7662      return has$2(data, code);
7663    };
7664    var I18n = {
7665      getData: getData,
7666      setCode: setCode,
7667      getCode: getCode,
7668      add: add$4,
7669      translate: translate,
7670      isRtl: isRtl$1,
7671      hasCode: hasCode
7672    };
7673
7674    var AddOnManager = function () {
7675      var items = [];
7676      var urls = {};
7677      var lookup = {};
7678      var _listeners = [];
7679      var runListeners = function (name, state) {
7680        var matchedListeners = filter$4(_listeners, function (listener) {
7681          return listener.name === name && listener.state === state;
7682        });
7683        each$k(matchedListeners, function (listener) {
7684          return listener.callback();
7685        });
7686      };
7687      var get = function (name) {
7688        if (lookup[name]) {
7689          return lookup[name].instance;
7690        }
7691        return undefined;
7692      };
7693      var dependencies = function (name) {
7694        var result;
7695        if (lookup[name]) {
7696          result = lookup[name].dependencies;
7697        }
7698        return result || [];
7699      };
7700      var requireLangPack = function (name, languages) {
7701        if (AddOnManager.languageLoad !== false) {
7702          waitFor(name, function () {
7703            var language = I18n.getCode();
7704            var wrappedLanguages = ',' + (languages || '') + ',';
7705            if (!language || languages && wrappedLanguages.indexOf(',' + language + ',') === -1) {
7706              return;
7707            }
7708            ScriptLoader.ScriptLoader.add(urls[name] + '/langs/' + language + '.js');
7709          }, 'loaded');
7710        }
7711      };
7712      var add = function (id, addOn, dependencies) {
7713        var addOnConstructor = addOn;
7714        items.push(addOnConstructor);
7715        lookup[id] = {
7716          instance: addOnConstructor,
7717          dependencies: dependencies
7718        };
7719        runListeners(id, 'added');
7720        return addOnConstructor;
7721      };
7722      var remove = function (name) {
7723        delete urls[name];
7724        delete lookup[name];
7725      };
7726      var createUrl = function (baseUrl, dep) {
7727        if (typeof dep === 'object') {
7728          return dep;
7729        }
7730        return typeof baseUrl === 'string' ? {
7731          prefix: '',
7732          resource: dep,
7733          suffix: ''
7734        } : {
7735          prefix: baseUrl.prefix,
7736          resource: dep,
7737          suffix: baseUrl.suffix
7738        };
7739      };
7740      var addComponents = function (pluginName, scripts) {
7741        var pluginUrl = urls[pluginName];
7742        each$k(scripts, function (script) {
7743          ScriptLoader.ScriptLoader.add(pluginUrl + '/' + script);
7744        });
7745      };
7746      var loadDependencies = function (name, addOnUrl, success, scope) {
7747        var deps = dependencies(name);
7748        each$k(deps, function (dep) {
7749          var newUrl = createUrl(addOnUrl, dep);
7750          load(newUrl.resource, newUrl, undefined, undefined);
7751        });
7752        if (success) {
7753          if (scope) {
7754            success.call(scope);
7755          } else {
7756            success.call(ScriptLoader);
7757          }
7758        }
7759      };
7760      var load = function (name, addOnUrl, success, scope, failure) {
7761        if (urls[name]) {
7762          return;
7763        }
7764        var urlString = typeof addOnUrl === 'string' ? addOnUrl : addOnUrl.prefix + addOnUrl.resource + addOnUrl.suffix;
7765        if (urlString.indexOf('/') !== 0 && urlString.indexOf('://') === -1) {
7766          urlString = AddOnManager.baseURL + '/' + urlString;
7767        }
7768        urls[name] = urlString.substring(0, urlString.lastIndexOf('/'));
7769        var done = function () {
7770          runListeners(name, 'loaded');
7771          loadDependencies(name, addOnUrl, success, scope);
7772        };
7773        if (lookup[name]) {
7774          done();
7775        } else {
7776          ScriptLoader.ScriptLoader.add(urlString, done, scope, failure);
7777        }
7778      };
7779      var waitFor = function (name, callback, state) {
7780        if (state === void 0) {
7781          state = 'added';
7782        }
7783        if (has$2(lookup, name) && state === 'added') {
7784          callback();
7785        } else if (has$2(urls, name) && state === 'loaded') {
7786          callback();
7787        } else {
7788          _listeners.push({
7789            name: name,
7790            state: state,
7791            callback: callback
7792          });
7793        }
7794      };
7795      return {
7796        items: items,
7797        urls: urls,
7798        lookup: lookup,
7799        _listeners: _listeners,
7800        get: get,
7801        dependencies: dependencies,
7802        requireLangPack: requireLangPack,
7803        add: add,
7804        remove: remove,
7805        createUrl: createUrl,
7806        addComponents: addComponents,
7807        load: load,
7808        waitFor: waitFor
7809      };
7810    };
7811    AddOnManager.languageLoad = true;
7812    AddOnManager.baseURL = '';
7813    AddOnManager.PluginManager = AddOnManager();
7814    AddOnManager.ThemeManager = AddOnManager();
7815
7816    var singleton = function (doRevoke) {
7817      var subject = Cell(Optional.none());
7818      var revoke = function () {
7819        return subject.get().each(doRevoke);
7820      };
7821      var clear = function () {
7822        revoke();
7823        subject.set(Optional.none());
7824      };
7825      var isSet = function () {
7826        return subject.get().isSome();
7827      };
7828      var get = function () {
7829        return subject.get();
7830      };
7831      var set = function (s) {
7832        revoke();
7833        subject.set(Optional.some(s));
7834      };
7835      return {
7836        clear: clear,
7837        isSet: isSet,
7838        get: get,
7839        set: set
7840      };
7841    };
7842    var value = function () {
7843      var subject = singleton(noop);
7844      var on = function (f) {
7845        return subject.get().each(f);
7846      };
7847      return __assign(__assign({}, subject), { on: on });
7848    };
7849
7850    var first = function (fn, rate) {
7851      var timer = null;
7852      var cancel = function () {
7853        if (!isNull(timer)) {
7854          clearTimeout(timer);
7855          timer = null;
7856        }
7857      };
7858      var throttle = function () {
7859        var args = [];
7860        for (var _i = 0; _i < arguments.length; _i++) {
7861          args[_i] = arguments[_i];
7862        }
7863        if (isNull(timer)) {
7864          timer = setTimeout(function () {
7865            timer = null;
7866            fn.apply(null, args);
7867          }, rate);
7868        }
7869      };
7870      return {
7871        cancel: cancel,
7872        throttle: throttle
7873      };
7874    };
7875    var last = function (fn, rate) {
7876      var timer = null;
7877      var cancel = function () {
7878        if (!isNull(timer)) {
7879          clearTimeout(timer);
7880          timer = null;
7881        }
7882      };
7883      var throttle = function () {
7884        var args = [];
7885        for (var _i = 0; _i < arguments.length; _i++) {
7886          args[_i] = arguments[_i];
7887        }
7888        cancel();
7889        timer = setTimeout(function () {
7890          timer = null;
7891          fn.apply(null, args);
7892        }, rate);
7893      };
7894      return {
7895        cancel: cancel,
7896        throttle: throttle
7897      };
7898    };
7899
7900    var read$4 = function (element, attr) {
7901      var value = get$6(element, attr);
7902      return value === undefined || value === '' ? [] : value.split(' ');
7903    };
7904    var add$3 = function (element, attr, id) {
7905      var old = read$4(element, attr);
7906      var nu = old.concat([id]);
7907      set$1(element, attr, nu.join(' '));
7908      return true;
7909    };
7910    var remove$5 = function (element, attr, id) {
7911      var nu = filter$4(read$4(element, attr), function (v) {
7912        return v !== id;
7913      });
7914      if (nu.length > 0) {
7915        set$1(element, attr, nu.join(' '));
7916      } else {
7917        remove$6(element, attr);
7918      }
7919      return false;
7920    };
7921
7922    var supports = function (element) {
7923      return element.dom.classList !== undefined;
7924    };
7925    var get$4 = function (element) {
7926      return read$4(element, 'class');
7927    };
7928    var add$2 = function (element, clazz) {
7929      return add$3(element, 'class', clazz);
7930    };
7931    var remove$4 = function (element, clazz) {
7932      return remove$5(element, 'class', clazz);
7933    };
7934
7935    var add$1 = function (element, clazz) {
7936      if (supports(element)) {
7937        element.dom.classList.add(clazz);
7938      } else {
7939        add$2(element, clazz);
7940      }
7941    };
7942    var cleanClass = function (element) {
7943      var classList = supports(element) ? element.dom.classList : get$4(element);
7944      if (classList.length === 0) {
7945        remove$6(element, 'class');
7946      }
7947    };
7948    var remove$3 = function (element, clazz) {
7949      if (supports(element)) {
7950        var classList = element.dom.classList;
7951        classList.remove(clazz);
7952      } else {
7953        remove$4(element, clazz);
7954      }
7955      cleanClass(element);
7956    };
7957    var has = function (element, clazz) {
7958      return supports(element) && element.dom.classList.contains(clazz);
7959    };
7960
7961    var descendants$1 = function (scope, predicate) {
7962      var result = [];
7963      each$k(children(scope), function (x) {
7964        if (predicate(x)) {
7965          result = result.concat([x]);
7966        }
7967        result = result.concat(descendants$1(x, predicate));
7968      });
7969      return result;
7970    };
7971
7972    var descendants = function (scope, selector) {
7973      return all(selector, scope);
7974    };
7975
7976    var annotation = constant('mce-annotation');
7977    var dataAnnotation = constant('data-mce-annotation');
7978    var dataAnnotationId = constant('data-mce-annotation-uid');
7979
7980    var identify = function (editor, annotationName) {
7981      var rng = editor.selection.getRng();
7982      var start = SugarElement.fromDom(rng.startContainer);
7983      var root = SugarElement.fromDom(editor.getBody());
7984      var selector = annotationName.fold(function () {
7985        return '.' + annotation();
7986      }, function (an) {
7987        return '[' + dataAnnotation() + '="' + an + '"]';
7988      });
7989      var newStart = child$1(start, rng.startOffset).getOr(start);
7990      var closest = closest$2(newStart, selector, function (n) {
7991        return eq(n, root);
7992      });
7993      var getAttr = function (c, property) {
7994        if (has$1(c, property)) {
7995          return Optional.some(get$6(c, property));
7996        } else {
7997          return Optional.none();
7998        }
7999      };
8000      return closest.bind(function (c) {
8001        return getAttr(c, '' + dataAnnotationId()).bind(function (uid) {
8002          return getAttr(c, '' + dataAnnotation()).map(function (name) {
8003            var elements = findMarkers(editor, uid);
8004            return {
8005              uid: uid,
8006              name: name,
8007              elements: elements
8008            };
8009          });
8010        });
8011      });
8012    };
8013    var isAnnotation = function (elem) {
8014      return isElement$6(elem) && has(elem, annotation());
8015    };
8016    var findMarkers = function (editor, uid) {
8017      var body = SugarElement.fromDom(editor.getBody());
8018      return descendants(body, '[' + dataAnnotationId() + '="' + uid + '"]');
8019    };
8020    var findAll = function (editor, name) {
8021      var body = SugarElement.fromDom(editor.getBody());
8022      var markers = descendants(body, '[' + dataAnnotation() + '="' + name + '"]');
8023      var directory = {};
8024      each$k(markers, function (m) {
8025        var uid = get$6(m, dataAnnotationId());
8026        var nodesAlready = get$9(directory, uid).getOr([]);
8027        directory[uid] = nodesAlready.concat([m]);
8028      });
8029      return directory;
8030    };
8031
8032    var setup$n = function (editor, _registry) {
8033      var changeCallbacks = Cell({});
8034      var initData = function () {
8035        return {
8036          listeners: [],
8037          previous: value()
8038        };
8039      };
8040      var withCallbacks = function (name, f) {
8041        updateCallbacks(name, function (data) {
8042          f(data);
8043          return data;
8044        });
8045      };
8046      var updateCallbacks = function (name, f) {
8047        var callbackMap = changeCallbacks.get();
8048        var data = get$9(callbackMap, name).getOrThunk(initData);
8049        var outputData = f(data);
8050        callbackMap[name] = outputData;
8051        changeCallbacks.set(callbackMap);
8052      };
8053      var fireCallbacks = function (name, uid, elements) {
8054        withCallbacks(name, function (data) {
8055          each$k(data.listeners, function (f) {
8056            return f(true, name, {
8057              uid: uid,
8058              nodes: map$3(elements, function (elem) {
8059                return elem.dom;
8060              })
8061            });
8062          });
8063        });
8064      };
8065      var fireNoAnnotation = function (name) {
8066        withCallbacks(name, function (data) {
8067          each$k(data.listeners, function (f) {
8068            return f(false, name);
8069          });
8070        });
8071      };
8072      var onNodeChange = last(function () {
8073        var callbackMap = changeCallbacks.get();
8074        var annotations = sort(keys(callbackMap));
8075        each$k(annotations, function (name) {
8076          updateCallbacks(name, function (data) {
8077            var prev = data.previous.get();
8078            identify(editor, Optional.some(name)).fold(function () {
8079              if (prev.isSome()) {
8080                fireNoAnnotation(name);
8081                data.previous.clear();
8082              }
8083            }, function (_a) {
8084              var uid = _a.uid, name = _a.name, elements = _a.elements;
8085              if (!is$1(prev, uid)) {
8086                fireCallbacks(name, uid, elements);
8087                data.previous.set(uid);
8088              }
8089            });
8090            return {
8091              previous: data.previous,
8092              listeners: data.listeners
8093            };
8094          });
8095        });
8096      }, 30);
8097      editor.on('remove', function () {
8098        onNodeChange.cancel();
8099      });
8100      editor.on('NodeChange', function () {
8101        onNodeChange.throttle();
8102      });
8103      var addListener = function (name, f) {
8104        updateCallbacks(name, function (data) {
8105          return {
8106            previous: data.previous,
8107            listeners: data.listeners.concat([f])
8108          };
8109        });
8110      };
8111      return { addListener: addListener };
8112    };
8113
8114    var setup$m = function (editor, registry) {
8115      var identifyParserNode = function (span) {
8116        return Optional.from(span.attr(dataAnnotation())).bind(registry.lookup);
8117      };
8118      editor.on('init', function () {
8119        editor.serializer.addNodeFilter('span', function (spans) {
8120          each$k(spans, function (span) {
8121            identifyParserNode(span).each(function (settings) {
8122              if (settings.persistent === false) {
8123                span.unwrap();
8124              }
8125            });
8126          });
8127        });
8128      });
8129    };
8130
8131    var create$7 = function () {
8132      var annotations = {};
8133      var register = function (name, settings) {
8134        annotations[name] = {
8135          name: name,
8136          settings: settings
8137        };
8138      };
8139      var lookup = function (name) {
8140        return get$9(annotations, name).map(function (a) {
8141          return a.settings;
8142        });
8143      };
8144      return {
8145        register: register,
8146        lookup: lookup
8147      };
8148    };
8149
8150    var unique = 0;
8151    var generate = function (prefix) {
8152      var date = new Date();
8153      var time = date.getTime();
8154      var random = Math.floor(Math.random() * 1000000000);
8155      unique++;
8156      return prefix + '_' + random + unique + String(time);
8157    };
8158
8159    var add = function (element, classes) {
8160      each$k(classes, function (x) {
8161        add$1(element, x);
8162      });
8163    };
8164
8165    var fromHtml = function (html, scope) {
8166      var doc = scope || document;
8167      var div = doc.createElement('div');
8168      div.innerHTML = html;
8169      return children(SugarElement.fromDom(div));
8170    };
8171    var fromDom$1 = function (nodes) {
8172      return map$3(nodes, SugarElement.fromDom);
8173    };
8174
8175    var get$3 = function (element) {
8176      return element.dom.innerHTML;
8177    };
8178    var set = function (element, content) {
8179      var owner = owner$1(element);
8180      var docDom = owner.dom;
8181      var fragment = SugarElement.fromDom(docDom.createDocumentFragment());
8182      var contentElements = fromHtml(content, docDom);
8183      append(fragment, contentElements);
8184      empty(element);
8185      append$1(element, fragment);
8186    };
8187
8188    var clone$1 = function (original, isDeep) {
8189      return SugarElement.fromDom(original.dom.cloneNode(isDeep));
8190    };
8191    var shallow = function (original) {
8192      return clone$1(original, false);
8193    };
8194    var deep$1 = function (original) {
8195      return clone$1(original, true);
8196    };
8197
8198    var TextWalker = function (startNode, rootNode, isBoundary) {
8199      if (isBoundary === void 0) {
8200        isBoundary = never;
8201      }
8202      var walker = new DomTreeWalker(startNode, rootNode);
8203      var walk = function (direction) {
8204        var next;
8205        do {
8206          next = walker[direction]();
8207        } while (next && !isText$7(next) && !isBoundary(next));
8208        return Optional.from(next).filter(isText$7);
8209      };
8210      return {
8211        current: function () {
8212          return Optional.from(walker.current()).filter(isText$7);
8213        },
8214        next: function () {
8215          return walk('next');
8216        },
8217        prev: function () {
8218          return walk('prev');
8219        },
8220        prev2: function () {
8221          return walk('prev2');
8222        }
8223      };
8224    };
8225
8226    var TextSeeker = function (dom, isBoundary) {
8227      var isBlockBoundary = isBoundary ? isBoundary : function (node) {
8228        return dom.isBlock(node) || isBr$5(node) || isContentEditableFalse$b(node);
8229      };
8230      var walk = function (node, offset, walker, process) {
8231        if (isText$7(node)) {
8232          var newOffset = process(node, offset, node.data);
8233          if (newOffset !== -1) {
8234            return Optional.some({
8235              container: node,
8236              offset: newOffset
8237            });
8238          }
8239        }
8240        return walker().bind(function (next) {
8241          return walk(next.container, next.offset, walker, process);
8242        });
8243      };
8244      var backwards = function (node, offset, process, root) {
8245        var walker = TextWalker(node, root, isBlockBoundary);
8246        return walk(node, offset, function () {
8247          return walker.prev().map(function (prev) {
8248            return {
8249              container: prev,
8250              offset: prev.length
8251            };
8252          });
8253        }, process).getOrNull();
8254      };
8255      var forwards = function (node, offset, process, root) {
8256        var walker = TextWalker(node, root, isBlockBoundary);
8257        return walk(node, offset, function () {
8258          return walker.next().map(function (next) {
8259            return {
8260              container: next,
8261              offset: 0
8262            };
8263          });
8264        }, process).getOrNull();
8265      };
8266      return {
8267        backwards: backwards,
8268        forwards: forwards
8269      };
8270    };
8271
8272    var round$2 = Math.round;
8273    var clone = function (rect) {
8274      if (!rect) {
8275        return {
8276          left: 0,
8277          top: 0,
8278          bottom: 0,
8279          right: 0,
8280          width: 0,
8281          height: 0
8282        };
8283      }
8284      return {
8285        left: round$2(rect.left),
8286        top: round$2(rect.top),
8287        bottom: round$2(rect.bottom),
8288        right: round$2(rect.right),
8289        width: round$2(rect.width),
8290        height: round$2(rect.height)
8291      };
8292    };
8293    var collapse = function (rect, toStart) {
8294      rect = clone(rect);
8295      if (toStart) {
8296        rect.right = rect.left;
8297      } else {
8298        rect.left = rect.left + rect.width;
8299        rect.right = rect.left;
8300      }
8301      rect.width = 0;
8302      return rect;
8303    };
8304    var isEqual = function (rect1, rect2) {
8305      return rect1.left === rect2.left && rect1.top === rect2.top && rect1.bottom === rect2.bottom && rect1.right === rect2.right;
8306    };
8307    var isValidOverflow = function (overflowY, rect1, rect2) {
8308      return overflowY >= 0 && overflowY <= Math.min(rect1.height, rect2.height) / 2;
8309    };
8310    var isAbove$1 = function (rect1, rect2) {
8311      var halfHeight = Math.min(rect2.height / 2, rect1.height / 2);
8312      if (rect1.bottom - halfHeight < rect2.top) {
8313        return true;
8314      }
8315      if (rect1.top > rect2.bottom) {
8316        return false;
8317      }
8318      return isValidOverflow(rect2.top - rect1.bottom, rect1, rect2);
8319    };
8320    var isBelow$1 = function (rect1, rect2) {
8321      if (rect1.top > rect2.bottom) {
8322        return true;
8323      }
8324      if (rect1.bottom < rect2.top) {
8325        return false;
8326      }
8327      return isValidOverflow(rect2.bottom - rect1.top, rect1, rect2);
8328    };
8329    var containsXY = function (rect, clientX, clientY) {
8330      return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
8331    };
8332
8333    var clamp$2 = function (value, min, max) {
8334      return Math.min(Math.max(value, min), max);
8335    };
8336
8337    var getSelectedNode = function (range) {
8338      var startContainer = range.startContainer, startOffset = range.startOffset;
8339      if (startContainer.hasChildNodes() && range.endOffset === startOffset + 1) {
8340        return startContainer.childNodes[startOffset];
8341      }
8342      return null;
8343    };
8344    var getNode$1 = function (container, offset) {
8345      if (isElement$5(container) && container.hasChildNodes()) {
8346        var childNodes = container.childNodes;
8347        var safeOffset = clamp$2(offset, 0, childNodes.length - 1);
8348        return childNodes[safeOffset];
8349      } else {
8350        return container;
8351      }
8352    };
8353    var getNodeUnsafe = function (container, offset) {
8354      if (offset < 0 && isElement$5(container) && container.hasChildNodes()) {
8355        return undefined;
8356      } else {
8357        return getNode$1(container, offset);
8358      }
8359    };
8360
8361    var 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]');
8362    var isExtendingChar = function (ch) {
8363      return typeof ch === 'string' && ch.charCodeAt(0) >= 768 && extendingChars.test(ch);
8364    };
8365
8366    var or = function () {
8367      var args = [];
8368      for (var _i = 0; _i < arguments.length; _i++) {
8369        args[_i] = arguments[_i];
8370      }
8371      return function (x) {
8372        for (var i = 0; i < args.length; i++) {
8373          if (args[i](x)) {
8374            return true;
8375          }
8376        }
8377        return false;
8378      };
8379    };
8380    var and = function () {
8381      var args = [];
8382      for (var _i = 0; _i < arguments.length; _i++) {
8383        args[_i] = arguments[_i];
8384      }
8385      return function (x) {
8386        for (var i = 0; i < args.length; i++) {
8387          if (!args[i](x)) {
8388            return false;
8389          }
8390        }
8391        return true;
8392      };
8393    };
8394
8395    var isElement$3 = isElement$5;
8396    var isCaretCandidate$2 = isCaretCandidate$3;
8397    var isBlock$1 = matchStyleValues('display', 'block table');
8398    var isFloated = matchStyleValues('float', 'left right');
8399    var isValidElementCaretCandidate = and(isElement$3, isCaretCandidate$2, not(isFloated));
8400    var isNotPre = not(matchStyleValues('white-space', 'pre pre-line pre-wrap'));
8401    var isText$4 = isText$7;
8402    var isBr$2 = isBr$5;
8403    var nodeIndex$1 = DOMUtils.nodeIndex;
8404    var resolveIndex$1 = getNodeUnsafe;
8405    var createRange$1 = function (doc) {
8406      return 'createRange' in doc ? doc.createRange() : DOMUtils.DOM.createRng();
8407    };
8408    var isWhiteSpace$1 = function (chr) {
8409      return chr && /[\r\n\t ]/.test(chr);
8410    };
8411    var isRange = function (rng) {
8412      return !!rng.setStart && !!rng.setEnd;
8413    };
8414    var isHiddenWhiteSpaceRange = function (range) {
8415      var container = range.startContainer;
8416      var offset = range.startOffset;
8417      if (isWhiteSpace$1(range.toString()) && isNotPre(container.parentNode) && isText$7(container)) {
8418        var text = container.data;
8419        if (isWhiteSpace$1(text[offset - 1]) || isWhiteSpace$1(text[offset + 1])) {
8420          return true;
8421        }
8422      }
8423      return false;
8424    };
8425    var getBrClientRect = function (brNode) {
8426      var doc = brNode.ownerDocument;
8427      var rng = createRange$1(doc);
8428      var nbsp$1 = doc.createTextNode(nbsp);
8429      var parentNode = brNode.parentNode;
8430      parentNode.insertBefore(nbsp$1, brNode);
8431      rng.setStart(nbsp$1, 0);
8432      rng.setEnd(nbsp$1, 1);
8433      var clientRect = clone(rng.getBoundingClientRect());
8434      parentNode.removeChild(nbsp$1);
8435      return clientRect;
8436    };
8437    var getBoundingClientRectWebKitText = function (rng) {
8438      var sc = rng.startContainer;
8439      var ec = rng.endContainer;
8440      var so = rng.startOffset;
8441      var eo = rng.endOffset;
8442      if (sc === ec && isText$7(ec) && so === 0 && eo === 1) {
8443        var newRng = rng.cloneRange();
8444        newRng.setEndAfter(ec);
8445        return getBoundingClientRect$1(newRng);
8446      } else {
8447        return null;
8448      }
8449    };
8450    var isZeroRect = function (r) {
8451      return r.left === 0 && r.right === 0 && r.top === 0 && r.bottom === 0;
8452    };
8453    var getBoundingClientRect$1 = function (item) {
8454      var clientRect;
8455      var clientRects = item.getClientRects();
8456      if (clientRects.length > 0) {
8457        clientRect = clone(clientRects[0]);
8458      } else {
8459        clientRect = clone(item.getBoundingClientRect());
8460      }
8461      if (!isRange(item) && isBr$2(item) && isZeroRect(clientRect)) {
8462        return getBrClientRect(item);
8463      }
8464      if (isZeroRect(clientRect) && isRange(item)) {
8465        return getBoundingClientRectWebKitText(item);
8466      }
8467      return clientRect;
8468    };
8469    var collapseAndInflateWidth = function (clientRect, toStart) {
8470      var newClientRect = collapse(clientRect, toStart);
8471      newClientRect.width = 1;
8472      newClientRect.right = newClientRect.left + 1;
8473      return newClientRect;
8474    };
8475    var getCaretPositionClientRects = function (caretPosition) {
8476      var clientRects = [];
8477      var addUniqueAndValidRect = function (clientRect) {
8478        if (clientRect.height === 0) {
8479          return;
8480        }
8481        if (clientRects.length > 0) {
8482          if (isEqual(clientRect, clientRects[clientRects.length - 1])) {
8483            return;
8484          }
8485        }
8486        clientRects.push(clientRect);
8487      };
8488      var addCharacterOffset = function (container, offset) {
8489        var range = createRange$1(container.ownerDocument);
8490        if (offset < container.data.length) {
8491          if (isExtendingChar(container.data[offset])) {
8492            return clientRects;
8493          }
8494          if (isExtendingChar(container.data[offset - 1])) {
8495            range.setStart(container, offset);
8496            range.setEnd(container, offset + 1);
8497            if (!isHiddenWhiteSpaceRange(range)) {
8498              addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect$1(range), false));
8499              return clientRects;
8500            }
8501          }
8502        }
8503        if (offset > 0) {
8504          range.setStart(container, offset - 1);
8505          range.setEnd(container, offset);
8506          if (!isHiddenWhiteSpaceRange(range)) {
8507            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect$1(range), false));
8508          }
8509        }
8510        if (offset < container.data.length) {
8511          range.setStart(container, offset);
8512          range.setEnd(container, offset + 1);
8513          if (!isHiddenWhiteSpaceRange(range)) {
8514            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect$1(range), true));
8515          }
8516        }
8517      };
8518      var container = caretPosition.container();
8519      var offset = caretPosition.offset();
8520      if (isText$4(container)) {
8521        addCharacterOffset(container, offset);
8522        return clientRects;
8523      }
8524      if (isElement$3(container)) {
8525        if (caretPosition.isAtEnd()) {
8526          var node = resolveIndex$1(container, offset);
8527          if (isText$4(node)) {
8528            addCharacterOffset(node, node.data.length);
8529          }
8530          if (isValidElementCaretCandidate(node) && !isBr$2(node)) {
8531            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect$1(node), false));
8532          }
8533        } else {
8534          var node = resolveIndex$1(container, offset);
8535          if (isText$4(node)) {
8536            addCharacterOffset(node, 0);
8537          }
8538          if (isValidElementCaretCandidate(node) && caretPosition.isAtEnd()) {
8539            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect$1(node), false));
8540            return clientRects;
8541          }
8542          var beforeNode = resolveIndex$1(caretPosition.container(), caretPosition.offset() - 1);
8543          if (isValidElementCaretCandidate(beforeNode) && !isBr$2(beforeNode)) {
8544            if (isBlock$1(beforeNode) || isBlock$1(node) || !isValidElementCaretCandidate(node)) {
8545              addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect$1(beforeNode), false));
8546            }
8547          }
8548          if (isValidElementCaretCandidate(node)) {
8549            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect$1(node), true));
8550          }
8551        }
8552      }
8553      return clientRects;
8554    };
8555    var CaretPosition = function (container, offset, clientRects) {
8556      var isAtStart = function () {
8557        if (isText$4(container)) {
8558          return offset === 0;
8559        }
8560        return offset === 0;
8561      };
8562      var isAtEnd = function () {
8563        if (isText$4(container)) {
8564          return offset >= container.data.length;
8565        }
8566        return offset >= container.childNodes.length;
8567      };
8568      var toRange = function () {
8569        var range = createRange$1(container.ownerDocument);
8570        range.setStart(container, offset);
8571        range.setEnd(container, offset);
8572        return range;
8573      };
8574      var getClientRects = function () {
8575        if (!clientRects) {
8576          clientRects = getCaretPositionClientRects(CaretPosition(container, offset));
8577        }
8578        return clientRects;
8579      };
8580      var isVisible = function () {
8581        return getClientRects().length > 0;
8582      };
8583      var isEqual = function (caretPosition) {
8584        return caretPosition && container === caretPosition.container() && offset === caretPosition.offset();
8585      };
8586      var getNode = function (before) {
8587        return resolveIndex$1(container, before ? offset - 1 : offset);
8588      };
8589      return {
8590        container: constant(container),
8591        offset: constant(offset),
8592        toRange: toRange,
8593        getClientRects: getClientRects,
8594        isVisible: isVisible,
8595        isAtStart: isAtStart,
8596        isAtEnd: isAtEnd,
8597        isEqual: isEqual,
8598        getNode: getNode
8599      };
8600    };
8601    CaretPosition.fromRangeStart = function (range) {
8602      return CaretPosition(range.startContainer, range.startOffset);
8603    };
8604    CaretPosition.fromRangeEnd = function (range) {
8605      return CaretPosition(range.endContainer, range.endOffset);
8606    };
8607    CaretPosition.after = function (node) {
8608      return CaretPosition(node.parentNode, nodeIndex$1(node) + 1);
8609    };
8610    CaretPosition.before = function (node) {
8611      return CaretPosition(node.parentNode, nodeIndex$1(node));
8612    };
8613    CaretPosition.isAbove = function (pos1, pos2) {
8614      return lift2(head(pos2.getClientRects()), last$2(pos1.getClientRects()), isAbove$1).getOr(false);
8615    };
8616    CaretPosition.isBelow = function (pos1, pos2) {
8617      return lift2(last$2(pos2.getClientRects()), head(pos1.getClientRects()), isBelow$1).getOr(false);
8618    };
8619    CaretPosition.isAtStart = function (pos) {
8620      return pos ? pos.isAtStart() : false;
8621    };
8622    CaretPosition.isAtEnd = function (pos) {
8623      return pos ? pos.isAtEnd() : false;
8624    };
8625    CaretPosition.isTextPosition = function (pos) {
8626      return pos ? isText$7(pos.container()) : false;
8627    };
8628    CaretPosition.isElementPosition = function (pos) {
8629      return CaretPosition.isTextPosition(pos) === false;
8630    };
8631
8632    var trimEmptyTextNode$1 = function (dom, node) {
8633      if (isText$7(node) && node.data.length === 0) {
8634        dom.remove(node);
8635      }
8636    };
8637    var insertNode = function (dom, rng, node) {
8638      rng.insertNode(node);
8639      trimEmptyTextNode$1(dom, node.previousSibling);
8640      trimEmptyTextNode$1(dom, node.nextSibling);
8641    };
8642    var insertFragment = function (dom, rng, frag) {
8643      var firstChild = Optional.from(frag.firstChild);
8644      var lastChild = Optional.from(frag.lastChild);
8645      rng.insertNode(frag);
8646      firstChild.each(function (child) {
8647        return trimEmptyTextNode$1(dom, child.previousSibling);
8648      });
8649      lastChild.each(function (child) {
8650        return trimEmptyTextNode$1(dom, child.nextSibling);
8651      });
8652    };
8653    var rangeInsertNode = function (dom, rng, node) {
8654      if (isDocumentFragment(node)) {
8655        insertFragment(dom, rng, node);
8656      } else {
8657        insertNode(dom, rng, node);
8658      }
8659    };
8660
8661    var isText$3 = isText$7;
8662    var isBogus = isBogus$2;
8663    var nodeIndex = DOMUtils.nodeIndex;
8664    var normalizedParent = function (node) {
8665      var parentNode = node.parentNode;
8666      if (isBogus(parentNode)) {
8667        return normalizedParent(parentNode);
8668      }
8669      return parentNode;
8670    };
8671    var getChildNodes = function (node) {
8672      if (!node) {
8673        return [];
8674      }
8675      return reduce(node.childNodes, function (result, node) {
8676        if (isBogus(node) && node.nodeName !== 'BR') {
8677          result = result.concat(getChildNodes(node));
8678        } else {
8679          result.push(node);
8680        }
8681        return result;
8682      }, []);
8683    };
8684    var normalizedTextOffset = function (node, offset) {
8685      while (node = node.previousSibling) {
8686        if (!isText$3(node)) {
8687          break;
8688        }
8689        offset += node.data.length;
8690      }
8691      return offset;
8692    };
8693    var equal = function (a) {
8694      return function (b) {
8695        return a === b;
8696      };
8697    };
8698    var normalizedNodeIndex = function (node) {
8699      var nodes, index;
8700      nodes = getChildNodes(normalizedParent(node));
8701      index = findIndex$1(nodes, equal(node), node);
8702      nodes = nodes.slice(0, index + 1);
8703      var numTextFragments = reduce(nodes, function (result, node, i) {
8704        if (isText$3(node) && isText$3(nodes[i - 1])) {
8705          result++;
8706        }
8707        return result;
8708      }, 0);
8709      nodes = filter$2(nodes, matchNodeNames([node.nodeName]));
8710      index = findIndex$1(nodes, equal(node), node);
8711      return index - numTextFragments;
8712    };
8713    var createPathItem = function (node) {
8714      var name;
8715      if (isText$3(node)) {
8716        name = 'text()';
8717      } else {
8718        name = node.nodeName.toLowerCase();
8719      }
8720      return name + '[' + normalizedNodeIndex(node) + ']';
8721    };
8722    var parentsUntil$1 = function (root, node, predicate) {
8723      var parents = [];
8724      for (node = node.parentNode; node !== root; node = node.parentNode) {
8725        if (predicate && predicate(node)) {
8726          break;
8727        }
8728        parents.push(node);
8729      }
8730      return parents;
8731    };
8732    var create$6 = function (root, caretPosition) {
8733      var container, offset, path = [], outputOffset, childNodes, parents;
8734      container = caretPosition.container();
8735      offset = caretPosition.offset();
8736      if (isText$3(container)) {
8737        outputOffset = normalizedTextOffset(container, offset);
8738      } else {
8739        childNodes = container.childNodes;
8740        if (offset >= childNodes.length) {
8741          outputOffset = 'after';
8742          offset = childNodes.length - 1;
8743        } else {
8744          outputOffset = 'before';
8745        }
8746        container = childNodes[offset];
8747      }
8748      path.push(createPathItem(container));
8749      parents = parentsUntil$1(root, container);
8750      parents = filter$2(parents, not(isBogus$2));
8751      path = path.concat(map$1(parents, function (node) {
8752        return createPathItem(node);
8753      }));
8754      return path.reverse().join('/') + ',' + outputOffset;
8755    };
8756    var resolvePathItem = function (node, name, index) {
8757      var nodes = getChildNodes(node);
8758      nodes = filter$2(nodes, function (node, index) {
8759        return !isText$3(node) || !isText$3(nodes[index - 1]);
8760      });
8761      nodes = filter$2(nodes, matchNodeNames([name]));
8762      return nodes[index];
8763    };
8764    var findTextPosition = function (container, offset) {
8765      var node = container, targetOffset = 0, dataLen;
8766      while (isText$3(node)) {
8767        dataLen = node.data.length;
8768        if (offset >= targetOffset && offset <= targetOffset + dataLen) {
8769          container = node;
8770          offset = offset - targetOffset;
8771          break;
8772        }
8773        if (!isText$3(node.nextSibling)) {
8774          container = node;
8775          offset = dataLen;
8776          break;
8777        }
8778        targetOffset += dataLen;
8779        node = node.nextSibling;
8780      }
8781      if (isText$3(container) && offset > container.data.length) {
8782        offset = container.data.length;
8783      }
8784      return CaretPosition(container, offset);
8785    };
8786    var resolve$2 = function (root, path) {
8787      var offset;
8788      if (!path) {
8789        return null;
8790      }
8791      var parts = path.split(',');
8792      var paths = parts[0].split('/');
8793      offset = parts.length > 1 ? parts[1] : 'before';
8794      var container = reduce(paths, function (result, value) {
8795        var match = /([\w\-\(\)]+)\[([0-9]+)\]/.exec(value);
8796        if (!match) {
8797          return null;
8798        }
8799        if (match[1] === 'text()') {
8800          match[1] = '#text';
8801        }
8802        return resolvePathItem(result, match[1], parseInt(match[2], 10));
8803      }, root);
8804      if (!container) {
8805        return null;
8806      }
8807      if (!isText$3(container)) {
8808        if (offset === 'after') {
8809          offset = nodeIndex(container) + 1;
8810        } else {
8811          offset = nodeIndex(container);
8812        }
8813        return CaretPosition(container.parentNode, offset);
8814      }
8815      return findTextPosition(container, parseInt(offset, 10));
8816    };
8817
8818    var isContentEditableFalse$9 = isContentEditableFalse$b;
8819    var getNormalizedTextOffset = function (trim, container, offset) {
8820      var node, trimmedOffset;
8821      trimmedOffset = trim(container.data.slice(0, offset)).length;
8822      for (node = container.previousSibling; node && isText$7(node); node = node.previousSibling) {
8823        trimmedOffset += trim(node.data).length;
8824      }
8825      return trimmedOffset;
8826    };
8827    var getPoint = function (dom, trim, normalized, rng, start) {
8828      var container = rng[start ? 'startContainer' : 'endContainer'];
8829      var offset = rng[start ? 'startOffset' : 'endOffset'];
8830      var point = [];
8831      var childNodes, after = 0;
8832      var root = dom.getRoot();
8833      if (isText$7(container)) {
8834        point.push(normalized ? getNormalizedTextOffset(trim, container, offset) : offset);
8835      } else {
8836        childNodes = container.childNodes;
8837        if (offset >= childNodes.length && childNodes.length) {
8838          after = 1;
8839          offset = Math.max(0, childNodes.length - 1);
8840        }
8841        point.push(dom.nodeIndex(childNodes[offset], normalized) + after);
8842      }
8843      for (; container && container !== root; container = container.parentNode) {
8844        point.push(dom.nodeIndex(container, normalized));
8845      }
8846      return point;
8847    };
8848    var getLocation = function (trim, selection, normalized, rng) {
8849      var dom = selection.dom, bookmark = {};
8850      bookmark.start = getPoint(dom, trim, normalized, rng, true);
8851      if (!selection.isCollapsed()) {
8852        bookmark.end = getPoint(dom, trim, normalized, rng, false);
8853      }
8854      if (isRangeInCaretContainerBlock(rng)) {
8855        bookmark.isFakeCaret = true;
8856      }
8857      return bookmark;
8858    };
8859    var findIndex = function (dom, name, element) {
8860      var count = 0;
8861      Tools.each(dom.select(name), function (node) {
8862        if (node.getAttribute('data-mce-bogus') === 'all') {
8863          return;
8864        }
8865        if (node === element) {
8866          return false;
8867        }
8868        count++;
8869      });
8870      return count;
8871    };
8872    var moveEndPoint$1 = function (rng, start) {
8873      var container, offset, childNodes;
8874      var prefix = start ? 'start' : 'end';
8875      container = rng[prefix + 'Container'];
8876      offset = rng[prefix + 'Offset'];
8877      if (isElement$5(container) && container.nodeName === 'TR') {
8878        childNodes = container.childNodes;
8879        container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)];
8880        if (container) {
8881          offset = start ? 0 : container.childNodes.length;
8882          rng['set' + (start ? 'Start' : 'End')](container, offset);
8883        }
8884      }
8885    };
8886    var normalizeTableCellSelection = function (rng) {
8887      moveEndPoint$1(rng, true);
8888      moveEndPoint$1(rng, false);
8889      return rng;
8890    };
8891    var findSibling = function (node, offset) {
8892      var sibling;
8893      if (isElement$5(node)) {
8894        node = getNode$1(node, offset);
8895        if (isContentEditableFalse$9(node)) {
8896          return node;
8897        }
8898      }
8899      if (isCaretContainer$2(node)) {
8900        if (isText$7(node) && isCaretContainerBlock$1(node)) {
8901          node = node.parentNode;
8902        }
8903        sibling = node.previousSibling;
8904        if (isContentEditableFalse$9(sibling)) {
8905          return sibling;
8906        }
8907        sibling = node.nextSibling;
8908        if (isContentEditableFalse$9(sibling)) {
8909          return sibling;
8910        }
8911      }
8912    };
8913    var findAdjacentContentEditableFalseElm = function (rng) {
8914      return findSibling(rng.startContainer, rng.startOffset) || findSibling(rng.endContainer, rng.endOffset);
8915    };
8916    var getOffsetBookmark = function (trim, normalized, selection) {
8917      var element = selection.getNode();
8918      var name = element ? element.nodeName : null;
8919      var rng = selection.getRng();
8920      if (isContentEditableFalse$9(element) || name === 'IMG') {
8921        return {
8922          name: name,
8923          index: findIndex(selection.dom, name, element)
8924        };
8925      }
8926      var sibling = findAdjacentContentEditableFalseElm(rng);
8927      if (sibling) {
8928        name = sibling.tagName;
8929        return {
8930          name: name,
8931          index: findIndex(selection.dom, name, sibling)
8932        };
8933      }
8934      return getLocation(trim, selection, normalized, rng);
8935    };
8936    var getCaretBookmark = function (selection) {
8937      var rng = selection.getRng();
8938      return {
8939        start: create$6(selection.dom.getRoot(), CaretPosition.fromRangeStart(rng)),
8940        end: create$6(selection.dom.getRoot(), CaretPosition.fromRangeEnd(rng))
8941      };
8942    };
8943    var getRangeBookmark = function (selection) {
8944      return { rng: selection.getRng() };
8945    };
8946    var createBookmarkSpan = function (dom, id, filled) {
8947      var args = {
8948        'data-mce-type': 'bookmark',
8949        id: id,
8950        'style': 'overflow:hidden;line-height:0px'
8951      };
8952      return filled ? dom.create('span', args, '&#xFEFF;') : dom.create('span', args);
8953    };
8954    var getPersistentBookmark = function (selection, filled) {
8955      var dom = selection.dom;
8956      var rng = selection.getRng();
8957      var id = dom.uniqueId();
8958      var collapsed = selection.isCollapsed();
8959      var element = selection.getNode();
8960      var name = element.nodeName;
8961      if (name === 'IMG') {
8962        return {
8963          name: name,
8964          index: findIndex(dom, name, element)
8965        };
8966      }
8967      var rng2 = normalizeTableCellSelection(rng.cloneRange());
8968      if (!collapsed) {
8969        rng2.collapse(false);
8970        var endBookmarkNode = createBookmarkSpan(dom, id + '_end', filled);
8971        rangeInsertNode(dom, rng2, endBookmarkNode);
8972      }
8973      rng = normalizeTableCellSelection(rng);
8974      rng.collapse(true);
8975      var startBookmarkNode = createBookmarkSpan(dom, id + '_start', filled);
8976      rangeInsertNode(dom, rng, startBookmarkNode);
8977      selection.moveToBookmark({
8978        id: id,
8979        keep: true
8980      });
8981      return { id: id };
8982    };
8983    var getBookmark$2 = function (selection, type, normalized) {
8984      if (type === 2) {
8985        return getOffsetBookmark(trim$3, normalized, selection);
8986      } else if (type === 3) {
8987        return getCaretBookmark(selection);
8988      } else if (type) {
8989        return getRangeBookmark(selection);
8990      } else {
8991        return getPersistentBookmark(selection, false);
8992      }
8993    };
8994    var getUndoBookmark = curry(getOffsetBookmark, identity, true);
8995
8996    var DOM$9 = DOMUtils.DOM;
8997    var defaultPreviewStyles = 'font-family font-size font-weight font-style text-decoration text-transform color background-color border border-radius outline text-shadow';
8998    var getBodySetting = function (editor, name, defaultValue) {
8999      var value = editor.getParam(name, defaultValue);
9000      if (value.indexOf('=') !== -1) {
9001        var bodyObj = editor.getParam(name, '', 'hash');
9002        return get$9(bodyObj, editor.id).getOr(defaultValue);
9003      } else {
9004        return value;
9005      }
9006    };
9007    var getIframeAttrs = function (editor) {
9008      return editor.getParam('iframe_attrs', {});
9009    };
9010    var getDocType = function (editor) {
9011      return editor.getParam('doctype', '<!DOCTYPE html>');
9012    };
9013    var getDocumentBaseUrl = function (editor) {
9014      return editor.getParam('document_base_url', '');
9015    };
9016    var getBodyId = function (editor) {
9017      return getBodySetting(editor, 'body_id', 'tinymce');
9018    };
9019    var getBodyClass = function (editor) {
9020      return getBodySetting(editor, 'body_class', '');
9021    };
9022    var getContentSecurityPolicy = function (editor) {
9023      return editor.getParam('content_security_policy', '');
9024    };
9025    var shouldPutBrInPre$1 = function (editor) {
9026      return editor.getParam('br_in_pre', true);
9027    };
9028    var getForcedRootBlock = function (editor) {
9029      if (editor.getParam('force_p_newlines', false)) {
9030        return 'p';
9031      }
9032      var block = editor.getParam('forced_root_block', 'p');
9033      if (block === false) {
9034        return '';
9035      } else if (block === true) {
9036        return 'p';
9037      } else {
9038        return block;
9039      }
9040    };
9041    var getForcedRootBlockAttrs = function (editor) {
9042      return editor.getParam('forced_root_block_attrs', {});
9043    };
9044    var getBrNewLineSelector = function (editor) {
9045      return editor.getParam('br_newline_selector', '.mce-toc h2,figcaption,caption');
9046    };
9047    var getNoNewLineSelector = function (editor) {
9048      return editor.getParam('no_newline_selector', '');
9049    };
9050    var shouldKeepStyles = function (editor) {
9051      return editor.getParam('keep_styles', true);
9052    };
9053    var shouldEndContainerOnEmptyBlock = function (editor) {
9054      return editor.getParam('end_container_on_empty_block', false);
9055    };
9056    var getFontStyleValues = function (editor) {
9057      return Tools.explode(editor.getParam('font_size_style_values', 'xx-small,x-small,small,medium,large,x-large,xx-large'));
9058    };
9059    var getFontSizeClasses = function (editor) {
9060      return Tools.explode(editor.getParam('font_size_classes', ''));
9061    };
9062    var getImagesDataImgFilter = function (editor) {
9063      return editor.getParam('images_dataimg_filter', always, 'function');
9064    };
9065    var isAutomaticUploadsEnabled = function (editor) {
9066      return editor.getParam('automatic_uploads', true, 'boolean');
9067    };
9068    var shouldReuseFileName = function (editor) {
9069      return editor.getParam('images_reuse_filename', false, 'boolean');
9070    };
9071    var shouldReplaceBlobUris = function (editor) {
9072      return editor.getParam('images_replace_blob_uris', true, 'boolean');
9073    };
9074    var getIconPackName = function (editor) {
9075      return editor.getParam('icons', '', 'string');
9076    };
9077    var getIconsUrl = function (editor) {
9078      return editor.getParam('icons_url', '', 'string');
9079    };
9080    var getImageUploadUrl = function (editor) {
9081      return editor.getParam('images_upload_url', '', 'string');
9082    };
9083    var getImageUploadBasePath = function (editor) {
9084      return editor.getParam('images_upload_base_path', '', 'string');
9085    };
9086    var getImagesUploadCredentials = function (editor) {
9087      return editor.getParam('images_upload_credentials', false, 'boolean');
9088    };
9089    var getImagesUploadHandler = function (editor) {
9090      return editor.getParam('images_upload_handler', null, 'function');
9091    };
9092    var shouldUseContentCssCors = function (editor) {
9093      return editor.getParam('content_css_cors', false, 'boolean');
9094    };
9095    var getReferrerPolicy = function (editor) {
9096      return editor.getParam('referrer_policy', '', 'string');
9097    };
9098    var getLanguageCode = function (editor) {
9099      return editor.getParam('language', 'en', 'string');
9100    };
9101    var getLanguageUrl = function (editor) {
9102      return editor.getParam('language_url', '', 'string');
9103    };
9104    var shouldIndentUseMargin = function (editor) {
9105      return editor.getParam('indent_use_margin', false);
9106    };
9107    var getIndentation = function (editor) {
9108      return editor.getParam('indentation', '40px', 'string');
9109    };
9110    var getContentCss = function (editor) {
9111      var contentCss = editor.getParam('content_css');
9112      if (isString$1(contentCss)) {
9113        return map$3(contentCss.split(','), trim$5);
9114      } else if (isArray$1(contentCss)) {
9115        return contentCss;
9116      } else if (contentCss === false || editor.inline) {
9117        return [];
9118      } else {
9119        return ['default'];
9120      }
9121    };
9122    var getFontCss = function (editor) {
9123      var fontCss = editor.getParam('font_css', []);
9124      return isArray$1(fontCss) ? fontCss : map$3(fontCss.split(','), trim$5);
9125    };
9126    var getDirectionality = function (editor) {
9127      return editor.getParam('directionality', I18n.isRtl() ? 'rtl' : undefined);
9128    };
9129    var getInlineBoundarySelector = function (editor) {
9130      return editor.getParam('inline_boundaries_selector', 'a[href],code,.mce-annotation', 'string');
9131    };
9132    var getObjectResizing = function (editor) {
9133      var selector = editor.getParam('object_resizing');
9134      if (selector === false || Env.iOS) {
9135        return false;
9136      } else {
9137        return isString$1(selector) ? selector : 'table,img,figure.image,div,video,iframe';
9138      }
9139    };
9140    var getResizeImgProportional = function (editor) {
9141      return editor.getParam('resize_img_proportional', true, 'boolean');
9142    };
9143    var getPlaceholder = function (editor) {
9144      return editor.getParam('placeholder', DOM$9.getAttrib(editor.getElement(), 'placeholder'), 'string');
9145    };
9146    var getEventRoot = function (editor) {
9147      return editor.getParam('event_root');
9148    };
9149    var getServiceMessage = function (editor) {
9150      return editor.getParam('service_message');
9151    };
9152    var getTheme = function (editor) {
9153      return editor.getParam('theme');
9154    };
9155    var shouldValidate = function (editor) {
9156      return editor.getParam('validate');
9157    };
9158    var isInlineBoundariesEnabled = function (editor) {
9159      return editor.getParam('inline_boundaries') !== false;
9160    };
9161    var getFormats = function (editor) {
9162      return editor.getParam('formats');
9163    };
9164    var getPreviewStyles = function (editor) {
9165      var style = editor.getParam('preview_styles', defaultPreviewStyles);
9166      if (isString$1(style)) {
9167        return style;
9168      } else {
9169        return '';
9170      }
9171    };
9172    var canFormatEmptyLines = function (editor) {
9173      return editor.getParam('format_empty_lines', false, 'boolean');
9174    };
9175    var getCustomUiSelector = function (editor) {
9176      return editor.getParam('custom_ui_selector', '', 'string');
9177    };
9178    var getThemeUrl = function (editor) {
9179      return editor.getParam('theme_url');
9180    };
9181    var isInline = function (editor) {
9182      return editor.getParam('inline');
9183    };
9184    var hasHiddenInput = function (editor) {
9185      return editor.getParam('hidden_input');
9186    };
9187    var shouldPatchSubmit = function (editor) {
9188      return editor.getParam('submit_patch');
9189    };
9190    var isEncodingXml = function (editor) {
9191      return editor.getParam('encoding') === 'xml';
9192    };
9193    var shouldAddFormSubmitTrigger = function (editor) {
9194      return editor.getParam('add_form_submit_trigger');
9195    };
9196    var shouldAddUnloadTrigger = function (editor) {
9197      return editor.getParam('add_unload_trigger');
9198    };
9199    var hasForcedRootBlock = function (editor) {
9200      return getForcedRootBlock(editor) !== '';
9201    };
9202    var getCustomUndoRedoLevels = function (editor) {
9203      return editor.getParam('custom_undo_redo_levels', 0, 'number');
9204    };
9205    var shouldDisableNodeChange = function (editor) {
9206      return editor.getParam('disable_nodechange');
9207    };
9208    var isReadOnly$1 = function (editor) {
9209      return editor.getParam('readonly');
9210    };
9211    var hasContentCssCors = function (editor) {
9212      return editor.getParam('content_css_cors');
9213    };
9214    var getPlugins = function (editor) {
9215      return editor.getParam('plugins', '', 'string');
9216    };
9217    var getExternalPlugins$1 = function (editor) {
9218      return editor.getParam('external_plugins');
9219    };
9220    var shouldBlockUnsupportedDrop = function (editor) {
9221      return editor.getParam('block_unsupported_drop', true, 'boolean');
9222    };
9223    var isVisualAidsEnabled = function (editor) {
9224      return editor.getParam('visual', true, 'boolean');
9225    };
9226    var getVisualAidsTableClass = function (editor) {
9227      return editor.getParam('visual_table_class', 'mce-item-table', 'string');
9228    };
9229    var getVisualAidsAnchorClass = function (editor) {
9230      return editor.getParam('visual_anchor_class', 'mce-item-anchor', 'string');
9231    };
9232    var getIframeAriaText = function (editor) {
9233      return editor.getParam('iframe_aria_text', 'Rich Text Area. Press ALT-0 for help.', 'string');
9234    };
9235
9236    var isElement$2 = isElement$5;
9237    var isText$2 = isText$7;
9238    var removeNode$1 = function (node) {
9239      var parentNode = node.parentNode;
9240      if (parentNode) {
9241        parentNode.removeChild(node);
9242      }
9243    };
9244    var trimCount = function (text) {
9245      var trimmedText = trim$3(text);
9246      return {
9247        count: text.length - trimmedText.length,
9248        text: trimmedText
9249      };
9250    };
9251    var deleteZwspChars = function (caretContainer) {
9252      var idx;
9253      while ((idx = caretContainer.data.lastIndexOf(ZWSP$1)) !== -1) {
9254        caretContainer.deleteData(idx, 1);
9255      }
9256    };
9257    var removeUnchanged = function (caretContainer, pos) {
9258      remove$2(caretContainer);
9259      return pos;
9260    };
9261    var removeTextAndReposition = function (caretContainer, pos) {
9262      var before = trimCount(caretContainer.data.substr(0, pos.offset()));
9263      var after = trimCount(caretContainer.data.substr(pos.offset()));
9264      var text = before.text + after.text;
9265      if (text.length > 0) {
9266        deleteZwspChars(caretContainer);
9267        return CaretPosition(caretContainer, pos.offset() - before.count);
9268      } else {
9269        return pos;
9270      }
9271    };
9272    var removeElementAndReposition = function (caretContainer, pos) {
9273      var parentNode = pos.container();
9274      var newPosition = indexOf$2(from(parentNode.childNodes), caretContainer).map(function (index) {
9275        return index < pos.offset() ? CaretPosition(parentNode, pos.offset() - 1) : pos;
9276      }).getOr(pos);
9277      remove$2(caretContainer);
9278      return newPosition;
9279    };
9280    var removeTextCaretContainer = function (caretContainer, pos) {
9281      return isText$2(caretContainer) && pos.container() === caretContainer ? removeTextAndReposition(caretContainer, pos) : removeUnchanged(caretContainer, pos);
9282    };
9283    var removeElementCaretContainer = function (caretContainer, pos) {
9284      return pos.container() === caretContainer.parentNode ? removeElementAndReposition(caretContainer, pos) : removeUnchanged(caretContainer, pos);
9285    };
9286    var removeAndReposition = function (container, pos) {
9287      return CaretPosition.isTextPosition(pos) ? removeTextCaretContainer(container, pos) : removeElementCaretContainer(container, pos);
9288    };
9289    var remove$2 = function (caretContainerNode) {
9290      if (isElement$2(caretContainerNode) && isCaretContainer$2(caretContainerNode)) {
9291        if (hasContent(caretContainerNode)) {
9292          caretContainerNode.removeAttribute('data-mce-caret');
9293        } else {
9294          removeNode$1(caretContainerNode);
9295        }
9296      }
9297      if (isText$2(caretContainerNode)) {
9298        deleteZwspChars(caretContainerNode);
9299        if (caretContainerNode.data.length === 0) {
9300          removeNode$1(caretContainerNode);
9301        }
9302      }
9303    };
9304
9305    var browser$2 = detect().browser;
9306    var isContentEditableFalse$8 = isContentEditableFalse$b;
9307    var isMedia$1 = isMedia$2;
9308    var isTableCell$3 = isTableCell$5;
9309    var inlineFakeCaretSelector = '*[contentEditable=false],video,audio,embed,object';
9310    var getAbsoluteClientRect = function (root, element, before) {
9311      var clientRect = collapse(element.getBoundingClientRect(), before);
9312      var scrollX;
9313      var scrollY;
9314      if (root.tagName === 'BODY') {
9315        var docElm = root.ownerDocument.documentElement;
9316        scrollX = root.scrollLeft || docElm.scrollLeft;
9317        scrollY = root.scrollTop || docElm.scrollTop;
9318      } else {
9319        var rootRect = root.getBoundingClientRect();
9320        scrollX = root.scrollLeft - rootRect.left;
9321        scrollY = root.scrollTop - rootRect.top;
9322      }
9323      clientRect.left += scrollX;
9324      clientRect.right += scrollX;
9325      clientRect.top += scrollY;
9326      clientRect.bottom += scrollY;
9327      clientRect.width = 1;
9328      var margin = element.offsetWidth - element.clientWidth;
9329      if (margin > 0) {
9330        if (before) {
9331          margin *= -1;
9332        }
9333        clientRect.left += margin;
9334        clientRect.right += margin;
9335      }
9336      return clientRect;
9337    };
9338    var trimInlineCaretContainers = function (root) {
9339      var fakeCaretTargetNodes = descendants(SugarElement.fromDom(root), inlineFakeCaretSelector);
9340      for (var i = 0; i < fakeCaretTargetNodes.length; i++) {
9341        var node = fakeCaretTargetNodes[i].dom;
9342        var sibling = node.previousSibling;
9343        if (endsWithCaretContainer$1(sibling)) {
9344          var data = sibling.data;
9345          if (data.length === 1) {
9346            sibling.parentNode.removeChild(sibling);
9347          } else {
9348            sibling.deleteData(data.length - 1, 1);
9349          }
9350        }
9351        sibling = node.nextSibling;
9352        if (startsWithCaretContainer$1(sibling)) {
9353          var data = sibling.data;
9354          if (data.length === 1) {
9355            sibling.parentNode.removeChild(sibling);
9356          } else {
9357            sibling.deleteData(0, 1);
9358          }
9359        }
9360      }
9361    };
9362    var FakeCaret = function (editor, root, isBlock, hasFocus) {
9363      var lastVisualCaret = value();
9364      var cursorInterval;
9365      var caretContainerNode;
9366      var rootBlock = getForcedRootBlock(editor);
9367      var caretBlock = rootBlock.length > 0 ? rootBlock : 'p';
9368      var show = function (before, element) {
9369        var rng;
9370        hide();
9371        if (isTableCell$3(element)) {
9372          return null;
9373        }
9374        if (isBlock(element)) {
9375          caretContainerNode = insertBlock$1(caretBlock, element, before);
9376          var clientRect = getAbsoluteClientRect(root, element, before);
9377          DomQuery(caretContainerNode).css('top', clientRect.top);
9378          var caret = DomQuery('<div class="mce-visual-caret" data-mce-bogus="all"></div>').css(__assign({}, clientRect)).appendTo(root)[0];
9379          lastVisualCaret.set({
9380            caret: caret,
9381            element: element,
9382            before: before
9383          });
9384          if (before) {
9385            DomQuery(caret).addClass('mce-visual-caret-before');
9386          }
9387          startBlink();
9388          rng = element.ownerDocument.createRange();
9389          rng.setStart(caretContainerNode, 0);
9390          rng.setEnd(caretContainerNode, 0);
9391        } else {
9392          caretContainerNode = insertInline$1(element, before);
9393          rng = element.ownerDocument.createRange();
9394          if (isInlineFakeCaretTarget(caretContainerNode.nextSibling)) {
9395            rng.setStart(caretContainerNode, 0);
9396            rng.setEnd(caretContainerNode, 0);
9397          } else {
9398            rng.setStart(caretContainerNode, 1);
9399            rng.setEnd(caretContainerNode, 1);
9400          }
9401          return rng;
9402        }
9403        return rng;
9404      };
9405      var hide = function () {
9406        trimInlineCaretContainers(root);
9407        if (caretContainerNode) {
9408          remove$2(caretContainerNode);
9409          caretContainerNode = null;
9410        }
9411        lastVisualCaret.on(function (caretState) {
9412          DomQuery(caretState.caret).remove();
9413          lastVisualCaret.clear();
9414        });
9415        if (cursorInterval) {
9416          Delay.clearInterval(cursorInterval);
9417          cursorInterval = undefined;
9418        }
9419      };
9420      var startBlink = function () {
9421        cursorInterval = Delay.setInterval(function () {
9422          if (hasFocus()) {
9423            DomQuery('div.mce-visual-caret', root).toggleClass('mce-visual-caret-hidden');
9424          } else {
9425            DomQuery('div.mce-visual-caret', root).addClass('mce-visual-caret-hidden');
9426          }
9427        }, 500);
9428      };
9429      var reposition = function () {
9430        lastVisualCaret.on(function (caretState) {
9431          var clientRect = getAbsoluteClientRect(root, caretState.element, caretState.before);
9432          DomQuery(caretState.caret).css(__assign({}, clientRect));
9433        });
9434      };
9435      var destroy = function () {
9436        return Delay.clearInterval(cursorInterval);
9437      };
9438      var getCss = function () {
9439        return '.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;' + '}';
9440      };
9441      return {
9442        show: show,
9443        hide: hide,
9444        getCss: getCss,
9445        reposition: reposition,
9446        destroy: destroy
9447      };
9448    };
9449    var isFakeCaretTableBrowser = function () {
9450      return browser$2.isIE() || browser$2.isEdge() || browser$2.isFirefox();
9451    };
9452    var isInlineFakeCaretTarget = function (node) {
9453      return isContentEditableFalse$8(node) || isMedia$1(node);
9454    };
9455    var isFakeCaretTarget = function (node) {
9456      return isInlineFakeCaretTarget(node) || isTable$3(node) && isFakeCaretTableBrowser();
9457    };
9458
9459    var isContentEditableFalse$7 = isContentEditableFalse$b;
9460    var isMedia = isMedia$2;
9461    var isBlockLike = matchStyleValues('display', 'block table table-cell table-caption list-item');
9462    var isCaretContainer = isCaretContainer$2;
9463    var isCaretContainerBlock = isCaretContainerBlock$1;
9464    var isElement$1 = isElement$5;
9465    var isCaretCandidate$1 = isCaretCandidate$3;
9466    var isForwards = function (direction) {
9467      return direction > 0;
9468    };
9469    var isBackwards = function (direction) {
9470      return direction < 0;
9471    };
9472    var skipCaretContainers = function (walk, shallow) {
9473      var node;
9474      while (node = walk(shallow)) {
9475        if (!isCaretContainerBlock(node)) {
9476          return node;
9477        }
9478      }
9479      return null;
9480    };
9481    var findNode$1 = function (node, direction, predicateFn, rootNode, shallow) {
9482      var walker = new DomTreeWalker(node, rootNode);
9483      var isCefOrCaretContainer = isContentEditableFalse$7(node) || isCaretContainerBlock(node);
9484      if (isBackwards(direction)) {
9485        if (isCefOrCaretContainer) {
9486          node = skipCaretContainers(walker.prev.bind(walker), true);
9487          if (predicateFn(node)) {
9488            return node;
9489          }
9490        }
9491        while (node = skipCaretContainers(walker.prev.bind(walker), shallow)) {
9492          if (predicateFn(node)) {
9493            return node;
9494          }
9495        }
9496      }
9497      if (isForwards(direction)) {
9498        if (isCefOrCaretContainer) {
9499          node = skipCaretContainers(walker.next.bind(walker), true);
9500          if (predicateFn(node)) {
9501            return node;
9502          }
9503        }
9504        while (node = skipCaretContainers(walker.next.bind(walker), shallow)) {
9505          if (predicateFn(node)) {
9506            return node;
9507          }
9508        }
9509      }
9510      return null;
9511    };
9512    var getParentBlock$2 = function (node, rootNode) {
9513      while (node && node !== rootNode) {
9514        if (isBlockLike(node)) {
9515          return node;
9516        }
9517        node = node.parentNode;
9518      }
9519      return null;
9520    };
9521    var isInSameBlock = function (caretPosition1, caretPosition2, rootNode) {
9522      return getParentBlock$2(caretPosition1.container(), rootNode) === getParentBlock$2(caretPosition2.container(), rootNode);
9523    };
9524    var getChildNodeAtRelativeOffset = function (relativeOffset, caretPosition) {
9525      if (!caretPosition) {
9526        return null;
9527      }
9528      var container = caretPosition.container();
9529      var offset = caretPosition.offset();
9530      if (!isElement$1(container)) {
9531        return null;
9532      }
9533      return container.childNodes[offset + relativeOffset];
9534    };
9535    var beforeAfter = function (before, node) {
9536      var range = node.ownerDocument.createRange();
9537      if (before) {
9538        range.setStartBefore(node);
9539        range.setEndBefore(node);
9540      } else {
9541        range.setStartAfter(node);
9542        range.setEndAfter(node);
9543      }
9544      return range;
9545    };
9546    var isNodesInSameBlock = function (root, node1, node2) {
9547      return getParentBlock$2(node1, root) === getParentBlock$2(node2, root);
9548    };
9549    var lean = function (left, root, node) {
9550      var siblingName = left ? 'previousSibling' : 'nextSibling';
9551      while (node && node !== root) {
9552        var sibling = node[siblingName];
9553        if (isCaretContainer(sibling)) {
9554          sibling = sibling[siblingName];
9555        }
9556        if (isContentEditableFalse$7(sibling) || isMedia(sibling)) {
9557          if (isNodesInSameBlock(root, sibling, node)) {
9558            return sibling;
9559          }
9560          break;
9561        }
9562        if (isCaretCandidate$1(sibling)) {
9563          break;
9564        }
9565        node = node.parentNode;
9566      }
9567      return null;
9568    };
9569    var before$2 = curry(beforeAfter, true);
9570    var after$2 = curry(beforeAfter, false);
9571    var normalizeRange = function (direction, root, range) {
9572      var node;
9573      var leanLeft = curry(lean, true, root);
9574      var leanRight = curry(lean, false, root);
9575      var container = range.startContainer;
9576      var offset = range.startOffset;
9577      if (isCaretContainerBlock$1(c
9577ontainer)) {
9578        if (!isElement$1(container)) {
9579          container = container.parentNode;
9580        }
9581        var location_1 = container.getAttribute('data-mce-caret');
9582        if (location_1 === 'before') {
9583          node = container.nextSibling;
9584          if (isFakeCaretTarget(node)) {
9585            return before$2(node);
9586          }
9587        }
9588        if (location_1 === 'after') {
9589          node = container.previousSibling;
9590          if (isFakeCaretTarget(node)) {
9591            return after$2(node);
9592          }
9593        }
9594      }
9595      if (!range.collapsed) {
9596        return range;
9597      }
9598      if (isText$7(container)) {
9599        if (isCaretContainer(container)) {
9600          if (direction === 1) {
9601            node = leanRight(container);
9602            if (node) {
9603              return before$2(node);
9604            }
9605            node = leanLeft(container);
9606            if (node) {
9607              return after$2(node);
9608            }
9609          }
9610          if (direction === -1) {
9611            node = leanLeft(container);
9612            if (node) {
9613              return after$2(node);
9614            }
9615            node = leanRight(container);
9616            if (node) {
9617              return before$2(node);
9618            }
9619          }
9620          return range;
9621        }
9622        if (endsWithCaretContainer$1(container) && offset >= container.data.length - 1) {
9623          if (direction === 1) {
9624            node = leanRight(container);
9625            if (node) {
9626              return before$2(node);
9627            }
9628          }
9629          return range;
9630        }
9631        if (startsWithCaretContainer$1(container) && offset <= 1) {
9632          if (direction === -1) {
9633            node = leanLeft(container);
9634            if (node) {
9635              return after$2(node);
9636            }
9637          }
9638          return range;
9639        }
9640        if (offset === container.data.length) {
9641          node = leanRight(container);
9642          if (node) {
9643            return before$2(node);
9644          }
9645          return range;
9646        }
9647        if (offset === 0) {
9648          node = leanLeft(container);
9649          if (node) {
9650            return after$2(node);
9651          }
9652          return range;
9653        }
9654      }
9655      return range;
9656    };
9657    var getRelativeCefElm = function (forward, caretPosition) {
9658      return Optional.from(getChildNodeAtRelativeOffset(forward ? 0 : -1, caretPosition)).filter(isContentEditableFalse$7);
9659    };
9660    var getNormalizedRangeEndPoint = function (direction, root, range) {
9661      var normalizedRange = normalizeRange(direction, root, range);
9662      if (direction === -1) {
9663        return CaretPosition.fromRangeStart(normalizedRange);
9664      }
9665      return CaretPosition.fromRangeEnd(normalizedRange);
9666    };
9667    var getElementFromPosition = function (pos) {
9668      return Optional.from(pos.getNode()).map(SugarElement.fromDom);
9669    };
9670    var getElementFromPrevPosition = function (pos) {
9671      return Optional.from(pos.getNode(true)).map(SugarElement.fromDom);
9672    };
9673    var getVisualCaretPosition = function (walkFn, caretPosition) {
9674      while (caretPosition = walkFn(caretPosition)) {
9675        if (caretPosition.isVisible()) {
9676          return caretPosition;
9677        }
9678      }
9679      return caretPosition;
9680    };
9681    var isMoveInsideSameBlock = function (from, to) {
9682      var inSameBlock = isInSameBlock(from, to);
9683      if (!inSameBlock && isBr$5(from.getNode())) {
9684        return true;
9685      }
9686      return inSameBlock;
9687    };
9688
9689    var HDirection;
9690    (function (HDirection) {
9691      HDirection[HDirection['Backwards'] = -1] = 'Backwards';
9692      HDirection[HDirection['Forwards'] = 1] = 'Forwards';
9693    }(HDirection || (HDirection = {})));
9694    var isContentEditableFalse$6 = isContentEditableFalse$b;
9695    var isText$1 = isText$7;
9696    var isElement = isElement$5;
9697    var isBr$1 = isBr$5;
9698    var isCaretCandidate = isCaretCandidate$3;
9699    var isAtomic = isAtomic$1;
9700    var isEditableCaretCandidate = isEditableCaretCandidate$1;
9701    var getParents$3 = function (node, root) {
9702      var parents = [];
9703      while (node && node !== root) {
9704        parents.push(node);
9705        node = node.parentNode;
9706      }
9707      return parents;
9708    };
9709    var nodeAtIndex = function (container, offset) {
9710      if (container.hasChildNodes() && offset < container.childNodes.length) {
9711        return container.childNodes[offset];
9712      }
9713      return null;
9714    };
9715    var getCaretCandidatePosition = function (direction, node) {
9716      if (isForwards(direction)) {
9717        if (isCaretCandidate(node.previousSibling) && !isText$1(node.previousSibling)) {
9718          return CaretPosition.before(node);
9719        }
9720        if (isText$1(node)) {
9721          return CaretPosition(node, 0);
9722        }
9723      }
9724      if (isBackwards(direction)) {
9725        if (isCaretCandidate(node.nextSibling) && !isText$1(node.nextSibling)) {
9726          return CaretPosition.after(node);
9727        }
9728        if (isText$1(node)) {
9729          return CaretPosition(node, node.data.length);
9730        }
9731      }
9732      if (isBackwards(direction)) {
9733        if (isBr$1(node)) {
9734          return CaretPosition.before(node);
9735        }
9736        return CaretPosition.after(node);
9737      }
9738      return CaretPosition.before(node);
9739    };
9740    var moveForwardFromBr = function (root, nextNode) {
9741      var nextSibling = nextNode.nextSibling;
9742      if (nextSibling && isCaretCandidate(nextSibling)) {
9743        if (isText$1(nextSibling)) {
9744          return CaretPosition(nextSibling, 0);
9745        } else {
9746          return CaretPosition.before(nextSibling);
9747        }
9748      } else {
9749        return findCaretPosition$1(HDirection.Forwards, CaretPosition.after(nextNode), root);
9750      }
9751    };
9752    var findCaretPosition$1 = function (direction, startPos, root) {
9753      var node;
9754      var nextNode;
9755      var innerNode;
9756      var caretPosition;
9757      if (!isElement(root) || !startPos) {
9758        return null;
9759      }
9760      if (startPos.isEqual(CaretPosition.after(root)) && root.lastChild) {
9761        caretPosition = CaretPosition.after(root.lastChild);
9762        if (isBackwards(direction) && isCaretCandidate(root.lastChild) && isElement(root.lastChild)) {
9763          return isBr$1(root.lastChild) ? CaretPosition.before(root.lastChild) : caretPosition;
9764        }
9765      } else {
9766        caretPosition = startPos;
9767      }
9768      var container = caretPosition.container();
9769      var offset = caretPosition.offset();
9770      if (isText$1(container)) {
9771        if (isBackwards(direction) && offset > 0) {
9772          return CaretPosition(container, --offset);
9773        }
9774        if (isForwards(direction) && offset < container.length) {
9775          return CaretPosition(container, ++offset);
9776        }
9777        node = container;
9778      } else {
9779        if (isBackwards(direction) && offset > 0) {
9780          nextNode = nodeAtIndex(container, offset - 1);
9781          if (isCaretCandidate(nextNode)) {
9782            if (!isAtomic(nextNode)) {
9783              innerNode = findNode$1(nextNode, direction, isEditableCaretCandidate, nextNode);
9784              if (innerNode) {
9785                if (isText$1(innerNode)) {
9786                  return CaretPosition(innerNode, innerNode.data.length);
9787                }
9788                return CaretPosition.after(innerNode);
9789              }
9790            }
9791            if (isText$1(nextNode)) {
9792              return CaretPosition(nextNode, nextNode.data.length);
9793            }
9794            return CaretPosition.before(nextNode);
9795          }
9796        }
9797        if (isForwards(direction) && offset < container.childNodes.length) {
9798          nextNode = nodeAtIndex(container, offset);
9799          if (isCaretCandidate(nextNode)) {
9800            if (isBr$1(nextNode)) {
9801              return moveForwardFromBr(root, nextNode);
9802            }
9803            if (!isAtomic(nextNode)) {
9804              innerNode = findNode$1(nextNode, direction, isEditableCaretCandidate, nextNode);
9805              if (innerNode) {
9806                if (isText$1(innerNode)) {
9807                  return CaretPosition(innerNode, 0);
9808                }
9809                return CaretPosition.before(innerNode);
9810              }
9811            }
9812            if (isText$1(nextNode)) {
9813              return CaretPosition(nextNode, 0);
9814            }
9815            return CaretPosition.after(nextNode);
9816          }
9817        }
9818        node = nextNode ? nextNode : caretPosition.getNode();
9819      }
9820      if (isForwards(direction) && caretPosition.isAtEnd() || isBackwards(direction) && caretPosition.isAtStart()) {
9821        node = findNode$1(node, direction, always, root, true);
9822        if (isEditableCaretCandidate(node, root)) {
9823          return getCaretCandidatePosition(direction, node);
9824        }
9825      }
9826      nextNode = findNode$1(node, direction, isEditableCaretCandidate, root);
9827      var rootContentEditableFalseElm = last$1(filter$4(getParents$3(container, root), isContentEditableFalse$6));
9828      if (rootContentEditableFalseElm && (!nextNode || !rootContentEditableFalseElm.contains(nextNode))) {
9829        if (isForwards(direction)) {
9830          caretPosition = CaretPosition.after(rootContentEditableFalseElm);
9831        } else {
9832          caretPosition = CaretPosition.before(rootContentEditableFalseElm);
9833        }
9834        return caretPosition;
9835      }
9836      if (nextNode) {
9837        return getCaretCandidatePosition(direction, nextNode);
9838      }
9839      return null;
9840    };
9841    var CaretWalker = function (root) {
9842      return {
9843        next: function (caretPosition) {
9844          return findCaretPosition$1(HDirection.Forwards, caretPosition, root);
9845        },
9846        prev: function (caretPosition) {
9847          return findCaretPosition$1(HDirection.Backwards, caretPosition, root);
9848        }
9849      };
9850    };
9851
9852    var walkToPositionIn = function (forward, root, start) {
9853      var position = forward ? CaretPosition.before(start) : CaretPosition.after(start);
9854      return fromPosition(forward, root, position);
9855    };
9856    var afterElement = function (node) {
9857      return isBr$5(node) ? CaretPosition.before(node) : CaretPosition.after(node);
9858    };
9859    var isBeforeOrStart = function (position) {
9860      if (CaretPosition.isTextPosition(position)) {
9861        return position.offset() === 0;
9862      } else {
9863        return isCaretCandidate$3(position.getNode());
9864      }
9865    };
9866    var isAfterOrEnd = function (position) {
9867      if (CaretPosition.isTextPosition(position)) {
9868        var container = position.container();
9869        return position.offset() === container.data.length;
9870      } else {
9871        return isCaretCandidate$3(position.getNode(true));
9872      }
9873    };
9874    var isBeforeAfterSameElement = function (from, to) {
9875      return !CaretPosition.isTextPosition(from) && !CaretPosition.isTextPosition(to) && from.getNode() === to.getNode(true);
9876    };
9877    var isAtBr = function (position) {
9878      return !CaretPosition.isTextPosition(position) && isBr$5(position.getNode());
9879    };
9880    var shouldSkipPosition = function (forward, from, to) {
9881      if (forward) {
9882        return !isBeforeAfterSameElement(from, to) && !isAtBr(from) && isAfterOrEnd(from) && isBeforeOrStart(to);
9883      } else {
9884        return !isBeforeAfterSameElement(to, from) && isBeforeOrStart(from) && isAfterOrEnd(to);
9885      }
9886    };
9887    var fromPosition = function (forward, root, pos) {
9888      var walker = CaretWalker(root);
9889      return Optional.from(forward ? walker.next(pos) : walker.prev(pos));
9890    };
9891    var navigate = function (forward, root, from) {
9892      return fromPosition(forward, root, from).bind(function (to) {
9893        if (isInSameBlock(from, to, root) && shouldSkipPosition(forward, from, to)) {
9894          return fromPosition(forward, root, to);
9895        } else {
9896          return Optional.some(to);
9897        }
9898      });
9899    };
9900    var navigateIgnore = function (forward, root, from, ignoreFilter) {
9901      return navigate(forward, root, from).bind(function (pos) {
9902        return ignoreFilter(pos) ? navigateIgnore(forward, root, pos, ignoreFilter) : Optional.some(pos);
9903      });
9904    };
9905    var positionIn = function (forward, element) {
9906      var startNode = forward ? element.firstChild : element.lastChild;
9907      if (isText$7(startNode)) {
9908        return Optional.some(CaretPosition(startNode, forward ? 0 : startNode.data.length));
9909      } else if (startNode) {
9910        if (isCaretCandidate$3(startNode)) {
9911          return Optional.some(forward ? CaretPosition.before(startNode) : afterElement(startNode));
9912        } else {
9913          return walkToPositionIn(forward, element, startNode);
9914        }
9915      } else {
9916        return Optional.none();
9917      }
9918    };
9919    var nextPosition = curry(fromPosition, true);
9920    var prevPosition = curry(fromPosition, false);
9921    var firstPositionIn = curry(positionIn, true);
9922    var lastPositionIn = curry(positionIn, false);
9923
9924    var CARET_ID$1 = '_mce_caret';
9925    var isCaretNode = function (node) {
9926      return isElement$5(node) && node.id === CARET_ID$1;
9927    };
9928    var getParentCaretContainer = function (body, node) {
9929      while (node && node !== body) {
9930        if (node.id === CARET_ID$1) {
9931          return node;
9932        }
9933        node = node.parentNode;
9934      }
9935      return null;
9936    };
9937
9938    var isStringPathBookmark = function (bookmark) {
9939      return isString$1(bookmark.start);
9940    };
9941    var isRangeBookmark = function (bookmark) {
9942      return has$2(bookmark, 'rng');
9943    };
9944    var isIdBookmark = function (bookmark) {
9945      return has$2(bookmark, 'id');
9946    };
9947    var isIndexBookmark = function (bookmark) {
9948      return has$2(bookmark, 'name');
9949    };
9950    var isPathBookmark = function (bookmark) {
9951      return Tools.isArray(bookmark.start);
9952    };
9953
9954    var addBogus = function (dom, node) {
9955      if (isElement$5(node) && dom.isBlock(node) && !node.innerHTML && !Env.ie) {
9956        node.innerHTML = '<br data-mce-bogus="1" />';
9957      }
9958      return node;
9959    };
9960    var resolveCaretPositionBookmark = function (dom, bookmark) {
9961      var pos;
9962      var rng = dom.createRng();
9963      pos = resolve$2(dom.getRoot(), bookmark.start);
9964      rng.setStart(pos.container(), pos.offset());
9965      pos = resolve$2(dom.getRoot(), bookmark.end);
9966      rng.setEnd(pos.container(), pos.offset());
9967      return rng;
9968    };
9969    var insertZwsp = function (node, rng) {
9970      var textNode = node.ownerDocument.createTextNode(ZWSP$1);
9971      node.appendChild(textNode);
9972      rng.setStart(textNode, 0);
9973      rng.setEnd(textNode, 0);
9974    };
9975    var isEmpty$1 = function (node) {
9976      return node.hasChildNodes() === false;
9977    };
9978    var tryFindRangePosition = function (node, rng) {
9979      return lastPositionIn(node).fold(never, function (pos) {
9980        rng.setStart(pos.container(), pos.offset());
9981        rng.setEnd(pos.container(), pos.offset());
9982        return true;
9983      });
9984    };
9985    var padEmptyCaretContainer = function (root, node, rng) {
9986      if (isEmpty$1(node) && getParentCaretContainer(root, node)) {
9987        insertZwsp(node, rng);
9988        return true;
9989      } else {
9990        return false;
9991      }
9992    };
9993    var setEndPoint = function (dom, start, bookmark, rng) {
9994      var point = bookmark[start ? 'start' : 'end'];
9995      var i, node, offset, children;
9996      var root = dom.getRoot();
9997      if (point) {
9998        offset = point[0];
9999        for (node = root, i = point.length - 1; i >= 1; i--) {
10000          children = node.childNodes;
10001          if (padEmptyCaretContainer(root, node, rng)) {
10002            return true;
10003          }
10004          if (point[i] > children.length - 1) {
10005            if (padEmptyCaretContainer(root, node, rng)) {
10006              return true;
10007            }
10008            return tryFindRangePosition(node, rng);
10009          }
10010          node = children[point[i]];
10011        }
10012        if (node.nodeType === 3) {
10013          offset = Math.min(point[0], node.nodeValue.length);
10014        }
10015        if (node.nodeType === 1) {
10016          offset = Math.min(point[0], node.childNodes.length);
10017        }
10018        if (start) {
10019          rng.setStart(node, offset);
10020        } else {
10021          rng.setEnd(node, offset);
10022        }
10023      }
10024      return true;
10025    };
10026    var isValidTextNode = function (node) {
10027      return isText$7(node) && node.data.length > 0;
10028    };
10029    var restoreEndPoint = function (dom, suffix, bookmark) {
10030      var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev;
10031      var keep = bookmark.keep;
10032      var container, offset;
10033      if (marker) {
10034        node = marker.parentNode;
10035        if (suffix === 'start') {
10036          if (!keep) {
10037            idx = dom.nodeIndex(marker);
10038          } else {
10039            if (marker.hasChildNodes()) {
10040              node = marker.firstChild;
10041              idx = 1;
10042            } else if (isValidTextNode(marker.nextSibling)) {
10043              node = marker.nextSibling;
10044              idx = 0;
10045            } else if (isValidTextNode(marker.previousSibling)) {
10046              node = marker.previousSibling;
10047              idx = marker.previousSibling.data.length;
10048            } else {
10049              node = marker.parentNode;
10050              idx = dom.nodeIndex(marker) + 1;
10051            }
10052          }
10053          container = node;
10054          offset = idx;
10055        } else {
10056          if (!keep) {
10057            idx = dom.nodeIndex(marker);
10058          } else {
10059            if (marker.hasChildNodes()) {
10060              node = marker.firstChild;
10061              idx = 1;
10062            } else if (isValidTextNode(marker.previousSibling)) {
10063              node = marker.previousSibling;
10064              idx = marker.previousSibling.data.length;
10065            } else {
10066              node = marker.parentNode;
10067              idx = dom.nodeIndex(marker);
10068            }
10069          }
10070          container = node;
10071          offset = idx;
10072        }
10073        if (!keep) {
10074          prev = marker.previousSibling;
10075          next = marker.nextSibling;
10076          Tools.each(Tools.grep(marker.childNodes), function (node) {
10077            if (isText$7(node)) {
10078              node.nodeValue = node.nodeValue.replace(/\uFEFF/g, '');
10079            }
10080          });
10081          while (marker = dom.get(bookmark.id + '_' + suffix)) {
10082            dom.remove(marker, true);
10083          }
10084          if (prev && next && prev.nodeType === next.nodeType && isText$7(prev) && !Env.opera) {
10085            idx = prev.nodeValue.length;
10086            prev.appendData(next.nodeValue);
10087            dom.remove(next);
10088            container = prev;
10089            offset = idx;
10090          }
10091        }
10092        return Optional.some(CaretPosition(container, offset));
10093      } else {
10094        return Optional.none();
10095      }
10096    };
10097    var resolvePaths = function (dom, bookmark) {
10098      var rng = dom.createRng();
10099      if (setEndPoint(dom, true, bookmark, rng) && setEndPoint(dom, false, bookmark, rng)) {
10100        return Optional.some(rng);
10101      } else {
10102        return Optional.none();
10103      }
10104    };
10105    var resolveId = function (dom, bookmark) {
10106      var startPos = restoreEndPoint(dom, 'start', bookmark);
10107      var endPos = restoreEndPoint(dom, 'end', bookmark);
10108      return lift2(startPos, endPos.or(startPos), function (spos, epos) {
10109        var rng = dom.createRng();
10110        rng.setStart(addBogus(dom, spos.container()), spos.offset());
10111        rng.setEnd(addBogus(dom, epos.container()), epos.offset());
10112        return rng;
10113      });
10114    };
10115    var resolveIndex = function (dom, bookmark) {
10116      return Optional.from(dom.select(bookmark.name)[bookmark.index]).map(function (elm) {
10117        var rng = dom.createRng();
10118        rng.selectNode(elm);
10119        return rng;
10120      });
10121    };
10122    var resolve$1 = function (selection, bookmark) {
10123      var dom = selection.dom;
10124      if (bookmark) {
10125        if (isPathBookmark(bookmark)) {
10126          return resolvePaths(dom, bookmark);
10127        } else if (isStringPathBookmark(bookmark)) {
10128          return Optional.some(resolveCaretPositionBookmark(dom, bookmark));
10129        } else if (isIdBookmark(bookmark)) {
10130          return resolveId(dom, bookmark);
10131        } else if (isIndexBookmark(bookmark)) {
10132          return resolveIndex(dom, bookmark);
10133        } else if (isRangeBookmark(bookmark)) {
10134          return Optional.some(bookmark.rng);
10135        }
10136      }
10137      return Optional.none();
10138    };
10139
10140    var getBookmark$1 = function (selection, type, normalized) {
10141      return getBookmark$2(selection, type, normalized);
10142    };
10143    var moveToBookmark = function (selection, bookmark) {
10144      resolve$1(selection, bookmark).each(function (rng) {
10145        selection.setRng(rng);
10146      });
10147    };
10148    var isBookmarkNode$1 = function (node) {
10149      return isElement$5(node) && node.tagName === 'SPAN' && node.getAttribute('data-mce-type') === 'bookmark';
10150    };
10151
10152    var is = function (expected) {
10153      return function (actual) {
10154        return expected === actual;
10155      };
10156    };
10157    var isNbsp = is(nbsp);
10158    var isWhiteSpace = function (chr) {
10159      return chr !== '' && ' \f\n\r\t\x0B'.indexOf(chr) !== -1;
10160    };
10161    var isContent = function (chr) {
10162      return !isWhiteSpace(chr) && !isNbsp(chr);
10163    };
10164
10165    var isNode = function (node) {
10166      return !!node.nodeType;
10167    };
10168    var isInlineBlock = function (node) {
10169      return node && /^(IMG)$/.test(node.nodeName);
10170    };
10171    var moveStart = function (dom, selection, rng) {
10172      var offset = rng.startOffset;
10173      var container = rng.startContainer;
10174      if (container === rng.endContainer) {
10175        if (isInlineBlock(container.childNodes[offset])) {
10176          return;
10177        }
10178      }
10179      if (isElement$5(container)) {
10180        var nodes = container.childNodes;
10181        var walker = void 0;
10182        if (offset < nodes.length) {
10183          container = nodes[offset];
10184          walker = new DomTreeWalker(container, dom.getParent(container, dom.isBlock));
10185        } else {
10186          container = nodes[nodes.length - 1];
10187          walker = new DomTreeWalker(container, dom.getParent(container, dom.isBlock));
10188          walker.next(true);
10189        }
10190        for (var node = walker.current(); node; node = walker.next()) {
10191          if (isText$7(node) && !isWhiteSpaceNode$1(node)) {
10192            rng.setStart(node, 0);
10193            selection.setRng(rng);
10194            return;
10195          }
10196        }
10197      }
10198    };
10199    var getNonWhiteSpaceSibling = function (node, next, inc) {
10200      if (node) {
10201        var nextName = next ? 'nextSibling' : 'previousSibling';
10202        for (node = inc ? node : node[nextName]; node; node = node[nextName]) {
10203          if (isElement$5(node) || !isWhiteSpaceNode$1(node)) {
10204            return node;
10205          }
10206        }
10207      }
10208    };
10209    var isTextBlock$1 = function (editor, name) {
10210      if (isNode(name)) {
10211        name = name.nodeName;
10212      }
10213      return !!editor.schema.getTextBlockElements()[name.toLowerCase()];
10214    };
10215    var isValid = function (ed, parent, child) {
10216      return ed.schema.isValidChild(parent, child);
10217    };
10218    var isWhiteSpaceNode$1 = function (node, allowSpaces) {
10219      if (allowSpaces === void 0) {
10220        allowSpaces = false;
10221      }
10222      if (isNonNullable(node) && isText$7(node)) {
10223        var data = allowSpaces ? node.data.replace(/ /g, '\xA0') : node.data;
10224        return isWhitespaceText(data);
10225      } else {
10226        return false;
10227      }
10228    };
10229    var isEmptyTextNode$1 = function (node) {
10230      return isNonNullable(node) && isText$7(node) && node.length === 0;
10231    };
10232    var replaceVars = function (value, vars) {
10233      if (isFunction(value)) {
10234        value = value(vars);
10235      } else if (isNonNullable(vars)) {
10236        value = value.replace(/%(\w+)/g, function (str, name) {
10237          return vars[name] || str;
10238        });
10239      }
10240      return value;
10241    };
10242    var isEq$5 = function (str1, str2) {
10243      str1 = str1 || '';
10244      str2 = str2 || '';
10245      str1 = '' + (str1.nodeName || str1);
10246      str2 = '' + (str2.nodeName || str2);
10247      return str1.toLowerCase() === str2.toLowerCase();
10248    };
10249    var normalizeStyleValue = function (dom, value, name) {
10250      if (name === 'color' || name === 'backgroundColor') {
10251        value = dom.toHex(value);
10252      }
10253      if (name === 'fontWeight' && value === 700) {
10254        value = 'bold';
10255      }
10256      if (name === 'fontFamily') {
10257        value = value.replace(/[\'\"]/g, '').replace(/,\s+/g, ',');
10258      }
10259      return '' + value;
10260    };
10261    var getStyle = function (dom, node, name) {
10262      return normalizeStyleValue(dom, dom.getStyle(node, name), name);
10263    };
10264    var getTextDecoration = function (dom, node) {
10265      var decoration;
10266      dom.getParent(node, function (n) {
10267        decoration = dom.getStyle(n, 'text-decoration');
10268        return decoration && decoration !== 'none';
10269      });
10270      return decoration;
10271    };
10272    var getParents$2 = function (dom, node, selector) {
10273      return dom.getParents(node, selector, dom.getRoot());
10274    };
10275    var isVariableFormatName = function (editor, formatName) {
10276      var hasVariableValues = function (format) {
10277        var isVariableValue = function (val) {
10278          return val.length > 1 && val.charAt(0) === '%';
10279        };
10280        return exists([
10281          'styles',
10282          'attributes'
10283        ], function (key) {
10284          return get$9(format, key).exists(function (field) {
10285            var fieldValues = isArray$1(field) ? field : values(field);
10286            return exists(fieldValues, isVariableValue);
10287          });
10288        });
10289      };
10290      return exists(editor.formatter.get(formatName), hasVariableValues);
10291    };
10292    var areSimilarFormats = function (editor, formatName, otherFormatName) {
10293      var validKeys = [
10294        'inline',
10295        'block',
10296        'selector',
10297        'attributes',
10298        'styles',
10299        'classes'
10300      ];
10301      var filterObj = function (format) {
10302        return filter$3(format, function (_, key) {
10303          return exists(validKeys, function (validKey) {
10304            return validKey === key;
10305          });
10306        });
10307      };
10308      return exists(editor.formatter.get(formatName), function (fmt1) {
10309        var filteredFmt1 = filterObj(fmt1);
10310        return exists(editor.formatter.get(otherFormatName), function (fmt2) {
10311          var filteredFmt2 = filterObj(fmt2);
10312          return equal$1(filteredFmt1, filteredFmt2);
10313        });
10314      });
10315    };
10316    var isBlockFormat = function (format) {
10317      return hasNonNullableKey(format, 'block');
10318    };
10319    var isSelectorFormat = function (format) {
10320      return hasNonNullableKey(format, 'selector');
10321    };
10322    var isInlineFormat = function (format) {
10323      return hasNonNullableKey(format, 'inline');
10324    };
10325    var isMixedFormat = function (format) {
10326      return isSelectorFormat(format) && isInlineFormat(format) && is$1(get$9(format, 'mixed'), true);
10327    };
10328    var shouldExpandToSelector = function (format) {
10329      return isSelectorFormat(format) && format.expand !== false && !isInlineFormat(format);
10330    };
10331
10332    var isBookmarkNode = isBookmarkNode$1;
10333    var getParents$1 = getParents$2;
10334    var isWhiteSpaceNode = isWhiteSpaceNode$1;
10335    var isTextBlock = isTextBlock$1;
10336    var isBogusBr = function (node) {
10337      return isBr$5(node) && node.getAttribute('data-mce-bogus') && !node.nextSibling;
10338    };
10339    var findParentContentEditable = function (dom, node) {
10340      var parent = node;
10341      while (parent) {
10342        if (isElement$5(parent) && dom.getContentEditable(parent)) {
10343          return dom.getContentEditable(parent) === 'false' ? parent : node;
10344        }
10345        parent = parent.parentNode;
10346      }
10347      return node;
10348    };
10349    var walkText = function (start, node, offset, predicate) {
10350      var str = node.data;
10351      for (var i = offset; start ? i >= 0 : i < str.length; start ? i-- : i++) {
10352        if (predicate(str.charAt(i))) {
10353          return start ? i + 1 : i;
10354        }
10355      }
10356      return -1;
10357    };
10358    var findSpace = function (start, node, offset) {
10359      return walkText(start, node, offset, function (c) {
10360        return isNbsp(c) || isWhiteSpace(c);
10361      });
10362    };
10363    var findContent = function (start, node, offset) {
10364      return walkText(start, node, offset, isContent);
10365    };
10366    var findWordEndPoint = function (dom, body, container, offset, start, includeTrailingSpaces) {
10367      var lastTextNode;
10368      var rootNode = dom.getParent(container, dom.isBlock) || body;
10369      var walk = function (container, offset, pred) {
10370        var textSeeker = TextSeeker(dom);
10371        var walker = start ? textSeeker.backwards : textSeeker.forwards;
10372        return Optional.from(walker(container, offset, function (text, textOffset) {
10373          if (isBookmarkNode(text.parentNode)) {
10374            return -1;
10375          } else {
10376            lastTextNode = text;
10377            return pred(start, text, textOffset);
10378          }
10379        }, rootNode));
10380      };
10381      var spaceResult = walk(container, offset, findSpace);
10382      return spaceResult.bind(function (result) {
10383        return includeTrailingSpaces ? walk(result.container, result.offset + (start ? -1 : 0), findContent) : Optional.some(result);
10384      }).orThunk(function () {
10385        return lastTextNode ? Optional.some({
10386          container: lastTextNode,
10387          offset: start ? 0 : lastTextNode.length
10388        }) : Optional.none();
10389      });
10390    };
10391    var findSelectorEndPoint = function (dom, formatList, rng, container, siblingName) {
10392      if (isText$7(container) && isEmpty$3(container.data) && container[siblingName]) {
10393        container = container[siblingName];
10394      }
10395      var parents = getParents$1(dom, container);
10396      for (var i = 0; i < parents.length; i++) {
10397        for (var y = 0; y < formatList.length; y++) {
10398          var curFormat = formatList[y];
10399          if (isNonNullable(curFormat.collapsed) && curFormat.collapsed !== rng.collapsed) {
10400            continue;
10401          }
10402          if (isSelectorFormat(curFormat) && dom.is(parents[i], curFormat.selector)) {
10403            return parents[i];
10404          }
10405        }
10406      }
10407      return container;
10408    };
10409    var findBlockEndPoint = function (editor, formatList, container, siblingName) {
10410      var node = container;
10411      var dom = editor.dom;
10412      var root = dom.getRoot();
10413      var format = formatList[0];
10414      if (isBlockFormat(format)) {
10415        node = format.wrapper ? null : dom.getParent(container, format.block, root);
10416      }
10417      if (!node) {
10418        var scopeRoot = dom.getParent(container, 'LI,TD,TH');
10419        node = dom.getParent(isText$7(container) ? container.parentNode : container, function (node) {
10420          return node !== root && isTextBlock(editor, node);
10421        }, scopeRoot);
10422      }
10423      if (node && isBlockFormat(format) && format.wrapper) {
10424        node = getParents$1(dom, node, 'ul,ol').reverse()[0] || node;
10425      }
10426      if (!node) {
10427        node = container;
10428        while (node[siblingName] && !dom.isBlock(node[siblingName])) {
10429          node = node[siblingName];
10430          if (isEq$5(node, 'br')) {
10431            break;
10432          }
10433        }
10434      }
10435      return node || container;
10436    };
10437    var isAtBlockBoundary$1 = function (dom, root, container, siblingName) {
10438      var parent = container.parentNode;
10439      if (isNonNullable(container[siblingName])) {
10440        return false;
10441      } else if (parent === root || isNullable(parent) || dom.isBlock(parent)) {
10442        return true;
10443      } else {
10444        return isAtBlockBoundary$1(dom, root, parent, siblingName);
10445      }
10446    };
10447    var findParentContainer = function (dom, formatList, container, offset, start) {
10448      var parent = container;
10449      var siblingName = start ? 'previousSibling' : 'nextSibling';
10450      var root = dom.getRoot();
10451      if (isText$7(container) && !isWhiteSpaceNode(container)) {
10452        if (start ? offset > 0 : offset < container.data.length) {
10453          return container;
10454        }
10455      }
10456      while (true) {
10457        if (!formatList[0].block_expand && dom.isBlock(parent)) {
10458          return parent;
10459        }
10460        for (var sibling = parent[siblingName]; sibling; sibling = sibling[siblingName]) {
10461          var allowSpaces = isText$7(sibling) && !isAtBlockBoundary$1(dom, root, sibling, siblingName);
10462          if (!isBookmarkNode(sibling) && !isBogusBr(sibling) && !isWhiteSpaceNode(sibling, allowSpaces)) {
10463            return parent;
10464          }
10465        }
10466        if (parent === root || parent.parentNode === root) {
10467          container = parent;
10468          break;
10469        }
10470        parent = parent.parentNode;
10471      }
10472      return container;
10473    };
10474    var isSelfOrParentBookmark = function (container) {
10475      return isBookmarkNode(container.parentNode) || isBookmarkNode(container);
10476    };
10477    var expandRng = function (editor, rng, formatList, includeTrailingSpace) {
10478      if (includeTrailingSpace === void 0) {
10479        includeTrailingSpace = false;
10480      }
10481      var startContainer = rng.startContainer, startOffset = rng.startOffset, endContainer = rng.endContainer, endOffset = rng.endOffset;
10482      var dom = editor.dom;
10483      var format = formatList[0];
10484      if (isElement$5(startContainer) && startContainer.hasChildNodes()) {
10485        startContainer = getNode$1(startContainer, startOffset);
10486        if (isText$7(startContainer)) {
10487          startOffset = 0;
10488        }
10489      }
10490      if (isElement$5(endContainer) && endContainer.hasChildNodes()) {
10491        endContainer = getNode$1(endContainer, rng.collapsed ? endOffset : endOffset - 1);
10492        if (isText$7(endContainer)) {
10493          endOffset = endContainer.nodeValue.length;
10494        }
10495      }
10496      startContainer = findParentContentEditable(dom, startContainer);
10497      endContainer = findParentContentEditable(dom, endContainer);
10498      if (isSelfOrParentBookmark(startContainer)) {
10499        startContainer = isBookmarkNode(startContainer) ? startContainer : startContainer.parentNode;
10500        if (rng.collapsed) {
10501          startContainer = startContainer.previousSibling || startContainer;
10502        } else {
10503          startContainer = startContainer.nextSibling || startContainer;
10504        }
10505        if (isText$7(startContainer)) {
10506          startOffset = rng.collapsed ? startContainer.length : 0;
10507        }
10508      }
10509      if (isSelfOrParentBookmark(endContainer)) {
10510        endContainer = isBookmarkNode(endContainer) ? endContainer : endContainer.parentNode;
10511        if (rng.collapsed) {
10512          endContainer = endContainer.nextSibling || endContainer;
10513        } else {
10514          endContainer = endContainer.previousSibling || endContainer;
10515        }
10516        if (isText$7(endContainer)) {
10517          endOffset = rng.collapsed ? 0 : endContainer.length;
10518        }
10519      }
10520      if (rng.collapsed) {
10521        var startPoint = findWordEndPoint(dom, editor.getBody(), startContainer, startOffset, true, includeTrailingSpace);
10522        startPoint.each(function (_a) {
10523          var container = _a.container, offset = _a.offset;
10524          startContainer = container;
10525          startOffset = offset;
10526        });
10527        var endPoint = findWordEndPoint(dom, editor.getBody(), endContainer, endOffset, false, includeTrailingSpace);
10528        endPoint.each(function (_a) {
10529          var container = _a.container, offset = _a.offset;
10530          endContainer = container;
10531          endOffset = offset;
10532        });
10533      }
10534      if (isInlineFormat(format) || format.block_expand) {
10535        if (!isInlineFormat(format) || (!isText$7(startContainer) || startOffset === 0)) {
10536          startContainer = findParentContainer(dom, formatList, startContainer, startOffset, true);
10537        }
10538        if (!isInlineFormat(format) || (!isText$7(endContainer) || endOffset === endContainer.nodeValue.length)) {
10539          endContainer = findParentContainer(dom, formatList, endContainer, endOffset, false);
10540        }
10541      }
10542      if (shouldExpandToSelector(format)) {
10543        startContainer = findSelectorEndPoint(dom, formatList, rng, startContainer, 'previousSibling');
10544        endContainer = findSelectorEndPoint(dom, formatList, rng, endContainer, 'nextSibling');
10545      }
10546      if (isBlockFormat(format) || isSelectorFormat(format)) {
10547        startContainer = findBlockEndPoint(editor, formatList, startContainer, 'previousSibling');
10548        endContainer = findBlockEndPoint(editor, formatList, endContainer, 'nextSibling');
10549        if (isBlockFormat(format)) {
10550          if (!dom.isBlock(startContainer)) {
10551            startContainer = findParentContainer(dom, formatList, startContainer, startOffset, true);
10552          }
10553          if (!dom.isBlock(endContainer)) {
10554            endContainer = findParentContainer(dom, formatList, endContainer, endOffset, false);
10555          }
10556        }
10557      }
10558      if (isElement$5(startContainer)) {
10559        startOffset = dom.nodeIndex(startContainer);
10560        startContainer = startContainer.parentNode;
10561      }
10562      if (isElement$5(endContainer)) {
10563        endOffset = dom.nodeIndex(endContainer) + 1;
10564        endContainer = endContainer.parentNode;
10565      }
10566      return {
10567        startContainer: startContainer,
10568        startOffset: startOffset,
10569        endContainer: endContainer,
10570        endOffset: endOffset
10571      };
10572    };
10573
10574    var walk$2 = function (dom, rng, callback) {
10575      var startOffset = rng.startOffset;
10576      var startContainer = getNode$1(rng.startContainer, startOffset);
10577      var endOffset = rng.endOffset;
10578      var endContainer = getNode$1(rng.endContainer, endOffset - 1);
10579      var exclude = function (nodes) {
10580        var firstNode = nodes[0];
10581        if (isText$7(firstNode) && firstNode === startContainer && startOffset >= firstNode.data.length) {
10582          nodes.splice(0, 1);
10583        }
10584        var lastNode = nodes[nodes.length - 1];
10585        if (endOffset === 0 && nodes.length > 0 && lastNode === endContainer && isText$7(lastNode)) {
10586          nodes.splice(nodes.length - 1, 1);
10587        }
10588        return nodes;
10589      };
10590      var collectSiblings = function (node, name, endNode) {
10591        var siblings = [];
10592        for (; node && node !== endNode; node = node[name]) {
10593          siblings.push(node);
10594        }
10595        return siblings;
10596      };
10597      var findEndPoint = function (node, root) {
10598        return dom.getParent(node, function (node) {
10599          return node.parentNode === root;
10600        }, root);
10601      };
10602      var walkBoundary = function (startNode, endNode, next) {
10603        var siblingName = next ? 'nextSibling' : 'previousSibling';
10604        for (var node = startNode, parent_1 = node.parentNode; node && node !== endNode; node = parent_1) {
10605          parent_1 = node.parentNode;
10606          var siblings_1 = collectSiblings(node === startNode ? node : node[siblingName], siblingName);
10607          if (siblings_1.length) {
10608            if (!next) {
10609              siblings_1.reverse();
10610            }
10611            callback(exclude(siblings_1));
10612          }
10613        }
10614      };
10615      if (startContainer === endContainer) {
10616        return callback(exclude([startContainer]));
10617      }
10618      var ancestor = dom.findCommonAncestor(startContainer, endContainer);
10619      if (dom.isChildOf(startContainer, endContainer)) {
10620        return walkBoundary(startContainer, ancestor, true);
10621      }
10622      if (dom.isChildOf(endContainer, startContainer)) {
10623        return walkBoundary(endContainer, ancestor);
10624      }
10625      var startPoint = findEndPoint(startContainer, ancestor) || startContainer;
10626      var endPoint = findEndPoint(endContainer, ancestor) || endContainer;
10627      walkBoundary(startContainer, startPoint, true);
10628      var siblings = collectSiblings(startPoint === startContainer ? startPoint : startPoint.nextSibling, 'nextSibling', endPoint === endContainer ? endPoint.nextSibling : endPoint);
10629      if (siblings.length) {
10630        callback(exclude(siblings));
10631      }
10632      walkBoundary(endContainer, endPoint);
10633    };
10634
10635    var getRanges = function (selection) {
10636      var ranges = [];
10637      if (selection) {
10638        for (var i = 0; i < selection.rangeCount; i++) {
10639          ranges.push(selection.getRangeAt(i));
10640        }
10641      }
10642      return ranges;
10643    };
10644    var getSelectedNodes = function (ranges) {
10645      return bind(ranges, function (range) {
10646        var node = getSelectedNode(range);
10647        return node ? [SugarElement.fromDom(node)] : [];
10648      });
10649    };
10650    var hasMultipleRanges = function (selection) {
10651      return getRanges(selection).length > 1;
10652    };
10653
10654    var getCellsFromRanges = function (ranges) {
10655      return filter$4(getSelectedNodes(ranges), isTableCell$4);
10656    };
10657    var getCellsFromElement = function (elm) {
10658      return descendants(elm, 'td[data-mce-selected],th[data-mce-selected]');
10659    };
10660    var getCellsFromElementOrRanges = function (ranges, element) {
10661      var selectedCells = getCellsFromElement(element);
10662      return selectedCells.length > 0 ? selectedCells : getCellsFromRanges(ranges);
10663    };
10664    var getCellsFromEditor = function (editor) {
10665      return getCellsFromElementOrRanges(getRanges(editor.selection.getSel()), SugarElement.fromDom(editor.getBody()));
10666    };
10667    var getClosestTable = function (cell, isRoot) {
10668      return ancestor$2(cell, 'table', isRoot);
10669    };
10670
10671    var getStartNode = function (rng) {
10672      var sc = rng.startContainer, so = rng.startOffset;
10673      if (isText$7(sc)) {
10674        return so === 0 ? Optional.some(SugarElement.fromDom(sc)) : Optional.none();
10675      } else {
10676        return Optional.from(sc.childNodes[so]).map(SugarElement.fromDom);
10677      }
10678    };
10679    var getEndNode = function (rng) {
10680      var ec = rng.endContainer, eo = rng.endOffset;
10681      if (isText$7(ec)) {
10682        return eo === ec.data.length ? Optional.some(SugarElement.fromDom(ec)) : Optional.none();
10683      } else {
10684        return Optional.from(ec.childNodes[eo - 1]).map(SugarElement.fromDom);
10685      }
10686    };
10687    var getFirstChildren = function (node) {
10688      return firstChild(node).fold(constant([node]), function (child) {
10689        return [node].concat(getFirstChildren(child));
10690      });
10691    };
10692    var getLastChildren$1 = function (node) {
10693      return lastChild(node).fold(constant([node]), function (child) {
10694        if (name(child) === 'br') {
10695          return prevSibling(child).map(function (sibling) {
10696            return [node].concat(getLastChildren$1(sibling));
10697          }).getOr([]);
10698        } else {
10699          return [node].concat(getLastChildren$1(child));
10700        }
10701      });
10702    };
10703    var hasAllContentsSelected = function (elm, rng) {
10704      return lift2(getStartNode(rng), getEndNode(rng), function (startNode, endNode) {
10705        var start = find$3(getFirstChildren(elm), curry(eq, startNode));
10706        var end = find$3(getLastChildren$1(elm), curry(eq, endNode));
10707        return start.isSome() && end.isSome();
10708      }).getOr(false);
10709    };
10710    var moveEndPoint = function (dom, rng, node, start) {
10711      var root = node, walker = new DomTreeWalker(node, root);
10712      var moveCaretBeforeOnEnterElementsMap = filter$3(dom.schema.getMoveCaretBeforeOnEnterElements(), function (_, name) {
10713        return !contains$3([
10714          'td',
10715          'th',
10716          'table'
10717        ], name.toLowerCase());
10718      });
10719      do {
10720        if (isText$7(node) && Tools.trim(node.nodeValue).length !== 0) {
10721          if (start) {
10722            rng.setStart(node, 0);
10723          } else {
10724            rng.setEnd(node, node.nodeValue.length);
10725          }
10726          return;
10727        }
10728        if (moveCaretBeforeOnEnterElementsMap[node.nodeName]) {
10729          if (start) {
10730            rng.setStartBefore(node);
10731          } else {
10732            if (node.nodeName === 'BR') {
10733              rng.setEndBefore(node);
10734            } else {
10735              rng.setEndAfter(node);
10736            }
10737          }
10738          return;
10739        }
10740      } while (node = start ? walker.next() : walker.prev());
10741      if (root.nodeName === 'BODY') {
10742        if (start) {
10743          rng.setStart(root, 0);
10744        } else {
10745          rng.setEnd(root, root.childNodes.length);
10746        }
10747      }
10748    };
10749    var hasAnyRanges = function (editor) {
10750      var sel = editor.selection.getSel();
10751      return sel && sel.rangeCount > 0;
10752    };
10753    var runOnRanges = function (editor, executor) {
10754      var fakeSelectionNodes = getCellsFromEditor(editor);
10755      if (fakeSelectionNodes.length > 0) {
10756        each$k(fakeSelectionNodes, function (elem) {
10757          var node = elem.dom;
10758          var fakeNodeRng = editor.dom.createRng();
10759          fakeNodeRng.setStartBefore(node);
10760          fakeNodeRng.setEndAfter(node);
10761          executor(fakeNodeRng, true);
10762        });
10763      } else {
10764        executor(editor.selection.getRng(), false);
10765      }
10766    };
10767    var preserve = function (selection, fillBookmark, executor) {
10768      var bookmark = getPersistentBookmark(selection, fillBookmark);
10769      executor(bookmark);
10770      selection.moveToBookmark(bookmark);
10771    };
10772
10773    var NodeValue = function (is, name) {
10774      var get = function (element) {
10775        if (!is(element)) {
10776          throw new Error('Can only get ' + name + ' value of a ' + name + ' node');
10777        }
10778        return getOption(element).getOr('');
10779      };
10780      var getOption = function (element) {
10781        return is(element) ? Optional.from(element.dom.nodeValue) : Optional.none();
10782      };
10783      var set = function (element, value) {
10784        if (!is(element)) {
10785          throw new Error('Can only set raw ' + name + ' value of a ' + n
10785ame + ' node');
10786        }
10787        element.dom.nodeValue = value;
10788      };
10789      return {
10790        get: get,
10791        getOption: getOption,
10792        set: set
10793      };
10794    };
10795
10796    var api$1 = NodeValue(isText$8, 'text');
10797    var get$2 = function (element) {
10798      return api$1.get(element);
10799    };
10800
10801    var isZeroWidth = function (elem) {
10802      return isText$8(elem) && get$2(elem) === ZWSP$1;
10803    };
10804    var context = function (editor, elem, wrapName, nodeName) {
10805      return parent(elem).fold(function () {
10806        return 'skipping';
10807      }, function (parent) {
10808        if (nodeName === 'br' || isZeroWidth(elem)) {
10809          return 'valid';
10810        } else if (isAnnotation(elem)) {
10811          return 'existing';
10812        } else if (isCaretNode(elem.dom)) {
10813          return 'caret';
10814        } else if (!isValid(editor, wrapName, nodeName) || !isValid(editor, name(parent), wrapName)) {
10815          return 'invalid-child';
10816        } else {
10817          return 'valid';
10818        }
10819      });
10820    };
10821
10822    var applyWordGrab = function (editor, rng) {
10823      var r = expandRng(editor, rng, [{ inline: 'span' }]);
10824      rng.setStart(r.startContainer, r.startOffset);
10825      rng.setEnd(r.endContainer, r.endOffset);
10826      editor.selection.setRng(rng);
10827    };
10828    var makeAnnotation = function (eDoc, _a, annotationName, decorate) {
10829      var _b = _a.uid, uid = _b === void 0 ? generate('mce-annotation') : _b, data = __rest(_a, ['uid']);
10830      var master = SugarElement.fromTag('span', eDoc);
10831      add$1(master, annotation());
10832      set$1(master, '' + dataAnnotationId(), uid);
10833      set$1(master, '' + dataAnnotation(), annotationName);
10834      var _c = decorate(uid, data), _d = _c.attributes, attributes = _d === void 0 ? {} : _d, _e = _c.classes, classes = _e === void 0 ? [] : _e;
10835      setAll$1(master, attributes);
10836      add(master, classes);
10837      return master;
10838    };
10839    var annotate = function (editor, rng, annotationName, decorate, data) {
10840      var newWrappers = [];
10841      var master = makeAnnotation(editor.getDoc(), data, annotationName, decorate);
10842      var wrapper = value();
10843      var finishWrapper = function () {
10844        wrapper.clear();
10845      };
10846      var getOrOpenWrapper = function () {
10847        return wrapper.get().getOrThunk(function () {
10848          var nu = shallow(master);
10849          newWrappers.push(nu);
10850          wrapper.set(nu);
10851          return nu;
10852        });
10853      };
10854      var processElements = function (elems) {
10855        each$k(elems, processElement);
10856      };
10857      var processElement = function (elem) {
10858        var ctx = context(editor, elem, 'span', name(elem));
10859        switch (ctx) {
10860        case 'invalid-child': {
10861            finishWrapper();
10862            var children$1 = children(elem);
10863            processElements(children$1);
10864            finishWrapper();
10865            break;
10866          }
10867        case 'valid': {
10868            var w = getOrOpenWrapper();
10869            wrap$3(elem, w);
10870            break;
10871          }
10872        }
10873      };
10874      var processNodes = function (nodes) {
10875        var elems = map$3(nodes, SugarElement.fromDom);
10876        processElements(elems);
10877      };
10878      walk$2(editor.dom, rng, function (nodes) {
10879        finishWrapper();
10880        processNodes(nodes);
10881      });
10882      return newWrappers;
10883    };
10884    var annotateWithBookmark = function (editor, name, settings, data) {
10885      editor.undoManager.transact(function () {
10886        var selection = editor.selection;
10887        var initialRng = selection.getRng();
10888        var hasFakeSelection = getCellsFromEditor(editor).length > 0;
10889        if (initialRng.collapsed && !hasFakeSelection) {
10890          applyWordGrab(editor, initialRng);
10891        }
10892        if (selection.getRng().collapsed && !hasFakeSelection) {
10893          var wrapper = makeAnnotation(editor.getDoc(), data, name, settings.decorate);
10894          set(wrapper, nbsp);
10895          selection.getRng().insertNode(wrapper.dom);
10896          selection.select(wrapper.dom);
10897        } else {
10898          preserve(selection, false, function () {
10899            runOnRanges(editor, function (selectionRng) {
10900              annotate(editor, selectionRng, name, settings.decorate, data);
10901            });
10902          });
10903        }
10904      });
10905    };
10906
10907    var Annotator = function (editor) {
10908      var registry = create$7();
10909      setup$m(editor, registry);
10910      var changes = setup$n(editor);
10911      return {
10912        register: function (name, settings) {
10913          registry.register(name, settings);
10914        },
10915        annotate: function (name, data) {
10916          registry.lookup(name).each(function (settings) {
10917            annotateWithBookmark(editor, name, settings, data);
10918          });
10919        },
10920        annotationChanged: function (name, callback) {
10921          changes.addListener(name, callback);
10922        },
10923        remove: function (name) {
10924          identify(editor, Optional.some(name)).each(function (_a) {
10925            var elements = _a.elements;
10926            each$k(elements, unwrap);
10927          });
10928        },
10929        getAll: function (name) {
10930          var directory = findAll(editor, name);
10931          return map$2(directory, function (elems) {
10932            return map$3(elems, function (elem) {
10933              return elem.dom;
10934            });
10935          });
10936        }
10937      };
10938    };
10939
10940    var BookmarkManager = function (selection) {
10941      return {
10942        getBookmark: curry(getBookmark$1, selection),
10943        moveToBookmark: curry(moveToBookmark, selection)
10944      };
10945    };
10946    BookmarkManager.isBookmarkNode = isBookmarkNode$1;
10947
10948    var getContentEditableRoot$1 = function (root, node) {
10949      while (node && node !== root) {
10950        if (isContentEditableTrue$4(node) || isContentEditableFalse$b(node)) {
10951          return node;
10952        }
10953        node = node.parentNode;
10954      }
10955      return null;
10956    };
10957
10958    var isXYWithinRange = function (clientX, clientY, range) {
10959      if (range.collapsed) {
10960        return false;
10961      }
10962      if (Env.browser.isIE() && range.startOffset === range.endOffset - 1 && range.startContainer === range.endContainer) {
10963        var elm = range.startContainer.childNodes[range.startOffset];
10964        if (isElement$5(elm)) {
10965          return exists(elm.getClientRects(), function (rect) {
10966            return containsXY(rect, clientX, clientY);
10967          });
10968        }
10969      }
10970      return exists(range.getClientRects(), function (rect) {
10971        return containsXY(rect, clientX, clientY);
10972      });
10973    };
10974
10975    var firePreProcess = function (editor, args) {
10976      return editor.fire('PreProcess', args);
10977    };
10978    var firePostProcess = function (editor, args) {
10979      return editor.fire('PostProcess', args);
10980    };
10981    var fireRemove = function (editor) {
10982      return editor.fire('remove');
10983    };
10984    var fireDetach = function (editor) {
10985      return editor.fire('detach');
10986    };
10987    var fireSwitchMode = function (editor, mode) {
10988      return editor.fire('SwitchMode', { mode: mode });
10989    };
10990    var fireObjectResizeStart = function (editor, target, width, height, origin) {
10991      editor.fire('ObjectResizeStart', {
10992        target: target,
10993        width: width,
10994        height: height,
10995        origin: origin
10996      });
10997    };
10998    var fireObjectResized = function (editor, target, width, height, origin) {
10999      editor.fire('ObjectResized', {
11000        target: target,
11001        width: width,
11002        height: height,
11003        origin: origin
11004      });
11005    };
11006    var firePreInit = function (editor) {
11007      return editor.fire('PreInit');
11008    };
11009    var firePostRender = function (editor) {
11010      return editor.fire('PostRender');
11011    };
11012    var fireInit = function (editor) {
11013      return editor.fire('Init');
11014    };
11015    var firePlaceholderToggle = function (editor, state) {
11016      return editor.fire('PlaceholderToggle', { state: state });
11017    };
11018    var fireError = function (editor, errorType, error) {
11019      return editor.fire(errorType, error);
11020    };
11021    var fireFormatApply = function (editor, format, node, vars) {
11022      return editor.fire('FormatApply', {
11023        format: format,
11024        node: node,
11025        vars: vars
11026      });
11027    };
11028    var fireFormatRemove = function (editor, format, node, vars) {
11029      return editor.fire('FormatRemove', {
11030        format: format,
11031        node: node,
11032        vars: vars
11033      });
11034    };
11035
11036    var VK = {
11037      BACKSPACE: 8,
11038      DELETE: 46,
11039      DOWN: 40,
11040      ENTER: 13,
11041      ESC: 27,
11042      LEFT: 37,
11043      RIGHT: 39,
11044      SPACEBAR: 32,
11045      TAB: 9,
11046      UP: 38,
11047      PAGE_UP: 33,
11048      PAGE_DOWN: 34,
11049      END: 35,
11050      HOME: 36,
11051      modifierPressed: function (e) {
11052        return e.shiftKey || e.ctrlKey || e.altKey || VK.metaKeyPressed(e);
11053      },
11054      metaKeyPressed: function (e) {
11055        return Env.mac ? e.metaKey : e.ctrlKey && !e.altKey;
11056      }
11057    };
11058
11059    var isContentEditableFalse$5 = isContentEditableFalse$b;
11060    var ControlSelection = function (selection, editor) {
11061      var elementSelectionAttr = 'data-mce-selected';
11062      var dom = editor.dom, each = Tools.each;
11063      var selectedElm, selectedElmGhost, resizeHelper, selectedHandle, resizeBackdrop;
11064      var startX, startY, selectedElmX, selectedElmY, startW, startH, ratio, resizeStarted;
11065      var width, height;
11066      var editableDoc = editor.getDoc(), rootDocument = document;
11067      var abs = Math.abs, round = Math.round, rootElement = editor.getBody();
11068      var startScrollWidth, startScrollHeight;
11069      var resizeHandles = {
11070        nw: [
11071          0,
11072          0,
11073          -1,
11074          -1
11075        ],
11076        ne: [
11077          1,
11078          0,
11079          1,
11080          -1
11081        ],
11082        se: [
11083          1,
11084          1,
11085          1,
11086          1
11087        ],
11088        sw: [
11089          0,
11090          1,
11091          -1,
11092          1
11093        ]
11094      };
11095      var isImage = function (elm) {
11096        return elm && (elm.nodeName === 'IMG' || editor.dom.is(elm, 'figure.image'));
11097      };
11098      var isMedia = function (elm) {
11099        return isMedia$2(elm) || dom.hasClass(elm, 'mce-preview-object');
11100      };
11101      var isEventOnImageOutsideRange = function (evt, range) {
11102        if (evt.type === 'longpress' || evt.type.indexOf('touch') === 0) {
11103          var touch = evt.touches[0];
11104          return isImage(evt.target) && !isXYWithinRange(touch.clientX, touch.clientY, range);
11105        } else {
11106          return isImage(evt.target) && !isXYWithinRange(evt.clientX, evt.clientY, range);
11107        }
11108      };
11109      var contextMenuSelectImage = function (evt) {
11110        var target = evt.target;
11111        if (isEventOnImageOutsideRange(evt, editor.selection.getRng()) && !evt.isDefaultPrevented()) {
11112          editor.selection.select(target);
11113        }
11114      };
11115      var getResizeTargets = function (elm) {
11116        if (dom.is(elm, 'figure.image')) {
11117          return [elm.querySelector('img')];
11118        } else if (dom.hasClass(elm, 'mce-preview-object') && isNonNullable(elm.firstElementChild)) {
11119          return [
11120            elm,
11121            elm.firstElementChild
11122          ];
11123        } else {
11124          return [elm];
11125        }
11126      };
11127      var isResizable = function (elm) {
11128        var selector = getObjectResizing(editor);
11129        if (!selector) {
11130          return false;
11131        }
11132        if (elm.getAttribute('data-mce-resize') === 'false') {
11133          return false;
11134        }
11135        if (elm === editor.getBody()) {
11136          return false;
11137        }
11138        if (dom.hasClass(elm, 'mce-preview-object')) {
11139          return is$2(SugarElement.fromDom(elm.firstElementChild), selector);
11140        } else {
11141          return is$2(SugarElement.fromDom(elm), selector);
11142        }
11143      };
11144      var createGhostElement = function (elm) {
11145        if (isMedia(elm)) {
11146          return dom.create('img', { src: Env.transparentSrc });
11147        } else {
11148          return elm.cloneNode(true);
11149        }
11150      };
11151      var setSizeProp = function (element, name, value) {
11152        if (isNonNullable(value)) {
11153          var targets = getResizeTargets(element);
11154          each$k(targets, function (target) {
11155            if (target.style[name] || !editor.schema.isValid(target.nodeName.toLowerCase(), name)) {
11156              dom.setStyle(target, name, value);
11157            } else {
11158              dom.setAttrib(target, name, '' + value);
11159            }
11160          });
11161        }
11162      };
11163      var setGhostElmSize = function (ghostElm, width, height) {
11164        setSizeProp(ghostElm, 'width', width);
11165        setSizeProp(ghostElm, 'height', height);
11166      };
11167      var resizeGhostElement = function (e) {
11168        var deltaX, deltaY, proportional;
11169        var resizeHelperX, resizeHelperY;
11170        deltaX = e.screenX - startX;
11171        deltaY = e.screenY - startY;
11172        width = deltaX * selectedHandle[2] + startW;
11173        height = deltaY * selectedHandle[3] + startH;
11174        width = width < 5 ? 5 : width;
11175        height = height < 5 ? 5 : height;
11176        if ((isImage(selectedElm) || isMedia(selectedElm)) && getResizeImgProportional(editor) !== false) {
11177          proportional = !VK.modifierPressed(e);
11178        } else {
11179          proportional = VK.modifierPressed(e);
11180        }
11181        if (proportional) {
11182          if (abs(deltaX) > abs(deltaY)) {
11183            height = round(width * ratio);
11184            width = round(height / ratio);
11185          } else {
11186            width = round(height / ratio);
11187            height = round(width * ratio);
11188          }
11189        }
11190        setGhostElmSize(selectedElmGhost, width, height);
11191        resizeHelperX = selectedHandle.startPos.x + deltaX;
11192        resizeHelperY = selectedHandle.startPos.y + deltaY;
11193        resizeHelperX = resizeHelperX > 0 ? resizeHelperX : 0;
11194        resizeHelperY = resizeHelperY > 0 ? resizeHelperY : 0;
11195        dom.setStyles(resizeHelper, {
11196          left: resizeHelperX,
11197          top: resizeHelperY,
11198          display: 'block'
11199        });
11200        resizeHelper.innerHTML = width + ' &times; ' + height;
11201        if (selectedHandle[2] < 0 && selectedElmGhost.clientWidth <= width) {
11202          dom.setStyle(selectedElmGhost, 'left', selectedElmX + (startW - width));
11203        }
11204        if (selectedHandle[3] < 0 && selectedElmGhost.clientHeight <= height) {
11205          dom.setStyle(selectedElmGhost, 'top', selectedElmY + (startH - height));
11206        }
11207        deltaX = rootElement.scrollWidth - startScrollWidth;
11208        deltaY = rootElement.scrollHeight - startScrollHeight;
11209        if (deltaX + deltaY !== 0) {
11210          dom.setStyles(resizeHelper, {
11211            left: resizeHelperX - deltaX,
11212            top: resizeHelperY - deltaY
11213          });
11214        }
11215        if (!resizeStarted) {
11216          fireObjectResizeStart(editor, selectedElm, startW, startH, 'corner-' + selectedHandle.name);
11217          resizeStarted = true;
11218        }
11219      };
11220      var endGhostResize = function () {
11221        var wasResizeStarted = resizeStarted;
11222        resizeStarted = false;
11223        if (wasResizeStarted) {
11224          setSizeProp(selectedElm, 'width', width);
11225          setSizeProp(selectedElm, 'height', height);
11226        }
11227        dom.unbind(editableDoc, 'mousemove', resizeGhostElement);
11228        dom.unbind(editableDoc, 'mouseup', endGhostResize);
11229        if (rootDocument !== editableDoc) {
11230          dom.unbind(rootDocument, 'mousemove', resizeGhostElement);
11231          dom.unbind(rootDocument, 'mouseup', endGhostResize);
11232        }
11233        dom.remove(selectedElmGhost);
11234        dom.remove(resizeHelper);
11235        dom.remove(resizeBackdrop);
11236        showResizeRect(selectedElm);
11237        if (wasResizeStarted) {
11238          fireObjectResized(editor, selectedElm, width, height, 'corner-' + selectedHandle.name);
11239          dom.setAttrib(selectedElm, 'style', dom.getAttrib(selectedElm, 'style'));
11240        }
11241        editor.nodeChanged();
11242      };
11243      var showResizeRect = function (targetElm) {
11244        unbindResizeHandleEvents();
11245        var position = dom.getPos(targetElm, rootElement);
11246        var selectedElmX = position.x;
11247        var selectedElmY = position.y;
11248        var rect = targetElm.getBoundingClientRect();
11249        var targetWidth = rect.width || rect.right - rect.left;
11250        var targetHeight = rect.height || rect.bottom - rect.top;
11251        if (selectedElm !== targetElm) {
11252          hideResizeRect();
11253          selectedElm = targetElm;
11254          width = height = 0;
11255        }
11256        var e = editor.fire('ObjectSelected', { target: targetElm });
11257        var selectedValue = dom.getAttrib(selectedElm, elementSelectionAttr, '1');
11258        if (isResizable(targetElm) && !e.isDefaultPrevented()) {
11259          each(resizeHandles, function (handle, name) {
11260            var handleElm;
11261            var startDrag = function (e) {
11262              var target = getResizeTargets(selectedElm)[0];
11263              startX = e.screenX;
11264              startY = e.screenY;
11265              startW = target.clientWidth;
11266              startH = target.clientHeight;
11267              ratio = startH / startW;
11268              selectedHandle = handle;
11269              selectedHandle.name = name;
11270              selectedHandle.startPos = {
11271                x: targetWidth * handle[0] + selectedElmX,
11272                y: targetHeight * handle[1] + selectedElmY
11273              };
11274              startScrollWidth = rootElement.scrollWidth;
11275              startScrollHeight = rootElement.scrollHeight;
11276              resizeBackdrop = dom.add(rootElement, 'div', {
11277                'class': 'mce-resize-backdrop',
11278                'data-mce-bogus': 'all'
11279              });
11280              dom.setStyles(resizeBackdrop, {
11281                position: 'fixed',
11282                left: '0',
11283                top: '0',
11284                width: '100%',
11285                height: '100%'
11286              });
11287              selectedElmGhost = createGhostElement(selectedElm);
11288              dom.addClass(selectedElmGhost, 'mce-clonedresizable');
11289              dom.setAttrib(selectedElmGhost, 'data-mce-bogus', 'all');
11290              selectedElmGhost.contentEditable = 'false';
11291              dom.setStyles(selectedElmGhost, {
11292                left: selectedElmX,
11293                top: selectedElmY,
11294                margin: 0
11295              });
11296              setGhostElmSize(selectedElmGhost, targetWidth, targetHeight);
11297              selectedElmGhost.removeAttribute(elementSelectionAttr);
11298              rootElement.appendChild(selectedElmGhost);
11299              dom.bind(editableDoc, 'mousemove', resizeGhostElement);
11300              dom.bind(editableDoc, 'mouseup', endGhostResize);
11301              if (rootDocument !== editableDoc) {
11302                dom.bind(rootDocument, 'mousemove', resizeGhostElement);
11303                dom.bind(rootDocument, 'mouseup', endGhostResize);
11304              }
11305              resizeHelper = dom.add(rootElement, 'div', {
11306                'class': 'mce-resize-helper',
11307                'data-mce-bogus': 'all'
11308              }, startW + ' &times; ' + startH);
11309            };
11310            handleElm = dom.get('mceResizeHandle' + name);
11311            if (handleElm) {
11312              dom.remove(handleElm);
11313            }
11314            handleElm = dom.add(rootElement, 'div', {
11315              'id': 'mceResizeHandle' + name,
11316              'data-mce-bogus': 'all',
11317              'class': 'mce-resizehandle',
11318              'unselectable': true,
11319              'style': 'cursor:' + name + '-resize; margin:0; padding:0'
11320            });
11321            if (Env.ie === 11) {
11322              handleElm.contentEditable = false;
11323            }
11324            dom.bind(handleElm, 'mousedown', function (e) {
11325              e.stopImmediatePropagation();
11326              e.preventDefault();
11327              startDrag(e);
11328            });
11329            handle.elm = handleElm;
11330            dom.setStyles(handleElm, {
11331              left: targetWidth * handle[0] + selectedElmX - handleElm.offsetWidth / 2,
11332              top: targetHeight * handle[1] + selectedElmY - handleElm.offsetHeight / 2
11333            });
11334          });
11335        } else {
11336          hideResizeRect();
11337        }
11338        if (!dom.getAttrib(selectedElm, elementSelectionAttr)) {
11339          selectedElm.setAttribute(elementSelectionAttr, selectedValue);
11340        }
11341      };
11342      var hideResizeRect = function () {
11343        unbindResizeHandleEvents();
11344        if (selectedElm) {
11345          selectedElm.removeAttribute(elementSelectionAttr);
11346        }
11347        each$j(resizeHandles, function (value, name) {
11348          var handleElm = dom.get('mceResizeHandle' + name);
11349          if (handleElm) {
11350            dom.unbind(handleElm);
11351            dom.remove(handleElm);
11352          }
11353        });
11354      };
11355      var updateResizeRect = function (e) {
11356        var startElm, controlElm;
11357        var isChildOrEqual = function (node, parent) {
11358          if (node) {
11359            do {
11360              if (node === parent) {
11361                return true;
11362              }
11363            } while (node = node.parentNode);
11364          }
11365        };
11366        if (resizeStarted || editor.removed) {
11367          return;
11368        }
11369        each(dom.select('img[data-mce-selected],hr[data-mce-selected]'), function (img) {
11370          img.removeAttribute(elementSelectionAttr);
11371        });
11372        controlElm = e.type === 'mousedown' ? e.target : selection.getNode();
11373        controlElm = dom.$(controlElm).closest('table,img,figure.image,hr,video,span.mce-preview-object')[0];
11374        if (isChildOrEqual(controlElm, rootElement)) {
11375          disableGeckoResize();
11376          startElm = selection.getStart(true);
11377          if (isChildOrEqual(startElm, controlElm) && isChildOrEqual(selection.getEnd(true), controlElm)) {
11378            showResizeRect(controlElm);
11379            return;
11380          }
11381        }
11382        hideResizeRect();
11383      };
11384      var isWithinContentEditableFalse = function (elm) {
11385        return isContentEditableFalse$5(getContentEditableRoot$1(editor.getBody(), elm));
11386      };
11387      var unbindResizeHandleEvents = function () {
11388        each$j(resizeHandles, function (handle) {
11389          if (handle.elm) {
11390            dom.unbind(handle.elm);
11391            delete handle.elm;
11392          }
11393        });
11394      };
11395      var disableGeckoResize = function () {
11396        try {
11397          editor.getDoc().execCommand('enableObjectResizing', false, 'false');
11398        } catch (ex) {
11399        }
11400      };
11401      editor.on('init', function () {
11402        disableGeckoResize();
11403        if (Env.browser.isIE() || Env.browser.isEdge()) {
11404          editor.on('mousedown click', function (e) {
11405            var target = e.target, nodeName = target.nodeName;
11406            if (!resizeStarted && /^(TABLE|IMG|HR)$/.test(nodeName) && !isWithinContentEditableFalse(target)) {
11407              if (e.button !== 2) {
11408                editor.selection.select(target, nodeName === 'TABLE');
11409              }
11410              if (e.type === 'mousedown') {
11411                editor.nodeChanged();
11412              }
11413            }
11414          });
11415          var handleMSControlSelect_1 = function (e) {
11416            var delayedSelect = function (node) {
11417              Delay.setEditorTimeout(editor, function () {
11418                return editor.selection.select(node);
11419              });
11420            };
11421            if (isWithinContentEditableFalse(e.target) || isMedia$2(e.target)) {
11422              e.preventDefault();
11423              delayedSelect(e.target);
11424              return;
11425            }
11426            if (/^(TABLE|IMG|HR)$/.test(e.target.nodeName)) {
11427              e.preventDefault();
11428              if (e.target.tagName === 'IMG') {
11429                delayedSelect(e.target);
11430              }
11431            }
11432          };
11433          dom.bind(rootElement, 'mscontrolselect', handleMSControlSelect_1);
11434          editor.on('remove', function () {
11435            return dom.unbind(rootElement, 'mscontrolselect', handleMSControlSelect_1);
11436          });
11437        }
11438        var throttledUpdateResizeRect = Delay.throttle(function (e) {
11439          if (!editor.composing) {
11440            updateResizeRect(e);
11441          }
11442        });
11443        editor.on('NodeChange ResizeEditor ResizeWindow ResizeContent drop', throttledUpdateResizeRect);
11444        editor.on('keyup compositionend', function (e) {
11445          if (selectedElm && selectedElm.nodeName === 'TABLE') {
11446            throttledUpdateResizeRect(e);
11447          }
11448        });
11449        editor.on('hide blur', hideResizeRect);
11450        editor.on('contextmenu longpress', contextMenuSelectImage, true);
11451      });
11452      editor.on('remove', unbindResizeHandleEvents);
11453      var destroy = function () {
11454        selectedElm = selectedElmGhost = resizeBackdrop = null;
11455      };
11456      return {
11457        isResizable: isResizable,
11458        showResizeRect: showResizeRect,
11459        hideResizeRect: hideResizeRect,
11460        updateResizeRect: updateResizeRect,
11461        destroy: destroy
11462      };
11463    };
11464
11465    var hasCeProperty = function (node) {
11466      return isContentEditableTrue$4(node) || isContentEditableFalse$b(node);
11467    };
11468    var findParent$1 = function (node, rootNode, predicate) {
11469      while (node && node !== rootNode) {
11470        if (predicate(node)) {
11471          return node;
11472        }
11473        node = node.parentNode;
11474      }
11475      return null;
11476    };
11477    var findClosestIeRange = function (clientX, clientY, doc) {
11478      var rects;
11479      var element = doc.elementFromPoint(clientX, clientY);
11480      var rng = doc.body.createTextRange();
11481      if (!element || element.tagName === 'HTML') {
11482        element = doc.body;
11483      }
11484      rng.moveToElementText(element);
11485      rects = Tools.toArray(rng.getClientRects());
11486      rects = rects.sort(function (a, b) {
11487        a = Math.abs(Math.max(a.top - clientY, a.bottom - clientY));
11488        b = Math.abs(Math.max(b.top - clientY, b.bottom - clientY));
11489        return a - b;
11490      });
11491      if (rects.length > 0) {
11492        clientY = (rects[0].bottom + rects[0].top) / 2;
11493        try {
11494          rng.moveToPoint(clientX, clientY);
11495          rng.collapse(true);
11496          return rng;
11497        } catch (ex) {
11498        }
11499      }
11500      return null;
11501    };
11502    var moveOutOfContentEditableFalse = function (rng, rootNode) {
11503      var parentElement = rng && rng.parentElement ? rng.parentElement() : null;
11504      return isContentEditableFalse$b(findParent$1(parentElement, rootNode, hasCeProperty)) ? null : rng;
11505    };
11506    var fromPoint = function (clientX, clientY, doc) {
11507      var rng, point;
11508      var pointDoc = doc;
11509      if (pointDoc.caretPositionFromPoint) {
11510        point = pointDoc.caretPositionFromPoint(clientX, clientY);
11511        if (point) {
11512          rng = doc.createRange();
11513          rng.setStart(point.offsetNode, point.offset);
11514          rng.collapse(true);
11515        }
11516      } else if (pointDoc.caretRangeFromPoint) {
11517        rng = pointDoc.caretRangeFromPoint(clientX, clientY);
11518      } else if (pointDoc.body.createTextRange) {
11519        rng = pointDoc.body.createTextRange();
11520        try {
11521          rng.moveToPoint(clientX, clientY);
11522          rng.collapse(true);
11523        } catch (ex) {
11524          rng = findClosestIeRange(clientX, clientY, doc);
11525        }
11526        return moveOutOfContentEditableFalse(rng, doc.body);
11527      }
11528      return rng;
11529    };
11530
11531    var isEq$4 = function (rng1, rng2) {
11532      return rng1 && rng2 && (rng1.startContainer === rng2.startContainer && rng1.startOffset === rng2.startOffset) && (rng1.endContainer === rng2.endContainer && rng1.endOffset === rng2.endOffset);
11533    };
11534
11535    var findParent = function (node, rootNode, predicate) {
11536      while (node && node !== rootNode) {
11537        if (predicate(node)) {
11538          return node;
11539        }
11540        node = node.parentNode;
11541      }
11542      return null;
11543    };
11544    var hasParent$1 = function (node, rootNode, predicate) {
11545      return findParent(node, rootNode, predicate) !== null;
11546    };
11547    var hasParentWithName = function (node, rootNode, name) {
11548      return hasParent$1(node, rootNode, function (node) {
11549        return node.nodeName === name;
11550      });
11551    };
11552    var isTable = function (node) {
11553      return node && node.nodeName === 'TABLE';
11554    };
11555    var isTableCell$2 = function (node) {
11556      return node && /^(TD|TH|CAPTION)$/.test(node.nodeName);
11557    };
11558    var isCeFalseCaretContainer = function (node, rootNode) {
11559      return isCaretContainer$2(node) && hasParent$1(node, rootNode, isCaretNode) === false;
11560    };
11561    var hasBrBeforeAfter = function (dom, node, left) {
11562      var walker = new DomTreeWalker(node, dom.getParent(node.parentNode, dom.isBlock) || dom.getRoot());
11563      while (node = walker[left ? 'prev' : 'next']()) {
11564        if (isBr$5(node)) {
11565          return true;
11566        }
11567      }
11568    };
11569    var isPrevNode = function (node, name) {
11570      return node.previousSibling && node.previousSibling.nodeName === name;
11571    };
11572    var hasContentEditableFalseParent = function (body, node) {
11573      while (node && node !== body) {
11574        if (isContentEditableFalse$b(node)) {
11575          return true;
11576        }
11577        node = node.parentNode;
11578      }
11579      return false;
11580    };
11581    var findTextNodeRelative = function (dom, isAfterNode, collapsed, left, startNode) {
11582      var lastInlineElement;
11583      var body = dom.getRoot();
11584      var node;
11585      var nonEmptyElementsMap = dom.schema.getNonEmptyElements();
11586      var parentBlockContainer = dom.getParent(startNode.parentNode, dom.isBlock) || body;
11587      if (left && isBr$5(startNode) && isAfterNode && dom.isEmpty(parentBlockContainer)) {
11588        return Optional.some(CaretPosition(startNode.parentNode, dom.nodeIndex(startNode)));
11589      }
11590      var walker = new DomTreeWalker(startNode, parentBlockContainer);
11591      while (node = walker[left ? 'prev' : 'next']()) {
11592        if (dom.getContentEditableParent(node) === 'false' || isCeFalseCaretContainer(node, body)) {
11593          return Optional.none();
11594        }
11595        if (isText$7(node) && node.nodeValue.length > 0) {
11596          if (hasParentWithName(node, body, 'A') === false) {
11597            return Optional.some(CaretPosition(node, left ? node.nodeValue.length : 0));
11598          }
11599          return Optional.none();
11600        }
11601        if (dom.isBlock(node) || nonEmptyElementsMap[node.nodeName.toLowerCase()]) {
11602          return Optional.none();
11603        }
11604        lastInlineElement = node;
11605      }
11606      if (collapsed && lastInlineElement) {
11607        return Optional.some(CaretPosition(lastInlineElement, 0));
11608      }
11609      return Optional.none();
11610    };
11611    var normalizeEndPoint = function (dom, collapsed, start, rng) {
11612      var container, offset;
11613      var body = dom.getRoot();
11614      var node;
11615      var directionLeft, normalized = false;
11616      container = rng[(start ? 'start' : 'end') + 'Container'];
11617      offset = rng[(start ? 'start' : 'end') + 'Offset'];
11618      var isAfterNode = isElement$5(container) && offset === container.childNodes.length;
11619      var nonEmptyElementsMap = dom.schema.getNonEmptyElements();
11620      directionLeft = start;
11621      if (isCaretContainer$2(container)) {
11622        return Optional.none();
11623      }
11624      if (isElement$5(container) && offset > container.childNodes.length - 1) {
11625        directionLeft = false;
11626      }
11627      if (isDocument$1(container)) {
11628        container = body;
11629        offset = 0;
11630      }
11631      if (container === body) {
11632        if (directionLeft) {
11633          node = container.childNodes[offset > 0 ? offset - 1 : 0];
11634          if (node) {
11635            if (isCaretContainer$2(node)) {
11636              return Optional.none();
11637            }
11638            if (nonEmptyElementsMap[node.nodeName] || isTable(node)) {
11639              return Optional.none();
11640            }
11641          }
11642        }
11643        if (container.hasChildNodes()) {
11644          offset = Math.min(!directionLeft && offset > 0 ? offset - 1 : offset, container.childNodes.length - 1);
11645          container = container.childNodes[offset];
11646          offset = isText$7(container) && isAfterNode ? container.data.length : 0;
11647          if (!collapsed && container === body.lastChild && isTable(container)) {
11648            return Optional.none();
11649          }
11650          if (hasContentEditableFalseParent(body, container) || isCaretContainer$2(container)) {
11651            return Optional.none();
11652          }
11653          if (container.hasChildNodes() && isTable(container) === false) {
11654            node = container;
11655            var walker = new DomTreeWalker(container, body);
11656            do {
11657              if (isContentEditableFalse$b(node) || isCaretContainer$2(node)) {
11658                normalized = false;
11659                break;
11660              }
11661              if (isText$7(node) && node.nodeValue.length > 0) {
11662                offset = directionLeft ? 0 : node.nodeValue.length;
11663                container = node;
11664                normalized = true;
11665                break;
11666              }
11667              if (nonEmptyElementsMap[node.nodeName.toLowerCase()] && !isTableCell$2(node)) {
11668                offset = dom.nodeIndex(node);
11669                container = node.parentNode;
11670                if (!directionLeft) {
11671                  offset++;
11672                }
11673                normalized = true;
11674                break;
11675              }
11676            } while (node = directionLeft ? walker.next() : walker.prev());
11677          }
11678        }
11679      }
11680      if (collapsed) {
11681        if (isText$7(container) && offset === 0) {
11682          findTextNodeRelative(dom, isAfterNode, collapsed, true, container).each(function (pos) {
11683            container = pos.container();
11684            offset = pos.offset();
11685            normalized = true;
11686          });
11687        }
11688        if (isElement$5(container)) {
11689          node = container.childNodes[offset];
11690          if (!node) {
11691            node = container.childNodes[offset - 1];
11692          }
11693          if (node && isBr$5(node) && !isPrevNode(node, 'A') && !hasBrBeforeAfter(dom, node, false) && !hasBrBeforeAfter(dom, node, true)) {
11694            findTextNodeRelative(dom, isAfterNode, collapsed, true, node).each(function (pos) {
11695              container = pos.container();
11696              offset = pos.offset();
11697              normalized = true;
11698            });
11699          }
11700        }
11701      }
11702      if (directionLeft && !collapsed && isText$7(container) && offset === container.nodeValue.length) {
11703        findTextNodeRelative(dom, isAfterNode, collapsed, false, container).each(function (pos) {
11704          container = pos.container();
11705          offset = pos.offset();
11706          normalized = true;
11707        });
11708      }
11709      return normalized ? Optional.some(CaretPosition(container, offset)) : Optional.none();
11710    };
11711    var normalize$2 = function (dom, rng) {
11712      var collapsed = rng.collapsed, normRng = rng.cloneRange();
11713      var startPos = CaretPosition.fromRangeStart(rng);
11714      normalizeEndPoint(dom, collapsed, true, normRng).each(function (pos) {
11715        if (!collapsed || !CaretPosition.isAbove(startPos, pos)) {
11716          normRng.setStart(pos.container(), pos.offset());
11717        }
11718      });
11719      if (!collapsed) {
11720        normalizeEndPoint(dom, collapsed, false, normRng).each(function (pos) {
11721          normRng.setEnd(pos.container(), pos.offset());
11722        });
11723      }
11724      if (collapsed) {
11725        normRng.collapse(true);
11726      }
11727      return isEq$4(rng, normRng) ? Optional.none() : Optional.some(normRng);
11728    };
11729
11730    var splitText = function (node, offset) {
11731      return node.splitText(offset);
11732    };
11733    var split = function (rng) {
11734      var startContainer = rng.startContainer, startOffset = rng.startOffset, endContainer = rng.endContainer, endOffset = rng.endOffset;
11735      if (startContainer === endContainer && isText$7(startContainer)) {
11736        if (startOffset > 0 && startOffset < startContainer.nodeValue.length) {
11737          endContainer = splitText(startContainer, startOffset);
11738          startContainer = endContainer.previousSibling;
11739          if (endOffset > startOffset) {
11740            endOffset = endOffset - startOffset;
11741            startContainer = endContainer = splitText(endContainer, endOffset).previousSibling;
11742            endOffset = endContainer.nodeValue.length;
11743            startOffset = 0;
11744          } else {
11745            endOffset = 0;
11746          }
11747        }
11748      } else {
11749        if (isText$7(startContainer) && startOffset > 0 && startOffset < startContainer.nodeValue.length) {
11750          startContainer = splitText(startContainer, startOffset);
11751          startOffset = 0;
11752        }
11753        if (isText$7(endContainer) && endOffset > 0 && endOffset < endContainer.nodeValue.length) {
11754          endContainer = splitText(endContainer, endOffset).previousSibling;
11755          endOffset = endContainer.nodeValue.length;
11756        }
11757      }
11758      return {
11759        startContainer: startContainer,
11760        startOffset: startOffset,
11761        endContainer: endContainer,
11762        endOffset: endOffset
11763      };
11764    };
11765
11766    var RangeUtils = function (dom) {
11767      var walk = function (rng, callback) {
11768        return walk$2(dom, rng, callback);
11769      };
11770      var split$1 = split;
11771      var normalize = function (rng) {
11772        return normalize$2(dom, rng).fold(never, function (normalizedRng) {
11773          rng.setStart(normalizedRng.startContainer, normalizedRng.startOffset);
11774          rng.setEnd(normalizedRng.endContainer, normalizedRng.endOffset);
11775          return true;
11776        });
11777      };
11778      return {
11779        walk: walk,
11780        split: split$1,
11781        normalize: normalize
11782      };
11783    };
11784    RangeUtils.compareRanges = isEq$4;
11785    RangeUtils.getCaretRangeFromPoint = fromPoint;
11786    RangeUtils.getSelectedNode = getSelectedNode;
11787    RangeUtils.getNode = getNode$1;
11788
11789    var Dimension = function (name, getOffset) {
11790      var set = function (element, h) {
11791        if (!isNumber(h) && !h.match(/^[0-9]+$/)) {
11792          throw new Error(name + '.set accepts only positive integer values. Value was ' + h);
11793        }
11794        var dom = element.dom;
11795        if (isSupported(dom)) {
11796          dom.style[name] = h + 'px';
11797        }
11798      };
11799      var get = function (element) {
11800        var r = getOffset(element);
11801        if (r <= 0 || r === null) {
11802          var css = get$5(element, name);
11803          return parseFloat(css) || 0;
11804        }
11805        return r;
11806      };
11807      var getOuter = get;
11808      var aggregate = function (element, properties) {
11809        return foldl(properties, function (acc, property) {
11810          var val = get$5(element, property);
11811          var value = val === undefined ? 0 : parseInt(val, 10);
11812          return isNaN(value) ? acc : acc + value;
11813        }, 0);
11814      };
11815      var max = function (element, value, properties) {
11816        var cumulativeInclusions = aggregate(element, properties);
11817        var absoluteMax = value > cumulativeInclusions ? value - cumulativeInclusions : 0;
11818        return absoluteMax;
11819      };
11820      return {
11821        set: set,
11822        get: get,
11823        getOuter: getOuter,
11824        aggregate: aggregate,
11825        max: max
11826      };
11827    };
11828
11829    var api = Dimension('height', function (element) {
11830      var dom = element.dom;
11831      return inBody(element) ? dom.getBoundingClientRect().height : dom.offsetHeight;
11832    });
11833    var get$1 = function (element) {
11834      return api.get(element);
11835    };
11836
11837    var walkUp = function (navigation, doc) {
11838      var frame = navigation.view(doc);
11839      return frame.fold(constant([]), function (f) {
11840        var parent = navigation.owner(f);
11841        var rest = walkUp(navigation, parent);
11842        return [f].concat(rest);
11843      });
11844    };
11845    var pathTo = function (element, navigation) {
11846      var d = navigation.owner(element);
11847      return walkUp(navigation, d);
11848    };
11849
11850    var view = function (doc) {
11851      var _a;
11852      var element = doc.dom === document ? Optional.none() : Optional.from((_a = doc.dom.defaultView) === null || _a === void 0 ? void 0 : _a.frameElement);
11853      return element.map(SugarElement.fromDom);
11854    };
11855    var owner = function (element) {
11856      return documentOrOwner(element);
11857    };
11858
11859    var Navigation = /*#__PURE__*/Object.freeze({
11860        __proto__: null,
11861        view: view,
11862        owner: owner
11863    });
11864
11865    var find$1 = function (element) {
11866      var doc = SugarElement.fromDom(document);
11867      var scroll = get$8(doc);
11868      var frames = pathTo(element, Navigation);
11869      var offset = viewport(element);
11870      var r = foldr(frames, function (b, a) {
11871        var loc = viewport(a);
11872        return {
11873          left: b.left + loc.left,
11874          top: b.top + loc.top
11875        };
11876      }, {
11877        left: 0,
11878        top: 0
11879      });
11880      return SugarPosition(r.left + offset.left + scroll.left, r.top + offset.top + scroll.top);
11881    };
11882
11883    var excludeFromDescend = function (element) {
11884      return name(element) === 'textarea';
11885    };
11886    var fireScrollIntoViewEvent = function (editor, data) {
11887      var scrollEvent = editor.fire('ScrollIntoView', data);
11888      return scrollEvent.isDefaultPrevented();
11889    };
11890    var fireAfterScrollIntoViewEvent = function (editor, data) {
11891      editor.fire('AfterScrollIntoView', data);
11892    };
11893    var descend = function (element, offset) {
11894      var children$1 = children(element);
11895      if (children$1.length === 0 || excludeFromDescend(element)) {
11896        return {
11897          element: element,
11898          offset: offset
11899        };
11900      } else if (offset < children$1.length && !excludeFromDescend(children$1[offset])) {
11901        return {
11902          element: children$1[offset],
11903          offset: 0
11904        };
11905      } else {
11906        var last = children$1[children$1.length - 1];
11907        if (excludeFromDescend(last)) {
11908          return {
11909            element: element,
11910            offset: offset
11911          };
11912        } else {
11913          if (name(last) === 'img') {
11914            return {
11915              element: last,
11916              offset: 1
11917            };
11918          } else if (isText$8(last)) {
11919            return {
11920              element: last,
11921              offset: get$2(last).length
11922            };
11923          } else {
11924            return {
11925              element: last,
11926              offset: children(last).length
11927            };
11928          }
11929        }
11930      }
11931    };
11932    var markerInfo = function (element, cleanupFun) {
11933      var pos = absolute(element);
11934      var height = get$1(element);
11935      return {
11936        element: element,
11937        bottom: pos.top + height,
11938        height: height,
11939        pos: pos,
11940        cleanup: cleanupFun
11941      };
11942    };
11943    var createMarker = function (element, offset) {
11944      var startPoint = descend(element, offset);
11945      var span = SugarElement.fromHtml('<span data-mce-bogus="all" style="display: inline-block;">' + ZWSP$1 + '</span>');
11946      before$4(startPoint.element, span);
11947      return markerInfo(span, function () {
11948        return remove$7(span);
11949      });
11950    };
11951    var elementMarker = function (element) {
11952      return markerInfo(SugarElement.fromDom(element), noop);
11953    };
11954    var withMarker = function (editor, f, rng, alignToTop) {
11955      preserveWith(editor, function (_s, _e) {
11956        return applyWithMarker(editor, f, rng, alignToTop);
11957      }, rng);
11958    };
11959    var withScrollEvents = function (editor, doc, f, marker, alignToTop) {
11960      var data = {
11961        elm: marker.element.dom,
11962        alignToTop: alignToTop
11963      };
11964      if (fireScrollIntoViewEvent(editor, data)) {
11965        return;
11966      }
11967      var scrollTop = get$8(doc).top;
11968      f(doc, scrollTop, marker, alignToTop);
11969      fireAfterScrollIntoViewEvent(editor, data);
11970    };
11971    var applyWithMarker = function (editor, f, rng, alignToTop) {
11972      var body = SugarElement.fromDom(editor.getBody());
11973      var doc = SugarElement.fromDom(editor.getDoc());
11974      reflow(body);
11975      var marker = createMarker(SugarElement.fromDom(rng.startContainer), rng.startOffset);
11976      withScrollEvents(editor, doc, f, marker, alignToTop);
11977      marker.cleanup();
11978    };
11979    var withElement = function (editor, element, f, alignToTop) {
11980      var doc = SugarElement.fromDom(editor.getDoc());
11981      withScrollEvents(editor, doc, f, elementMarker(element), alignToTop);
11982    };
11983    var preserveWith = function (editor, f, rng) {
11984      var startElement = rng.startContainer;
11985      var startOffset = rng.startOffset;
11986      var endElement = rng.endContainer;
11987      var endOffset = rng.endOffset;
11988      f(SugarElement.fromDom(startElement), SugarElement.fromDom(endElement));
11989      var newRng = editor.dom.createRng();
11990      newRng.setStart(startElement, startOffset);
11991      newRng.setEnd(endElement, endOffset);
11992      editor.selection.setRng(rng);
11993    };
11994    var scrollToMarker = function (marker, viewHeight, alignToTop, doc) {
11995      var pos = marker.pos;
11996      if (alignToTop) {
11997        to(pos.left, pos.top, doc);
11998      } else {
11999        var y = pos.top - viewHeight + marker.height;
12000        to(pos.left, y, doc);
12001      }
12002    };
12003    var intoWindowIfNeeded = function (doc, scrollTop, viewHeight, marker, alignToTo
12003p) {
12004      var viewportBottom = viewHeight + scrollTop;
12005      var markerTop = marker.pos.top;
12006      var markerBottom = marker.bottom;
12007      var largerThanViewport = markerBottom - markerTop >= viewHeight;
12008      if (markerTop < scrollTop) {
12009        scrollToMarker(marker, viewHeight, alignToTop !== false, doc);
12010      } else if (markerTop > viewportBottom) {
12011        var align = largerThanViewport ? alignToTop !== false : alignToTop === true;
12012        scrollToMarker(marker, viewHeight, align, doc);
12013      } else if (markerBottom > viewportBottom && !largerThanViewport) {
12014        scrollToMarker(marker, viewHeight, alignToTop === true, doc);
12015      }
12016    };
12017    var intoWindow = function (doc, scrollTop, marker, alignToTop) {
12018      var viewHeight = doc.dom.defaultView.innerHeight;
12019      intoWindowIfNeeded(doc, scrollTop, viewHeight, marker, alignToTop);
12020    };
12021    var intoFrame = function (doc, scrollTop, marker, alignToTop) {
12022      var frameViewHeight = doc.dom.defaultView.innerHeight;
12023      intoWindowIfNeeded(doc, scrollTop, frameViewHeight, marker, alignToTop);
12024      var op = find$1(marker.element);
12025      var viewportBounds = getBounds(window);
12026      if (op.top < viewportBounds.y) {
12027        intoView(marker.element, alignToTop !== false);
12028      } else if (op.top > viewportBounds.bottom) {
12029        intoView(marker.element, alignToTop === true);
12030      }
12031    };
12032    var rangeIntoWindow = function (editor, rng, alignToTop) {
12033      return withMarker(editor, intoWindow, rng, alignToTop);
12034    };
12035    var elementIntoWindow = function (editor, element, alignToTop) {
12036      return withElement(editor, element, intoWindow, alignToTop);
12037    };
12038    var rangeIntoFrame = function (editor, rng, alignToTop) {
12039      return withMarker(editor, intoFrame, rng, alignToTop);
12040    };
12041    var elementIntoFrame = function (editor, element, alignToTop) {
12042      return withElement(editor, element, intoFrame, alignToTop);
12043    };
12044    var scrollElementIntoView = function (editor, element, alignToTop) {
12045      var scroller = editor.inline ? elementIntoWindow : elementIntoFrame;
12046      scroller(editor, element, alignToTop);
12047    };
12048    var scrollRangeIntoView = function (editor, rng, alignToTop) {
12049      var scroller = editor.inline ? rangeIntoWindow : rangeIntoFrame;
12050      scroller(editor, rng, alignToTop);
12051    };
12052
12053    var getDocument = function () {
12054      return SugarElement.fromDom(document);
12055    };
12056
12057    var focus$1 = function (element) {
12058      return element.dom.focus();
12059    };
12060    var hasFocus$1 = function (element) {
12061      var root = getRootNode(element).dom;
12062      return element.dom === root.activeElement;
12063    };
12064    var active = function (root) {
12065      if (root === void 0) {
12066        root = getDocument();
12067      }
12068      return Optional.from(root.dom.activeElement).map(SugarElement.fromDom);
12069    };
12070    var search = function (element) {
12071      return active(getRootNode(element)).filter(function (e) {
12072        return element.dom.contains(e.dom);
12073      });
12074    };
12075
12076    var create$5 = function (start, soffset, finish, foffset) {
12077      return {
12078        start: start,
12079        soffset: soffset,
12080        finish: finish,
12081        foffset: foffset
12082      };
12083    };
12084    var SimRange = { create: create$5 };
12085
12086    var adt$1 = Adt.generate([
12087      { before: ['element'] },
12088      {
12089        on: [
12090          'element',
12091          'offset'
12092        ]
12093      },
12094      { after: ['element'] }
12095    ]);
12096    var cata = function (subject, onBefore, onOn, onAfter) {
12097      return subject.fold(onBefore, onOn, onAfter);
12098    };
12099    var getStart$2 = function (situ) {
12100      return situ.fold(identity, identity, identity);
12101    };
12102    var before$1 = adt$1.before;
12103    var on = adt$1.on;
12104    var after$1 = adt$1.after;
12105    var Situ = {
12106      before: before$1,
12107      on: on,
12108      after: after$1,
12109      cata: cata,
12110      getStart: getStart$2
12111    };
12112
12113    var adt = Adt.generate([
12114      { domRange: ['rng'] },
12115      {
12116        relative: [
12117          'startSitu',
12118          'finishSitu'
12119        ]
12120      },
12121      {
12122        exact: [
12123          'start',
12124          'soffset',
12125          'finish',
12126          'foffset'
12127        ]
12128      }
12129    ]);
12130    var exactFromRange = function (simRange) {
12131      return adt.exact(simRange.start, simRange.soffset, simRange.finish, simRange.foffset);
12132    };
12133    var getStart$1 = function (selection) {
12134      return selection.match({
12135        domRange: function (rng) {
12136          return SugarElement.fromDom(rng.startContainer);
12137        },
12138        relative: function (startSitu, _finishSitu) {
12139          return Situ.getStart(startSitu);
12140        },
12141        exact: function (start, _soffset, _finish, _foffset) {
12142          return start;
12143        }
12144      });
12145    };
12146    var domRange = adt.domRange;
12147    var relative = adt.relative;
12148    var exact = adt.exact;
12149    var getWin = function (selection) {
12150      var start = getStart$1(selection);
12151      return defaultView(start);
12152    };
12153    var range = SimRange.create;
12154    var SimSelection = {
12155      domRange: domRange,
12156      relative: relative,
12157      exact: exact,
12158      exactFromRange: exactFromRange,
12159      getWin: getWin,
12160      range: range
12161    };
12162
12163    var browser$1 = detect().browser;
12164    var clamp$1 = function (offset, element) {
12165      var max = isText$8(element) ? get$2(element).length : children(element).length + 1;
12166      if (offset > max) {
12167        return max;
12168      } else if (offset < 0) {
12169        return 0;
12170      }
12171      return offset;
12172    };
12173    var normalizeRng = function (rng) {
12174      return SimSelection.range(rng.start, clamp$1(rng.soffset, rng.start), rng.finish, clamp$1(rng.foffset, rng.finish));
12175    };
12176    var isOrContains = function (root, elm) {
12177      return !isRestrictedNode(elm.dom) && (contains$1(root, elm) || eq(root, elm));
12178    };
12179    var isRngInRoot = function (root) {
12180      return function (rng) {
12181        return isOrContains(root, rng.start) && isOrContains(root, rng.finish);
12182      };
12183    };
12184    var shouldStore = function (editor) {
12185      return editor.inline === true || browser$1.isIE();
12186    };
12187    var nativeRangeToSelectionRange = function (r) {
12188      return SimSelection.range(SugarElement.fromDom(r.startContainer), r.startOffset, SugarElement.fromDom(r.endContainer), r.endOffset);
12189    };
12190    var readRange = function (win) {
12191      var selection = win.getSelection();
12192      var rng = !selection || selection.rangeCount === 0 ? Optional.none() : Optional.from(selection.getRangeAt(0));
12193      return rng.map(nativeRangeToSelectionRange);
12194    };
12195    var getBookmark = function (root) {
12196      var win = defaultView(root);
12197      return readRange(win.dom).filter(isRngInRoot(root));
12198    };
12199    var validate = function (root, bookmark) {
12200      return Optional.from(bookmark).filter(isRngInRoot(root)).map(normalizeRng);
12201    };
12202    var bookmarkToNativeRng = function (bookmark) {
12203      var rng = document.createRange();
12204      try {
12205        rng.setStart(bookmark.start.dom, bookmark.soffset);
12206        rng.setEnd(bookmark.finish.dom, bookmark.foffset);
12207        return Optional.some(rng);
12208      } catch (_) {
12209        return Optional.none();
12210      }
12211    };
12212    var store = function (editor) {
12213      var newBookmark = shouldStore(editor) ? getBookmark(SugarElement.fromDom(editor.getBody())) : Optional.none();
12214      editor.bookmark = newBookmark.isSome() ? newBookmark : editor.bookmark;
12215    };
12216    var storeNative = function (editor, rng) {
12217      var root = SugarElement.fromDom(editor.getBody());
12218      var range = shouldStore(editor) ? Optional.from(rng) : Optional.none();
12219      var newBookmark = range.map(nativeRangeToSelectionRange).filter(isRngInRoot(root));
12220      editor.bookmark = newBookmark.isSome() ? newBookmark : editor.bookmark;
12221    };
12222    var getRng = function (editor) {
12223      var bookmark = editor.bookmark ? editor.bookmark : Optional.none();
12224      return bookmark.bind(function (x) {
12225        return validate(SugarElement.fromDom(editor.getBody()), x);
12226      }).bind(bookmarkToNativeRng);
12227    };
12228    var restore = function (editor) {
12229      getRng(editor).each(function (rng) {
12230        return editor.selection.setRng(rng);
12231      });
12232    };
12233
12234    var isEditorUIElement$1 = function (elm) {
12235      var className = elm.className.toString();
12236      return className.indexOf('tox-') !== -1 || className.indexOf('mce-') !== -1;
12237    };
12238    var FocusManager = { isEditorUIElement: isEditorUIElement$1 };
12239
12240    var isManualNodeChange = function (e) {
12241      return e.type === 'nodechange' && e.selectionChange;
12242    };
12243    var registerPageMouseUp = function (editor, throttledStore) {
12244      var mouseUpPage = function () {
12245        throttledStore.throttle();
12246      };
12247      DOMUtils.DOM.bind(document, 'mouseup', mouseUpPage);
12248      editor.on('remove', function () {
12249        DOMUtils.DOM.unbind(document, 'mouseup', mouseUpPage);
12250      });
12251    };
12252    var registerFocusOut = function (editor) {
12253      editor.on('focusout', function () {
12254        store(editor);
12255      });
12256    };
12257    var registerMouseUp = function (editor, throttledStore) {
12258      editor.on('mouseup touchend', function (_e) {
12259        throttledStore.throttle();
12260      });
12261    };
12262    var registerEditorEvents = function (editor, throttledStore) {
12263      var browser = detect().browser;
12264      if (browser.isIE()) {
12265        registerFocusOut(editor);
12266      } else {
12267        registerMouseUp(editor, throttledStore);
12268      }
12269      editor.on('keyup NodeChange', function (e) {
12270        if (!isManualNodeChange(e)) {
12271          store(editor);
12272        }
12273      });
12274    };
12275    var register$3 = function (editor) {
12276      var throttledStore = first(function () {
12277        store(editor);
12278      }, 0);
12279      editor.on('init', function () {
12280        if (editor.inline) {
12281          registerPageMouseUp(editor, throttledStore);
12282        }
12283        registerEditorEvents(editor, throttledStore);
12284      });
12285      editor.on('remove', function () {
12286        throttledStore.cancel();
12287      });
12288    };
12289
12290    var documentFocusInHandler;
12291    var DOM$8 = DOMUtils.DOM;
12292    var isEditorUIElement = function (elm) {
12293      return FocusManager.isEditorUIElement(elm);
12294    };
12295    var isEditorContentAreaElement = function (elm) {
12296      var classList = elm.classList;
12297      if (classList !== undefined) {
12298        return classList.contains('tox-edit-area') || classList.contains('tox-edit-area__iframe') || classList.contains('mce-content-body');
12299      } else {
12300        return false;
12301      }
12302    };
12303    var isUIElement = function (editor, elm) {
12304      var customSelector = getCustomUiSelector(editor);
12305      var parent = DOM$8.getParent(elm, function (elm) {
12306        return isEditorUIElement(elm) || (customSelector ? editor.dom.is(elm, customSelector) : false);
12307      });
12308      return parent !== null;
12309    };
12310    var getActiveElement = function (editor) {
12311      try {
12312        var root = getRootNode(SugarElement.fromDom(editor.getElement()));
12313        return active(root).fold(function () {
12314          return document.body;
12315        }, function (x) {
12316          return x.dom;
12317        });
12318      } catch (ex) {
12319        return document.body;
12320      }
12321    };
12322    var registerEvents$1 = function (editorManager, e) {
12323      var editor = e.editor;
12324      register$3(editor);
12325      editor.on('focusin', function () {
12326        var focusedEditor = editorManager.focusedEditor;
12327        if (focusedEditor !== editor) {
12328          if (focusedEditor) {
12329            focusedEditor.fire('blur', { focusedEditor: editor });
12330          }
12331          editorManager.setActive(editor);
12332          editorManager.focusedEditor = editor;
12333          editor.fire('focus', { blurredEditor: focusedEditor });
12334          editor.focus(true);
12335        }
12336      });
12337      editor.on('focusout', function () {
12338        Delay.setEditorTimeout(editor, function () {
12339          var focusedEditor = editorManager.focusedEditor;
12340          if (!isUIElement(editor, getActiveElement(editor)) && focusedEditor === editor) {
12341            editor.fire('blur', { focusedEditor: null });
12342            editorManager.focusedEditor = null;
12343          }
12344        });
12345      });
12346      if (!documentFocusInHandler) {
12347        documentFocusInHandler = function (e) {
12348          var activeEditor = editorManager.activeEditor;
12349          if (activeEditor) {
12350            getOriginalEventTarget(e).each(function (target) {
12351              if (target.ownerDocument === document) {
12352                if (target !== document.body && !isUIElement(activeEditor, target) && editorManager.focusedEditor === activeEditor) {
12353                  activeEditor.fire('blur', { focusedEditor: null });
12354                  editorManager.focusedEditor = null;
12355                }
12356              }
12357            });
12358          }
12359        };
12360        DOM$8.bind(document, 'focusin', documentFocusInHandler);
12361      }
12362    };
12363    var unregisterDocumentEvents = function (editorManager, e) {
12364      if (editorManager.focusedEditor === e.editor) {
12365        editorManager.focusedEditor = null;
12366      }
12367      if (!editorManager.activeEditor) {
12368        DOM$8.unbind(document, 'focusin', documentFocusInHandler);
12369        documentFocusInHandler = null;
12370      }
12371    };
12372    var setup$l = function (editorManager) {
12373      editorManager.on('AddEditor', curry(registerEvents$1, editorManager));
12374      editorManager.on('RemoveEditor', curry(unregisterDocumentEvents, editorManager));
12375    };
12376
12377    var getContentEditableHost = function (editor, node) {
12378      return editor.dom.getParent(node, function (node) {
12379        return editor.dom.getContentEditable(node) === 'true';
12380      });
12381    };
12382    var getCollapsedNode = function (rng) {
12383      return rng.collapsed ? Optional.from(getNode$1(rng.startContainer, rng.startOffset)).map(SugarElement.fromDom) : Optional.none();
12384    };
12385    var getFocusInElement = function (root, rng) {
12386      return getCollapsedNode(rng).bind(function (node) {
12387        if (isTableSection(node)) {
12388          return Optional.some(node);
12389        } else if (contains$1(root, node) === false) {
12390          return Optional.some(root);
12391        } else {
12392          return Optional.none();
12393        }
12394      });
12395    };
12396    var normalizeSelection$1 = function (editor, rng) {
12397      getFocusInElement(SugarElement.fromDom(editor.getBody()), rng).bind(function (elm) {
12398        return firstPositionIn(elm.dom);
12399      }).fold(function () {
12400        editor.selection.normalize();
12401        return;
12402      }, function (caretPos) {
12403        return editor.selection.setRng(caretPos.toRange());
12404      });
12405    };
12406    var focusBody = function (body) {
12407      if (body.setActive) {
12408        try {
12409          body.setActive();
12410        } catch (ex) {
12411          body.focus();
12412        }
12413      } else {
12414        body.focus();
12415      }
12416    };
12417    var hasElementFocus = function (elm) {
12418      return hasFocus$1(elm) || search(elm).isSome();
12419    };
12420    var hasIframeFocus = function (editor) {
12421      return editor.iframeElement && hasFocus$1(SugarElement.fromDom(editor.iframeElement));
12422    };
12423    var hasInlineFocus = function (editor) {
12424      var rawBody = editor.getBody();
12425      return rawBody && hasElementFocus(SugarElement.fromDom(rawBody));
12426    };
12427    var hasUiFocus = function (editor) {
12428      var dos = getRootNode(SugarElement.fromDom(editor.getElement()));
12429      return active(dos).filter(function (elem) {
12430        return !isEditorContentAreaElement(elem.dom) && isUIElement(editor, elem.dom);
12431      }).isSome();
12432    };
12433    var hasFocus = function (editor) {
12434      return editor.inline ? hasInlineFocus(editor) : hasIframeFocus(editor);
12435    };
12436    var hasEditorOrUiFocus = function (editor) {
12437      return hasFocus(editor) || hasUiFocus(editor);
12438    };
12439    var focusEditor = function (editor) {
12440      var selection = editor.selection;
12441      var body = editor.getBody();
12442      var rng = selection.getRng();
12443      editor.quirks.refreshContentEditable();
12444      if (editor.bookmark !== undefined && hasFocus(editor) === false) {
12445        getRng(editor).each(function (bookmarkRng) {
12446          editor.selection.setRng(bookmarkRng);
12447          rng = bookmarkRng;
12448        });
12449      }
12450      var contentEditableHost = getContentEditableHost(editor, selection.getNode());
12451      if (editor.$.contains(body, contentEditableHost)) {
12452        focusBody(contentEditableHost);
12453        normalizeSelection$1(editor, rng);
12454        activateEditor(editor);
12455        return;
12456      }
12457      if (!editor.inline) {
12458        if (!Env.opera) {
12459          focusBody(body);
12460        }
12461        editor.getWin().focus();
12462      }
12463      if (Env.gecko || editor.inline) {
12464        focusBody(body);
12465        normalizeSelection$1(editor, rng);
12466      }
12467      activateEditor(editor);
12468    };
12469    var activateEditor = function (editor) {
12470      return editor.editorManager.setActive(editor);
12471    };
12472    var focus = function (editor, skipFocus) {
12473      if (editor.removed) {
12474        return;
12475      }
12476      if (skipFocus) {
12477        activateEditor(editor);
12478      } else {
12479        focusEditor(editor);
12480      }
12481    };
12482
12483    var getEndpointElement = function (root, rng, start, real, resolve) {
12484      var container = start ? rng.startContainer : rng.endContainer;
12485      var offset = start ? rng.startOffset : rng.endOffset;
12486      return Optional.from(container).map(SugarElement.fromDom).map(function (elm) {
12487        return !real || !rng.collapsed ? child$1(elm, resolve(elm, offset)).getOr(elm) : elm;
12488      }).bind(function (elm) {
12489        return isElement$6(elm) ? Optional.some(elm) : parent(elm).filter(isElement$6);
12490      }).map(function (elm) {
12491        return elm.dom;
12492      }).getOr(root);
12493    };
12494    var getStart = function (root, rng, real) {
12495      return getEndpointElement(root, rng, true, real, function (elm, offset) {
12496        return Math.min(childNodesCount(elm), offset);
12497      });
12498    };
12499    var getEnd = function (root, rng, real) {
12500      return getEndpointElement(root, rng, false, real, function (elm, offset) {
12501        return offset > 0 ? offset - 1 : offset;
12502      });
12503    };
12504    var skipEmptyTextNodes = function (node, forwards) {
12505      var orig = node;
12506      while (node && isText$7(node) && node.length === 0) {
12507        node = forwards ? node.nextSibling : node.previousSibling;
12508      }
12509      return node || orig;
12510    };
12511    var getNode = function (root, rng) {
12512      var elm, startContainer, endContainer;
12513      if (!rng) {
12514        return root;
12515      }
12516      startContainer = rng.startContainer;
12517      endContainer = rng.endContainer;
12518      var startOffset = rng.startOffset;
12519      var endOffset = rng.endOffset;
12520      elm = rng.commonAncestorContainer;
12521      if (!rng.collapsed) {
12522        if (startContainer === endContainer) {
12523          if (endOffset - startOffset < 2) {
12524            if (startContainer.hasChildNodes()) {
12525              elm = startContainer.childNodes[startOffset];
12526            }
12527          }
12528        }
12529        if (startContainer.nodeType === 3 && endContainer.nodeType === 3) {
12530          if (startContainer.length === startOffset) {
12531            startContainer = skipEmptyTextNodes(startContainer.nextSibling, true);
12532          } else {
12533            startContainer = startContainer.parentNode;
12534          }
12535          if (endOffset === 0) {
12536            endContainer = skipEmptyTextNodes(endContainer.previousSibling, false);
12537          } else {
12538            endContainer = endContainer.parentNode;
12539          }
12540          if (startContainer && startContainer === endContainer) {
12541            return startContainer;
12542          }
12543        }
12544      }
12545      if (elm && elm.nodeType === 3) {
12546        return elm.parentNode;
12547      }
12548      return elm;
12549    };
12550    var getSelectedBlocks = function (dom, rng, startElm, endElm) {
12551      var node;
12552      var selectedBlocks = [];
12553      var root = dom.getRoot();
12554      startElm = dom.getParent(startElm || getStart(root, rng, rng.collapsed), dom.isBlock);
12555      endElm = dom.getParent(endElm || getEnd(root, rng, rng.collapsed), dom.isBlock);
12556      if (startElm && startElm !== root) {
12557        selectedBlocks.push(startElm);
12558      }
12559      if (startElm && endElm && startElm !== endElm) {
12560        node = startElm;
12561        var walker = new DomTreeWalker(startElm, root);
12562        while ((node = walker.next()) && node !== endElm) {
12563          if (dom.isBlock(node)) {
12564            selectedBlocks.push(node);
12565          }
12566        }
12567      }
12568      if (endElm && startElm !== endElm && endElm !== root) {
12569        selectedBlocks.push(endElm);
12570      }
12571      return selectedBlocks;
12572    };
12573    var select = function (dom, node, content) {
12574      return Optional.from(node).map(function (node) {
12575        var idx = dom.nodeIndex(node);
12576        var rng = dom.createRng();
12577        rng.setStart(node.parentNode, idx);
12578        rng.setEnd(node.parentNode, idx + 1);
12579        if (content) {
12580          moveEndPoint(dom, rng, node, true);
12581          moveEndPoint(dom, rng, node, false);
12582        }
12583        return rng;
12584      });
12585    };
12586
12587    var processRanges = function (editor, ranges) {
12588      return map$3(ranges, function (range) {
12589        var evt = editor.fire('GetSelectionRange', { range: range });
12590        return evt.range !== range ? evt.range : range;
12591      });
12592    };
12593
12594    var typeLookup = {
12595      '#text': 3,
12596      '#comment': 8,
12597      '#cdata': 4,
12598      '#pi': 7,
12599      '#doctype': 10,
12600      '#document-fragment': 11
12601    };
12602    var walk$1 = function (node, root, prev) {
12603      var startName = prev ? 'lastChild' : 'firstChild';
12604      var siblingName = prev ? 'prev' : 'next';
12605      if (node[startName]) {
12606        return node[startName];
12607      }
12608      if (node !== root) {
12609        var sibling = node[siblingName];
12610        if (sibling) {
12611          return sibling;
12612        }
12613        for (var parent_1 = node.parent; parent_1 && parent_1 !== root; parent_1 = parent_1.parent) {
12614          sibling = parent_1[siblingName];
12615          if (sibling) {
12616            return sibling;
12617          }
12618        }
12619      }
12620    };
12621    var isEmptyTextNode = function (node) {
12622      if (!isWhitespaceText(node.value)) {
12623        return false;
12624      }
12625      var parentNode = node.parent;
12626      if (parentNode && (parentNode.name !== 'span' || parentNode.attr('style')) && /^[ ]+$/.test(node.value)) {
12627        return false;
12628      }
12629      return true;
12630    };
12631    var isNonEmptyElement = function (node) {
12632      var isNamedAnchor = node.name === 'a' && !node.attr('href') && node.attr('id');
12633      return node.attr('name') || node.attr('id') && !node.firstChild || node.attr('data-mce-bookmark') || isNamedAnchor;
12634    };
12635    var AstNode = function () {
12636      function AstNode(name, type) {
12637        this.name = name;
12638        this.type = type;
12639        if (type === 1) {
12640          this.attributes = [];
12641          this.attributes.map = {};
12642        }
12643      }
12644      AstNode.create = function (name, attrs) {
12645        var node = new AstNode(name, typeLookup[name] || 1);
12646        if (attrs) {
12647          each$j(attrs, function (value, attrName) {
12648            node.attr(attrName, value);
12649          });
12650        }
12651        return node;
12652      };
12653      AstNode.prototype.replace = function (node) {
12654        var self = this;
12655        if (node.parent) {
12656          node.remove();
12657        }
12658        self.insert(node, self);
12659        self.remove();
12660        return self;
12661      };
12662      AstNode.prototype.attr = function (name, value) {
12663        var self = this;
12664        var attrs;
12665        if (typeof name !== 'string') {
12666          if (name !== undefined && name !== null) {
12667            each$j(name, function (value, key) {
12668              self.attr(key, value);
12669            });
12670          }
12671          return self;
12672        }
12673        if (attrs = self.attributes) {
12674          if (value !== undefined) {
12675            if (value === null) {
12676              if (name in attrs.map) {
12677                delete attrs.map[name];
12678                var i = attrs.length;
12679                while (i--) {
12680                  if (attrs[i].name === name) {
12681                    attrs.splice(i, 1);
12682                    return self;
12683                  }
12684                }
12685              }
12686              return self;
12687            }
12688            if (name in attrs.map) {
12689              var i = attrs.length;
12690              while (i--) {
12691                if (attrs[i].name === name) {
12692                  attrs[i].value = value;
12693                  break;
12694                }
12695              }
12696            } else {
12697              attrs.push({
12698                name: name,
12699                value: value
12700              });
12701            }
12702            attrs.map[name] = value;
12703            return self;
12704          }
12705          return attrs.map[name];
12706        }
12707      };
12708      AstNode.prototype.clone = function () {
12709        var self = this;
12710        var clone = new AstNode(self.name, self.type);
12711        var selfAttrs;
12712        if (selfAttrs = self.attributes) {
12713          var cloneAttrs = [];
12714          cloneAttrs.map = {};
12715          for (var i = 0, l = selfAttrs.length; i < l; i++) {
12716            var selfAttr = selfAttrs[i];
12717            if (selfAttr.name !== 'id') {
12718              cloneAttrs[cloneAttrs.length] = {
12719                name: selfAttr.name,
12720                value: selfAttr.value
12721              };
12722              cloneAttrs.map[selfAttr.name] = selfAttr.value;
12723            }
12724          }
12725          clone.attributes = cloneAttrs;
12726        }
12727        clone.value = self.value;
12728        clone.shortEnded = self.shortEnded;
12729        return clone;
12730      };
12731      AstNode.prototype.wrap = function (wrapper) {
12732        var self = this;
12733        self.parent.insert(wrapper, self);
12734        wrapper.append(self);
12735        return self;
12736      };
12737      AstNode.prototype.unwrap = function () {
12738        var self = this;
12739        for (var node = self.firstChild; node;) {
12740          var next = node.next;
12741          self.insert(node, self, true);
12742          node = next;
12743        }
12744        self.remove();
12745      };
12746      AstNode.prototype.remove = function () {
12747        var self = this, parent = self.parent, next = self.next, prev = self.prev;
12748        if (parent) {
12749          if (parent.firstChild === self) {
12750            parent.firstChild = next;
12751            if (next) {
12752              next.prev = null;
12753            }
12754          } else {
12755            prev.next = next;
12756          }
12757          if (parent.lastChild === self) {
12758            parent.lastChild = prev;
12759            if (prev) {
12760              prev.next = null;
12761            }
12762          } else {
12763            next.prev = prev;
12764          }
12765          self.parent = self.next = self.prev = null;
12766        }
12767        return self;
12768      };
12769      AstNode.prototype.append = function (node) {
12770        var self = this;
12771        if (node.parent) {
12772          node.remove();
12773        }
12774        var last = self.lastChild;
12775        if (last) {
12776          last.next = node;
12777          node.prev = last;
12778          self.lastChild = node;
12779        } else {
12780          self.lastChild = self.firstChild = node;
12781        }
12782        node.parent = self;
12783        return node;
12784      };
12785      AstNode.prototype.insert = function (node, refNode, before) {
12786        if (node.parent) {
12787          node.remove();
12788        }
12789        var parent = refNode.parent || this;
12790        if (before) {
12791          if (refNode === parent.firstChild) {
12792            parent.firstChild = node;
12793          } else {
12794            refNode.prev.next = node;
12795          }
12796          node.prev = refNode.prev;
12797          node.next = refNode;
12798          refNode.prev = node;
12799        } else {
12800          if (refNode === parent.lastChild) {
12801            parent.lastChild = node;
12802          } else {
12803            refNode.next.prev = node;
12804          }
12805          node.next = refNode.next;
12806          node.prev = refNode;
12807          refNode.next = node;
12808        }
12809        node.parent = parent;
12810        return node;
12811      };
12812      AstNode.prototype.getAll = function (name) {
12813        var self = this;
12814        var collection = [];
12815        for (var node = self.firstChild; node; node = walk$1(node, self)) {
12816          if (node.name === name) {
12817            collection.push(node);
12818          }
12819        }
12820        return collection;
12821      };
12822      AstNode.prototype.children = function () {
12823        var self = this;
12824        var collection = [];
12825        for (var node = self.firstChild; node; node = node.next) {
12826          collection.push(node);
12827        }
12828        return collection;
12829      };
12830      AstNode.prototype.empty = function () {
12831        var self = this;
12832        if (self.firstChild) {
12833          var nodes = [];
12834          for (var node = self.firstChild; node; node = walk$1(node, self)) {
12835            nodes.push(node);
12836          }
12837          var i = nodes.length;
12838          while (i--) {
12839            var node = nodes[i];
12840            node.parent = node.firstChild = node.lastChild = node.next = node.prev = null;
12841          }
12842        }
12843        self.firstChild = self.lastChild = null;
12844        return self;
12845      };
12846      AstNode.prototype.isEmpty = function (elements, whitespace, predicate) {
12847        if (whitespace === void 0) {
12848          whitespace = {};
12849        }
12850        var self = this;
12851        var node = self.firstChild;
12852        if (isNonEmptyElement(self)) {
12853          return false;
12854        }
12855        if (node) {
12856          do {
12857            if (node.type === 1) {
12858              if (node.attr('data-mce-bogus')) {
12859                continue;
12860              }
12861              if (elements[node.name]) {
12862                return false;
12863              }
12864              if (isNonEmptyElement(node)) {
12865                return false;
12866              }
12867            }
12868            if (node.type === 8) {
12869              return false;
12870            }
12871            if (node.type === 3 && !isEmptyTextNode(node)) {
12872              return false;
12873            }
12874            if (node.type === 3 && node.parent && whitespace[node.parent.name] && isWhitespaceText(node.value)) {
12875              return false;
12876            }
12877            if (predicate && predicate(node)) {
12878              return false;
12879            }
12880          } while (node = walk$1(node, self));
12881        }
12882        return true;
12883      };
12884      AstNode.prototype.walk = function (prev) {
12885        return walk$1(this, null, prev);
12886      };
12887      return AstNode;
12888    }();
12889
12890    var unescapedTextParents = Tools.makeMap('NOSCRIPT STYLE SCRIPT XMP IFRAME NOEMBED NOFRAMES PLAINTEXT', ' ');
12891    var containsZwsp = function (node) {
12892      return isString$1(node.nodeValue) && contains$2(node.nodeValue, ZWSP$1);
12893    };
12894    var getTemporaryNodeSelector = function (tempAttrs) {
12895      return (tempAttrs.length === 0 ? '' : map$3(tempAttrs, function (attr) {
12896        return '[' + attr + ']';
12897      }).join(',') + ',') + '[data-mce-bogus="all"]';
12898    };
12899    var getTemporaryNodes = function (tempAttrs, body) {
12900      return body.querySelectorAll(getTemporaryNodeSelector(tempAttrs));
12901    };
12902    var createWalker = function (body, whatToShow, filter) {
12903      return document.createTreeWalker(body, whatToShow, filter, false);
12904    };
12905    var createZwspCommentWalker = function (body) {
12906      return createWalker(body, NodeFilter.SHOW_COMMENT, function (node) {
12907        return containsZwsp(node) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
12908      });
12909    };
12910    var createUnescapedZwspTextWalker = function (body) {
12911      return createWalker(body, NodeFilter.SHOW_TEXT, function (node) {
12912        if (containsZwsp(node)) {
12913          var parent_1 = node.parentNode;
12914          return parent_1 && has$2(unescapedTextParents, parent_1.nodeName) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
12915        } else {
12916          return NodeFilter.FILTER_SKIP;
12917        }
12918      });
12919    };
12920    var hasZwspComment = function (body) {
12921      return createZwspCommentWalker(body).nextNode() !== null;
12922    };
12923    var hasUnescapedZwspText = function (body) {
12924      return createUnescapedZwspTextWalker(body).nextNode() !== null;
12925    };
12926    var hasTemporaryNode = function (tempAttrs, body) {
12927      return body.querySelector(getTemporaryNodeSelector(tempAttrs)) !== null;
12928    };
12929    var trimTemporaryNodes = function (tempAttrs, body) {
12930      each$k(getTemporaryNodes(tempAttrs, body), function (elm) {
12931        var element = SugarElement.fromDom(elm);
12932        if (get$6(element, 'data-mce-bogus') === 'all') {
12933          remove$7(element);
12934        } else {
12935          each$k(tempAttrs, function (attr) {
12936            if (has$1(element, attr)) {
12937              remove$6(element, attr);
12938            }
12939          });
12940        }
12941      });
12942    };
12943    var emptyAllNodeValuesInWalker = function (walker) {
12944      var curr = walker.nextNode();
12945      while (curr !== null) {
12946        curr.nodeValue = null;
12947        curr = walker.nextNode();
12948      }
12949    };
12950    var emptyZwspComments = compose(emptyAllNodeValuesInWalker, createZwspCommentWalker);
12951    var emptyUnescapedZwspTexts = compose(emptyAllNodeValuesInWalker, createUnescapedZwspTextWalker);
12952    var trim$1 = function (body, tempAttrs) {
12953      var conditionalTrims = [
12954        {
12955          condition: curry(hasTemporaryNode, tempAttrs),
12956          action: curry(trimTemporaryNodes, tempAttrs)
12957        },
12958        {
12959          condition: hasZwspComment,
12960          action: emptyZwspComments
12961        },
12962        {
12963          condition: hasUnescapedZwspText,
12964          action: emptyUnescapedZwspTexts
12965        }
12966      ];
12967      var trimmed = body;
12968      var cloned = false;
12969      each$k(conditionalTrims, function (_a) {
12970        var condition = _a.condition, action = _a.action;
12971        if (condition(trimmed)) {
12972          if (!cloned) {
12973            trimmed = body.cloneNode(true);
12974            cloned = true;
12975          }
12976          action(trimmed);
12977        }
12978      });
12979      return trimmed;
12980    };
12981
12982    var trimEmptyContents = function (editor, html) {
12983      var blockName = getForcedRootBlock(editor);
12984      var emptyRegExp = new RegExp('^(<' + blockName + '[^>]*>(&nbsp;|&#160;|\\s|\xA0|<br \\/>|)<\\/' + blockName + '>[\r\n]*|<br \\/>[\r\n]*)$');
12985      return html.replace(emptyRegExp, '');
12986    };
12987    var setupArgs$3 = function (args, format) {
12988      return __assign(__assign({}, args), {
12989        format: format,
12990        get: true,
12991        getInner: true
12992      });
12993    };
12994    var getContentFromBody = function (editor, args, format, body) {
12995      var defaultedArgs = setupArgs$3(args, format);
12996      var updatedArgs = args.no_events ? defaultedArgs : editor.fire('BeforeGetContent', defaultedArgs);
12997      var content;
12998      if (updatedArgs.format === 'raw') {
12999        content = Tools.trim(trim$3(trim$1(body, editor.serializer.getTempAttrs()).innerHTML));
13000      } else if (updatedArgs.format === 'text') {
13001        content = editor.dom.isEmpty(body) ? '' : trim$3(body.innerText || body.textContent);
13002      } else if (updatedArgs.format === 'tree') {
13003        content = editor.serializer.serialize(body, updatedArgs);
13004      } else {
13005        content = trimEmptyContents(editor, editor.serializer.serialize(body, updatedArgs));
13006      }
13007      if (!contains$3([
13008          'text',
13009          'tree'
13010        ], updatedArgs.format) && !isWsPreserveElement(SugarElement.fromDom(body))) {
13011        updatedArgs.content = Tools.trim(content);
13012      } else {
13013        updatedArgs.content = content;
13014      }
13015      if (updatedArgs.no_events) {
13016        return updatedArgs.content;
13017      } else {
13018        return editor.fire('GetContent', updatedArgs).content;
13019      }
13020    };
13021    var getContentInternal = function (editor, args, format) {
13022      return Optional.from(editor.getBody()).fold(constant(args.format === 'tree' ? new AstNode('body', 11) : ''), function (body) {
13023        return getContentFromBody(editor, args, format, body);
13024      });
13025    };
13026
13027    var each$d = Tools.each;
13028    var ElementUtils = function (dom) {
13029      var compare = function (node1, node2) {
13030        if (node1.nodeName !== node2.nodeName) {
13031          return false;
13032        }
13033        var getAttribs = function (node) {
13034          var attribs = {};
13035          each$d(dom.getAttribs(node), function (attr) {
13036            var name = attr.nodeName.toLowerCase();
13037            if (name.indexOf('_') !== 0 && name !== 'style' && name.indexOf('data-') !== 0) {
13038              attribs[name] = dom.getAttrib(node, name);
13039            }
13040          });
13041          return attribs;
13042        };
13043        var compareObjects = function (obj1, obj2) {
13044          var value, name;
13045          for (name in obj1) {
13046            if (has$2(obj1, name)) {
13047              value = obj2[name];
13048              if (typeof value === 'undefined') {
13049                return false;
13050              }
13051              if (obj1[name] !== value) {
13052                return false;
13053              }
13054              delete obj2[name];
13055            }
13056          }
13057          for (name in obj2) {
13058            if (has$2(obj2, name)) {
13059              return false;
13060            }
13061          }
13062          return true;
13063        };
13064        if (!compareObjects(getAttribs(node1), getAttribs(node2))) {
13065          return false;
13066        }
13067        if (!compareObjects(dom.parseStyle(dom.getAttrib(node1, 'style')), dom.parseStyle(dom.getAttrib(node2, 'style')))) {
13068          return false;
13069        }
13070        return !isBookmarkNode$1(node1) && !isBookmarkNode$1(node2);
13071      };
13072      return { compare: compare };
13073    };
13074
13075    var makeMap$1 = Tools.makeMap;
13076    var Writer = function (settings) {
13077      var html = [];
13078      settings = settings || {};
13079      var indent = settings.indent;
13080      var indentBefore = makeMap$1(settings.indent_before || '');
13081      var indentAfter = makeMap$1(settings.indent_after || '');
13082      var encode = Entities.getEncodeFunc(settings.entity_encoding || 'raw', settings.entities);
13083      var htmlOutput = settings.element_format === 'html';
13084      return {
13085        start: function (name, attrs, empty) {
13086          var i, l, attr, value;
13087          if (indent && indentBefore[name] && html.length > 0) {
13088            value = html[html.length - 1];
13089            if (value.length > 0 && value !== '\n') {
13090              html.push('\n');
13091            }
13092          }
13093          html.push('<', name);
13094          if (attrs) {
13095            for (i = 0, l = attrs.length; i < l; i++) {
13096              attr = attrs[i];
13097              html.push(' ', attr.name, '="', encode(attr.value, true), '"');
13098            }
13099          }
13100          if (!empty || htmlOutput) {
13101            html[html.length] = '>';
13102          } else {
13103            html[html.length] = ' />';
13104          }
13105          if (empty && indent && indentAfter[name] && html.length > 0) {
13106            value = html[html.length - 1];
13107            if (value.length > 0 && value !== '\n') {
13108              html.push('\n');
13109            }
13110          }
13111        },
13112        end: function (name) {
13113          var value;
13114          html.push('</', name, '>');
13115          if (indent && indentAfter[name] && html.length > 0) {
13116            value = html[html.length - 1];
13117            if (value.length > 0 && value !== '\n') {
13118              html.push('\n');
13119            }
13120          }
13121        },
13122        text: function (text, raw) {
13123          if (text.length > 0) {
13124            html[html.length] = raw ? text : encode(text);
13125          }
13126        },
13127        cdata: function (text) {
13128          html.push('<![CDATA[', text, ']]>');
13129        },
13130        comment: function (text) {
13131          html.push('<!--', text, '-->');
13132        },
13133        pi: function (name, text) {
13134          if (text) {
13135            html.push('<?', name, ' ', encode(text), '?>');
13136          } else {
13137            html.push('<?', name, '?>');
13138          }
13139          if (indent) {
13140            html.push('\n');
13141          }
13142        },
13143        doctype: function (text) {
13144          html.push('<!DOCTYPE', text, '>', indent ? '\n' : '');
13145        },
13146        reset: function () {
13147          html.length = 0;
13148        },
13149        getContent: function () {
13150          return html.join('').replace(/\n$/, '');
13151        }
13152      };
13153    };
13154
13155    var HtmlSerializer = function (settings, schema) {
13156      if (schema === void 0) {
13157        schema = Schema();
13158      }
13159      var writer = Writer(settings);
13160      settings = settings || {};
13161      settings.validate = 'validate' in settings ? settings.validate : true;
13162      var serialize = function (node) {
13163        var validate = settings.validate;
13164        var handlers = {
13165          3: function (node) {
13166            writer.text(node.value, node.raw);
13167          },
13168          8: function (node) {
13169            writer.comment(node.value);
13170          },
13171          7: function (node) {
13172            writer.pi(node.name, node.value);
13173          },
13174          10: function (node) {
13175            writer.doctype(node.value);
13176          },
13177          4: function (node) {
13178            writer.cdata(node.value);
13179          },
13180          11: function (node) {
13181            if (node = node.firstChild) {
13182              do {
13183                walk(node);
13184              } while (node = node.next);
13185            }
13186          }
13187        };
13188        writer.reset();
13189        var walk = function (node) {
13190          var handler = handlers[node.type];
13191          if (!handler) {
13192            var name_1 = node.name;
13193            var isEmpty = node.shortEnded;
13194            var attrs = node.attributes;
13195            if (validate && attrs && attrs.length > 1) {
13196              var sortedAttrs = [];
13197              sortedAttrs.map = {};
13198              var elementRule = schema.getElementRule(node.name);
13199              if (elementRule) {
13200                for (var i = 0, l = elementRule.attributesOrder.length; i < l; i++) {
13201                  var attrName = elementRule.attributesOrder[i];
13202                  if (attrName in attrs.map) {
13203                    var attrValue = attrs.map[attrName];
13204                    sortedAttrs.map[attrName] = attrValue;
13205                    sortedAttrs.push({
13206                      name: attrName,
13207                      value: attrValue
13208                    });
13209                  }
13210                }
13211                for (var i = 0, l = attrs.length; i < l; i++) {
13212                  var attrName = attrs[i].name;
13213                  if (!(attrName in sortedAttrs.map)) {
13214                    var attrValue = attrs.map[attrName];
13215                    sortedAttrs.map[attrName] = attrValue;
13216                    sortedAttrs.push({
13217                      name: attrName,
13218                      value: attrValue
13219                    });
13220                  }
13221                }
13222                attrs = sortedAttrs;
13223              }
13224            }
13225            writer.start(node.name, attrs, isEmpty);
13226            if (!isEmpty) {
13227              if (node = node.firstChild) {
13228                do {
13229                  walk(node);
13230                } while (node = node.next);
13231              }
13232              writer.end(name_1);
13233            }
13234          } else {
13235            handler(node);
13236          }
13237        };
13238        if (node.type === 1 && !settings.inner) {
13239          walk(node);
13240        } else {
13241          handlers[11](node);
13242        }
13243        return writer.getContent();
13244      };
13245      return { serialize: serialize };
13246    };
13247
13248    var nonInheritableStyles = new Set();
13249    (function () {
13250      var nonInheritableStylesArr = [
13251        'margin',
13252        'margin-left',
13253        'margin-right',
13254        'margin-top',
13255        'margin-bottom',
13256        'padding',
13257        'padding-left',
13258        'padding-right',
13259        'padding-top',
13260        'padding-bottom',
13261        'border',
13262        'border-width',
13263        'border-style',
13264        'border-color',
13265        'background',
13266        'background-attachment',
13267        'background-clip',
13268        'background-color',
13269        'background-image',
13270        'background-origin',
13271        'background-position',
13272        'background-repeat',
13273        'background-size',
13274        'float',
13275        'position',
13276        'left',
13277        'right',
13278        'top',
13279        'bottom',
13280        'z-index',
13281        'display',
13282        'transform',
13283        'width',
13284        'max-width',
13285        'min-width',
13286        'height',
13287        'max-height',
13288        'min-height',
13289        'overflow',
13290        'overflow-x',
13291        'overflow-y',
13292        'text-overflow',
13293        'vertical-align',
13294        'transition',
13295        'transition-delay',
13296        'transition-duration',
13297        'transition-property',
13298        'transition-timing-function'
13299      ];
13300      each$k(nonInheritableStylesArr, function (style) {
13301        nonInheritableStyles.add(style);
13302      });
13303    }());
13304    var shorthandStyleProps = [
13305      'font',
13306      'text-decoration',
13307      'text-emphasis'
13308    ];
13309    var getStyleProps = function (dom, node) {
13310      return keys(dom.parseStyle(dom.getAttrib(node, 'style')));
13311    };
13312    var isNonInheritableStyle = function (style) {
13313      return nonInheritableStyles.has(style);
13314    };
13315    var hasInheritableStyles = function (dom, node) {
13316      return forall(getStyleProps(dom, node), function (style) {
13317        return !isNonInheritableStyle(style);
13318      });
13319    };
13320    var getLonghandStyleProps = function (styles) {
13321      return filter$4(styles, function (style) {
13322        return exists(shorthandStyleProps, function (prop) {
13323          return startsWith(style, prop);
13324        });
13325      });
13326    };
13327    var hasStyleConflict = function (dom, node, parentNode) {
13328      var nodeStyleProps = getStyleProps(dom, node);
13329      var parentNodeStyleProps = getStyleProps(dom, parentNode);
13330      var valueMismatch = function (prop) {
13331        var nodeValue = dom.getStyle(node, prop);
13332        var parentValue = dom.getStyle(parentNode, prop);
13333        return isNotEmpty(nodeValue) && isNotEmpty(parentValue) && nodeValue !== parentValue;
13334      };
13335      return exists(nodeStyleProps, function (nodeStyleProp) {
13336        var propExists = function (props) {
13337          return exists(props, function (prop) {
13338            return prop === nodeStyleProp;
13339          });
13340        };
13341        if (!propExists(parentNodeStyleProps) && propExists(shorthandStyleProps)) {
13342          var longhandProps = getLonghandStyleProps(parentNodeStyleProps);
13343          return exists(longhandProps, valueMismatch);
13344        } else {
13345          return valueMismatch(nodeStyleProp);
13346        }
13347      });
13348    };
13349
13350    var isChar = function (forward, predicate, pos) {
13351      return Optional.from(pos.container()).filter(isText$7).exists(function (text) {
13352        var delta = forward ? 0 : -1;
13353        return predicate(text.data.charAt(pos.offset() + delta));
13354      });
13355    };
13356    var isBeforeSpace = curry(isChar, true, isWhiteSpace);
13357    var isAfterSpace = curry(isChar, false, isWhiteSpace);
13358    var isEmptyText = function (pos) {
13359      var container = pos.container();
13360      return isText$7(container) && (container.data.length === 0 || isZwsp(container.data) && BookmarkManager.isBookmarkNode(container.parentNode));
13361    };
13362    var matchesElementPosition = function (before, predicate) {
13363      return function (pos) {
13364        return Optional.from(getChildNodeAtRelativeOffset(before ? 0 : -1, pos)).filter(predicate).isSome();
13365      };
13366    };
13367    var isImageBlock = function (node) {
13368      return isImg(node) && get$5(SugarElement.fromDom(node), 'display') === 'block';
13369    };
13370    var isCefNode = function (node) {
13371      return isContentEditableFalse$b(node) && !isBogusAll$1(node);
13372    };
13373    var isBeforeImageBlock = matchesElementPosition(true, isImageBlock);
13374    var isAfterImageBlock = matchesElementPosition(false, isImageBlock);
13375    var isBeforeMedia = matchesElementPosition(true, isMedia$2);
13376    var isAfterMedia = matchesElementPosition(false, isMedia$2);
13377    var isBeforeTable = matchesElementPosition(true, isTable$3);
13378    var isAfterTable = matchesElementPosition(false, isTable$3);
13379    var isBeforeContentEditableFalse = matchesElementPosition(true, isCefNode);
13380    var isAfterContentEditableFalse = matchesElementPosition(false, isCefNode);
13381
13382    var getLastChildren = function (elm) {
13383      var children = [];
13384      var rawNode = elm.dom;
13385      while (rawNode) {
13386        children.push(SugarElement.fromDom(rawNode));
13387        rawNode = rawNode.lastChild;
13388      }
13389      return children;
13390    };
13391    var removeTrailingBr = function (elm) {
13392      var allBrs = descendants(elm, 'br');
13393      var brs = filter$4(getLastChildren(elm).slice(-1), isBr$4);
13394      if (allBrs.length === brs.length) {
13395        each$k(brs, remove$7);
13396      }
13397    };
13398    var fillWithPaddingBr = function (elm) {
13399      empty(elm);
13400      append$1(elm, SugarElement.fromHtml('<br data-mce-bogus="1">'));
13401    };
13402    var trimBlockTrailingBr = function (elm) {
13403      lastChild(elm).each(function (lastChild) {
13404        prevSibling(lastChild).each(function (lastChildPrevSibling) {
13405          if (isBlock$2(elm) && isBr$4(lastChild) && isBlock$2(lastChildPrevSibling)) {
13406            remove$7(lastChild);
13407          }
13408        });
13409      });
13410    };
13411
13412    var dropLast = function (xs) {
13413      return xs.slice(0, -1);
13414    };
13415    var parentsUntil = function (start, root, predicate) {
13416      if (contains$1(root, start)) {
13417        return dropLast(parents$1(start, function (elm) {
13418          return predicate(elm) || eq(elm, root);
13419        }));
13420      } else {
13421        return [];
13422      }
13423    };
13424    var parents = function (start, root) {
13425      return parentsUntil(start, root, never);
13426    };
13427    var parentsAndSelf = function (start, root) {
13428      return [start].concat(parents(start, root));
13429    };
13430
13431    var navigateIgnoreEmptyTextNodes = function (forward, root, from) {
13432      return navigateIgnore(forward, root, from, isEmptyText);
13433    };
13434    var getClosestBlock$1 = function (root, pos) {
13435      return find$3(parentsAndSelf(SugarElement.fromDom(pos.container()), root), isBlock$2);
13436    };
13437    var isAtBeforeAfterBlockBoundary = function (forward, root, pos) {
13438      return navigateIgnoreEmptyTextNodes(forward, root.dom, pos).forall(function (newPos) {
13439        return getClosestBlock$1(root, pos).fold(function () {
13440          return isInSameBlock(newPos, pos, root.dom) === false;
13441        }, function (fromBlock) {
13442          return isInSameBlock(newPos, pos, root.dom) === false && contains$1(fromBlock, SugarElement.fromDom(newPos.container()));
13443        });
13444      });
13445    };
13446    var isAtBlockBoundary = function (forward, root, pos) {
13447      return getClosestBlock$1(root, pos).fold(function () {
13448        return navigateIgnoreEmptyTextNodes(forward, root.dom, pos).forall(function (newPos) {
13449          return isInSameBlock(newPos, pos, root.dom) === false;
13450        });
13451      }, function (parent) {
13452        return navigateIgnoreEmptyTextNodes(forward, parent.dom, pos).isNone();
13453      });
13454    };
13455    var isAtStartOfBlock = curry(isAtBlockBoundary, false);
13456    var isAtEndOfBlock = curry(isAtBlockBoundary, true);
13457    var isBeforeBlock = curry(isAtBeforeAfterBlockBoundary, false);
13458    var isAfterBlock = curry(isAtBeforeAfterBlockBoundary, true);
13459
13460    var isBr = function (pos) {
13461      return getElementFromPosition(pos).exists(isBr$4);
13462    };
13463    var findBr = function (forward, root, pos) {
13464      var parentBlocks = filter$4(parentsAndSelf(SugarElement.fromDom(pos.container()), root), isBlock$2);
13465      var scope = head(parentBlocks).getOr(root);
13466      return fromPosition(forward, scope.dom, pos).filter(isBr);
13467    };
13468    var isBeforeBr$1 = function (root, pos) {
13469      return getElementFromPosition(pos).exists(isBr$4) || findBr(true, root, pos).isSome();
13470    };
13471    var isAfterBr = function (root, pos) {
13472      return getElementFromPrevPosition(pos).exists(isBr$4) || findBr(false, root, pos).isSome();
13473    };
13474    var findPreviousBr = curry(findBr, false);
13475    var findNextBr = curry(findBr, true);
13476
13477    var isInMiddleOfText = function (pos) {
13478      return CaretPosition.isTextPosition(pos) && !pos.isAtStart() && !pos.isAt
13478End();
13479    };
13480    var getClosestBlock = function (root, pos) {
13481      var parentBlocks = filter$4(parentsAndSelf(SugarElement.fromDom(pos.container()), root), isBlock$2);
13482      return head(parentBlocks).getOr(root);
13483    };
13484    var hasSpaceBefore = function (root, pos) {
13485      if (isInMiddleOfText(pos)) {
13486        return isAfterSpace(pos);
13487      } else {
13488        return isAfterSpace(pos) || prevPosition(getClosestBlock(root, pos).dom, pos).exists(isAfterSpace);
13489      }
13490    };
13491    var hasSpaceAfter = function (root, pos) {
13492      if (isInMiddleOfText(pos)) {
13493        return isBeforeSpace(pos);
13494      } else {
13495        return isBeforeSpace(pos) || nextPosition(getClosestBlock(root, pos).dom, pos).exists(isBeforeSpace);
13496      }
13497    };
13498    var isPreValue = function (value) {
13499      return contains$3([
13500        'pre',
13501        'pre-wrap'
13502      ], value);
13503    };
13504    var isInPre = function (pos) {
13505      return getElementFromPosition(pos).bind(function (elm) {
13506        return closest$3(elm, isElement$6);
13507      }).exists(function (elm) {
13508        return isPreValue(get$5(elm, 'white-space'));
13509      });
13510    };
13511    var isAtBeginningOfBody = function (root, pos) {
13512      return prevPosition(root.dom, pos).isNone();
13513    };
13514    var isAtEndOfBody = function (root, pos) {
13515      return nextPosition(root.dom, pos).isNone();
13516    };
13517    var isAtLineBoundary = function (root, pos) {
13518      return isAtBeginningOfBody(root, pos) || isAtEndOfBody(root, pos) || isAtStartOfBlock(root, pos) || isAtEndOfBlock(root, pos) || isAfterBr(root, pos) || isBeforeBr$1(root, pos);
13519    };
13520    var needsToHaveNbsp = function (root, pos) {
13521      if (isInPre(pos)) {
13522        return false;
13523      } else {
13524        return isAtLineBoundary(root, pos) || hasSpaceBefore(root, pos) || hasSpaceAfter(root, pos);
13525      }
13526    };
13527    var needsToBeNbspLeft = function (root, pos) {
13528      if (isInPre(pos)) {
13529        return false;
13530      } else {
13531        return isAtStartOfBlock(root, pos) || isBeforeBlock(root, pos) || isAfterBr(root, pos) || hasSpaceBefore(root, pos);
13532      }
13533    };
13534    var leanRight = function (pos) {
13535      var container = pos.container();
13536      var offset = pos.offset();
13537      if (isText$7(container) && offset < container.data.length) {
13538        return CaretPosition(container, offset + 1);
13539      } else {
13540        return pos;
13541      }
13542    };
13543    var needsToBeNbspRight = function (root, pos) {
13544      if (isInPre(pos)) {
13545        return false;
13546      } else {
13547        return isAtEndOfBlock(root, pos) || isAfterBlock(root, pos) || isBeforeBr$1(root, pos) || hasSpaceAfter(root, pos);
13548      }
13549    };
13550    var needsToBeNbsp = function (root, pos) {
13551      return needsToBeNbspLeft(root, pos) || needsToBeNbspRight(root, leanRight(pos));
13552    };
13553    var isNbspAt = function (text, offset) {
13554      return isNbsp(text.charAt(offset));
13555    };
13556    var hasNbsp = function (pos) {
13557      var container = pos.container();
13558      return isText$7(container) && contains$2(container.data, nbsp);
13559    };
13560    var normalizeNbspMiddle = function (text) {
13561      var chars = text.split('');
13562      return map$3(chars, function (chr, i) {
13563        if (isNbsp(chr) && i > 0 && i < chars.length - 1 && isContent(chars[i - 1]) && isContent(chars[i + 1])) {
13564          return ' ';
13565        } else {
13566          return chr;
13567        }
13568      }).join('');
13569    };
13570    var normalizeNbspAtStart = function (root, node) {
13571      var text = node.data;
13572      var firstPos = CaretPosition(node, 0);
13573      if (isNbspAt(text, 0) && !needsToBeNbsp(root, firstPos)) {
13574        node.data = ' ' + text.slice(1);
13575        return true;
13576      } else {
13577        return false;
13578      }
13579    };
13580    var normalizeNbspInMiddleOfTextNode = function (node) {
13581      var text = node.data;
13582      var newText = normalizeNbspMiddle(text);
13583      if (newText !== text) {
13584        node.data = newText;
13585        return true;
13586      } else {
13587        return false;
13588      }
13589    };
13590    var normalizeNbspAtEnd = function (root, node) {
13591      var text = node.data;
13592      var lastPos = CaretPosition(node, text.length - 1);
13593      if (isNbspAt(text, text.length - 1) && !needsToBeNbsp(root, lastPos)) {
13594        node.data = text.slice(0, -1) + ' ';
13595        return true;
13596      } else {
13597        return false;
13598      }
13599    };
13600    var normalizeNbsps = function (root, pos) {
13601      return Optional.some(pos).filter(hasNbsp).bind(function (pos) {
13602        var container = pos.container();
13603        var normalized = normalizeNbspAtStart(root, container) || normalizeNbspInMiddleOfTextNode(container) || normalizeNbspAtEnd(root, container);
13604        return normalized ? Optional.some(pos) : Optional.none();
13605      });
13606    };
13607    var normalizeNbspsInEditor = function (editor) {
13608      var root = SugarElement.fromDom(editor.getBody());
13609      if (editor.selection.isCollapsed()) {
13610        normalizeNbsps(root, CaretPosition.fromRangeStart(editor.selection.getRng())).each(function (pos) {
13611          editor.selection.setRng(pos.toRange());
13612        });
13613      }
13614    };
13615
13616    var normalizeContent = function (content, isStartOfContent, isEndOfContent) {
13617      var result = foldl(content, function (acc, c) {
13618        if (isWhiteSpace(c) || isNbsp(c)) {
13619          if (acc.previousCharIsSpace || acc.str === '' && isStartOfContent || acc.str.length === content.length - 1 && isEndOfContent) {
13620            return {
13621              previousCharIsSpace: false,
13622              str: acc.str + nbsp
13623            };
13624          } else {
13625            return {
13626              previousCharIsSpace: true,
13627              str: acc.str + ' '
13628            };
13629          }
13630        } else {
13631          return {
13632            previousCharIsSpace: false,
13633            str: acc.str + c
13634          };
13635        }
13636      }, {
13637        previousCharIsSpace: false,
13638        str: ''
13639      });
13640      return result.str;
13641    };
13642    var normalize$1 = function (node, offset, count) {
13643      if (count === 0) {
13644        return;
13645      }
13646      var elm = SugarElement.fromDom(node);
13647      var root = ancestor$3(elm, isBlock$2).getOr(elm);
13648      var whitespace = node.data.slice(offset, offset + count);
13649      var isEndOfContent = offset + count >= node.data.length && needsToBeNbspRight(root, CaretPosition(node, node.data.length));
13650      var isStartOfContent = offset === 0 && needsToBeNbspLeft(root, CaretPosition(node, 0));
13651      node.replaceData(offset, count, normalizeContent(whitespace, isStartOfContent, isEndOfContent));
13652    };
13653    var normalizeWhitespaceAfter = function (node, offset) {
13654      var content = node.data.slice(offset);
13655      var whitespaceCount = content.length - lTrim(content).length;
13656      normalize$1(node, offset, whitespaceCount);
13657    };
13658    var normalizeWhitespaceBefore = function (node, offset) {
13659      var content = node.data.slice(0, offset);
13660      var whitespaceCount = content.length - rTrim(content).length;
13661      normalize$1(node, offset - whitespaceCount, whitespaceCount);
13662    };
13663    var mergeTextNodes = function (prevNode, nextNode, normalizeWhitespace, mergeToPrev) {
13664      if (mergeToPrev === void 0) {
13665        mergeToPrev = true;
13666      }
13667      var whitespaceOffset = rTrim(prevNode.data).length;
13668      var newNode = mergeToPrev ? prevNode : nextNode;
13669      var removeNode = mergeToPrev ? nextNode : prevNode;
13670      if (mergeToPrev) {
13671        newNode.appendData(removeNode.data);
13672      } else {
13673        newNode.insertData(0, removeNode.data);
13674      }
13675      remove$7(SugarElement.fromDom(removeNode));
13676      if (normalizeWhitespace) {
13677        normalizeWhitespaceAfter(newNode, whitespaceOffset);
13678      }
13679      return newNode;
13680    };
13681
13682    var needsReposition = function (pos, elm) {
13683      var container = pos.container();
13684      var offset = pos.offset();
13685      return CaretPosition.isTextPosition(pos) === false && container === elm.parentNode && offset > CaretPosition.before(elm).offset();
13686    };
13687    var reposition = function (elm, pos) {
13688      return needsReposition(pos, elm) ? CaretPosition(pos.container(), pos.offset() - 1) : pos;
13689    };
13690    var beforeOrStartOf = function (node) {
13691      return isText$7(node) ? CaretPosition(node, 0) : CaretPosition.before(node);
13692    };
13693    var afterOrEndOf = function (node) {
13694      return isText$7(node) ? CaretPosition(node, node.data.length) : CaretPosition.after(node);
13695    };
13696    var getPreviousSiblingCaretPosition = function (elm) {
13697      if (isCaretCandidate$3(elm.previousSibling)) {
13698        return Optional.some(afterOrEndOf(elm.previousSibling));
13699      } else {
13700        return elm.previousSibling ? lastPositionIn(elm.previousSibling) : Optional.none();
13701      }
13702    };
13703    var getNextSiblingCaretPosition = function (elm) {
13704      if (isCaretCandidate$3(elm.nextSibling)) {
13705        return Optional.some(beforeOrStartOf(elm.nextSibling));
13706      } else {
13707        return elm.nextSibling ? firstPositionIn(elm.nextSibling) : Optional.none();
13708      }
13709    };
13710    var findCaretPositionBackwardsFromElm = function (rootElement, elm) {
13711      var startPosition = CaretPosition.before(elm.previousSibling ? elm.previousSibling : elm.parentNode);
13712      return prevPosition(rootElement, startPosition).fold(function () {
13713        return nextPosition(rootElement, CaretPosition.after(elm));
13714      }, Optional.some);
13715    };
13716    var findCaretPositionForwardsFromElm = function (rootElement, elm) {
13717      return nextPosition(rootElement, CaretPosition.after(elm)).fold(function () {
13718        return prevPosition(rootElement, CaretPosition.before(elm));
13719      }, Optional.some);
13720    };
13721    var findCaretPositionBackwards = function (rootElement, elm) {
13722      return getPreviousSiblingCaretPosition(elm).orThunk(function () {
13723        return getNextSiblingCaretPosition(elm);
13724      }).orThunk(function () {
13725        return findCaretPositionBackwardsFromElm(rootElement, elm);
13726      });
13727    };
13728    var findCaretPositionForward = function (rootElement, elm) {
13729      return getNextSiblingCaretPosition(elm).orThunk(function () {
13730        return getPreviousSiblingCaretPosition(elm);
13731      }).orThunk(function () {
13732        return findCaretPositionForwardsFromElm(rootElement, elm);
13733      });
13734    };
13735    var findCaretPosition = function (forward, rootElement, elm) {
13736      return forward ? findCaretPositionForward(rootElement, elm) : findCaretPositionBackwards(rootElement, elm);
13737    };
13738    var findCaretPosOutsideElmAfterDelete = function (forward, rootElement, elm) {
13739      return findCaretPosition(forward, rootElement, elm).map(curry(reposition, elm));
13740    };
13741    var setSelection$1 = function (editor, forward, pos) {
13742      pos.fold(function () {
13743        editor.focus();
13744      }, function (pos) {
13745        editor.selection.setRng(pos.toRange(), forward);
13746      });
13747    };
13748    var eqRawNode = function (rawNode) {
13749      return function (elm) {
13750        return elm.dom === rawNode;
13751      };
13752    };
13753    var isBlock = function (editor, elm) {
13754      return elm && has$2(editor.schema.getBlockElements(), name(elm));
13755    };
13756    var paddEmptyBlock = function (elm) {
13757      if (isEmpty$2(elm)) {
13758        var br = SugarElement.fromHtml('<br data-mce-bogus="1">');
13759        empty(elm);
13760        append$1(elm, br);
13761        return Optional.some(CaretPosition.before(br.dom));
13762      } else {
13763        return Optional.none();
13764      }
13765    };
13766    var deleteNormalized = function (elm, afterDeletePosOpt, normalizeWhitespace) {
13767      var prevTextOpt = prevSibling(elm).filter(isText$8);
13768      var nextTextOpt = nextSibling(elm).filter(isText$8);
13769      remove$7(elm);
13770      return lift3(prevTextOpt, nextTextOpt, afterDeletePosOpt, function (prev, next, pos) {
13771        var prevNode = prev.dom, nextNode = next.dom;
13772        var offset = prevNode.data.length;
13773        mergeTextNodes(prevNode, nextNode, normalizeWhitespace);
13774        return pos.container() === nextNode ? CaretPosition(prevNode, offset) : pos;
13775      }).orThunk(function () {
13776        if (normalizeWhitespace) {
13777          prevTextOpt.each(function (elm) {
13778            return normalizeWhitespaceBefore(elm.dom, elm.dom.length);
13779          });
13780          nextTextOpt.each(function (elm) {
13781            return normalizeWhitespaceAfter(elm.dom, 0);
13782          });
13783        }
13784        return afterDeletePosOpt;
13785      });
13786    };
13787    var isInlineElement = function (editor, element) {
13788      return has$2(editor.schema.getTextInlineElements(), name(element));
13789    };
13790    var deleteElement$2 = function (editor, forward, elm, moveCaret) {
13791      if (moveCaret === void 0) {
13792        moveCaret = true;
13793      }
13794      var afterDeletePos = findCaretPosOutsideElmAfterDelete(forward, editor.getBody(), elm.dom);
13795      var parentBlock = ancestor$3(elm, curry(isBlock, editor), eqRawNode(editor.getBody()));
13796      var normalizedAfterDeletePos = deleteNormalized(elm, afterDeletePos, isInlineElement(editor, elm));
13797      if (editor.dom.isEmpty(editor.getBody())) {
13798        editor.setContent('');
13799        editor.selection.setCursorLocation();
13800      } else {
13801        parentBlock.bind(paddEmptyBlock).fold(function () {
13802          if (moveCaret) {
13803            setSelection$1(editor, forward, normalizedAfterDeletePos);
13804          }
13805        }, function (paddPos) {
13806          if (moveCaret) {
13807            setSelection$1(editor, forward, Optional.some(paddPos));
13808          }
13809        });
13810      }
13811    };
13812
13813    var isRootFromElement = function (root) {
13814      return function (cur) {
13815        return eq(root, cur);
13816      };
13817    };
13818    var getTableCells = function (table) {
13819      return descendants(table, 'td,th');
13820    };
13821    var getTableDetailsFromRange = function (rng, isRoot) {
13822      var getTable = function (node) {
13823        return getClosestTable(SugarElement.fromDom(node), isRoot);
13824      };
13825      var startTable = getTable(rng.startContainer);
13826      var endTable = getTable(rng.endContainer);
13827      var isStartInTable = startTable.isSome();
13828      var isEndInTable = endTable.isSome();
13829      var isSameTable = lift2(startTable, endTable, eq).getOr(false);
13830      var isMultiTable = !isSameTable && isStartInTable && isEndInTable;
13831      return {
13832        startTable: startTable,
13833        endTable: endTable,
13834        isStartInTable: isStartInTable,
13835        isEndInTable: isEndInTable,
13836        isSameTable: isSameTable,
13837        isMultiTable: isMultiTable
13838      };
13839    };
13840
13841    var tableCellRng = function (start, end) {
13842      return {
13843        start: start,
13844        end: end
13845      };
13846    };
13847    var tableSelection = function (rng, table, cells) {
13848      return {
13849        rng: rng,
13850        table: table,
13851        cells: cells
13852      };
13853    };
13854    var deleteAction = Adt.generate([
13855      {
13856        singleCellTable: [
13857          'rng',
13858          'cell'
13859        ]
13860      },
13861      { fullTable: ['table'] },
13862      {
13863        partialTable: [
13864          'cells',
13865          'outsideDetails'
13866        ]
13867      },
13868      {
13869        multiTable: [
13870          'startTableCells',
13871          'endTableCells',
13872          'betweenRng'
13873        ]
13874      }
13875    ]);
13876    var getClosestCell$1 = function (container, isRoot) {
13877      return closest$2(SugarElement.fromDom(container), 'td,th', isRoot);
13878    };
13879    var isExpandedCellRng = function (cellRng) {
13880      return !eq(cellRng.start, cellRng.end);
13881    };
13882    var getTableFromCellRng = function (cellRng, isRoot) {
13883      return getClosestTable(cellRng.start, isRoot).bind(function (startParentTable) {
13884        return getClosestTable(cellRng.end, isRoot).bind(function (endParentTable) {
13885          return someIf(eq(startParentTable, endParentTable), startParentTable);
13886        });
13887      });
13888    };
13889    var isSingleCellTable = function (cellRng, isRoot) {
13890      return !isExpandedCellRng(cellRng) && getTableFromCellRng(cellRng, isRoot).exists(function (table) {
13891        var rows = table.dom.rows;
13892        return rows.length === 1 && rows[0].cells.length === 1;
13893      });
13894    };
13895    var getCellRng = function (rng, isRoot) {
13896      var startCell = getClosestCell$1(rng.startContainer, isRoot);
13897      var endCell = getClosestCell$1(rng.endContainer, isRoot);
13898      return lift2(startCell, endCell, tableCellRng);
13899    };
13900    var getCellRangeFromStartTable = function (isRoot) {
13901      return function (startCell) {
13902        return getClosestTable(startCell, isRoot).bind(function (table) {
13903          return last$2(getTableCells(table)).map(function (endCell) {
13904            return tableCellRng(startCell, endCell);
13905          });
13906        });
13907      };
13908    };
13909    var getCellRangeFromEndTable = function (isRoot) {
13910      return function (endCell) {
13911        return getClosestTable(endCell, isRoot).bind(function (table) {
13912          return head(getTableCells(table)).map(function (startCell) {
13913            return tableCellRng(startCell, endCell);
13914          });
13915        });
13916      };
13917    };
13918    var getTableSelectionFromCellRng = function (isRoot) {
13919      return function (cellRng) {
13920        return getTableFromCellRng(cellRng, isRoot).map(function (table) {
13921          return tableSelection(cellRng, table, getTableCells(table));
13922        });
13923      };
13924    };
13925    var getTableSelections = function (cellRng, selectionDetails, rng, isRoot) {
13926      if (rng.collapsed || !cellRng.forall(isExpandedCellRng)) {
13927        return Optional.none();
13928      }
13928 else if (selectionDetails.isSameTable) {
13929        var sameTableSelection = cellRng.bind(getTableSelectionFromCellRng(isRoot));
13930        return Optional.some({
13931          start: sameTableSelection,
13932          end: sameTableSelection
13933        });
13934      } else {
13935        var startCell = getClosestCell$1(rng.startContainer, isRoot);
13936        var endCell = getClosestCell$1(rng.endContainer, isRoot);
13937        var startTableSelection = startCell.bind(getCellRangeFromStartTable(isRoot)).bind(getTableSelectionFromCellRng(isRoot));
13938        var endTableSelection = endCell.bind(getCellRangeFromEndTable(isRoot)).bind(getTableSelectionFromCellRng(isRoot));
13939        return Optional.some({
13940          start: startTableSelection,
13941          end: endTableSelection
13942        });
13943      }
13944    };
13945    var getCellIndex = function (cells, cell) {
13946      return findIndex$2(cells, function (x) {
13947        return eq(x, cell);
13948      });
13949    };
13950    var getSelectedCells = function (tableSelection) {
13951      return lift2(getCellIndex(tableSelection.cells, tableSelection.rng.start), getCellIndex(tableSelection.cells, tableSelection.rng.end
13951), function (startIndex, endIndex) {
13952        return tableSelection.cells.slice(startIndex, endIndex + 1);
13953      });
13954    };
13955    var isSingleCellTableContentSelected = function (optCellRng, rng, isRoot) {
13956      return optCellRng.exists(function (cellRng) {
13957        return isSingleCellTable(cellRng, isRoot) && hasAllContentsSelected(cellRng.start, rng);
13958      });
13959    };
13960    var unselectCells = function (rng, selectionDetails) {
13961      var startTable = selectionDetails.startTable, endTable = selectionDetails.endTable;
13962      var otherContentRng = rng.cloneRange();
13963      startTable.each(function (table) {
13964        return otherContentRng.setStartAfter(table.dom);
13965      });
13966      endTable.each(function (table) {
13967        return otherContentRng.setEndBefore(table.dom);
13968      });
13969      return otherContentRng;
13970    };
13971    var handleSingleTable = function (cellRng, selectionDetails, rng, isRoot) {
13972      return getTableSelections(cellRng, selectionDetails, rng, isRoot).bind(function (_a) {
13973        var start = _a.start, end = _a.end;
13974        return start.or(end);
13975      }).bind(function (tableSelection) {
13976        var isSameTable = selectionDetails.isSameTable;
13977        var selectedCells = getSelectedCells(tableSelection).getOr([]);
13978        if (isSameTable && tableSelection.cells.length === selectedCells.length) {
13979          return Optional.some(deleteAction.fullTable(tableSelection.table));
13980        } else if (selectedCells.length > 0) {
13981          if (isSameTable) {
13982            return Optional.some(deleteAction.partialTable(selectedCells, Optional.none()));
13983          } else {
13984            var otherContentRng = unselectCells(rng, selectionDetails);
13985            return Optional.some(deleteAction.partialTable(selectedCells, Optional.some(__assign(__assign({}, selectionDetails), { rng: otherContentRng }))));
13986          }
13987        } else {
13988          return Optional.none();
13989        }
13990      });
13991    };
13992    var handleMultiTable = function (cellRng, selectionDetails, rng, isRoot) {
13993      return getTableSelections(cellRng, selectionDetails, rng, isRoot).bind(function (_a) {
13994        var start = _a.start, end = _a.end;
13995        var startTableSelectedCells = start.bind(getSelectedCells).getOr([]);
13996        var endTableSelectedCells = end.bind(getSelectedCells).getOr([]);
13997        if (startTableSelectedCells.length > 0 && endTableSelectedCells.length > 0) {
13998          var otherContentRng = unselectCells(rng, selectionDetails);
13999          return Optional.some(deleteAction.multiTable(startTableSelectedCells, endTableSelectedCells, otherContentRng));
14000        } else {
14001          return Optional.none();
14002        }
14003      });
14004    };
14005    var getActionFromRange = function (root, rng) {
14006      var isRoot = isRootFromElement(root);
14007      var optCellRng = getCellRng(rng, isRoot);
14008      var selectionDetails = getTableDetailsFromRange(rng, isRoot);
14009      if (isSingleCellTableContentSelected(optCellRng, rng, isRoot)) {
14010        return optCellRng.map(function (cellRng) {
14011          return deleteAction.singleCellTable(rng, cellRng.start);
14012        });
14013      } else if (selectionDetails.isMultiTable) {
14014        return handleMultiTable(optCellRng, selectionDetails, rng, isRoot);
14015      } else {
14016        return handleSingleTable(optCellRng, selectionDetails, rng, isRoot);
14017      }
14018    };
14019
14020    var freefallRtl = function (root) {
14021      var child = isComment$1(root) ? prevSibling(root) : lastChild(root);
14022      return child.bind(freefallRtl).orThunk(function () {
14023        return Optional.some(root);
14024      });
14025    };
14026    var cleanCells = function (cells) {
14027      return each$k(cells, function (cell) {
14028        remove$6(cell, 'contenteditable');
14029        fillWithPaddingBr(cell);
14030      });
14031    };
14032    var getOutsideBlock = function (editor, container) {
14033      return Optional.from(editor.dom.getParent(container, editor.dom.isBlock)).map(SugarElement.fromDom);
14034    };
14035    var handleEmptyBlock = function (editor, startInTable, emptyBlock) {
14036      emptyBlock.each(function (block) {
14037        if (startInTable) {
14038          remove$7(block);
14039        } else {
14040          fillWithPaddingBr(block);
14041          editor.selection.setCursorLocation(block.dom, 0);
14042        }
14043      });
14044    };
14045    var deleteContentInsideCell = function (editor, cell, rng, isFirstCellInSelection) {
14046      var insideTableRng = rng.cloneRange();
14047      if (isFirstCellInSelection) {
14048        insideTableRng.setStart(rng.startContainer, rng.startOffset);
14049        insideTableRng.setEndAfter(cell.dom.lastChild);
14050      } else {
14051        insideTableRng.setStartBefore(cell.dom.firstChild);
14052        insideTableRng.setEnd(rng.endContainer, rng.endOffset);
14053      }
14054      deleteCellContents(editor, insideTableRng, cell, false);
14055    };
14056    var collapseAndRestoreCellSelection = function (editor) {
14057      var selectedCells = getCellsFromEditor(editor);
14058      var selectedNode = SugarElement.fromDom(editor.selection.getNode());
14059      if (isTableCell$5(selectedNode.dom) && isEmpty$2(selectedNode)) {
14060        editor.selection.setCursorLocation(selectedNode.dom, 0);
14061      } else {
14062        editor.selection.collapse(true);
14063      }
14064      if (selectedCells.length > 1 && exists(selectedCells, function (cell) {
14065          return eq(cell, selectedNode);
14066        })) {
14067        set$1(selectedNode, 'data-mce-selected', '1');
14068      }
14069    };
14070    var emptySingleTableCells = function (editor, cells, outsideDetails) {
14071      var editorRng = editor.selection.getRng();
14072      var cellsToClean = outsideDetails.bind(function (_a) {
14073        var rng = _a.rng, isStartInTable = _a.isStartInTable;
14074        var outsideBlock = getOutsideBlock(editor, isStartInTable ? rng.endContainer : rng.startContainer);
14075        rng.deleteContents();
14076        handleEmptyBlock(editor, isStartInTable, outsideBlock.filter(isEmpty$2));
14077        var endPointCell = isStartInTable ? cells[0] : cells[cells.length - 1];
14078        deleteContentInsideCell(editor, endPointCell, editorRng, isStartInTable);
14079        if (!isEmpty$2(endPointCell)) {
14080          return Optional.some(isStartInTable ? cells.slice(1) : cells.slice(0, -1));
14081        } else {
14082          return Optional.none();
14083        }
14084      }).getOr(cells);
14085      cleanCells(cellsToClean);
14086      collapseAndRestoreCellSelection(editor);
14087      return true;
14088    };
14089    var emptyMultiTableCells = function (editor, startTableCells, endTableCells, betweenRng) {
14090      var rng = editor.selection.getRng();
14091      var startCell = startTableCells[0];
14092      var endCell = endTableCells[endTableCells.length - 1];
14093      deleteContentInsideCell(editor, startCell, rng, true);
14094      deleteContentInsideCell(editor, endCell, rng, false);
14095      var startTableCellsToClean = isEmpty$2(startCell) ? startTableCells : startTableCells.slice(1);
14096      var endTableCellsToClean = isEmpty$2(endCell) ? endTableCells : endTableCells.slice(0, -1);
14097      cleanCells(startTableCellsToClean.concat(endTableCellsToClean));
14098      betweenRng.deleteContents();
14099      collapseAndRestoreCellSelection(editor);
14100      return true;
14101    };
14102    var deleteCellContents = function (editor, rng, cell, moveSelection) {
14103      if (moveSelection === void 0) {
14104        moveSelection = true;
14105      }
14106      rng.deleteContents();
14107      var lastNode = freefallRtl(cell).getOr(cell);
14108      var lastBlock = SugarElement.fromDom(editor.dom.getParent(lastNode.dom, editor.dom.isBlock));
14109      if (isEmpty$2(lastBlock)) {
14110        fillWithPaddingBr(lastBlock);
14111        if (moveSelection) {
14112          editor.selection.setCursorLocation(lastBlock.dom, 0);
14113        }
14114      }
14115      if (!eq(cell, lastBlock)) {
14116        var additionalCleanupNodes = is$1(parent(lastBlock), cell) ? [] : siblings(lastBlock);
14117        each$k(additionalCleanupNodes.concat(children(cell)), function (node) {
14118          if (!eq(node, lastBlock) && !contains$1(node, lastBlock) && isEmpty$2(node)) {
14119            remove$7(node);
14120          }
14121        });
14122      }
14123      return true;
14124    };
14125    var deleteTableElement = function (editor, table) {
14126      deleteElement$2(editor, false, table);
14127      return true;
14128    };
14129    var deleteCellRange = function (editor, rootElm, rng) {
14130      return getActionFromRange(rootElm, rng).map(function (action) {
14131        return action.fold(curry(deleteCellContents, editor), curry(deleteTableElement, editor), curry(emptySingleTableCells, editor), curry(emptyMultiTableCells, editor));
14132      });
14133    };
14134    var deleteCaptionRange = function (editor, caption) {
14135      return emptyElement(editor, caption);
14136    };
14137    var deleteTableRange = function (editor, rootElm, rng, startElm) {
14138      return getParentCaption(rootElm, startElm).fold(function () {
14139        return deleteCellRange(editor, rootElm, rng);
14140      }, function (caption) {
14141        return deleteCaptionRange(editor, caption);
14142      }).getOr(false);
14143    };
14144    var deleteRange$2 = function (editor, startElm, selectedCells) {
14145      var rootNode = SugarElement.fromDom(editor.getBody());
14146      var rng = editor.selection.getRng();
14147      return selectedCells.length !== 0 ? emptySingleTableCells(editor, selectedCells, Optional.none()) : deleteTableRange(editor, rootNode, rng, startElm);
14148    };
14149    var getParentCell = function (rootElm, elm) {
14150      return find$3(parentsAndSelf(elm, rootElm), isTableCell$4);
14151    };
14152    var getParentCaption = function (rootElm, elm) {
14153      return find$3(parentsAndSelf(elm, rootElm), isTag('caption'));
14154    };
14155    var deleteBetweenCells = function (editor, rootElm, forward, fromCell, from) {
14156      return navigate(forward, editor.getBody(), from).bind(function (to) {
14157        return getParentCell(rootElm, SugarElement.fromDom(to.getNode())).map(function (toCell) {
14158          return eq(toCell, fromCell) === false;
14159        });
14160      });
14161    };
14162    var emptyElement = function (editor, elm) {
14163      fillWithPaddingBr(elm);
14164      editor.selection.setCursorLocation(elm.dom, 0);
14165      return Optional.some(true);
14166    };
14167    var isDeleteOfLastCharPos = function (fromCaption, forward, from, to) {
14168      return firstPositionIn(fromCaption.dom).bind(function (first) {
14169        return lastPositionIn(fromCaption.dom).map(function (last) {
14170          return forward ? from.isEqual(first) && to.isEqual(last) : from.isEqual(last) && to.isEqual(first);
14171        });
14172      }).getOr(true);
14173    };
14174    var emptyCaretCaption = function (editor, elm) {
14175      return emptyElement(editor, elm);
14176    };
14177    var validateCaretCaption = function (rootElm, fromCaption, to) {
14178      return getParentCaption(rootElm, SugarElement.fromDom(to.getNode())).map(function (toCaption) {
14179        return eq(toCaption, fromCaption) === false;
14180      });
14181    };
14182    var deleteCaretInsideCaption = function (editor, rootElm, forward, fromCaption, from) {
14183      return navigate(forward, editor.getBody(), from).bind(function (to) {
14184        return isDeleteOfLastCharPos(fromCaption, forward, from, to) ? emptyCaretCaption(editor, fromCaption) : validateCaretCaption(rootElm, fromCaption, to);
14185      }).or(Optional.some(true));
14186    };
14187    var deleteCaretCells = function (editor, forward, rootElm, startElm) {
14188      var from = CaretPosition.fromRangeStart(editor.selection.getRng());
14189      return getParentCell(rootElm, startElm).bind(function (fromCell) {
14190        return isEmpty$2(fromCell) ? emptyElement(editor, fromCell) : deleteBetweenCells(editor, rootElm, forward, fromCell, from);
14191      }).getOr(false);
14192    };
14193    var deleteCaretCaption = function (editor, forward, rootElm, fromCaption) {
14194      var from = CaretPosition.fromRangeStart(editor.selection.getRng());
14195      return isEmpty$2(fromCaption) ? emptyElement(editor, fromCaption) : deleteCaretInsideCaption(editor, rootElm, forward, fromCaption, from);
14196    };
14197    var isNearTable = function (forward, pos) {
14198      return forward ? isBeforeTable(pos) : isAfterTable(pos);
14199    };
14200    var isBeforeOrAfterTable = function (editor, forward) {
14201      var fromPos = CaretPosition.fromRangeStart(editor.selection.getRng());
14202      return isNearTable(forward, fromPos) || fromPosition(forward, editor.getBody(), fromPos).exists(function (pos) {
14203        return isNearTable(forward, pos);
14204      });
14205    };
14206    var deleteCaret$3 = function (editor, forward, startElm) {
14207      var rootElm = SugarElement.fromDom(editor.getBody());
14208      return getParentCaption(rootElm, startElm).fold(function () {
14209        return deleteCaretCells(editor, forward, rootElm, startElm) || isBeforeOrAfterTable(editor, forward);
14210      }, function (fromCaption) {
14211        return deleteCaretCaption(editor, forward, rootElm, fromCaption).getOr(false);
14212      });
14213    };
14214    var backspaceDelete$9 = function (editor, forward) {
14215      var startElm = SugarElement.fromDom(editor.selection.getStart(true));
14216      var cells = getCellsFromEditor(editor);
14217      return editor.selection.isCollapsed() && cells.length === 0 ? deleteCaret$3(editor, forward, startElm) : deleteRange$2(editor, startElm, cells);
14218    };
14219
14220    var createRange = function (sc, so, ec, eo) {
14221      var rng = document.createRange();
14222      rng.setStart(sc, so);
14223      rng.setEnd(ec, eo);
14224      return rng;
14225    };
14226    var normalizeBlockSelectionRange = function (rng) {
14227      var startPos = CaretPosition.fromRangeStart(rng);
14228      var endPos = CaretPosition.fromRangeEnd(rng);
14229      var rootNode = rng.commonAncestorContainer;
14230      return fromPosition(false, rootNode, endPos).map(function (newEndPos) {
14231        if (!isInSameBlock(startPos, endPos, rootNode) && isInSameBlock(startPos, newEndPos, rootNode)) {
14232          return createRange(startPos.container(), startPos.offset(), newEndPos.container(), newEndPos.offset());
14233        } else {
14234          return rng;
14235        }
14236      }).getOr(rng);
14237    };
14238    var normalize = function (rng) {
14239      return rng.collapsed ? rng : normalizeBlockSelectionRange(rng);
14240    };
14241
14242    var hasOnlyOneChild$1 = function (node) {
14243      return node.firstChild && node.firstChild === node.lastChild;
14244    };
14245    var isPaddingNode = function (node) {
14246      return node.name === 'br' || node.value === nbsp;
14247    };
14248    var isPaddedEmptyBlock = function (schema, node) {
14249      var blockElements = schema.getBlockElements();
14250      return blockElements[node.name] && hasOnlyOneChild$1(node) && isPaddingNode(node.firstChild);
14251    };
14252    var isEmptyFragmentElement = function (schema, node) {
14253      var nonEmptyElements = schema.getNonEmptyElements();
14254      return node && (node.isEmpty(nonEmptyElements) || isPaddedEmptyBlock(schema, node));
14255    };
14256    var isListFragment = function (schema, fragment) {
14257      var firstChild = fragment.firstChild;
14258      var lastChild = fragment.lastChild;
14259      if (firstChild && firstChild.name === 'meta') {
14260        firstChild = firstChild.next;
14261      }
14262      if (lastChild && lastChild.attr('id') === 'mce_marker') {
14263        lastChild = lastChild.prev;
14264      }
14265      if (isEmptyFragmentElement(schema, lastChild)) {
14266        lastChild = lastChild.prev;
14267      }
14268      if (!firstChild || firstChild !== lastChild) {
14269        return false;
14270      }
14271      return firstChild.name === 'ul' || firstChild.name === 'ol';
14272    };
14273    var cleanupDomFragment = function (domFragment) {
14274      var firstChild = domFragment.firstChild;
14275      var lastChild = domFragment.lastChild;
14276      if (firstChild && firstChild.nodeName === 'META') {
14277        firstChild.parentNode.removeChild(firstChild);
14278      }
14279      if (lastChild && lastChild.id === 'mce_marker') {
14280        lastChild.parentNode.removeChild(lastChild);
14281      }
14282      return domFragment;
14283    };
14284    var toDomFragment = function (dom, serializer, fragment) {
14285      var html = serializer.serialize(fragment);
14286      var domFragment = dom.createFragment(html);
14287      return cleanupDomFragment(domFragment);
14288    };
14289    var listItems = function (elm) {
14290      return filter$4(elm.childNodes, function (child) {
14291        return child.nodeName === 'LI';
14292      });
14293    };
14294    var isPadding = function (node) {
14295      return node.data === nbsp || isBr$5(node);
14296    };
14297    var isListItemPadded = function (node) {
14298      return node && node.firstChild && node.firstChild === node.lastChild && isPadding(node.firstChild);
14299    };
14300    var isEmptyOrPadded = function (elm) {
14301      return !elm.firstChild || isListItemPadded(elm);
14302    };
14303    var trimListItems = function (elms) {
14304      return elms.length > 0 && isEmptyOrPadded(elms[elms.length - 1]) ? elms.slice(0, -1) : elms;
14305    };
14306    var getParentLi = function (dom, node) {
14307      var parentBlock = dom.getParent(node, dom.isBlock);
14308      return parentBlock && parentBlock.nodeName === 'LI' ? parentBlock : null;
14309    };
14310    var isParentBlockLi = function (dom, node) {
14311      return !!getParentLi(dom, node);
14312    };
14313    var getSplit = function (parentNode, rng) {
14314      var beforeRng = rng.cloneRange();
14315      var afterRng = rng.cloneRange();
14316      beforeRng.setStartBefore(parentNode);
14317      afterRng.setEndAfter(parentNode);
14318      return [
14319        beforeRng.cloneContents(),
14320        afterRng.cloneContents()
14321      ];
14322    };
14323    var findFirstIn = function (node, rootNode) {
14324      var caretPos = CaretPosition.before(node);
14325      var caretWalker = CaretWalker(rootNode);
14326      var newCaretPos = caretWalker.next(caretPos);
14327      return newCaretPos ? newCaretPos.toRange() : null;
14328    };
14329    var findLastOf = function (node, rootNode) {
14330      var caretPos = CaretPosition.after(node);
14331      var caretWalker = CaretWalker(rootNode);
14332      var newCaretPos = caretWalker.prev(caretPos);
14333      return newCaretPos ? newCaretPos.toRange() : null;
14334    };
14335    var insertMiddle = function (target, elms, rootNode, rng) {
14336      var parts = getSplit(target, rng);
14337      var parentElm = target.parentNode;
14338      parentElm.insertBefore(parts[0], target);
14339      Tools.each(elms, function (li) {
14340        parentElm.insertBefore(li, target);
14341      });
14342      parentElm.insertBefore(parts[1], target);
14343      parentElm.removeChild(target);
14344      return findLastOf(elms[elms.length - 1], rootNode);
14345    };
14346    var insertBefore$1 = function (target, elms, rootNode) {
14347      var parentElm = target.parentNode;
14348      Tools.each(elms, function (elm) {
14349        parentElm.insertBefore(elm, target);
14350      });
14351      return findFirstIn(target, rootNode);
14352    };
14353    var insertAfter$1 = function (target, elms, rootNode, dom) {
14354      dom.insertAfter(elms.reverse(), target);
14355      return findLastOf(elms[0], rootNode);
14356    };
14357    var insertAtCaret$1 = function (serializer, dom, rng, fragment) {
14358      var domFragment = toDomFragment(dom, serializer, fragment);
14359      var liTarget = getParentLi(dom, rng.startContainer);
14360      var liElms = trimListItems(listItems(domFragment.firstChild));
14361      var BEGINNING = 1, END = 2;
14362      var rootNode = dom.getRoot();
14363      var isAt = function (location) {
14364        var caretPos = CaretPosition.fromRangeStart(rng);
14365        var caretWalker = CaretWalker(dom.getRoot());
14366        var newPos = location === BEGINNING ? caretWalker.prev(caretPos) : caretWalker.next(caretPos);
14367        return newPos ? getParentLi(dom, newPos.getNode()) !== liTarget : true;
14368      };
14369      if (isAt(BEGINNING)) {
14370        return insertBefore$1(liTarget, liElms, rootNode);
14371      } else if (isAt(END)) {
14372        return insertAfter$1(liTarget, liElms, rootNode, dom);
14373      }
14374      return insertMiddle(liTarget, liElms, rootNode, rng);
14375    };
14376
14377    var trimOrPadLeftRight = function (dom, rng, html) {
14378      var root = SugarElement.fromDom(dom.getRoot());
14379      if (needsToBeNbspLeft(root, CaretPosition.fromRangeStart(rng))) {
14380        html = html.replace(/^ /, '&nbsp;');
14381      } else {
14382        html = html.replace(/^&nbsp;/, ' ');
14383      }
14384      if (needsToBeNbspRight(root, CaretPosition.fromRangeEnd(rng))) {
14385        html = html.replace(/(&nbsp;| )(<br( \/)>)?$/, '&nbsp;');
14386      } else {
14387        html = html.replace(/&nbsp;(<br( \/)?>)?$/, ' ');
14388      }
14389      return html;
14390    };
14391
14392    var isTableCell$1 = isTableCell$5;
14393    var isTableCellContentSelected = function (dom, rng, cell) {
14394      if (cell !== null) {
14395        var endCell = dom.getParent(rng.endContainer, isTableCell$1);
14396        return cell === endCell && hasAllContentsSelected(SugarElement.fromDom(cell), rng);
14397      } else {
14398        return false;
14399      }
14400    };
14401    var validInsertion = function (editor, value, parentNode) {
14402      if (parentNode.getAttribute('data-mce-bogus') === 'all') {
14403        parentNode.parentNode.insertBefore(editor.dom.createFragment(value), parentNode);
14404      } else {
14405        var node = parentNode.firstChild;
14406        var node2 = parentNode.lastChild;
14407        if (!node || node === node2 && node.nodeName === 'BR') {
14408          editor.dom.setHTML(parentNode, value);
14409        } else {
14410          editor.selection.setContent(value);
14411        }
14412      }
14413    };
14414    var trimBrsFromTableCell = function (dom, elm) {
14415      Optional.from(dom.getParent(elm, 'td,th')).map(SugarElement.fromDom).each(trimBlockTrailingBr);
14416    };
14417    var reduceInlineTextElements = function (editor, merge) {
14418      var textInlineElements = editor.schema.getTextInlineElements();
14419      var dom = editor.dom;
14420      if (merge) {
14421        var root_1 = editor.getBody();
14422        var elementUtils_1 = ElementUtils(dom);
14423        Tools.each(dom.select('*[data-mce-fragment]'), function (node) {
14424          var isInline = isNonNullable(textInlineElements[node.nodeName.toLowerCase()]);
14425          if (isInline && hasInheritableStyles(dom, node)) {
14426            for (var parentNode = node.parentNode; isNonNullable(parentNode) && parentNode !== root_1; parentNode = parentNode.parentNode) {
14427              var styleConflict = hasStyleConflict(dom, node, parentNode);
14428              if (styleConflict) {
14429                break;
14430              }
14431              if (elementUtils_1.compare(parentNode, node)) {
14432                dom.remove(node, true);
14433                break;
14434              }
14435            }
14436          }
14437        });
14438      }
14439    };
14440    var markFragmentElements = function (fragment) {
14441      var node = fragment;
14442      while (node = node.walk()) {
14443        if (node.type === 1) {
14444          node.attr('data-mce-fragment', '1');
14445        }
14446      }
14447    };
14448    var unmarkFragmentElements = function (elm) {
14449      Tools.each(elm.getElementsByTagName('*'), function (elm) {
14450        elm.removeAttribute('data-mce-fragment');
14451      });
14452    };
14453    var isPartOfFragment = function (node) {
14454      return !!node.getAttribute('data-mce-fragment');
14455    };
14456    var canHaveChildren = function (editor, node) {
14457      return node && !editor.schema.getShortEndedElements()[node.nodeName];
14458    };
14459    var moveSelectionToMarker = function (editor, marker) {
14460      var nextRng;
14461      var dom = editor.dom;
14462      var selection = editor.selection;
14463      if (!marker) {
14464        return;
14465      }
14466      selection.scrollIntoView(marker);
14467      var parentEditableElm = getContentEditableRoot$1(editor.getBody(), marker);
14468      if (dom.getContentEditable(parentEditableElm) === 'false') {
14469        dom.remove(marker);
14470        selection.select(parentEditableElm);
14471        return;
14472      }
14473      var rng = dom.createRng();
14474      var node = marker.previousSibling;
14475      if (isText$7(node)) {
14476        rng.setStart(node, node.nodeValue.length);
14477        if (!Env.ie) {
14478          var node2 = marker.nextSibling;
14479          if (isText$7(node2)) {
14480            node.appendData(node2.data);
14481            node2.parentNode.removeChild(node2);
14482          }
14483        }
14484      } else {
14485        rng.setStartBefore(marker);
14486        rng.setEndBefore(marker);
14487      }
14488      var findNextCaretRng = function (rng) {
14489        var caretPos = CaretPosition.fromRangeStart(rng);
14490        var caretWalker = CaretWalker(editor.getBody());
14491        caretPos = caretWalker.next(caretPos);
14492        if (caretPos) {
14493          return caretPos.toRange();
14494        }
14495      };
14496      var parentBlock = dom.getParent(marker, dom.isBlock);
14497      dom.remove(marker);
14498      if (parentBlock && dom.isEmpty(parentBlock)) {
14499        editor.$(parentBlock).empty();
14500        rng.setStart(parentBlock, 0);
14501        rng.setEnd(parentBlock, 0);
14502        if (!isTableCell$1(parentBlock) && !isPartOfFragment(parentBlock) && (nextRng = findNextCaretRng(rng))) {
14503          rng = nextRng;
14504          dom.remove(parentBlock);
14505        } else {
14506          dom.add(parentBlock, dom.create('br', { 'data-mce-bogus': '1' }));
14507        }
14508      }
14509      selection.setRng(rng);
14510    };
14511    var deleteSelectedContent = function (editor) {
14512      var dom = editor.dom;
14513      var rng = normalize(editor.selection.getRng());
14514      editor.selection.setRng(rng);
14515      var startCell = dom.getParent(rng.startContainer, isTableCell$1);
14516      if (isTableCellContentSelected(dom, rng, startCell)) {
14517        deleteCellContents(editor, rng, SugarElement.fromDom(startCell));
14518      } else {
14519        editor.getDoc().execCommand('Delete', false, null);
14520      }
14521    };
14522    var insertHtmlAtCaret = function (editor, value, details) {
14523      var parentNode;
14524      var rng, node;
14525      var selection = editor.selection;
14526      var dom = editor.dom;
14527      if (/^ | $/.test(value)) {
14528        value = trimOrPadLeftRight(dom, selection.getRng(), value);
14529      }
14530      var parser = editor.parser;
14531      var merge = details.merge;
14532      var serializer = HtmlSerializer({ validate: shouldValidate(editor) }, editor.schema);
14533      var bookmarkHtml = '<span id="mce_marker" data-mce-type="bookmark">
14533&#xFEFF;</span>';
14534      var args = editor.fire('BeforeSetContent', {
14535        content: value,
14536        format: 'html',
14537        selection: true,
14538        paste: details.paste
14539      });
14540      if (args.isDefaultPrevented()) {
14541        editor.fire('SetContent', {
14542          content: args.content,
14543          format: 'html',
14544          selection: true,
14545          paste: details.paste
14546        });
14547        return;
14548      }
14549      value = args.content;
14550      if (!details.preserve_zwsp) {
14551        value = trim$3(value);
14552      }
14553      if (value.indexOf('{$caret}') === -1) {
14554        value += '{$caret}';
14555      }
14556      value = value.replace(/\{\$caret\}/, bookmarkHtml);
14557      rng = selection.getRng();
14558      var caretElement = rng.startContainer || (rng.parentElement ? rng.parentElement() : null);
14559      var body = editor.getBody();
14560      if (caretElement === body && selection.isCollapsed()) {
14561        if (dom.isBlock(body.firstChild) && canHaveChildren(editor, body.firstChild) && dom.isEmpty(body.firstChild)) {
14562          rng = dom.createRng();
14563          rng.setStart(body.firstChild, 0);
14564          rng.setEnd(body.firstChild, 0);
14565          selection.setRng(rng);
14566        }
14567      }
14568      if (!selection.isCollapsed()) {
14569        deleteSelectedContent(editor);
14570      }
14571      parentNode = selection.getNode();
14572      var parserArgs = {
14573        context: parentNode.nodeName.toLowerCase(),
14574        data: details.data,
14575        insert: true
14576      };
14577      var fragment = parser.parse(value, parserArgs);
14578      if (details.paste === true && isListFragment(editor.schema, fragment) && isParentBlockLi(dom, parentNode)) {
14579        rng = insertAtCaret$1(serializer, dom, selection.getRng(), fragment);
14580        selection.setRng(rng);
14581        editor.fire('SetContent', args);
14582        return;
14583      }
14584      markFragmentElements(fragment);
14585      node = fragment.lastChild;
14586      if (node.attr('id') === 'mce_marker') {
14587        var marker = node;
14588        for (node = node.prev; node; node = node.walk(true)) {
14589          if (node.type === 3 || !dom.isBlock(node.name)) {
14590            if (editor.schema.isValidChild(node.parent.name, 'span')) {
14591              node.parent.insert(marker, node, node.name === 'br');
14592            }
14593            break;
14594          }
14595        }
14596      }
14597      editor._selectionOverrides.showBlockCaretContainer(parentNode);
14598      if (!parserArgs.invalid) {
14599        value = serializer.serialize(fragment);
14600        validInsertion(editor, value, parentNode);
14601      } else {
14602        editor.selection.setContent(bookmarkHtml);
14603        parentNode = selection.getNode();
14604        var rootNode = editor.getBody();
14605        if (parentNode.nodeType === 9) {
14606          parentNode = node = rootNode;
14607        } else {
14608          node = parentNode;
14609        }
14610        while (node !== rootNode) {
14611          parentNode = node;
14612          node = node.parentNode;
14613        }
14614        value = parentNode === rootNode ? rootNode.innerHTML : dom.getOuterHTML(parentNode);
14615        value = serializer.serialize(parser.parse(value.replace(/<span (id="mce_marker"|id=mce_marker).+?<\/span>/i, function () {
14616          return serializer.serialize(fragment);
14617        })));
14618        if (parentNode === rootNode) {
14619          dom.setHTML(rootNode, value);
14620        } else {
14621          dom.setOuterHTML(parentNode, value);
14622        }
14623      }
14624      reduceInlineTextElements(editor, merge);
14625      moveSelectionToMarker(editor, dom.get('mce_marker'));
14626      unmarkFragmentElements(editor.getBody());
14627      trimBrsFromTableCell(dom, selection.getStart());
14628      editor.fire('SetContent', args);
14629      editor.addVisual();
14630    };
14631
14632    var traverse = function (node, fn) {
14633      fn(node);
14634      if (node.firstChild) {
14635        traverse(node.firstChild, fn);
14636      }
14637      if (node.next) {
14638        traverse(node.next, fn);
14639      }
14640    };
14641    var findMatchingNodes = function (nodeFilters, attributeFilters, node) {
14642      var nodeMatches = {};
14643      var attrMatches = {};
14644      var matches = [];
14645      if (node.firstChild) {
14646        traverse(node.firstChild, function (node) {
14647          each$k(nodeFilters, function (filter) {
14648            if (filter.name === node.name) {
14649              if (nodeMatches[filter.name]) {
14650                nodeMatches[filter.name].nodes.push(node);
14651              } else {
14652                nodeMatches[filter.name] = {
14653                  filter: filter,
14654                  nodes: [node]
14655                };
14656              }
14657            }
14658          });
14659          each$k(attributeFilters, function (filter) {
14660            if (typeof node.attr(filter.name) === 'string') {
14661              if (attrMatches[filter.name]) {
14662                attrMatches[filter.name].nodes.push(node);
14663              } else {
14664                attrMatches[filter.name] = {
14665                  filter: filter,
14666                  nodes: [node]
14667                };
14668              }
14669            }
14670          });
14671        });
14672      }
14673      for (var name_1 in nodeMatches) {
14674        if (has$2(nodeMatches, name_1)) {
14675          matches.push(nodeMatches[name_1]);
14676        }
14677      }
14678      for (var name_2 in attrMatches) {
14679        if (has$2(attrMatches, name_2)) {
14680          matches.push(attrMatches[name_2]);
14681        }
14682      }
14683      return matches;
14684    };
14685    var filter$1 = function (nodeFilters, attributeFilters, node) {
14686      var matches = findMatchingNodes(nodeFilters, attributeFilters, node);
14687      each$k(matches, function (match) {
14688        each$k(match.filter.callbacks, function (callback) {
14689          callback(match.nodes, match.filter.name, {});
14690        });
14691      });
14692    };
14693
14694    var defaultFormat$1 = 'html';
14695    var isTreeNode = function (content) {
14696      return content instanceof AstNode;
14697    };
14698    var moveSelection = function (editor) {
14699      if (hasFocus(editor)) {
14700        firstPositionIn(editor.getBody()).each(function (pos) {
14701          var node = pos.getNode();
14702          var caretPos = isTable$3(node) ? firstPositionIn(node).getOr(pos) : pos;
14703          editor.selection.setRng(caretPos.toRange());
14704        });
14705      }
14706    };
14707    var setEditorHtml = function (editor, html, noSelection) {
14708      editor.dom.setHTML(editor.getBody(), html);
14709      if (noSelection !== true) {
14710        moveSelection(editor);
14711      }
14712    };
14713    var setContentString = function (editor, body, content, args) {
14714      content = trim$3(content);
14715      if (content.length === 0 || /^\s+$/.test(content)) {
14716        var padd = '<br data-mce-bogus="1">';
14717        if (body.nodeName === 'TABLE') {
14718          content = '<tr><td>' + padd + '</td></tr>';
14719        } else if (/^(UL|OL)$/.test(body.nodeName)) {
14720          content = '<li>' + padd + '</li>';
14721        }
14722        var forcedRootBlockName = getForcedRootBlock(editor);
14723        if (forcedRootBlockName && editor.schema.isValidChild(body.nodeName.toLowerCase(), forcedRootBlockName.toLowerCase())) {
14724          content = padd;
14725          content = editor.dom.createHTML(forcedRootBlockName, getForcedRootBlockAttrs(editor), content);
14726        } else if (!content) {
14727          content = '<br data-mce-bogus="1">';
14728        }
14729        setEditorHtml(editor, content, args.no_selection);
14730        editor.fire('SetContent', args);
14731      } else {
14732        if (args.format !== 'raw') {
14733          content = HtmlSerializer({ validate: editor.validate }, editor.schema).serialize(editor.parser.parse(content, {
14734            isRootContent: true,
14735            insert: true
14736          }));
14737        }
14738        args.content = isWsPreserveElement(SugarElement.fromDom(body)) ? content : Tools.trim(content);
14739        setEditorHtml(editor, args.content, args.no_selection);
14740        if (!args.no_events) {
14741          editor.fire('SetContent', args);
14742        }
14743      }
14744      return args.content;
14745    };
14746    var setContentTree = function (editor, body, content, args) {
14747      filter$1(editor.parser.getNodeFilters(), editor.parser.getAttributeFilters(), content);
14748      var html = HtmlSerializer({ validate: editor.validate }, editor.schema).serialize(content);
14749      args.content = trim$3(isWsPreserveElement(SugarElement.fromDom(body)) ? html : Tools.trim(html));
14750      setEditorHtml(editor, args.content, args.no_selection);
14751      if (!args.no_events) {
14752        editor.fire('SetContent', args);
14753      }
14754      return content;
14755    };
14756    var setupArgs$2 = function (args, content) {
14757      return __assign(__assign({ format: defaultFormat$1 }, args), {
14758        set: true,
14759        content: isTreeNode(content) ? '' : content
14760      });
14761    };
14762    var setContentInternal = function (editor, content, args) {
14763      var defaultedArgs = setupArgs$2(args, content);
14764      var updatedArgs = args.no_events ? defaultedArgs : editor.fire('BeforeSetContent', defaultedArgs);
14765      if (!isTreeNode(content)) {
14766        content = updatedArgs.content;
14767      }
14768      return Optional.from(editor.getBody()).fold(constant(content), function (body) {
14769        return isTreeNode(content) ? setContentTree(editor, body, content, updatedArgs) : setContentString(editor, body, content, updatedArgs);
14770      });
14771    };
14772
14773    var sibling = function (scope, predicate) {
14774      return sibling$2(scope, predicate).isSome();
14775    };
14776
14777    var ensureIsRoot = function (isRoot) {
14778      return isFunction(isRoot) ? isRoot : never;
14779    };
14780    var ancestor = function (scope, transform, isRoot) {
14781      var element = scope.dom;
14782      var stop = ensureIsRoot(isRoot);
14783      while (element.parentNode) {
14784        element = element.parentNode;
14785        var el = SugarElement.fromDom(element);
14786        var transformed = transform(el);
14787        if (transformed.isSome()) {
14788          return transformed;
14789        } else if (stop(el)) {
14790          break;
14791        }
14792      }
14793      return Optional.none();
14794    };
14795    var closest$1 = function (scope, transform, isRoot) {
14796      var current = transform(scope);
14797      var stop = ensureIsRoot(isRoot);
14798      return current.orThunk(function () {
14799        return stop(scope) ? Optional.none() : ancestor(scope, transform, stop
14799);
14800      });
14801    };
14802
14803    var isEq$3 = isEq$5;
14804    var matchesUnInheritedFormatSelector = function (ed, node, name) {
14805      var formatList = ed.formatter.get(name);
14806      if (formatList) {
14807        for (var i = 0; i < formatList.length; i++) {
14808          var format = formatList[i];
14809          if (isSelectorFormat(format) && format.inherit === false && ed.dom.is(node, format.selector)) {
14810            return true;
14811          }
14812        }
14813      }
14814      return false;
14815    };
14816    var matchParents = function (editor, node, name, vars, similar) {
14817      var root = editor.dom.getRoot();
14818      if (node === root) {
14819        return false;
14820      }
14821      node = editor.dom.getParent(node, function (node) {
14822        if (matchesUnInheritedFormatSelector(editor, node, name)) {
14823          return true;
14824        }
14825        return node.parentNode === root || !!matchNode(editor, node, name, vars, true);
14826      });
14827      return !!matchNode(editor, node, name, vars, similar);
14828    };
14829    var matchName$1 = function (dom, node, format) {
14830      if (isEq$3(node, format.inline)) {
14831        return true;
14832      }
14833      if (isEq$3(node, format.block)) {
14834        return true;
14835      }
14836      if (format.selector) {
14837        return node.nodeType === 1 && dom.is(node, format.selector);
14838      }
14839    };
14840    var matchItems = function (dom, node, format, itemName, similar, vars) {
14841      var items = format[itemName];
14842      if (isFunction(format.onmatch)) {
14843        return format.onmatch(node, format, itemName);
14844      }
14845      if (items) {
14846        if (isUndefined(items.length)) {
14847          for (var key in items) {
14848            if (has$2(items, key)) {
14849              var value = itemName === 'attributes' ? dom.getAttrib(node, key) : getStyle(dom, node, key);
14850              var expectedValue = replaceVars(items[key], vars);
14851              var isEmptyValue = isNullable(value) || isEmpty$3(value);
14852              if (isEmptyValue && isNullable(expectedValue)) {
14853                continue;
14854              }
14855              if (similar && isEmptyValue && !format.exact) {
14856                return false;
14857              }
14858              if ((!similar || format.exact) && !isEq$3(value, normalizeStyleValue(dom, expectedValue, key))) {
14859                return false;
14860              }
14861            }
14862          }
14863        } else {
14864          for (var i = 0; i < items.length; i++) {
14865            if (itemName === 'attributes' ? dom.getAttrib(node, items[i]) : getStyle(dom, node, items[i])) {
14866              return true;
14867            }
14868          }
14869        }
14870      }
14871      return true;
14872    };
14873    var matchNode = function (ed, node, name, vars, similar) {
14874      var formatList = ed.formatter.get(name);
14875      var dom = ed.dom;
14876      if (formatList && node) {
14877        for (var i = 0; i < formatList.length; i++) {
14878          var format = formatList[i];
14879          if (matchName$1(ed.dom, node, format) && matchItems(dom, node, format, 'attributes', similar, vars) && matchItems(dom, node, format, 'styles', similar, vars)) {
14880            var classes = format.classes;
14881            if (classes) {
14882              for (var x = 0; x < classes.length; x++) {
14883                if (!ed.dom.hasClass(node, replaceVars(classes[x], vars))) {
14884                  return;
14885                }
14886              }
14887            }
14888            return format;
14889          }
14890        }
14891      }
14892    };
14893    var match$2 = function (editor, name, vars, node, similar) {
14894      if (node) {
14895        return matchParents(editor, node, name, vars, similar);
14896      }
14897      node = editor.selection.getNode();
14898      if (matchParents(editor, node, name, vars, similar)) {
14899        return true;
14900      }
14901      var startNode = editor.selection.getStart();
14902      if (startNode !== node) {
14903        if (matchParents(editor, startNode, name, vars, similar)) {
14904          return true;
14905        }
14906      }
14907      return false;
14908    };
14909    var matchAll = function (editor, names, vars) {
14910      var matchedFormatNames = [];
14911      var checkedMap = {};
14912      var startElement = editor.selection.getStart();
14913      editor.dom.getParent(startElement, function (node) {
14914        for (var i = 0; i < names.length; i++) {
14915          var name_1 = names[i];
14916          if (!checkedMap[name_1] && matchNode(editor, node, name_1, vars)) {
14917            checkedMap[name_1] = true;
14918            matchedFormatNames.push(name_1);
14919          }
14920        }
14921      }, editor.dom.getRoot());
14922      return matchedFormatNames;
14923    };
14924    var closest = function (editor, names) {
14925      var isRoot = function (elm) {
14926        return eq(elm, SugarElement.fromDom(editor.getBody()));
14927      };
14928      var match = function (elm, name) {
14929        return matchNode(editor, elm.dom, name) ? Optional.some(name) : Optional.none();
14930      };
14931      return Optional.from(editor.selection.getStart(true)).bind(function (rawElm) {
14932        return closest$1(SugarElement.fromDom(rawElm), function (elm) {
14933          return findMap(names, function (name) {
14934            return match(elm, name);
14935          });
14936        }, isRoot);
14937      }).getOrNull();
14938    };
14939    var canApply = function (editor, name) {
14940      var formatList = editor.formatter.get(name);
14941      var dom = editor.dom;
14942      if (formatList) {
14943        var startNode = editor.selection.getStart();
14944        var parents = getParents$2(dom, startNode);
14945        for (var x = formatList.length - 1; x >= 0; x--) {
14946          var format = formatList[x];
14947          if (!isSelectorFormat(format) || isNonNullable(format.defaultBlock)) {
14948            return true;
14949          }
14950          for (var i = parents.length - 1; i >= 0; i--) {
14951            if (dom.is(parents[i], format.selector)) {
14952              return true;
14953            }
14954          }
14955        }
14956      }
14957      return false;
14958    };
14959    var matchAllOnNode = function (editor, node, formatNames) {
14960      return foldl(formatNames, function (acc, name) {
14961        var matchSimilar = isVariableFormatName(editor, name);
14962        if (editor.formatter.matchNode(node, name, {}, matchSimilar)) {
14963          return acc.concat([name]);
14964        } else {
14965          return acc;
14966        }
14967      }, []);
14968    };
14969
14970    var ZWSP = ZWSP$1, CARET_ID = '_mce_caret';
14971    var importNode = function (ownerDocument, node) {
14972      return ownerDocument.importNode(node, true);
14973    };
14974    var getEmptyCaretContainers = function (node) {
14975      var nodes = [];
14976      while (node) {
14977        if (node.nodeType === 3 && node.nodeValue !== ZWSP || node.childNodes.length > 1) {
14978          return [];
14979        }
14980        if (node.nodeType === 1) {
14981          nodes.push(node);
14982        }
14983        node = node.firstChild;
14984      }
14985      return nodes;
14986    };
14987    var isCaretContainerEmpty = function (node) {
14988      return getEmptyCaretContainers(node).length > 0;
14989    };
14990    var findFirstTextNode = function (node) {
14991      if (node) {
14992        var walker = new DomTreeWalker(node, node);
14993        for (node = walker.current(); node; node = walker.next()) {
14994          if (isText$7(node)) {
14995            return node;
14996          }
14997        }
14998      }
14999      return null;
15000    };
15001    var createCaretContainer = function (fill) {
15002      var caretContainer = SugarElement.fromTag('span');
15003      setAll$1(caretContainer, {
15004        'id': CARET_ID,
15005        'data-mce-bogus': '1',
15006        'data-mce-type': 'format-caret'
15007      });
15008      if (fill) {
15009        append$1(caretContainer, SugarElement.fromText(ZWSP));
15010      }
15011      return caretContainer;
15012    };
15013    var trimZwspFromCaretContainer = function (caretContainerNode) {
15014      var textNode = findFirstTextNode(caretContainerNode);
15015      if (textNode && textNode.nodeValue.charAt(0) === ZWSP) {
15016        textNode.deleteData(0, 1);
15017      }
15018      return textNode;
15019    };
15020    var removeCaretContainerNode = function (editor, node, moveCaret) {
15021      if (moveCaret === void 0) {
15022        moveCaret = true;
15023      }
15024      var dom = editor.dom, selection = editor.selection;
15025      if (isCaretContainerEmpty(node)) {
15026        deleteElement$2(editor, false, SugarElement.fromDom(node), moveCaret);
15027      } else {
15028        var rng = selection.getRng();
15029        var block = dom.getParent(node, dom.isBlock);
15030        var startContainer = rng.startContainer;
15031        var startOffset = rng.startOffset;
15032        var endContainer = rng.endContainer;
15033        var endOffset = rng.endOffset;
15034        var textNode = trimZwspFromCaretContainer(node);
15035        dom.remove(node, true);
15036        if (startContainer === textNode && startOffset > 0) {
15037          rng.setStart(textNode, startOffset - 1);
15038        }
15039        if (endContainer === textNode && endOffset > 0) {
15040          rng.setEnd(textNode, endOffset - 1);
15041        }
15042        if (block && dom.isEmpty(block)) {
15043          fillWithPaddingBr(SugarElement.fromDom(block));
15044        }
15045        selection.setRng(rng);
15046      }
15047    };
15048    var removeCaretContainer = function (editor, node, moveCaret) {
15049      if (moveCaret === void 0) {
15050        moveCaret = true;
15051      }
15052      var dom = editor.dom, selection = editor.selection;
15053      if (!node) {
15054        node = getParentCaretContainer(editor.getBody(), selection.getStart());
15055        if (!node) {
15056          while (node = dom.get(CARET_ID)) {
15057            removeCaretContainerNode(editor, node, false);
15058          }
15059        }
15060      } else {
15061        removeCaretContainerNode(editor, node, moveCaret);
15062      }
15063    };
15064    var insertCaretContainerNode = function (editor, caretContainer, formatNode) {
15065      var dom = editor.dom, block = dom.getParent(formatNode, curry(isTextBlock$1, editor));
15066      if (block && dom.isEmpty(block)) {
15067        formatNode.parentNode.replaceChild(caretContainer, formatNode);
15068      } else {
15069        removeTrailingBr(SugarElement.fromDom(formatNode));
15070        if (dom.isEmpty(formatNode)) {
15071          formatNode.parentNode.replaceChild(caretContainer, formatNode);
15072        } else {
15073          dom.insertAfter(caretContainer, formatNode);
15074        }
15075      }
15076    };
15077    var appendNode = function (parentNode, node) {
15078      parentNode.appendChild(node);
15079      return node;
15080    };
15081    var insertFormatNodesIntoCaretContainer = function (formatNodes, caretContainer) {
15082      var innerMostFormatNode = foldr(formatNodes, function (parentNode, formatNode) {
15083        return appendNode(parentNode, formatNode.cloneNode(false));
15084      }, caretContainer);
15085      return appendNode(innerMostFormatNode, innerMostFormatNode.ownerDocument.createTextNode(ZWSP));
15086    };
15087    var cleanFormatNode = function (editor, caretContainer, formatNode, name, vars, similar) {
15088      var formatter = editor.formatter;
15089      var dom = editor.dom;
15090      var validFormats = filter$4(keys(formatter.get()), function (formatName) {
15091        return formatName !== name && !contains$2(formatName, 'removeformat');
15092      });
15093      var matchedFormats = matchAllOnNode(editor, formatNode, validFormats);
15094      var uniqueFormats = filter$4(matchedFormats, function (fmtName) {
15095        return !areSimilarFormats(editor, fmtName, name);
15096      });
15097      if (uniqueFormats.length > 0) {
15098        var clonedFormatNode = formatNode.cloneNode(false);
15099        dom.add(caretContainer, clonedFormatNode);
15100        formatter.remove(name, vars, clonedFormatNode, similar);
15101        dom.remove(clonedFormatNode);
15102        return Optional.some(clonedFormatNode);
15103      } else {
15104        return Optional.none();
15105      }
15106    };
15107    var applyCaretFormat = function (editor, name, vars) {
15108      var caretContainer, textNode;
15109      var selection = editor.selection;
15110      var selectionRng = selection.getRng();
15111      var offset = selectionRng.startOffset;
15112      var container = selectionRng.startContainer;
15113      var text = container.nodeValue;
15114      caretContainer = getParentCaretContainer(editor.getBody(), selection.getStart());
15115      if (caretContainer) {
15116        textNode = findFirstTextNode(caretContainer);
15117      }
15118      var wordcharRegex = /[^\s\u00a0\u00ad\u200b\ufeff]/;
15119      if (text && offset > 0 && offset < text.length && wordcharRegex.test(text.charAt(offset)) && wordcharRegex.test(text.charAt(offset - 1))) {
15120        var bookmark = selection.getBookmark();
15121        selectionRng.collapse(true);
15122        var rng = expandRng(editor, selectionRng, editor.formatter.get(name));
15123        rng = split(rng);
15124        editor.formatter.apply(name, vars, rng);
15125        selection.moveToBookmark(bookmark);
15126      } else {
15127        if (!caretContainer || textNode.nodeValue !== ZWSP) {
15128          caretContainer = importNode(editor.getDoc(), createCaretContainer(true).dom);
15129          textNode = caretContainer.firstChild;
15130          selectionRng.insertNode(caretContainer);
15131          offset = 1;
15132          editor.formatter.apply(name, vars, caretContainer);
15133        } else {
15134          editor.formatter.apply(name, vars, caretContainer);
15135        }
15136        selection.setCursorLocation(textNode, offset);
15137      }
15138    };
15139    var removeCaretFormat = function (editor, name, vars, similar) {
15140      var dom = editor.dom;
15141      var selection = editor.selection;
15142      var hasContentAfter, node, formatNode;
15143      var parents = [];
15144      var rng = selection.getRng();
15145      var container = rng.startContainer;
15146      var offset = rng.startOffset;
15147      node = container;
15148      if (container.nodeType === 3) {
15149        if (offset !== container.nodeValue.length) {
15150          hasContentAfter = true;
15151        }
15152        node = node.parentNode;
15153      }
15154      while (node) {
15155        if (matchNode(editor, node, name, vars, similar)) {
15156          formatNode = node;
15157          break;
15158        }
15159        if (node.nextSibling) {
15160          hasContentAfter = true;
15161        }
15162        parents.push(node);
15163        node = node.parentNode;
15164      }
15165      if (!formatNode) {
15166        return;
15167      }
15168      if (hasContentAfter) {
15169        var bookmark = selection.getBookmark();
15170        rng.collapse(true);
15171        var expandedRng = expandRng(editor, rng, editor.formatter.get(name), true);
15172        expandedRng = split(expandedRng);
15173        editor.formatter.remove(name, vars, expandedRng, similar);
15174        selection.moveToBookmark(bookmark);
15175      } else {
15176        var caretContainer = getParentCaretContainer(editor.getBody(), formatNode);
15177        var newCaretContainer = createCaretContainer(false).dom;
15178        insertCaretContainerNode(editor, newCaretContainer, caretContainer !== null ? caretContainer : formatNode);
15179        var cleanedFormatNode = cleanFormatNode(editor, newCaretContainer, formatNode, name, vars, similar);
15180        var caretTextNode = insertFormatNodesIntoCaretContainer(parents.concat(cleanedFormatNode.toArray()), newCaretContainer);
15181        removeCaretContainerNode(editor, caretContainer, false);
15182        selection.setCursorLocation(caretTextNode, 1);
15183        if (dom.isEmpty(formatNode)) {
15184          dom.remove(formatNode);
15185        }
15186      }
15187    };
15188    var disableCaretContainer = function (editor, keyCode) {
15189      var selection = editor.selection, body = editor.getBody();
15190      removeCaretContainer(editor, null, false);
15191      if ((keyCode === 8 || keyCode === 46) && selection.isCollapsed() && selection.getStart().innerHTML === ZWSP) {
15192        removeCaretContainer(editor, getParentCaretContainer(body, selection.getStart()));
15193      }
15194      if (keyCode === 37 || keyCode === 39) {
15195        removeCaretContainer(editor, getParentCaretContainer(body, selection.getStart()));
15196      }
15197    };
15198    var setup$k = function (editor) {
15199      editor.on('mouseup keydown', function (e) {
15200        disableCaretContainer(editor, e.keyCode);
15201      });
15202    };
15203    var replaceWithCaretFormat = function (targetNode, formatNodes) {
15204      var caretContainer = createCaretContainer(false);
15205      var innerMost = insertFormatNodesIntoCaretContainer(formatNodes, caretContainer.dom);
15206      before$4(SugarElement.fromDom(targetNode), caretContainer);
15207      remove$7(SugarElement.fromDom(targetNode));
15208      return CaretPosition(innerMost, 0);
15209    };
15210    var isFormatElement = function (editor, element) {
15211      var inlineElements = editor.schema.getTextInlineElements();
15212      return has$2(inlineElements, name(element)) && !isCaretNode(element.dom) && !isBogus$2(element.dom);
15213    };
15214    var isEmptyCaretFormatElement = function (element) {
15215      return isCaretNode(element.dom) && isCaretContainerEmpty(element.dom);
15216    };
15217
15218    var postProcessHooks = {};
15219    var filter = filter$2;
15220    var each$c = each$i;
15221    var addPostProcessHook = function (name, hook) {
15222      var hooks = postProcessHooks[name];
15223      if (!hooks) {
15224        postProcessHooks[name] = [];
15225      }
15226      postProcessHooks[name].push(hook);
15227    };
15228    var postProcess$1 = function (name, editor) {
15229      each$c(postProcessHooks[name], function (hook) {
15230        hook(editor);
15231      });
15232    };
15233    addPostProcessHook('pre', function (editor) {
15234      var rng = editor.selection.getRng();
15235      var blocks;
15236      var hasPreSibling = function (pre) {
15237        return isPre(pre.previousSibling) && indexOf$1(blocks, pre.previousSibling) !== -1;
15238      };
15239      var joinPre = function (pre1, pre2) {
15240        DomQuery(pre2).remove();
15241        DomQuery(pre1).append('<br><br>').append(pre2.childNodes);
15242      };
15243      var isPre = matchNodeNames(['pre']);
15244      if (!rng.collapsed) {
15245        blocks = editor.selection.getSelectedBlocks();
15246        each$c(filter(filter(blocks, isPre), hasPreSibling), function (pre) {
15247          joinPre(pre.previousSibling, pre);
15248        });
15249      }
15250    });
15251
15252    var each$b = Tools.each;
15253    var isElementNode$1 = function (node) {
15254      return isElement$5(node) && !isBookmarkNode$1(node) && !isCaretNode(node) && !isBogus$2(node);
15255    };
15256    var findElementSibling = function (node, siblingName) {
15257      for (var sibling = node; sibling; sibling = sibling[siblingName]) {
15258        if (isText$7(sibling) && isNotEmpty(sibling.data)) {
15259          return node;
15260        }
15261        if (isElement$5(sibling) && !isBookmarkNode$1(sibling)) {
15262          return sibling;
15263        }
15264      }
15265      return node;
15266    };
15267    var mergeSiblingsNodes = function (dom, prev, next) {
15268      var elementUtils = ElementUtils(dom);
15269      if (prev && next) {
15270        prev = findElementSibling(prev, 'previousSibling');
15271        next = findElementSibling(next, 'nextSibling');
15272        if (elementUtils.compare(prev, next)) {
15273          for (var sibling = prev.nextSibling; sibling && sibling !== next;) {
15274            var tmpSibling = sibling;
15275            sibling = sibling.nextSibling;
15276            prev.appendChild(tmpSibling);
15277          }
15278          dom.remove(next);
15279          Tools.each(Tools.grep(next.childNodes), function (node) {
15280            prev.appendChild(node);
15281          });
15282          return prev;
15283        }
15284      }
15285      return next;
15286    };
15287    var mergeSiblings = function (dom, format, vars, node) {
15288      if (node && format.merge_siblings !== false) {
15289        var newNode = mergeSiblingsNodes(dom, getNonWhiteSpaceSibling(node), node);
15290        mergeSiblingsNodes(dom, newNode, getNonWhiteSpaceSibling(newNode, true));
15291      }
15292    };
15293    var clearChildStyles = function (dom, format, node) {
15294      if (format.clear_child_styles) {
15295        var selector = format.links ? '*:not(a)' : '*';
15296        each$b(dom.select(selector, node), function (node) {
15297          if (isElementNode$1(node)) {
15298            each$b(format.styles, function (value, name) {
15299              dom.setStyle(node, name, '');
15300            });
15301          }
15302        });
15303      }
15304    };
15305    var processChildElements = function (node, filter, process) {
15306      each$b(node.childNodes, function (node) {
15307        if (isElementNode$1(node)) {
15308          if (filter(node)) {
15309            process(node);
15310          }
15311          if (node.hasChildNodes()) {
15312            processChildElements(node, filter, process);
15313          }
15314        }
15315      });
15316    };
15317    var unwrapEmptySpan = function (dom, node) {
15318      if (node.nodeName === 'SPAN' && dom.getAttribs(node).length === 0) {
15319        dom.remove(node, true);
15320      }
15321    };
15322    var hasStyle = function (dom, name) {
15323      return function (node) {
15324        return !!(node && getStyle(dom, node, name));
15325      };
15326    };
15327    var applyStyle = function (dom, name, value) {
15328      return function (node) {
15329        dom.setStyle(node, name, value);
15330        if (node.getAttribute('style') === '') {
15331          node.removeAttribute('style');
15332        }
15333        unwrapEmptySpan(dom, node);
15334      };
15335    };
15336
15337    var removeResult = Adt.generate([
15338      { keep: [] },
15339      { rename: ['name'] },
15340      { removed: [] }
15341    ]);
15342    var MCE_ATTR_RE = /^(src|href|style)$/;
15343    var each$a = Tools.each;
15344    var isEq$2 = isEq$5;
15345    var isTableCellOrRow = function (node) {
15346      return /^(TR|TH|TD)$/.test(node.nodeName);
15347    };
15348    var isChildOfInlineParent = function (dom, node, parent) {
15349      return dom.isChildOf(node, parent) && node !== parent && !dom.isBlock(parent);
15350    };
15351    var getContainer = function (ed, rng, start) {
15352      var container = rng[start ? 'startContainer' : 'endContainer'];
15353      var offset = rng[start ? 'startOffset' : 'endOffset'];
15354      if (isElement$5(container)) {
15355        var lastIdx = container.childNodes.length - 1;
15356        if (!start && offset) {
15357          offset--;
15358        }
15359        container = container.childNodes[offset > lastIdx ? lastIdx : offset];
15360      }
15361      if (isText$7(container) && start && offset >= container.nodeValue.length) {
15362        container = new DomTreeWalker(container, ed.getBody()).next() || container;
15363      }
15364      if (isText$7(container) && !start && offset === 0) {
15365        container = new DomTreeWalker(container, ed.getBody()).prev() || container;
15366      }
15367      return container;
15368    };
15369    var normalizeTableSelection = function (node, start) {
15370      var prop = start ? 'firstChild' : 'lastChild';
15371      if (isTableCellOrRow(node) && node[prop]) {
15372        var childNode = node[prop];
15373        if (node.nodeName === 'TR') {
15374          return childNode[prop] || childNode;
15375        } else {
15376          return childNode;
15377        }
15378      }
15379      return node;
15380    };
15381    var wrap$1 = function (dom, node, name, attrs) {
15382      var wrapper = dom.create(name, attrs);
15383      node.parentNode.insertBefore(wrapper, node);
15384      wrapper.appendChild(node);
15385      return wrapper;
15386    };
15387    var wrapWithSiblings = function (dom, node, next, name, attrs) {
15388      var start = SugarElement.fromDom(node);
15389      var wrapper = SugarElement.fromDom(dom.create(name, attrs));
15390      var siblings = next ? nextSiblings(start) : prevSiblings(start);
15391      append(wrapper, siblings);
15392      if (next) {
15393        before$4(start, wrapper);
15394        prepend(wrapper, start);
15395      } else {
15396        after$3(start, wrapper);
15397        append$1(wrapper, start);
15398      }
15399      return wrapper.dom;
15400    };
15401    var matchName = function (dom, node, format) {
15402      if (isInlineFormat(format) && isEq$2(node, format.inline)) {
15403        return true;
15404      }
15405      if (isBlockFormat(format) && isEq$2(node, format.block)) {
15406        return true;
15407      }
15408      if (isSelectorFormat(format)) {
15409        return isElement$5(node) && dom.is(node, format.selector);
15410      }
15411    };
15412    var isColorFormatAndAnchor = function (node, format) {
15413      return format.links && node.nodeName === 'A';
15414    };
15415    var find = function (dom, node, next, inc) {
15416      var sibling = getNonWhiteSpaceSibling(node, next, inc);
15417      return isNullable(sibling) || sibling.nodeName === 'BR' || dom.isBlock(sibling);
15418    };
15419    var removeNode = function (ed, node, format) {
15420      var parentNode = node.parentNode;
15421      var rootBlockElm;
15422      var dom = ed.dom, forcedRootBlock = getForcedRootBlock(ed);
15423      if (isBlockFormat(format)) {
15424        if (!forcedRootBlock) {
15425          if (dom.isBlock(node) && !dom.isBlock(parentNode)) {
15426            if (!find(dom, node, false) && !find(dom, node.firstChild, true, true)) {
15427              node.insertBefore(dom.create('br'), node.firstChild);
15428            }
15429            if (!find(dom, node, true) && !find(dom, node.lastChild, false, true)) {
15430              node.appendChild(dom.create('br'));
15431            }
15432          }
15433        } else {
15434          if (parentNode === dom.getRoot()) {
15435            if (!format.list_block || !isEq$2(node, format.list_block)) {
15436              each$k(from(node.childNodes), function (node) {
15437                if (isValid(ed, forcedRootBlock, node.nodeName.toLowerCase())) {
15438                  if (!rootBlockElm) {
15439                    rootBlockElm = wrap$1(dom, node, forcedRootBlock);
15440                    dom.setAttribs(rootBlockElm, ed.settings.forced_root_block_attrs);
15441                  } else {
15442                    rootBlockElm.appendChild(node);
15443                  }
15444                } else {
15445                  rootBlockElm = null;
15446                }
15447              });
15448            }
15449          }
15450        }
15451      }
15452      if (isMixedFormat(format) && !isEq$2(format.inline, node)) {
15453        return;
15454      }
15455      dom.remove(node, true);
15456    };
15457    var removeFormatInternal = function (ed, format, vars, node, compareNode) {
15458      var stylesModified;
15459      var dom = ed.dom;
15460      if (!matchName(dom, node, format) && !isColorFormatAndAnchor(node, format)) {
15461        return removeResult.keep();
15462      }
15463      var elm = node;
15464      if (isInlineFormat(format) && format.remove === 'all' && isArray$1(format.preserve_attributes)) {
15465        var attrsToPreserve = filter$4(dom.getAttribs(elm), function (attr) {
15466          return contains$3(format.preserve_attributes, attr.name.toLowerCase());
15467        });
15468        dom.removeAllAttribs(elm);
15469        each$k(attrsToPreserve, function (attr) {
15470          return dom.setAttrib(elm, attr.name, attr.value);
15471        });
15472        if (attrsToPreserve.length > 0) {
15473          return removeResult.rename('span');
15474        }
15475      }
15476      if (format.remove !== 'all') {
15477        each$a(format.styles, function (value, name) {
15478          value = normalizeStyleValue(dom, replaceVars(value, vars), name + '');
15479          if (isNumber(name)) {
15480            name = value;
15481            compareNode = null;
15482          }
15483          if (format.remove_similar || (!compareNode || isEq$2(getStyle(dom, compareNode, name), value))) {
15484            dom.setStyle(elm, name, '');
15485          }
15486          stylesModified = true;
15487        });
15488        if (stylesModified && dom.getAttrib(elm, 'style') === '') {
15489          elm.removeAttribute('style');
15490          elm.removeAttribute('data-mce-style');
15491        }
15492        each$a(format.attributes, function (value, name) {
15493          var valueOut;
15494          value = replaceVars(value, vars);
15495          if (isNumber(name)) {
15496            name = value;
15497            compareNode = null;
15498          }
15499          if (format.remove_similar || (!compareNode || isEq$2(dom.getAttrib(compareNode, name), value))) {
15500            if (name === 'class') {
15501              value = dom.getAttrib(elm, name);
15502              if (value) {
15503                valueOut = '';
15504                each$k(value.split(/\s+/), function (cls) {
15505                  if (/mce\-\w+/.test(cls)) {
15506                    valueOut += (valueOut ? ' ' : '') + cls;
15507                  }
15508                });
15509                if (valueOut) {
15510                  dom.setAttrib(elm, name, valueOut);
15511                  return;
15512                }
15513              }
15514            }
15515            if (MCE_ATTR_RE.test(name)) {
15516              elm.removeAttribute('data-mce-' + name);
15517            }
15518            if (name === 'style' && matchNodeNames(['li'])(elm) && dom.getStyle(elm, 'list-style-type') === 'none') {
15519              elm.removeAttribute(name);
15520              dom.setStyle(elm, 'list-style-type', 'none');
15521              return;
15522            }
15523            if (name === 'class') {
15524              elm.removeAttribute('className');
15525            }
15526            elm.removeAttribute(name);
15527          }
15528        });
15529        each$a(format.classes, function (value) {
15530          value = replaceVars(value, vars);
15531          if (!compareNode || dom.hasClass(compareNode, value)) {
15532            dom.removeClass(elm, value);
15533          }
15534        });
15535        var attrs = dom.getAttribs(elm);
15536        for (var i = 0; i < attrs.length; i++) {
15537          var attrName = attrs[i].nodeName;
15538          if (attrName.indexOf('_') !== 0 && attrName.indexOf('data-') !== 0) {
15539            return removeResult.keep();
15540          }
15541        }
15542      }
15543      if (format.remove !== 'none') {
15544        removeNode(ed, elm, format);
15545        return removeResult.removed();
15546      }
15547      return removeResult.keep();
15548    };
15549    var removeFormat$1 = function (ed, format, vars, node, compareNode) {
15550      return removeFormatInternal(ed, format, vars, node, compareNode).fold(never, function (newName) {
15551        ed.dom.rename(node, newName);
15552        return true;
15553      }, always);
15554    };
15555    var findFormatRoot = function (editor, container, name, vars, similar) {
15556      var formatRoot;
15557      each$k(getParents$2(editor.dom, container.parentNode).reverse(), function (parent) {
15558        if (!formatRoot && parent.id !== '_start' && parent.id !== '_end') {
15559          var format = matchNode(editor, parent, name, vars, similar);
15560          if (format && format.split !== false) {
15561            formatRoot = parent;
15562          }
15563        }
15564      });
15565      return formatRoot;
15566    };
15567    var removeFormatFromClone = function (editor, format, vars, clone) {
15568      return removeFormatInternal(editor, format, vars, clone, clone).fold(constant(clone), function (newName) {
15569        var fragment = editor.dom.createFragment();
15570        fragment.appendChild(clone);
15571        return editor.dom.rename(clone, newName);
15572      }, constant(null));
15573    };
15574    var wrapAndSplit = function (editor, formatList, formatRoot, container, target, split, format, vars) {
15575      var clone, lastClone, firstClone;
15576      var dom = editor.dom;
15577      if (formatRoot) {
15578        var formatRootParent = formatRoot.parentNode;
15579        for (var parent_1 = container.parentNode; parent_1 && parent_1 !== formatRootParent; parent_1 = parent_1.parentNode) {
15580          clone = dom.clone(parent_1, false);
15581          for (var i = 0; i < formatList.length; i++) {
15582            clone = removeFormatFromClone(editor, formatList[i], vars, clone);
15583            if (clone === null) {
15584              break;
15585            }
15586          }
15587          if (clone) {
15588            if (lastClone) {
15589              clone.appendChild(lastClone);
15590            }
15591            if (!firstClone) {
15592              firstClone = clone;
15593            }
15594            lastClone = clone;
15595          }
15596        }
15597        if (split && (!format.mixed || !dom.isBlock(formatRoot))) {
15598          container = dom.split(formatRoot, container);
15599        }
15600        if (lastClone) {
15601          target.parentNode.insertBefore(lastClone, target);
15602          firstClone.appendChild(target);
15603          if (isInlineFormat(format)) {
15604            mergeSiblings(dom, format, vars, lastClone);
15605          }
15606        }
15607      }
15608      return container;
15609    };
15610    var remove$1 = function (ed, name, vars, node, similar) {
15611      var formatList = ed.formatter.get(name);
15612      var format = formatList[0];
15613      var contentEditable = true;
15614      var dom = ed.dom;
15615      var selection = ed.selection;
15616      var splitToFormatRoot = function (container) {
15617        var formatRoot = findFormatRoot(ed, container, name, vars, similar);
15618        return wrapAndSplit(ed, formatList, formatRoot, container, container, true, format, vars);
15619      };
15620      var isRemoveBookmarkNode = function (node) {
15621        return isBookmarkNode$1(node) && isElement$5(node) && (node.id === '_start' || node.id === '_end');
15622      };
15623      var removeNodeFormat = function (node) {
15624        return exists(formatList, function (fmt) {
15625          return removeFormat$1(ed, fmt, vars, node, node);
15626        });
15627      };
15628      var process = function (node) {
15629        var lastContentEditable = true;
15630        var hasContentEditableState = false;
15631        if (isElement$5(node) && dom.getContentEditable(node)) {
15632          lastContentEditable = contentEditable;
15633          contentEditable = dom.getContentEditable(node) === 'true';
15634          hasContentEditableState = true;
15635        }
15636        var children = from(node.childNodes);
15637        if (contentEditable && !hasContentEditableState) {
15638          var removed = removeNodeFormat(node);
15639          var currentNodeMatches = removed || exists(formatList, function (f) {
15640            return matchName$1(dom, node, f);
15641          });
15642          var parentNode = node.parentNode;
15643          if (!currentNodeMatches && isNonNullable(parentNode) && shouldExpandToSelector(format)) {
15644            removeNodeFormat(parentNode);
15645          }
15646        }
15647        if (format.deep) {
15648          if (children.length) {
15649            for (var i = 0; i < children.length; i++) {
15650              process(children[i]);
15651            }
15652            if (hasContentEditableState) {
15653              contentEditable = lastContentEditable;
15654            }
15655          }
15656        }
15657        var textDecorations = [
15658          'underline',
15659          'line-through',
15660          'overline'
15661        ];
15662        each$k(textDecorations, function (decoration) {
15663          if (isElement$5(node) && ed.dom.getStyle(node, 'text-decoration') === decoration && node.parentNode && getTextDecoration(dom, node.parentNode) === decoration) {
15664            removeFormat$1(ed, {
15665              deep: false,
15666              exact: true,
15667              inline: 'span',
15668              styles: { textDecoration: decoration }
15669            }, null, node);
15670          }
15671        });
15672      };
15673      var unwrap = function (start) {
15674        var node = dom.get(start ? '_start' : '_end');
15675        var out = node[start ? 'firstChild' : 'lastChild'];
15676        if (isRemoveBookmarkNode(out)) {
15677          out = out[start ? 'firstChild' : 'lastChild'];
15678        }
15679        if (isText$7(out) && out.data.length === 0) {
15680          out = start ? node.previousSibling || node.nextSibling : node.nextSibling || node.previousSibling;
15681        }
15682        dom.remove(node, true);
15683        return out;
15684      };
15685      var removeRngStyle = function (rng) {
15686        var startContainer, endContainer;
15687        var expandedRng = expandRng(ed, rng, formatList, rng.collapsed);
15688        if (format.split) {
15689          expandedRng = split(expandedRng);
15690          startContainer = getContainer(ed, expandedRng, true);
15691          endContainer = getContainer(ed, expandedRng);
15692          if (startContainer !== endContainer) {
15693            startContainer = normalizeTableSelection(startContainer, true);
15694            endContainer = normalizeTableSelection(endContainer, false);
15695            if (isChildOfInlineParent(dom, startContainer, endContainer)) {
15696              var marker = Optional.from(startContainer.firstChild).getOr(startContainer);
15697              splitToFormatRoot(wrapWithSiblings(dom, marker, true, 'span', {
15698                'id': '_start',
15699                'data-mce-type': 'bookmark'
15700              }));
15701              unwrap(true);
15702              return;
15703            }
15704            if (isChildOfInlineParent(dom, endContainer, startContainer)) {
15705              var marker = Optional.from(endContainer.lastChild).getOr(endContainer);
15706              splitToFormatRoot(wrapWithSiblings(dom, marker, false, 'span', {
15707                'id': '_end',
15708                'data-mce-type': 'bookmark'
15709              }));
15710              unwrap(false);
15711              return;
15712            }
15713            startContainer = wrap$1(dom, startContainer, 'span', {
15714              'id': '_start',
15715              'data-mce-type': 'bookmark'
15716            });
15717            endContainer = wrap$1(dom, endContainer, 'span', {
15718              'id': '_end',
15719              'data-mce-type': 'bookmark'
15720            });
15721            var newRng = dom.createRng();
15722            newRng.setStartAfter(startContainer);
15723            newRng.setEndBefore(endContainer);
15724            walk$2(dom, newRng, function (nodes) {
15725              each$k(nodes, function (n) {
15726                if (!isBookmarkNode$1(n) && !isBookmarkNode$1(n.parentNode)) {
15727                  splitToFormatRoot(n);
15728                }
15729              });
15730            });
15731            splitToFormatRoot(startContainer);
15732            splitToFormatRoot(endContainer);
15733            startContainer = unwrap(true);
15734            endContainer = unwrap();
15735          } else {
15736            startContainer = endContainer = splitToFormatRoot(startContainer);
15737          }
15738          expandedRng.startContainer = startContainer.parentNode ? startContainer.parentNode : startContainer;
15739          expandedRng.startOffset = dom.nodeIndex(startContainer);
15740          expandedRng.endContainer = endContainer.parentNode ? endContainer.parentNode : endContainer;
15741          expandedRng.endOffset = dom.nodeIndex(endContainer) + 1;
15742        }
15743        walk$2(dom, expandedRng, function (nodes) {
15744          each$k(nodes, process);
15745        });
15746      };
15747      if (node) {
15748        if (isNode(node)) {
15749          var rng = dom.createRng();
15750          rng.setStartBefore(node);
15751          rng.setEndAfter(node);
15752          removeRngStyle(rng);
15753        } else {
15754          removeRngStyle(node);
15755        }
15756        fireFormatRemove(ed, name, node, vars);
15757        return;
15758      }
15759      if (dom.getContentEditable(selection.getNode()) === 'false') {
15760        node = selection.getNode();
15761        for (var i = 0; i < formatList.length; i++) {
15762          if (formatList[i].ceFalseOverride) {
15763            if (removeFormat$1(ed, formatList[i], vars, node, node)) {
15764              break;
15765            }
15766          }
15767        }
15768        fireFormatRemove(ed, name, node, vars);
15769        return;
15770      }
15771      if (!selection.isCollapsed() || !isInlineFormat(format) || getCellsFromEditor(ed).length) {
15772        preserve(selection, true, function () {
15773          runOnRanges(ed, removeRngStyle);
15774        });
15775        if (isInlineFormat(format) && match$2(ed, name, vars, selection.getStart())) {
15776          moveStart(dom, selection, selection.getRng());
15777        }
15778        ed.nodeChanged();
15779      } else {
15780        removeCaretFormat(ed, name, vars, similar);
15781      }
15782      fireFormatRemove(ed, name, node, vars);
15783    };
15784
15785    var each$9 = Tools.each;
15786    var mergeTextDecorationsAndColor = function (dom, format, vars, node) {
15787      var processTextDecorationsAndColor = function (n) {
15788        if (n.nodeType === 1 && n.parentNode && n.parentNode.nodeType === 1) {
15789          var textDecoration = getTextDecoration(dom, n.parentNode);
15790          if (dom.getStyle(n, 'color') && textDecoration) {
15791            dom.setStyle(n, 'text-decoration', textDecoration);
15792          } else if (dom.getStyle(n, 'text-decoration') === textDecoration) {
15793            dom.setStyle(n, 'text-decoration', null);
15794          }
15795        }
15796      };
15797      if (format.styles && (format.styles.color || format.styles.textDecoration)) {
15798        Tools.walk(node, processTextDecorationsAndColor, 'childNodes');
15799        processTextDecorationsAndColor(node);
15800      }
15801    };
15802    var mergeBackgroundColorAndFontSize = function (dom, format, vars, node) {
15803      if (format.styles && format.styles.backgroundColor) {
15804        processChildElements(node, hasStyle(dom, 'fontSize'), applyStyle(dom, 'backgroundColor', replaceVars(format.styles.backgroundColor, vars)));
15805      }
15806    };
15807    var mergeSubSup = function (dom, format, vars, node) {
15808      if (isInlineFormat(format) && (format.inline === 'sub' || format.inline === 'sup')) {
15809        processChildElements(node, hasStyle(dom, 'fontSize'), applyStyle(dom, 'fontSize', ''));
15810        dom.remove(dom.select(format.inline === 'sup' ? 'sub' : 'sup', node), true);
15811      }
15812    };
15813    var mergeWithChildren = function (editor, formatList, vars, node) {
15814      each$9(formatList, function (format) {
15815        if (isInlineFormat(format)) {
15816          each$9(editor.dom.select(format.inline, node), function (child) {
15817            if (!isElementNode$1(child)) {
15818              return;
15819            }
15820            removeFormat$1(editor, format, vars, child, format.exact ? child : null);
15821          });
15822        }
15823        clearChildStyles(editor.dom, format, node);
15824      });
15825    };
15826    var mergeWithParents = function (editor, format, name, vars, node) {
15827      if (matchNode(editor, node.parentNode, name, vars)) {
15828        if (removeFormat$1(editor, format, vars, node)) {
15829          return;
15830        }
15831      }
15832      if (format.merge_with_parents) {
15833        editor.dom.getParent(node.parentNode, function (parent) {
15834          if (matchNode(editor, parent, name, vars)) {
15835            removeFormat$1(editor, format, vars, node);
15836            return true;
15837          }
15838        });
15839      }
15840    };
15841
15842    var each$8 = Tools.each;
15843    var isElementNode = function (node) {
15844      return isElement$5(node) && !isBookmarkNode$1(node) && !isCaretNode(node) && !isBogus$2(node);
15845    };
15846    var canFormatBR = function (editor, format, node, parentName) {
15847      if (canFormatEmptyLines(editor) && isInlineFormat(format)) {
15848        var validBRParentElements = getTextRootBlockElements(editor.schema);
15849        var hasCaretNodeSibling = sibling(SugarElement.fromDom(node), function (sibling) {
15850          return isCaretNode(sibling.dom);
15851        });
15852        return hasNonNullableKey(validBRParentElements, parentName) && isEmpty$2(SugarElement.fromDom(node.parentNode), false) && !hasCaretNodeSibling;
15853      } else {
15854        return false;
15855      }
15856    };
15857    var applyFormat$1 = function (ed, name, vars, node) {
15858      var formatList = ed.formatter.get(name);
15859      var format = formatList[0];
15860      var isCollapsed = !node && ed.selection.isCollapsed();
15861      var dom = ed.dom;
15862      var selection = ed.selection;
15863      var setElementFormat = function (elm, fmt) {
15864        if (fmt === void 0) {
15865          fmt = format;
15866        }
15867        if (isFunction(fmt.onformat)) {
15868          fmt.onformat(elm, fmt, vars, node);
15869        }
15870        each$8(fmt.styles, function (value, name) {
15871          dom.setStyle(elm, name, replaceVars(value, vars));
15872        });
15873        if (fmt.styles) {
15874          var styleVal = dom.getAttrib(elm, 'style');
15875          if (styleVal) {
15876            dom.setAttrib(elm, 'data-mce-style', styleVal);
15877          }
15878        }
15879        each$8(fmt.attributes, function (value, name) {
15880          dom.setAttrib(elm, name, replaceVars(value, vars));
15881        });
15882        each$8(fmt.classes, function (value) {
15883          value = replaceVars(value, vars);
15884          if (!dom.hasClass(elm, value)) {
15885            dom.addClass(elm, value);
15886          }
15887        });
15888      };
15889      var applyNodeStyle = function (formatList, node) {
15890        var found = false;
15891        each$8(formatList, function (format) {
15892          if (!isSelectorFormat(format)) {
15893            return false;
15894          }
15895          if (isNonNullable(format.collapsed) && format.collapsed !== isCollapsed) {
15896            return;
15897          }
15898          if (dom.is(node, format.selector) && !isCaretNode(node)) {
15899            setElementFormat(node, format);
15900            found = true;
15901            return false;
15902          }
15903        });
15904        return found;
15905      };
15906      var createWrapElement = function (wrapName) {
15907        if (isString$1(wrapName)) {
15908          var wrapElm = dom.create(wrapName);
15909          setElementFormat(wrapElm);
15910          return wrapElm;
15911        } else {
15912          return null;
15913        }
15914      };
15915      var applyRngStyle = function (dom, rng, nodeSpecific) {
15916        var newWrappers = [];
15917        var contentEditable = true;
15918        var wrapName = format.inline || format.block;
15919        var wrapElm = createWrapElement(wrapName);
15920        walk$2(dom, rng, function (nodes) {
15921          var currentWrapElm;
15922          var process = function (node) {
15923            var hasContentEditableState = false;
15924            var lastContentEditable = contentEditable;
15925            var nodeName = node.nodeName.toLowerCase();
15926            var parentNode = node.parentNode;
15927            var parentName = parentNode.nodeName.toLowerCase();
15928            if (isElement$5(node) && dom.getContentEditable(node)) {
15929              lastContentEditable = contentEditable;
15930              contentEditable = dom.getContentEditable(node) === 'true';
15931              hasContentEditableState = true;
15932            }
15933            if (isBr$5(node) && !canFormatBR(ed, format, node, parentName)) {
15934              currentWrapElm = null;
15935              if (isBlockFormat(format)) {
15936                dom.remove(node);
15937              }
15938              return;
15939            }
15940            if (isBlockFormat(format) && format.wrapper && matchNode(ed, node, name, vars)) {
15941              currentWrapElm = null;
15942              return;
15943            }
15944            if (contentEditable && !hasContentEditableState && isBlockFormat(format) && !format.wrapper && isTextBlock$1(ed, nodeName) && isValid(ed, parentName, wrapName)) {
15945              var elm = dom.rename(node, wrapName);
15946              setElementFormat(elm);
15947              newWrappers.push(elm);
15948              currentWrapElm = null;
15949              return;
15950            }
15951            if (isSelectorFormat(format)) {
15952              var found = applyNodeStyle(formatList, node);
15953              if (!found && isNonNullable(parentNode) && shouldExpandToSelector(format)) {
15954                found = applyNodeStyle(formatList, parentNode);
15955              }
15956              if (!isInlineFormat(format) || found) {
15957                currentWrapElm = null;
15958                return;
15959              }
15960            }
15961            if (contentEditable && !hasContentEditableState && isValid(ed, wrapName, nodeName) && isValid(ed, parentName, wrapName) && !(!nodeSpecific && isText$7(node) && isZwsp(node.data)) && !isCaretNode(node) && (!isInlineFormat(format) || !dom.isBlock(node))) {
15962              if (!currentWrapElm) {
15963                currentWrapElm = dom.clone(wrapElm, false);
15964                node.parentNode.insertBefore(currentWrapElm, node);
15965                newWrappers.push(currentWrapElm);
15966              }
15967              currentWrapElm.appendChild(node);
15968            } else {
15969              currentWrapElm = null;
15970              each$k(from(node.childNodes), process);
15971              if (hasContentEditableState) {
15972                contentEditable = lastContentEditable;
15973              }
15974              currentWrapElm = null;
15975            }
15976          };
15977          each$k(nodes, process);
15978        });
15979        if (format.links === true) {
15980          each$k(newWrappers, function (node) {
15981            var process = function (node) {
15982              if (node.nodeName === 'A') {
15983                setElementFormat(node, format);
15984              }
15985              each$k(from(node.childNodes), process);
15986            };
15987            process(node);
15988          });
15989        }
15990        each$k(newWrappers, function (node) {
15991          var getChildCount = function (node) {
15992            var count = 0;
15993            each$k(node.childNodes, function (node) {
15994              if (!isEmptyTextNode$1(node) && !isBookmarkNode$1(node)) {
15995                count++;
15996              }
15997            });
15998            return count;
15999          };
16000          var mergeStyles = function (node) {
16001            var childElement = find$3(node.childNodes, isElementNode).filter(function (child) {
16002              return matchName$1(dom, child, format);
16003            });
16004            return childElement.map(function (child) {
16005              var clone = dom.clone(child, false);
16006              setElementFormat(clone);
16007              dom.replace(clone, node, true);
16008              dom.remove(child, true);
16009              return clone;
16010            }).getOr(node);
16011          };
16012          var childCount = getChildCount(node);
16013          if ((newWrappers.length > 1 || !dom.isBlock(node)) && childCount === 0) {
16014            dom.remove(node, true);
16015            return;
16016          }
16017          if (isInlineFormat(format) || isBlockFormat(format) && format.wrapper) {
16018            if (!format.exact && childCount === 1) {
16019              node = mergeStyles(node);
16020            }
16021            mergeWithChildren(ed, formatList, vars, node);
16022            mergeWithParents(ed, format, name, vars, node);
16023            mergeBackgroundColorAndFontSize(dom, format, vars, node);
16024            mergeTextDecorationsAndColor(dom, format, vars, node);
16025            mergeSubSup(dom, format, vars, node);
16026            mergeSiblings(dom, format, vars, node);
16027          }
16028        });
16029      };
16030      if (dom.getContentEditable(selection.getNode()) === 'false') {
16031        node = selection.getNode();
16032        for (var i = 0, l = formatList.length; i < l; i++) {
16033          var formatItem = formatList[i];
16034          if (formatItem.ceFalseOverride && isSelectorFormat(formatItem) && dom.is(node, formatItem.selector)) {
16035            setElementFormat(node, formatItem);
16036            break;
16037          }
16038        }
16039        fireFormatApply(ed, name, node, vars);
16040        return;
16041      }
16042      if (format) {
16043        if (node) {
16044          if (isNode(node)) {
16045            if (!applyNodeStyle(formatList, node)) {
16046              var rng = dom.createRng();
16047              rng.setStartBefore(node);
16048              rng.setEndAfter(node);
16049              applyRngStyle(dom, expandRng(ed, rng, formatList), true);
16050            }
16051          } else {
16052            applyRngStyle(dom, node, true);
16053          }
16054        } else {
16055          if (!isCollapsed || !isInlineFormat(format) || getCellsFromEditor(ed).length) {
16056            var curSelNode = selection.getNode();
16057            var firstFormat = formatList[0];
16058            if (!ed.settings.forced_root_block && firstFormat.defaultBlock && !dom.getParent(curSelNode, dom.isBlock)) {
16059              applyFormat$1(ed, firstFormat.defaultBlock);
16060            }
16061            selection.setRng(normalize(selection.getRng()));
16062            preserve(selection, true, function () {
16063              runOnRanges(ed, function (selectionRng, fake) {
16064                var expandedRng = fake ? selectionRng : expandRng(ed, selectionRng, formatList);
16065                applyRngStyle(dom, expandedRng, false);
16066              });
16067            });
16068            moveStart(dom, selection, selection.getRng());
16069            ed.nodeChanged();
16070          } else {
16071            applyCaretFormat(ed, name, vars);
16072          }
16073        }
16074        postProcess$1(name, ed);
16075      }
16076      fireFormatApply(ed, name, node, vars);
16077    };
16078
16079    var hasVars = function (value) {
16080      return has$2(value, 'vars');
16081    };
16082    var setup$j = function (registeredFormatListeners, editor) {
16083      registeredFormatListeners.set({});
16084      editor.on('NodeChange', function (e) {
16085        updateAndFireChangeCallbacks(editor, e.element, registeredFormatListeners.get());
16086      });
16087      editor.on('FormatApply FormatRemove', function (e) {
16088        var element = Optional.from(e.node).map(function (nodeOrRange) {
16089          return isNode(nodeOrRange) ? nodeOrRange : nodeOrRange.startContainer;
16090        }).bind(function (node) {
16091          return isElement$5(node) ? Optional.some(node) : Optional.from(node.parentElement);
16092        }).getOrThunk(function () {
16093          return fallbackElement(editor);
16094        });
16095        updateAndFireChangeCallbacks(editor, element, registeredFormatListeners.get());
16096      });
16097    };
16098    var fallbackElement = function (editor) {
16099      return editor.selection.getStart();
16100    };
16101    var matchingNode = function (editor, parents, format, similar, vars) {
16102      var isMatchingNode = function (node) {
16103        var matchingFormat = editor.formatter.matchNode(node, format, vars !== null && vars !== void 0 ? vars : {}, similar);
16104        return !isUndefined(matchingFormat);
16105      };
16106      var isUnableToMatch = function (node) {
16107        if (matchesUnInheritedFormatSelector(editor, node, format)) {
16108          return true;
16109        } else {
16110          if (!similar) {
16111            return isNonNullable(editor.formatter.matchNode(node, format, vars, true));
16112          } else {
16113            return false;
16114          }
16115        }
16116      };
16117      return findUntil$1(parents, isMatchingNode, isUnableToMatch);
16118    };
16119    var getParents = function (editor, elm) {
16120      var element = elm !== null && elm !== void 0 ? elm : fallbackElement(editor);
16121      return filter$4(getParents$2(editor.dom, element), function (node) {
16122        return isElement$5(node) && !isBogus$2(node);
16123      });
16124    };
16125    var updateAndFireChangeCallbacks = function (editor, elm, registeredCallbacks) {
16126      var parents = getParents(editor, elm);
16127      each$j(registeredCallbacks, function (data, format) {
16128        var runIfChanged = function (spec) {
16129          var match = matchingNode(editor, parents, format, spec.similar, hasVars(spec) ? spec.vars : undefined);
16130          var isSet = match.isSome();
16131          if (spec.state.get() !== isSet) {
16132            spec.state.set(isSet);
16133            var node_1 = match.getOr(elm);
16134            if (hasVars(spec)) {
16135              spec.callback(isSet, {
16136                node: node_1,
16137                format: format,
16138                parents: parents
16139              });
16140            } else {
16141              each$k(spec.callbacks, function (callback) {
16142                return callback(isSet, {
16143                  node: node_1,
16144                  format: format,
16145                  parents: parents
16146                });
16147              });
16148            }
16149          }
16150        };
16151        each$k([
16152          data.withSimilar,
16153          data.withoutSimilar
16154        ], runIfChanged);
16155        each$k(data.withVars, runIfChanged);
16156      });
16157    };
16158    var addListeners = function (editor, registeredFormatListeners, formats, callback, similar, vars) {
16159      var formatChangeItems = registeredFormatListeners.get();
16160      each$k(formats.split(','), function (format) {
16161        var group = get$9(formatChangeItems, format).getOrThunk(function () {
16162          var base = {
16163            withSimilar: {
16164              state: Cell(false),
16165              similar: true,
16166              callbacks: []
16167            },
16168            withoutSimilar: {
16169              state: Cell(false),
16170              similar: false,
16171              callbacks: []
16172            },
16173            withVars: []
16174          };
16175          formatChangeItems[format] = base;
16176          return base;
16177        });
16178        var getCurrent = function () {
16179          var parents = getParents(editor);
16180          return matchingNode(editor, parents, format, similar, vars).isSome();
16181        };
16182        if (isUndefined(vars)) {
16183          var toAppendTo = similar ? group.withSimilar : group.withoutSimilar;
16184          toAppendTo.callbacks.push(callback);
16185          if (toAppendTo.callbacks.length === 1) {
16186            toAppendTo.state.set(getCurrent());
16187          }
16188        } else {
16189          group.withVars.push({
16190            state: Cell(getCurrent()),
16191            similar: similar,
16192            vars: vars,
16193            callback: callback
16194          });
16195        }
16196      });
16197      registeredFormatListeners.set(formatChangeItems);
16198    };
16199    var removeListeners = function (registeredFormatListeners, formats, callback) {
16200      var formatChangeItems = registeredFormatListeners.get();
16201      each$k(formats.split(','), function (format) {
16202        return get$9(formatChangeItems, format).each(function (group) {
16203          formatChangeItems[format] = {
16204            withSimilar: __assign(__assign({}, group.withSimilar), {
16205              callbacks: filter$4(group.withSimilar.callbacks, function (cb) {
16206                return cb !== callback;
16207              })
16208            }),
16209            withoutSimilar: __assign(__assign({}, group.withoutSimilar), {
16210              callbacks: filter$4(group.withoutSimilar.callbacks, function (cb) {
16211                return cb !== callback;
16212              })
16213            }),
16214            withVars: filter$4(group.withVars, function (item) {
16215              return item.callback !== callback;
16216            })
16217          };
16218        });
16219      });
16220      registeredFormatListeners.set(formatChangeItems);
16221    };
16222    var formatChangedInternal = function (editor, registeredFormatListeners, formats, callback, similar, vars) {
16223      if (registeredFormatListeners.get() === null) {
16224        setup$j(registeredFormatListeners, editor);
16225      }
16226      addListeners(editor, registeredFormatListeners, formats, callback, similar, vars);
16227      return {
16228        unbind: function () {
16229          return removeListeners(registeredFormatListeners, formats, callback);
16230        }
16231      };
16232    };
16233
16234    var toggle = function (editor, name, vars, node) {
16235      var fmt = editor.formatter.get(name);
16236      if (match$2(editor, name, vars, node) && (!('toggle' in fmt[0]) || fmt[0].toggle)) {
16237        remove$1(editor, name, vars, node);
16238      } else {
16239        applyFormat$1(editor, name, vars, node);
16240      }
16241    };
16242
16243    var fromElements = function (elements, scope) {
16244      var doc = scope || document;
16245      var fragment = doc.createDocumentFragment();
16246      each$k(elements, function (element) {
16247        fragment.appendChild(element.dom);
16248      });
16249      return SugarElement.fromDom(fragment);
16250    };
16251
16252    var tableModel = function (element, width, rows) {
16253      return {
16254        element: element,
16255        width: width,
16256        rows: rows
16257      };
16258    };
16259    var tableRow = function (element, cells) {
16260      return {
16261        element: element,
16262        cells: cells
16263      };
16264    };
16265    var cellPosition = function (x, y) {
16266      return {
16267        x: x,
16268        y: y
16269      };
16270    };
16271    var getSpan = function (td, key) {
16272      var value = parseInt(get$6(td, key), 10);
16273      return isNaN(value) ? 1 : value;
16274    };
16275    var fillout = function (table, x, y, tr, td) {
16276      var rowspan = getSpan(td, 'rowspan');
16277      var colspan = getSpan(td, 'colspan');
16278      var rows = table.rows;
16279      for (var y2 = y; y2 < y + rowspan; y2++) {
16280        if (!rows[y2]) {
16281          rows[y2] = tableRow(deep$1(tr), []);
16282        }
16283        for (var x2 = x; x2 < x + colspan; x2++) {
16284          var cells = rows[y2].cells;
16285          cells[x2] = y2 === y && x2 === x ? td : shallow(td);
16286        }
16287      }
16288    };
16289    var cellExists = function (table, x, y) {
16290      var rows = table.rows;
16291      var cells = rows[y] ? rows[y].cells : [];
16292      return !!cells[x];
16293    };
16294    var skipCellsX = function (table, x, y) {
16295      while (cellExists(table, x, y)) {
16296        x++;
16297      }
16298      return x;
16299    };
16300    var getWidth = function (rows) {
16301      return foldl(rows, function (acc, row) {
16302        return row.cells.length > acc ? row.cells.length : acc;
16303      }, 0);
16304    };
16305    var findElementPos = function (table, element) {
16306      var rows = table.rows;
16307      for (var y = 0; y < rows.length; y++) {
16308        var cells = rows[y].cells;
16309        for (var x = 0; x < cells.length; x++) {
16310          if (eq(cells[x], element)) {
16311            return Optional.some(cellPosition(x, y));
16312          }
16313        }
16314      }
16315      return Optional.none();
16316    };
16317    var extractRows = function (table, sx, sy, ex, ey) {
16318      var newRows = [];
16319      var rows = table.rows;
16320      for (var y = sy; y <= ey; y++) {
16321        var cells = rows[y].cells;
16322        var slice = sx < ex ? cells.slice(sx, ex + 1) : cells.slice(ex, sx + 1);
16323        newRows.push(tableRow(rows[y].element, slice));
16324      }
16325      return newRows;
16326    };
16327    var subTable = function (table, startPos, endPos) {
16328      var sx = startPos.x, sy = startPos.y;
16329      var ex = endPos.x, ey = endPos.y;
16330      var newRows = sy < ey ? extractRows(table, sx, sy, ex, ey) : extractRows(table, sx, ey, ex, sy);
16331      return tableModel(table.element, getWidth(newRows), newRows);
16332    };
16333    var createDomTable = function (table, rows) {
16334      var tableElement = shallow(table.element);
16335      var tableBody = SugarElement.fromTag('tbody');
16336      append(tableBody, rows);
16337      append$1(tableElement, tableBody);
16338      return tableElement;
16339    };
16340    var modelRowsToDomRows = function (table) {
16341      return map$3(table.rows, function (row) {
16342        var cells = map$3(row.cells, function (cell) {
16343          var td = deep$1(cell);
16344          remove$6(td, 'colspan');
16345          remove$6(td, 'rowspan');
16346          return td;
16347        });
16348        var tr = shallow(row.element);
16349        append(tr, cells);
16350        return tr;
16351      });
16352    };
16353    var fromDom = function (tableElm) {
16354      var table = tableModel(shallow(tableElm), 0, []);
16355      each$k(descendants(tableElm, 'tr'), function (tr, y) {
16356        each$k(descendants(tr, 'td,th'), function (td, x) {
16357          fillout(table, skipCellsX(table, x, y), y, tr, td);
16358        });
16359      });
16360      return tableModel(table.element, getWidth(table.rows), table.rows);
16361    };
16362    var toDom = function (table) {
16363      return createDomTable(table, modelRowsToDomRows(table));
16364    };
16365    var subsection = function (table, startElement, endElement) {
16366      return findElementPos(table, startElement).bind(function (startPos) {
16367        return findElementPos(table, endElement).map(function (endPos) {
16368          return subTable(table, startPos, endPos);
16369        });
16370      });
16371    };
16372
16373    var findParentListContainer = function (parents) {
16374      return find$3(parents, function (elm) {
16375        return name(elm) === 'ul' || name(elm) === 'ol';
16376      });
16377    };
16378    var getFullySelectedListWrappers = function (parents, rng) {
16379      return find$3(parents, function (elm) {
16380        return name(elm) === 'li' && hasAllContentsSelected(elm, rng);
16381      }).fold(constant([]), function (_li) {
16382        return findParentListContainer(parents).map(function (listCont) {
16383          var listElm = SugarElement.fromTag(name(listCont));
16384          var listStyles = filter$3(getAllRaw(listCont), function (_style, name) {
16385            return startsWith(name, 'list-style');
16386          });
16387          setAll(listElm, listStyles);
16388          return [
16389            SugarElement.fromTag('li'),
16390            listElm
16391          ];
16392        }).getOr([]);
16393      });
16394    };
16395    var wrap = function (innerElm, elms) {
16396      var wrapped = foldl(elms, function (acc, elm) {
16397        append$1(elm, acc);
16398        return elm;
16399      }, innerElm);
16400      return elms.length > 0 ? fromElements([wrapped]) : wrapped;
16401    };
16402    var directListWrappers = function (commonAnchorContainer) {
16403      if (isListItem(commonAnchorContainer)) {
16404        return parent(commonAnchorContainer).filter(isList).fold(constant([]), function (listElm) {
16405          return [
16406            commonAnchorContainer,
16407            listElm
16408          ];
16409        });
16410      } else {
16411        return isList(commonAnchorContainer) ? [commonAnchorContainer] : [];
16412      }
16413    };
16414    var getWrapElements = function (rootNode, rng) {
16415      var commonAnchorContainer = SugarElement.fromDom(rng.commonAncestorContainer);
16416      var parents = parentsAndSelf(commonAnchorContainer, rootNode);
16417      var wrapElements = filter$4(parents, function (elm) {
16418        return isInline$1(elm) || isHeading(elm);
16419      });
16420      var listWrappers = getFullySelectedListWrappers(parents, rng);
16421      var allWrappers = wrapElements.concat(listWrappers.length ? listWrappers : directListWrappers(commonAnchorContainer));
16422      return map$3(allWrappers, shallow);
16423    };
16424    var emptyFragment = function () {
16425      return fromElements([]);
16426    };
16427    var getFragmentFromRange = function (rootNode, rng) {
16428      return wrap(SugarElement.fromDom(rng.cloneContents()), getWrapElements(rootNode, rng));
16429    };
16430    var getParentTable = function (rootElm, cell) {
16431      return ancestor$2(cell, 'table', curry(eq, rootElm));
16432    };
16433    var getTableFragment = function (rootNode, selectedTableCells) {
16434      return getParentTable(rootNode, selectedTableCells[0]).bind(function (tableElm) {
16435        var firstCell = selectedTableCells[0];
16436        var lastCell = selectedTableCells[selectedTableCells.length - 1];
16437        var fullTableModel = fromDom(tableElm);
16438        return subsection(fullTableModel, firstCell, lastCell).map(function (sectionedTableModel) {
16439          return fromElements([toDom(sectionedTableModel)]);
16440        });
16441      }).getOrThunk(emptyFragment);
16442    };
16443    var getSelectionFragment = function (rootNode, ranges) {
16444      return ranges.length > 0 && ranges[0].collapsed ? emptyFragment() : getFragmentFromRange(rootNode, ranges[0]);
16445    };
16446    var read$3 = function (rootNode, ranges) {
16447      var selectedCells = getCellsFromElementOrRanges(ranges, rootNode);
16448      return selectedCells.length > 0 ? getTableFragment(rootNode, selectedCells) : getSelectionFragment(rootNode, ranges);
16449    };
16450
16451    var trimLeadingCollapsibleText = function (text) {
16452      return text.replace(/^[ \f\n\r\t\v]+/, '');
16453    };
16454    var isCollapsibleWhitespace = function (text, index) {
16455      return index >= 0 && index < text.length && isWhiteSpace(text.charAt(index));
16456    };
16457    var getInnerText = function (bin, shouldTrim) {
16458      var text = trim$3(bin.innerText);
16459      return shouldTrim ? trimLeadingCollapsibleText(text) : text;
16460    };
16461    var getContextNodeName = function (parentBlockOpt) {
16462      return parentBlockOpt.map(function (block) {
16463        return block.nodeName;
16464      }).getOr('div').toLowerCase();
16465    };
16466    var getTextContent = function (editor) {
16467      return Optional.from(editor.selection.getRng()).map(function (rng) {
16468        var parentBlockOpt = Optional.from(editor.dom.getParent(rng.commonAncestorContainer, editor.dom.isBlock));
16469        var body = editor.getBody();
16470        var contextNodeName = getContextNodeName(parentBlockOpt);
16471        var shouldTrimSpaces = Env.browser.isIE() && contextNodeName !== 'pre';
16472        var bin = editor.dom.add(body, contextNodeName, {
16473          'data-mce-bogus': 'all',
16474          'style': 'overflow: hidden; opacity: 0;'
16475        }, rng.cloneContents());
16476        var text = getInnerText(bin, shouldTrimSpaces);
16477        var nonRenderedText = trim$3(bin.textContent);
16478        editor.dom.remove(bin);
16479        if (isCollapsibleWhitespace(nonRenderedText, 0) || isCollapsibleWhitespace(nonRenderedText, nonRenderedText.length - 1)) {
16480          var parentBlock = parentBlockOpt.getOr(body);
16481          var parentBlockText = getInnerText(parentBlock, shouldTrimSpaces);
16482          var textIndex = parentBlockText.indexOf(text);
16483          if (textIndex === -1) {
16484            return text;
16485          } else {
16486            var hasProceedingSpace = isCollapsibleWhitespace(parentBlockText, textIndex - 1);
16487            var hasTrailingSpace = isCollapsibleWhitespace(parentBlockText, textIndex + text.length);
16488            return (hasProceedingSpace ? ' ' : '') + text + (hasTrailingSpace ? ' ' : '');
16489          }
16490        } else {
16491          return text;
16492        }
16493      }).getOr('');
16494    };
16495    var getSerializedContent = function (editor, args) {
16496      var rng = editor.selection.getRng(), tmpElm = editor.dom.create('body');
16497      var sel = editor.selection.getSel();
16498      var ranges = processRanges(editor, getRanges(sel));
16499      var fragment = args.contextual ? read$3(SugarElement.fromDom(editor.getBody()), ranges).dom : rng.cloneContents();
16500      if (fragment) {
16501        tmpElm.appendChild(fragment);
16502      }
16503      return editor.selection.serializer.serialize(tmpElm, args);
16504    };
16505    var setupArgs$1 = function (args, format) {
16506      return __assign(__assign({}, args), {
16507        format: format,
16508        get: true,
16509        selection: true
16510      });
16511    };
16512    var getSelectedContentInternal = function (editor, format, args) {
16513      if (args === void 0) {
16514        args = {};
16515      }
16516      var defaultedArgs = setupArgs$1(args, format);
16517      var updatedArgs = editor.fire('BeforeGetContent', defaultedArgs);
16518      if (updatedArgs.isDefaultPrevented()) {
16519        editor.fire('GetContent', updatedArgs);
16520        return updatedArgs.content;
16521      }
16522      if (updatedArgs.format === 'text') {
16523        return getTextContent(editor);
16524      } else {
16525        updatedArgs.getInner = true;
16526        var content = getSerializedContent(editor, updatedArgs);
16527        if (updatedArgs.format === 'tree') {
16528          return content;
16529        } else {
16530          updatedArgs.content = editor.selection.isCollapsed() ? '' : content;
16531          editor.fire('GetContent', updatedArgs);
16532          return updatedArgs.content;
16533        }
16534      }
16535    };
16536
16537    var KEEP = 0, INSERT = 1, DELETE = 2;
16538    var diff = function (left, right) {
16539      var size = left.length + right.length + 2;
16540      var vDown = new Array(size);
16541      var vUp = new Array(size);
16542      var snake = function (start, end, diag) {
16543        return {
16544          start: start,
16545          end: end,
16546          diag: diag
16547        };
16548      };
16549      var buildScript = function (start1, end1, start2, end2, script) {
16550        var middle = getMiddleSnake(start1, end1, start2, end2);
16551        if (middle === null || middle.start === end1 && middle.diag === end1 - end2 || middle.end === start1 && middle.diag === start1 - start2) {
16552          var i = start1;
16553          var j = start2;
16554          while (i < end1 || j < end2) {
16555            if (i < end1 && j < end2 && left[i] === right[j]) {
16556              script.push([
16557                KEEP,
16558                left[i]
16559              ]);
16560              ++i;
16561              ++j;
16562            } else {
16563              if (end1 - start1 > end2 - start2) {
16564                script.push([
16565                  DELETE,
16566                  left[i]
16567                ]);
16568                ++i;
16569              } else {
16570                script.push([
16571                  INSERT,
16572                  right[j]
16573                ]);
16574                ++j;
16575              }
16576            }
16577          }
16578        } else {
16579          buildScript(start1, middle.start, start2, middle.start - middle.diag, script);
16580          for (var i2 = middle.start; i2 < middle.end; ++i2) {
16581            script.push([
16582              KEEP,
16583              left[i2]
16584            ]);
16585          }
16586          buildScript(middle.end, end1, middle.end - middle.diag, end2, script);
16587        }
16588      };
16589      var buildSnake = function (start, diag, end1, end2) {
16590        var end = start;
16591        while (end - diag < end2 && end < end1 && left[end] === right[end - diag]) {
16592          ++end;
16593        }
16594        return snake(start, end, diag);
16595      };
16596      var getMiddleSnake = function (start1, end1, start2, end2) {
16597        var m = end1 - start1;
16598        var n = end2 - start2;
16599        if (m === 0 || n === 0) {
16600          return null;
16601        }
16602        var delta = m - n;
16603        var sum = n + m;
16604        var offset = (sum % 2 === 0 ? sum : sum + 1) / 2;
16605        vDown[1 + offset] = start1;
16606        vUp[1 + offset] = end1 + 1;
16607        var d, k, i, x, y;
16608        for (d = 0; d <= offset; ++d) {
16609          for (k = -d; k <= d; k += 2) {
16610            i = k + offset;
16611            if (k === -d || k !== d && vDown[i - 1] < vDown[i + 1]) {
16612              vDown[i] = vDown[i + 1];
16613            } else {
16614              vDown[i] = vDown[i - 1] + 1;
16615            }
16616            x = vDown[i];
16617            y = x - start1 + start2 - k;
16618            while (x < end1 && y < end2 && left[x] === right[y]) {
16619              vDown[i] = ++x;
16620              ++y;
16621            }
16622            if (delta % 2 !== 0 && delta - d <= k && k <= delta + d) {
16623              if (vUp[i - delta] <= vDown[i]) {
16624                return buildSnake(vUp[i - delta], k + start1 - start2, end1, end2);
16625              }
16626            }
16627          }
16628          for (k = delta - d; k <= delta + d; k += 2) {
16629            i = k + offset - delta;
16630            if (k === delta - d || k !== delta + d && vUp[i + 1] <= vUp[i - 1]) {
16631              vUp[i] = vUp[i + 1] - 1;
16632            } else {
16633              vUp[i] = vUp[i - 1];
16634            }
16635            x = vUp[i] - 1;
16636            y = x - start1 + start2 - k;
16637            while (x >= start1 && y >= start2 && left[x] === right[y]) {
16638              vUp[i] = x--;
16639              y--;
16640            }
16641            if (delta % 2 === 0 && -d <= k && k <= d) {
16642              if (vUp[i] <= vDown[i + delta]) {
16643                return buildSnake(vUp[i], k + start1 - start2, end1, end2);
16644              }
16645            }
16646          }
16647        }
16648      };
16649      var script = [];
16650      buildScript(0, left.length, 0, right.length, script);
16651      return script;
16652    };
16653
16654    var getOuterHtml = function (elm) {
16655      if (isElement$5(elm)) {
16656        return elm.outerHTML;
16657      } else if (isText$7(elm)) {
16658        return Entities.encodeRaw(elm.data, false);
16659      } else if (isComment(elm)) {
16660        return '<!--' + elm.data + '-->';
16661      }
16662      return '';
16663    };
16664    var createFragment = function (html) {
16665      var node;
16666      var container = document.createElement('div');
16667      var frag = document.createDocumentFragment();
16668      if (html) {
16669        container.innerHTML = html;
16670      }
16671      while (node = container.firstChild) {
16672        frag.appendChild(node);
16673      }
16674      return frag;
16675    };
16676    var insertAt = function (elm, html, index) {
16677      var fragment = createFragment(html);
16678      if (elm.hasChildNodes() && index < elm.childNodes.length) {
16679        var target = elm.childNodes[index];
16680        target.parentNode.insertBefore(fragment, target);
16681      } else {
16682        elm.appendChild(fragment);
16683      }
16684    };
16685    var removeAt = function (elm, index) {
16686      if (elm.hasChildNodes() && index < elm.childNodes.length) {
16687        var target = elm.childNodes[index];
16688        target.parentNode.removeChild(target);
16689      }
16690    };
16691    var applyDiff = function (diff, elm) {
16692      var index = 0;
16693      each$k(diff, function (action) {
16694        if (action[0] === KEEP) {
16695          index++;
16696        } else if (action[0] === INSERT) {
16697          insertAt(elm, action[1], index);
16698          index++;
16699        } else if (action[0] === DELETE) {
16700          removeAt(elm, index);
16701        }
16702      });
16703    };
16704    var read$2 = function (elm, trimZwsp) {
16705      return filter$4(map$3(from(elm.childNodes), trimZwsp ? compose(trim$3, getOuterHtml) : getOuterHtml), function (item) {
16706        return item.length > 0;
16707      });
16708    };
16709    var write = function (fragments, elm) {
16710      var currentFragments = map$3(from(elm.childNodes), getOuterHtml);
16711      applyDiff(diff(currentFragments, fragments), elm);
16712      return elm;
16713    };
16714
16715    var lazyTempDocument$1 = cached(function () {
16716      return document.implementation.createHTMLDocument('undo');
16717    });
16718    var hasIframes = function (body) {
16719      return body.querySelector('iframe') !== null;
16720    };
16721    var createFragmentedLevel = function (fragments) {
16722      return {
16723        type: 'fragmented',
16724        fragments: fragments,
16725        content: '',
16726        bookmark: null,
16727        beforeBookmark: null
16728      };
16729    };
16730    var createCompleteLevel = function (content) {
16731      return {
16732        type: 'complete',
16733        fragments: null,
16734        content: content,
16735        bookmark: null,
16736        beforeBookmark: null
16737      };
16738    };
16739    var createFromEditor = function (editor) {
16740      var tempAttrs = editor.serializer.getTempAttrs();
16741      var body = trim$1(editor.getBody(), tempAttrs);
16742      return hasIframes(body) ? createFragmentedLevel(read$2(body, true)) : createCompleteLevel(trim$3(body.innerHTML));
16743    };
16744    var applyToEditor = function (editor, level, before) {
16745      var bookmark = before ? level.beforeBookmark : level.bookmark;
16746      if (level.type === 'fragmented') {
16747        write(level.fragments, editor.getBody());
16748      } else {
16749        editor.setContent(level.content, {
16750          format: 'raw',
16751          no_selection: isNonNullable(bookmark) && isPathBookmark(bookmark) ? !bookmark.isFakeCaret : true
16752        });
16753      }
16754      editor.selection.moveToBookmark(bookmark);
16755    };
16756    var getLevelContent = function (level) {
16757      return level.type === 'fragmented' ? level.fragments.join('') : level.content;
16758    };
16759    var getCleanLevelContent = function (level) {
16760      var elm = SugarElement.fromTag('body', lazyTempDocument$1());
16761      set(elm, getLevelContent(level));
16762      each$k(descendants(elm, '*[data-mce-bogus]'), unwrap);
16763      return get$3(elm);
16764    };
16765    var hasEqualContent = function (level1, level2) {
16766      return getLevelContent(level1) === getLevelContent(level2);
16767    };
16768    var hasEqualCleanedContent = function (level1, level2) {
16769      return getCleanLevelContent(level1) === getCleanLevelContent(level2);
16770    };
16771    var isEq$1 = function (level1, level2) {
16772      if (!level1 || !level2) {
16773        return false;
16774      } else if (hasEqualContent(level1, level2)) {
16775        return true;
16776      } else {
16777        return hasEqualCleanedContent(level1, level2);
16778      }
16779    };
16780
16781    var isUnlocked = function (locks) {
16782      return locks.get() === 0;
16783    };
16784
16785    var setTyping = function (undoManager, typing, locks) {
16786      if (isUnlocked(locks)) {
16787        undoManager.typing = typing;
16788      }
16789    };
16790    var endTyping = function (undoManager, locks) {
16791      if (undoManager.typing) {
16792        setTyping(undoManager, false, locks);
16793        undoManager.add();
16794      }
16795    };
16796    var endTypingLevelIgnoreLocks = function (undoManager) {
16797      if (undoManager.typing) {
16798        undoManager.typing = false;
16799        undoManager.add();
16800      }
16801    };
16802
16803    var beforeChange$1 = function (editor, locks, beforeBookmark) {
16804      if (isUnlocked(locks)) {
16805        beforeBookmark.set(getUndoBookmark(editor.selection));
16806      }
16807    };
16808    var addUndoLevel$1 = function (editor, undoManager, index, locks, beforeBookmark, level, event) {
16809      var currentLevel = createFromEditor(editor);
16810      level = level || {};
16811      level = Tools.extend(level, currentLevel);
16812      if (isUnlocked(locks) === false || editor.removed) {
16813        return null;
16814      }
16815      var lastLevel = undoManager.data[index.get()];
16816      if (editor.fire('BeforeAddUndo', {
16817          level: level,
16818          lastLevel: lastLevel,
16819          originalEvent: event
16820        }).isDefaultPrevented()) {
16821        return null;
16822      }
16823      if (lastLevel && isEq$1(lastLevel, level)) {
16824        return null;
16825      }
16826      if (undoManager.data[index.get()]) {
16827        beforeBookmark.get().each(function (bm) {
16828          undoManager.data[index.get()].beforeBookmark = bm;
16829        });
16830      }
16831      var customUndoRedoLevels = getCustomUndoRedoLevels(editor);
16832      if (customUndoRedoLevels) {
16833        if (undoManager.data.length > customUndoRedoLevels) {
16834          for (var i = 0; i < undoManager.data.length - 1; i++) {
16835            undoManager.data[i] = undoManager.data[i + 1];
16836          }
16837          undoManager.data.length--;
16838          index.set(undoManager.data.length);
16839        }
16840      }
16841      level.bookmark = getUndoBookmark(editor.selection);
16842      if (index.get() < undoManager.data.length - 1) {
16843        undoManager.data.length = index.get() + 1;
16844      }
16845      undoManager.data.push(level);
16846      index.set(undoManager.data.length - 1);
16847      var args = {
16848        level: level,
16849        lastLevel: lastLevel,
16850        originalEvent: event
16851      };
16852      if (index.get() > 0) {
16853        editor.setDirty(true);
16854        editor.fire('AddUndo', args);
16855        editor.fire('change', args);
16856      } else {
16857        editor.fire('AddUndo', args);
16858      }
16859      return level;
16860    };
16861    var clear$1 = function (editor, undoManager, index) {
16862      undoManager.data = [];
16863      index.set(0);
16864      undoManager.typing = false;
16865      editor.fire('ClearUndos');
16866    };
16867    var extra$1 = function (editor, undoManager, index, callback1, callback2) {
16868      if (undoManager.transact(callback1)) {
16869        var bookmark = undoManager.data[index.get()].bookmark;
16870        var lastLevel = undoManager.data[index.get() - 1];
16871        applyToEditor(editor, lastLevel, true);
16872        if (undoManager.transact(callback2)) {
16873          undoManager.data[index.get() - 1].beforeBookmark = bookmark;
16874        }
16875      }
16876    };
16877    var redo$1 = function (editor, index, data) {
16878      var level;
16879      if (index.get() < data.length - 1) {
16880        index.set(index.get() + 1);
16881        level = data[index.get()];
16882        applyToEditor(editor, level, false);
16883        editor.setDirty(true);
16884        editor.fire('Redo', { level: level });
16885      }
16886      return level;
16887    };
16888    var undo$1 = function (editor, undoManager, locks, index) {
16889      var level;
16890      if (undoManager.typing) {
16891        undoManager.add();
16892        undoManager.typing = false;
16893        setTyping(undoManager, false, locks);
16894      }
16895      if (index.get() > 0) {
16896        index.set(index.get() - 1);
16897        level = undoManager.data[index.get()];
16898        applyToEditor(editor, level, true);
16899        editor.setDirty(true);
16900        editor.fire('Undo', { level: level });
16901      }
16902      return level;
16903    };
16904    var reset$1 = function (undoManager) {
16905      undoManager.clear();
16906      undoManager.add();
16907    };
16908    var hasUndo$1 = function (editor, undoManager, index) {
16909      return index.get() > 0 || undoManager.typing && undoManager.data[0] && !isEq$1(createFromEditor(editor), undoManager.data[0]);
16910    };
16911    var hasRedo$1 = function (undoManager, index) {
16912      return index.get() < undoManager.data.length - 1 && !undoManager.typing;
16913    };
16914    var transact$1 = function (undoManager, locks, callback) {
16915      endTyping(undoManager, locks);
16916      undoManager.beforeChange();
16917      undoManager.ignore(callback);
16918      return undoManager.add();
16919    };
16920    var ignore$1 = function (locks, callback) {
16921      try {
16922        locks.set(locks.get() + 1);
16923        callback();
16924      } finally {
16925        locks.set(locks.get() - 1);
16926      }
16927    };
16928
16929    var addVisualInternal = function (editor, elm) {
16930      var dom = editor.dom;
16931      var scope = isNonNullable(elm) ? elm : editor.getBody();
16932      if (isUndefined(editor.hasVisual)) {
16933        editor.hasVisual = isVisualAidsEnabled(editor);
16934      }
16935      each$k(dom.select('table,a', scope), function (matchedElm) {
16936        switch (matchedElm.nodeName) {
16937        case 'TABLE':
16938          var cls = getVisualAidsTableClass(editor);
16939          var value = dom.getAttrib(matchedElm, 'border');
16940          if ((!value || value === '0') && editor.hasVisual) {
16941            dom.addClass(matchedElm, cls);
16942          } else {
16943            dom.removeClass(matchedElm, cls);
16944          }
16945          break;
16946        case 'A':
16947          if (!dom.getAttrib(matchedElm, 'href')) {
16948            var value_1 = dom.getAttrib(matchedElm, 'name') || matchedElm.id;
16949            var cls_1 = getVisualAidsAnchorClass(editor);
16950            if (value_1 && editor.hasVisual) {
16951              dom.addClass(matchedElm, cls_1);
16952            } else {
16953              dom.removeClass(matchedElm, cls_1);
16954            }
16955          }
16956          break;
16957        }
16958      });
16959      editor.fire('VisualAid', {
16960        element: elm,
16961        hasVisual: editor.hasVisual
16962      });
16963    };
16964
16965    var makePlainAdaptor = function (editor) {
16966      return {
16967        undoManager: {
16968          beforeChange: function (locks, beforeBookmark) {
16969            return beforeChange$1(editor, locks, beforeBookmark);
16970          },
16971          add: function (undoManager, index, locks, beforeBookmark, level, event) {
16972            return addUndoLevel$1(editor, undoManager, index, locks, beforeBookmark, level, event);
16973          },
16974          undo: function (undoManager, locks, index) {
16975            return undo$1(editor, undoManager, locks, index);
16976          },
16977          redo: function (index, data) {
16978            return redo$1(editor, index, data);
16979          },
16980          clear: function (undoManager, index) {
16981            return clear$1(editor, undoManager, index);
16982          },
16983          reset: function (undoManager) {
16984            return reset$1(undoManager);
16985          },
16986          hasUndo: function (undoManager, index) {
16987            return hasUndo$1(editor, undoManager, index);
16988          },
16989          hasRedo: function (undoManager, index) {
16990            return hasRedo$1(undoManager, index);
16991          },
16992          transact: function (undoManager, locks, callback) {
16993            return transact$1(undoManager, locks, callback);
16994          },
16995          ignore: function (locks, callback) {
16996            return ignore$1(locks, callback);
16997          },
16998          extra: function (undoManager, index, callback1, callback2) {
16999            return extra$1(editor, undoManager, index, callback1, callback2);
17000          }
17001        },
17002        formatter: {
17003          match: function (name, vars, node, similar) {
17004            return match$2(editor, name, vars, node, similar);
17005          },
17006          matchAll: function (names, vars) {
17007            return matchAll(editor, names, vars);
17008          },
17009          matchNode: function (node, name, vars, similar) {
17010            return matchNode(editor, node, name, vars, similar);
17011          },
17012          canApply: function (name) {
17013            return canApply(editor, name);
17014          },
17015          closest: function (names) {
17016            return closest(editor, names);
17017          },
17018          apply: function (name, vars, node) {
17019            return applyFormat$1(editor, name, vars, node);
17020          },
17021          remove: function (name, vars, node, similar) {
17022            return remove$1(editor, name, vars, node, similar);
17023          },
17024          toggle: function (name, vars, node) {
17025            return toggle(editor, name, vars, node);
17026          },
17027          formatChanged: function (registeredFormatListeners, formats, callback, similar, vars) {
17028            return formatChangedInternal(editor, registeredFormatListeners, formats, callback, similar, vars);
17029          }
17030        },
17031        editor: {
17032          getContent: function (args, format) {
17033            return getContentInternal(editor, args, format);
17034          },
17035          setContent: function (content, args) {
17036            return setContentInternal(editor, content, args);
17037          },
17038          insertContent: function (value, details) {
17039            return insertHtmlAtCaret(editor, value, details);
17040          },
17041          addVisual: function (elm) {
17042            return addVisualInternal(editor, elm);
17043          }
17044        },
17045        selection: {
17046          getContent: function (format, args) {
17047            return getSelectedContentInternal(editor, format, args);
17048          }
17049        },
17050        raw: {
17051          getModel: function () {
17052            return Optional.none();
17053          }
17054        }
17055      };
17056    };
17057    var makeRtcAdaptor = function (rtcEditor) {
17058      var defaultVars = function (vars) {
17059        return isObject(vars) ? vars : {};
17060      };
17061      var undoManager = rtcEditor.undoManager, formatter = rtcEditor.formatter, editor = rtcEditor.editor, selection = rtcEditor.selection, raw = rtcEditor.raw;
17062      return {
17063        undoManager: {
17064          beforeChange: undoManager.beforeChange,
17065          add: undoManager.add,
17066          undo: undoManager.undo,
17067          redo: undoManager.redo,
17068          clear: undoManager.clear,
17069          reset: undoManager.reset,
17070          hasUndo: undoManager.hasUndo,
17071          hasRedo: undoManager.hasRedo,
17072          transact: function (_undoManager, _locks, fn) {
17073            return undoManager.transact(fn);
17074          },
17075          ignore: function (_locks, callback) {
17076            return undoManager.ignore(callback);
17077          },
17078          extra: function (_undoManager, _index, callback1, callback2) {
17079            return undoManager.extra(callback1, callback2);
17080          }
17081        },
17082        formatter: {
17083          match: function (name, vars, _node, similar) {
17084            return formatter.match(name, defaultVars(vars), similar);
17085          },
17086          matchAll: formatter.matchAll,
17087          matchNode: formatter.matchNode,
17088          canApply: function (name) {
17089            return formatter.canApply(name);
17090          },
17091          closest: function (names) {
17092            return formatter.closest(names);
17093          },
17094          apply: function (name, vars, _node) {
17095            return formatter.apply(name, defaultVars(vars));
17096          },
17097          remove: function (name, vars, _node, _similar) {
17098            return formatter.remove(name, defaultVars(vars));
17099          },
17100          toggle: function (name, vars, _node) {
17101            return formatter.toggle(name, defaultVars(vars));
17102          },
17103          formatChanged: function (_rfl, formats, callback, similar, vars) {
17104            return formatter.formatChanged(formats, callback, similar, vars);
17105          }
17106        },
17107        editor: {
17108          getContent: function (args, _format) {
17109            return editor.getContent(args);
17110          },
17111          setContent: function (content, args) {
17112            return editor.setContent(content, args);
17113          },
17114          insertContent: function (content, _details) {
17115            return editor.insertContent(content);
17116          },
17117          addVisual: editor.addVisual
17118        },
17119        selection: {
17120          getContent: function (_format, args) {
17121            return selection.getContent(args);
17122          }
17123        },
17124        raw: {
17125          getModel: function () {
17126            return Optional.some(raw.getRawModel());
17127          }
17128        }
17129      };
17130    };
17131    var makeNoopAdaptor = function () {
17132      var nul = constant(null);
17133      var empty = constant('');
17134      return {
17135        undoManager: {
17136          beforeChange: noop,
17137          add: nul,
17138          undo: nul,
17139          redo: nul,
17140          clear: noop,
17141          reset: noop,
17142          hasUndo: never,
17143          hasRedo: never,
17144          transact: nul,
17145          ignore: noop,
17146          extra: noop
17147        },
17148        formatter: {
17149          match: never,
17150          matchAll: constant([]),
17151          matchNode: constant(undefined),
17152          canApply: never,
17153          closest: empty,
17154          apply: noop,
17155          remove: noop,
17156          toggle: noop,
17157          formatChanged: constant({ unbind: noop })
17158        },
17159        editor: {
17160          getContent: empty,
17161          setContent: empty,
17162          insertContent: noop,
17163          addVisual: noop
17164        },
17165        selection: { getContent: empty },
17166        raw: { getModel: constant(Optional.none()) }
17167      };
17168    };
17169    var isRtc = function (editor) {
17170      return has$2(editor.plugins, 'rtc');
17171    };
17172    var getRtcSetup = function (editor) {
17173      return get$9(editor.plugins, 'rtc').bind(function (rtcPlugin) {
17174        return Optional.from(rtcPlugin.setup);
17175      });
17176    };
17177    var setup$i = function (editor) {
17178      var editorCast = editor;
17179      return getRtcSetup(editor).fold(function () {
17180        editorCast.rtcInstance = makePlainAdaptor(editor);
17181        return Optional.none();
17182      }, function (setup) {
17183        editorCast.rtcInstance = makeNoopAdaptor();
17184        return Optional.some(function () {
17185          return setup().then(function (rtcEditor) {
17186            editorCast.rtcInstance = makeRtcAdaptor(rtcEditor);
17187            return rtcEditor.rtc.isRemote;
17188          });
17189        });
17190      });
17191    };
17192    var getRtcInstanceWithFallback = function (editor) {
17193      return editor.rtcInstance ? editor.rtcInstance : makePlainAdaptor(editor);
17194    };
17195    var getRtcInstanceWithError = function (editor) {
17196      var rtcInstance = editor.rtcInstance;
17197      if (!rtcInstance) {
17198        throw new Error('Failed to get RTC instance not yet initialized.');
17199      } else {
17200        return rtcInstance;
17201      }
17202    };
17203    var beforeChange = function (editor, locks, beforeBookmark) {
17204      getRtcInstanceWithError(editor).undoManager.beforeChange(locks, beforeBookmark);
17205    };
17206    var addUndoLevel = function (editor, undoManager, index, locks, beforeBookmark, level, event) {
17207      return getRtcInstanceWithError(editor).undoManager.add(undoManager, index, locks, beforeBookmark, level, event);
17208    };
17209    var undo = function (editor, undoManager, locks, index) {
17210      return getRtcInstanceWithError(editor).undoManager.undo(undoManager, locks, index);
17211    };
17212    var redo = function (editor, index, data) {
17213      return getRtcInstanceWithError(editor).undoManager.redo(index, data);
17214    };
17215    var clear = function (editor, undoManager, index) {
17216      getRtcInstanceWithError(editor).undoManager.clear(undoManager, index);
17217    };
17218    var reset = function (editor, undoManager) {
17219      getRtcInstanceWithError(editor).undoManager.reset(undoManager);
17220    };
17221    var hasUndo = function (editor, undoManager, index) {
17222      return getRtcInstanceWithError(editor).undoManager.hasUndo(undoManager, index);
17223    };
17224    var hasRedo = function (editor, undoManager, index) {
17225      return getRtcInstanceWithError(editor).undoManager.hasRedo(undoManager, index);
17226    };
17227    var transact = function (editor, undoManager, locks, callback) {
17228      return getRtcInstanceWithError(editor).undoManager.transact(undoManager, locks, callback);
17229    };
17230    var ignore = function (editor, locks, callback) {
17231      getRtcInstanceWithError(editor).undoManager.ignore(locks, callback);
17232    };
17233    var extra = function (editor, undoManager, index, callback1, callback2) {
17234      getRtcInstanceWithError(editor).undoManager.extra(undoManager, index, callback1, callback2);
17235    };
17236    var matchFormat = function (editor, name, vars, node, similar) {
17237      return getRtcInstanceWithError(editor).formatter.match(name, vars, node, similar);
17238    };
17239    var matchAllFormats = function (editor, names, vars) {
17240      return getRtcInstanceWithError(editor).formatter.matchAll(names, vars);
17241    };
17242    var matchNodeFormat = function (editor, node, name, vars, similar) {
17243      return getRtcInstanceWithError(editor).formatter.matchNode(node, name, vars, similar);
17244    };
17245    var canApplyFormat = function (editor, name) {
17246      return getRtcInstanceWithError(editor).formatter.canApply(name);
17247    };
17248    var closestFormat = function (editor, names) {
17249      return getRtcInstanceWithError(editor).formatter.closest(names);
17250    };
17251    var applyFormat = function (editor, name, vars, node) {
17252      getRtcInstanceWithError(editor).formatter.apply(name, vars, node);
17253    };
17254    var removeFormat = function (editor, name, vars, node, similar) {
17255      getRtcInstanceWithError(editor).formatter.remove(name, vars, node, similar);
17256    };
17257    var toggleFormat = function (editor, name, vars, node) {
17258      getRtcInstanceWithError(editor).formatter.toggle(name, vars, node);
17259    };
17260    var formatChanged = function (editor, registeredFormatListeners, formats, callback, similar, vars) {
17261      return getRtcInstanceWithError(editor).formatter.formatChanged(registeredFormatListeners, formats, callback, similar, vars);
17262    };
17263    var getContent$2 = function (editor, args, format) {
17264      return getRtcInstanceWithFallback(editor).editor.getContent(args, format);
17265    };
17266    var setContent$2 = function (editor, content, args) {
17267      return getRtcInstanceWithFallback(editor).editor.setContent(content, args);
17268    };
17269    var insertContent = function (editor, value, details) {
17270      return getRtcInstanceWithFallback(editor).editor.insertContent(value, details);
17271    };
17272    var getSelectedContent = function (editor, format, args) {
17273      return getRtcInstanceWithError(editor).selection.getContent(format, args);
17274    };
17275    var addVisual$1 = function (editor, elm) {
17276      return getRtcInstanceWithError(editor).editor.addVisual(elm);
17277    };
17278
17279    var getContent$1 = function (editor, args) {
17280      if (args === void 0) {
17281        args = {};
17282      }
17283      var format = args.format ? args.format : 'html';
17284      return getSelectedContent(editor, format, args);
17285    };
17286
17287    var removeEmpty = function (text) {
17288      if (text.dom.length === 0) {
17289        remove$7(text);
17290        return Optional.none();
17291      } else {
17292        return Optional.some(text);
17293      }
17294    };
17295    var walkPastBookmark = function (node, start) {
17296      return node.filter(function (elm) {
17297        return BookmarkManager.isBookmarkNode(elm.dom);
17298      }).bind(start ? nextSibling : prevSibling);
17299    };
17300    var merge = function (outer, inner, rng, start) {
17301      var outerElm = outer.dom;
17302      var innerElm = inner.dom;
17303      var oldLength = start ? outerElm.length : innerElm.length;
17304      if (start) {
17305        mergeTextNodes(outerElm, innerElm, false, !start);
17306        rng.setStart(innerElm, oldLength);
17307      } else {
17308        mergeTextNodes(innerElm, outerElm, false, !start);
17309        rng.setEnd(innerElm, oldLength);
17310      }
17311    };
17312    var normalizeTextIfRequired = function (inner, start) {
17313      parent(inner).each(function (root) {
17314        var text = inner.dom;
17315        if (start && needsToBeNbspLeft(root, CaretPosition(text, 0))) {
17316          normalizeWhitespaceAfter(text, 0);
17317        } else if (!start && needsToBeNbspRight(root, CaretPosition(text, text.length))) {
17318          normalizeWhitespaceBefore(text, text.length);
17319        }
17320      });
17321    };
17322    var mergeAndNormalizeText = function (outerNode, innerNode, rng, start) {
17323      outerNode.bind(function (outer) {
17324        var normalizer = start ? normalizeWhitespaceBefore : normalizeWhitespaceAfter;
17325        normalizer(outer.dom, start ? outer.dom.length : 0);
17326        return innerNode.filter(isText$8).map(function (inner) {
17327          return merge(outer, inner, rng, start);
17328        });
17329      }).orThunk(function () {
17330        var innerTextNode = walkPastBookmark(innerNode, start).or(innerNode).filter(isText$8);
17331        return innerTextNode.map(function (inner) {
17332          return normalizeTextIfRequired(inner, start);
17333        });
17334      });
17335    };
17336    var rngSetContent = function (rng, fragment) {
17337      var firstChild = Optional.from(fragment.firstChild).map(SugarElement.fromDom);
17338      var lastChild = Optional.from(fragment.lastChild).map(SugarElement.fromDom);
17339      rng.deleteContents();
17340      rng.insertNode(fragment);
17341      var prevText = firstChild.bind(prevSibling).filter(isText$8).bind(removeEmpty);
17342      var nextText = lastChild.bind(nextSibling).filter(isText$8).bind(removeEmpty);
17343      mergeAndNormalizeText(prevText, firstChild, rng, true);
17344      mergeAndNormalizeText(nextText, lastChild, rng, false);
17345      rng.collapse(false);
17346    };
17347    var setupArgs = function (args, content) {
17348      return __assign(__assign({ format: 'html' }, args), {
17349        set: true,
17350        selection: true,
17351        content: content
17352      });
17353    };
17354    var cleanContent = function (editor, args) {
17355      if (args.format !== 'raw') {
17356        var rng = editor.selection.getRng();
17357        var contextBlock = editor.dom.getParent(rng.commonAncestorContainer, editor.dom.isBlock);
17358        var contextArgs = contextBlock ? { context: contextBlock.nodeName.toLowerCase() } : {};
17359        var node = editor.parser.parse(args.content, __assign(__assign({
17360          isRootContent: true,
17361          forced_root_block: false
17362        }, contextArgs), args));
17363        return HtmlSerializer({ validate: editor.validate }, editor.schema).serialize(node);
17364      } else {
17365        return args.content;
17366      }
17367    };
17368    var setContent$1 = function (editor, content, args) {
17369      if (args === void 0) {
17370        args = {};
17371      }
17372      var defaultedArgs = setupArgs(args, content);
17373      var updatedArgs = defaultedArgs;
17374      if (!defaultedArgs.no_events) {
17375        var eventArgs = editor.fire('BeforeSetContent', defaultedArgs);
17376        if (eventArgs.isDefaultPrevented()) {
17377          editor.fire('SetContent', eventArgs);
17378          return;
17379        } else {
17380          updatedArgs = eventArgs;
17381        }
17382      }
17383      updatedArgs.content = cleanContent(editor, updatedArgs);
17384      var rng = editor.selection.getRng();
17385      rngSetContent(rng, rng.createContextualFragment(updatedArgs.content));
17386      editor.selection.setRng(rng);
17387      scrollRangeIntoView(editor, rng);
17388      if (!updatedArgs.no_events) {
17389        editor.fire('SetContent', updatedArgs);
17390      }
17391    };
17392
17393    var deleteFromCallbackMap = function (callbackMap, selector, callback) {
17394      if (callbackMap && has$2(callbackMap, selector)) {
17395        var newCallbacks = filter$4(callbackMap[selector], function (cb) {
17396          return cb !== callback;
17397        });
17398        if (newCallbacks.length === 0) {
17399          delete callbackMap[selector];
17400        } else {
17401          callbackMap[selector] = newCallbacks;
17402        }
17403      }
17404    };
17405    function SelectorChanged (dom, editor) {
17406      var selectorChangedData;
17407      var currentSelectors;
17408      var findMatchingNode = function (selector, nodes) {
17409        return find$3(nodes, function (node) {
17410          return dom.is(node, selector);
17411        });
17412      };
17413      var getParents = function (elem) {
17414        return dom.getParents(elem, null, dom.getRoot());
17415      };
17416      return {
17417        selectorChangedWithUnbind: function (selector, callback) {
17418          if (!selectorChangedData) {
17419            selectorChangedData = {};
17420            currentSelectors = {};
17421            editor.on('NodeChange', function (e) {
17422              var node = e.element;
17423              var parents = getParents(node);
17424              var matchedSelectors = {};
17425              Tools.each(selectorChangedData, function (callbacks, selector) {
17426                findMatchingNode(selector, parents).each(function (node) {
17427                  if (!currentSelectors[selector]) {
17428                    each$k(callbacks, function (callback) {
17429                      callback(true, {
17430                        node: node,
17431                        selector: selector,
17432                        parents: parents
17433                      });
17434                    });
17435                    currentSelectors[selector] = callbacks;
17436                  }
17437                  matchedSelectors[selector] = callbacks;
17438                });
17439              });
17440              Tools.each(currentSelectors, function (callbacks, selector) {
17441                if (!matchedSelectors[selector]) {
17442                  delete currentSelectors[selector];
17443                  Tools.each(callbacks, function (callback) {
17444                    callback(false, {
17445                      node: node,
17446                      selector: selector,
17447                      parents: parents
17448                    });
17449                  });
17450                }
17451              });
17452            });
17453          }
17454          if (!selectorChangedData[selector]) {
17455            selectorChangedData[selector] = [];
17456          }
17457          selectorChangedData[selector].push(callback);
17458          findMatchingNode(selector, getParents(editor.selection.getStart())).each(function () {
17459            currentSelectors[selector] = selectorChangedData[selector];
17460          });
17461          return {
17462            unbind: function () {
17463              deleteFromCallbackMap(selectorChangedData, selector, callback);
17464              deleteFromCallbackMap(currentSelectors, selector, callback);
17465            }
17466          };
17467        }
17468      };
17469    }
17470
17471    var isNativeIeSelection = function (rng) {
17472      return !!rng.select;
17473    };
17474    var isAttachedToDom = function (node) {
17475      return !!(node && node.ownerDocument) && contains$1(SugarElement.fromDom(node.ownerDocument), SugarElement.fromDom(node));
17476    };
17477    var isValidRange = function (rng) {
17478      if (!rng) {
17479        return false;
17480      } else if (isNativeIeSelection(rng)) {
17481        return true;
17482      } else {
17483        return isAttachedToDom(rng.startContainer) && isAttachedToDom(rng.endContainer);
17484      }
17485    };
17486    var EditorSelection = function (dom, win, serializer, editor) {
17487      var selectedRange;
17488      var explicitRange;
17489      var selectorChangedWithUnbind = SelectorChanged(dom, editor).selectorChangedWithUnbind;
17490      var setCursorLocation = function (node, offset) {
17491        var rng = dom.createRng();
17492        if (isNonNullable(node) && isNonNullable(offset)) {
17493          rng.setStart(node, offset);
17494          rng.setEnd(node, offset);
17495          setRng(rng);
17496          collapse(false);
17497        } else {
17498          moveEndPoint(dom, rng, editor.getBody(), true);
17499          setRng(rng);
17500        }
17501      };
17502      var getContent = function (args) {
17503        return getContent$1(editor, args);
17504      };
17505      var setContent = function (content, args) {
17506        return setContent$1(editor, content, args);
17507      };
17508      var getStart$1 = function (real) {
17509        return getStart(editor.getBody(), getRng$1(), real);
17510      };
17511      var getEnd$1 = function (real) {
17512        return getEnd(editor.getBody(), getRng$1(), real);
17513      };
17514      var getBookmark = function (type, normalized) {
17515        return bookmarkManager.getBookmark(type, normalized);
17516      };
17517      var moveToBookmark = function (bookmark) {
17518        return bookmarkManager.moveToBookmark(bookmark);
17519      };
17520      var select$1 = function (node, content) {
17521        select(dom, node, content).each(setRng);
17522        return node;
17523      };
17524      var isCollapsed = function () {
17525        var rng = getRng$1(), sel = getSel();
17526        if (!rng || rng.item) {
17527          return false;
17528        }
17529        if (rng.compareEndPoints) {
17530          return rng.compareEndPoints('StartToEnd', rng) === 0;
17531        }
17532        return !sel || rng.collapsed;
17533      };
17534      var collapse = function (toStart) {
17535        var rng = getRng$1();
17536        rng.collapse(!!toStart);
17537        setRng(rng);
17538      };
17539      var getSel = function () {
17540        return win.getSelection ? win.getSelection() : win.document.selection;
17541      };
17542      var getRng$1 = function () {
17543        var selection, rng, elm;
17544        var tryCompareBoundaryPoints = function (how, sourceRange, destinationRange) {
17545          try {
17546            return sourceRange.compareBoundaryPoints(how, destinationRange);
17547          } catch (ex) {
17548            return -1;
17549          }
17550        };
17551        var doc = win.document;
17552        if (editor.bookmark !== undefined && hasFocus(editor) === false) {
17553          var bookmark = getRng(editor);
17554          if (bookmark.isSome()) {
17555            return bookmark.map(function (r) {
17556              return processRanges(editor, [r])[0];
17557            }).getOr(doc.createRange());
17558          }
17559        }
17560        try {
17561          if ((selection = getSel()) && !isRestrictedNode(selection.anchorNode)) {
17562            if (selection.rangeCount > 0) {
17563              rng = selection.getRangeAt(0);
17564            } else {
17565              rng = selection.createRange ? selection.createRange() : doc.createRange();
17566            }
17567            rng = processRanges(editor, [rng])[0];
17568          }
17569        } catch (ex) {
17570        }
17571        if (!rng) {
17572          rng = doc.createRange ? doc.createRange() : doc.body.createTextRange();
17573        }
17574        if (rng.setStart && rng.startContainer.nodeType === 9 && rng.collapsed) {
17575          elm = dom.getRoot();
17576          rng.setStart(elm, 0);
17577          rng.setEnd(elm, 0);
17578        }
17579        if (selectedRange && explicitRange) {
17580          if (tryCompareBoundaryPoints(rng.START_TO_START, rng, selectedRange) === 0 && tryCompareBoundaryPoints(rng.END_TO_END, rng, selectedRange) === 0) {
17581            rng = explicitRange;
17582          } else {
17583            selectedRange = null;
17584            explicitRange = null;
17585          }
17586        }
17587        return rng;
17588      };
17589      var setRng = function (rng, forward) {
17590        var node;
17591        if (!isValidRange(rng)) {
17592          return;
17593        }
17594        var ieRange = isNativeIeSelection(rng) ? rng : null;
17595        if (ieRange) {
17596          explicitRange = null;
17597          try {
17598            ieRange.select();
17599          } catch (ex) {
17600          }
17601          return;
17602        }
17603        var sel = getSel();
17604        var evt = editor.fire('SetSelectionRange', {
17605          range: rng,
17606          forward: forward
17607        });
17608        rng = evt.range;
17609        if (sel) {
17610          explicitRange = rng;
17611          try {
17612            sel.removeAllRanges();
17613            sel.addRange(rng);
17614          } catch (ex) {
17615          }
17616          if (forward === false && sel.extend) {
17617            sel.collapse(rng.endContainer, rng.endOffset);
17618            sel.extend(rng.startContainer, rng.startOffset);
17619          }
17620          selectedRange = sel.rangeCount > 0 ? sel.getRangeAt(0) : null;
17621        }
17622        if (!rng.collapsed && rng.startContainer === rng.endContainer && sel.setBaseAndExtent && !Env.ie) {
17623          if (rng.endOffset - rng.startOffset < 2) {
17624            if (rng.startContainer.hasChildNodes()) {
17625              node = rng.startContainer.childNodes[rng.startOffset];
17626              if (node && node.tagName === 'IMG') {
17627                sel.setBaseAndExtent(rng.startContainer, rng.startOffset, rng.endContainer, rng.endOffset);
17628                if (sel.anchorNode !== rng.startContainer || sel.focusNode !== rng.endContainer) {
17629                  sel.setBaseAndExtent(node, 0, node, 1);
17630                }
17631              }
17632            }
17633          }
17634        }
17635        editor.fire('AfterSetSelectionRange', {
17636          range: rng,
17637          forward: forward
17638        });
17639      };
17640      var setNode = function (elm) {
17641        setContent(dom.getOuterHTML(elm));
17642        return elm;
17643      };
17644      var getNode$1 = function () {
17645        return getNode(editor.getBody(), getRng$1());
17646      };
17647      var getSelectedBlocks$1 = function (startElm, endElm) {
17648        return getSelectedBlocks(dom, getRng$1(), startElm, endElm);
17649      };
17650      var isForward = function () {
17651        var sel = getSel();
17652        var anchorNode = sel === null || sel === void 0 ? void 0 : sel.anchorNode;
17653        var focusNode = sel === null || sel === void 0 ? void 0 : sel.focusNode;
17654        if (!sel || !anchorNode || !focusNode || isRestrictedNode(anchorNode) || isRestrictedNode(focusNode)) {
17655          return true;
17656        }
17657        var anchorRange = dom.createRng();
17658        anchorRange.setStart(anchorNode, sel.anchorOffset);
17659        anchorRange.collapse(true);
17660        var focusRange = dom.createRng();
17661        focusRange.setStart(focusNode, sel.focusOffset);
17662        focusRange.collapse(true);
17663        return anchorRange.compareBoundaryPoints(anchorRange.START_TO_START, focusRange) <= 0;
17664      };
17665      var normalize = function () {
17666        var rng = getRng$1();
17667        var sel = getSel();
17668        if (!hasMultipleRanges(sel) && hasAnyRanges(editor)) {
17669          var normRng = normalize$2(dom, rng);
17670          normRng.each(function (normRng) {
17671            setRng(normRng, isForward());
17672          });
17673          return normRng.getOr(rng);
17674        }
17675        return rng;
17676      };
17677      var selectorChanged = function (selector, callback) {
17678        selectorChangedWithUnbind(selector, callback);
17679        return exports;
17680      };
17681      var getScrollContainer = function () {
17682        var scrollContainer;
17683        var node = dom.getRoot();
17684        while (node && node.nodeName !== 'BODY') {
17685          if (node.scrollHeight > node.clientHeight) {
17686            scrollContainer = node;
17687            break;
17688          }
17689          node = node.parentNode;
17690        }
17691        return scrollContainer;
17692      };
17693      var scrollIntoView = function (elm, alignToTop) {
17694        if (isNonNullable(elm)) {
17695          scrollElementIntoView(editor, elm, alignToTop);
17696        } else {
17697          scrollRangeIntoView(editor, getRng$1(), alignToTop);
17698        }
17699      };
17700      var placeCaretAt = function (clientX, clientY) {
17701        return setRng(fromPoint(clientX, clientY, editor.getDoc()));
17702      };
17703      var getBoundingClientRect = function () {
17704        var rng = getRng$1();
17705        return rng.collapsed ? CaretPosition.fromRangeStart(rng).getClientRects()[0] : rng.getBoundingClientRect();
17706      };
17707      var destroy = function () {
17708        win = selectedRange = explicitRange = null;
17709        controlSelection.destroy();
17710      };
17711      var exports = {
17712        bookmarkManager: null,
17713        controlSelection: null,
17714        dom: dom,
17715        win: win,
17716        serializer: serializer,
17717        editor: editor,
17718        collapse: collapse,
17719        setCursorLocation: setCursorLocation,
17720        getContent: getContent,
17721        setContent: setContent,
17722        getBookmark: getBookmark,
17723        moveToBookmark: moveToBookmark,
17724        select: select$1,
17725        isCollapsed: isCollapsed,
17726        isForward: isForward,
17727        setNode: setNode,
17728        getNode: getNode$1,
17729        getSel: getSel,
17730        setRng: setRng,
17731        getRng: getRng$1,
17732        getStart: getStart$1,
17733        getEnd: getEnd$1,
17734        getSelectedBlocks: getSelectedBlocks$1,
17735        normalize: normalize,
17736        selectorChanged: selectorChanged,
17737        selectorChangedWithUnbind: selectorChangedWithUnbind,
17738        getScrollContainer: getScrollContainer,
17739        scrollIntoView: scrollIntoView,
17740        placeCaretAt: placeCaretAt,
17741        getBoundingClientRect: getBoundingClientRect,
17742        destroy: destroy
17743      };
17744      var bookmarkManager = BookmarkManager(exports);
17745      var controlSelection = ControlSelection(exports, editor);
17746      exports.bookmarkManager = bookmarkManager;
17747      exports.controlSelection = controlSelection;
17748      return exports;
17749    };
17750
17751    var removeAttrs = function (node, names) {
17752      each$k(names, function (name) {
17753        node.attr(name, null);
17754      });
17755    };
17756    var addFontToSpansFilter = function (domParser, styles, fontSizes) {
17757      domParser.addNodeFilter('font', function (nodes) {
17758        each$k(nodes, function (node) {
17759          var props = styles.parse(node.attr('style'));
17760          var color = node.attr('color');
17761          var face = node.attr('face');
17762          var size = node.attr('size');
17763          if (color) {
17764            props.color = color;
17765          }
17766          if (face) {
17767            props['font-family'] = face;
17768          }
17769          if (size) {
17770            props['font-size'] = fontSizes[parseInt(node.attr('size'), 10) - 1];
17771          }
17772          node.name = 'span';
17773          node.attr('style', styles.serialize(props));
17774          removeAttrs(node, [
17775            'color',
17776            'face',
17777            'size'
17778          ]);
17779        });
17780      });
17781    };
17782    var addStrikeToSpanFilter = function (domParser, styles) {
17783      domParser.addNodeFilter('strike', function (nodes) {
17784        each$k(nodes, function (node) {
17785          var props = styles.parse(node.attr('style'));
17786          props['text-decoration'] = 'line-through';
17787          node.name = 'span';
17788          node.attr('style', styles.serialize(props));
17789        });
17790      });
17791    };
17792    var addFilters = function (domParser, settings) {
17793      var styles = Styles();
17794      if (settings.convert_fonts_to_spans) {
17795        addFontToSpansFilter(domParser, styles, Tools.explode(settings.font_size_legacy_values));
17796      }
17797      addStrikeToSpanFilter(domParser, styles);
17798    };
17799    var register$2 = function (domParser, settings) {
17800      if (settings.inline_styles) {
17801        addFilters(domParser, settings);
17802      }
17803    };
17804
17805    var blobUriToBlob = function (url) {
17806      return new promiseObj(function (resolve, reject) {
17807        var rejectWithError = function () {
17808          reject('Cannot convert ' + url + ' to Blob. Resource might not exist or is inaccessible.');
17809        };
17810        try {
17811          var xhr_1 = new XMLHttpRequest();
17812          xhr_1.open('GET', url, true);
17813          xhr_1.responseType = 'blob';
17814          xhr_1.onload = function () {
17815            if (xhr_1.status === 200) {
17816              resolve(xhr_1.response);
17817            } else {
17818              rejectWithError();
17819            }
17820          };
17821          xhr_1.onerror = rejectWithError;
17822          xhr_1.send();
17823        } catch (ex) {
17824          rejectWithError();
17825        }
17826      });
17827    };
17828    var parseDataUri$1 = function (uri) {
17829      var type;
17830      var uriParts = decodeURIComponent(uri).split(',');
17831      var matches = /data:([^;]+)/.exec(uriParts[0]);
17832      if (matches) {
17833        type = matches[1];
17834      }
17835      return {
17836        type: type,
17837        data: uriParts[1]
17838      };
17839    };
17840    var buildBlob = function (type, data) {
17841      var str;
17842      try {
17843        str = atob(data);
17844      } catch (e) {
17845        return Optional.none();
17846      }
17847      var arr = new Uint8Array(str.length);
17848      for (var i = 0; i < arr.length; i++) {
17849        arr[i] = str.charCodeAt(i);
17850      }
17851      return Optional.some(new Blob([arr], { type: type }));
17852    };
17853    var dataUriToBlob = function (uri) {
17854      return new promiseObj(function (resolve) {
17855        var _a = parseDataUri$1(uri), type = _a.type, data = _a.data;
17856        buildBlob(type, data).fold(function () {
17857          return resolve(new Blob([]));
17858        }, resolve);
17859      });
17860    };
17861    var uriToBlob = function (url) {
17862      if (url.indexOf('blob:') === 0) {
17863        return blobUriToBlob(url);
17864      }
17865      if (url.indexOf('data:') === 0) {
17866        return dataUriToBlob(url);
17867      }
17868      return null;
17869    };
17870    var blobToDataUri = function (blob) {
17871      return new promiseObj(function (resolve) {
17872        var reader = new FileReader();
17873        reader.onloadend = function () {
17874          resolve(reader.result);
17875        };
17876        reader.readAsDataURL(blob);
17877      });
17878    };
17879
17880    var count$1 = 0;
17881    var uniqueId = function (prefix) {
17882      return (prefix || 'blobid') + count$1++;
17883    };
17884    var imageToBlobInfo = function (blobCache, img, resolve, reject) {
17885      var base64, blobInfo;
17886      if (img.src.indexOf('blob:') === 0) {
17887        blobInfo = blobCache.getByUri(img.src);
17888        if (blobInfo) {
17889          resolve({
17890            image: img,
17891            blobInfo: blobInfo
17892          });
17893        } else {
17894          uriToBlob(img.src).then(function (blob) {
17895            blobToDataUri(blob).then(function (dataUri) {
17896              base64 = parseDataUri$1(dataUri).data;
17897              blobInfo = blobCache.create(uniqueId(), blob, base64);
17898              blobCache.add(blobInfo);
17899              resolve({
17900                image: img,
17901                blobInfo: blobInfo
17902              });
17903            });
17904          }, function (err) {
17905            reject(err);
17906          });
17907        }
17908        return;
17909      }
17910      var _a = parseDataUri$1(img.src), data = _a.data, type = _a.type;
17911      base64 = data;
17912      blobInfo = blobCache.getByData(base64, type);
17913      if (blobInfo) {
17914        resolve({
17915          image: img,
17916          blobInfo: blobInfo
17917        });
17918      } else {
17919        uriToBlob(img.src).then(function (blob) {
17920          blobInfo = blobCache.create(uniqueId(), blob, base64);
17921          blobCache.add(blobInfo);
17922          resolve({
17923            image: img,
17924            blobInfo: blobInfo
17925          });
17926        }, function (err) {
17927          reject(err);
17928        });
17929      }
17930    };
17931    var getAllImages = function (elm) {
17932      return elm ? from(elm.getElementsByTagName('img')) : [];
17933    };
17934    var ImageScanner = function (uploadStatus, blobCache) {
17935      var cachedPromises = {};
17936      var findAll = function (elm, predicate) {
17937        if (!predicate) {
17938          predicate = always;
17939        }
17940        var images = filter$4(getAllImages(elm), function (img) {
17941          var src = img.src;
17942          if (!Env.fileApi) {
17943            return false;
17944          }
17945          if (img.hasAttribute('data-mce-bogus')) {
17946            return false;
17947          }
17948          if (img.hasAttribute('data-mce-placeholder')) {
17949            return false;
17950          }
17951          if (!src || src === Env.transparentSrc) {
17952            return false;
17953          }
17954          if (src.indexOf('blob:') === 0) {
17955            return !uploadStatus.isUploaded(src) && predicate(img);
17956          }
17957          if (src.indexOf('data:') === 0) {
17958            return predicate(img);
17959          }
17960          return false;
17961        });
17962        var promises = map$3(images, function (img) {
17963          if (cachedPromises[img.src] !== undefined) {
17964            return new promiseObj(function (resolve) {
17965              cachedPromises[img.src].then(function (imageInfo) {
17966                if (typeof imageInfo === 'string') {
17967                  return imageInfo;
17968                }
17969                resolve({
17970                  image: img,
17971                  blobInfo: imageInfo.blobInfo
17972                });
17973              });
17974            });
17975          }
17976          var newPromise = new promiseObj(function (resolve, reject) {
17977            imageToBlobInfo(blobCache, img, resolve, reject);
17978          }).then(function (result) {
17979            delete cachedPromises[result.image.src];
17980            return result;
17981          }).catch(function (error) {
17982            delete cachedPromises[img.src];
17983            return error;
17984          });
17985          cachedPromises[img.src] = newPromise;
17986          return newPromise;
17987        });
17988        return promiseObj.all(promises);
17989      };
17990      return { findAll: findAll };
17991    };
17992
17993    var extractBase64DataUris = function (html) {
17994      var dataImageUri = /data:[^;<"'\s]+;base64,([a-z0-9\+\/=\s]+)/gi;
17995      var chunks = [];
17996      var uris = {};
17997      var prefix = generate('img');
17998      var matches;
17999      var index = 0;
18000      var count = 0;
18001      while (matches = dataImageUri.exec(html)) {
18002        var uri = matches[0];
18003        var imageId = prefix + '_' + count++;
18004        uris[imageId] = uri;
18005        if (index < matches.index) {
18006          chunks.push(html.substr(index, matches.index - index));
18007        }
18008        chunks.push(imageId);
18009        index = matches.index + uri.length;
18010      }
18011      var re = new RegExp(prefix + '_[0-9]+', 'g');
18012      if (index === 0) {
18013        return {
18014          prefix: prefix,
18015          uris: uris,
18016          html: html,
18017          re: re
18018        };
18019      } else {
18020        if (index < html.length) {
18021          chunks.push(html.substr(index));
18022        }
18023        return {
18024          prefix: prefix,
18025          uris: uris,
18026          html: chunks.join(''),
18027          re: re
18028        };
18029      }
18030    };
18031    var restoreDataUris = function (html, result) {
18032      return html.replace(result.re, function (imageId) {
18033        return get$9(result.uris, imageId).getOr(imageId);
18034      });
18035    };
18036    var parseDataUri = function (uri) {
18037      var matches = /data:([^;]+);base64,([a-z0-9\+\/=\s]+)/i.exec(uri);
18038      if (matches) {
18039        return Optional.some({
18040          type: matches[1],
18041          data: decodeURIComponent(matches[2])
18042        });
18043      } else {
18044        return Optional.none();
18045      }
18046    };
18047
18048    var paddEmptyNode = function (settings, args, blockElements, node) {
18049      var brPreferred = settings.padd_empty_with_br || args.insert;
18050      if (brPreferred && blockElements[node.name]) {
18051        node.empty().append(new AstNode('br', 1)).shortEnded = true;
18052      } else {
18053        node.empty().append(new AstNode('#text', 3)).value = nbsp;
18054      }
18055    };
18056    var isPaddedWithNbsp = function (node) {
18057      return hasOnlyChild(node, '#text') && node.firstChild.value === nbsp;
18058    };
18059    var hasOnlyChild = function (node, name) {
18060      return node && node.firstChild && node.firstChild === node.lastChild && node.firstChild.name === name;
18061    };
18062    var isPadded = function (schema, node) {
18063      var rule = schema.getElementRule(node.name);
18064      return rule && rule.paddEmpty;
18065    };
18066    var isEmpty = function (schema, nonEmptyElements, whitespaceElements, node) {
18067      return node.isEmpty(nonEmptyElements, whitespaceElements, function (node) {
18068        return isPadded(schema, node);
18069      });
18070    };
18071    var isLineBreakNode = function (node, blockElements) {
18072      return node && (has$2(blockElements, node.name) || node.name === 'br');
18073    };
18074
18075    var isBogusImage = function (img) {
18076      return isNonNullable(img.attr('data-mce-bogus'));
18077    };
18078    var isInternalImageSource = function (img) {
18079      return img.attr('src') === Env.transparentSrc || isNonNullable(img.attr('data-mce-placeholder'));
18080    };
18081    var isValidDataImg = function (img, settings) {
18082      if (settings.images_dataimg_filter) {
18083        var imgElem_1 = new Image();
18084        imgElem_1.src = img.attr('src');
18085        each$j(img.attributes.map, function (value, key) {
18086          imgElem_1.setAttribute(key, value);
18087        });
18088        return settings.images_dataimg_filter(imgElem_1);
18089      } else {
18090        return true;
18091      }
18092    };
18093    var registerBase64ImageFilter = function (parser, settings) {
18094      var blobCache = settings.blob_cache;
18095      var processImage = function (img) {
18096        var inputSrc = img.attr('src');
18097        if (isInternalImageSource(img) || isBogusImage(img)) {
18098          return;
18099        }
18100        parseDataUri(inputSrc).filter(function () {
18101          return isValidDataImg(img, settings);
18102        }).bind(function (_a) {
18103          var type = _a.type, data = _a.data;
18104          return Optional.from(blobCache.getByData(data, type)).orThunk(function () {
18105            return buildBlob(type, data).map(function (blob) {
18106              var blobInfo = blobCache.create(uniqueId(), blob, data);
18107              blobCache.add(blobInfo);
18108              return blobInfo;
18109            });
18110          });
18111        }).each(function (blobInfo) {
18112          img.attr('src', blobInfo.blobUri());
18113        });
18114      };
18115      if (blobCache) {
18116        parser.addAttributeFilter('src', function (nodes) {
18117          return each$k(nodes, processImage);
18118        });
18119      }
18120    };
18121    var register$1 = function (parser, settings) {
18122      var schema = parser.schema;
18123      if (settings.remove_trailing_brs) {
18124        parser.addNodeFilter('br', function (nodes, _, args) {
18125          var i;
18126          var l = nodes.length;
18127          var node;
18128          var blockElements = Tools.extend({}, schema.getBlockElements());
18129          var nonEmptyElements = schema.getNonEmptyElements();
18130          var parent, lastParent, prev, prevName;
18131          var whiteSpaceElements = schema.getWhiteSpaceElements();
18132          var elementRule, textNode;
18133          blockElements.body = 1;
18134          for (i = 0; i < l; i++) {
18135            node = nodes[i];
18136            parent = node.parent;
18137            if (blockElements[node.parent.name] && node === parent.lastChild) {
18138              prev = node.prev;
18139              while (prev) {
18140                prevName = prev.name;
18141                if (prevName !== 'span' || prev.attr('data-mce-type') !== 'bookmark') {
18142                  if (prevName === 'br') {
18143                    node = null;
18144                  }
18145                  break;
18146                }
18147                prev = prev.prev;
18148              }
18149              if (node) {
18150                node.remove();
18151                if (isEmpty(schema, nonEmptyElements, whiteSpaceElements, parent)) {
18152                  elementRule = schema.getElementRule(parent.name);
18153                  if (elementRule) {
18154                    if (elementRule.removeEmpty) {
18155                      parent.remove();
18156                    } else if (elementRule.paddEmpty) {
18157                      paddEmptyNode(settings, args, blockElements, parent);
18158                    }
18159                  }
18160                }
18161              }
18162            } else {
18163              lastParent = node;
18164              while (parent && parent.firstChild === lastParent && parent.lastChild === lastParent) {
18165                lastParent = parent;
18166                if (blockElements[parent.name]) {
18167                  break;
18168                }
18169                parent = parent.parent;
18170              }
18171              if (lastParent === parent && settings.padd_empty_with_br !== true) {
18172                textNode = new AstNode('#text', 3);
18173                textNode.value = nbsp;
18174                node.replace(textNode);
18175              }
18176            }
18177          }
18178        });
18179      }
18180      parser.addAttributeFilter('href', function (nodes) {
18181        var i = nodes.length;
18182        var appendRel = function (rel) {
18183          var parts = rel.split(' ').filter(function (p) {
18184            return p.length > 0;
18185          });
18186          return parts.concat(['noopener']).sort().join(' ');
18187        };
18188        var addNoOpener = function (rel) {
18189          var newRel = rel ? Tools.trim(rel) : '';
18190          if (!/\b(noopener)\b/g.test(newRel)) {
18191            return appendRel(newRel);
18192          } else {
18193            return newRel;
18194          }
18195        };
18196        if (!settings.allow_unsafe_link_target) {
18197          while (i--) {
18198            var node = nodes[i];
18199            if (node.name === 'a' && node.attr('target') === '_blank') {
18200              node.attr('rel', addNoOpener(node.attr('rel')));
18201            }
18202          }
18203        }
18204      });
18205      if (!settings.allow_html_in_named_anchor) {
18206        parser.addAttributeFilter('id,name', function (nodes) {
18207          var i = nodes.length, sibling, prevSibling, parent, node;
18208          while (i--) {
18209            node = nodes[i];
18210            if (node.name === 'a' && node.firstChild && !node.attr('href')) {
18211              parent = node.parent;
18212              sibling = node.lastChild;
18213              do {
18214                prevSibling = sibling.prev;
18215                parent.insert(sibling, node);
18216                sibling = prevSibling;
18217              } while (sibling);
18218            }
18219          }
18220        });
18221      }
18222      if (settings.fix_list_elements) {
18223        parser.addNodeFilter('ul,ol', function (nodes) {
18224          var i = nodes.length, node, parentNode;
18225          while (i--) {
18226            node = nodes[i];
18227            parentNode = node.parent;
18228            if (parentNode.name === 'ul' || parentNode.name === 'ol') {
18229              if (node.prev && node.prev.name === 'li') {
18230                node.prev.append(node);
18231              } else {
18232                var li = new AstNode('li', 1);
18233                li.attr('style', 'list-style-type: none');
18234                node.wrap(li);
18235              }
18236            }
18237          }
18238        });
18239      }
18240      if (settings.validate && schema.getValidClasses()) {
18241        parser.addAttributeFilter('class', function (nodes) {
18242          var validClasses = schema.getValidClasses();
18243          var i = nodes.length;
18244          while (i--) {
18245            var node = nodes[i];
18246            var classList = node.attr('class').split(' ');
18247            var classValue = '';
18248            for (var ci = 0; ci < classList.length; ci++) {
18249              var className = classList[ci];
18250              var valid = false;
18251              var validClassesMap = validClasses['*'];
18252              if (validClassesMap && validClassesMap[className]) {
18253                valid = true;
18254              }
18255              validClassesMap = validClasses[node.name];
18256              if (!valid && validClassesMap && validClassesMap[className]) {
18257                valid = true;
18258              }
18259              if (valid) {
18260                if (classValue) {
18261                  classValue += ' ';
18262                }
18263                classValue += className;
18264              }
18265            }
18266            if (!classValue.length) {
18267              classValue = null;
18268            }
18269            node.attr('class', classValue);
18270          }
18271        });
18272      }
18273      registerBase64ImageFilter(parser, settings);
18274    };
18275
18276    var each$7 = Tools.each, trim = Tools.trim;
18277    var queryParts = 'source protocol authority userInfo user password host port relative path directory file query anchor'.split(' ');
18278    var DEFAULT_PORTS = {
18279      ftp: 21,
18280      http: 80,
18281      https: 443,
18282      mailto: 25
18283    };
18284    var safeSvgDataUrlElements = [
18285      'img',
18286      'video'
18287    ];
18288    var blockSvgDataUris = function (allowSvgDataUrls, tagName) {
18289      if (isNonNullable(allowSvgDataUrls)) {
18290        return !allowSvgDataUrls;
18291      } else {
18292        return isNonNullable(tagName) ? !contains$3(safeSvgDataUrlElements, tagName) : true;
18293      }
18294    };
18295    var isInvalidUri = function (settings, uri, tagName) {
18296      if (settings.allow_html_data_urls) {
18297        return false;
18298      } else if (/^data:image\//i.test(uri)) {
18299        return blockSvgDataUris(settings.allow_svg_data_urls, tagName) && /^data:image\/svg\+xml/i.test(uri);
18300      } else {
18301        return /^data:/i.test(uri);
18302      }
18303    };
18304    var URI = function () {
18305      function URI(url, settings) {
18306        url = trim(url);
18307        this.settings = settings || {};
18308        var baseUri = this.settings.base_uri;
18309        var self = this;
18310        if (/^([\w\-]+):([^\/]{2})/i.test(url) || /^\s*#/.test(url)) {
18311          self.source = url;
18312          return;
18313        }
18314        var isProtocolRelative = url.indexOf('//') === 0;
18315        if (url.indexOf('/') === 0 && !isProtocolRelative) {
18316          url = (baseUri ? baseUri.protocol || 'http' : 'http') + '://mce_host' + url;
18317        }
18318        if (!/^[\w\-]*:?\/\//.test(url)) {
18319          var baseUrl = this.settings.base_uri ? this.settings.base_uri.path : new URI(document.location.href).directory;
18320          if (this.settings.base_uri && this.settings.base_uri.protocol == '') {
18321            url = '//mce_host' + self.toAbsPath(baseUrl, url);
18322          } else {
18323            var match = /([^#?]*)([#?]?.*)/.exec(url);
18324            url = (baseUri && baseUri.protocol || 'http') + '://mce_host' + self.toAbsPath(baseUrl, match[1]) + match[2];
18325          }
18326        }
18327        url = url.replace(/@@/g, '(mce_at)');
18328        var urlMatch = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@\/]*):?([^:@\/]*))?@)?(\[[a-zA-Z0-9:.%]+\]|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(url);
18329        each$7(queryParts, function (v, i) {
18330          var part = urlMatch[i];
18331          if (part) {
18332            part = part.replace(/\(mce_at\)/g, '@@');
18333          }
18334          self[v] = part;
18335        });
18336        if (baseUri) {
18337          if (!self.protocol) {
18338            self.protocol = baseUri.protocol;
18339          }
18340          if (!self.userInfo) {
18341            self.userInfo = baseUri.userInfo;
18342          }
18343          if (!self.port && self.host === 'mce_host') {
18344            self.port = baseUri.port;
18345          }
18346          if (!self.host || self.host === 'mce_host') {
18347            self.host = baseUri.host;
18348          }
18349          self.source = '';
18350        }
18351        if (isProtocolRelative) {
18352          self.protocol = '';
18353        }
18354      }
18355      URI.parseDataUri = function (uri) {
18356        var type;
18357        var uriComponents = decodeURIComponent(uri).split(',');
18358        var matches = /data:([^;]+)/.exec(uriComponents[0]);
18359        if (matches) {
18360          type = matches[1];
18361        }
18362        return {
18363          type: type,
18364          data: uriComponents[1]
18365        };
18366      };
18367      URI.isDomSafe = function (uri, context, options) {
18368        if (options === void 0) {
18369          options = {};
18370        }
18371        if (options.allow_script_urls) {
18372          return true;
18373        } else {
18374          var decodedUri = Entities.decode(uri).replace(/[\s\u0000-\u001F]+/g, '');
18375          try {
18376            decodedUri = decodeURIComponent(decodedUri);
18377          } catch (ex) {
18378            decodedUri = unescape(decodedUri);
18379          }
18380          if (/((java|vb)script|mhtml):/i.test(decodedUri)) {
18381            return false;
18382          }
18383          return !isInvalidUri(options, decodedUri, context);
18384        }
18385      };
18386      URI.getDocumentBaseUrl = function (loc) {
18387        var baseUrl;
18388        if (loc.protocol.indexOf('http') !== 0 && loc.protocol !== 'file:') {
18389          baseUrl = loc.href;
18390        } else {
18391          baseUrl = loc.protocol + '//' + loc.host + loc.pathname;
18392        }
18393        if (/^[^:]+:\/\/\/?[^\/]+\//.test(baseUrl)) {
18394          baseUrl = baseUrl.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');
18395          if (!/[\/\\]$/.test(baseUrl)) {
18396            baseUrl += '/';
18397          }
18398        }
18399        return baseUrl;
18400      };
18401      URI.prototype.setPath = function (path) {
18402        var pathMatch = /^(.*?)\/?(\w+)?$/.exec(path);
18403        this.path = pathMatch[0];
18404        this.directory = pathMatch[1];
18405        this.file = pathMatch[2];
18406        this.source = '';
18407        this.getURI();
18408      };
18409      URI.prototype.toRelative = function (uri) {
18410        var output;
18411        if (uri === './') {
18412          return uri;
18413        }
18414        var relativeUri = new URI(uri, { base_uri: this });
18415        if (relativeUri.host !== 'mce_host' && this.host !== relativeUri.host && relativeUri.host || this.port !== relativeUri.port || this.protocol !== relativeUri.protocol && relativeUri.protocol !== '') {
18416          return relativeUri.getURI();
18417        }
18418        var tu = this.getURI(), uu = relativeUri.getURI();
18419        if (tu === uu || tu.charAt(tu.length - 1) === '/' && tu.substr(0, tu.length - 1) === uu) {
18420          return tu;
18421        }
18422        output = this.toRelPath(this.path, relativeUri.path);
18423        if (relativeUri.query) {
18424          output += '?' + relativeUri.query;
18425        }
18426        if (relativeUri.anchor) {
18427          output += '#' + relativeUri.anchor;
18428        }
18429        return output;
18430      };
18431      URI.prototype.toAbsolute = function (uri, noHost) {
18432        var absoluteUri = new URI(uri, { base_uri: this });
18433        return absoluteUri.getURI(noHost && this.isSameOrigin(absoluteUri));
18434      };
18435      URI.prototype.isSameOrigin = function (uri) {
18436        if (this.host == uri.host && this.protocol == uri.protocol) {
18437          if (this.port == uri.port) {
18438            return true;
18439          }
18440          var defaultPort = DEFAULT_PORTS[this.protocol];
18441          if (defaultPort && (this.port || defaultPort) == (uri.port || defaultPort)) {
18442            return true;
18443          }
18444        }
18445        return false;
18446      };
18447      URI.prototype.toRelPath = function (base, path) {
18448        var breakPoint = 0, out = '', i, l;
18449        var normalizedBase = base.substring(0, base.lastIndexOf('/')).split('/');
18450        var items = path.split('/');
18451        if (normalizedBase.length >= items.length) {
18452          for (i = 0, l = normalizedBase.length; i < l; i++) {
18453            if (i >= items.length || normalizedBase[i] !== items[i]) {
18454              breakPoint = i + 1;
18455              break;
18456            }
18457          }
18458        }
18459        if (normalizedBase.length < items.length) {
18460          for (i = 0, l = items.length; i < l; i++) {
18461            if (i >= normalizedBase.length || normalizedBase[i] !== items[i]) {
18462              breakPoint = i + 1;
18463              break;
18464            }
18465          }
18466        }
18467        if (breakPoint === 1) {
18468          return path;
18469        }
18470        for (i = 0, l = normalizedBase.length - (breakPoint - 1); i < l; i++) {
18471          out += '../';
18472        }
18473        for (i = breakPoint - 1, l = items.length; i < l; i++) {
18474          if (i !== breakPoint - 1) {
18475            out += '/' + items[i];
18476          } else {
18477            out += items[i];
18478          }
18479        }
18480        return out;
18481      };
18482      URI.prototype.toAbsPath = function (base, path) {
18483        var i, nb = 0, o = [], outPath;
18484        var tr = /\/$/.test(path) ? '/' : '';
18485        var normalizedBase = base.split('/');
18486        var normalizedPath = path.split('/');
18487        each$7(normalizedBase, function (k) {
18488          if (k) {
18489            o.push(k);
18490          }
18491        });
18492        normalizedBase = o;
18493        for (i = normalizedPath.length - 1, o = []; i >= 0; i--) {
18494          if (normalizedPath[i].length === 0 || normalizedPath[i] === '.') {
18495            continue;
18496          }
18497          if (normalizedPath[i] === '..') {
18498            nb++;
18499            continue;
18500          }
18501          if (nb > 0) {
18502            nb--;
18503            continue;
18504          }
18505          o.push(normalizedPath[i]);
18506        }
18507        i = normalizedBase.length - nb;
18508        if (i <= 0) {
18509          outPath = reverse(o).join('/');
18510        } else {
18511          outPath = normalizedBase.slice(0, i).join('/') + '/' + reverse(o).join('/');
18512        }
18513        if (outPath.indexOf('/') !== 0) {
18514          outPath = '/' + outPath;
18515        }
18516        if (tr && outPath.lastIndexOf('/') !== outPath.length - 1) {
18517          outPath += tr;
18518        }
18519        return outPath;
18520      };
18521      URI.prototype.getURI = function (noProtoHost) {
18522        if (noProtoHost === void 0) {
18523          noProtoHost = false;
18524        }
18525        var s;
18526        if (!this.source || noProtoHost) {
18527          s = '';
18528          if (!noProtoHost) {
18529            if (this.protocol) {
18530              s += this.protocol + '://';
18531            } else {
18532              s += '//';
18533            }
18534            if (this.userInfo) {
18535              s += this.userInfo + '@';
18536            }
18537            if (this.host) {
18538              s += this.host;
18539            }
18540            if (this.port) {
18541              s += ':' + this.port;
18542            }
18543          }
18544          if (this.path) {
18545            s += this.path;
18546          }
18547          if (this.query) {
18548            s += '?' + this.query;
18549          }
18550          if (this.anchor) {
18551            s += '#' + this.anchor;
18552          }
18553          this.source = s;
18554        }
18555        return this.source;
18556      };
18557      return URI;
18558    }();
18559
18560    var filteredClobberElements = Tools.makeMap('button,fieldset,form,iframe,img,image,input,object,output,select,textarea');
18561    var isValidPrefixAttrName = function (name) {
18562      return name.indexOf('data-') === 0 || name.indexOf('aria-') === 0;
18563    };
18564    var lazyTempDocument = cached(function () {
18565      return document.implementation.createHTMLDocument('parser');
18566    });
18567    var findMatchingEndTagIndex = function (schema, html, startIndex) {
18568      var startTagRegExp = /<([!?\/])?([A-Za-z0-9\-_:.]+)/g;
18569      var endTagRegExp = /(?:\s(?:[^'">]+(?:"[^"]*"|'[^']*'))*[^"'>]*(?:"[^">]*|'[^'>]*)?|\s*|\/)>/g;
18570      var shortEndedElements = schema.getShortEndedElements();
18571      var count = 1, index = startIndex;
18572      while (count !== 0) {
18573        startTagRegExp.lastIndex = index;
18574        while (true) {
18575          var startMatch = startTagRegExp.exec(html);
18576          if (startMatch === null) {
18577            return index;
18578          } else if (startMatch[1] === '!') {
18579            if (startsWith(startMatch[2], '--')) {
18580              index = findCommentEndIndex(html, false, startMatch.index + '!--'.length);
18581            } else {
18582              index = findCommentEndIndex(html, true, startMatch.index + 1);
18583            }
18584            break;
18585          } else {
18586            endTagRegExp.lastIndex = startTagRegExp.lastIndex;
18587            var endMatch = endTagRegExp.exec(html);
18588            if (isNull(endMatch) || endMatch.index !== startTagRegExp.lastIndex) {
18589              continue;
18590            }
18591            if (startMatch[1] === '/') {
18592              count -= 1;
18593            } else if (!has$2(shortEndedElements, startMatch[2])) {
18594              count += 1;
18595            }
18596            index = startTagRegExp.lastIndex + endMatch[0].length;
18597            break;
18598          }
18599        }
18600      }
18601      return index;
18602    };
18603    var isConditionalComment = function (html, startIndex) {
18604      return /^\s*\[if [\w\W]+\]>.*<!\[endif\](--!?)?>/.test(html.substr(startIndex));
18605    };
18606    var findCommentEndIndex = function (html, isBogus, startIndex) {
18607      if (startIndex === void 0) {
18608        startIndex = 0;
18609      }
18610      var lcHtml = html.toLowerCase();
18611      if (lcHtml.indexOf('[if ', startIndex) !== -1 && isConditionalComment(lcHtml, startIndex)) {
18612        var endIfIndex = lcHtml.indexOf('[endif]', startIndex);
18613        return lcHtml.indexOf('>', endIfIndex);
18614      } else {
18615        if (isBogus) {
18616          var endIndex = lcHtml.indexOf('>', startIndex);
18617          return endIndex !== -1 ? endIndex : lcHtml.length;
18618        } else {
18619          var endCommentRegexp = /--!?>/g;
18620          endCommentRegexp.lastIndex = startIndex;
18621          var match = endCommentRegexp.exec(html);
18622          return match ? match.index + match[0].length : lcHtml.length;
18623        }
18624      }
18625    };
18626    var checkBogusAttribute = function (regExp, attrString) {
18627      var matches = regExp.exec(attrString);
18628      if (matches) {
18629        var name_1 = matches[1];
18630        var value = matches[2];
18631        return typeof name_1 === 'string' && name_1.toLowerCase() === 'data-mce-bogus' ? value : null;
18632      } else {
18633        return null;
18634      }
18635    };
18636    var SaxParser = function (settings, schema) {
18637      if (schema === void 0) {
18638        schema = Schema();
18639      }
18640      settings = settings || {};
18641      var doc = lazyTempDocument();
18642      var form = doc.createElement('form');
18643      if (settings.fix_self_closing !== false) {
18644        settings.fix_self_closing = true;
18645      }
18646      var comment = settings.comment ? settings.comment : noop;
18647      var cdata = settings.cdata ? settings.cdata : noop;
18648      var text = settings.text ? settings.text : noop;
18649      var start = settings.start ? settings.start : noop;
18650      var end = settings.end ? settings.end : noop;
18651      var pi = settings.pi ? settings.pi : noop;
18652      var doctype = settings.doctype ? settings.doctype : noop;
18653      var parseInternal = function (base64Extract, format) {
18654        if (format === void 0) {
18655          format = 'html';
18656        }
18657        var html = base64Extract.html;
18658        var matches, index = 0, value, endRegExp;
18659        var stack = [];
18660        var attrList, i, textData, name;
18661        var isInternalElement, isShortEnded;
18662        var elementRule, isValidElement, attr, attribsValue, validAttributesMap, validAttributePatterns;
18663        var attributesRequired, attributesDefault, attributesForced;
18664        var anyAttributesRequired, attrValue, idCount = 0;
18665        var decode = Entities.decode;
18666        var filteredUrlAttrs = Tools.makeMap('src,href,data,background,action,formaction,poster,xlink:href');
18667        var parsingMode = format === 'html' ? 0 : 1;
18668        var processEndTag = function (name) {
18669          var pos, i;
18670          pos = stack.length;
18671          while (pos--) {
18672            if (stack[pos].name === name) {
18673              break;
18674            }
18675          }
18676          if (pos >= 0) {
18677            for (i = stack.length - 1; i >= pos; i--) {
18678              name = stack[i];
18679              if (name.valid) {
18680                end(name.name);
18681              }
18682            }
18683            stack.length = pos;
18684          }
18685        };
18686        var processText = function (value, raw) {
18687          return text(restoreDataUris(value, base64Extract), raw);
18688        };
18689        var processComment = function (value) {
18690          if (value === '') {
18691            return;
18692          }
18693          if (value.charAt(0) === '>') {
18694            value = ' ' + value;
18695          }
18696          if (!settings.allow_conditional_comments && value.substr(0, 3).toLowerCase() === '[if') {
18697            value = ' ' + value;
18698          }
18699          comment(restoreDataUris(value, base64Extract));
18700        };
18701        var processAttr = function (value) {
18702          return restoreDataUris(value, base64Extract);
18703        };
18704        var processMalformedComment = function (value, startIndex) {
18705          var startTag = value || '';
18706          var isBogus = !startsWith(startTag, '--');
18707          var endIndex = findCommentEndIndex(html, isBogus, startIndex);
18708          value = html.substr(startIndex, endIndex - startIndex);
18709          processComment(isBogus ? startTag + value : value);
18710          return endIndex + 1;
18711        };
18712        var parseAttribute = function (tagName, name, value, val2, val3) {
18713          name = name.toLowerCase();
18714          value = processAttr(name in fillAttrsMap ? name : decode(value || val2 || val3 || ''));
18715          if (validate && !isInternalElement && isValidPrefixAttrName(name) === false) {
18716            var attrRule = validAttributesMap[name];
18717            if (!attrRule && validAttributePatterns) {
18718              var i_1 = validAttributePatterns.length;
18719              while (i_1--) {
18720                attrRule = validAttributePatterns[i_1];
18721                if (attrRule.pattern.test(name)) {
18722                  break;
18723                }
18724              }
18725              if (i_1 === -1) {
18726                attrRule = null;
18727              }
18728            }
18729            if (!attrRule) {
18730              return;
18731            }
18732            if (attrRule.validValues && !(value in attrRule.validValues)) {
18733              return;
18734            }
18735          }
18736          var isNameOrId = name === 'name' || name === 'id';
18737          if (isNameOrId && tagName in filteredClobberElements && (value in doc || value in form)) {
18738            return;
18739          }
18740          if (filteredUrlAttrs[name] && !URI.isDomSafe(value, tagName, settings)) {
18741            return;
18742          }
18743          if (isInternalElement && (name in filteredUrlAttrs || name.indexOf('on') === 0)) {
18744            return;
18745          }
18746          attrList.map[name] = value;
18747          attrList.push({
18748            name: name,
18749            value: value
18750          });
18751        };
18752        var tokenRegExp = new RegExp('<(?:' + '(?:!--([\\w\\W]*?)--!?>)|' + '(?:!\\[CDATA\\[([\\w\\W]*?)\\]\\]>)|' + '(?:![Dd][Oo][Cc][Tt][Yy][Pp][Ee]([\\w\\W]*?)>)|' + '(?:!(--)?)|' + '(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|' + '(?:\\/([A-Za-z][A-Za-z0-9\\-_\\:\\.]*)>)|' + '(?:([A-Za-z][A-Za-z0-9\\-_:.]*)(\\s(?:[^\'">]+(?:"[^"]*"|\'[^\']*\'))*[^"\'>]*(?:"[^">]*|\'[^\'>]*)?|\\s*|\\/)>)' + ')', 'g');
18753        var attrRegExp = /([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:[^\"])*)\")|(?:\'((?:[^\'])*)\')|([^>\s]+)))?/g;
18754        var shortEndedElements = schema.getShortEndedElements();
18755        var selfClosing = settings.self_closing_elements || schema.getSelfClosingElements();
18756        var fillAttrsMap = schema.getBoolAttrs();
18757        var validate = settings.validate;
18758        var removeInternalElements = settings.remove_internals;
18759        var fixSelfClosing = settings.fix_self_closing;
18760        var specialElements = schema.getSpecialElements();
18761        var processHtml = html + '>';
18762        while (matches = tokenRegExp.exec(processHtml)) {
18763          var matchText = matches[0];
18764          if (index < matches.index) {
18765            processText(decode(html.substr(index, matches.index - index)));
18766          }
18767          if (value = matches[7]) {
18768            value = value.toLowerCase();
18769            if (value.charAt(0) === ':') {
18770              value = value.substr(1);
18771            }
18772            processEndTag(value);
18773          } else if (value = matches[8]) {
18774            if (matches.index + matchText.length > html.length) {
18775              processText(decode(html.substr(matches.index)));
18776              index = matches.index + matchText.length;
18777              continue;
18778            }
18779            value = value.toLowerCase();
18780            if (value.charAt(0) === ':') {
18781              value = value.substr(1);
18782            }
18783            isShortEnded = value in shortEndedElements;
18784            if (fixSelfClosing && selfClosing[value] && stack.length > 0 && stack[stack.length - 1].name === value) {
18785              processEndTag(value);
18786            }
18787            var bogusValue = checkBogusAttribute(attrRegExp, matches[9]);
18788            if (bogusValue !== null) {
18789              if (bogusValue === 'all') {
18790                index = findMatchingEndTagIndex(schema, html, tokenRegExp.lastIndex);
18791                tokenRegExp.lastIndex = index;
18792                continue;
18793              }
18794              isValidElement = false;
18795            }
18796            if (!validate || (elementRule = schema.getElementRule(value))) {
18797              isValidElement = true;
18798              if (validate) {
18799                validAttributesMap = elementRule.attributes;
18800                validAttributePatterns = elementRule.attributePatterns;
18801              }
18802              if (attribsValue = matches[9]) {
18803                isInternalElement = attribsValue.indexOf('data-mce-type') !== -1;
18804                if (isInternalElement && removeInternalElements) {
18805                  isValidElement = false;
18806                }
18807                attrList = [];
18808                attrList.map = {};
18809                attribsValue.replace(attrRegExp, function (match, name, val, val2, val3) {
18810                  parseAttribute(value, name, val, val2, val3);
18811                  return '';
18812                });
18813              } else {
18814                attrList = [];
18815                attrList.map = {};
18816              }
18817              if (validate && !isInternalElement) {
18818                attributesRequired = elementRule.attributesRequired;
18819                attributesDefault = elementRule.attributesDefault;
18820                attributesForced = elementRule.attributesForced;
18821                anyAttributesRequired = elementRule.removeEmptyAttrs;
18822                if (anyAttributesRequired && !attrList.length) {
18823                  isValidElement = false;
18824                }
18825                if (attributesForced) {
18826                  i = attributesForced.length;
18827                  while (i--) {
18828                    attr = attributesForced[i];
18829                    name = attr.name;
18830                    attrValue = attr.value;
18831                    if (attrValue === '{$uid}') {
18832                      attrValue = 'mce_' + idCount++;
18833                    }
18834                    attrList.map[name] = attrValue;
18835                    attrList.push({
18836                      name: name,
18837                      value: attrValue
18838                    });
18839                  }
18840                }
18841                if (attributesDefault) {
18842                  i = attributesDefault.length;
18843                  while (i--) {
18844                    attr = attributesDefault[i];
18845                    name = attr.name;
18846                    if (!(name in attrList.map)) {
18847                      attrValue = attr.value;
18848                      if (attrValue === '{$uid}') {
18849                        attrValue = 'mce_' + idCount++;
18850                      }
18851                      attrList.map[name] = attrValue;
18852                      attrList.push({
18853                        name: name,
18854                        value: attrValue
18855                      });
18856                    }
18857                  }
18858                }
18859                if (attributesRequired) {
18860                  i = attributesRequired.length;
18861                  while (i--) {
18862                    if (attributesRequired[i] in attrList.map) {
18863                      break;
18864                    }
18865                  }
18866                  if (i === -1) {
18867                    isValidElement = false;
18868                  }
18869                }
18870                if (attr = attrList.map['data-mce-bogus']) {
18871                  if (attr === 'all') {
18872                    index = findMatchingEndTagIndex(schema, html, tokenRegExp.lastIndex);
18873                    tokenRegExp.lastIndex = index;
18874                    continue;
18875                  }
18876                  isValidElement = false;
18877                }
18878              }
18879              if (isValidElement) {
18880                start(value, attrList, isShortEnded);
18881              }
18882            } else {
18883              isValidElement = false;
18884            }
18885            if (endRegExp = specialElements[value]) {
18886              endRegExp.lastIndex = index = matches.index + matchText.length;
18887              if (matches = endRegExp.exec(html)) {
18888                if (isValidElement) {
18889                  textData = html.substr(index, matches.index - index);
18890                }
18891                index = matches.index + matches[0].length;
18892              } else {
18893                textData = html.substr(index);
18894                index = html.length;
18895              }
18896              if (isValidElement) {
18897                if (textData.length > 0) {
18898                  processText(textData, true);
18899                }
18900                end(value);
18901              }
18902              tokenRegExp.lastIndex = index;
18903              continue;
18904            }
18905            if (!isShortEnded) {
18906              if (!attribsValue || attribsValue.indexOf('/') !== attribsValue.length - 1) {
18907                stack.push({
18908                  name: value,
18909                  valid: isValidElement
18910                });
18911              } else if (isValidElement) {
18912                end(value);
18913              }
18914            }
18915          } else if (value = matches[1]) {
18916            processComment(value);
18917          } else if (value = matches[2]) {
18918            var isValidCdataSection = parsingMode === 1 || settings.preserve_cdata || stack.length > 0 && schema.isValidChild(stack[stack.length - 1].name, '#cdata');
18919            if (isValidCdataSection) {
18920              cdata(value);
18921            } else {
18922              index = processMalformedComment('', matches.index + 2);
18923              tokenRegExp.lastIndex = index;
18924              continue;
18925            }
18926          } else if (value = matches[3]) {
18927            doctype(value);
18928          } else if ((value = matches[4]) || matchText === '<!') {
18929            index = processMalformedComment(value, matches.index + matchText.length);
18930            tokenRegExp.lastIndex = index;
18931            continue;
18932          } else if (value = matches[5]) {
18933            if (parsingMode === 1) {
18934              pi(value, matches[6]);
18935            } else {
18936              index = processMalformedComment('?', matches.index + 2);
18937              tokenRegExp.lastIndex = index;
18938              continue;
18939            }
18940          }
18941          index = matches.index + matchText.length;
18942        }
18943        if (index < html.length) {
18944          processText(decode(html.substr(index)));
18945        }
18946        for (i = stack.length - 1; i >= 0; i--) {
18947          value = stack[i];
18948          if (value.valid) {
18949            end(value.name);
18950          }
18951        }
18952      };
18953      var parse = function (html, format) {
18954        if (format === void 0) {
18955          format = 'html';
18956        }
18957        parseInternal(extractBase64DataUris(html), format);
18958      };
18959      return { parse: parse };
18960    };
18961    SaxParser.findEndTag = findMatchingEndTagIndex;
18962
18963    var makeMap = Tools.makeMap, each$6 = Tools.each, explode$2 = Tools.explode, extend$4 = Tools.extend;
18964    var DomParser = function (settings, schema) {
18965      if (schema === void 0) {
18966        schema = Schema();
18967      }
18968      var nodeFilters = {};
18969      var attributeFilters = [];
18970      var matchedNodes = {};
18971      var matchedAttributes = {};
18972      settings = settings || {};
18973      settings.validate = 'validate' in settings ? settings.validate : true;
18974      settings.root_name = settings.root_name || 'body';
18975      var fixInvalidChildren = function (nodes) {
18976        var nonSplitableElements = makeMap('tr,td,th,tbody,thead,tfoot,table');
18977        var nonEmptyElements = schema.getNonEmptyElements();
18978        var whitespaceElements = schema.getWhiteSpaceElements();
18979        var textBlockElements = schema.getTextBlockElements();
18980        var specialElements = schema.getSpecialElements();
18981        var removeOrUnwrapInvalidNode = function (node, originalNodeParent) {
18982          if (originalNodeParent === void 0) {
18983            originalNodeParent = node.parent;
18984          }
18985          if (specialElements[node.name]) {
18986            node.empty().remove();
18987          } else {
18988            var children = node.children();
18989            for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
18990              var childNode = children_1[_i];
18991              if (!schema.isValidChild(originalNodeParent.name, childNode.name)) {
18992                removeOrUnwrapInvalidNode(childNode, originalNodeParent);
18993              }
18994            }
18995            node.unwrap();
18996          }
18997        };
18998        for (var ni = 0; ni < nodes.length; ni++) {
18999          var node = nodes[ni];
19000          var parent_1 = void 0, newParent = void 0, tempNode = void 0;
19001          if (!node.parent || node.fixed) {
19002            continue;
19003          }
19004          if (textBlockElements[node.name] && node.parent.name === 'li') {
19005            var sibling = node.next;
19006            while (sibling) {
19007              if (textBlockElements[sibling.name]) {
19008                sibling.name = 'li';
19009                sibling.fixed = true;
19010                node.parent.insert(sibling, node.parent);
19011              } else {
19012                break;
19013              }
19014              sibling = sibling.next;
19015            }
19016            node.unwrap();
19017            continue;
19018          }
19019          var parents = [node];
19020          for (parent_1 = node.parent; parent_1 && !schema.isValidChild(parent_1.name, node.name) && !nonSplitableElements[parent_1.name]; parent_1 = parent_1.parent) {
19021            parents.push(parent_1);
19022          }
19023          if (parent_1 && parents.length > 1) {
19024            if (schema.isValidChild(parent_1.name, node.name)) {
19025              parents.reverse();
19026              newParent = filterNode(parents[0].clone());
19027              var currentNode = newParent;
19028              for (var i = 0; i < parents.length - 1; i++) {
19029                if (schema.isValidChild(currentNode.name, parents[i].name)) {
19030                  tempNode = filterNode(parents[i].clone());
19031                  currentNode.append(tempNode);
19032                } else {
19033                  tempNode = currentNode;
19034                }
19035                for (var childNode = parents[i].firstChild; childNode && childNode !== parents[i + 1];) {
19036                  var nextNode = childNode.next;
19037                  tempNode.append(childNode);
19038                  childNode = nextNode;
19039                }
19040                currentNode = tempNode;
19041              }
19042              if (!isEmpty(schema, nonEmptyElements, whitespaceElements, newParent)) {
19043                parent_1.insert(newParent, parents[0], true);
19044                parent_1.insert(node, newParent);
19045              } else {
19046                parent_1.insert(node, parents[0], true);
19047              }
19048              parent_1 = parents[0];
19049              if (isEmpty(schema, nonEmptyElements, whitespaceElements, parent_1) || hasOnlyChild(parent_1, 'br')) {
19050                parent_1.empty().remove();
19051              }
19052            } else {
19053              removeOrUnwrapInvalidNode(node);
19054            }
19055          } else if (node.parent) {
19056            if (node.name === 'li') {
19057              var sibling = node.prev;
19058              if (sibling && (sibling.name === 'ul' || sibling.name === 'ol')) {
19059                sibling.append(node);
19060                continue;
19061              }
19062              sibling = node.next;
19063              if (sibling && (sibling.name === 'ul' || sibling.name === 'ol')) {
19064                sibling.insert(node, sibling.firstChild, true);
19065                continue;
19066              }
19067              node.wrap(filterNode(new AstNode('ul', 1)));
19068              continue;
19069            }
19070            if (schema.isValidChild(node.parent.name, 'div') && schema.isValidChild('div', node.name)) {
19071              node.wrap(filterNode(new AstNode('div', 1)));
19072            } else {
19073              removeOrUnwrapInvalidNode(node);
19074            }
19075          }
19076        }
19077      };
19078      var filterNode = function (node) {
19079        var name = node.name;
19080        if (name in nodeFilters) {
19081          var list = matchedNodes[name];
19082          if (list) {
19083            list.push(node);
19084          } else {
19085            matchedNodes[name] = [node];
19086          }
19087        }
19088        var i = attributeFilters.length;
19089        while (i--) {
19090          var attrName = attributeFilters[i].name;
19091          if (attrName in node.attributes.map) {
19092            var list = matchedAttributes[attrName];
19093            if (list) {
19094              list.push(node);
19095            } else {
19096              matchedAttributes[attrName] = [node];
19097            }
19098          }
19099        }
19100        return node;
19101      };
19102      var addNodeFilter = function (name, callback) {
19103        each$6(explode$2(name), function (name) {
19104          var list = nodeFilters[name];
19105          if (!list) {
19106            nodeFilters[name] = list = [];
19107          }
19108          list.push(callback);
19109        });
19110      };
19111      var getNodeFilters = function () {
19112        var out = [];
19113        for (var name_1 in nodeFilters) {
19114          if (has$2(nodeFilters, name_1)) {
19115            out.push({
19116              name: name_1,
19117              callbacks: nodeFilters[name_1]
19118            });
19119          }
19120        }
19121        return out;
19122      };
19123      var addAttributeFilter = function (name, callback) {
19124        each$6(explode$2(name), function (name) {
19125          var i;
19126          for (i = 0; i < attributeFilters.length; i++) {
19127            if (attributeFilters[i].name === name) {
19128              attributeFilters[i].callbacks.push(callback);
19129              return;
19130            }
19131          }
19132          attributeFilters.push({
19133            name: name,
19134            callbacks: [callback]
19135          });
19136        });
19137      };
19138      var getAttributeFilters = function () {
19139        return [].concat(attributeFilters);
19140      };
19141      var parse = function (html, args) {
19142        var nodes, i, l, fi, fl, list, name;
19143        var invalidChildren = [];
19144        var node;
19145        var getRootBlockName = function (name) {
19146          if (name === false) {
19147            return '';
19148          } else if (name === true) {
19149            return 'p';
19150          } else {
19151            return name;
19152          }
19153        };
19154        args = args || {};
19155        matchedNodes = {};
19156        matchedAttributes = {};
19157        var blockElements = extend$4(makeMap('script,style,head,html,body,title,meta,param'), schema.getBlockElements());
19158        var textRootBlockElements = getTextRootBlockElements(schema);
19159        var nonEmptyElements = schema.getNonEmptyElements();
19160        var children = schema.children;
19161        var validate = settings.validate;
19162        var forcedRootBlockName = 'forced_root_block' in args ? args.forced_root_block : settings.forced_root_block;
19163        var rootBlockName = getRootBlockName(forcedRootBlockName);
19164        var whiteSpaceElements = schema.getWhiteSpaceElements();
19165        var startWhiteSpaceRegExp = /^[ \t\r\n]+/;
19166        var endWhiteSpaceRegExp = /[ \t\r\n]+$/;
19167        var allWhiteSpaceRegExp = /[ \t\r\n]+/g;
19168        var isAllWhiteSpaceRegExp = /^[ \t\r\n]+$/;
19169        var isInWhiteSpacePreservedElement = has$2(whiteSpaceElements, args.context) || has$2(whiteSpaceElements, settings.root_name);
19170        var addRootBlocks = function () {
19171          var node = rootNode.firstChild, rootBlockNode = null;
19172          var trim = function (rootBlock) {
19173            if (rootBlock) {
19174              node = rootBlock.firstChild;
19175              if (node && node.type === 3) {
19176                node.value = node.value.replace(startWhiteSpaceRegExp, '');
19177              }
19178              node = rootBlock.lastChild;
19179              if (node && node.type === 3) {
19180                node.value = node.value.replace(endWhiteSpaceRegExp, '');
19181              }
19182            }
19183          };
19184          if (!schema.isValidChild(rootNode.name, rootBlockName.toLowerCase())) {
19185            return;
19186          }
19187          while (node) {
19188            var next = node.next;
19189            if (node.type === 3 || node.type === 1 && node.name !== 'p' && !blockElements[node.name] && !node.attr('data-mce-type')) {
19190              if (!rootBlockNode) {
19191                rootBlockNode = createNode(rootBlockName, 1);
19192                rootBlockNode.attr(settings.forced_root_block_attrs);
19193                rootNode.insert(rootBlockNode, node);
19194                rootBlockNode.append(node);
19195              } else {
19196                rootBlockNode.append(node);
19197              }
19198            } else {
19199              trim(rootBlockNode);
19200              rootBlockNode = null;
19201            }
19202            node = next;
19203          }
19204          trim(rootBlockNode);
19205        };
19206        var createNode = function (name, type) {
19207          var node = new AstNode(name, type);
19208          var list;
19209          if (name in nodeFilters) {
19210            list = matchedNodes[name];
19211            if (list) {
19212              list.push(node);
19213            } else {
19214              matchedNodes[name] = [node];
19215            }
19216          }
19217          return node;
19218        };
19219        var removeWhitespaceBefore = function (node) {
19220          var blockElements = schema.getBlockElements();
19221          for (var textNode = node.prev; textNode && textNode.type === 3;) {
19222            var textVal = textNode.value.replace(endWhiteSpaceRegExp, '');
19223            if (textVal.length > 0) {
19224              textNode.value = textVal;
19225              return;
19226            }
19227            var textNodeNext = textNode.next;
19228            if (textNodeNext) {
19229              if (textNodeNext.type === 3 && textNodeNext.value.length) {
19230                textNode = textNode.prev;
19231                continue;
19232              }
19233              if (!blockElements[textNodeNext.name] && textNodeNext.name !== 'script' && textNodeNext.name !== 'style') {
19234                textNode = textNode.prev;
19235                continue;
19236              }
19237            }
19238            var sibling = textNode.prev;
19239            textNode.remove();
19240            textNode = sibling;
19241          }
19242        };
19243        var cloneAndExcludeBlocks = function (input) {
19244          var output = {};
19245          for (var name_2 in input) {
19246            if (name_2 !== 'li' && name_2 !== 'p') {
19247              output[name_2] = input[name_2];
19248            }
19249          }
19250          return output;
19251        };
19252        var isTextRootBlockEmpty = function (node) {
19253          var tempNode = node;
19254          while (isNonNullable(tempNode)) {
19255            if (tempNode.name in textRootBlockElements) {
19256              return isEmpty(schema, nonEmptyElements, whiteSpaceElements, tempNode);
19257            } else {
19258              tempNode = tempNode.parent;
19259            }
19260          }
19261          return false;
19262        };
19263        var parser = SaxParser({
19264          validate: validate,
19265          document: settings.document,
19266          allow_html_data_urls: settings.allow_html_data_urls,
19267          allow_svg_data_urls: settings.allow_svg_data_urls,
19268          allow_script_urls: settings.allow_script_urls,
19269          allow_conditional_comments: settings.allow_conditional_comments,
19270          preserve_cdata: settings.preserve_cdata,
19271          self_closing_elements: cloneAndExcludeBlocks(schema.getSelfClosingElements()),
19272          cdata: function (text) {
19273            node.append(createNode('#cdata', 4)).value = text;
19274          },
19275          text: function (text, raw) {
19276            var textNode;
19277            if (!isInWhiteSpacePreservedElement) {
19278              text = text.replace(allWhiteSpaceRegExp, ' ');
19279              if (isLineBreakNode(node.lastChild, blockElements)) {
19280                text = text.replace(startWhiteSpaceRegExp, '');
19281              }
19282            }
19283            if (text.length !== 0) {
19284              textNode = createNode('#text', 3);
19285              textNode.raw = !!raw;
19286              node.append(textNode).value = text;
19287            }
19288          },
19289          comment: function (text) {
19290            node.append(createNode('#comment', 8)).value = text;
19291          },
19292          pi: function (name, text) {
19293            node.append(createNode(name, 7)).value = text;
19294            removeWhitespaceBefore(node);
19295          },
19296          doctype: function (text) {
19297            var newNode = node.append(createNode('#doctype', 10));
19298            newNode.value = text;
19299            removeWhitespaceBefore(node);
19300          },
19301          start: function (name, attrs, empty) {
19302            var elementRule = validate ? schema.getElementRule(name) : {};
19303            if (elementRule) {
19304              var newNode = createNode(elementRule.outputName || name, 1);
19305              newNode.attributes = attrs;
19306              newNode.shortEnded = empty;
19307              node.append(newNode);
19308              var parent_2 = children[node.name];
19309              if (parent_2 && children[newNode.name] && !parent_2[newNode.name]) {
19310                invalidChildren.push(newNode);
19311              }
19312              var attrFiltersLen = attributeFilters.length;
19313              while (attrFiltersLen--) {
19314                var attrName = attributeFilters[attrFiltersLen].name;
19315                if (attrName in attrs.map) {
19316                  list = matchedAttributes[attrName];
19317                  if (list) {
19318                    list.push(newNode);
19319                  } else {
19320                    matchedAttributes[attrName] = [newNode];
19321                  }
19322                }
19323              }
19324              if (blockElements[name]) {
19325                removeWhitespaceBefore(newNode);
19326              }
19327              if (!empty) {
19328                node = newNode;
19329              }
19330              if (!isInWhiteSpacePreservedElement && whiteSpaceElements[name]) {
19331                isInWhiteSpacePreservedElement = true;
19332              }
19333            }
19334          },
19335          end: function (name) {
19336            var textNode, text, sibling;
19337            var elementRule = validate ? schema.getElementRule(name) : {};
19338            if (elementRule) {
19339              if (blockElements[name]) {
19340                if (!isInWhiteSpacePreservedElement) {
19341                  textNode = node.firstChild;
19342                  if (textNode && textNode.type === 3) {
19343                    text = textNode.value.replace(startWhiteSpaceRegExp, '');
19344                    if (text.length > 0) {
19345                      textNode.value = text;
19346                      textNode = textNode.next;
19347                    } else {
19348                      sibling = textNode.next;
19349                      textNode.remove();
19350                      textNode = sibling;
19351                      while (textNode && textNode.type === 3) {
19352                        text = textNode.value;
19353                        sibling = textNode.next;
19354                        if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) {
19355                          textNode.remove();
19356                          textNode = sibling;
19357                        }
19358                        textNode = sibling;
19359                      }
19360                    }
19361                  }
19362                  textNode = node.lastChild;
19363                  if (textNode && textNode.type === 3) {
19364                    text = textNode.value.replace(endWhiteSpaceRegExp, '');
19365                    if (text.length > 0) {
19366                      textNode.value = text;
19367                      textNode = textNode.prev;
19368                    } else {
19369                      sibling = textNode.prev;
19370                      textNode.remove();
19371                      textNode = sibling;
19372                      while (textNode && textNode.type === 3) {
19373                        text = textNode.value;
19374                        sibling = textNode.prev;
19375                        if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) {
19376                          textNode.remove();
19377                          textNode = sibling;
19378                        }
19379                        textNode = sibling;
19380                      }
19381                    }
19382                  }
19383                }
19384              }
19385              if (isInWhiteSpacePreservedElement && whiteSpaceElements[name]) {
19386                isInWhiteSpacePreservedElement = false;
19387              }
19388              var isNodeEmpty = isEmpty(schema, nonEmptyElements, whiteSpaceElements, node);
19389              var parentNode = node.parent;
19390              if (elementRule.paddInEmptyBlock && isNodeEmpty && isTextRootBlockEmpty(node)) {
19391                paddEmptyNode(settings, args, blockElements, node);
19392              } else if (elementRule.removeEmpty && isNodeEmpty) {
19393                if (blockElements[node.name]) {
19394                  node.empty().remove();
19395                } else {
19396                  node.unwrap();
19397                }
19398              } else if (elementRule.paddEmpty && (isPaddedWithNbsp(node) || isNodeEmpty)) {
19399                paddEmptyNode(settings, args, blockElements, node);
19400              }
19401              node = parentNode;
19402            }
19403          }
19404        }, schema);
19405        var rootNode = node = new AstNode(args.context || settings.root_name, 11);
19406        parser.parse(html, args.format);
19407        if (validate && invalidChildren.length) {
19408          if (!args.context) {
19409            fixInvalidChildren(invalidChildren);
19410          } else {
19411            args.invalid = true;
19412          }
19413        }
19414        if (rootBlockName && (rootNode.name === 'body' || args.isRootContent)) {
19415          addRootBlocks();
19416        }
19417        if (!args.invalid) {
19418          for (name in matchedNodes) {
19419            if (!has$2(matchedNodes, name)) {
19420              continue;
19421            }
19422            list = nodeFilters[name];
19423            nodes = matchedNodes[name];
19424            fi = nodes.length;
19425            while (fi--) {
19426              if (!nodes[fi].parent) {
19427                nodes.splice(fi, 1);
19428              }
19429            }
19430            for (i = 0, l = list.length; i < l; i++) {
19431              list[i](nodes, name, args);
19432            }
19433          }
19434          for (i = 0, l = attributeFilters.length; i < l; i++) {
19435            list = attributeFilters[i];
19436            if (list.name in matchedAttributes) {
19437              nodes = matchedAttributes[list.name];
19438              fi = nodes.length;
19439              while (fi--) {
19440                if (!nodes[fi].parent) {
19441                  nodes.splice(fi, 1);
19442                }
19443              }
19444              for (fi = 0, fl = list.callbacks.length; fi < fl; fi++) {
19445                list.callbacks[fi](nodes, list.name, args);
19446              }
19447            }
19448          }
19449        }
19450        return rootNode;
19451      };
19452      var exports = {
19453        schema: schema,
19454        addAttributeFilter: addAttributeFilter,
19455        getAttributeFilters: getAttributeFilters,
19456        addNodeFilter: addNodeFilter,
19457        getNodeFilters: getNodeFilters,
19458        filterNode: filterNode,
19459        parse: parse
19460      };
19461      register$1(exports, settings);
19462      register$2(exports, settings);
19463      return exports;
19464    };
19465
19466    var register = function (htmlParser, settings, dom) {
19467      htmlParser.addAttributeFilter('data-mce-tabindex', function (nodes, name) {
19468        var i = nodes.length;
19469        while (i--) {
19470          var node = nodes[i];
19471          node.attr('tabindex', node.attr('data-mce-tabindex'));
19472          node.attr(name, null);
19473        }
19474      });
19475      htmlParser.addAttributeFilter('src,href,style', function (nodes, name) {
19476        var internalName = 'data-mce-' + name;
19477        var urlConverter = settings.url_converter;
19478        var urlConverterScope = settings.url_converter_scope;
19479        var i = nodes.length;
19480        while (i--) {
19481          var node = nodes[i];
19482          var value = node.attr(internalName);
19483          if (value !== undefined) {
19484            node.attr(name, value.length > 0 ? value : null);
19485            node.attr(internalName, null);
19486          } else {
19487            value = node.attr(name);
19488            if (name === 'style') {
19489              value = dom.serializeStyle(dom.parseStyle(value), node.name);
19490            } else if (urlConverter) {
19491              value = urlConverter.call(urlConverterScope, value, name, node.name);
19492            }
19493            node.attr(name, value.length > 0 ? value : null);
19494          }
19495        }
19496      });
19497      htmlParser.addAttributeFilter('class', function (nodes) {
19498        var i = nodes.length;
19499        while (i--) {
19500          var node = nodes[i];
19501          var value = node.attr('class');
19502          if (value) {
19503            value = node.attr('class').replace(/(?:^|\s)mce-item-\w+(?!\S)/g, '');
19504            node.attr('class', value.length > 0 ? value : null);
19505          }
19506        }
19507      });
19508      htmlParser.addAttributeFilter('data-mce-type', function (nodes, name, args) {
19509        var i = nodes.length;
19510        while (i--) {
19511          var node = nodes[i];
19512          if (node.attr('data-mce-type') === 'bookmark' && !args.cleanup) {
19513            var hasChildren = Optional.from(node.firstChild).exists(function (firstChild) {
19514              return !isZwsp(firstChild.value);
19515            });
19516            if (hasChildren) {
19517              node.unwrap();
19518            } else {
19519              node.remove();
19520            }
19521          }
19522        }
19523      });
19524      htmlParser.addNodeFilter('noscript', function (nodes) {
19525        var i = nodes.length;
19526        while (i--) {
19527          var node = nodes[i].firstChild;
19528          if (node) {
19529            node.value = Entities.decode(node.value);
19530          }
19531        }
19532      });
19533      htmlParser.addNodeFilter('script,style', function (nodes, name) {
19534        var trim = function (value) {
19535          return value.replace(/(<!--\[CDATA\[|\]\]-->)/g, '\n').replace(/^[\r\n]*|[\r\n]*$/g, '').replace(/^\s*((<!--)?(\s*\/\/)?\s*<!\[CDATA\[|(<!--\s*)?\/\*\s*<!\[CDATA\[\s*\*\/|(\/\/)?\s*<!--|\/\*\s*<!--\s*\*\/)\s*[\r\n]*/gi, '').replace(/\s*(\/\*\s*\]\]>\s*\*\/(-->)?|\s*\/\/\s*\]\]>(-->)?|\/\/\s*(-->)?|\]\]>|\/\*\s*-->\s*\*\/|\s*-->\s*)\s*$/g, '');
19536        };
19537        var i = nodes.length;
19538        while (i--) {
19539          var node = nodes[i];
19540          var value = node.firstChild ? node.firstChild.value : '';
19541          if (name === 'script') {
19542            var type = node.attr('type');
19543            if (type) {
19544              node.attr('type', type === 'mce-no/type' ? null : type.replace(/^mce\-/, ''));
19545            }
19546            if (settings.element_format === 'xhtml' && value.length > 0) {
19547              node.firstChild.value = '// <![CDATA[\n' + trim(value) + '\n// ]]>';
19548            }
19549          } else {
19550            if (settings.element_format === 'xhtml' && value.length > 0) {
19551              node.firstChild.value = '<!--\n' + trim(value) + '\n-->';
19552            }
19553          }
19554        }
19555      });
19556      htmlParser.addNodeFilter('#comment', function (nodes) {
19557        var i = nodes.length;
19558        while (i--) {
19559          var node = nodes[i];
19560          if (settings.preserve_cdata && node.value.indexOf('[CDATA[') 
19560=== 0) {
19561            node.name = '#cdata';
19562            node.type = 4;
19563            node.value = dom.decode(node.value.replace(/^\[CDATA\[|\]\]$/g, ''));
19564          } else if (node.value.indexOf('mce:protected ') === 0) {
19565            node.name = '#text';
19566            node.type = 3;
19567            node.raw = true;
19568            node.value = unescape(node.value).substr(14);
19569          }
19570        }
19571      });
19572      htmlParser.addNodeFilter('xml:namespace,input', function (nodes, name) {
19573        var i = nodes.length;
19574        while (i--) {
19575          var node = nodes[i];
19576          if (node.type === 7) {
19577            node.remove();
19578          } else if (node.type === 1) {
19579            if (name === 'input' && !node.attr('type')) {
19580              node.attr('type', 'text');
19581            }
19582          }
19583        }
19584      });
19585      htmlParser.addAttributeFilter('data-mce-type', function (nodes) {
19586        each$k(nodes, function (node) {
19587          if (node.attr('data-mce-type') === 'format-caret') {
19588            if (node.isEmpty(htmlParser.schema.getNonEmptyElements())) {
19589              node.remove();
19590            } else {
19591              node.unwrap();
19592            }
19593          }
19594        });
19595      });
19596      htmlParser.addAttributeFilter('data-mce-src,data-mce-href,data-mce-style,' + 'data-mce-selected,data-mce-expando,' + 'data-mce-type,data-mce-resize,data-mce-placeholder', function (nodes, name) {
19597        var i = nodes.length;
19598        while (i--) {
19599          nodes[i].attr(name, null);
19600        }
19601      });
19602    };
19603    var trimTrailingBr = function (rootNode) {
19604      var isBr = function (node) {
19605        return node && node.name === 'br';
19606      };
19607      var brNode1 = rootNode.lastChild;
19608      if (isBr(brNode1)) {
19609        var brNode2 = brNode1.prev;
19610        if (isBr(brNode2)) {
19611          brNode1.remove();
19612          brNode2.remove();
19613        }
19614      }
19615    };
19616
19617    var preProcess = function (editor, node, args) {
19618      var oldDoc;
19619      var dom = editor.dom;
19620      var clonedNode = node.cloneNode(true);
19621      var impl = document.implementation;
19622      if (impl.createHTMLDocument) {
19623        var doc_1 = impl.createHTMLDocument('');
19624        Tools.each(clonedNode.nodeName === 'BODY' ? clonedNode.childNodes : [clonedNode], function (node) {
19625          doc_1.body.appendChild(doc_1.importNode(node, true));
19626        });
19627        if (clonedNode.nodeName !== 'BODY') {
19628          clonedNode = doc_1.body.firstChild;
19629        } else {
19630          clonedNode = doc_1.body;
19631        }
19632        oldDoc = dom.doc;
19633        dom.doc = doc_1;
19634      }
19635      firePreProcess(editor, __assign(__assign({}, args), { node: clonedNode }));
19636      if (oldDoc) {
19637        dom.doc = oldDoc;
19638      }
19639      return clonedNode;
19640    };
19641    var shouldFireEvent = function (editor, args) {
19642      return editor && editor.hasEventListeners('PreProcess') && !args.no_events;
19643    };
19644    var process = function (editor, node, args) {
19645      return shouldFireEvent(editor, args) ? preProcess(editor, node, args) : node;
19646    };
19647
19648    var addTempAttr = function (htmlParser, tempAttrs, name) {
19649      if (Tools.inArray(tempAttrs, name) === -1) {
19650        htmlParser.addAttributeFilter(name, function (nodes, name) {
19651          var i = nodes.length;
19652          while (i--) {
19653            nodes[i].attr(name, null);
19654          }
19655        });
19656        tempAttrs.push(name);
19657      }
19658    };
19659    var postProcess = function (editor, args, content) {
19660      if (!args.no_events && editor) {
19661        var outArgs = firePostProcess(editor, __assign(__assign({}, args), { content: content }));
19662        return outArgs.content;
19663      } else {
19664        return content;
19665      }
19666    };
19667    var getHtmlFromNode = function (dom, node, args) {
19668      var html = trim$3(args.getInner ? node.innerHTML : dom.getOuterHTML(node));
19669      return args.selection || isWsPreserveElement(SugarElement.fromDom(node)) ? html : Tools.trim(html);
19670    };
19671    var parseHtml = function (htmlParser, html, args) {
19672      var parserArgs = args.selection ? __assign({ forced_root_block: false }, args) : args;
19673      var rootNode = htmlParser.parse(html, parserArgs);
19674      trimTrailingBr(rootNode);
19675      return rootNode;
19676    };
19677    var serializeNode = function (settings, schema, node) {
19678      var htmlSerializer = HtmlSerializer(settings, schema);
19679      return htmlSerializer.serialize(node);
19680    };
19681    var toHtml = function (editor, settings, schema, rootNode, args) {
19682      var content = serializeNode(settings, schema, rootNode);
19683      return postProcess(editor, args, content);
19684    };
19685    var DomSerializerImpl = function (settings, editor) {
19686      var tempAttrs = ['data-mce-selected'];
19687      var dom = editor && editor.dom ? editor.dom : DOMUtils.DOM;
19688      var schema = editor && editor.schema ? editor.schema : Schema(settings);
19689      settings.entity_encoding = settings.entity_encoding || 'named';
19690      settings.remove_trailing_brs = 'remove_trailing_brs' in settings ? settings.remove_trailing_brs : true;
19691      var htmlParser = DomParser(settings, schema);
19692      register(htmlParser, settings, dom);
19693      var serialize = function (node, parserArgs) {
19694        if (parserArgs === void 0) {
19695          parserArgs = {};
19696        }
19697        var args = __assign({ format: 'html' }, parserArgs);
19698        var targetNode = process(editor, node, args);
19699        var html = getHtmlFromNode(dom, targetNode, args);
19700        var rootNode = parseHtml(htmlParser, html, args);
19701        return args.format === 'tree' ? rootNode : toHtml(editor, settings, schema, rootNode, args);
19702      };
19703      return {
19704        schema: schema,
19705        addNodeFilter: htmlParser.addNodeFilter,
19706        addAttributeFilter: htmlParser.addAttributeFilter,
19707        serialize: serialize,
19708        addRules: schema.addValidElements,
19709        setRules: schema.setValidElements,
19710        addTempAttr: curry(addTempAttr, htmlParser, tempAttrs),
19711        getTempAttrs: constant(tempAttrs),
19712        getNodeFilters: htmlParser.getNodeFilters,
19713        getAttributeFilters: htmlParser.getAttributeFilters
19714      };
19715    };
19716
19717    var DomSerializer = function (settings, editor) {
19718      var domSerializer = DomSerializerImpl(settings, editor);
19719      return {
19720        schema: domSerializer.schema,
19721        addNodeFilter: domSerializer.addNodeFilter,
19722        addAttributeFilter: domSerializer.addAttributeFilter,
19723        serialize: domSerializer.serialize,
19724        addRules: domSerializer.addRules,
19725        setRules: domSerializer.setRules,
19726        addTempAttr: domSerializer.addTempAttr,
19727        getTempAttrs: domSerializer.getTempAttrs,
19728        getNodeFilters: domSerializer.getNodeFilters,
19729        getAttributeFilters: domSerializer.getAttributeFilters
19730      };
19731    };
19732
19733    var defaultFormat = 'html';
19734    var getContent = function (editor, args) {
19735      if (args === void 0) {
19736        args = {};
19737      }
19738      var format = args.format ? args.format : defaultFormat;
19739      return getContent$2(editor, args, format);
19740    };
19741
19742    var setContent = function (editor, content, args) {
19743      if (args === void 0) {
19744        args = {};
19745      }
19746      return setContent$2(editor, content, args);
19747    };
19748
19749    var DOM$7 = DOMUtils.DOM;
19750    var restoreOriginalStyles = function (editor) {
19751      DOM$7.setStyle(editor.id, 'display', editor.orgDisplay);
19752    };
19753    var safeDestroy = function (x) {
19754      return Optional.from(x).each(function (x) {
19755        return x.destroy();
19756      });
19757    };
19758    var clearDomReferences = function (editor) {
19759      editor.contentAreaContainer = editor.formElement = editor.container = editor.editorContainer = null;
19760      editor.bodyElement = editor.contentDocument = editor.contentWindow = null;
19761      editor.iframeElement = editor.targetElm = null;
19762      if (editor.selection) {
19763        editor.selection = editor.selection.win = editor.selection.dom = editor.selection.dom.doc = null;
19764      }
19765    };
19766    var restoreForm = function (editor) {
19767      var form = editor.formElement;
19768      if (form) {
19769        if (form._mceOldSubmit) {
19770          form.submit = form._mceOldSubmit;
19771          form._mceOldSubmit = null;
19772        }
19773        DOM$7.unbind(form, 'submit reset', editor.formEventDelegate);
19774      }
19775    };
19776    var remove = function (editor) {
19777      if (!editor.removed) {
19778        var _selectionOverrides = editor._selectionOverrides, editorUpload = editor.editorUpload;
19779        var body = editor.getBody();
19780        var element = editor.getElement();
19781        if (body) {
19782          editor.save({ is_removing: true });
19783        }
19784        editor.removed = true;
19785        editor.unbindAllNativeEvents();
19786        if (editor.hasHiddenInput && element) {
19787          DOM$7.remove(element.nextSibling);
19788        }
19789        fireRemove(editor);
19790        editor.editorManager.remove(editor);
19791        if (!editor.inline && body) {
19792          restoreOriginalStyles(editor);
19793        }
19794        fireDetach(editor);
19795        DOM$7.remove(editor.getContainer());
19796        safeDestroy(_selectionOverrides);
19797        safeDestroy(editorUpload);
19798        editor.destroy();
19799      }
19800    };
19801    var destroy = function (editor, automatic) {
19802      var selection = editor.selection, dom = editor.dom;
19803      if (editor.destroyed) {
19804        return;
19805      }
19806      if (!automatic && !editor.removed) {
19807        editor.remove();
19808        return;
19809      }
19810      if (!automatic) {
19811        editor.editorManager.off('beforeunload', editor._beforeUnload);
19812        if (editor.theme && editor.theme.destroy) {
19813          editor.theme.destroy();
19814        }
19815        safeDestroy(selection);
19816        safeDestroy(dom);
19817      }
19818      restoreForm(editor);
19819      clearDomReferences(editor);
19820      editor.destroyed = true;
19821    };
19822
19823    var deep = function (old, nu) {
19824      var bothObjects = isObject(old) && isObject(nu);
19825      return bothObjects ? deepMerge(old, nu) : nu;
19826    };
19827    var baseMerge = function (merger) {
19828      return function () {
19829        var objects = [];
19830        for (var _i = 0; _i < arguments.length; _i++) {
19831          objects[_i] = arguments[_i];
19832        }
19833        if (objects.length === 0) {
19834          throw new Error('Can\'t merge zero objects');
19835        }
19836        var ret = {};
19837        for (var j = 0; j < objects.length; j++) {
19838          var curObject = objects[j];
19839          for (var key in curObject) {
19840            if (has$2(curObject, key)) {
19841              ret[key] = merger(ret[key], curObject[key]);
19842            }
19843          }
19844        }
19845        return ret;
19846      };
19847    };
19848    var deepMerge = baseMerge(deep);
19849
19850    var deprecatedSettings = ('autoresize_on_init,content_editable_state,convert_fonts_to_spans,inline_styles,padd_empty_with_br,block_elements,' + 'boolean_attributes,editor_deselector,editor_selector,elements,file_browser_callback_types,filepicker_validator_handler,' + 'force_hex_style_colors,force_p_newlines,gecko_spellcheck,images_dataimg_filter,media_scripts,mode,move_caret_before_on_enter_elements,' + 'non_empty_elements,self_closing_elements,short_ended_elements,special,spellchecker_select_languages,spellchecker_whitelist,' + 'tab_focus,table_responsive_width,text_block_elements,text_inline_elements,toolbar_drawer,types,validate,whitespace_elements,' + 'paste_word_valid_elements,paste_retain_style_properties,paste_convert_word_fake_lists').split(',');
19851    var deprecatedPlugins = 'bbcode,colorpicker,contextmenu,fullpage,legacyoutput,spellchecker,textcolor'.split(',');
19852    var movedToPremiumPlugins = 'imagetools,toc'.split(',');
19853    var getDeprecatedSettings = function (settings) {
19854      var settingNames = filter$4(deprecatedSettings, function (setting) {
19855        return has$2(settings, setting);
19856      });
19857      var forcedRootBlock = settings.forced_root_block;
19858      if (forcedRootBlock === false || forcedRootBlock === '') {
19859        settingNames.push('forced_root_block (false only)');
19860      }
19861      return sort(settingNames);
19862    };
19863    var getDeprecatedPlugins = function (settings) {
19864      var plugins = Tools.makeMap(settings.plugins, ' ');
19865      var hasPlugin = function (plugin) {
19866        return has$2(plugins, plugin);
19867      };
19868      var pluginNames = __spreadArray(__spreadArray([], filter$4(deprecatedPlugins, hasPlugin), true), bind(movedToPremiumPlugins, function (plugin) {
19869        return hasPlugin(plugin) ? [plugin + ' (moving to premium)'] : [];
19870      }), true);
19871      return sort(pluginNames);
19872    };
19873    var logDeprecationsWarning = function (rawSettings, finalSettings) {
19874      var deprecatedSettings = getDeprecatedSettings(rawSettings);
19875      var deprecatedPlugins = getDeprecatedPlugins(finalSettings);
19876      var hasDeprecatedPlugins = deprecatedPlugins.length > 0;
19877      var hasDeprecatedSettings = deprecatedSettings.length > 0;
19878      var isLegacyMobileTheme = finalSettings.theme === 'mobile';
19879      if (hasDeprecatedPlugins || hasDeprecatedSettings || isLegacyMobileTheme) {
19880        var listJoiner = '\n- ';
19881        var themesMessage = isLegacyMobileTheme ? '\n\nThemes:' + listJoiner + 'mobile' : '';
19882        var pluginsMessage = hasDeprecatedPlugins ? '\n\nPlugins:' + listJoiner + deprecatedPlugins.join(listJoiner) : '';
19883        var settingsMessage = hasDeprecatedSettings ? '\n\nSettings:' + listJoiner + deprecatedSettings.join(listJoiner) : '';
19884        console.warn('The following deprecated features are currently enabled, these will be removed in TinyMCE 6.0. ' + 'See https://www.tiny.cloud/docs/release-notes/6.0-upcoming-changes/ for more information.' + themesMessage + pluginsMessage + settingsMessage);
19885      }
19886    };
19887
19888    var sectionResult = function (sections, settings) {
19889      return {
19890        sections: constant(sections),
19891        settings: constant(settings)
19892      };
19893    };
19894    var deviceDetection = detect().deviceType;
19895    var isTouch = deviceDetection.isTouch();
19896    var isPhone = deviceDetection.isPhone();
19897    var isTablet = deviceDetection.isTablet();
19898    var legacyMobilePlugins = [
19899      'lists',
19900      'autolink',
19901      'autosave'
19902    ];
19903    var defaultTouchSettings = {
19904      table_grid: false,
19905      object_resizing: false,
19906      resize: false
19907    };
19908    var normalizePlugins = function (plugins) {
19909      var pluginNames = isArray$1(plugins) ? plugins.join(' ') : plugins;
19910      var trimmedPlugins = map$3(isString$1(pluginNames) ? pluginNames.split(' ') : [], trim$5);
19911      return filter$4(trimmedPlugins, function (item) {
19912        return item.length > 0;
19913      });
19914    };
19915    var filterLegacyMobilePlugins = function (plugins) {
19916      return filter$4(plugins, curry(contains$3, legacyMobilePlugins));
19917    };
19918    var extractSections = function (keys, settings) {
19919      var result = bifilter(settings, function (value, key) {
19920        return contains$3(keys, key);
19921      });
19922      return sectionResult(result.t, result.f);
19923    };
19924    var getSection = function (sectionResult, name, defaults) {
19925      if (defaults === void 0) {
19926        defaults = {};
19927      }
19928      var sections = sectionResult.sections();
19929      var sectionSettings = get$9(sections, name).getOr({});
19930      return Tools.extend({}, defaults, sectionSettings);
19931    };
19932    var hasSection = function (sectionResult, name) {
19933      return has$2(sectionResult.sections(), name);
19934    };
19935    var isSectionTheme = function (sectionResult, name, theme) {
19936      var section = sectionResult.sections();
19937      return hasSection(sectionResult, name) && section[name].theme === theme;
19938    };
19939    var getSectionConfig = function (sectionResult, name) {
19940      return hasSection(sectionResult, name) ? sectionResult.sections()[name] : {};
19941    };
19942    var getToolbarMode = function (settings, defaultVal) {
19943      return get$9(settings, 'toolbar_mode').orThunk(function () {
19944        return get$9(settings, 'toolbar_drawer').map(function (val) {
19945          return val === false ? 'wrap' : val;
19946        });
19947      }).getOr(defaultVal);
19948    };
19949    var getDefaultSettings = function (settings, id, documentBaseUrl, isTouch, editor) {
19950      var baseDefaults = {
19951        id: id,
19952        theme: 'silver',
19953        toolbar_mode: getToolbarMode(settings, 'floating'),
19954        plugins: '',
19955        document_base_url: documentBaseUrl,
19956        add_form_submit_trigger: true,
19957        submit_patch: true,
19958        add_unload_trigger: true,
19959        convert_urls: true,
19960        relative_urls: true,
19961        remove_script_host: true,
19962        object_resizing: true,
19963        doctype: '<!DOCTYPE html>',
19964        visual: true,
19965        font_size_legacy_values: 'xx-small,small,medium,large,x-large,xx-large,300%',
19966        forced_root_block: 'p',
19967        hidden_input: true,
19968        inline_styles: true,
19969        convert_fonts_to_spans: true,
19970        indent: true,
19971        indent_before: '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,f
19971igure,figcaption,option,optgroup,datalist',
19972        indent_after: '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',
19973        entity_encoding: 'named',
19974        url_converter: editor.convertURL,
19975        url_converter_scope: editor
19976      };
19977      return __assign(__assign({}, baseDefaults), isTouch ? defaultTouchSettings : {});
19978    };
19979    var getDefaultMobileSettings = function (mobileSettings, isPhone) {
19980      var defaultMobileSettings = {
19981        resize: false,
19982        toolbar_mode: getToolbarMode(mobileSettings, 'scrolling'),
19983        toolbar_sticky: false
19984      };
19985      var defaultPhoneSettings = { menubar: false };
19986      return __assign(__assign(__assign({}, defaultTouchSettings), defaultMobileSettings), isPhone ? defaultPhoneSettings : {});
19987    };
19988    var getExternalPlugins = function (overrideSettings, settings) {
19989      var userDefinedExternalPlugins = settings.external_plugins ? settings.external_plugins : {};
19990      if (overrideSettings && overrideSettings.external_plugins) {
19991        return Tools.extend({}, overrideSettings.external_plugins, userDefinedExternalPlugins);
19992      } else {
19993        return userDefinedExternalPlugins;
19994      }
19995    };
19996    var combinePlugins = function (forcedPlugins, plugins) {
19997      return [].concat(normalizePlugins(forcedPlugins)).concat(normalizePlugins(plugins));
19998    };
19999    var getPlatformPlugins = function (isMobileDevice, sectionResult, desktopPlugins, mobilePlugins) {
20000      if (isMobileDevice && isSectionTheme(sectionResult, 'mobile', 'mobile')) {
20001        return filterLegacyMobilePlugins(mobilePlugins);
20002      } else if (isMobileDevice && hasSection(sectionResult, 'mobile')) {
20003        return mobilePlugins;
20004      } else {
20005        return desktopPlugins;
20006      }
20007    };
20008    var processPlugins = function (isMobileDevice, sectionResult, defaultOverrideSettings, settings) {
20009      var forcedPlugins = normalizePlugins(defaultOverrideSettings.forced_plugins);
20010      var desktopPlugins = normalizePlugins(settings.plugins);
20011      var mobileConfig = getSectionConfig(sectionResult, 'mobile');
20012      var mobilePlugins = mobileConfig.plugins ? normalizePlugins(mobileConfig.plugins) : desktopPlugins;
20013      var platformPlugins = getPlatformPlugins(isMobileDevice, sectionResult, desktopPlugins, mobilePlugins);
20014      var combinedPlugins = combinePlugins(forcedPlugins, platformPlugins);
20015      if (Env.browser.isIE() && contains$3(combinedPlugins, 'rtc')) {
20016        throw new Error('RTC plugin is not supported on IE 11.');
20017      }
20018      return Tools.extend(settings, { plugins: combinedPlugins.join(' ') });
20019    };
20020    var isOnMobile = function (isMobileDevice, sectionResult) {
20021      return isMobileDevice && hasSection(sectionResult, 'mobile');
20022    };
20023    var combineSettings = function (isMobileDevice, isPhone, defaultSettings, defaultOverrideSettings, settings) {
20024      var defaultDeviceSettings = isMobileDevice ? { mobile: getDefaultMobileSettings(settings.mobile || {}, isPhone) } : {};
20025      var sectionResult = extractSections(['mobile'], deepMerge(defaultDeviceSettings, settings));
20026      var extendedSettings = Tools.extend(defaultSettings, defaultOverrideSettings, sectionResult.settings(), isOnMobile(isMobileDevice, sectionResult) ? getSection(sectionResult, 'mobile') : {}, {
20027        validate: true,
20028        external_plugins: getExternalPlugins(defaultOverrideSettings, sectionResult.settings())
20029      });
20030      return processPlugins(isMobileDevice, sectionResult, defaultOverrideSettings, extendedSettings);
20031    };
20032    var getEditorSettings = function (editor, id, documentBaseUrl, defaultOverrideSettings, settings) {
20033      var defaultSettings = getDefaultSettings(settings, id, documentBaseUrl, isTouch, editor);
20034      var finalSettings = combineSettings(isPhone || isTablet, isPhone, defaultSettings, defaultOverrideSettings, settings);
20035      if (finalSettings.deprecation_warnings !== false) {
20036        logDeprecationsWarning(settings, finalSettings);
20037      }
20038      return finalSettings;
20039    };
20040    var getFiltered = function (predicate, editor, name) {
20041      return Optional.from(editor.settings[name]).filter(predicate);
20042    };
20043    var getParamObject = function (value) {
20044      var output = {};
20045      if (typeof value === 'string') {
20046        each$k(value.indexOf('=') > 0 ? value.split(/[;,](?![^=;,]*(?:[;,]|$))/) : value.split(','), function (val) {
20047          var arr = val.split('=');
20048          if (arr.length > 1) {
20049            output[Tools.trim(arr[0])] = Tools.trim(arr[1]);
20050          } else {
20051            output[Tools.trim(arr[0])] = Tools.trim(arr[0]);
20052          }
20053        });
20054      } else {
20055        output = value;
20056      }
20057      return output;
20058    };
20059    var isArrayOf = function (p) {
20060      return function (a) {
20061        return isArray$1(a) && forall(a, p);
20062      };
20063    };
20064    var getParam = function (editor, name, defaultVal, type) {
20065      var value = name in editor.settings ? editor.settings[name] : defaultVal;
20066      if (type === 'hash') {
20067        return getParamObject(value);
20068      } else if (type === 'string') {
20069        return getFiltered(isString$1, editor, name).getOr(defaultVal);
20070      } else if (type === 'number') {
20071        return getFiltered(isNumber, editor, name).getOr(defaultVal);
20072      } else if (type === 'boolean') {
20073        return getFiltered(isBoolean, editor, name).getOr(defaultVal);
20074      } else if (type === 'object') {
20075        return getFiltered(isObject, editor, name).getOr(defaultVal);
20076      } else if (type === 'array') {
20077        return getFiltered(isArray$1, editor, name).getOr(defaultVal);
20078      } else if (type === 'string[]') {
20079        return getFiltered(isArrayOf(isString$1), editor, name).getOr(defaultVal);
20080      } else if (type === 'function') {
20081        return getFiltered(isFunction, editor, name).getOr(defaultVal);
20082      } else {
20083        return value;
20084      }
20085    };
20086
20087    var CreateIconManager = function () {
20088      var lookup = {};
20089      var add = function (id, iconPack) {
20090        lookup[id] = iconPack;
20091      };
20092      var get = function (id) {
20093        if (lookup[id]) {
20094          return lookup[id];
20095        }
20096        return { icons: {} };
20097      };
20098      var has = function (id) {
20099        return has$2(lookup, id);
20100      };
20101      return {
20102        add: add,
20103        get: get,
20104        has: has
20105      };
20106    };
20107    var IconManager = CreateIconManager();
20108
20109    var getProp = function (propName, elm) {
20110      var rawElm = elm.dom;
20111      return rawElm[propName];
20112    };
20113    var getComputedSizeProp = function (propName, elm) {
20114      return parseInt(get$5(elm, propName), 10);
20115    };
20116    var getClientWidth = curry(getProp, 'clientWidth');
20117    var getClientHeight = curry(getProp, 'clientHeight');
20118    var getMarginTop = curry(getComputedSizeProp, 'margin-top');
20119    var getMarginLeft = curry(getComputedSizeProp, 'margin-left');
20120    var getBoundingClientRect = function (elm) {
20121      return elm.dom.getBoundingClientRect();
20122    };
20123    var isInsideElementContentArea = function (bodyElm, clientX, clientY) {
20124      var clientWidth = getClientWidth(bodyElm);
20125      var clientHeight = getClientHeight(bodyElm);
20126      return clientX >= 0 && clientY >= 0 && clientX <= clientWidth && clientY <= clientHeight;
20127    };
20128    var transpose = function (inline, elm, clientX, clientY) {
20129      var clientRect = getBoundingClientRect(elm);
20130      var deltaX = inline ? clientRect.left + elm.dom.clientLeft + getMarginLeft(elm) : 0;
20131      var deltaY = inline ? clientRect.top + elm.dom.clientTop + getMarginTop(elm) : 0;
20132      var x = clientX - deltaX;
20133      var y = clientY - deltaY;
20134      return {
20135        x: x,
20136        y: y
20137      };
20138    };
20139    var isXYInContentArea = function (editor, clientX, clientY) {
20140      var bodyElm = SugarElement.fromDom(editor.getBody());
20141      var targetElm = editor.inline ? bodyElm : documentElement(bodyElm);
20142      var transposedPoint = transpose(editor.inline, targetElm, clientX, clientY);
20143      return isInsideElementContentArea(targetElm, transposedPoint.x, transposedPoint.y);
20144    };
20145    var fromDomSafe = function (node) {
20146      return Optional.from(node).map(SugarElement.fromDom);
20147    };
20148    var isEditorAttachedToDom = function (editor) {
20149      var rawContainer = editor.inline ? editor.getBody() : editor.getContentAreaContainer();
20150      return fromDomSafe(rawContainer).map(inBody).getOr(false);
20151    };
20152
20153    var NotificationManagerImpl = function () {
20154      var unimplemented = function () {
20155        throw new Error('Theme did not provide a NotificationManager implementation.');
20156      };
20157      return {
20158        open: unimplemented,
20159        close: unimplemented,
20160        reposition: unimplemented,
20161        getArgs: unimplemented
20162      };
20163    };
20164
20165    var NotificationManager = function (editor) {
20166      var notifications = [];
20167      var getImplementation = function () {
20168        var theme = editor.theme;
20169        return theme && theme.getNotificationManagerImpl ? theme.getNotificationManagerImpl() : NotificationManagerImpl();
20170      };
20171      var getTopNotification = function () {
20172        return Optional.from(notifications[0]);
20173      };
20174      var isEqual = function (a, b) {
20175        return a.type === b.type && a.text === b.text && !a.progressBar && !a.timeout && !b.progressBar && !b.timeout;
20176      };
20177      var reposition = function () {
20178        if (notifications.length > 0) {
20179          getImplementation().reposition(notifications);
20180        }
20181      };
20182      var addNotification = function (notification) {
20183        notifications.push(notification);
20184      };
20185      var closeNotification = function (notification) {
20186        findIndex$2(notifications, function (otherNotification) {
20187          return otherNotification === notification;
20188        }).each(function (index) {
20189          notifications.splice(index, 1);
20190        });
20191      };
20192      var open = function (spec, fireEvent) {
20193        if (fireEvent === void 0) {
20194          fireEvent = true;
20195        }
20196        if (editor.removed || !isEditorAttachedToDom(editor)) {
20197          return;
20198        }
20199        if (fireEvent) {
20200          editor.fire('BeforeOpenNotification', { notification: spec });
20201        }
20202        return find$3(notifications, function (notification) {
20203          return isEqual(getImplementation().getArgs(notification), spec);
20204        }).getOrThunk(function () {
20205          editor.editorManager.setActive(editor);
20206          var notification = getImplementation().open(spec, function () {
20207            closeNotification(notification);
20208            reposition();
20209            getTopNotification().fold(function () {
20210              return editor.focus();
20211            }, function (top) {
20212              return focus$1(SugarElement.fromDom(top.getEl()));
20213            });
20214          });
20215          addNotification(notification);
20216          reposition();
20217          editor.fire('OpenNotification', { notification: __assign({}, notification) });
20218          return notification;
20219        });
20220      };
20221      var close = function () {
20222        getTopNotification().each(function (notification) {
20223          getImplementation().close(notification);
20224          closeNotification(notification);
20225          reposition();
20226        });
20227      };
20228      var getNotifications = constant(notifications);
20229      var registerEvents = function (editor) {
20230        editor.on('SkinLoaded', function () {
20231          var serviceMessage = getServiceMessage(editor);
20232          if (serviceMessage) {
20233            open({
20234              text: serviceMessage,
20235              type: 'warning',
20236              timeout: 0
20237            }, false);
20238          }
20239          reposition();
20240        });
20241        editor.on('show ResizeEditor ResizeWindow NodeChange', function () {
20242          Delay.requestAnimationFrame(reposition);
20243        });
20244        editor.on('remove', function () {
20245          each$k(notifications.slice(), function (notification) {
20246            getImplementation().close(notification);
20247          });
20248        });
20249      };
20250      registerEvents(editor);
20251      return {
20252        open: open,
20253        close: close,
20254        getNotifications: getNotifications
20255      };
20256    };
20257
20258    var PluginManager = AddOnManager.PluginManager;
20259
20260    var ThemeManager = AddOnManager.ThemeManager;
20261
20262    function WindowManagerImpl () {
20263      var unimplemented = function () {
20264        throw new Error('Theme did not provide a WindowManager implementation.');
20265      };
20266      return {
20267        open: unimplemented,
20268        openUrl: unimplemented,
20269        alert: unimplemented,
20270        confirm: unimplemented,
20271        close: unimplemented,
20272        getParams: unimplemented,
20273        setParams: unimplemented
20274      };
20275    }
20276
20277    var WindowManager = function (editor) {
20278      var dialogs = [];
20279      var getImplementation = function () {
20280        var theme = editor.theme;
20281        return theme && theme.getWindowManagerImpl ? theme.getWindowManagerImpl() : WindowManagerImpl();
20282      };
20283      var funcBind = function (scope, f) {
20284        return function () {
20285          var args = [];
20286          for (var _i = 0; _i < arguments.length; _i++) {
20287            args[_i] = arguments[_i];
20288          }
20289          return f ? f.apply(scope, args) : undefined;
20290        };
20291      };
20292      var fireOpenEvent = function (dialog) {
20293        editor.fire('OpenWindow', { dialog: dialog });
20294      };
20295      var fireCloseEvent = function (dialog) {
20296        editor.fire('CloseWindow', { dialog: dialog });
20297      };
20298      var addDialog = function (dialog) {
20299        dialogs.push(dialog);
20300        fireOpenEvent(dialog);
20301      };
20302      var closeDialog = function (dialog) {
20303        fireCloseEvent(dialog);
20304        dialogs = filter$4(dialogs, function (otherDialog) {
20305          return otherDialog !== dialog;
20306        });
20307        if (dialogs.length === 0) {
20308          editor.focus();
20309        }
20310      };
20311      var getTopDialog = function () {
20312        return Optional.from(dialogs[dialogs.length - 1]);
20313      };
20314      var storeSelectionAndOpenDialog = function (openDialog) {
20315        editor.editorManager.setActive(editor);
20316        store(editor);
20317        var dialog = openDialog();
20318        addDialog(dialog);
20319        return dialog;
20320      };
20321      var open = function (args, params) {
20322        return storeSelectionAndOpenDialog(function () {
20323          return getImplementation().open(args, params, closeDialog);
20324        });
20325      };
20326      var openUrl = function (args) {
20327        return storeSelectionAndOpenDialog(function () {
20328          return getImplementation().openUrl(args, closeDialog);
20329        });
20330      };
20331      var alert = function (message, callback, scope) {
20332        var windowManagerImpl = getImplementation();
20333        windowManagerImpl.alert(message, funcBind(scope ? scope : windowManagerImpl, 
20333callback));
20334      };
20335      var confirm = function (message, callback, scope) {
20336        var windowManagerImpl = getImplementation();
20337        windowManagerImpl.confirm(message, funcBind(scope ? scope : windowManagerImpl, callback));
20338      };
20339      var close = function () {
20340        getTopDialog().each(function (dialog) {
20341          getImplementation().close(dialog);
20342          closeDialog(dialog);
20343        });
20344      };
20345      editor.on('remove', function () {
20346        each$k(dialogs, function (dialog) {
20347          getImplementation().close(dialog);
20348        });
20349      });
20350      return {
20351        open: open,
20352        openUrl: openUrl,
20353        alert: alert,
20354        confirm: confirm,
20355        close: close
20356      };
20357    };
20358
20359    var displayNotification = function (editor, message) {
20360      editor.notificationManager.open({
20361        type: 'error',
20362        text: message
20363      });
20364    };
20365    var displayError = function (editor, message) {
20366      if (editor._skinLoaded) {
20367        displayNotification(editor, message);
20368      } else {
20369        editor.on('SkinLoaded', function () {
20370          displayNotification(editor, message);
20371        });
20372      }
20373    };
20374    var uploadError = function (editor, message) {
20375      displayError(editor, I18n.translate([
20376        'Failed to upload image: {0}',
20377        message
20378      ]));
20379    };
20380    var logError = function (editor, errorType, msg) {
20381      fireError(editor, errorType, { message: msg });
20382      console.error(msg);
20383    };
20384    var createLoadError = function (type, url, name) {
20385      return name ? 'Failed to load ' + type + ': ' + name + ' from url ' + url : 'Failed to load ' + type + ' url: ' + url;
20386    };
20387    var pluginLoadError = function (editor, url, name) {
20388      logError(editor, 'PluginLoadError', createLoadError('plugin', url, name));
20389    };
20390    var iconsLoadError = function (editor, url, name) {
20391      logError(editor, 'IconsLoadError', createLoadError('icons', url, name));
20392    };
20393    var languageLoadError = function (editor, url, name) {
20394      logError(editor, 'LanguageLoadError', createLoadError('language', url, name));
20395    };
20396    var pluginInitError = function (editor, name, err) {
20397      var message = I18n.translate([
20398        'Failed to initialize plugin: {0}',
20399        name
20400      ]);
20401      fireError(editor, 'PluginLoadError', { message: message });
20402      initError(message, err);
20403      displayError(editor, message);
20404    };
20405    var initError = function (message) {
20406      var x = [];
20407      for (var _i = 1; _i < arguments.length; _i++) {
20408        x[_i - 1] = arguments[_i];
20409      }
20410      var console = window.console;
20411      if (console) {
20412        if (console.error) {
20413          console.error.apply(console, __spreadArray([message], x, false));
20414        } else {
20415          console.log.apply(console, __spreadArray([message], x, false));
20416        }
20417      }
20418    };
20419
20420    var isContentCssSkinName = function (url) {
20421      return /^[a-z0-9\-]+$/i.test(url);
20422    };
20423    var getContentCssUrls = function (editor) {
20424      return transformToUrls(editor, getContentCss(editor));
20425    };
20426    var getFontCssUrls = function (editor) {
20427      return transformToUrls(editor, getFontCss(editor));
20428    };
20429    var transformToUrls = function (editor, cssLinks) {
20430      var skinUrl = editor.editorManager.baseURL + '/skins/content';
20431      var suffix = editor.editorManager.suffix;
20432      var contentCssFile = 'content' + suffix + '.css';
20433      var inline = editor.inline === true;
20434      return map$3(cssLinks, function (url) {
20435        if (isContentCssSkinName(url) && !inline) {
20436          return skinUrl + '/' + url + '/' + contentCssFile;
20437        } else {
20438          return editor.documentBaseURI.toAbsolute(url);
20439        }
20440      });
20441    };
20442    var appendContentCssFromSettings = function (editor) {
20443      editor.contentCSS = editor.contentCSS.concat(getContentCssUrls(editor), getFontCssUrls(editor));
20444    };
20445
20446    var UploadStatus = function () {
20447      var PENDING = 1, UPLOADED = 2;
20448      var blobUriStatuses = {};
20449      var createStatus = function (status, resultUri) {
20450        return {
20451          status: status,
20452          resultUri: resultUri
20453        };
20454      };
20455      var hasBlobUri = function (blobUri) {
20456        return blobUri in blobUriStatuses;
20457      };
20458      var getResultUri = function (blobUri) {
20459        var result = blobUriStatuses[blobUri];
20460        return result ? result.resultUri : null;
20461      };
20462      var isPending = function (blobUri) {
20463        return hasBlobUri(blobUri) ? blobUriStatuses[blobUri].status === PENDING : false;
20464      };
20465      var isUploaded = function (blobUri) {
20466        return hasBlobUri(blobUri) ? blobUriStatuses[blobUri].status === UPLOADED : false;
20467      };
20468      var markPending = function (blobUri) {
20469        blobUriStatuses[blobUri] = createStatus(PENDING, null);
20470      };
20471      var markUploaded = function (blobUri, resultUri) {
20472        blobUriStatuses[blobUri] = createStatus(UPLOADED, resultUri);
20473      };
20474      var removeFailed = function (blobUri) {
20475        delete blobUriStatuses[blobUri];
20476      };
20477      var destroy = function () {
20478        blobUriStatuses = {};
20479      };
20480      return {
20481        hasBlobUri: hasBlobUri,
20482        getResultUri: getResultUri,
20483        isPending: isPending,
20484        isUploaded: isUploaded,
20485        markPending: markPending,
20486        markUploaded: markUploaded,
20487        removeFailed: removeFailed,
20488        destroy: destroy
20489      };
20490    };
20491
20492    var count = 0;
20493    var seed = function () {
20494      var rnd = function () {
20495        return Math.round(Math.random() * 4294967295).toString(36);
20496      };
20497      var now = new Date().getTime();
20498      return 's' + now.toString(36) + rnd() + rnd() + rnd();
20499    };
20500    var uuid = function (prefix) {
20501      return prefix + count++ + seed();
20502    };
20503
20504    var BlobCache = function () {
20505      var cache = [];
20506      var mimeToExt = function (mime) {
20507        var mimes = {
20508          'image/jpeg': 'jpg',
20509          'image/jpg': 'jpg',
20510          'image/gif': 'gif',
20511          'image/png': 'png',
20512          'image/apng': 'apng',
20513          'image/avif': 'avif',
20514          'image/svg+xml': 'svg',
20515          'image/webp': 'webp',
20516          'image/bmp': 'bmp',
20517          'image/tiff': 'tiff'
20518        };
20519        return mimes[mime.toLowerCase()] || 'dat';
20520      };
20521      var create = function (o, blob, base64, name, filename) {
20522        if (isString$1(o)) {
20523          var id = o;
20524          return toBlobInfo({
20525            id: id,
20526            name: name,
20527            filename: filename,
20528            blob: blob,
20529            base64: base64
20530          });
20531        } else if (isObject(o)) {
20532          return toBlobInfo(o);
20533        } else {
20534          throw new Error('Unknown input type');
20535        }
20536      };
20537      var toBlobInfo = function (o) {
20538        if (!o.blob || !o.base64) {
20539          throw new Error('blob and base64 representations of the image are required for BlobInfo to be created');
20540        }
20541        var id = o.id || uuid('blobid');
20542        var name = o.name || id;
20543        var blob = o.blob;
20544        return {
20545          id: constant(id),
20546          name: constant(name),
20547          filename: constant(o.filename || name + '.' + mimeToExt(blob.type)),
20548          blob: constant(blob),
20549          base64: constant(o.base64),
20550          blobUri: constant(o.blobUri || URL.createObjectURL(blob)),
20551          uri: constant(o.uri)
20552        };
20553      };
20554      var add = function (blobInfo) {
20555        if (!get(blobInfo.id())) {
20556          cache.push(blobInfo);
20557        }
20558      };
20559      var findFirst = function (predicate) {
20560        return find$3(cache, predicate).getOrUndefined();
20561      };
20562      var get = function (id) {
20563        return findFirst(function (cachedBlobInfo) {
20564          return cachedBlobInfo.id() === id;
20565        });
20566      };
20567      var getByUri = function (blobUri) {
20568        return findFirst(function (blobInfo) {
20569          return blobInfo.blobUri() === blobUri;
20570        });
20571      };
20572      var getByData = function (base64, type) {
20573        return findFirst(function (blobInfo) {
20574          return blobInfo.base64() === base64 && blobInfo.blob().type === type;
20575        });
20576      };
20577      var removeByUri = function (blobUri) {
20578        cache = filter$4(cache, function (blobInfo) {
20579          if (blobInfo.blobUri() === blobUri) {
20580            URL.revokeObjectURL(blobInfo.blobUri());
20581            return false;
20582          }
20583          return true;
20584        });
20585      };
20586      var destroy = function () {
20587        each$k(cache, function (cachedBlobInfo) {
20588          URL.revokeObjectURL(cachedBlobInfo.blobUri());
20589        });
20590        cache = [];
20591      };
20592      return {
20593        create: create,
20594        add: add,
20595        get: get,
20596        getByUri: getByUri,
20597        getByData: getByData,
20598        findFirst: findFirst,
20599        removeByUri: removeByUri,
20600        destroy: destroy
20601      };
20602    };
20603
20604    var Uploader = function (uploadStatus, settings) {
20605      var pendingPromises = {};
20606      var pathJoin = function (path1, path2) {
20607        if (path1) {
20608          return path1.replace(/\/$/, '') + '/' + path2.replace(/^\//, '');
20609        }
20610        return path2;
20611      };
20612      var defaultHandler = function (blobInfo, success, failure, progress) {
20613        var xhr = new XMLHttpRequest();
20614        xhr.open('POST', settings.url);
20615        xhr.withCredentials = settings.credentials;
20616        xhr.upload.onprogress = function (e) {
20617          progress(e.loaded / e.total * 100);
20618        };
20619        xhr.onerror = function () {
20620          failure('Image upload failed due to a XHR Transport error. Code: ' + xhr.status);
20621        };
20622        xhr.onload = function () {
20623          if (xhr.status < 200 || xhr.status >= 300) {
20624            failure('HTTP Error: ' + xhr.status);
20625            return;
20626          }
20627          var json = JSON.parse(xhr.responseText);
20628          if (!json || typeof json.location !== 'string') {
20629            failure('Invalid JSON: ' + xhr.responseText);
20630            return;
20631          }
20632          success(pathJoin(settings.basePath, json.location));
20633        };
20634        var formData = new FormData();
20635        formData.append('file', blobInfo.blob(), blobInfo.filename());
20636        xhr.send(formData);
20637      };
20638      var noUpload = function () {
20639        return new promiseObj(function (resolve) {
20640          resolve([]);
20641        });
20642      };
20643      var handlerSuccess = function (blobInfo, url) {
20644        return {
20645          url: url,
20646          blobInfo: blobInfo,
20647          status: true
20648        };
20649      };
20650      var handlerFailure = function (blobInfo, message, options) {
20651        return {
20652          url: '',
20653          blobInfo: blobInfo,
20654          status: false,
20655          error: {
20656            message: message,
20657            options: options
20658          }
20659        };
20660      };
20661      var resolvePending = function (blobUri, result) {
20662        Tools.each(pendingPromises[blobUri], function (resolve) {
20663          resolve(result);
20664        });
20665        delete pendingPromises[blobUri];
20666      };
20667      var uploadBlobInfo = function (blobInfo, handler, openNotification) {
20668        uploadStatus.markPending(blobInfo.blobUri());
20669        return new promiseObj(function (resolve) {
20670          var notification, progress;
20671          try {
20672            var closeNotification_1 = function () {
20673              if (notification) {
20674                notification.close();
20675                progress = noop;
20676              }
20677            };
20678            var success = function (url) {
20679              closeNotification_1();
20680              uploadStatus.markUploaded(blobInfo.blobUri(), url);
20681              resolvePending(blobInfo.blobUri(), handlerSuccess(blobInfo, url));
20682              resolve(handlerSuccess(blobInfo, url));
20683            };
20684            var failure = function (error, options) {
20685              var failureOptions = options ? options : {};
20686              closeNotification_1();
20687              uploadStatus.removeFailed(blobInfo.blobUri());
20688              resolvePending(blobInfo.blobUri(), handlerFailure(blobInfo, error, failureOptions));
20689              resolve(handlerFailure(blobInfo, error, failureOptions));
20690            };
20691            progress = function (percent) {
20692              if (percent < 0 || percent > 100) {
20693                return;
20694              }
20695              Optional.from(notification).orThunk(function () {
20696                return Optional.from(openNotification).map(apply);
20697              }).each(function (n) {
20698                notification = n;
20699                n.progressBar.value(percent);
20700              });
20701            };
20702            handler(blobInfo, success, failure, progress);
20703          } catch (ex) {
20704            resolve(handlerFailure(blobInfo, ex.message, {}));
20705          }
20706        });
20707      };
20708      var isDefaultHandler = function (handler) {
20709        return handler === defaultHandler;
20710      };
20711      var pendingUploadBlobInfo = function (blobInfo) {
20712        var blobUri = blobInfo.blobUri();
20713        return new promiseObj(function (resolve) {
20714          pendingPromises[blobUri] = pendingPromises[blobUri] || [];
20715          pendingPromises[blobUri].push(resolve);
20716        });
20717      };
20718      var uploadBlobs = function (blobInfos, openNotification) {
20719        blobInfos = Tools.grep(blobInfos, function (blobInfo) {
20720          return !uploadStatus.isUploaded(blobInfo.blobUri());
20721        });
20722        return promiseObj.all(Tools.map(blobInfos, function (blobInfo) {
20723          return uploadStatus.isPending(blobInfo.blobUri()) ? pe
20723ndingUploadBlobInfo(blobInfo) : uploadBlobInfo(blobInfo, settings.handler, openNotification);
20724        }));
20725      };
20726      var upload = function (blobInfos, openNotification) {
20727        return !settings.url && isDefaultHandler(settings.handler) ? noUpload() : uploadBlobs(blobInfos, openNotification);
20728      };
20729      if (isFunction(settings.handler) === false) {
20730        settings.handler = defaultHandler;
20731      }
20732      return { upload: upload };
20733    };
20734
20735    var openNotification = function (editor) {
20736      return function () {
20737        return editor.notificationManager.open({
20738          text: editor.translate('Image uploading...'),
20739          type: 'info',
20740          timeout: -1,
20741          progressBar: true
20742        });
20743      };
20744    };
20745    var createUploader = function (editor, uploadStatus) {
20746      return Uploader(uploadStatus, {
20747        url: getImageUploadUrl(editor),
20748        basePath: getImageUploadBasePath(editor),
20749        credentials: getImagesUploadCredentials(editor),
20750        handler: getImagesUploadHandler(editor)
20751      });
20752    };
20753    var ImageUploader = function (editor) {
20754      var uploadStatus = UploadStatus();
20755      var uploader = createUploader(editor, uploadStatus);
20756      return {
20757        upload: function (blobInfos, showNotification) {
20758          if (showNotification === void 0) {
20759            showNotification = true;
20760          }
20761          return uploader.upload(blobInfos, showNotification ? openNotification(editor) : undefined);
20762        }
20763      };
20764    };
20765
20766    var UploadChangeHandler = function (editor) {
20767      var lastChangedLevel = Cell(null);
20768      editor.on('change AddUndo', function (e) {
20769        lastChangedLevel.set(__assign({}, e.level));
20770      });
20771      var fireIfChanged = function () {
20772        var data = editor.undoManager.data;
20773        last$2(data).filter(function (level) {
20774          return !isEq$1(lastChangedLevel.get(), level);
20775        }).each(function (level) {
20776          editor.setDirty(true);
20777          editor.fire('change', {
20778            level: level,
20779            lastLevel: get$a(data, data.length - 2).getOrNull()
20780          });
20781        });
20782      };
20783      return { fireIfChanged: fireIfChanged };
20784    };
20785    var EditorUpload = function (editor) {
20786      var blobCache = BlobCache();
20787      var uploader, imageScanner;
20788      var uploadStatus = UploadStatus();
20789      var urlFilters = [];
20790      var changeHandler = UploadChangeHandler(editor);
20791      var aliveGuard = function (callback) {
20792        return function (result) {
20793          if (editor.selection) {
20794            return callback(result);
20795          }
20796          return [];
20797        };
20798      };
20799      var cacheInvalidator = function (url) {
20800        return url + (url.indexOf('?') === -1 ? '?' : '&') + new Date().getTime();
20801      };
20802      var replaceString = function (content, search, replace) {
20803        var index = 0;
20804        do {
20805          index = content.indexOf(search, index);
20806          if (index !== -1) {
20807            content = content.substring(0, index) + replace + content.substr(index + search.length);
20808            index += replace.length - search.length + 1;
20809          }
20810        } while (index !== -1);
20811        return content;
20812      };
20813      var replaceImageUrl = function (content, targetUrl, replacementUrl) {
20814        var replacementString = 'src="' + replacementUrl + '"' + (replacementUrl === Env.transparentSrc ? ' data-mce-placeholder="1"' : '');
20815        content = replaceString(content, 'src="' + targetUrl + '"', replacementString);
20816        content = replaceString(content, 'data-mce-src="' + targetUrl + '"', 'data-mce-src="' + replacementUrl + '"');
20817        return content;
20818      };
20819      var replaceUrlInUndoStack = function (targetUrl, replacementUrl) {
20820        each$k(editor.undoManager.data, function (level) {
20821          if (level.type === 'fragmented') {
20822            level.fragments = map$3(level.fragments, function (fragment) {
20823              return replaceImageUrl(fragment, targetUrl, replacementUrl);
20824            });
20825          } else {
20826            level.content = replaceImageUrl(level.content, targetUrl, replacementUrl);
20827          }
20828        });
20829      };
20830      var replaceImageUriInView = function (image, resultUri) {
20831        var src = editor.convertURL(resultUri, 'src');
20832        replaceUrlInUndoStack(image.src, resultUri);
20833        editor.$(image).attr({
20834          'src': shouldReuseFileName(editor) ? cacheInvalidator(resultUri) : resultUri,
20835          'data-mce-src': src
20836        });
20837      };
20838      var uploadImages = function (callback) {
20839        if (!uploader) {
20840          uploader = createUploader(editor, uploadStatus);
20841        }
20842        return scanForImages().then(aliveGuard(function (imageInfos) {
20843          var blobInfos = map$3(imageInfos, function (imageInfo) {
20844            return imageInfo.blobInfo;
20845          });
20846          return uploader.upload(blobInfos, openNotification(editor)).then(aliveGuard(function (result) {
20847            var imagesToRemove = [];
20848            var filteredResult = map$3(result, function (uploadInfo, index) {
20849              var blobInfo = imageInfos[index].blobInfo;
20850              var image = imageInfos[index].image;
20851              if (uploadInfo.status && shouldReplaceBlobUris(editor)) {
20852                blobCache.removeByUri(image.src);
20853                if (isRtc(editor)) ; else {
20854                  replaceImageUriInView(image, uploadInfo.url);
20855                }
20856              } else if (uploadInfo.error) {
20857                if (uploadInfo.error.options.remove) {
20858                  replaceUrlInUndoStack(image.getAttribute('src'), Env.transparentSrc);
20859                  imagesToRemove.push(image);
20860                }
20861                uploadError(editor, uploadInfo.error.message);
20862              }
20863              return {
20864                element: image,
20865                status: uploadInfo.status,
20866                uploadUri: uploadInfo.url,
20867                blobInfo: blobInfo
20868              };
20869            });
20870            if (filteredResult.length > 0) {
20871              changeHandler.fireIfChanged();
20872            }
20873            if (imagesToRemove.length > 0) {
20874              if (isRtc(editor)) {
20875                console.error('Removing images on failed uploads is currently unsupported for RTC');
20876              } else {
20877                editor.undoManager.transact(function () {
20878                  each$k(imagesToRemove, function (element) {
20879                    editor.dom.remove(element);
20880                    blobCache.removeByUri(element.src);
20881                  });
20882                });
20883              }
20884            }
20885            if (callback) {
20886              callback(filteredResult);
20887            }
20888            return filteredResult;
20889          }));
20890        }));
20891      };
20892      var uploadImagesAuto = function (callback) {
20893        if (isAutomaticUploadsEnabled(editor)) {
20894          return uploadImages(callback);
20895        }
20896      };
20897      var isValidDataUriImage = function (imgElm) {
20898        if (forall(urlFilters, function (filter) {
20899            return filter(imgElm);
20900          }) === false) {
20901          return false;
20902        }
20903        if (imgElm.getAttribute('src').indexOf('data:') === 0) {
20904          var dataImgFilter = getImagesDataImgFilter(editor);
20905          return dataImgFilter(imgElm);
20906        }
20907        return true;
20908      };
20909      var addFilter = function (filter) {
20910        urlFilters.push(filter);
20911      };
20912      var scanForImages = function () {
20913        if (!imageScanner) {
20914          imageScanner = ImageScanner(uploadStatus, blobCache);
20915        }
20916        return imageScanner.findAll(editor.getBody(), isValidDataUriImage).then(aliveGuard(function (result) {
20917          result = filter$4(result, function (resultItem) {
20918            if (typeof resultItem === 'string') {
20919              displayError(editor, resultItem);
20920              return false;
20921            }
20922            return true;
20923          });
20924          if (isRtc(editor)) ; else {
20925            each$k(result, function (resultItem) {
20926              replaceUrlInUndoStack(resultItem.image.src, resultItem.blobInfo.blobUri());
20927              resultItem.image.src = resultItem.blobInfo.blobUri();
20928              resultItem.image.removeAttribute('data-mce-src');
20929            });
20930          }
20931          return result;
20932        }));
20933      };
20934      var destroy = function () {
20935        blobCache.destroy();
20936        uploadStatus.destroy();
20937        imageScanner = uploader = null;
20938      };
20939      var replaceBlobUris = function (content) {
20940        return content.replace(/src="(blob:[^"]+)"/g, function (match, blobUri) {
20941          var resultUri = uploadStatus.getResultUri(blobUri);
20942          if (resultUri) {
20943            return 'src="' + resultUri + '"';
20944          }
20945          var blobInfo = blobCache.getByUri(blobUri);
20946          if (!blobInfo) {
20947            blobInfo = foldl(editor.editorManager.get(), function (result, editor) {
20948              return result || editor.editorUpload && editor.editorUpload.blobCache.getByUri(blobUri);
20949            }, null);
20950          }
20951          if (blobInfo) {
20952            var blob = blobInfo.blob();
20953            return 'src="data:' + blob.type + ';base64,' + blobInfo.base64() + '"';
20954          }
20955          return match;
20956        });
20957      };
20958      editor.on('SetContent', function () {
20959        if (isAutomaticUploadsEnabled(editor)) {
20960          uploadImagesAuto();
20961        } else {
20962          scanForImages();
20963        }
20964      });
20965      editor.on('RawSaveContent', function (e) {
20966        e.content = replaceBlobUris(e.content);
20967      });
20968      editor.on('GetContent', function (e) {
20969        if (e.source_view || e.format === 'raw' || e.format === 'tree') {
20970          return;
20971        }
20972        e.content = replaceBlobUris(e.content);
20973      });
20974      editor.on('PostRender', function () {
20975        editor.parser.addNodeFilter('img', function (images) {
20976          each$k(images, function (img) {
20977            var src = img.attr('src');
20978            if (blobCache.getByUri(src)) {
20979              return;
20980            }
20981            var resultUri = uploadStatus.getResultUri(src);
20982            if (resultUri) {
20983              img.attr('src', resultUri);
20984            }
20985          });
20986        });
20987      });
20988      return {
20989        blobCache: blobCache,
20990        addFilter: addFilter,
20991        uploadImages: uploadImages,
20992        uploadImagesAuto: uploadImagesAuto,
20993        scanForImages: scanForImages,
20994        destroy: destroy
20995      };
20996    };
20997
20998    var get = function (dom) {
20999      var formats = {
21000        valigntop: [{
21001            selector: 'td,th',
21002            styles: { verticalAlign: 'top' }
21003          }],
21004        valignmiddle: [{
21005            selector: 'td,th',
21006            styles: { verticalAlign: 'middle' }
21007          }],
21008        valignbottom: [{
21009            selector: 'td,th',
21010            styles: { verticalAlign: 'bottom' }
21011          }],
21012        alignleft: [
21013          {
21014            selector: 'figure.image',
21015            collapsed: false,
21016            classes: 'align-left',
21017            ceFalseOverride: true,
21018            preview: 'font-family font-size'
21019          },
21020          {
21021            selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
21022            styles: { textAlign: 'left' },
21023            inherit: false,
21024            preview: false,
21025            defaultBlock: 'div'
21026          },
21027          {
21028            selector: 'img,table,audio,video',
21029            collapsed: false,
21030            styles: { float: 'left' },
21031            preview: 'font-family font-size'
21032          }
21033        ],
21034        aligncenter: [
21035          {
21036            selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
21037            styles: { textAlign: 'center' },
21038            inherit: false,
21039            preview: 'font-family font-size',
21040            defaultBlock: 'div'
21041          },
21042          {
21043            selector: 'figure.image',
21044            collapsed: false,
21045            classes: 'align-center',
21046            ceFalseOverride: true,
21047            preview: 'font-family font-size'
21048          },
21049          {
21050            selector: 'img,audio,video',
21051            collapsed: false,
21052            styles: {
21053              display: 'block',
21054              marginLeft: 'auto',
21055              marginRight: 'auto'
21056            },
21057            preview: false
21058          },
21059          {
21060            selector: 'table',
21061            collapsed: false,
21062            styles: {
21063              marginLeft: 'auto',
21064              marginRight: 'auto'
21065            },
21066            preview: 'font-family font-size'
21067          }
21068        ],
21069        alignright: [
21070          {
21071            selector: 'figure.image',
21072            collapsed: false,
21073            classes: 'align-right',
21074            ceFalseOverride: true,
21075            preview: 'font-family font-size'
21076          },
21077          {
21078            selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
21079            styles: { textAlign: 'right' },
21080            inherit: false,
21081            preview: 'font-family font-size',
21082            defaultBlock: 'div'
21083          },
21084          {
21085            selector: 'img,table,audio,video',
21086            collapsed: false,
21087            styles: { float: 'right' },
21088            preview: 'font-family font-size'
21089          }
21090        ],
21091        alignjustify: [{
21092            selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
21093            styles: { textAlign: 'justify' },
21094            inherit: false,
21095            defaultBlock: 'div',
21096            preview: 'font-family font-size'
21097          }],
21098        bold: [
21099          {
21100            inline: 'strong',
21101            remove: 'all',
21102            preserve_attributes: [
21103              'class',
21104              'style'
21105            ]
21106          },
21107          {
21108            inline: 'span',
21109            styles: { fontWeight: 'bold' }
21110          },
21111          {
21112            inline: 'b',
21113            remove: 'all',
21114            preserve_attributes: [
21115              'class',
21116              'style'
21117            ]
21118          }
21119        ],
21120        italic: [
21121          {
21122            inline: 'em',
21123            remove: 'all',
21124            preserve_attributes: [
21125              'class',
21126              'style'
21127            ]
21128          },
21129          {
21130            inline: 'span',
21131            styles: { fontStyle: 'italic' }
21132          },
21133          {
21134            inline: 'i',
21135            remove: 'all',
21136            preserve_attributes: [
21137              'class',
21138              'style'
21139            ]
21140          }
21141        ],
21142        underline: [
21143          {
21144            inline: 'span',
21145            styles: { textDecoration: 'underline' },
21146            exact: true
21147          },
21148          {
21149            inline: 'u',
21150            remove: 'all',
21151            preserve_attributes: [
21152              'class',
21153              'style'
21154            ]
21155          }
21156        ],
21157        strikethrough: [
21158          {
21159            inline: 'span',
21160            styles: { textDecoration: 'line-through' },
21161            exact: true
21162          },
21163          {
21164            inline: 'strike',
21165            remove: 'all',
21166            preserve_attributes: [
21167              'class',
21168              'style'
21169            ]
21170          },
21171          {
21172            inline: 's',
21173            remove: 'all',
21174            preserve_attributes: [
21175              'class',
21176              'style'
21177            ]
21178          }
21179        ],
21180        forecolor: {
21181          inline: 'span',
21182          styles: { color: '%value' },
21183          links: true,
21184          remove_similar: true,
21185          clear_child_styles: true
21186        },
21187        hilitecolor: {
21188          inline: 'span',
21189          styles: { backgroundColor: '%value' },
21190          links: true,
21191          remove_similar: true,
21192          clear_child_styles: true
21193        },
21194        fontname: {
21195          inline: 'span',
21196          toggle: false,
21197          styles: { fontFamily: '%value' },
21198          clear_child_styles: true
21199        },
21200        fontsize: {
21201          inline: 'span',
21202          toggle: false,
21203          styles: { fontSize: '%value' },
21204          clear_child_styles: true
21205        },
21206        lineheight: {
21207          selector: 'h1,h2,h3,h4,h5,h6,p,li,td,th,div',
21208          defaultBlock: 'p',
21209          styles: { lineHeight: '%value' }
21210        },
21211        fontsize_class: {
21212          inline: 'span',
21213          attributes: { class: '%value' }
21214        },
21215        blockquote: {
21216          block: 'blockquote',
21217          wrapper: true,
21218          remove: 'all'
21219        },
21220        subscript: { inline: 'sub' },
21221        superscript: { inline: 'sup' },
21222        code: { inline: 'code' },
21223        link: {
21224          inline: 'a',
21225          selector: 'a',
21226          remove: 'all',
21227          split: true,
21228          deep: true,
21229          onmatch: function (node, _fmt, _itemName) {
21230            return isElement$5(node) && node.hasAttribute('href');
21231          },
21232          onformat: function (elm, _fmt, vars) {
21233            Tools.each(vars, function (value, key) {
21234              dom.setAttrib(elm, key, value);
21235            });
21236          }
21237        },
21238        lang: {
21239          inline: 'span',
21240          clear_child_styles: true,
21241          remove_similar: true,
21242          attributes: {
21243            'lang': '%value',
21244            'data-mce-lang': function (vars) {
21245              var _a;
21246              return (_a = vars === null || vars === void 0 ? void 0 : vars.customValue) !== null && _a !== void 0 ? _a : null;
21247            }
21248          }
21249        },
21250        removeformat: [
21251          {
21252            selector: 'b,strong,em,i,font,u,strike,s,sub,sup,dfn,code,samp,kbd,var,cite,mark,q,del,ins,small',
21253            remove: 'all',
21254            split: true,
21255            expand: false,
21256            block_expand: true,
21257            deep: true
21258          },
21259          {
21260            selector: 'span',
21261            attributes: [
21262              'style',
21263              'class'
21264            ],
21265            remove: 'empty',
21266            split: true,
21267            expand: false,
21268            deep: true
21269          },
21270          {
21271            selector: '*',
21272            attributes: [
21273              'style',
21274              'class'
21275            ],
21276            split: false,
21277            expand: false,
21278            deep: true
21279          }
21280        ]
21281      };
21282      Tools.each('p h1 h2 h3 h4 h5 h6 div address pre dt dd samp'.split(/\s/), function (name) {
21283        formats[name] = {
21284          block: name,
21285          remove: 'all'
21286        };
21287      });
21288      return formats;
21289    };
21290
21291    var FormatRegistry = function (editor) {
21292      var formats = {};
21293      var get$1 = function (name) {
21294        return isNonNullable(name) ? formats[name] : formats;
21295      };
21296      var has = function (name) {
21297        return has$2(formats, name);
21298      };
21299      var register = function (name, format) {
21300        if (name) {
21301          if (!isString$1(name)) {
21302            each$j(name, function (format, name) {
21303              register(name, format);
21304            });
21305          } else {
21306            if (!isArray$1(format)) {
21307              format = [format];
21308            }
21309            each$k(format, function (format) {
21310              if (isUndefined(format.deep)) {
21311                format.deep = !isSelectorFormat(format);
21312              }
21313              if (isUndefined(format.split)) {
21314                format.split = !isSelectorFormat(format) || isInlineFormat(format);
21315              }
21316              if (isUndefined(format.remove) && isSelectorFormat(format) && !isInlineFormat(format)) {
21317                format.remove = 'none';
21318              }
21319              if (isSelectorFormat(format) && isInlineFormat(format)) {
21320                format.mixed = true;
21321                format.block_expand = true;
21322              }
21323              if (isString$1(format.classes)) {
21324                format.classes = format.classes.split(/\s+/);
21325              }
21326            });
21327            formats[name] = format;
21328          }
21329        }
21330      };
21331      var unregister = function (name) {
21332        if (name && formats[name]) {
21333          delete formats[name];
21334        }
21335        return formats;
21336      };
21337      register(get(editor.dom));
21338      register(getFormats(editor));
21339      return {
21340        get: get$1,
21341        has: has,
21342        register: register,
21343        unregister: unregister
21344      };
21345    };
21346
21347    var each$5 = Tools.each;
21348    var dom = DOMUtils.DOM;
21349    var parsedSelectorToHtml = function (ancestry, editor) {
21350      var elm, item, fragment;
21351      var schema = editor && editor.schema || Schema({});
21352      var decorate = function (elm, item) {
21353        if (item.classes.length) {
21354          dom.addClass(elm, item.classes.join(' '));
21355        }
21356        dom.setAttribs(elm, item.attrs);
21357      };
21358      var createElement = function (sItem) {
21359        item = typeof sItem === 'string' ? {
21360          name: sItem,
21361          classes: [],
21362          attrs: {}
21363        } : sItem;
21364        var elm = dom.create(item.name);
21365        decorate(elm, item);
21366        return elm;
21367      };
21368      var getRequiredParent = function (elm, candidate) {
21369        var name = typeof elm !== 'string' ? elm.nodeName.toLowerCase() : elm;
21370        var elmRule = schema.getElementRule(name);
21371        var parentsRequired = elmRule && elmRule.parentsRequired;
21372        if (parentsRequired && parentsRequired.length) {
21373          return candidate && Tools.inArray(parentsRequired, candidate) !== -1 ? candidate : parentsRequired[0];
21374        } else {
21375          return false;
21376        }
21377      };
21378      var wrapInHtml = function (elm, ancestry, siblings) {
21379        var parent, parentCandidate;
21380        var ancestor = ancestry.length > 0 && ancestry[0];
21381        var ancestorName = ancestor && ancestor.name;
21382        var parentRequired = getRequiredParent(elm, ancestorName);
21383        if (parentRequired) {
21384          if (ancestorName === parentRequired) {
21385            parentCandidate = ancestry[0];
21386            ancestry = ancestry.slice(1);
21387          } else {
21388            parentCandidate = parentRequired;
21389          }
21390        } else if (ancestor) {
21391          parentCandidate = ancestry[0];
21392          ancestry = ancestry.slice(1);
21393        } else if (!siblings) {
21394          return elm;
21395        }
21396        if (parentCandidate) {
21397          parent = createElement(parentCandidate);
21398          parent.appendChild(elm);
21399        }
21400        if (siblings) {
21401          if (!parent) {
21402            parent = dom.create('div');
21403            parent.appendChild(elm);
21404          }
21405          Tools.each(siblings, function (sibling) {
21406            var siblingElm = createElement(sibling);
21407            parent.insertBefore(siblingElm, elm);
21408          });
21409        }
21410        return wrapInHtml(parent, ancestry, parentCandidate && parentCandidate.siblings);
21411      };
21412      if (ancestry && ancestry.length) {
21413        item = ancestry[0];
21414        elm = createElement(item);
21415        fragment = dom.create('div');
21416        fragment.appendChild(wrapInHtml(elm, ancestry.slice(1), item.siblings));
21417        return fragment;
21418      } else {
21419        return '';
21420      }
21421    };
21422    var parseSelectorItem = function (item) {
21423      var tagName;
21424      var obj = {
21425        classes: [],
21426        attrs: {}
21427      };
21428      item = obj.selector = Tools.trim(item);
21429      if (item !== '*') {
21430        tagName = item.replace(/(?:([#\.]|::?)([\w\-]+)|(\[)([^\]]+)\]?)/g, function ($0, $1, $2, $3, $4) {
21431          switch ($1) {
21432          case '#':
21433            obj.attrs.id = $2;
21434            break;
21435          case '.':
21436            obj.classes.push($2);
21437            break;
21438          case ':':
21439            if (Tools.inArray('checked disabled enabled read-only required'.split(' '), $2) !== -1) {
21440              obj.attrs[$2] = $2;
21441            }
21442            break;
21443          }
21444          if ($3 === '[') {
21445            var m = $4.match(/([\w\-]+)(?:\=\"([^\"]+))?/);
21446            if (m) {
21447              obj.attrs[m[1]] = m[2];
21448            }
21449          }
21450          return '';
21451        });
21452      }
21453      obj.name = tagName || 'div';
21454      return obj;
21455    };
21456    var parseSelector = function (selector) {
21457      if (!selector || typeof selector !== 'string') {
21458        return [];
21459      }
21460      selector = selector.split(/\s*,\s*/)[0];
21461      selector = selector.replace(/\s*(~\+|~|\+|>)\s*/g, '$1');
21462      return Tools.map(selector.split(/(?:>|\s+(?![^\[\]]+\]))/), function (item) {
21463        var siblings = Tools.map(item.split(/(?:~\+|~|\+)/), parseSelectorItem);
21464        var obj = siblings.pop();
21465        if (siblings.length) {
21466          obj.siblings = siblings;
21467        }
21468        return obj;
21469      }).reverse();
21470    };
21471    var getCssText = function (editor, format) {
21472      var name, previewFrag;
21473      var previewCss = '', parentFontSize;
21474      var previewStyles = getPreviewStyles(editor);
21475      if (previewStyles === '') {
21476        return '';
21477      }
21478      var removeVars = function (val) {
21479        return val.replace(/%(\w+)/g, '');
21480      };
21481      if (typeof format === 'string') {
21482        format = editor.formatter.get(format);
21483        if (!format) {
21484          return;
21485        }
21486        format = format[0];
21487      }
21488      if ('preview' in format) {
21489        var previewOpt = get$9(format, 'preview');
21490        if (is$1(previewOpt, false)) {
21491          return '';
21492        } else {
21493          previewStyles = previewOpt.getOr(previewStyles);
21494        }
21495      }
21496      name = format.block || format.inline || 'span';
21497      var items = parseSelector(format.selector);
21498      if (items.length) {
21499        if (!items[0].name) {
21500          items[0].name = name;
21501        }
21502        name = format.selector;
21503        previewFrag = parsedSelectorToHtml(items, editor);
21504      } else {
21505        previewFrag = parsedSelectorToHtml([name], editor);
21506      }
21507      var previewElm = dom.select(name, previewFrag)[0] || previewFrag.firstChild;
21508      each$5(format.styles, function (value, name) {
21509        var newValue = removeVars(value);
21510        if (newValue) {
21511          dom.setStyle(previewElm, name, newValue);
21512        }
21513      });
21514      each$5(format.attributes, function (value, name) {
21515        var newValue = removeVars(value);
21516        if (newValue) {
21517          dom.setAttrib(previewElm, name, newValue);
21518        }
21519      });
21520      each$5(format.classes, function (value) {
21521        var newValue = removeVars(value);
21522        if (!dom.hasClass(previewElm, newValue)) {
21523          dom.addClass(previewElm, newValue);
21524        }
21525      });
21526      editor.fire('PreviewFormats');
21527      dom.setStyles(previewFrag, {
21528        position: 'absolute',
21529        left: -65535
21530      });
21531      editor.getBody().appendChild(previewFrag);
21532      parentFontSize = dom.getStyle(editor.getBody(), 'fontSize', true);
21533      parentFontSize = /px$/.test(parentFontSize) ? parseInt(parentFontSize, 10) : 0;
21534      each$5(previewStyles.split(' '), function (name) {
21535        var value = dom.getStyle(previewElm, name, true);
21536        if (name === 'background-color' && /transparent|rgba\s*\([^)]+,\s*0\)/.test(value)) {
21537          value = dom.getStyle(editor.getBody(), name, true);
21538          if (dom.toHex(value).toLowerCase() === '#ffffff') {
21539            return;
21540          }
21541        }
21542        if (name === 'color') {
21543          if (dom.toHex(value).toLowerCase() === '#000000') {
21544            return;
21545          }
21546        }
21547        if (name === 'font-size') {
21548          if (/em|%$/.test(value)) {
21549            if (parentFontSize === 0) {
21550              return;
21551            }
21552            var numValue = parseFloat(value) / (/%$/.test(value) ? 100 : 1);
21553            value = numValue * parentFontSize + 'px';
21554          }
21555        }
21556        if (name === 'border' && value) {
21557          previewCss += 'padding:0 2px;';
21558        }
21559        previewCss += name + ':' + value + ';';
21560      });
21561      editor.fire('AfterPreviewFormats');
21562      dom.remove(previewFrag);
21563      return previewCss;
21564    };
21565
21566    var setup$h = function (editor) {
21567      editor.addShortcut('meta+b', '', 'Bold');
21568      editor.addShortcut('meta+i', '', 'Italic');
21569      editor.addShortcut('meta+u', '', 'Underline');
21570      for (var i = 1; i <= 6; i++) {
21571        editor.addShortcut('access+' + i, '', [
21572          'FormatBlock',
21573          false,
21574          'h' + i
21575        ]);
21576      }
21577      editor.addShortcut('access+7', '', [
21578        'FormatBlock',
21579        false,
21580        'p'
21581      ]);
21582      editor.addShortcut('access+8', '', [
21583        'FormatBlock',
21584        false,
21585        'div'
21586      ]);
21587      editor.addShortcut('access+9', '', [
21588        'FormatBlock',
21589        false,
21590        'address'
21591      ]);
21592    };
21593
21594    var Formatter = function (editor) {
21595      var formats = FormatRegistry(editor);
21596      var formatChangeState = Cell(null);
21597      setup$h(editor);
21598      setup$k(editor);
21599      return {
21600        get: formats.get,
21601        has: formats.has,
21602        register: formats.register,
21603        unregister: formats.unregister,
21604        apply: function (name, vars, node) {
21605          applyFormat(editor, name, vars, node);
21606        },
21607        remove: function (name, vars, node, similar) {
21608          removeFormat(editor, name, vars, node, similar);
21609        },
21610        toggle: function (name, vars, node) {
21611          toggleFormat(editor, name, vars, node);
21612        },
21613        match: function (name, vars, node, similar) {
21614          return matchFormat(editor, name, vars, node, similar);
21615        },
21616        closest: function (names) {
21617          return closestFormat(editor, names);
21618        },
21619        matchAll: function (names, vars) {
21620          return matchAllFormats(editor, names, vars);
21621        },
21622        matchNode: function (node, name, vars, similar) {
21623          return matchNodeFormat(editor, node, name, vars, similar);
21624        },
21625        canApply: function (name) {
21626          return canApplyFormat(editor, name);
21627        },
21628        formatChanged: function (formats, callback, similar, vars) {
21629          return formatChanged(editor, formatChangeState, formats, callback, similar, vars);
21630        },
21631        getCssText: curry(getCssText, editor)
21632      };
21633    };
21634
21635    var shouldIgnoreCommand = function (cmd) {
21636      switch (cmd.toLowerCase()) {
21637      case 'undo':
21638      case 'redo':
21639      case 'mcerepaint':
21640      case 'mcefocus':
21641        return true;
21642      default:
21643        return false;
21644      }
21645    };
21646    var registerEvents = function (editor, undoManager, locks) {
21647      var isFirstTypedCharacter = Cell(false);
21648      var addNonTypingUndoLevel = function (e) {
21649        setTyping(undoManager, false, locks);
21650        undoManager.add({}, e);
21651      };
21652      editor.on('init', function () {
21653        undoManager.add();
21654      });
21655      editor.on('BeforeExecCommand', function (e) {
21656        var cmd = e.command;
21657        if (!shouldIgnoreCommand(cmd)) {
21658          endTyping(undoManager, locks);
21659          undoManager.beforeChange();
21660        }
21661      });
21662      editor.on('ExecCommand', function (e) {
21663        var cmd = e.command;
21664        if (!shouldIgnoreCommand(cmd)) {
21665          addNonTypingUndoLevel(e);
21666        }
21667      });
21668      editor.on('ObjectResizeStart cut', function () {
21669        undoManager.beforeChange();
21670      });
21671      editor.on('SaveContent ObjectResized blur', addNonTypingUndoLevel);
21672      editor.on('dragend', addNonTypingUndoLevel);
21673      editor.on('keyup', function (e) {
21674        var keyCode = e.keyCode;
21675        if (e.isDefaultPrevented()) {
21676          return;
21677        }
21678        if (keyCode >= 33 && keyCode <= 36 || keyCode >= 37 && keyCode <= 40 || keyCode === 45 || e.ctrlKey) {
21679          addNonTypingUndoLevel();
21680          editor.nodeChanged();
21681        }
21682        if (keyCode === 46 || keyCode === 8) {
21683          editor.nodeChanged();
21684        }
21685        if (isFirstTypedCharacter.get() && undoManager.typing && isEq$1(createFromEditor(editor), undoManager.data[0]) === false) {
21686          if (editor.isDirty() === false) {
21687            editor.setDirty(true);
21688            editor.fire('change', {
21689              level: undoManager.data[0],
21690              lastLevel: null
21691            });
21692          }
21693          editor.fire('TypingUndo');
21694          isFirstTypedCharacter.set(false);
21695          editor.nodeChanged();
21696        }
21697      });
21698      editor.on('keydown', function (e) {
21699        var keyCode = e.keyCode;
21700        if (e.isDefaultPrevented()) {
21701          return;
21702        }
21703        if (keyCode >= 33 && keyCode <= 36 || keyCode >= 37 && keyCode <= 40 || keyCode === 45) {
21704          if (undoManager.typing) {
21705            addNonTypingUndoLevel(e);
21706          }
21707          return;
21708        }
21709        var modKey = e.ctrlKey && !e.altKey || e.metaKey;
21710        if ((keyCode < 16 || keyCode > 20) && keyCode !== 224 && keyCode !== 91 && !undoManager.typing && !modKey) {
21711          undoManager.beforeChange();
21712          setTyping(undoManager, true, locks);
21713          undoManager.add({}, e);
21714          isFirstTypedCharacter.set(true);
21715        }
21716      });
21717      editor.on('mousedown', function (e) {
21718        if (undoManager.typing) {
21719          addNonTypingUndoLevel(e);
21720        }
21721      });
21722      var isInsertReplacementText = function (event) {
21723        return event.inputType === 'insertReplacementText';
21724      };
21725      var isInsertTextDataNull = function (event) {
21726        return event.inputType === 'insertText' && event.data === null;
21727      };
21728      var isInsertFromPasteOrDrop = function (event) {
21729        return event.inputType === 'insertFromPaste' || event.inputType === 'insertFromDrop';
21730      };
21731      editor.on('input', function (e) {
21732        if (e.inputType && (isInsertReplacementText(e) || isInsertTextDataNull(e) || isInsertFromPasteOrDrop(e))) {
21733          addNonTypingUndoLevel(e);
21734        }
21735      });
21736      editor.on('AddUndo Undo Redo ClearUndos', function (e) {
21737        if (!e.isDefaultPrevented()) {
21738          editor.nodeChanged();
21739        }
21740      });
21741    };
21742    var addKeyboardShortcuts = function (editor) {
21743      editor.addShortcut('meta+z', '', 'Undo');
21744      editor.addShortcut('meta+y,meta+shift+z', '', 'Redo');
21745    };
21746
21747    var UndoManager = function (editor) {
21748      var beforeBookmark = value();
21749      var locks = Cell(0);
21750      var index = Cell(0);
21751      var undoManager = {
21752        data: [],
21753        typing: false,
21754        beforeChange: function () {
21755          beforeChange(editor, locks, beforeBookmark);
21756        },
21757        add: function (level, event) {
21758          return addUndoLevel(editor, undoManager, index, locks, beforeBookmark, level, event);
21759        },
21760        undo: function () {
21761          return undo(editor, undoManager, locks, index);
21762        },
21763        redo: function () {
21764          return redo(editor, index, undoManager.data);
21765        },
21766        clear: function () {
21767          clear(editor, undoManager, index);
21768        },
21769        reset: function () {
21770          reset(editor, undoManager);
21771        },
21772        hasUndo: function () {
21773          return hasUndo(editor, undoManager, index);
21774        },
21775        hasRedo: function () {
21776          return hasRedo(editor, undoManager, index);
21777        },
21778        transact: function (callback) {
21779          return transact(editor, undoManager, locks, callback);
21780        },
21781        ignore: function (callback) {
21782          ignore(editor, locks, callback);
21783        },
21784        extra: function (callback1, callback2) {
21785          extra(editor, undoManager, index, callback1, callback2);
21786        }
21787      };
21788      if (!isRtc(editor)) {
21789        registerEvents(editor, undoManager, locks);
21790      }
21791      addKeyboardShortcuts(editor);
21792      return undoManager;
21793    };
21794
21795    var nonTypingKeycodes = [
21796      9,
21797      27,
21798      VK.HOME,
21799      VK.END,
21800      19,
21801      20,
21802      44,
21803      144,
21804      145,
21805      33,
21806      34,
21807      45,
21808      16,
21809      17,
21810      18,
21811      91,
21812      92,
21813      93,
21814      VK.DOWN,
21815      VK.UP,
21816      VK.LEFT,
21817      VK.RIGHT
21818    ].concat(Env.browser.isFirefox() ? [224] : []);
21819    var placeholderAttr = 'data-mce-placeholder';
21820    var isKeyboardEvent = function (e) {
21821      return e.type === 'keydown' || e.type === 'keyup';
21822    };
21823    var isDeleteEvent = function (e) {
21824      var keyCode = e.keyCode;
21825      return keyCode === VK.BACKSPACE || keyCode === VK.DELETE;
21826    };
21827    var isNonTypingKeyboardEvent = function (e) {
21828      if (isKeyboardEvent(e)) {
21829        var keyCode = e.keyCode;
21830        return !isDeleteEvent(e) && (VK.metaKeyPressed(e) || e.altKey || keyCode >= 112 && keyCode <= 123 || contains$3(nonTypingKeycodes, keyCode));
21831      } else {
21832        return false;
21833      }
21834    };
21835    var isTypingKeyboardEvent = function (e) {
21836      return isKeyboardEvent(e) && !(isDeleteEvent(e) || e.type === 'keyup' && e.keyCode === 229);
21837    };
21838    var isVisuallyEmpty = function (dom, rootElm, forcedRootBlock) {
21839      if (isEmpty$2(SugarElement.fromDom(rootElm), false)) {
21840        var isForcedRootBlockFalse = forcedRootBlock === '';
21841        var firstElement = rootElm.firstElementChild;
21842        if (!firstElement) {
21843          return true;
21844        } else if (dom.getStyle(rootElm.firstElementChild, 'padding-left') || dom.getStyle(rootElm.firstElementChild, 'padding-right')) {
21845          return false;
21846        } else {
21847          return isForcedRootBlockFalse ? !dom.isBlock(firstElement) : forcedRootBlock === firstElement.nodeName.toLowerCase();
21848        }
21849      } else {
21850        return false;
21851      }
21852    };
21853    var setup$g = function (editor) {
21854      var dom = editor.dom;
21855      var rootBlock = getForcedRootBlock(editor);
21856      var placeholder = getPlaceholder(editor);
21857      var updatePlaceholder = function (e, initial) {
21858        if (isNonTypingKeyboardEvent(e)) {
21859          return;
21860        }
21861        var body = editor.getBody();
21862        var showPlaceholder = isTypingKeyboardEvent(e) ? false : isVisuallyEmpty(dom, body, rootBlock);
21863        var isPlaceholderShown = dom.getAttrib(body, placeholderAttr) !== '';
21864        if (isPlaceholderShown !== showPlaceholder || initial) {
21865          dom.setAttrib(body, placeholderAttr, showPlaceholder ? placeholder : null);
21866          dom.setAttrib(body, 'aria-placeholder', showPlaceholder ? placeholder : null);
21867          firePlaceholderToggle(editor, showPlaceholder);
21868          editor.on(showPlaceholder ? 'keydown' : 'keyup', updatePlaceholder);
21869          editor.off(showPlaceholder ? 'keyup' : 'keydown', updatePlaceholder);
21870        }
21871      };
21872      if (placeholder) {
21873        editor.on('init', function (e) {
21874          updatePlaceholder(e, true);
21875          editor.on('change SetContent ExecCommand', updatePlaceholder);
21876          editor.on('paste', function (e) {
21877            return Delay.setEditorTimeout(editor, function () {
21878              return updatePlaceholder(e);
21879            });
21880          });
21881        });
21882      }
21883    };
21884
21885    var strongRtl = /[\u0591-\u07FF\uFB1D-\uFDFF\uFE70-\uFEFC]/;
21886    var hasStrongRtl = function (text) {
21887      return strongRtl.test(text);
21888    };
21889
21890    var isInlineTarget = function (editor, elm) {
21891      return is$2(SugarElement.fromDom(elm), getInlineBoundarySelector(editor));
21892    };
21893    var isRtl = function (element) {
21894      return DOMUtils.DOM.getStyle(element, 'direction', true) === 'rtl' || hasStrongRtl(element.textContent);
21895    };
21896    var findInlineParents = function (isInlineTarget, rootNode, pos) {
21897      return filter$4(DOMUtils.DOM.getParents(pos.container(), '*', rootNode), isInlineTarget);
21898    };
21899    var findRootInline = function (isInlineTarget, rootNode, pos) {
21900      var parents = findInlineParents(isInlineTarget, rootNode, pos);
21901      return Optional.from(parents[parents.length - 1]);
21902    };
21903    var hasSameParentBlock = function (rootNode, node1, node2) {
21904      var block1 = getParentBlock$2(node1, rootNode);
21905      var block2 = getParentBlock$2(node2, rootNode);
21906      return block1 && block1 === block2;
21907    };
21908    var isAtZwsp = function (pos) {
21909      return isBeforeInline(pos) || isAfterInline(pos);
21910    };
21911    var normalizePosition = function (forward, pos) {
21912      if (!pos) {
21913        return pos;
21914      }
21915      var container = pos.container(), offset = pos.offset();
21916      if (forward) {
21917        if (isCaretContainerInline(container)) {
21918          if (isText$7(container.nextSibling)) {
21919            return CaretPosition(container.nextSibling, 0);
21920          } else {
21921            return CaretPosition.after(container);
21922          }
21923        } else {
21924          return isBeforeInline(pos) ? CaretPosition(container, offset + 1) : pos;
21925        }
21926      } else {
21927        if (isCaretContainerInline(container)) {
21928          if (isText$7(container.previousSibling)) {
21929            return CaretPosition(container.previousSibling, container.previousSibling.data.length);
21930          } else {
21931            return CaretPosition.before(container);
21932          }
21933        } else {
21934          return isAfterInline(pos) ? CaretPosition(container, offset - 1) : pos;
21935        }
21936      }
21937    };
21938    var normalizeForwards = curry(normalizePosition, true);
21939    var normalizeBackwards = curry(normalizePosition, false);
21940
21941    var isBeforeRoot = function (rootNode) {
21942      return function (elm) {
21943        return eq(rootNode, SugarElement.fromDom(elm.dom.parentNode));
21944      };
21945    };
21946    var isTextBlockOrListItem = function (element) {
21947      return isTextBlock$2(element) || isListItem(element);
21948    };
21949    var getParentBlock$1 = function (rootNode, elm) {
21950      if (contains$1(rootNode, elm)) {
21951        return closest$3(elm, isTextBlockOrListItem, isBeforeRoot(rootNode));
21952      } else {
21953        return Optional.none();
21954      }
21955    };
21956    var placeCaretInEmptyBody = function (editor) {
21957      var body = editor.getBody();
21958      var node = body.firstChild && editor.dom.isBlock(body.firstChild) ? body.firstChild : body;
21959      editor.selection.setCursorLocation(node, 0);
21960    };
21961    var paddEmptyBody = function (editor) {
21962      if (editor.dom.isEmpty(editor.getBody())) {
21963        editor.setContent('');
21964        placeCaretInEmptyBody(editor);
21965      }
21966    };
21967    var willDeleteLastPositionInElement = function (forward, fromPos, elm) {
21968      return lift2(firstPositionIn(elm), lastPositionIn(elm), function (firstPos, lastPos) {
21969        var normalizedFirstPos = normalizePosition(true, firstPos);
21970        var normalizedLastPos = normalizePosition(false, lastPos);
21971        var normalizedFromPos = normalizePosition(false, fromPos);
21972        if (forward) {
21973          return nextPosition(elm, normalizedFromPos).exists(function (nextPos) {
21974            return nextPos.isEqual(normalizedLastPos) && fromPos.isEqual(normalizedFirstPos);
21975          });
21976        } else {
21977          return prevPosition(elm, normalizedFromPos).exists(function (prevPos) {
21978            return prevPos.isEqual(normalizedFirstPos) && fromPos.isEqual(normalizedLastPos);
21979          });
21980        }
21981      }).getOr(true);
21982    };
21983
21984    var blockPosition = function (block, position) {
21985      return {
21986        block: block,
21987        position: position
21988      };
21989    };
21990    var blockBoundary = function (from, to) {
21991      return {
21992        from: from,
21993        to: to
21994      };
21995    };
21996    var getBlockPosition = function (rootNode, pos) {
21997      var rootElm = SugarElement.fromDom(rootNode);
21998      var containerElm = SugarElement.fromDom(pos.container());
21999      return getParentBlock$1(rootElm, containerElm).map(function (block) {
22000        return blockPosition(block, pos);
22001      });
22002    };
22003    var isDifferentBlocks = function (blockBoundary) {
22004      return eq(blockBoundary.from.block, blockBoundary.to.block) === false;
22005    };
22006    var hasSameParent = function (blockBoundary) {
22007      return parent(blockBoundary.from.block).bind(function (parent1) {
22008        return parent(blockBoundary.to.block).filter(function (parent2) {
22009          return eq(parent1, parent2);
22010        });
22011      }).isSome();
22012    };
22013    var isEditable$1 = function (blockBoundary) {
22014      return isContentEditableFalse$b(blockBoundary.from.block.dom) === false && isContentEditableFalse$b(blockBoundary.to.block.dom) === false;
22015    };
22016    var skipLastBr = function (rootNode, forward, blockPosition) {
22017      if (isBr$5(blockPosition.position.getNode()) && isEmpty$2(blockPosition.block) === false) {
22018        return positionIn(false, blockPosition.block.dom).bind(function (lastPositionInBlock) {
22019          if (lastPositionInBlock.isEqual(blockPosition.position)) {
22020            return fromPosition(forward, rootNode, lastPositionInBlock).bind(function (to) {
22021              return getBlockPosition(rootNode, to);
22022            });
22023          } else {
22024            return Optional.some(blockPosition);
22025          }
22026        }).getOr(blockPosition);
22027      } else {
22028        return blockPosition;
22029      }
22030    };
22031    var readFromRange = function (rootNode, forward, rng) {
22032      var fromBlockPos = getBlockPosition(rootNode, CaretPosition.fromRangeStart(rng));
22033      var toBlockPos = fromBlockPos.bind(function (blockPos) {
22034        return fromPosition(forward, rootNode, blockPos.position).bind(function (to) {
22035          return getBlockPosition(rootNode, to).map(function (blockPos) {
22036            return skipLastBr(rootNode, forward, blockPos);
22037          });
22038        });
22039      });
22040      return lift2(fromBlockPos, toBlockPos, blockBoundary).filter(function (blockBoundary) {
22041        return isDifferentBlocks(blockBoundary) && hasSameParent(blockBoundary) && isEditable$1(blockBoundary);
22042      });
22043    };
22044    var read$1 = function (rootNode, forward, rng) {
22045      return rng.collapsed ? readFromRange(rootNode, forward, rng) : Optional.none();
22046    };
22047
22048    var getChildrenUntilBlockBoundary = function (block) {
22049      var children$1 = children(block);
22050      return findIndex$2(children$1, isBlock$2).fold(constant(children$1), function (index) {
22051        return children$1.slice(0, index);
22052      });
22053    };
22054    var extractChildren = function (block) {
22055      var children = getChildrenUntilBlockBoundary(block);
22056      each$k(children, remove$7);
22057      return children;
22058    };
22059    var removeEmptyRoot = function (rootNode, block) {
22060      var parents = parentsAndSelf(block, rootNode);
22061      return find$3(parents.reverse(), function (element) {
22062        return isEmpty$2(element);
22063      }).each(remove$7);
22064    };
22065    var isEmptyBefore = function (el) {
22066      return filter$4(prevSiblings(el), function (el) {
22067        return !isEmpty$2(el);
22068      }).length === 0;
22069    };
22070    var nestedBlockMerge = function (rootNode, fromBlock, toBlock, insertionPoint) {
22071      if (isEmpty$2(toBlock)) {
22072        fillWithPaddingBr(toBlock);
22073        return firstPositionIn(toBlock.dom);
22074      }
22075      if (isEmptyBefore(insertionPoint) && isEmpty$2(fromBlock)) {
22076        before$4(insertionPoint, SugarElement.fromTag('br'));
22077      }
22078      var position = prevPosition(toBlock.dom, CaretPosition.before(insertionPoint.dom));
22079      each$k(extractChildren(fromBlock), function (child) {
22080        before$4(insertionPoint, child);
22081      });
22082      removeEmptyRoot(rootNode, fromBlock);
22083      return position;
22084    };
22085    var sidelongBlockMerge = function (rootNode, fromBlock, toBlock) {
22086      if (isEmpty$2(toBlock)) {
22087        remove$7(toBlock);
22088        if (isEmpty$2(fromBlock)) {
22089          fillWithPaddingBr(fromBlock);
22090        }
22091        return firstPositionIn(fromBlock.dom);
22092      }
22093      var position = lastPositionIn(toBlock.dom);
22094      each$k(extractChildren(fromBlock), function (child) {
22095        append$1(toBlock, child);
22096      });
22097      removeEmptyRoot(rootNode, fromBlock);
22098      return position;
22099    };
22100    var findInsertionPoint = function (toBlock, block) {
22101      var parentsAndSelf$1 = parentsAndSelf(block, toBlock);
22102      return Optional.from(parentsAndSelf$1[parentsAndSelf$1.length - 1]);
22103    };
22104    var getInsertionPoint = function (fromBlock, toBlock) {
22105      return contains$1(toBlock, fromBlock) ? findInsertionPoint(toBlock, fromBlock) : Optional.none();
22106    };
22107    var trimBr = function (first, block) {
22108      positionIn(first, block.dom).map(function (position) {
22109        return position.getNode();
22110      }).map(SugarElement.fromDom).filter(isBr$4).each(remove$7);
22111    };
22112    var mergeBlockInto = function (rootNode, fromBlock, toBlock) {
22113      trimBr(true, fromBlock);
22114      trimBr(false, toBlock);
22115      return getInsertionPoint(fromBlock, toBlock).fold(curry(sidelongBlockMerge, rootNode, fromBlock, toBlock), curry(nestedBlockMerge, rootNode, fromBlock, toBlock));
22116    };
22117    var mergeBlocks = function (rootNode, forward, block1, block2) {
22118      return forward ? mergeBlockInto(rootNode, block2, block1) : mergeBlockInto(rootNode, block1, block2);
22119    };
22120
22121    var backspaceDelete$8 = function (editor, forward) {
22122      var rootNode = SugarElement.fromDom(editor.getBody());
22123      var position = read$1(rootNode.dom, forward, editor.selection.getRng()).bind(function (blockBoundary) {
22124        return mergeBlocks(rootNode, forward, blockBoundary.from.block, blockBoundary.to.block);
22125      });
22126      position.each(function (pos) {
22127        editor.selection.setRng(pos.toRange());
22128      });
22129      return position.isSome();
22130    };
22131
22132    var deleteRangeMergeBlocks = function (rootNode, selection) {
22133      var rng = selection.getRng();
22134      return lift2(getParentBlock$1(rootNode, SugarElement.fromDom(rng.startContainer)), getParentBlock$1(rootNode, SugarElement.fromDom(rng.endContainer)), function (block1, block2) {
22135        if (eq(block1, block2) === false) {
22136          rng.deleteContents();
22137          mergeBlocks(rootNode, true, block1, block2).each(function (pos) {
22138            selection.setRng(pos.toRange());
22139          });
22140          return true;
22141        } else {
22142          return false;
22143        }
22144      }).getOr(false);
22145    };
22146    var isRawNodeInTable = function (root, rawNode) {
22147      var node = SugarElement.fromDom(rawNode);
22148      var isRoot = curry(eq, root);
22149      return ancestor$3(node, isTableCell$4, isRoot).isSome();
22150    };
22151    var isSelectionInTable = function (root, rng) {
22152      return isRawNodeInTable(root, rng.startContainer) || isRawNodeInTable(root, rng.endContainer);
22153    };
22154    var isEverythingSelected = function (root, rng) {
22155      var noPrevious = prevPosition(root.dom, CaretPosition.fromRangeStart(rng)).isNone();
22156      var noNext = nextPosition(root.dom, CaretPosition.fromRangeEnd(rng)).isNone();
22157      return !isSelectionInTable(root, rng) && noPrevious && noNext;
22158    };
22159    var emptyEditor = function (editor) {
22160      editor.setContent('');
22161      editor.selection.setCursorLocation();
22162      return true;
22163    };
22164    var deleteRange$1 = function (editor) {
22165      var rootNode = SugarElement.fromDom(editor.getBody());
22166      var rng = editor.selection.getRng();
22167      return isEverythingSelected(rootNode, rng) ? emptyEditor(editor) : deleteRangeMergeBlocks(rootNode, editor.selection);
22168    };
22169    var backspaceDelete$7 = function (editor, _forward) {
22170      return editor.selection.isCollapsed() ? false : deleteRange$1(editor);
22171    };
22172
22173    var isContentEditableTrue$2 = isContentEditableTrue$4;
22174    var isContentEditableFalse$4 = isContentEditableFalse$b;
22175    var showCaret = function (direction, editor, node, before, scrollIntoView) {
22176      return Optional.from(editor._selectionOverrides.showCaret(direction, node, before, scrollIntoView));
22177    };
22178    var getNodeRange = function (node) {
22179      var rng = node.ownerDocument.createRange();
22180      rng.selectNode(node);
22181      return rng;
22182    };
22183    var selectNode = function (editor, node) {
22184      var e = editor.fire('BeforeObjectSelected', { target: node });
22185      if (e.isDefaultPrevented()) {
22186        return Optional.none();
22187      }
22188      return Optional.some(getNodeRange(node));
22189    };
22190    var renderCaretAtRange = function (editor, range, scrollIntoView) {
22191      var normalizedRange = normalizeRange(1, editor.getBody(), range);
22192      var caretPosition = CaretPosition.fromRangeStart(normalizedRange);
22193      var caretPositionNode = caretPosition.getNode();
22194      if (isInlineFakeCaretTarget(caretPositionNode)) {
22195        return showCaret(1, editor, caretPositionNode, !caretPosition.isAtEnd(), false);
22196      }
22197      var caretPositionBeforeNode = caretPosition.getNode(true);
22198      if (isInlineFakeCaretTarget(caretPositionBeforeNode)) {
22199        return showCaret(1, editor, caretPositionBeforeNode, false, false);
22200      }
22201      var ceRoot = editor.dom.getParent(caretPosition.getNode(), function (node) {
22202        return isContentEditableFalse$4(node) || isContentEditableTrue$2(node);
22203      });
22204      if (isInlineFakeCaretTarget(ceRoot)) {
22205        return showCaret(1, editor, ceRoot, false, scrollIntoView);
22206      }
22207      return Optional.none();
22208    };
22209    var renderRangeCaret = function (editor, range, scrollIntoView) {
22210      return range.collapsed ? renderCaretAtRange(editor, range, scrollIntoView).getOr(range) : range;
22211    };
22212
22213    var isBeforeBoundary = function (pos) {
22214      return isBeforeContentEditableFalse(pos) || isBeforeMedia(pos);
22215    };
22216    var isAfterBoundary = function (pos) {
22217      return isAfterContentEditableFalse(pos) || isAfterMedia(pos);
22218    };
22219    var trimEmptyTextNode = function (dom, node) {
22220      if (isText$7(node) && node.data.length === 0) {
22221        dom.remove(node);
22222      }
22223    };
22224    var deleteContentAndShowCaret = function (editor, range, node, direction, forward, peekCaretPosition) {
22225      showCaret(direction, editor, peekCaretPosition.getNode(!forward), forward, true).each(function (caretRange) {
22226        if (range.collapsed) {
22227          var deleteRange = range.cloneRange();
22228          if (forward) {
22229            deleteRange.setEnd(caretRange.startContainer, caretRange.startOffset);
22230          } else {
22231            deleteRange.setStart(caretRange.endContainer, caretRange.endOffset);
22232          }
22233          deleteRange.deleteContents();
22234        } else {
22235          range.deleteContents();
22236        }
22237        editor.selection.setRng(caretRange);
22238      });
22239      trimEmptyTextNode(editor.dom, node);
22240      return true;
22241    };
22242    var deleteBoundaryText = function (editor, forward) {
22243      var range = editor.selection.getRng();
22244      if (!isText$7(range.commonAncestorContainer)) {
22245        return false;
22246      }
22247      var direction = forward ? HDirection.Forwards : HDirection.Backwards;
22248      var caretWalker = CaretWalker(editor.getBody());
22249      var getNextPosFn = curry(getVisualCaretPosition, forward ? caretWalker.next : caretWalker.prev);
22250      var isBeforeFn = forward ? isBeforeBoundary : isAfterBoundary;
22251      var caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range);
22252      var nextCaretPosition = normalizePosition(forward, getNextPosFn(caretPosition));
22253      if (!nextCaretPosition || !isMoveInsideSameBlock(caretPosition, nextCaretPosition)) {
22254        return false;
22255      } else if (isBeforeFn(nextCaretPosition)) {
22256        return deleteContentAndShowCaret(editor, range, caretPosition.getNode(), direction, forward, nextCaretPosition);
22257      }
22258      var peekCaretPosition = getNextPosFn(nextCaretPosition);
22259      if (peekCaretPosition && isBeforeFn(peekCaretPosition)) {
22260        if (isMoveInsideSameBlock(nextCaretPosition, peekCaretPosition)) {
22261          return deleteContentAndShowCaret(editor, range, caretPosition.getNode(), direction, forward, peekCaretPosition);
22262        }
22263      }
22264      return false;
22265    };
22266    var backspaceDelete$6 = function (editor, forward) {
22267      return deleteBoundaryText(editor, forward);
22268    };
22269
22270    var isCompoundElement = function (node) {
22271      return isTableCell$4(SugarElement.fromDom(node)) || isListItem(SugarElement.fromDom(node));
22272    };
22273    var DeleteAction = Adt.generate([
22274      { remove: ['element'] },
22275      { moveToElement: ['element'] },
22276      { moveToPosition: ['position'] }
22277    ]);
22278    var isAtContentEditableBlockCaret = function (forward, from) {
22279      var elm = from.getNode(forward === false);
22280      var caretLocation = forward ? 'after' : 'before';
22281      return isElement$5(elm) && elm.getAttribute('data-mce-caret') === caretLocation;
22282    };
22283    var isDeleteFromCefDifferentBlocks = function (root, forward, from, to) {
22284      var inSameBlock = function (elm) {
22285        return isInline$1(SugarElement.fromDom(elm)) && !isInSameBlock(from, to, root);
22286      };
22287      return getRelativeCefElm(!forward, from).fold(function () {
22288        return getRelativeCefElm(forward, to).fold(never, inSameBlock);
22289      }, inSameBlock);
22290    };
22291    var deleteEmptyBlockOrMoveToCef = function (root, forward, from, to) {
22292      var toCefElm = to.getNode(forward === false);
22293      return getParentBlock$1(SugarElement.fromDom(root), SugarElement.fromDom(from.getNode())).map(function (blockElm) {
22294        return isEmpty$2(blockElm) ? DeleteAction.remove(blockElm.dom) : DeleteAction.moveToElement(toCefElm);
22295      }).orThunk(function () {
22296        return Optional.some(DeleteAction.moveToElement(toCefElm));
22297      });
22298    };
22299    var findCefPosition = function (root, forward, from) {
22300      return fromPosition(forward, root, from).bind(function (to) {
22301        if (isCompoundElement(to.getNode())) {
22302          return Optional.none();
22303        } else if (isDeleteFromCefDifferentBlocks(root, forward, from, to)) {
22304          return Optional.none();
22305        } else if (forward && isContentEditableFalse$b(to.getNode())) {
22306          return deleteEmptyBlockOrMoveToCef(root, forward, from, to);
22307        } else if (forward === false && isContentEditableFalse$b(to.getNode(true))) {
22308          return deleteEmptyBlockOrMoveToCef(root, forward, from, to);
22309        } else if (forward && isAfterContentEditableFalse(from)) {
22310          return Optional.some(DeleteAction.moveToPosition(to));
22311        } else if (forward === false && isBeforeContentEditableFalse(from)) {
22312          return Optional.some(DeleteAction.moveToPosition(to));
22313        } else {
22314          return Optional.none();
22315        }
22316      });
22317    };
22318    var getContentEditableBlockAction = function (forward, elm) {
22319      if (forward && isContentEditableFalse$b(elm.nextSibling)) {
22320        return Optional.some(DeleteAction.moveToElement(elm.nextSibling));
22321      } else if (forward === false && isContentEditableFalse$b(elm.previousSibling)) {
22322        return Optional.some(DeleteAction.moveToElement(elm.previousSibling));
22323      } else {
22324        return Optional.none();
22325      }
22326    };
22327    var skipMoveToActionFromInlineCefToContent = function (root, from, deleteAction) {
22328      return deleteAction.fold(function (elm) {
22329        return Optional.some(DeleteAction.remove(elm));
22330      }, function (elm) {
22331        return Optional.some(DeleteAction.moveToElement(elm));
22332      }, function (to) {
22333        if (isInSameBlock(from, to, root)) {
22334          return Optional.none();
22335        } else {
22336          return Optional.some(DeleteAction.moveToPosition(to));
22337        }
22338      });
22339    };
22340    var getContentEditableAction = function (root, forward, from) {
22341      if (isAtContentEditableBlockCaret(forward, from)) {
22342        return getContentEditableBlockAction(forward, from.getNode(forward === false)).fold(function () {
22343          return findCefPosition(root, forward, from);
22344        }, Optional.some);
22345      } else {
22346        return findCefPosition(root, forward, from).bind(function (deleteAction) {
22347          return skipMoveToActionFromInlineCefToContent(root, from, deleteAction);
22348        });
22349      }
22350    };
22351    var read = function (root, forward, rng) {
22352      var normalizedRange = normalizeRange(forward ? 1 : -1, root, rng);
22353      var from = CaretPosition.fromRangeStart(normalizedRange);
22354      var rootElement = SugarElement.fromDom(root);
22355      if (forward === false && isAfterContentEditableFalse(from)) {
22356        return Optional.some(DeleteAction.remove(from.getNode(true)));
22357      } else if (forward && isBeforeContentEditableFalse(from)) {
22358        return Optional.some(DeleteAction.remove(from.getNode()));
22359      } else if (forward === false && isBeforeContentEditableFalse(from) && isAfterBr(rootElement, from)) {
22360        return findPreviousBr(rootElement, from).map(function (br) {
22361          return DeleteAction.remove(br.getNode());
22362        });
22363      } else if (forward && isAfterContentEditableFalse(from) && isBeforeBr$1(rootElement, from)) {
22364        return findNextBr(rootElement, from).map(function (br) {
22365          return DeleteAction.remove(br.getNode());
22366        });
22367      } else {
22368        return getContentEditableAction(root, forward, from);
22369      }
22370    };
22371
22372    var deleteElement$1 = function (editor, forward) {
22373      return function (element) {
22374        editor._selectionOverrides.hideFakeCaret();
22375        deleteElement$2(editor, forward, SugarElement.fromDom(element));
22376        return true;
22377      };
22378    };
22379    var moveToElement = function (editor, forward) {
22380      return function (element) {
22381        var pos = forward ? CaretPosition.before(element) : CaretPosition.after(element);
22382        editor.selection.setRng(pos.toRange());
22383        return true;
22384      };
22385    };
22386    var moveToPosition = function (editor) {
22387      return function (pos) {
22388        editor.selection.setRng(pos.toRange());
22389        return true;
22390      };
22391    };
22392    var getAncestorCe = function (editor, node) {
22393      return Optional.from(getContentEditableRoot$1(editor.getBody(), node));
22394    };
22395    var backspaceDeleteCaret = function (editor, forward) {
22396      var selectedNode = editor.selection.getNode();
22397      return getAncestorCe(editor, selectedNode).filter(isContentEditableFalse$b).fold(function () {
22398        return read(editor.getBody(), forward, editor.selection.getRng()).exists(function (deleteAction) {
22399          return deleteAction.fold(deleteElement$1(editor, forward), moveToElement(editor, forward), moveToPosition(editor));
22400        });
22401      }, always);
22402    };
22403    var deleteOffscreenSelection = function (rootElement) {
22404      each$k(descendants(rootElement, '.mce-offscreen-selection'), remove$7);
22405    };
22406    var backspaceDeleteRange = function (editor, forward) {
22407      var selectedNode = editor.selection.getNode();
22408      if (isContentEditableFalse$b(selectedNode) && !isTableCell$5(selectedNode)) {
22409        var hasCefAncestor = getAncestorCe(editor, selectedNode.parentNode).filter(isContentEditableFalse$b);
22410        return hasCefAncestor.fold(function () {
22411          deleteOffscreenSelection(SugarElement.fromDom(editor.getBody()));
22412          deleteElement$2(editor, forward, SugarElement.fromDom(editor.selection.getNode()));
22413          paddEmptyBody(editor);
22414          return true;
22415        }, always);
22416      }
22417      return false;
22418    };
22419    var paddEmptyElement = function (editor) {
22420      var dom = editor.dom, selection = editor.selection;
22421      var ceRoot = getContentEditableRoot$1(editor.getBody(), selection.getNode());
22422      if (isContentEditableTrue$4(ceRoot) && dom.isBlock(ceRoot) && dom.isEmpty(ceRoot)) {
22423        var br = dom.create('br', { 'data-mce-bogus': '1' });
22424        dom.setHTML(ceRoot, '');
22425        ceRoot.appendChild(br);
22426        selection.setRng(CaretPosition.before(br).toRange());
22427      }
22428      return true;
22429    };
22430    var backspaceDelete$5 = function (editor, forward) {
22431      if (editor.selection.isCollapsed()) {
22432        return backspaceDeleteCaret(editor, forward);
22433      } else {
22434        return backspaceDeleteRange(editor, forward);
22435      }
22436    };
22437
22438    var deleteCaret$2 = function (editor, forward) {
22439      var fromPos = CaretPosition.fromRangeStart(editor.selection.getRng());
22440      return fromPosition(forward, editor.getBody(), fromPos).filter(function (pos) {
22441        return forward ? isBeforeImageBlock(pos) : isAfterImageBlock(pos);
22442      }).bind(function (pos) {
22443        return Optional.from(getChildNodeAtRelativeOffset(forward ? 0 : -1, pos));
22444      }).exists(function (elm) {
22445        editor.selection.select(elm);
22446        return true;
22447      });
22448    };
22449    var backspaceDelete$4 = function (editor, forward) {
22450      return editor.selection.isCollapsed() ? deleteCaret$2(editor, forward) : false;
22451    };
22452
22453    var isText = isText$7;
22454    var startsWithCaretContainer = function (node) {
22455      return isText(node) && node.data[0] === ZWSP$1;
22456    };
22457    var endsWithCaretContainer = function (node) {
22458      return isText(node) && node.data[node.data.length - 1] === ZWSP$1;
22459    };
22460    var createZwsp = function (node) {
22461      return node.ownerDocument.createTextNode(ZWSP$1);
22462    };
22463    var insertBefore = function (node) {
22464      if (isText(node.previousSibling)) {
22465        if (endsWithCaretContainer(node.previousSibling)) {
22466          return node.previousSibling;
22467        } else {
22468          node.previousSibling.appendData(ZWSP$1);
22469          return node.previousSibling;
22470        }
22471      } else if (isText(node)) {
22472        if (startsWithCaretContainer(node)) {
22473          return node;
22474        } else {
22475          node.insertData(0, ZWSP$1);
22476          return node;
22477        }
22478      } else {
22479        var newNode = createZwsp(node);
22480        node.parentNode.insertBefore(newNode, node);
22481        return newNode;
22482      }
22483    };
22484    var insertAfter = function (node) {
22485      if (isText(node.nextSibling)) {
22486        if (startsWithCaretContainer(node.nextSibling)) {
22487          return node.nextSibling;
22488        } else {
22489          node.nextSibling.insertData(0, ZWSP$1);
22490          return node.nextSibling;
22491        }
22492      } else if (isText(node)) {
22493        if (endsWithCaretContainer(node)) {
22494          return node;
22495        } else {
22496          node.appendData(ZWSP$1);
22497          return node;
22498        }
22499      } else {
22500        var newNode = createZwsp(node);
22501        if (node.nextSibling) {
22502          node.parentNode.insertBefore(newNode, node.nextSibling);
22503        } else {
22504          node.parentNode.appendChild(newNode);
22505        }
22506        return newNode;
22507      }
22508    };
22509    var insertInline = function (before, node) {
22510      return before ? insertBefore(node) : insertAfter(node);
22511    };
22512    var insertInlineBefore = curry(insertInline, true);
22513    var insertInlineAfter = curry(insertInline, false);
22514
22515    var insertInlinePos = function (pos, before) {
22516      if (isText$7(pos.container())) {
22517        return insertInline(before, pos.container());
22518      } else {
22519        return insertInline(before, pos.getNode());
22520      }
22521    };
22522    var isPosCaretContainer = function (pos, caret) {
22523      var caretNode = caret.get();
22524      return caretNode && pos.container() === caretNode && isCaretContainerInline(caretNode);
22525    };
22526    var renderCaret = function (caret, location) {
22527      return location.fold(function (element) {
22528        remove$2(caret.get());
22529        var text = insertInlineBefore(element);
22530        caret.set(text);
22531        return Optional.some(CaretPosition(text, text.length - 1));
22532      }, function (element) {
22533        return firstPositionIn(element).map(function (pos) {
22534          if (!isPosCaretContainer(pos, caret)) {
22535            remove$2(caret.get());
22536            var text = insertInlinePos(pos, true);
22537            caret.set(text);
22538            return CaretPosition(text, 1);
22539          } else {
22540            return CaretPosition(caret.get(), 1);
22541          }
22542        });
22543      }, function (element) {
22544        return lastPositionIn(element).map(function (pos) {
22545          if (!isPosCaretContainer(pos, caret)) {
22546            remove$2(caret.get());
22547            var text = insertInlinePos(pos, false);
22548            caret.set(text);
22549            return CaretPosition(text, text.length - 1);
22550          } else {
22551            return CaretPosition(caret.get(), caret.get().length - 1);
22552          }
22553        });
22554      }, function (element) {
22555        remove$2(caret.get());
22556        var text = insertInlineAfter(element);
22557        caret.set(text);
22558        return Optional.some(CaretPosition(text, 1));
22559      });
22560    };
22561
22562    var evaluateUntil = function (fns, args) {
22563      for (var i = 0; i < fns.length; i++) {
22564        var result = fns[i].apply(null, args);
22565        if (result.isSome()) {
22566          return result;
22567        }
22568      }
22569      return Optional.none();
22570    };
22571
22572    var Location = Adt.generate([
22573      { before: ['element'] },
22574      { start: ['element'] },
22575      { end: ['element'] },
22576      { after: ['element'] }
22577    ]);
22578    var rescope$1 = function (rootNode, node) {
22579      var parentBlock = getParentBlock$2(node, rootNode);
22580      return parentBlock ? parentBlock : rootNode;
22581    };
22582    var before = function (isInlineTarget, rootNode, pos) {
22583      var nPos = normalizeForwards(pos);
22584      var scope = rescope$1(rootNode, nPos.container());
22585      return findRootInline(isInlineTarget, scope, nPos).fold(function () {
22586        return nextPosition(scope, nPos).bind(curry(findRootInline, isInlineTarget, scope)).map(function (inline) {
22587          return Location.before(inline);
22588        });
22589      }, Optional.none);
22590    };
22591    var isNotInsideFormatCaretContainer = function (rootNode, elm) {
22592      return getParentCaretContainer(rootNode, elm) === null;
22593    };
22594    var findInsideRootInline = function (isInlineTarget, rootNode, pos) {
22595      return findRootInline(isInlineTarget, rootNode, pos).filter(curry(isNotInsideFormatCaretContainer, rootNode));
22596    };
22597    var start$1 = function (isInlineTarget, rootNode, pos) {
22598      var nPos = normalizeBackwards(pos);
22599      return findInsideRootInline(isInlineTarget, rootNode, nPos).bind(function (inline) {
22600        var prevPos = prevPosition(inline, nPos);
22601        return prevPos.isNone() ? Optional.some(Location.start(inline)) : Optional.none();
22602      });
22603    };
22604    var end = function (isInlineTarget, rootNode, pos) {
22605      var nPos = normalizeForwards(pos);
22606      return findInsideRootInline(isInlineTarget, rootNode, nPos).bind(function (inline) {
22607        var nextPos = nextPosition(inline, nPos);
22608        return nextPos.isNone() ? Optional.some(Location.end(inline)) : Optional.none();
22609      });
22610    };
22611    var after = function (isInlineTarget, rootNode, pos) {
22612      var nPos = normalizeBackwards(pos);
22613      var scope = rescope$1(rootNode, nPos.container());
22614      return findRootInline(isInlineTarget, scope, nPos).fold(function () {
22615        return prevPosition(scope, nPos).bind(curry(findRootInline, isInlineTarget, scope)).map(function (inline) {
22616          return Location.after(inline);
22617        });
22618      }, Optional.none);
22619    };
22620    var isValidLocation = function (location) {
22621      return isRtl(getElement(location)) === false;
22622    };
22623    var readLocation = function (isInlineTarget, rootNode, pos) {
22624      var location = evaluateUntil([
22625        before,
22626        start$1,
22627        end,
22628        after
22629      ], [
22630        isInlineTarget,
22631        rootNode,
22632        pos
22633      ]);
22634      return location.filter(isValidLocation);
22635    };
22636    var getElement = function (location) {
22637      return location.fold(identity, identity, identity, identity);
22638    };
22639    var getName = function (location) {
22640      return location.fold(constant('before'), constant('start'), constant('end'), constant('after'));
22641    };
22642    var outside = function (location) {
22643      return location.fold(Location.before, Location.before, Location.after, Location.after);
22644    };
22645    var inside = function (location) {
22646      return location.fold(Location.start, Location.start, Location.end, Location.end);
22647    };
22648    var isEq = function (location1, location2) {
22649      return getName(location1) === getName(location2) && getElement(location1) === getElement(location2);
22650    };
22651    var betweenInlines = function (forward, isInlineTarget, rootNode, from, to, location) {
22652      return lift2(findRootInline(isInlineTarget, rootNode, from), findRootInline(isInlineTarget, rootNode, to), function (fromInline, toInline) {
22653        if (fromInline !== toInline && hasSameParentBlock(rootNode, fromInline, toInline)) {
22654          return Location.after(forward ? fromInline : toInline);
22655        } else {
22656          return location;
22657        }
22658      }).getOr(location);
22659    };
22660    var skipNoMovement = function (fromLocation, toLocation) {
22661      return fromLocation.fold(always, function (fromLocation) {
22662        return !isEq(fromLocation, toLocation);
22663      });
22664    };
22665    var findLocationTraverse = function (forward, isInlineTarget, rootNode, fromLocation, pos) {
22666      var from = normalizePosition(forward, pos);
22667      var to = fromPosition(forward, rootNode, from).map(curry(normalizePosition, forward));
22668      var location = to.fold(function () {
22669        return fromLocation.map(outside);
22670      }, function (to) {
22671        return readLocation(isInlineTarget, rootNode, to).map(curry(betweenInlines, forward, isInlineTarget, rootNode, from, to)).filter(curry(skipNoMovement, fromLocation));
22672      });
22673      return location.filter(isValidLocation);
22674    };
22675    var findLocationSimple = function (forward, location) {
22676      if (forward) {
22677        return location.fold(compose(Optional.some, Location.start), Optional.none, compose(Optional.some, Location.after), Optional.none);
22678      } else {
22679        return location.fold(Optional.none, compose(Optional.some, Location.before), Optional.none, compose(Optional.some, Location.end));
22680      }
22681    };
22682    var findLocation$1 = function (forward, isInlineTarget, rootNode, pos) {
22683      var from = normalizePosition(forward, pos);
22684      var fromLocation = readLocation(isInlineTarget, rootNode, from);
22685      return readLocation(isInlineTarget, rootNode, from).bind(curry(findLocationSimple, forward)).orThunk(function () {
22686        return findLocationTraverse(forward, isInlineTarget, rootNode, fromLocation, pos);
22687      });
22688    };
22689    curry(findLocation$1, false);
22690    curry(findLocation$1, true);
22691
22692    var hasSelectionModifyApi = function (editor) {
22693      return isFunction(editor.selection.getSel().modify);
22694    };
22695    var moveRel = function (forward, selection, pos) {
22696      var delta = forward ? 1 : -1;
22697      selection.setRng(CaretPosition(pos.container(), pos.offset() + delta).toRange());
22698      selection.getSel().modify('move', forward ? 'forward' : 'backward', 'word');
22699      return true;
22700    };
22701    var moveByWord = function (forward, editor) {
22702      var rng = editor.selection.getRng();
22703      var pos = forward ? CaretPosition.fromRangeEnd(rng) : CaretPosition.fromRangeStart(rng);
22704      if (!hasSelectionModifyApi(editor)) {
22705        return false;
22706      } else if (forward && isBeforeInline(pos)) {
22707        return moveRel(true, editor.selection, pos);
22708      } else if (!forward && isAfterInline(pos)) {
22709        return moveRel(false, editor.selection, pos);
22710      } else {
22711        return false;
22712      }
22713    };
22714
22715    var BreakType;
22716    (function (BreakType) {
22717      BreakType[BreakType['Br'] = 0] = 'Br';
22718      BreakType[BreakType['Block'] = 1] = 'Block';
22719      BreakType[BreakType['Wrap'] = 2] = 'Wrap';
22720      BreakType[BreakType['Eol'] = 3] = 'Eol';
22721    }(BreakType || (BreakType = {})));
22722    var flip = function (direction, positions) {
22723      return direction === HDirection.Backwards ? reverse(positions) : positions;
22724    };
22725    var walk = function (direction, caretWalker, pos) {
22726      return direction === HDirection.Forwards ? caretWalker.next(pos) : caretWalker.prev(pos);
22727    };
22728    var getBreakType = function (scope, direction, currentPos, nextPos) {
22729      if (isBr$5(nextPos.getNode(direction === HDirection.Forwards))) {
22730        return BreakType.Br;
22731      } else if (isInSameBlock(currentPos, nextPos) === false) {
22732        return BreakType.Block;
22733      } else {
22734        return BreakType.Wrap;
22735      }
22736    };
22737    var getPositionsUntil = function (predicate, direction, scope, start) {
22738      var caretWalker = CaretWalker(scope);
22739      var currentPos = start;
22740      var positions = [];
22741      while (currentPos) {
22742        var nextPos = walk(direction, caretWalker, currentPos);
22743        if (!nextPos) {
22744          break;
22745        }
22746        if (isBr$5(nextPos.getNode(false))) {
22747          if (direction === HDirection.Forwards) {
22748            return {
22749              positions: flip(direction, positions).concat([nextPos]),
22750              breakType: BreakType.Br,
22751              breakAt: Optional.some(nextPos)
22752            };
22753          } else {
22754            return {
22755              positions: flip(direction, positions),
22756              breakType: BreakType.Br,
22757              breakAt: Optional.some(nextPos)
22758            };
22759          }
22760        }
22761        if (!nextPos.isVisible()) {
22762          currentPos = nextPos;
22763          continue;
22764        }
22765        if (predicate(currentPos, nextPos)) {
22766          var breakType = getBreakType(scope, direction, currentPos, nextPos);
22767          return {
22768            positions: flip(direction, positions),
22769            breakType: breakType,
22770            breakAt: Optional.some(nextPos)
22771          };
22772        }
22773        positions.push(nextPos);
22774        currentPos = nextPos;
22775      }
22776      return {
22777        positions: flip(direction, positions),
22778        breakType: BreakType.Eol,
22779        breakAt: Optional.none()
22780      };
22781    };
22782    var getAdjacentLinePositions = function (direction, getPositionsUntilBreak, scope, start) {
22783      return getPositionsUntilBreak(scope, start).breakAt.map(function (pos) {
22784        var positions = getPositionsUntilBreak(scope, pos).positions;
22785        return direction === HDirection.Backwards ? positions.concat(pos) : [pos].concat(positions);
22786      }).getOr([]);
22787    };
22788    var findClosestHorizontalPositionFromPoint = function (positions, x) {
22789      return foldl(positions, function (acc, newPos) {
22790        return acc.fold(function () {
22791          return Optional.some(newPos);
22792        }, function (lastPos) {
22793          return lift2(head(lastPos.getClientRects()), head(newPos.getClientRects()), function (lastRect, newRect) {
22794            var lastDist = Math.abs(x - lastRect.left);
22795            var newDist = Math.abs(x - newRect.left);
22796            return newDist <= lastDist ? newPos : lastPos;
22797          }).or(acc);
22798        });
22799      }, Optional.none());
22800    };
22801    var findClosestHorizontalPosition = function (positions, pos) {
22802      return head(pos.getClientRects()).bind(function (targetRect) {
22803        return findClosestHorizontalPositionFromPoint(positions, targetRect.left);
22804      });
22805    };
22806    var getPositionsUntilPreviousLine = curry(getPositionsUntil, CaretPosition.isAbove, -1);
22807    var getPositionsUntilNextLine = curry(getPositionsUntil, CaretPosition.isBelow, 1);
22808    var getPositionsAbove = curry(getAdjacentLinePositions, -1, getPositionsUntilPreviousLine);
22809    var getPositionsBelow = curry(getAdjacentLinePositions, 1, getPositionsUntilNextLine);
22810    var isAtFirstLine = function (scope, pos) {
22811      return getPositionsUntilPreviousLine(scope, pos).breakAt.isNone();
22812    };
22813    var isAtLastLine = function (scope, pos) {
22814      return getPositionsUntilNextLine(scope, pos).breakAt.isNone();
22815    };
22816    var getFirstLinePositions = function (scope) {
22817      return firstPositionIn(scope).map(function (pos) {
22818        return [pos].concat(getPositionsUntilNextLine(scope, pos).positions);
22819      }).getOr([]);
22820    };
22821    var getLastLinePositions = function (scope) {
22822      return lastPositionIn(scope).map(function (pos) {
22823        return getPositionsUntilPreviousLine(scope, pos).positions.concat(pos);
22824      }).getOr([]);
22825    };
22826
22827    var getNodeClientRects = function (node) {
22828      var toArrayWithNode = function (clientRects) {
22829        return map$3(clientRects, function (rect) {
22830          var clientRect = clone(rect);
22831          clientRect.node = node;
22832          return clientRect;
22833        });
22834      };
22835      if (isElement$5(node)) {
22836        return toArrayWithNode(node.getClientRects());
22837      }
22838      if (isText$7(node)) {
22839        var rng = node.ownerDocument.createRange();
22840        rng.setStart(node, 0);
22841        rng.setEnd(node, node.data.length);
22842        return toArrayWithNode(rng.getClientRects());
22843      }
22844    };
22845    var getClientRects = function (nodes) {
22846      return bind(nodes, getNodeClientRects);
22847    };
22848
22849    var VDirection;
22850    (function (VDirection) {
22851      VDirection[VDirection['Up'] = -1] = 'Up';
22852      VDirection[VDirection['Down'] = 1] = 'Down';
22853    }(VDirection || (VDirection = {})));
22854    var findUntil = function (direction, root, predicateFn, node) {
22855      while (node = findNode$1(node, direction, isEditableCaretCandidate$1, root)) {
22856        if (predicateFn(node)) {
22857          return;
22858        }
22859      }
22860    };
22861    var walkUntil$1 = function (direction, isAboveFn, isBeflowFn, root, predicateFn, caretPosition) {
22862      var line = 0;
22863      var result = [];
22864      var add = function (node) {
22865        var clientRects = getClientRects([node]);
22866        if (direction === -1) {
22867          clientRects = clientRects.reverse();
22868        }
22869        for (var i = 0; i < clientRects.length; i++) {
22870          var clientRect = clientRects[i];
22871          if (isBeflowFn(clientRect, targetClientRect)) {
22872            continue;
22873          }
22874          if (result.length > 0 && isAboveFn(clientRect, last$1(result))) {
22875            line++;
22876          }
22877          clientRect.line = line;
22878          if (predicateFn(clientRect)) {
22879            return true;
22880          }
22881          result.push(clientRect);
22882        }
22883      };
22884      var targetClientRect = last$1(caretPosition.getClientRects());
22885      if (!targetClientRect) {
22886        return result;
22887      }
22888      var node = caretPosition.getNode();
22889      add(node);
22890      findUntil(direction, root, add, node);
22891      return result;
22892    };
22893    var aboveLineNumber = function (lineNumber, clientRect) {
22894      return clientRect.line > lineNumber;
22895    };
22896    var isLineNumber = function (lineNumber, clientRect) {
22897      return clientRect.line === lineNumber;
22898    };
22899    var upUntil = curry(walkUntil$1, VDirection.Up, isAbove$1, isBelow$1);
22900    var downUntil = curry(walkUntil$1, VDirection.Down, isBelow$1, isAbove$1);
22901    var positionsUntil = function (direction, root, predicateFn, node) {
22902      var caretWalker = CaretWalker(root);
22903      var walkFn;
22904      var isBelowFn;
22905      var isAboveFn;
22906      var caretPosition;
22907      var result = [];
22908      var line = 0;
22909      var getClientRect = function (caretPosition) {
22910        if (direction === 1) {
22911          return last$1(caretPosition.getClientRects());
22912        }
22913        return last$1(caretPosition.getClientRects());
22914      };
22915      if (direction === 1) {
22916        walkFn = caretWalker.next;
22917        isBelowFn = isBelow$1;
22918        isAboveFn = isAbove$1;
22919        caretPosition = CaretPosition.after(node);
22920      } else {
22921        walkFn = caretWalker.prev;
22922        isBelowFn = isAbove$1;
22923        isAboveFn = isBelow$1;
22924        caretPosition = CaretPosition.before(node);
22925      }
22926      var targetClientRect = getClientRect(caretPosition);
22927      do {
22928        if (!caretPosition.isVisible()) {
22929          continue;
22930        }
22931        var rect = getClientRect(caretPosition);
22932        if (isAboveFn(rect, targetClientRect)) {
22933          continue;
22934        }
22935        if (result.length > 0 && isBelowFn(rect, last$1(result))) {
22936          line++;
22937        }
22938        var clientRect = clone(rect);
22939        clientRect.position = caretPosition;
22940        clientRect.line = line;
22941        if (predicateFn(clientRect)) {
22942          return result;
22943        }
22944        result.push(clientRect);
22945      } while (caretPosition = walkFn(caretPosition));
22946      return result;
22947    };
22948    var isAboveLine = function (lineNumber) {
22949      return function (clientRect) {
22950        return aboveLineNumber(lineNumber, clientRect);
22951      };
22952    };
22953    var isLine = function (lineNumber) {
22954      return function (clientRect) {
22955        return isLineNumber(lineNumber, clientRect);
22956      };
22957    };
22958
22959    var isContentEditableFalse$3 = isContentEditableFalse$b;
22960    var findNode = findNode$1;
22961    var distanceToRectLeft = function (clientRect, clientX) {
22962      return Math.abs(clientRect.left - clientX);
22963    };
22964    var distanceToRectRight = function (clientRect, clientX) {
22965      return Math.abs(clientRect.right - clientX);
22966    };
22967    var isInsideX = function (clientX, clientRect) {
22968      return clientX >= clientRect.left && clientX <= clientRect.right;
22969    };
22970    var isInsideY = function (clientY, clientRect) {
22971      return clientY >= clientRect.top && clientY <= clientRect.bottom;
22972    };
22973    var isNodeClientRect = function (rect) {
22974      return hasNonNullableKey(rect, 'node');
22975    };
22976    var findClosestClientRect = function (clientRects, clientX, allowInside) {
22977      if (allowInside === void 0) {
22978        allowInside = always;
22979      }
22980      return reduce(clientRects, function (oldClientRect, clientRect) {
22981        if (isInsideX(clientX, clientRect)) {
22982          return allowInside(clientRect) ? clientRect : oldClientRect;
22983        }
22984        if (isInsideX(clientX, oldClientRect)) {
22985          return allowInside(oldClientRect) ? oldClientRect : clientRect;
22986        }
22987        var oldDistance = Math.min(distanceToRectLeft(oldClientRect, clientX), distanceToRectRight(oldClientRect, clientX));
22988        var newDistance = Math.min(distanceToRectLeft(clientRect, clientX), distanceToRectRight(clientRect, clientX));
22989        if (newDistance === oldDistance && isNodeClientRect(clientRect) && isContentEditableFalse$3(clientRect.node)) {
22990          return clientRect;
22991        }
22992        if (newDistance < oldDistance) {
22993          return clientRect;
22994        }
22995        return oldClientRect;
22996      });
22997    };
22998    var walkUntil = function (direction, root, predicateFn, startNode, includeChildren) {
22999      var node = findNode(startNode, direction, isEditableCaretCandidate$1, root, !includeChildren);
23000      do {
23001        if (!node || predicateFn(node)) {
23002          return;
23003        }
23004      } while (node = findNode(node, direction, isEditableCaretCandidate$1, root));
23005    };
23006    var findLineNodeRects = function (root, targetNodeRect, includeChildren) {
23007      if (includeChildren === void 0) {
23008        includeChildren = true;
23009      }
23010      var clientRects = [];
23011      var collect = function (checkPosFn, node) {
23012        var lineRects = filter$4(getClientRects([node]), function (clientRect) {
23013          return !checkPosFn(clientRect, targetNodeRect);
23014        });
23015        clientRects = clientRects.concat(lineRects);
23016        return lineRects.length === 0;
23017      };
23018      clientRects.push(targetNodeRect);
23019      walkUntil(VDirection.Up, root, curry(collect, isAbove$1), targetNodeRect.node, includeChildren);
23020      walkUntil(VDirection.Down, root, curry(collect, isBelow$1), targetNodeRect.node, includeChildren);
23021      return clientRects;
23022    };
23023    var getFakeCaretTargets = function (root) {
23024      return filter$4(from(root.getElementsByTagName('*')), isFakeCaretTarget);
23025    };
23026    var caretInfo = function (clientRect, clientX) {
23027      return {
23028        node: clientRect.node,
23029        before: distanceToRectLeft(clientRect, clientX) < distanceToRectRight(clientRect, clientX)
23030      };
23031    };
23032    var closestFakeCaret = function (root, clientX, clientY) {
23033      var fakeTargetNodeRects = getClientRects(getFakeCaretTargets(root));
23034      var targetNodeRects = filter$4(fakeTargetNodeRects, curry(isInsideY, clientY));
23035      var checkInside = function (clientRect) {
23036        return !isTable$3(clientRect.node) && !isMedia$2(clientRect.node);
23037      };
23038      var closestNodeRect = findClosestClientRect(targetNodeRects, clientX, checkInside);
23039      if (closestNodeRect) {
23040        var includeChildren = checkInside(closestNodeRect);
23041        closestNodeRect = findClosestClientRect(findLineNodeRects(root, closestNodeRect, includeChildren), clientX, checkInside);
23042        if (closestNodeRect && isFakeCaretTarget(closestNodeRect.node)) {
23043          return caretInfo(closestNodeRect, clientX);
23044        }
23045      }
23046      return null;
23047    };
23048
23049    var moveToRange = function (editor, rng) {
23050      editor.selection.setRng(rng);
23051      scrollRangeIntoView(editor, editor.selection.getRng());
23052    };
23053    var renderRangeCaretOpt = function (editor, range, scrollIntoView) {
23054      return Optional.some(renderRangeCaret(editor, range, scrollIntoView));
23055    };
23056    var moveHorizontally = function (editor, direction, range, isBefore, isAfter, isElement) {
23057      var forwards = direction === HDirection.Forwards;
23058      var caretWalker = CaretWalker(editor.getBody());
23059      var getNextPosFn = curry(getVisualCaretPosition, forwards ? caretWalker.next : caretWalker.prev);
23060      var isBeforeFn = forwards ? isBefore : isAfter;
23061      if (!range.collapsed) {
23062        var node = getSelectedNode(range);
23063        if (isElement(node)) {
23064          return showCaret(direction, editor, node, direction === HDirection.Backwards, false);
23065        }
23066      }
23067      var caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range);
23068      if (isBeforeFn(caretPosition)) {
23069        return selectNode(editor, caretPosition.getNode(!forwards));
23070      }
23071      var nextCaretPosition = normalizePosition(forwards, getNextPosFn(caretPosition));
23072      var rangeIsInContainerBlock = isRangeInCaretContainerBlock(range);
23073      if (!nextCaretPosition) {
23074        return rangeIsInContainerBlock ? Optional.some(range) : Optional.none();
23075      }
23076      if (isBeforeFn(nextCaretPosition)) {
23077        return showCaret(direction, editor, nextCaretPosition.getNode(!forwards), forwards, false);
23078      }
23079      var peekCaretPosition = getNextPosFn(nextCaretPosition);
23080      if (peekCaretPosition && isBeforeFn(peekCaretPosition)) {
23081        if (isMoveInsideSameBlock(nextCaretPosition, peekCaretPosition)) {
23082          return showCaret(direction, editor, peekCaretPosition.getNode(!forwards), forwards, false);
23083        }
23084      }
23085      if (rangeIsInContainerBlock) {
23086        return renderRangeCaretOpt(editor, nextCaretPosition.toRange(), false);
23087      }
23088      return Optional.none();
23089    };
23090    var moveVertically = function (editor, direction, range, isBefore, isAfter, isElement) {
23091      var caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range);
23092      var caretClientRect = last$1(caretPosition.getClientRects());
23093      var forwards = direction === VDirection.Down;
23094      if (!caretClientRect) {
23095        return Optional.none();
23096      }
23097      var walkerFn = forwards ? downUntil : upUntil;
23098      var linePositions = walkerFn(editor.getBody(), isAboveLine(1), caretPosition);
23099      var nextLinePositions = filter$4(linePositions, isLine(1));
23100      var clientX = caretClientRect.left;
23101      var nextLineRect = findClosestClientRect(nextLinePositions, clientX);
23102      if (nextLineRect && isElement(nextLineRect.node)) {
23103        var dist1 = Math.abs(clientX - nextLineRect.left);
23104        var dist2 = Math.abs(clientX - nextLineRect.right);
23105        return showCaret(direction, editor, nextLineRect.node, dist1 < dist2, false);
23106      }
23107      var currentNode;
23108      if (isBefore(caretPosition)) {
23109        currentNode = caretPosition.getNode();
23110      } else if (isAfter(caretPosition)) {
23111        currentNode = caretPosition.getNode(true);
23112      } else {
23113        currentNode = getSelectedNode(range);
23114      }
23115      if (currentNode) {
23116        var caretPositions = positionsUntil(direction, editor.getBody(), isAboveLine(1), currentNode);
23117        var closestNextLineRect = findClosestClientRect(filter$4(caretPositions, isLine(1)), clientX);
23118        if (closestNextLineRect) {
23119          return renderRangeCaretOpt(editor, closestNextLineRect.position.toRange(), false);
23120        }
23121        closestNextLineRect = last$1(filter$4(caretPositions, isLine(0)));
23122        if (closestNextLineRect) {
23123          return renderRangeCaretOpt(editor, closestNextLineRect.position.toRange(), false);
23124        }
23125      }
23126      if (nextLinePositions.length === 0) {
23127        return getLineEndPoint(editor, forwards).filter(forwards ? isAfter : isBefore).map(function (pos) {
23128          return renderRangeCaret(editor, pos.toRange(), false);
23129        });
23130      }
23131      return Optional.none();
23132    };
23133    var getLineEndPoint = function (editor, forward) {
23134      var rng = editor.selection.getRng();
23135      var body = editor.getBody();
23136      if (forward) {
23137        var from = CaretPosition.fromRangeEnd(rng);
23138        var result = getPositionsUntilNextLine(body, from);
23139        return last$2(result.positions);
23140      } else {
23141        var from = CaretPosition.fromRangeStart(rng);
23142        var result = getPositionsUntilPreviousLine(body, from);
23143        return head(result.positions);
23144      }
23145    };
23146    var moveToLineEndPoint$3 = function (editor, forward, isElementPosition) {
23147      return getLineEndPoint(editor, forward).filter(isElementPosition).exists(function (pos) {
23148        editor.selection.setRng(pos.toRange());
23149        return true;
23150      });
23151    };
23152
23153    var setCaretPosition = function (editor, pos) {
23154      var rng = editor.dom.createRng();
23155      rng.setStart(pos.container(), pos.offset());
23156      rng.setEnd(pos.container(), pos.offset());
23157      editor.selection.setRng(rng);
23158    };
23159    var setSelected = function (state, elm) {
23160      if (state) {
23161        elm.setAttribute('data-mce-selected', 'inline-boundary');
23162      } else {
23163        elm.removeAttribute('data-mce-selected');
23164      }
23165    };
23166    var renderCaretLocation = function (editor, caret, location) {
23167      return renderCaret(caret, location).map(function (pos) {
23168        setCaretPosition(editor, pos);
23169        return location;
23170      });
23171    };
23172    var findLocation = function (editor, caret, forward) {
23173      var rootNode = editor.getBody();
23174      var from = CaretPosition.fromRangeStart(editor.selection.getRng());
23175      var isInlineTarget$1 = curry(isInlineTarget, editor);
23176      var location = findLocation$1(forward, isInlineTarget$1, rootNode, from);
23177      return location.bind(function (location) {
23178        return renderCaretLocation(editor, caret, location);
23179      });
23180    };
23181    var toggleInlines = function (isInlineTarget, dom, elms) {
23182      var inlineBoundaries = map$3(descendants(SugarElement.fromDom(dom.getRoot()), '*[data-mce-selected="inline-boundary"]'), function (e) {
23183        return e.dom;
23184      });
23185      var selectedInlines = filter$4(inlineBoundaries, isInlineTarget);
23186      var targetInlines = filter$4(elms, isInlineTarget);
23187      each$k(difference(selectedInlines, targetInlines), curry(setSelected, false));
23188      each$k(difference(targetInlines, selectedInlines), curry(setSelected, true));
23189    };
23190    var safeRemoveCaretContainer = function (editor, caret) {
23191      if (editor.selection.isCollapsed() && editor.composing !== true && caret.get()) {
23192        var pos = CaretPosition.fromRangeStart(editor.selection.getRng());
23193        if (CaretPosition.isTextPosition(pos) && isAtZwsp(pos) === false) {
23194          setCaretPosition(editor, removeAndReposition(caret.get(), pos));
23195          caret.set(null);
23196        }
23197      }
23198    };
23199    var renderInsideInlineCaret = function (isInlineTarget, editor, caret, elms) {
23200      if (editor.selection.isCollapsed()) {
23201        var inlines = filter$4(elms, isInlineTarget);
23202        each$k(inlines, function (_inline) {
23203          var pos = CaretPosition.fromRangeStart(editor.selection.getRng());
23204          readLocation(isInlineTarget, editor.getBody(), pos).bind(function (location) {
23205            return renderCaretLocation(editor, caret, location);
23206          });
23207        });
23208      }
23209    };
23210    var move$2 = function (editor, caret, forward) {
23211      return isInlineBoundariesEnabled(editor) ? findLocation(editor, caret, forward).isSome() : false;
23212    };
23213    var moveWord = function (forward, editor, _caret) {
23214      return isInlineBoundariesEnabled(editor) ? moveByWord(forward, editor) : false;
23215    };
23216    var setupSelectedState = function (editor) {
23217      var caret = Cell(null);
23218      var isInlineTarget$1 = curry(isInlineTarget, editor);
23219      editor.on('NodeChange', function (e) {
23220        if (isInlineBoundariesEnabled(editor) && !(Env.browser.isIE() && e.initial)) {
23221          toggleInlines(isInlineTarget$1, editor.dom, e.parents);
23222          safeRemoveCaretContainer(editor, caret);
23223          renderInsideInlineCaret(isInlineTarget$1, editor, caret, e.parents);
23224        }
23225      });
23226      return caret;
23227    };
23228    var moveNextWord = curry(moveWord, true);
23229    var movePrevWord = curry(moveWord, false);
23230    var moveToLineEndPoint$2 = function (editor, forward, caret) {
23231      if (isInlineBoundariesEnabled(editor)) {
23232        var linePoint = getLineEndPoint(editor, forward).getOrThunk(function () {
23233          var rng = editor.selection.getRng();
23234          return forward ? CaretPosition.fromRangeEnd(rng) : CaretPosition.fromRangeStart(rng);
23235        });
23236        return readLocation(curry(isInlineTarget, editor), editor.getBody(), linePoint).exists(function (loc) {
23237          var outsideLoc = outside(loc);
23238          return renderCaret(caret, outsideLoc).exists(function (pos) {
23239            setCaretPosition(editor, pos);
23240            return true;
23241          });
23242        });
23243      } else {
23244        return false;
23245      }
23246    };
23247
23248    var rangeFromPositions = function (from, to) {
23249      var range = document.createRange();
23250      range.setStart(from.container(), from.offset());
23251      range.setEnd(to.container(), to.offset());
23252      return range;
23253    };
23254    var hasOnlyTwoOrLessPositionsLeft = function (elm) {
23255      return lift2(firstPositionIn(elm), lastPositionIn(elm), function (firstPos, lastPos) {
23256        var normalizedFirstPos = normalizePosition(true, firstPos);
23257        var normalizedLastPos = normalizePosition(false, lastPos);
23258        return nextPosition(elm, normalizedFirstPos).forall(function (pos) {
23259          return pos.isEqual(normalizedLastPos);
23260        });
23261      }).getOr(true);
23262    };
23263    var setCaretLocation = function (editor, caret) {
23264      return function (location) {
23265        return renderCaret(caret, location).exists(function (pos) {
23266          setCaretPosition(editor, pos);
23267          return true;
23268        });
23269      };
23270    };
23271    var deleteFromTo = function (editor, caret, from, to) {
23272      var rootNode = editor.getBody();
23273      var isInlineTarget$1 = curry(isInlineTarget, editor);
23274      editor.undoManager.ignore(function () {
23275        editor.selection.setRng(rangeFromPositions(from, to));
23276        editor.execCommand('Delete');
23277        readLocation(isInlineTarget$1, rootNode, CaretPosition.fromRangeStart(editor.selection.getRng())).map(inside).map(setCaretLocation(editor, caret));
23278      });
23279      editor.nodeChanged();
23280    };
23281    var rescope = function (rootNode, node) {
23282      var parentBlock = getParentBlock$2(node, rootNode);
23283      return parentBlock ? parentBlock : rootNode;
23284    };
23285    var backspaceDeleteCollapsed = function (editor, caret, forward, from) {
23286      var rootNode = rescope(editor.getBody(), from.container());
23287      var isInlineTarget$1 = curry(isInlineTarget, editor);
23288      var fromLocation = readLocation(isInlineTarget$1, rootNode, from);
23289      return fromLocation.bind(function (location) {
23290        if (forward) {
23291          return location.fold(constant(Optional.some(inside(location))), Optional.none, constant(Optional.some(outside(location))), Optional.none);
23292        } else {
23293          return location.fold(Optional.none, constant(Optional.some(outside(location))), Optional.none, constant(Optional.some(inside(location))));
23294        }
23295      }).map(setCaretLocation(editor, caret)).getOrThunk(function () {
23296        var toPosition = navigate(forward, rootNode, from);
23297        var toLocation = toPosition.bind(function (pos) {
23298          return readLocation(isInlineTarget$1, rootNode, pos);
23299        });
23300        return lift2(fromLocation, toLocation, function () {
23301          return findRootInline(isInlineTarget$1, rootNode, from).exists(function (elm) {
23302            if (hasOnlyTwoOrLessPositionsLeft(elm)) {
23303              deleteElement$2(editor, forward, SugarElement.fromDom(elm));
23304              return true;
23305            } else {
23306              return false;
23307            }
23308          });
23309        }).orThunk(function () {
23310          return toLocation.bind(function (_) {
23311            return toPosition.map(function (to) {
23312              if (forward) {
23313                deleteFromTo(editor, caret, from, to);
23314              } else {
23315                deleteFromTo(editor, caret, to, from);
23316              }
23317              return true;
23318            });
23319          });
23320        }).getOr(false);
23321      });
23322    };
23323    var backspaceDelete$3 = function (editor, caret, forward) {
23324      if (editor.selection.isCollapsed() && isInlineBoundariesEnabled(editor)) {
23325        var from = CaretPosition.fromRangeStart(editor.selection.getRng());
23326        return backspaceDeleteCollapsed(editor, caret, forward, from);
23327      }
23328      return false;
23329    };
23330
23331    var getParentInlines = function (rootElm, startElm) {
23332      var parents = parentsAndSelf(startElm, rootElm);
23333      return findIndex$2(parents, isBlock$2).fold(constant(parents), function (index) {
23334        return parents.slice(0, index);
23335      });
23336    };
23337    var hasOnlyOneChild = function (elm) {
23338      return childNodesCount(elm) === 1;
23339    };
23340    var deleteLastPosition = function (forward, editor, target, parentInlines) {
23341      var isFormatElement$1 = curry(isFormatElement, editor);
23342      var formatNodes = map$3(filter$4(parentInlines, isFormatElement$1), function (elm) {
23343        return elm.dom;
23344      });
23345      if (formatNodes.length === 0) {
23346        deleteElement$2(editor, forward, target);
23347      } else {
23348        var pos = replaceWithCaretFormat(target.dom, formatNodes);
23349        editor.selection.setRng(pos.toRange());
23350      }
23351    };
23352    var deleteCaret$1 = function (editor, forward) {
23353      var rootElm = SugarElement.fromDom(editor.getBody());
23354      var startElm = SugarElement.fromDom(editor.selection.getStart());
23355      var parentInlines = filter$4(getParentInlines(rootElm, startElm), hasOnlyOneChild);
23356      return last$2(parentInlines).exists(function (target) {
23357        var fromPos = CaretPosition.fromRangeStart(editor.selection.getRng());
23358        if (willDeleteLastPositionInElement(forward, fromPos, target.dom) && !isEmptyCaretFormatElement(target)) {
23359          deleteLastPosition(forward, editor, target, parentInlines);
23360          return true;
23361        } else {
23362          return false;
23363        }
23364      });
23365    };
23366    var backspaceDelete$2 = function (editor, forward) {
23367      return editor.selection.isCollapsed() ? deleteCaret$1(editor, forward) : false;
23368    };
23369
23370    var deleteElement = function (editor, forward, element) {
23371      editor._selectionOverrides.hideFakeCaret();
23372      deleteElement$2(editor, forward, SugarElement.fromDom(element));
23373      return true;
23374    };
23375    var deleteCaret = function (editor, forward) {
23376      var isNearMedia = forward ? isBeforeMedia : isAfterMedia;
23377      var direction = forward ? HDirection.Forwards : HDirection.Backwards;
23378      var fromPos = getNormalizedRangeEndPoint(direction, editor.getBody(), editor.selection.getRng());
23379      if (isNearMedia(fromPos)) {
23380        return deleteElement(editor, forward, fromPos.getNode(!forward));
23381      } else {
23382        return Optional.from(normalizePosition(forward, fromPos)).filter(function (pos) {
23383          return isNearMedia(pos) && isMoveInsideSameBlock(fromPos, pos);
23384        }).exists(function (pos) {
23385          return deleteElement(editor, forward, pos.getNode(!forward));
23386        });
23387      }
23388    };
23389    var deleteRange = function (editor, forward) {
23390      var selectedNode = editor.selection.getNode();
23391      return isMedia$2(selectedNode) ? deleteElement(editor, forward, selectedNode) : false;
23392    };
23393    var backspaceDelete$1 = function (editor, forward) {
23394      return editor.selection.isCollapsed() ? deleteCaret(editor, forward) : deleteRange(editor, forward);
23395    };
23396
23397    var isEditable = function (target) {
23398      return closest$3(target, function (elm) {
23399        return isContentEditableTrue$4(elm.dom) || isContentEditableFalse$b(elm.dom);
23400      }).exists(function (elm) {
23401        return isContentEditableTrue$4(elm.dom);
23402      });
23403    };
23404    var parseIndentValue = function (value) {
23405      var number = parseInt(value, 10);
23406      return isNaN(number) ? 0 : number;
23407    };
23408    var getIndentStyleName = function (useMargin, element) {
23409      var indentStyleName = useMargin || isTable$2(element) ? 'margin' : 'padding';
23410      var suffix = get$5(element, 'direction') === 'rtl' ? '-right' : '-left';
23411      return indentStyleName + suffix;
23412    };
23413    var indentElement = function (dom, command, useMargin, value, unit, element) {
23414      var indentStyleName = getIndentStyleName(useMargin, SugarElement.fromDom(element));
23415      if (command === 'outdent') {
23416        var styleValue = Math.max(0, parseIndentValue(element.style[indentStyleName]) - value);
23417        dom.setStyle(element, indentStyleName, styleValue ? styleValue + unit : '');
23418      } else {
23419        var styleValue = parseIndentValue(element.style[indentStyleName]) + value + unit;
23420        dom.setStyle(element, indentStyleName, styleValue);
23421      }
23422    };
23423    var validateBlocks = function (editor, blocks) {
23424      return forall(blocks, function (block) {
23425        var indentStyleName = getIndentStyleName(shouldIndentUseMargin(editor), block);
23426        var intentValue = getRaw(block, indentStyleName).map(parseIndentValue).getOr(0);
23427        var contentEditable = editor.dom.getContentEditable(block.dom);
23428        return contentEditable !== 'false' && intentValue > 0;
23429      });
23430    };
23431    var canOutdent = function (editor) {
23432      var blocks = getBlocksToIndent(editor);
23433      return !editor.mode.isReadOnly() && (blocks.length > 1 || validateBlocks(editor, blocks));
23434    };
23435    var isListComponent = function (el) {
23436      return isList(el) || isListItem(el);
23437    };
23438    var parentIsListComponent = function (el) {
23439      return parent(el).exists(isListComponent);
23440    };
23441    var getBlocksToIndent = function (editor) {
23442      return filter$4(fromDom$1(editor.selection.getSelectedBlocks()), function (el) {
23443        return !isListComponent(el) && !parentIsListComponent(el) && isEditable(el);
23444      });
23445    };
23446    var handle = function (editor, command) {
23447      var dom = editor.dom, selection = editor.selection, formatter = editor.formatter;
23448      var indentation = getIndentation(editor);
23449      var indentUnit = /[a-z%]+$/i.exec(indentation)[0];
23450      var indentValue = parseInt(indentation, 10);
23451      var useMargin = shouldIndentUseMargin(editor);
23452      var forcedRootBlock = getForcedRootBlock(editor);
23453      if (!editor.queryCommandState('InsertUnorderedList') && !editor.queryCommandState('InsertOrderedList')) {
23454        if (forcedRootBlock === '' && !dom.getParent(selection.getNode(), dom.isBlock)) {
23455          formatter.apply('div');
23456        }
23457      }
23458      each$k(getBlocksToIndent(editor), function (block) {
23459        indentElement(dom, command, useMargin, indentValue, indentUnit, block.dom);
23460      });
23461    };
23462
23463    var backspaceDelete = function (editor, _forward) {
23464      if (editor.selection.isCollapsed() && canOutdent(editor)) {
23465        var dom = editor.dom;
23466        var rng = editor.selection.getRng();
23467        var pos = CaretPosition.fromRangeStart(rng);
23468        var block = dom.getParent(rng.startContainer, dom.isBlock);
23469        if (block !== null && isAtStartOfBlock(SugarElement.fromDom(block), pos)) {
23470          handle(editor, 'outdent');
23471          return true;
23472        }
23473      }
23474      return false;
23475    };
23476
23477    var nativeCommand = function (editor, command) {
23478      editor.getDoc().execCommand(command, false, null);
23479    };
23480    var deleteCommand = function (editor, caret) {
23481      if (backspaceDelete(editor)) {
23482        return;
23483      } else if (backspaceDelete$5(editor, false)) {
23484        return;
23485      } else if (backspaceDelete$6(editor, false)) {
23486        return;
23487      } else if (backspaceDelete$3(editor, caret, false)) {
23488        return;
23489      } else if (backspaceDelete$8(editor, false)) {
23490        return;
23491      } else if (backspaceDelete$9(editor)) {
23492        return;
23493      } else if (backspaceDelete$4(editor, false)) {
23494        return;
23495      } else if (backspaceDelete$1(editor, false)) {
23496        return;
23497      } else if (backspaceDelete$7(editor)) {
23498        return;
23499      } else if (backspaceDelete$2(editor, false)) {
23500        return;
23501      } else {
23502        nativeCommand(editor, 'Delete');
23503        paddEmptyBody(editor);
23504      }
23505    };
23506    var forwardDeleteCommand = function (editor, caret) {
23507      if (backspaceDelete$5(editor, true)) {
23508        return;
23509      } else if (backspaceDelete$6(editor, true)) {
23510        return;
23511      } else if (backspaceDelete$3(editor, caret, true)) {
23512        return;
23513      } else if (backspaceDelete$8(editor, true)) {
23514        return;
23515      } else if (backspaceDelete$9(editor)) {
23516        return;
23517      } else if (backspaceDelete$4(editor, true)) {
23518        return;
23519      } else if (backspaceDelete$1(editor, true)) {
23520        return;
23521      } else if (backspaceDelete$7(editor)) {
23522        return;
23523      } else if (backspaceDelete$2(editor, true)) {
23524        return;
23525      } else {
23526        nativeCommand(editor, 'ForwardDelete');
23527      }
23528    };
23529    var setup$f = function (editor, caret) {
23530      editor.addCommand('delete', function () {
23531        deleteCommand(editor, caret);
23532      });
23533      editor.addCommand('forwardDelete', function () {
23534        forwardDeleteCommand(editor, caret);
23535      });
23536    };
23537
23538    var SIGNIFICANT_MOVE = 5;
23539    var LONGPRESS_DELAY = 400;
23540    var getTouch = function (event) {
23541      if (event.touches === undefined || event.touches.length !== 1) {
23542        return Optional.none();
23543      }
23544      return Optional.some(event.touches[0]);
23545    };
23546    var isFarEnough = function (touch, data) {
23547      var distX = Math.abs(touch.clientX - data.x);
23548      var distY = Math.abs(touch.clientY - data.y);
23549      return distX > SIGNIFICANT_MOVE || distY > SIGNIFICANT_MOVE;
23550    };
23551    var setup$e = function (editor) {
23552      var startData = value();
23553      var longpressFired = Cell(false);
23554      var debounceLongpress = last(function (e) {
23555        editor.fire('longpress', __assign(__assign({}, e), { type: 'longpress' }));
23556        longpressFired.set(true);
23557      }, LONGPRESS_DELAY);
23558      editor.on('touchstart', function (e) {
23559        getTouch(e).each(function (touch) {
23560          debounceLongpress.cancel();
23561          var data = {
23562            x: touch.clientX,
23563            y: touch.clientY,
23564            target: e.target
23565          };
23566          debounceLongpress.throttle(e);
23567          longpressFired.set(false);
23568          startData.set(data);
23569        });
23570      }, true);
23571      editor.on('touchmove', function (e) {
23572        debounceLongpress.cancel();
23573        getTouch(e).each(function (touch) {
23574          startData.on(function (data) {
23575            if (isFarEnough(touch, data)) {
23576              startData.clear();
23577              longpressFired.set(false);
23578              editor.fire('longpresscancel');
23579            }
23580          });
23581        });
23582      }, true);
23583      editor.on('touchend touchcancel', function (e) {
23584        debounceLongpress.cancel();
23585        if (e.type === 'touchcancel') {
23586          return;
23587        }
23588        startData.get().filter(function (data) {
23589          return data.target.isEqualNode(e.target);
23590        }).each(function () {
23591          if (longpressFired.get()) {
23592            e.preventDefault();
23593          } else {
23594            editor.fire('tap', __assign(__assign({}, e), { type: 'tap' }));
23595          }
23596        });
23597      }, true);
23598    };
23599
23600    var isBlockElement = function (blockElements, node) {
23601      return has$2(blockElements, node.nodeName);
23602    };
23603    var isValidTarget = function (blockElements, node) {
23604      if (isText$7(node)) {
23605        return true;
23606      } else if (isElement$5(node)) {
23607        return !isBlockElement(blockElements, node) && !isBookmarkNode$1(node);
23608      } else {
23609        return false;
23610      }
23611    };
23612    var hasBlockParent = function (blockElements, root, node) {
23613      return exists(parents(SugarElement.fromDom(node), SugarElement.fromDom(root)), function (elm) {
23614        return isBlockElement(blockElements, elm.dom);
23615      });
23616    };
23617    var shouldRemoveTextNode = function (blockElements, node) {
23618      if (isText$7(node)) {
23619        if (node.nodeValue.length === 0) {
23620          return true;
23621        } else if (/^\s+$/.test(node.nodeValue) && (!node.nextSibling || isBlockElement(blockElements, node.nextSibling))) {
23622          return true;
23623        }
23624      }
23625      return false;
23626    };
23627    var addRootBlocks = function (editor) {
23628      var dom = editor.dom, selection = editor.selection;
23629      var schema = editor.schema, blockElements = schema.getBlockElements();
23630      var node = selection.getStart();
23631      var rootNode = editor.getBody();
23632      var rootBlockNode, tempNode, wrapped;
23633      var forcedRootBlock = getForcedRootBlock(editor);
23634      if (!node || !isElement$5(node) || !forcedRootBlock) {
23635        return;
23636      }
23637      var rootNodeName = rootNode.nodeName.toLowerCase();
23638      if (!schema.isValidChild(rootNodeName, forcedRootBlock.toLowerCase()) || hasBlockParent(blockElements, rootNode, node)) {
23639        return;
23640      }
23641      var rng = selection.getRng();
23642      var startContainer = rng.startContainer;
23643      var startOffset = rng.startOffset;
23644      var endContainer = rng.endContainer;
23645      var endOffset = rng.endOffset;
23646      var restoreSelection = hasFocus(editor);
23647      node = rootNode.firstChild;
23648      while (node) {
23649        if (isValidTarget(blockElements, node)) {
23650          if (shouldRemoveTextNode(blockElements, node)) {
23651            tempNode = node;
23652            node = node.nextSibling;
23653            dom.remove(tempNode);
23654            continue;
23655          }
23656          if (!rootBlockNode) {
23657            rootBlockNode = dom.create(forcedRootBlock, getForcedRootBlockAttrs(editor));
23658            node.parentNode.insertBefore(rootBlockNode, node);
23659            wrapped = true;
23660          }
23661          tempNode = node;
23662          node = node.nextSibling;
23663          rootBlockNode.appendChild(tempNode);
23664        } else {
23665          rootBlockNode = null;
23666          node = node.nextSibling;
23667        }
23668      }
23669      if (wrapped && restoreSelection) {
23670        rng.setStart(startContainer, startOffset);
23671        rng.setEnd(endContainer, endOffset);
23672        selection.setRng(rng);
23673        editor.nodeChanged();
23674      }
23675    };
23676    var setup$d = function (editor) {
23677      if (getForcedRootBlock(editor)) {
23678        editor.on('NodeChange', curry(addRootBlocks, editor));
23679      }
23680    };
23681
23682    var findBlockCaretContainer = function (editor) {
23683      return descendant(SugarElement.fromDom(editor.getBody()), '*[data-mce-caret]').map(function (elm) {
23684        return elm.dom;
23685      }).getOrNull();
23686    };
23687    var removeIeControlRect = function (editor) {
23688      editor.selection.setRng(editor.selection.getRng());
23689    };
23690    var showBlockCaretContainer = function (editor, blockCaretContainer) {
23691      if (blockCaretContainer.hasAttribute('data-mce-caret')) {
23692        showCaretContainerBlock(blockCaretContainer);
23693        removeIeControlRect(editor);
23694        editor.selection.scrollIntoView(blockCaretContainer);
23695      }
23696    };
23697    var handleBlockContainer = function (editor, e) {
23698      var blockCaretContainer = findBlockCaretContainer(editor);
23699      if (!blockCaretContainer) {
23700        return;
23701      }
23702      if (e.type === 'compositionstart') {
23703        e.preventDefault();
23704        e.stopPropagation();
23705        showBlockCaretContainer(editor, blockCaretContainer);
23706        return;
23707      }
23708      if (hasContent(blockCaretContainer)) {
23709        showBlockCaretContainer(editor, blockCaretContainer);
23710        editor.undoManager.add();
23711      }
23712    };
23713    var setup$c = function (editor) {
23714      editor.on('keyup compositionstart', curry(handleBlockContainer, editor));
23715    };
23716
23717    var isContentEditableFalse$2 = isContentEditableFalse$b;
23718    var moveToCeFalseHorizontally = function (direction, editor, range) {
23719      return moveHorizontally(editor, direction, range, isBeforeContentEditableFalse, isAfterContentEditableFalse, isContentEditableFalse$2);
23720    };
23721    var moveToCeFalseVertically = function (direction, editor, range) {
23722      var isBefore = function (caretPosition) {
23723        return isBeforeContentEditableFalse(caretPosition) || isBeforeTable(caretPosition);
23724      };
23725      var isAfter = function (caretPosition) {
23726        return isAfterContentEditableFalse(caretPosition) || isAfterTable(caretPosition);
23727      };
23728      return moveVertically(editor, direction, range, isBefore, isAfter, isContentEditableFalse$2);
23729    };
23730    var createTextBlock = function (editor) {
23731      var textBlock = editor.dom.create(getForcedRootBlock(editor));
23732      if (!Env.ie || Env.ie >= 11) {
23733        textBlock.innerHTML = '<br data-mce-bogus="1">';
23734      }
23735      return textBlock;
23736    };
23737    var exitPreBlock = function (editor, direction, range) {
23738      var caretWalker = CaretWalker(editor.getBody());
23739      var getVisualCaretPosition$1 = curry(getVisualCaretPosition, direction === 1 ? caretWalker.next : caretWalker.prev);
23740      if (range.collapsed && hasForcedRootBlock(editor)) {
23741        var pre = editor.dom.getParent(range.startContainer, 'PRE');
23742        if (!pre) {
23743          return;
23744        }
23745        var caretPos = getVisualCaretPosition$1(CaretPosition.fromRangeStart(range));
23746        if (!caretPos) {
23747          var newBlock = createTextBlock(editor);
23748          if (direction === 1) {
23749            editor.$(pre).after(newBlock);
23750          } else {
23751            editor.$(pre).before(newBlock);
23752          }
23753          editor.selection.select(newBlock, true);
23754          editor.selection.collapse();
23755        }
23756      }
23757    };
23758    var getHorizontalRange = function (editor, forward) {
23759      var direction = forward ? HDirection.Forwards : HDirection.Backwards;
23760      var range = editor.selection.getRng();
23761      return moveToCeFalseHorizontally(direction, editor, range).orThunk(function () {
23762        exitPreBlock(editor, direction, range);
23763        return Optional.none();
23764      });
23765    };
23766    var getVerticalRange = function (editor, down) {
23767      var direction = down ? 1 : -1;
23768      var range = editor.selection.getRng();
23769      return moveToCeFalseVertically(direction, editor, range).orThunk(function () {
23770        exitPreBlock(editor, direction, range);
23771        return Optional.none();
23772      });
23773    };
23774    var moveH$2 = function (editor, forward) {
23775      return getHorizontalRange(editor, forward).exists(function (newRange) {
23776        moveToRange(editor, newRange);
23777        return true;
23778      });
23779    };
23780    var moveV$3 = function (editor, down) {
23781      return getVerticalRange(editor, down).exists(function (newRange) {
23782        moveToRange(editor, newRange);
23783        return true;
23784      });
23785    };
23786    var moveToLineEndPoint$1 = function (editor, forward) {
23787      var isCefPosition = forward ? isAfterContentEditableFalse : isBeforeContentEditableFalse;
23788      return moveToLineEndPoint$3(editor, forward, isCefPosition);
23789    };
23790
23791    var isTarget = function (node) {
23792      return contains$3(['figcaption'], name(node));
23793    };
23794    var rangeBefore = function (target) {
23795      var rng = document.createRange();
23796      rng.setStartBefore(target.dom);
23797      rng.setEndBefore(target.dom);
23798      return rng;
23799    };
23800    var insertElement = function (root, elm, forward) {
23801      if (forward) {
23802        append$1(root, elm);
23803      } else {
23804        prepend(root, elm);
23805      }
23806    };
23807    var insertBr = function (root, forward) {
23808      var br = SugarElement.fromTag('br');
23809      insertElement(root, br, forward);
23810      return rangeBefore(br);
23811    };
23812    var insertBlock = function (root, forward, blockName, attrs) {
23813      var block = SugarElement.fromTag(blockName);
23814      var br = SugarElement.fromTag('br');
23815      setAll$1(block, attrs);
23816      append$1(block, br);
23817      insertElement(root, block, forward);
23818      return rangeBefore(br);
23819    };
23820    var insertEmptyLine = function (root, rootBlockName, attrs, forward) {
23821      if (rootBlockName === '') {
23822        return insertBr(root, forward);
23823      } else {
23824        return insertBlock(root, forward, rootBlockName, attrs);
23825      }
23826    };
23827    var getClosestTargetBlock = function (pos, root) {
23828      var isRoot = curry(eq, root);
23829      return closest$3(SugarElement.fromDom(pos.container()), isBlock$2, isRoot).filter(isTarget);
23830    };
23831    var isAtFirstOrLastLine = function (root, forward, pos) {
23832      return forward ? isAtLastLine(root.dom, pos) : isAtFirstLine(root.dom, pos);
23833    };
23834    var moveCaretToNewEmptyLine = function (editor, forward) {
23835      var root = SugarElement.fromDom(editor.getBody());
23836      var pos = CaretPosition.fromRangeStart(editor.selection.getRng());
23837      var rootBlock = getForcedRootBlock(editor);
23838      var rootBlockAttrs = getForcedRootBlockAttrs(editor);
23839      return getClosestTargetBlock(pos, root).exists(function () {
23840        if (isAtFirstOrLastLine(root, forward, pos)) {
23841          var rng = insertEmptyLine(root, rootBlock, rootBlockAttrs, forward);
23842          editor.selection.setRng(rng);
23843          return true;
23844        } else {
23845          return false;
23846        }
23847      });
23848    };
23849    var moveV$2 = function (editor, forward) {
23850      if (editor.selection.isCollapsed()) {
23851        return moveCaretToNewEmptyLine(editor, forward);
23852      } else {
23853        return false;
23854      }
23855    };
23856
23857    var defaultPatterns = function (patterns) {
23858      return map$3(patterns, function (pattern) {
23859        return __assign({
23860          shiftKey: false,
23861          altKey: false,
23862          ctrlKey: false,
23863          metaKey: false,
23864          keyCode: 0,
23865          action: noop
23866        }, pattern);
23867      });
23868    };
23869    var matchesEvent = function (pattern, evt) {
23870      return evt.keyCode === pattern.keyCode && evt.shiftKey === pattern.shiftKey && evt.altKey === pattern.altKey && evt.ctrlKey === pattern.ctrlKey && evt.metaKey === pattern.metaKey;
23871    };
23872    var match$1 = function (patterns, evt) {
23873      return bind(defaultPatterns(patterns), function (pattern) {
23874        return matchesEvent(pattern, evt) ? [pattern] : [];
23875      });
23876    };
23877    var action = function (f) {
23878      var x = [];
23879      for (var _i = 1; _i < arguments.length; _i++) {
23880        x[_i - 1] = arguments[_i];
23881      }
23882      return function () {
23883        return f.apply(null, x);
23884      };
23885    };
23886    var execute = function (patterns, evt) {
23887      return find$3(match$1(patterns, evt), function (pattern) {
23888        return pattern.action();
23889      });
23890    };
23891
23892    var moveH$1 = function (editor, forward) {
23893      var direction = forward ? HDirection.Forwards : HDirection.Backwards;
23894      var range = editor.selection.getRng();
23895      return moveHorizontally(editor, direction, range, isBeforeMedia, isAfterMedia, isMedia$2).exists(function (newRange) {
23896        moveToRange(editor, newRange);
23897        return true;
23898      });
23899    };
23900    var moveV$1 = function (editor, down) {
23901      var direction = down ? 1 : -1;
23902      var range = editor.selection.getRng();
23903      return moveVertically(editor, direction, range, isBeforeMedia, isAfterMedia, isMedia$2).exists(function (newRange) {
23904        moveToRange(editor, newRange);
23905        return true;
23906      });
23907    };
23908    var moveToLineEndPoint = function (editor, forward) {
23909      var isNearMedia = forward ? isAfterMedia : isBeforeMedia;
23910      return moveToLineEndPoint$3(editor, forward, isNearMedia);
23911    };
23912
23913    var deflate = function (rect, delta) {
23914      return {
23915        left: rect.left - delta,
23916        top: rect.top - delta,
23917        right: rect.right + delta * 2,
23918        bottom: rect.bottom + delta * 2,
23919        width: rect.width + delta,
23920        height: rect.height + delta
23921      };
23922    };
23923    var getCorners = function (getYAxisValue, tds) {
23924      return bind(tds, function (td) {
23925        var rect = deflate(clone(td.getBoundingClientRect()), -1);
23926        return [
23927          {
23928            x: rect.left,
23929            y: getYAxisValue(rect),
23930            cell: td
23931          },
23932          {
23933            x: rect.right,
23934            y: getYAxisValue(rect),
23935            cell: td
23936          }
23937        ];
23938      });
23939    };
23940    var findClosestCorner = function (corners, x, y) {
23941      return foldl(corners, function (acc, newCorner) {
23942        return acc.fold(function () {
23943          return Optional.some(newCorner);
23944        }, function (oldCorner) {
23945          var oldDist = Math.sqrt(Math.abs(oldCorner.x - x) + Math.abs(oldCorner.y - y));
23946          var newDist = Math.sqrt(Math.abs(newCorner.x - x) + Math.abs(newCorner.y - y));
23947          return Optional.some(newDist < oldDist ? newCorner : oldCorner);
23948        });
23949      }, Optional.none());
23950    };
23951    var getClosestCell = function (getYAxisValue, isTargetCorner, table, x, y) {
23952      var cells = descendants(SugarElement.fromDom(table), 'td,th,caption').map(function (e) {
23953        return e.dom;
23954      });
23955      var corners = filter$4(getCorners(getYAxisValue, cells), function (corner) {
23956        return isTargetCorner(corner, y);
23957      });
23958      return findClosestCorner(corners, x, y).map(function (corner) {
23959        return corner.cell;
23960      });
23961    };
23962    var getBottomValue = function (rect) {
23963      return rect.bottom;
23964    };
23965    var getTopValue = function (rect) {
23966      return rect.top;
23967    };
23968    var isAbove = function (corner, y) {
23969      return corner.y < y;
23970    };
23971    var isBelow = function (corner, y) {
23972      return corner.y > y;
23973    };
23974    var getClosestCellAbove = curry(getClosestCell, getBottomValue, isAbove);
23975    var getClosestCellBelow = curry(getClosestCell, getTopValue, isBelow);
23976    var findClosestPositionInAboveCell = function (table, pos) {
23977      return head(pos.getClientRects()).bind(function (rect) {
23978        return getClosestCellAbove(table, rect.left, rect.top);
23979      }).bind(function (cell) {
23980        return findClosestHorizontalPosition(getLastLinePositions(cell), pos);
23981      });
23982    };
23983    var findClosestPositionInBelowCell = function (table, pos) {
23984      return last$2(pos.getClientRects()).bind(function (rect) {
23985        return getClosestCellBelow(table, rect.left, rect.top);
23986      }).bind(function (cell) {
23987        return findClosestHorizontalPosition(getFirstLinePositions(cell), pos);
23988      });
23989    };
23990
23991    var hasNextBreak = function (getPositionsUntil, scope, lineInfo) {
23992      return lineInfo.breakAt.exists(function (breakPos) {
23993        return getPositionsUntil(scope, breakPos).breakAt.isSome();
23994      });
23995    };
23996    var startsWithWrapBreak = function (lineInfo) {
23997      return lineInfo.breakType === BreakType.Wrap && lineInfo.positions.length === 0;
23998    };
23999    var startsWithBrBreak = function (lineInfo) {
24000      return lineInfo.breakType === BreakType.Br && lineInfo.positions.length === 1;
24001    };
24002    var isAtTableCellLine = function (getPositionsUntil, scope, pos) {
24003      var lineInfo = getPositionsUntil(scope, pos);
24004      if (startsWithWrapBreak(lineInfo) || !isBr$5(pos.getNode()) && startsWithBrBreak(lineInfo)) {
24005        return !hasNextBreak(getPositionsUntil, scope, lineInfo);
24006      } else {
24007        return lineInfo.breakAt.isNone();
24008      }
24009    };
24010    var isAtFirstTableCellLine = curry(isAtTableCellLine, getPositionsUntilPreviousLine);
24011    var isAtLastTableCellLine = curry(isAtTableCellLine, getPositionsUntilNextLine);
24012    var isCaretAtStartOrEndOfTable = function (forward, rng, table) {
24013      var caretPos = CaretPosition.fromRangeStart(rng);
24014      return positionIn(!forward, table).exists(function (pos) {
24015        return pos.isEqual(caretPos);
24016      });
24017    };
24018    var navigateHorizontally = function (editor, forward, table, _td) {
24019      var rng = editor.selection.getRng();
24020      var direction = forward ? 1 : -1;
24021      if (isFakeCaretTableBrowser() && isCaretAtStartOrEndOfTable(forward, rng, table)) {
24022        showCaret(direction, editor, table, !forward, false).each(function (newRng) {
24023          moveToRange(editor, newRng);
24024        });
24025        return true;
24026      }
24027      return false;
24028    };
24029    var getClosestAbovePosition = function (root, table, start) {
24030      return findClosestPositionInAboveCell(table, start).orThunk(function () {
24031        return head(start.getClientRects()).bind(function (rect) {
24032          return findClosestHorizontalPositionFromPoint(getPositionsAbove(root, CaretPosition.before(table)), rect.left);
24033        });
24034      }).getOr(CaretPosition.before(table));
24035    };
24036    var getClosestBelowPosition = function (root, table, start) {
24037      return findClosestPositionInBelowCell(table, start).orThunk(function () {
24038        return head(start.getClientRects()).bind(function (rect) {
24039          return findClosestHorizontalPositionFromPoint(getPositionsBelow(root, CaretPosition.after(table)), rect.left);
24040        });
24041      }).getOr(CaretPosition.after(table));
24042    };
24043    var getTable = function (previous, pos) {
24044      var node = pos.getNode(previous);
24045      return isElement$5(node) && node.nodeName === 'TABLE' ? Optional.some(node) : Optional.none();
24046    };
24047    var renderBlock = function (down, editor, table, pos) {
24048      var forcedRootBlock = getForcedRootBlock(editor);
24049      if (forcedRootBlock) {
24050        editor.undoManager.transact(function () {
24051          var element = SugarElement.fromTag(forcedRootBlock);
24052          setAll$1(element, getForcedRootBlockAttrs(editor));
24053          append$1(element, SugarElement.fromTag('br'));
24054          if (down) {
24055            after$3(SugarElement.fromDom(table), element);
24056          } else {
24057            before$4(SugarElement.fromDom(table), element);
24058          }
24059          var rng = editor.dom.createRng();
24060          rng.setStart(element.dom, 0);
24061          rng.setEnd(element.dom, 0);
24062          moveToRange(editor, rng);
24063        });
24064      } else {
24065        moveToRange(editor, pos.toRange());
24066      }
24067    };
24068    var moveCaret = function (editor, down, pos) {
24069      var table = down ? getTable(true, pos) : getTable(false, pos);
24070      var last = down === false;
24071      table.fold(function () {
24072        return moveToRange(editor, pos.toRange());
24073      }, function (table) {
24074        return positionIn(last, editor.getBody()).filter(function (lastPos) {
24075          return lastPos.isEqual(pos);
24076        }).fold(function () {
24077          return moveToRange(editor, pos.toRange());
24078        }, function (_) {
24079          return renderBlock(down, editor, table, pos);
24080        });
24081      });
24082    };
24083    var navigateVertically = function (editor, down, table, td) {
24084      var rng = editor.selection.getRng();
24085      var pos = CaretPosition.fromRangeStart(rng);
24086      var root = editor.getBody();
24087      if (!down && isAtFirstTableCellLine(td, pos)) {
24088        var newPos = getClosestAbovePosition(root, table, pos);
24089        moveCaret(editor, down, newPos);
24090        return true;
24091      } else if (down && isAtLastTableCellLine(td, pos)) {
24092        var newPos = getClosestBelowPosition(root, table, pos);
24093        moveCaret(editor, down, newPos);
24094        return true;
24095      } else {
24096        return false;
24097      }
24098    };
24099    var move$1 = function (editor, forward, mover) {
24100      return Optional.from(editor.dom.getParent(editor.selection.getNode(), 'td,th')).bind(function (td) {
24101        return Optional.from(editor.dom.getParent(td, 'table')).map(function (table) {
24102          return mover(editor, forward, table, td);
24103        });
24104      }).getOr(false);
24105    };
24106    var moveH = function (editor, forward) {
24107      return move$1(editor, forward, navigateHorizontally);
24108    };
24109    var moveV = function (editor, forward) {
24110      return move$1(editor, forward, navigateVertically);
24111    };
24112
24113    var executeKeydownOverride$3 = function (editor, caret, evt) {
24114      var os = detect().os;
24115      execute([
24116        {
24117          keyCode: VK.RIGHT,
24118          action: action(moveH$2, editor, true)
24119        },
24120        {
24121          keyCode: VK.LEFT,
24122          action: action(moveH$2, editor, false)
24123        },
24124        {
24125          keyCode: VK.UP,
24126          action: action(moveV$3, editor, false)
24127        },
24128        {
24129          keyCode: VK.DOWN,
24130          action: action(moveV$3, editor, true)
24131        },
24132        {
24133          keyCode: VK.RIGHT,
24134          action: action(moveH, editor, true)
24135        },
24136        {
24137          keyCode: VK.LEFT,
24138          action: action(moveH, editor, false)
24139        },
24140        {
24141          keyCode: VK.UP,
24142          action: action(moveV, editor, false)
24143        },
24144        {
24145          keyCode: VK.DOWN,
24146          action: action(moveV, editor, true)
24147        },
24148        {
24149          keyCode: VK.RIGHT,
24150          action: action(moveH$1, editor, true)
24151        },
24152        {
24153          keyCode: VK.LEFT,
24154          action: action(moveH$1, editor, false)
24155        },
24156        {
24157          keyCode: VK.UP,
24158          action: action(moveV$1, editor, false)
24159        },
24160        {
24161          keyCode: VK.DOWN,
24162          action: action(moveV$1, editor, true)
24163        },
24164        {
24165          keyCode: VK.RIGHT,
24166          action: action(move$2, editor, caret, true)
24167        },
24168        {
24169          keyCode: VK.LEFT,
24170          action: action(move$2, editor, caret, false)
24171        },
24172        {
24173          keyCode: VK.RIGHT,
24174          ctrlKey: !os.isOSX(),
24175          altKey: os.isOSX(),
24176          action: action(moveNextWord, editor, caret)
24177        },
24178        {
24179          keyCode: VK.LEFT,
24180          ctrlKey: !os.isOSX(),
24181          altKey: os.isOSX(),
24182          action: action(movePrevWord, editor, caret)
24183        },
24184        {
24185          keyCode: VK.UP,
24186          action: action(moveV$2, editor, false)
24187        },
24188        {
24189          keyCode: VK.DOWN,
24190          action: action(moveV$2, editor, true)
24191        }
24192      ], evt).each(function (_) {
24193        evt.preventDefault();
24194      });
24195    };
24196    var setup$b = function (editor, caret) {
24197      editor.on('keydown', function (evt) {
24198        if (evt.isDefaultPrevented() === false) {
24199          executeKeydownOverride$3(editor, caret, evt);
24200        }
24201      });
24202    };
24203
24204    var executeKeydownOverride$2 = function (editor, caret, evt) {
24205      execute([
24206        {
24207          keyCode: VK.BACKSPACE,
24208          action: action(backspaceDelete, editor, false)
24209        },
24210        {
24211          keyCode: VK.BACKSPACE,
24212          action: action(backspaceDelete$5, editor, false)
24213        },
24214        {
24215          keyCode: VK.DELETE,
24216          action: action(backspaceDelete$5, editor, true)
24217        },
24218        {
24219          keyCode: VK.BACKSPACE,
24220          action: action(backspaceDelete$6, editor, false)
24221        },
24222        {
24223          keyCode: VK.DELETE,
24224          action: action(backspaceDelete$6, editor, true)
24225        },
24226        {
24227          keyCode: VK.BACKSPACE,
24228          action: action(backspaceDelete$3, editor, caret, false)
24229        },
24230        {
24231          keyCode: VK.DELETE,
24232          action: action(backspaceDelete$3, editor, caret, true)
24233        },
24234        {
24235          keyCode: VK.BACKSPACE,
24236          action: action(backspaceDelete$9, editor, false)
24237        },
24238        {
24239          keyCode: VK.DELETE,
24240          action: action(backspaceDelete$9, editor, true)
24241        },
24242        {
24243          keyCode: VK.BACKSPACE,
24244          action: action(backspaceDelete$4, editor, false)
24245        },
24246        {
24247          keyCode: VK.DELETE,
24248          action: action(backspaceDelete$4, editor, true)
24249        },
24250        {
24251          keyCode: VK.BACKSPACE,
24252          action: action(backspaceDelete$1, editor, false)
24253        },
24254        {
24255          keyCode: VK.DELETE,
24256          action: action(backspaceDelete$1, editor, true)
24257        },
24258        {
24259          keyCode: VK.BACKSPACE,
24260          action: action(backspaceDelete$7, editor, false)
24261        },
24262        {
24263          keyCode: VK.DELETE,
24264          action: action(backspaceDelete$7, editor, true)
24265        },
24266        {
24267          keyCode: VK.BACKSPACE,
24268          action: action(backspaceDelete$8, editor, false)
24269        },
24270        {
24271          keyCode: VK.DELETE,
24272          action: action(backspaceDelete$8, editor, true)
24273        },
24274        {
24275          keyCode: VK.BACKSPACE,
24276          action: action(backspaceDelete$2, editor, false)
24277        },
24278        {
24279          keyCode: VK.DELETE,
24280          action: action(backspaceDelete$2, editor, true)
24281        }
24282      ], evt).each(function (_) {
24283        evt.preventDefault();
24284      });
24285    };
24286    var executeKeyupOverride = function (editor, evt) {
24287      execute([
24288        {
24289          keyCode: VK.BACKSPACE,
24290          action: action(paddEmptyElement, editor)
24291        },
24292        {
24293          keyCode: VK.DELETE,
24294          action: action(paddEmptyElement, editor)
24295        }
24296      ], evt);
24297    };
24298    var setup$a = function (editor, caret) {
24299      editor.on('keydown', function (evt) {
24300        if (evt.isDefaultPrevented() === false) {
24301          executeKeydownOverride$2(editor, caret, evt);
24302        }
24303      });
24304      editor.on('keyup', function (evt) {
24305        if (evt.isDefaultPrevented() === false) {
24306          executeKeyupOverride(editor, evt);
24307        }
24308      });
24309    };
24310
24311    var firstNonWhiteSpaceNodeSibling = function (node) {
24312      while (node) {
24313        if (node.nodeType === 1 || node.nodeType === 3 && node.data && /[\r\n\s]/.test(node.data)) {
24314          return node;
24315        }
24316        node = node.nextSibling;
24317      }
24318    };
24319    var moveToCaretPosition = function (editor, root) {
24320      var node, lastNode = root;
24321      var dom = editor.dom;
24322      var moveCaretBeforeOnEnterElementsMap = editor.schema.getMoveCaretBeforeOnEnterElements();
24323      if (!root) {
24324        return;
24325      }
24326      if (/^(LI|DT|DD)$/.test(root.nodeName)) {
24327        var firstChild = firstNonWhiteSpaceNodeSibling(root.firstChild);
24328        if (firstChild && /^(UL|OL|DL)$/.test(firstChild.nodeName)) {
24329          root.insertBefore(dom.doc.createTextNode(nbsp), root.firstChild);
24330        }
24331      }
24332      var rng = dom.createRng();
24333      root.normalize();
24334      if (root.hasChildNodes()) {
24335        var walker = new DomTreeWalker(root, root);
24336        while (node = walker.current()) {
24337          if (isText$7(node)) {
24338            rng.setStart(node, 0);
24339            rng.setEnd(node, 0);
24340            break;
24341          }
24342          if (moveCaretBeforeOnEnterElementsMap[node.nodeName.toLowerCase()]) {
24343            rng.setStartBefore(node);
24344            rng.setEndBefore(node);
24345            break;
24346          }
24347          lastNode = node;
24348          node = walker.next();
24349        }
24350        if (!node) {
24351          rng.setStart(lastNode, 0);
24352          rng.setEnd(lastNode, 0);
24353        }
24354      } else {
24355        if (isBr$5(root)) {
24356          if (root.nextSibling && dom.isBlock(root.nextSibling)) {
24357            rng.setStartBefore(root);
24358            rng.setEndBefore(root);
24359          } else {
24360            rng.setStartAfter(root);
24361            rng.setEndAfter(root);
24362          }
24363        } else {
24364          rng.setStart(root, 0);
24365          rng.setEnd(root, 0);
24366        }
24367      }
24368      editor.selection.setRng(rng);
24369      scrollRangeIntoView(editor, rng);
24370    };
24371    var getEditableRoot$1 = function (dom, node) {
24372      var root = dom.getRoot();
24373      var parent, editableRoot;
24374      parent = node;
24375      while (parent !== root && dom.getContentEditable(parent) !== 'false') {
24376        if (dom.getContentEditable(parent) === 'true') {
24377          editableRoot = parent;
24378        }
24379        parent = parent.parentNode;
24380      }
24381      return parent !== root ? editableRoot : root;
24382    };
24383    var getParentBlock = function (editor) {
24384      return Optional.from(editor.dom.getParent(editor.selection.getStart(true), editor.dom.isBlock));
24385    };
24386    var getParentBlockName = function (editor) {
24387      return getParentBlock(editor).fold(constant(''), function (parentBlock) {
24388        return parentBlock.nodeName.toUpperCase();
24389      });
24390    };
24391    var isListItemParentBlock = function (editor) {
24392      return getParentBlock(editor).filter(function (elm) {
24393        return isListItem(SugarElement.fromDom(elm));
24394      }).isSome();
24395    };
24396
24397    var hasFirstChild = function (elm, name) {
24398      return elm.firstChild && elm.firstChild.nodeName === name;
24399    };
24400    var isFirstChild = function (elm) {
24401      var _a;
24402      return ((_a = elm.parentNode) === null || _a === void 0 ? void 0 : _a.firstChild) === elm;
24403    };
24404    var hasParent = function (elm, parentName) {
24405      return elm && elm.parentNode && elm.parentNode.nodeName === parentName;
24406    };
24407    var isListBlock = function (elm) {
24408      return elm && /^(OL|UL|LI)$/.test(elm.nodeName);
24409    };
24410    var isNestedList = function (elm) {
24411      return isListBlock(elm) && isListBlock(elm.parentNode);
24412    };
24413    var getContainerBlock = function (containerBlock) {
24414      var containerBlockParent = containerBlock.parentNode;
24415      if (/^(LI|DT|DD)$/.test(containerBlockParent.nodeName)) {
24416        return containerBlockParent;
24417      }
24418      return containerBlock;
24419    };
24420    var isFirstOrLastLi = function (containerBlock, parentBlock, first) {
24421      var node = containerBlock[first ? 'firstChild' : 'lastChild'];
24422      while (node) {
24423        if (isElement$5(node)) {
24424          break;
24425        }
24426        node = node[first ? 'nextSibling' : 'previousSibling'];
24427      }
24428      return node === parentBlock;
24429    };
24430    var insert$3 = function (editor, createNewBlock, containerBlock, parentBlock, newBlockName) {
24431      var dom = editor.dom;
24432      var rng = editor.selection.getRng();
24433      if (containerBlock === editor.getBody()) {
24434        return;
24435      }
24436      if (isNestedList(containerBlock)) {
24437        newBlockName = 'LI';
24438      }
24439      var newBlock = newBlockName ? createNewBlock(newBlockName) : dom.create('BR');
24440      if (isFirstOrLastLi(containerBlock, parentBlock, true) && isFirstOrLastLi(containerBlock, parentBlock, false)) {
24441        if (hasParent(containerBlock, 'LI')) {
24442          var containerBlockParent = getContainerBlock(containerBlock);
24443          dom.insertAfter(newBlock, containerBlockParent);
24444          if (isFirstChild(containerBlock)) {
24445            dom.remove(containerBlockParent);
24446          } else {
24447            dom.remove(containerBlock);
24448          }
24449        } else {
24450          dom.replace(newBlock, containerBlock);
24451        }
24452      } else if (isFirstOrLastLi(containerBlock, parentBlock, true)) {
24453        if (hasParent(containerBlock, 'LI')) {
24454          dom.insertAfter(newBlock, getContainerBlock(containerBlock));
24455          newBlock.appendChild(dom.doc.createTextNode(' '));
24456          newBlock.appendChild(containerBlock);
24457        } else {
24458          containerBlock.parentNode.insertBefore(newBlock, containerBlock);
24459        }
24460        dom.remove(parentBlock);
24461      } else if (isFirstOrLastLi(containerBlock, parentBlock, false)) {
24462        dom.insertAfter(newBlock, getContainerBlock(containerBlock));
24463        dom.remove(parentBlock);
24464      } else {
24465        containerBlock = getContainerBlock(containerBlock);
24466        var tmpRng = rng.cloneRange();
24467        tmpRng.setStartAfter(parentBlock);
24468        tmpRng.setEndAfter(containerBlock);
24469        var fragment = tmpRng.extractContents();
24470        if (newBlockName === 'LI' && hasFirstChild(fragment, 'LI')) {
24471          newBlock = fragment.firstChild;
24472          dom.insertAfter(fragment, containerBlock);
24473        } else {
24474          dom.insertAfter(fragment, containerBlock);
24475          dom.insertAfter(newBlock, containerBlock);
24476        }
24477        dom.remove(parentBlock);
24478      }
24479      moveToCaretPosition(editor, newBlock);
24480    };
24481
24482    var trimZwsp = function (fragment) {
24483      each$k(descendants$1(SugarElement.fromDom(fragment), isText$8), function (text) {
24484        var rawNode = text.dom;
24485        rawNode.nodeValue = trim$3(rawNode.nodeValue);
24486      });
24487    };
24488    var isEmptyAnchor = function (dom, elm) {
24489      return elm && elm.nodeName === 'A' && dom.isEmpty(elm);
24490    };
24491    var isTableCell = function (node) {
24492      return node && /^(TD|TH|CAPTION)$/.test(node.nodeName);
24493    };
24494    var emptyBlock = function (elm) {
24495      elm.innerHTML = '<br data-mce-bogus="1">';
24496    };
24497    var containerAndSiblingName = function (container, nodeName) {
24498      return container.nodeName === nodeName || container.previousSibling && container.previousSibling.nodeName === nodeName;
24499    };
24500    var canSplitBlock = function (dom, node) {
24501      return node && dom.isBlock(node) && !/^(TD|TH|CAPTION|FORM)$/.test(node.nodeName) && !/^(fixed|absolute)/i.test(node.style.position) && dom.getContentEditable(node) !== 'true';
24502    };
24503    var trimInlineElementsOnLeftSideOfBlock = function (dom, nonEmptyElementsMap, block) {
24504      var node = block;
24505      var firstChilds = [];
24506      var i;
24507      if (!node) {
24508        return;
24509      }
24510      while (node = node.firstChild) {
24511        if (dom.isBlock(node)) {
24512          return;
24513        }
24514        if (isElement$5(node) && !nonEmptyElementsMap[node.nodeName.toLowerCase()]) {
24515          firstChilds.push(node);
24516        }
24517      }
24518      i = firstChilds.length;
24519      while (i--) {
24520        node = firstChilds[i];
24521        if (!node.hasChildNodes() || node.firstChild === node.lastChild && node.firstChild.nodeValue === '') {
24522          dom.remove(node);
24523        } else {
24524          if (isEmptyAnchor(dom, node)) {
24525            dom.remove(node);
24526          }
24527        }
24528      }
24529    };
24530    var normalizeZwspOffset = function (start, container, offset) {
24531      if (isText$7(container) === false) {
24532        return offset;
24533      } else if (start) {
24534        return offset === 1 && container.data.charAt(offset - 1) === ZWSP$1 ? 0 : offset;
24535      } else {
24536        return offset === container.data.length - 1 && container.data.charAt(offset) === ZWSP$1 ? container.data.length : offset;
24537      }
24538    };
24539    var includeZwspInRange = function (rng) {
24540      var newRng = rng.cloneRange();
24541      newRng.setStart(rng.startContainer, normalizeZwspOffset(true, rng.startContainer, rng.startOffset));
24542      newRng.setEnd(rng.endContainer, normalizeZwspOffset(false, rng.endContainer, rng.endOffset));
24543      return newRng;
24544    };
24545    var trimLeadingLineBreaks = function (node) {
24546      do {
24547        if (isText$7(node)) {
24548          node.nodeValue = node.nodeValue.replace(/^[\r\n]+/, '');
24549        }
24550        node = node.firstChild;
24551      } while (node);
24552    };
24553    var getEditableRoot = function (dom, node) {
24554      var root = dom.getRoot();
24555      var parent, editableRoot;
24556      parent = node;
24557      while (parent !== root && dom.getContentEditable(parent) !== 'false') {
24558        if (dom.getContentEditable(parent) === 'true') {
24559          editableRoot = parent;
24560        }
24561        parent = parent.parentNode;
24562      }
24563      return parent !== root ? editableRoot : root;
24564    };
24565    var applyAttributes = function (editor, node, forcedRootBlockAttrs) {
24566      var dom = editor.dom;
24567      Optional.from(forcedRootBlockAttrs.style).map(dom.parseStyle).each(function (attrStyles) {
24568        var currentStyles = getAllRaw(SugarElement.fromDom(node));
24569        var newStyles = __assign(__assign({}, currentStyles), attrStyles);
24570        dom.setStyles(node, newStyles);
24571      });
24572      var attrClassesOpt = Optional.from(forcedRootBlockAttrs.class).map(function (attrClasses) {
24573        return attrClasses.split(/\s+/);
24574      });
24575      var currentClassesOpt = Optional.from(node.className).map(function (currentClasses) {
24576        return filter$4(currentClasses.split(/\s+/), function (clazz) {
24577          return clazz !== '';
24578        });
24579      });
24580      lift2(attrClassesOpt, currentClassesOpt, function (attrClasses, currentClasses) {
24581        var filteredClasses = filter$4(currentClasses, function (clazz) {
24582          return !contains$3(attrClasses, clazz);
24583        });
24584        var newClasses = __spreadArray(__spreadArray([], attrClasses, true), filteredClasses, true);
24585        dom.setAttrib(node, 'class', newClasses.join(' '));
24586      });
24587      var appliedAttrs = [
24588        'style',
24589        'class'
24590      ];
24591      var remainingAttrs = filter$3(forcedRootBlockAttrs, function (_, attrs) {
24592        return !contains$3(appliedAttrs, attrs);
24593      });
24594      dom.setAttribs(node, remainingAttrs);
24595    };
24596    var setForcedBlockAttrs = function (editor, node) {
24597      var forcedRootBlockName = getForcedRootBlock(editor);
24598      if (forcedRootBlockName && forcedRootBlockName.toLowerCase() === node.tagName.toLowerCase()) {
24599        var forcedRootBlockAttrs = getForcedRootBlockAttrs(editor);
24600        applyAttributes(editor, node, forcedRootBlockAttrs);
24601      }
24602    };
24603    var wrapSelfAndSiblingsInDefaultBlock = function (editor, newBlockName, rng, container, offset) {
24604      var newBlock, parentBlock, startNode, node, next, rootBlockName;
24605      var blockName = newBlockName || 'P';
24606      var dom = editor.dom, editableRoot = getEditableRoot(dom, container);
24607      parentBlock = dom.getParent(container, dom.isBlock);
24608      if (!parentBlock || !canSplitBlock(dom, parentBlock)) {
24609        parentBlock = parentBlock || editableRoot;
24610        if (parentBlock === editor.getBody() || isTableCell(parentBlock)) {
24611          rootBlockName = parentBlock.nodeName.toLowerCase();
24612        } else {
24613          rootBlockName = parentBlock.parentNode.nodeName.toLowerCase();
24614        }
24615        if (!parentBlock.hasChildNodes()) {
24616          newBlock = dom.create(blockName);
24617          setForcedBlockAttrs(editor, newBlock);
24618          parentBlock.appendChild(newBlock);
24619          rng.setStart(newBlock, 0);
24620          rng.setEnd(newBlock, 0);
24621          return newBlock;
24622        }
24623        node = container;
24624        while (node.parentNode !== parentBlock) {
24625          node = node.parentNode;
24626        }
24627        while (node && !dom.isBlock(node)) {
24628          startNode = node;
24629          node = node.previousSibling;
24630        }
24631        if (startNode && editor.schema.isValidChild(rootBlockName, blockName.toLowerCase())) {
24632          newBlock = dom.create(blockName);
24633          setForcedBlockAttrs(editor, newBlock);
24634          startNode.parentNode.insertBefore(newBlock, startNode);
24635          node = startNode;
24636          while (node && !dom.isBlock(node)) {
24637            next = node.nextSibling;
24638            newBlock.appendChild(node);
24639            node = next;
24640          }
24641          rng.setStart(container, offset);
24642          rng.setEnd(container, offset);
24643        }
24644      }
24645      return container;
24646    };
24647    var addBrToBlockIfNeeded = function (dom, block) {
24648      block.normalize();
24649      var lastChild = block.lastChild;
24650      if (!lastChild || /^(left|right)$/gi.test(dom.getStyle(lastChild, 'float', true))) {
24651        dom.add(block, 'br');
24652      }
24653    };
24654    var insert$2 = function (editor, evt) {
24655      var tmpRng, container, offset, parentBlock;
24656      var newBlock, fragment, containerBlock, parentBlockName, newBlockName, isAfterLastNodeInContainer;
24657      var dom = editor.dom;
24658      var schema = editor.schema, nonEmptyElementsMap = schema.getNonEmptyElements();
24659      var rng = editor.selection.getRng();
24660      var createNewBlock = function (name) {
24661        var node = container, block, clonedNode, caretNode;
24662        var textInlineElements = schema.getTextInlineElements();
24663        if (name || parentBlockName === 'TABLE' || parentBlockName === 'HR') {
24664          block = dom.create(name || newBlockName);
24665        } else {
24666          block = parentBlock.cloneNode(false);
24667        }
24668        caretNode = block;
24669        if (shouldKeepStyles(editor) === false) {
24670          dom.setAttrib(block, 'style', null);
24671          dom.setAttrib(block, 'class', null);
24672        } else {
24673          do {
24674            if (textInlineElements[node.nodeName]) {
24675              if (isCaretNode(node) || isBookmarkNode$1(node)) {
24676                continue;
24677              }
24678              clonedNode = node.cloneNode(false);
24679              dom.setAttrib(clonedNode, 'id', '');
24680              if (block.hasChildNodes()) {
24681                clonedNode.appendChild(block.firstChild);
24682                block.appendChild(clonedNode);
24683              } else {
24684                caretNode = clonedNode;
24685                block.appendChild(clonedNode);
24686              }
24687            }
24688          } while ((node = node.parentNode) && node !== editableRoot);
24689        }
24690        setForcedBlockAttrs(editor, block);
24691        emptyBlock(caretNode);
24692        return block;
24693      };
24694      var isCaretAtStartOrEndOfBlock = function (start) {
24695        var node, name;
24696        var normalizedOffset = normalizeZwspOffset(start, container, offset);
24697        if (isText$7(container) && (start ? normalizedOffset > 0 : normalizedOffset < container.nodeValue.length)) {
24698          return false;
24699        }
24700        if (container.parentNode === parentBlock && isAfterLastNodeInContainer && !start) {
24701          return true;
24702        }
24703        if (start && isElement$5(container) && container === parentBlock.firstChild) {
24704          return true;
24705        }
24706        if (containerAndSiblingName(container, 'TABLE') || containerAndSiblingName(container, 'HR')) {
24707          return isAfterLastNodeInContainer && !start || !isAfterLastNodeInContainer && start;
24708        }
24709        var walker = new DomTreeWalker(container, parentBlock);
24710        if (isText$7(container)) {
24711          if (start && normalizedOffset === 0) {
24712            walker.prev();
24713          } else if (!start && normalizedOffset === container.nodeValue.length) {
24714            walker.next();
24715          }
24716        }
24717        while (node = walker.current()) {
24718          if (isElement$5(node)) {
24719            if (!node.getAttribute('data-mce-bogus')) {
24720              name = node.nodeName.toLowerCase();
24721              if (nonEmptyElementsMap[name] && name !== 'br') {
24722                return false;
24723              }
24724            }
24725          } else if (isText$7(node) && !isWhitespaceText(node.nodeValue)) {
24726            return false;
24727          }
24728          if (start) {
24729            walker.prev();
24730          } else {
24731            walker.next();
24732          }
24733        }
24734        return true;
24735      };
24736      var insertNewBlockAfter = function () {
24737        if (/^(H[1-6]|PRE|FIGURE)$/.test(parentBlockName) && containerBlockName !== 'HGROUP') {
24738          newBlock = createNewBlock(newBlockName);
24739        } else {
24740          newBlock = createNewBlock();
24741        }
24742        if (shouldEndContainerOnEmptyBlock(editor) && canSplitBlock(dom, containerBlock) && dom.isEmpty(parentBlock)) {
24743          newBlock = dom.split(containerBlock, parentBlock);
24744        } else {
24745          dom.insertAfter(newBlock, parentBlock);
24746        }
24747        moveToCaretPosition(editor, newBlock);
24748      };
24749      normalize$2(dom, rng).each(function (normRng) {
24750        rng.setStart(normRng.startContainer, normRng.startOffset);
24751        rng.setEnd(normRng.endContainer, normRng.endOffset);
24752      });
24753      container = rng.startContainer;
24754      offset = rng.startOffset;
24755      newBlockName = getForcedRootBlock(editor);
24756      var shiftKey = !!(evt && evt.shiftKey);
24757      var ctrlKey = !!(evt && evt.ctrlKey);
24758      if (isElement$5(container) && container.hasChildNodes()) {
24759        isAfterLastNodeInContainer = offset > container.childNodes.length - 1;
24760        container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;
24761        if (isAfterLastNodeInContainer && isText$7(container)) {
24762          offset = container.nodeValue.length;
24763        } else {
24764          offset = 0;
24765        }
24766      }
24767      var editableRoot = getEditableRoot(dom, container);
24768      if (!editableRoot) {
24769        return;
24770      }
24771      if (newBlockName && !shiftKey || !newBlockName && shiftKey) {
24772        container = wrapSelfAndSiblingsInDefaultBlock(editor, newBlockName, rng, container, offset);
24773      }
24774      parentBlock = dom.getParent(container, dom.isBlock);
24775      containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null;
24776      parentBlockName = parentBlock ? parentBlock.nodeName.toUpperCase() : '';
24777      var containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : '';
24778      if (containerBlockName === 'LI' && !ctrlKey) {
24779        parentBlock = containerBlock;
24780        containerBlock = containerBlock.parentNode;
24781        parentBlockName = containerBlockName;
24782      }
24783      if (/^(LI|DT|DD)$/.test(parentBlockName)) {
24784        if (dom.isEmpty(parentBlock)) {
24785          insert$3(editor, createNewBlock, containerBlock, parentBlock, newBlockName);
24786          return;
24787        }
24788      }
24789      if (newBlockName && parentBlock === editor.getBody()) {
24790        return;
24791      }
24792      newBlockName = newBlockName || 'P';
24793      if (isCaretContainerBlock$1(parentBlock)) {
24794        newBlock = showCaretContainerBlock(parentBlock);
24795        if (dom.isEmpty(parentBlock)) {
24796          emptyBlock(parentBlock);
24797        }
24798        setForcedBlockAttrs(editor, newBlock);
24799        moveToCaretPosition(editor, newBlock);
24800      } else if (isCaretAtStartOrEndOfBlock()) {
24801        insertNewBlockAfter();
24802      } else if (isCaretAtStartOrEndOfBlock(true)) {
24803        newBlock = parentBlock.parentNode.insertBefore(createNewBlock(), parentBlock);
24804        moveToCaretPosition(editor, containerAndSiblingName(parentBlock, 'HR') ? newBlock : parentBlock);
24805      } else {
24806        tmpRng = includeZwspInRange(rng).cloneRange();
24807        tmpRng.setEndAfter(parentBlock);
24808        fragment = tmpRng.extractContents();
24809        trimZwsp(fragment);
24810        trimLeadingLineBreaks(fragment);
24811        newBlock = fragment.firstChild;
24812        dom.insertAfter(fragment, parentBlock);
24813        trimInlineElementsOnLeftSideOfBlock(dom, nonEmptyElementsMap, newBlock);
24814        addBrToBlockIfNeeded(dom, parentBlock);
24815        if (dom.isEmpty(parentBlock)) {
24816          emptyBlock(parentBlock);
24817        }
24818        newBlock.normalize();
24819        if (dom.isEmpty(newBlock)) {
24820          dom.remove(newBlock);
24821          insertNewBlockAfter();
24822        } else {
24823          setForcedBlockAttrs(editor, newBlock);
24824          moveToCaretPosition(editor, newBlock);
24825        }
24826      }
24827      dom.setAttrib(newBlock, 'id', '');
24828      editor.fire('NewBlock', { newBlock: newBlock });
24829    };
24830
24831    var hasRightSideContent = function (schema, container, parentBlock) {
24832      var walker = new DomTreeWalker(container, parentBlock);
24833      var node;
24834      var nonEmptyElementsMap = schema.getNonEmptyElements();
24835      while (node = walker.next()) {
24836        if (nonEmptyElementsMap[node.nodeName.toLowerCase()] || node.length > 0) {
24837          return true;
24838        }
24839      }
24840    };
24841    var moveSelectionToBr = function (editor, brElm, extraBr) {
24842      var rng = editor.dom.createRng();
24843      if (!extraBr) {
24844        rng.setStartAfter(brElm);
24845        rng.setEndAfter(brElm);
24846      } else {
24847        rng.setStartBefore(brElm);
24848        rng.setEndBefore(brElm);
24849      }
24850      editor.selection.setRng(rng);
24851      scrollRangeIntoView(editor, rng);
24852    };
24853    var insertBrAtCaret = function (editor, evt) {
24854      var selection = editor.selection;
24855      var dom = editor.dom;
24856      var rng = selection.getRng();
24857      var brElm;
24858      var extraBr;
24859      normalize$2(dom, rng).each(function (normRng) {
24860        rng.setStart(normRng.startContainer, normRng.startOffset);
24861        rng.setEnd(normRng.endContainer, normRng.endOffset);
24862      });
24863      var offset = rng.startOffset;
24864      var container = rng.startContainer;
24865      if (container.nodeType === 1 && container.hasChildNodes()) {
24866        var isAfterLastNodeInContainer = offset > container.childNodes.length - 1;
24867        container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;
24868        if (isAfterLastNodeInContainer && container.nodeType === 3) {
24869          offset = container.nodeValue.length;
24870        } else {
24871          offset = 0;
24872        }
24873      }
24874      var parentBlock = dom.getParent(container, dom.isBlock);
24875      var containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null;
24876      var containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : '';
24877      var isControlKey = !!(evt && evt.ctrlKey);
24878      if (containerBlockName === 'LI' && !isControlKey) {
24879        parentBlock = containerBlock;
24880      }
24881      if (container && container.nodeType === 3 && offset >= container.nodeValue.length) {
24882        if (!hasRightSideContent(editor.schema, container, parentBlock)) {
24883          brElm = dom.create('br');
24884          rng.insertNode(brElm);
24885          rng.setStartAfter(brElm);
24886          rng.setEndAfter(brElm);
24887          extraBr = true;
24888        }
24889      }
24890      brElm = dom.create('br');
24891      rangeInsertNode(dom, rng, brElm);
24892      moveSelectionToBr(editor, brElm, extraBr);
24893      editor.undoManager.add();
24894    };
24895    var insertBrBefore = function (editor, inline) {
24896      var br = SugarElement.fromTag('br');
24897      before$4(SugarElement.fromDom(inline), br);
24898      editor.undoManager.add();
24899    };
24900    var insertBrAfter = function (editor, inline) {
24901      if (!hasBrAfter(editor.getBody(), inline)) {
24902        after$3(SugarElement.fromDom(inline), SugarElement.fromTag('br'));
24903      }
24904      var br = SugarElement.fromTag('br');
24905      after$3(SugarElement.fromDom(inline), br);
24906      moveSelectionToBr(editor, br.dom, false);
24907      editor.undoManager.add();
24908    };
24909    var isBeforeBr = function (pos) {
24910      return isBr$5(pos.getNode());
24911    };
24912    var hasBrAfter = function (rootNode, startNode) {
24913      if (isBeforeBr(CaretPosition.after(startNode))) {
24914        return true;
24915      } else {
24916        return nextPosition(rootNode, CaretPosition.after(startNode)).map(function (pos) {
24917          return isBr$5(pos.getNode());
24918        }).getOr(false);
24919      }
24920    };
24921    var isAnchorLink = function (elm) {
24922      return elm && elm.nodeName === 'A' && 'href' in elm;
24923    };
24924    var isInsideAnchor = function (location) {
24925      return location.fold(never, isAnchorLink, isAnchorLink, never);
24926    };
24927    var readInlineAnchorLocation = function (editor) {
24928      var isInlineTarget$1 = curry(isInlineTarget, editor);
24929      var position = CaretPosition.fromRangeStart(editor.selection.getRng());
24930      return readLocation(isInlineTarget$1, editor.getBody(), position).filter(isInsideAnchor);
24931    };
24932    var insertBrOutsideAnchor = function (editor, location) {
24933      location.fold(noop, curry(insertBrBefore, editor), curry(insertBrAfter, editor), noop);
24934    };
24935    var insert$1 = function (editor, evt) {
24936      var anchorLocation = readInlineAnchorLocation(editor);
24937      if (anchorLocation.isSome()) {
24938        anchorLocation.each(curry(insertBrOutsideAnchor, editor));
24939      } else {
24940        insertBrAtCaret(editor, evt);
24941      }
24942    };
24943
24944    var matchesSelector = function (editor, selector) {
24945      return getParentBlock(editor).filter(function (parentBlock) {
24946        return selector.length > 0 && is$2(SugarElement.fromDom(parentBlock), selector);
24947      }).isSome();
24948    };
24949    var shouldInsertBr = function (editor) {
24950      return matchesSelector(editor, getBrNewLineSelector(editor));
24951    };
24952    var shouldBlockNewLine$1 = function (editor) {
24953      return matchesSelector(editor, getNoNewLineSelector(editor));
24954    };
24955
24956    var newLineAction = Adt.generate([
24957      { br: [] },
24958      { block: [] },
24959      { none: [] }
24960    ]);
24961    var shouldBlockNewLine = function (editor, _shiftKey) {
24962      return shouldBlockNewLine$1(editor);
24963    };
24964    var isBrMode = function (requiredState) {
24965      return function (editor, _shiftKey) {
24966        var brMode = getForcedRootBlock(editor) === '';
24967        return brMode === requiredState;
24968      };
24969    };
24970    var inListBlock = function (requiredState) {
24971      return function (editor, _shiftKey) {
24972        return isListItemParentBlock(editor) === requiredState;
24973      };
24974    };
24975    var inBlock = function (blockName, requiredState) {
24976      return function (editor, _shiftKey) {
24977        var state = getParentBlockName(editor) === blockName.toUpperCase();
24978        return state === requiredState;
24979      };
24980    };
24981    var inPreBlock = function (requiredState) {
24982      return inBlock('pre', requiredState);
24983    };
24984    var inSummaryBlock = function () {
24985      return inBlock('summary', true);
24986    };
24987    var shouldPutBrInPre = function (requiredState) {
24988      return function (editor, _shiftKey) {
24989        return shouldPutBrInPre$1(editor) === requiredState;
24990      };
24991    };
24992    var inBrContext = function (editor, _shiftKey) {
24993      return shouldInsertBr(editor);
24994    };
24995    var hasShiftKey = function (_editor, shiftKey) {
24996      return shiftKey;
24997    };
24998    var canInsertIntoEditableRoot = function (editor) {
24999      var forcedRootBlock = getForcedRootBlock(editor);
25000      var rootEditable = getEditableRoot$1(editor.dom, editor.selection.getStart());
25001      return rootEditable && editor.schema.isValidChild(rootEditable.nodeName, forcedRootBlock ? forcedRootBlock : 'P');
25002    };
25003    var match = function (predicates, action) {
25004      return function (editor, shiftKey) {
25005        var isMatch = foldl(predicates, function (res, p) {
25006          return res && p(editor, shiftKey);
25007        }, true);
25008        return isMatch ? Optional.some(action) : Optional.none();
25009      };
25010    };
25011    var getAction = function (editor, evt) {
25012      return evaluateUntil([
25013        match([shouldBlockNewLine], newLineAction.none()),
25014        match([inSummaryBlock()], newLineAction.br()),
25015        match([
25016          inPreBlock(true),
25017          shouldPutBrInPre(false),
25018          hasShiftKey
25019        ], newLineAction.br()),
25020        match([
25021          inPreBlock(true),
25022          shouldPutBrInPre(false)
25023        ], newLineAction.block()),
25024        match([
25025          inPreBlock(true),
25026          shouldPutBrInPre(true),
25027          hasShiftKey
25028        ], newLineAction.block()),
25029        match([
25030          inPreBlock(true),
25031          shouldPutBrInPre(true)
25032        ], newLineAction.br()),
25033        match([
25034          inListBlock(true),
25035          hasShiftKey
25036        ], newLineAction.br()),
25037        match([inListBlock(true)], newLineAction.block()),
25038        match([
25039          isBrMode(true),
25040          hasShiftKey,
25041          canInsertIntoEditableRoot
25042        ], newLineAction.block()),
25043        match([isBrMode(true)], newLineAction.br()),
25044        match([inBrContext], newLineAction.br()),
25045        match([
25046          isBrMode(false),
25047          hasShiftKey
25048        ], newLineAction.br()),
25049        match([canInsertIntoEditableRoot], newLineAction.block())
25050      ], [
25051        editor,
25052        !!(evt && evt.shiftKey)
25053      ]).getOr(newLineAction.none());
25054    };
25055
25056    var insert = function (editor, evt) {
25057      getAction(editor, evt).fold(function () {
25058        insert$1(editor, evt);
25059      }, function () {
25060        insert$2(editor, evt);
25061      }, noop);
25062    };
25063
25064    var handleEnterKeyEvent = function (editor, event) {
25065      if (event.isDefaultPrevented()) {
25066        return;
25067      }
25068      event.preventDefault();
25069      endTypingLevelIgnoreLocks(editor.undoManager);
25070      editor.undoManager.transact(function () {
25071        if (editor.selection.isCollapsed() === false) {
25072          editor.execCommand('Delete');
25073        }
25074        insert(editor, event);
25075      });
25076    };
25077    var setup$9 = function (editor) {
25078      editor.on('keydown', function (event) {
25079        if (event.keyCode === VK.ENTER) {
25080          handleEnterKeyEvent(editor, event);
25081        }
25082      });
25083    };
25084
25085    var executeKeydownOverride$1 = function (editor, caret, evt) {
25086      execute([
25087        {
25088          keyCode: VK.END,
25089          action: action(moveToLineEndPoint$1, editor, true)
25090        },
25091        {
25092          keyCode: VK.HOME,
25093          action: action(moveToLineEndPoint$1, editor, false)
25094        },
25095        {
25096          keyCode: VK.END,
25097          action: action(moveToLineEndPoint, editor, true)
25098        },
25099        {
25100          keyCode: VK.HOME,
25101          action: action(moveToLineEndPoint, editor, false)
25102        },
25103        {
25104          keyCode: VK.END,
25105          action: action(moveToLineEndPoint$2, editor, true, caret)
25106        },
25107        {
25108          keyCode: VK.HOME,
25109          action: action(moveToLineEndPoint$2, editor, false, caret)
25110        }
25111      ], evt).each(function (_) {
25112        evt.preventDefault();
25113      });
25114    };
25115    var setup$8 = function (editor, caret) {
25116      editor.on('keydown', function (evt) {
25117        if (evt.isDefaultPrevented() === false) {
25118          executeKeydownOverride$1(editor, caret, evt);
25119        }
25120      });
25121    };
25122
25123    var browser = detect().browser;
25124    var setupIeInput = function (editor) {
25125      var keypressThrotter = first(function () {
25126        if (!editor.composing) {
25127          normalizeNbspsInEditor(editor);
25128        }
25129      }, 0);
25130      if (browser.isIE()) {
25131        editor.on('keypress', function (_e) {
25132          keypressThrotter.throttle();
25133        });
25134        editor.on('remove', function (_e) {
25135          keypressThrotter.cancel();
25136        });
25137      }
25138    };
25139    var setup$7 = function (editor) {
25140      setupIeInput(editor);
25141      editor.on('input', function (e) {
25142        if (e.isComposing === false) {
25143          normalizeNbspsInEditor(editor);
25144        }
25145      });
25146    };
25147
25148    var platform = detect();
25149    var executeKeyupAction = function (editor, caret, evt) {
25150      execute([
25151        {
25152          keyCode: VK.PAGE_UP,
25153          action: action(moveToLineEndPoint$2, editor, false, caret)
25154        },
25155        {
25156          keyCode: VK.PAGE_DOWN,
25157          action: action(moveToLineEndPoint$2, editor, true, caret)
25158        }
25159      ], evt);
25160    };
25161    var stopImmediatePropagation = function (e) {
25162      return e.stopImmediatePropagation();
25163    };
25164    var isPageUpDown = function (evt) {
25165      return evt.keyCode === VK.PAGE_UP || evt.keyCode === VK.PAGE_DOWN;
25166    };
25167    var setNodeChangeBlocker = function (blocked, editor, block) {
25168      if (block && !blocked.get()) {
25169        editor.on('NodeChange', stopImmediatePropagation, true);
25170      } else if (!block && blocked.get()) {
25171        editor.off('NodeChange', stopImmediatePropagation);
25172      }
25173      blocked.set(block);
25174    };
25175    var setup$6 = function (editor, caret) {
25176      if (platform.os.isOSX()) {
25177        return;
25178      }
25179      var blocked = Cell(false);
25180      editor.on('keydown', function (evt) {
25181        if (isPageUpDown(evt)) {
25182          setNodeChangeBlocker(blocked, editor, true);
25183        }
25184      });
25185      editor.on('keyup', function (evt) {
25186        if (evt.isDefaultPrevented() === false) {
25187          executeKeyupAction(editor, caret, evt);
25188        }
25189        if (isPageUpDown(evt) && blocked.get()) {
25190          setNodeChangeBlocker(blocked, editor, false);
25191          editor.nodeChanged();
25192        }
25193      });
25194    };
25195
25196    var insertTextAtPosition = function (text, pos) {
25197      var container = pos.container();
25198      var offset = pos.offset();
25199      if (isText$7(container)) {
25200        container.insertData(offset, text);
25201        return Optional.some(CaretPosition(container, offset + text.length));
25202      } else {
25203        return getElementFromPosition(pos).map(function (elm) {
25204          var textNode = SugarElement.fromText(text);
25205          if (pos.isAtEnd()) {
25206            after$3(elm, textNode);
25207          } else {
25208            before$4(elm, textNode);
25209          }
25210          return CaretPosition(textNode.dom, text.length);
25211        });
25212      }
25213    };
25214    var insertNbspAtPosition = curry(insertTextAtPosition, nbsp);
25215    var insertSpaceAtPosition = curry(insertTextAtPosition, ' ');
25216
25217    var locationToCaretPosition = function (root) {
25218      return function (location) {
25219        return location.fold(function (element) {
25220          return prevPosition(root.dom, CaretPosition.before(element));
25221        }, function (element) {
25222          return firstPositionIn(element);
25223        }, function (element) {
25224          return lastPositionIn(element);
25225        }, function (element) {
25226          return nextPosition(root.dom, CaretPosition.after(element));
25227        });
25228      };
25229    };
25230    var insertInlineBoundarySpaceOrNbsp = function (root, pos) {
25231      return function (checkPos) {
25232        return needsToHaveNbsp(root, checkPos) ? insertNbspAtPosition(pos) : insertSpaceAtPosition(pos);
25233      };
25234    };
25235    var setSelection = function (editor) {
25236      return function (pos) {
25237        editor.selection.setRng(pos.toRange());
25238        editor.nodeChanged();
25239        return true;
25240      };
25241    };
25242    var insertSpaceOrNbspAtSelection = function (editor) {
25243      var pos = CaretPosition.fromRangeStart(editor.selection.getRng());
25244      var root = SugarElement.fromDom(editor.getBody());
25245      if (editor.selection.isCollapsed()) {
25246        var isInlineTarget$1 = curry(isInlineTarget, editor);
25247        var caretPosition = CaretPosition.fromRangeStart(editor.selection.getRng());
25248        return readLocation(isInlineTarget$1, editor.getBody(), caretPosition).bind(locationToCaretPosition(root)).bind(insertInlineBoundarySpaceOrNbsp(root, pos)).exists(setSelection(editor));
25249      } else {
25250        return false;
25251      }
25252    };
25253
25254    var executeKeydownOverride = function (editor, evt) {
25255      execute([{
25256          keyCode: VK.SPACEBAR,
25257          action: action(insertSpaceOrNbspAtSelection, editor)
25258        }], evt).each(function (_) {
25259        evt.preventDefault();
25260      });
25261    };
25262    var setup$5 = function (editor) {
25263      editor.on('keydown', function (evt) {
25264        if (evt.isDefaultPrevented() === false) {
25265          executeKeydownOverride(editor, evt);
25266        }
25267      });
25268    };
25269
25270    var registerKeyboardOverrides = function (editor) {
25271      var caret = setupSelectedState(editor);
25272      setup$c(editor);
25273      setup$b(editor, caret);
25274      setup$a(editor, caret);
25275      setup$9(editor);
25276      setup$5(editor);
25277      setup$7(editor);
25278      setup$8(editor, caret);
25279      setup$6(editor, caret);
25280      return caret;
25281    };
25282    var setup$4 = function (editor) {
25283      if (!isRtc(editor)) {
25284        return registerKeyboardOverrides(editor);
25285      } else {
25286        return Cell(null);
25287      }
25288    };
25289
25290    var NodeChange = function () {
25291      function NodeChange(editor) {
25292        this.lastPath = [];
25293        this.editor = editor;
25294        var lastRng;
25295        var self = this;
25296        if (!('onselectionchange' in editor.getDoc())) {
25297          editor.on('NodeChange click mouseup keyup focus', function (e) {
25298            var nativeRng = editor.selection.getRng();
25299            var fakeRng = {
25300              startContainer: nativeRng.startContainer,
25301              startOffset: nativeRng.startOffset,
25302              endContainer: nativeRng.endContainer,
25303              endOffset: nativeRng.endOffset
25304            };
25305            if (e.type === 'nodechange' || !isEq$4(fakeRng, lastRng)) {
25306              editor.fire('SelectionChange');
25307            }
25308            lastRng = fakeRng;
25309          });
25310        }
25311        editor.on('contextmenu', function () {
25312          editor.fire('SelectionChange');
25313        });
25314        editor.on('SelectionChange', function () {
25315          var startElm = editor.selection.getStart(true);
25316          if (!startElm || !Env.range && editor.selection.isCollapsed()) {
25317            return;
25318          }
25319          if (hasAnyRanges(editor) && !self.isSameElementPath(startElm) && editor.dom.isChildOf(startElm, editor.getBody())) {
25320            editor.nodeChanged({ selectionChange: true });
25321          }
25322        });
25323        editor.on('mouseup', function (e) {
25324          if (!e.isDefaultPrevented() && hasAnyRanges(editor)) {
25325            if (editor.selection.getNode().nodeName === 'IMG') {
25326              Delay.setEditorTimeout(editor, function () {
25327                editor.nodeChanged();
25328              });
25329            } else {
25330              editor.nodeChanged();
25331            }
25332          }
25333        });
25334      }
25335      NodeChange.prototype.nodeChanged = function (args) {
25336        var selection = this.editor.selection;
25337        var node, parents, root;
25338        if (this.editor.initialized && selection && !shouldDisableNodeChange(this.editor) && !this.editor.mode.isReadOnly()) {
25339          root = this.editor.getBody();
25340          node = selection.getStart(true) || root;
25341          if (node.ownerDocument !== this.editor.getDoc() || !this.editor.dom.isChildOf(node, root)) {
25342            node = root;
25343          }
25344          parents = [];
25345          this.editor.dom.getParent(node, function (node) {
25346            if (node === root) {
25347              return true;
25348            }
25349            parents.push(node);
25350          });
25351          args = args || {};
25352          args.element = node;
25353          args.parents = parents;
25354          this.editor.fire('NodeChange', args);
25355        }
25356      };
25357      NodeChange.prototype.isSameElementPath = function (startElm) {
25358        var i;
25359        var currentPath = this.editor.$(startElm).parentsUntil(this.editor.getBody()).add(startElm);
25360        if (currentPath.length === this.lastPath.length) {
25361          for (i = currentPath.length; i >= 0; i--) {
25362            if (currentPath[i] !== this.lastPath[i]) {
25363              break;
25364            }
25365          }
25366          if (i === -1) {
25367            this.lastPath = currentPath;
25368            return true;
25369          }
25370        }
25371        this.lastPath = currentPath;
25372        return false;
25373      };
25374      return NodeChange;
25375    }();
25376
25377    var preventSummaryToggle = function (editor) {
25378      editor.on('click', function (e) {
25379        if (editor.dom.getParent(e.target, 'details')) {
25380          e.preventDefault();
25381        }
25382      });
25383    };
25384    var filterDetails = function (editor) {
25385      editor.parser.addNodeFilter('details', function (elms) {
25386        each$k(elms, function (details) {
25387          details.attr('data-mce-open', details.attr('open'));
25388          details.attr('open', 'open');
25389        });
25390      });
25391      editor.serializer.addNodeFilter('details', function (elms) {
25392        each$k(elms, function (details) {
25393          var open = details.attr('data-mce-open');
25394          details.attr('open', isString$1(open) ? open : null);
25395          details.attr('data-mce-open', null);
25396        });
25397      });
25398    };
25399    var setup$3 = function (editor) {
25400      preventSummaryToggle(editor);
25401      filterDetails(editor);
25402    };
25403
25404    var isTextBlockNode = function (node) {
25405      return isElement$5(node) && isTextBlock$2(SugarElement.fromDom(node));
25406    };
25407    var normalizeSelection = function (editor) {
25408      var rng = editor.selection.getRng();
25409      var startPos = CaretPosition.fromRangeStart(rng);
25410      var endPos = CaretPosition.fromRangeEnd(rng);
25411      if (CaretPosition.isElementPosition(startPos)) {
25412        var container = startPos.container();
25413        if (isTextBlockNode(container)) {
25414          firstPositionIn(container).each(function (pos) {
25415            return rng.setStart(pos.container(), pos.offset());
25416          });
25417        }
25418      }
25419      if (CaretPosition.isElementPosition(endPos)) {
25420        var container = startPos.container();
25421        if (isTextBlockNode(container)) {
25422          lastPositionIn(container).each(function (pos) {
25423            return rng.setEnd(pos.container(), pos.offset());
25424          });
25425        }
25426      }
25427      editor.selection.setRng(normalize(rng));
25428    };
25429    var setup$2 = function (editor) {
25430      editor.on('click', function (e) {
25431        if (e.detail >= 3) {
25432          normalizeSelection(editor);
25433        }
25434      });
25435    };
25436
25437    var getAbsolutePosition = function (elm) {
25438      var clientRect = elm.getBoundingClientRect();
25439      var doc = elm.ownerDocument;
25440      var docElem = doc.documentElement;
25441      var win = doc.defaultView;
25442      return {
25443        top: clientRect.top + win.pageYOffset - docElem.clientTop,
25444        left: clientRect.left + win.pageXOffset - docElem.clientLeft
25445      };
25446    };
25447    var getBodyPosition = function (editor) {
25448      return editor.inline ? getAbsolutePosition(editor.getBody()) : {
25449        left: 0,
25450        top: 0
25451      };
25452    };
25453    var getScrollPosition = function (editor) {
25454      var body = editor.getBody();
25455      return editor.inline ? {
25456        left: body.scrollLeft,
25457        top: body.scrollTop
25458      } : {
25459        left: 0,
25460        top: 0
25461      };
25462    };
25463    var getBodyScroll = function (editor) {
25464      var body = editor.getBody(), docElm = editor.getDoc().documentElement;
25465      var inlineScroll = {
25466        left: body.scrollLeft,
25467        top: body.scrollTop
25468      };
25469      var iframeScroll = {
25470        left: body.scrollLeft || docElm.scrollLeft,
25471        top: body.scrollTop || docElm.scrollTop
25472      };
25473      return editor.inline ? inlineScroll : iframeScroll;
25474    };
25475    var getMousePosition = function (editor, event) {
25476      if (event.target.ownerDocument !== editor.getDoc()) {
25477        var iframePosition = getAbsolutePosition(editor.getContentAreaContainer());
25478        var scrollPosition = getBodyScroll(editor);
25479        return {
25480          left: event.pageX - iframePosition.left + scrollPosition.left,
25481          top: event.pageY - iframePosition.top + scrollPosition.top
25482        };
25483      }
25484      return {
25485        left: event.pageX,
25486        top: event.pageY
25487      };
25488    };
25489    var calculatePosition = function (bodyPosition, scrollPosition, mousePosition) {
25490      return {
25491        pageX: mousePosition.left - bodyPosition.left + scrollPosition.left,
25492        pageY: mousePosition.top - bodyPosition.top + scrollPosition.top
25493      };
25494    };
25495    var calc = function (editor, event) {
25496      return calculatePosition(getBodyPosition(editor), getScrollPosition(editor), getMousePosition(editor, event));
25497    };
25498
25499    var isContentEditableFalse$1 = isContentEditableFalse$b, isContentEditableTrue$1 = isContentEditableTrue$4;
25500    var isDraggable = function (rootElm, elm) {
25501      return isContentEditableFalse$1(elm) && elm !== rootElm;
25502    };
25503    var isValidDropTarget = function (editor, targetElement, dragElement) {
25504      if (targetElement === dragElement || editor.dom.isChildOf(targetElement, dragElement)) {
25505        return false;
25506      }
25507      return !isContentEditableFalse$1(targetElement);
25508    };
25509    var cloneElement = function (elm) {
25510      var cloneElm = elm.cloneNode(true);
25511      cloneElm.removeAttribute('data-mce-selected');
25512      return cloneElm;
25513    };
25514    var createGhost = function (editor, elm, width, height) {
25515      var dom = editor.dom;
25516      var clonedElm = elm.cloneNode(true);
25517      dom.setStyles(clonedElm, {
25518        width: width,
25519        height: height
25520      });
25521      dom.setAttrib(clonedElm, 'data-mce-selected', null);
25522      var ghostElm = dom.create('div', {
25523        'class': 'mce-drag-container',
25524        'data-mce-bogus': 'all',
25525        'unselectable': 'on',
25526        'contenteditable': 'false'
25527      });
25528      dom.setStyles(ghostElm, {
25529        position: 'absolute',
25530        opacity: 0.5,
25531        overflow: 'hidden',
25532        border: 0,
25533        padding: 0,
25534        margin: 0,
25535        width: width,
25536        height: height
25537      });
25538      dom.setStyles(clonedElm, {
25539        margin: 0,
25540        boxSizing: 'border-box'
25541      });
25542      ghostElm.appendChild(clonedElm);
25543      return ghostElm;
25544    };
25545    var appendGhostToBody = function (ghostElm, bodyElm) {
25546      if (ghostElm.parentNode !== bodyElm) {
25547        bodyElm.appendChild(ghostElm);
25548      }
25549    };
25550    var moveGhost = function (ghostElm, position, width, height, maxX, maxY) {
25551      var overflowX = 0, overflowY = 0;
25552      ghostElm.style.left = position.pageX + 'px';
25553      ghostElm.style.top = position.pageY + 'px';
25554      if (position.pageX + width > maxX) {
25555        overflowX = position.pageX + width - maxX;
25556      }
25557      if (position.pageY + height > maxY) {
25558        overflowY = position.pageY + height - maxY;
25559      }
25560      ghostElm.style.width = width - overflowX + 'px';
25561      ghostElm.style.height = height - overflowY + 'px';
25562    };
25563    var removeElement = function (elm) {
25564      if (elm && elm.parentNode) {
25565        elm.parentNode.removeChild(elm);
25566      }
25567    };
25568    var isLeftMouseButtonPressed = function (e) {
25569      return e.button === 0;
25570    };
25571    var applyRelPos = function (state, position) {
25572      return {
25573        pageX: position.pageX - state.relX,
25574        pageY: position.pageY + 5
25575      };
25576    };
25577    var start = function (state, editor) {
25578      return function (e) {
25579        if (isLeftMouseButtonPressed(e)) {
25580          var ceElm = find$3(editor.dom.getParents(e.target), or(isContentEditableFalse$1, isContentEditableTrue$1)).getOr(null);
25581          if (isDraggable(editor.getBody(), ceElm)) {
25582            var elmPos = editor.dom.getPos(ceElm);
25583            var bodyElm = editor.getBody();
25584            var docElm = editor.getDoc().documentElement;
25585            state.set({
25586              element: ceElm,
25587              dragging: false,
25588              screenX: e.screenX,
25589              screenY: e.screenY,
25590              maxX: (editor.inline ? bodyElm.scrollWidth : docElm.offsetWidth) - 2,
25591              maxY: (editor.inline ? bodyElm.scrollHeight : docElm.offsetHeight) - 2,
25592              relX: e.pageX - elmPos.x,
25593              relY: e.pageY - elmPos.y,
25594              width: ceElm.offsetWidth,
25595              height: ceElm.offsetHeight,
25596              ghost: createGhost(editor, ceElm, ceElm.offsetWidth, ceElm.offsetHeight)
25597            });
25598          }
25599        }
25600      };
25601    };
25602    var move = function (state, editor) {
25603      var throttledPlaceCaretAt = Delay.throttle(function (clientX, clientY) {
25604        editor._selectionOverrides.hideFakeCaret();
25605        editor.selection.placeCaretAt(clientX, clientY);
25606      }, 0);
25607      editor.on('remove', throttledPlaceCaretAt.stop);
25608      return function (e) {
25609        return state.on(function (state) {
25610          var movement = Math.max(Math.abs(e.screenX - state.screenX), Math.abs(e.screenY - state.screenY));
25611          if (!state.dragging && movement > 10) {
25612            var args = editor.fire('dragstart', { target: state.element });
25613            if (args.isDefaultPrevented()) {
25614              return;
25615            }
25616            state.dragging = true;
25617            editor.focus();
25618          }
25619          if (state.dragging) {
25620            var targetPos = applyRelPos(state, calc(editor, e));
25621            appendGhostToBody(state.ghost, editor.getBody());
25622            moveGhost(state.ghost, targetPos, state.width, state.height, state.maxX, state.maxY);
25623            throttledPlaceCaretAt(e.clientX, e.clientY);
25624          }
25625        });
25626      };
25627    };
25628    var getRawTarget = function (selection) {
25629      var rng = selection.getSel().getRangeAt(0);
25630      var startContainer = rng.startContainer;
25631      return startContainer.nodeType === 3 ? startContainer.parentNode : startContainer;
25632    };
25633    var drop = function (state, editor) {
25634      return function (e) {
25635        state.on(function (state) {
25636          if (state.dragging) {
25637            if (isValidDropTarget(editor, getRawTarget(editor.selection), state.element)) {
25638              var targetClone_1 = cloneElement(state.element);
25639              var args = editor.fire('drop', {
25640                clientX: e.clientX,
25641                clientY: e.clientY
25642              });
25643              if (!args.isDefaultPrevented()) {
25644                editor.undoManager.transact(function () {
25645                  removeElement(state.element);
25646                  editor.insertContent(editor.dom.getOuterHTML(targetClone_1));
25647                  editor._selectionOverrides.hideFakeCaret();
25648                });
25649              }
25650            }
25651            editor.fire('dragend');
25652          }
25653        });
25654        removeDragState(state);
25655      };
25656    };
25657    var stop = function (state, editor) {
25658      return function () {
25659        state.on(function (state) {
25660          if (state.dragging) {
25661            editor.fire('dragend');
25662          }
25663        });
25664        removeDragState(state);
25665      };
25666    };
25667    var removeDragState = function (state) {
25668      state.on(function (state) {
25669        removeElement(state.ghost);
25670      });
25671      state.clear();
25672    };
25673    var bindFakeDragEvents = function (editor) {
25674      var state = value();
25675      var pageDom = DOMUtils.DOM;
25676      var rootDocument = document;
25677      var dragStartHandler = start(state, editor);
25678      var dragHandler = move(state, editor);
25679      var dropHandler = drop(state, editor);
25680      var dragEndHandler = stop(state, editor);
25681      editor.on('mousedown', dragStartHandler);
25682      editor.on('mousemove', dragHandler);
25683      editor.on('mouseup', dropHandler);
25684      pageDom.bind(rootDocument, 'mousemove', dragHandler);
25685      pageDom.bind(rootDocument, 'mouseup', dragEndHandler);
25686      editor.on('remove', function () {
25687        pageDom.unbind(rootDocument, 'mousemove', dragHandler);
25688        pageDom.unbind(rootDocument, 'mouseup', dragEndHandler);
25689      });
25690      editor.on('keydown', function (e) {
25691        if (e.keyCode === VK.ESC) {
25692          dragEndHandler();
25693        }
25694      });
25695    };
25696    var blockIeDrop = function (editor) {
25697      editor.on('drop', function (e) {
25698        var realTarget = typeof e.clientX !== 'undefined' ? editor.getDoc().elementFromPoint(e.clientX, e.clientY) : null;
25699        if (isContentEditableFalse$1(realTarget) || editor.dom.getContentEditableParent(realTarget) === 'false') {
25700          e.preventDefault();
25701        }
25702      });
25703    };
25704    var blockUnsupportedFileDrop = function (editor) {
25705      var preventFileDrop = function (e) {
25706        if (!e.isDefaultPrevented()) {
25707          var dataTransfer = e.dataTransfer;
25708          if (dataTransfer && (contains$3(dataTransfer.types, 'Files') || dataTransfer.files.length > 0)) {
25709            e.preventDefault();
25710            if (e.type === 'drop') {
25711              displayError(editor, 'Dropped file type is not supported');
25712            }
25713          }
25714        }
25715      };
25716      var preventFileDropIfUIElement = function (e) {
25717        if (isUIElement(editor, e.target)) {
25718          preventFileDrop(e);
25719        }
25720      };
25721      var setup = function () {
25722        var pageDom = DOMUtils.DOM;
25723        var dom = editor.dom;
25724        var doc = document;
25725        var editorRoot = editor.inline ? editor.getBody() : editor.getDoc();
25726        var eventNames = [
25727          'drop',
25728          'dragover'
25729        ];
25730        each$k(eventNames, function (name) {
25731          pageDom.bind(doc, name, preventFileDropIfUIElement);
25732          dom.bind(editorRoot, name, preventFileDrop);
25733        });
25734        editor.on('remove', function () {
25735          each$k(eventNames, function (name) {
25736            pageDom.unbind(doc, name, preventFileDropIfUIElement);
25737            dom.unbind(editorRoot, name, preventFileDrop);
25738          });
25739        });
25740      };
25741      editor.on('init', function () {
25742        Delay.setEditorTimeout(editor, setup, 0);
25743      });
25744    };
25745    var init$2 = function (editor) {
25746      bindFakeDragEvents(editor);
25747      blockIeDrop(editor);
25748      if (shouldBlockUnsupportedDrop(editor)) {
25749        blockUnsupportedFileDrop(editor);
25750      }
25751    };
25752
25753    var setup$1 = function (editor) {
25754      var renderFocusCaret = first(function () {
25755        if (!editor.removed && editor.getBody().contains(document.activeElement)) {
25756          var rng = editor.selection.getRng();
25757          if (rng.collapsed) {
25758            var caretRange = renderRangeCaret(editor, rng, false);
25759            editor.selection.setRng(caretRange);
25760          }
25761        }
25762      }, 0);
25763      editor.on('focus', function () {
25764        renderFocusCaret.throttle();
25765      });
25766      editor.on('blur', function () {
25767        renderFocusCaret.cancel();
25768      });
25769    };
25770
25771    var setup = function (editor) {
25772      editor.on('init', function () {
25773        editor.on('focusin', function (e) {
25774          var target = e.target;
25775          if (isMedia$2(target)) {
25776            var ceRoot = getContentEditableRoot$1(editor.getBody(), target);
25777            var node = isContentEditableFalse$b(ceRoot) ? ceRoot : target;
25778            if (editor.selection.getNode() !== node) {
25779              selectNode(editor, node).each(function (rng) {
25780                return editor.selection.setRng(rng);
25781              });
25782            }
25783          }
25784        });
25785      });
25786    };
25787
25788    var isContentEditableTrue = isContentEditableTrue$4;
25789    var isContentEditableFalse = isContentEditableFalse$b;
25790    var getContentEditableRoot = function (editor, node) {
25791      return getContentEditableRoot$1(editor.getBody(), node);
25792    };
25793    var SelectionOverrides = function (editor) {
25794      var selection = editor.selection, dom = editor.dom;
25795      var isBlock = dom.isBlock;
25796      var rootNode = editor.getBody();
25797      var fakeCaret = FakeCaret(editor, rootNode, isBlock, function () {
25798        return hasFocus(editor);
25799      });
25800      var realSelectionId = 'sel-' + dom.uniqueId();
25801      var elementSelectionAttr = 'data-mce-selected';
25802      var selectedElement;
25803      var isFakeSelectionElement = function (node) {
25804        return dom.hasClass(node, 'mce-offscreen-selection');
25805      };
25806      var isFakeSelectionTargetElement = function (node) {
25807        return node !== rootNode && (isContentEditableFalse(node) || isMedia$2(node)) && dom.isChildOf(node, rootNode);
25808      };
25809      var isNearFakeSelectionElement = function (pos) {
25810        return isBeforeContentEditableFalse(pos) || isAfterContentEditableFalse(pos) || isBeforeMedia(pos) || isAfterMedia(pos);
25811      };
25812      var getRealSelectionElement = function () {
25813        var container = dom.get(realSelectionId);
25814        return container ? container.getElementsByTagName('*')[0] : container;
25815      };
25816      var setRange = function (range) {
25817        if (range) {
25818          selection.setRng(range);
25819        }
25820      };
25821      var getRange = selection.getRng;
25822      var showCaret = function (direction, node, before, scrollIntoView) {
25823        if (scrollIntoView === void 0) {
25824          scrollIntoView = true;
25825        }
25826        var e = editor.fire('ShowCaret', {
25827          target: node,
25828          direction: direction,
25829          before: before
25830        });
25831        if (e.isDefaultPrevented()) {
25832          return null;
25833        }
25834        if (scrollIntoView) {
25835          selection.scrollIntoView(node, direction === -1);
25836        }
25837        return fakeCaret.show(before, node);
25838      };
25839      var showBlockCaretContainer = function (blockCaretContainer) {
25840        if (blockCaretContainer.hasAttribute('data-mce-caret')) {
25841          showCaretContainerBlock(blockCaretContainer);
25842          setRange(getRange());
25843          selection.scrollIntoView(blockCaretContainer);
25844        }
25845      };
25846      var registerEvents = function () {
25847        editor.on('mouseup', function (e) {
25848          var range = getRange();
25849          if (range.collapsed && isXYInContentArea(editor, e.clientX, e.clientY)) {
25850            renderCaretAtRange(editor, range, false).each(setRange);
25851          }
25852        });
25853        editor.on('click', function (e) {
25854          var contentEditableRoot = getContentEditableRoot(editor, e.target);
25855          if (contentEditableRoot) {
25856            if (isContentEditableFalse(contentEditableRoot)) {
25857              e.preventDefault();
25858              editor.focus();
25859            }
25860            if (isContentEditableTrue(contentEditableRoot)) {
25861              if (dom.isChildOf(contentEditableRoot, selection.getNode())) {
25862                removeElementSelection();
25863              }
25864            }
25865          }
25866        });
25867        editor.on('blur NewBlock', removeElementSelection);
25868        editor.on('ResizeWindow FullscreenStateChanged', fakeCaret.reposition);
25869        var hasNormalCaretPosition = function (elm) {
25870          var start = elm.firstChild;
25871          if (isNullable(start)) {
25872            return false;
25873          }
25874          var startPos = CaretPosition.before(start);
25875          if (isBr$5(startPos.getNode()) && elm.childNodes.length === 1) {
25876            return !isNearFakeSelectionElement(startPos);
25877          } else {
25878            var caretWalker = CaretWalker(elm);
25879            var newPos = caretWalker.next(startPos);
25880            return newPos && !isNearFakeSelectionElement(newPos);
25881          }
25882        };
25883        var isInSameBlock = function (node1, node2) {
25884          var block1 = dom.getParent(node1, isBlock);
25885          var block2 = dom.getParent(node2, isBlock);
25886          return block1 === block2;
25887        };
25888        var hasBetterMouseTarget = function (targetNode, caretNode) {
25889          var targetBlock = dom.getParent(targetNode, isBlock);
25890          var caretBlock = dom.getParent(caretNode, isBlock);
25891          if (isNullable(targetBlock)) {
25892            return false;
25893          }
25894          if (targetNode !== caretBlock && dom.isChildOf(targetBlock, caretBlock) && isContentEditableFalse(getContentEditableRoot(editor, targetBlock)) === false) {
25895            return true;
25896          }
25897          return !dom.isChildOf(caretBlock, targetBlock) && !isInSameBlock(targetBlock, caretBlock) && hasNormalCaretPosition(targetBlock);
25898        };
25899        editor.on('tap', function (e) {
25900          var targetElm = e.target;
25901          var contentEditableRoot = getContentEditableRoot(editor, targetElm);
25902          if (isContentEditableFalse(contentEditableRoot)) {
25903            e.preventDefault();
25904            selectNode(editor, contentEditableRoot).each(setElementSelection);
25905          } else if (isFakeSelectionTargetElement(targetElm)) {
25906            selectNode(editor, targetElm).each(setElementSelection);
25907          }
25908        }, true);
25909        editor.on('mousedown', function (e) {
25910          var targetElm = e.target;
25911          if (targetElm !== rootNode && targetElm.nodeName !== 'HTML' && !dom.isChildOf(targetElm, rootNode)) {
25912            return;
25913          }
25914          if (isXYInContentArea(editor, e.clientX, e.clientY) === false) {
25915            return;
25916          }
25917          var contentEditableRoot = getContentEditableRoot(editor, targetElm);
25918          if (contentEditableRoot) {
25919            if (isContentEditableFalse(contentEditableRoot)) {
25920              e.preventDefault();
25921              selectNode(editor, contentEditableRoot).each(setElementSelection);
25922            } else {
25923              removeElementSelection();
25924              if (!(isContentEditableTrue(contentEditableRoot) && e.shiftKey) && !isXYWithinRange(e.clientX, e.clientY, selection.getRng())) {
25925                hideFakeCaret();
25926                selection.placeCaretAt(e.clientX, e.clientY);
25927              }
25928            }
25929          } else if (isFakeSelectionTargetElement(targetElm)) {
25930            selectNode(editor, targetElm).each(setElementSelection);
25931          } else if (isFakeCaretTarget(targetElm) === false) {
25932            removeElementSelection();
25933            hideFakeCaret();
25934            var fakeCaretInfo = closestFakeCaret(rootNode, e.clientX, e.clientY);
25935            if (fakeCaretInfo) {
25936              if (!hasBetterMouseTarget(targetElm, fakeCaretInfo.node)) {
25937                e.preventDefault();
25938                var range = showCaret(1, fakeCaretInfo.node, fakeCaretInfo.before, false);
25939                setRange(range);
25940                editor.getBody().focus();
25941              }
25942            }
25943          }
25944        });
25945        editor.on('keypress', function (e) {
25946          if (VK.modifierPressed(e)) {
25947            return;
25948          }
25949          if (isContentEditableFalse(selection.getNode())) {
25950            e.preventDefault();
25951          }
25952        });
25953        editor.on('GetSelectionRange', function (e) {
25954          var rng = e.range;
25955          if (selectedElement) {
25956            if (!selectedElement.parentNode) {
25957              selectedElement = null;
25958              return;
25959            }
25960            rng = rng.cloneRange();
25961            rng.selectNode(selectedElement);
25962            e.range = rng;
25963          }
25964        });
25965        editor.on('SetSelectionRange', function (e) {
25966          e.range = normalizeShortEndedElementSelection(e.range);
25967          var rng = setElementSelection(e.range, e.forward);
25968          if (rng) {
25969            e.range = rng;
25970          }
25971        });
25972        var isPasteBin = function (node) {
25973          return node.id === 'mcepastebin';
25974        };
25975        editor.on('AfterSetSelectionRange', function (e) {
25976          var rng = e.range;
25977          var parentNode = rng.startContainer.parentNode;
25978          if (!isRangeInCaretContainer(rng) && !isPasteBin(parentNode)) {
25979            hideFakeCaret();
25980          }
25981          if (!isFakeSelectionElement(parentNode)) {
25982            removeElementSelection();
25983          }
25984        });
25985        editor.on('copy', function (e) {
25986          var clipboardData = e.clipboardData;
25987          if (!e.isDefaultPrevented() && e.clipboardData && !Env.ie) {
25988            var realSelectionElement = getRealSelectionElement();
25989            if (realSelectionElement) {
25990              e.preventDefault();
25991              clipboardData.clearData();
25992              clipboardData.setData('text/html', realSelectionElement.outerHTML);
25993              clipboardData.setData('text/plain', realSelectionElement.outerText || realSelectionElement.innerText);
25994            }
25995          }
25996        });
25997        init$2(editor);
25998        setup$1(editor);
25999        setup(editor);
26000      };
26001      var isWithinCaretContainer = function (node) {
26002        return isCaretContainer$2(node) || startsWithCaretContainer$1(node) || endsWithCaretContainer$1(node);
26003      };
26004      var isRangeInCaretContainer = function (rng) {
26005        return isWithinCaretContainer(rng.startContainer) || isWithinCaretContainer(rng.endContainer);
26006      };
26007      var normalizeShortEndedElementSelection = function (rng) {
26008        var shortEndedElements = editor.schema.getShortEndedElements();
26009        var newRng = dom.createRng();
26010        var startContainer = rng.startContainer;
26011        var startOffset = rng.startOffset;
26012        var endContainer = rng.endContainer;
26013        var endOffset = rng.endOffset;
26014        if (has$2(shortEndedElements, startContainer.nodeName.toLowerCase())) {
26015          if (startOffset === 0) {
26016            newRng.setStartBefore(startContainer);
26017          } else {
26018            newRng.setStartAfter(startContainer);
26019          }
26020        } else {
26021          newRng.setStart(startContainer, startOffset);
26022        }
26023        if (has$2(shortEndedElements, endContainer.nodeName.toLowerCase())) {
26024          if (endOffset === 0) {
26025            newRng.setEndBefore(endContainer);
26026          } else {
26027            newRng.setEndAfter(endContainer);
26028          }
26029        } else {
26030          newRng.setEnd(endContainer, endOffset);
26031        }
26032        return newRng;
26033      };
26034      var setupOffscreenSelection = function (node, targetClone, origTargetClone) {
26035        var $ = editor.$;
26036        var $realSelectionContainer = descendant(SugarElement.fromDom(editor.getBody()), '#' + realSelectionId).fold(function () {
26037          return $([]);
26038        }, function (elm) {
26039          return $([elm.dom]);
26040        });
26041        if ($realSelectionContainer.length === 0) {
26042          $realSelectionContainer = $('<div data-mce-bogus="all" class="mce-offscreen-selection"></div>').attr('id', realSelectionId);
26043          $realSelectionContainer.appendTo(editor.getBody());
26044        }
26045        var newRange = dom.createRng();
26046        if (targetClone === origTargetClone && Env.ie) {
26047          $realSelectionContainer.empty().append('<p style="font-size: 0" data-mce-bogus="all">\xA0</p>').append(targetClone);
26048          newRange.setStartAfter($realSelectionContainer[0].firstChild.firstChild);
26049          newRange.setEndAfter(targetClone);
26050        } else {
26051          $realSelectionContainer.empty().append(nbsp).append(targetClone).append(nbsp);
26052          newRange.setStart($realSelectionContainer[0].firstChild, 1);
26053          newRange.setEnd($realSelectionContainer[0].lastChild, 0);
26054        }
26055        $realSelectionContainer.css({ top: dom.getPos(node, editor.getBody()).y });
26056        $realSelectionContainer[0].focus();
26057        var sel = selection.getSel();
26058        sel.removeAllRanges();
26059        sel.addRange(newRange);
26060        return newRange;
26061      };
26062      var selectElement = function (elm) {
26063        var targetClone = elm.cloneNode(true);
26064        var e = editor.fire('ObjectSelected', {
26065          target: elm,
26066          targetClone: targetClone
26067        });
26068        if (e.isDefaultPrevented()) {
26069          return null;
26070        }
26071        var range = setupOffscreenSelection(elm, e.targetClone, targetClone);
26072        var nodeElm = SugarElement.fromDom(elm);
26073        each$k(descendants(SugarElement.fromDom(editor.getBody()), '*[data-mce-selected]'), function (elm) {
26074          if (!eq(nodeElm, elm)) {
26075            remove$6(elm, elementSelectionAttr);
26076          }
26077        });
26078        if (!dom.getAttrib(elm, elementSelectionAttr)) {
26079          elm.setAttribute(elementSelectionAttr, '1');
26080        }
26081        selectedElement = elm;
26082        hideFakeCaret();
26083        return range;
26084      };
26085      var setElementSelection = function (range, forward) {
26086        if (!range) {
26087          return null;
26088        }
26089        if (range.collapsed) {
26090          if (!isRangeInCaretContainer(range)) {
26091            var dir = forward ? 1 : -1;
26092            var caretPosition = getNormalizedRangeEndPoint(dir, rootNode, range);
26093            var beforeNode = caretPosition.getNode(!forward);
26094            if (isFakeCaretTarget(beforeNode)) {
26095              return showCaret(dir, beforeNode, forward ? !caretPosition.isAtEnd() : false, false);
26096            }
26097            var afterNode = caretPosition.getNode(forward);
26098            if (isFakeCaretTarget(afterNode)) {
26099              return showCaret(dir, afterNode, forward ? false : !caretPosition.isAtEnd(), false);
26100            }
26101          }
26102          return null;
26103        }
26104        var startContainer = range.startContainer;
26105        var startOffset = range.startOffset;
26106        var endOffset = range.endOffset;
26107        if (startContainer.nodeType === 3 && startOffset === 0 && isContentEditableFalse(startContainer.parentNode)) {
26108          startContainer = startContainer.parentNode;
26109          startOffset = dom.nodeIndex(startContainer);
26110          startContainer = startContainer.parentNode;
26111        }
26112        if (startContainer.nodeType !== 1) {
26113          return null;
26114        }
26115        if (endOffset === startOffset + 1 && startContainer === range.endContainer) {
26116          var node = startContainer.childNodes[startOffset];
26117          if (isFakeSelectionTargetElement(node)) {
26118            return selectElement(node);
26119          }
26120        }
26121        return null;
26122      };
26123      var removeElementSelection = function () {
26124        if (selectedElement) {
26125          selectedElement.removeAttribute(elementSelectionAttr);
26126        }
26127        descendant(SugarElement.fromDom(editor.getBody()), '#' + realSelectionId).each(remove$7);
26128        selectedElement = null;
26129      };
26130      var destroy = function () {
26131        fakeCaret.destroy();
26132        selectedElement = null;
26133      };
26134      var hideFakeCaret = function () {
26135        fakeCaret.hide();
26136      };
26137      if (Env.ceFalse && !isRtc(editor)) {
26138        registerEvents();
26139      }
26140      return {
26141        showCaret: showCaret,
26142        showBlockCaretContainer: showBlockCaretContainer,
26143        hideFakeCaret: hideFakeCaret,
26144        destroy: destroy
26145      };
26146    };
26147
26148    var Quirks = function (editor) {
26149      var each = Tools.each;
26150      var BACKSPACE = VK.BACKSPACE, DELETE = VK.DELETE, dom = editor.dom, selection = editor.selection, parser = editor.parser;
26151      var isGecko = Env.gecko, isIE = Env.ie, isWebKit = Env.webkit;
26152      var mceInternalUrlPrefix = 'data:text/mce-internal,';
26153      var mceInternalDataType = isIE ? 'Text' : 'URL';
26154      var setEditorCommandState = function (cmd, state) {
26155        try {
26156          editor.getDoc().execCommand(cmd, false, state);
26157        } catch (ex) {
26158        }
26159      };
26160      var isDefaultPrevented = function (e) {
26161        return e.isDefaultPrevented();
26162      };
26163      var setMceInternalContent = function (e) {
26164        var selectionHtml, internalContent;
26165        if (e.dataTransfer) {
26166          if (editor.selection.isCollapsed() && e.target.tagName === 'IMG') {
26167            selection.select(e.target);
26168          }
26169          selectionHtml = editor.selection.getContent();
26170          if (selectionHtml.length > 0) {
26171            internalContent = mceInternalUrlPrefix + escape(editor.id) + ',' + escape(selectionHtml);
26172            e.dataTransfer.setData(mceInternalDataType, internalContent);
26173          }
26174        }
26175      };
26176      var getMceInternalContent = function (e) {
26177        var internalContent;
26178        if (e.dataTransfer) {
26179          internalContent = e.dataTransfer.getData(mceInternalDataType);
26180          if (internalContent && internalContent.indexOf(mceInternalUrlPrefix) >= 0) {
26181            internalContent = internalContent.substr(mceInternalUrlPrefix.length).split(',');
26182            return {
26183              id: unescape(internalContent[0]),
26184              html: unescape(internalContent[1])
26185            };
26186          }
26187        }
26188        return null;
26189      };
26190      var insertClipboardContents = function (content, internal) {
26191        if (editor.queryCommandSupported('mceInsertClipboardContent')) {
26192          editor.execCommand('mceInsertClipboardContent', false, {
26193            content: content,
26194            internal: internal
26195          });
26196        } else {
26197          editor.execCommand('mceInsertContent', false, content);
26198        }
26199      };
26200      var emptyEditorWhenDeleting = function () {
26201        var serializeRng = function (rng) {
26202          var body = dom.create('body');
26203          var contents = rng.cloneContents();
26204          body.appendChild(contents);
26205          return selection.serializer.serialize(body, { format: 'html' });
26206        };
26207        var allContentsSelected = function (rng) {
26208          var selection = serializeRng(rng);
26209          var allRng = dom.createRng();
26210          allRng.selectNode(editor.getBody());
26211          var allSelection = serializeRng(allRng);
26212          return selection === allSelection;
26213        };
26214        editor.on('keydown', function (e) {
26215          var keyCode = e.keyCode;
26216          var isCollapsed, body;
26217          if (!isDefaultPrevented(e) && (keyCode === DELETE || keyCode === BACKSPACE)) {
26218            isCollapsed = editor.selection.isCollapsed();
26219            body = editor.getBody();
26220            if (isCollapsed && !dom.isEmpty(body)) {
26221              return;
26222            }
26223            if (!isCollapsed && !allContentsSelected(editor.selection.getRng())) {
26224              return;
26225            }
26226            e.preventDefault();
26227            editor.setContent('');
26228            if (body.firstChild && dom.isBlock(body.firstChild)) {
26229              editor.selection.setCursorLocation(body.firstChild, 0);
26230            } else {
26231              editor.selection.setCursorLocation(body, 0);
26232            }
26233            editor.nodeChanged();
26234          }
26235        });
26236      };
26237      var selectAll = function () {
26238        editor.shortcuts.add('meta+a', null, 'SelectAll');
26239      };
26240      var documentElementEditingFocus = function () {
26241        if (!editor.inline) {
26242          dom.bind(editor.getDoc(), 'mousedown mouseup', function (e) {
26243            var rng;
26244            if (e.target === editor.getDoc().documentElement) {
26245              rng = selection.getRng();
26246              editor.getBody().focus();
26247              if (e.type === 'mousedown') {
26248                if (isCaretContainer$2(rng.startContainer)) {
26249                  return;
26250                }
26251                selection.placeCaretAt(e.clientX, e.clientY);
26252              } else {
26253                selection.setRng(rng);
26254              }
26255            }
26256          });
26257        }
26258      };
26259      var removeHrOnBackspace = function () {
26260        editor.on('keydown', function (e) {
26261          if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) {
26262            if (!editor.getBody().getElementsByTagName('hr').length) {
26263              return;
26264            }
26265            if (selection.isCollapsed() && selection.getRng().startOffset === 0) {
26266              var node = selection.getNode();
26267              var previousSibling = node.previousSibling;
26268              if (node.nodeName === 'HR') {
26269                dom.remove(node);
26270                e.preventDefault();
26271                return;
26272              }
26273              if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === 'hr') {
26274                dom.remove(previousSibling);
26275                e.preventDefault();
26276              }
26277            }
26278          }
26279        });
26280      };
26281      var focusBody = function () {
26282        if (!Range.prototype.getClientRects) {
26283          editor.on('mousedown', function (e) {
26284            if (!isDefaultPrevented(e) && e.target.nodeName === 'HTML') {
26285              var body_1 = editor.getBody();
26286              body_1.blur();
26287              Delay.setEditorTimeout(editor, function () {
26288                body_1.focus();
26289              });
26290            }
26291          });
26292        }
26293      };
26294      var selectControlElements = function () {
26295        editor.on('click', function (e) {
26296          var target = e.target;
26297          if (/^(IMG|HR)$/.test(target.nodeName) && dom.getContentEditableParent(target) !== 'false') {
26298            e.preventDefault();
26299            editor.selection.select(target);
26300            editor.nodeChanged();
26301          }
26302          if (target.nodeName === 'A' && dom.hasClass(target, 'mce-item-anchor')) {
26303            e.preventDefault();
26304            selection.select(target);
26305          }
26306        });
26307      };
26308      var removeStylesWhenDeletingAcrossBlockElements = function () {
26309        var getAttributeApplyFunction = function () {
26310          var template = dom.getAttribs(selection.getStart().cloneNode(false));
26311          return function () {
26312            var target = selection.getStart();
26313            if (target !== editor.getBody()) {
26314              dom.setAttrib(target, 'style', null);
26315              each(template, function (attr) {
26316                target.setAttributeNode(attr.cloneNode(true));
26317              });
26318            }
26319          };
26320        };
26321        var isSelectionAcrossElements = function () {
26322          return !selection.isCollapsed() && dom.getParent(selection.getStart(), dom.isBlock) !== dom.getParent(selection.getEnd(), dom.isBlock);
26323        };
26324        editor.on('keypress', function (e) {
26325          var applyAttributes;
26326          if (!isDefaultPrevented(e) && (e.keyCode === 8 || e.keyCode === 46) && isSelectionAcrossElements()) {
26327            applyAttributes = getAttributeApplyFunction();
26328            editor.getDoc().execCommand('delete', false, null);
26329            applyAttributes();
26330            e.preventDefault();
26331            return false;
26332          }
26333        });
26334        dom.bind(editor.getDoc(), 'cut', function (e) {
26335          var applyAttributes;
26336          if (!isDefaultPrevented(e) && isSelectionAcrossElements()) {
26337            applyAttributes = getAttributeApplyFunction();
26338            Delay.setEditorTimeout(editor, function () {
26339              applyAttributes();
26340            });
26341          }
26342        });
26343      };
26344      var disableBackspaceIntoATable = function () {
26345        editor.on('keydown', function (e) {
26346          if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) {
26347            if (selection.isCollapsed() && selection.getRng().startOffset === 0) {
26348              var previousSibling = selection.getNode().previousSibling;
26349              if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === 'table') {
26350                e.preventDefault();
26351                return false;
26352              }
26353            }
26354          }
26355        });
26356      };
26357      var removeBlockQuoteOnBackSpace = function () {
26358        editor.on('keydown', function (e) {
26359          var rng, parent;
26360          if (isDefaultPrevented(e) || e.keyCode !== VK.BACKSPACE) {
26361            return;
26362          }
26363          rng = selection.getRng();
26364          var container = rng.startContainer;
26365          var offset = rng.startOffset;
26366          var root = dom.getRoot();
26367          parent = container;
26368          if (!rng.collapsed || offset !== 0) {
26369            return;
26370          }
26371          while (parent && parent.parentNode && parent.parentNode.firstChild === parent && parent.parentNode !== root) {
26372            parent = parent.parentNode;
26373          }
26374          if (parent.tagName === 'BLOCKQUOTE') {
26375            editor.formatter.toggle('blockquote', null, parent);
26376            rng = dom.createRng();
26377            rng.setStart(container, 0);
26378            rng.setEnd(container, 0);
26379            selection.setRng(rng);
26380          }
26381        });
26382      };
26383      var setGeckoEditingOptions = function () {
26384        var setOpts = function () {
26385          setEditorCommandState('StyleWithCSS', false);
26386          setEditorCommandState('enableInlineTableEditing', false);
26387          if (!getObjectResizing(editor)) {
26388            setEditorCommandState('enableObjectResizing', false);
26389          }
26390        };
26391        if (!isReadOnly$1(editor)) {
26392          editor.on('BeforeExecCommand mousedown', setOpts);
26393        }
26394      };
26395      var addBrAfterLastLinks = function () {
26396        var fixLinks = function () {
26397          each(dom.select('a'), function (node) {
26398            var parentNode = node.parentNode;
26399            var root = dom.getRoot();
26400            if (parentNode.lastChild === node) {
26401              while (parentNode && !dom.isBlock(parentNode)) {
26402                if (parentNode.parentNode.lastChild !== parentNode || parentNode === root) {
26403                  return;
26404                }
26405                parentNode = parentNode.parentNode;
26406              }
26407              dom.add(parentNode, 'br', { 'data-mce-bogus': 1 });
26408            }
26409          });
26410        };
26411        editor.on('SetContent ExecCommand', function (e) {
26412          if (e.type === 'setcontent' || e.command === 'mceInsertLink') {
26413            fixLinks();
26414          }
26415        });
26416      };
26417      var setDefaultBlockType = function () {
26418        if (getForcedRootBlock(editor)) {
26419          editor.on('init', function () {
26420            setEditorCommandState('DefaultParagraphSeparator', getForcedRootBlock(editor));
26421          });
26422        }
26423      };
26424      var normalizeSelection = function () {
26425        editor.on('keyup focusin mouseup', function (e) {
26426          if (!VK.modifierPressed(e)) {
26427            selection.normalize();
26428          }
26429        }, true);
26430      };
26431      var showBrokenImageIcon = function () {
26432        editor.contentStyles.push('img:-moz-broken {' + '-moz-force-broken-image-icon:1;' + 'min-width:24px;' + 'min-height:24px' + '}');
26433      };
26434      var restoreFocusOnKeyDown = function () {
26435        if (!editor.inline) {
26436          editor.on('keydown', function () {
26437            if (document.activeElement === document.body) {
26438              editor.getWin().focus();
26439            }
26440          });
26441        }
26442      };
26443      var bodyHeight = function () {
26444        if (!editor.inline) {
26445          editor.contentStyles.push('body {min-height: 150px}');
26446          editor.on('click', function (e) {
26447            var rng;
26448            if (e.target.nodeName === 'HTML') {
26449              if (Env.ie > 11) {
26450                editor.getBody().focus();
26451                return;
26452              }
26453              rng = editor.selection.getRng();
26454              editor.getBody().focus();
26455              editor.selection.setRng(rng);
26456              editor.selection.normalize();
26457              editor.nodeChanged();
26458            }
26459          });
26460        }
26461      };
26462      var blockCmdArrowNavigation = function () {
26463        if (Env.mac) {
26464          editor.on('keydown', function (e) {
26465            if (VK.metaKeyPressed(e) && !e.shiftKey && (e.keyCode === 37 || e.keyCode === 39)) {
26466              e.preventDefault();
26467              var selection_1 = editor.selection.getSel();
26468              selection_1.modify('move', e.keyCode === 37 ? 'backward' : 'forward', 'lineboundary');
26469            }
26470          });
26471        }
26472      };
26473      var disableAutoUrlDetect = function () {
26474        setEditorCommandState('AutoUrlDetect', false);
26475      };
26476      var tapLinksAndImages = function () {
26477        editor.on('click', function (e) {
26478          var elm = e.target;
26479          do {
26480            if (elm.tagName === 'A') {
26481              e.preventDefault();
26482              return;
26483            }
26484          } while (elm = elm.parentNode);
26485        });
26486        editor.contentStyles.push('.mce-content-body {-webkit-touch-callout: none}');
26487      };
26488      var blockFormSubmitInsideEditor = function () {
26489        editor.on('init', function () {
26490          editor.dom.bind(editor.getBody(), 'submit', function (e) {
26491            e.preventDefault();
26492          });
26493        });
26494      };
26495      var removeAppleInterchangeBrs = function () {
26496        parser.addNodeFilter('br', function (nodes) {
26497          var i = nodes.length;
26498          while (i--) {
26499            if (nodes[i].attr('class') === 'Apple-interchange-newline') {
26500              nodes[i].remove();
26501            }
26502          }
26503        });
26504      };
26505      var ieInternalDragAndDrop = function () {
26506        editor.on('dragstart', function (e) {
26507          setMceInternalContent(e);
26508        });
26509        editor.on('drop', function (e) {
26510          if (!isDefaultPrevented(e)) {
26511            var internalContent = getMceInternalContent(e);
26512            if (internalContent && internalContent.id !== editor.id) {
26513              e.preventDefault();
26514              var rng = fromPoint(e.x, e.y, editor.getDoc());
26515              selection.setRng(rng);
26516              insertClipboardContents(internalContent.html, true);
26517            }
26518          }
26519        });
26520      };
26521      var refreshContentEditable = noop;
26522      var isHidden = function () {
26523        if (!isGecko || editor.removed) {
26524          return false;
26525        }
26526        var sel = editor.selection.getSel();
26527        return !sel || !sel.rangeCount || sel.rangeCount === 0;
26528      };
26529      var setupRtc = function () {
26530        if (isWebKit) {
26531          documentElementEditingFocus();
26532          selectControlElements();
26533          blockFormSubmitInsideEditor();
26534          selectAll();
26535          if (Env.iOS) {
26536            restoreFocusOnKeyDown();
26537            bodyHeight();
26538            tapLinksAndImages();
26539          }
26540        }
26541        if (isGecko) {
26542          focusBody();
26543          setGeckoEditingOptions();
26544          showBrokenImageIcon();
26545          blockCmdArrowNavigation();
26546        }
26547      };
26548      var setup = function () {
26549        removeBlockQuoteOnBackSpace();
26550        emptyEditorWhenDeleting();
26551        if (!Env.windowsPhone) {
26552          normalizeSelection();
26553        }
26554        if (isWebKit) {
26555          documentElementEditingFocus();
26556          selectControlElements();
26557          setDefaultBlockType();
26558          blockFormSubmitInsideEditor();
26559          disableBackspaceIntoATable();
26560          removeAppleInterchangeBrs();
26561          if (Env.iOS) {
26562            restoreFocusOnKeyDown();
26563            bodyHeight();
26564            tapLinksAndImages();
26565          } else {
26566            selectAll();
26567          }
26568        }
26569        if (Env.ie >= 11) {
26570          bodyHeight();
26571          disableBackspaceIntoATable();
26572        }
26573        if (Env.ie) {
26574          selectAll();
26575          disableAutoUrlDetect();
26576          ieInternalDragAndDrop();
26577        }
26578        if (isGecko) {
26579          removeHrOnBackspace();
26580          focusBody();
26581          removeStylesWhenDeletingAcrossBlockElements();
26582          setGeckoEditingOptions();
26583          addBrAfterLastLinks();
26584          showBrokenImageIcon();
26585          blockCmdArrowNavigation();
26586          disableBackspaceIntoATable();
26587        }
26588      };
26589      if (isRtc(editor)) {
26590        setupRtc();
26591      } else {
26592        setup();
26593      }
26594      return {
26595        refreshContentEditable: refreshContentEditable,
26596        isHidden: isHidden
26597      };
26598    };
26599
26600    var DOM$6 = DOMUtils.DOM;
26601    var appendStyle = function (editor, text) {
26602      var body = SugarElement.fromDom(editor.getBody());
26603      var container = getStyleContainer(getRootNode(body));
26604      var style = SugarElement.fromTag('style');
26605      set$1(style, 'type', 'text/css');
26606      append$1(style, SugarElement.fromText(text));
26607      append$1(container, style);
26608      editor.on('remove', function () {
26609        remove$7(style);
26610      });
26611    };
26612    var getRootName = function (editor) {
26613      return editor.inline ? editor.getElement().nodeName.toLowerCase() : undefined;
26614    };
26615    var removeUndefined = function (obj) {
26616      return filter$3(obj, function (v) {
26617        return isUndefined(v) === false;
26618      });
26619    };
26620    var mkSchemaSettings = function (editor) {
26621      var settings = editor.settings;
26622      return removeUndefined({
26623        block_elements: settings.block_elements,
26624        boolean_attributes: settings.boolean_attributes,
26625        custom_elements: settings.custom_elements,
26626        extended_valid_elements: settings.extended_valid_elements,
26627        invalid_elements: settings.invalid_elements,
26628        invalid_styles: settings.invalid_styles,
26629        move_caret_before_on_enter_elements: settings.move_caret_before_on_enter_elements,
26630        non_empty_elements: settings.non_empty_elements,
26631        schema: settings.schema,
26632        self_closing_elements: settings.self_closing_elements,
26633        short_ended_elements: settings.short_ended_elements,
26634        special: settings.special,
26635        text_block_elements: settings.text_block_elements,
26636        text_inline_elements: settings.text_inline_elements,
26637        valid_children: settings.valid_children,
26638        valid_classes: settings.valid_classes,
26639        valid_elements: settings.valid_elements,
26640        valid_styles: settings.valid_styles,
26641        verify_html: settings.verify_html,
26642        whitespace_elements: settings.whitespace_elements,
26643        padd_empty_block_inline_children: settings.format_empty_lines
26644      });
26645    };
26646    var mkParserSettings = function (editor) {
26647      var settings = editor.settings;
26648      var blobCache = editor.editorUpload.blobCache;
26649      return removeUndefined({
26650        allow_conditional_comments: settings.allow_conditional_comments,
26651        allow_html_data_urls: settings.allow_html_data_urls,
26652        allow_svg_data_urls: settings.allow_svg_data_urls,
26653        allow_html_in_named_anchor: settings.allow_html_in_named_anchor,
26654        allow_script_urls: settings.allow_script_urls,
26655        allow_unsafe_link_target: settings.allow_unsafe_link_target,
26656        convert_fonts_to_spans: settings.convert_fonts_to_spans,
26657        fix_list_elements: settings.fix_list_elements,
26658        font_size_legacy_values: settings.font_size_legacy_values,
26659        forced_root_block: settings.forced_root_block,
26660        forced_root_block_attrs: settings.forced_root_block_attrs,
26661        padd_empty_with_br: settings.padd_empty_with_br,
26662        preserve_cdata: settings.preserve_cdata,
26663        remove_trailing_brs: settings.remove_trailing_brs,
26664        inline_styles: settings.inline_styles,
26665        root_name: getRootName(editor),
26666        validate: true,
26667        blob_cache: blobCache,
26668        document: editor.getDoc(),
26669        images_dataimg_filter: settings.images_dataimg_filter
26670      });
26671    };
26672    var mkSerializerSettings = function (editor) {
26673      var settings = editor.settings;
26674      return __assign(__assign(__assign({}, mkParserSettings(editor)), mkSchemaSettings(editor)), removeUndefined({
26675        url_converter: settings.url_converter,
26676        url_converter_scope: settings.url_converter_scope,
26677        element_format: settings.element_format,
26678        entities: settings.entities,
26679        entity_encoding: settings.entity_encoding,
26680        indent: settings.indent,
26681        indent_after: settings.indent_after,
26682        indent_before: settings.indent_before
26683      }));
26684    };
26685    var createParser = function (editor) {
26686      var parser = DomParser(mkParserSettings(editor), editor.schema);
26687      parser.addAttributeFilter('src,href,style,tabindex', function (nodes, name) {
26688        var i = nodes.length, node, value;
26689        var dom = editor.dom;
26690        var internalName = 'data-mce-' + name;
26691        while (i--) {
26692          node = nodes[i];
26693          value = node.attr(name);
26694          if (value && !node.attr(internalName)) {
26695            if (value.indexOf('data:') === 0 || value.indexOf('blob:') === 0) {
26696              continue;
26697            }
26698            if (name === 'style') {
26699              value = dom.serializeStyle(dom.parseStyle(value), node.name);
26700              if (!value.length) {
26701                value = null;
26702              }
26703              node.attr(internalName, value);
26704              node.attr(name, value);
26705            } else if (name === 'tabindex') {
26706              node.attr(internalName, value);
26707              node.attr(name, null);
26708            } else {
26709              node.attr(internalName, editor.convertURL(value, name, node.name));
26710            }
26711          }
26712        }
26713      });
26714      parser.addNodeFilter('script', function (nodes) {
26715        var i = nodes.length;
26716        while (i--) {
26717          var node = nodes[i];
26718          var type = node.attr('type') || 'no/type';
26719          if (type.indexOf('mce-') !== 0) {
26720            node.attr('type', 'mce-' + type);
26721          }
26722        }
26723      });
26724      if (editor.settings.preserve_cdata) {
26725        parser.addNodeFilter('#cdata', function (nodes) {
26726          var i = nodes.length;
26727          while (i--) {
26728            var node = nodes[i];
26729            node.type = 8;
26730            node.name = '#comment';
26731            node.value = '[CDATA[' + editor.dom.encode(node.value) + ']]';
26732          }
26733        });
26734      }
26735      parser.addNodeFilter('p,h1,h2,h3,h4,h5,h6,div', function (nodes) {
26736        var i = nodes.length;
26737        var nonEmptyElements = editor.schema.getNonEmptyElements();
26738        while (i--) {
26739          var node = nodes[i];
26740          if (node.isEmpty(nonEmptyElements) && node.getAll('br').length === 0) {
26741            node.append(new AstNode('br', 1)).shortEnded = true;
26742          }
26743        }
26744      });
26745      return parser;
26746    };
26747    var autoFocus = function (editor) {
26748      if (editor.settings.auto_focus) {
26749        Delay.setEditorTimeout(editor, function () {
26750          var focusEditor;
26751          if (editor.settings.auto_focus === true) {
26752            focusEditor = editor;
26753          } else {
26754            focusEditor = editor.editorManager.get(editor.settings.auto_focus);
26755          }
26756          if (!focusEditor.destroyed) {
26757            focusEditor.focus();
26758          }
26759        }, 100);
26760      }
26761    };
26762    var moveSelectionToFirstCaretPosition = function (editor) {
26763      var root = editor.dom.getRoot();
26764      if (!editor.inline && (!hasAnyRanges(editor) || editor.selection.getStart(true) === root)) {
26765        firstPositionIn(root).each(function (pos) {
26766          var node = pos.getNode();
26767          var caretPos = isTable$3(node) ? firstPositionIn(node).getOr(pos) : pos;
26768          if (Env.browser.isIE()) {
26769            storeNative(editor, caretPos.toRange());
26770          } else {
26771            editor.selection.setRng(caretPos.toRange());
26772          }
26773        });
26774      }
26775    };
26776    var initEditor = function (editor) {
26777      editor.bindPendingEventDelegates();
26778      editor.initialized = true;
26779      fireInit(editor);
26780      editor.focus(true);
26781      moveSelectionToFirstCaretPosition(editor);
26782      editor.nodeChanged({ initial: true });
26783      editor.execCallback('init_instance_callback', editor);
26784      autoFocus(editor);
26785    };
26786    var getStyleSheetLoader$1 = function (editor) {
26787      return editor.inline ? editor.ui.styleSheetLoader : editor.dom.styleSheetLoader;
26788    };
26789    var makeStylesheetLoadingPromises = function (editor, css, framedFonts) {
26790      var promises = [new promiseObj(function (resolve, reject) {
26791          return getStyleSheetLoader$1(editor).loadAll(css, resolve, reject);
26792        })];
26793      if (editor.inline) {
26794        return promises;
26795      } else {
26796        return promises.concat([new promiseObj(function (resolve, reject) {
26797            return editor.ui.styleSheetLoader.loadAll(framedFonts, resolve, reject);
26798          })]);
26799      }
26800    };
26801    var loadContentCss = function (editor) {
26802      var styleSheetLoader = getStyleSheetLoader$1(editor);
26803      var fontCss = getFontCss(editor);
26804      var css = editor.contentCSS;
26805      var removeCss = function () {
26806        styleSheetLoader.unloadAll(css);
26807        if (!editor.inline) {
26808          editor.ui.styleSheetLoader.unloadAll(fontCss);
26809        }
26810      };
26811      var loaded = function () {
26812        if (editor.removed) {
26813          removeCss();
26814        } else {
26815          editor.on('remove', removeCss);
26816        }
26817      };
26818      if (editor.contentStyles.length > 0) {
26819        var contentCssText_1 = '';
26820        Tools.each(editor.contentStyles, function (style) {
26821          contentCssText_1 += style + '\r\n';
26822        });
26823        editor.dom.addStyle(contentCssText_1);
26824      }
26825      var allStylesheets = promiseObj.all(makeStylesheetLoadingPromises(editor, css, fontCss)).then(loaded).catch(loaded);
26826      if (editor.settings.content_style) {
26827        appendStyle(editor, editor.settings.content_style);
26828      }
26829      return allStylesheets;
26830    };
26831    var preInit = function (editor) {
26832      var settings = editor.settings, doc = editor.getDoc(), body = editor.getBody();
26833      firePreInit(editor);
26834      if (!settings.browser_spellcheck && !settings.gecko_spellcheck) {
26835        doc.body.spellcheck = false;
26836        DOM$6.setAttrib(body, 'spellcheck', 'false');
26837      }
26838      editor.quirks = Quirks(editor);
26839      firePostRender(editor);
26840      var directionality = getDirectionality(editor);
26841      if (directionality !== undefined) {
26842        body.dir = directionality;
26843      }
26844      if (settings.protect) {
26845        editor.on('BeforeSetContent', function (e) {
26846          Tools.each(settings.protect, function (pattern) {
26847            e.content = e.content.replace(pattern, function (str) {
26848              return '<!--mce:protected ' + escape(str) + '-->';
26849            });
26850          });
26851        });
26852      }
26853      editor.on('SetContent', function () {
26854        editor.addVisual(editor.getBody());
26855      });
26856      editor.on('compositionstart compositionend', function (e) {
26857        editor.composing = e.type === 'compositionstart';
26858      });
26859    };
26860    var loadInitialContent = function (editor) {
26861      if (!isRtc(editor)) {
26862        editor.load({
26863          initial: true,
26864          format: 'html'
26865        });
26866      }
26867      editor.startContent = editor.getContent({ format: 'raw' });
26868    };
26869    var initEditorWithInitialContent = function (editor) {
26870      if (editor.removed !== true) {
26871        loadInitialContent(editor);
26872        initEditor(editor);
26873      }
26874    };
26875    var initContentBody = function (editor, skipWrite) {
26876      var settings = editor.settings;
26877      var targetElm = editor.getElement();
26878      var doc = editor.getDoc();
26879      if (!settings.inline) {
26880        editor.getElement().style.visibility = editor.orgVisibility;
26881      }
26882      if (!skipWrite && !editor.inline) {
26883        doc.open();
26884        doc.write(editor.iframeHTML);
26885        doc.close();
26886      }
26887      if (editor.inline) {
26888        DOM$6.addClass(targetElm, 'mce-content-body');
26889        editor.contentDocument = doc = document;
26890        editor.contentWindow = window;
26891        editor.bodyElement = targetElm;
26892        editor.contentAreaContainer = targetElm;
26893      }
26894      var body = editor.getBody();
26895      body.disabled = true;
26896      editor.readonly = !!settings.readonly;
26897      if (!editor.readonly) {
26898        if (editor.inline && DOM$6.getStyle(body, 'position', true) === 'static') {
26899          body.style.position = 'relative';
26900        }
26901        body.contentEditable = editor.getParam('content_editable_state', true);
26902      }
26903      body.disabled = false;
26904      editor.editorUpload = EditorUpload(editor);
26905      editor.schema = Schema(mkSchemaSettings(editor));
26906      editor.dom = DOMUtils(doc, {
26907        keep_values: true,
26908        url_converter: editor.convertURL,
26909        url_converter_scope: editor,
26910        hex_colors: settings.force_hex_style_colors,
26911        update_styles: true,
26912        root_element: editor.inline ? editor.getBody() : null,
26913        collect: function () {
26914          return editor.inline;
26915        },
26916        schema: editor.schema,
26917        contentCssCors: shouldUseContentCssCors(editor),
26918        referrerPolicy: getReferrerPolicy(editor),
26919        onSetAttrib: function (e) {
26920          editor.fire('SetAttrib', e);
26921        }
26922      });
26923      editor.parser = createParser(editor);
26924      editor.serializer = DomSerializer(mkSerializerSettings(editor), editor);
26925      editor.selection = EditorSelection(editor.dom, editor.getWin(), editor.serializer, editor);
26926      editor.annotator = Annotator(editor);
26927      editor.formatter = Formatter(editor);
26928      editor.undoManager = UndoManager(editor);
26929      editor._nodeChangeDispatcher = new NodeChange(editor);
26930      editor._selectionOverrides = SelectionOverrides(editor);
26931      setup$e(editor);
26932      setup$3(editor);
26933      if (!isRtc(editor)) {
26934        setup$2(editor);
26935      }
26936      var caret = setup$4(editor);
26937      setup$f(editor, caret);
26938      setup$d(editor);
26939      setup$g(editor);
26940      var setupRtcThunk = setup$i(editor);
26941      preInit(editor);
26942      setupRtcThunk.fold(function () {
26943        loadContentCss(editor).then(function () {
26944          return initEditorWithInitialContent(editor);
26945        });
26946      }, function (setupRtc) {
26947        editor.setProgressState(true);
26948        loadContentCss(editor).then(function () {
26949          setupRtc().then(function (_rtcMode) {
26950            editor.setProgressState(false);
26951            initEditorWithInitialContent(editor);
26952          }, function (err) {
26953            editor.notificationManager.open({
26954              type: 'error',
26955              text: String(err)
26956            });
26957            initEditorWithInitialContent(editor);
26958          });
26959        });
26960      });
26961    };
26962
26963    var DOM$5 = DOMUtils.DOM;
26964    var relaxDomain = function (editor, ifr) {
26965      if (document.domain !== window.location.hostname && Env.browser.isIE()) {
26966        var bodyUuid = uuid('mce');
26967        editor[bodyUuid] = function () {
26968          initContentBody(editor);
26969        };
26970        var domainRelaxUrl = 'javascript:(function(){' + 'document.open();document.domain="' + document.domain + '";' + 'var ed = window.parent.tinymce.get("' + editor.id + '");document.write(ed.iframeHTML);' + 'document.close();ed.' + bodyUuid + '(true);})()';
26971        DOM$5.setAttrib(ifr, 'src', domainRelaxUrl);
26972        return true;
26973      }
26974      return false;
26975    };
26976    var createIframeElement = function (id, title, height, customAttrs) {
26977      var iframe = SugarElement.fromTag('iframe');
26978      setAll$1(iframe, customAttrs);
26979      setAll$1(iframe, {
26980        id: id + '_ifr',
26981        frameBorder: '0',
26982        allowTransparency: 'true',
26983        title: title
26984      });
26985      add$1(iframe, 'tox-edit-area__iframe');
26986      return iframe;
26987    };
26988    var getIframeHtml = function (editor) {
26989      var iframeHTML = getDocType(editor) + '<html><head>';
26990      if (getDocumentBaseUrl(editor) !== editor.documentBaseUrl) {
26991        iframeHTML += '<base href="' + editor.documentBaseURI.getURI() + '" />';
26992      }
26993      iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';
26994      var bodyId = getBodyId(editor);
26995      var bodyClass = getBodyClass(editor);
26996      var translatedAriaText = editor.translate(getIframeAriaText(editor));
26997      if (getContentSecurityPolicy(editor)) {
26998        iframeHTML += '<meta http-equiv="Content-Security-Policy" content="' + getContentSecurityPolicy(editor) + '" />';
26999      }
27000      iframeHTML += '</head>' + ('<body id="' + bodyId + '" class="mce-content-body ' + bodyClass + '" data-id="' + editor.id + '" aria-label="' + translatedAriaText + '">') + '<br>' + '</body></html>';
27001      return iframeHTML;
27002    };
27003    var createIframe = function (editor, o) {
27004      var iframeTitle = editor.translate('Rich Text Area');
27005      var ifr = createIframeElement(editor.id, iframeTitle, o.height, getIframeAttrs(editor)).dom;
27006      ifr.onload = function () {
27007        ifr.onload = null;
27008        editor.fire('load');
27009      };
27010      var isDomainRelaxed = relaxDomain(editor, ifr);
27011      editor.contentAreaContainer = o.iframeContainer;
27012      editor.iframeElement = ifr;
27013      editor.iframeHTML = getIframeHtml(editor);
27014      DOM$5.add(o.iframeContainer, ifr);
27015      return isDomainRelaxed;
27016    };
27017    var init$1 = function (editor, boxInfo) {
27018      var isDomainRelaxed = createIframe(editor, boxInfo);
27019      if (boxInfo.editorContainer) {
27020        DOM$5.get(boxInfo.editorContainer).style.display = editor.orgDisplay;
27021        editor.hidden = DOM$5.isHidden(boxInfo.editorContainer);
27022      }
27023      editor.getElement().style.display = 'none';
27024      DOM$5.setAttrib(editor.id, 'aria-hidden', 'true');
27025      if (!isDomainRelaxed) {
27026        initContentBody(editor);
27027      }
27028    };
27029
27030    var DOM$4 = DOMUtils.DOM;
27031    var initPlugin = function (editor, initializedPlugins, plugin) {
27032      var Plugin = PluginManager.get(plugin);
27033      var pluginUrl = PluginManager.urls[plugin] || editor.documentBaseUrl.replace(/\/$/, '');
27034      plugin = Tools.trim(plugin);
27035      if (Plugin && Tools.inArray(initializedPlugins, plugin) === -1) {
27036        Tools.each(PluginManager.dependencies(plugin), function (dep) {
27037          initPlugin(editor, initializedPlugins, dep);
27038        });
27039        if (editor.plugins[plugin]) {
27040          return;
27041        }
27042        try {
27043          var pluginInstance = new Plugin(editor, pluginUrl, editor.$);
27044          editor.plugins[plugin] = pluginInstance;
27045          if (pluginInstance.init) {
27046            pluginInstance.init(editor, pluginUrl);
27047            initializedPlugins.push(plugin);
27048          }
27049        } catch (e) {
27050          pluginInitError(editor, plugin, e);
27051        }
27052      }
27053    };
27054    var trimLegacyPrefix = function (name) {
27055      return name.replace(/^\-/, '');
27056    };
27057    var initPlugins = function (editor) {
27058      var initializedPlugins = [];
27059      Tools.each(getPlugins(editor).split(/[ ,]/), function (name) {
27060        initPlugin(editor, initializedPlugins, trimLegacyPrefix(name));
27061      });
27062    };
27063    var initIcons = function (editor) {
27064      var iconPackName = Tools.trim(getIconPackName(editor));
27065      var currentIcons = editor.ui.registry.getAll().icons;
27066      var loadIcons = __assign(__assign({}, IconManager.get('default').icons), IconManager.get(iconPackName).icons);
27067      each$j(loadIcons, function (svgData, icon) {
27068        if (!has$2(currentIcons, icon)) {
27069          editor.ui.registry.addIcon(icon, svgData);
27070        }
27071      });
27072    };
27073    var initTheme = function (editor) {
27074      var theme = getTheme(editor);
27075      if (isString$1(theme)) {
27076        editor.settings.theme = trimLegacyPrefix(theme);
27077        var Theme = ThemeManager.get(theme);
27078        editor.theme = new Theme(editor, ThemeManager.urls[theme]);
27079        if (editor.theme.init) {
27080          editor.theme.init(editor, ThemeManager.urls[theme] || editor.documentBaseUrl.replace(/\/$/, ''), editor.$);
27081        }
27082      } else {
27083        editor.theme = {};
27084      }
27085    };
27086    var renderFromLoadedTheme = function (editor) {
27087      return editor.theme.renderUI();
27088    };
27089    var renderFromThemeFunc = function (editor) {
27090      var elm = editor.getElement();
27091      var theme = getTheme(editor);
27092      var info = theme(editor, elm);
27093      if (info.editorContainer.nodeType) {
27094        info.editorContainer.id = info.editorContainer.id || editor.id + '_parent';
27095      }
27096      if (info.iframeContainer && info.iframeContainer.nodeType) {
27097        info.iframeContainer.id = info.iframeContainer.id || editor.id + '_iframecontainer';
27098      }
27099      info.height = info.iframeHeight ? info.iframeHeight : elm.offsetHeight;
27100      return info;
27101    };
27102    var createThemeFalseResult = function (element) {
27103      return {
27104        editorContainer: element,
27105        iframeContainer: element,
27106        api: {}
27107      };
27108    };
27109    var renderThemeFalseIframe = function (targetElement) {
27110      var iframeContainer = DOM$4.create('div');
27111      DOM$4.insertAfter(iframeContainer, targetElement);
27112      return createThemeFalseResult(iframeContainer);
27113    };
27114    var renderThemeFalse = function (editor) {
27115      var targetElement = editor.getElement();
27116      return editor.inline ? createThemeFalseResult(null) : renderThemeFalseIframe(targetElement);
27117    };
27118    var renderThemeUi = function (editor) {
27119      var elm = editor.getElement();
27120      editor.orgDisplay = elm.style.display;
27121      if (isString$1(getTheme(editor))) {
27122        return renderFromLoadedTheme(editor);
27123      } else if (isFunction(getTheme(editor))) {
27124        return renderFromThemeFunc(editor);
27125      } else {
27126        return renderThemeFalse(editor);
27127      }
27128    };
27129    var augmentEditorUiApi = function (editor, api) {
27130      var uiApiFacade = {
27131        show: Optional.from(api.show).getOr(noop),
27132        hide: Optional.from(api.hide).getOr(noop),
27133        disable: Optional.from(api.disable).getOr(noop),
27134        isDisabled: Optional.from(api.isDisabled).getOr(never),
27135        enable: function () {
27136          if (!editor.mode.isReadOnly()) {
27137            Optional.from(api.enable).map(call);
27138          }
27139        }
27140      };
27141      editor.ui = __assign(__assign({}, editor.ui), uiApiFacade);
27142    };
27143    var init = function (editor) {
27144      editor.fire('ScriptsLoaded');
27145      initIcons(editor);
27146      initTheme(editor);
27147      initPlugins(editor);
27148      var renderInfo = renderThemeUi(editor);
27149      augmentEditorUiApi(editor, Optional.from(renderInfo.api).getOr({}));
27150      var boxInfo = {
27151        editorContainer: renderInfo.editorContainer,
27152        iframeContainer: renderInfo.iframeContainer
27153      };
27154      editor.editorContainer = boxInfo.editorContainer ? boxInfo.editorContainer : null;
27155      appendContentCssFromSettings(editor);
27156      if (editor.inline) {
27157        return initContentBody(editor);
27158      } else {
27159        return init$1(editor, boxInfo);
27160      }
27161    };
27162
27163    var DOM$3 = DOMUtils.DOM;
27164    var hasSkipLoadPrefix = function (name) {
27165      return name.charAt(0) === '-';
27166    };
27167    var loadLanguage = function (scriptLoader, editor) {
27168      var languageCode = getLanguageCode(editor);
27169      var languageUrl = getLanguageUrl(editor);
27170      if (I18n.hasCode(languageCode) === false && languageCode !== 'en') {
27171        var url_1 = languageUrl !== '' ? languageUrl : editor.editorManager.baseURL + '/langs/' + languageCode + '.js';
27172        scriptLoader.add(url_1, noop, undefined, function () {
27173          languageLoadError(editor, url_1, languageCode);
27174        });
27175      }
27176    };
27177    var loadTheme = function (scriptLoader, editor, suffix, callback) {
27178      var theme = getTheme(editor);
27179      if (isString$1(theme)) {
27180        if (!hasSkipLoadPrefix(theme) && !has$2(ThemeManager.urls, theme)) {
27181          var themeUrl = getThemeUrl(editor);
27182          if (themeUrl) {
27183            ThemeManager.load(theme, editor.documentBaseURI.toAbsolute(themeUrl));
27184          } else {
27185            ThemeManager.load(theme, 'themes/' + theme + '/theme' + suffix + '.js');
27186          }
27187        }
27188        scriptLoader.loadQueue(function () {
27189          ThemeManager.waitFor(theme, callback);
27190        });
27191      } else {
27192        callback();
27193      }
27194    };
27195    var getIconsUrlMetaFromUrl = function (editor) {
27196      return Optional.from(getIconsUrl(editor)).filter(function (url) {
27197        return url.length > 0;
27198      }).map(function (url) {
27199        return {
27200          url: url,
27201          name: Optional.none()
27202        };
27203      });
27204    };
27205    var getIconsUrlMetaFromName = function (editor, name, suffix) {
27206      return Optional.from(name).filter(function (name) {
27207        return name.length > 0 && !IconManager.has(name);
27208      }).map(function (name) {
27209        return {
27210          url: editor.editorManager.baseURL + '/icons/' + name + '/icons' + suffix + '.js',
27211          name: Optional.some(name)
27212        };
27213      });
27214    };
27215    var loadIcons = function (scriptLoader, editor, suffix) {
27216      var defaultIconsUrl = getIconsUrlMetaFromName(editor, 'default', suffix);
27217      var customIconsUrl = getIconsUrlMetaFromUrl(editor).orThunk(function () {
27218        return getIconsUrlMetaFromName(editor, getIconPackName(editor), '');
27219      });
27220      each$k(cat([
27221        defaultIconsUrl,
27222        customIconsUrl
27223      ]), function (urlMeta) {
27224        scriptLoader.add(urlMeta.url, noop, undefined, function () {
27225          iconsLoadError(editor, urlMeta.url, urlMeta.name.getOrUndefined());
27226        });
27227      });
27228    };
27229    var loadPlugins = function (editor, suffix) {
27230      Tools.each(getExternalPlugins$1(editor), function (url, name) {
27231        PluginManager.load(name, url, noop, undefined, function () {
27232          pluginLoadError(editor, url, name);
27233        });
27234        editor.settings.plugins += ' ' + name;
27235      });
27236      Tools.each(getPlugins(editor).split(/[ ,]/), function (plugin) {
27237        plugin = Tools.trim(plugin);
27238        if (plugin && !PluginManager.urls[plugin]) {
27239          if (hasSkipLoadPrefix(plugin)) {
27240            plugin = plugin.substr(1, plugin.length);
27241            var dependencies = PluginManager.dependencies(plugin);
27242            Tools.each(dependencies, function (depPlugin) {
27243              var defaultSettings = {
27244                prefix: 'plugins/',
27245                resource: depPlugin,
27246                suffix: '/plugin' + suffix + '.js'
27247              };
27248              var dep = PluginManager.createUrl(defaultSettings, depPlugin);
27249              PluginManager.load(dep.resource, dep, noop, undefined, function () {
27250                pluginLoadError(editor, dep.prefix + dep.resource + dep.suffix, dep.resource);
27251              });
27252            });
27253          } else {
27254            var url_2 = {
27255              prefix: 'plugins/',
27256              resource: plugin,
27257              suffix: '/plugin' + suffix + '.js'
27258            };
27259            PluginManager.load(plugin, url_2, noop, undefined, function () {
27260              pluginLoadError(editor, url_2.prefix + url_2.resource + url_2.suffix, plugin);
27261            });
27262          }
27263        }
27264      });
27265    };
27266    var loadScripts = function (editor, suffix) {
27267      var scriptLoader = ScriptLoader.ScriptLoader;
27268      loadTheme(scriptLoader, editor, suffix, function () {
27269        loadLanguage(scriptLoader, editor);
27270        loadIcons(scriptLoader, editor, suffix);
27271        loadPlugins(editor, suffix);
27272        scriptLoader.loadQueue(function () {
27273          if (!editor.removed) {
27274            init(editor);
27275          }
27276        }, editor, function () {
27277          if (!editor.removed) {
27278            init(editor);
27279          }
27280        });
27281      });
27282    };
27283    var getStyleSheetLoader = function (element, editor) {
27284      return instance.forElement(element, {
27285        contentCssCors: hasContentCssCors(editor),
27286        referrerPolicy: getReferrerPolicy(editor)
27287      });
27288    };
27289    var render = function (editor) {
27290      var id = editor.id;
27291      I18n.setCode(getLanguageCode(editor));
27292      var readyHandler = function () {
27293        DOM$3.unbind(window, 'ready', readyHandler);
27294        editor.render();
27295      };
27296      if (!EventUtils.Event.domLoaded) {
27297        DOM$3.bind(window, 'ready', readyHandler);
27298        return;
27299      }
27300      if (!editor.getElement()) {
27301        return;
27302      }
27303      if (!Env.contentEditable) {
27304        return;
27305      }
27306      var element = SugarElement.fromDom(editor.getElement());
27307      var snapshot = clone$3(element);
27308      editor.on('remove', function () {
27309        eachr(element.dom.attributes, function (attr) {
27310          return remove$6(element, attr.name);
27311        });
27312        setAll$1(element, snapshot);
27313      });
27314      editor.ui.styleSheetLoader = getStyleSheetLoader(element, editor);
27315      if (!isInline(editor)) {
27316        editor.orgVisibility = editor.getElement().style.visibility;
27317        editor.getElement().style.visibility = 'hidden';
27318      } else {
27319        editor.inline = true;
27320      }
27321      var form = editor.getElement().form || DOM$3.getParent(id, 'form');
27322      if (form) {
27323        editor.formElement = form;
27324        if (hasHiddenInput(editor) && !isTextareaOrInput(editor.getElement())) {
27325          DOM$3.insertAfter(DOM$3.create('input', {
27326            type: 'hidden',
27327            name: id
27328          }), id);
27329          editor.hasHiddenInput = true;
27330        }
27331        editor.formEventDelegate = function (e) {
27332          editor.fire(e.type, e);
27333        };
27334        DOM$3.bind(form, 'submit reset', editor.formEventDelegate);
27335        editor.on('reset', function () {
27336          editor.resetContent();
27337        });
27338        if (shouldPatchSubmit(editor) && !form.submit.nodeType && !form.submit.length && !form._mceOldSubmit) {
27339          form._mceOldSubmit = form.submit;
27340          form.submit = function () {
27341            editor.editorManager.triggerSave();
27342            editor.setDirty(false);
27343            return form._mceOldSubmit(form);
27344          };
27345        }
27346      }
27347      editor.windowManager = WindowManager(editor);
27348      editor.notificationManager = NotificationManager(editor);
27349      if (isEncodingXml(editor)) {
27350        editor.on('GetContent', function (e) {
27351          if (e.save) {
27352            e.content = DOM$3.encode(e.content);
27353          }
27354        });
27355      }
27356      if (shouldAddFormSubmitTrigger(editor)) {
27357        editor.on('submit', function () {
27358          if (editor.initialized) {
27359            editor.save();
27360          }
27361        });
27362      }
27363      if (shouldAddUnloadTrigger(editor)) {
27364        editor._beforeUnload = function () {
27365          if (editor.initialized && !editor.destroyed && !editor.isHidden()) {
27366            editor.save({
27367              format: 'raw',
27368              no_events: true,
27369              set_dirty: false
27370            });
27371          }
27372        };
27373        editor.editorManager.on('BeforeUnload', editor._beforeUnload);
27374      }
27375      editor.editorManager.add(editor);
27376      loadScripts(editor, editor.suffix);
27377    };
27378
27379    var addVisual = function (editor, elm) {
27380      return addVisual$1(editor, elm);
27381    };
27382
27383    var legacyPropNames = {
27384      'font-size': 'size',
27385      'font-family': 'face'
27386    };
27387    var getSpecifiedFontProp = function (propName, rootElm, elm) {
27388      var getProperty = function (elm) {
27389        return getRaw(elm, propName).orThunk(function () {
27390          if (name(elm) === 'font') {
27391            return get$9(legacyPropNames, propName).bind(function (legacyPropName) {
27392              return getOpt(elm, legacyPropName);
27393            });
27394          } else {
27395            return Optional.none();
27396          }
27397        });
27398      };
27399      var isRoot = function (elm) {
27400        return eq(SugarElement.fromDom(rootElm), elm);
27401      };
27402      return closest$1(SugarElement.fromDom(elm), function (elm) {
27403        return getProperty(elm);
27404      }, isRoot);
27405    };
27406    var normalizeFontFamily = function (fontFamily) {
27407      return fontFamily.replace(/[\'\"\\]/g, '').replace(/,\s+/g, ',');
27408    };
27409    var getComputedFontProp = function (propName, elm) {
27410      return Optional.from(DOMUtils.DOM.getStyle(elm, propName, true));
27411    };
27412    var getFontProp = function (propName) {
27413      return function (rootElm, elm) {
27414        return Optional.from(elm).map(SugarElement.fromDom).filter(isElement$6).bind(function (element) {
27415          return getSpecifiedFontProp(propName, rootElm, element.dom).or(getComputedFontProp(propName, element.dom));
27416        }).getOr('');
27417      };
27418    };
27419    var getFontSize = getFontProp('font-size');
27420    var getFontFamily = compose(normalizeFontFamily, getFontProp('font-family'));
27421
27422    var findFirstCaretElement = function (editor) {
27423      return firstPositionIn(editor.getBody()).map(function (caret) {
27424        var container = caret.container();
27425        return isText$7(container) ? container.parentNode : container;
27426      });
27427    };
27428    var getCaretElement = function (editor) {
27429      return Optional.from(editor.selection.getRng()).bind(function (rng) {
27430        var root = editor.getBody();
27431        var atStartOfNode = rng.startContainer === root && rng.startOffset === 0;
27432        return atStartOfNode ? Optional.none() : Optional.from(editor.selection.getStart(true));
27433      });
27434    };
27435    var bindRange = function (editor, binder) {
27436      return getCaretElement(editor).orThunk(curry(findFirstCaretElement, editor)).map(SugarElement.fromDom).filter(isElement$6).bind(binder);
27437    };
27438    var mapRange = function (editor, mapper) {
27439      return bindRange(editor, compose1(Optional.some, mapper));
27440    };
27441
27442    var fromFontSizeNumber = function (editor, value) {
27443      if (/^[0-9.]+$/.test(value)) {
27444        var fontSizeNumber = parseInt(value, 10);
27445        if (fontSizeNumber >= 1 && fontSizeNumber <= 7) {
27446          var fontSizes = getFontStyleValues(editor);
27447          var fontClasses = getFontSizeClasses(editor);
27448          if (fontClasses) {
27449            return fontClasses[fontSizeNumber - 1] || value;
27450          } else {
27451            return fontSizes[fontSizeNumber - 1] || value;
27452          }
27453        } else {
27454          return value;
27455        }
27456      } else {
27457        return value;
27458      }
27459    };
27460    var normalizeFontNames = function (font) {
27461      var fonts = font.split(/\s*,\s*/);
27462      return map$3(fonts, function (font) {
27463        if (font.indexOf(' ') !== -1 && !(startsWith(font, '"') || startsWith(font, '\''))) {
27464          return '\'' + font + '\'';
27465        } else {
27466          return font;
27467        }
27468      }).join(',');
27469    };
27470    var fontNameAction = function (editor, value) {
27471      var font = fromFontSizeNumber(editor, value);
27472      editor.formatter.toggle('fontname', { value: normalizeFontNames(font) });
27473      editor.nodeChanged();
27474    };
27475    var fontNameQuery = function (editor) {
27476      return mapRange(editor, function (elm) {
27477        return getFontFamily(editor.getBody(), elm.dom);
27478      }).getOr('');
27479    };
27480    var fontSizeAction = function (editor, value) {
27481      editor.formatter.toggle('fontsize', { value: fromFontSizeNumber(editor, value) });
27482      editor.nodeChanged();
27483    };
27484    var fontSizeQuery = function (editor) {
27485      return mapRange(editor, function (elm) {
27486        return getFontSize(editor.getBody(), elm.dom);
27487      }).getOr('');
27488    };
27489
27490    var lineHeightQuery = function (editor) {
27491      return mapRange(editor, function (elm) {
27492        var root = SugarElement.fromDom(editor.getBody());
27493        var specifiedStyle = closest$1(elm, function (elm) {
27494          return getRaw(elm, 'line-height');
27495        }, curry(eq, root));
27496        var computedStyle = function () {
27497          var lineHeight = parseFloat(get$5(elm, 'line-height'));
27498          var fontSize = parseFloat(get$5(elm, 'font-size'));
27499          return String(lineHeight / fontSize);
27500        };
27501        return specifiedStyle.getOrThunk(computedStyle);
27502      }).getOr('');
27503    };
27504    var lineHeightAction = function (editor, lineHeight) {
27505      editor.formatter.toggle('lineheight', { value: String(lineHeight) });
27506      editor.nodeChanged();
27507    };
27508
27509    var processValue = function (value) {
27510      if (typeof value !== 'string') {
27511        var details = Tools.extend({
27512          paste: value.paste,
27513          data: { paste: value.paste }
27514        }, value);
27515        return {
27516          content: value.content,
27517          details: details
27518        };
27519      }
27520      return {
27521        content: value,
27522        details: {}
27523      };
27524    };
27525    var insertAtCaret = function (editor, value) {
27526      var result = processValue(value);
27527      insertContent(editor, result.content, result.details);
27528    };
27529
27530    var each$4 = Tools.each;
27531    var map = Tools.map, inArray = Tools.inArray;
27532    var EditorCommands = function () {
27533      function EditorCommands(editor) {
27534        this.commands = {
27535          state: {},
27536          exec: {},
27537          value: {}
27538        };
27539        this.editor = editor;
27540        this.setupCommands(editor);
27541      }
27542      EditorCommands.prototype.execCommand = function (command, ui, value, args
27542) {
27543        var func, state = false;
27544        var self = this;
27545        if (self.editor.removed) {
27546          return;
27547        }
27548        if (command.toLowerCase() !== 'mcefocus') {
27549          if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint)$/.test(command) && (!args || !args.skip_focus)) {
27550            self.editor.focus();
27551          } else {
27552            restore(self.editor);
27553          }
27554        }
27555        args = self.editor.fire('BeforeExecCommand', {
27556          command: command,
27557          ui: ui,
27558          value: value
27559        });
27560        if (args.isDefaultPrevented()) {
27561          return false;
27562        }
27563        var customCommand = command.toLowerCase();
27564        if (func = self.commands.exec[customCommand]) {
27565          func(customCommand, ui, value);
27566          self.editor.fire('ExecCommand', {
27567            command: command,
27568            ui: ui,
27569            value: value
27570          });
27571          return true;
27572        }
27573        each$4(this.editor.plugins, function (p) {
27574          if (p.execCommand && p.execCommand(command, ui, value)) {
27575            self.editor.fire('ExecCommand', {
27576              command: command,
27577              ui: ui,
27578              value: value
27579            });
27580            state = true;
27581            return false;
27582          }
27583        });
27584        if (state) {
27585          return state;
27586        }
27587        if (self.editor.theme && self.editor.theme.execCommand && self.editor.theme.execCommand(command, ui, value)) {
27588          self.editor.fire('ExecCommand', {
27589            command: command,
27590            ui: ui,
27591            value: value
27592          });
27593          return true;
27594        }
27595        try {
27596          state = self.editor.getDoc().execCommand(command, ui, value);
27597        } catch (ex) {
27598        }
27599        if (state) {
27600          self.editor.fire('ExecCommand', {
27601            command: command,
27602            ui: ui,
27603            value: value
27604          });
27605          return true;
27606        }
27607        return false;
27608      };
27609      EditorCommands.prototype.queryCommandState = function (command) {
27610        var func;
27611        if (this.editor.quirks.isHidden() || this.editor.removed) {
27612          return;
27613        }
27614        command = command.toLowerCase();
27615        if (func = this.commands.state[command]) {
27616          return func(command);
27617        }
27618        try {
27619          return this.editor.getDoc().queryCommandState(command);
27620        } catch (ex) {
27621        }
27622        return false;
27623      };
27624      EditorCommands.prototype.queryCommandValue = function (command) {
27625        var func;
27626        if (this.editor.quirks.isHidden() || this.editor.removed) {
27627          return;
27628        }
27629        command = command.toLowerCase();
27630        if (func = this.commands.value[command]) {
27631          return func(command);
27632        }
27633        try {
27634          return this.editor.getDoc().queryCommandValue(command);
27635        } catch (ex) {
27636        }
27637      };
27638      EditorCommands.prototype.addCommands = function (commandList, type) {
27639        if (type === void 0) {
27640          type = 'exec';
27641        }
27642        var self = this;
27643        each$4(commandList, function (callback, command) {
27644          each$4(command.toLowerCase().split(','), function (command) {
27645            self.commands[type][command] = callback;
27646          });
27647        });
27648      };
27649      EditorCommands.prototype.addCommand = function (command, callback, scope) {
27650        var _this = this;
27651        command = command.toLowerCase();
27652        this.commands.exec[command] = function (command, ui, value, args) {
27653          return callback.call(scope || _this.editor, ui, value, args);
27654        };
27655      };
27656      EditorCommands.prototype.queryCommandSupported = function (command) {
27657        command = command.toLowerCase();
27658        if (this.commands.exec[command]) {
27659          return true;
27660        }
27661        try {
27662          return this.editor.getDoc().queryCommandSupported(command);
27663        } catch (ex) {
27664        }
27665        return false;
27666      };
27667      EditorCommands.prototype.addQueryStateHandler = function (command, callback, scope) {
27668        var _this = this;
27669        command = command.toLowerCase();
27670        this.commands.state[command] = function () {
27671          return callback.call(scope || _this.editor);
27672        };
27673      };
27674      EditorCommands.prototype.addQueryValueHandler = function (command, callback, scope) {
27675        var _this = this;
27676        command = command.toLowerCase();
27677        this.commands.value[command] = function () {
27678          return callback.call(scope || _this.editor);
27679        };
27680      };
27681      EditorCommands.prototype.hasCustomCommand = function (command) {
27682        command = command.toLowerCase();
27683        return !!this.commands.exec[command];
27684      };
27685      EditorCommands.prototype.execNativeCommand = function (command, ui, value) {
27686        if (ui === undefined) {
27687          ui = false;
27688        }
27689        if (value === undefined) {
27690          value = null;
27691        }
27692        return this.editor.getDoc().execCommand(command, ui, value);
27693      };
27694      EditorCommands.prototype.isFormatMatch = function (name) {
27695        return this.editor.formatter.match(name);
27696      };
27697      EditorCommands.prototype.toggleFormat = function (name, value) {
27698        this.editor.formatter.toggle(name, value);
27699        this.editor.nodeChanged();
27700      };
27701      EditorCommands.prototype.storeSelection = function (type) {
27702        this.selectionBookmark = this.editor.selection.getBookmark(type);
27703      };
27704      EditorCommands.prototype.restoreSelection = function () {
27705        this.editor.selection.moveToBookmark(this.selectionBookmark);
27706      };
27707      EditorCommands.prototype.setupCommands = function (editor) {
27708        var self = this;
27709        this.addCommands({
27710          'mceResetDesignMode,mceBeginUndoLevel': noop,
27711          'mceEndUndoLevel,mceAddUndoLevel': function () {
27712            editor.undoManager.add();
27713          },
27714          'mceFocus': function (_command, _ui, value) {
27715            focus(editor, value);
27716          },
27717          'Cut,Copy,Paste': function (command) {
27718            var doc = editor.getDoc();
27719            var failed;
27720            try {
27721              self.execNativeCommand(command);
27722            } catch (ex) {
27723              failed = true;
27724            }
27725            if (command === 'paste' && !doc.queryCommandEnabled(command)) {
27726              failed = true;
27727            }
27728            if (failed || !doc.queryCommandSupported(command)) {
27729              var msg = editor.translate('Your browser doesn\'t support direct access to the clipboard. ' + 'Please use the Ctrl+X/C/V keyboard shortcuts instead.');
27730              if (Env.mac) {
27731                msg = msg.replace(/Ctrl\+/g, '\u2318+');
27732              }
27733              editor.notificationManager.open({
27734                text: msg,
27735                type: 'error'
27736              });
27737            }
27738          },
27739          'unlink': function () {
27740            if (editor.selection.isCollapsed()) {
27741              var elm = editor.dom.getParent(editor.selection.getStart(), 'a');
27742              if (elm) {
27743                editor.dom.remove(elm, true);
27744              }
27745              return;
27746            }
27747            editor.formatter.remove('link');
27748          },
27749          'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull,JustifyNone': function (command) {
27750            var align = command.substring(7);
27751            if (align === 'full') {
27752              align = 'justify';
27753            }
27754            each$4('left,center,right,justify'.split(','), function (name) {
27755              if (align !== name) {
27756                editor.formatter.remove('align' + name);
27757              }
27758            });
27759            if (align !== 'none') {
27760              self.toggleFormat('align' + align);
27761            }
27762          },
27763          'InsertUnorderedList,InsertOrderedList': function (command) {
27764            var listParent;
27765            self.execNativeCommand(command);
27766            var listElm = editor.dom.getParent(editor.selection.getNode(), 'ol,ul');
27767            if (listElm) {
27768              listParent = listElm.parentNode;
27769              if (/^(H[1-6]|P|ADDRESS|PRE)$/.test(listParent.nodeName)) {
27770                self.storeSelection();
27771                editor.dom.split(listParent, listElm);
27772                self.restoreSelection();
27773              }
27774            }
27775          },
27776          'Bold,Italic,Underline,Strikethrough,Superscript,Subscript': function (command) {
27777            self.toggleFormat(command);
27778          },
27779          'ForeColor,HiliteColor': function (command, ui, value) {
27780            self.toggleFormat(command, { value: value });
27781          },
27782          'FontName': function (command, ui, value) {
27783            fontNameAction(editor, value);
27784          },
27785          'FontSize': function (command, ui, value) {
27786            fontSizeAction(editor, value);
27787          },
27788          'LineHeight': function (command, ui, value) {
27789            lineHeightAction(editor, value);
27790          },
27791          'Lang': function (command, ui, lang) {
27792            self.toggleFormat(command, {
27793              value: lang.code,
27794              customValue: lang.customCode
27795            });
27796          },
27797          'RemoveFormat': function (command) {
27798            editor.formatter.remove(command);
27799          },
27800          'mceBlockQuote': function () {
27801            self.toggleFormat('blockquote');
27802          },
27803          'FormatBlock': function (command, ui, value) {
27804            return self.toggleFormat(value || 'p');
27805          },
27806          'mceCleanup': function () {
27807            var bookmark = editor.selection.getBookmark();
27808            editor.setContent(editor.getContent());
27809            editor.selection.moveToBookmark(bookmark);
27810          },
27811          'mceRemoveNode': function (command, ui, value) {
27812            var node = value || editor.selection.getNode();
27813            if (node !== editor.getBody()) {
27814              self.storeSelection();
27815              editor.dom.remove(node, true);
27816              self.restoreSelection();
27817            }
27818          },
27819          'mceSelectNodeDepth': function (command, ui, value) {
27820            var counter = 0;
27821            editor.dom.getParent(editor.selection.getNode(), function (node) {
27822              if (node.nodeType === 1 && counter++ === value) {
27823                editor.selection.select(node);
27824                return false;
27825              }
27826            }, editor.getBody());
27827          },
27828          'mceSelectNode': function (command, ui, value) {
27829            editor.selection.select(value);
27830          },
27831          'mceInsertContent': function (command, ui, value) {
27832            insertAtCaret(editor, value);
27833          },
27834          'mceInsertRawHTML': function (command, ui, value) {
27835            editor.selection.setContent('tiny_mce_marker');
27836            var content = editor.getContent();
27837            editor.setContent(content.replace(/tiny_mce_marker/g, function () {
27838              return value;
27839            }));
27840          },
27841          'mceInsertNewLine': function (command, ui, value) {
27842            insert(editor, value);
27843          },
27844          'mceToggleFormat': function (command, ui, value) {
27845            self.toggleFormat(value);
27846          },
27847          'mceSetContent': function (command, ui, value) {
27848            editor.setContent(value);
27849          },
27850          'Indent,Outdent': function (command) {
27851            handle(editor, command);
27852          },
27853          'mceRepaint': noop,
27854          'InsertHorizontalRule': function () {
27855            editor.execCommand('mceInsertContent', false, '<hr />');
27856          },
27857          'mceToggleVisualAid': function () {
27858            editor.hasVisual = !editor.hasVisual;
27859            editor.addVisual();
27860          },
27861          'mceReplaceContent': function (command, ui, value) {
27862            editor.execCommand('mceInsertContent', false, value.replace(/\{\$selection\}/g, editor.selection.getContent({ format: 'text' })));
27863          },
27864          'mceInsertLink': function (command, ui, value) {
27865            if (typeof value === 'string') {
27866              value = { href: value };
27867            }
27868            var anchor = editor.dom.getParent(editor.selection.getNode(), 'a');
27869            value.href = value.href.replace(/ /g, '%20');
27870            if (!anchor || !value.href) {
27871              editor.formatter.remove('link');
27872            }
27873            if (value.href) {
27874              editor.formatter.apply('link', value, anchor);
27875            }
27876          },
27877          'selectAll': function () {
27878            var editingHost = editor.dom.getParent(editor.selection.getStart(), isContentEditableTrue$4);
27879            if (editingHost) {
27880              var rng = editor.dom.createRng();
27881              rng.selectNodeContents(editingHost);
27882              editor.selection.setRng(rng);
27883            }
27884          },
27885          'mceNewDocument': function () {
27886            editor.setContent('');
27887          },
27888          'InsertLineBreak': function (command, ui, value) {
27889            insert$1(editor, value);
27890            return true;
27891          }
27892        });
27893        var alignStates = function (name) {
27894          return function () {
27895            var selection = editor.selection;
27896            var nodes = selection.isCollapsed() ? [editor.dom.getParent(selection.getNode(), editor.dom.isBlock)] : selection.getSelectedBlocks();
27897            var matches = map(nodes, function (node) {
27898              return !!editor.formatter.matchNode(node, name);
27899            });
27900            return inArray(matches, true) !== -1;
27901          };
27902        };
27903        self.addCommands({
27904          'JustifyLeft': alignStates('alignleft'),
27905          'JustifyCenter': alignStates('aligncenter'),
27906          'JustifyRight': alignStates('alignright'),
27907          'JustifyFull': alignStates('alignjustify'),
27908          'Bold,Italic,Underline,Strikethrough,Superscript,Subscript': function (command) {
27909            return self.isFormatMatch(command);
27910          },
27911          'mceBlockQuote': function () {
27912            return self.isFormatMatch('blockquote');
27913          },
27914          'Outdent': function () {
27915            return canOutdent(editor);
27916          },
27917          'InsertUnorderedList,InsertOrderedList': function (command) {
27918            var list = editor.dom.getParent(editor.selection.getNode(), 'ul,ol');
27919            return list && (command === 'insertunorderedlist' && list.tagName === 'UL' || command === 'insertorderedlist' && list.tagName === 'OL');
27920          }
27921        }, 'state');
27922        self.addCommands({
27923          Undo: function () {
27924            editor.undoManager.undo();
27925          },
27926          Redo: function () {
27927            editor.undoManager.redo();
27928          }
27929        });
27930        self.addQueryValueHandler('FontName', function () {
27931          return fontNameQuery(editor);
27932        }, this);
27933        self.addQueryValueHandler('FontSize', function () {
27934          return fontSizeQuery(editor);
27935        }, this);
27936        self.addQueryValueHandler('LineHeight', function () {
27937          return lineHeightQuery(editor);
27938        }, this);
27939      };
27940      return EditorCommands;
27941    }();
27942
27943    var internalContentEditableAttr = 'data-mce-contenteditable';
27944    var toggleClass = function (elm, cls, state) {
27945      if (has(elm, cls) && state === false) {
27946        remove$3(elm, cls);
27947      } else if (state) {
27948        add$1(elm, cls);
27949      }
27950    };
27951    var setEditorCommandState = function (editor, cmd, state) {
27952      try {
27953        editor.getDoc().execCommand(cmd, false, String(state));
27954      } catch (ex) {
27955      }
27956    };
27957    var setContentEditable = function (elm, state) {
27958      elm.dom.contentEditable = state ? 'true' : 'false';
27959    };
27960    var switchOffContentEditableTrue = function (elm) {
27961      each$k(descendants(elm, '*[contenteditable="true"]'), function (elm) {
27962        set$1(elm, internalContentEditableAttr, 'true');
27963        setContentEditable(elm, false);
27964      });
27965    };
27966    var switchOnContentEditableTrue = function (elm) {
27967      each$k(descendants(elm, '*[' + internalContentEditableAttr + '="true"]'), function (elm) {
27968        remove$6(elm, internalContentEditableAttr);
27969        setContentEditable(elm, true);
27970      });
27971    };
27972    var removeFakeSelection = function (editor) {
27973      Optional.from(editor.selection.getNode()).each(function (elm) {
27974        elm.removeAttribute('data-mce-selected');
27975      });
27976    };
27977    var restoreFakeSelection = function (editor) {
27978      editor.selection.setRng(editor.selection.getRng());
27979    };
27980    var toggleReadOnly = function (editor, state) {
27981      var body = SugarElement.fromDom(editor.getBody());
27982      toggleClass(body, 'mce-content-readonly', state);
27983      if (state) {
27984        editor.selection.controlSelection.hideResizeRect();
27985        editor._selectionOverrides.hideFakeCaret();
27986        removeFakeSelection(editor);
27987        editor.readonly = true;
27988        setContentEditable(body, false);
27989        switchOffContentEditableTrue(body);
27990      } else {
27991        editor.readonly = false;
27992        setContentEditable(body, true);
27993        switchOnContentEditableTrue(body);
27994        setEditorCommandState(editor, 'StyleWithCSS', false);
27995        setEditorCommandState(editor, 'enableInlineTableEditing', false);
27996        setEditorCommandState(editor, 'enableObjectResizing', false);
27997        if (hasEditorOrUiFocus(editor)) {
27998          editor.focus();
27999        }
28000        restoreFakeSelection(editor);
28001        editor.nodeChanged();
28002      }
28003    };
28004    var isReadOnly = function (editor) {
28005      return editor.readonly;
28006    };
28007    var registerFilters = function (editor) {
28008      editor.parser.addAttributeFilter('contenteditable', function (nodes) {
28009        if (isReadOnly(editor)) {
28010          each$k(nodes, function (node) {
28011            node.attr(internalContentEditableAttr, node.attr('contenteditable'));
28012            node.attr('contenteditable', 'false');
28013          });
28014        }
28015      });
28016      editor.serializer.addAttributeFilter(internalContentEditableAttr, function (nodes) {
28017        if (isReadOnly(editor)) {
28018          each$k(nodes, function (node) {
28019            node.attr('contenteditable', node.attr(internalContentEditableAttr));
28020          });
28021        }
28022      });
28023      editor.serializer.addTempAttr(internalContentEditableAttr);
28024    };
28025    var registerReadOnlyContentFilters = function (editor) {
28026      if (editor.serializer) {
28027        registerFilters(editor);
28028      } else {
28029        editor.on('PreInit', function () {
28030          registerFilters(editor);
28031        });
28032      }
28033    };
28034    var isClickEvent = function (e) {
28035      return e.type === 'click';
28036    };
28037    var getAnchorHrefOpt = function (editor, elm) {
28038      var isRoot = function (elm) {
28039        return eq(elm, SugarElement.fromDom(editor.getBody()));
28040      };
28041      return closest$2(elm, 'a', isRoot).bind(function (a) {
28042        return getOpt(a, 'href');
28043      });
28044    };
28045    var processReadonlyEvents = function (editor, e) {
28046      if (isClickEvent(e) && !VK.metaKeyPressed(e)) {
28047        var elm = SugarElement.fromDom(e.target);
28048        getAnchorHrefOpt(editor, elm).each(function (href) {
28049          e.preventDefault();
28050          if (/^#/.test(href)) {
28051            var targetEl = editor.dom.select(href + ',[name="' + removeLeading(href, '#') + '"]');
28052            if (targetEl.length) {
28053              editor.selection.scrollIntoView(targetEl[0], true);
28054            }
28055          } else {
28056            window.open(href, '_blank', 'rel=noopener noreferrer,menubar=yes,toolbar=yes,location=yes,status=yes,resizable=yes,scrollbars=yes');
28057          }
28058        });
28059      }
28060    };
28061    var registerReadOnlySelectionBlockers = function (editor) {
28062      editor.on('ShowCaret', function (e) {
28063        if (isReadOnly(editor)) {
28064          e.preventDefault();
28065        }
28066      });
28067      editor.on('ObjectSelected', function (e) {
28068        if (isReadOnly(editor)) {
28069          e.preventDefault();
28070        }
28071      });
28072    };
28073
28074    var nativeEvents = Tools.makeMap('focus blur focusin focusout click dblclick mousedown mouseup mousemove mouseover beforepaste paste cut copy selectionchange ' + 'mouseout mouseenter mouseleave wheel keydown keypress keyup input beforeinput contextmenu dragstart dragend dragover ' + 'draggesture dragdrop drop drag submit ' + 'compositionstart compositionend compositionupdate touchstart touchmove touchend touchcancel', ' ');
28075    var EventDispatcher = function () {
28076      function EventDispatcher(settings) {
28077        this.bindings = {};
28078        this.settings = settings || {};
28079        this.scope = this.settings.scope || this;
28080        this.toggleEvent = this.settings.toggleEvent || never;
28081      }
28082      EventDispatcher.isNative = function (name) {
28083        return !!nativeEvents[name.toLowerCase()];
28084      };
28085      EventDispatcher.prototype.fire = function (name, args) {
28086        var lcName = name.toLowerCase();
28087        var event = normalize$3(lcName, args || {}, this.scope);
28088        if (this.settings.beforeFire) {
28089          this.settings.beforeFire(event);
28090        }
28091        var handlers = this.bindings[lcName];
28092        if (handlers) {
28093          for (var i = 0, l = handlers.length; i < l; i++) {
28094            var callback = handlers[i];
28095            if (callback.removed) {
28096              continue;
28097            }
28098            if (callback.once) {
28099              this.off(lcName, callback.func);
28100            }
28101            if (event.isImmediatePropagationStopped()) {
28102              return event;
28103            }
28104            if (callback.func.call(this.scope, event) === false) {
28105              event.preventDefault();
28106              return event;
28107            }
28108          }
28109        }
28110        return event;
28111      };
28112      EventDispatcher.prototype.on = function (name, callback, prepend, extra) {
28113        if (callback === false) {
28114          callback = never;
28115        }
28116        if (callback) {
28117          var wrappedCallback = {
28118            func: callback,
28119            removed: false
28120          };
28121          if (extra) {
28122            Tools.extend(wrappedCallback, extra);
28123          }
28124          var names = name.toLowerCase().split(' ');
28125          var i = names.length;
28126          while (i--) {
28127            var currentName = names[i];
28128            var handlers = this.bindings[currentName];
28129            if (!handlers) {
28130              handlers = [];
28131              this.toggleEvent(currentName, true);
28132            }
28133            if (prepend) {
28134              handlers = __spreadArray([wrappedCallback], handlers, true);
28135            } else {
28136              handlers = __spreadArray(__spreadArray([], handlers, true), [wrappedCallback], false);
28137            }
28138            this.bindings[currentName] = handlers;
28139          }
28140        }
28141        return this;
28142      };
28143      EventDispatcher.prototype.off = function (name, callback) {
28144        var _this = this;
28145        if (name) {
28146          var names = name.toLowerCase().split(' ');
28147          var i = names.length;
28148          while (i--) {
28149            var currentName = names[i];
28150            var handlers = this.bindings[currentName];
28151            if (!currentName) {
28152              each$j(this.bindings, function (_value, bindingName) {
28153                _this.toggleEvent(bindingName, false);
28154                delete _this.bindings[bindingName];
28155              });
28156              return this;
28157            }
28158            if (handlers) {
28159              if (!callback) {
28160                handlers.length = 0;
28161              } else {
28162                var filteredHandlers = partition(handlers, function (handler) {
28163                  return handler.func === callback;
28164                });
28165                handlers = filteredHandlers.fail;
28166                this.bindings[currentName] = handlers;
28167                each$k(filteredHandlers.pass, function (handler) {
28168                  handler.removed = true;
28169                });
28170              }
28171              if (!handlers.length) {
28172                this.toggleEvent(name, false);
28173                delete this.bindings[currentName];
28174              }
28175            }
28176          }
28177        } else {
28178          each$j(this.bindings, function (_value, name) {
28179            _this.toggleEvent(name, false);
28180          });
28181          this.bindings = {};
28182        }
28183        return this;
28184      };
28185      EventDispatcher.prototype.once = function (name, callback, prepend) {
28186        return this.on(name, callback, prepend, { once: true });
28187      };
28188      EventDispatcher.prototype.has = function (name) {
28189        name = name.toLowerCase();
28190        return !(!this.bindings[name] || this.bindings[name].length === 0);
28191      };
28192      return EventDispatcher;
28193    }();
28194
28195    var getEventDispatcher = function (obj) {
28196      if (!obj._eventDispatcher) {
28197        obj._eventDispatcher = new EventDispatcher({
28198          scope: obj,
28199          toggleEvent: function (name, state) {
28200            if (EventDispatcher.isNative(name) && obj.toggleNativeEvent) {
28201              obj.toggleNativeEvent(name, state);
28202            }
28203          }
28204        });
28205      }
28206      return obj._eventDispatcher;
28207    };
28208    var Observable = {
28209      fire: function (name, args, bubble) {
28210        var self = this;
28211        if (self.removed && name !== 'remove' && name !== 'detach') {
28212          return args;
28213        }
28214        var dispatcherArgs = getEventDispatcher(self).fire(name, args);
28215        if (bubble !== false && self.parent) {
28216          var parent_1 = self.parent();
28217          while (parent_1 && !dispatcherArgs.isPropagationStopped()) {
28218            parent_1.fire(name, dispatcherArgs, false);
28219            parent_1 = parent_1.parent();
28220          }
28221        }
28222        return dispatcherArgs;
28223      },
28224      on: function (name, callback, prepend) {
28225        return getEventDispatcher(this).on(name, callback, prepend);
28226      },
28227      off: function (name, callback) {
28228        return getEventDispatcher(this).off(name, callback);
28229      },
28230      once: function (name, callback) {
28231        return getEventDispatcher(this).once(name, callback);
28232      },
28233      hasEventListeners: function (name) {
28234        return getEventDispatcher(this).has(name);
28235      }
28236    };
28237
28238    var DOM$2 = DOMUtils.DOM;
28239    var customEventRootDelegates;
28240    var getEventTarget = function (editor, eventName) {
28241      if (eventName === 'selectionchange') {
28242        return editor.getDoc();
28243      }
28244      if (!editor.inline && /^mouse|touch|click|contextmenu|drop|dragover|dragend/.test(eventName)) {
28245        return editor.getDoc().documentElement;
28246      }
28247      var eventRoot = getEventRoot(editor);
28248      if (eventRoot) {
28249        if (!editor.eventRoot) {
28250          editor.eventRoot = DOM$2.select(eventRoot)[0];
28251        }
28252        return editor.eventRoot;
28253      }
28254      return editor.getBody();
28255    };
28256    var isListening = function (editor) {
28257      return !editor.hidden && !isReadOnly(editor);
28258    };
28259    var fireEvent = function (editor, eventName, e) {
28260      if (isListening(editor)) {
28261        editor.fire(eventName, e);
28262      } else if (isReadOnly(editor)) {
28263        processReadonlyEvents(editor, e);
28264      }
28265    };
28266    var bindEventDelegate = function (editor, eventName) {
28267      var delegate;
28268      if (!editor.delegates) {
28269        editor.delegates = {};
28270      }
28271      if (editor.delegates[eventName] || editor.removed) {
28272        return;
28273      }
28274      var eventRootElm = getEventTarget(editor, eventName);
28275      if (getEventRoot(editor)) {
28276        if (!customEventRootDelegates) {
28277          customEventRootDelegates = {};
28278          editor.editorManager.on('removeEditor', function () {
28279            if (!editor.editorManager.activeEditor) {
28280              if (customEventRootDelegates) {
28281                each$j(customEventRootDelegates, function (_value, name) {
28282                  editor.dom.unbind(getEventTarget(editor, name));
28283                });
28284                customEventRootDelegates = null;
28285              }
28286            }
28287          });
28288        }
28289        if (customEventRootDelegates[eventName]) {
28290          return;
28291        }
28292        delegate = function (e) {
28293          var target = e.target;
28294          var editors = editor.editorManager.get();
28295          var i = editors.length;
28296          while (i--) {
28297            var body = editors[i].getBody();
28298            if (body === target || DOM$2.isChildOf(target, body)) {
28299              fireEvent(editors[i], eventName, e);
28300            }
28301          }
28302        };
28303        customEventRootDelegates[eventName] = delegate;
28304        DOM$2.bind(eventRootElm, eventName, delegate);
28305      } else {
28306        delegate = function (e) {
28307          fireEvent(editor, eventName, e);
28308        };
28309        DOM$2.bind(eventRootElm, eventName, delegate);
28310        editor.delegates[eventName] = delegate;
28311      }
28312    };
28313    var EditorObservable = __assign(__assign({}, Observable), {
28314      bindPendingEventDelegates: function () {
28315        var self = this;
28316        Tools.each(self._pendingNativeEvents, function (name) {
28317          bindEventDelegate(self, name);
28318        });
28319      },
28320      toggleNativeEvent: function (name, state) {
28321        var self = this;
28322        if (name === 'focus' || name === 'blur') {
28323          return;
28324        }
28325        if (self.removed) {
28326          return;
28327        }
28328        if (state) {
28329          if (self.initialized) {
28330            bindEventDelegate(self, name);
28331          } else {
28332            if (!self._pendingNativeEvents) {
28333              self._pendingNativeEvents = [name];
28334            } else {
28335              self._pendingNativeEvents.push(name);
28336            }
28337          }
28338        } else if (self.initialized) {
28339          self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]);
28340          delete self.delegates[name];
28341        }
28342      },
28343      unbindAllNativeEvents: function () {
28344        var self = this;
28345        var body = self.getBody();
28346        var dom = self.dom;
28347        if (self.delegates) {
28348          each$j(self.delegates, function (value, name) {
28349            self.dom.unbind(getEventTarget(self, name), name, value);
28350          });
28351          delete self.delegates;
28352        }
28353        if (!self.inline && body && dom) {
28354          body.onload = null;
28355          dom.unbind(self.getWin());
28356          dom.unbind(self.getDoc());
28357        }
28358        if (dom) {
28359          dom.unbind(body);
28360          dom.unbind(self.getContainer());
28361        }
28362      }
28363    });
28364
28365    var defaultModes = [
28366      'design',
28367      'readonly'
28368    ];
28369    var switchToMode = function (editor, activeMode, availableModes, mode) {
28370      var oldMode = availableModes[activeMode.get()];
28371      var newMode = availableModes[mode];
28372      try {
28373        newMode.activate();
28374      } catch (e) {
28375        console.error('problem while activating editor mode ' + mode + ':', e);
28376        return;
28377      }
28378      oldMode.deactivate();
28379      if (oldMode.editorReadOnly !== newMode.editorReadOnly) {
28380        toggleReadOnly(editor, newMode.editorReadOnly);
28381      }
28382      activeMode.set(mode);
28383      fireSwitchMode(editor, mode);
28384    };
28385    var setMode = function (editor, availableModes, activeMode, mode) {
28386      if (mode === activeMode.get()) {
28387        return;
28388      } else if (!has$2(availableModes, mode)) {
28389        throw new Error('Editor mode \'' + mode + '\' is invalid');
28390      }
28391      if (editor.initialized) {
28392        switchToMode(editor, activeMode, availableModes, mode);
28393      } else {
28394        editor.on('init', function () {
28395          return switchToMode(editor, activeMode, availableModes, mode);
28396        });
28397      }
28398    };
28399    var registerMode = function (availableModes, mode, api) {
28400      var _a;
28401      if (contains$3(defaultModes, mode)) {
28402        throw new Error('Cannot override default mode ' + mode);
28403      }
28404      return __assign(__assign({}, availableModes), (_a = {}, _a[mode] = __assign(__assign({}, api), {
28405        deactivate: function () {
28406          try {
28407            api.deactivate();
28408          } catch (e) {
28409            console.error('problem while deactivating editor mode ' + mode + ':', e);
28410          }
28411        }
28412      }), _a));
28413    };
28414
28415    var create$4 = function (editor) {
28416      var activeMode = Cell('design');
28417      var availableModes = Cell({
28418        design: {
28419          activate: noop,
28420          deactivate: noop,
28421          editorReadOnly: false
28422        },
28423        readonly: {
28424          activate: noop,
28425          deactivate: noop,
28426          editorReadOnly: true
28427        }
28428      });
28429      registerReadOnlyContentFilters(editor);
28430      registerReadOnlySelectionBlockers(editor);
28431      return {
28432        isReadOnly: function () {
28433          return isReadOnly(editor);
28434        },
28435        set: function (mode) {
28436          return setMode(editor, availableModes.get(), activeMode, mode);
28437        },
28438        get: function () {
28439          return activeMode.get();
28440        },
28441        register: function (mode, api) {
28442          availableModes.set(registerMode(availableModes.get(), mode, api));
28443        }
28444      };
28445    };
28446
28447    var each$3 = Tools.each, explode$1 = Tools.explode;
28448    var keyCodeLookup = {
28449      f1: 112,
28450      f2: 113,
28451      f3: 114,
28452      f4: 115,
28453      f5: 116,
28454      f6: 117,
28455      f7: 118,
28456      f8: 119,
28457      f9: 120,
28458      f10: 121,
28459      f11: 122,
28460      f12: 123
28461    };
28462    var modifierNames = Tools.makeMap('alt,ctrl,shift,meta,access');
28463    var parseShortcut = function (pattern) {
28464      var key;
28465      var shortcut = {};
28466      each$3(explode$1(pattern.toLowerCase(), '+'), function (value) {
28467        if (value in modifierNames) {
28468          shortcut[value] = true;
28469        } else {
28470          if (/^[0-9]{2,}$/.test(value)) {
28471            shortcut.keyCode = parseInt(value, 10);
28472          } else {
28473            shortcut.charCode = value.charCodeAt(0);
28474            shortcut.keyCode = keyCodeLookup[value] || value.toUpperCase().charCodeAt(0);
28475          }
28476        }
28477      });
28478      var id = [shortcut.keyCode];
28479      for (key in modifierNames) {
28480        if (shortcut[key]) {
28481          id.push(key);
28482        } else {
28483          shortcut[key] = false;
28484        }
28485      }
28486      shortcut.id = id.join(',');
28487      if (shortcut.access) {
28488        shortcut.alt = true;
28489        if (Env.mac) {
28490          shortcut.ctrl = true;
28491        } else {
28492          shortcut.shift = true;
28493        }
28494      }
28495      if (shortcut.meta) {
28496        if (Env.mac) {
28497          shortcut.meta = true;
28498        } else {
28499          shortcut.ctrl = true;
28500          shortcut.meta = false;
28501        }
28502      }
28503      return shortcut;
28504    };
28505    var Shortcuts = function () {
28506      function Shortcuts(editor) {
28507        this.shortcuts = {};
28508        this.pendingPatterns = [];
28509        this.editor = editor;
28510        var self = this;
28511        editor.on('keyup keypress keydown', function (e) {
28512          if ((self.hasModifier(e) || self.isFunctionKey(e)) && !e.isDefaultPrevented()) {
28513            each$3(self.shortcuts, function (shortcut) {
28514              if (self.matchShortcut(e, shortcut)) {
28515                self.pendingPatterns = shortcut.subpatterns.slice(0);
28516                if (e.type === 'keydown') {
28517                  self.executeShortcutAction(shortcut);
28518                }
28519                return true;
28520              }
28521            });
28522            if (self.matchShortcut(e, self.pendingPatterns[0])) {
28523              if (self.pendingPatterns.length === 1) {
28524                if (e.type === 'keydown') {
28525                  self.executeShortcutAction(self.pendingPatterns[0]);
28526                }
28527              }
28528              self.pendingPatterns.shift();
28529            }
28530          }
28531        });
28532      }
28533      Shortcuts.prototype.add = function (pattern, desc, cmdFunc, scope) {
28534        var self = this;
28535        var func = self.normalizeCommandFunc(cmdFunc);
28536        each$3(explode$1(Tools.trim(pattern)), function (pattern) {
28537          var shortcut = self.createShortcut(pattern, desc, func, scope);
28538          self.shortcuts[shortcut.id] = shortcut;
28539        });
28540        return true;
28541      };
28542      Shortcuts.prototype.remove = function (pattern) {
28543        var shortcut = this.createShortcut(pattern);
28544        if (this.shortcuts[shortcut.id]) {
28545          delete this.shortcuts[shortcut.id];
28546          return true;
28547        }
28548        return false;
28549      };
28550      Shortcuts.prototype.normalizeCommandFunc = function (cmdFunc) {
28551        var self = this;
28552        var cmd = cmdFunc;
28553        if (typeof cmd === 'string') {
28554          return function () {
28555            self.editor.execCommand(cmd, false, null);
28556          };
28557        } else if (Tools.isArray(cmd)) {
28558          return function () {
28559            self.editor.execCommand(cmd[0], cmd[1], cmd[2]);
28560          };
28561        } else {
28562          return cmd;
28563        }
28564      };
28565      Shortcuts.prototype.createShortcut = function (pattern, desc, cmdFunc, scope) {
28566        var shortcuts = Tools.map(explode$1(pattern, '>'), parseShortcut);
28567        shortcuts[shortcuts.length - 1] = Tools.extend(shortcuts[shortcuts.length - 1], {
28568          func: cmdFunc,
28569          scope: scope || this.editor
28570        });
28571        return Tools.extend(shortcuts[0], {
28572          desc: this.editor.translate(desc),
28573          subpatterns: shortcuts.slice(1)
28574        });
28575      };
28576      Shortcuts.prototype.hasModifier = function (e) {
28577        return e.altKey || e.ctrlKey || e.metaKey;
28578      };
28579      Shortcuts.prototype.isFunctionKey = function (e) {
28580        return e.type === 'keydown' && e.keyCode >= 112 && e.keyCode <= 123;
28581      };
28582      Shortcuts.prototype.matchShortcut = function (e, shortcut) {
28583        if (!shortcut) {
28584          return false;
28585        }
28586        if (shortcut.ctrl !== e.ctrlKey || shortcut.meta !== e.metaKey) {
28587          return false;
28588        }
28589        if (shortcut.alt !== e.altKey || shortcut.shift !== e.shiftKey) {
28590          return false;
28591        }
28592        if (e.keyCode === shortcut.keyCode || e.charCode && e.charCode === shortcut.charCode) {
28593          e.preventDefault();
28594          return true;
28595        }
28596        return false;
28597      };
28598      Shortcuts.prototype.executeShortcutAction = function (shortcut) {
28599        return shortcut.func ? shortcut.func.call(shortcut.scope) : null;
28600      };
28601      return Shortcuts;
28602    }();
28603
28604    var create$3 = function () {
28605      var buttons = {};
28606      var menuItems = {};
28607      var popups = {};
28608      var icons = {};
28609      var contextMenus = {};
28610      var contextToolbars = {};
28611      var sidebars = {};
28612      var add = function (collection, type) {
28613        return function (name, spec) {
28614          return collection[name.toLowerCase()] = __assign(__assign({}, spec), { type: type });
28615        };
28616      };
28617      var addIcon = function (name, svgData) {
28618        return icons[name.toLowerCase()] = svgData;
28619      };
28620      return {
28621        addButton: add(buttons, 'button'),
28622        addGroupToolbarButton: add(buttons, 'grouptoolbarbutton'),
28623        addToggleButton: add(buttons, 'togglebutton'),
28624        addMenuButton: add(buttons, 'menubutton'),
28625        addSplitButton: add(buttons, 'splitbutton'),
28626        addMenuItem: add(menuItems, 'menuitem'),
28627        addNestedMenuItem: add(menuItems, 'nestedmenuitem'),
28628        addToggleMenuItem: add(menuItems, 'togglemenuitem'),
28629        addAutocompleter: add(popups, 'autocompleter'),
28630        addContextMenu: add(contextMenus, 'contextmenu'),
28631        addContextToolbar: add(contextToolbars, 'contexttoolbar'),
28632        addContextForm: add(contextToolbars, 'contextform'),
28633        addSidebar: add(sidebars, 'sidebar'),
28634        addIcon: addIcon,
28635        getAll: function () {
28636          return {
28637            buttons: buttons,
28638            menuItems: menuItems,
28639            icons: icons,
28640            popups: popups,
28641            contextMenus: contextMenus,
28642            contextToolbars: contextToolbars,
28643            sidebars: sidebars
28644          };
28645        }
28646      };
28647    };
28648
28649    var registry = function () {
28650      var bridge = create$3();
28651      return {
28652        addAutocompleter: bridge.addAutocompleter,
28653        addButton: bridge.addButton,
28654        addContextForm: bridge.addContextForm,
28655        addContextMenu: bridge.addContextMenu,
28656        addContextToolbar: bridge.addContextToolbar,
28657        addIcon: bridge.addIcon,
28658        addMenuButton: bridge.addMenuButton,
28659        addMenuItem: bridge.addMenuItem,
28660        addNestedMenuItem: bridge.addNestedMenuItem,
28661        addSidebar: bridge.addSidebar,
28662        addSplitButton: bridge.addSplitButton,
28663        addToggleButton: bridge.addToggleButton,
28664        addGroupToolbarButton: bridge.addGroupToolbarButton,
28665        addToggleMenuItem: bridge.addToggleMenuItem,
28666        getAll: bridge.getAll
28667      };
28668    };
28669
28670    var DOM$1 = DOMUtils.DOM;
28671    var extend$3 = Tools.extend, each$2 = Tools.each;
28672    var resolve = Tools.resolve;
28673    var ie = Env.ie;
28674    var Editor = function () {
28675      function Editor(id, settings, editorManager) {
28676        var _this = this;
28677        this.plugins = {};
28678        this.contentCSS = [];
28679        this.contentStyles = [];
28680        this.loadedCSS = {};
28681        this.isNotDirty = false;
28682        this.editorManager = editorManager;
28683        this.documentBaseUrl = editorManager.documentBaseURL;
28684        extend$3(this, EditorObservable);
28685        this.settings = getEditorSettings(this, id, this.documentBaseUrl, editorManager.defaultSettings, settings);
28686        if (this.settings.suffix) {
28687          editorManager.suffix = this.settings.suffix;
28688        }
28689        this.suffix = editorManager.suffix;
28690        if (this.settings.base_url) {
28691          editorManager._setBaseUrl(this.settings.base_url);
28692        }
28693        this.baseUri = editorManager.baseURI;
28694        if (this.settings.referrer_policy) {
28695          ScriptLoader.ScriptLoader._setReferrerPolicy(this.settings.referrer_policy);
28696          DOMUtils.DOM.styleSheetLoader._setReferrerPolicy(this.settings.referrer_policy);
28697        }
28698        AddOnManager.languageLoad = this.settings.language_load;
28699        AddOnManager.baseURL = editorManager.baseURL;
28700        this.id = id;
28701        this.setDirty(false);
28702        this.documentBaseURI = new URI(this.settings.document_base_url, { base_uri: this.baseUri });
28703        this.baseURI = this.baseUri;
28704        this.inline = !!this.settings.inline;
28705        this.shortcuts = new Shortcuts(this);
28706        this.editorCommands = new EditorCommands(this);
28707        if (this.settings.cache_suffix) {
28708          Env.cacheSuffix = this.settings.cache_suffix.replace(/^[\?\&]+/, '');
28709        }
28710        this.ui = {
28711          registry: registry(),
28712          styleSheetLoader: undefined,
28713          show: noop,
28714          hide: noop,
28715          enable: noop,
28716          disable: noop,
28717          isDisabled: never
28718        };
28719        var self = this;
28720        var modeInstance = create$4(self);
28721        this.mode = modeInstance;
28722        this.setMode = modeInstance.set;
28723        editorManager.fire('SetupEditor', { editor: this });
28724        this.execCallback('setup', this);
28725        this.$ = DomQuery.overrideDefaults(function () {
28726          return {
28727            context: _this.inline ? _this.getBody() : _this.getDoc(),
28728            element: _this.getBody()
28729          };
28730        });
28731      }
28732      Editor.prototype.render = function () {
28733        render(this);
28734      };
28735      Editor.prototype.focus = function (skipFocus) {
28736        this.execCommand('mceFocus', false, skipFocus);
28737      };
28738      Editor.prototype.hasFocus = function () {
28739        return hasFocus(this);
28740      };
28741      Editor.prototype.execCallback = function (name) {
28742        var x = [];
28743        for (var _i = 1; _i < arguments.length; _i++) {
28744          x[_i - 1] = arguments[_i];
28745        }
28746        var self = this;
28747        var callback = self.settings[name], scope;
28748        if (!callback) {
28749          return;
28750        }
28751        if (self.callbackLookup && (scope = self.callbackLookup[name])) {
28752          callback = scope.func;
28753          scope = scope.scope;
28754        }
28755        if (typeof callback === 'string') {
28756          scope = callback.replace(/\.\w+$/, '');
28757          scope = scope ? resolve(scope) : 0;
28758          callback = resolve(callback);
28759          self.callbackLookup = self.callbackLookup || {};
28760          self.callbackLookup[name] = {
28761            func: callback,
28762            scope: scope
28763          };
28764        }
28765        return callback.apply(scope || self, x);
28766      };
28767      Editor.prototype.translate = function (text) {
28768        return I18n.translate(text);
28769      };
28770      Editor.prototype.getParam = function (name, defaultVal, type) {
28771        return getParam(this, name, defaultVal, type);
28772      };
28773      Editor.prototype.hasPlugin = function (name, loaded) {
28774        var hasPlugin = contains$3(getPlugins(this).split(/[ ,]/), name);
28775        if (hasPlugin) {
28776          return loaded ? PluginManager.get(name) !== undefined : true;
28777        } else {
28778          return false;
28779        }
28780      };
28781      Editor.prototype.nodeChanged = function (args) {
28782        this._nodeChangeDispatcher.nodeChanged(args);
28783      };
28784      Editor.prototype.addCommand = function (name, callback, scope) {
28785        this.editorCommands.addCommand(name, callback, scope);
28786      };
28787      Editor.prototype.addQueryStateHandler = function (name, callback, scope) {
28788        this.editorCommands.addQueryStateHandler(name, callback, scope);
28789      };
28790      Editor.prototype.addQueryValueHandler = function (name, callback, scope) {
28791        this.editorCommands.addQueryValueHandler(name, callback, scope);
28792      };
28793      Editor.prototype.addShortcut = function (pattern, desc, cmdFunc, scope) {
28794        this.shortcuts.add(pattern, desc, cmdFunc, scope);
28795      };
28796      Editor.prototype.execCommand = function (cmd, ui, value, args
28796) {
28797        return this.editorCommands.execCommand(cmd, ui, value, args);
28798      };
28799      Editor.prototype.queryCommandState = function (cmd) {
28800        return this.editorCommands.queryCommandState(cmd);
28801      };
28802      Editor.prototype.queryCommandValue = function (cmd) {
28803        return this.editorCommands.queryCommandValue(cmd);
28804      };
28805      Editor.prototype.queryCommandSupported = function (cmd) {
28806        return this.editorCommands.queryCommandSupported(cmd);
28807      };
28808      Editor.prototype.show = function () {
28809        var self = this;
28810        if (self.hidden) {
28811          self.hidden = false;
28812          if (self.inline) {
28813            self.getBody().contentEditable = 'true';
28814          } else {
28815            DOM$1.show(self.getContainer());
28816            DOM$1.hide(self.id);
28817          }
28818          self.load();
28819          self.fire('show');
28820        }
28821      };
28822      Editor.prototype.hide = function () {
28823        var self = this, doc = self.getDoc();
28824        if (!self.hidden) {
28825          if (ie && doc && !self.inline) {
28826            doc.execCommand('SelectAll');
28827          }
28828          self.save();
28829          if (self.inline) {
28830            self.getBody().contentEditable = 'false';
28831            if (self === self.editorManager.focusedEditor) {
28832              self.editorManager.focusedEditor = null;
28833            }
28834          } else {
28835            DOM$1.hide(self.getContainer());
28836            DOM$1.setStyle(self.id, 'display', self.orgDisplay);
28837          }
28838          self.hidden = true;
28839          self.fire('hide');
28840        }
28841      };
28842      Editor.prototype.isHidden = function () {
28843        return !!this.hidden;
28844      };
28845      Editor.prototype.setProgressState = function (state, time) {
28846        this.fire('ProgressState', {
28847          state: state,
28848          time: time
28849        });
28850      };
28851      Editor.prototype.load = function (args) {
28852        var self = this;
28853        var elm = self.getElement(), html;
28854        if (self.removed) {
28855          return '';
28856        }
28857        if (elm) {
28858          args = args || {};
28859          args.load = true;
28860          var value = isTextareaOrInput(elm) ? elm.value : elm.innerHTML;
28861          html = self.setContent(value, args);
28862          args.element = elm;
28863          if (!args.no_events) {
28864            self.fire('LoadContent', args);
28865          }
28866          args.element = elm = null;
28867          return html;
28868        }
28869      };
28870      Editor.prototype.save = function (args) {
28871        var self = this;
28872        var elm = self.getElement(), html, form;
28873        if (!elm || !self.initialized || self.removed) {
28874          return;
28875        }
28876        args = args || {};
28877        args.save = true;
28878        args.element = elm;
28879        html = args.content = self.getContent(args);
28880        if (!args.no_events) {
28881          self.fire('SaveContent', args);
28882        }
28883        if (args.format === 'raw') {
28884          self.fire('RawSaveContent', args);
28885        }
28886        html = args.content;
28887        if (!isTextareaOrInput(elm)) {
28888          if (args.is_removing || !self.inline) {
28889            elm.innerHTML = html;
28890          }
28891          if (form = DOM$1.getParent(self.id, 'form')) {
28892            each$2(form.elements, function (elm) {
28893              if (elm.name === self.id) {
28894                elm.value = html;
28895                return false;
28896              }
28897            });
28898          }
28899        } else {
28900          elm.value = html;
28901        }
28902        args.element = elm = null;
28903        if (args.set_dirty !== false) {
28904          self.setDirty(false);
28905        }
28906        return html;
28907      };
28908      Editor.prototype.setContent = function (content, args) {
28909        return setContent(this, content, args);
28910      };
28911      Editor.prototype.getContent = function (args) {
28912        return getContent(this, args);
28913      };
28914      Editor.prototype.insertContent = function (content, args) {
28915        if (args) {
28916          content = extend$3({ content: content }, args);
28917        }
28918        this.execCommand('mceInsertContent', false, content);
28919      };
28920      Editor.prototype.resetContent = function (initialContent) {
28921        if (initialContent === undefined) {
28922          setContent(this, this.startContent, { format: 'raw' });
28923        } else {
28924          setContent(this, initialContent);
28925        }
28926        this.undoManager.reset();
28927        this.setDirty(false);
28928        this.nodeChanged();
28929      };
28930      Editor.prototype.isDirty = function () {
28931        return !this.isNotDirty;
28932      };
28933      Editor.prototype.setDirty = function (state) {
28934        var oldState = !this.isNotDirty;
28935        this.isNotDirty = !state;
28936        if (state && state !== oldState) {
28937          this.fire('dirty');
28938        }
28939      };
28940      Editor.prototype.getContainer = function () {
28941        var self = this;
28942        if (!self.container) {
28943          self.container = DOM$1.get(self.editorContainer || self.id + '_parent');
28944        }
28945        return self.container;
28946      };
28947      Editor.prototype.getContentAreaContainer = function () {
28948        return this.contentAreaContainer;
28949      };
28950      Editor.prototype.getElement = function () {
28951        if (!this.targetElm) {
28952          this.targetElm = DOM$1.get(this.id);
28953        }
28954        return this.targetElm;
28955      };
28956      Editor.prototype.getWin = function () {
28957        var self = this;
28958        var elm;
28959        if (!self.contentWindow) {
28960          elm = self.iframeElement;
28961          if (elm) {
28962            self.contentWindow = elm.contentWindow;
28963          }
28964        }
28965        return self.contentWindow;
28966      };
28967      Editor.prototype.getDoc = function () {
28968        var self = this;
28969        var win;
28970        if (!self.contentDocument) {
28971          win = self.getWin();
28972          if (win) {
28973            self.contentDocument = win.document;
28974          }
28975        }
28976        return self.contentDocument;
28977      };
28978      Editor.prototype.getBody = function () {
28979        var doc = this.getDoc();
28980        return this.bodyElement || (doc ? doc.body : null);
28981      };
28982      Editor.prototype.convertURL = function (url, name, elm) {
28983        var self = this, settings = self.settings;
28984        if (settings.urlconverter_callback) {
28985          return self.execCallback('urlconverter_callback', url, elm, true, name);
28986        }
28987        if (!settings.convert_urls || elm && elm.nodeName === 'LINK' || url.indexOf('file:') === 0 || url.length === 0) {
28988          return url;
28989        }
28990        if (settings.relative_urls) {
28991          return self.documentBaseURI.toRelative(url);
28992        }
28993        url = self.documentBaseURI.toAbsolute(url, settings.remove_script_host);
28994        return url;
28995      };
28996      Editor.prototype.addVisual = function (elm) {
28997        addVisual(this, elm);
28998      };
28999      Editor.prototype.remove = function () {
29000        remove(this);
29001      };
29002      Editor.prototype.destroy = function (automatic) {
29003        destroy(this, automatic);
29004      };
29005      Editor.prototype.uploadImages = function (callback) {
29006        return this.editorUpload.uploadImages(callback);
29007      };
29008      Editor.prototype._scanForImages = function () {
29009        return this.editorUpload.scanForImages();
29010      };
29011      Editor.prototype.addButton = function () {
29012        throw new Error('editor.addButton has been removed in tinymce 5x, use editor.ui.registry.addButton or editor.ui.registry.addToggleButton or editor.ui.registry.addSplitButton instead');
29013      };
29014      Editor.prototype.addSidebar = function () {
29015        throw new Error('editor.addSidebar has been removed in tinymce 5x, use editor.ui.registry.addSidebar instead');
29016      };
29017      Editor.prototype.addMenuItem = function () {
29018        throw new Error('editor.addMenuItem has been removed in tinymce 5x, use editor.ui.registry.addMenuItem instead');
29019      };
29020      Editor.prototype.addContextToolbar = function () {
29021        throw new Error('editor.addContextToolbar has been removed in tinymce 5x, use editor.ui.registry.addContextToolbar instead');
29022      };
29023      return Editor;
29024    }();
29025
29026    var DOM = DOMUtils.DOM;
29027    var explode = Tools.explode, each$1 = Tools.each, extend$2 = Tools.extend;
29028    var instanceCounter = 0, boundGlobalEvents = false;
29029    var beforeUnloadDelegate;
29030    var legacyEditors = [];
29031    var editors = [];
29032    var isValidLegacyKey = function (id) {
29033      return id !== 'length';
29034    };
29035    var globalEventDelegate = function (e) {
29036      var type = e.type;
29037      each$1(EditorManager.get(), function (editor) {
29038        switch (type) {
29039        case 'scroll':
29040          editor.fire('ScrollWindow', e);
29041          break;
29042        case 'resize':
29043          editor.fire('ResizeWindow', e);
29044          break;
29045        }
29046      });
29047    };
29048    var toggleGlobalEvents = function (state) {
29049      if (state !== boundGlobalEvents) {
29050        if (state) {
29051          DomQuery(window).on('resize scroll', globalEventDelegate);
29052        } else {
29053          DomQuery(window).off('resize scroll', globalEventDelegate);
29054        }
29055        boundGlobalEvents = state;
29056      }
29057    };
29058    var removeEditorFromList = function (targetEditor) {
29059      var oldEditors = editors;
29060      delete legacyEditors[targetEditor.id];
29061      for (var i = 0; i < legacyEditors.length; i++) {
29062        if (legacyEditors[i] === targetEditor) {
29063          legacyEditors.splice(i, 1);
29064          break;
29065        }
29066      }
29067      editors = filter$4(editors, function (editor) {
29068        return targetEditor !== editor;
29069      });
29070      if (EditorManager.activeEditor === targetEditor) {
29071        EditorManager.activeEditor = editors.length > 0 ? editors[0] : null;
29072      }
29073      if (EditorManager.focusedEditor === targetEditor) {
29074        EditorManager.focusedEditor = null;
29075      }
29076      return oldEditors.length !== editors.length;
29077    };
29078    var purgeDestroyedEditor = function (editor) {
29079      if (editor && editor.initialized && !(editor.getContainer() || editor.getBody()).parentNode) {
29080        removeEditorFromList(editor);
29081        editor.unbindAllNativeEvents();
29082        editor.destroy(true);
29083        editor.removed = true;
29084        editor = null;
29085      }
29086      return editor;
29087    };
29088    var isQuirksMode = document.compatMode !== 'CSS1Compat';
29089    var EditorManager = __assign(__assign({}, Observable), {
29090      baseURI: null,
29091      baseURL: null,
29092      defaultSettings: {},
29093      documentBaseURL: null,
29094      suffix: null,
29095      $: DomQuery,
29096      majorVersion: '5',
29097      minorVersion: '10.9',
29098      releaseDate: '2023-11-15',
29099      editors: legacyEditors,
29100      i18n: I18n,
29101      activeEditor: null,
29102      focusedEditor: null,
29103      settings: {},
29104      setup: function () {
29105        var self = this;
29106        var baseURL, documentBaseURL, suffix = '';
29107        documentBaseURL = URI.getDocumentBaseUrl(document.location);
29108        if (/^[^:]+:\/\/\/?[^\/]+\//.test(documentBaseURL)) {
29109          documentBaseURL = documentBaseURL.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');
29110          if (!/[\/\\]$/.test(documentBaseURL)) {
29111            documentBaseURL += '/';
29112          }
29113        }
29114        var preInit = window.tinymce || window.tinyMCEPreInit;
29115        if (preInit) {
29116          baseURL = preInit.base || preInit.baseURL;
29117          suffix = preInit.suffix;
29118        } else {
29119          var scripts = document.getElementsByTagName('script');
29120          for (var i = 0; i < scripts.length; i++) {
29121            var src = scripts[i].src || '';
29122            if (src === '') {
29123              continue;
29124            }
29125            var srcScript = src.substring(src.lastIndexOf('/'));
29126            if (/tinymce(\.full|\.jquery|)(\.min|\.dev|)\.js/.test(src)) {
29127              if (srcScript.indexOf('.min') !== -1) {
29128                suffix = '.min';
29129              }
29130              baseURL = src.substring(0, src.lastIndexOf('/'));
29131              break;
29132            }
29133          }
29134          if (!baseURL && document.currentScript) {
29135            var src = document.currentScript.src;
29136            if (src.indexOf('.min') !== -1) {
29137              suffix = '.min';
29138            }
29139            baseURL = src.substring(0, src.lastIndexOf('/'));
29140          }
29141        }
29142        self.baseURL = new URI(documentBaseURL).toAbsolute(baseURL);
29143        self.documentBaseURL = documentBaseURL;
29144        self.baseURI = new URI(self.baseURL);
29145        self.suffix = suffix;
29146        setup$l(self);
29147      },
29148      overrideDefaults: function (defaultSettings) {
29149        var baseUrl = defaultSettings.base_url;
29150        if (baseUrl) {
29151          this._setBaseUrl(baseUrl);
29152        }
29153        var suffix = defaultSettings.suffix;
29154        if (defaultSettings.suffix) {
29155          this.suffix = suffix;
29156        }
29157        this.defaultSettings = defaultSettings;
29158        var pluginBaseUrls = defaultSettings.plugin_base_urls;
29159        if (pluginBaseUrls !== undefined) {
29160          each$j(pluginBaseUrls, function (pluginBaseUrl, pluginName) {
29161            AddOnManager.PluginManager.urls[pluginName] = pluginBaseUrl;
29162          });
29163        }
29164      },
29165      init: function (settings) {
29166        var self = this;
29167        var result;
29168        var invalidInlineTargets = Tools.makeMap('area base basefont br col frame hr img input isindex link meta param embed source wbr track ' + 'colgroup option table tbody tfoot thead tr th td script noscript style textarea video audio iframe object menu', ' ');
29169        var isInvalidInlineTarget = function (settings, elm) {
29170          return settings.inline && elm.tagName.toLowerCase() in invali
29170dInlineTargets;
29171        };
29172        var createId = function (elm) {
29173          var id = elm.id;
29174          if (!id) {
29175            id = get$9(elm, 'name').filter(function (name) {
29176              return !DOM.get(name);
29177            }).getOrThunk(DOM.uniqueId);
29178            elm.setAttribute('id', id);
29179          }
29180          return id;
29181        };
29182        var execCallback = function (name) {
29183          var callback = settings[name];
29184          if (!callback) {
29185            return;
29186          }
29187          return callback.apply(self, []);
29188        };
29189        var hasClass = function (elm, className) {
29190          return className.constructor === RegExp ? className.test(elm.className) : DOM.hasClass(elm, className);
29191        };
29192        var findTargets = function (settings) {
29193          var targets = [];
29194          if (Env.browser.isIE() && Env.browser.version.major < 11) {
29195            initError('TinyMCE does not support the browser you are using. For a list of supported' + ' browsers please see: https://www.tinymce.com/docs/get-started/system-requirements/');
29196            return [];
29197          } else if (isQuirksMode) {
29198            initError('Failed to initialize the editor as the document is not in standards mode. ' + 'TinyMCE requires standards mode.');
29199            return [];
29200          }
29201          if (settings.types) {
29202            each$1(settings.types, function (type) {
29203              targets = targets.concat(DOM.select(type.selector));
29204            });
29205            return targets;
29206          } else if (settings.selector) {
29207            return DOM.select(settings.selector);
29208          } else if (settings.target) {
29209            return [settings.target];
29210          }
29211          switch (settings.mode) {
29212          case 'exact':
29213            var l = settings.elements || '';
29214            if (l.length > 0) {
29215              each$1(explode(l), function (id) {
29216                var elm = DOM.get(id);
29217                if (elm) {
29218                  targets.push(elm);
29219                } else {
29220                  each$1(document.forms, function (f) {
29221                    each$1(f.elements, function (e) {
29222                      if (e.name === id) {
29223                        id = 'mce_editor_' + instanceCounter++;
29224                        DOM.setAttrib(e, 'id', id);
29225                        targets.push(e);
29226                      }
29227                    });
29228                  });
29229                }
29230              });
29231            }
29232            break;
29233          case 'textareas':
29234          case 'specific_textareas':
29235            each$1(DOM.select('textarea'), function (elm) {
29236              if (settings.editor_deselector && hasClass(elm, settings.editor_deselector)) {
29237                return;
29238              }
29239              if (!settings.editor_selector || hasClass(elm, settings.editor_selector)) {
29240                targets.push(elm);
29241              }
29242            });
29243            break;
29244          }
29245          return targets;
29246        };
29247        var provideResults = function (editors) {
29248          result = editors;
29249        };
29250        var initEditors = function () {
29251          var initCount = 0;
29252          var editors = [];
29253          var targets;
29254          var createEditor = function (id, settings, targetElm) {
29255            var editor = new Editor(id, settings, self);
29256            editors.push(editor);
29257            editor.on('init', function () {
29258              if (++initCount === targets.length) {
29259                provideResults(editors);
29260              }
29261            });
29262            editor.targetElm = editor.targetElm || targetElm;
29263            editor.render();
29264          };
29265          DOM.unbind(window, 'ready', initEditors);
29266          execCallback('onpageload');
29267          targets = DomQuery.unique(findTargets(settings));
29268          if (settings.types) {
29269            each$1(settings.types, function (type) {
29270              Tools.each(targets, function (elm) {
29271                if (DOM.is(elm, type.selector)) {
29272                  createEditor(createId(elm), extend$2({}, settings, type), elm);
29273                  return false;
29274                }
29275                return true;
29276              });
29277            });
29278            return;
29279          }
29280          Tools.each(targets, function (elm) {
29281            purgeDestroyedEditor(self.get(elm.id));
29282          });
29283          targets = Tools.grep(targets, function (elm) {
29284            return !self.get(elm.id);
29285          });
29286          if (targets.length === 0) {
29287            provideResults([]);
29288          } else {
29289            each$1(targets, function (elm) {
29290              if (isInvalidInlineTarget(settings, elm)) {
29291                initError('Could not initialize inline editor on invalid inline target element', elm);
29292              } else {
29293                createEditor(createId(elm), settings, elm);
29294              }
29295            });
29296          }
29297        };
29298        self.settings = settings;
29299        DOM.bind(window, 'ready', initEditors);
29300        return new promiseObj(function (resolve) {
29301          if (result) {
29302            resolve(result);
29303          } else {
29304            provideResults = function (editors) {
29305              resolve(editors);
29306            };
29307          }
29308        });
29309      },
29310      get: function (id) {
29311        if (arguments.length === 0) {
29312          return editors.slice(0);
29313        } else if (isString$1(id)) {
29314          return find$3(editors, function (editor) {
29315            return editor.id === id;
29316          }).getOr(null);
29317        } else if (isNumber(id)) {
29318          return editors[id] ? editors[id] : null;
29319        } else {
29320          return null;
29321        }
29322      },
29323      add: function (editor) {
29324        var self = this;
29325        var existingEditor = legacyEditors[editor.id];
29326        if (existingEditor === editor) {
29327          return editor;
29328        }
29329        if (self.get(editor.id) === null) {
29330          if (isValidLegacyKey(editor.id)) {
29331            legacyEditors[editor.id] = editor;
29332          }
29333          legacyEditors.push(editor);
29334          editors.push(editor);
29335        }
29336        toggleGlobalEvents(true);
29337        self.activeEditor = editor;
29338        self.fire('AddEditor', { editor: editor });
29339        if (!beforeUnloadDelegate) {
29340          beforeUnloadDelegate = function (e) {
29341            var event = self.fire('BeforeUnload');
29342            if (event.returnValue) {
29343              e.preventDefault();
29344              e.returnValue = event.returnValue;
29345              return event.returnValue;
29346            }
29347          };
29348          window.addEventListener('beforeunload', beforeUnloadDelegate);
29349        }
29350        return editor;
29351      },
29352      createEditor: function (id, settings) {
29353        return this.add(new Editor(id, settings, this));
29354      },
29355      remove: function (selector) {
29356        var self = this;
29357        var i, editor;
29358        if (!selector) {
29359          for (i = editors.length - 1; i >= 0; i--) {
29360            self.remove(editors[i]);
29361          }
29362          return;
29363        }
29364        if (isString$1(selector)) {
29365          each$1(DOM.select(selector), function (elm) {
29366            editor = self.get(elm.id);
29367            if (editor) {
29368              self.remove(editor);
29369            }
29370          });
29371          return;
29372        }
29373        editor = selector;
29374        if (isNull(self.get(editor.id))) {
29375          return null;
29376        }
29377        if (removeEditorFromList(editor)) {
29378          self.fire('RemoveEditor', { editor: editor });
29379        }
29380        if (editors.length === 0) {
29381          window.removeEventListener('beforeunload', beforeUnloadDelegate);
29382        }
29383        editor.remove();
29384        toggleGlobalEvents(editors.length > 0);
29385        return editor;
29386      },
29387      execCommand: function (cmd, ui, value) {
29388        var self = this, editor = self.get(value);
29389        switch (cmd) {
29390        case 'mceAddEditor':
29391          if (!self.get(value)) {
29392            new Editor(value, self.settings, self).render();
29393          }
29394          return true;
29395        case 'mceRemoveEditor':
29396          if (editor) {
29397            editor.remove();
29398          }
29399          return true;
29400        case 'mceToggleEditor':
29401          if (!editor) {
29402            self.execCommand('mceAddEditor', false, value);
29403            return true;
29404          }
29405          if (editor.isHidden()) {
29406            editor.show();
29407          } else {
29408            editor.hide();
29409          }
29410          return true;
29411        }
29412        if (self.activeEditor) {
29413          return self.activeEditor.execCommand(cmd, ui, value);
29414        }
29415        return false;
29416      },
29417      triggerSave: function () {
29418        each$1(editors, function (editor) {
29419          editor.save();
29420        });
29421      },
29422      addI18n: function (code, items) {
29423        I18n.add(code, items);
29424      },
29425      translate: function (text) {
29426        return I18n.translate(text);
29427      },
29428      setActive: function (editor) {
29429        var activeEditor = this.activeEditor;
29430        if (this.activeEditor !== editor) {
29431          if (activeEditor) {
29432            activeEditor.fire('deactivate', { relatedTarget: editor });
29433          }
29434          editor.fire('activate', { relatedTarget: activeEditor });
29435        }
29436        this.activeEditor = editor;
29437      },
29438      _setBaseUrl: function (baseUrl) {
29439        this.baseURL = new URI(this.documentBaseURL).toAbsolute(baseUrl.replace(/\/+$/, ''));
29440        this.baseURI = new URI(this.baseURL);
29441      }
29442    });
29443    EditorManager.setup();
29444
29445    var min$1 = Math.min, max$1 = Math.max, round$1 = Math.round;
29446    var relativePosition = function (rect, targetRect, rel) {
29447      var x = targetRect.x;
29448      var y = targetRect.y;
29449      var w = rect.w;
29450      var h = rect.h;
29451      var targetW = targetRect.w;
29452      var targetH = targetRect.h;
29453      var relChars = (rel || '').split('');
29454      if (relChars[0] === 'b') {
29455        y += targetH;
29456      }
29457      if (relChars[1] === 'r') {
29458        x += targetW;
29459      }
29460      if (relChars[0] === 'c') {
29461        y += round$1(targetH / 2);
29462      }
29463      if (relChars[1] === 'c') {
29464        x += round$1(targetW / 2);
29465      }
29466      if (relChars[3] === 'b') {
29467        y -= h;
29468      }
29469      if (relChars[4] === 'r') {
29470        x -= w;
29471      }
29472      if (relChars[3] === 'c') {
29473        y -= round$1(h / 2);
29474      }
29475      if (relChars[4] === 'c') {
29476        x -= round$1(w / 2);
29477      }
29478      return create$2(x, y, w, h);
29479    };
29480    var findBestRelativePosition = function (rect, targetRect, constrainRect, rels) {
29481      var pos, i;
29482      for (i = 0; i < rels.length; i++) {
29483        pos = relativePosition(rect, targetRect, rels[i]);
29484        if (pos.x >= constrainRect.x && pos.x + pos.w <= constrainRect.w + constrainRect.x && pos.y >= constrainRect.y && pos.y + pos.h <= constrainRect.h + constrainRect.y) {
29485          return rels[i];
29486        }
29487      }
29488      return null;
29489    };
29490    var inflate = function (rect, w, h) {
29491      return create$2(rect.x - w, rect.y - h, rect.w + w * 2, rect.h + h * 2);
29492    };
29493    var intersect = function (rect, cropRect) {
29494      var x1 = max$1(rect.x, cropRect.x);
29495      var y1 = max$1(rect.y, cropRect.y);
29496      var x2 = min$1(rect.x + rect.w, cropRect.x + cropRect.w);
29497      var y2 = min$1(rect.y + rect.h, cropRect.y + cropRect.h);
29498      if (x2 - x1 < 0 || y2 - y1 < 0) {
29499        return null;
29500      }
29501      return create$2(x1, y1, x2 - x1, y2 - y1);
29502    };
29503    var clamp = function (rect, clampRect, fixedSize) {
29504      var x1 = rect.x;
29505      var y1 = rect.y;
29506      var x2 = rect.x + rect.w;
29507      var y2 = rect.y + rect.h;
29508      var cx2 = clampRect.x + clampRect.w;
29509      var cy2 = clampRect.y + clampRect.h;
29510      var underflowX1 = max$1(0, clampRect.x - x1);
29511      var underflowY1 = max$1(0, clampRect.y - y1);
29512      var overflowX2 = max$1(0, x2 - cx2);
29513      var overflowY2 = max$1(0, y2 - cy2);
29514      x1 += underflowX1;
29515      y1 += underflowY1;
29516      if (fixedSize) {
29517        x2 += underflowX1;
29518        y2 += underflowY1;
29519        x1 -= overflowX2;
29520        y1 -= overflowY2;
29521      }
29522      x2 -= overflowX2;
29523      y2 -= overflowY2;
29524      return create$2(x1, y1, x2 - x1, y2 - y1);
29525    };
29526    var create$2 = function (x, y, w, h) {
29527      return {
29528        x: x,
29529        y: y,
29530        w: w,
29531        h: h
29532      };
29533    };
29534    var fromClientRect = function (clientRect) {
29535      return create$2(clientRect.left, clientRect.top, clientRect.width, clientRect.height);
29536    };
29537    var Rect = {
29538      inflate: inflate,
29539      relativePosition: relativePosition,
29540      findBestRelativePosition: findBestRelativePosition,
29541      intersect: intersect,
29542      clamp: clamp,
29543      create: create$2,
29544      fromClientRect: fromClientRect
29545    };
29546
29547    var awaiter = function (resolveCb, rejectCb, timeout) {
29548      if (timeout === void 0) {
29549        timeout = 1000;
29550      }
29551      var done = false;
29552      var timer = null;
29553      var complete = function (completer) {
29554        return function () {
29555          var args = [];
29556          for (var _i = 0; _i < arguments.length; _i++) {
29557            args[_i] = arguments[_i];
29558          }
29559          if (!done) {
29560            done = true;
29561            if (timer !== null) {
29562              clearTimeout(timer);
29563              timer = null;
29564            }
29565            completer.apply(null, args);
29566          }
29567        };
29568      };
29569      var resolve = complete(resolveCb);
29570      var reject = complete(rejectCb);
29571      var start = function () {
29572        var args = [];
29573        for (var _i = 0; _i < arguments.length; _i++) {
29574          args[_i] = arguments[_i];
29575        }
29576        if (!done && timer === null) {
29577          timer = setTimeout(function () {
29578            return reject.apply(null, args);
29579          }, timeout);
29580        }
29581      };
29582      return {
29583        start: start,
29584        resolve: resolve,
29585        reject: reject
29586      };
29587    };
29588    var create$1 = function () {
29589      var tasks = {};
29590      var resultFns = {};
29591      var load = function (id, url) {
29592        var loadErrMsg = 'Script at URL "' + url + '" failed to load';
29593        var runErrMsg = 'Script at URL "' + url + '" did not call `tinymce.Resource.add(\'' + id + '\', data)` within 1 second';
29594        if (tasks[id] !== undefined) {
29595          return tasks[id];
29596        } else {
29597          var task = new promiseObj(function (resolve, reject) {
29598            var waiter = awaiter(resolve, reject);
29599            resultFns[id] = waiter.resolve;
29600            ScriptLoader.ScriptLoader.loadScript(url, function () {
29601              return waiter.start(runErrMsg);
29602            }, function () {
29603              return waiter.reject(loadErrMsg);
29604            });
29605          });
29606          tasks[id] = task;
29607          return task;
29608        }
29609      };
29610      var add = function (id, data) {
29611        if (resultFns[id] !== undefined) {
29612          resultFns[id](data);
29613          delete resultFns[id];
29614        }
29615        tasks[id] = promiseObj.resolve(data);
29616      };
29617      return {
29618        load: load,
29619        add: add
29620      };
29621    };
29622    var Resource = create$1();
29623
29624    var each = Tools.each, extend$1 = Tools.extend;
29625    var extendClass, initializing;
29626    var Class = function () {
29627    };
29628    Class.extend = extendClass = function (props) {
29629      var self = this;
29630      var _super = self.prototype;
29631      var Class = function () {
29632        var i, mixins, mixin;
29633        var self = this;
29634        if (!initializing) {
29635          if (self.init) {
29636            self.init.apply(self, arguments);
29637          }
29638          mixins = self.Mixins;
29639          if (mixins) {
29640            i = mixins.length;
29641            while (i--) {
29642              mixin = mixins[i];
29643              if (mixin.init) {
29644                mixin.init.apply(self, arguments);
29645              }
29646            }
29647          }
29648        }
29649      };
29650      var dummy = function () {
29651        return this;
29652      };
29653      var createMethod = function (name, fn) {
29654        return function () {
29655          var self = this;
29656          var tmp = self._super;
29657          self._super = _super[name];
29658          var ret = fn.apply(self, arguments);
29659          self._super = tmp;
29660          return ret;
29661        };
29662      };
29663      initializing = true;
29664      var prototype = new self();
29665      initializing = false;
29666      if (props.Mixins) {
29667        each(props.Mixins, function (mixin) {
29668          for (var name_1 in mixin) {
29669            if (name_1 !== 'init') {
29670              props[name_1] = mixin[name_1];
29671            }
29672          }
29673        });
29674        if (_super.Mixins) {
29675          props.Mixins = _super.Mixins.concat(props.Mixins);
29676        }
29677      }
29678      if (props.Methods) {
29679        each(props.Methods.split(','), function (name) {
29680          props[name] = dummy;
29681        });
29682      }
29683      if (props.Properties) {
29684        each(props.Properties.split(','), function (name) {
29685          var fieldName = '_' + name;
29686          props[name] = function (value) {
29687            var self = this;
29688            if (value !== undefined) {
29689              self[fieldName] = value;
29690              return self;
29691            }
29692            return self[fieldName];
29693          };
29694        });
29695      }
29696      if (props.Statics) {
29697        each(props.Statics, function (func, name) {
29698          Class[name] = func;
29699        });
29700      }
29701      if (props.Defaults && _super.Defaults) {
29702        props.Defaults = extend$1({}, _super.Defaults, props.Defaults);
29703      }
29704      each$j(props, function (member, name) {
29705        if (typeof member === 'function' && _super[name]) {
29706          prototype[name] = createMethod(name, member);
29707        } else {
29708          prototype[name] = member;
29709        }
29710      });
29711      Class.prototype = prototype;
29712      Class.constructor = Class;
29713      Class.extend = extendClass;
29714      return Class;
29715    };
29716
29717    var min = Math.min, max = Math.max, round = Math.round;
29718    var Color = function (value) {
29719      var self = {};
29720      var r = 0, g = 0, b = 0;
29721      var rgb2hsv = function (r, g, b) {
29722        var h, s, v;
29723        h = 0;
29724        s = 0;
29725        v = 0;
29726        r = r / 255;
29727        g = g / 255;
29728        b = b / 255;
29729        var minRGB = min(r, min(g, b));
29730        var maxRGB = max(r, max(g, b));
29731        if (minRGB === maxRGB) {
29732          v = minRGB;
29733          return {
29734            h: 0,
29735            s: 0,
29736            v: v * 100
29737          };
29738        }
29739        var d = r === minRGB ? g - b : b === minRGB ? r - g : b - r;
29740        h = r === minRGB ? 3 : b === minRGB ? 1 : 5;
29741        h = 60 * (h - d / (maxRGB - minRGB));
29742        s = (maxRGB - minRGB) / maxRGB;
29743        v = maxRGB;
29744        return {
29745          h: round(h),
29746          s: round(s * 100),
29747          v: round(v * 100)
29748        };
29749      };
29750      var hsvToRgb = function (hue, saturation, brightness) {
29751        hue = (parseInt(hue, 10) || 0) % 360;
29752        saturation = parseInt(saturation, 10) / 100;
29753        brightness = parseInt(brightness, 10) / 100;
29754        saturation = max(0, min(saturation, 1));
29755        brightness = max(0, min(brightness, 1));
29756        if (saturation === 0) {
29757          r = g = b = round(255 * brightness);
29758          return;
29759        }
29760        var side = hue / 60;
29761        var chroma = brightness * saturation;
29762        var x = chroma * (1 - Math.abs(side % 2 - 1));
29763        var match = brightness - chroma;
29764        switch (Math.floor(side)) {
29765        case 0:
29766          r = chroma;
29767          g = x;
29768          b = 0;
29769          break;
29770        case 1:
29771          r = x;
29772          g = chroma;
29773          b = 0;
29774          break;
29775        case 2:
29776          r = 0;
29777          g = chroma;
29778          b = x;
29779          break;
29780        case 3:
29781          r = 0;
29782          g = x;
29783          b = chroma;
29784          break;
29785        case 4:
29786          r = x;
29787          g = 0;
29788          b = chroma;
29789          break;
29790        case 5:
29791          r = chroma;
29792          g = 0;
29793          b = x;
29794          break;
29795        default:
29796          r = g = b = 0;
29797        }
29798        r = round(255 * (r + match));
29799        g = round(255 * (g + match));
29800        b = round(255 * (b + match));
29801      };
29802      var toHex = function () {
29803        var hex = function (val) {
29804          val = parseInt(val, 10).toString(16);
29805          return val.length > 1 ? val : '0' + val;
29806        };
29807        return '#' + hex(r) + hex(g) + hex(b);
29808      };
29809      var toRgb = function () {
29810        return {
29811          r: r,
29812          g: g,
29813          b: b
29814        };
29815      };
29816      var toHsv = function () {
29817        return rgb2hsv(r, g, b);
29818      };
29819      var parse = function (value) {
29820        var matches;
29821        if (typeof value === 'object') {
29822          if ('r' in value) {
29823            r = value.r;
29824            g = value.g;
29825            b = value.b;
29826          } else if ('v' in value) {
29827            hsvToRgb(value.h, value.s, value.v);
29828          }
29829        } else {
29830          if (matches = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)[^\)]*\)/gi.exec(value)) {
29831            r = parseInt(matches[1], 10);
29832            g = parseInt(matches[2], 10);
29833            b = parseInt(matches[3], 10);
29834          } else if (matches = /#([0-F]{2})([0-F]{2})([0-F]{2})/gi.exec(value)) {
29835            r = parseInt(matches[1], 16);
29836            g = parseInt(matches[2], 16);
29837            b = parseInt(matches[3], 16);
29838          } else if (matches = /#([0-F])([0-F])([0-F])/gi.exec(value)) {
29839            r = parseInt(matches[1] + matches[1], 16);
29840            g = parseInt(matches[2] + matches[2], 16);
29841            b = parseInt(matches[3] + matches[3], 16);
29842          }
29843        }
29844        r = r < 0 ? 0 : r >
29844 255 ? 255 : r;
29845        g = g < 0 ? 0 : g > 255 ? 255 : g;
29846        b = b < 0 ? 0 : b > 255 ? 255 : b;
29847        return self;
29848      };
29849      if (value) {
29850        parse(value);
29851      }
29852      self.toRgb = toRgb;
29853      self.toHsv = toHsv;
29854      self.toHex = toHex;
29855      self.parse = parse;
29856      return self;
29857    };
29858
29859    var serialize = function (obj) {
29860      var data = JSON.stringify(obj);
29861      if (!isString$1(data)) {
29862        return data;
29863      }
29864      return data.replace(/[\u0080-\uFFFF]/g, function (match) {
29865        var hexCode = match.charCodeAt(0).toString(16);
29866        return '\\u' + '0000'.substring(hexCode.length) + hexCode;
29867      });
29868    };
29869    var JSONUtils = {
29870      serialize: serialize,
29871      parse: function (text) {
29872        try {
29873          return JSON.parse(text);
29874        } catch (ex) {
29875        }
29876      }
29877    };
29878
29879    var JSONP = {
29880      callbacks: {},
29881      count: 0,
29882      send: function (settings) {
29883        var self = this, dom = DOMUtils.DOM, count = settings.count !== undefined ? settings.count : self.count;
29884        var id = 'tinymce_jsonp_' + count;
29885        self.callbacks[count] = function (json) {
29886          dom.remove(id);
29887          delete self.callbacks[count];
29888          settings.callback(json);
29889        };
29890        dom.add(dom.doc.body, 'script', {
29891          id: id,
29892          src: settings.url,
29893          type: 'text/javascript'
29894        });
29895        self.count++;
29896      }
29897    };
29898
29899    var XHR = __assign(__assign({}, Observable), {
29900      send: function (settings) {
29901        var xhr, count = 0;
29902        var ready = function () {
29903          if (!settings.async || xhr.readyState === 4 || count++ > 10000) {
29904            if (settings.success && count < 10000 && xhr.status === 200) {
29905              settings.success.call(settings.success_scope, '' + xhr.responseText, xhr, settings);
29906            } else if (settings.error) {
29907              settings.error.call(settings.error_scope, count > 10000 ? 'TIMED_OUT' : 'GENERAL', xhr, settings);
29908            }
29909            xhr = null;
29910          } else {
29911            Delay.setTimeout(ready, 10);
29912          }
29913        };
29914        settings.scope = settings.scope || this;
29915        settings.success_scope = settings.success_scope || settings.scope;
29916        settings.error_scope = settings.error_scope || settings.scope;
29917        settings.async = settings.async !== false;
29918        settings.data = settings.data || '';
29919        XHR.fire('beforeInitialize', { settings: settings });
29920        xhr = new XMLHttpRequest();
29921        if (xhr.overrideMimeType) {
29922          xhr.overrideMimeType(settings.content_type);
29923        }
29924        xhr.open(settings.type || (settings.data ? 'POST' : 'GET'), settings.url, settings.async);
29925        if (settings.crossDomain) {
29926          xhr.withCredentials = true;
29927        }
29928        if (settings.content_type) {
29929          xhr.setRequestHeader('Content-Type', settings.content_type);
29930        }
29931        if (settings.requestheaders) {
29932          Tools.each(settings.requestheaders, function (header) {
29933            xhr.setRequestHeader(header.key, header.value);
29934          });
29935        }
29936        xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
29937        xhr = XHR.fire('beforeSend', {
29938          xhr: xhr,
29939          settings: settings
29940        }).xhr;
29941        xhr.send(settings.data);
29942        if (!settings.async) {
29943          return ready();
29944        }
29945        Delay.setTimeout(ready, 10);
29946      }
29947    });
29948
29949    var extend = Tools.extend;
29950    var JSONRequest = function () {
29951      function JSONRequest(settings) {
29952        this.settings = extend({}, settings);
29953        this.count = 0;
29954      }
29955      JSONRequest.sendRPC = function (o) {
29956        return new JSONRequest().send(o);
29957      };
29958      JSONRequest.prototype.send = function (args) {
29959        var ecb = args.error, scb = args.success;
29960        var xhrArgs = extend(this.settings, args);
29961        xhrArgs.success = function (c, x) {
29962          c = JSONUtils.parse(c);
29963          if (typeof c === 'undefined') {
29964            c = { error: 'JSON Parse error.' };
29965          }
29966          if (c.error) {
29967            ecb.call(xhrArgs.error_scope || xhrArgs.scope, c.error, x);
29968          } else {
29969            scb.call(xhrArgs.success_scope || xhrArgs.scope, c.result);
29970          }
29971        };
29972        xhrArgs.error = function (ty, x) {
29973          if (ecb) {
29974            ecb.call(xhrArgs.error_scope || xhrArgs.scope, ty, x);
29975          }
29976        };
29977        xhrArgs.data = JSONUtils.serialize({
29978          id: args.id || 'c' + this.count++,
29979          method: args.method,
29980          params: args.params
29981        });
29982        xhrArgs.content_type = 'application/json';
29983        XHR.send(xhrArgs);
29984      };
29985      return JSONRequest;
29986    }();
29987
29988    var create = function () {
29989      return function () {
29990        var data = {};
29991        var keys = [];
29992        var storage = {
29993          getItem: function (key) {
29994            var item = data[key];
29995            return item ? item : null;
29996          },
29997          setItem: function (key, value) {
29998            keys.push(key);
29999            data[key] = String(value);
30000          },
30001          key: function (index) {
30002            return keys[index];
30003          },
30004          removeItem: function (key) {
30005            keys = keys.filter(function (k) {
30006              return k === key;
30007            });
30008            delete data[key];
30009          },
30010          clear: function () {
30011            keys = [];
30012            data = {};
30013          },
30014          length: 0
30015        };
30016        Object.defineProperty(storage, 'length', {
30017          get: function () {
30018            return keys.length;
30019          },
30020          configurable: false,
30021          enumerable: false
30022        });
30023        return storage;
30024      }();
30025    };
30026
30027    var localStorage;
30028    try {
30029      var test = '__storage_test__';
30030      localStorage = window.localStorage;
30031      localStorage.setItem(test, test);
30032      localStorage.removeItem(test);
30033    } catch (e) {
30034      localStorage = create();
30035    }
30036    var LocalStorage = localStorage;
30037
30038    var publicApi = {
30039      geom: { Rect: Rect },
30040      util: {
30041        Promise: promiseObj,
30042        Delay: Delay,
30043        Tools: Tools,
30044        VK: VK,
30045        URI: URI,
30046        Class: Class,
30047        EventDispatcher: EventDispatcher,
30048        Observable: Observable,
30049        I18n: I18n,
30050        XHR: XHR,
30051        JSON: JSONUtils,
30052        JSONRequest: JSONRequest,
30053        JSONP: JSONP,
30054        LocalStorage: LocalStorage,
30055        Color: Color,
30056        ImageUploader: ImageUploader
30057      },
30058      dom: {
30059        EventUtils: EventUtils,
30060        Sizzle: Sizzle,
30061        DomQuery: DomQuery,
30062        TreeWalker: DomTreeWalker,
30063        TextSeeker: TextSeeker,
30064        DOMUtils: DOMUtils,
30065        ScriptLoader: ScriptLoader,
30066        RangeUtils: RangeUtils,
30067        Serializer: DomSerializer,
30068        StyleSheetLoader: StyleSheetLoader,
30069        ControlSelection: ControlSelection,
30070        BookmarkManager: BookmarkManager,
30071        Selection: EditorSelection,
30072        Event: EventUtils.Event
30073      },
30074      html: {
30075        Styles: Styles,
30076        Entities: Entities,
30077        Node: AstNode,
30078        Schema: Schema,
30079        SaxParser: SaxParser,
30080        DomParser: DomParser,
30081        Writer: Writer,
30082        Serializer: HtmlSerializer
30083      },
30084      Env: Env,
30085      AddOnManager: AddOnManager,
30086      Annotator: Annotator,
30087      Formatter: Formatter,
30088      UndoManager: UndoManager,
30089      EditorCommands: EditorCommands,
30090      WindowManager: WindowManager,
30091      NotificationManager: NotificationManager,
30092      EditorObservable: EditorObservable,
30093      Shortcuts: Shortcuts,
30094      Editor: Editor,
30095      FocusManager: FocusManager,
30096      EditorManager: EditorManager,
30097      DOM: DOMUtils.DOM,
30098      ScriptLoader: ScriptLoader.ScriptLoader,
30099      PluginManager: PluginManager,
30100      ThemeManager: ThemeManager,
30101      IconManager: IconManager,
30102      Resource: Resource,
30103      trim: Tools.trim,
30104      isArray: Tools.isArray,
30105      is: Tools.is,
30106      toArray: Tools.toArray,
30107      makeMap: Tools.makeMap,
30108      each: Tools.each,
30109      map: Tools.map,
30110      grep: Tools.grep,
30111      inArray: Tools.inArray,
30112      extend: Tools.extend,
30113      create: Tools.create,
30114      walk: Tools.walk,
30115      createNS: Tools.createNS,
30116      resolve: Tools.resolve,
30117      explode: Tools.explode,
30118      _addCacheSuffix: Tools._addCacheSuffix,
30119      isOpera: Env.opera,
30120      isWebKit: Env.webkit,
30121      isIE: Env.ie,
30122      isGecko: Env.gecko,
30123      isMac: Env.mac
30124    };
30125    var tinymce = Tools.extend(EditorManager, publicApi);
30126
30127    var exportToModuleLoaders = function (tinymce) {
30128      if (typeof module === 'object') {
30129        try {
30130          module.exports = tinymce;
30131        } catch (_) {
30132        }
30133      }
30134    };
30135    var exportToWindowGlobal = function (tinymce) {
30136      window.tinymce = tinymce;
30137      window.tinyMCE = tinymce;
30138    };
30139    exportToWindowGlobal(tinymce);
30140    exportToModuleLoaders(tinymce);
30141
30142}());

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.