CasperSecurity

Current Path : /var/www/uim.org.in/admin/tinymce/
Upload File :
Current File : /var/www/uim.org.in/admin/tinymce/tinymce.js

/**
 * Copyright (c) Tiny Technologies, Inc. All rights reserved.
 * Licensed under the LGPL or a commercial license.
 * For LGPL see License.txt in the project root for license information.
 * For commercial licenses see https://www.tiny.cloud/
 *
 * Version: 5.2.0 (2020-02-13)
 */
(function (domGlobals) {
    'use strict';

    var noop = function () {
    };
    var compose = function (fa, fb) {
      return function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
          args[_i] = arguments[_i];
        }
        return fa(fb.apply(null, args));
      };
    };
    var constant = function (value) {
      return function () {
        return value;
      };
    };
    var identity = function (x) {
      return x;
    };
    function curry(fn) {
      var initialArgs = [];
      for (var _i = 1; _i < arguments.length; _i++) {
        initialArgs[_i - 1] = arguments[_i];
      }
      return function () {
        var restArgs = [];
        for (var _i = 0; _i < arguments.length; _i++) {
          restArgs[_i] = arguments[_i];
        }
        var all = initialArgs.concat(restArgs);
        return fn.apply(null, all);
      };
    }
    var not = function (f) {
      return function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
          args[_i] = arguments[_i];
        }
        return !f.apply(null, args);
      };
    };
    var die = function (msg) {
      return function () {
        throw new Error(msg);
      };
    };
    var never = constant(false);
    var always = constant(true);

    var none = function () {
      return NONE;
    };
    var NONE = function () {
      var eq = function (o) {
        return o.isNone();
      };
      var call = function (thunk) {
        return thunk();
      };
      var id = function (n) {
        return n;
      };
      var me = {
        fold: function (n, s) {
          return n();
        },
        is: never,
        isSome: never,
        isNone: always,
        getOr: id,
        getOrThunk: call,
        getOrDie: function (msg) {
          throw new Error(msg || 'error: getOrDie called on none.');
        },
        getOrNull: constant(null),
        getOrUndefined: constant(undefined),
        or: id,
        orThunk: call,
        map: none,
        each: noop,
        bind: none,
        exists: never,
        forall: always,
        filter: none,
        equals: eq,
        equals_: eq,
        toArray: function () {
          return [];
        },
        toString: constant('none()')
      };
      if (Object.freeze) {
        Object.freeze(me);
      }
      return me;
    }();
    var some = function (a) {
      var constant_a = constant(a);
      var self = function () {
        return me;
      };
      var bind = function (f) {
        return f(a);
      };
      var me = {
        fold: function (n, s) {
          return s(a);
        },
        is: function (v) {
          return a === v;
        },
        isSome: always,
        isNone: never,
        getOr: constant_a,
        getOrThunk: constant_a,
        getOrDie: constant_a,
        getOrNull: constant_a,
        getOrUndefined: constant_a,
        or: self,
        orThunk: self,
        map: function (f) {
          return some(f(a));
        },
        each: function (f) {
          f(a);
        },
        bind: bind,
        exists: bind,
        forall: bind,
        filter: function (f) {
          return f(a) ? me : NONE;
        },
        toArray: function () {
          return [a];
        },
        toString: function () {
          return 'some(' + a + ')';
        },
        equals: function (o) {
          return o.is(a);
        },
        equals_: function (o, elementEq) {
          return o.fold(never, function (b) {
            return elementEq(a, b);
          });
        }
      };
      return me;
    };
    var from = function (value) {
      return value === null || value === undefined ? NONE : some(value);
    };
    var Option = {
      some: some,
      none: none,
      from: from
    };

    var typeOf = function (x) {
      if (x === null) {
        return 'null';
      }
      var t = typeof x;
      if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) {
        return 'array';
      }
      if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) {
        return 'string';
      }
      return t;
    };
    var isType = function (type) {
      return function (value) {
        return typeOf(value) === type;
      };
    };
    var isString = isType('string');
    var isObject = isType('object');
    var isArray = isType('array');
    var isNull = isType('null');
    var isBoolean = isType('boolean');
    var isFunction = isType('function');
    var isNumber = isType('number');

    var nativeSlice = Array.prototype.slice;
    var nativeIndexOf = Array.prototype.indexOf;
    var nativePush = Array.prototype.push;
    var rawIndexOf = function (ts, t) {
      return nativeIndexOf.call(ts, t);
    };
    var indexOf = function (xs, x) {
      var r = rawIndexOf(xs, x);
      return r === -1 ? Option.none() : Option.some(r);
    };
    var contains = function (xs, x) {
      return rawIndexOf(xs, x) > -1;
    };
    var exists = function (xs, pred) {
      for (var i = 0, len = xs.length; i < len; i++) {
        var x = xs[i];
        if (pred(x, i)) {
          return true;
        }
      }
      return false;
    };
    var map = function (xs, f) {
      var len = xs.length;
      var r = new Array(len);
      for (var i = 0; i < len; i++) {
        var x = xs[i];
        r[i] = f(x, i);
      }
      return r;
    };
    var each = function (xs, f) {
      for (var i = 0, len = xs.length; i < len; i++) {
        var x = xs[i];
        f(x, i);
      }
    };
    var eachr = function (xs, f) {
      for (var i = xs.length - 1; i >= 0; i--) {
        var x = xs[i];
        f(x, i);
      }
    };
    var partition = function (xs, pred) {
      var pass = [];
      var fail = [];
      for (var i = 0, len = xs.length; i < len; i++) {
        var x = xs[i];
        var arr = pred(x, i) ? pass : fail;
        arr.push(x);
      }
      return {
        pass: pass,
        fail: fail
      };
    };
    var filter = function (xs, pred) {
      var r = [];
      for (var i = 0, len = xs.length; i < len; i++) {
        var x = xs[i];
        if (pred(x, i)) {
          r.push(x);
        }
      }
      return r;
    };
    var foldr = function (xs, f, acc) {
      eachr(xs, function (x) {
        acc = f(acc, x);
      });
      return acc;
    };
    var foldl = function (xs, f, acc) {
      each(xs, function (x) {
        acc = f(acc, x);
      });
      return acc;
    };
    var find = function (xs, pred) {
      for (var i = 0, len = xs.length; i < len; i++) {
        var x = xs[i];
        if (pred(x, i)) {
          return Option.some(x);
        }
      }
      return Option.none();
    };
    var findIndex = function (xs, pred) {
      for (var i = 0, len = xs.length; i < len; i++) {
        var x = xs[i];
        if (pred(x, i)) {
          return Option.some(i);
        }
      }
      return Option.none();
    };
    var flatten = function (xs) {
      var r = [];
      for (var i = 0, len = xs.length; i < len; ++i) {
        if (!isArray(xs[i])) {
          throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);
        }
        nativePush.apply(r, xs[i]);
      }
      return r;
    };
    var bind = function (xs, f) {
      return flatten(map(xs, f));
    };
    var forall = function (xs, pred) {
      for (var i = 0, len = xs.length; i < len; ++i) {
        var x = xs[i];
        if (pred(x, i) !== true) {
          return false;
        }
      }
      return true;
    };
    var reverse = function (xs) {
      var r = nativeSlice.call(xs, 0);
      r.reverse();
      return r;
    };
    var difference = function (a1, a2) {
      return filter(a1, function (x) {
        return !contains(a2, x);
      });
    };
    var mapToObject = function (xs, f) {
      var r = {};
      for (var i = 0, len = xs.length; i < len; i++) {
        var x = xs[i];
        r[String(x)] = f(x, i);
      }
      return r;
    };
    var sort = function (xs, comparator) {
      var copy = nativeSlice.call(xs, 0);
      copy.sort(comparator);
      return copy;
    };
    var head = function (xs) {
      return xs.length === 0 ? Option.none() : Option.some(xs[0]);
    };
    var last = function (xs) {
      return xs.length === 0 ? Option.none() : Option.some(xs[xs.length - 1]);
    };
    var from$1 = isFunction(Array.from) ? Array.from : function (x) {
      return nativeSlice.call(x);
    };

    var keys = Object.keys;
    var hasOwnProperty = Object.hasOwnProperty;
    var each$1 = function (obj, f) {
      var props = keys(obj);
      for (var k = 0, len = props.length; k < len; k++) {
        var i = props[k];
        var x = obj[i];
        f(x, i);
      }
    };
    var map$1 = function (obj, f) {
      return tupleMap(obj, function (x, i) {
        return {
          k: i,
          v: f(x, i)
        };
      });
    };
    var tupleMap = function (obj, f) {
      var r = {};
      each$1(obj, function (x, i) {
        var tuple = f(x, i);
        r[tuple.k] = tuple.v;
      });
      return r;
    };
    var objAcc = function (r) {
      return function (x, i) {
        r[i] = x;
      };
    };
    var internalFilter = function (obj, pred, onTrue, onFalse) {
      var r = {};
      each$1(obj, function (x, i) {
        (pred(x, i) ? onTrue : onFalse)(x, i);
      });
      return r;
    };
    var bifilter = function (obj, pred) {
      var t = {};
      var f = {};
      internalFilter(obj, pred, objAcc(t), objAcc(f));
      return {
        t: t,
        f: f
      };
    };
    var get = function (obj, key) {
      return has(obj, key) ? Option.from(obj[key]) : Option.none();
    };
    var has = function (obj, key) {
      return hasOwnProperty.call(obj, key);
    };

    var __assign = function () {
      __assign = Object.assign || function __assign(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
          s = arguments[i];
          for (var p in s)
            if (Object.prototype.hasOwnProperty.call(s, p))
              t[p] = s[p];
        }
        return t;
      };
      return __assign.apply(this, arguments);
    };
    function __rest(s, e) {
      var t = {};
      for (var p in s)
        if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
          t[p] = s[p];
      if (s != null && typeof Object.getOwnPropertySymbols === 'function')
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
          if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
            t[p[i]] = s[p[i]];
        }
      return t;
    }

    var fromHtml = function (html, scope) {
      var doc = scope || domGlobals.document;
      var div = doc.createElement('div');
      div.innerHTML = html;
      if (!div.hasChildNodes() || div.childNodes.length > 1) {
        domGlobals.console.error('HTML does not have a single root node', html);
        throw new Error('HTML must have a single root node');
      }
      return fromDom(div.childNodes[0]);
    };
    var fromTag = function (tag, scope) {
      var doc = scope || domGlobals.document;
      var node = doc.createElement(tag);
      return fromDom(node);
    };
    var fromText = function (text, scope) {
      var doc = scope || domGlobals.document;
      var node = doc.createTextNode(text);
      return fromDom(node);
    };
    var fromDom = function (node) {
      if (node === null || node === undefined) {
        throw new Error('Node cannot be null or undefined');
      }
      return { dom: constant(node) };
    };
    var fromPoint = function (docElm, x, y) {
      var doc = docElm.dom();
      return Option.from(doc.elementFromPoint(x, y)).map(fromDom);
    };
    var Element = {
      fromHtml: fromHtml,
      fromTag: fromTag,
      fromText: fromText,
      fromDom: fromDom,
      fromPoint: fromPoint
    };

    var Cell = function (initial) {
      var value = initial;
      var get = function () {
        return value;
      };
      var set = function (v) {
        value = v;
      };
      var clone = function () {
        return Cell(get());
      };
      return {
        get: get,
        set: set,
        clone: clone
      };
    };

    var firstMatch = function (regexes, s) {
      for (var i = 0; i < regexes.length; i++) {
        var x = regexes[i];
        if (x.test(s)) {
          return x;
        }
      }
      return undefined;
    };
    var find$1 = function (regexes, agent) {
      var r = firstMatch(regexes, agent);
      if (!r) {
        return {
          major: 0,
          minor: 0
        };
      }
      var group = function (i) {
        return Number(agent.replace(r, '$' + i));
      };
      return nu(group(1), group(2));
    };
    var detect = function (versionRegexes, agent) {
      var cleanedAgent = String(agent).toLowerCase();
      if (versionRegexes.length === 0) {
        return unknown();
      }
      return find$1(versionRegexes, cleanedAgent);
    };
    var unknown = function () {
      return nu(0, 0);
    };
    var nu = function (major, minor) {
      return {
        major: major,
        minor: minor
      };
    };
    var Version = {
      nu: nu,
      detect: detect,
      unknown: unknown
    };

    var edge = 'Edge';
    var chrome = 'Chrome';
    var ie = 'IE';
    var opera = 'Opera';
    var firefox = 'Firefox';
    var safari = 'Safari';
    var isBrowser = function (name, current) {
      return function () {
        return current === name;
      };
    };
    var unknown$1 = function () {
      return nu$1({
        current: undefined,
        version: Version.unknown()
      });
    };
    var nu$1 = function (info) {
      var current = info.current;
      var version = info.version;
      return {
        current: current,
        version: version,
        isEdge: isBrowser(edge, current),
        isChrome: isBrowser(chrome, current),
        isIE: isBrowser(ie, current),
        isOpera: isBrowser(opera, current),
        isFirefox: isBrowser(firefox, current),
        isSafari: isBrowser(safari, current)
      };
    };
    var Browser = {
      unknown: unknown$1,
      nu: nu$1,
      edge: constant(edge),
      chrome: constant(chrome),
      ie: constant(ie),
      opera: constant(opera),
      firefox: constant(firefox),
      safari: constant(safari)
    };

    var windows = 'Windows';
    var ios = 'iOS';
    var android = 'Android';
    var linux = 'Linux';
    var osx = 'OSX';
    var solaris = 'Solaris';
    var freebsd = 'FreeBSD';
    var chromeos = 'ChromeOS';
    var isOS = function (name, current) {
      return function () {
        return current === name;
      };
    };
    var unknown$2 = function () {
      return nu$2({
        current: undefined,
        version: Version.unknown()
      });
    };
    var nu$2 = function (info) {
      var current = info.current;
      var version = info.version;
      return {
        current: current,
        version: version,
        isWindows: isOS(windows, current),
        isiOS: isOS(ios, current),
        isAndroid: isOS(android, current),
        isOSX: isOS(osx, current),
        isLinux: isOS(linux, current),
        isSolaris: isOS(solaris, current),
        isFreeBSD: isOS(freebsd, current),
        isChromeOS: isOS(chromeos, current)
      };
    };
    var OperatingSystem = {
      unknown: unknown$2,
      nu: nu$2,
      windows: constant(windows),
      ios: constant(ios),
      android: constant(android),
      linux: constant(linux),
      osx: constant(osx),
      solaris: constant(solaris),
      freebsd: constant(freebsd),
      chromeos: constant(chromeos)
    };

    var DeviceType = function (os, browser, userAgent, mediaMatch) {
      var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true;
      var isiPhone = os.isiOS() && !isiPad;
      var isMobile = os.isiOS() || os.isAndroid();
      var isTouch = isMobile || mediaMatch('(pointer:coarse)');
      var isTablet = isiPad || !isiPhone && isMobile && mediaMatch('(min-device-width:768px)');
      var isPhone = isiPhone || isMobile && !isTablet;
      var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false;
      var isDesktop = !isPhone && !isTablet && !iOSwebview;
      return {
        isiPad: constant(isiPad),
        isiPhone: constant(isiPhone),
        isTablet: constant(isTablet),
        isPhone: constant(isPhone),
        isTouch: constant(isTouch),
        isAndroid: os.isAndroid,
        isiOS: os.isiOS,
        isWebView: constant(iOSwebview),
        isDesktop: constant(isDesktop)
      };
    };

    var detect$1 = function (candidates, userAgent) {
      var agent = String(userAgent).toLowerCase();
      return find(candidates, function (candidate) {
        return candidate.search(agent);
      });
    };
    var detectBrowser = function (browsers, userAgent) {
      return detect$1(browsers, userAgent).map(function (browser) {
        var version = Version.detect(browser.versionRegexes, userAgent);
        return {
          current: browser.name,
          version: version
        };
      });
    };
    var detectOs = function (oses, userAgent) {
      return detect$1(oses, userAgent).map(function (os) {
        var version = Version.detect(os.versionRegexes, userAgent);
        return {
          current: os.name,
          version: version
        };
      });
    };
    var UaString = {
      detectBrowser: detectBrowser,
      detectOs: detectOs
    };

    var checkRange = function (str, substr, start) {
      if (substr === '') {
        return true;
      }
      if (str.length < substr.length) {
        return false;
      }
      var x = str.substr(start, start + substr.length);
      return x === substr;
    };
    var contains$1 = function (str, substr) {
      return str.indexOf(substr) !== -1;
    };
    var startsWith = function (str, prefix) {
      return checkRange(str, prefix, 0);
    };
    var trim = function (str) {
      return str.replace(/^\s+|\s+$/g, '');
    };
    var lTrim = function (str) {
      return str.replace(/^\s+/g, '');
    };
    var rTrim = function (str) {
      return str.replace(/\s+$/g, '');
    };

    var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/;
    var checkContains = function (target) {
      return function (uastring) {
        return contains$1(uastring, target);
      };
    };
    var browsers = [
      {
        name: 'Edge',
        versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/],
        search: function (uastring) {
          return contains$1(uastring, 'edge/') && contains$1(uastring, 'chrome') && contains$1(uastring, 'safari') && contains$1(uastring, 'applewebkit');
        }
      },
      {
        name: 'Chrome',
        versionRegexes: [
          /.*?chrome\/([0-9]+)\.([0-9]+).*/,
          normalVersionRegex
        ],
        search: function (uastring) {
          return contains$1(uastring, 'chrome') && !contains$1(uastring, 'chromeframe');
        }
      },
      {
        name: 'IE',
        versionRegexes: [
          /.*?msie\ ?([0-9]+)\.([0-9]+).*/,
          /.*?rv:([0-9]+)\.([0-9]+).*/
        ],
        search: function (uastring) {
          return contains$1(uastring, 'msie') || contains$1(uastring, 'trident');
        }
      },
      {
        name: 'Opera',
        versionRegexes: [
          normalVersionRegex,
          /.*?opera\/([0-9]+)\.([0-9]+).*/
        ],
        search: checkContains('opera')
      },
      {
        name: 'Firefox',
        versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/],
        search: checkContains('firefox')
      },
      {
        name: 'Safari',
        versionRegexes: [
          normalVersionRegex,
          /.*?cpu os ([0-9]+)_([0-9]+).*/
        ],
        search: function (uastring) {
          return (contains$1(uastring, 'safari') || contains$1(uastring, 'mobile/')) && contains$1(uastring, 'applewebkit');
        }
      }
    ];
    var oses = [
      {
        name: 'Windows',
        search: checkContains('win'),
        versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/]
      },
      {
        name: 'iOS',
        search: function (uastring) {
          return contains$1(uastring, 'iphone') || contains$1(uastring, 'ipad');
        },
        versionRegexes: [
          /.*?version\/\ ?([0-9]+)\.([0-9]+).*/,
          /.*cpu os ([0-9]+)_([0-9]+).*/,
          /.*cpu iphone os ([0-9]+)_([0-9]+).*/
        ]
      },
      {
        name: 'Android',
        search: checkContains('android'),
        versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/]
      },
      {
        name: 'OSX',
        search: checkContains('mac os x'),
        versionRegexes: [/.*?mac\ os\ x\ ?([0-9]+)_([0-9]+).*/]
      },
      {
        name: 'Linux',
        search: checkContains('linux'),
        versionRegexes: []
      },
      {
        name: 'Solaris',
        search: checkContains('sunos'),
        versionRegexes: []
      },
      {
        name: 'FreeBSD',
        search: checkContains('freebsd'),
        versionRegexes: []
      },
      {
        name: 'ChromeOS',
        search: checkContains('cros'),
        versionRegexes: [/.*?chrome\/([0-9]+)\.([0-9]+).*/]
      }
    ];
    var PlatformInfo = {
      browsers: constant(browsers),
      oses: constant(oses)
    };

    var detect$2 = function (userAgent, mediaMatch) {
      var browsers = PlatformInfo.browsers();
      var oses = PlatformInfo.oses();
      var browser = UaString.detectBrowser(browsers, userAgent).fold(Browser.unknown, Browser.nu);
      var os = UaString.detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu);
      var deviceType = DeviceType(os, browser, userAgent, mediaMatch);
      return {
        browser: browser,
        os: os,
        deviceType: deviceType
      };
    };
    var PlatformDetection = { detect: detect$2 };

    var mediaMatch = function (query) {
      return domGlobals.window.matchMedia(query).matches;
    };
    var platform = Cell(PlatformDetection.detect(domGlobals.navigator.userAgent, mediaMatch));
    var detect$3 = function () {
      return platform.get();
    };

    var Immutable = function () {
      var fields = [];
      for (var _i = 0; _i < arguments.length; _i++) {
        fields[_i] = arguments[_i];
      }
      return function () {
        var values = [];
        for (var _i = 0; _i < arguments.length; _i++) {
          values[_i] = arguments[_i];
        }
        if (fields.length !== values.length) {
          throw new Error('Wrong number of arguments to struct. Expected "[' + fields.length + ']", got ' + values.length + ' arguments');
        }
        var struct = {};
        each(fields, function (name, i) {
          struct[name] = constant(values[i]);
        });
        return struct;
      };
    };

    var toArray = function (target, f) {
      var r = [];
      var recurse = function (e) {
        r.push(e);
        return f(e);
      };
      var cur = f(target);
      do {
        cur = cur.bind(recurse);
      } while (cur.isSome());
      return r;
    };
    var Recurse = { toArray: toArray };

    var compareDocumentPosition = function (a, b, match) {
      return (a.compareDocumentPosition(b) & match) !== 0;
    };
    var documentPositionPreceding = function (a, b) {
      return compareDocumentPosition(a, b, domGlobals.Node.DOCUMENT_POSITION_PRECEDING);
    };
    var documentPositionContainedBy = function (a, b) {
      return compareDocumentPosition(a, b, domGlobals.Node.DOCUMENT_POSITION_CONTAINED_BY);
    };
    var Node = {
      documentPositionPreceding: documentPositionPreceding,
      documentPositionContainedBy: documentPositionContainedBy
    };

    var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE;
    var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE;
    var COMMENT = domGlobals.Node.COMMENT_NODE;
    var DOCUMENT = domGlobals.Node.DOCUMENT_NODE;
    var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE;
    var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE;
    var ELEMENT = domGlobals.Node.ELEMENT_NODE;
    var TEXT = domGlobals.Node.TEXT_NODE;
    var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE;
    var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE;
    var ENTITY = domGlobals.Node.ENTITY_NODE;
    var NOTATION = domGlobals.Node.NOTATION_NODE;

    var ELEMENT$1 = ELEMENT;
    var DOCUMENT$1 = DOCUMENT;
    var is = function (element, selector) {
      var dom = element.dom();
      if (dom.nodeType !== ELEMENT$1) {
        return false;
      } else {
        var elem = dom;
        if (elem.matches !== undefined) {
          return elem.matches(selector);
        } else if (elem.msMatchesSelector !== undefined) {
          return elem.msMatchesSelector(selector);
        } else if (elem.webkitMatchesSelector !== undefined) {
          return elem.webkitMatchesSelector(selector);
        } else if (elem.mozMatchesSelector !== undefined) {
          return elem.mozMatchesSelector(selector);
        } else {
          throw new Error('Browser lacks native selectors');
        }
      }
    };
    var bypassSelector = function (dom) {
      return dom.nodeType !== ELEMENT$1 && dom.nodeType !== DOCUMENT$1 || dom.childElementCount === 0;
    };
    var all = function (selector, scope) {
      var base = scope === undefined ? domGlobals.document : scope.dom();
      return bypassSelector(base) ? [] : map(base.querySelectorAll(selector), Element.fromDom);
    };
    var one = function (selector, scope) {
      var base = scope === undefined ? domGlobals.document : scope.dom();
      return bypassSelector(base) ? Option.none() : Option.from(base.querySelector(selector)).map(Element.fromDom);
    };

    var eq = function (e1, e2) {
      return e1.dom() === e2.dom();
    };
    var regularContains = function (e1, e2) {
      var d1 = e1.dom();
      var d2 = e2.dom();
      return d1 === d2 ? false : d1.contains(d2);
    };
    var ieContains = function (e1, e2) {
      return Node.documentPositionContainedBy(e1.dom(), e2.dom());
    };
    var browser = detect$3().browser;
    var contains$2 = browser.isIE() ? ieContains : regularContains;

    var owner = function (element) {
      return Element.fromDom(element.dom().ownerDocument);
    };
    var documentElement = function (element) {
      return Element.fromDom(element.dom().ownerDocument.documentElement);
    };
    var defaultView = function (element) {
      return Element.fromDom(element.dom().ownerDocument.defaultView);
    };
    var parent = function (element) {
      return Option.from(element.dom().parentNode).map(Element.fromDom);
    };
    var parents = function (element, isRoot) {
      var stop = isFunction(isRoot) ? isRoot : never;
      var dom = element.dom();
      var ret = [];
      while (dom.parentNode !== null && dom.parentNode !== undefined) {
        var rawParent = dom.parentNode;
        var p = Element.fromDom(rawParent);
        ret.push(p);
        if (stop(p) === true) {
          break;
        } else {
          dom = rawParent;
        }
      }
      return ret;
    };
    var prevSibling = function (element) {
      return Option.from(element.dom().previousSibling).map(Element.fromDom);
    };
    var nextSibling = function (element) {
      return Option.from(element.dom().nextSibling).map(Element.fromDom);
    };
    var prevSiblings = function (element) {
      return reverse(Recurse.toArray(element, prevSibling));
    };
    var nextSiblings = function (element) {
      return Recurse.toArray(element, nextSibling);
    };
    var children = function (element) {
      return map(element.dom().childNodes, Element.fromDom);
    };
    var child = function (element, index) {
      var cs = element.dom().childNodes;
      return Option.from(cs[index]).map(Element.fromDom);
    };
    var firstChild = function (element) {
      return child(element, 0);
    };
    var lastChild = function (element) {
      return child(element, element.dom().childNodes.length - 1);
    };
    var childNodesCount = function (element) {
      return element.dom().childNodes.length;
    };
    var spot = Immutable('element', 'offset');

    var before = function (marker, element) {
      var parent$1 = parent(marker);
      parent$1.each(function (v) {
        v.dom().insertBefore(element.dom(), marker.dom());
      });
    };
    var after = function (marker, element) {
      var sibling = nextSibling(marker);
      sibling.fold(function () {
        var parent$1 = parent(marker);
        parent$1.each(function (v) {
          append(v, element);
        });
      }, function (v) {
        before(v, element);
      });
    };
    var prepend = function (parent, element) {
      var firstChild$1 = firstChild(parent);
      firstChild$1.fold(function () {
        append(parent, element);
      }, function (v) {
        parent.dom().insertBefore(element.dom(), v.dom());
      });
    };
    var append = function (parent, element) {
      parent.dom().appendChild(element.dom());
    };
    var wrap = function (element, wrapper) {
      before(element, wrapper);
      append(wrapper, element);
    };

    var before$1 = function (marker, elements) {
      each(elements, function (x) {
        before(marker, x);
      });
    };
    var append$1 = function (parent, elements) {
      each(elements, function (x) {
        append(parent, x);
      });
    };

    var empty = function (element) {
      element.dom().textContent = '';
      each(children(element), function (rogue) {
        remove(rogue);
      });
    };
    var remove = function (element) {
      var dom = element.dom();
      if (dom.parentNode !== null) {
        dom.parentNode.removeChild(dom);
      }
    };
    var unwrap = function (wrapper) {
      var children$1 = children(wrapper);
      if (children$1.length > 0) {
        before$1(wrapper, children$1);
      }
      remove(wrapper);
    };

    var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')();

    var name = function (element) {
      var r = element.dom().nodeName;
      return r.toLowerCase();
    };
    var type = function (element) {
      return element.dom().nodeType;
    };
    var isType$1 = function (t) {
      return function (element) {
        return type(element) === t;
      };
    };
    var isElement = isType$1(ELEMENT);
    var isText = isType$1(TEXT);

    var inBody = function (element) {
      var dom = isText(element) ? element.dom().parentNode : element.dom();
      return dom !== undefined && dom !== null && dom.ownerDocument.body.contains(dom);
    };

    var r = function (left, top) {
      var translate = function (x, y) {
        return r(left + x, top + y);
      };
      return {
        left: constant(left),
        top: constant(top),
        translate: translate
      };
    };
    var Position = r;

    var boxPosition = function (dom) {
      var box = dom.getBoundingClientRect();
      return Position(box.left, box.top);
    };
    var firstDefinedOrZero = function (a, b) {
      return a !== undefined ? a : b !== undefined ? b : 0;
    };
    var absolute = function (element) {
      var doc = element.dom().ownerDocument;
      var body = doc.body;
      var win = doc.defaultView;
      var html = doc.documentElement;
      if (body === element.dom()) {
        return Position(body.offsetLeft, body.offsetTop);
      }
      var scrollTop = firstDefinedOrZero(win.pageYOffset, html.scrollTop);
      var scrollLeft = firstDefinedOrZero(win.pageXOffset, html.scrollLeft);
      var clientTop = firstDefinedOrZero(html.clientTop, body.clientTop);
      var clientLeft = firstDefinedOrZero(html.clientLeft, body.clientLeft);
      return viewport(element).translate(scrollLeft - clientLeft, scrollTop - clientTop);
    };
    var viewport = function (element) {
      var dom = element.dom();
      var doc = dom.ownerDocument;
      var body = doc.body;
      if (body === dom) {
        return Position(body.offsetLeft, body.offsetTop);
      }
      if (!inBody(element)) {
        return Position(0, 0);
      }
      return boxPosition(dom);
    };

    var isSafari = detect$3().browser.isSafari();
    var get$1 = function (_DOC) {
      var doc = _DOC !== undefined ? _DOC.dom() : domGlobals.document;
      var x = doc.body.scrollLeft || doc.documentElement.scrollLeft;
      var y = doc.body.scrollTop || doc.documentElement.scrollTop;
      return Position(x, y);
    };
    var to = function (x, y, _DOC) {
      var doc = _DOC !== undefined ? _DOC.dom() : domGlobals.document;
      var win = doc.defaultView;
      win.scrollTo(x, y);
    };
    var intoView = function (element, alignToTop) {
      if (isSafari && isFunction(element.dom().scrollIntoViewIfNeeded)) {
        element.dom().scrollIntoViewIfNeeded(false);
      } else {
        element.dom().scrollIntoView(alignToTop);
      }
    };

    var get$2 = function (_win) {
      var win = _win === undefined ? domGlobals.window : _win;
      return Option.from(win['visualViewport']);
    };
    var bounds = function (x, y, width, height) {
      return {
        x: constant(x),
        y: constant(y),
        width: constant(width),
        height: constant(height),
        right: constant(x + width),
        bottom: constant(y + height)
      };
    };
    var getBounds = function (_win) {
      var win = _win === undefined ? domGlobals.window : _win;
      var doc = win.document;
      var scroll = get$1(Element.fromDom(doc));
      return get$2(win).fold(function () {
        var html = win.document.documentElement;
        var width = html.clientWidth;
        var height = html.clientHeight;
        return bounds(scroll.left(), scroll.top(), width, height);
      }, function (visualViewport) {
        return bounds(Math.max(visualViewport.pageLeft, scroll.left()), Math.max(visualViewport.pageTop, scroll.top()), visualViewport.width, visualViewport.height);
      });
    };

    var isNodeType = function (type) {
      return function (node) {
        return !!node && node.nodeType === type;
      };
    };
    var isRestrictedNode = function (node) {
      return !!node && !Object.getPrototypeOf(node);
    };
    var isElement$1 = isNodeType(1);
    var matchNodeNames = function (names) {
      var lowercasedNames = names.map(function (s) {
        return s.toLowerCase();
      });
      return function (node) {
        if (node && node.nodeName) {
          var nodeName = node.nodeName.toLowerCase();
          return contains(lowercasedNames, nodeName);
        }
        return false;
      };
    };
    var matchStyleValues = function (name, values) {
      var items = values.toLowerCase().split(' ');
      return function (node) {
        var i, cssValue;
        if (isElement$1(node)) {
          for (i = 0; i < items.length; i++) {
            var computed = node.ownerDocument.defaultView.getComputedStyle(node, null);
            cssValue = computed ? computed.getPropertyValue(name) : null;
            if (cssValue === items[i]) {
              return true;
            }
          }
        }
        return false;
      };
    };
    var hasPropValue = function (propName, propValue) {
      return function (node) {
        return isElement$1(node) && node[propName] === propValue;
      };
    };
    var hasAttribute = function (attrName, attrValue) {
      return function (node) {
        return isElement$1(node) && node.hasAttribute(attrName);
      };
    };
    var hasAttributeValue = function (attrName, attrValue) {
      return function (node) {
        return isElement$1(node) && node.getAttribute(attrName) === attrValue;
      };
    };
    var isBogus = function (node) {
      return isElement$1(node) && node.hasAttribute('data-mce-bogus');
    };
    var isBogusAll = function (node) {
      return isElement$1(node) && node.getAttribute('data-mce-bogus') === 'all';
    };
    var isTable = function (node) {
      return isElement$1(node) && node.tagName === 'TABLE';
    };
    var hasContentEditableState = function (value) {
      return function (node) {
        if (isElement$1(node)) {
          if (node.contentEditable === value) {
            return true;
          }
          if (node.getAttribute('data-mce-contenteditable') === value) {
            return true;
          }
        }
        return false;
      };
    };
    var isTextareaOrInput = matchNodeNames([
      'textarea',
      'input'
    ]);
    var isText$1 = isNodeType(3);
    var isComment = isNodeType(8);
    var isDocument = isNodeType(9);
    var isDocumentFragment = isNodeType(11);
    var isBr = matchNodeNames(['br']);
    var isContentEditableTrue = hasContentEditableState('true');
    var isContentEditableFalse = hasContentEditableState('false');
    var NodeType = {
      isText: isText$1,
      isElement: isElement$1,
      isComment: isComment,
      isDocument: isDocument,
      isDocumentFragment: isDocumentFragment,
      isBr: isBr,
      isContentEditableTrue: isContentEditableTrue,
      isContentEditableFalse: isContentEditableFalse,
      isRestrictedNode: isRestrictedNode,
      matchNodeNames: matchNodeNames,
      hasPropValue: hasPropValue,
      hasAttribute: hasAttribute,
      hasAttributeValue: hasAttributeValue,
      matchStyleValues: matchStyleValues,
      isBogus: isBogus,
      isBogusAll: isBogusAll,
      isTable: isTable,
      isTextareaOrInput: isTextareaOrInput
    };

    var isSupported = function (dom) {
      return dom.style !== undefined && isFunction(dom.style.getPropertyValue);
    };

    var rawSet = function (dom, key, value) {
      if (isString(value) || isBoolean(value) || isNumber(value)) {
        dom.setAttribute(key, value + '');
      } else {
        domGlobals.console.error('Invalid call to Attr.set. Key ', key, ':: Value ', value, ':: Element ', dom);
        throw new Error('Attribute value was not simple');
      }
    };
    var set = function (element, key, value) {
      rawSet(element.dom(), key, value);
    };
    var setAll = function (element, attrs) {
      var dom = element.dom();
      each$1(attrs, function (v, k) {
        rawSet(dom, k, v);
      });
    };
    var get$3 = function (element, key) {
      var v = element.dom().getAttribute(key);
      return v === null ? undefined : v;
    };
    var getOpt = function (element, key) {
      return Option.from(get$3(element, key));
    };
    var has$1 = function (element, key) {
      var dom = element.dom();
      return dom && dom.hasAttribute ? dom.hasAttribute(key) : false;
    };
    var remove$1 = function (element, key) {
      element.dom().removeAttribute(key);
    };

    var get$4 = function (element, property) {
      var dom = element.dom();
      var styles = domGlobals.window.getComputedStyle(dom);
      var r = styles.getPropertyValue(property);
      var v = r === '' && !inBody(element) ? getUnsafeProperty(dom, property) : r;
      return v === null ? undefined : v;
    };
    var getUnsafeProperty = function (dom, property) {
      return isSupported(dom) ? dom.style.getPropertyValue(property) : '';
    };
    var getRaw = function (element, property) {
      var dom = element.dom();
      var raw = getUnsafeProperty(dom, property);
      return Option.from(raw).filter(function (r) {
        return r.length > 0;
      });
    };
    var reflow = function (e) {
      return e.dom().offsetWidth;
    };

    var browser$1 = detect$3().browser;
    var firstElement = function (nodes) {
      return find(nodes, isElement);
    };
    var getTableCaptionDeltaY = function (elm) {
      if (browser$1.isFirefox() && name(elm) === 'table') {
        return firstElement(children(elm)).filter(function (elm) {
          return name(elm) === 'caption';
        }).bind(function (caption) {
          return firstElement(nextSiblings(caption)).map(function (body) {
            var bodyTop = body.dom().offsetTop;
            var captionTop = caption.dom().offsetTop;
            var captionHeight = caption.dom().offsetHeight;
            return bodyTop <= captionTop ? -captionHeight : 0;
          });
        }).getOr(0);
      } else {
        return 0;
      }
    };
    var hasChild = function (elm, child) {
      return elm.children && contains(elm.children, child);
    };
    var getPos = function (body, elm, rootElm) {
      var x = 0, y = 0, offsetParent;
      var doc = body.ownerDocument;
      var pos;
      rootElm = rootElm ? rootElm : body;
      if (elm) {
        if (rootElm === body && elm.getBoundingClientRect && get$4(Element.fromDom(body), 'position') === 'static') {
          pos = elm.getBoundingClientRect();
          x = pos.left + (doc.documentElement.scrollLeft || body.scrollLeft) - doc.documentElement.clientLeft;
          y = pos.top + (doc.documentElement.scrollTop || body.scrollTop) - doc.documentElement.clientTop;
          return {
            x: x,
            y: y
          };
        }
        offsetParent = elm;
        while (offsetParent && offsetParent !== rootElm && offsetParent.nodeType && !hasChild(offsetParent, rootElm)) {
          x += offsetParent.offsetLeft || 0;
          y += offsetParent.offsetTop || 0;
          offsetParent = offsetParent.offsetParent;
        }
        offsetParent = elm.parentNode;
        while (offsetParent && offsetParent !== rootElm && offsetParent.nodeType && !hasChild(offsetParent, rootElm)) {
          x -= offsetParent.scrollLeft || 0;
          y -= offsetParent.scrollTop || 0;
          offsetParent = offsetParent.parentNode;
        }
        y += getTableCaptionDeltaY(Element.fromDom(elm));
      }
      return {
        x: x,
        y: y
      };
    };
    var Position$1 = { getPos: getPos };

    var exports$1 = {}, module$1 = { exports: exports$1 };
    (function (define, exports, module, require) {
      (function (f) {
        if (typeof exports === 'object' && typeof module !== 'undefined') {
          module.exports = f();
        } else if (typeof define === 'function' && define.amd) {
          define([], f);
        } else {
          var g;
          if (typeof window !== 'undefined') {
            g = window;
          } else if (typeof global !== 'undefined') {
            g = global;
          } else if (typeof self !== 'undefined') {
            g = self;
          } else {
            g = this;
          }
          g.EphoxContactWrapper = f();
        }
      }(function () {
        return function () {
          function r(e, n, t) {
            function o(i, f) {
              if (!n[i]) {
                if (!e[i]) {
                  var c = 'function' == typeof require && require;
                  if (!f && c)
                    return c(i, !0);
                  if (u)
                    return u(i, !0);
                  var a = new Error('Cannot find module \'' + i + '\'');
                  throw a.code = 'MODULE_NOT_FOUND', a;
                }
                var p = n[i] = { exports: {} };
                e[i][0].call(p.exports, function (r) {
                  var n = e[i][1][r];
                  return o(n || r);
                }, p, p.exports, r, e, n, t);
              }
              return n[i].exports;
            }
            for (var u = 'function' == typeof require && require, i = 0; i < t.length; i++)
              o(t[i]);
            return o;
          }
          return r;
        }()({
          1: [
            function (require, module, exports) {
              var process = module.exports = {};
              var cachedSetTimeout;
              var cachedClearTimeout;
              function defaultSetTimout() {
                throw new Error('setTimeout has not been defined');
              }
              function defaultClearTimeout() {
                throw new Error('clearTimeout has not been defined');
              }
              (function () {
                try {
                  if (typeof setTimeout === 'function') {
                    cachedSetTimeout = setTimeout;
                  } else {
                    cachedSetTimeout = defaultSetTimout;
                  }
                } catch (e) {
                  cachedSetTimeout = defaultSetTimout;
                }
                try {
                  if (typeof clearTimeout === 'function') {
                    cachedClearTimeout = clearTimeout;
                  } else {
                    cachedClearTimeout = defaultClearTimeout;
                  }
                } catch (e) {
                  cachedClearTimeout = defaultClearTimeout;
                }
              }());
              function runTimeout(fun) {
                if (cachedSetTimeout === setTimeout) {
                  return setTimeout(fun, 0);
                }
                if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
                  cachedSetTimeout = setTimeout;
                  return setTimeout(fun, 0);
                }
                try {
                  return cachedSetTimeout(fun, 0);
                } catch (e) {
                  try {
                    return cachedSetTimeout.call(null, fun, 0);
                  } catch (e) {
                    return cachedSetTimeout.call(this, fun, 0);
                  }
                }
              }
              function runClearTimeout(marker) {
                if (cachedClearTimeout === clearTimeout) {
                  return clearTimeout(marker);
                }
                if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
                  cachedClearTimeout = clearTimeout;
                  return clearTimeout(marker);
                }
                try {
                  return cachedClearTimeout(marker);
                } catch (e) {
                  try {
                    return cachedClearTimeout.call(null, marker);
                  } catch (e) {
                    return cachedClearTimeout.call(this, marker);
                  }
                }
              }
              var queue = [];
              var draining = false;
              var currentQueue;
              var queueIndex = -1;
              function cleanUpNextTick() {
                if (!draining || !currentQueue) {
                  return;
                }
                draining = false;
                if (currentQueue.length) {
                  queue = currentQueue.concat(queue);
                } else {
                  queueIndex = -1;
                }
                if (queue.length) {
                  drainQueue();
                }
              }
              function drainQueue() {
                if (draining) {
                  return;
                }
                var timeout = runTimeout(cleanUpNextTick);
                draining = true;
                var len = queue.length;
                while (len) {
                  currentQueue = queue;
                  queue = [];
                  while (++queueIndex < len) {
                    if (currentQueue) {
                      currentQueue[queueIndex].run();
                    }
                  }
                  queueIndex = -1;
                  len = queue.length;
                }
                currentQueue = null;
                draining = false;
                runClearTimeout(timeout);
              }
              process.nextTick = function (fun) {
                var args = new Array(arguments.length - 1);
                if (arguments.length > 1) {
                  for (var i = 1; i < arguments.length; i++) {
                    args[i - 1] = arguments[i];
                  }
                }
                queue.push(new Item(fun, args));
                if (queue.length === 1 && !draining) {
                  runTimeout(drainQueue);
                }
              };
              function Item(fun, array) {
                this.fun = fun;
                this.array = array;
              }
              Item.prototype.run = function () {
                this.fun.apply(null, this.array);
              };
              process.title = 'browser';
              process.browser = true;
              process.env = {};
              process.argv = [];
              process.version = '';
              process.versions = {};
              function noop() {
              }
              process.on = noop;
              process.addListener = noop;
              process.once = noop;
              process.off = noop;
              process.removeListener = noop;
              process.removeAllListeners = noop;
              process.emit = noop;
              process.prependListener = noop;
              process.prependOnceListener = noop;
              process.listeners = function (name) {
                return [];
              };
              process.binding = function (name) {
                throw new Error('process.binding is not supported');
              };
              process.cwd = function () {
                return '/';
              };
              process.chdir = function (dir) {
                throw new Error('process.chdir is not supported');
              };
              process.umask = function () {
                return 0;
              };
            },
            {}
          ],
          2: [
            function (require, module, exports) {
              (function (setImmediate) {
                (function (root) {
                  var setTimeoutFunc = setTimeout;
                  function noop() {
                  }
                  function bind(fn, thisArg) {
                    return function () {
                      fn.apply(thisArg, arguments);
                    };
                  }
                  function Promise(fn) {
                    if (typeof this !== 'object')
                      throw new TypeError('Promises must be constructed via new');
                    if (typeof fn !== 'function')
                      throw new TypeError('not a function');
                    this._state = 0;
                    this._handled = false;
                    this._value = undefined;
                    this._deferreds = [];
                    doResolve(fn, this);
                  }
                  function handle(self, deferred) {
                    while (self._state === 3) {
                      self = self._value;
                    }
                    if (self._state === 0) {
                      self._deferreds.push(deferred);
                      return;
                    }
                    self._handled = true;
                    Promise._immediateFn(function () {
                      var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
                      if (cb === null) {
                        (self._state === 1 ? resolve : reject)(deferred.promise, self._value);
                        return;
                      }
                      var ret;
                      try {
                        ret = cb(self._value);
                      } catch (e) {
                        reject(deferred.promise, e);
                        return;
                      }
                      resolve(deferred.promise, ret);
                    });
                  }
                  function resolve(self, newValue) {
                    try {
                      if (newValue === self)
                        throw new TypeError('A promise cannot be resolved with itself.');
                      if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
                        var then = newValue.then;
                        if (newValue instanceof Promise) {
                          self._state = 3;
                          self._value = newValue;
                          finale(self);
                          return;
                        } else if (typeof then === 'function') {
                          doResolve(bind(then, newValue), self);
                          return;
                        }
                      }
                      self._state = 1;
                      self._value = newValue;
                      finale(self);
                    } catch (e) {
                      reject(self, e);
                    }
                  }
                  function reject(self, newValue) {
                    self._state = 2;
                    self._value = newValue;
                    finale(self);
                  }
                  function finale(self) {
                    if (self._state === 2 && self._deferreds.length === 0) {
                      Promise._immediateFn(function () {
                        if (!self._handled) {
                          Promise._unhandledRejectionFn(self._value);
                        }
                      });
                    }
                    for (var i = 0, len = self._deferreds.length; i < len; i++) {
                      handle(self, self._deferreds[i]);
                    }
                    self._deferreds = null;
                  }
                  function Handler(onFulfilled, onRejected, promise) {
                    this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
                    this.onRejected = typeof onRejected === 'function' ? onRejected : null;
                    this.promise = promise;
                  }
                  function doResolve(fn, self) {
                    var done = false;
                    try {
                      fn(function (value) {
                        if (done)
                          return;
                        done = true;
                        resolve(self, value);
                      }, function (reason) {
                        if (done)
                          return;
                        done = true;
                        reject(self, reason);
                      });
                    } catch (ex) {
                      if (done)
                        return;
                      done = true;
                      reject(self, ex);
                    }
                  }
                  Promise.prototype['catch'] = function (onRejected) {
                    return this.then(null, onRejected);
                  };
                  Promise.prototype.then = function (onFulfilled, onRejected) {
                    var prom = new this.constructor(noop);
                    handle(this, new Handler(onFulfilled, onRejected, prom));
                    return prom;
                  };
                  Promise.all = function (arr) {
                    var args = Array.prototype.slice.call(arr);
                    return new Promise(function (resolve, reject) {
                      if (args.length === 0)
                        return resolve([]);
                      var remaining = args.length;
                      function res(i, val) {
                        try {
                          if (val && (typeof val === 'object' || typeof val === 'function')) {
                            var then = val.then;
                            if (typeof then === 'function') {
                              then.call(val, function (val) {
                                res(i, val);
                              }, reject);
                              return;
                            }
                          }
                          args[i] = val;
                          if (--remaining === 0) {
                            resolve(args);
                          }
                        } catch (ex) {
                          reject(ex);
                        }
                      }
                      for (var i = 0; i < args.length; i++) {
                        res(i, args[i]);
                      }
                    });
                  };
                  Promise.resolve = function (value) {
                    if (value && typeof value === 'object' && value.constructor === Promise) {
                      return value;
                    }
                    return new Promise(function (resolve) {
                      resolve(value);
                    });
                  };
                  Promise.reject = function (value) {
                    return new Promise(function (resolve, reject) {
                      reject(value);
                    });
                  };
                  Promise.race = function (values) {
                    return new Promise(function (resolve, reject) {
                      for (var i = 0, len = values.length; i < len; i++) {
                        values[i].then(resolve, reject);
                      }
                    });
                  };
                  Promise._immediateFn = typeof setImmediate === 'function' ? function (fn) {
                    setImmediate(fn);
                  } : function (fn) {
                    setTimeoutFunc(fn, 0);
                  };
                  Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {
                    if (typeof console !== 'undefined' && console) {
                      console.warn('Possible Unhandled Promise Rejection:', err);
                    }
                  };
                  Promise._setImmediateFn = function _setImmediateFn(fn) {
                    Promise._immediateFn = fn;
                  };
                  Promise._setUnhandledRejectionFn = function _setUnhandledRejectionFn(fn) {
                    Promise._unhandledRejectionFn = fn;
                  };
                  if (typeof module !== 'undefined' && module.exports) {
                    module.exports = Promise;
                  } else if (!root.Promise) {
                    root.Promise = Promise;
                  }
                }(this));
              }.call(this, require('timers').setImmediate));
            },
            { 'timers': 3 }
          ],
          3: [
            function (require, module, exports) {
              (function (setImmediate, clearImmediate) {
                var nextTick = require('process/browser.js').nextTick;
                var apply = Function.prototype.apply;
                var slice = Array.prototype.slice;
                var immediateIds = {};
                var nextImmediateId = 0;
                exports.setTimeout = function () {
                  return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);
                };
                exports.setInterval = function () {
                  return new Timeout(apply.call(setInterval, window, arguments), clearInterval);
                };
                exports.clearTimeout = exports.clearInterval = function (timeout) {
                  timeout.close();
                };
                function Timeout(id, clearFn) {
                  this._id = id;
                  this._clearFn = clearFn;
                }
                Timeout.prototype.unref = Timeout.prototype.ref = function () {
                };
                Timeout.prototype.close = function () {
                  this._clearFn.call(window, this._id);
                };
                exports.enroll = function (item, msecs) {
                  clearTimeout(item._idleTimeoutId);
                  item._idleTimeout = msecs;
                };
                exports.unenroll = function (item) {
                  clearTimeout(item._idleTimeoutId);
                  item._idleTimeout = -1;
                };
                exports._unrefActive = exports.active = function (item) {
                  clearTimeout(item._idleTimeoutId);
                  var msecs = item._idleTimeout;
                  if (msecs >= 0) {
                    item._idleTimeoutId = setTimeout(function onTimeout() {
                      if (item._onTimeout)
                        item._onTimeout();
                    }, msecs);
                  }
                };
                exports.setImmediate = typeof setImmediate === 'function' ? setImmediate : function (fn) {
                  var id = nextImmediateId++;
                  var args = arguments.length < 2 ? false : slice.call(arguments, 1);
                  immediateIds[id] = true;
                  nextTick(function onNextTick() {
                    if (immediateIds[id]) {
                      if (args) {
                        fn.apply(null, args);
                      } else {
                        fn.call(null);
                      }
                      exports.clearImmediate(id);
                    }
                  });
                  return id;
                };
                exports.clearImmediate = typeof clearImmediate === 'function' ? clearImmediate : function (id) {
                  delete immediateIds[id];
                };
              }.call(this, require('timers').setImmediate, require('timers').clearImmediate));
            },
            {
              'process/browser.js': 1,
              'timers': 3
            }
          ],
          4: [
            function (require, module, exports) {
              var promisePolyfill = require('promise-polyfill');
              var Global = function () {
                if (typeof window !== 'undefined') {
                  return window;
                } else {
                  return Function('return this;')();
                }
              }();
              module.exports = { boltExport: Global.Promise || promisePolyfill };
            },
            { 'promise-polyfill': 2 }
          ]
        }, {}, [4])(4);
      }));
    }(undefined, exports$1, module$1, undefined));
    var Promise = module$1.exports.boltExport;

    var nu$3 = function (baseFn) {
      var data = Option.none();
      var callbacks = [];
      var map = function (f) {
        return nu$3(function (nCallback) {
          get(function (data) {
            nCallback(f(data));
          });
        });
      };
      var get = function (nCallback) {
        if (isReady()) {
          call(nCallback);
        } else {
          callbacks.push(nCallback);
        }
      };
      var set = function (x) {
        data = Option.some(x);
        run(callbacks);
        callbacks = [];
      };
      var isReady = function () {
        return data.isSome();
      };
      var run = function (cbs) {
        each(cbs, call);
      };
      var call = function (cb) {
        data.each(function (x) {
          domGlobals.setTimeout(function () {
            cb(x);
          }, 0);
        });
      };
      baseFn(set);
      return {
        get: get,
        map: map,
        isReady: isReady
      };
    };
    var pure = function (a) {
      return nu$3(function (callback) {
        callback(a);
      });
    };
    var LazyValue = {
      nu: nu$3,
      pure: pure
    };

    var errorReporter = function (err) {
      domGlobals.setTimeout(function () {
        throw err;
      }, 0);
    };
    var make = function (run) {
      var get = function (callback) {
        run().then(callback, errorReporter);
      };
      var map = function (fab) {
        return make(function () {
          return run().then(fab);
        });
      };
      var bind = function (aFutureB) {
        return make(function () {
          return run().then(function (v) {
            return aFutureB(v).toPromise();
          });
        });
      };
      var anonBind = function (futureB) {
        return make(function () {
          return run().then(function () {
            return futureB.toPromise();
          });
        });
      };
      var toLazy = function () {
        return LazyValue.nu(get);
      };
      var toCached = function () {
        var cache = null;
        return make(function () {
          if (cache === null) {
            cache = run();
          }
          return cache;
        });
      };
      var toPromise = run;
      return {
        map: map,
        bind: bind,
        anonBind: anonBind,
        toLazy: toLazy,
        toCached: toCached,
        toPromise: toPromise,
        get: get
      };
    };
    var nu$4 = function (baseFn) {
      return make(function () {
        return new Promise(baseFn);
      });
    };
    var pure$1 = function (a) {
      return make(function () {
        return Promise.resolve(a);
      });
    };
    var Future = {
      nu: nu$4,
      pure: pure$1
    };

    var par = function (asyncValues, nu) {
      return nu(function (callback) {
        var r = [];
        var count = 0;
        var cb = function (i) {
          return function (value) {
            r[i] = value;
            count++;
            if (count >= asyncValues.length) {
              callback(r);
            }
          };
        };
        if (asyncValues.length === 0) {
          callback([]);
        } else {
          each(asyncValues, function (asyncValue, i) {
            asyncValue.get(cb(i));
          });
        }
      });
    };

    var par$1 = function (futures) {
      return par(futures, Future.nu);
    };

    var value = function (o) {
      var is = function (v) {
        return o === v;
      };
      var or = function (opt) {
        return value(o);
      };
      var orThunk = function (f) {
        return value(o);
      };
      var map = function (f) {
        return value(f(o));
      };
      var mapError = function (f) {
        return value(o);
      };
      var each = function (f) {
        f(o);
      };
      var bind = function (f) {
        return f(o);
      };
      var fold = function (_, onValue) {
        return onValue(o);
      };
      var exists = function (f) {
        return f(o);
      };
      var forall = function (f) {
        return f(o);
      };
      var toOption = function () {
        return Option.some(o);
      };
      return {
        is: is,
        isValue: always,
        isError: never,
        getOr: constant(o),
        getOrThunk: constant(o),
        getOrDie: constant(o),
        or: or,
        orThunk: orThunk,
        fold: fold,
        map: map,
        mapError: mapError,
        each: each,
        bind: bind,
        exists: exists,
        forall: forall,
        toOption: toOption
      };
    };
    var error = function (message) {
      var getOrThunk = function (f) {
        return f();
      };
      var getOrDie = function () {
        return die(String(message))();
      };
      var or = function (opt) {
        return opt;
      };
      var orThunk = function (f) {
        return f();
      };
      var map = function (f) {
        return error(message);
      };
      var mapError = function (f) {
        return error(f(message));
      };
      var bind = function (f) {
        return error(message);
      };
      var fold = function (onError, _) {
        return onError(message);
      };
      return {
        is: never,
        isValue: never,
        isError: always,
        getOr: identity,
        getOrThunk: getOrThunk,
        getOrDie: getOrDie,
        or: or,
        orThunk: orThunk,
        fold: fold,
        map: map,
        mapError: mapError,
        each: noop,
        bind: bind,
        exists: never,
        forall: always,
        toOption: Option.none
      };
    };
    var fromOption = function (opt, err) {
      return opt.fold(function () {
        return error(err);
      }, value);
    };
    var Result = {
      value: value,
      error: error,
      fromOption: fromOption
    };

    var promise = function () {
      function bind(fn, thisArg) {
        return function () {
          fn.apply(thisArg, arguments);
        };
      }
      var isArray = Array.isArray || function (value) {
        return Object.prototype.toString.call(value) === '[object Array]';
      };
      var Promise = function (fn) {
        if (typeof this !== 'object') {
          throw new TypeError('Promises must be constructed via new');
        }
        if (typeof fn !== 'function') {
          throw new TypeError('not a function');
        }
        this._state = null;
        this._value = null;
        this._deferreds = [];
        doResolve(fn, bind(resolve, this), bind(reject, this));
      };
      var asap = Promise.immediateFn || typeof domGlobals.setImmediate === 'function' && domGlobals.setImmediate || function (fn) {
        domGlobals.setTimeout(fn, 1);
      };
      function handle(deferred) {
        var me = this;
        if (this._state === null) {
          this._deferreds.push(deferred);
          return;
        }
        asap(function () {
          var cb = me._state ? deferred.onFulfilled : deferred.onRejected;
          if (cb === null) {
            (me._state ? deferred.resolve : deferred.reject)(me._value);
            return;
          }
          var ret;
          try {
            ret = cb(me._value);
          } catch (e) {
            deferred.reject(e);
            return;
          }
          deferred.resolve(ret);
        });
      }
      function resolve(newValue) {
        try {
          if (newValue === this) {
            throw new TypeError('A promise cannot be resolved with itself.');
          }
          if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
            var then = newValue.then;
            if (typeof then === 'function') {
              doResolve(bind(then, newValue), bind(resolve, this), bind(reject, this));
              return;
            }
          }
          this._state = true;
          this._value = newValue;
          finale.call(this);
        } catch (e) {
          reject.call(this, e);
        }
      }
      function reject(newValue) {
        this._state = false;
        this._value = newValue;
        finale.call(this);
      }
      function finale() {
        for (var i = 0, len = this._deferreds.length; i < len; i++) {
          handle.call(this, this._deferreds[i]);
        }
        this._deferreds = null;
      }
      function Handler(onFulfilled, onRejected, resolve, reject) {
        this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
        this.onRejected = typeof onRejected === 'function' ? onRejected : null;
        this.resolve = resolve;
        this.reject = reject;
      }
      function doResolve(fn, onFulfilled, onRejected) {
        var done = false;
        try {
          fn(function (value) {
            if (done) {
              return;
            }
            done = true;
            onFulfilled(value);
          }, function (reason) {
            if (done) {
              return;
            }
            done = true;
            onRejected(reason);
          });
        } catch (ex) {
          if (done) {
            return;
          }
          done = true;
          onRejected(ex);
        }
      }
      Promise.prototype.catch = function (onRejected) {
        return this.then(null, onRejected);
      };
      Promise.prototype.then = function (onFulfilled, onRejected) {
        var me = this;
        return new Promise(function (resolve, reject) {
          handle.call(me, new Handler(onFulfilled, onRejected, resolve, reject));
        });
      };
      Promise.all = function () {
        var args = Array.prototype.slice.call(arguments.length === 1 && isArray(arguments[0]) ? arguments[0] : arguments);
        return new Promise(function (resolve, reject) {
          if (args.length === 0) {
            return resolve([]);
          }
          var remaining = args.length;
          function res(i, val) {
            try {
              if (val && (typeof val === 'object' || typeof val === 'function')) {
                var then = val.then;
                if (typeof then === 'function') {
                  then.call(val, function (val) {
                    res(i, val);
                  }, reject);
                  return;
                }
              }
              args[i] = val;
              if (--remaining === 0) {
                resolve(args);
              }
            } catch (ex) {
              reject(ex);
            }
          }
          for (var i = 0; i < args.length; i++) {
            res(i, args[i]);
          }
        });
      };
      Promise.resolve = function (value) {
        if (value && typeof value === 'object' && value.constructor === Promise) {
          return value;
        }
        return new Promise(function (resolve) {
          resolve(value);
        });
      };
      Promise.reject = function (value) {
        return new Promise(function (resolve, reject) {
          reject(value);
        });
      };
      Promise.race = function (values) {
        return new Promise(function (resolve, reject) {
          for (var i = 0, len = values.length; i < len; i++) {
            values[i].then(resolve, reject);
          }
        });
      };
      return Promise;
    };
    var promiseObj = window.Promise ? window.Promise : promise();

    var requestAnimationFramePromise;
    var requestAnimationFrame = function (callback, element) {
      var i, requestAnimationFrameFunc = domGlobals.window.requestAnimationFrame;
      var vendors = [
        'ms',
        'moz',
        'webkit'
      ];
      var featurefill = function (callback) {
        domGlobals.window.setTimeout(callback, 0);
      };
      for (i = 0; i < vendors.length && !requestAnimationFrameFunc; i++) {
        requestAnimationFrameFunc = domGlobals.window[vendors[i] + 'RequestAnimationFrame'];
      }
      if (!requestAnimationFrameFunc) {
        requestAnimationFrameFunc = featurefill;
      }
      requestAnimationFrameFunc(callback, element);
    };
    var wrappedSetTimeout = function (callback, time) {
      if (typeof time !== 'number') {
        time = 0;
      }
      return domGlobals.setTimeout(callback, time);
    };
    var wrappedSetInterval = function (callback, time) {
      if (typeof time !== 'number') {
        time = 1;
      }
      return domGlobals.setInterval(callback, time);
    };
    var wrappedClearTimeout = function (id) {
      return domGlobals.clearTimeout(id);
    };
    var wrappedClearInterval = function (id) {
      return domGlobals.clearInterval(id);
    };
    var debounce = function (callback, time) {
      var timer, func;
      func = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
          args[_i] = arguments[_i];
        }
        domGlobals.clearTimeout(timer);
        timer = wrappedSetTimeout(function () {
          callback.apply(this, args);
        }, time);
      };
      func.stop = function () {
        domGlobals.clearTimeout(timer);
      };
      return func;
    };
    var Delay = {
      requestAnimationFrame: function (callback, element) {
        if (requestAnimationFramePromise) {
          requestAnimationFramePromise.then(callback);
          return;
        }
        requestAnimationFramePromise = new promiseObj(function (resolve) {
          if (!element) {
            element = domGlobals.document.body;
          }
          requestAnimationFrame(resolve, element);
        }).then(callback);
      },
      setTimeout: wrappedSetTimeout,
      setInterval: wrappedSetInterval,
      setEditorTimeout: function (editor, callback, time) {
        return wrappedSetTimeout(function () {
          if (!editor.removed) {
            callback();
          }
        }, time);
      },
      setEditorInterval: function (editor, callback, time) {
        var timer;
        timer = wrappedSetInterval(function () {
          if (!editor.removed) {
            callback();
          } else {
            domGlobals.clearInterval(timer);
          }
        }, time);
        return timer;
      },
      debounce: debounce,
      throttle: debounce,
      clearInterval: wrappedClearInterval,
      clearTimeout: wrappedClearTimeout
    };

    var userAgent = domGlobals.navigator.userAgent;
    var platform$1 = detect$3();
    var browser$2 = platform$1.browser;
    var os = platform$1.os;
    var deviceType = platform$1.deviceType;
    var webkit = /WebKit/.test(userAgent) && !browser$2.isEdge();
    var fileApi = 'FormData' in domGlobals.window && 'FileReader' in domGlobals.window && 'URL' in domGlobals.window && !!domGlobals.URL.createObjectURL;
    var windowsPhone = userAgent.indexOf('Windows Phone') !== -1;
    var Env = {
      opera: browser$2.isOpera(),
      webkit: webkit,
      ie: browser$2.isIE() || browser$2.isEdge() ? browser$2.version.major : false,
      gecko: browser$2.isFirefox(),
      mac: os.isOSX() || os.isiOS(),
      iOS: deviceType.isiPad() || deviceType.isiPhone(),
      android: os.isAndroid(),
      contentEditable: true,
      transparentSrc: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
      caretAfter: true,
      range: domGlobals.window.getSelection && 'Range' in domGlobals.window,
      documentMode: browser$2.isIE() ? domGlobals.document.documentMode || 7 : 10,
      fileApi: fileApi,
      ceFalse: true,
      cacheSuffix: null,
      container: null,
      experimentalShadowDom: false,
      canHaveCSP: !browser$2.isIE(),
      desktop: deviceType.isDesktop(),
      windowsPhone: windowsPhone,
      browser: {
        current: browser$2.current,
        version: browser$2.version,
        isChrome: browser$2.isChrome,
        isEdge: browser$2.isEdge,
        isFirefox: browser$2.isFirefox,
        isIE: browser$2.isIE,
        isOpera: browser$2.isOpera,
        isSafari: browser$2.isSafari
      },
      os: {
        current: os.current,
        version: os.version,
        isAndroid: os.isAndroid,
        isChromeOS: os.isChromeOS,
        isFreeBSD: os.isFreeBSD,
        isiOS: os.isiOS,
        isLinux: os.isLinux,
        isOSX: os.isOSX,
        isSolaris: os.isSolaris,
        isWindows: os.isWindows
      },
      deviceType: {
        isDesktop: deviceType.isDesktop,
        isiPad: deviceType.isiPad,
        isiPhone: deviceType.isiPhone,
        isPhone: deviceType.isPhone,
        isTablet: deviceType.isTablet,
        isTouch: deviceType.isTouch,
        isWebView: deviceType.isWebView
      }
    };

    var isArray$1 = Array.isArray;
    var toArray$1 = function (obj) {
      var array = obj, i, l;
      if (!isArray$1(obj)) {
        array = [];
        for (i = 0, l = obj.length; i < l; i++) {
          array[i] = obj[i];
        }
      }
      return array;
    };
    var each$2 = function (o, cb, s) {
      var n, l;
      if (!o) {
        return 0;
      }
      s = s || o;
      if (o.length !== undefined) {
        for (n = 0, l = o.length; n < l; n++) {
          if (cb.call(s, o[n], n, o) === false) {
            return 0;
          }
        }
      } else {
        for (n in o) {
          if (o.hasOwnProperty(n)) {
            if (cb.call(s, o[n], n, o) === false) {
              return 0;
            }
          }
        }
      }
      return 1;
    };
    var map$2 = function (array, callback) {
      var out = [];
      each$2(array, function (item, index) {
        out.push(callback(item, index, array));
      });
      return out;
    };
    var filter$1 = function (a, f) {
      var o = [];
      each$2(a, function (v, index) {
        if (!f || f(v, index, a)) {
          o.push(v);
        }
      });
      return o;
    };
    var indexOf$1 = function (a, v) {
      var i, l;
      if (a) {
        for (i = 0, l = a.length; i < l; i++) {
          if (a[i] === v) {
            return i;
          }
        }
      }
      return -1;
    };
    var reduce = function (collection, iteratee, accumulator, thisArg) {
      var i = 0;
      if (arguments.length < 3) {
        accumulator = collection[0];
      }
      for (; i < collection.length; i++) {
        accumulator = iteratee.call(thisArg, accumulator, collection[i], i);
      }
      return accumulator;
    };
    var findIndex$1 = function (array, predicate, thisArg) {
      var i, l;
      for (i = 0, l = array.length; i < l; i++) {
        if (predicate.call(thisArg, array[i], i, array)) {
          return i;
        }
      }
      return -1;
    };
    var find$2 = function (array, predicate, thisArg) {
      var idx = findIndex$1(array, predicate, thisArg);
      if (idx !== -1) {
        return array[idx];
      }
      return undefined;
    };
    var last$1 = function (collection) {
      return collection[collection.length - 1];
    };
    var ArrUtils = {
      isArray: isArray$1,
      toArray: toArray$1,
      each: each$2,
      map: map$2,
      filter: filter$1,
      indexOf: indexOf$1,
      reduce: reduce,
      findIndex: findIndex$1,
      find: find$2,
      last: last$1
    };

    var whiteSpaceRegExp = /^\s*|\s*$/g;
    var trim$1 = function (str) {
      return str === null || str === undefined ? '' : ('' + str).replace(whiteSpaceRegExp, '');
    };
    var is$1 = function (obj, type) {
      if (!type) {
        return obj !== undefined;
      }
      if (type === 'array' && ArrUtils.isArray(obj)) {
        return true;
      }
      return typeof obj === type;
    };
    var makeMap = function (items, delim, map) {
      var i;
      items = items || [];
      delim = delim || ',';
      if (typeof items === 'string') {
        items = items.split(delim);
      }
      map = map || {};
      i = items.length;
      while (i--) {
        map[items[i]] = {};
      }
      return map;
    };
    var hasOwnProperty$1 = function (obj, prop) {
      return Object.prototype.hasOwnProperty.call(obj, prop);
    };
    var create = function (s, p, root) {
      var self = this;
      var sp, ns, cn, scn, c, de = 0;
      s = /^((static) )?([\w.]+)(:([\w.]+))?/.exec(s);
      cn = s[3].match(/(^|\.)(\w+)$/i)[2];
      ns = self.createNS(s[3].replace(/\.\w+$/, ''), root);
      if (ns[cn]) {
        return;
      }
      if (s[2] === 'static') {
        ns[cn] = p;
        if (this.onCreate) {
          this.onCreate(s[2], s[3], ns[cn]);
        }
        return;
      }
      if (!p[cn]) {
        p[cn] = function () {
        };
        de = 1;
      }
      ns[cn] = p[cn];
      self.extend(ns[cn].prototype, p);
      if (s[5]) {
        sp = self.resolve(s[5]).prototype;
        scn = s[5].match(/\.(\w+)$/i)[1];
        c = ns[cn];
        if (de) {
          ns[cn] = function () {
            return sp[scn].apply(this, arguments);
          };
        } else {
          ns[cn] = function () {
            this.parent = sp[scn];
            return c.apply(this, arguments);
          };
        }
        ns[cn].prototype[cn] = ns[cn];
        self.each(sp, function (f, n) {
          ns[cn].prototype[n] = sp[n];
        });
        self.each(p, function (f, n) {
          if (sp[n]) {
            ns[cn].prototype[n] = function () {
              this.parent = sp[n];
              return f.apply(this, arguments);
            };
          } else {
            if (n !== cn) {
              ns[cn].prototype[n] = f;
            }
          }
        });
      }
      self.each(p.static, function (f, n) {
        ns[cn][n] = f;
      });
    };
    var extend = function (obj, ext) {
      var x = [];
      for (var _i = 2; _i < arguments.length; _i++) {
        x[_i - 2] = arguments[_i];
      }
      var i, l, name;
      var args = arguments;
      var value;
      for (i = 1, l = args.length; i < l; i++) {
        ext = args[i];
        for (name in ext) {
          if (ext.hasOwnProperty(name)) {
            value = ext[name];
            if (value !== undefined) {
              obj[name] = value;
            }
          }
        }
      }
      return obj;
    };
    var walk = function (o, f, n, s) {
      s = s || this;
      if (o) {
        if (n) {
          o = o[n];
        }
        ArrUtils.each(o, function (o, i) {
          if (f.call(s, o, i, n) === false) {
            return false;
          }
          walk(o, f, n, s);
        });
      }
    };
    var createNS = function (n, o) {
      var i, v;
      o = o || domGlobals.window;
      n = n.split('.');
      for (i = 0; i < n.length; i++) {
        v = n[i];
        if (!o[v]) {
          o[v] = {};
        }
        o = o[v];
      }
      return o;
    };
    var resolve = function (n, o) {
      var i, l;
      o = o || domGlobals.window;
      n = n.split('.');
      for (i = 0, l = n.length; i < l; i++) {
        o = o[n[i]];
        if (!o) {
          break;
        }
      }
      return o;
    };
    var explode = function (s, d) {
      if (!s || is$1(s, 'array')) {
        return s;
      }
      return ArrUtils.map(s.split(d || ','), trim$1);
    };
    var _addCacheSuffix = function (url) {
      var cacheSuffix = Env.cacheSuffix;
      if (cacheSuffix) {
        url += (url.indexOf('?') === -1 ? '?' : '&') + cacheSuffix;
      }
      return url;
    };
    var Tools = {
      trim: trim$1,
      isArray: ArrUtils.isArray,
      is: is$1,
      toArray: ArrUtils.toArray,
      makeMap: makeMap,
      each: ArrUtils.each,
      map: ArrUtils.map,
      grep: ArrUtils.filter,
      inArray: ArrUtils.indexOf,
      hasOwn: hasOwnProperty$1,
      extend: extend,
      create: create,
      walk: walk,
      createNS: createNS,
      resolve: resolve,
      explode: explode,
      _addCacheSuffix: _addCacheSuffix
    };

    function StyleSheetLoader(document, settings) {
      if (settings === void 0) {
        settings = {};
      }
      var idCount = 0;
      var loadedStates = {};
      var maxLoadTime;
      maxLoadTime = settings.maxLoadTime || 5000;
      var _setReferrerPolicy = function (referrerPolicy) {
        settings.referrerPolicy = referrerPolicy;
      };
      var appendToHead = function (node) {
        document.getElementsByTagName('head')[0].appendChild(node);
      };
      var load = function (url, loadedCallback, errorCallback) {
        var link, style, startTime, state;
        var resolve = function (status) {
          state.status = status;
          state.passed = [];
          state.failed = [];
          if (link) {
            link.onload = null;
            link.onerror = null;
            link = null;
          }
        };
        var passed = function () {
          var callbacks = state.passed;
          var i = callbacks.length;
          while (i--) {
            callbacks[i]();
          }
          resolve(2);
        };
        var failed = function () {
          var callbacks = state.failed;
          var i = callbacks.length;
          while (i--) {
            callbacks[i]();
          }
          resolve(3);
        };
        var isOldWebKit = function () {
          var webKitChunks = domGlobals.navigator.userAgent.match(/WebKit\/(\d*)/);
          return !!(webKitChunks && parseInt(webKitChunks[1], 10) < 536);
        };
        var wait = function (testCallback, waitCallback) {
          if (!testCallback()) {
            if (new Date().getTime() - startTime < maxLoadTime) {
              Delay.setTimeout(waitCallback);
            } else {
              failed();
            }
          }
        };
        var waitForWebKitLinkLoaded = function () {
          wait(function () {
            var styleSheets = document.styleSheets;
            var styleSheet, i = styleSheets.length, owner;
            while (i--) {
              styleSheet = styleSheets[i];
              owner = styleSheet.ownerNode ? styleSheet.ownerNode : styleSheet.owningElement;
              if (owner && owner.id === link.id) {
                passed();
                return true;
              }
            }
          }, waitForWebKitLinkLoaded);
        };
        var waitForGeckoLinkLoaded = function () {
          wait(function () {
            try {
              var cssRules = style.sheet.cssRules;
              passed();
              return !!cssRules;
            } catch (ex) {
            }
          }, waitForGeckoLinkLoaded);
        };
        url = Tools._addCacheSuffix(url);
        if (!loadedStates[url]) {
          state = {
            passed: [],
            failed: []
          };
          loadedStates[url] = state;
        } else {
          state = loadedStates[url];
        }
        if (loadedCallback) {
          state.passed.push(loadedCallback);
        }
        if (errorCallback) {
          state.failed.push(errorCallback);
        }
        if (state.status === 1) {
          return;
        }
        if (state.status === 2) {
          passed();
          return;
        }
        if (state.status === 3) {
          failed();
          return;
        }
        state.status = 1;
        link = document.createElement('link');
        link.rel = 'stylesheet';
        link.type = 'text/css';
        link.id = 'u' + idCount++;
        link.async = false;
        link.defer = false;
        startTime = new Date().getTime();
        if (settings.contentCssCors) {
          link.crossOrigin = 'anonymous';
        }
        if (settings.referrerPolicy) {
          set(Element.fromDom(link), 'referrerpolicy', settings.referrerPolicy);
        }
        if ('onload' in link && !isOldWebKit()) {
          link.onload = waitForWebKitLinkLoaded;
          link.onerror = failed;
        } else {
          if (domGlobals.navigator.userAgent.indexOf('Firefox') > 0) {
            style = document.createElement('style');
            style.textContent = '@import "' + url + '"';
            waitForGeckoLinkLoaded();
            appendToHead(style);
            return;
          }
          waitForWebKitLinkLoaded();
        }
        appendToHead(link);
        link.href = url;
      };
      var loadF = function (url) {
        return Future.nu(function (resolve) {
          load(url, compose(resolve, constant(Result.value(url))), compose(resolve, constant(Result.error(url))));
        });
      };
      var unbox = function (result) {
        return result.fold(identity, identity);
      };
      var loadAll = function (urls, success, failure) {
        par$1(map(urls, loadF)).get(function (result) {
          var parts = partition(result, function (r) {
            return r.isValue();
          });
          if (parts.fail.length > 0) {
            failure(parts.fail.map(unbox));
          } else {
            success(parts.pass.map(unbox));
          }
        });
      };
      return {
        load: load,
        loadAll: loadAll,
        _setReferrerPolicy: _setReferrerPolicy
      };
    }

    var blocks = [
      'article',
      'aside',
      'details',
      'div',
      'dt',
      'figcaption',
      'footer',
      'form',
      'fieldset',
      'header',
      'hgroup',
      'html',
      'main',
      'nav',
      'section',
      'summary',
      'body',
      'p',
      'dl',
      'multicol',
      'dd',
      'figure',
      'address',
      'center',
      'blockquote',
      'h1',
      'h2',
      'h3',
      'h4',
      'h5',
      'h6',
      'listing',
      'xmp',
      'pre',
      'plaintext',
      'menu',
      'dir',
      'ul',
      'ol',
      'li',
      'hr',
      'table',
      'tbody',
      'thead',
      'tfoot',
      'th',
      'tr',
      'td',
      'caption'
    ];
    var voids = [
      'area',
      'base',
      'basefont',
      'br',
      'col',
      'frame',
      'hr',
      'img',
      'input',
      'isindex',
      'link',
      'meta',
      'param',
      'embed',
      'source',
      'wbr',
      'track'
    ];
    var tableCells = [
      'td',
      'th'
    ];
    var tableSections = [
      'thead',
      'tbody',
      'tfoot'
    ];
    var textBlocks = [
      'h1',
      'h2',
      'h3',
      'h4',
      'h5',
      'h6',
      'p',
      'div',
      'address',
      'pre',
      'form',
      'blockquote',
      'center',
      'dir',
      'fieldset',
      'header',
      'footer',
      'article',
      'section',
      'hgroup',
      'aside',
      'nav',
      'figure'
    ];
    var headings = [
      'h1',
      'h2',
      'h3',
      'h4',
      'h5',
      'h6'
    ];
    var listItems = [
      'li',
      'dd',
      'dt'
    ];
    var lists = [
      'ul',
      'ol',
      'dl'
    ];
    var wsElements = [
      'pre',
      'script',
      'textarea',
      'style'
    ];
    var lazyLookup = function (items) {
      var lookup;
      return function (node) {
        lookup = lookup ? lookup : mapToObject(items, constant(true));
        return lookup.hasOwnProperty(name(node));
      };
    };
    var isHeading = lazyLookup(headings);
    var isBlock = lazyLookup(blocks);
    var isTable$1 = function (node) {
      return name(node) === 'table';
    };
    var isInline = function (node) {
      return isElement(node) && !isBlock(node);
    };
    var isBr$1 = function (node) {
      return isElement(node) && name(node) === 'br';
    };
    var isTextBlock = lazyLookup(textBlocks);
    var isList = lazyLookup(lists);
    var isListItem = lazyLookup(listItems);
    var isVoid = lazyLookup(voids);
    var isTableSection = lazyLookup(tableSections);
    var isTableCell = lazyLookup(tableCells);
    var isWsPreserveElement = lazyLookup(wsElements);

    var surroundedBySpans = function (node) {
      var previousIsSpan = node.previousSibling && node.previousSibling.nodeName === 'SPAN';
      var nextIsSpan = node.nextSibling && node.nextSibling.nodeName === 'SPAN';
      return previousIsSpan && nextIsSpan;
    };
    var isBookmarkNode = function (node) {
      return node && node.tagName === 'SPAN' && node.getAttribute('data-mce-type') === 'bookmark';
    };
    var trimNode = function (dom, node) {
      var i, children = node.childNodes;
      if (NodeType.isElement(node) && isBookmarkNode(node)) {
        return;
      }
      for (i = children.length - 1; i >= 0; i--) {
        trimNode(dom, children[i]);
      }
      if (NodeType.isDocument(node) === false) {
        if (NodeType.isText(node) && node.nodeValue.length > 0) {
          var trimmedLength = Tools.trim(node.nodeValue).length;
          if (dom.isBlock(node.parentNode) || trimmedLength > 0) {
            return;
          }
          if (trimmedLength === 0 && surroundedBySpans(node)) {
            return;
          }
        } else if (NodeType.isElement(node)) {
          children = node.childNodes;
          if (children.length === 1 && isBookmarkNode(children[0])) {
            node.parentNode.insertBefore(children[0], node);
          }
          if (children.length || isVoid(Element.fromDom(node))) {
            return;
          }
        }
        dom.remove(node);
      }
      return node;
    };
    var TrimNode = { trimNode: trimNode };

    var makeMap$1 = Tools.makeMap;
    var namedEntities, baseEntities, reverseEntities;
    var attrsCharsRegExp = /[&<>\"\u0060\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
    var textCharsRegExp = /[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
    var rawCharsRegExp = /[<>&\"\']/g;
    var entityRegExp = /&#([a-z0-9]+);?|&([a-z0-9]+);/gi;
    var asciiMap = {
      128: '\u20AC',
      130: '\u201A',
      131: '\u0192',
      132: '\u201E',
      133: '\u2026',
      134: '\u2020',
      135: '\u2021',
      136: '\u02c6',
      137: '\u2030',
      138: '\u0160',
      139: '\u2039',
      140: '\u0152',
      142: '\u017d',
      145: '\u2018',
      146: '\u2019',
      147: '\u201C',
      148: '\u201D',
      149: '\u2022',
      150: '\u2013',
      151: '\u2014',
      152: '\u02DC',
      153: '\u2122',
      154: '\u0161',
      155: '\u203A',
      156: '\u0153',
      158: '\u017e',
      159: '\u0178'
    };
    baseEntities = {
      '"': '&quot;',
      '\'': '&#39;',
      '<': '&lt;',
      '>': '&gt;',
      '&': '&amp;',
      '`': '&#96;'
    };
    reverseEntities = {
      '&lt;': '<',
      '&gt;': '>',
      '&amp;': '&',
      '&quot;': '"',
      '&apos;': '\''
    };
    var nativeDecode = function (text) {
      var elm;
      elm = Element.fromTag('div').dom();
      elm.innerHTML = text;
      return elm.textContent || elm.innerText || text;
    };
    var buildEntitiesLookup = function (items, radix) {
      var i, chr, entity;
      var lookup = {};
      if (items) {
        items = items.split(',');
        radix = radix || 10;
        for (i = 0; i < items.length; i += 2) {
          chr = String.fromCharCode(parseInt(items[i], radix));
          if (!baseEntities[chr]) {
            entity = '&' + items[i + 1] + ';';
            lookup[chr] = entity;
            lookup[entity] = chr;
          }
        }
        return lookup;
      }
    };
    namedEntities = buildEntitiesLookup('50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,' + '5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,' + '5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,' + '5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,' + '68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,' + '6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,' + '6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,' + '75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,' + '7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,' + '7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,' + 'sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,' + 'st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,' + 't9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,' + 'tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,' + 'u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,' + '81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,' + '8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,' + '8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,' + '8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,' + '8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,' + 'nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,' + 'rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,' + 'Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,' + '80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,' + '811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro', 32);
    var encodeRaw = function (text, attr) {
      return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {
        return baseEntities[chr] || chr;
      });
    };
    var encodeAllRaw = function (text) {
      return ('' + text).replace(rawCharsRegExp, function (chr) {
        return baseEntities[chr] || chr;
      });
    };
    var encodeNumeric = function (text, attr) {
      return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {
        if (chr.length > 1) {
          return '&#' + ((chr.charCodeAt(0) - 55296) * 1024 + (chr.charCodeAt(1) - 56320) + 65536) + ';';
        }
        return baseEntities[chr] || '&#' + chr.charCodeAt(0) + ';';
      });
    };
    var encodeNamed = function (text, attr, entities) {
      entities = entities || namedEntities;
      return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {
        return baseEntities[chr] || entities[chr] || chr;
      });
    };
    var getEncodeFunc = function (name, entities) {
      var entitiesMap = buildEntitiesLookup(entities) || namedEntities;
      var encodeNamedAndNumeric = function (text, attr) {
        return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {
          if (baseEntities[chr] !== undefined) {
            return baseEntities[chr];
          }
          if (entitiesMap[chr] !== undefined) {
            return entitiesMap[chr];
          }
          if (chr.length > 1) {
            return '&#' + ((chr.charCodeAt(0) - 55296) * 1024 + (chr.charCodeAt(1) - 56320) + 65536) + ';';
          }
          return '&#' + chr.charCodeAt(0) + ';';
        });
      };
      var encodeCustomNamed = function (text, attr) {
        return encodeNamed(text, attr, entitiesMap);
      };
      var nameMap = makeMap$1(name.replace(/\+/g, ','));
      if (nameMap.named && nameMap.numeric) {
        return encodeNamedAndNumeric;
      }
      if (nameMap.named) {
        if (entities) {
          return encodeCustomNamed;
        }
        return encodeNamed;
      }
      if (nameMap.numeric) {
        return encodeNumeric;
      }
      return encodeRaw;
    };
    var decode = function (text) {
      return text.replace(entityRegExp, function (all, numeric) {
        if (numeric) {
          if (numeric.charAt(0).toLowerCase() === 'x') {
            numeric = parseInt(numeric.substr(1), 16);
          } else {
            numeric = parseInt(numeric, 10);
          }
          if (numeric > 65535) {
            numeric -= 65536;
            return String.fromCharCode(55296 + (numeric >> 10), 56320 + (numeric & 1023));
          }
          return asciiMap[numeric] || String.fromCharCode(numeric);
        }
        return reverseEntities[all] || namedEntities[all] || nativeDecode(all);
      });
    };
    var Entities = {
      encodeRaw: encodeRaw,
      encodeAllRaw: encodeAllRaw,
      encodeNumeric: encodeNumeric,
      encodeNamed: encodeNamed,
      getEncodeFunc: getEncodeFunc,
      decode: decode
    };

    var mapCache = {}, dummyObj = {};
    var makeMap$2 = Tools.makeMap, each$3 = Tools.each, extend$1 = Tools.extend, explode$1 = Tools.explode, inArray = Tools.inArray;
    var split = function (items, delim) {
      items = Tools.trim(items);
      return items ? items.split(delim || ' ') : [];
    };
    var compileSchema = function (type) {
      var schema = {};
      var globalAttributes, blockContent;
      var phrasingContent, flowContent, html4BlockContent, html4PhrasingContent;
      var add = function (name, attributes, children) {
        var ni, attributesOrder, element;
        var arrayToMap = function (array, obj) {
          var map = {};
          var i, l;
          for (i = 0, l = array.length; i < l; i++) {
            map[array[i]] = obj || {};
          }
          return map;
        };
        children = children || [];
        attributes = attributes || '';
        if (typeof children === 'string') {
          children = split(children);
        }
        name = split(name);
        ni = name.length;
        while (ni--) {
          attributesOrder = split([
            globalAttributes,
            attributes
          ].join(' '));
          element = {
            attributes: arrayToMap(attributesOrder),
            attributesOrder: attributesOrder,
            children: arrayToMap(children, dummyObj)
          };
          schema[name[ni]] = element;
        }
      };
      var addAttrs = function (name, attributes) {
        var ni, schemaItem, i, l;
        name = split(name);
        ni = name.length;
        attributes = split(attributes);
        while (ni--) {
          schemaItem = schema[name[ni]];
          for (i = 0, l = attributes.length; i < l; i++) {
            schemaItem.attributes[attributes[i]] = {};
            schemaItem.attributesOrder.push(attributes[i]);
          }
        }
      };
      if (mapCache[type]) {
        return mapCache[type];
      }
      globalAttributes = 'id accesskey class dir lang style tabindex title role';
      blockContent = 'address blockquote div dl fieldset form h1 h2 h3 h4 h5 h6 hr menu ol p pre table ul';
      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';
      if (type !== 'html4') {
        globalAttributes += ' contenteditable contextmenu draggable dropzone ' + 'hidden spellcheck translate';
        blockContent += ' article aside details dialog figure main header footer hgroup section nav';
        phrasingContent += ' audio canvas command datalist mark meter output picture ' + 'progress time wbr video ruby bdi keygen';
      }
      if (type !== 'html5-strict') {
        globalAttributes += ' xml:lang';
        html4PhrasingContent = 'acronym applet basefont big font strike tt';
        phrasingContent = [
          phrasingContent,
          html4PhrasingContent
        ].join(' ');
        each$3(split(html4PhrasingContent), function (name) {
          add(name, '', phrasingContent);
        });
        html4BlockContent = 'center dir isindex noframes';
        blockContent = [
          blockContent,
          html4BlockContent
        ].join(' ');
        flowContent = [
          blockContent,
          phrasingContent
        ].join(' ');
        each$3(split(html4BlockContent), function (name) {
          add(name, '', flowContent);
        });
      }
      flowContent = flowContent || [
        blockContent,
        phrasingContent
      ].join(' ');
      add('html', 'manifest', 'head body');
      add('head', '', 'base command link meta noscript script style title');
      add('title hr noscript br');
      add('base', 'href target');
      add('link', 'href rel media hreflang type sizes hreflang');
      add('meta', 'name http-equiv content charset');
      add('style', 'media type scoped');
      add('script', 'src async defer type charset');
      add('body', 'onafterprint onbeforeprint onbeforeunload onblur onerror onfocus ' + 'onhashchange onload onmessage onoffline ononline onpagehide onpageshow ' + 'onpopstate onresize onscroll onstorage onunload', flowContent);
      add('address dt dd div caption', '', flowContent);
      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);
      add('blockquote', 'cite', flowContent);
      add('ol', 'reversed start type', 'li');
      add('ul', '', 'li');
      add('li', 'value', flowContent);
      add('dl', '', 'dt dd');
      add('a', 'href target rel media hreflang type', phrasingContent);
      add('q', 'cite', phrasingContent);
      add('ins del', 'cite datetime', flowContent);
      add('img', 'src sizes srcset alt usemap ismap width height');
      add('iframe', 'src name width height', flowContent);
      add('embed', 'src type width height');
      add('object', 'data type typemustmatch name usemap form width height', [
        flowContent,
        'param'
      ].join(' '));
      add('param', 'name value');
      add('map', 'name', [
        flowContent,
        'area'
      ].join(' '));
      add('area', 'alt coords shape href target rel media hreflang type');
      add('table', 'border', 'caption colgroup thead tfoot tbody tr' + (type === 'html4' ? ' col' : ''));
      add('colgroup', 'span', 'col');
      add('col', 'span');
      add('tbody thead tfoot', '', 'tr');
      add('tr', '', 'td th');
      add('td', 'colspan rowspan headers', flowContent);
      add('th', 'colspan rowspan headers scope abbr', flowContent);
      add('form', 'accept-charset action autocomplete enctype method name novalidate target', flowContent);
      add('fieldset', 'disabled form name', [
        flowContent,
        'legend'
      ].join(' '));
      add('label', 'form for', phrasingContent);
      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');
      add('button', 'disabled form formaction formenctype formmethod formnovalidate formtarget name type value', type === 'html4' ? flowContent : phrasingContent);
      add('select', 'disabled form multiple name required size', 'option optgroup');
      add('optgroup', 'disabled label', 'option');
      add('option', 'disabled label selected value');
      add('textarea', 'cols dirname disabled form maxlength name readonly required rows wrap');
      add('menu', 'type label', [
        flowContent,
        'li'
      ].join(' '));
      add('noscript', '', flowContent);
      if (type !== 'html4') {
        add('wbr');
        add('ruby', '', [
          phrasingContent,
          'rt rp'
        ].join(' '));
        add('figcaption', '', flowContent);
        add('mark rt rp summary bdi', '', phrasingContent);
        add('canvas', 'width height', flowContent);
        add('video', 'src crossorigin poster preload autoplay mediagroup loop ' + 'muted controls width height buffered', [
          flowContent,
          'track source'
        ].join(' '));
        add('audio', 'src crossorigin preload autoplay mediagroup loop muted controls ' + 'buffered volume', [
          flowContent,
          'track source'
        ].join(' '));
        add('picture', '', 'img source');
        add('source', 'src srcset type media sizes');
        add('track', 'kind src srclang label default');
        add('datalist', '', [
          phrasingContent,
          'option'
        ].join(' '));
        add('article section nav aside main header footer', '', flowContent);
        add('hgroup', '', 'h1 h2 h3 h4 h5 h6');
        add('figure', '', [
          flowContent,
          'figcaption'
        ].join(' '));
        add('time', 'datetime', phrasingContent);
        add('dialog', 'open', flowContent);
        add('command', 'type label icon disabled checked radiogroup command');
        add('output', 'for form name', phrasingContent);
        add('progress', 'value max', phrasingContent);
        add('meter', 'value min max low high optimum', phrasingContent);
        add('details', 'open', [
          flowContent,
          'summary'
        ].join(' '));
        add('keygen', 'autofocus challenge disabled form keytype name');
      }
      if (type !== 'html5-strict') {
        addAttrs('script', 'language xml:space');
        addAttrs('style', 'xml:space');
        addAttrs('object', 'declare classid code codebase codetype archive standby align border hspace vspace');
        addAttrs('embed', 'align name hspace vspace');
        addAttrs('param', 'valuetype type');
        addAttrs('a', 'charset name rev shape coords');
        addAttrs('br', 'clear');
        addAttrs('applet', 'codebase archive code object alt name width height align hspace vspace');
        addAttrs('img', 'name longdesc align border hspace vspace');
        addAttrs('iframe', 'longdesc frameborder marginwidth marginheight scrolling align');
        addAttrs('font basefont', 'size color face');
        addAttrs('input', 'usemap align');
        addAttrs('select');
        addAttrs('textarea');
        addAttrs('h1 h2 h3 h4 h5 h6 div p legend caption', 'align');
        addAttrs('ul', 'type compact');
        addAttrs('li', 'type');
        addAttrs('ol dl menu dir', 'compact');
        addAttrs('pre', 'width xml:space');
        addAttrs('hr', 'align noshade size width');
        addAttrs('isindex', 'prompt');
        addAttrs('table', 'summary width frame rules cellspacing cellpadding align bgcolor');
        addAttrs('col', 'width align char charoff valign');
        addAttrs('colgroup', 'width align char charoff valign');
        addAttrs('thead', 'align char charoff valign');
        addAttrs('tr', 'align char charoff valign bgcolor');
        addAttrs('th', 'axis align char charoff valign nowrap bgcolor width height');
        addAttrs('form', 'accept');
        addAttrs('td', 'abbr axis scope align char charoff valign nowrap bgcolor width height');
        addAttrs('tfoot', 'align char charoff valign');
        addAttrs('tbody', 'align char charoff valign');
        addAttrs('area', 'nohref');
        addAttrs('body', 'background bgcolor text link vlink alink');
      }
      if (type !== 'html4') {
        addAttrs('input button select textarea', 'autofocus');
        addAttrs('input textarea', 'placeholder');
        addAttrs('a', 'download');
        addAttrs('link script img', 'crossorigin');
        addAttrs('img', 'loading');
        addAttrs('iframe', 'sandbox seamless allowfullscreen loading');
      }
      each$3(split('a form meter progress dfn'), function (name) {
        if (schema[name]) {
          delete schema[name].children[name];
        }
      });
      delete schema.caption.children.table;
      delete schema.script;
      mapCache[type] = schema;
      return schema;
    };
    var compileElementMap = function (value, mode) {
      var styles;
      if (value) {
        styles = {};
        if (typeof value === 'string') {
          value = { '*': value };
        }
        each$3(value, function (value, key) {
          styles[key] = styles[key.toUpperCase()] = mode === 'map' ? makeMap$2(value, /[, ]/) : explode$1(value, /[, ]/);
        });
      }
      return styles;
    };
    function Schema(settings) {
      var elements = {};
      var children = {};
      var patternElements = [];
      var validStyles;
      var invalidStyles;
      var schemaItems;
      var whiteSpaceElementsMap, selfClosingElementsMap, shortEndedElementsMap, boolAttrMap, validClasses;
      var blockElementsMap, nonEmptyElementsMap, moveCaretBeforeOnEnterElementsMap, textBlockElementsMap, textInlineElementsMap;
      var customElementsMap = {}, specialElements = {};
      var createLookupTable = function (option, defaultValue, extendWith) {
        var value = settings[option];
        if (!value) {
          value = mapCache[option];
          if (!value) {
            value = makeMap$2(defaultValue, ' ', makeMap$2(defaultValue.toUpperCase(), ' '));
            value = extend$1(value, extendWith);
            mapCache[option] = value;
          }
        } else {
          value = makeMap$2(value, /[, ]/, makeMap$2(value.toUpperCase(), /[, ]/));
        }
        return value;
      };
      settings = settings || {};
      schemaItems = compileSchema(settings.schema);
      if (settings.verify_html === false) {
        settings.valid_elements = '*[*]';
      }
      validStyles = compileElementMap(settings.valid_styles);
      invalidStyles = compileElementMap(settings.invalid_styles, 'map');
      validClasses = compileElementMap(settings.valid_classes, 'map');
      whiteSpaceElementsMap = createLookupTable('whitespace_elements', 'pre script noscript style textarea video audio iframe object code');
      selfClosingElementsMap = createLookupTable('self_closing_elements', 'colgroup dd dt li option p td tfoot th thead tr');
      shortEndedElementsMap = createLookupTable('short_ended_elements', 'area base basefont br col frame hr img input isindex link ' + 'meta param embed source wbr track');
      boolAttrMap = createLookupTable('boolean_attributes', 'checked compact declare defer disabled ismap multiple nohref noresize ' + 'noshade nowrap readonly selected autoplay loop controls');
      nonEmptyElementsMap = createLookupTable('non_empty_elements', 'td th iframe video audio object ' + 'script pre code', shortEndedElementsMap);
      moveCaretBeforeOnEnterElementsMap = createLookupTable('move_caret_before_on_enter_elements', 'table', nonEmptyElementsMap);
      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');
      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);
      textInlineElementsMap = createLookupTable('text_inline_elements', 'span strong b em i font strike u var cite ' + 'dfn code mark q sup sub samp');
      each$3((settings.special || 'script noscript noframes noembed title style textarea xmp').split(' '), function (name) {
        specialElements[name] = new RegExp('</' + name + '[^>]*>', 'gi');
      });
      var patternToRegExp = function (str) {
        return new RegExp('^' + str.replace(/([?+*])/g, '.$1') + '$');
      };
      var addValidElements = function (validElements) {
        var ei, el, ai, al, matches, element, attr, attrData, elementName, attrName, attrType, attributes, attributesOrder, prefix, outputName, globalAttributes, globalAttributesOrder, key, value;
        var elementRuleRegExp = /^([#+\-])?([^\[!\/]+)(?:\/([^\[!]+))?(?:(!?)\[([^\]]+)\])?$/, attrRuleRegExp = /^([!\-])?(\w+[\\:]:\w+|[^=:<]+)?(?:([=:<])(.*))?$/, hasPatternsRegExp = /[*?+]/;
        if (validElements) {
          validElements = split(validElements, ',');
          if (elements['@']) {
            globalAttributes = elements['@'].attributes;
            globalAttributesOrder = elements['@'].attributesOrder;
          }
          for (ei = 0, el = validElements.length; ei < el; ei++) {
            matches = elementRuleRegExp.exec(validElements[ei]);
            if (matches) {
              prefix = matches[1];
              elementName = matches[2];
              outputName = matches[3];
              attrData = matches[5];
              attributes = {};
              attributesOrder = [];
              element = {
                attributes: attributes,
                attributesOrder: attributesOrder
              };
              if (prefix === '#') {
                element.paddEmpty = true;
              }
              if (prefix === '-') {
                element.removeEmpty = true;
              }
              if (matches[4] === '!') {
                element.removeEmptyAttrs = true;
              }
              if (globalAttributes) {
                for (key in globalAttributes) {
                  attributes[key] = globalAttributes[key];
                }
                attributesOrder.push.apply(attributesOrder, globalAttributesOrder);
              }
              if (attrData) {
                attrData = split(attrData, '|');
                for (ai = 0, al = attrData.length; ai < al; ai++) {
                  matches = attrRuleRegExp.exec(attrData[ai]);
                  if (matches) {
                    attr = {};
                    attrType = matches[1];
                    attrName = matches[2].replace(/[\\:]:/g, ':');
                    prefix = matches[3];
                    value = matches[4];
                    if (attrType === '!') {
                      element.attributesRequired = element.attributesRequired || [];
                      element.attributesRequired.push(attrName);
                      attr.required = true;
                    }
                    if (attrType === '-') {
                      delete attributes[attrName];
                      attributesOrder.splice(inArray(attributesOrder, attrName), 1);
                      continue;
                    }
                    if (prefix) {
                      if (prefix === '=') {
                        element.attributesDefault = element.attributesDefault || [];
                        element.attributesDefault.push({
                          name: attrName,
                          value: value
                        });
                        attr.defaultValue = value;
                      }
                      if (prefix === ':') {
                        element.attributesForced = element.attributesForced || [];
                        element.attributesForced.push({
                          name: attrName,
                          value: value
                        });
                        attr.forcedValue = value;
                      }
                      if (prefix === '<') {
                        attr.validValues = makeMap$2(value, '?');
                      }
                    }
                    if (hasPatternsRegExp.test(attrName)) {
                      element.attributePatterns = element.attributePatterns || [];
                      attr.pattern = patternToRegExp(attrName);
                      element.attributePatterns.push(attr);
                    } else {
                      if (!attributes[attrName]) {
                        attributesOrder.push(attrName);
                      }
                      attributes[attrName] = attr;
                    }
                  }
                }
              }
              if (!globalAttributes && elementName === '@') {
                globalAttributes = attributes;
                globalAttributesOrder = attributesOrder;
              }
              if (outputName) {
                element.outputName = elementName;
                elements[outputName] = element;
              }
              if (hasPatternsRegExp.test(elementName)) {
                element.pattern = patternToRegExp(elementName);
                patternElements.push(element);
              } else {
                elements[elementName] = element;
              }
            }
          }
        }
      };
      var setValidElements = function (validElements) {
        elements = {};
        patternElements = [];
        addValidElements(validElements);
        each$3(schemaItems, function (element, name) {
          children[name] = element.children;
        });
      };
      var addCustomElements = function (customElements) {
        var customElementRegExp = /^(~)?(.+)$/;
        if (customElements) {
          mapCache.text_block_elements = mapCache.block_elements = null;
          each$3(split(customElements, ','), function (rule) {
            var matches = customElementRegExp.exec(rule), inline = matches[1] === '~', cloneName = inline ? 'span' : 'div', name = matches[2];
            children[name] = children[cloneName];
            customElementsMap[name] = cloneName;
            if (!inline) {
              blockElementsMap[name.toUpperCase()] = {};
              blockElementsMap[name] = {};
            }
            if (!elements[name]) {
              var customRule = elements[cloneName];
              customRule = extend$1({}, customRule);
              delete customRule.removeEmptyAttrs;
              delete customRule.removeEmpty;
              elements[name] = customRule;
            }
            each$3(children, function (element, elmName) {
              if (element[cloneName]) {
                children[elmName] = element = extend$1({}, children[elmName]);
                element[name] = element[cloneName];
              }
            });
          });
        }
      };
      var addValidChildren = function (validChildren) {
        var childRuleRegExp = /^([+\-]?)(\w+)\[([^\]]+)\]$/;
        mapCache[settings.schema] = null;
        if (validChildren) {
          each$3(split(validChildren, ','), function (rule) {
            var matches = childRuleRegExp.exec(rule);
            var parent, prefix;
            if (matches) {
              prefix = matches[1];
              if (prefix) {
                parent = children[matches[2]];
              } else {
                parent = children[matches[2]] = { '#comment': {} };
              }
              parent = children[matches[2]];
              each$3(split(matches[3], '|'), function (child) {
                if (prefix === '-') {
                  delete parent[child];
                } else {
                  parent[child] = {};
                }
              });
            }
          });
        }
      };
      var getElementRule = function (name) {
        var element = elements[name], i;
        if (element) {
          return element;
        }
        i = patternElements.length;
        while (i--) {
          element = patternElements[i];
          if (element.pattern.test(name)) {
            return element;
          }
        }
      };
      if (!settings.valid_elements) {
        each$3(schemaItems, function (element, name) {
          elements[name] = {
            attributes: element.attributes,
            attributesOrder: element.attributesOrder
          };
          children[name] = element.children;
        });
        if (settings.schema !== 'html5') {
          each$3(split('strong/b em/i'), function (item) {
            item = split(item, '/');
            elements[item[1]].outputName = item[0];
          });
        }
        each$3(split('ol ul sub sup blockquote span font a table tbody tr strong em b i'), function (name) {
          if (elements[name]) {
            elements[name].removeEmpty = true;
          }
        });
        each$3(split('p h1 h2 h3 h4 h5 h6 th td pre div address caption li'), function (name) {
          elements[name].paddEmpty = true;
        });
        each$3(split('span'), function (name) {
          elements[name].removeEmptyAttrs = true;
        });
      } else {
        setValidElements(settings.valid_elements);
      }
      addCustomElements(settings.custom_elements);
      addValidChildren(settings.valid_children);
      addValidElements(settings.extended_valid_elements);
      addValidChildren('+ol[ul|ol],+ul[ul|ol]');
      each$3({
        dd: 'dl',
        dt: 'dl',
        li: 'ul ol',
        td: 'tr',
        th: 'tr',
        tr: 'tbody thead tfoot',
        tbody: 'table',
        thead: 'table',
        tfoot: 'table',
        legend: 'fieldset',
        area: 'map',
        param: 'video audio object'
      }, function (parents, item) {
        if (elements[item]) {
          elements[item].parentsRequired = split(parents);
        }
      });
      if (settings.invalid_elements) {
        each$3(explode$1(settings.invalid_elements), function (item) {
          if (elements[item]) {
            delete elements[item];
          }
        });
      }
      if (!getElementRule('span')) {
        addValidElements('span[!data-mce-type|*]');
      }
      var getValidStyles = function () {
        return validStyles;
      };
      var getInvalidStyles = function () {
        return invalidStyles;
      };
      var getValidClasses = function () {
        return validClasses;
      };
      var getBoolAttrs = function () {
        return boolAttrMap;
      };
      var getBlockElements = function () {
        return blockElementsMap;
      };
      var getTextBlockElements = function () {
        return textBlockElementsMap;
      };
      var getTextInlineElements = function () {
        return textInlineElementsMap;
      };
      var getShortEndedElements = function () {
        return shortEndedElementsMap;
      };
      var getSelfClosingElements = function () {
        return selfClosingElementsMap;
      };
      var getNonEmptyElements = function () {
        return nonEmptyElementsMap;
      };
      var getMoveCaretBeforeOnEnterElements = function () {
        return moveCaretBeforeOnEnterElementsMap;
      };
      var getWhiteSpaceElements = function () {
        return whiteSpaceElementsMap;
      };
      var getSpecialElements = function () {
        return specialElements;
      };
      var isValidChild = function (name, child) {
        var parent = children[name.toLowerCase()];
        return !!(parent && parent[child.toLowerCase()]);
      };
      var isValid = function (name, attr) {
        var attrPatterns, i;
        var rule = getElementRule(name);
        if (rule) {
          if (attr) {
            if (rule.attributes[attr]) {
              return true;
            }
            attrPatterns = rule.attributePatterns;
            if (attrPatterns) {
              i = attrPatterns.length;
              while (i--) {
                if (attrPatterns[i].pattern.test(name)) {
                  return true;
                }
              }
            }
          } else {
            return true;
          }
        }
        return false;
      };
      var getCustomElements = function () {
        return customElementsMap;
      };
      return {
        children: children,
        elements: elements,
        getValidStyles: getValidStyles,
        getValidClasses: getValidClasses,
        getBlockElements: getBlockElements,
        getInvalidStyles: getInvalidStyles,
        getShortEndedElements: getShortEndedElements,
        getTextBlockElements: getTextBlockElements,
        getTextInlineElements: getTextInlineElements,
        getBoolAttrs: getBoolAttrs,
        getElementRule: getElementRule,
        getSelfClosingElements: getSelfClosingElements,
        getNonEmptyElements: getNonEmptyElements,
        getMoveCaretBeforeOnEnterElements: getMoveCaretBeforeOnEnterElements,
        getWhiteSpaceElements: getWhiteSpaceElements,
        getSpecialElements: getSpecialElements,
        isValidChild: isValidChild,
        isValid: isValid,
        getCustomElements: getCustomElements,
        addValidElements: addValidElements,
        setValidElements: setValidElements,
        addCustomElements: addCustomElements,
        addValidChildren: addValidChildren
      };
    }

    var zeroWidth = '\uFEFF';
    var nbsp = '\xA0';

    var toHex = function (match, r, g, b) {
      var hex = function (val) {
        val = parseInt(val, 10).toString(16);
        return val.length > 1 ? val : '0' + val;
      };
      return '#' + hex(r) + hex(g) + hex(b);
    };
    var Styles = function (settings, schema) {
      var rgbRegExp = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi;
      var urlOrStrRegExp = /(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi;
      var styleRegExp = /\s*([^:]+):\s*([^;]+);?/g;
      var trimRightRegExp = /\s+$/;
      var i;
      var encodingLookup = {};
      var encodingItems;
      var validStyles;
      var invalidStyles;
      var invisibleChar = zeroWidth;
      settings = settings || {};
      if (schema) {
        validStyles = schema.getValidStyles();
        invalidStyles = schema.getInvalidStyles();
      }
      encodingItems = ('\\" \\\' \\; \\: ; : ' + invisibleChar).split(' ');
      for (i = 0; i < encodingItems.length; i++) {
        encodingLookup[encodingItems[i]] = invisibleChar + i;
        encodingLookup[invisibleChar + i] = encodingItems[i];
      }
      return {
        toHex: function (color) {
          return color.replace(rgbRegExp, toHex);
        },
        parse: function (css) {
          var styles = {};
          var matches, name, value, isEncoded;
          var urlConverter = settings.url_converter;
          var urlConverterScope = settings.url_converter_scope || this;
          var compress = function (prefix, suffix, noJoin) {
            var top, right, bottom, left;
            top = styles[prefix + '-top' + suffix];
            if (!top) {
              return;
            }
            right = styles[prefix + '-right' + suffix];
            if (!right) {
              return;
            }
            bottom = styles[prefix + '-bottom' + suffix];
            if (!bottom) {
              return;
            }
            left = styles[prefix + '-left' + suffix];
            if (!left) {
              return;
            }
            var box = [
              top,
              right,
              bottom,
              left
            ];
            i = box.length - 1;
            while (i--) {
              if (box[i] !== box[i + 1]) {
                break;
              }
            }
            if (i > -1 && noJoin) {
              return;
            }
            styles[prefix + suffix] = i === -1 ? box[0] : box.join(' ');
            delete styles[prefix + '-top' + suffix];
            delete styles[prefix + '-right' + suffix];
            delete styles[prefix + '-bottom' + suffix];
            delete styles[prefix + '-left' + suffix];
          };
          var canCompress = function (key) {
            var value = styles[key], i;
            if (!value) {
              return;
            }
            value = value.split(' ');
            i = value.length;
            while (i--) {
              if (value[i] !== value[0]) {
                return false;
              }
            }
            styles[key] = value[0];
            return true;
          };
          var compress2 = function (target, a, b, c) {
            if (!canCompress(a)) {
              return;
            }
            if (!canCompress(b)) {
              return;
            }
            if (!canCompress(c)) {
              return;
            }
            styles[target] = styles[a] + ' ' + styles[b] + ' ' + styles[c];
            delete styles[a];
            delete styles[b];
            delete styles[c];
          };
          var encode = function (str) {
            isEncoded = true;
            return encodingLookup[str];
          };
          var decode = function (str, keepSlashes) {
            if (isEncoded) {
              str = str.replace(/\uFEFF[0-9]/g, function (str) {
                return encodingLookup[str];
              });
            }
            if (!keepSlashes) {
              str = str.replace(/\\([\'\";:])/g, '$1');
            }
            return str;
          };
          var decodeSingleHexSequence = function (escSeq) {
            return String.fromCharCode(parseInt(escSeq.slice(1), 16));
          };
          var decodeHexSequences = function (value) {
            return value.replace(/\\[0-9a-f]+/gi, decodeSingleHexSequence);
          };
          var processUrl = function (match, url, url2, url3, str, str2) {
            str = str || str2;
            if (str) {
              str = decode(str);
              return '\'' + str.replace(/\'/g, '\\\'') + '\'';
            }
            url = decode(url || url2 || url3);
            if (!settings.allow_script_urls) {
              var scriptUrl = url.replace(/[\s\r\n]+/g, '');
              if (/(java|vb)script:/i.test(scriptUrl)) {
                return '';
              }
              if (!settings.allow_svg_data_urls && /^data:image\/svg/i.test(scriptUrl)) {
                return '';
              }
            }
            if (urlConverter) {
              url = urlConverter.call(urlConverterScope, url, 'style');
            }
            return 'url(\'' + url.replace(/\'/g, '\\\'') + '\')';
          };
          if (css) {
            css = css.replace(/[\u0000-\u001F]/g, '');
            css = css.replace(/\\[\"\';:\uFEFF]/g, encode).replace(/\"[^\"]+\"|\'[^\']+\'/g, function (str) {
              return str.replace(/[;:]/g, encode);
            });
            while (matches = styleRegExp.exec(css)) {
              styleRegExp.lastIndex = matches.index + matches[0].length;
              name = matches[1].replace(trimRightRegExp, '').toLowerCase();
              value = matches[2].replace(trimRightRegExp, '');
              if (name && value) {
                name = decodeHexSequences(name);
                value = decodeHexSequences(value);
                if (name.indexOf(invisibleChar) !== -1 || name.indexOf('"') !== -1) {
                  continue;
                }
                if (!settings.allow_script_urls && (name === 'behavior' || /expression\s*\(|\/\*|\*\//.test(value))) {
                  continue;
                }
                if (name === 'font-weight' && value === '700') {
                  value = 'bold';
                } else if (name === 'color' || name === 'background-color') {
                  value = value.toLowerCase();
                }
                value = value.replace(rgbRegExp, toHex);
                value = value.replace(urlOrStrRegExp, processUrl);
                styles[name] = isEncoded ? decode(value, true) : value;
              }
            }
            compress('border', '', true);
            compress('border', '-width');
            compress('border', '-color');
            compress('border', '-style');
            compress('padding', '');
            compress('margin', '');
            compress2('border', 'border-width', 'border-style', 'border-color');
            if (styles.border === 'medium none') {
              delete styles.border;
            }
            if (styles['border-image'] === 'none') {
              delete styles['border-image'];
            }
          }
          return styles;
        },
        serialize: function (styles, elementName) {
          var css = '', name, value;
          var serializeStyles = function (name) {
            var styleList, i, l, value;
            styleList = validStyles[name];
            if (styleList) {
              for (i = 0, l = styleList.length; i < l; i++) {
                name = styleList[i];
                value = styles[name];
                if (value) {
                  css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';';
                }
              }
            }
          };
          var isValid = function (name, elementName) {
            var styleMap;
            styleMap = invalidStyles['*'];
            if (styleMap && styleMap[name]) {
              return false;
            }
            styleMap = invalidStyles[elementName];
            if (styleMap && styleMap[name]) {
              return false;
            }
            return true;
          };
          if (elementName && validStyles) {
            serializeStyles('*');
            serializeStyles(elementName);
          } else {
            for (name in styles) {
              value = styles[name];
              if (value && (!invalidStyles || isValid(name, elementName))) {
                css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';';
              }
            }
          }
          return css;
        }
      };
    };

    var eventExpandoPrefix = 'mce-data-';
    var mouseEventRe = /^(?:mouse|contextmenu)|click/;
    var deprecated = {
      keyLocation: 1,
      layerX: 1,
      layerY: 1,
      returnValue: 1,
      webkitMovementX: 1,
      webkitMovementY: 1,
      keyIdentifier: 1,
      mozPressure: 1
    };
    var hasIsDefaultPrevented = function (event) {
      return event.isDefaultPrevented === returnTrue || event.isDefaultPrevented === returnFalse;
    };
    var returnFalse = function () {
      return false;
    };
    var returnTrue = function () {
      return true;
    };
    var addEvent = function (target, name, callback, capture) {
      if (target.addEventListener) {
        target.addEventListener(name, callback, capture || false);
      } else if (target.attachEvent) {
        target.attachEvent('on' + name, callback);
      }
    };
    var removeEvent = function (target, name, callback, capture) {
      if (target.removeEventListener) {
        target.removeEventListener(name, callback, capture || false);
      } else if (target.detachEvent) {
        target.detachEvent('on' + name, callback);
      }
    };
    var getTargetFromShadowDom = function (event, defaultTarget) {
      if (event.composedPath) {
        var composedPath = event.composedPath();
        if (composedPath && composedPath.length > 0) {
          return composedPath[0];
        }
      }
      return defaultTarget;
    };
    var fix = function (originalEvent, data) {
      var name;
      var event = data || {};
      for (name in originalEvent) {
        if (!deprecated[name]) {
          event[name] = originalEvent[name];
        }
      }
      if (!event.target) {
        event.target = event.srcElement || domGlobals.document;
      }
      if (Env.experimentalShadowDom) {
        event.target = getTargetFromShadowDom(originalEvent, event.target);
      }
      if (originalEvent && mouseEventRe.test(originalEvent.type) && originalEvent.pageX === undefined && originalEvent.clientX !== undefined) {
        var eventDoc = event.target.ownerDocument || domGlobals.document;
        var doc = eventDoc.documentElement;
        var body = eventDoc.body;
        event.pageX = originalEvent.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
        event.pageY = originalEvent.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
      }
      event.preventDefault = function () {
        event.isDefaultPrevented = returnTrue;
        if (originalEvent) {
          if (originalEvent.preventDefault) {
            originalEvent.preventDefault();
          } else {
            originalEvent.returnValue = false;
          }
        }
      };
      event.stopPropagation = function () {
        event.isPropagationStopped = returnTrue;
        if (originalEvent) {
          if (originalEvent.stopPropagation) {
            originalEvent.stopPropagation();
          } else {
            originalEvent.cancelBubble = true;
          }
        }
      };
      event.stopImmediatePropagation = function () {
        event.isImmediatePropagationStopped = returnTrue;
        event.stopPropagation();
      };
      if (hasIsDefaultPrevented(event) === false) {
        event.isDefaultPrevented = returnFalse;
        event.isPropagationStopped = returnFalse;
        event.isImmediatePropagationStopped = returnFalse;
      }
      if (typeof event.metaKey === 'undefined') {
        event.metaKey = false;
      }
      return event;
    };
    var bindOnReady = function (win, callback, eventUtils) {
      var doc = win.document, event = { type: 'ready' };
      if (eventUtils.domLoaded) {
        callback(event);
        return;
      }
      var isDocReady = function () {
        return doc.readyState === 'complete' || doc.readyState === 'interactive' && doc.body;
      };
      var readyHandler = function () {
        removeEvent(win, 'DOMContentLoaded', readyHandler);
        removeEvent(win, 'load', readyHandler);
        if (!eventUtils.domLoaded) {
          eventUtils.domLoaded = true;
          callback(event);
        }
      };
      if (isDocReady()) {
        readyHandler();
      } else {
        addEvent(win, 'DOMContentLoaded', readyHandler);
      }
      addEvent(win, 'load', readyHandler);
    };
    var EventUtils = function () {
      function EventUtils() {
        this.domLoaded = false;
        this.events = {};
        this.count = 1;
        this.expando = eventExpandoPrefix + (+new Date()).toString(32);
        this.hasMouseEnterLeave = 'onmouseenter' in domGlobals.document.documentElement;
        this.hasFocusIn = 'onfocusin' in domGlobals.document.documentElement;
        this.count = 1;
      }
      EventUtils.prototype.bind = function (target, names, callback, scope) {
        var self = this;
        var id, callbackList, i, name, fakeName, nativeHandler, capture;
        var win = domGlobals.window;
        var defaultNativeHandler = function (evt) {
          self.executeHandlers(fix(evt || win.event), id);
        };
        if (!target || target.nodeType === 3 || target.nodeType === 8) {
          return;
        }
        if (!target[self.expando]) {
          id = self.count++;
          target[self.expando] = id;
          self.events[id] = {};
        } else {
          id = target[self.expando];
        }
        scope = scope || target;
        var namesList = names.split(' ');
        i = namesList.length;
        while (i--) {
          name = namesList[i];
          nativeHandler = defaultNativeHandler;
          fakeName = capture = false;
          if (name === 'DOMContentLoaded') {
            name = 'ready';
          }
          if (self.domLoaded && name === 'ready' && target.readyState === 'complete') {
            callback.call(scope, fix({ type: name }));
            continue;
          }
          if (!self.hasMouseEnterLeave) {
            fakeName = self.mouseEnterLeave[name];
            if (fakeName) {
              nativeHandler = function (evt) {
                var current, related;
                current = evt.currentTarget;
                related = evt.relatedTarget;
                if (related && current.contains) {
                  related = current.contains(related);
                } else {
                  while (related && related !== current) {
                    related = related.parentNode;
                  }
                }
                if (!related) {
                  evt = fix(evt || win.event);
                  evt.type = evt.type === 'mouseout' ? 'mouseleave' : 'mouseenter';
                  evt.target = current;
                  self.executeHandlers(evt, id);
                }
              };
            }
          }
          if (!self.hasFocusIn && (name === 'focusin' || name === 'focusout')) {
            capture = true;
            fakeName = name === 'focusin' ? 'focus' : 'blur';
            nativeHandler = function (evt) {
              evt = fix(evt || win.event);
              evt.type = evt.type === 'focus' ? 'focusin' : 'focusout';
              self.executeHandlers(evt, id);
            };
          }
          callbackList = self.events[id][name];
          if (!callbackList) {
            self.events[id][name] = callbackList = [{
                func: callback,
                scope: scope
              }];
            callbackList.fakeName = fakeName;
            callbackList.capture = capture;
            callbackList.nativeHandler = nativeHandler;
            if (name === 'ready') {
              bindOnReady(target, nativeHandler, self);
            } else {
              addEvent(target, fakeName || name, nativeHandler, capture);
            }
          } else {
            if (name === 'ready' && self.domLoaded) {
              callback(fix({ type: name }));
            } else {
              callbackList.push({
                func: callback,
                scope: scope
              });
            }
          }
        }
        target = callbackList = 0;
        return callback;
      };
      EventUtils.prototype.unbind = function (target, names, callback) {
        var id, callbackList, i, ci, name, eventMap;
        if (!target || target.nodeType === 3 || target.nodeType === 8) {
          return this;
        }
        id = target[this.expando];
        if (id) {
          eventMap = this.events[id];
          if (names) {
            var namesList = names.split(' ');
            i = namesList.length;
            while (i--) {
              name = namesList[i];
              callbackList = eventMap[name];
              if (callbackList) {
                if (callback) {
                  ci = callbackList.length;
                  while (ci--) {
                    if (callbackList[ci].func === callback) {
                      var nativeHandler = callbackList.nativeHandler;
                      var fakeName = callbackList.fakeName, capture = callbackList.capture;
                      callbackList = callbackList.slice(0, ci).concat(callbackList.slice(ci + 1));
                      callbackList.nativeHandler = nativeHandler;
                      callbackList.fakeName = fakeName;
                      callbackList.capture = capture;
                      eventMap[name] = callbackList;
                    }
                  }
                }
                if (!callback || callbackList.length === 0) {
                  delete eventMap[name];
                  removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture);
                }
              }
            }
          } else {
            for (name in eventMap) {
              callbackList = eventMap[name];
              removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture);
            }
            eventMap = {};
          }
          for (name in eventMap) {
            return this;
          }
          delete this.events[id];
          try {
            delete target[this.expando];
          } catch (ex) {
            target[this.expando] = null;
          }
        }
        return this;
      };
      EventUtils.prototype.fire = function (target, name, args) {
        var id;
        if (!target || target.nodeType === 3 || target.nodeType === 8) {
          return this;
        }
        var event = fix(null, args);
        event.type = name;
        event.target = target;
        do {
          id = target[this.expando];
          if (id) {
            this.executeHandlers(event, id);
          }
          target = target.parentNode || target.ownerDocument || target.defaultView || target.parentWindow;
        } while (target && !event.isPropagationStopped());
        return this;
      };
      EventUtils.prototype.clean = function (target) {
        var i, children;
        if (!target || target.nodeType === 3 || target.nodeType === 8) {
          return this;
        }
        if (target[this.expando]) {
          this.unbind(target);
        }
        if (!target.getElementsByTagName) {
          target = target.document;
        }
        if (target && target.getElementsByTagName) {
          this.unbind(target);
          children = target.getElementsByTagName('*');
          i = children.length;
          while (i--) {
            target = children[i];
            if (target[this.expando]) {
              this.unbind(target);
            }
          }
        }
        return this;
      };
      EventUtils.prototype.destroy = function () {
        this.events = {};
      };
      EventUtils.prototype.cancel = function (e) {
        if (e) {
          e.preventDefault();
          e.stopImmediatePropagation();
        }
        return false;
      };
      EventUtils.prototype.executeHandlers = function (evt, id) {
        var callbackList, i, l, callback;
        var container = this.events[id];
        callbackList = container && container[evt.type];
        if (callbackList) {
          for (i = 0, l = callbackList.length; i < l; i++) {
            callback = callbackList[i];
            if (callback && callback.func.call(callback.scope, evt) === false) {
              evt.preventDefault();
            }
            if (evt.isImmediatePropagationStopped()) {
              return;
            }
          }
        }
      };
      EventUtils.Event = new EventUtils();
      return EventUtils;
    }();

    var i, support, Expr, getText, isXML, tokenize, compile, select, outermostContext, sortInput, hasDuplicate, setDocument, document, docElem, documentIsHTML, rbuggyQSA, rbuggyMatches, matches, contains$3, expando = 'sizzle' + -new Date(), preferredDoc = domGlobals.window.document, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), sortOrder = function (a, b) {
        if (a === b) {
          hasDuplicate = true;
        }
        return 0;
      }, strundefined = typeof undefined, MAX_NEGATIVE = 1 << 31, hasOwn = {}.hasOwnProperty, arr = [], pop = arr.pop, push_native = arr.push, push = arr.push, slice = arr.slice, indexOf$2 = arr.indexOf || function (elem) {
        var i = 0, len = this.length;
        for (; i < len; i++) {
          if (this[i] === elem) {
            return i;
          }
        }
        return -1;
      }, 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 = {
        ID: new RegExp('^#(' + identifier + ')'),
        CLASS: new RegExp('^\\.(' + identifier + ')'),
        TAG: new RegExp('^(' + identifier + '|[*])'),
        ATTR: new RegExp('^' + attributes),
        PSEUDO: new RegExp('^' + pseudos),
        CHILD: new RegExp('^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(' + whitespace + '*(even|odd|(([+-]|)(\\d*)n|)' + whitespace + '*(?:([+-]|)' + whitespace + '*(\\d+)|))' + whitespace + '*\\)|)', 'i'),
        bool: new RegExp('^(?:' + booleans + ')$', 'i'),
        needsContext: new RegExp('^' + whitespace + '*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(' + whitespace + '*((?:-\\d)?\\d*)' + whitespace + '*\\)|)(?=[^-]|$)', 'i')
      }, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rnative = /^[^{]+\{\s*\[native \w/, rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rsibling = /[+~]/, rescape = /'|\\/g, runescape = new RegExp('\\\\([\\da-f]{1,6}' + whitespace + '?|(' + whitespace + ')|.)', 'ig'), funescape = function (_, escaped, escapedWhitespace) {
        var high = '0x' + escaped - 65536;
        return high !== high || escapedWhitespace ? escaped : high < 0 ? String.fromCharCode(high + 65536) : String.fromCharCode(high >> 10 | 55296, high & 1023 | 56320);
      };
    try {
      push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes);
      arr[preferredDoc.childNodes.length].nodeType;
    } catch (e) {
      push = {
        apply: arr.length ? function (target, els) {
          push_native.apply(target, slice.call(els));
        } : function (target, els) {
          var j = target.length, i = 0;
          while (target[j++] = els[i++]) {
          }
          target.length = j - 1;
        }
      };
    }
    var Sizzle = function (selector, context, results, seed) {
      var match, elem, m, nodeType, i, groups, old, nid, newContext, newSelector;
      if ((context ? context.ownerDocument || context : preferredDoc) !== document) {
        setDocument(context);
      }
      context = context || document;
      results = results || [];
      if (!selector || typeof selector !== 'string') {
        return results;
      }
      if ((nodeType = context.nodeType) !== 1 && nodeType !== 9) {
        return [];
      }
      if (documentIsHTML && !seed) {
        if (match = rquickExpr.exec(selector)) {
          if (m = match[1]) {
            if (nodeType === 9) {
              elem = context.getElementById(m);
              if (elem && elem.parentNode) {
                if (elem.id === m) {
                  results.push(elem);
                  return results;
                }
              } else {
                return results;
              }
            } else {
              if (context.ownerDocument && (elem = context.ownerDocument.getElementById(m)) && contains$3(context, elem) && elem.id === m) {
                results.push(elem);
                return results;
              }
            }
          } else if (match[2]) {
            push.apply(results, context.getElementsByTagName(selector));
            return results;
          } else if ((m = match[3]) && support.getElementsByClassName) {
            push.apply(results, context.getElementsByClassName(m));
            return results;
          }
        }
        if (support.qsa && (!rbuggyQSA || !rbuggyQSA.test(selector))) {
          nid = old = expando;
          newContext = context;
          newSelector = nodeType === 9 && selector;
          if (nodeType === 1 && context.nodeName.toLowerCase() !== 'object') {
            groups = tokenize(selector);
            if (old = context.getAttribute('id')) {
              nid = old.replace(rescape, '\\$&');
            } else {
              context.setAttribute('id', nid);
            }
            nid = '[id=\'' + nid + '\'] ';
            i = groups.length;
            while (i--) {
              groups[i] = nid + toSelector(groups[i]);
            }
            newContext = rsibling.test(selector) && testContext(context.parentNode) || context;
            newSelector = groups.join(',');
          }
          if (newSelector) {
            try {
              push.apply(results, newContext.querySelectorAll(newSelector));
              return results;
            } catch (qsaError) {
            } finally {
              if (!old) {
                context.removeAttribute('id');
              }
            }
          }
        }
      }
      return select(selector.replace(rtrim, '$1'), context, results, seed);
    };
    function createCache() {
      var keys = [];
      function cache(key, value) {
        if (keys.push(key + ' ') > Expr.cacheLength) {
          delete cache[keys.shift()];
        }
        return cache[key + ' '] = value;
      }
      return cache;
    }
    function markFunction(fn) {
      fn[expando] = true;
      return fn;
    }
    function siblingCheck(a, b) {
      var cur = b && a, diff = cur && a.nodeType === 1 && b.nodeType === 1 && (~b.sourceIndex || MAX_NEGATIVE) - (~a.sourceIndex || MAX_NEGATIVE);
      if (diff) {
        return diff;
      }
      if (cur) {
        while (cur = cur.nextSibling) {
          if (cur === b) {
            return -1;
          }
        }
      }
      return a ? 1 : -1;
    }
    function createInputPseudo(type) {
      return function (elem) {
        var name = elem.nodeName.toLowerCase();
        return name === 'input' && elem.type === type;
      };
    }
    function createButtonPseudo(type) {
      return function (elem) {
        var name = elem.nodeName.toLowerCase();
        return (name === 'input' || name === 'button') && elem.type === type;
      };
    }
    function createPositionalPseudo(fn) {
      return markFunction(function (argument) {
        argument = +argument;
        return markFunction(function (seed, matches) {
          var j, matchIndexes = fn([], seed.length, argument), i = matchIndexes.length;
          while (i--) {
            if (seed[j = matchIndexes[i]]) {
              seed[j] = !(matches[j] = seed[j]);
            }
          }
        });
      });
    }
    function testContext(context) {
      return context && typeof context.getElementsByTagName !== strundefined && context;
    }
    support = Sizzle.support = {};
    isXML = Sizzle.isXML = function (elem) {
      var documentElement = elem && (elem.ownerDocument || elem).documentElement;
      return documentElement ? documentElement.nodeName !== 'HTML' : false;
    };
    setDocument = Sizzle.setDocument = function (node) {
      var hasCompare, doc = node ? node.ownerDocument || node : preferredDoc, parent = doc.defaultView;
      function getTop(win) {
        try {
          return win.top;
        } catch (ex) {
        }
        return null;
      }
      if (doc === document || doc.nodeType !== 9 || !doc.documentElement) {
        return document;
      }
      document = doc;
      docElem = doc.documentElement;
      documentIsHTML = !isXML(doc);
      if (parent && parent !== getTop(parent)) {
        if (parent.addEventListener) {
          parent.addEventListener('unload', function () {
            setDocument();
          }, false);
        } else if (parent.attachEvent) {
          parent.attachEvent('onunload', function () {
            setDocument();
          });
        }
      }
      support.attributes = true;
      support.getElementsByTagName = true;
      support.getElementsByClassName = rnative.test(doc.getElementsByClassName);
      support.getById = true;
      Expr.find.ID = function (id, context) {
        if (typeof context.getElementById !== strundefined && documentIsHTML) {
          var m = context.getElementById(id);
          return m && m.parentNode ? [m] : [];
        }
      };
      Expr.filter.ID = function (id) {
        var attrId = id.replace(runescape, funescape);
        return function (elem) {
          return elem.getAttribute('id') === attrId;
        };
      };
      Expr.find.TAG = support.getElementsByTagName ? function (tag, context) {
        if (typeof context.getElementsByTagName !== strundefined) {
          return context.getElementsByTagName(tag);
        }
      } : function (tag, context) {
        var elem, tmp = [], i = 0, results = context.getElementsByTagName(tag);
        if (tag === '*') {
          while (elem = results[i++]) {
            if (elem.nodeType === 1) {
              tmp.push(elem);
            }
          }
          return tmp;
        }
        return results;
      };
      Expr.find.CLASS = support.getElementsByClassName && function (className, context) {
        if (documentIsHTML) {
          return context.getElementsByClassName(className);
        }
      };
      rbuggyMatches = [];
      rbuggyQSA = [];
      support.disconnectedMatch = true;
      rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join('|'));
      rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join('|'));
      hasCompare = rnative.test(docElem.compareDocumentPosition);
      contains$3 = hasCompare || rnative.test(docElem.contains) ? function (a, b) {
        var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode;
        return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16));
      } : function (a, b) {
        if (b) {
          while (b = b.parentNode) {
            if (b === a) {
              return true;
            }
          }
        }
        return false;
      };
      sortOrder = hasCompare ? function (a, b) {
        if (a === b) {
          hasDuplicate = true;
          return 0;
        }
        var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
        if (compare) {
          return compare;
        }
        compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1;
        if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) {
          if (a === doc || a.ownerDocument === preferredDoc && contains$3(preferredDoc, a)) {
            return -1;
          }
          if (b === doc || b.ownerDocument === preferredDoc && contains$3(preferredDoc, b)) {
            return 1;
          }
          return sortInput ? indexOf$2.call(sortInput, a) - indexOf$2.call(sortInput, b) : 0;
        }
        return compare & 4 ? -1 : 1;
      } : function (a, b) {
        if (a === b) {
          hasDuplicate = true;
          return 0;
        }
        var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [a], bp = [b];
        if (!aup || !bup) {
          return a === doc ? -1 : b === doc ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf$2.call(sortInput, a) - indexOf$2.call(sortInput, b) : 0;
        } else if (aup === bup) {
          return siblingCheck(a, b);
        }
        cur = a;
        while (cur = cur.parentNode) {
          ap.unshift(cur);
        }
        cur = b;
        while (cur = cur.parentNode) {
          bp.unshift(cur);
        }
        while (ap[i] === bp[i]) {
          i++;
        }
        return i ? siblingCheck(ap[i], bp[i]) : ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0;
      };
      return doc;
    };
    Sizzle.matches = function (expr, elements) {
      return Sizzle(expr, null, null, elements);
    };
    Sizzle.matchesSelector = function (elem, expr) {
      if ((elem.ownerDocument || elem) !== document) {
        setDocument(elem);
      }
      expr = expr.replace(rattributeQuotes, '=\'$1\']');
      if (support.matchesSelector && documentIsHTML && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) {
        try {
          var ret = matches.call(elem, expr);
          if (ret || support.disconnectedMatch || elem.document && elem.document.nodeType !== 11) {
            return ret;
          }
        } catch (e) {
        }
      }
      return Sizzle(expr, document, null, [elem]).length > 0;
    };
    Sizzle.contains = function (context, elem) {
      if ((context.ownerDocument || context) !== document) {
        setDocument(context);
      }
      return contains$3(context, elem);
    };
    Sizzle.attr = function (elem, name) {
      if ((elem.ownerDocument || elem) !== document) {
        setDocument(elem);
      }
      var fn = Expr.attrHandle[name.toLowerCase()], val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined;
      return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null;
    };
    Sizzle.error = function (msg) {
      throw new Error('Syntax error, unrecognized expression: ' + msg);
    };
    Sizzle.uniqueSort = function (results) {
      var elem, duplicates = [], j = 0, i = 0;
      hasDuplicate = !support.detectDuplicates;
      sortInput = !support.sortStable && results.slice(0);
      results.sort(sortOrder);
      if (hasDuplicate) {
        while (elem = results[i++]) {
          if (elem === results[i]) {
            j = duplicates.push(i);
          }
        }
        while (j--) {
          results.splice(duplicates[j], 1);
        }
      }
      sortInput = null;
      return results;
    };
    getText = Sizzle.getText = function (elem) {
      var node, ret = '', i = 0, nodeType = elem.nodeType;
      if (!nodeType) {
        while (node = elem[i++]) {
          ret += getText(node);
        }
      } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {
        if (typeof elem.textContent === 'string') {
          return elem.textContent;
        } else {
          for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
            ret += getText(elem);
          }
        }
      } else if (nodeType === 3 || nodeType === 4) {
        return elem.nodeValue;
      }
      return ret;
    };
    Expr = Sizzle.selectors = {
      cacheLength: 50,
      createPseudo: markFunction,
      match: matchExpr,
      attrHandle: {},
      find: {},
      relative: {
        '>': {
          dir: 'parentNode',
          first: true
        },
        ' ': { dir: 'parentNode' },
        '+': {
          dir: 'previousSibling',
          first: true
        },
        '~': { dir: 'previousSibling' }
      },
      preFilter: {
        ATTR: function (match) {
          match[1] = match[1].replace(runescape, funescape);
          match[3] = (match[3] || match[4] || match[5] || '').replace(runescape, funescape);
          if (match[2] === '~=') {
            match[3] = ' ' + match[3] + ' ';
          }
          return match.slice(0, 4);
        },
        CHILD: function (match) {
          match[1] = match[1].toLowerCase();
          if (match[1].slice(0, 3) === 'nth') {
            if (!match[3]) {
              Sizzle.error(match[0]);
            }
            match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === 'even' || match[3] === 'odd'));
            match[5] = +(match[7] + match[8] || match[3] === 'odd');
          } else if (match[3]) {
            Sizzle.error(match[0]);
          }
          return match;
        },
        PSEUDO: function (match) {
          var excess, unquoted = !match[6] && match[2];
          if (matchExpr.CHILD.test(match[0])) {
            return null;
          }
          if (match[3]) {
            match[2] = match[4] || match[5] || '';
          } else if (unquoted && rpseudo.test(unquoted) && (excess = tokenize(unquoted, true)) && (excess = unquoted.indexOf(')', unquoted.length - excess) - unquoted.length)) {
            match[0] = match[0].slice(0, excess);
            match[2] = unquoted.slice(0, excess);
          }
          return match.slice(0, 3);
        }
      },
      filter: {
        TAG: function (nodeNameSelector) {
          var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();
          return nodeNameSelector === '*' ? function () {
            return true;
          } : function (elem) {
            return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
          };
        },
        CLASS: function (className) {
          var pattern = classCache[className + ' '];
          return pattern || (pattern = new RegExp('(^|' + whitespace + ')' + className + '(' + whitespace + '|$)')) && classCache(className, function (elem) {
            return pattern.test(typeof elem.className === 'string' && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute('class') || '');
          });
        },
        ATTR: function (name, operator, check) {
          return function (elem) {
            var result = Sizzle.attr(elem, name);
            if (result == null) {
              return operator === '!=';
            }
            if (!operator) {
              return true;
            }
            result += '';
            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;
          };
        },
        CHILD: function (type, what, argument, first, last) {
          var simple = type.slice(0, 3) !== 'nth', forward = type.slice(-4) !== 'last', ofType = what === 'of-type';
          return first === 1 && last === 0 ? function (elem) {
            return !!elem.parentNode;
          } : function (elem, context, xml) {
            var cache, outerCache, node, diff, nodeIndex, start, dir = simple !== forward ? 'nextSibling' : 'previousSibling', parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType;
            if (parent) {
              if (simple) {
                while (dir) {
                  node = elem;
                  while (node = node[dir]) {
                    if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) {
                      return false;
                    }
                  }
                  start = dir = type === 'only' && !start && 'nextSibling';
                }
                return true;
              }
              start = [forward ? parent.firstChild : parent.lastChild];
              if (forward && useCache) {
                outerCache = parent[expando] || (parent[expando] = {});
                cache = outerCache[type] || [];
                nodeIndex = cache[0] === dirruns && cache[1];
                diff = cache[0] === dirruns && cache[2];
                node = nodeIndex && parent.childNodes[nodeIndex];
                while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {
                  if (node.nodeType === 1 && ++diff && node === elem) {
                    outerCache[type] = [
                      dirruns,
                      nodeIndex,
                      diff
                    ];
                    break;
                  }
                }
              } else if (useCache && (cache = (elem[expando] || (elem[expando] = {}))[type]) && cache[0] === dirruns) {
                diff = cache[1];
              } else {
                while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {
                  if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) {
                    if (useCache) {
                      (node[expando] || (node[expando] = {}))[type] = [
                        dirruns,
                        diff
                      ];
                    }
                    if (node === elem) {
                      break;
                    }
                  }
                }
              }
              diff -= last;
              return diff === first || diff % first === 0 && diff / first >= 0;
            }
          };
        },
        PSEUDO: function (pseudo, argument) {
          var args, fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error('unsupported pseudo: ' + pseudo);
          if (fn[expando]) {
            return fn(argument);
          }
          if (fn.length > 1) {
            args = [
              pseudo,
              pseudo,
              '',
              argument
            ];
            return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) {
              var idx, matched = fn(seed, argument), i = matched.length;
              while (i--) {
                idx = indexOf$2.call(seed, matched[i]);
                seed[idx] = !(matches[idx] = matched[i]);
              }
            }) : function (elem) {
              return fn(elem, 0, args);
            };
          }
          return fn;
        }
      },
      pseudos: {
        not: markFunction(function (selector) {
          var input = [], results = [], matcher = compile(selector.replace(rtrim, '$1'));
          return matcher[expando] ? markFunction(function (seed, matches, context, xml) {
            var elem, unmatched = matcher(seed, null, xml, []), i = seed.length;
            while (i--) {
              if (elem = unmatched[i]) {
                seed[i] = !(matches[i] = elem);
              }
            }
          }) : function (elem, context, xml) {
            input[0] = elem;
            matcher(input, null, xml, results);
            return !results.pop();
          };
        }),
        has: markFunction(function (selector) {
          return function (elem) {
            return Sizzle(selector, elem).length > 0;
          };
        }),
        contains: markFunction(function (text) {
          text = text.replace(runescape, funescape);
          return function (elem) {
            return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1;
          };
        }),
        lang: markFunction(function (lang) {
          if (!ridentifier.test(lang || '')) {
            Sizzle.error('unsupported lang: ' + lang);
          }
          lang = lang.replace(runescape, funescape).toLowerCase();
          return function (elem) {
            var elemLang;
            do {
              if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute('xml:lang') || elem.getAttribute('lang')) {
                elemLang = elemLang.toLowerCase();
                return elemLang === lang || elemLang.indexOf(lang + '-') === 0;
              }
            } while ((elem = elem.parentNode) && elem.nodeType === 1);
            return false;
          };
        }),
        target: function (elem) {
          var hash = domGlobals.window.location && domGlobals.window.location.hash;
          return hash && hash.slice(1) === elem.id;
        },
        root: function (elem) {
          return elem === docElem;
        },
        focus: function (elem) {
          return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
        },
        enabled: function (elem) {
          return elem.disabled === false;
        },
        disabled: function (elem) {
          return elem.disabled === true;
        },
        checked: function (elem) {
          var nodeName = elem.nodeName.toLowerCase();
          return nodeName === 'input' && !!elem.checked || nodeName === 'option' && !!elem.selected;
        },
        selected: function (elem) {
          if (elem.parentNode) {
            elem.parentNode.selectedIndex;
          }
          return elem.selected === true;
        },
        empty: function (elem) {
          for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
            if (elem.nodeType < 6) {
              return false;
            }
          }
          return true;
        },
        parent: function (elem) {
          return !Expr.pseudos.empty(elem);
        },
        header: function (elem) {
          return rheader.test(elem.nodeName);
        },
        input: function (elem) {
          return rinputs.test(elem.nodeName);
        },
        button: function (elem) {
          var name = elem.nodeName.toLowerCase();
          return name === 'input' && elem.type === 'button' || name === 'button';
        },
        text: function (elem) {
          var attr;
          return elem.nodeName.toLowerCase() === 'input' && elem.type === 'text' && ((attr = elem.getAttribute('type')) == null || attr.toLowerCase() === 'text');
        },
        first: createPositionalPseudo(function () {
          return [0];
        }),
        last: createPositionalPseudo(function (matchIndexes, length) {
          return [length - 1];
        }),
        eq: createPositionalPseudo(function (matchIndexes, length, argument) {
          return [argument < 0 ? argument + length : argument];
        }),
        even: createPositionalPseudo(function (matchIndexes, length) {
          var i = 0;
          for (; i < length; i += 2) {
            matchIndexes.push(i);
          }
          return matchIndexes;
        }),
        odd: createPositionalPseudo(function (matchIndexes, length) {
          var i = 1;
          for (; i < length; i += 2) {
            matchIndexes.push(i);
          }
          return matchIndexes;
        }),
        lt: createPositionalPseudo(function (matchIndexes, length, argument) {
          var i = argument < 0 ? argument + length : argument;
          for (; --i >= 0;) {
            matchIndexes.push(i);
          }
          return matchIndexes;
        }),
        gt: createPositionalPseudo(function (matchIndexes, length, argument) {
          var i = argument < 0 ? argument + length : argument;
          for (; ++i < length;) {
            matchIndexes.push(i);
          }
          return matchIndexes;
        })
      }
    };
    Expr.pseudos.nth = Expr.pseudos.eq;
    for (i in {
        radio: true,
        checkbox: true,
        file: true,
        password: true,
        image: true
      }) {
      Expr.pseudos[i] = createInputPseudo(i);
    }
    for (i in {
        submit: true,
        reset: true
      }) {
      Expr.pseudos[i] = createButtonPseudo(i);
    }
    function setFilters() {
    }
    setFilters.prototype = Expr.filters = Expr.pseudos;
    Expr.setFilters = new setFilters();
    tokenize = Sizzle.tokenize = function (selector, parseOnly) {
      var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[selector + ' '];
      if (cached) {
        return parseOnly ? 0 : cached.slice(0);
      }
      soFar = selector;
      groups = [];
      preFilters = Expr.preFilter;
      while (soFar) {
        if (!matched || (match = rcomma.exec(soFar))) {
          if (match) {
            soFar = soFar.slice(match[0].length) || soFar;
          }
          groups.push(tokens = []);
        }
        matched = false;
        if (match = rcombinators.exec(soFar)) {
          matched = match.shift();
          tokens.push({
            value: matched,
            type: match[0].replace(rtrim, ' ')
          });
          soFar = soFar.slice(matched.length);
        }
        for (type in Expr.filter) {
          if (!Expr.filter.hasOwnProperty(type))
            continue;
          if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) {
            matched = match.shift();
            tokens.push({
              value: matched,
              type: type,
              matches: match
            });
            soFar = soFar.slice(matched.length);
          }
        }
        if (!matched) {
          break;
        }
      }
      return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) : tokenCache(selector, groups).slice(0);
    };
    function toSelector(tokens) {
      var i = 0, len = tokens.length, selector = '';
      for (; i < len; i++) {
        selector += tokens[i].value;
      }
      return selector;
    }
    function addCombinator(matcher, combinator, base) {
      var dir = combinator.dir, checkNonElements = base && dir === 'parentNode', doneName = done++;
      return combinator.first ? function (elem, context, xml) {
        while (elem = elem[dir]) {
          if (elem.nodeType === 1 || checkNonElements) {
            return matcher(elem, context, xml);
          }
        }
      } : function (elem, context, xml) {
        var oldCache, outerCache, newCache = [
            dirruns,
            doneName
          ];
        if (xml) {
          while (elem = elem[dir]) {
            if (elem.nodeType === 1 || checkNonElements) {
              if (matcher(elem, context, xml)) {
                return true;
              }
            }
          }
        } else {
          while (elem = elem[dir]) {
            if (elem.nodeType === 1 || checkNonElements) {
              outerCache = elem[expando] || (elem[expando] = {});
              if ((oldCache = outerCache[dir]) && oldCache[0] === dirruns && oldCache[1] === doneName) {
                return newCache[2] = oldCache[2];
              } else {
                outerCache[dir] = newCache;
                if (newCache[2] = matcher(elem, context, xml)) {
                  return true;
                }
              }
            }
          }
        }
      };
    }
    function elementMatcher(matchers) {
      return matchers.length > 1 ? function (elem, context, xml) {
        var i = matchers.length;
        while (i--) {
          if (!matchers[i](elem, context, xml)) {
            return false;
          }
        }
        return true;
      } : matchers[0];
    }
    function multipleContexts(selector, contexts, results) {
      var i = 0, len = contexts.length;
      for (; i < len; i++) {
        Sizzle(selector, contexts[i], results);
      }
      return results;
    }
    function condense(unmatched, map, filter, context, xml) {
      var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null;
      for (; i < len; i++) {
        if (elem = unmatched[i]) {
          if (!filter || filter(elem, context, xml)) {
            newUnmatched.push(elem);
            if (mapped) {
              map.push(i);
            }
          }
        }
      }
      return newUnmatched;
    }
    function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {
      if (postFilter && !postFilter[expando]) {
        postFilter = setMatcher(postFilter);
      }
      if (postFinder && !postFinder[expando]) {
        postFinder = setMatcher(postFinder, postSelector);
      }
      return markFunction(function (seed, results, context, xml) {
        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;
        if (matcher) {
          matcher(matcherIn, matcherOut, context, xml);
        }
        if (postFilter) {
          temp = condense(matcherOut, postMap);
          postFilter(temp, [], context, xml);
          i = temp.length;
          while (i--) {
            if (elem = temp[i]) {
              matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);
            }
          }
        }
        if (seed) {
          if (postFinder || preFilter) {
            if (postFinder) {
              temp = [];
              i = matcherOut.length;
              while (i--) {
                if (elem = matcherOut[i]) {
                  temp.push(matcherIn[i] = elem);
                }
              }
              postFinder(null, matcherOut = [], temp, xml);
            }
            i = matcherOut.length;
            while (i--) {
              if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf$2.call(seed, elem) : preMap[i]) > -1) {
                seed[temp] = !(results[temp] = elem);
              }
            }
          }
        } else {
          matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut);
          if (postFinder) {
            postFinder(null, results, matcherOut, xml);
          } else {
            push.apply(results, matcherOut);
          }
        }
      });
    }
    function matcherFromTokens(tokens) {
      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) {
          return elem === checkContext;
        }, implicitRelative, true), matchAnyContext = addCombinator(function (elem) {
          return indexOf$2.call(checkContext, elem) > -1;
        }, implicitRelative, true), matchers = [function (elem, context, xml) {
            return !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml));
          }];
      for (; i < len; i++) {
        if (matcher = Expr.relative[tokens[i].type]) {
          matchers = [addCombinator(elementMatcher(matchers), matcher)];
        } else {
          matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);
          if (matcher[expando]) {
            j = ++i;
            for (; j < len; j++) {
              if (Expr.relative[tokens[j].type]) {
                break;
              }
            }
            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));
          }
          matchers.push(matcher);
        }
      }
      return elementMatcher(matchers);
    }
    function matcherFromGroupMatchers(elementMatchers, setMatchers) {
      var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function (seed, context, xml, results, outermost) {
          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;
          if (outermost) {
            outermostContext = context !== document && context;
          }
          for (; i !== len && (elem = elems[i]) != null; i++) {
            if (byElement && elem) {
              j = 0;
              while (matcher = elementMatchers[j++]) {
                if (matcher(elem, context, xml)) {
                  results.push(elem);
                  break;
                }
              }
              if (outermost) {
                dirruns = dirrunsUnique;
              }
            }
            if (bySet) {
              if (elem = !matcher && elem) {
                matchedCount--;
              }
              if (seed) {
                unmatched.push(elem);
              }
            }
          }
          matchedCount += i;
          if (bySet && i !== matchedCount) {
            j = 0;
            while (matcher = setMatchers[j++]) {
              matcher(unmatched, setMatched, context, xml);
            }
            if (seed) {
              if (matchedCount > 0) {
                while (i--) {
                  if (!(unmatched[i] || setMatched[i])) {
                    setMatched[i] = pop.call(results);
                  }
                }
              }
              setMatched = condense(setMatched);
            }
            push.apply(results, setMatched);
            if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) {
              Sizzle.uniqueSort(results);
            }
          }
          if (outermost) {
            dirruns = dirrunsUnique;
            outermostContext = contextBackup;
          }
          return unmatched;
        };
      return bySet ? markFunction(superMatcher) : superMatcher;
    }
    compile = Sizzle.compile = function (selector, match) {
      var i, setMatchers = [], elementMatchers = [], cached = compilerCache[selector + ' '];
      if (!cached) {
        if (!match) {
          match = tokenize(selector);
        }
        i = match.length;
        while (i--) {
          cached = matcherFromTokens(match[i]);
          if (cached[expando]) {
            setMatchers.push(cached);
          } else {
            elementMatchers.push(cached);
          }
        }
        cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers));
        cached.selector = selector;
      }
      return cached;
    };
    select = Sizzle.select = function (selector, context, results, seed) {
      var i, tokens, token, type, find, compiled = typeof selector === 'function' && selector, match = !seed && tokenize(selector = compiled.selector || selector);
      results = results || [];
      if (match.length === 1) {
        tokens = match[0] = match[0].slice(0);
        if (tokens.length > 2 && (token = tokens[0]).type === 'ID' && support.getById && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) {
          context = (Expr.find.ID(token.matches[0].replace(runescape, funescape), context) || [])[0];
          if (!context) {
            return results;
          } else if (compiled) {
            context = context.parentNode;
          }
          selector = selector.slice(tokens.shift().value.length);
        }
        i = matchExpr.needsContext.test(selector) ? 0 : tokens.length;
        while (i--) {
          token = tokens[i];
          if (Expr.relative[type = token.type]) {
            break;
          }
          if (find = Expr.find[type]) {
            if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testContext(context.parentNode) || context)) {
              tokens.splice(i, 1);
              selector = seed.length && toSelector(tokens);
              if (!selector) {
                push.apply(results, seed);
                return results;
              }
              break;
            }
          }
        }
      }
      (compiled || compile(selector, match))(seed, context, !documentIsHTML, results, rsibling.test(selector) && testContext(context.parentNode) || context);
      return results;
    };
    support.sortStable = expando.split('').sort(sortOrder).join('') === expando;
    support.detectDuplicates = !!hasDuplicate;
    setDocument();
    support.sortDetached = true;

    var doc = domGlobals.document, push$1 = Array.prototype.push, slice$1 = Array.prototype.slice;
    var rquickExpr$1 = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/;
    var Event = EventUtils.Event;
    var skipUniques = Tools.makeMap('children,contents,next,prev');
    var isDefined = function (obj) {
      return typeof obj !== 'undefined';
    };
    var isString$1 = function (obj) {
      return typeof obj === 'string';
    };
    var isWindow = function (obj) {
      return obj && obj === obj.window;
    };
    var createFragment = function (html, fragDoc) {
      var frag, node, container;
      fragDoc = fragDoc || doc;
      container = fragDoc.createElement('div');
      frag = fragDoc.createDocumentFragment();
      container.innerHTML = html;
      while (node = container.firstChild) {
        frag.appendChild(node);
      }
      return frag;
    };
    var domManipulate = function (targetNodes, sourceItem, callback, reverse) {
      var i;
      if (isString$1(sourceItem)) {
        sourceItem = createFragment(sourceItem, getElementDocument(targetNodes[0]));
      } else if (sourceItem.length && !sourceItem.nodeType) {
        sourceItem = DomQuery.makeArray(sourceItem);
        if (reverse) {
          for (i = sourceItem.length - 1; i >= 0; i--) {
            domManipulate(targetNodes, sourceItem[i], callback, reverse);
          }
        } else {
          for (i = 0; i < sourceItem.length; i++) {
            domManipulate(targetNodes, sourceItem[i], callback, reverse);
          }
        }
        return targetNodes;
      }
      if (sourceItem.nodeType) {
        i = targetNodes.length;
        while (i--) {
          callback.call(targetNodes[i], sourceItem);
        }
      }
      return targetNodes;
    };
    var hasClass = function (node, className) {
      return node && className && (' ' + node.className + ' ').indexOf(' ' + className + ' ') !== -1;
    };
    var wrap$1 = function (elements, wrapper, all) {
      var lastParent, newWrapper;
      wrapper = DomQuery(wrapper)[0];
      elements.each(function () {
        var self = this;
        if (!all || lastParent !== self.parentNode) {
          lastParent = self.parentNode;
          newWrapper = wrapper.cloneNode(false);
          self.parentNode.insertBefore(newWrapper, self);
          newWrapper.appendChild(self);
        } else {
          newWrapper.appendChild(self);
        }
      });
      return elements;
    };
    var numericCssMap = Tools.makeMap('fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom', ' ');
    var booleanMap = Tools.makeMap('checked compact declare defer disabled ismap multiple nohref noshade nowrap readonly selected', ' ');
    var propFix = {
      for: 'htmlFor',
      class: 'className',
      readonly: 'readOnly'
    };
    var cssFix = { float: 'cssFloat' };
    var attrHooks = {}, cssHooks = {};
    var DomQueryConstructor = function (selector, context) {
      return new DomQuery.fn.init(selector, context);
    };
    var inArray$1 = function (item, array) {
      var i;
      if (array.indexOf) {
        return array.indexOf(item);
      }
      i = array.length;
      while (i--) {
        if (array[i] === item) {
          return i;
        }
      }
      return -1;
    };
    var whiteSpaceRegExp$1 = /^\s*|\s*$/g;
    var trim$2 = function (str) {
      return str === null || str === undefined ? '' : ('' + str).replace(whiteSpaceRegExp$1, '');
    };
    var each$4 = function (obj, callback) {
      var length, key, i, value;
      if (obj) {
        length = obj.length;
        if (length === undefined) {
          for (key in obj) {
            if (obj.hasOwnProperty(key)) {
              value = obj[key];
              if (callback.call(value, key, value) === false) {
                break;
              }
            }
          }
        } else {
          for (i = 0; i < length; i++) {
            value = obj[i];
            if (callback.call(value, i, value) === false) {
              break;
            }
          }
        }
      }
      return obj;
    };
    var grep = function (array, callback) {
      var out = [];
      each$4(array, function (i, item) {
        if (callback(item, i)) {
          out.push(item);
        }
      });
      return out;
    };
    var getElementDocument = function (element) {
      if (!element) {
        return doc;
      }
      if (element.nodeType === 9) {
        return element;
      }
      return element.ownerDocument;
    };
    DomQueryConstructor.fn = DomQueryConstructor.prototype = {
      constructor: DomQueryConstructor,
      selector: '',
      context: null,
      length: 0,
      init: function (selector, context) {
        var self = this;
        var match, node;
        if (!selector) {
          return self;
        }
        if (selector.nodeType) {
          self.context = self[0] = selector;
          self.length = 1;
          return self;
        }
        if (context && context.nodeType) {
          self.context = context;
        } else {
          if (context) {
            return DomQuery(selector).attr(context);
          }
          self.context = context = domGlobals.document;
        }
        if (isString$1(selector)) {
          self.selector = selector;
          if (selector.charAt(0) === '<' && selector.charAt(selector.length - 1) === '>' && selector.length >= 3) {
            match = [
              null,
              selector,
              null
            ];
          } else {
            match = rquickExpr$1.exec(selector);
          }
          if (match) {
            if (match[1]) {
              node = createFragment(selector, getElementDocument(context)).firstChild;
              while (node) {
                push$1.call(self, node);
                node = node.nextSibling;
              }
            } else {
              node = getElementDocument(context).getElementById(match[2]);
              if (!node) {
                return self;
              }
              if (node.id !== match[2]) {
                return self.find(selector);
              }
              self.length = 1;
              self[0] = node;
            }
          } else {
            return DomQuery(context).find(selector);
          }
        } else {
          this.add(selector, false);
        }
        return self;
      },
      toArray: function () {
        return Tools.toArray(this);
      },
      add: function (items, sort) {
        var self = this;
        var nodes, i;
        if (isString$1(items)) {
          return self.add(DomQuery(items));
        }
        if (sort !== false) {
          nodes = DomQuery.unique(self.toArray().concat(DomQuery.makeArray(items)));
          self.length = nodes.length;
          for (i = 0; i < nodes.length; i++) {
            self[i] = nodes[i];
          }
        } else {
          push$1.apply(self, DomQuery.makeArray(items));
        }
        return self;
      },
      attr: function (name, value) {
        var self = this;
        var hook;
        if (typeof name === 'object') {
          each$4(name, function (name, value) {
            self.attr(name, value);
          });
        } else if (isDefined(value)) {
          this.each(function () {
            var hook;
            if (this.nodeType === 1) {
              hook = attrHooks[name];
              if (hook && hook.set) {
                hook.set(this, value);
                return;
              }
              if (value === null) {
                this.removeAttribute(name, 2);
              } else {
                this.setAttribute(name, value, 2);
              }
            }
          });
        } else {
          if (self[0] && self[0].nodeType === 1) {
            hook = attrHooks[name];
            if (hook && hook.get) {
              return hook.get(self[0], name);
            }
            if (booleanMap[name]) {
              return self.prop(name) ? name : undefined;
            }
            value = self[0].getAttribute(name, 2);
            if (value === null) {
              value = undefined;
            }
          }
          return value;
        }
        return self;
      },
      removeAttr: function (name) {
        return this.attr(name, null);
      },
      prop: function (name, value) {
        var self = this;
        name = propFix[name] || name;
        if (typeof name === 'object') {
          each$4(name, function (name, value) {
            self.prop(name, value);
          });
        } else if (isDefined(value)) {
          this.each(function () {
            if (this.nodeType === 1) {
              this[name] = value;
            }
          });
        } else {
          if (self[0] && self[0].nodeType && name in self[0]) {
            return self[0][name];
          }
          return value;
        }
        return self;
      },
      css: function (name, value) {
        var self = this;
        var elm, hook;
        var camel = function (name) {
          return name.replace(/-(\D)/g, function (a, b) {
            return b.toUpperCase();
          });
        };
        var dashed = function (name) {
          return name.replace(/[A-Z]/g, function (a) {
            return '-' + a;
          });
        };
        if (typeof name === 'object') {
          each$4(name, function (name, value) {
            self.css(name, value);
          });
        } else {
          if (isDefined(value)) {
            name = camel(name);
            if (typeof value === 'number' && !numericCssMap[name]) {
              value = value.toString() + 'px';
            }
            self.each(function () {
              var style = this.style;
              hook = cssHooks[name];
              if (hook && hook.set) {
                hook.set(this, value);
                return;
              }
              try {
                this.style[cssFix[name] || name] = value;
              } catch (ex) {
              }
              if (value === null || value === '') {
                if (style.removeProperty) {
                  style.removeProperty(dashed(name));
                } else {
                  style.removeAttribute(name);
                }
              }
            });
          } else {
            elm = self[0];
            hook = cssHooks[name];
            if (hook && hook.get) {
              return hook.get(elm);
            }
            if (elm.ownerDocument.defaultView) {
              try {
                return elm.ownerDocument.defaultView.getComputedStyle(elm, null).getPropertyValue(dashed(name));
              } catch (ex) {
                return undefined;
              }
            } else if (elm.currentStyle) {
              return elm.currentStyle[camel(name)];
            } else {
              return '';
            }
          }
        }
        return self;
      },
      remove: function () {
        var self = this;
        var node, i = this.length;
        while (i--) {
          node = self[i];
          Event.clean(node);
          if (node.parentNode) {
            node.parentNode.removeChild(node);
          }
        }
        return this;
      },
      empty: function () {
        var self = this;
        var node, i = this.length;
        while (i--) {
          node = self[i];
          while (node.firstChild) {
            node.removeChild(node.firstChild);
          }
        }
        return this;
      },
      html: function (value) {
        var self = this;
        var i;
        if (isDefined(value)) {
          i = self.length;
          try {
            while (i--) {
              self[i].innerHTML = value;
            }
          } catch (ex) {
            DomQuery(self[i]).empty().append(value);
          }
          return self;
        }
        return self[0] ? self[0].innerHTML : '';
      },
      text: function (value) {
        var self = this;
        var i;
        if (isDefined(value)) {
          i = self.length;
          while (i--) {
            if ('innerText' in self[i]) {
              self[i].innerText = value;
            } else {
              self[0].textContent = value;
            }
          }
          return self;
        }
        return self[0] ? self[0].innerText || self[0].textContent : '';
      },
      append: function () {
        return domManipulate(this, arguments, function (node) {
          if (this.nodeType === 1 || this.host && this.host.nodeType === 1) {
            this.appendChild(node);
          }
        });
      },
      prepend: function () {
        return domManipulate(this, arguments, function (node) {
          if (this.nodeType === 1 || this.host && this.host.nodeType === 1) {
            this.insertBefore(node, this.firstChild);
          }
        }, true);
      },
      before: function () {
        var self = this;
        if (self[0] && self[0].parentNode) {
          return domManipulate(self, arguments, function (node) {
            this.parentNode.insertBefore(node, this);
          });
        }
        return self;
      },
      after: function () {
        var self = this;
        if (self[0] && self[0].parentNode) {
          return domManipulate(self, arguments, function (node) {
            this.parentNode.insertBefore(node, this.nextSibling);
          }, true);
        }
        return self;
      },
      appendTo: function (val) {
        DomQuery(val).append(this);
        return this;
      },
      prependTo: function (val) {
        DomQuery(val).prepend(this);
        return this;
      },
      replaceWith: function (content) {
        return this.before(content).remove();
      },
      wrap: function (content) {
        return wrap$1(this, content);
      },
      wrapAll: function (content) {
        return wrap$1(this, content, true);
      },
      wrapInner: function (content) {
        this.each(function () {
          DomQuery(this).contents().wrapAll(content);
        });
        return this;
      },
      unwrap: function () {
        return this.parent().each(function () {
          DomQuery(this).replaceWith(this.childNodes);
        });
      },
      clone: function () {
        var result = [];
        this.each(function () {
          result.push(this.cloneNode(true));
        });
        return DomQuery(result);
      },
      addClass: function (className) {
        return this.toggleClass(className, true);
      },
      removeClass: function (className) {
        return this.toggleClass(className, false);
      },
      toggleClass: function (className, state) {
        var self = this;
        if (typeof className !== 'string') {
          return self;
        }
        if (className.indexOf(' ') !== -1) {
          each$4(className.split(' '), function () {
            self.toggleClass(this, state);
          });
        } else {
          self.each(function (index, node) {
            var existingClassName, classState;
            classState = hasClass(node, className);
            if (classState !== state) {
              existingClassName = node.className;
              if (classState) {
                node.className = trim$2((' ' + existingClassName + ' ').replace(' ' + className + ' ', ' '));
              } else {
                node.className += existingClassName ? ' ' + className : className;
              }
            }
          });
        }
        return self;
      },
      hasClass: function (className) {
        return hasClass(this[0], className);
      },
      each: function (callback) {
        return each$4(this, callback);
      },
      on: function (name, callback) {
        return this.each(function () {
          Event.bind(this, name, callback);
        });
      },
      off: function (name, callback) {
        return this.each(function () {
          Event.unbind(this, name, callback);
        });
      },
      trigger: function (name) {
        return this.each(function () {
          if (typeof name === 'object') {
            Event.fire(this, name.type, name);
          } else {
            Event.fire(this, name);
          }
        });
      },
      show: function () {
        return this.css('display', '');
      },
      hide: function () {
        return this.css('display', 'none');
      },
      slice: function () {
        return new DomQuery(slice$1.apply(this, arguments));
      },
      eq: function (index) {
        return index === -1 ? this.slice(index) : this.slice(index, +index + 1);
      },
      first: function () {
        return this.eq(0);
      },
      last: function () {
        return this.eq(-1);
      },
      find: function (selector) {
        var i, l;
        var ret = [];
        for (i = 0, l = this.length; i < l; i++) {
          DomQuery.find(selector, this[i], ret);
        }
        return DomQuery(ret);
      },
      filter: function (selector) {
        if (typeof selector === 'function') {
          return DomQuery(grep(this.toArray(), function (item, i) {
            return selector(i, item);
          }));
        }
        return DomQuery(DomQuery.filter(selector, this.toArray()));
      },
      closest: function (selector) {
        var result = [];
        if (selector instanceof DomQuery) {
          selector = selector[0];
        }
        this.each(function (i, node) {
          while (node) {
            if (typeof selector === 'string' && DomQuery(node).is(selector)) {
              result.push(node);
              break;
            } else if (node === selector) {
              result.push(node);
              break;
            }
            node = node.parentNode;
          }
        });
        return DomQuery(result);
      },
      offset: function (offset) {
        var elm, doc, docElm;
        var x = 0, y = 0, pos;
        if (!offset) {
          elm = this[0];
          if (elm) {
            doc = elm.ownerDocument;
            docElm = doc.documentElement;
            if (elm.getBoundingClientRect) {
              pos = elm.getBoundingClientRect();
              x = pos.left + (docElm.scrollLeft || doc.body.scrollLeft) - docElm.clientLeft;
              y = pos.top + (docElm.scrollTop || doc.body.scrollTop) - docElm.clientTop;
            }
          }
          return {
            left: x,
            top: y
          };
        }
        return this.css(offset);
      },
      push: push$1,
      sort: Array.prototype.sort,
      splice: Array.prototype.splice
    };
    Tools.extend(DomQueryConstructor, {
      extend: Tools.extend,
      makeArray: function (object) {
        if (isWindow(object) || object.nodeType) {
          return [object];
        }
        return Tools.toArray(object);
      },
      inArray: inArray$1,
      isArray: Tools.isArray,
      each: each$4,
      trim: trim$2,
      grep: grep,
      find: Sizzle,
      expr: Sizzle.selectors,
      unique: Sizzle.uniqueSort,
      text: Sizzle.getText,
      contains: Sizzle.contains,
      filter: function (expr, elems, not) {
        var i = elems.length;
        if (not) {
          expr = ':not(' + expr + ')';
        }
        while (i--) {
          if (elems[i].nodeType !== 1) {
            elems.splice(i, 1);
          }
        }
        if (elems.length === 1) {
          elems = DomQuery.find.matchesSelector(elems[0], expr) ? [elems[0]] : [];
        } else {
          elems = DomQuery.find.matches(expr, elems);
        }
        return elems;
      }
    });
    var dir = function (el, prop, until) {
      var matched = [];
      var cur = el[prop];
      if (typeof until !== 'string' && until instanceof DomQuery) {
        until = until[0];
      }
      while (cur && cur.nodeType !== 9) {
        if (until !== undefined) {
          if (cur === until) {
            break;
          }
          if (typeof until === 'string' && DomQuery(cur).is(until)) {
            break;
          }
        }
        if (cur.nodeType === 1) {
          matched.push(cur);
        }
        cur = cur[prop];
      }
      return matched;
    };
    var sibling = function (node, siblingName, nodeType, until) {
      var result = [];
      if (until instanceof DomQuery) {
        until = until[0];
      }
      for (; node; node = node[siblingName]) {
        if (nodeType && node.nodeType !== nodeType) {
          continue;
        }
        if (until !== undefined) {
          if (node === until) {
            break;
          }
          if (typeof until === 'string' && DomQuery(node).is(until)) {
            break;
          }
        }
        result.push(node);
      }
      return result;
    };
    var firstSibling = function (node, siblingName, nodeType) {
      for (node = node[siblingName]; node; node = node[siblingName]) {
        if (node.nodeType === nodeType) {
          return node;
        }
      }
      return null;
    };
    each$4({
      parent: function (node) {
        var parent = node.parentNode;
        return parent && parent.nodeType !== 11 ? parent : null;
      },
      parents: function (node) {
        return dir(node, 'parentNode');
      },
      next: function (node) {
        return firstSibling(node, 'nextSibling', 1);
      },
      prev: function (node) {
        return firstSibling(node, 'previousSibling', 1);
      },
      children: function (node) {
        return sibling(node.firstChild, 'nextSibling', 1);
      },
      contents: function (node) {
        return Tools.toArray((node.nodeName === 'iframe' ? node.contentDocument || node.contentWindow.document : node).childNodes);
      }
    }, function (name, fn) {
      DomQueryConstructor.fn[name] = function (selector) {
        var self = this;
        var result = [];
        self.each(function () {
          var nodes = fn.call(result, this, selector, result);
          if (nodes) {
            if (DomQuery.isArray(nodes)) {
              result.push.apply(result, nodes);
            } else {
              result.push(nodes);
            }
          }
        });
        if (this.length > 1) {
          if (!skipUniques[name]) {
            result = DomQuery.unique(result);
          }
          if (name.indexOf('parents') === 0) {
            result = result.reverse();
          }
        }
        var wrappedResult = DomQuery(result);
        if (selector) {
          return wrappedResult.filter(selector);
        }
        return wrappedResult;
      };
    });
    each$4({
      parentsUntil: function (node, until) {
        return dir(node, 'parentNode', until);
      },
      nextUntil: function (node, until) {
        return sibling(node, 'nextSibling', 1, until).slice(1);
      },
      prevUntil: function (node, until) {
        return sibling(node, 'previousSibling', 1, until).slice(1);
      }
    }, function (name, fn) {
      DomQueryConstructor.fn[name] = function (selector, filter) {
        var self = this;
        var result = [];
        self.each(function () {
          var nodes = fn.call(result, this, selector, result);
          if (nodes) {
            if (DomQuery.isArray(nodes)) {
              result.push.apply(result, nodes);
            } else {
              result.push(nodes);
            }
          }
        });
        if (this.length > 1) {
          result = DomQuery.unique(result);
          if (name.indexOf('parents') === 0 || name === 'prevUntil') {
            result = result.reverse();
          }
        }
        var wrappedResult = DomQuery(result);
        if (filter) {
          return wrappedResult.filter(filter);
        }
        return wrappedResult;
      };
    });
    DomQueryConstructor.fn.is = function (selector) {
      return !!selector && this.filter(selector).length > 0;
    };
    DomQueryConstructor.fn.init.prototype = DomQueryConstructor.fn;
    DomQueryConstructor.overrideDefaults = function (callback) {
      var defaults;
      var sub = function (selector, context) {
        defaults = defaults || callback();
        if (arguments.length === 0) {
          selector = defaults.element;
        }
        if (!context) {
          context = defaults.context;
        }
        return new sub.fn.init(selector, context);
      };
      DomQuery.extend(sub, this);
      return sub;
    };
    DomQueryConstructor.attrHooks = attrHooks;
    DomQueryConstructor.cssHooks = cssHooks;
    var DomQuery = DomQueryConstructor;

    var TreeWalker = function () {
      function TreeWalker(startNode, rootNode) {
        this.node = startNode;
        this.rootNode = rootNode;
        this.current = this.current.bind(this);
        this.next = this.next.bind(this);
        this.prev = this.prev.bind(this);
        this.prev2 = this.prev2.bind(this);
      }
      TreeWalker.prototype.current = function () {
        return this.node;
      };
      TreeWalker.prototype.next = function (shallow) {
        this.node = this.findSibling(this.node, 'firstChild', 'nextSibling', shallow);
        return this.node;
      };
      TreeWalker.prototype.prev = function (shallow) {
        this.node = this.findSibling(this.node, 'lastChild', 'previousSibling', shallow);
        return this.node;
      };
      TreeWalker.prototype.prev2 = function (shallow) {
        this.node = this.findPreviousNode(this.node, 'lastChild', 'previousSibling', shallow);
        return this.node;
      };
      TreeWalker.prototype.findSibling = function (node, startName, siblingName, shallow) {
        var sibling, parent;
        if (node) {
          if (!shallow && node[startName]) {
            return node[startName];
          }
          if (node !== this.rootNode) {
            sibling = node[siblingName];
            if (sibling) {
              return sibling;
            }
            for (parent = node.parentNode; parent && parent !== this.rootNode; parent = parent.parentNode) {
              sibling = parent[siblingName];
              if (sibling) {
                return sibling;
              }
            }
          }
        }
      };
      TreeWalker.prototype.findPreviousNode = function (node, startName, siblingName, shallow) {
        var sibling, parent, child;
        if (node) {
          sibling = node[siblingName];
          if (this.rootNode && sibling === this.rootNode) {
            return;
          }
          if (sibling) {
            if (!shallow) {
              for (child = sibling[startName]; child; child = child[startName]) {
                if (!child[startName]) {
                  return child;
                }
              }
            }
            return sibling;
          }
          parent = node.parentNode;
          if (parent && parent !== this.rootNode) {
            return parent;
          }
        }
      };
      return TreeWalker;
    }();

    var each$5 = Tools.each;
    var grep$1 = Tools.grep;
    var isIE = Env.ie;
    var simpleSelectorRe = /^([a-z0-9],?)+$/i;
    var whiteSpaceRegExp$2 = /^[ \t\r\n]*$/;
    var setupAttrHooks = function (styles, settings, getContext) {
      var keepValues = settings.keep_values;
      var keepUrlHook = {
        set: function ($elm, value, name) {
          if (settings.url_converter) {
            value = settings.url_converter.call(settings.url_converter_scope || getContext(), value, name, $elm[0]);
          }
          $elm.attr('data-mce-' + name, value).attr(name, value);
        },
        get: function ($elm, name) {
          return $elm.attr('data-mce-' + name) || $elm.attr(name);
        }
      };
      var attrHooks = {
        style: {
          set: function ($elm, value) {
            if (value !== null && typeof value === 'object') {
              $elm.css(value);
              return;
            }
            if (keepValues) {
              $elm.attr('data-mce-style', value);
            }
            if (value !== null && typeof value === 'string') {
              $elm.removeAttr('style');
              $elm.css(styles.parse(value));
            } else {
              $elm.attr('style', value);
            }
          },
          get: function ($elm) {
            var value = $elm.attr('data-mce-style') || $elm.attr('style');
            value = styles.serialize(styles.parse(value), $elm[0].nodeName);
            return value;
          }
        }
      };
      if (keepValues) {
        attrHooks.href = attrHooks.src = keepUrlHook;
      }
      return attrHooks;
    };
    var updateInternalStyleAttr = function (styles, $elm) {
      var rawValue = $elm.attr('style');
      var value = styles.serialize(styles.parse(rawValue), $elm[0].nodeName);
      if (!value) {
        value = null;
      }
      $elm.attr('data-mce-style', value);
    };
    var findNodeIndex = function (node, normalized) {
      var idx = 0, lastNodeType, nodeType;
      if (node) {
        for (lastNodeType = node.nodeType, node = node.previousSibling; node; node = node.previousSibling) {
          nodeType = node.nodeType;
          if (normalized && nodeType === 3) {
            if (nodeType === lastNodeType || !node.nodeValue.length) {
              continue;
            }
          }
          idx++;
          lastNodeType = nodeType;
        }
      }
      return idx;
    };
    function DOMUtils(doc, settings) {
      var _this = this;
      if (settings === void 0) {
        settings = {};
      }
      var attrHooks;
      var addedStyles = {};
      var win = domGlobals.window;
      var files = {};
      var counter = 0;
      var stdMode = true;
      var boxModel = true;
      var styleSheetLoader = StyleSheetLoader(doc, {
        contentCssCors: settings.contentCssCors,
        referrerPolicy: settings.referrerPolicy
      });
      var boundEvents = [];
      var schema = settings.schema ? settings.schema : Schema({});
      var styles = Styles({
        url_converter: settings.url_converter,
        url_converter_scope: settings.url_converter_scope
      }, settings.schema);
      var events = settings.ownEvents ? new EventUtils() : EventUtils.Event;
      var blockElementsMap = schema.getBlockElements();
      var $ = DomQuery.overrideDefaults(function () {
        return {
          context: doc,
          element: self.getRoot()
        };
      });
      var isBlock = function (node) {
        if (typeof node === 'string') {
          return !!blockElementsMap[node];
        } else if (node) {
          var type = node.nodeType;
          if (type) {
            return !!(type === 1 && blockElementsMap[node.nodeName]);
          }
        }
        return false;
      };
      var get = function (elm) {
        if (elm && doc && typeof elm === 'string') {
          var node = doc.getElementById(elm);
          if (node && node.id !== elm) {
            return doc.getElementsByName(elm)[1];
          } else {
            return node;
          }
        }
        return elm;
      };
      var $$ = function (elm) {
        if (typeof elm === 'string') {
          elm = get(elm);
        }
        return $(elm);
      };
      var getAttrib = function (elm, name, defaultVal) {
        var hook, value;
        var $elm = $$(elm);
        if ($elm.length) {
          hook = attrHooks[name];
          if (hook && hook.get) {
            value = hook.get($elm, name);
          } else {
            value = $elm.attr(name);
          }
        }
        if (typeof value === 'undefined') {
          value = defaultVal || '';
        }
        return value;
      };
      var getAttribs = function (elm) {
        var node = get(elm);
        if (!node) {
          return [];
        }
        return node.attributes;
      };
      var setAttrib = function (elm, name, value) {
        var originalValue, hook;
        if (value === '') {
          value = null;
        }
        var $elm = $$(elm);
        originalValue = $elm.attr(name);
        if (!$elm.length) {
          return;
        }
        hook = attrHooks[name];
        if (hook && hook.set) {
          hook.set($elm, value, name);
        } else {
          $elm.attr(name, value);
        }
        if (originalValue !== value && settings.onSetAttrib) {
          settings.onSetAttrib({
            attrElm: $elm,
            attrName: name,
            attrValue: value
          });
        }
      };
      var clone = function (node, deep) {
        if (!isIE || node.nodeType !== 1 || deep) {
          return node.cloneNode(deep);
        }
        if (!deep) {
          var clone_1 = doc.createElement(node.nodeName);
          each$5(getAttribs(node), function (attr) {
            setAttrib(clone_1, attr.nodeName, getAttrib(node, attr.nodeName));
          });
          return clone_1;
        }
        return null;
      };
      var getRoot = function () {
        return settings.root_element || doc.body;
      };
      var getViewPort = function (argWin) {
        var vp = getBounds(argWin);
        return {
          x: vp.x(),
          y: vp.y(),
          w: vp.width(),
          h: vp.height()
        };
      };
      var getPos = function (elm, rootElm) {
        return Position$1.getPos(doc.body, get(elm), rootElm);
      };
      var setStyle = function (elm, name, value) {
        var $elm = isString(name) ? $$(elm).css(name, value) : $$(elm).css(name);
        if (settings.update_styles) {
          updateInternalStyleAttr(styles, $elm);
        }
      };
      var setStyles = function (elm, stylesArg) {
        var $elm = $$(elm).css(stylesArg);
        if (settings.update_styles) {
          updateInternalStyleAttr(styles, $elm);
        }
      };
      var getStyle = function (elm, name, computed) {
        var $elm = $$(elm);
        if (computed) {
          return $elm.css(name);
        }
        name = name.replace(/-(\D)/g, function (a, b) {
          return b.toUpperCase();
        });
        if (name === 'float') {
          name = Env.browser.isIE() ? 'styleFloat' : 'cssFloat';
        }
        return $elm[0] && $elm[0].style ? $elm[0].style[name] : undefined;
      };
      var getSize = function (elm) {
        var w, h;
        elm = get(elm);
        w = getStyle(elm, 'width');
        h = getStyle(elm, 'height');
        if (w.indexOf('px') === -1) {
          w = 0;
        }
        if (h.indexOf('px') === -1) {
          h = 0;
        }
        return {
          w: parseInt(w, 10) || elm.offsetWidth || elm.clientWidth,
          h: parseInt(h, 10) || elm.offsetHeight || elm.clientHeight
        };
      };
      var getRect = function (elm) {
        var pos, size;
        elm = get(elm);
        pos = getPos(elm);
        size = getSize(elm);
        return {
          x: pos.x,
          y: pos.y,
          w: size.w,
          h: size.h
        };
      };
      var is = function (elm, selector) {
        var i;
        if (!elm) {
          return false;
        }
        if (!Array.isArray(elm)) {
          if (selector === '*') {
            return elm.nodeType === 1;
          }
          if (simpleSelectorRe.test(selector)) {
            var selectors = selector.toLowerCase().split(/,/);
            var elmName = elm.nodeName.toLowerCase();
            for (i = selectors.length - 1; i >= 0; i--) {
              if (selectors[i] === elmName) {
                return true;
              }
            }
            return false;
          }
          if (elm.nodeType && elm.nodeType !== 1) {
            return false;
          }
        }
        var elms = !Array.isArray(elm) ? [elm] : elm;
        return Sizzle(selector, elms[0].ownerDocument || elms[0], null, elms).length > 0;
      };
      var getParents = function (elm, selector, root, collect) {
        var result = [];
        var selectorVal;
        var node = get(elm);
        collect = collect === undefined;
        root = root || (getRoot().nodeName !== 'BODY' ? getRoot().parentNode : null);
        if (Tools.is(selector, 'string')) {
          selectorVal = selector;
          if (selector === '*') {
            selector = function (node) {
              return node.nodeType === 1;
            };
          } else {
            selector = function (node) {
              return is(node, selectorVal);
            };
          }
        }
        while (node) {
          if (node === root || !node.nodeType || node.nodeType === 9) {
            break;
          }
          if (!selector || typeof selector === 'function' && selector(node)) {
            if (collect) {
              result.push(node);
            } else {
              return [node];
            }
          }
          node = node.parentNode;
        }
        return collect ? result : null;
      };
      var getParent = function (node, selector, root) {
        var parents = getParents(node, selector, root, false);
        return parents && parents.length > 0 ? parents[0] : null;
      };
      var _findSib = function (node, selector, name) {
        var func = selector;
        if (node) {
          if (typeof selector === 'string') {
            func = function (node) {
              return is(node, selector);
            };
          }
          for (node = node[name]; node; node = node[name]) {
            if (typeof func === 'function' && func(node)) {
              return node;
            }
          }
        }
        return null;
      };
      var getNext = function (node, selector) {
        return _findSib(node, selector, 'nextSibling');
      };
      var getPrev = function (node, selector) {
        return _findSib(node, selector, 'previousSibling');
      };
      var select = function (selector, scope) {
        return Sizzle(selector, get(scope) || settings.root_element || doc, []);
      };
      var run = function (elm, func, scope) {
        var result;
        var node = typeof elm === 'string' ? get(elm) : elm;
        if (!node) {
          return false;
        }
        if (Tools.isArray(node) && (node.length || node.length === 0)) {
          result = [];
          each$5(node, function (elm, i) {
            if (elm) {
              if (typeof elm === 'string') {
                elm = get(elm);
              }
              result.push(func.call(scope, elm, i));
            }
          });
          return result;
        }
        var context = scope ? scope : _this;
        return func.call(context, node);
      };
      var setAttribs = function (elm, attrs) {
        $$(elm).each(function (i, node) {
          each$5(attrs, function (value, name) {
            setAttrib(node, name, value);
          });
        });
      };
      var setHTML = function (elm, html) {
        var $elm = $$(elm);
        if (isIE) {
          $elm.each(function (i, target) {
            if (target.canHaveHTML === false) {
              return;
            }
            while (target.firstChild) {
              target.removeChild(target.firstChild);
            }
            try {
              target.innerHTML = '<br>' + html;
              target.removeChild(target.firstChild);
            } catch (ex) {
              DomQuery('<div></div>').html('<br>' + html).contents().slice(1).appendTo(target);
            }
            return html;
          });
        } else {
          $elm.html(html);
        }
      };
      var add = function (parentElm, name, attrs, html, create) {
        return run(parentElm, function (parentElm) {
          var newElm = typeof name === 'string' ? doc.createElement(name) : name;
          setAttribs(newElm, attrs);
          if (html) {
            if (typeof html !== 'string' && html.nodeType) {
              newElm.appendChild(html);
            } else if (typeof html === 'string') {
              setHTML(newElm, html);
            }
          }
          return !create ? parentElm.appendChild(newElm) : newElm;
        });
      };
      var create = function (name, attrs, html) {
        return add(doc.createElement(name), name, attrs, html, true);
      };
      var decode = Entities.decode;
      var encode = Entities.encodeAllRaw;
      var createHTML = function (name, attrs, html) {
        var outHtml = '', key;
        outHtml += '<' + name;
        for (key in attrs) {
          if (attrs.hasOwnProperty(key) && attrs[key] !== null && typeof attrs[key] !== 'undefined') {
            outHtml += ' ' + key + '="' + encode(attrs[key]) + '"';
          }
        }
        if (typeof html !== 'undefined') {
          return outHtml + '>' + html + '</' + name + '>';
        }
        return outHtml + ' />';
      };
      var createFragment = function (html) {
        var node;
        var container = doc.createElement('div');
        var frag = doc.createDocumentFragment();
        if (html) {
          container.innerHTML = html;
        }
        while (node = container.firstChild) {
          frag.appendChild(node);
        }
        return frag;
      };
      var remove = function (node, keepChildren) {
        var $node = $$(node);
        if (keepChildren) {
          $node.each(function () {
            var child;
            while (child = this.firstChild) {
              if (child.nodeType === 3 && child.data.length === 0) {
                this.removeChild(child);
              } else {
                this.parentNode.insertBefore(child, this);
              }
            }
          }).remove();
        } else {
          $node.remove();
        }
        return $node.length > 1 ? $node.toArray() : $node[0];
      };
      var removeAllAttribs = function (e) {
        return run(e, function (e) {
          var i;
          var attrs = e.attributes;
          for (i = attrs.length - 1; i >= 0; i--) {
            e.removeAttributeNode(attrs.item(i));
          }
        });
      };
      var parseStyle = function (cssText) {
        return styles.parse(cssText);
      };
      var serializeStyle = function (stylesArg, name) {
        return styles.serialize(stylesArg, name);
      };
      var addStyle = function (cssText) {
        var head, styleElm;
        if (self !== DOMUtils.DOM && doc === domGlobals.document) {
          if (addedStyles[cssText]) {
            return;
          }
          addedStyles[cssText] = true;
        }
        styleElm = doc.getElementById('mceDefaultStyles');
        if (!styleElm) {
          styleElm = doc.createElement('style');
          styleElm.id = 'mceDefaultStyles';
          styleElm.type = 'text/css';
          head = doc.getElementsByTagName('head')[0];
          if (head.firstChild) {
            head.insertBefore(styleElm, head.firstChild);
          } else {
            head.appendChild(styleElm);
          }
        }
        if (styleElm.styleSheet) {
          styleElm.styleSheet.cssText += cssText;
        } else {
          styleElm.appendChild(doc.createTextNode(cssText));
        }
      };
      var loadCSS = function (url) {
        var head;
        if (self !== DOMUtils.DOM && doc === domGlobals.document) {
          DOMUtils.DOM.loadCSS(url);
          return;
        }
        if (!url) {
          url = '';
        }
        head = doc.getElementsByTagName('head')[0];
        each$5(url.split(','), function (url) {
          var link;
          url = Tools._addCacheSuffix(url);
          if (files[url]) {
            return;
          }
          files[url] = true;
          link = create('link', __assign(__assign({
            rel: 'stylesheet',
            type: 'text/css',
            href: url
          }, settings.contentCssCors ? { crossOrigin: 'anonymous' } : {}), settings.referrerPolicy ? { referrerPolicy: settings.referrerPolicy } : {}));
          head.appendChild(link);
        });
      };
      var toggleClass = function (elm, cls, state) {
        $$(elm).toggleClass(cls, state).each(function () {
          if (this.className === '') {
            DomQuery(this).attr('class', null);
          }
        });
      };
      var addClass = function (elm, cls) {
        $$(elm).addClass(cls);
      };
      var removeClass = function (elm, cls) {
        toggleClass(elm, cls, false);
      };
      var hasClass = function (elm, cls) {
        return $$(elm).hasClass(cls);
      };
      var show = function (elm) {
        $$(elm).show();
      };
      var hide = function (elm) {
        $$(elm).hide();
      };
      var isHidden = function (elm) {
        return $$(elm).css('display') === 'none';
      };
      var uniqueId = function (prefix) {
        return (!prefix ? 'mce_' : prefix) + counter++;
      };
      var getOuterHTML = function (elm) {
        var node = typeof elm === 'string' ? get(elm) : elm;
        return NodeType.isElement(node) ? node.outerHTML : DomQuery('<div></div>').append(DomQuery(node).clone()).html();
      };
      var setOuterHTML = function (elm, html) {
        $$(elm).each(function () {
          try {
            if ('outerHTML' in this) {
              this.outerHTML = html;
              return;
            }
          } catch (ex) {
          }
          remove(DomQuery(this).html(html), true);
        });
      };
      var insertAfter = function (node, reference) {
        var referenceNode = get(reference);
        return run(node, function (node) {
          var parent, nextSibling;
          parent = referenceNode.parentNode;
          nextSibling = referenceNode.nextSibling;
          if (nextSibling) {
            parent.insertBefore(node, nextSibling);
          } else {
            parent.appendChild(node);
          }
          return node;
        });
      };
      var replace = function (newElm, oldElm, keepChildren) {
        return run(oldElm, function (oldElm) {
          if (Tools.is(oldElm, 'array')) {
            newElm = newElm.cloneNode(true);
          }
          if (keepChildren) {
            each$5(grep$1(oldElm.childNodes), function (node) {
              newElm.appendChild(node);
            });
          }
          return oldElm.parentNode.replaceChild(newElm, oldElm);
        });
      };
      var rename = function (elm, name) {
        var newElm;
        if (elm.nodeName !== name.toUpperCase()) {
          newElm = create(name);
          each$5(getAttribs(elm), function (attrNode) {
            setAttrib(newElm, attrNode.nodeName, getAttrib(elm, attrNode.nodeName));
          });
          replace(newElm, elm, true);
        }
        return newElm || elm;
      };
      var findCommonAncestor = function (a, b) {
        var ps = a, pe;
        while (ps) {
          pe = b;
          while (pe && ps !== pe) {
            pe = pe.parentNode;
          }
          if (ps === pe) {
            break;
          }
          ps = ps.parentNode;
        }
        if (!ps && a.ownerDocument) {
          return a.ownerDocument.documentElement;
        }
        return ps;
      };
      var toHex = function (rgbVal) {
        return styles.toHex(Tools.trim(rgbVal));
      };
      var isEmpty = function (node, elements) {
        var i, attributes, type, name, brCount = 0;
        node = node.firstChild;
        if (node) {
          var walker = new TreeWalker(node, node.parentNode);
          var whitespace = schema ? schema.getWhiteSpaceElements() : {};
          elements = elements || (schema ? schema.getNonEmptyElements() : null);
          do {
            type = node.nodeType;
            if (NodeType.isElement(node)) {
              var bogusVal = node.getAttribute('data-mce-bogus');
              if (bogusVal) {
                node = walker.next(bogusVal === 'all');
                continue;
              }
              name = node.nodeName.toLowerCase();
              if (elements && elements[name]) {
                if (name === 'br') {
                  brCount++;
                  node = walker.next();
                  continue;
                }
                return false;
              }
              attributes = getAttribs(node);
              i = attributes.length;
              while (i--) {
                name = attributes[i].nodeName;
                if (name === 'name' || name === 'data-mce-bookmark') {
                  return false;
                }
              }
            }
            if (type === 8) {
              return false;
            }
            if (type === 3 && !whiteSpaceRegExp$2.test(node.nodeValue)) {
              return false;
            }
            if (type === 3 && node.parentNode && whitespace[node.parentNode.nodeName] && whiteSpaceRegExp$2.test(node.nodeValue)) {
              return false;
            }
            node = walker.next();
          } while (node);
        }
        return brCount <= 1;
      };
      var createRng = function () {
        return doc.createRange();
      };
      var split = function (parentElm, splitElm, replacementElm) {
        var r = createRng(), bef, aft, pa;
        if (parentElm && splitElm) {
          r.setStart(parentElm.parentNode, findNodeIndex(parentElm));
          r.setEnd(splitElm.parentNode, findNodeIndex(splitElm));
          bef = r.extractContents();
          r = createRng();
          r.setStart(splitElm.parentNode, findNodeIndex(splitElm) + 1);
          r.setEnd(parentElm.parentNode, findNodeIndex(parentElm) + 1);
          aft = r.extractContents();
          pa = parentElm.parentNode;
          pa.insertBefore(TrimNode.trimNode(self, bef), parentElm);
          if (replacementElm) {
            pa.insertBefore(replacementElm, parentElm);
          } else {
            pa.insertBefore(splitElm, parentElm);
          }
          pa.insertBefore(TrimNode.trimNode(self, aft), parentElm);
          remove(parentElm);
          return replacementElm || splitElm;
        }
      };
      var bind = function (target, name, func, scope) {
        if (Tools.isArray(target)) {
          var i = target.length;
          var rv = [];
          while (i--) {
            rv[i] = bind(target[i], name, func, scope);
          }
          return rv;
        }
        if (settings.collect && (target === doc || target === win)) {
          boundEvents.push([
            target,
            name,
            func,
            scope
          ]);
        }
        return events.bind(target, name, func, scope || self);
      };
      var unbind = function (target, name, func) {
        var i;
        if (Tools.isArray(target)) {
          i = target.length;
          var rv = [];
          while (i--) {
            rv[i] = unbind(target[i], name, func);
          }
          return rv;
        }
        if (boundEvents && (target === doc || target === win)) {
          i = boundEvents.length;
          while (i--) {
            var item = boundEvents[i];
            if (target === item[0] && (!name || name === item[1]) && (!func || func === item[2])) {
              events.unbind(item[0], item[1], item[2]);
            }
          }
        }
        return events.unbind(target, name, func);
      };
      var fire = function (target, name, evt) {
        return events.fire(target, name, evt);
      };
      var getContentEditable = function (node) {
        if (node && NodeType.isElement(node)) {
          var contentEditable = node.getAttribute('data-mce-contenteditable');
          if (contentEditable && contentEditable !== 'inherit') {
            return contentEditable;
          }
          return node.contentEditable !== 'inherit' ? node.contentEditable : null;
        } else {
          return null;
        }
      };
      var getContentEditableParent = function (node) {
        var root = getRoot();
        var state = null;
        for (; node && node !== root; node = node.parentNode) {
          state = getContentEditable(node);
          if (state !== null) {
            break;
          }
        }
        return state;
      };
      var destroy = function () {
        if (boundEvents) {
          var i = boundEvents.length;
          while (i--) {
            var item = boundEvents[i];
            events.unbind(item[0], item[1], item[2]);
          }
        }
        if (Sizzle.setDocument) {
          Sizzle.setDocument();
        }
      };
      var isChildOf = function (node, parent) {
        while (node) {
          if (parent === node) {
            return true;
          }
          node = node.parentNode;
        }
        return false;
      };
      var dumpRng = function (r) {
        return 'startContainer: ' + r.startContainer.nodeName + ', startOffset: ' + r.startOffset + ', endContainer: ' + r.endContainer.nodeName + ', endOffset: ' + r.endOffset;
      };
      var self = {
        doc: doc,
        settings: settings,
        win: win,
        files: files,
        stdMode: stdMode,
        boxModel: boxModel,
        styleSheetLoader: styleSheetLoader,
        boundEvents: boundEvents,
        styles: styles,
        schema: schema,
        events: events,
        isBlock: isBlock,
        $: $,
        $$: $$,
        root: null,
        clone: clone,
        getRoot: getRoot,
        getViewPort: getViewPort,
        getRect: getRect,
        getSize: getSize,
        getParent: getParent,
        getParents: getParents,
        get: get,
        getNext: getNext,
        getPrev: getPrev,
        select: select,
        is: is,
        add: add,
        create: create,
        createHTML: createHTML,
        createFragment: createFragment,
        remove: remove,
        setStyle: setStyle,
        getStyle: getStyle,
        setStyles: setStyles,
        removeAllAttribs: removeAllAttribs,
        setAttrib: setAttrib,
        setAttribs: setAttribs,
        getAttrib: getAttrib,
        getPos: getPos,
        parseStyle: parseStyle,
        serializeStyle: serializeStyle,
        addStyle: addStyle,
        loadCSS: loadCSS,
        addClass: addClass,
        removeClass: removeClass,
        hasClass: hasClass,
        toggleClass: toggleClass,
        show: show,
        hide: hide,
        isHidden: isHidden,
        uniqueId: uniqueId,
        setHTML: setHTML,
        getOuterHTML: getOuterHTML,
        setOuterHTML: setOuterHTML,
        decode: decode,
        encode: encode,
        insertAfter: insertAfter,
        replace: replace,
        rename: rename,
        findCommonAncestor: findCommonAncestor,
        toHex: toHex,
        run: run,
        getAttribs: getAttribs,
        isEmpty: isEmpty,
        createRng: createRng,
        nodeIndex: findNodeIndex,
        split: split,
        bind: bind,
        unbind: unbind,
        fire: fire,
        getContentEditable: getContentEditable,
        getContentEditableParent: getContentEditableParent,
        destroy: destroy,
        isChildOf: isChildOf,
        dumpRng: dumpRng
      };
      attrHooks = setupAttrHooks(styles, settings, function () {
        return self;
      });
      return self;
    }
    (function (DOMUtils) {
      DOMUtils.DOM = DOMUtils(domGlobals.document);
      DOMUtils.nodeIndex = findNodeIndex;
    }(DOMUtils || (DOMUtils = {})));
    var DOMUtils$1 = DOMUtils;

    var DOM = DOMUtils$1.DOM;
    var each$6 = Tools.each, grep$2 = Tools.grep;
    var QUEUED = 0;
    var LOADING = 1;
    var LOADED = 2;
    var FAILED = 3;
    var ScriptLoader = function () {
      function ScriptLoader(settings) {
        if (settings === void 0) {
          settings = {};
        }
        this.states = {};
        this.queue = [];
        this.scriptLoadedCallbacks = {};
        this.queueLoadedCallbacks = [];
        this.loading = 0;
        this.settings = settings;
      }
      ScriptLoader.prototype._setReferrerPolicy = function (referrerPolicy) {
        this.settings.referrerPolicy = referrerPolicy;
      };
      ScriptLoader.prototype.loadScript = function (url, success, failure) {
        var dom = DOM;
        var elm, id;
        var done = function () {
          dom.remove(id);
          if (elm) {
            elm.onreadystatechange = elm.onload = elm = null;
          }
          success();
        };
        var error = function () {
          if (isFunction(failure)) {
            failure();
          } else {
            if (typeof domGlobals.console !== 'undefined' && domGlobals.console.log) {
              domGlobals.console.log('Failed to load script: ' + url);
            }
          }
        };
        id = dom.uniqueId();
        elm = domGlobals.document.createElement('script');
        elm.id = id;
        elm.type = 'text/javascript';
        elm.src = Tools._addCacheSuffix(url);
        if (this.settings.referrerPolicy) {
          dom.setAttrib(elm, 'referrerpolicy', this.settings.referrerPolicy);
        }
        elm.onload = done;
        elm.onerror = error;
        (domGlobals.document.getElementsByTagName('head')[0] || domGlobals.document.body).appendChild(elm);
      };
      ScriptLoader.prototype.isDone = function (url) {
        return this.states[url] === LOADED;
      };
      ScriptLoader.prototype.markDone = function (url) {
        this.states[url] = LOADED;
      };
      ScriptLoader.prototype.add = function (url, success, scope, failure) {
        var state = this.states[url];
        if (state === undefined) {
          this.queue.push(url);
          this.states[url] = QUEUED;
        }
        if (success) {
          if (!this.scriptLoadedCallbacks[url]) {
            this.scriptLoadedCallbacks[url] = [];
          }
          this.scriptLoadedCallbacks[url].push({
            success: success,
            failure: failure,
            scope: scope || this
          });
        }
      };
      ScriptLoader.prototype.load = function (url, success, scope, failure) {
        return this.add(url, success, scope, failure);
      };
      ScriptLoader.prototype.remove = function (url) {
        delete this.states[url];
        delete this.scriptLoadedCallbacks[url];
      };
      ScriptLoader.prototype.loadQueue = function (success, scope, failure) {
        this.loadScripts(this.queue, success, scope, failure);
      };
      ScriptLoader.prototype.loadScripts = function (scripts, success, scope, failure) {
        var self = this;
        var loadScripts;
        var failures = [];
        var execCallbacks = function (name, url) {
          each$6(self.scriptLoadedCallbacks[url], function (callback) {
            if (isFunction(callback[name])) {
              callback[name].call(callback.scope);
            }
          });
          self.scriptLoadedCallbacks[url] = undefined;
        };
        self.queueLoadedCallbacks.push({
          success: success,
          failure: failure,
          scope: scope || this
        });
        loadScripts = function () {
          var loadingScripts = grep$2(scripts);
          scripts.length = 0;
          each$6(loadingScripts, function (url) {
            if (self.states[url] === LOADED) {
              execCallbacks('success', url);
              return;
            }
            if (self.states[url] === FAILED) {
              execCallbacks('failure', url);
              return;
            }
            if (self.states[url] !== LOADING) {
              self.states[url] = LOADING;
              self.loading++;
              self.loadScript(url, function () {
                self.states[url] = LOADED;
                self.loading--;
                execCallbacks('success', url);
                loadScripts();
              }, function () {
                self.states[url] = FAILED;
                self.loading--;
                failures.push(url);
                execCallbacks('failure', url);
                loadScripts();
              });
            }
          });
          if (!self.loading) {
            var notifyCallbacks = self.queueLoadedCallbacks.slice(0);
            self.queueLoadedCallbacks.length = 0;
            each$6(notifyCallbacks, function (callback) {
              if (failures.length === 0) {
                if (isFunction(callback.success)) {
                  callback.success.call(callback.scope);
                }
              } else {
                if (isFunction(callback.failure)) {
                  callback.failure.call(callback.scope, failures);
                }
              }
            });
          }
        };
        loadScripts();
      };
      ScriptLoader.ScriptLoader = new ScriptLoader();
      return ScriptLoader;
    }();

    var isRaw = function (str) {
      return isObject(str) && has(str, 'raw');
    };
    var isTokenised = function (str) {
      return isArray(str) && str.length > 1;
    };
    var data = {};
    var currentCode = Cell('en');
    var getLanguageData = function () {
      return get(data, currentCode.get());
    };
    var getData = function () {
      return map$1(data, function (value) {
        return __assign({}, value);
      });
    };
    var setCode = function (newCode) {
      if (newCode) {
        currentCode.set(newCode);
      }
    };
    var getCode = function () {
      return currentCode.get();
    };
    var add = function (code, items) {
      var langData = data[code];
      if (!langData) {
        data[code] = langData = {};
      }
      each$1(items, function (translation, name) {
        langData[name.toLowerCase()] = translation;
      });
    };
    var translate = function (text) {
      var langData = getLanguageData().getOr({});
      var toString = function (obj) {
        if (isFunction(obj)) {
          return Object.prototype.toString.call(obj);
        }
        return !isEmpty(obj) ? '' + obj : '';
      };
      var isEmpty = function (text) {
        return text === '' || text === null || text === undefined;
      };
      var getLangData = function (text) {
        var textstr = toString(text);
        return get(langData, textstr.toLowerCase()).map(toString).getOr(textstr);
      };
      var removeContext = function (str) {
        return str.replace(/{context:\w+}$/, '');
      };
      var translated = function (text) {
        return text;
      };
      if (isEmpty(text)) {
        return translated('');
      }
      if (isRaw(text)) {
        return translated(toString(text.raw));
      }
      if (isTokenised(text)) {
        var values_1 = text.slice(1);
        var substitued = getLangData(text[0]).replace(/\{([0-9]+)\}/g, function ($1, $2) {
          return has(values_1, $2) ? toString(values_1[$2]) : $1;
        });
        return translated(removeContext(substitued));
      }
      return translated(removeContext(getLangData(text)));
    };
    var isRtl = function () {
      return getLanguageData().bind(function (items) {
        return get(items, '_dir');
      }).exists(function (dir) {
        return dir === 'rtl';
      });
    };
    var hasCode = function (code) {
      return has(data, code);
    };
    var I18n = {
      getData: getData,
      setCode: setCode,
      getCode: getCode,
      add: add,
      translate: translate,
      isRtl: isRtl,
      hasCode: hasCode
    };

    function AddOnManager() {
      var _this = this;
      var items = [];
      var urls = {};
      var lookup = {};
      var _listeners = [];
      var runListeners = function (name, state) {
        var matchedListeners = filter(_listeners, function (listener) {
          return listener.name === name && listener.state === state;
        });
        each(matchedListeners, function (listener) {
          return listener.callback();
        });
      };
      var get = function (name) {
        if (lookup[name]) {
          return lookup[name].instance;
        }
        return undefined;
      };
      var dependencies = function (name) {
        var result;
        if (lookup[name]) {
          result = lookup[name].dependencies;
        }
        return result || [];
      };
      var requireLangPack = function (name, languages) {
        if (AddOnManager.languageLoad !== false) {
          waitFor(name, function () {
            var language = I18n.getCode();
            var wrappedLanguages = ',' + (languages || '') + ',';
            if (!language || languages && wrappedLanguages.indexOf(',' + language + ',') === -1) {
              return;
            }
            ScriptLoader.ScriptLoader.add(urls[name] + '/langs/' + language + '.js');
          }, 'loaded');
        }
      };
      var add = function (id, addOn, dependencies) {
        var addOnConstructor = addOn;
        items.push(addOnConstructor);
        lookup[id] = {
          instance: addOnConstructor,
          dependencies: dependencies
        };
        runListeners(id, 'added');
        return addOnConstructor;
      };
      var remove = function (name) {
        delete urls[name];
        delete lookup[name];
      };
      var createUrl = function (baseUrl, dep) {
        if (typeof dep === 'object') {
          return dep;
        }
        return typeof baseUrl === 'string' ? {
          prefix: '',
          resource: dep,
          suffix: ''
        } : {
          prefix: baseUrl.prefix,
          resource: dep,
          suffix: baseUrl.suffix
        };
      };
      var addComponents = function (pluginName, scripts) {
        var pluginUrl = _this.urls[pluginName];
        each(scripts, function (script) {
          ScriptLoader.ScriptLoader.add(pluginUrl + '/' + script);
        });
      };
      var loadDependencies = function (name, addOnUrl, success, scope) {
        var deps = dependencies(name);
        each(deps, function (dep) {
          var newUrl = createUrl(addOnUrl, dep);
          load(newUrl.resource, newUrl, undefined, undefined);
        });
        if (success) {
          if (scope) {
            success.call(scope);
          } else {
            success.call(ScriptLoader);
          }
        }
      };
      var load = function (name, addOnUrl, success, scope, failure) {
        if (urls[name]) {
          return;
        }
        var urlString = typeof addOnUrl === 'string' ? addOnUrl : addOnUrl.prefix + addOnUrl.resource + addOnUrl.suffix;
        if (urlString.indexOf('/') !== 0 && urlString.indexOf('://') === -1) {
          urlString = AddOnManager.baseURL + '/' + urlString;
        }
        urls[name] = urlString.substring(0, urlString.lastIndexOf('/'));
        var done = function () {
          runListeners(name, 'loaded');
          loadDependencies(name, addOnUrl, success, scope);
        };
        if (lookup[name]) {
          done();
        } else {
          ScriptLoader.ScriptLoader.add(urlString, done, scope, failure);
        }
      };
      var waitFor = function (name, callback, state) {
        if (state === void 0) {
          state = 'added';
        }
        if (has(lookup, name) && state === 'added') {
          callback();
        } else if (has(urls, name) && state === 'loaded') {
          callback();
        } else {
          _listeners.push({
            name: name,
            state: state,
            callback: callback
          });
        }
      };
      return {
        items: items,
        urls: urls,
        lookup: lookup,
        _listeners: _listeners,
        get: get,
        dependencies: dependencies,
        requireLangPack: requireLangPack,
        add: add,
        remove: remove,
        createUrl: createUrl,
        addComponents: addComponents,
        load: load,
        waitFor: waitFor
      };
    }
    (function (AddOnManager) {
      AddOnManager.PluginManager = AddOnManager();
      AddOnManager.ThemeManager = AddOnManager();
    }(AddOnManager || (AddOnManager = {})));
    var AddOnManager$1 = AddOnManager;

    var first = function (fn, rate) {
      var timer = null;
      var cancel = function () {
        if (timer !== null) {
          domGlobals.clearTimeout(timer);
          timer = null;
        }
      };
      var throttle = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
          args[_i] = arguments[_i];
        }
        if (timer === null) {
          timer = domGlobals.setTimeout(function () {
            fn.apply(null, args);
            timer = null;
          }, rate);
        }
      };
      return {
        cancel: cancel,
        throttle: throttle
      };
    };
    var last$2 = function (fn, rate) {
      var timer = null;
      var cancel = function () {
        if (timer !== null) {
          domGlobals.clearTimeout(timer);
          timer = null;
        }
      };
      var throttle = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
          args[_i] = arguments[_i];
        }
        if (timer !== null) {
          domGlobals.clearTimeout(timer);
        }
        timer = domGlobals.setTimeout(function () {
          fn.apply(null, args);
          timer = null;
        }, rate);
      };
      return {
        cancel: cancel,
        throttle: throttle
      };
    };

    var read = function (element, attr) {
      var value = get$3(element, attr);
      return value === undefined || value === '' ? [] : value.split(' ');
    };
    var add$1 = function (element, attr, id) {
      var old = read(element, attr);
      var nu = old.concat([id]);
      set(element, attr, nu.join(' '));
      return true;
    };
    var remove$2 = function (element, attr, id) {
      var nu = filter(read(element, attr), function (v) {
        return v !== id;
      });
      if (nu.length > 0) {
        set(element, attr, nu.join(' '));
      } else {
        remove$1(element, attr);
      }
      return false;
    };

    var supports = function (element) {
      return element.dom().classList !== undefined;
    };
    var get$5 = function (element) {
      return read(element, 'class');
    };
    var add$2 = function (element, clazz) {
      return add$1(element, 'class', clazz);
    };
    var remove$3 = function (element, clazz) {
      return remove$2(element, 'class', clazz);
    };

    var add$3 = function (element, clazz) {
      if (supports(element)) {
        element.dom().classList.add(clazz);
      } else {
        add$2(element, clazz);
      }
    };
    var cleanClass = function (element) {
      var classList = supports(element) ? element.dom().classList : get$5(element);
      if (classList.length === 0) {
        remove$1(element, 'class');
      }
    };
    var remove$4 = function (element, clazz) {
      if (supports(element)) {
        var classList = element.dom().classList;
        classList.remove(clazz);
      } else {
        remove$3(element, clazz);
      }
      cleanClass(element);
    };
    var has$2 = function (element, clazz) {
      return supports(element) && element.dom().classList.contains(clazz);
    };

    var descendants = function (scope, predicate) {
      var result = [];
      each(children(scope), function (x) {
        if (predicate(x)) {
          result = result.concat([x]);
        }
        result = result.concat(descendants(x, predicate));
      });
      return result;
    };

    var descendants$1 = function (scope, selector) {
      return all(selector, scope);
    };

    function ClosestOrAncestor (is, ancestor, scope, a, isRoot) {
      return is(scope, a) ? Option.some(scope) : isFunction(isRoot) && isRoot(scope) ? Option.none() : ancestor(scope, a, isRoot);
    }

    var ancestor = function (scope, predicate, isRoot) {
      var element = scope.dom();
      var stop = isFunction(isRoot) ? isRoot : constant(false);
      while (element.parentNode) {
        element = element.parentNode;
        var el = Element.fromDom(element);
        if (predicate(el)) {
          return Option.some(el);
        } else if (stop(el)) {
          break;
        }
      }
      return Option.none();
    };
    var closest = function (scope, predicate, isRoot) {
      var is = function (s, test) {
        return test(s);
      };
      return ClosestOrAncestor(is, ancestor, scope, predicate, isRoot);
    };

    var ancestor$1 = function (scope, selector, isRoot) {
      return ancestor(scope, function (e) {
        return is(e, selector);
      }, isRoot);
    };
    var descendant = function (scope, selector) {
      return one(selector, scope);
    };
    var closest$1 = function (scope, selector, isRoot) {
      return ClosestOrAncestor(is, ancestor$1, scope, selector, isRoot);
    };

    var annotation = constant('mce-annotation');
    var dataAnnotation = constant('data-mce-annotation');
    var dataAnnotationId = constant('data-mce-annotation-uid');

    var identify = function (editor, annotationName) {
      var rng = editor.selection.getRng();
      var start = Element.fromDom(rng.startContainer);
      var root = Element.fromDom(editor.getBody());
      var selector = annotationName.fold(function () {
        return '.' + annotation();
      }, function (an) {
        return '[' + dataAnnotation() + '="' + an + '"]';
      });
      var newStart = child(start, rng.startOffset).getOr(start);
      var closest = closest$1(newStart, selector, function (n) {
        return eq(n, root);
      });
      var getAttr = function (c, property) {
        if (has$1(c, property)) {
          return Option.some(get$3(c, property));
        } else {
          return Option.none();
        }
      };
      return closest.bind(function (c) {
        return getAttr(c, '' + dataAnnotationId()).bind(function (uid) {
          return getAttr(c, '' + dataAnnotation()).map(function (name) {
            var elements = findMarkers(editor, uid);
            return {
              uid: uid,
              name: name,
              elements: elements
            };
          });
        });
      });
    };
    var isAnnotation = function (elem) {
      return isElement(elem) && has$2(elem, annotation());
    };
    var findMarkers = function (editor, uid) {
      var body = Element.fromDom(editor.getBody());
      return descendants$1(body, '[' + dataAnnotationId() + '="' + uid + '"]');
    };
    var findAll = function (editor, name) {
      var body = Element.fromDom(editor.getBody());
      var markers = descendants$1(body, '[' + dataAnnotation() + '="' + name + '"]');
      var directory = {};
      each(markers, function (m) {
        var uid = get$3(m, dataAnnotationId());
        var nodesAlready = directory.hasOwnProperty(uid) ? directory[uid] : [];
        directory[uid] = nodesAlready.concat([m]);
      });
      return directory;
    };

    var setup = function (editor, registry) {
      var changeCallbacks = Cell({});
      var initData = function () {
        return {
          listeners: [],
          previous: Cell(Option.none())
        };
      };
      var withCallbacks = function (name, f) {
        updateCallbacks(name, function (data) {
          f(data);
          return data;
        });
      };
      var updateCallbacks = function (name, f) {
        var callbackMap = changeCallbacks.get();
        var data = callbackMap.hasOwnProperty(name) ? callbackMap[name] : initData();
        var outputData = f(data);
        callbackMap[name] = outputData;
        changeCallbacks.set(callbackMap);
      };
      var fireCallbacks = function (name, uid, elements) {
        withCallbacks(name, function (data) {
          each(data.listeners, function (f) {
            return f(true, name, {
              uid: uid,
              nodes: map(elements, function (elem) {
                return elem.dom();
              })
            });
          });
        });
      };
      var fireNoAnnotation = function (name) {
        withCallbacks(name, function (data) {
          each(data.listeners, function (f) {
            return f(false, name);
          });
        });
      };
      var onNodeChange = last$2(function () {
        var callbackMap = changeCallbacks.get();
        var annotations = sort(keys(callbackMap));
        each(annotations, function (name) {
          updateCallbacks(name, function (data) {
            var prev = data.previous.get();
            identify(editor, Option.some(name)).fold(function () {
              if (prev.isSome()) {
                fireNoAnnotation(name);
                data.previous.set(Option.none());
              }
            }, function (_a) {
              var uid = _a.uid, name = _a.name, elements = _a.elements;
              if (!prev.is(uid)) {
                fireCallbacks(name, uid, elements);
                data.previous.set(Option.some(uid));
              }
            });
            return {
              previous: data.previous,
              listeners: data.listeners
            };
          });
        });
      }, 30);
      editor.on('remove', function () {
        onNodeChange.cancel();
      });
      editor.on('NodeChange', function () {
        onNodeChange.throttle();
      });
      var addListener = function (name, f) {
        updateCallbacks(name, function (data) {
          return {
            previous: data.previous,
            listeners: data.listeners.concat([f])
          };
        });
      };
      return { addListener: addListener };
    };

    var setup$1 = function (editor, registry) {
      var identifyParserNode = function (span) {
        return Option.from(span.attr(dataAnnotation())).bind(registry.lookup);
      };
      editor.on('init', function () {
        editor.serializer.addNodeFilter('span', function (spans) {
          each(spans, function (span) {
            identifyParserNode(span).each(function (settings) {
              if (settings.persistent === false) {
                span.unwrap();
              }
            });
          });
        });
      });
    };

    var create$1 = function () {
      var annotations = {};
      var register = function (name, settings) {
        annotations[name] = {
          name: name,
          settings: settings
        };
      };
      var lookup = function (name) {
        return annotations.hasOwnProperty(name) ? Option.from(annotations[name]).map(function (a) {
          return a.settings;
        }) : Option.none();
      };
      return {
        register: register,
        lookup: lookup
      };
    };

    var unique = 0;
    var generate = function (prefix) {
      var date = new Date();
      var time = date.getTime();
      var random = Math.floor(Math.random() * 1000000000);
      unique++;
      return prefix + '_' + random + unique + String(time);
    };

    var add$4 = function (element, classes) {
      each(classes, function (x) {
        add$3(element, x);
      });
    };

    var fromHtml$1 = function (html, scope) {
      var doc = scope || domGlobals.document;
      var div = doc.createElement('div');
      div.innerHTML = html;
      return children(Element.fromDom(div));
    };

    var get$6 = function (element) {
      return element.dom().innerHTML;
    };
    var set$1 = function (element, content) {
      var owner$1 = owner(element);
      var docDom = owner$1.dom();
      var fragment = Element.fromDom(docDom.createDocumentFragment());
      var contentElements = fromHtml$1(content, docDom);
      append$1(fragment, contentElements);
      empty(element);
      append(element, fragment);
    };

    var clone = function (original, isDeep) {
      return Element.fromDom(original.dom().cloneNode(isDeep));
    };
    var shallow = function (original) {
      return clone(original, false);
    };
    var deep = function (original) {
      return clone(original, true);
    };

    var ZWSP = zeroWidth;
    var isZwsp = function (chr) {
      return chr === ZWSP;
    };
    var trim$3 = function (text) {
      return text.replace(new RegExp(ZWSP, 'g'), '');
    };
    var Zwsp = {
      isZwsp: isZwsp,
      ZWSP: ZWSP,
      trim: trim$3
    };

    var isElement$2 = NodeType.isElement;
    var isText$2 = NodeType.isText;
    var isCaretContainerBlock = function (node) {
      if (isText$2(node)) {
        node = node.parentNode;
      }
      return isElement$2(node) && node.hasAttribute('data-mce-caret');
    };
    var isCaretContainerInline = function (node) {
      return isText$2(node) && Zwsp.isZwsp(node.data);
    };
    var isCaretContainer = function (node) {
      return isCaretContainerBlock(node) || isCaretContainerInline(node);
    };
    var hasContent = function (node) {
      return node.firstChild !== node.lastChild || !NodeType.isBr(node.firstChild);
    };
    var insertInline = function (node, before) {
      var doc, sibling, textNode, parentNode;
      doc = node.ownerDocument;
      textNode = doc.createTextNode(Zwsp.ZWSP);
      parentNode = node.parentNode;
      if (!before) {
        sibling = node.nextSibling;
        if (isText$2(sibling)) {
          if (isCaretContainer(sibling)) {
            return sibling;
          }
          if (startsWithCaretContainer(sibling)) {
            sibling.splitText(1);
            return sibling;
          }
        }
        if (node.nextSibling) {
          parentNode.insertBefore(textNode, node.nextSibling);
        } else {
          parentNode.appendChild(textNode);
        }
      } else {
        sibling = node.previousSibling;
        if (isText$2(sibling)) {
          if (isCaretContainer(sibling)) {
            return sibling;
          }
          if (endsWithCaretContainer(sibling)) {
            return sibling.splitText(sibling.data.length - 1);
          }
        }
        parentNode.insertBefore(textNode, node);
      }
      return textNode;
    };
    var isBeforeInline = function (pos) {
      var container = pos.container();
      if (!pos || !NodeType.isText(container)) {
        return false;
      }
      return container.data.charAt(pos.offset()) === Zwsp.ZWSP || pos.isAtStart() && isCaretContainerInline(container.previousSibling);
    };
    var isAfterInline = function (pos) {
      var container = pos.container();
      if (!pos || !NodeType.isText(container)) {
        return false;
      }
      return container.data.charAt(pos.offset() - 1) === Zwsp.ZWSP || pos.isAtEnd() && isCaretContainerInline(container.nextSibling);
    };
    var createBogusBr = function () {
      var br = domGlobals.document.createElement('br');
      br.setAttribute('data-mce-bogus', '1');
      return br;
    };
    var insertBlock = function (blockName, node, before) {
      var doc, blockNode, parentNode;
      doc = node.ownerDocument;
      blockNode = doc.createElement(blockName);
      blockNode.setAttribute('data-mce-caret', before ? 'before' : 'after');
      blockNode.setAttribute('data-mce-bogus', 'all');
      blockNode.appendChild(createBogusBr());
      parentNode = node.parentNode;
      if (!before) {
        if (node.nextSibling) {
          parentNode.insertBefore(blockNode, node.nextSibling);
        } else {
          parentNode.appendChild(blockNode);
        }
      } else {
        parentNode.insertBefore(blockNode, node);
      }
      return blockNode;
    };
    var startsWithCaretContainer = function (node) {
      return isText$2(node) && node.data[0] === Zwsp.ZWSP;
    };
    var endsWithCaretContainer = function (node) {
      return isText$2(node) && node.data[node.data.length - 1] === Zwsp.ZWSP;
    };
    var trimBogusBr = function (elm) {
      var brs = elm.getElementsByTagName('br');
      var lastBr = brs[brs.length - 1];
      if (NodeType.isBogus(lastBr)) {
        lastBr.parentNode.removeChild(lastBr);
      }
    };
    var showCaretContainerBlock = function (caretContainer) {
      if (caretContainer && caretContainer.hasAttribute('data-mce-caret')) {
        trimBogusBr(caretContainer);
        caretContainer.removeAttribute('data-mce-caret');
        caretContainer.removeAttribute('data-mce-bogus');
        caretContainer.removeAttribute('style');
        caretContainer.removeAttribute('_moz_abspos');
        return caretContainer;
      }
      return null;
    };
    var isRangeInCaretContainerBlock = function (range) {
      return isCaretContainerBlock(range.startContainer);
    };

    var isContentEditableTrue$1 = NodeType.isContentEditableTrue;
    var isContentEditableFalse$1 = NodeType.isContentEditableFalse;
    var isBr$2 = NodeType.isBr;
    var isText$3 = NodeType.isText;
    var isInvalidTextElement = NodeType.matchNodeNames([
      'script',
      'style',
      'textarea'
    ]);
    var isAtomicInline = NodeType.matchNodeNames([
      'img',
      'input',
      'textarea',
      'hr',
      'iframe',
      'video',
      'audio',
      'object'
    ]);
    var isTable$2 = NodeType.matchNodeNames(['table']);
    var isCaretContainer$1 = isCaretContainer;
    var isCaretCandidate = function (node) {
      if (isCaretContainer$1(node)) {
        return false;
      }
      if (isText$3(node)) {
        if (isInvalidTextElement(node.parentNode)) {
          return false;
        }
        return true;
      }
      return isAtomicInline(node) || isBr$2(node) || isTable$2(node) || isNonUiContentEditableFalse(node);
    };
    var isUnselectable = function (node) {
      return NodeType.isElement(node) && node.getAttribute('unselectable') === 'true';
    };
    var isNonUiContentEditableFalse = function (node) {
      return isUnselectable(node) === false && isContentEditableFalse$1(node);
    };
    var isInEditable = function (node, root) {
      for (node = node.parentNode; node && node !== root; node = node.parentNode) {
        if (isNonUiContentEditableFalse(node)) {
          return false;
        }
        if (isContentEditableTrue$1(node)) {
          return true;
        }
      }
      return true;
    };
    var isAtomicContentEditableFalse = function (node) {
      if (!isNonUiContentEditableFalse(node)) {
        return false;
      }
      return foldl(from$1(node.getElementsByTagName('*')), function (result, elm) {
        return result || isContentEditableTrue$1(elm);
      }, false) !== true;
    };
    var isAtomic = function (node) {
      return isAtomicInline(node) || isAtomicContentEditableFalse(node);
    };
    var isEditableCaretCandidate = function (node, root) {
      return isCaretCandidate(node) && isInEditable(node, root);
    };

    var round = Math.round;
    var clone$1 = function (rect) {
      if (!rect) {
        return {
          left: 0,
          top: 0,
          bottom: 0,
          right: 0,
          width: 0,
          height: 0
        };
      }
      return {
        left: round(rect.left),
        top: round(rect.top),
        bottom: round(rect.bottom),
        right: round(rect.right),
        width: round(rect.width),
        height: round(rect.height)
      };
    };
    var collapse = function (rect, toStart) {
      rect = clone$1(rect);
      if (toStart) {
        rect.right = rect.left;
      } else {
        rect.left = rect.left + rect.width;
        rect.right = rect.left;
      }
      rect.width = 0;
      return rect;
    };
    var isEqual = function (rect1, rect2) {
      return rect1.left === rect2.left && rect1.top === rect2.top && rect1.bottom === rect2.bottom && rect1.right === rect2.right;
    };
    var isValidOverflow = function (overflowY, rect1, rect2) {
      return overflowY >= 0 && overflowY <= Math.min(rect1.height, rect2.height) / 2;
    };
    var isAbove = function (rect1, rect2) {
      if (rect1.bottom - rect1.height / 2 < rect2.top) {
        return true;
      }
      if (rect1.top > rect2.bottom) {
        return false;
      }
      return isValidOverflow(rect2.top - rect1.bottom, rect1, rect2);
    };
    var isBelow = function (rect1, rect2) {
      if (rect1.top > rect2.bottom) {
        return true;
      }
      if (rect1.bottom < rect2.top) {
        return false;
      }
      return isValidOverflow(rect2.bottom - rect1.top, rect1, rect2);
    };
    var containsXY = function (rect, clientX, clientY) {
      return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
    };

    var getSelectedNode = function (range) {
      var startContainer = range.startContainer, startOffset = range.startOffset;
      if (startContainer.hasChildNodes() && range.endOffset === startOffset + 1) {
        return startContainer.childNodes[startOffset];
      }
      return null;
    };
    var getNode = function (container, offset) {
      if (container.nodeType === 1 && container.hasChildNodes()) {
        if (offset >= container.childNodes.length) {
          offset = container.childNodes.length - 1;
        }
        container = container.childNodes[offset];
      }
      return container;
    };

    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]');
    var isExtendingChar = function (ch) {
      return typeof ch === 'string' && ch.charCodeAt(0) >= 768 && extendingChars.test(ch);
    };

    var lift2 = function (oa, ob, f) {
      return oa.isSome() && ob.isSome() ? Option.some(f(oa.getOrDie(), ob.getOrDie())) : Option.none();
    };
    var lift3 = function (oa, ob, oc, f) {
      return oa.isSome() && ob.isSome() && oc.isSome() ? Option.some(f(oa.getOrDie(), ob.getOrDie(), oc.getOrDie())) : Option.none();
    };
    var someIf = function (b, a) {
      return b ? Option.some(a) : Option.none();
    };

    var slice$2 = [].slice;
    var or = function () {
      var x = [];
      for (var _i = 0; _i < arguments.length; _i++) {
        x[_i] = arguments[_i];
      }
      var args = slice$2.call(arguments);
      return function (x) {
        for (var i = 0; i < args.length; i++) {
          if (args[i](x)) {
            return true;
          }
        }
        return false;
      };
    };
    var and = function () {
      var x = [];
      for (var _i = 0; _i < arguments.length; _i++) {
        x[_i] = arguments[_i];
      }
      var args = slice$2.call(arguments);
      return function (x) {
        for (var i = 0; i < args.length; i++) {
          if (!args[i](x)) {
            return false;
          }
        }
        return true;
      };
    };
    var Predicate = {
      and: and,
      or: or
    };

    var isElement$3 = NodeType.isElement;
    var isCaretCandidate$1 = isCaretCandidate;
    var isBlock$1 = NodeType.matchStyleValues('display', 'block table');
    var isFloated = NodeType.matchStyleValues('float', 'left right');
    var isValidElementCaretCandidate = Predicate.and(isElement$3, isCaretCandidate$1, not(isFloated));
    var isNotPre = not(NodeType.matchStyleValues('white-space', 'pre pre-line pre-wrap'));
    var isText$4 = NodeType.isText;
    var isBr$3 = NodeType.isBr;
    var nodeIndex = DOMUtils$1.nodeIndex;
    var resolveIndex = getNode;
    var createRange = function (doc) {
      return 'createRange' in doc ? doc.createRange() : DOMUtils$1.DOM.createRng();
    };
    var isWhiteSpace = function (chr) {
      return chr && /[\r\n\t ]/.test(chr);
    };
    var isRange = function (rng) {
      return !!rng.setStart && !!rng.setEnd;
    };
    var isHiddenWhiteSpaceRange = function (range) {
      var container = range.startContainer;
      var offset = range.startOffset;
      var text;
      if (isWhiteSpace(range.toString()) && isNotPre(container.parentNode) && NodeType.isText(container)) {
        text = container.data;
        if (isWhiteSpace(text[offset - 1]) || isWhiteSpace(text[offset + 1])) {
          return true;
        }
      }
      return false;
    };
    var getBrClientRect = function (brNode) {
      var doc = brNode.ownerDocument;
      var rng = createRange(doc);
      var nbsp$1 = doc.createTextNode(nbsp);
      var parentNode = brNode.parentNode;
      var clientRect;
      parentNode.insertBefore(nbsp$1, brNode);
      rng.setStart(nbsp$1, 0);
      rng.setEnd(nbsp$1, 1);
      clientRect = clone$1(rng.getBoundingClientRect());
      parentNode.removeChild(nbsp$1);
      return clientRect;
    };
    var getBoundingClientRectWebKitText = function (rng) {
      var sc = rng.startContainer;
      var ec = rng.endContainer;
      var so = rng.startOffset;
      var eo = rng.endOffset;
      if (sc === ec && NodeType.isText(ec) && so === 0 && eo === 1) {
        var newRng = rng.cloneRange();
        newRng.setEndAfter(ec);
        return getBoundingClientRect(newRng);
      } else {
        return null;
      }
    };
    var isZeroRect = function (r) {
      return r.left === 0 && r.right === 0 && r.top === 0 && r.bottom === 0;
    };
    var getBoundingClientRect = function (item) {
      var clientRect, clientRects;
      clientRects = item.getClientRects();
      if (clientRects.length > 0) {
        clientRect = clone$1(clientRects[0]);
      } else {
        clientRect = clone$1(item.getBoundingClientRect());
      }
      if (!isRange(item) && isBr$3(item) && isZeroRect(clientRect)) {
        return getBrClientRect(item);
      }
      if (isZeroRect(clientRect) && isRange(item)) {
        return getBoundingClientRectWebKitText(item);
      }
      return clientRect;
    };
    var collapseAndInflateWidth = function (clientRect, toStart) {
      var newClientRect = collapse(clientRect, toStart);
      newClientRect.width = 1;
      newClientRect.right = newClientRect.left + 1;
      return newClientRect;
    };
    var getCaretPositionClientRects = function (caretPosition) {
      var clientRects = [];
      var beforeNode, node;
      var addUniqueAndValidRect = function (clientRect) {
        if (clientRect.height === 0) {
          return;
        }
        if (clientRects.length > 0) {
          if (isEqual(clientRect, clientRects[clientRects.length - 1])) {
            return;
          }
        }
        clientRects.push(clientRect);
      };
      var addCharacterOffset = function (container, offset) {
        var range = createRange(container.ownerDocument);
        if (offset < container.data.length) {
          if (isExtendingChar(container.data[offset])) {
            return clientRects;
          }
          if (isExtendingChar(container.data[offset - 1])) {
            range.setStart(container, offset);
            range.setEnd(container, offset + 1);
            if (!isHiddenWhiteSpaceRange(range)) {
              addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(range), false));
              return clientRects;
            }
          }
        }
        if (offset > 0) {
          range.setStart(container, offset - 1);
          range.setEnd(container, offset);
          if (!isHiddenWhiteSpaceRange(range)) {
            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(range), false));
          }
        }
        if (offset < container.data.length) {
          range.setStart(container, offset);
          range.setEnd(container, offset + 1);
          if (!isHiddenWhiteSpaceRange(range)) {
            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(range), true));
          }
        }
      };
      if (isText$4(caretPosition.container())) {
        addCharacterOffset(caretPosition.container(), caretPosition.offset());
        return clientRects;
      }
      if (isElement$3(caretPosition.container())) {
        if (caretPosition.isAtEnd()) {
          node = resolveIndex(caretPosition.container(), caretPosition.offset());
          if (isText$4(node)) {
            addCharacterOffset(node, node.data.length);
          }
          if (isValidElementCaretCandidate(node) && !isBr$3(node)) {
            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(node), false));
          }
        } else {
          node = resolveIndex(caretPosition.container(), caretPosition.offset());
          if (isText$4(node)) {
            addCharacterOffset(node, 0);
          }
          if (isValidElementCaretCandidate(node) && caretPosition.isAtEnd()) {
            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(node), false));
            return clientRects;
          }
          beforeNode = resolveIndex(caretPosition.container(), caretPosition.offset() - 1);
          if (isValidElementCaretCandidate(beforeNode) && !isBr$3(beforeNode)) {
            if (isBlock$1(beforeNode) || isBlock$1(node) || !isValidElementCaretCandidate(node)) {
              addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(beforeNode), false));
            }
          }
          if (isValidElementCaretCandidate(node)) {
            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(node), true));
          }
        }
      }
      return clientRects;
    };
    function CaretPosition(container, offset, clientRects) {
      var isAtStart = function () {
        if (isText$4(container)) {
          return offset === 0;
        }
        return offset === 0;
      };
      var isAtEnd = function () {
        if (isText$4(container)) {
          return offset >= container.data.length;
        }
        return offset >= container.childNodes.length;
      };
      var toRange = function () {
        var range;
        range = createRange(container.ownerDocument);
        range.setStart(container, offset);
        range.setEnd(container, offset);
        return range;
      };
      var getClientRects = function () {
        if (!clientRects) {
          clientRects = getCaretPositionClientRects(CaretPosition(container, offset));
        }
        return clientRects;
      };
      var isVisible = function () {
        return getClientRects().length > 0;
      };
      var isEqual = function (caretPosition) {
        return caretPosition && container === caretPosition.container() && offset === caretPosition.offset();
      };
      var getNode = function (before) {
        return resolveIndex(container, before ? offset - 1 : offset);
      };
      return {
        container: constant(container),
        offset: constant(offset),
        toRange: toRange,
        getClientRects: getClientRects,
        isVisible: isVisible,
        isAtStart: isAtStart,
        isAtEnd: isAtEnd,
        isEqual: isEqual,
        getNode: getNode
      };
    }
    (function (CaretPosition) {
      CaretPosition.fromRangeStart = function (range) {
        return CaretPosition(range.startContainer, range.startOffset);
      };
      CaretPosition.fromRangeEnd = function (range) {
        return CaretPosition(range.endContainer, range.endOffset);
      };
      CaretPosition.after = function (node) {
        return CaretPosition(node.parentNode, nodeIndex(node) + 1);
      };
      CaretPosition.before = function (node) {
        return CaretPosition(node.parentNode, nodeIndex(node));
      };
      CaretPosition.isAbove = function (pos1, pos2) {
        return lift2(head(pos2.getClientRects()), last(pos1.getClientRects()), isAbove).getOr(false);
      };
      CaretPosition.isBelow = function (pos1, pos2) {
        return lift2(last(pos2.getClientRects()), head(pos1.getClientRects()), isBelow).getOr(false);
      };
      CaretPosition.isAtStart = function (pos) {
        return pos ? pos.isAtStart() : false;
      };
      CaretPosition.isAtEnd = function (pos) {
        return pos ? pos.isAtEnd() : false;
      };
      CaretPosition.isTextPosition = function (pos) {
        return pos ? NodeType.isText(pos.container()) : false;
      };
      CaretPosition.isElementPosition = function (pos) {
        return CaretPosition.isTextPosition(pos) === false;
      };
    }(CaretPosition || (CaretPosition = {})));
    var CaretPosition$1 = CaretPosition;

    var isText$5 = NodeType.isText;
    var isBogus$1 = NodeType.isBogus;
    var nodeIndex$1 = DOMUtils$1.nodeIndex;
    var normalizedParent = function (node) {
      var parentNode = node.parentNode;
      if (isBogus$1(parentNode)) {
        return normalizedParent(parentNode);
      }
      return parentNode;
    };
    var getChildNodes = function (node) {
      if (!node) {
        return [];
      }
      return ArrUtils.reduce(node.childNodes, function (result, node) {
        if (isBogus$1(node) && node.nodeName !== 'BR') {
          result = result.concat(getChildNodes(node));
        } else {
          result.push(node);
        }
        return result;
      }, []);
    };
    var normalizedTextOffset = function (node, offset) {
      while (node = node.previousSibling) {
        if (!isText$5(node)) {
          break;
        }
        offset += node.data.length;
      }
      return offset;
    };
    var equal = function (a) {
      return function (b) {
        return a === b;
      };
    };
    var normalizedNodeIndex = function (node) {
      var nodes, index, numTextFragments;
      nodes = getChildNodes(normalizedParent(node));
      index = ArrUtils.findIndex(nodes, equal(node), node);
      nodes = nodes.slice(0, index + 1);
      numTextFragments = ArrUtils.reduce(nodes, function (result, node, i) {
        if (isText$5(node) && isText$5(nodes[i - 1])) {
          result++;
        }
        return result;
      }, 0);
      nodes = ArrUtils.filter(nodes, NodeType.matchNodeNames([node.nodeName]));
      index = ArrUtils.findIndex(nodes, equal(node), node);
      return index - numTextFragments;
    };
    var createPathItem = function (node) {
      var name;
      if (isText$5(node)) {
        name = 'text()';
      } else {
        name = node.nodeName.toLowerCase();
      }
      return name + '[' + normalizedNodeIndex(node) + ']';
    };
    var parentsUntil = function (root, node, predicate) {
      var parents = [];
      for (node = node.parentNode; node !== root; node = node.parentNode) {
        if (predicate && predicate(node)) {
          break;
        }
        parents.push(node);
      }
      return parents;
    };
    var create$2 = function (root, caretPosition) {
      var container, offset, path = [], outputOffset, childNodes, parents;
      container = caretPosition.container();
      offset = caretPosition.offset();
      if (isText$5(container)) {
        outputOffset = normalizedTextOffset(container, offset);
      } else {
        childNodes = container.childNodes;
        if (offset >= childNodes.length) {
          outputOffset = 'after';
          offset = childNodes.length - 1;
        } else {
          outputOffset = 'before';
        }
        container = childNodes[offset];
      }
      path.push(createPathItem(container));
      parents = parentsUntil(root, container);
      parents = ArrUtils.filter(parents, not(NodeType.isBogus));
      path = path.concat(ArrUtils.map(parents, function (node) {
        return createPathItem(node);
      }));
      return path.reverse().join('/') + ',' + outputOffset;
    };
    var resolvePathItem = function (node, name, index) {
      var nodes = getChildNodes(node);
      nodes = ArrUtils.filter(nodes, function (node, index) {
        return !isText$5(node) || !isText$5(nodes[index - 1]);
      });
      nodes = ArrUtils.filter(nodes, NodeType.matchNodeNames([name]));
      return nodes[index];
    };
    var findTextPosition = function (container, offset) {
      var node = container, targetOffset = 0, dataLen;
      while (isText$5(node)) {
        dataLen = node.data.length;
        if (offset >= targetOffset && offset <= targetOffset + dataLen) {
          container = node;
          offset = offset - targetOffset;
          break;
        }
        if (!isText$5(node.nextSibling)) {
          container = node;
          offset = dataLen;
          break;
        }
        targetOffset += dataLen;
        node = node.nextSibling;
      }
      if (isText$5(container) && offset > container.data.length) {
        offset = container.data.length;
      }
      return CaretPosition$1(container, offset);
    };
    var resolve$1 = function (root, path) {
      var parts, container, offset;
      if (!path) {
        return null;
      }
      parts = path.split(',');
      path = parts[0].split('/');
      offset = parts.length > 1 ? parts[1] : 'before';
      container = ArrUtils.reduce(path, function (result, value) {
        value = /([\w\-\(\)]+)\[([0-9]+)\]/.exec(value);
        if (!value) {
          return null;
        }
        if (value[1] === 'text()') {
          value[1] = '#text';
        }
        return resolvePathItem(result, value[1], parseInt(value[2], 10));
      }, root);
      if (!container) {
        return null;
      }
      if (!isText$5(container)) {
        if (offset === 'after') {
          offset = nodeIndex$1(container) + 1;
        } else {
          offset = nodeIndex$1(container);
        }
        return CaretPosition$1(container.parentNode, offset);
      }
      return findTextPosition(container, parseInt(offset, 10));
    };

    var trimEmptyTextNode = function (dom, node) {
      if (NodeType.isText(node) && node.data.length === 0) {
        dom.remove(node);
      }
    };
    var insertNode = function (dom, rng, node) {
      rng.insertNode(node);
      trimEmptyTextNode(dom, node.previousSibling);
      trimEmptyTextNode(dom, node.nextSibling);
    };
    var insertFragment = function (dom, rng, frag) {
      var firstChild = Option.from(frag.firstChild);
      var lastChild = Option.from(frag.lastChild);
      rng.insertNode(frag);
      firstChild.each(function (child) {
        return trimEmptyTextNode(dom, child.previousSibling);
      });
      lastChild.each(function (child) {
        return trimEmptyTextNode(dom, child.nextSibling);
      });
    };
    var rangeInsertNode = function (dom, rng, node) {
      if (NodeType.isDocumentFragment(node)) {
        insertFragment(dom, rng, node);
      } else {
        insertNode(dom, rng, node);
      }
    };

    var isContentEditableFalse$2 = NodeType.isContentEditableFalse;
    var getNormalizedTextOffset = function (trim, container, offset) {
      var node, trimmedOffset;
      trimmedOffset = trim(container.data.slice(0, offset)).length;
      for (node = container.previousSibling; node && NodeType.isText(node); node = node.previousSibling) {
        trimmedOffset += trim(node.data).length;
      }
      return trimmedOffset;
    };
    var getPoint = function (dom, trim, normalized, rng, start) {
      var container = rng[start ? 'startContainer' : 'endContainer'];
      var offset = rng[start ? 'startOffset' : 'endOffset'];
      var point = [];
      var childNodes, after = 0;
      var root = dom.getRoot();
      if (NodeType.isText(container)) {
        point.push(normalized ? getNormalizedTextOffset(trim, container, offset) : offset);
      } else {
        childNodes = container.childNodes;
        if (offset >= childNodes.length && childNodes.length) {
          after = 1;
          offset = Math.max(0, childNodes.length - 1);
        }
        point.push(dom.nodeIndex(childNodes[offset], normalized) + after);
      }
      for (; container && container !== root; container = container.parentNode) {
        point.push(dom.nodeIndex(container, normalized));
      }
      return point;
    };
    var getLocation = function (trim, selection, normalized, rng) {
      var dom = selection.dom, bookmark = {};
      bookmark.start = getPoint(dom, trim, normalized, rng, true);
      if (!selection.isCollapsed()) {
        bookmark.end = getPoint(dom, trim, normalized, rng, false);
      }
      return bookmark;
    };
    var findIndex$2 = function (dom, name, element) {
      var count = 0;
      Tools.each(dom.select(name), function (node) {
        if (node.getAttribute('data-mce-bogus') === 'all') {
          return;
        }
        if (node === element) {
          return false;
        }
        count++;
      });
      return count;
    };
    var moveEndPoint = function (rng, start) {
      var container, offset, childNodes;
      var prefix = start ? 'start' : 'end';
      container = rng[prefix + 'Container'];
      offset = rng[prefix + 'Offset'];
      if (NodeType.isElement(container) && container.nodeName === 'TR') {
        childNodes = container.childNodes;
        container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)];
        if (container) {
          offset = start ? 0 : container.childNodes.length;
          rng['set' + (start ? 'Start' : 'End')](container, offset);
        }
      }
    };
    var normalizeTableCellSelection = function (rng) {
      moveEndPoint(rng, true);
      moveEndPoint(rng, false);
      return rng;
    };
    var findSibling = function (node, offset) {
      var sibling;
      if (NodeType.isElement(node)) {
        node = getNode(node, offset);
        if (isContentEditableFalse$2(node)) {
          return node;
        }
      }
      if (isCaretContainer(node)) {
        if (NodeType.isText(node) && isCaretContainerBlock(node)) {
          node = node.parentNode;
        }
        sibling = node.previousSibling;
        if (isContentEditableFalse$2(sibling)) {
          return sibling;
        }
        sibling = node.nextSibling;
        if (isContentEditableFalse$2(sibling)) {
          return sibling;
        }
      }
    };
    var findAdjacentContentEditableFalseElm = function (rng) {
      return findSibling(rng.startContainer, rng.startOffset) || findSibling(rng.endContainer, rng.endOffset);
    };
    var getOffsetBookmark = function (trim, normalized, selection) {
      var element = selection.getNode();
      var name = element ? element.nodeName : null;
      var rng = selection.getRng();
      if (isContentEditableFalse$2(element) || name === 'IMG') {
        return {
          name: name,
          index: findIndex$2(selection.dom, name, element)
        };
      }
      var sibling = findAdjacentContentEditableFalseElm(rng);
      if (sibling) {
        name = sibling.tagName;
        return {
          name: name,
          index: findIndex$2(selection.dom, name, sibling)
        };
      }
      return getLocation(trim, selection, normalized, rng);
    };
    var getCaretBookmark = function (selection) {
      var rng = selection.getRng();
      return {
        start: create$2(selection.dom.getRoot(), CaretPosition$1.fromRangeStart(rng)),
        end: create$2(selection.dom.getRoot(), CaretPosition$1.fromRangeEnd(rng))
      };
    };
    var getRangeBookmark = function (selection) {
      return { rng: selection.getRng() };
    };
    var createBookmarkSpan = function (dom, id, filled) {
      var args = {
        'data-mce-type': 'bookmark',
        'id': id,
        'style': 'overflow:hidden;line-height:0px'
      };
      return filled ? dom.create('span', args, '&#xFEFF;') : dom.create('span', args);
    };
    var getPersistentBookmark = function (selection, filled) {
      var dom = selection.dom;
      var rng = selection.getRng();
      var id = dom.uniqueId();
      var collapsed = selection.isCollapsed();
      var element = selection.getNode();
      var name = element.nodeName;
      if (name === 'IMG') {
        return {
          name: name,
          index: findIndex$2(dom, name, element)
        };
      }
      var rng2 = normalizeTableCellSelection(rng.cloneRange());
      if (!collapsed) {
        rng2.collapse(false);
        var endBookmarkNode = createBookmarkSpan(dom, id + '_end', filled);
        rangeInsertNode(dom, rng2, endBookmarkNode);
      }
      rng = normalizeTableCellSelection(rng);
      rng.collapse(true);
      var startBookmarkNode = createBookmarkSpan(dom, id + '_start', filled);
      rangeInsertNode(dom, rng, startBookmarkNode);
      selection.moveToBookmark({
        id: id,
        keep: 1
      });
      return { id: id };
    };
    var getBookmark = function (selection, type, normalized) {
      if (type === 2) {
        return getOffsetBookmark(Zwsp.trim, normalized, selection);
      } else if (type === 3) {
        return getCaretBookmark(selection);
      } else if (type) {
        return getRangeBookmark(selection);
      } else {
        return getPersistentBookmark(selection, false);
      }
    };
    var GetBookmark = {
      getBookmark: getBookmark,
      getUndoBookmark: curry(getOffsetBookmark, identity, true),
      getPersistentBookmark: getPersistentBookmark
    };

    var TextWalker = function (startNode, rootNode, isBoundary) {
      if (isBoundary === void 0) {
        isBoundary = never;
      }
      var walker = new TreeWalker(startNode, rootNode);
      var walk = function (direction) {
        var next;
        do {
          next = walker[direction]();
        } while (next && !NodeType.isText(next) && !isBoundary(next));
        return Option.from(next).filter(NodeType.isText);
      };
      return {
        current: function () {
          return Option.from(walker.current()).filter(NodeType.isText);
        },
        next: function () {
          return walk('next');
        },
        prev: function () {
          return walk('prev');
        },
        prev2: function () {
          return walk('prev2');
        }
      };
    };

    var TextSeeker = function (dom, isBoundary) {
      var isBlockBoundary = isBoundary ? isBoundary : function (node) {
        return dom.isBlock(node) || NodeType.isBr(node) || NodeType.isContentEditableFalse(node);
      };
      var walk = function (node, offset, walker, process) {
        if (NodeType.isText(node)) {
          var newOffset = process(node, offset, node.data);
          if (newOffset !== -1) {
            return Option.some({
              container: node,
              offset: newOffset
            });
          }
        }
        return walker().bind(function (next) {
          return walk(next.container, next.offset, walker, process);
        });
      };
      var backwards = function (node, offset, process, root) {
        var walker = TextWalker(node, root, isBlockBoundary);
        return walk(node, offset, function () {
          return walker.prev().map(function (prev) {
            return {
              container: prev,
              offset: prev.length
            };
          });
        }, process).getOrNull();
      };
      var forwards = function (node, offset, process, root) {
        var walker = TextWalker(node, root, isBlockBoundary);
        return walk(node, offset, function () {
          return walker.next().map(function (next) {
            return {
              container: next,
              offset: 0
            };
          });
        }, process).getOrNull();
      };
      return {
        backwards: backwards,
        forwards: forwards
      };
    };

    var CARET_ID = '_mce_caret';
    var isCaretNode = function (node) {
      return NodeType.isElement(node) && node.id === CARET_ID;
    };
    var getParentCaretContainer = function (body, node) {
      while (node && node !== body) {
        if (node.id === CARET_ID) {
          return node;
        }
        node = node.parentNode;
      }
      return null;
    };

    var isElement$4 = NodeType.isElement;
    var isText$6 = NodeType.isText;
    var removeNode = function (node) {
      var parentNode = node.parentNode;
      if (parentNode) {
        parentNode.removeChild(node);
      }
    };
    var getNodeValue = function (node) {
      try {
        return node.nodeValue;
      } catch (ex) {
        return '';
      }
    };
    var setNodeValue = function (node, text) {
      if (text.length === 0) {
        removeNode(node);
      } else {
        node.nodeValue = text;
      }
    };
    var trimCount = function (text) {
      var trimmedText = Zwsp.trim(text);
      return {
        count: text.length - trimmedText.length,
        text: trimmedText
      };
    };
    var removeUnchanged = function (caretContainer, pos) {
      remove$5(caretContainer);
      return pos;
    };
    var removeTextAndReposition = function (caretContainer, pos) {
      var before = trimCount(caretContainer.data.substr(0, pos.offset()));
      var after = trimCount(caretContainer.data.substr(pos.offset()));
      var text = before.text + after.text;
      if (text.length > 0) {
        setNodeValue(caretContainer, text);
        return CaretPosition$1(caretContainer, pos.offset() - before.count);
      } else {
        return pos;
      }
    };
    var removeElementAndReposition = function (caretContainer, pos) {
      var parentNode = pos.container();
      var newPosition = indexOf(from$1(parentNode.childNodes), caretContainer).map(function (index) {
        return index < pos.offset() ? CaretPosition$1(parentNode, pos.offset() - 1) : pos;
      }).getOr(pos);
      remove$5(caretContainer);
      return newPosition;
    };
    var removeTextCaretContainer = function (caretContainer, pos) {
      return isText$6(caretContainer) && pos.container() === caretContainer ? removeTextAndReposition(caretContainer, pos) : removeUnchanged(caretContainer, pos);
    };
    var removeElementCaretContainer = function (caretContainer, pos) {
      return pos.container() === caretContainer.parentNode ? removeElementAndReposition(caretContainer, pos) : removeUnchanged(caretContainer, pos);
    };
    var removeAndReposition = function (container, pos) {
      return CaretPosition$1.isTextPosition(pos) ? removeTextCaretContainer(container, pos) : removeElementCaretContainer(container, pos);
    };
    var remove$5 = function (caretContainerNode) {
      if (isElement$4(caretContainerNode) && isCaretContainer(caretContainerNode)) {
        if (hasContent(caretContainerNode)) {
          caretContainerNode.removeAttribute('data-mce-caret');
        } else {
          removeNode(caretContainerNode);
        }
      }
      if (isText$6(caretContainerNode)) {
        var text = Zwsp.trim(getNodeValue(caretContainerNode));
        setNodeValue(caretContainerNode, text);
      }
    };
    var CaretContainerRemove = {
      removeAndReposition: removeAndReposition,
      remove: remove$5
    };

    var DOM$1 = DOMUtils$1.DOM;
    var getBodySetting = function (editor, name, defaultValue) {
      var value = editor.getParam(name, defaultValue);
      if (value.indexOf('=') !== -1) {
        var bodyObj = editor.getParam(name, '', 'hash');
        return bodyObj.hasOwnProperty(editor.id) ? bodyObj[editor.id] : defaultValue;
      } else {
        return value;
      }
    };
    var getIframeAttrs = function (editor) {
      return editor.getParam('iframe_attrs', {});
    };
    var getDocType = function (editor) {
      return editor.getParam('doctype', '<!DOCTYPE html>');
    };
    var getDocumentBaseUrl = function (editor) {
      return editor.getParam('document_base_url', '');
    };
    var getBodyId = function (editor) {
      return getBodySetting(editor, 'body_id', 'tinymce');
    };
    var getBodyClass = function (editor) {
      return getBodySetting(editor, 'body_class', '');
    };
    var getContentSecurityPolicy = function (editor) {
      return editor.getParam('content_security_policy', '');
    };
    var shouldPutBrInPre = function (editor) {
      return editor.getParam('br_in_pre', true);
    };
    var getForcedRootBlock = function (editor) {
      if (editor.getParam('force_p_newlines', false)) {
        return 'p';
      }
      var block = editor.getParam('forced_root_block', 'p');
      if (block === false) {
        return '';
      } else if (block === true) {
        return 'p';
      } else {
        return block;
      }
    };
    var getForcedRootBlockAttrs = function (editor) {
      return editor.getParam('forced_root_block_attrs', {});
    };
    var getBrNewLineSelector = function (editor) {
      return editor.getParam('br_newline_selector', '.mce-toc h2,figcaption,caption');
    };
    var getNoNewLineSelector = function (editor) {
      return editor.getParam('no_newline_selector', '');
    };
    var shouldKeepStyles = function (editor) {
      return editor.getParam('keep_styles', true);
    };
    var shouldEndContainerOnEmptyBlock = function (editor) {
      return editor.getParam('end_container_on_empty_block', false);
    };
    var getFontStyleValues = function (editor) {
      return Tools.explode(editor.getParam('font_size_style_values', 'xx-small,x-small,small,medium,large,x-large,xx-large'));
    };
    var getFontSizeClasses = function (editor) {
      return Tools.explode(editor.getParam('font_size_classes', ''));
    };
    var getImagesDataImgFilter = function (editor) {
      return editor.getParam('images_dataimg_filter', constant(true), 'function');
    };
    var isAutomaticUploadsEnabled = function (editor) {
      return editor.getParam('automatic_uploads', true, 'boolean');
    };
    var shouldReuseFileName = function (editor) {
      return editor.getParam('images_reuse_filename', false, 'boolean');
    };
    var shouldReplaceBlobUris = function (editor) {
      return editor.getParam('images_replace_blob_uris', true, 'boolean');
    };
    var getIconPackName = function (editor) {
      return editor.getParam('icons', '', 'string');
    };
    var getIconsUrl = function (editor) {
      return editor.getParam('icons_url', '', 'string');
    };
    var getImageUploadUrl = function (editor) {
      return editor.getParam('images_upload_url', '', 'string');
    };
    var getImageUploadBasePath = function (editor) {
      return editor.getParam('images_upload_base_path', '', 'string');
    };
    var getImagesUploadCredentials = function (editor) {
      return editor.getParam('images_upload_credentials', false, 'boolean');
    };
    var getImagesUploadHandler = function (editor) {
      return editor.getParam('images_upload_handler', null, 'function');
    };
    var shouldUseContentCssCors = function (editor) {
      return editor.getParam('content_css_cors', false, 'boolean');
    };
    var getReferrerPolicy = function (editor) {
      return editor.getParam('referrer_policy', '', 'string');
    };
    var getLanguageCode = function (editor) {
      return editor.getParam('language', 'en', 'string');
    };
    var getLanguageUrl = function (editor) {
      return editor.getParam('language_url', '', 'string');
    };
    var shouldIndentUseMargin = function (editor) {
      return editor.getParam('indent_use_margin', false);
    };
    var getIndentation = function (editor) {
      return editor.getParam('indentation', '40px', 'string');
    };
    var getContentCss = function (editor) {
      var contentCss = editor.settings.content_css;
      if (isString(contentCss)) {
        return map(contentCss.split(','), trim);
      } else if (isArray(contentCss)) {
        return contentCss;
      } else if (contentCss === false || editor.inline) {
        return [];
      } else {
        return ['default'];
      }
    };
    var getDirectionality = function (editor) {
      return editor.getParam('directionality', I18n.isRtl() ? 'rtl' : undefined);
    };
    var getInlineBoundarySelector = function (editor) {
      return editor.getParam('inline_boundaries_selector', 'a[href],code,.mce-annotation', 'string');
    };
    var getObjectResizing = function (editor) {
      return editor.getParam('object_resizing');
    };
    var getResizeImgProportional = function (editor) {
      return editor.getParam('resize_img_proportional', true, 'boolean');
    };
    var getPlaceholder = function (editor) {
      return editor.getParam('placeholder', DOM$1.getAttrib(editor.getElement(), 'placeholder'), 'string');
    };
    var Settings = {
      getIframeAttrs: getIframeAttrs,
      getDocType: getDocType,
      getDocumentBaseUrl: getDocumentBaseUrl,
      getBodyId: getBodyId,
      getBodyClass: getBodyClass,
      getContentSecurityPolicy: getContentSecurityPolicy,
      shouldPutBrInPre: shouldPutBrInPre,
      getForcedRootBlock: getForcedRootBlock,
      getForcedRootBlockAttrs: getForcedRootBlockAttrs,
      getBrNewLineSelector: getBrNewLineSelector,
      getNoNewLineSelector: getNoNewLineSelector,
      shouldKeepStyles: shouldKeepStyles,
      shouldEndContainerOnEmptyBlock: shouldEndContainerOnEmptyBlock,
      getFontStyleValues: getFontStyleValues,
      getFontSizeClasses: getFontSizeClasses,
      getIconPackName: getIconPackName,
      getIconsUrl: getIconsUrl,
      getImagesDataImgFilter: getImagesDataImgFilter,
      isAutomaticUploadsEnabled: isAutomaticUploadsEnabled,
      shouldReuseFileName: shouldReuseFileName,
      shouldReplaceBlobUris: shouldReplaceBlobUris,
      getImageUploadUrl: getImageUploadUrl,
      getImageUploadBasePath: getImageUploadBasePath,
      getImagesUploadCredentials: getImagesUploadCredentials,
      getImagesUploadHandler: getImagesUploadHandler,
      shouldUseContentCssCors: shouldUseContentCssCors,
      getReferrerPolicy: getReferrerPolicy,
      getLanguageCode: getLanguageCode,
      getLanguageUrl: getLanguageUrl,
      shouldIndentUseMargin: shouldIndentUseMargin,
      getIndentation: getIndentation,
      getContentCss: getContentCss,
      getDirectionality: getDirectionality,
      getInlineBoundarySelector: getInlineBoundarySelector,
      getObjectResizing: getObjectResizing,
      getResizeImgProportional: getResizeImgProportional,
      getPlaceholder: getPlaceholder
    };

    var browser$3 = detect$3().browser;
    var isContentEditableFalse$3 = NodeType.isContentEditableFalse;
    var isTableCell$1 = function (node) {
      return NodeType.isElement(node) && /^(TD|TH)$/i.test(node.tagName);
    };
    var getAbsoluteClientRect = function (root, element, before) {
      var clientRect = collapse(element.getBoundingClientRect(), before);
      var docElm, scrollX, scrollY, margin, rootRect;
      if (root.tagName === 'BODY') {
        docElm = root.ownerDocument.documentElement;
        scrollX = root.scrollLeft || docElm.scrollLeft;
        scrollY = root.scrollTop || docElm.scrollTop;
      } else {
        rootRect = root.getBoundingClientRect();
        scrollX = root.scrollLeft - rootRect.left;
        scrollY = root.scrollTop - rootRect.top;
      }
      clientRect.left += scrollX;
      clientRect.right += scrollX;
      clientRect.top += scrollY;
      clientRect.bottom += scrollY;
      clientRect.width = 1;
      margin = element.offsetWidth - element.clientWidth;
      if (margin > 0) {
        if (before) {
          margin *= -1;
        }
        clientRect.left += margin;
        clientRect.right += margin;
      }
      return clientRect;
    };
    var trimInlineCaretContainers = function (root) {
      var contentEditableFalseNodes, node, sibling, i, data;
      contentEditableFalseNodes = DomQuery('*[contentEditable=false]', root);
      for (i = 0; i < contentEditableFalseNodes.length; i++) {
        node = contentEditableFalseNodes[i];
        sibling = node.previousSibling;
        if (endsWithCaretContainer(sibling)) {
          data = sibling.data;
          if (data.length === 1) {
            sibling.parentNode.removeChild(sibling);
          } else {
            sibling.deleteData(data.length - 1, 1);
          }
        }
        sibling = node.nextSibling;
        if (startsWithCaretContainer(sibling)) {
          data = sibling.data;
          if (data.length === 1) {
            sibling.parentNode.removeChild(sibling);
          } else {
            sibling.deleteData(0, 1);
          }
        }
      }
    };
    var FakeCaret = function (editor, root, isBlock, hasFocus) {
      var lastVisualCaret = Cell(Option.none());
      var cursorInterval, caretContainerNode;
      var rootBlock = Settings.getForcedRootBlock(editor);
      var caretBlock = rootBlock.length > 0 ? rootBlock : 'p';
      var show = function (before, element) {
        var clientRect, rng;
        hide();
        if (isTableCell$1(element)) {
          return null;
        }
        if (isBlock(element)) {
          caretContainerNode = insertBlock(caretBlock, element, before);
          clientRect = getAbsoluteClientRect(root, element, before);
          DomQuery(caretContainerNode).css('top', clientRect.top);
          var caret = DomQuery('<div class="mce-visual-caret" data-mce-bogus="all"></div>').css(clientRect).appendTo(root)[0];
          lastVisualCaret.set(Option.some({
            caret: caret,
            element: element,
            before: before
          }));
          lastVisualCaret.get().each(function (caretState) {
            if (before) {
              DomQuery(caretState.caret).addClass('mce-visual-caret-before');
            }
          });
          startBlink();
          rng = element.ownerDocument.createRange();
          rng.setStart(caretContainerNode, 0);
          rng.setEnd(caretContainerNode, 0);
        } else {
          caretContainerNode = insertInline(element, before);
          rng = element.ownerDocument.createRange();
          if (isContentEditableFalse$3(caretContainerNode.nextSibling)) {
            rng.setStart(caretContainerNode, 0);
            rng.setEnd(caretContainerNode, 0);
          } else {
            rng.setStart(caretContainerNode, 1);
            rng.setEnd(caretContainerNode, 1);
          }
          return rng;
        }
        return rng;
      };
      var hide = function () {
        trimInlineCaretContainers(root);
        if (caretContainerNode) {
          CaretContainerRemove.remove(caretContainerNode);
          caretContainerNode = null;
        }
        lastVisualCaret.get().each(function (caretState) {
          DomQuery(caretState.caret).remove();
          lastVisualCaret.set(Option.none());
        });
        Delay.clearInterval(cursorInterval);
      };
      var startBlink = function () {
        cursorInterval = Delay.setInterval(function () {
          if (hasFocus()) {
            DomQuery('div.mce-visual-caret', root).toggleClass('mce-visual-caret-hidden');
          } else {
            DomQuery('div.mce-visual-caret', root).addClass('mce-visual-caret-hidden');
          }
        }, 500);
      };
      var reposition = function () {
        lastVisualCaret.get().each(function (caretState) {
          var clientRect = getAbsoluteClientRect(root, caretState.element, caretState.before);
          DomQuery(caretState.caret).css(__assign({}, clientRect));
        });
      };
      var destroy = function () {
        return Delay.clearInterval(cursorInterval);
      };
      var getCss = function () {
        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;' + '}';
      };
      return {
        show: show,
        hide: hide,
        getCss: getCss,
        reposition: reposition,
        destroy: destroy
      };
    };
    var isFakeCaretTableBrowser = function () {
      return browser$3.isIE() || browser$3.isEdge() || browser$3.isFirefox();
    };
    var isFakeCaretTarget = function (node) {
      return isContentEditableFalse$3(node) || NodeType.isTable(node) && isFakeCaretTableBrowser();
    };

    var isContentEditableFalse$4 = NodeType.isContentEditableFalse;
    var isBlockLike = NodeType.matchStyleValues('display', 'block table table-cell table-caption list-item');
    var isCaretContainer$2 = isCaretContainer;
    var isCaretContainerBlock$1 = isCaretContainerBlock;
    var isElement$5 = NodeType.isElement;
    var isCaretCandidate$2 = isCaretCandidate;
    var isForwards = function (direction) {
      return direction > 0;
    };
    var isBackwards = function (direction) {
      return direction < 0;
    };
    var skipCaretContainers = function (walk, shallow) {
      var node;
      while (node = walk(shallow)) {
        if (!isCaretContainerBlock$1(node)) {
          return node;
        }
      }
      return null;
    };
    var findNode = function (node, direction, predicateFn, rootNode, shallow) {
      var walker = new TreeWalker(node, rootNode);
      if (isBackwards(direction)) {
        if (isContentEditableFalse$4(node) || isCaretContainerBlock$1(node)) {
          node = skipCaretContainers(walker.prev, true);
          if (predicateFn(node)) {
            return node;
          }
        }
        while (node = skipCaretContainers(walker.prev, shallow)) {
          if (predicateFn(node)) {
            return node;
          }
        }
      }
      if (isForwards(direction)) {
        if (isContentEditableFalse$4(node) || isCaretContainerBlock$1(node)) {
          node = skipCaretContainers(walker.next, true);
          if (predicateFn(node)) {
            return node;
          }
        }
        while (node = skipCaretContainers(walker.next, shallow)) {
          if (predicateFn(node)) {
            return node;
          }
        }
      }
      return null;
    };
    var getParentBlock = function (node, rootNode) {
      while (node && node !== rootNode) {
        if (isBlockLike(node)) {
          return node;
        }
        node = node.parentNode;
      }
      return null;
    };
    var isInSameBlock = function (caretPosition1, caretPosition2, rootNode) {
      return getParentBlock(caretPosition1.container(), rootNode) === getParentBlock(caretPosition2.container(), rootNode);
    };
    var getChildNodeAtRelativeOffset = function (relativeOffset, caretPosition) {
      var container, offset;
      if (!caretPosition) {
        return null;
      }
      container = caretPosition.container();
      offset = caretPosition.offset();
      if (!isElement$5(container)) {
        return null;
      }
      return container.childNodes[offset + relativeOffset];
    };
    var beforeAfter = function (before, node) {
      var range = node.ownerDocument.createRange();
      if (before) {
        range.setStartBefore(node);
        range.setEndBefore(node);
      } else {
        range.setStartAfter(node);
        range.setEndAfter(node);
      }
      return range;
    };
    var isNodesInSameBlock = function (root, node1, node2) {
      return getParentBlock(node1, root) === getParentBlock(node2, root);
    };
    var lean = function (left, root, node) {
      var sibling, siblingName;
      if (left) {
        siblingName = 'previousSibling';
      } else {
        siblingName = 'nextSibling';
      }
      while (node && node !== root) {
        sibling = node[siblingName];
        if (isCaretContainer$2(sibling)) {
          sibling = sibling[siblingName];
        }
        if (isContentEditableFalse$4(sibling)) {
          if (isNodesInSameBlock(root, sibling, node)) {
            return sibling;
          }
          break;
        }
        if (isCaretCandidate$2(sibling)) {
          break;
        }
        node = node.parentNode;
      }
      return null;
    };
    var before$2 = curry(beforeAfter, true);
    var after$1 = curry(beforeAfter, false);
    var normalizeRange = function (direction, root, range) {
      var node, container, offset, location;
      var leanLeft = curry(lean, true, root);
      var leanRight = curry(lean, false, root);
      container = range.startContainer;
      offset = range.startOffset;
      if (isCaretContainerBlock(container)) {
        if (!isElement$5(container)) {
          container = container.parentNode;
        }
        location = container.getAttribute('data-mce-caret');
        if (location === 'before') {
          node = container.nextSibling;
          if (isFakeCaretTarget(node)) {
            return before$2(node);
          }
        }
        if (location === 'after') {
          node = container.previousSibling;
          if (isFakeCaretTarget(node)) {
            return after$1(node);
          }
        }
      }
      if (!range.collapsed) {
        return range;
      }
      if (NodeType.isText(container)) {
        if (isCaretContainer$2(container)) {
          if (direction === 1) {
            node = leanRight(container);
            if (node) {
              return before$2(node);
            }
            node = leanLeft(container);
            if (node) {
              return after$1(node);
            }
          }
          if (direction === -1) {
            node = leanLeft(container);
            if (node) {
              return after$1(node);
            }
            node = leanRight(container);
            if (node) {
              return before$2(node);
            }
          }
          return range;
        }
        if (endsWithCaretContainer(container) && offset >= container.data.length - 1) {
          if (direction === 1) {
            node = leanRight(container);
            if (node) {
              return before$2(node);
            }
          }
          return range;
        }
        if (startsWithCaretContainer(container) && offset <= 1) {
          if (direction === -1) {
            node = leanLeft(container);
            if (node) {
              return after$1(node);
            }
          }
          return range;
        }
        if (offset === container.data.length) {
          node = leanRight(container);
          if (node) {
            return before$2(node);
          }
          return range;
        }
        if (offset === 0) {
          node = leanLeft(container);
          if (node) {
            return after$1(node);
          }
          return range;
        }
      }
      return range;
    };
    var getRelativeCefElm = function (forward, caretPosition) {
      return Option.from(getChildNodeAtRelativeOffset(forward ? 0 : -1, caretPosition)).filter(isContentEditableFalse$4);
    };
    var getNormalizedRangeEndPoint = function (direction, root, range) {
      var normalizedRange = normalizeRange(direction, root, range);
      if (direction === -1) {
        return CaretPosition.fromRangeStart(normalizedRange);
      }
      return CaretPosition.fromRangeEnd(normalizedRange);
    };
    var getElementFromPosition = function (pos) {
      return Option.from(pos.getNode()).map(Element.fromDom);
    };
    var getElementFromPrevPosition = function (pos) {
      return Option.from(pos.getNode(true)).map(Element.fromDom);
    };
    var getVisualCaretPosition = function (walkFn, caretPosition) {
      while (caretPosition = walkFn(caretPosition)) {
        if (caretPosition.isVisible()) {
          return caretPosition;
        }
      }
      return caretPosition;
    };
    var isMoveInsideSameBlock = function (from, to) {
      var inSameBlock = isInSameBlock(from, to);
      if (!inSameBlock && NodeType.isBr(from.getNode())) {
        return true;
      }
      return inSameBlock;
    };

    var HDirection;
    (function (HDirection) {
      HDirection[HDirection['Backwards'] = -1] = 'Backwards';
      HDirection[HDirection['Forwards'] = 1] = 'Forwards';
    }(HDirection || (HDirection = {})));
    var isContentEditableFalse$5 = NodeType.isContentEditableFalse;
    var isText$7 = NodeType.isText;
    var isElement$6 = NodeType.isElement;
    var isBr$4 = NodeType.isBr;
    var isCaretCandidate$3 = isCaretCandidate;
    var isAtomic$1 = isAtomic;
    var isEditableCaretCandidate$1 = isEditableCaretCandidate;
    var getParents = function (node, root) {
      var parents = [];
      while (node && node !== root) {
        parents.push(node);
        node = node.parentNode;
      }
      return parents;
    };
    var nodeAtIndex = function (container, offset) {
      if (container.hasChildNodes() && offset < container.childNodes.length) {
        return container.childNodes[offset];
      }
      return null;
    };
    var getCaretCandidatePosition = function (direction, node) {
      if (isForwards(direction)) {
        if (isCaretCandidate$3(node.previousSibling) && !isText$7(node.previousSibling)) {
          return CaretPosition$1.before(node);
        }
        if (isText$7(node)) {
          return CaretPosition$1(node, 0);
        }
      }
      if (isBackwards(direction)) {
        if (isCaretCandidate$3(node.nextSibling) && !isText$7(node.nextSibling)) {
          return CaretPosition$1.after(node);
        }
        if (isText$7(node)) {
          return CaretPosition$1(node, node.data.length);
        }
      }
      if (isBackwards(direction)) {
        if (isBr$4(node)) {
          return CaretPosition$1.before(node);
        }
        return CaretPosition$1.after(node);
      }
      return CaretPosition$1.before(node);
    };
    var moveForwardFromBr = function (root, nextNode) {
      var nextSibling = nextNode.nextSibling;
      if (nextSibling && isCaretCandidate$3(nextSibling)) {
        if (isText$7(nextSibling)) {
          return CaretPosition$1(nextSibling, 0);
        } else {
          return CaretPosition$1.before(nextSibling);
        }
      } else {
        return findCaretPosition(HDirection.Forwards, CaretPosition$1.after(nextNode), root);
      }
    };
    var findCaretPosition = function (direction, startPos, root) {
      var node, nextNode, innerNode;
      var rootContentEditableFalseElm, caretPosition;
      if (!isElement$6(root) || !startPos) {
        return null;
      }
      if (startPos.isEqual(CaretPosition$1.after(root)) && root.lastChild) {
        caretPosition = CaretPosition$1.after(root.lastChild);
        if (isBackwards(direction) && isCaretCandidate$3(root.lastChild) && isElement$6(root.lastChild)) {
          return isBr$4(root.lastChild) ? CaretPosition$1.before(root.lastChild) : caretPosition;
        }
      } else {
        caretPosition = startPos;
      }
      var container = caretPosition.container();
      var offset = caretPosition.offset();
      if (isText$7(container)) {
        if (isBackwards(direction) && offset > 0) {
          return CaretPosition$1(container, --offset);
        }
        if (isForwards(direction) && offset < container.length) {
          return CaretPosition$1(container, ++offset);
        }
        node = container;
      } else {
        if (isBackwards(direction) && offset > 0) {
          nextNode = nodeAtIndex(container, offset - 1);
          if (isCaretCandidate$3(nextNode)) {
            if (!isAtomic$1(nextNode)) {
              innerNode = findNode(nextNode, direction, isEditableCaretCandidate$1, nextNode);
              if (innerNode) {
                if (isText$7(innerNode)) {
                  return CaretPosition$1(innerNode, innerNode.data.length);
                }
                return CaretPosition$1.after(innerNode);
              }
            }
            if (isText$7(nextNode)) {
              return CaretPosition$1(nextNode, nextNode.data.length);
            }
            return CaretPosition$1.before(nextNode);
          }
        }
        if (isForwards(direction) && offset < container.childNodes.length) {
          nextNode = nodeAtIndex(container, offset);
          if (isCaretCandidate$3(nextNode)) {
            if (isBr$4(nextNode)) {
              return moveForwardFromBr(root, nextNode);
            }
            if (!isAtomic$1(nextNode)) {
              innerNode = findNode(nextNode, direction, isEditableCaretCandidate$1, nextNode);
              if (innerNode) {
                if (isText$7(innerNode)) {
                  return CaretPosition$1(innerNode, 0);
                }
                return CaretPosition$1.before(innerNode);
              }
            }
            if (isText$7(nextNode)) {
              return CaretPosition$1(nextNode, 0);
            }
            return CaretPosition$1.after(nextNode);
          }
        }
        node = nextNode ? nextNode : caretPosition.getNode();
      }
      if (isForwards(direction) && caretPosition.isAtEnd() || isBackwards(direction) && caretPosition.isAtStart()) {
        node = findNode(node, direction, constant(true), root, true);
        if (isEditableCaretCandidate$1(node, root)) {
          return getCaretCandidatePosition(direction, node);
        }
      }
      nextNode = findNode(node, direction, isEditableCaretCandidate$1, root);
      rootContentEditableFalseElm = ArrUtils.last(filter(getParents(container, root), isContentEditableFalse$5));
      if (rootContentEditableFalseElm && (!nextNode || !rootContentEditableFalseElm.contains(nextNode))) {
        if (isForwards(direction)) {
          caretPosition = CaretPosition$1.after(rootContentEditableFalseElm);
        } else {
          caretPosition = CaretPosition$1.before(rootContentEditableFalseElm);
        }
        return caretPosition;
      }
      if (nextNode) {
        return getCaretCandidatePosition(direction, nextNode);
      }
      return null;
    };
    var CaretWalker = function (root) {
      return {
        next: function (caretPosition) {
          return findCaretPosition(HDirection.Forwards, caretPosition, root);
        },
        prev: function (caretPosition) {
          return findCaretPosition(HDirection.Backwards, caretPosition, root);
        }
      };
    };

    var walkToPositionIn = function (forward, root, start) {
      var position = forward ? CaretPosition$1.before(start) : CaretPosition$1.after(start);
      return fromPosition(forward, root, position);
    };
    var afterElement = function (node) {
      return NodeType.isBr(node) ? CaretPosition$1.before(node) : CaretPosition$1.after(node);
    };
    var isBeforeOrStart = function (position) {
      if (CaretPosition$1.isTextPosition(position)) {
        return position.offset() === 0;
      } else {
        return isCaretCandidate(position.getNode());
      }
    };
    var isAfterOrEnd = function (position) {
      if (CaretPosition$1.isTextPosition(position)) {
        var container = position.container();
        return position.offset() === container.data.length;
      } else {
        return isCaretCandidate(position.getNode(true));
      }
    };
    var isBeforeAfterSameElement = function (from, to) {
      return !CaretPosition$1.isTextPosition(from) && !CaretPosition$1.isTextPosition(to) && from.getNode() === to.getNode(true);
    };
    var isAtBr = function (position) {
      return !CaretPosition$1.isTextPosition(position) && NodeType.isBr(position.getNode());
    };
    var shouldSkipPosition = function (forward, from, to) {
      if (forward) {
        return !isBeforeAfterSameElement(from, to) && !isAtBr(from) && isAfterOrEnd(from) && isBeforeOrStart(to);
      } else {
        return !isBeforeAfterSameElement(to, from) && isBeforeOrStart(from) && isAfterOrEnd(to);
      }
    };
    var fromPosition = function (forward, root, pos) {
      var walker = CaretWalker(root);
      return Option.from(forward ? walker.next(pos) : walker.prev(pos));
    };
    var navigate = function (forward, root, from) {
      return fromPosition(forward, root, from).bind(function (to) {
        if (isInSameBlock(from, to, root) && shouldSkipPosition(forward, from, to)) {
          return fromPosition(forward, root, to);
        } else {
          return Option.some(to);
        }
      });
    };
    var navigateIgnore = function (forward, root, from, ignoreFilter) {
      return navigate(forward, root, from).bind(function (pos) {
        return ignoreFilter(pos) ? navigateIgnore(forward, root, pos, ignoreFilter) : Option.some(pos);
      });
    };
    var positionIn = function (forward, element) {
      var startNode = forward ? element.firstChild : element.lastChild;
      if (NodeType.isText(startNode)) {
        return Option.some(CaretPosition$1(startNode, forward ? 0 : startNode.data.length));
      } else if (startNode) {
        if (isCaretCandidate(startNode)) {
          return Option.some(forward ? CaretPosition$1.before(startNode) : afterElement(startNode));
        } else {
          return walkToPositionIn(forward, element, startNode);
        }
      } else {
        return Option.none();
      }
    };
    var nextPosition = curry(fromPosition, true);
    var prevPosition = curry(fromPosition, false);
    var CaretFinder = {
      fromPosition: fromPosition,
      nextPosition: nextPosition,
      prevPosition: prevPosition,
      navigate: navigate,
      navigateIgnore: navigateIgnore,
      positionIn: positionIn,
      firstPositionIn: curry(positionIn, true),
      lastPositionIn: curry(positionIn, false)
    };

    var isStringPathBookmark = function (bookmark) {
      return typeof bookmark.start === 'string';
    };
    var isRangeBookmark = function (bookmark) {
      return bookmark.hasOwnProperty('rng');
    };
    var isIdBookmark = function (bookmark) {
      return bookmark.hasOwnProperty('id');
    };
    var isIndexBookmark = function (bookmark) {
      return bookmark.hasOwnProperty('name');
    };
    var isPathBookmark = function (bookmark) {
      return Tools.isArray(bookmark.start);
    };

    var addBogus = function (dom, node) {
      if (NodeType.isElement(node) && dom.isBlock(node) && !node.innerHTML && !Env.ie) {
        node.innerHTML = '<br data-mce-bogus="1" />';
      }
      return node;
    };
    var resolveCaretPositionBookmark = function (dom, bookmark) {
      var rng, pos;
      rng = dom.createRng();
      pos = resolve$1(dom.getRoot(), bookmark.start);
      rng.setStart(pos.container(), pos.offset());
      pos = resolve$1(dom.getRoot(), bookmark.end);
      rng.setEnd(pos.container(), pos.offset());
      return rng;
    };
    var insertZwsp = function (node, rng) {
      var textNode = node.ownerDocument.createTextNode(Zwsp.ZWSP);
      node.appendChild(textNode);
      rng.setStart(textNode, 0);
      rng.setEnd(textNode, 0);
    };
    var isEmpty = function (node) {
      return node.hasChildNodes() === false;
    };
    var tryFindRangePosition = function (node, rng) {
      return CaretFinder.lastPositionIn(node).fold(function () {
        return false;
      }, function (pos) {
        rng.setStart(pos.container(), pos.offset());
        rng.setEnd(pos.container(), pos.offset());
        return true;
      });
    };
    var padEmptyCaretContainer = function (root, node, rng) {
      if (isEmpty(node) && getParentCaretContainer(root, node)) {
        insertZwsp(node, rng);
        return true;
      } else {
        return false;
      }
    };
    var setEndPoint = function (dom, start, bookmark, rng) {
      var point = bookmark[start ? 'start' : 'end'];
      var i, node, offset, children;
      var root = dom.getRoot();
      if (point) {
        offset = point[0];
        for (node = root, i = point.length - 1; i >= 1; i--) {
          children = node.childNodes;
          if (padEmptyCaretContainer(root, node, rng)) {
            return true;
          }
          if (point[i] > children.length - 1) {
            if (padEmptyCaretContainer(root, node, rng)) {
              return true;
            }
            return tryFindRangePosition(node, rng);
          }
          node = children[point[i]];
        }
        if (node.nodeType === 3) {
          offset = Math.min(point[0], node.nodeValue.length);
        }
        if (node.nodeType === 1) {
          offset = Math.min(point[0], node.childNodes.length);
        }
        if (start) {
          rng.setStart(node, offset);
        } else {
          rng.setEnd(node, offset);
        }
      }
      return true;
    };
    var isValidTextNode = function (node) {
      return NodeType.isText(node) && node.data.length > 0;
    };
    var restoreEndPoint = function (dom, suffix, bookmark) {
      var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev;
      var keep = bookmark.keep;
      var container, offset;
      if (marker) {
        node = marker.parentNode;
        if (suffix === 'start') {
          if (!keep) {
            idx = dom.nodeIndex(marker);
          } else {
            if (marker.hasChildNodes()) {
              node = marker.firstChild;
              idx = 1;
            } else if (isValidTextNode(marker.nextSibling)) {
              node = marker.nextSibling;
              idx = 0;
            } else if (isValidTextNode(marker.previousSibling)) {
              node = marker.previousSibling;
              idx = marker.previousSibling.data.length;
            } else {
              node = marker.parentNode;
              idx = dom.nodeIndex(marker) + 1;
            }
          }
          container = node;
          offset = idx;
        } else {
          if (!keep) {
            idx = dom.nodeIndex(marker);
          } else {
            if (marker.hasChildNodes()) {
              node = marker.firstChild;
              idx = 1;
            } else if (isValidTextNode(marker.previousSibling)) {
              node = marker.previousSibling;
              idx = marker.previousSibling.data.length;
            } else {
              node = marker.parentNode;
              idx = dom.nodeIndex(marker);
            }
          }
          container = node;
          offset = idx;
        }
        if (!keep) {
          prev = marker.previousSibling;
          next = marker.nextSibling;
          Tools.each(Tools.grep(marker.childNodes), function (node) {
            if (NodeType.isText(node)) {
              node.nodeValue = node.nodeValue.replace(/\uFEFF/g, '');
            }
          });
          while (marker = dom.get(bookmark.id + '_' + suffix)) {
            dom.remove(marker, true);
          }
          if (prev && next && prev.nodeType === next.nodeType && NodeType.isText(prev) && !Env.opera) {
            idx = prev.nodeValue.length;
            prev.appendData(next.nodeValue);
            dom.remove(next);
            if (suffix === 'start') {
              container = prev;
              offset = idx;
            } else {
              container = prev;
              offset = idx;
            }
          }
        }
        return Option.some(CaretPosition$1(container, offset));
      } else {
        return Option.none();
      }
    };
    var resolvePaths = function (dom, bookmark) {
      var rng = dom.createRng();
      if (setEndPoint(dom, true, bookmark, rng) && setEndPoint(dom, false, bookmark, rng)) {
        return Option.some(rng);
      } else {
        return Option.none();
      }
    };
    var resolveId = function (dom, bookmark) {
      var startPos = restoreEndPoint(dom, 'start', bookmark);
      var endPos = restoreEndPoint(dom, 'end', bookmark);
      return lift2(startPos, endPos.or(startPos), function (spos, epos) {
        var rng = dom.createRng();
        rng.setStart(addBogus(dom, spos.container()), spos.offset());
        rng.setEnd(addBogus(dom, epos.container()), epos.offset());
        return rng;
      });
    };
    var resolveIndex$1 = function (dom, bookmark) {
      return Option.from(dom.select(bookmark.name)[bookmark.index]).map(function (elm) {
        var rng = dom.createRng();
        rng.selectNode(elm);
        return rng;
      });
    };
    var resolve$2 = function (selection, bookmark) {
      var dom = selection.dom;
      if (bookmark) {
        if (isPathBookmark(bookmark)) {
          return resolvePaths(dom, bookmark);
        } else if (isStringPathBookmark(bookmark)) {
          return Option.some(resolveCaretPositionBookmark(dom, bookmark));
        } else if (isIdBookmark(bookmark)) {
          return resolveId(dom, bookmark);
        } else if (isIndexBookmark(bookmark)) {
          return resolveIndex$1(dom, bookmark);
        } else if (isRangeBookmark(bookmark)) {
          return Option.some(bookmark.rng);
        }
      }
      return Option.none();
    };
    var ResolveBookmark = { resolve: resolve$2 };

    var getBookmark$1 = function (selection, type, normalized) {
      return GetBookmark.getBookmark(selection, type, normalized);
    };
    var moveToBookmark = function (selection, bookmark) {
      ResolveBookmark.resolve(selection, bookmark).each(function (rng) {
        selection.setRng(rng);
      });
    };
    var isBookmarkNode$1 = function (node) {
      return NodeType.isElement(node) && node.tagName === 'SPAN' && node.getAttribute('data-mce-type') === 'bookmark';
    };
    var Bookmarks = {
      getBookmark: getBookmark$1,
      moveToBookmark: moveToBookmark,
      isBookmarkNode: isBookmarkNode$1
    };

    var is$2 = function (expected) {
      return function (actual) {
        return expected === actual;
      };
    };
    var isNbsp = is$2(nbsp);
    var isWhiteSpace$1 = function (chr) {
      return chr !== '' && ' \f\n\r\t\x0B'.indexOf(chr) !== -1;
    };
    var isContent = function (chr) {
      return !isWhiteSpace$1(chr) && !isNbsp(chr);
    };

    var isNode = function (node) {
      return !!node.nodeType;
    };
    var isInlineBlock = function (node) {
      return node && /^(IMG)$/.test(node.nodeName);
    };
    var moveStart = function (dom, selection, rng) {
      var offset = rng.startOffset;
      var container = rng.startContainer, walker, node, nodes;
      if (rng.startContainer === rng.endContainer) {
        if (isInlineBlock(rng.startContainer.childNodes[rng.startOffset])) {
          return;
        }
      }
      if (container.nodeType === 1) {
        nodes = container.childNodes;
        if (offset < nodes.length) {
          container = nodes[offset];
          walker = new TreeWalker(container, dom.getParent(container, dom.isBlock));
        } else {
          container = nodes[nodes.length - 1];
          walker = new TreeWalker(container, dom.getParent(container, dom.isBlock));
          walker.next(true);
        }
        for (node = walker.current(); node; node = walker.next()) {
          if (node.nodeType === 3 && !isWhiteSpaceNode(node)) {
            rng.setStart(node, 0);
            selection.setRng(rng);
            return;
          }
        }
      }
    };
    var getNonWhiteSpaceSibling = function (node, next, inc) {
      if (node) {
        var nextName = next ? 'nextSibling' : 'previousSibling';
        for (node = inc ? node : node[nextName]; node; node = node[nextName]) {
          if (node.nodeType === 1 || !isWhiteSpaceNode(node)) {
            return node;
          }
        }
      }
    };
    var isTextBlock$1 = function (editor, name) {
      if (isNode(name)) {
        name = name.nodeName;
      }
      return !!editor.schema.getTextBlockElements()[name.toLowerCase()];
    };
    var isValid = function (ed, parent, child) {
      return ed.schema.isValidChild(parent, child);
    };
    var isWhiteSpaceNode = function (node) {
      return node && NodeType.isText(node) && /^([\t \r\n]+|)$/.test(node.nodeValue);
    };
    var isEmptyTextNode = function (node) {
      return node && NodeType.isText(node) && node.length === 0;
    };
    var replaceVars = function (value, vars) {
      if (typeof value !== 'string') {
        value = value(vars);
      } else if (vars) {
        value = value.replace(/%(\w+)/g, function (str, name) {
          return vars[name] || str;
        });
      }
      return value;
    };
    var isEq = function (str1, str2) {
      str1 = str1 || '';
      str2 = str2 || '';
      str1 = '' + (str1.nodeName || str1);
      str2 = '' + (str2.nodeName || str2);
      return str1.toLowerCase() === str2.toLowerCase();
    };
    var normalizeStyleValue = function (dom, value, name) {
      if (name === 'color' || name === 'backgroundColor') {
        value = dom.toHex(value);
      }
      if (name === 'fontWeight' && value === 700) {
        value = 'bold';
      }
      if (name === 'fontFamily') {
        value = value.replace(/[\'\"]/g, '').replace(/,\s+/g, ',');
      }
      return '' + value;
    };
    var getStyle = function (dom, node, name) {
      return normalizeStyleValue(dom, dom.getStyle(node, name), name);
    };
    var getTextDecoration = function (dom, node) {
      var decoration;
      dom.getParent(node, function (n) {
        decoration = dom.getStyle(n, 'text-decoration');
        return decoration && decoration !== 'none';
      });
      return decoration;
    };
    var getParents$1 = function (dom, node, selector) {
      return dom.getParents(node, selector, dom.getRoot());
    };

    var isBookmarkNode$2 = Bookmarks.isBookmarkNode;
    var getParents$2 = getParents$1, isWhiteSpaceNode$1 = isWhiteSpaceNode, isTextBlock$2 = isTextBlock$1;
    var isBogusBr = function (node) {
      return node.nodeName === 'BR' && node.getAttribute('data-mce-bogus') && !node.nextSibling;
    };
    var findParentContentEditable = function (dom, node) {
      var parent = node;
      while (parent) {
        if (NodeType.isElement(parent) && dom.getContentEditable(parent)) {
          return dom.getContentEditable(parent) === 'false' ? parent : node;
        }
        parent = parent.parentNode;
      }
      return node;
    };
    var walkText = function (start, node, offset, predicate) {
      var str = node.data;
      for (var i = offset; start ? i >= 0 : i < str.length; start ? i-- : i++) {
        if (predicate(str.charAt(i))) {
          return start ? i + 1 : i;
        }
      }
      return -1;
    };
    var findSpace = function (start, node, offset) {
      return walkText(start, node, offset, function (c) {
        return isNbsp(c) || isWhiteSpace$1(c);
      });
    };
    var findContent = function (start, node, offset) {
      return walkText(start, node, offset, isContent);
    };
    var findWordEndPoint = function (dom, body, container, offset, start, includeTrailingSpaces) {
      var lastTextNode;
      var rootNode = dom.getParent(container, dom.isBlock) || body;
      var walk = function (container, offset, pred) {
        var textSeeker = TextSeeker(dom);
        var walker = start ? textSeeker.backwards : textSeeker.forwards;
        return Option.from(walker(container, offset, function (text, textOffset) {
          if (isBookmarkNode$2(text.parentNode)) {
            return -1;
          } else {
            lastTextNode = text;
            return pred(start, text, textOffset);
          }
        }, rootNode));
      };
      var spaceResult = walk(container, offset, findSpace);
      return spaceResult.bind(function (result) {
        return includeTrailingSpaces ? walk(result.container, result.offset + (start ? -1 : 0), findContent) : Option.some(result);
      }).orThunk(function () {
        return lastTextNode ? Option.some({
          container: lastTextNode,
          offset: start ? 0 : lastTextNode.length
        }) : Option.none();
      });
    };
    var findSelectorEndPoint = function (dom, format, rng, container, siblingName) {
      if (NodeType.isText(container) && container.nodeValue.length === 0 && container[siblingName]) {
        container = container[siblingName];
      }
      var parents = getParents$2(dom, container);
      for (var i = 0; i < parents.length; i++) {
        for (var y = 0; y < format.length; y++) {
          var curFormat = format[y];
          if ('collapsed' in curFormat && curFormat.collapsed !== rng.collapsed) {
            continue;
          }
          if (dom.is(parents[i], curFormat.selector)) {
            return parents[i];
          }
        }
      }
      return container;
    };
    var findBlockEndPoint = function (editor, format, container, siblingName) {
      var node;
      var dom = editor.dom;
      var root = dom.getRoot();
      if (!format[0].wrapper) {
        node = dom.getParent(container, format[0].block, root);
      }
      if (!node) {
        var scopeRoot = dom.getParent(container, 'LI,TD,TH');
        node = dom.getParent(NodeType.isText(container) ? container.parentNode : container, function (node) {
          return node !== root && isTextBlock$2(editor, node);
        }, scopeRoot);
      }
      if (node && format[0].wrapper) {
        node = getParents$2(dom, node, 'ul,ol').reverse()[0] || node;
      }
      if (!node) {
        node = container;
        while (node[siblingName] && !dom.isBlock(node[siblingName])) {
          node = node[siblingName];
          if (isEq(node, 'br')) {
            break;
          }
        }
      }
      return node || container;
    };
    var findParentContainer = function (dom, format, startContainer, startOffset, endContainer, endOffset, start) {
      var container, parent, sibling, siblingName, root;
      container = parent = start ? startContainer : endContainer;
      siblingName = start ? 'previousSibling' : 'nextSibling';
      root = dom.getRoot();
      if (NodeType.isText(container) && !isWhiteSpaceNode$1(container)) {
        if (start ? startOffset > 0 : endOffset < container.nodeValue.length) {
          return container;
        }
      }
      while (true) {
        if (!format[0].block_expand && dom.isBlock(parent)) {
          return parent;
        }
        for (sibling = parent[siblingName]; sibling; sibling = sibling[siblingName]) {
          if (!isBookmarkNode$2(sibling) && !isWhiteSpaceNode$1(sibling) && !isBogusBr(sibling)) {
            return parent;
          }
        }
        if (parent === root || parent.parentNode === root) {
          container = parent;
          break;
        }
        parent = parent.parentNode;
      }
      return container;
    };
    var expandRng = function (editor, rng, format, includeTrailingSpace) {
      if (includeTrailingSpace === void 0) {
        includeTrailingSpace = false;
      }
      var startContainer = rng.startContainer, startOffset = rng.startOffset, endContainer = rng.endContainer, endOffset = rng.endOffset;
      var dom = editor.dom;
      if (NodeType.isElement(startContainer) && startContainer.hasChildNodes()) {
        startContainer = getNode(startContainer, startOffset);
        if (NodeType.isText(startContainer)) {
          startOffset = 0;
        }
      }
      if (NodeType.isElement(endContainer) && endContainer.hasChildNodes()) {
        endContainer = getNode(endContainer, rng.collapsed ? endOffset : endOffset - 1);
        if (NodeType.isText(endContainer)) {
          endOffset = endContainer.nodeValue.length;
        }
      }
      startContainer = findParentContentEditable(dom, startContainer);
      endContainer = findParentContentEditable(dom, endContainer);
      if (isBookmarkNode$2(startContainer.parentNode) || isBookmarkNode$2(startContainer)) {
        startContainer = isBookmarkNode$2(startContainer) ? startContainer : startContainer.parentNode;
        if (rng.collapsed) {
          startContainer = startContainer.previousSibling || startContainer;
        } else {
          startContainer = startContainer.nextSibling || startContainer;
        }
        if (NodeType.isText(startContainer)) {
          startOffset = rng.collapsed ? startContainer.length : 0;
        }
      }
      if (isBookmarkNode$2(endContainer.parentNode) || isBookmarkNode$2(endContainer)) {
        endContainer = isBookmarkNode$2(endContainer) ? endContainer : endContainer.parentNode;
        if (rng.collapsed) {
          endContainer = endContainer.nextSibling || endContainer;
        } else {
          endContainer = endContainer.previousSibling || endContainer;
        }
        if (NodeType.isText(endContainer)) {
          endOffset = rng.collapsed ? 0 : endContainer.length;
        }
      }
      if (rng.collapsed) {
        var startPoint = findWordEndPoint(dom, editor.getBody(), startContainer, startOffset, true, includeTrailingSpace);
        startPoint.each(function (_a) {
          var container = _a.container, offset = _a.offset;
          startContainer = container;
          startOffset = offset;
        });
        var endPoint = findWordEndPoint(dom, editor.getBody(), endContainer, endOffset, false, includeTrailingSpace);
        endPoint.each(function (_a) {
          var container = _a.container, offset = _a.offset;
          endContainer = container;
          endOffset = offset;
        });
      }
      if (format[0].inline || format[0].block_expand) {
        if (!format[0].inline || (!NodeType.isText(startContainer) || startOffset === 0)) {
          startContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, true);
        }
        if (!format[0].inline || (!NodeType.isText(endContainer) || endOffset === endContainer.nodeValue.length)) {
          endContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, false);
        }
      }
      if (format[0].selector && format[0].expand !== false && !format[0].inline) {
        startContainer = findSelectorEndPoint(dom, format, rng, startContainer, 'previousSibling');
        endContainer = findSelectorEndPoint(dom, format, rng, endContainer, 'nextSibling');
      }
      if (format[0].block || format[0].selector) {
        startContainer = findBlockEndPoint(editor, format, startContainer, 'previousSibling');
        endContainer = findBlockEndPoint(editor, format, endContainer, 'nextSibling');
        if (format[0].block) {
          if (!dom.isBlock(startContainer)) {
            startContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, true);
          }
          if (!dom.isBlock(endContainer)) {
            endContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, false);
          }
        }
      }
      if (NodeType.isElement(startContainer)) {
        startOffset = dom.nodeIndex(startContainer);
        startContainer = startContainer.parentNode;
      }
      if (NodeType.isElement(endContainer)) {
        endOffset = dom.nodeIndex(endContainer) + 1;
        endContainer = endContainer.parentNode;
      }
      return {
        startContainer: startContainer,
        startOffset: startOffset,
        endContainer: endContainer,
        endOffset: endOffset
      };
    };

    var each$7 = Tools.each;
    var getEndChild = function (container, index) {
      var childNodes = container.childNodes;
      index--;
      if (index > childNodes.length - 1) {
        index = childNodes.length - 1;
      } else if (index < 0) {
        index = 0;
      }
      return childNodes[index] || container;
    };
    var walk$1 = function (dom, rng, callback) {
      var startContainer = rng.startContainer;
      var startOffset = rng.startOffset;
      var endContainer = rng.endContainer;
      var endOffset = rng.endOffset;
      var nodes = dom.select('td[data-mce-selected],th[data-mce-selected]');
      if (nodes.length > 0) {
        each$7(nodes, function (node) {
          callback([node]);
        });
        return;
      }
      var exclude = function (nodes) {
        var node;
        node = nodes[0];
        if (node.nodeType === 3 && node === startContainer && startOffset >= node.nodeValue.length) {
          nodes.splice(0, 1);
        }
        node = nodes[nodes.length - 1];
        if (endOffset === 0 && nodes.length > 0 && node === endContainer && node.nodeType === 3) {
          nodes.splice(nodes.length - 1, 1);
        }
        return nodes;
      };
      var collectSiblings = function (node, name, endNode) {
        var siblings = [];
        for (; node && node !== endNode; node = node[name]) {
          siblings.push(node);
        }
        return siblings;
      };
      var findEndPoint = function (node, root) {
        do {
          if (node.parentNode === root) {
            return node;
          }
          node = node.parentNode;
        } while (node);
      };
      var walkBoundary = function (startNode, endNode, next) {
        var siblingName = next ? 'nextSibling' : 'previousSibling';
        for (var node = startNode, parent_1 = node.parentNode; node && node !== endNode; node = parent_1) {
          parent_1 = node.parentNode;
          var siblings_1 = collectSiblings(node === startNode ? node : node[siblingName], siblingName);
          if (siblings_1.length) {
            if (!next) {
              siblings_1.reverse();
            }
            callback(exclude(siblings_1));
          }
        }
      };
      if (startContainer.nodeType === 1 && startContainer.hasChildNodes()) {
        startContainer = startContainer.childNodes[startOffset];
      }
      if (endContainer.nodeType === 1 && endContainer.hasChildNodes()) {
        endContainer = getEndChild(endContainer, endOffset);
      }
      if (startContainer === endContainer) {
        return callback(exclude([startContainer]));
      }
      var ancestor = dom.findCommonAncestor(startContainer, endContainer);
      for (var node = startContainer; node; node = node.parentNode) {
        if (node === endContainer) {
          return walkBoundary(startContainer, ancestor, true);
        }
        if (node === ancestor) {
          break;
        }
      }
      for (var node = endContainer; node; node = node.parentNode) {
        if (node === startContainer) {
          return walkBoundary(endContainer, ancestor);
        }
        if (node === ancestor) {
          break;
        }
      }
      var startPoint = findEndPoint(startContainer, ancestor) || startContainer;
      var endPoint = findEndPoint(endContainer, ancestor) || endContainer;
      walkBoundary(startContainer, startPoint, true);
      var siblings = collectSiblings(startPoint === startContainer ? startPoint : startPoint.nextSibling, 'nextSibling', endPoint === endContainer ? endPoint.nextSibling : endPoint);
      if (siblings.length) {
        callback(exclude(siblings));
      }
      walkBoundary(endContainer, endPoint);
    };
    var RangeWalk = { walk: walk$1 };

    function NodeValue (is, name) {
      var get = function (element) {
        if (!is(element)) {
          throw new Error('Can only get ' + name + ' value of a ' + name + ' node');
        }
        return getOption(element).getOr('');
      };
      var getOption = function (element) {
        return is(element) ? Option.from(element.dom().nodeValue) : Option.none();
      };
      var set = function (element, value) {
        if (!is(element)) {
          throw new Error('Can only set raw ' + name + ' value of a ' + name + ' node');
        }
        element.dom().nodeValue = value;
      };
      return {
        get: get,
        getOption: getOption,
        set: set
      };
    }

    var api = NodeValue(isText, 'text');
    var get$7 = function (element) {
      return api.get(element);
    };

    var isZeroWidth = function (elem) {
      return isText(elem) && get$7(elem) === zeroWidth;
    };
    var context = function (editor, elem, wrapName, nodeName) {
      return parent(elem).fold(function () {
        return 'skipping';
      }, function (parent) {
        if (nodeName === 'br' || isZeroWidth(elem)) {
          return 'valid';
        } else if (isAnnotation(elem)) {
          return 'existing';
        } else if (isCaretNode(elem)) {
          return 'caret';
        } else if (!isValid(editor, wrapName, nodeName) || !isValid(editor, name(parent), wrapName)) {
          return 'invalid-child';
        } else {
          return 'valid';
        }
      });
    };

    var applyWordGrab = function (editor, rng) {
      var r = expandRng(editor, rng, [{ inline: true }]);
      rng.setStart(r.startContainer, r.startOffset);
      rng.setEnd(r.endContainer, r.endOffset);
      editor.selection.setRng(rng);
    };
    var makeAnnotation = function (eDoc, _a, annotationName, decorate) {
      var _b = _a.uid, uid = _b === void 0 ? generate('mce-annotation') : _b, data = __rest(_a, ['uid']);
      var master = Element.fromTag('span', eDoc);
      add$3(master, annotation());
      set(master, '' + dataAnnotationId(), uid);
      set(master, '' + dataAnnotation(), annotationName);
      var _c = decorate(uid, data), _d = _c.attributes, attributes = _d === void 0 ? {} : _d, _e = _c.classes, classes = _e === void 0 ? [] : _e;
      setAll(master, attributes);
      add$4(master, classes);
      return master;
    };
    var annotate = function (editor, rng, annotationName, decorate, data) {
      var newWrappers = [];
      var master = makeAnnotation(editor.getDoc(), data, annotationName, decorate);
      var wrapper = Cell(Option.none());
      var finishWrapper = function () {
        wrapper.set(Option.none());
      };
      var getOrOpenWrapper = function () {
        return wrapper.get().getOrThunk(function () {
          var nu = shallow(master);
          newWrappers.push(nu);
          wrapper.set(Option.some(nu));
          return nu;
        });
      };
      var processElements = function (elems) {
        each(elems, processElement);
      };
      var processElement = function (elem) {
        var ctx = context(editor, elem, 'span', name(elem));
        switch (ctx) {
        case 'invalid-child': {
            finishWrapper();
            var children$1 = children(elem);
            processElements(children$1);
            finishWrapper();
            break;
          }
        case 'valid': {
            var w = getOrOpenWrapper();
            wrap(elem, w);
            break;
          }
        }
      };
      var processNodes = function (nodes) {
        var elems = map(nodes, Element.fromDom);
        processElements(elems);
      };
      RangeWalk.walk(editor.dom, rng, function (nodes) {
        finishWrapper();
        processNodes(nodes);
      });
      return newWrappers;
    };
    var annotateWithBookmark = function (editor, name, settings, data) {
      editor.undoManager.transact(function () {
        var initialRng = editor.selection.getRng();
        if (initialRng.collapsed) {
          applyWordGrab(editor, initialRng);
        }
        if (editor.selection.getRng().collapsed) {
          var wrapper = makeAnnotation(editor.getDoc(), data, name, settings.decorate);
          set$1(wrapper, nbsp);
          editor.selection.getRng().insertNode(wrapper.dom());
          editor.selection.select(wrapper.dom());
        } else {
          var bookmark = GetBookmark.getPersistentBookmark(editor.selection, false);
          var rng = editor.selection.getRng();
          annotate(editor, rng, name, settings.decorate, data);
          editor.selection.moveToBookmark(bookmark);
        }
      });
    };

    var Annotator = function (editor) {
      var registry = create$1();
      setup$1(editor, registry);
      var changes = setup(editor);
      return {
        register: function (name, settings) {
          registry.register(name, settings);
        },
        annotate: function (name, data) {
          registry.lookup(name).each(function (settings) {
            annotateWithBookmark(editor, name, settings, data);
          });
        },
        annotationChanged: function (name, callback) {
          changes.addListener(name, callback);
        },
        remove: function (name) {
          identify(editor, Option.some(name)).each(function (_a) {
            var elements = _a.elements;
            each(elements, unwrap);
          });
        },
        getAll: function (name) {
          var directory = findAll(editor, name);
          return map$1(directory, function (elems) {
            return map(elems, function (elem) {
              return elem.dom();
            });
          });
        }
      };
    };

    var whiteSpaceRegExp$3 = /^[ \t\r\n]*$/;
    var typeLookup = {
      '#text': 3,
      '#comment': 8,
      '#cdata': 4,
      '#pi': 7,
      '#doctype': 10,
      '#document-fragment': 11
    };
    var walk$2 = function (node, root, prev) {
      var startName = prev ? 'lastChild' : 'firstChild';
      var siblingName = prev ? 'prev' : 'next';
      if (node[startName]) {
        return node[startName];
      }
      if (node !== root) {
        var sibling = node[siblingName];
        if (sibling) {
          return sibling;
        }
        for (var parent_1 = node.parent; parent_1 && parent_1 !== root; parent_1 = parent_1.parent) {
          sibling = parent_1[siblingName];
          if (sibling) {
            return sibling;
          }
        }
      }
    };
    var isEmptyTextNode$1 = function (node) {
      if (!whiteSpaceRegExp$3.test(node.value)) {
        return false;
      }
      var parentNode = node.parent;
      if (parentNode && (parentNode.name !== 'span' || parentNode.attr('style')) && /^[ ]+$/.test(node.value)) {
        return false;
      }
      return true;
    };
    var Node$1 = function () {
      function Node(name, type) {
        this.name = name;
        this.type = type;
        if (type === 1) {
          this.attributes = [];
          this.attributes.map = {};
        }
      }
      Node.create = function (name, attrs) {
        var node = new Node(name, typeLookup[name] || 1);
        if (attrs) {
          for (var attrName in attrs) {
            node.attr(attrName, attrs[attrName]);
          }
        }
        return node;
      };
      Node.prototype.replace = function (node) {
        var self = this;
        if (node.parent) {
          node.remove();
        }
        self.insert(node, self);
        self.remove();
        return self;
      };
      Node.prototype.attr = function (name, value) {
        var self = this;
        var attrs;
        if (typeof name !== 'string') {
          for (var key in name) {
            self.attr(key, name[key]);
          }
          return self;
        }
        if (attrs = self.attributes) {
          if (value !== undefined) {
            if (value === null) {
              if (name in attrs.map) {
                delete attrs.map[name];
                var i = attrs.length;
                while (i--) {
                  if (attrs[i].name === name) {
                    attrs.splice(i, 1);
                    return self;
                  }
                }
              }
              return self;
            }
            if (name in attrs.map) {
              var i = attrs.length;
              while (i--) {
                if (attrs[i].name === name) {
                  attrs[i].value = value;
                  break;
                }
              }
            } else {
              attrs.push({
                name: name,
                value: value
              });
            }
            attrs.map[name] = value;
            return self;
          }
          return attrs.map[name];
        }
      };
      Node.prototype.clone = function () {
        var self = this;
        var clone = new Node(self.name, self.type);
        var selfAttrs;
        if (selfAttrs = self.attributes) {
          var cloneAttrs = [];
          cloneAttrs.map = {};
          for (var i = 0, l = selfAttrs.length; i < l; i++) {
            var selfAttr = selfAttrs[i];
            if (selfAttr.name !== 'id') {
              cloneAttrs[cloneAttrs.length] = {
                name: selfAttr.name,
                value: selfAttr.value
              };
              cloneAttrs.map[selfAttr.name] = selfAttr.value;
            }
          }
          clone.attributes = cloneAttrs;
        }
        clone.value = self.value;
        clone.shortEnded = self.shortEnded;
        return clone;
      };
      Node.prototype.wrap = function (wrapper) {
        var self = this;
        self.parent.insert(wrapper, self);
        wrapper.append(self);
        return self;
      };
      Node.prototype.unwrap = function () {
        var self = this;
        for (var node = self.firstChild; node;) {
          var next = node.next;
          self.insert(node, self, true);
          node = next;
        }
        self.remove();
      };
      Node.prototype.remove = function () {
        var self = this, parent = self.parent, next = self.next, prev = self.prev;
        if (parent) {
          if (parent.firstChild === self) {
            parent.firstChild = next;
            if (next) {
              next.prev = null;
            }
          } else {
            prev.next = next;
          }
          if (parent.lastChild === self) {
            parent.lastChild = prev;
            if (prev) {
              prev.next = null;
            }
          } else {
            next.prev = prev;
          }
          self.parent = self.next = self.prev = null;
        }
        return self;
      };
      Node.prototype.append = function (node) {
        var self = this;
        if (node.parent) {
          node.remove();
        }
        var last = self.lastChild;
        if (last) {
          last.next = node;
          node.prev = last;
          self.lastChild = node;
        } else {
          self.lastChild = self.firstChild = node;
        }
        node.parent = self;
        return node;
      };
      Node.prototype.insert = function (node, refNode, before) {
        if (node.parent) {
          node.remove();
        }
        var parent = refNode.parent || this;
        if (before) {
          if (refNode === parent.firstChild) {
            parent.firstChild = node;
          } else {
            refNode.prev.next = node;
          }
          node.prev = refNode.prev;
          node.next = refNode;
          refNode.prev = node;
        } else {
          if (refNode === parent.lastChild) {
            parent.lastChild = node;
          } else {
            refNode.next.prev = node;
          }
          node.next = refNode.next;
          node.prev = refNode;
          refNode.next = node;
        }
        node.parent = parent;
        return node;
      };
      Node.prototype.getAll = function (name) {
        var self = this;
        var collection = [];
        for (var node = self.firstChild; node; node = walk$2(node, self)) {
          if (node.name === name) {
            collection.push(node);
          }
        }
        return collection;
      };
      Node.prototype.empty = function () {
        var self = this;
        if (self.firstChild) {
          var nodes = [];
          for (var node = self.firstChild; node; node = walk$2(node, self)) {
            nodes.push(node);
          }
          var i = nodes.length;
          while (i--) {
            var node = nodes[i];
            node.parent = node.firstChild = node.lastChild = node.next = node.prev = null;
          }
        }
        self.firstChild = self.lastChild = null;
        return self;
      };
      Node.prototype.isEmpty = function (elements, whitespace, predicate) {
        if (whitespace === void 0) {
          whitespace = {};
        }
        var self = this;
        var node = self.firstChild;
        if (node) {
          do {
            if (node.type === 1) {
              if (node.attr('data-mce-bogus')) {
                continue;
              }
              if (elements[node.name]) {
                return false;
              }
              var i = node.attributes.length;
              while (i--) {
                var name_1 = node.attributes[i].name;
                if (name_1 === 'name' || name_1.indexOf('data-mce-bookmark') === 0) {
                  return false;
                }
              }
            }
            if (node.type === 8) {
              return false;
            }
            if (node.type === 3 && !isEmptyTextNode$1(node)) {
              return false;
            }
            if (node.type === 3 && node.parent && whitespace[node.parent.name] && whiteSpaceRegExp$3.test(node.value)) {
              return false;
            }
            if (predicate && predicate(node)) {
              return false;
            }
          } while (node = walk$2(node, self));
        }
        return true;
      };
      Node.prototype.walk = function (prev) {
        return walk$2(this, null, prev);
      };
      return Node;
    }();

    var isValidPrefixAttrName = function (name) {
      return name.indexOf('data-') === 0 || name.indexOf('aria-') === 0;
    };
    var isInvalidUri = function (settings, uri) {
      if (settings.allow_html_data_urls) {
        return false;
      } else if (/^data:image\//i.test(uri)) {
        return settings.allow_svg_data_urls === false && /^data:image\/svg\+xml/i.test(uri);
      } else {
        return /^data:/i.test(uri);
      }
    };
    var findEndTagIndex = function (schema, html, startIndex) {
      var count = 1, index, matches, tokenRegExp, shortEndedElements;
      shortEndedElements = schema.getShortEndedElements();
      tokenRegExp = /<([!?\/])?([A-Za-z0-9\-_\:\.]+)((?:\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\/|\s+)>/g;
      tokenRegExp.lastIndex = index = startIndex;
      while (matches = tokenRegExp.exec(html)) {
        index = tokenRegExp.lastIndex;
        if (matches[1] === '/') {
          count--;
        } else if (!matches[1]) {
          if (matches[2] in shortEndedElements) {
            continue;
          }
          count++;
        }
        if (count === 0) {
          break;
        }
      }
      return index;
    };
    var isConditionalComment = function (html, startIndex) {
      return /^\s*\[if [\w\W]+\]>.*<!\[endif\](--!?)?>/.test(html.substr(startIndex));
    };
    var findCommentEndIndex = function (html, isBogus, startIndex) {
      if (startIndex === void 0) {
        startIndex = 0;
      }
      var lcHtml = html.toLowerCase();
      if (lcHtml.indexOf('[if ', startIndex) !== -1 && isConditionalComment(lcHtml, startIndex)) {
        var endIfIndex = lcHtml.indexOf('[endif]', startIndex);
        return lcHtml.indexOf('>', endIfIndex);
      } else {
        if (isBogus) {
          var endIndex = lcHtml.indexOf('>', startIndex);
          return endIndex !== -1 ? endIndex : lcHtml.length;
        } else {
          var endCommentRegexp = /--!?>/;
          endCommentRegexp.lastIndex = startIndex;
          var match = endCommentRegexp.exec(html);
          return match ? match.index + match[0].length : lcHtml.length;
        }
      }
    };
    var checkBogusAttribute = function (regExp, attrString) {
      var matches = regExp.exec(attrString);
      if (matches) {
        var name_1 = matches[1];
        var value = matches[2];
        return typeof name_1 === 'string' && name_1.toLowerCase() === 'data-mce-bogus' ? value : null;
      } else {
        return null;
      }
    };
    function SaxParser(settings, schema) {
      if (schema === void 0) {
        schema = Schema();
      }
      var noop = function () {
      };
      settings = settings || {};
      if (settings.fix_self_closing !== false) {
        settings.fix_self_closing = true;
      }
      var comment = settings.comment ? settings.comment : noop;
      var cdata = settings.cdata ? settings.cdata : noop;
      var text = settings.text ? settings.text : noop;
      var start = settings.start ? settings.start : noop;
      var end = settings.end ? settings.end : noop;
      var pi = settings.pi ? settings.pi : noop;
      var doctype = settings.doctype ? settings.doctype : noop;
      var parse = function (html, format) {
        if (format === void 0) {
          format = 'html';
        }
        var matches, index = 0, value, endRegExp;
        var stack = [];
        var attrList, i, textData, name;
        var isInternalElement, removeInternalElements, shortEndedElements, fillAttrsMap, isShortEnded;
        var validate, elementRule, isValidElement, attr, attribsValue, validAttributesMap, validAttributePatterns;
        var attributesRequired, attributesDefault, attributesForced, processHtml;
        var anyAttributesRequired, selfClosing, tokenRegExp, attrRegExp, specialElements, attrValue, idCount = 0;
        var decode = Entities.decode;
        var fixSelfClosing;
        var filteredUrlAttrs = Tools.makeMap('src,href,data,background,formaction,poster,xlink:href');
        var scriptUriRegExp = /((java|vb)script|mhtml):/i;
        var parsingMode = format === 'html' ? 0 : 1;
        var processEndTag = function (name) {
          var pos, i;
          pos = stack.length;
          while (pos--) {
            if (stack[pos].name === name) {
              break;
            }
          }
          if (pos >= 0) {
            for (i = stack.length - 1; i >= pos; i--) {
              name = stack[i];
              if (name.valid) {
                end(name.name);
              }
            }
            stack.length = pos;
          }
        };
        var processComment = function (value) {
          if (value === '') {
            return;
          }
          if (value.charAt(0) === '>') {
            value = ' ' + value;
          }
          if (!settings.allow_conditional_comments && value.substr(0, 3).toLowerCase() === '[if') {
            value = ' ' + value;
          }
          comment(value);
        };
        var processMalformedComment = function (value, startIndex) {
          var startTag = value || '';
          var isBogus = !startsWith(startTag, '--');
          var endIndex = findCommentEndIndex(html, isBogus, startIndex);
          value = html.substr(startIndex, endIndex - startIndex);
          processComment(isBogus ? startTag + value : value);
          return endIndex + 1;
        };
        var parseAttribute = function (match, name, value, val2, val3) {
          var attrRule, i;
          var trimRegExp = /[\s\u0000-\u001F]+/g;
          name = name.toLowerCase();
          value = name in fillAttrsMap ? name : decode(value || val2 || val3 || '');
          if (validate && !isInternalElement && isValidPrefixAttrName(name) === false) {
            attrRule = validAttributesMap[name];
            if (!attrRule && validAttributePatterns) {
              i = validAttributePatterns.length;
              while (i--) {
                attrRule = validAttributePatterns[i];
                if (attrRule.pattern.test(name)) {
                  break;
                }
              }
              if (i === -1) {
                attrRule = null;
              }
            }
            if (!attrRule) {
              return;
            }
            if (attrRule.validValues && !(value in attrRule.validValues)) {
              return;
            }
          }
          if (filteredUrlAttrs[name] && !settings.allow_script_urls) {
            var uri = value.replace(trimRegExp, '');
            try {
              uri = decodeURIComponent(uri);
            } catch (ex) {
              uri = unescape(uri);
            }
            if (scriptUriRegExp.test(uri)) {
              return;
            }
            if (isInvalidUri(settings, uri)) {
              return;
            }
          }
          if (isInternalElement && (name in filteredUrlAttrs || name.indexOf('on') === 0)) {
            return;
          }
          attrList.map[name] = value;
          attrList.push({
            name: name,
            value: value
          });
        };
        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');
        attrRegExp = /([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:[^\"])*)\")|(?:\'((?:[^\'])*)\')|([^>\s]+)))?/g;
        shortEndedElements = schema.getShortEndedElements();
        selfClosing = settings.self_closing_elements || schema.getSelfClosingElements();
        fillAttrsMap = schema.getBoolAttrs();
        validate = settings.validate;
        removeInternalElements = settings.remove_internals;
        fixSelfClosing = settings.fix_self_closing;
        specialElements = schema.getSpecialElements();
        processHtml = html + '>';
        while (matches = tokenRegExp.exec(processHtml)) {
          var matchText = matches[0];
          if (index < matches.index) {
            text(decode(html.substr(index, matches.index - index)));
          }
          if (value = matches[7]) {
            value = value.toLowerCase();
            if (value.charAt(0) === ':') {
              value = value.substr(1);
            }
            processEndTag(value);
          } else if (value = matches[8]) {
            if (matches.index + matchText.length > html.length) {
              text(decode(html.substr(matches.index)));
              index = matches.index + matchText.length;
              continue;
            }
            value = value.toLowerCase();
            if (value.charAt(0) === ':') {
              value = value.substr(1);
            }
            isShortEnded = value in shortEndedElements;
            if (fixSelfClosing && selfClosing[value] && stack.length > 0 && stack[stack.length - 1].name === value) {
              processEndTag(value);
            }
            var bogusValue = checkBogusAttribute(attrRegExp, matches[9]);
            if (bogusValue !== null) {
              if (bogusValue === 'all') {
                index = findEndTagIndex(schema, html, tokenRegExp.lastIndex);
                tokenRegExp.lastIndex = index;
                continue;
              }
              isValidElement = false;
            }
            if (!validate || (elementRule = schema.getElementRule(value))) {
              isValidElement = true;
              if (validate) {
                validAttributesMap = elementRule.attributes;
                validAttributePatterns = elementRule.attributePatterns;
              }
              if (attribsValue = matches[9]) {
                isInternalElement = attribsValue.indexOf('data-mce-type') !== -1;
                if (isInternalElement && removeInternalElements) {
                  isValidElement = false;
                }
                attrList = [];
                attrList.map = {};
                attribsValue.replace(attrRegExp, parseAttribute);
              } else {
                attrList = [];
                attrList.map = {};
              }
              if (validate && !isInternalElement) {
                attributesRequired = elementRule.attributesRequired;
                attributesDefault = elementRule.attributesDefault;
                attributesForced = elementRule.attributesForced;
                anyAttributesRequired = elementRule.removeEmptyAttrs;
                if (anyAttributesRequired && !attrList.length) {
                  isValidElement = false;
                }
                if (attributesForced) {
                  i = attributesForced.length;
                  while (i--) {
                    attr = attributesForced[i];
                    name = attr.name;
                    attrValue = attr.value;
                    if (attrValue === '{$uid}') {
                      attrValue = 'mce_' + idCount++;
                    }
                    attrList.map[name] = attrValue;
                    attrList.push({
                      name: name,
                      value: attrValue
                    });
                  }
                }
                if (attributesDefault) {
                  i = attributesDefault.length;
                  while (i--) {
                    attr = attributesDefault[i];
                    name = attr.name;
                    if (!(name in attrList.map)) {
                      attrValue = attr.value;
                      if (attrValue === '{$uid}') {
                        attrValue = 'mce_' + idCount++;
                      }
                      attrList.map[name] = attrValue;
                      attrList.push({
                        name: name,
                        value: attrValue
                      });
                    }
                  }
                }
                if (attributesRequired) {
                  i = attributesRequired.length;
                  while (i--) {
                    if (attributesRequired[i] in attrList.map) {
                      break;
                    }
                  }
                  if (i === -1) {
                    isValidElement = false;
                  }
                }
                if (attr = attrList.map['data-mce-bogus']) {
                  if (attr === 'all') {
                    index = findEndTagIndex(schema, html, tokenRegExp.lastIndex);
                    tokenRegExp.lastIndex = index;
                    continue;
                  }
                  isValidElement = false;
                }
              }
              if (isValidElement) {
                start(value, attrList, isShortEnded);
              }
            } else {
              isValidElement = false;
            }
            if (endRegExp = specialElements[value]) {
              endRegExp.lastIndex = index = matches.index + matchText.length;
              if (matches = endRegExp.exec(html)) {
                if (isValidElement) {
                  textData = html.substr(index, matches.index - index);
                }
                index = matches.index + matches[0].length;
              } else {
                textData = html.substr(index);
                index = html.length;
              }
              if (isValidElement) {
                if (textData.length > 0) {
                  text(textData, true);
                }
                end(value);
              }
              tokenRegExp.lastIndex = index;
              continue;
            }
            if (!isShortEnded) {
              if (!attribsValue || attribsValue.indexOf('/') !== attribsValue.length - 1) {
                stack.push({
                  name: value,
                  valid: isValidElement
                });
              } else if (isValidElement) {
                end(value);
              }
            }
          } else if (value = matches[1]) {
            processComment(value);
          } else if (value = matches[2]) {
            var isValidCdataSection = parsingMode === 1 || settings.preserve_cdata || stack.length > 0 && schema.isValidChild(stack[stack.length - 1].name, '#cdata');
            if (isValidCdataSection) {
              cdata(value);
            } else {
              index = processMalformedComment('', matches.index + 2);
              tokenRegExp.lastIndex = index;
              continue;
            }
          } else if (value = matches[3]) {
            doctype(value);
          } else if ((value = matches[4]) || matchText === '<!') {
            index = processMalformedComment(value, matches.index + matchText.length);
            tokenRegExp.lastIndex = index;
            continue;
          } else if (value = matches[5]) {
            if (parsingMode === 1) {
              pi(value, matches[6]);
            } else {
              index = processMalformedComment('?', matches.index + 2);
              tokenRegExp.lastIndex = index;
              continue;
            }
          }
          index = matches.index + matchText.length;
        }
        if (index < html.length) {
          text(decode(html.substr(index)));
        }
        for (i = stack.length - 1; i >= 0; i--) {
          value = stack[i];
          if (value.valid) {
            end(value.name);
          }
        }
      };
      return { parse: parse };
    }
    (function (SaxParser) {
      SaxParser.findEndTag = findEndTagIndex;
    }(SaxParser || (SaxParser = {})));
    var SaxParser$1 = SaxParser;

    var trimHtml = function (tempAttrs, html) {
      var trimContentRegExp = new RegExp(['\\s?(' + tempAttrs.join('|') + ')="[^"]+"'].join('|'), 'gi');
      return html.replace(trimContentRegExp, '');
    };
    var trimInternal = function (serializer, html) {
      var content = html;
      var bogusAllRegExp = /<(\w+) [^>]*data-mce-bogus="all"[^>]*>/g;
      var endTagIndex, index, matchLength, matches, shortEndedElements;
      var schema = serializer.schema;
      content = trimHtml(serializer.getTempAttrs(), content);
      shortEndedElements = schema.getShortEndedElements();
      while (matches = bogusAllRegExp.exec(content)) {
        index = bogusAllRegExp.lastIndex;
        matchLength = matches[0].length;
        if (shortEndedElements[matches[1]]) {
          endTagIndex = index;
        } else {
          endTagIndex = SaxParser$1.findEndTag(schema, content, index);
        }
        content = content.substring(0, index - matchLength) + content.substring(endTagIndex);
        bogusAllRegExp.lastIndex = index - matchLength;
      }
      return Zwsp.trim(content);
    };
    var trimExternal = trimInternal;
    var TrimHtml = {
      trimExternal: trimExternal,
      trimInternal: trimInternal
    };

    var defaultFormat = 'html';
    var trimEmptyContents = function (editor, html) {
      var blockName = Settings.getForcedRootBlock(editor);
      var emptyRegExp = new RegExp('^(<' + blockName + '[^>]*>(&nbsp;|&#160;|\\s|\xA0|<br \\/>|)<\\/' + blockName + '>[\r\n]*|<br \\/>[\r\n]*)$');
      return html.replace(emptyRegExp, '');
    };
    var getContentFromBody = function (editor, args, body) {
      var content;
      args.format = args.format ? args.format : defaultFormat;
      args.get = true;
      args.getInner = true;
      if (!args.no_events) {
        editor.fire('BeforeGetContent', args);
      }
      if (args.format === 'raw') {
        content = Tools.trim(TrimHtml.trimExternal(editor.serializer, body.innerHTML));
      } else if (args.format === 'text') {
        content = Zwsp.trim(body.innerText || body.textContent);
      } else if (args.format === 'tree') {
        return editor.serializer.serialize(body, args);
      } else {
        content = trimEmptyContents(editor, editor.serializer.serialize(body, args));
      }
      if (args.format !== 'text' && !isWsPreserveElement(Element.fromDom(body))) {
        args.content = Tools.trim(content);
      } else {
        args.content = content;
      }
      if (!args.no_events) {
        editor.fire('GetContent', args);
      }
      return args.content;
    };
    var getContent = function (editor, args) {
      if (args === void 0) {
        args = {};
      }
      return Option.from(editor.getBody()).fold(constant(args.format === 'tree' ? new Node$1('body', 11) : ''), function (body) {
        return getContentFromBody(editor, args, body);
      });
    };

    var makeMap$3 = Tools.makeMap;
    var Writer = function (settings) {
      var html = [];
      var indent, indentBefore, indentAfter, encode, htmlOutput;
      settings = settings || {};
      indent = settings.indent;
      indentBefore = makeMap$3(settings.indent_before || '');
      indentAfter = makeMap$3(settings.indent_after || '');
      encode = Entities.getEncodeFunc(settings.entity_encoding || 'raw', settings.entities);
      htmlOutput = settings.element_format === 'html';
      return {
        start: function (name, attrs, empty) {
          var i, l, attr, value;
          if (indent && indentBefore[name] && html.length > 0) {
            value = html[html.length - 1];
            if (value.length > 0 && value !== '\n') {
              html.push('\n');
            }
          }
          html.push('<', name);
          if (attrs) {
            for (i = 0, l = attrs.length; i < l; i++) {
              attr = attrs[i];
              html.push(' ', attr.name, '="', encode(attr.value, true), '"');
            }
          }
          if (!empty || htmlOutput) {
            html[html.length] = '>';
          } else {
            html[html.length] = ' />';
          }
          if (empty && indent && indentAfter[name] && html.length > 0) {
            value = html[html.length - 1];
            if (value.length > 0 && value !== '\n') {
              html.push('\n');
            }
          }
        },
        end: function (name) {
          var value;
          html.push('</', name, '>');
          if (indent && indentAfter[name] && html.length > 0) {
            value = html[html.length - 1];
            if (value.length > 0 && value !== '\n') {
              html.push('\n');
            }
          }
        },
        text: function (text, raw) {
          if (text.length > 0) {
            html[html.length] = raw ? text : encode(text);
          }
        },
        cdata: function (text) {
          html.push('<![CDATA[', text, ']]>');
        },
        comment: function (text) {
          html.push('<!--', text, '-->');
        },
        pi: function (name, text) {
          if (text) {
            html.push('<?', name, ' ', encode(text), '?>');
          } else {
            html.push('<?', name, '?>');
          }
          if (indent) {
            html.push('\n');
          }
        },
        doctype: function (text) {
          html.push('<!DOCTYPE', text, '>', indent ? '\n' : '');
        },
        reset: function () {
          html.length = 0;
        },
        getContent: function () {
          return html.join('').replace(/\n$/, '');
        }
      };
    };

    var Serializer = function (settings, schema) {
      if (schema === void 0) {
        schema = Schema();
      }
      var writer = Writer(settings);
      settings = settings || {};
      settings.validate = 'validate' in settings ? settings.validate : true;
      var serialize = function (node) {
        var handlers, validate;
        validate = settings.validate;
        handlers = {
          3: function (node) {
            writer.text(node.value, node.raw);
          },
          8: function (node) {
            writer.comment(node.value);
          },
          7: function (node) {
            writer.pi(node.name, node.value);
          },
          10: function (node) {
            writer.doctype(node.value);
          },
          4: function (node) {
            writer.cdata(node.value);
          },
          11: function (node) {
            if (node = node.firstChild) {
              do {
                walk(node);
              } while (node = node.next);
            }
          }
        };
        writer.reset();
        var walk = function (node) {
          var handler = handlers[node.type];
          var name, isEmpty, attrs, attrName, attrValue, sortedAttrs, i, l, elementRule;
          if (!handler) {
            name = node.name;
            isEmpty = node.shortEnded;
            attrs = node.attributes;
            if (validate && attrs && attrs.length > 1) {
              sortedAttrs = [];
              sortedAttrs.map = {};
              elementRule = schema.getElementRule(node.name);
              if (elementRule) {
                for (i = 0, l = elementRule.attributesOrder.length; i < l; i++) {
                  attrName = elementRule.attributesOrder[i];
                  if (attrName in attrs.map) {
                    attrValue = attrs.map[attrName];
                    sortedAttrs.map[attrName] = attrValue;
                    sortedAttrs.push({
                      name: attrName,
                      value: attrValue
                    });
                  }
                }
                for (i = 0, l = attrs.length; i < l; i++) {
                  attrName = attrs[i].name;
                  if (!(attrName in sortedAttrs.map)) {
                    attrValue = attrs.map[attrName];
                    sortedAttrs.map[attrName] = attrValue;
                    sortedAttrs.push({
                      name: attrName,
                      value: attrValue
                    });
                  }
                }
                attrs = sortedAttrs;
              }
            }
            writer.start(node.name, attrs, isEmpty);
            if (!isEmpty) {
              if (node = node.firstChild) {
                do {
                  walk(node);
                } while (node = node.next);
              }
              writer.end(name);
            }
          } else {
            handler(node);
          }
        };
        if (node.type === 1 && !settings.inner) {
          walk(node);
        } else {
          handlers[11](node);
        }
        return writer.getContent();
      };
      return { serialize: serialize };
    };

    var traverse = function (node, fn) {
      fn(node);
      if (node.firstChild) {
        traverse(node.firstChild, fn);
      }
      if (node.next) {
        traverse(node.next, fn);
      }
    };
    var findMatchingNodes = function (nodeFilters, attributeFilters, node) {
      var nodeMatches = {};
      var attrMatches = {};
      var matches = [];
      if (node.firstChild) {
        traverse(node.firstChild, function (node) {
          each(nodeFilters, function (filter) {
            if (filter.name === node.name) {
              if (nodeMatches[filter.name]) {
                nodeMatches[filter.name].nodes.push(node);
              } else {
                nodeMatches[filter.name] = {
                  filter: filter,
                  nodes: [node]
                };
              }
            }
          });
          each(attributeFilters, function (filter) {
            if (typeof node.attr(filter.name) === 'string') {
              if (attrMatches[filter.name]) {
                attrMatches[filter.name].nodes.push(node);
              } else {
                attrMatches[filter.name] = {
                  filter: filter,
                  nodes: [node]
                };
              }
            }
          });
        });
      }
      for (var name_1 in nodeMatches) {
        if (nodeMatches.hasOwnProperty(name_1)) {
          matches.push(nodeMatches[name_1]);
        }
      }
      for (var name_2 in attrMatches) {
        if (attrMatches.hasOwnProperty(name_2)) {
          matches.push(attrMatches[name_2]);
        }
      }
      return matches;
    };
    var filter$2 = function (nodeFilters, attributeFilters, node) {
      var matches = findMatchingNodes(nodeFilters, attributeFilters, node);
      each(matches, function (match) {
        each(match.filter.callbacks, function (callback) {
          callback(match.nodes, match.filter.name, {});
        });
      });
    };

    var hasFocus = function (element) {
      var doc = owner(element).dom();
      return element.dom() === doc.activeElement;
    };
    var active = function (_doc) {
      var doc = _doc !== undefined ? _doc.dom() : domGlobals.document;
      return Option.from(doc.activeElement).map(Element.fromDom);
    };
    var search = function (element) {
      return active(owner(element)).filter(function (e) {
        return element.dom().contains(e.dom());
      });
    };

    var generate$1 = function (cases) {
      if (!isArray(cases)) {
        throw new Error('cases must be an array');
      }
      if (cases.length === 0) {
        throw new Error('there must be at least one case');
      }
      var constructors = [];
      var adt = {};
      each(cases, function (acase, count) {
        var keys$1 = keys(acase);
        if (keys$1.length !== 1) {
          throw new Error('one and only one name per case');
        }
        var key = keys$1[0];
        var value = acase[key];
        if (adt[key] !== undefined) {
          throw new Error('duplicate key detected:' + key);
        } else if (key === 'cata') {
          throw new Error('cannot have a case named cata (sorry)');
        } else if (!isArray(value)) {
          throw new Error('case arguments must be an array');
        }
        constructors.push(key);
        adt[key] = function () {
          var argLength = arguments.length;
          if (argLength !== value.length) {
            throw new Error('Wrong number of arguments to case ' + key + '. Expected ' + value.length + ' (' + value + '), got ' + argLength);
          }
          var args = new Array(argLength);
          for (var i = 0; i < args.length; i++) {
            args[i] = arguments[i];
          }
          var match = function (branches) {
            var branchKeys = keys(branches);
            if (constructors.length !== branchKeys.length) {
              throw new Error('Wrong number of arguments to match. Expected: ' + constructors.join(',') + '\nActual: ' + branchKeys.join(','));
            }
            var allReqd = forall(constructors, function (reqKey) {
              return contains(branchKeys, reqKey);
            });
            if (!allReqd) {
              throw new Error('Not all branches were specified when using match. Specified: ' + branchKeys.join(', ') + '\nRequired: ' + constructors.join(', '));
            }
            return branches[key].apply(null, args);
          };
          return {
            fold: function () {
              if (arguments.length !== cases.length) {
                throw new Error('Wrong number of arguments to fold. Expected ' + cases.length + ', got ' + arguments.length);
              }
              var target = arguments[count];
              return target.apply(null, args);
            },
            match: match,
            log: function (label) {
              domGlobals.console.log(label, {
                constructors: constructors,
                constructor: key,
                params: args
              });
            }
          };
        };
      });
      return adt;
    };
    var Adt = { generate: generate$1 };

    var create$3 = Immutable('start', 'soffset', 'finish', 'foffset');
    var SimRange = { create: create$3 };

    var adt = Adt.generate([
      { before: ['element'] },
      {
        on: [
          'element',
          'offset'
        ]
      },
      { after: ['element'] }
    ]);
    var cata = function (subject, onBefore, onOn, onAfter) {
      return subject.fold(onBefore, onOn, onAfter);
    };
    var getStart = function (situ) {
      return situ.fold(identity, identity, identity);
    };
    var before$3 = adt.before;
    var on = adt.on;
    var after$2 = adt.after;
    var Situ = {
      before: before$3,
      on: on,
      after: after$2,
      cata: cata,
      getStart: getStart
    };

    var adt$1 = Adt.generate([
      { domRange: ['rng'] },
      {
        relative: [
          'startSitu',
          'finishSitu'
        ]
      },
      {
        exact: [
          'start',
          'soffset',
          'finish',
          'foffset'
        ]
      }
    ]);
    var exactFromRange = function (simRange) {
      return adt$1.exact(simRange.start(), simRange.soffset(), simRange.finish(), simRange.foffset());
    };
    var getStart$1 = function (selection) {
      return selection.match({
        domRange: function (rng) {
          return Element.fromDom(rng.startContainer);
        },
        relative: function (startSitu, finishSitu) {
          return Situ.getStart(startSitu);
        },
        exact: function (start, soffset, finish, foffset) {
          return start;
        }
      });
    };
    var domRange = adt$1.domRange;
    var relative = adt$1.relative;
    var exact = adt$1.exact;
    var getWin = function (selection) {
      var start = getStart$1(selection);
      return defaultView(start);
    };
    var range = SimRange.create;
    var Selection = {
      domRange: domRange,
      relative: relative,
      exact: exact,
      exactFromRange: exactFromRange,
      getWin: getWin,
      range: range
    };

    var browser$4 = detect$3().browser;
    var clamp = function (offset, element) {
      var max = isText(element) ? get$7(element).length : children(element).length + 1;
      if (offset > max) {
        return max;
      } else if (offset < 0) {
        return 0;
      }
      return offset;
    };
    var normalizeRng = function (rng) {
      return Selection.range(rng.start(), clamp(rng.soffset(), rng.start()), rng.finish(), clamp(rng.foffset(), rng.finish()));
    };
    var isOrContains = function (root, elm) {
      return !NodeType.isRestrictedNode(elm.dom()) && (contains$2(root, elm) || eq(root, elm));
    };
    var isRngInRoot = function (root) {
      return function (rng) {
        return isOrContains(root, rng.start()) && isOrContains(root, rng.finish());
      };
    };
    var shouldStore = function (editor) {
      return editor.inline === true || browser$4.isIE();
    };
    var nativeRangeToSelectionRange = function (r) {
      return Selection.range(Element.fromDom(r.startContainer), r.startOffset, Element.fromDom(r.endContainer), r.endOffset);
    };
    var readRange = function (win) {
      var selection = win.getSelection();
      var rng = !selection || selection.rangeCount === 0 ? Option.none() : Option.from(selection.getRangeAt(0));
      return rng.map(nativeRangeToSelectionRange);
    };
    var getBookmark$2 = function (root) {
      var win = defaultView(root);
      return readRange(win.dom()).filter(isRngInRoot(root));
    };
    var validate = function (root, bookmark) {
      return Option.from(bookmark).filter(isRngInRoot(root)).map(normalizeRng);
    };
    var bookmarkToNativeRng = function (bookmark) {
      var rng = domGlobals.document.createRange();
      try {
        rng.setStart(bookmark.start().dom(), bookmark.soffset());
        rng.setEnd(bookmark.finish().dom(), bookmark.foffset());
        return Option.some(rng);
      } catch (_) {
        return Option.none();
      }
    };
    var store = function (editor) {
      var newBookmark = shouldStore(editor) ? getBookmark$2(Element.fromDom(editor.getBody())) : Option.none();
      editor.bookmark = newBookmark.isSome() ? newBookmark : editor.bookmark;
    };
    var storeNative = function (editor, rng) {
      var root = Element.fromDom(editor.getBody());
      var range = shouldStore(editor) ? Option.from(rng) : Option.none();
      var newBookmark = range.map(nativeRangeToSelectionRange).filter(isRngInRoot(root));
      editor.bookmark = newBookmark.isSome() ? newBookmark : editor.bookmark;
    };
    var getRng = function (editor) {
      var bookmark = editor.bookmark ? editor.bookmark : Option.none();
      return bookmark.bind(function (x) {
        return validate(Element.fromDom(editor.getBody()), x);
      }).bind(bookmarkToNativeRng);
    };
    var restore = function (editor) {
      getRng(editor).each(function (rng) {
        editor.selection.setRng(rng);
      });
    };
    var SelectionBookmark = {
      store: store,
      storeNative: storeNative,
      readRange: readRange,
      restore: restore,
      getRng: getRng,
      getBookmark: getBookmark$2,
      validate: validate
    };

    var isEditorUIElement = function (elm) {
      var className = elm.className.toString();
      return className.indexOf('tox-') !== -1 || className.indexOf('mce-') !== -1;
    };
    var FocusManager = { isEditorUIElement: isEditorUIElement };

    var isManualNodeChange = function (e) {
      return e.type === 'nodechange' && e.selectionChange;
    };
    var registerPageMouseUp = function (editor, throttledStore) {
      var mouseUpPage = function () {
        throttledStore.throttle();
      };
      DOMUtils$1.DOM.bind(domGlobals.document, 'mouseup', mouseUpPage);
      editor.on('remove', function () {
        DOMUtils$1.DOM.unbind(domGlobals.document, 'mouseup', mouseUpPage);
      });
    };
    var registerFocusOut = function (editor) {
      editor.on('focusout', function () {
        SelectionBookmark.store(editor);
      });
    };
    var registerMouseUp = function (editor, throttledStore) {
      editor.on('mouseup touchend', function (e) {
        throttledStore.throttle();
      });
    };
    var registerEditorEvents = function (editor, throttledStore) {
      var browser = detect$3().browser;
      if (browser.isIE()) {
        registerFocusOut(editor);
      } else {
        registerMouseUp(editor, throttledStore);
      }
      editor.on('keyup NodeChange', function (e) {
        if (!isManualNodeChange(e)) {
          SelectionBookmark.store(editor);
        }
      });
    };
    var register = function (editor) {
      var throttledStore = first(function () {
        SelectionBookmark.store(editor);
      }, 0);
      editor.on('init', function () {
        if (editor.inline) {
          registerPageMouseUp(editor, throttledStore);
        }
        registerEditorEvents(editor, throttledStore);
      });
      editor.on('remove', function () {
        throttledStore.cancel();
      });
    };
    var SelectionRestore = { register: register };

    var documentFocusInHandler;
    var DOM$2 = DOMUtils$1.DOM;
    var isEditorUIElement$1 = function (elm) {
      return FocusManager.isEditorUIElement(elm);
    };
    var isEditorContentAreaElement = function (elm) {
      var classList = elm.classList;
      if (classList !== undefined) {
        return classList.contains('tox-edit-area') || classList.contains('tox-edit-area__iframe') || classList.contains('mce-content-body');
      } else {
        return false;
      }
    };
    var isUIElement = function (editor, elm) {
      var customSelector = editor ? editor.settings.custom_ui_selector : '';
      var parent = DOM$2.getParent(elm, function (elm) {
        return isEditorUIElement$1(elm) || (customSelector ? editor.dom.is(elm, customSelector) : false);
      });
      return parent !== null;
    };
    var getActiveElement = function () {
      try {
        return domGlobals.document.activeElement;
      } catch (ex) {
        return domGlobals.document.body;
      }
    };
    var registerEvents = function (editorManager, e) {
      var editor = e.editor;
      SelectionRestore.register(editor);
      editor.on('focusin', function () {
        var self = this;
        var focusedEditor = editorManager.focusedEditor;
        if (focusedEditor !== self) {
          if (focusedEditor) {
            focusedEditor.fire('blur', { focusedEditor: self });
          }
          editorManager.setActive(self);
          editorManager.focusedEditor = self;
          self.fire('focus', { blurredEditor: focusedEditor });
          self.focus(true);
        }
      });
      editor.on('focusout', function () {
        var self = this;
        Delay.setEditorTimeout(self, function () {
          var focusedEditor = editorManager.focusedEditor;
          if (!isUIElement(self, getActiveElement()) && focusedEditor === self) {
            self.fire('blur', { focusedEditor: null });
            editorManager.focusedEditor = null;
          }
        });
      });
      if (!documentFocusInHandler) {
        documentFocusInHandler = function (e) {
          var activeEditor = editorManager.activeEditor;
          var target;
          target = e.target;
          if (activeEditor && target.ownerDocument === domGlobals.document) {
            if (target !== domGlobals.document.body && !isUIElement(activeEditor, target) && editorManager.focusedEditor === activeEditor) {
              activeEditor.fire('blur', { focusedEditor: null });
              editorManager.focusedEditor = null;
            }
          }
        };
        DOM$2.bind(domGlobals.document, 'focusin', documentFocusInHandler);
      }
    };
    var unregisterDocumentEvents = function (editorManager, e) {
      if (editorManager.focusedEditor === e.editor) {
        editorManager.focusedEditor = null;
      }
      if (!editorManager.activeEditor) {
        DOM$2.unbind(domGlobals.document, 'focusin', documentFocusInHandler);
        documentFocusInHandler = null;
      }
    };
    var setup$2 = function (editorManager) {
      editorManager.on('AddEditor', curry(registerEvents, editorManager));
      editorManager.on('RemoveEditor', curry(unregisterDocumentEvents, editorManager));
    };
    var FocusController = {
      setup: setup$2,
      isEditorUIElement: isEditorUIElement$1,
      isEditorContentAreaElement: isEditorContentAreaElement,
      isUIElement: isUIElement
    };

    var getContentEditableHost = function (editor, node) {
      return editor.dom.getParent(node, function (node) {
        return editor.dom.getContentEditable(node) === 'true';
      });
    };
    var getCollapsedNode = function (rng) {
      return rng.collapsed ? Option.from(getNode(rng.startContainer, rng.startOffset)).map(Element.fromDom) : Option.none();
    };
    var getFocusInElement = function (root, rng) {
      return getCollapsedNode(rng).bind(function (node) {
        if (isTableSection(node)) {
          return Option.some(node);
        } else if (contains$2(root, node) === false) {
          return Option.some(root);
        } else {
          return Option.none();
        }
      });
    };
    var normalizeSelection = function (editor, rng) {
      getFocusInElement(Element.fromDom(editor.getBody()), rng).bind(function (elm) {
        return CaretFinder.firstPositionIn(elm.dom());
      }).fold(function () {
        editor.selection.normalize();
        return;
      }, function (caretPos) {
        return editor.selection.setRng(caretPos.toRange());
      });
    };
    var focusBody = function (body) {
      if (body.setActive) {
        try {
          body.setActive();
        } catch (ex) {
          body.focus();
        }
      } else {
        body.focus();
      }
    };
    var hasElementFocus = function (elm) {
      return hasFocus(elm) || search(elm).isSome();
    };
    var hasIframeFocus = function (editor) {
      return editor.iframeElement && hasFocus(Element.fromDom(editor.iframeElement));
    };
    var hasInlineFocus = function (editor) {
      var rawBody = editor.getBody();
      return rawBody && hasElementFocus(Element.fromDom(rawBody));
    };
    var hasUiFocus = function (editor) {
      return active().filter(function (elem) {
        return !FocusController.isEditorContentAreaElement(elem.dom()) && FocusController.isUIElement(editor, elem.dom());
      }).isSome();
    };
    var hasFocus$1 = function (editor) {
      return editor.inline ? hasInlineFocus(editor) : hasIframeFocus(editor);
    };
    var hasEditorOrUiFocus = function (editor) {
      return hasFocus$1(editor) || hasUiFocus(editor);
    };
    var focusEditor = function (editor) {
      var selection = editor.selection;
      var body = editor.getBody();
      var rng = selection.getRng();
      editor.quirks.refreshContentEditable();
      if (editor.bookmark !== undefined && hasFocus$1(editor) === false) {
        SelectionBookmark.getRng(editor).each(function (bookmarkRng) {
          editor.selection.setRng(bookmarkRng);
          rng = bookmarkRng;
        });
      }
      var contentEditableHost = getContentEditableHost(editor, selection.getNode());
      if (editor.$.contains(body, contentEditableHost)) {
        focusBody(contentEditableHost);
        normalizeSelection(editor, rng);
        activateEditor(editor);
        return;
      }
      if (!editor.inline) {
        if (!Env.opera) {
          focusBody(body);
        }
        editor.getWin().focus();
      }
      if (Env.gecko || editor.inline) {
        focusBody(body);
        normalizeSelection(editor, rng);
      }
      activateEditor(editor);
    };
    var activateEditor = function (editor) {
      return editor.editorManager.setActive(editor);
    };
    var focus = function (editor, skipFocus) {
      if (editor.removed) {
        return;
      }
      skipFocus ? activateEditor(editor) : focusEditor(editor);
    };
    var EditorFocus = {
      focus: focus,
      hasFocus: hasFocus$1,
      hasEditorOrUiFocus: hasEditorOrUiFocus
    };

    var defaultFormat$1 = 'html';
    var isTreeNode = function (content) {
      return content instanceof Node$1;
    };
    var moveSelection = function (editor) {
      if (EditorFocus.hasFocus(editor)) {
        CaretFinder.firstPositionIn(editor.getBody()).each(function (pos) {
          var node = pos.getNode();
          var caretPos = NodeType.isTable(node) ? CaretFinder.firstPositionIn(node).getOr(pos) : pos;
          editor.selection.setRng(caretPos.toRange());
        });
      }
    };
    var setEditorHtml = function (editor, html) {
      editor.dom.setHTML(editor.getBody(), html);
      moveSelection(editor);
    };
    var setContentString = function (editor, body, content, args) {
      var forcedRootBlockName, padd;
      if (content.length === 0 || /^\s+$/.test(content)) {
        padd = '<br data-mce-bogus="1">';
        if (body.nodeName === 'TABLE') {
          content = '<tr><td>' + padd + '</td></tr>';
        } else if (/^(UL|OL)$/.test(body.nodeName)) {
          content = '<li>' + padd + '</li>';
        }
        forcedRootBlockName = Settings.getForcedRootBlock(editor);
        if (forcedRootBlockName && editor.schema.isValidChild(body.nodeName.toLowerCase(), forcedRootBlockName.toLowerCase())) {
          content = padd;
          content = editor.dom.createHTML(forcedRootBlockName, editor.settings.forced_root_block_attrs, content);
        } else if (!content) {
          content = '<br data-mce-bogus="1">';
        }
        setEditorHtml(editor, content);
        editor.fire('SetContent', args);
      } else {
        if (args.format !== 'raw') {
          content = Serializer({ validate: editor.validate }, editor.schema).serialize(editor.parser.parse(content, {
            isRootContent: true,
            insert: true
          }));
        }
        args.content = isWsPreserveElement(Element.fromDom(body)) ? content : Tools.trim(content);
        setEditorHtml(editor, args.content);
        if (!args.no_events) {
          editor.fire('SetContent', args);
        }
      }
      return args.content;
    };
    var setContentTree = function (editor, body, content, args) {
      filter$2(editor.parser.getNodeFilters(), editor.parser.getAttributeFilters(), content);
      var html = Serializer({ validate: editor.validate }, editor.schema).serialize(content);
      args.content = isWsPreserveElement(Element.fromDom(body)) ? html : Tools.trim(html);
      setEditorHtml(editor, args.content);
      if (!args.no_events) {
        editor.fire('SetContent', args);
      }
      return content;
    };
    var setContent = function (editor, content, args) {
      if (args === void 0) {
        args = {};
      }
      args.format = args.format ? args.format : defaultFormat$1;
      args.set = true;
      args.content = isTreeNode(content) ? '' : content;
      if (!isTreeNode(content) && !args.no_events) {
        editor.fire('BeforeSetContent', args);
        content = args.content;
      }
      return Option.from(editor.getBody()).fold(constant(content), function (body) {
        return isTreeNode(content) ? setContentTree(editor, body, content, args) : setContentString(editor, body, content, args);
      });
    };

    var firePreProcess = function (editor, args) {
      return editor.fire('PreProcess', args);
    };
    var firePostProcess = function (editor, args) {
      return editor.fire('PostProcess', args);
    };
    var fireRemove = function (editor) {
      return editor.fire('remove');
    };
    var fireDetach = function (editor) {
      return editor.fire('detach');
    };
    var fireSwitchMode = function (editor, mode) {
      return editor.fire('SwitchMode', { mode: mode });
    };
    var fireObjectResizeStart = function (editor, target, width, height) {
      editor.fire('ObjectResizeStart', {
        target: target,
        width: width,
        height: height
      });
    };
    var fireObjectResized = function (editor, target, width, height) {
      editor.fire('ObjectResized', {
        target: target,
        width: width,
        height: height
      });
    };
    var firePreInit = function (editor) {
      return editor.fire('PreInit');
    };
    var firePostRender = function (editor) {
      return editor.fire('PostRender');
    };
    var fireInit = function (editor) {
      return editor.fire('Init');
    };
    var firePlaceholderToggle = function (editor, state) {
      return editor.fire('PlaceholderToggle', { state: state });
    };
    var fireError = function (editor, errorType, error) {
      return editor.fire(errorType, error);
    };

    var DOM$3 = DOMUtils$1.DOM;
    var restoreOriginalStyles = function (editor) {
      DOM$3.setStyle(editor.id, 'display', editor.orgDisplay);
    };
    var safeDestroy = function (x) {
      return Option.from(x).each(function (x) {
        return x.destroy();
      });
    };
    var clearDomReferences = function (editor) {
      editor.contentAreaContainer = editor.formElement = editor.container = editor.editorContainer = null;
      editor.bodyElement = editor.contentDocument = editor.contentWindow = null;
      editor.iframeElement = editor.targetElm = null;
      if (editor.selection) {
        editor.selection = editor.selection.win = editor.selection.dom = editor.selection.dom.doc = null;
      }
    };
    var restoreForm = function (editor) {
      var form = editor.formElement;
      if (form) {
        if (form._mceOldSubmit) {
          form.submit = form._mceOldSubmit;
          form._mceOldSubmit = null;
        }
        DOM$3.unbind(form, 'submit reset', editor.formEventDelegate);
      }
    };
    var remove$6 = function (editor) {
      if (!editor.removed) {
        var _selectionOverrides = editor._selectionOverrides, editorUpload = editor.editorUpload;
        var body = editor.getBody();
        var element = editor.getElement();
        if (body) {
          editor.save({ is_removing: true });
        }
        editor.removed = true;
        editor.unbindAllNativeEvents();
        if (editor.hasHiddenInput && element) {
          DOM$3.remove(element.nextSibling);
        }
        fireRemove(editor);
        editor.editorManager.remove(editor);
        if (!editor.inline && body) {
          restoreOriginalStyles(editor);
        }
        fireDetach(editor);
        DOM$3.remove(editor.getContainer());
        safeDestroy(_selectionOverrides);
        safeDestroy(editorUpload);
        editor.destroy();
      }
    };
    var destroy = function (editor, automatic) {
      var selection = editor.selection, dom = editor.dom;
      if (editor.destroyed) {
        return;
      }
      if (!automatic && !editor.removed) {
        editor.remove();
        return;
      }
      if (!automatic) {
        editor.editorManager.off('beforeunload', editor._beforeUnload);
        if (editor.theme && editor.theme.destroy) {
          editor.theme.destroy();
        }
        safeDestroy(selection);
        safeDestroy(dom);
      }
      restoreForm(editor);
      clearDomReferences(editor);
      editor.destroyed = true;
    };

    var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
    var deep$1 = function (old, nu) {
      var bothObjects = isObject(old) && isObject(nu);
      return bothObjects ? deepMerge(old, nu) : nu;
    };
    var baseMerge = function (merger) {
      return function () {
        var objects = new Array(arguments.length);
        for (var i = 0; i < objects.length; i++) {
          objects[i] = arguments[i];
        }
        if (objects.length === 0) {
          throw new Error('Can\'t merge zero objects');
        }
        var ret = {};
        for (var j = 0; j < objects.length; j++) {
          var curObject = objects[j];
          for (var key in curObject) {
            if (hasOwnProperty$2.call(curObject, key)) {
              ret[key] = merger(ret[key], curObject[key]);
            }
          }
        }
        return ret;
      };
    };
    var deepMerge = baseMerge(deep$1);

    var sectionResult = Immutable('sections', 'settings');
    var deviceDetection = detect$3().deviceType;
    var isTouch = deviceDetection.isTouch();
    var isPhone = deviceDetection.isPhone();
    var isTablet = deviceDetection.isTablet();
    var legacyMobilePlugins = [
      'lists',
      'autolink',
      'autosave'
    ];
    var defaultTouchSettings = {
      table_grid: false,
      object_resizing: false,
      resize: false
    };
    var normalizePlugins = function (plugins) {
      var pluginNames = isArray(plugins) ? plugins.join(' ') : plugins;
      var trimmedPlugins = map(isString(pluginNames) ? pluginNames.split(' ') : [], trim);
      return filter(trimmedPlugins, function (item) {
        return item.length > 0;
      });
    };
    var filterLegacyMobilePlugins = function (plugins) {
      return filter(plugins, curry(contains, legacyMobilePlugins));
    };
    var extractSections = function (keys, settings) {
      var result = bifilter(settings, function (value, key) {
        return contains(keys, key);
      });
      return sectionResult(result.t, result.f);
    };
    var getSection = function (sectionResult, name, defaults) {
      if (defaults === void 0) {
        defaults = {};
      }
      var sections = sectionResult.sections();
      var sectionSettings = sections.hasOwnProperty(name) ? sections[name] : {};
      return Tools.extend({}, defaults, sectionSettings);
    };
    var hasSection = function (sectionResult, name) {
      return sectionResult.sections().hasOwnProperty(name);
    };
    var isSectionTheme = function (sectionResult, name, theme) {
      var section = sectionResult.sections();
      return hasSection(sectionResult, name) && section[name].theme === theme;
    };
    var getSectionConfig = function (sectionResult, name) {
      return hasSection(sectionResult, name) ? sectionResult.sections()[name] : {};
    };
    var getToolbarMode = function (settings, defaultVal) {
      return get(settings, 'toolbar_mode').orThunk(function () {
        return get(settings, 'toolbar_drawer').map(function (val) {
          return val === false ? 'wrap' : val;
        });
      }).getOr(defaultVal);
    };
    var getDefaultSettings = function (settings, id, documentBaseUrl, isTouch, editor) {
      var baseDefaults = {
        id: id,
        theme: 'silver',
        toolbar_mode: getToolbarMode(settings, 'floating'),
        plugins: '',
        document_base_url: documentBaseUrl,
        add_form_submit_trigger: true,
        submit_patch: true,
        add_unload_trigger: true,
        convert_urls: true,
        relative_urls: true,
        remove_script_host: true,
        object_resizing: true,
        doctype: '<!DOCTYPE html>',
        visual: true,
        font_size_legacy_values: 'xx-small,small,medium,large,x-large,xx-large,300%',
        forced_root_block: 'p',
        hidden_input: true,
        inline_styles: true,
        convert_fonts_to_spans: true,
        indent: true,
        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,figure,figcaption,option,optgroup,datalist',
        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',
        entity_encoding: 'named',
        url_converter: editor.convertURL,
        url_converter_scope: editor
      };
      return __assign(__assign({}, baseDefaults), isTouch ? defaultTouchSettings : {});
    };
    var getDefaultMobileSettings = function (settings, isPhone) {
      var defaultMobileSettings = {
        resize: false,
        toolbar_mode: getToolbarMode(settings, 'scrolling'),
        toolbar_sticky: false
      };
      var defaultPhoneSettings = { menubar: false };
      return __assign(__assign(__assign({}, defaultTouchSettings), defaultMobileSettings), isPhone ? defaultPhoneSettings : {});
    };
    var getExternalPlugins = function (overrideSettings, settings) {
      var userDefinedExternalPlugins = settings.external_plugins ? settings.external_plugins : {};
      if (overrideSettings && overrideSettings.external_plugins) {
        return Tools.extend({}, overrideSettings.external_plugins, userDefinedExternalPlugins);
      } else {
        return userDefinedExternalPlugins;
      }
    };
    var combinePlugins = function (forcedPlugins, plugins) {
      return [].concat(normalizePlugins(forcedPlugins)).concat(normalizePlugins(plugins));
    };
    var processPlugins = function (isMobileDevice, sectionResult, defaultOverrideSettings, settings) {
      var forcedPlugins = normalizePlugins(defaultOverrideSettings.forced_plugins);
      var desktopPlugins = normalizePlugins(settings.plugins);
      var mobileConfig = getSectionConfig(sectionResult, 'mobile');
      var mobilePlugins = mobileConfig.plugins ? normalizePlugins(mobileConfig.plugins) : desktopPlugins;
      var platformPlugins = isMobileDevice && isSectionTheme(sectionResult, 'mobile', 'mobile') ? filterLegacyMobilePlugins(mobilePlugins) : isMobileDevice && hasSection(sectionResult, 'mobile') ? mobilePlugins : desktopPlugins;
      var combinedPlugins = combinePlugins(forcedPlugins, platformPlugins);
      return Tools.extend(settings, { plugins: combinedPlugins.join(' ') });
    };
    var isOnMobile = function (isMobileDevice, sectionResult) {
      return isMobileDevice && hasSection(sectionResult, 'mobile');
    };
    var combineSettings = function (isMobileDevice, isPhone, defaultSettings, defaultOverrideSettings, settings) {
      var defaultDeviceSettings = isMobileDevice ? { mobile: getDefaultMobileSettings(settings, isPhone) } : {};
      var sectionResult = extractSections(['mobile'], deepMerge(defaultDeviceSettings, settings));
      var extendedSettings = Tools.extend(defaultSettings, defaultOverrideSettings, sectionResult.settings(), isOnMobile(isMobileDevice, sectionResult) ? getSection(sectionResult, 'mobile') : {}, {
        validate: true,
        external_plugins: getExternalPlugins(defaultOverrideSettings, sectionResult.settings())
      });
      return processPlugins(isMobileDevice, sectionResult, defaultOverrideSettings, extendedSettings);
    };
    var getEditorSettings = function (editor, id, documentBaseUrl, defaultOverrideSettings, settings) {
      var defaultSettings = getDefaultSettings(settings, id, documentBaseUrl, isTouch, editor);
      return combineSettings(isPhone || isTablet, isPhone, defaultSettings, defaultOverrideSettings, settings);
    };
    var getFiltered = function (predicate, editor, name) {
      return Option.from(editor.settings[name]).filter(predicate);
    };
    var getParamObject = function (value) {
      var output = {};
      if (typeof value === 'string') {
        each(value.indexOf('=') > 0 ? value.split(/[;,](?![^=;,]*(?:[;,]|$))/) : value.split(','), function (val) {
          var arr = val.split('=');
          if (arr.length > 1) {
            output[Tools.trim(arr[0])] = Tools.trim(arr[1]);
          } else {
            output[Tools.trim(arr[0])] = Tools.trim(arr[0]);
          }
        });
      } else {
        output = value;
      }
      return output;
    };
    var isArrayOf = function (p) {
      return function (a) {
        return isArray(a) && forall(a, p);
      };
    };
    var getParam = function (editor, name, defaultVal, type) {
      var value = name in editor.settings ? editor.settings[name] : defaultVal;
      if (type === 'hash') {
        return getParamObject(value);
      } else if (type === 'string') {
        return getFiltered(isString, editor, name).getOr(defaultVal);
      } else if (type === 'number') {
        return getFiltered(isNumber, editor, name).getOr(defaultVal);
      } else if (type === 'boolean') {
        return getFiltered(isBoolean, editor, name).getOr(defaultVal);
      } else if (type === 'object') {
        return getFiltered(isObject, editor, name).getOr(defaultVal);
      } else if (type === 'array') {
        return getFiltered(isArray, editor, name).getOr(defaultVal);
      } else if (type === 'string[]') {
        return getFiltered(isArrayOf(isString), editor, name).getOr(defaultVal);
      } else if (type === 'function') {
        return getFiltered(isFunction, editor, name).getOr(defaultVal);
      } else {
        return value;
      }
    };

    var CreateIconManager = function () {
      var lookup = {};
      var add = function (id, iconPack) {
        lookup[id] = iconPack;
      };
      var get = function (id) {
        if (lookup[id]) {
          return lookup[id];
        }
        return { icons: {} };
      };
      var has$1 = function (id) {
        return has(lookup, id);
      };
      return {
        add: add,
        get: get,
        has: has$1
      };
    };
    var IconManager = CreateIconManager();

    var getProp = function (propName, elm) {
      var rawElm = elm.dom();
      return rawElm[propName];
    };
    var getComputedSizeProp = function (propName, elm) {
      return parseInt(get$4(elm, propName), 10);
    };
    var getClientWidth = curry(getProp, 'clientWidth');
    var getClientHeight = curry(getProp, 'clientHeight');
    var getMarginTop = curry(getComputedSizeProp, 'margin-top');
    var getMarginLeft = curry(getComputedSizeProp, 'margin-left');
    var getBoundingClientRect$1 = function (elm) {
      return elm.dom().getBoundingClientRect();
    };
    var isInsideElementContentArea = function (bodyElm, clientX, clientY) {
      var clientWidth = getClientWidth(bodyElm);
      var clientHeight = getClientHeight(bodyElm);
      return clientX >= 0 && clientY >= 0 && clientX <= clientWidth && clientY <= clientHeight;
    };
    var transpose = function (inline, elm, clientX, clientY) {
      var clientRect = getBoundingClientRect$1(elm);
      var deltaX = inline ? clientRect.left + elm.dom().clientLeft + getMarginLeft(elm) : 0;
      var deltaY = inline ? clientRect.top + elm.dom().clientTop + getMarginTop(elm) : 0;
      var x = clientX - deltaX;
      var y = clientY - deltaY;
      return {
        x: x,
        y: y
      };
    };
    var isXYInContentArea = function (editor, clientX, clientY) {
      var bodyElm = Element.fromDom(editor.getBody());
      var targetElm = editor.inline ? bodyElm : documentElement(bodyElm);
      var transposedPoint = transpose(editor.inline, targetElm, clientX, clientY);
      return isInsideElementContentArea(targetElm, transposedPoint.x, transposedPoint.y);
    };
    var fromDomSafe = function (node) {
      return Option.from(node).map(Element.fromDom);
    };
    var isEditorAttachedToDom = function (editor) {
      var rawContainer = editor.inline ? editor.getBody() : editor.getContentAreaContainer();
      return fromDomSafe(rawContainer).map(function (container) {
        return contains$2(owner(container), container);
      }).getOr(false);
    };
    var EditorView = {
      isXYInContentArea: isXYInContentArea,
      isEditorAttachedToDom: isEditorAttachedToDom
    };

    function NotificationManagerImpl() {
      var unimplemented = function () {
        throw new Error('Theme did not provide a NotificationManager implementation.');
      };
      return {
        open: unimplemented,
        close: unimplemented,
        reposition: unimplemented,
        getArgs: unimplemented
      };
    }

    function NotificationManager(editor) {
      var notifications = [];
      var getImplementation = function () {
        var theme = editor.theme;
        return theme && theme.getNotificationManagerImpl ? theme.getNotificationManagerImpl() : NotificationManagerImpl();
      };
      var getTopNotification = function () {
        return Option.from(notifications[0]);
      };
      var isEqual = function (a, b) {
        return a.type === b.type && a.text === b.text && !a.progressBar && !a.timeout && !b.progressBar && !b.timeout;
      };
      var reposition = function () {
        if (notifications.length > 0) {
          getImplementation().reposition(notifications);
        }
      };
      var addNotification = function (notification) {
        notifications.push(notification);
      };
      var closeNotification = function (notification) {
        findIndex(notifications, function (otherNotification) {
          return otherNotification === notification;
        }).each(function (index) {
          notifications.splice(index, 1);
        });
      };
      var open = function (spec) {
        if (editor.removed || !EditorView.isEditorAttachedToDom(editor)) {
          return;
        }
        return find(notifications, function (notification) {
          return isEqual(getImplementation().getArgs(notification), spec);
        }).getOrThunk(function () {
          editor.editorManager.setActive(editor);
          var notification = getImplementation().open(spec, function () {
            closeNotification(notification);
            reposition();
          });
          addNotification(notification);
          reposition();
          return notification;
        });
      };
      var close = function () {
        getTopNotification().each(function (notification) {
          getImplementation().close(notification);
          closeNotification(notification);
          reposition();
        });
      };
      var getNotifications = function () {
        return notifications;
      };
      var registerEvents = function (editor) {
        editor.on('SkinLoaded', function () {
          var serviceMessage = editor.settings.service_message;
          if (serviceMessage) {
            open({
              text: serviceMessage,
              type: 'warning',
              timeout: 0
            });
          }
        });
        editor.on('ResizeEditor ResizeWindow NodeChange', function () {
          Delay.requestAnimationFrame(reposition);
        });
        editor.on('remove', function () {
          each(notifications.slice(), function (notification) {
            getImplementation().close(notification);
          });
        });
      };
      registerEvents(editor);
      return {
        open: open,
        close: close,
        getNotifications: getNotifications
      };
    }

    var PluginManager = AddOnManager$1.PluginManager;

    var ThemeManager = AddOnManager$1.ThemeManager;

    function WindowManagerImpl () {
      var unimplemented = function () {
        throw new Error('Theme did not provide a WindowManager implementation.');
      };
      return {
        open: unimplemented,
        openUrl: unimplemented,
        alert: unimplemented,
        confirm: unimplemented,
        close: unimplemented,
        getParams: unimplemented,
        setParams: unimplemented
      };
    }

    var WindowManager = function (editor) {
      var dialogs = [];
      var getImplementation = function () {
        var theme = editor.theme;
        return theme && theme.getWindowManagerImpl ? theme.getWindowManagerImpl() : WindowManagerImpl();
      };
      var funcBind = function (scope, f) {
        return function () {
          return f ? f.apply(scope, arguments) : undefined;
        };
      };
      var fireOpenEvent = function (dialog) {
        editor.fire('OpenWindow', { dialog: dialog });
      };
      var fireCloseEvent = function (dialog) {
        editor.fire('CloseWindow', { dialog: dialog });
      };
      var addDialog = function (dialog) {
        dialogs.push(dialog);
        fireOpenEvent(dialog);
      };
      var closeDialog = function (dialog) {
        fireCloseEvent(dialog);
        dialogs = filter(dialogs, function (otherDialog) {
          return otherDialog !== dialog;
        });
        if (dialogs.length === 0) {
          editor.focus();
        }
      };
      var getTopDialog = function () {
        return Option.from(dialogs[dialogs.length - 1]);
      };
      var storeSelectionAndOpenDialog = function (openDialog) {
        editor.editorManager.setActive(editor);
        SelectionBookmark.store(editor);
        var dialog = openDialog();
        addDialog(dialog);
        return dialog;
      };
      var open = function (args, params) {
        return storeSelectionAndOpenDialog(function () {
          return getImplementation().open(args, params, closeDialog);
        });
      };
      var openUrl = function (args) {
        return storeSelectionAndOpenDialog(function () {
          return getImplementation().openUrl(args, closeDialog);
        });
      };
      var alert = function (message, callback, scope) {
        getImplementation().alert(message, funcBind(scope ? scope : this, callback));
      };
      var confirm = function (message, callback, scope) {
        getImplementation().confirm(message, funcBind(scope ? scope : this, callback));
      };
      var close = function () {
        getTopDialog().each(function (dialog) {
          getImplementation().close(dialog);
          closeDialog(dialog);
        });
      };
      editor.on('remove', function () {
        each(dialogs, function (dialog) {
          getImplementation().close(dialog);
        });
      });
      return {
        open: open,
        openUrl: openUrl,
        alert: alert,
        confirm: confirm,
        close: close
      };
    };

    var displayNotification = function (editor, message) {
      editor.notificationManager.open({
        type: 'error',
        text: message
      });
    };
    var displayError = function (editor, message) {
      if (editor._skinLoaded) {
        displayNotification(editor, message);
      } else {
        editor.on('SkinLoaded', function () {
          displayNotification(editor, message);
        });
      }
    };
    var uploadError = function (editor, message) {
      displayError(editor, I18n.translate([
        'Failed to upload image: {0}',
        message
      ]));
    };
    var logError = function (editor, errorType, msg) {
      fireError(editor, errorType, { message: msg });
      domGlobals.console.error(msg);
    };
    var createLoadError = function (type, url, name) {
      return name ? 'Failed to load ' + type + ': ' + name + ' from url ' + url : 'Failed to load ' + type + ' url: ' + url;
    };
    var pluginLoadError = function (editor, url, name) {
      logError(editor, 'PluginLoadError', createLoadError('plugin', url, name));
    };
    var iconsLoadError = function (editor, url, name) {
      logError(editor, 'IconsLoadError', createLoadError('icons', url, name));
    };
    var languageLoadError = function (editor, url, name) {
      logError(editor, 'LanguageLoadError', createLoadError('language', url, name));
    };
    var pluginInitError = function (editor, name, err) {
      var message = I18n.translate([
        'Failed to initialize plugin: {0}',
        name
      ]);
      initError(message, err);
      displayError(editor, message);
    };
    var initError = function (message) {
      var x = [];
      for (var _i = 1; _i < arguments.length; _i++) {
        x[_i - 1] = arguments[_i];
      }
      var console = domGlobals.window.console;
      if (console) {
        if (console.error) {
          console.error.apply(console, arguments);
        } else {
          console.log.apply(console, arguments);
        }
      }
    };
    var ErrorReporter = {
      pluginLoadError: pluginLoadError,
      iconsLoadError: iconsLoadError,
      languageLoadError: languageLoadError,
      pluginInitError: pluginInitError,
      uploadError: uploadError,
      displayError: displayError,
      initError: initError
    };

    var getAll = function () {
      return {
        'accessibility-check': '<svg width="24" height="24"><path d="M12 2a2 2 0 0 1 2 2 2 2 0 0 1-2 2 2 2 0 0 1-2-2c0-1.1.9-2 2-2zm8 7h-5v12c0 .6-.4 1-1 1a1 1 0 0 1-1-1v-5c0-.6-.4-1-1-1a1 1 0 0 0-1 1v5c0 .6-.4 1-1 1a1 1 0 0 1-1-1V9H4a1 1 0 1 1 0-2h16c.6 0 1 .4 1 1s-.4 1-1 1z" fill-rule="nonzero"/></svg>',
        'action-next': '<svg width="24" height="24"><path fill-rule="nonzero" d="M5.7 7.3a1 1 0 0 0-1.4 1.4l7.7 7.7 7.7-7.7a1 1 0 1 0-1.4-1.4L12 13.6 5.7 7.3z"/></svg>',
        'action-prev': '<svg width="24" height="24"><path fill-rule="nonzero" d="M18.3 15.7a1 1 0 0 0 1.4-1.4L12 6.6l-7.7 7.7a1 1 0 0 0 1.4 1.4L12 9.4l6.3 6.3z"/></svg>',
        'align-center': '<svg width="24" height="24"><path d="M5 5h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm3 4h8c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 1 1 0-2zm0 8h8c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 0 1 0-2zm-3-4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2z" fill-rule="evenodd"/></svg>',
        'align-justify': '<svg width="24" height="24"><path d="M5 5h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm0 4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm0 4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2zm0 4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2z" fill-rule="evenodd"/></svg>',
        'align-left': '<svg width="24" height="24"><path d="M5 5h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm0 4h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm0 8h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2zm0-4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2z" fill-rule="evenodd"/></svg>',
        'align-none': '<svg width="24" height="24"><path d="M14.2 5L13 7H5a1 1 0 1 1 0-2h9.2zm4 0h.8a1 1 0 0 1 0 2h-2l1.2-2zm-6.4 4l-1.2 2H5a1 1 0 0 1 0-2h6.8zm4 0H19a1 1 0 0 1 0 2h-4.4l1.2-2zm-6.4 4l-1.2 2H5a1 1 0 0 1 0-2h4.4zm4 0H19a1 1 0 0 1 0 2h-6.8l1.2-2zM7 17l-1.2 2H5a1 1 0 0 1 0-2h2zm4 0h8a1 1 0 0 1 0 2H9.8l1.2-2zm5.2-13.5l1.3.7-9.7 16.3-1.3-.7 9.7-16.3z" fill-rule="evenodd"/></svg>',
        'align-right': '<svg width="24" height="24"><path d="M5 5h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm6 4h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0 8h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm-6-4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2z" fill-rule="evenodd"/></svg>',
        'arrow-left': '<svg width="24" height="24"><path d="M5.6 13l12 6a1 1 0 0 0 1.4-1V6a1 1 0 0 0-1.4-.9l-12 6a1 1 0 0 0 0 1.8z" fill-rule="evenodd"/></svg>',
        'arrow-right': '<svg width="24" height="24"><path d="M18.5 13l-12 6A1 1 0 0 1 5 18V6a1 1 0 0 1 1.4-.9l12 6a1 1 0 0 1 0 1.8z" fill-rule="evenodd"/></svg>',
        'bold': '<svg width="24" height="24"><path d="M7.8 19c-.3 0-.5 0-.6-.2l-.2-.5V5.7c0-.2 0-.4.2-.5l.6-.2h5c1.5 0 2.7.3 3.5 1 .7.6 1.1 1.4 1.1 2.5a3 3 0 0 1-.6 1.9c-.4.6-1 1-1.6 1.2.4.1.9.3 1.3.6s.8.7 1 1.2c.4.4.5 1 .5 1.6 0 1.3-.4 2.3-1.3 3-.8.7-2.1 1-3.8 1H7.8zm5-8.3c.6 0 1.2-.1 1.6-.5.4-.3.6-.7.6-1.3 0-1.1-.8-1.7-2.3-1.7H9.3v3.5h3.4zm.5 6c.7 0 1.3-.1 1.7-.4.4-.4.6-.9.6-1.5s-.2-1-.7-1.4c-.4-.3-1-.4-2-.4H9.4v3.8h4z" fill-rule="evenodd"/></svg>',
        'bookmark': '<svg width="24" height="24"><path d="M6 4v17l6-4 6 4V4c0-.6-.4-1-1-1H7a1 1 0 0 0-1 1z" fill-rule="nonzero"/></svg>',
        'border-width': '<svg width="24" height="24"><path d="M5 14.8h14a1 1 0 0 1 0 2H5a1 1 0 0 1 0-2zm-.5 3.7h15c.3 0 .5.2.5.5s-.2.5-.5.5h-15a.5.5 0 1 1 0-1zm.5-8.3h14c.6 0 1 .4 1 1v1c0 .5-.4 1-1 1H5a1 1 0 0 1-1-1v-1c0-.6.4-1 1-1zm0-5.7h14c.6 0 1 .4 1 1v2c0 .6-.4 1-1 1H5a1 1 0 0 1-1-1v-2c0-.6.4-1 1-1z" fill-rule="evenodd"/></svg>',
        'brightness': '<svg width="24" height="24"><path d="M12 17c.3 0 .5.1.7.3.2.2.3.4.3.7v1c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3 1 1 0 0 1-.7-.3 1 1 0 0 1-.3-.7v-1c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3zm0-10a1 1 0 0 1-.7-.3A1 1 0 0 1 11 6V5c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3.3 0 .5.1.7.3.2.2.3.4.3.7v1c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3zm7 4c.3 0 .5.1.7.3.2.2.3.4.3.7 0 .3-.1.5-.3.7a1 1 0 0 1-.7.3h-1a1 1 0 0 1-.7-.3 1 1 0 0 1-.3-.7c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h1zM7 12c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3H5a1 1 0 0 1-.7-.3A1 1 0 0 1 4 12c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h1c.3 0 .5.1.7.3.2.2.3.4.3.7zm10 3.5l.7.8c.2.1.3.4.3.6 0 .3-.1.6-.3.8a1 1 0 0 1-.8.3 1 1 0 0 1-.6-.3l-.8-.7a1 1 0 0 1-.3-.8c0-.2.1-.5.3-.7a1 1 0 0 1 1.4 0zm-10-7l-.7-.8a1 1 0 0 1-.3-.6c0-.3.1-.6.3-.8.2-.2.5-.3.8-.3.2 0 .5.1.7.3l.7.7c.2.2.3.5.3.8 0 .2-.1.5-.3.7a1 1 0 0 1-.7.3 1 1 0 0 1-.8-.3zm10 0a1 1 0 0 1-.8.3 1 1 0 0 1-.7-.3 1 1 0 0 1-.3-.7c0-.3.1-.6.3-.8l.8-.7c.1-.2.4-.3.6-.3.3 0 .6.1.8.3.2.2.3.5.3.8 0 .2-.1.5-.3.7l-.7.7zm-10 7c.2-.2.5-.3.8-.3.2 0 .5.1.7.3a1 1 0 0 1 0 1.4l-.8.8a1 1 0 0 1-.6.3 1 1 0 0 1-.8-.3 1 1 0 0 1-.3-.8c0-.2.1-.5.3-.6l.7-.8zM12 8a4 4 0 0 1 3.7 2.4 4 4 0 0 1 0 3.2A4 4 0 0 1 12 16a4 4 0 0 1-3.7-2.4 4 4 0 0 1 0-3.2A4 4 0 0 1 12 8zm0 6.5c.7 0 1.3-.2 1.8-.7.5-.5.7-1.1.7-1.8s-.2-1.3-.7-1.8c-.5-.5-1.1-.7-1.8-.7s-1.3.2-1.8.7c-.5.5-.7 1.1-.7 1.8s.2 1.3.7 1.8c.5.5 1.1.7 1.8.7z" fill-rule="evenodd"/></svg>',
        'browse': '<svg width="24" height="24"><path d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-4v-2h4V8H5v10h4v2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14zm-8 9.4l-2.3 2.3a1 1 0 1 1-1.4-1.4l4-4a1 1 0 0 1 1.4 0l4 4a1 1 0 0 1-1.4 1.4L13 13.4V20a1 1 0 0 1-2 0v-6.6z" fill-rule="nonzero"/></svg>',
        'cancel': '<svg width="24" height="24"><path d="M12 4.6a7.4 7.4 0 1 1 0 14.8 7.4 7.4 0 0 1 0-14.8zM12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18zm0 8L14.8 8l1 1.1-2.7 2.8 2.7 2.7-1.1 1.1-2.7-2.7-2.7 2.7-1-1.1 2.6-2.7-2.7-2.7 1-1.1 2.8 2.7z" fill-rule="nonzero"/></svg>',
        'change-case': '<svg width="24" height="24"><path d="M18.4 18.2v-.6c-.5.8-1.3 1.2-2.4 1.2-2.2 0-3.3-1.6-3.3-4.8 0-3.1 1-4.7 3.3-4.7 1.1 0 1.8.3 2.4 1.1v-.6c0-.5.4-.8.8-.8s.8.3.8.8v8.4c0 .5-.4.8-.8.8a.8.8 0 0 1-.8-.8zm-2-7.4c-1.3 0-1.8.9-1.8 3.2 0 2.4.5 3.3 1.7 3.3 1.3 0 1.8-.9 1.8-3.2 0-2.4-.5-3.3-1.7-3.3zM10 15.7H5.5l-.8 2.6a1 1 0 0 1-1 .7h-.2a.7.7 0 0 1-.7-1l4-12a1 1 0 1 1 2 0l4 12a.7.7 0 0 1-.8 1h-.2a1 1 0 0 1-1-.7l-.8-2.6zm-.3-1.5l-2-6.5-1.9 6.5h3.9z" fill-rule="evenodd"/></svg>',
        'character-count': '<svg width="24" height="24"><path d="M4 11.5h16v1H4v-1zm4.8-6.8V10H7.7V5.8h-1v-1h2zM11 8.3V9h2v1h-3V7.7l2-1v-.9h-2v-1h3v2.4l-2 1zm6.3-3.4V10h-3.1V9h2.1V8h-2.1V6.8h2.1v-1h-2.1v-1h3.1zM5.8 16.4c0-.5.2-.8.5-1 .2-.2.6-.3 1.2-.3l.8.1c.2 0 .4.2.5.3l.4.4v2.8l.2.3H8.2v-.1-.2l-.6.3H7c-.4 0-.7 0-1-.2a1 1 0 0 1-.3-.9c0-.3 0-.6.3-.8.3-.2.7-.4 1.2-.4l.6-.2h.3v-.2l-.1-.2a.8.8 0 0 0-.5-.1 1 1 0 0 0-.4 0l-.3.4h-1zm2.3.8h-.2l-.2.1-.4.1a1 1 0 0 0-.4.2l-.2.2.1.3.5.1h.4l.4-.4v-.6zm2-3.4h1.2v1.7l.5-.3h.5c.5 0 .9.1 1.2.5.3.4.5.8.5 1.4 0 .6-.2 1.1-.5 1.5-.3.4-.7.6-1.3.6l-.6-.1-.4-.4v.4h-1.1v-5.4zm1.1 3.3c0 .3 0 .6.2.8a.7.7 0 0 0 1.2 0l.2-.8c0-.4 0-.6-.2-.8a.7.7 0 0 0-.6-.3l-.6.3-.2.8zm6.1-.5c0-.2 0-.3-.2-.4a.8.8 0 0 0-.5-.2c-.3 0-.5.1-.6.3l-.2.9c0 .3 0 .6.2.8.1.2.3.3.6.3.2 0 .4 0 .5-.2l.2-.4h1.1c0 .5-.3.8-.6 1.1a2 2 0 0 1-1.3.4c-.5 0-1-.2-1.3-.6a2 2 0 0 1-.5-1.4c0-.6.1-1.1.5-1.5.3-.4.8-.5 1.4-.5.5 0 1 0 1.2.3.4.3.5.7.5 1.2h-1v-.1z" fill-rule="evenodd"/></svg>',
        'checklist-rtl': '<svg width="24" height="24"><path d="M5 17h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm14.2 11c.2-.4.6-.5.9-.3.3.2.4.6.2 1L18 20c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8zm0-6c.2-.4.6-.5.9-.3.3.2.4.6.2 1L18 14c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8zm0-6c.2-.4.6-.5.9-.3.3.2.4.6.2 1L18 8c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8z" fill-rule="evenodd"/></svg>',
        'checklist': '<svg width="24" height="24"><path d="M11 17h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0-6h8a1 1 0 0 1 0 2h-8a1 1 0 0 1 0-2zM7.2 16c.2-.4.6-.5.9-.3.3.2.4.6.2 1L6 20c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8zm0-6c.2-.4.6-.5.9-.3.3.2.4.6.2 1L6 14c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8zm0-6c.2-.4.6-.5.9-.3.3.2.4.6.2 1L6 8c-.2.3-.7.4-1 0L3.8 6.9a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8z" fill-rule="evenodd"/></svg>',
        'checkmark': '<svg width="24" height="24"><path d="M18.2 5.4a1 1 0 0 1 1.6 1.2l-8 12a1 1 0 0 1-1.5.1l-5-5a1 1 0 1 1 1.4-1.4l4.1 4.1 7.4-11z" fill-rule="nonzero"/></svg>',
        'chevron-down': '<svg width="10" height="10"><path d="M8.7 2.2c.3-.3.8-.3 1 0 .4.4.4.9 0 1.2L5.7 7.8c-.3.3-.9.3-1.2 0L.2 3.4a.8.8 0 0 1 0-1.2c.3-.3.8-.3 1.1 0L5 6l3.7-3.8z" fill-rule="nonzero"/></svg>',
        'chevron-left': '<svg width="10" height="10"><path d="M7.8 1.3L4 5l3.8 3.7c.3.3.3.8 0 1-.4.4-.9.4-1.2 0L2.2 5.7a.8.8 0 0 1 0-1.2L6.6.2C7 0 7.4 0 7.8.2c.3.3.3.8 0 1.1z" fill-rule="nonzero"/></svg>',
        'chevron-right': '<svg width="10" height="10"><path d="M2.2 1.3a.8.8 0 0 1 0-1c.4-.4.9-.4 1.2 0l4.4 4.1c.3.4.3.9 0 1.2L3.4 9.8c-.3.3-.8.3-1.2 0a.8.8 0 0 1 0-1.1L6 5 2.2 1.3z" fill-rule="nonzero"/></svg>',
        'chevron-up': '<svg width="10" height="10"><path d="M8.7 7.8L5 4 1.3 7.8c-.3.3-.8.3-1 0a.8.8 0 0 1 0-1.2l4.1-4.4c.3-.3.9-.3 1.2 0l4.2 4.4c.3.3.3.9 0 1.2-.3.3-.8.3-1.1 0z" fill-rule="nonzero"/></svg>',
        'close': '<svg width="24" height="24"><path d="M17.3 8.2L13.4 12l3.9 3.8a1 1 0 0 1-1.5 1.5L12 13.4l-3.8 3.9a1 1 0 0 1-1.5-1.5l3.9-3.8-3.9-3.8a1 1 0 0 1 1.5-1.5l3.8 3.9 3.8-3.9a1 1 0 0 1 1.5 1.5z" fill-rule="evenodd"/></svg>',
        'code-sample': '<svg width="24" height="26"><path d="M7.1 11a2.8 2.8 0 0 1-.8 2 2.8 2.8 0 0 1 .8 2v1.7c0 .3.1.6.4.8.2.3.5.4.8.4.3 0 .4.2.4.4v.8c0 .2-.1.4-.4.4-.7 0-1.4-.3-2-.8-.5-.6-.8-1.3-.8-2V15c0-.3-.1-.6-.4-.8-.2-.3-.5-.4-.8-.4a.4.4 0 0 1-.4-.4v-.8c0-.2.2-.4.4-.4.3 0 .6-.1.8-.4.3-.2.4-.5.4-.8V9.3c0-.7.3-1.4.8-2 .6-.5 1.3-.8 2-.8.3 0 .4.2.4.4v.8c0 .2-.1.4-.4.4-.3 0-.6.1-.8.4-.3.2-.4.5-.4.8V11zm9.8 0V9.3c0-.3-.1-.6-.4-.8-.2-.3-.5-.4-.8-.4a.4.4 0 0 1-.4-.4V7c0-.2.1-.4.4-.4.7 0 1.4.3 2 .8.5.6.8 1.3.8 2V11c0 .3.1.6.4.8.2.3.5.4.8.4.2 0 .4.2.4.4v.8c0 .2-.2.4-.4.4-.3 0-.6.1-.8.4-.3.2-.4.5-.4.8v1.7c0 .7-.3 1.4-.8 2-.6.5-1.3.8-2 .8a.4.4 0 0 1-.4-.4v-.8c0-.2.1-.4.4-.4.3 0 .6-.1.8-.4.3-.2.4-.5.4-.8V15a2.8 2.8 0 0 1 .8-2 2.8 2.8 0 0 1-.8-2zm-3.3-.4c0 .4-.1.8-.5 1.1-.3.3-.7.5-1.1.5-.4 0-.8-.2-1.1-.5-.4-.3-.5-.7-.5-1.1 0-.5.1-.9.5-1.2.3-.3.7-.4 1.1-.4.4 0 .8.1 1.1.4.4.3.5.7.5 1.2zM12 13c.4 0 .8.1 1.1.5.4.3.5.7.5 1.1 0 1-.1 1.6-.5 2a3 3 0 0 1-1.1 1c-.4.3-.8.4-1.1.4a.5.5 0 0 1-.5-.5V17a3 3 0 0 0 1-.2l.6-.6c-.6 0-1-.2-1.3-.5-.2-.3-.3-.7-.3-1 0-.5.1-1 .5-1.2.3-.4.7-.5 1.1-.5z" fill-rule="evenodd"/></svg>',
        'color-levels': '<svg width="24" height="24"><path d="M17.5 11.4A9 9 0 0 1 18 14c0 .5 0 1-.2 1.4 0 .4-.3.9-.5 1.3a6.2 6.2 0 0 1-3.7 3 5.7 5.7 0 0 1-3.2 0A5.9 5.9 0 0 1 7.6 18a6.2 6.2 0 0 1-1.4-2.6 6.7 6.7 0 0 1 0-2.8c0-.4.1-.9.3-1.3a13.6 13.6 0 0 1 2.3-4A20 20 0 0 1 12 4a26.4 26.4 0 0 1 3.2 3.4 18.2 18.2 0 0 1 2.3 4zm-2 4.5c.4-.7.5-1.4.5-2a7.3 7.3 0 0 0-1-3.2c.2.6.2 1.2.2 1.9a4.5 4.5 0 0 1-1.3 3 5.3 5.3 0 0 1-2.3 1.5 4.9 4.9 0 0 1-2 .1 4.3 4.3 0 0 0 2.4.8 4 4 0 0 0 2-.6 4 4 0 0 0 1.5-1.5z" fill-rule="evenodd"/></svg>',
        'color-picker': '<svg width="24" height="24"><path d="M12 3a9 9 0 0 0 0 18 1.5 1.5 0 0 0 1.1-2.5c-.2-.3-.4-.6-.4-1 0-.8.7-1.5 1.5-1.5H16a5 5 0 0 0 5-5c0-4.4-4-8-9-8zm-5.5 9a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm3-4a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm3 4a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z" fill-rule="nonzero"/></svg>',
        'color-swatch-remove-color': '<svg width="24" height="24"><path stroke="#000" stroke-width="2" d="M21 3L3 21" fill-rule="evenodd"/></svg>',
        'color-swatch': '<svg width="24" height="24"><rect x="3" y="3" width="18" height="18" rx="1" fill-rule="evenodd"/></svg>',
        'comment-add': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="M9 19l3-2h7c.6 0 1-.4 1-1V6c0-.6-.4-1-1-1H5a1 1 0 0 0-1 1v10c0 .6.4 1 1 1h4v2zm-2 4v-4H5a3 3 0 0 1-3-3V6a3 3 0 0 1 3-3h14a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3h-6.4L7 23z"/><path d="M13 10h2a1 1 0 0 1 0 2h-2v2a1 1 0 0 1-2 0v-2H9a1 1 0 0 1 0-2h2V8a1 1 0 0 1 2 0v2z"/></g></svg>',
        'comment': '<svg width="24" height="24"><path fill-rule="nonzero" d="M9 19l3-2h7c.6 0 1-.4 1-1V6c0-.6-.4-1-1-1H5a1 1 0 0 0-1 1v10c0 .6.4 1 1 1h4v2zm-2 4v-4H5a3 3 0 0 1-3-3V6a3 3 0 0 1 3-3h14a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3h-6.4L7 23z"/></svg>',
        'contrast': '<svg width="24" height="24"><path d="M12 4a7.8 7.8 0 0 1 5.7 2.3A8 8 0 1 1 12 4zm-6 8a6 6 0 0 0 6 6V6a6 6 0 0 0-6 6z" fill-rule="evenodd"/></svg>',
        'copy': '<svg width="24" height="24"><path d="M16 3H6a2 2 0 0 0-2 2v11h2V5h10V3zm1 4a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-7a2 2 0 0 1-2-2V9c0-1.2.9-2 2-2h7zm0 12V9h-7v10h7z" fill-rule="nonzero"/></svg>',
        'crop': '<svg width="24" height="24"><path d="M17 8v7h2c.6 0 1 .4 1 1s-.4 1-1 1h-2v2c0 .6-.4 1-1 1a1 1 0 0 1-1-1v-2H7V9H5a1 1 0 1 1 0-2h2V5c0-.6.4-1 1-1s1 .4 1 1v2h7l3-3 1 1-3 3zM9 9v5l5-5H9zm1 6h5v-5l-5 5z" fill-rule="evenodd"/></svg>',
        'cut': '<svg width="24" height="24"><path d="M18 15c.6.7 1 1.4 1 2.3 0 .8-.2 1.5-.7 2l-.8.5-1 .2c-.4 0-.8 0-1.2-.3a3.9 3.9 0 0 1-2.1-2.2c-.2-.5-.3-1-.2-1.5l-1-1-1 1c0 .5 0 1-.2 1.5-.1.5-.4 1-.9 1.4-.3.4-.7.6-1.2.8l-1.2.3c-.4 0-.7 0-1-.2-.3 0-.6-.3-.8-.5-.5-.5-.8-1.2-.7-2 0-.9.4-1.6 1-2.2A3.7 3.7 0 0 1 8.6 14H9l1-1-4-4-.5-1a3.3 3.3 0 0 1 0-2c0-.4.3-.7.5-1l6 6 6-6 .5 1a3.3 3.3 0 0 1 0 2c0 .4-.3.7-.5 1l-4 4 1 1h.5c.4 0 .8 0 1.2.3.5.2.9.4 1.2.8zm-8.5 2.2l.1-.4v-.3-.4a1 1 0 0 0-.2-.5 1 1 0 0 0-.4-.2 1.6 1.6 0 0 0-.8 0 2.6 2.6 0 0 0-.8.3 2.5 2.5 0 0 0-.9 1.1l-.1.4v.7l.2.5.5.2h.7a2.5 2.5 0 0 0 .8-.3 2.8 2.8 0 0 0 1-1zm2.5-2.8c.4 0 .7-.1 1-.4.3-.3.4-.6.4-1s-.1-.7-.4-1c-.3-.3-.6-.4-1-.4s-.7.1-1 .4c-.3.3-.4.6-.4 1s.1.7.4 1c.3.3.6.4 1 .4zm5.4 4l.2-.5v-.4-.3a2.6 2.6 0 0 0-.3-.8 2.4 2.4 0 0 0-.7-.7 2.5 2.5 0 0 0-.8-.3 1.5 1.5 0 0 0-.8 0 1 1 0 0 0-.4.2 1 1 0 0 0-.2.5 1.5 1.5 0 0 0 0 .7v.4l.3.4.3.4a2.8 2.8 0 0 0 .8.5l.4.1h.7l.5-.2z" fill-rule="evenodd"/></svg>',
        'document-properties': '<svg width="24" height="24"><path d="M14.4 3H7a2 2 0 0 0-2 2v14c0 1.1.9 2 2 2h10a2 2 0 0 0 2-2V7.6L14.4 3zM17 19H7V5h6v4h4v10z" fill-rule="nonzero"/></svg>',
        'drag': '<svg width="24" height="24"><path d="M13 5h2v2h-2V5zm0 4h2v2h-2V9zM9 9h2v2H9V9zm4 4h2v2h-2v-2zm-4 0h2v2H9v-2zm0 4h2v2H9v-2zm4 0h2v2h-2v-2zM9 5h2v2H9V5z" fill-rule="evenodd"/></svg>',
        'duplicate': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="M16 3v2H6v11H4V5c0-1.1.9-2 2-2h10zm3 8h-2V9h-7v10h9a2 2 0 0 1-2 2h-7a2 2 0 0 1-2-2V9c0-1.2.9-2 2-2h7a2 2 0 0 1 2 2v2z"/><path d="M17 14h1a1 1 0 0 1 0 2h-1v1a1 1 0 0 1-2 0v-1h-1a1 1 0 0 1 0-2h1v-1a1 1 0 0 1 2 0v1z"/></g></svg>',
        'edit-block': '<svg width="24" height="24"><path fill-rule="nonzero" d="M19.8 8.8l-9.4 9.4c-.2.2-.5.4-.9.4l-5.4 1.2 1.2-5.4.5-.8 9.4-9.4c.7-.7 1.8-.7 2.5 0l2.1 2.1c.7.7.7 1.8 0 2.5zm-2-.2l1-.9v-.3l-2.2-2.2a.3.3 0 0 0-.3 0l-1 1L18 8.5zm-1 1l-2.5-2.4-6 6 2.5 2.5 6-6zm-7 7.1l-2.6-2.4-.3.3-.1.2-.7 3 3.1-.6h.1l.4-.5z"/></svg>',
        'edit-image': '<svg width="24" height="24"><path d="M18 16h2V7a2 2 0 0 0-2-2H7v2h11v9zM6 17h15a1 1 0 0 1 0 2h-1v1a1 1 0 0 1-2 0v-1H6a2 2 0 0 1-2-2V7H3a1 1 0 1 1 0-2h1V4a1 1 0 1 1 2 0v13zm3-5.3l1.3 2 3-4.7 3.7 6H7l2-3.3z" fill-rule="nonzero"/></svg>',
        'embed-page': '<svg width="24" height="24"><path d="M19 6V5H5v14h2A13 13 0 0 1 19 6zm0 1.4c-.8.8-1.6 2.4-2.2 4.6H19V7.4zm0 5.6h-2.4c-.4 1.8-.6 3.8-.6 6h3v-6zm-4 6c0-2.2.2-4.2.6-6H13c-.7 1.8-1.1 3.8-1.1 6h3zm-4 0c0-2.2.4-4.2 1-6H9.6A12 12 0 0 0 8 19h3zM4 3h16c.6 0 1 .4 1 1v16c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V4c0-.6.4-1 1-1zm11.8 9c.4-1.9 1-3.4 1.8-4.5a9.2 9.2 0 0 0-4 4.5h2.2zm-3.4 0a12 12 0 0 1 2.8-4 12 12 0 0 0-5 4h2.2z" fill-rule="nonzero"/></svg>',
        'embed': '<svg width="24" height="24"><path d="M4 3h16c.6 0 1 .4 1 1v16c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V4c0-.6.4-1 1-1zm1 2v14h14V5H5zm4.8 2.6l5.6 4a.5.5 0 0 1 0 .8l-5.6 4A.5.5 0 0 1 9 16V8a.5.5 0 0 1 .8-.4z" fill-rule="nonzero"/></svg>',
        'emoji': '<svg width="24" height="24"><path d="M9 11c.6 0 1-.4 1-1s-.4-1-1-1a1 1 0 0 0-1 1c0 .6.4 1 1 1zm6 0c.6 0 1-.4 1-1s-.4-1-1-1a1 1 0 0 0-1 1c0 .6.4 1 1 1zm-3 5.5c2.1 0 4-1.5 4.4-3.5H7.6c.5 2 2.3 3.5 4.4 3.5zM12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16zm0 14.5a6.5 6.5 0 1 1 0-13 6.5 6.5 0 0 1 0 13z" fill-rule="nonzero"/></svg>',
        'fill': '<svg width="24" height="26"><path d="M16.6 12l-9-9-1.4 1.4 2.4 2.4-5.2 5.1c-.5.6-.5 1.6 0 2.2L9 19.6a1.5 1.5 0 0 0 2.2 0l5.5-5.5c.5-.6.5-1.6 0-2.2zM5.2 13L10 8.2l4.8 4.8H5.2zM19 14.5s-2 2.2-2 3.5c0 1.1.9 2 2 2a2 2 0 0 0 2-2c0-1.3-2-3.5-2-3.5z" fill-rule="nonzero"/></svg>',
        'flip-horizontally': '<svg width="24" height="24"><path d="M14 19h2v-2h-2v2zm4-8h2V9h-2v2zM4 7v10c0 1.1.9 2 2 2h3v-2H6V7h3V5H6a2 2 0 0 0-2 2zm14-2v2h2a2 2 0 0 0-2-2zm-7 16h2V3h-2v18zm7-6h2v-2h-2v2zm-4-8h2V5h-2v2zm4 12a2 2 0 0 0 2-2h-2v2z" fill-rule="nonzero"/></svg>',
        'flip-vertically': '<svg width="24" height="24"><path d="M5 14v2h2v-2H5zm8 4v2h2v-2h-2zm4-14H7a2 2 0 0 0-2 2v3h2V6h10v3h2V6a2 2 0 0 0-2-2zm2 14h-2v2a2 2 0 0 0 2-2zM3 11v2h18v-2H3zm6 7v2h2v-2H9zm8-4v2h2v-2h-2zM5 18c0 1.1.9 2 2 2v-2H5z" fill-rule="nonzero"/></svg>',
        'format-painter': '<svg width="24" height="24"><path d="M18 5V4c0-.5-.4-1-1-1H5a1 1 0 0 0-1 1v4c0 .6.5 1 1 1h12c.6 0 1-.4 1-1V7h1v4H9v9c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-7h8V5h-3z" fill-rule="nonzero"/></svg>',
        'format': '<svg width="24" height="24"><path fill-rule="evenodd" d="M17 5a1 1 0 0 1 0 2h-4v11a1 1 0 0 1-2 0V7H7a1 1 0 1 1 0-2h10z"/></svg>',
        'fullscreen': '<svg width="24" height="24"><path d="M15.3 10l-1.2-1.3 2.9-3h-2.3a.9.9 0 1 1 0-1.7H19c.5 0 .9.4.9.9v4.4a.9.9 0 1 1-1.8 0V7l-2.9 3zm0 4l3 3v-2.3a.9.9 0 1 1 1.7 0V19c0 .5-.4.9-.9.9h-4.4a.9.9 0 1 1 0-1.8H17l-3-2.9 1.3-1.2zM10 15.4l-2.9 3h2.3a.9.9 0 1 1 0 1.7H5a.9.9 0 0 1-.9-.9v-4.4a.9.9 0 1 1 1.8 0V17l2.9-3 1.2 1.3zM8.7 10L5.7 7v2.3a.9.9 0 0 1-1.7 0V5c0-.5.4-.9.9-.9h4.4a.9.9 0 0 1 0 1.8H7l3 2.9-1.3 1.2z" fill-rule="nonzero"/></svg>',
        'gallery': '<svg width="24" height="24"><path fill-rule="nonzero" d="M5 15.7l2.3-2.2c.3-.3.7-.3 1 0L11 16l5.1-5c.3-.4.8-.4 1 0l2 1.9V8H5v7.7zM5 18V19h3l1.8-1.9-2-2L5 17.9zm14-3l-2.5-2.4-6.4 6.5H19v-4zM4 6h16c.6 0 1 .4 1 1v13c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V7c0-.6.4-1 1-1zm6 7a2 2 0 1 1 0-4 2 2 0 0 1 0 4zM4.5 4h15a.5.5 0 1 1 0 1h-15a.5.5 0 0 1 0-1zm2-2h11a.5.5 0 1 1 0 1h-11a.5.5 0 0 1 0-1z"/></svg>',
        'gamma': '<svg width="24" height="24"><path d="M4 3h16c.6 0 1 .4 1 1v16c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V4c0-.6.4-1 1-1zm1 2v14h14V5H5zm6.5 11.8V14L9.2 8.7a5.1 5.1 0 0 0-.4-.8l-.1-.2H8 8v-1l.3-.1.3-.1h.7a1 1 0 0 1 .6.5l.1.3a8.5 8.5 0 0 1 .3.6l1.9 4.6 2-5.2a1 1 0 0 1 1-.6.5.5 0 0 1 .5.6L13 14v2.8a.7.7 0 0 1-1.4 0z" fill-rule="nonzero"/></svg>',
        'help': '<svg width="24" height="24"><g fill-rule="evenodd"><path d="M12 5.5a6.5 6.5 0 0 0-6 9 6.3 6.3 0 0 0 1.4 2l1 1a6.3 6.3 0 0 0 3.6 1 6.5 6.5 0 0 0 6-9 6.3 6.3 0 0 0-1.4-2l-1-1a6.3 6.3 0 0 0-3.6-1zM12 4a7.8 7.8 0 0 1 5.7 2.3A8 8 0 1 1 12 4z"/><path d="M9.6 9.7a.7.7 0 0 1-.7-.8c0-1.1 1.5-1.8 3.2-1.8 1.8 0 3.2.8 3.2 2.4 0 1.4-.4 2.1-1.5 2.8-.2 0-.3.1-.3.2a2 2 0 0 0-.8.8.8.8 0 0 1-1.4-.6c.3-.7.8-1 1.3-1.5l.4-.2c.7-.4.8-.6.8-1.5 0-.5-.6-.9-1.7-.9-.5 0-1 .1-1.4.3-.2 0-.3.1-.3.2v-.2c0 .4-.4.8-.8.8z" fill-rule="nonzero"/><circle cx="12" cy="16" r="1"/></g></svg>',
        'highlight-bg-color': '<svg width="24" height="24"><g fill-rule="evenodd"><path id="tox-icon-highlight-bg-color__color" d="M3 18h18v3H3z"/><path fill-rule="nonzero" d="M7.7 16.7H3l3.3-3.3-.7-.8L10.2 8l4 4.1-4 4.2c-.2.2-.6.2-.8 0l-.6-.7-1.1 1.1zm5-7.5L11 7.4l3-2.9a2 2 0 0 1 2.6 0L18 6c.7.7.7 2 0 2.7l-2.9 2.9-1.8-1.8-.5-.6"/></g></svg>',
        'home': '<svg width="24" height="24"><path fill-rule="nonzero" d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>',
        'horizontal-rule': '<svg width="24" height="24"><path d="M4 11h16v2H4z" fill-rule="evenodd"/></svg>',
        'image-options': '<svg width="24" height="24"><path d="M6 10a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2zm12 0a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2zm-6 0a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2z" fill-rule="nonzero"/></svg>',
        'image': '<svg width="24" height="24"><path d="M5 15.7l3.3-3.2c.3-.3.7-.3 1 0L12 15l4.1-4c.3-.4.8-.4 1 0l2 1.9V5H5v10.7zM5 18V19h3l2.8-2.9-2-2L5 17.9zm14-3l-2.5-2.4-6.4 6.5H19v-4zM4 3h16c.6 0 1 .4 1 1v16c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V4c0-.6.4-1 1-1zm6 8a2 2 0 1 0 0-4 2 2 0 0 0 0 4z" fill-rule="nonzero"/></svg>',
        'indent': '<svg width="24" height="24"><path d="M7 5h12c.6 0 1 .4 1 1s-.4 1-1 1H7a1 1 0 1 1 0-2zm5 4h7c.6 0 1 .4 1 1s-.4 1-1 1h-7a1 1 0 0 1 0-2zm0 4h7c.6 0 1 .4 1 1s-.4 1-1 1h-7a1 1 0 0 1 0-2zm-5 4h12a1 1 0 0 1 0 2H7a1 1 0 0 1 0-2zm-2.6-3.8L6.2 12l-1.8-1.2a1 1 0 0 1 1.2-1.6l3 2a1 1 0 0 1 0 1.6l-3 2a1 1 0 1 1-1.2-1.6z" fill-rule="evenodd"/></svg>',
        'info': '<svg width="24" height="24"><path d="M12 4a7.8 7.8 0 0 1 5.7 2.3A8 8 0 1 1 12 4zm-1 3v2h2V7h-2zm3 10v-1h-1v-5h-3v1h1v4h-1v1h4z" fill-rule="evenodd"/></svg>',
        'insert-character': '<svg width="24" height="24"><path d="M15 18h4l1-2v4h-6v-3.3l1.4-1a6 6 0 0 0 1.8-2.9 6.3 6.3 0 0 0-.1-4.1 5.8 5.8 0 0 0-3-3.2c-.6-.3-1.3-.5-2.1-.5a5.1 5.1 0 0 0-3.9 1.8 6.3 6.3 0 0 0-1.3 6 6.2 6.2 0 0 0 1.8 3l1.4.9V20H4v-4l1 2h4v-.5l-2-1L5.4 15A6.5 6.5 0 0 1 4 11c0-1 .2-1.9.6-2.7A7 7 0 0 1 6.3 6C7.1 5.4 8 5 9 4.5c1-.3 2-.5 3.1-.5a8.8 8.8 0 0 1 5.7 2 7 7 0 0 1 1.7 2.3 6 6 0 0 1 .2 4.8c-.2.7-.6 1.3-1 1.9a7.6 7.6 0 0 1-3.6 2.5v.5z" fill-rule="evenodd"/></svg>',
        'insert-time': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="M12 19a7 7 0 1 0 0-14 7 7 0 0 0 0 14zm0 2a9 9 0 1 1 0-18 9 9 0 0 1 0 18z"/><path d="M16 12h-3V7c0-.6-.4-1-1-1a1 1 0 0 0-1 1v7h5c.6 0 1-.4 1-1s-.4-1-1-1z"/></g></svg>',
        'invert': '<svg width="24" height="24"><path d="M18 19.3L16.5 18a5.8 5.8 0 0 1-3.1 1.9 6.1 6.1 0 0 1-5.5-1.6A5.8 5.8 0 0 1 6 14v-.3l.1-1.2A13.9 13.9 0 0 1 7.7 9l-3-3 .7-.8 2.8 2.9 9 8.9 1.5 1.6-.7.6zm0-5.5v.3l-.1 1.1-.4 1-1.2-1.2a4.3 4.3 0 0 0 .2-1v-.2c0-.4 0-.8-.2-1.3l-.5-1.4a14.8 14.8 0 0 0-3-4.2L12 6a26.1 26.1 0 0 0-2.2 2.5l-1-1a20.9 20.9 0 0 1 2.9-3.3L12 4l1 .8a22.2 22.2 0 0 1 4 5.4c.6 1.2 1 2.4 1 3.6z" fill-rule="evenodd"/></svg>',
        'italic': '<svg width="24" height="24"><path d="M16.7 4.7l-.1.9h-.3c-.6 0-1 0-1.4.3-.3.3-.4.6-.5 1.1l-2.1 9.8v.6c0 .5.4.8 1.4.8h.2l-.2.8H8l.2-.8h.2c1.1 0 1.8-.5 2-1.5l2-9.8.1-.5c0-.6-.4-.8-1.4-.8h-.3l.2-.9h5.8z" fill-rule="evenodd"/></svg>',
        'line': '<svg width="24" height="24"><path d="M15 9l-8 8H4v-3l8-8 3 3zm1-1l-3-3 1-1h1c-.2 0 0 0 0 0l2 2s0 .2 0 0v1l-1 1zM4 18h16v2H4v-2z" fill-rule="evenodd"/></svg>',
        'link': '<svg width="24" height="24"><path d="M6.2 12.3a1 1 0 0 1 1.4 1.4l-2.1 2a2 2 0 1 0 2.7 2.8l4.8-4.8a1 1 0 0 0 0-1.4 1 1 0 1 1 1.4-1.3 2.9 2.9 0 0 1 0 4L9.6 20a3.9 3.9 0 0 1-5.5-5.5l2-2zm11.6-.6a1 1 0 0 1-1.4-1.4l2-2a2 2 0 1 0-2.6-2.8L11 10.3a1 1 0 0 0 0 1.4A1 1 0 1 1 9.6 13a2.9 2.9 0 0 1 0-4L14.4 4a3.9 3.9 0 0 1 5.5 5.5l-2 2z" fill-rule="nonzero"/></svg>',
        'list-bull-circle': '<svg width="48" height="48"><g fill-rule="evenodd"><path d="M11 16a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm0 1a3 3 0 1 1 0-6 3 3 0 0 1 0 6zM11 26a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm0 1a3 3 0 1 1 0-6 3 3 0 0 1 0 6zM11 36a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm0 1a3 3 0 1 1 0-6 3 3 0 0 1 0 6z" fill-rule="nonzero"/><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/></g></svg>',
        'list-bull-default': '<svg width="48" height="48"><g fill-rule="evenodd"><circle cx="11" cy="14" r="3"/><circle cx="11" cy="24" r="3"/><circle cx="11" cy="34" r="3"/><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/></g></svg>',
        'list-bull-square': '<svg width="48" height="48"><g fill-rule="evenodd"><path d="M8 11h6v6H8zM8 21h6v6H8zM8 31h6v6H8z"/><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/></g></svg>',
        'list-num-default-rtl': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z"/><path d="M37.4 17v-4.8l-1.6 1v-1.1l1.6-1h1.2V17zM33.3 17.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm1.7 5.7c0-1.2 1-2 2.2-2 1.3 0 2.1.8 2.1 1.8 0 .7-.3 1.2-1.3 2.2l-1.2 1v.2h2.6v1h-4.3v-.9l2-1.9c.8-.8 1-1.1 1-1.5 0-.5-.4-.8-1-.8-.5 0-.9.3-.9.9H35zm-1.7 4.3c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm3.2 7.3v-1h.7c.6 0 1-.3 1-.8 0-.4-.4-.7-1-.7s-1 .3-1 .8H35c0-1.1 1-1.8 2.2-1.8 1.2 0 2.1.6 2.1 1.6 0 .7-.4 1.2-1 1.3v.1c.7.1 1.3.7 1.3 1.4 0 1-1 1.9-2.4 1.9-1.3 0-2.2-.8-2.3-2h1.2c0 .6.5 1 1.1 1 .6 0 1-.4 1-1 0-.5-.3-.8-1-.8h-.7zm-3.3 2.7c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7z"/></g></svg>',
        'list-num-default': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/><path d="M10 17v-4.8l-1.5 1v-1.1l1.6-1h1.2V17h-1.2zm3.6.1c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .7.3.7.7 0 .4-.2.7-.7.7zm-5 5.7c0-1.2.8-2 2.1-2s2.1.8 2.1 1.8c0 .7-.3 1.2-1.4 2.2l-1.1 1v.2h2.6v1H8.6v-.9l2-1.9c.8-.8 1-1.1 1-1.5 0-.5-.4-.8-1-.8-.5 0-.9.3-.9.9H8.5zm6.3 4.3c-.5 0-.7-.3-.7-.7 0-.4.2-.7.7-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zM10 34.4v-1h.7c.6 0 1-.3 1-.8 0-.4-.4-.7-1-.7s-1 .3-1 .8H8.6c0-1.1 1-1.8 2.2-1.8 1.3 0 2.1.6 2.1 1.6 0 .7-.4 1.2-1 1.3v.1c.8.1 1.3.7 1.3 1.4 0 1-1 1.9-2.4 1.9-1.3 0-2.2-.8-2.3-2h1.2c0 .6.5 1 1.1 1 .7 0 1-.4 1-1 0-.5-.3-.8-1-.8h-.7zm4.7 2.7c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7z"/></g></svg>',
        'list-num-lower-alpha-rtl': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z"/><path d="M36.5 16c-.9 0-1.5-.5-1.5-1.3s.6-1.3 1.8-1.4h1v-.4c0-.4-.2-.6-.7-.6-.4 0-.7.1-.8.4h-1.1c0-.8.8-1.4 2-1.4S39 12 39 13V16h-1.2v-.6c-.3.4-.8.7-1.4.7zm.4-.8c.6 0 1-.4 1-.9V14h-1c-.5.1-.7.3-.7.6 0 .4.3.6.7.6zM33.1 16.1c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7zM37.7 26c-.7 0-1.2-.2-1.5-.7v.7H35v-6.3h1.2v2.5c.3-.5.8-.9 1.5-.9 1.1 0 1.8 1 1.8 2.4 0 1.5-.7 2.4-1.8 2.4zm-.5-3.6c-.6 0-1 .5-1 1.3s.4 1.4 1 1.4c.7 0 1-.6 1-1.4 0-.8-.3-1.3-1-1.3zM33.2 26.1c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7zm6 7h-1c-.1-.5-.4-.8-1-.8s-1 .5-1 1.4c0 1 .4 1.4 1 1.4.5 0 .9-.2 1-.7h1c0 1-.8 1.7-2 1.7-1.4 0-2.2-.9-2.2-2.4s.8-2.4 2.2-2.4c1.2 0 2 .7 2 1.7zm-6.1 3c-.5 0-.7-.3-.7-.7 0-.4.2-.7.7-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z"/></g></svg>',
        'list-num-lower-alpha': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/><path d="M10.3 15.2c.5 0 1-.4 1-.9V14h-1c-.5.1-.8.3-.8.6 0 .4.3.6.8.6zm-.4.9c-1 0-1.5-.6-1.5-1.4 0-.8.6-1.3 1.7-1.4h1.1v-.4c0-.4-.2-.6-.7-.6-.5 0-.8.1-.9.4h-1c0-.8.8-1.4 2-1.4 1.1 0 1.8.6 1.8 1.6V16h-1.1v-.6h-.1c-.2.4-.7.7-1.3.7zm4.6 0c-.5 0-.7-.3-.7-.7 0-.4.2-.7.7-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm-3.2 10c-.6 0-1.2-.3-1.4-.8v.7H8.5v-6.3H10v2.5c.3-.5.8-.9 1.4-.9 1.2 0 1.9 1 1.9 2.4 0 1.5-.7 2.4-1.9 2.4zm-.4-3.7c-.7 0-1 .5-1 1.3s.3 1.4 1 1.4c.6 0 1-.6 1-1.4 0-.8-.4-1.3-1-1.3zm4 3.7c-.5 0-.7-.3-.7-.7 0-.4.2-.7.7-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm-2.2 7h-1.2c0-.5-.4-.8-.9-.8-.6 0-1 .5-1 1.4 0 1 .4 1.4 1 1.4.5 0 .8-.2 1-.7h1c0 1-.8 1.7-2 1.7-1.4 0-2.2-.9-2.2-2.4s.8-2.4 2.2-2.4c1.2 0 2 .7 2 1.7zm1.8 3c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z"/></g></svg>',
        'list-num-lower-greek-rtl': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z"/><path d="M37.4 16c-1.2 0-2-.8-2-2.3 0-1.5.8-2.4 2-2.4.6 0 1 .4 1.3 1v-.9H40v3.2c0 .4.1.5.4.5h.2v.9h-.6c-.6 0-1-.2-1-.7h-.2c-.2.4-.7.8-1.3.8zm.3-1c.6 0 1-.5 1-1.3s-.4-1.3-1-1.3-1 .5-1 1.3.4 1.4 1 1.4zM33.3 16.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zM36 21.9c0-1.5.8-2.3 2.1-2.3 1.2 0 2 .6 2 1.6 0 .6-.3 1-.9 1.3.9.3 1.3.8 1.3 1.7 0 1.2-.7 1.9-1.8 1.9-.6 0-1.1-.3-1.4-.8v2.2H36V22zm1.8 1.2v-1h.3c.5 0 .9-.2.9-.7 0-.5-.3-.8-.9-.8-.5 0-.8.3-.8 1v2.2c0 .8.4 1.3 1 1.3s1-.4 1-1-.4-1-1.2-1h-.3zM33.3 26.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zM37.1 34.6L34.8 30h1.4l1.7 3.5 1.7-3.5h1.1l-2.2 4.6v.1c.5.8.7 1.4.7 1.8 0 .4-.2.8-.4 1-.2.2-.6.3-1 .3-.9 0-1.3-.4-1.3-1.2 0-.5.2-1 .5-1.7l.1-.2zm.7 1a2 2 0 0 0-.4.9c0 .3.1.4.4.4.3 0 .4-.1.4-.4 0-.2-.1-.6-.4-1zM33.3 36.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z"/></g></svg>',
        'list-num-lower-greek': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/><path d="M10.5 15c.7 0 1-.5 1-1.3s-.3-1.3-1-1.3c-.5 0-.9.5-.9 1.3s.4 1.4 1 1.4zm-.3 1c-1.1 0-1.8-.8-1.8-2.3 0-1.5.7-2.4 1.8-2.4.7 0 1.1.4 1.3 1h.1v-.9h1.2v3.2c0 .4.1.5.4.5h.2v.9h-.6c-.6 0-1-.2-1.1-.7h-.1c-.2.4-.7.8-1.4.8zm5 .1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7zm-4.9 7v-1h.3c.6 0 1-.2 1-.7 0-.5-.4-.8-1-.8-.5 0-.8.3-.8 1v2.2c0 .8.4 1.3 1.1 1.3.6 0 1-.4 1-1s-.5-1-1.3-1h-.3zM8.6 22c0-1.5.7-2.3 2-2.3 1.2 0 2 .6 2 1.6 0 .6-.3 1-.8 1.3.8.3 1.3.8 1.3 1.7 0 1.2-.8 1.9-1.9 1.9-.6 0-1.1-.3-1.3-.8v2.2H8.5V22zm6.2 4.2c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .7.3.7.7 0 .4-.2.7-.7.7zm-4.5 8.5L8 30h1.4l1.7 3.5 1.7-3.5h1.1l-2.2 4.6v.1c.5.8.7 1.4.7 1.8 0 .4-.1.8-.4 1-.2.2-.6.3-1 .3-.9 0-1.3-.4-1.3-1.2 0-.5.2-1 .5-1.7l.1-.2zm.7 1a2 2 0 0 0-.4.9c0 .3.1.4.4.4.3 0 .4-.1.4-.4 0-.2-.1-.6-.4-1zm4.5.5c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z"/></g></svg>',
        'list-num-lower-roman-rtl': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z"/><path d="M32.9 16v-1.2h-1.3V16H33zm0 10v-1.2h-1.3V26H33zm0 10v-1.2h-1.3V36H33z"/><path fill-rule="nonzero" d="M36 21h-1.5v5H36zM36 31h-1.5v5H36zM39 21h-1.5v5H39zM39 31h-1.5v5H39zM42 31h-1.5v5H42zM36 11h-1.5v5H36zM36 19h-1.5v1H36zM36 29h-1.5v1H36zM39 19h-1.5v1H39zM39 29h-1.5v1H39zM42 29h-1.5v1H42zM36 9h-1.5v1H36z"/></g></svg>',
        'list-num-lower-roman': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/><path d="M15.1 16v-1.2h1.3V16H15zm0 10v-1.2h1.3V26H15zm0 10v-1.2h1.3V36H15z"/><path fill-rule="nonzero" d="M12 21h1.5v5H12zM12 31h1.5v5H12zM9 21h1.5v5H9zM9 31h1.5v5H9zM6 31h1.5v5H6zM12 11h1.5v5H12zM12 19h1.5v1H12zM12 29h1.5v1H12zM9 19h1.5v1H9zM9 29h1.5v1H9zM6 29h1.5v1H6zM12 9h1.5v1H12z"/></g></svg>',
        'list-num-upper-alpha-rtl': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z"/><path d="M39.3 17l-.5-1.4h-2l-.5 1.4H35l2-6h1.6l2 6h-1.3zm-1.6-4.7l-.7 2.3h1.6l-.8-2.3zM33.4 17c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .7.3.7.7 0 .4-.2.7-.7.7zm4.7 9.9h-2.7v-6H38c1.2 0 1.9.6 1.9 1.5 0 .6-.5 1.2-1 1.3.7.1 1.3.7 1.3 1.5 0 1-.8 1.7-2 1.7zm-1.4-5v1.5h1c.6 0 1-.3 1-.8 0-.4-.4-.7-1-.7h-1zm0 4h1.1c.7 0 1.1-.3 1.1-.8 0-.6-.4-.9-1.1-.9h-1.1V26zM33 27.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm4.9 10c-1.8 0-2.8-1.1-2.8-3.1s1-3.1 2.8-3.1c1.4 0 2.5.9 2.6 2.2h-1.3c0-.7-.6-1.1-1.3-1.1-1 0-1.6.7-1.6 2s.6 2 1.6 2c.7 0 1.2-.4 1.4-1h1.2c-.1 1.3-1.2 2.2-2.6 2.2zm-4.5 0c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z"/></g></svg>',
        'list-num-upper-alpha': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/><path d="M12.6 17l-.5-1.4h-2L9.5 17H8.3l2-6H12l2 6h-1.3zM11 12.3l-.7 2.3h1.6l-.8-2.3zm4.7 4.8c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .7.3.7.7 0 .4-.2.7-.7.7zM11.4 27H8.7v-6h2.6c1.2 0 1.9.6 1.9 1.5 0 .6-.5 1.2-1 1.3.7.1 1.3.7 1.3 1.5 0 1-.8 1.7-2 1.7zM10 22v1.5h1c.6 0 1-.3 1-.8 0-.4-.4-.7-1-.7h-1zm0 4H11c.7 0 1.1-.3 1.1-.8 0-.6-.4-.9-1.1-.9H10V26zm5.4 1.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm-4.1 10c-1.8 0-2.8-1.1-2.8-3.1s1-3.1 2.8-3.1c1.4 0 2.5.9 2.6 2.2h-1.3c0-.7-.6-1.1-1.3-1.1-1 0-1.6.7-1.6 2s.6 2 1.6 2c.7 0 1.2-.4 1.4-1h1.2c-.1 1.3-1.2 2.2-2.6 2.2zm4.5 0c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z"/></g></svg>',
        'list-num-upper-roman-rtl': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z"/><path d="M31.6 17v-1.2H33V17h-1.3zm0 10v-1.2H33V27h-1.3zm0 10v-1.2H33V37h-1.3z"/><path fill-rule="nonzero" d="M34.5 20H36v7h-1.5zM34.5 30H36v7h-1.5zM37.5 20H39v7h-1.5zM37.5 30H39v7h-1.5zM40.5 30H42v7h-1.5zM34.5 10H36v7h-1.5z"/></g></svg>',
        'list-num-upper-roman': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/><path d="M15.1 17v-1.2h1.3V17H15zm0 10v-1.2h1.3V27H15zm0 10v-1.2h1.3V37H15z"/><path fill-rule="nonzero" d="M12 20h1.5v7H12zM12 30h1.5v7H12zM9 20h1.5v7H9zM9 30h1.5v7H9zM6 30h1.5v7H6zM12 10h1.5v7H12z"/></g></svg>',
        'lock': '<svg width="24" height="24"><path d="M16.3 11c.2 0 .3 0 .5.2l.2.6v7.4c0 .3 0 .4-.2.6l-.6.2H7.8c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6v-7.4c0-.3 0-.4.2-.6l.5-.2H8V8c0-.8.3-1.5.9-2.1.6-.6 1.3-.9 2.1-.9h2c.8 0 1.5.3 2.1.9.6.6.9 1.3.9 2.1v3h.3zM10 8v3h4V8a1 1 0 0 0-.3-.7A1 1 0 0 0 13 7h-2a1 1 0 0 0-.7.3 1 1 0 0 0-.3.7z" fill-rule="evenodd"/></svg>',
        'ltr': '<svg width="24" height="24"><path d="M11 5h7a1 1 0 0 1 0 2h-1v11a1 1 0 0 1-2 0V7h-2v11a1 1 0 0 1-2 0v-6c-.5 0-1 0-1.4-.3A3.4 3.4 0 0 1 7.8 10a3.3 3.3 0 0 1 0-2.8 3.4 3.4 0 0 1 1.8-1.8L11 5zM4.4 16.2L6.2 15l-1.8-1.2a1 1 0 0 1 1.2-1.6l3 2a1 1 0 0 1 0 1.6l-3 2a1 1 0 1 1-1.2-1.6z" fill-rule="evenodd"/></svg>',
        'more-drawer': '<svg width="24" height="24"><path d="M6 10a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2zm12 0a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2zm-6 0a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2z" fill-rule="nonzero"/></svg>',
        'new-document': '<svg width="24" height="24"><path d="M14.4 3H7a2 2 0 0 0-2 2v14c0 1.1.9 2 2 2h10a2 2 0 0 0 2-2V7.6L14.4 3zM17 19H7V5h6v4h4v10z" fill-rule="nonzero"/></svg>',
        'new-tab': '<svg width="24" height="24"><path d="M15 13l2-2v8H5V7h8l-2 2H7v8h8v-4zm4-8v5.5l-2-2-5.6 5.5H10v-1.4L15.5 7l-2-2H19z" fill-rule="evenodd"/></svg>',
        'non-breaking': '<svg width="24" height="24"><path d="M11 11H8a1 1 0 1 1 0-2h3V6c0-.6.4-1 1-1s1 .4 1 1v3h3c.6 0 1 .4 1 1s-.4 1-1 1h-3v3c0 .6-.4 1-1 1a1 1 0 0 1-1-1v-3zm10 4v5H3v-5c0-.6.4-1 1-1s1 .4 1 1v3h14v-3c0-.6.4-1 1-1s1 .4 1 1z" fill-rule="evenodd"/></svg>',
        'notice': '<svg width="24" height="24"><path d="M17.8 9.8L15.4 4 20 8.5v7L15.5 20h-7L4 15.5v-7L8.5 4h7l2.3 5.8zm0 0l2.2 5.7-2.3-5.8zM13 17v-2h-2v2h2zm0-4V7h-2v6h2z" fill-rule="evenodd"/></svg>',
        'ordered-list-rtl': '<svg width="24" height="24"><path d="M6 17h8a1 1 0 0 1 0 2H6a1 1 0 0 1 0-2zm0-6h8a1 1 0 0 1 0 2H6a1 1 0 0 1 0-2zm0-6h8a1 1 0 0 1 0 2H6a1 1 0 1 1 0-2zm13-1v3.5a.5.5 0 1 1-1 0V5h-.5a.5.5 0 1 1 0-1H19zm-1 8.8l.2.2h1.3a.5.5 0 1 1 0 1h-1.6a1 1 0 0 1-.9-1V13c0-.4.3-.8.6-1l1.2-.4.2-.3a.2.2 0 0 0-.2-.2h-1.3a.5.5 0 0 1-.5-.5c0-.3.2-.5.5-.5h1.6c.5 0 .9.4.9 1v.1c0 .4-.3.8-.6 1l-1.2.4-.2.3zm2 4.2v2c0 .6-.4 1-1 1h-1.5a.5.5 0 0 1 0-1h1.2a.3.3 0 1 0 0-.6h-1.3a.4.4 0 1 1 0-.8h1.3a.3.3 0 0 0 0-.6h-1.2a.5.5 0 1 1 0-1H19c.6 0 1 .4 1 1z" fill-rule="evenodd"/></svg>',
        'ordered-list': '<svg width="24" height="24"><path d="M10 17h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 1 1 0-2zM6 4v3.5c0 .3-.2.5-.5.5a.5.5 0 0 1-.5-.5V5h-.5a.5.5 0 0 1 0-1H6zm-1 8.8l.2.2h1.3c.3 0 .5.2.5.5s-.2.5-.5.5H4.9a1 1 0 0 1-.9-1V13c0-.4.3-.8.6-1l1.2-.4.2-.3a.2.2 0 0 0-.2-.2H4.5a.5.5 0 0 1-.5-.5c0-.3.2-.5.5-.5h1.6c.5 0 .9.4.9 1v.1c0 .4-.3.8-.6 1l-1.2.4-.2.3zM7 17v2c0 .6-.4 1-1 1H4.5a.5.5 0 0 1 0-1h1.2c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3H4.4a.4.4 0 1 1 0-.8h1.3c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3H4.5a.5.5 0 1 1 0-1H6c.6 0 1 .4 1 1z" fill-rule="evenodd"/></svg>',
        'orientation': '<svg width="24" height="24"><path d="M7.3 6.4L1 13l6.4 6.5 6.5-6.5-6.5-6.5zM3.7 13l3.6-3.7L11 13l-3.7 3.7-3.6-3.7zM12 6l2.8 2.7c.3.3.3.8 0 1-.3.4-.9.4-1.2 0L9.2 5.7a.8.8 0 0 1 0-1.2L13.6.2c.3-.3.9-.3 1.2 0 .3.3.3.8 0 1.1L12 4h1a9 9 0 1 1-4.3 16.9l1.5-1.5A7 7 0 1 0 13 6h-1z" fill-rule="nonzero"/></svg>',
        'outdent': '<svg width="24" height="24"><path d="M7 5h12c.6 0 1 .4 1 1s-.4 1-1 1H7a1 1 0 1 1 0-2zm5 4h7c.6 0 1 .4 1 1s-.4 1-1 1h-7a1 1 0 0 1 0-2zm0 4h7c.6 0 1 .4 1 1s-.4 1-1 1h-7a1 1 0 0 1 0-2zm-5 4h12a1 1 0 0 1 0 2H7a1 1 0 0 1 0-2zm1.6-3.8a1 1 0 0 1-1.2 1.6l-3-2a1 1 0 0 1 0-1.6l3-2a1 1 0 0 1 1.2 1.6L6.8 12l1.8 1.2z" fill-rule="evenodd"/></svg>',
        'page-break': '<svg width="24" height="24"><g fill-rule="evenodd"><path d="M5 11c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2zm3 0h1c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 0 1 0-2zm4 0c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2zm3 0h1c.6 0 1 .4 1 1s-.4 1-1 1h-1a1 1 0 0 1 0-2zm4 0c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2zM7 3v5h10V3c0-.6.4-1 1-1s1 .4 1 1v7H5V3c0-.6.4-1 1-1s1 .4 1 1zM6 22a1 1 0 0 1-1-1v-7h14v7c0 .6-.4 1-1 1a1 1 0 0 1-1-1v-5H7v5c0 .6-.4 1-1 1z"/></g></svg>',
        'paragraph': '<svg width="24" height="24"><path fill-rule="evenodd" d="M10 5h7a1 1 0 0 1 0 2h-1v11a1 1 0 0 1-2 0V7h-2v11a1 1 0 0 1-2 0v-6c-.5 0-1 0-1.4-.3A3.4 3.4 0 0 1 6.8 10a3.3 3.3 0 0 1 0-2.8 3.4 3.4 0 0 1 1.8-1.8L10 5z"/></svg>',
        'paste-text': '<svg width="24" height="24"><path d="M18 9V5h-2v1c0 .6-.4 1-1 1H9a1 1 0 0 1-1-1V5H6v13h3V9h9zM9 20H6a2 2 0 0 1-2-2V5c0-1.1.9-2 2-2h3.2A3 3 0 0 1 12 1a3 3 0 0 1 2.8 2H18a2 2 0 0 1 2 2v4h1v12H9v-1zm1.5-9.5v9h9v-9h-9zM12 3a1 1 0 0 0-1 1c0 .5.4 1 1 1s1-.5 1-1-.4-1-1-1zm0 9h6v2h-.5l-.5-1h-1v4h.8v1h-3.6v-1h.8v-4h-1l-.5 1H12v-2z" fill-rule="nonzero"/></svg>',
        'paste': '<svg width="24" height="24"><path d="M18 9V5h-2v1c0 .6-.4 1-1 1H9a1 1 0 0 1-1-1V5H6v13h3V9h9zM9 20H6a2 2 0 0 1-2-2V5c0-1.1.9-2 2-2h3.2A3 3 0 0 1 12 1a3 3 0 0 1 2.8 2H18a2 2 0 0 1 2 2v4h1v12H9v-1zm1.5-9.5v9h9v-9h-9zM12 3a1 1 0 0 0-1 1c0 .5.4 1 1 1s1-.5 1-1-.4-1-1-1z" fill-rule="nonzero"/></svg>',
        'permanent-pen': '<svg width="24" height="24"><path d="M10.5 17.5L8 20H3v-3l3.5-3.5a2 2 0 0 1 0-3L14 3l1 1-7.3 7.3a1 1 0 0 0 0 1.4l3.6 3.6c.4.4 1 .4 1.4 0L20 9l1 1-7.6 7.6a2 2 0 0 1-2.8 0l-.1-.1z" fill-rule="nonzero"/></svg>',
        'plus': '<svg width="24" height="24"><path d="M12 4c.5 0 1 .4 1 .9V11h6a1 1 0 0 1 .1 2H13v6a1 1 0 0 1-2 .1V13H5a1 1 0 0 1-.1-2H11V5c0-.6.4-1 1-1z"/></svg>',
        'preferences': '<svg width="24" height="24"><path d="M20.1 13.5l-1.9.2a5.8 5.8 0 0 1-.6 1.5l1.2 1.5c.4.4.3 1 0 1.4l-.7.7a1 1 0 0 1-1.4 0l-1.5-1.2a6.2 6.2 0 0 1-1.5.6l-.2 1.9c0 .5-.5.9-1 .9h-1a1 1 0 0 1-1-.9l-.2-1.9a5.8 5.8 0 0 1-1.5-.6l-1.5 1.2a1 1 0 0 1-1.4 0l-.7-.7a1 1 0 0 1 0-1.4l1.2-1.5a6.2 6.2 0 0 1-.6-1.5l-1.9-.2a1 1 0 0 1-.9-1v-1c0-.5.4-1 .9-1l1.9-.2a5.8 5.8 0 0 1 .6-1.5L5.2 7.3a1 1 0 0 1 0-1.4l.7-.7a1 1 0 0 1 1.4 0l1.5 1.2a6.2 6.2 0 0 1 1.5-.6l.2-1.9c0-.5.5-.9 1-.9h1c.5 0 1 .4 1 .9l.2 1.9a5.8 5.8 0 0 1 1.5.6l1.5-1.2a1 1 0 0 1 1.4 0l.7.7c.3.4.4 1 0 1.4l-1.2 1.5a6.2 6.2 0 0 1 .6 1.5l1.9.2c.5 0 .9.5.9 1v1c0 .5-.4 1-.9 1zM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" fill-rule="evenodd"/></svg>',
        'preview': '<svg width="24" height="24"><path d="M3.5 12.5c.5.8 1.1 1.6 1.8 2.3 2 2 4.2 3.2 6.7 3.2s4.7-1.2 6.7-3.2a16.2 16.2 0 0 0 2.1-2.8 15.7 15.7 0 0 0-2.1-2.8c-2-2-4.2-3.2-6.7-3.2a9.3 9.3 0 0 0-6.7 3.2A16.2 16.2 0 0 0 3.2 12c0 .2.2.3.3.5zm-2.4-1l.7-1.2L4 7.8C6.2 5.4 8.9 4 12 4c3 0 5.8 1.4 8.1 3.8a18.2 18.2 0 0 1 2.8 3.7v1l-.7 1.2-2.1 2.5c-2.3 2.4-5 3.8-8.1 3.8-3 0-5.8-1.4-8.1-3.8a18.2 18.2 0 0 1-2.8-3.7 1 1 0 0 1 0-1zm12-3.3a2 2 0 1 0 2.7 2.6 4 4 0 1 1-2.6-2.6z" fill-rule="nonzero"/></svg>',
        'print': '<svg width="24" height="24"><path d="M18 8H6a3 3 0 0 0-3 3v6h2v3h14v-3h2v-6a3 3 0 0 0-3-3zm-1 10H7v-4h10v4zm.5-5c-.8 0-1.5-.7-1.5-1.5s.7-1.5 1.5-1.5 1.5.7 1.5 1.5-.7 1.5-1.5 1.5zm.5-8H6v2h12V5z" fill-rule="nonzero"/></svg>',
        'quote': '<svg width="24" height="24"><path d="M7.5 17h.9c.4 0 .7-.2.9-.6L11 13V8c0-.6-.4-1-1-1H6a1 1 0 0 0-1 1v4c0 .6.4 1 1 1h2l-1.3 2.7a1 1 0 0 0 .8 1.3zm8 0h.9c.4 0 .7-.2.9-.6L19 13V8c0-.6-.4-1-1-1h-4a1 1 0 0 0-1 1v4c0 .6.4 1 1 1h2l-1.3 2.7a1 1 0 0 0 .8 1.3z" fill-rule="nonzero"/></svg>',
        'redo': '<svg width="24" height="24"><path d="M17.6 10H12c-2.8 0-4.4 1.4-4.9 3.5-.4 2 .3 4 1.4 4.6a1 1 0 1 1-1 1.8c-2-1.2-2.9-4.1-2.3-6.8.6-3 3-5.1 6.8-5.1h5.6l-3.3-3.3a1 1 0 1 1 1.4-1.4l5 5a1 1 0 0 1 0 1.4l-5 5a1 1 0 0 1-1.4-1.4l3.3-3.3z" fill-rule="nonzero"/></svg>',
        'reload': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="M5 22.1l-1.2-4.7v-.2a1 1 0 0 1 1-1l5 .4a1 1 0 1 1-.2 2l-2.2-.2a7.8 7.8 0 0 0 8.4.2 7.5 7.5 0 0 0 3.5-6.4 1 1 0 1 1 2 0 9.5 9.5 0 0 1-4.5 8 9.9 9.9 0 0 1-10.2 0l.4 1.4a1 1 0 1 1-2 .5zM13.6 7.4c0-.5.5-1 1-.9l2.8.2a8 8 0 0 0-9.5-1 7.5 7.5 0 0 0-3.6 7 1 1 0 0 1-2 0 9.5 9.5 0 0 1 4.5-8.6 10 10 0 0 1 10.9.3l-.3-1a1 1 0 0 1 2-.5l1.1 4.8a1 1 0 0 1-1 1.2l-5-.4a1 1 0 0 1-.9-1z"/></g></svg>',
        'remove-formatting': '<svg width="24" height="24"><path d="M13.2 6a1 1 0 0 1 0 .2l-2.6 10a1 1 0 0 1-1 .8h-.2a.8.8 0 0 1-.8-1l2.6-10H8a1 1 0 1 1 0-2h9a1 1 0 0 1 0 2h-3.8zM5 18h7a1 1 0 0 1 0 2H5a1 1 0 0 1 0-2zm13 1.5L16.5 18 15 19.5a.7.7 0 0 1-1-1l1.5-1.5-1.5-1.5a.7.7 0 0 1 1-1l1.5 1.5 1.5-1.5a.7.7 0 0 1 1 1L17.5 17l1.5 1.5a.7.7 0 0 1-1 1z" fill-rule="evenodd"/></svg>',
        'remove': '<svg width="24" height="24"><path d="M16 7h3a1 1 0 0 1 0 2h-1v9a3 3 0 0 1-3 3H9a3 3 0 0 1-3-3V9H5a1 1 0 1 1 0-2h3V6a3 3 0 0 1 3-3h2a3 3 0 0 1 3 3v1zm-2 0V6c0-.6-.4-1-1-1h-2a1 1 0 0 0-1 1v1h4zm2 2H8v9c0 .6.4 1 1 1h6c.6 0 1-.4 1-1V9zm-7 3a1 1 0 0 1 2 0v4a1 1 0 0 1-2 0v-4zm4 0a1 1 0 0 1 2 0v4a1 1 0 0 1-2 0v-4z" fill-rule="nonzero"/></svg>',
        'resize-handle': '<svg width="10" height="10"><g fill-rule="nonzero"><path d="M8.1 1.1A.5.5 0 1 1 9 2l-7 7A.5.5 0 1 1 1 8l7-7zM8.1 5.1A.5.5 0 1 1 9 6l-3 3A.5.5 0 1 1 5 8l3-3z"/></g></svg>',
        'resize': '<svg width="24" height="24"><path d="M4 5c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h6c.3 0 .5.1.7.3.2.2.3.4.3.7 0 .3-.1.5-.3.7a1 1 0 0 1-.7.3H7.4L18 16.6V13c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3.3 0 .5.1.7.3.2.2.3.4.3.7v6c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3h-6a1 1 0 0 1-.7-.3 1 1 0 0 1-.3-.7c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h3.6L6 7.4V11c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3 1 1 0 0 1-.7-.3A1 1 0 0 1 4 11V5z" fill-rule="evenodd"/></svg>',
        'restore-draft': '<svg width="24" height="24"><g fill-rule="evenodd"><path d="M17 13c0 .6-.4 1-1 1h-4V8c0-.6.4-1 1-1s1 .4 1 1v4h2c.6 0 1 .4 1 1z"/><path d="M4.7 10H9a1 1 0 0 1 0 2H3a1 1 0 0 1-1-1V5a1 1 0 1 1 2 0v3l2.5-2.4a9.2 9.2 0 0 1 10.8-1.5A9 9 0 0 1 13.4 21c-2.4.1-4.7-.7-6.5-2.2a1 1 0 1 1 1.3-1.5 7.2 7.2 0 0 0 11.6-3.7 7 7 0 0 0-3.5-7.7A7.2 7.2 0 0 0 8 7L4.7 10z" fill-rule="nonzero"/></g></svg>',
        'rotate-left': '<svg width="24" height="24"><path d="M4.7 10H9a1 1 0 0 1 0 2H3a1 1 0 0 1-1-1V5a1 1 0 1 1 2 0v3l2.5-2.4a9.2 9.2 0 0 1 10.8-1.5A9 9 0 0 1 13.4 21c-2.4.1-4.7-.7-6.5-2.2a1 1 0 1 1 1.3-1.5 7.2 7.2 0 0 0 11.6-3.7 7 7 0 0 0-3.5-7.7A7.2 7.2 0 0 0 8 7L4.7 10z" fill-rule="nonzero"/></svg>',
        'rotate-right': '<svg width="24" height="24"><path d="M20 8V5a1 1 0 0 1 2 0v6c0 .6-.4 1-1 1h-6a1 1 0 0 1 0-2h4.3L16 7A7.2 7.2 0 0 0 7.7 6a7 7 0 0 0 3 13.1c1.9.1 3.7-.5 5-1.7a1 1 0 0 1 1.4 1.5A9.2 9.2 0 0 1 2.2 14c-.9-3.9 1-8 4.5-9.9 3.5-1.9 8-1.3 10.8 1.5L20 8z" fill-rule="nonzero"/></svg>',
        'rtl': '<svg width="24" height="24"><path d="M8 5h8v2h-2v12h-2V7h-2v12H8v-7c-.5 0-1 0-1.4-.3A3.4 3.4 0 0 1 4.8 10a3.3 3.3 0 0 1 0-2.8 3.4 3.4 0 0 1 1.8-1.8L8 5zm12 11.2a1 1 0 1 1-1 1.6l-3-2a1 1 0 0 1 0-1.6l3-2a1 1 0 1 1 1 1.6L18.4 15l1.8 1.2z" fill-rule="evenodd"/></svg>',
        'save': '<svg width="24" height="24"><path d="M5 16h14a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-2c0-1.1.9-2 2-2zm0 2v2h14v-2H5zm10 0h2v2h-2v-2zm-4-6.4L8.7 9.3a1 1 0 1 0-1.4 1.4l4 4c.4.4 1 .4 1.4 0l4-4a1 1 0 1 0-1.4-1.4L13 11.6V4a1 1 0 0 0-2 0v7.6z" fill-rule="nonzero"/></svg>',
        'search': '<svg width="24" height="24"><path d="M16 17.3a8 8 0 1 1 1.4-1.4l4.3 4.4a1 1 0 0 1-1.4 1.4l-4.4-4.3zm-5-.3a6 6 0 1 0 0-12 6 6 0 0 0 0 12z" fill-rule="nonzero"/></svg>',
        'select-all': '<svg width="24" height="24"><path d="M3 5h2V3a2 2 0 0 0-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2a2 2 0 0 0-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8a2 2 0 0 0 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2zM7 17h10V7H7v10zm2-8h6v6H9V9z" fill-rule="nonzero"/></svg>',
        'selected': '<svg width="24" height="24"><path fill-rule="nonzero" d="M6 4h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2zm3.6 10.9L7 12.3a.7.7 0 0 0-1 1L9.6 17 18 8.6a.7.7 0 0 0 0-1 .7.7 0 0 0-1 0l-7.4 7.3z"/></svg>',
        'settings': '<svg width="24" height="24"><path d="M11 6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8v.3c0 .2 0 .3-.2.5l-.6.2H7.8c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6V8H5a1 1 0 1 1 0-2h2v-.3c0-.2 0-.3.2-.5l.5-.2h2.5c.3 0 .4 0 .6.2l.2.5V6zM8 8h2V6H8v2zm9 2.8v.2h2c.6 0 1 .4 1 1s-.4 1-1 1h-2v.3c0 .2 0 .3-.2.5l-.6.2h-2.4c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6V13H5a1 1 0 0 1 0-2h8v-.3c0-.2 0-.3.2-.5l.6-.2h2.4c.3 0 .4 0 .6.2l.2.6zM14 13h2v-2h-2v2zm-3 2.8v.2h8c.6 0 1 .4 1 1s-.4 1-1 1h-8v.3c0 .2 0 .3-.2.5l-.6.2H7.8c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6V18H5a1 1 0 0 1 0-2h2v-.3c0-.2 0-.3.2-.5l.5-.2h2.5c.3 0 .4 0 .6.2l.2.6zM8 18h2v-2H8v2z" fill-rule="evenodd"/></svg>',
        'sharpen': '<svg width="24" height="24"><path d="M16 6l4 4-8 9-8-9 4-4h8zm-4 10.2l5.5-6.2-.1-.1H12v-.3h5.1l-.2-.2H12V9h4.6l-.2-.2H12v-.3h4.1l-.2-.2H12V8h3.6l-.2-.2H8.7L6.5 10l.1.1H12v.3H6.9l.2.2H12v.3H7.3l.2.2H12v.3H7.7l.3.2h4v.3H8.2l.2.2H12v.3H8.6l.3.2H12v.3H9l.3.2H12v.3H9.5l.2.2H12v.3h-2l.2.2H12v.3h-1.6l.2.2H12v.3h-1.1l.2.2h.9v.3h-.7l.2.2h.5v.3h-.3l.3.2z" fill-rule="evenodd"/></svg>',
        'sort-asc': '<svg width="24" height="24"><g fill-rule="evenodd"><path d="M4 8h5a1 1 0 1 1 0 2H4a1 1 0 1 1 0-2zm0 8h8a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2zm0-4h7a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2z"/><path fill-rule="nonzero" d="M16 8.4l-2.3 2.3a1 1 0 0 1-1.4-1.4l4-4a1 1 0 0 1 1.4 0l4 4a1 1 0 1 1-1.4 1.4L18 8.4V18a1 1 0 0 1-2 0V8.4z"/></g></svg>',
        'sort-dsc': '<svg width="24" height="24"><g fill-rule="evenodd"><path d="M4 16h5a1 1 0 0 0 0-2H4a1 1 0 0 0 0 2zm0-8h8a1 1 0 0 0 0-2H4a1 1 0 1 0 0 2zm0 4h7a1 1 0 0 0 0-2H4a1 1 0 0 0 0 2z"/><path fill-rule="nonzero" d="M16 15.6l-2.3-2.3a1 1 0 0 0-1.4 1.4l4 4c.4.4 1 .4 1.4 0l4-4a1 1 0 0 0-1.4-1.4L18 15.6V6a1 1 0 0 0-2 0v9.6z"/></g></svg>',
        'sourcecode': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="M9.8 15.7c.3.3.3.8 0 1-.3.4-.9.4-1.2 0l-4.4-4.1a.8.8 0 0 1 0-1.2l4.4-4.2c.3-.3.9-.3 1.2 0 .3.3.3.8 0 1.1L6 12l3.8 3.7zM14.2 15.7c-.3.3-.3.8 0 1 .4.4.9.4 1.2 0l4.4-4.1c.3-.3.3-.9 0-1.2l-4.4-4.2a.8.8 0 0 0-1.2 0c-.3.3-.3.8 0 1.1L18 12l-3.8 3.7z"/></g></svg>',
        'spell-check': '<svg width="24" height="24"><path d="M6 8v3H5V5c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h2c.3 0 .5.1.7.3.2.2.3.4.3.7v6H8V8H6zm0-3v2h2V5H6zm13 0h-3v5h3v1h-3a1 1 0 0 1-.7-.3 1 1 0 0 1-.3-.7V5c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h3v1zm-5 1.5l-.1.7c-.1.2-.3.3-.6.3.3 0 .5.1.6.3l.1.7V10c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3h-3V4h3c.3 0 .5.1.7.3.2.2.3.4.3.7v1.5zM13 10V8h-2v2h2zm0-3V5h-2v2h2zm3 5l1 1-6.5 7L7 15.5l1.3-1 2.2 2.2L16 12z" fill-rule="evenodd"/></svg>',
        'strike-through': '<svg width="24" height="24"><g fill-rule="evenodd"><path d="M15.6 8.5c-.5-.7-1-1.1-1.3-1.3-.6-.4-1.3-.6-2-.6-2.7 0-2.8 1.7-2.8 2.1 0 1.6 1.8 2 3.2 2.3 4.4.9 4.6 2.8 4.6 3.9 0 1.4-.7 4.1-5 4.1A6.2 6.2 0 0 1 7 16.4l1.5-1.1c.4.6 1.6 2 3.7 2 1.6 0 2.5-.4 3-1.2.4-.8.3-2-.8-2.6-.7-.4-1.6-.7-2.9-1-1-.2-3.9-.8-3.9-3.6C7.6 6 10.3 5 12.4 5c2.9 0 4.2 1.6 4.7 2.4l-1.5 1.1z"/><path d="M5 11h14a1 1 0 0 1 0 2H5a1 1 0 0 1 0-2z" fill-rule="nonzero"/></g></svg>',
        'subscript': '<svg width="24" height="24"><path d="M10.4 10l4.6 4.6-1.4 1.4L9 11.4 4.4 16 3 14.6 7.6 10 3 5.4 4.4 4 9 8.6 13.6 4 15 5.4 10.4 10zM21 19h-5v-1l1-.8 1.7-1.6c.3-.4.5-.8.5-1.2 0-.3 0-.6-.2-.7-.2-.2-.5-.3-.9-.3a2 2 0 0 0-.8.2l-.7.3-.4-1.1 1-.6 1.2-.2c.8 0 1.4.3 1.8.7.4.4.6.9.6 1.5s-.2 1.1-.5 1.6a8 8 0 0 1-1.3 1.3l-.6.6h2.6V19z" fill-rule="nonzero"/></svg>',
        'superscript': '<svg width="24" height="24"><path d="M15 9.4L10.4 14l4.6 4.6-1.4 1.4L9 15.4 4.4 20 3 18.6 7.6 14 3 9.4 4.4 8 9 12.6 13.6 8 15 9.4zm5.9 1.6h-5v-1l1-.8 1.7-1.6c.3-.5.5-.9.5-1.3 0-.3 0-.5-.2-.7-.2-.2-.5-.3-.9-.3l-.8.2-.7.4-.4-1.2c.2-.2.5-.4 1-.5.3-.2.8-.2 1.2-.2.8 0 1.4.2 1.8.6.4.4.6 1 .6 1.6 0 .5-.2 1-.5 1.5l-1.3 1.4-.6.5h2.6V11z" fill-rule="nonzero"/></svg>',
        'table-cell-properties': '<svg width="24" height="24"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14zm-8 9H5v5h6v-5zm8 0h-6v5h6v-5zm-8-7H5v5h6V6z"/></svg>',
        'table-cell-select-all': '<svg width="24" height="24"><g fill-rule="evenodd"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14zm0 2H5v12h14V6z"/><path d="M13 6v5h6v2h-6v5h-2v-5H5v-2h6V6h2z" opacity=".2"/></g></svg>',
        'table-cell-select-inner': '<svg width="24" height="24"><g fill-rule="evenodd"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14zm0 2H5v12h14V6z" opacity=".2"/><path d="M13 6v5h6v2h-6v5h-2v-5H5v-2h6V6h2z"/></g></svg>',
        'table-delete-column': '<svg width="24" height="24"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14zm-4 4h-2V6h-2v2H9V6H5v12h4v-2h2v2h2v-2h2v2h4V6h-4v2zm.3.5l1 1.2-3 2.3 3 2.3-1 1.2L12 13l-3.3 2.6-1-1.2 3-2.3-3-2.3 1-1.2L12 11l3.3-2.5z"/></svg>',
        'table-delete-row': '<svg width="24" height="24"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14zm0 2H5v3h2.5v2H5v2h2.5v2H5v3h14v-3h-2.5v-2H19v-2h-2.5V9H19V6zm-4.7 1.8l1.2 1L13 12l2.6 3.3-1.2 1-2.3-3-2.3 3-1.2-1L11 12 8.5 8.7l1.2-1 2.3 3 2.3-3z"/></svg>',
        'table-delete-table': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14zM5 6v12h14V6H5z"/><path d="M14.4 8.6l1 1-2.3 2.4 2.3 2.4-1 1-2.4-2.3-2.4 2.3-1-1 2.3-2.4-2.3-2.4 1-1 2.4 2.3z"/></g></svg>',
        'table-insert-column-after': '<svg width="24" height="24"><path fill-rule="nonzero" d="M20 4c.6 0 1 .4 1 1v2a1 1 0 0 1-2 0V6h-8v12h8v-1a1 1 0 0 1 2 0v2c0 .5-.4 1-.9 1H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h15zM9 13H5v5h4v-5zm7-5c.5 0 1 .4 1 .9V11h2a1 1 0 0 1 .1 2H17v2a1 1 0 0 1-2 .1V13h-2a1 1 0 0 1-.1-2H15V9c0-.6.4-1 1-1zM9 6H5v5h4V6z"/></svg>',
        'table-insert-column-before': '<svg width="24" height="24"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a1 1 0 0 1-1-1v-2a1 1 0 0 1 2 0v1h8V6H5v1a1 1 0 1 1-2 0V5c0-.6.4-1 1-1h15zm0 9h-4v5h4v-5zM8 8c.5 0 1 .4 1 .9V11h2a1 1 0 0 1 .1 2H9v2a1 1 0 0 1-2 .1V13H5a1 1 0 0 1-.1-2H7V9c0-.6.4-1 1-1zm11-2h-4v5h4V6z"/></svg>',
        'table-insert-row-above': '<svg width="24" height="24"><path fill-rule="nonzero" d="M6 4a1 1 0 1 1 0 2H5v6h14V6h-1a1 1 0 0 1 0-2h2c.6 0 1 .4 1 1v13a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5c0-.6.4-1 1-1h2zm5 10H5v4h6v-4zm8 0h-6v4h6v-4zM12 3c.5 0 1 .4 1 .9V6h2a1 1 0 0 1 0 2h-2v2a1 1 0 0 1-2 .1V8H9a1 1 0 0 1 0-2h2V4c0-.6.4-1 1-1z"/></svg>',
        'table-insert-row-after': '<svg width="24" height="24"><path fill-rule="nonzero" d="M12 13c.5 0 1 .4 1 .9V16h2a1 1 0 0 1 .1 2H13v2a1 1 0 0 1-2 .1V18H9a1 1 0 0 1-.1-2H11v-2c0-.6.4-1 1-1zm6 7a1 1 0 0 1 0-2h1v-6H5v6h1a1 1 0 0 1 0 2H4a1 1 0 0 1-1-1V6c0-1.1.9-2 2-2h14a2 2 0 0 1 2 2v13c0 .5-.4 1-.9 1H18zM11 6H5v4h6V6zm8 0h-6v4h6V6z"/></svg>',
        'table-left-header': '<svg width="24" height="24"><path d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14zm0 9h-4v5h4v-5zm-6 0H9v5h4v-5zm0-7H9v5h4V6zm6 0h-4v5h4V6z"/></svg>',
        'table-merge-cells': '<svg width="24" height="24"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14zM5 15.5V18h3v-2.5H5zm14-5h-9V18h9v-7.5zM19 6h-4v2.5h4V6zM8 6H5v2.5h3V6zm5 0h-3v2.5h3V6zm-8 7.5h3v-3H5v3z"/></svg>',
        'table-row-properties': '<svg width="24" height="24"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14zM5 15v3h6v-3H5zm14 0h-6v3h6v-3zm0-9h-6v3h6V6zM5 9h6V6H5v3z"/></svg>',
        'table-split-cells': '<svg width="24" height="24"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14zM8 15.5H5V18h3v-2.5zm11-5h-9V18h9v-7.5zm-2.5 1l1 1-2 2 2 2-1 1-2-2-2 2-1-1 2-2-2-2 1-1 2 2 2-2zm-8.5-1H5v3h3v-3zM19 6h-4v2.5h4V6zM8 6H5v2.5h3V6zm5 0h-3v2.5h3V6z"/></svg>',
        'table-top-header': '<svg width="24" height="24"><path d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14zm-8 11H5v3h6v-3zm8 0h-6v3h6v-3zm0-5h-6v3h6v-3zM5 13h6v-3H5v3z"/></svg>',
        'table': '<svg width="24" height="24"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14zM5 14v4h6v-4H5zm14 0h-6v4h6v-4zm0-6h-6v4h6V8zM5 12h6V8H5v4z"/></svg>',
        'template': '<svg width="24" height="24"><path d="M19 19v-1H5v1h14zM9 16v-4a5 5 0 1 1 6 0v4h4a2 2 0 0 1 2 2v3H3v-3c0-1.1.9-2 2-2h4zm4 0v-5l.8-.6a3 3 0 1 0-3.6 0l.8.6v5h2z" fill-rule="nonzero"/></svg>',
        'temporary-placeholder': '<svg width="24" height="24"><g fill-rule="evenodd"><path d="M9 7.6V6h2.5V4.5a.5.5 0 1 1 1 0V6H15v1.6a8 8 0 1 1-6 0zm-2.6 5.3a.5.5 0 0 0 .3.6c.3 0 .6 0 .6-.3l.1-.2a5 5 0 0 1 3.3-2.8c.3-.1.4-.4.4-.6-.1-.3-.4-.5-.6-.4a6 6 0 0 0-4.1 3.7z"/><circle cx="14" cy="4" r="1"/><circle cx="12" cy="2" r="1"/><circle cx="10" cy="4" r="1"/></g></svg>',
        'text-color': '<svg width="24" height="24"><g fill-rule="evenodd"><path id="tox-icon-text-color__color" d="M3 18h18v3H3z"/><path d="M8.7 16h-.8a.5.5 0 0 1-.5-.6l2.7-9c.1-.3.3-.4.5-.4h2.8c.2 0 .4.1.5.4l2.7 9a.5.5 0 0 1-.5.6h-.8a.5.5 0 0 1-.4-.4l-.7-2.2c0-.3-.3-.4-.5-.4h-3.4c-.2 0-.4.1-.5.4l-.7 2.2c0 .3-.2.4-.4.4zm2.6-7.6l-.6 2a.5.5 0 0 0 .5.6h1.6a.5.5 0 0 0 .5-.6l-.6-2c0-.3-.3-.4-.5-.4h-.4c-.2 0-.4.1-.5.4z"/></g></svg>',
        'toc': '<svg width="24" height="24"><path d="M5 5c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 1 1 0-2zm3 0h11c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 1 1 0-2zm-3 8c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2zm3 0h11c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 0 1 0-2zm0-4c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 1 1 0-2zm3 0h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm-3 8c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2zm3 0h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2z" fill-rule="evenodd"/></svg>',
        'translate': '<svg width="24" height="24"><path d="M12.7 14.3l-.3.7-.4.7-2.2-2.2-3.1 3c-.3.4-.8.4-1 0a.7.7 0 0 1 0-1l3.1-3A12.4 12.4 0 0 1 6.7 9H8a10.1 10.1 0 0 0 1.7 2.4c.5-.5 1-1.1 1.4-1.8l.9-2H4.7a.7.7 0 1 1 0-1.5h4.4v-.7c0-.4.3-.8.7-.8.4 0 .7.4.7.8v.7H15c.4 0 .8.3.8.7 0 .4-.4.8-.8.8h-1.4a12.3 12.3 0 0 1-1 2.4 13.5 13.5 0 0 1-1.7 2.3l1.9 1.8zm4.3-3l2.7 7.3a.5.5 0 0 1-.4.7 1 1 0 0 1-1-.7l-.6-1.5h-3.4l-.6 1.5a1 1 0 0 1-1 .7.5.5 0 0 1-.4-.7l2.7-7.4a1 1 0 1 1 2 0zm-2.2 4.4h2.4L16 12.5l-1.2 3.2z" fill-rule="evenodd"/></svg>',
        'underline': '<svg width="24" height="24"><path d="M16 5c.6 0 1 .4 1 1v5.5a4 4 0 0 1-.4 1.8l-1 1.4a5.3 5.3 0 0 1-5.5 1 5 5 0 0 1-1.6-1c-.5-.4-.8-.9-1.1-1.4a4 4 0 0 1-.4-1.8V6c0-.6.4-1 1-1s1 .4 1 1v5.5c0 .3 0 .6.2 1l.6.7a3.3 3.3 0 0 0 2.2.8 3.4 3.4 0 0 0 2.2-.8c.3-.2.4-.5.6-.8l.2-.9V6c0-.6.4-1 1-1zM8 17h8c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 0 1 0-2z" fill-rule="evenodd"/></svg>',
        'undo': '<svg width="24" height="24"><path d="M6.4 8H12c3.7 0 6.2 2 6.8 5.1.6 2.7-.4 5.6-2.3 6.8a1 1 0 0 1-1-1.8c1.1-.6 1.8-2.7 1.4-4.6-.5-2.1-2.1-3.5-4.9-3.5H6.4l3.3 3.3a1 1 0 1 1-1.4 1.4l-5-5a1 1 0 0 1 0-1.4l5-5a1 1 0 0 1 1.4 1.4L6.4 8z" fill-rule="nonzero"/></svg>',
        'unlink': '<svg width="24" height="24"><path d="M6.2 12.3a1 1 0 0 1 1.4 1.4l-2 2a2 2 0 1 0 2.6 2.8l4.8-4.8a1 1 0 0 0 0-1.4 1 1 0 1 1 1.4-1.3 2.9 2.9 0 0 1 0 4L9.6 20a3.9 3.9 0 0 1-5.5-5.5l2-2zm11.6-.6a1 1 0 0 1-1.4-1.4l2.1-2a2 2 0 1 0-2.7-2.8L11 10.3a1 1 0 0 0 0 1.4A1 1 0 1 1 9.6 13a2.9 2.9 0 0 1 0-4L14.4 4a3.9 3.9 0 0 1 5.5 5.5l-2 2zM7.6 6.3a.8.8 0 0 1-1 1.1L3.3 4.2a.7.7 0 1 1 1-1l3.2 3.1zM5.1 8.6a.8.8 0 0 1 0 1.5H3a.8.8 0 0 1 0-1.5H5zm5-3.5a.8.8 0 0 1-1.5 0V3a.8.8 0 0 1 1.5 0V5zm6 11.8a.8.8 0 0 1 1-1l3.2 3.2a.8.8 0 0 1-1 1L16 17zm-2.2 2a.8.8 0 0 1 1.5 0V21a.8.8 0 0 1-1.5 0V19zm5-3.5a.7.7 0 1 1 0-1.5H21a.8.8 0 0 1 0 1.5H19z" fill-rule="nonzero"/></svg>',
        'unlock': '<svg width="24" height="24"><path d="M16 5c.8 0 1.5.3 2.1.9.6.6.9 1.3.9 2.1v3h-2V8a1 1 0 0 0-.3-.7A1 1 0 0 0 16 7h-2a1 1 0 0 0-.7.3 1 1 0 0 0-.3.7v3h.3c.2 0 .3 0 .5.2l.2.6v7.4c0 .3 0 .4-.2.6l-.6.2H4.8c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6v-7.4c0-.3 0-.4.2-.6l.5-.2H11V8c0-.8.3-1.5.9-2.1.6-.6 1.3-.9 2.1-.9h2z" fill-rule="evenodd"/></svg>',
        'unordered-list': '<svg width="24" height="24"><path d="M11 5h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0 6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0 6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zM4.5 6c0-.4.1-.8.4-1 .3-.4.7-.5 1.1-.5.4 0 .8.1 1 .4.4.3.5.7.5 1.1 0 .4-.1.8-.4 1-.3.4-.7.5-1.1.5-.4 0-.8-.1-1-.4-.4-.3-.5-.7-.5-1.1zm0 6c0-.4.1-.8.4-1 .3-.4.7-.5 1.1-.5.4 0 .8.1 1 .4.4.3.5.7.5 1.1 0 .4-.1.8-.4 1-.3.4-.7.5-1.1.5-.4 0-.8-.1-1-.4-.4-.3-.5-.7-.5-1.1zm0 6c0-.4.1-.8.4-1 .3-.4.7-.5 1.1-.5.4 0 .8.1 1 .4.4.3.5.7.5 1.1 0 .4-.1.8-.4 1-.3.4-.7.5-1.1.5-.4 0-.8-.1-1-.4-.4-.3-.5-.7-.5-1.1z" fill-rule="evenodd"/></svg>',
        'unselected': '<svg width="24" height="24"><path fill-rule="nonzero" d="M6 4h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2zm0 1a1 1 0 0 0-1 1v12c0 .6.4 1 1 1h12c.6 0 1-.4 1-1V6c0-.6-.4-1-1-1H6z"/></svg>',
        'upload': '<svg width="24" height="24"><path d="M18 19v-2a1 1 0 0 1 2 0v3c0 .6-.4 1-1 1H5a1 1 0 0 1-1-1v-3a1 1 0 0 1 2 0v2h12zM11 6.4L8.7 8.7a1 1 0 0 1-1.4-1.4l4-4a1 1 0 0 1 1.4 0l4 4a1 1 0 1 1-1.4 1.4L13 6.4V16a1 1 0 0 1-2 0V6.4z" fill-rule="nonzero"/></svg>',
        'user': '<svg width="24" height="24"><path d="M12 24a12 12 0 1 1 0-24 12 12 0 0 1 0 24zm-8.7-5.3a11 11 0 0 0 17.4 0C19.4 16.3 14.6 15 12 15c-2.6 0-7.4 1.3-8.7 3.7zM12 13c2.2 0 4-2 4-4.5S14.2 4 12 4 8 6 8 8.5 9.8 13 12 13z" fill-rule="nonzero"/></svg>',
        'visualblocks': '<svg width="24" height="24"><path d="M9 19v2H7v-2h2zm-4 0v2a2 2 0 0 1-2-2h2zm8 0v2h-2v-2h2zm8 0a2 2 0 0 1-2 2v-2h2zm-4 0v2h-2v-2h2zM15 7a1 1 0 0 1 0 2v7a1 1 0 0 1-2 0V9h-1v7a1 1 0 0 1-2 0v-4a2.5 2.5 0 0 1-.2-5H15zM5 15v2H3v-2h2zm16 0v2h-2v-2h2zM5 11v2H3v-2h2zm16 0v2h-2v-2h2zM5 7v2H3V7h2zm16 0v2h-2V7h2zM5 3v2H3c0-1.1.9-2 2-2zm8 0v2h-2V3h2zm6 0a2 2 0 0 1 2 2h-2V3zM9 3v2H7V3h2zm8 0v2h-2V3h2z" fill-rule="evenodd"/></svg>',
        'visualchars': '<svg width="24" height="24"><path d="M10 5h7a1 1 0 0 1 0 2h-1v11a1 1 0 0 1-2 0V7h-2v11a1 1 0 0 1-2 0v-6c-.5 0-1 0-1.4-.3A3.4 3.4 0 0 1 6.8 10a3.3 3.3 0 0 1 0-2.8 3.4 3.4 0 0 1 1.8-1.8L10 5z" fill-rule="evenodd"/></svg>',
        'warning': '<svg width="24" height="24"><path d="M19.8 18.3c.2.5.3.9 0 1.2-.1.3-.5.5-1 .5H5.2c-.5 0-.9-.2-1-.5-.3-.3-.2-.7 0-1.2L11 4.7l.5-.5.5-.2c.2 0 .3 0 .5.2.2 0 .3.3.5.5l6.8 13.6zM12 18c.3 0 .5-.1.7-.3.2-.2.3-.4.3-.7a1 1 0 0 0-.3-.7 1 1 0 0 0-.7-.3 1 1 0 0 0-.7.3 1 1 0 0 0-.3.7c0 .3.1.5.3.7.2.2.4.3.7.3zm.7-3l.3-4a1 1 0 0 0-.3-.7 1 1 0 0 0-.7-.3 1 1 0 0 0-.7.3 1 1 0 0 0-.3.7l.3 4h1.4z" fill-rule="evenodd"/></svg>',
        'zoom-in': '<svg width="24" height="24"><path d="M16 17.3a8 8 0 1 1 1.4-1.4l4.3 4.4a1 1 0 0 1-1.4 1.4l-4.4-4.3zm-5-.3a6 6 0 1 0 0-12 6 6 0 0 0 0 12zm-1-9a1 1 0 0 1 2 0v6a1 1 0 0 1-2 0V8zm-2 4a1 1 0 0 1 0-2h6a1 1 0 0 1 0 2H8z" fill-rule="nonzero"/></svg>',
        'zoom-out': '<svg width="24" height="24"><path d="M16 17.3a8 8 0 1 1 1.4-1.4l4.3 4.4a1 1 0 0 1-1.4 1.4l-4.4-4.3zm-5-.3a6 6 0 1 0 0-12 6 6 0 0 0 0 12zm-3-5a1 1 0 0 1 0-2h6a1 1 0 0 1 0 2H8z" fill-rule="nonzero"/></svg>'
      };
    };

    var isContentCssSkinName = function (url) {
      return /^[a-z0-9\-]+$/i.test(url);
    };
    var getContentCssUrls = function (editor) {
      var contentCss = Settings.getContentCss(editor);
      var skinUrl = editor.editorManager.baseURL + '/skins/content';
      var suffix = editor.editorManager.suffix;
      var contentCssFile = 'content' + suffix + '.css';
      var inline = editor.inline === true;
      return map(contentCss, function (url) {
        if (isContentCssSkinName(url) && !inline) {
          return skinUrl + '/' + url + '/' + contentCssFile;
        } else {
          return editor.documentBaseURI.toAbsolute(url);
        }
      });
    };
    var appendContentCssFromSettings = function (editor) {
      editor.contentCSS = editor.contentCSS.concat(getContentCssUrls(editor));
    };

    function BookmarkManager(selection) {
      return {
        getBookmark: curry(Bookmarks.getBookmark, selection),
        moveToBookmark: curry(Bookmarks.moveToBookmark, selection)
      };
    }
    (function (BookmarkManager) {
      BookmarkManager.isBookmarkNode = Bookmarks.isBookmarkNode;
    }(BookmarkManager || (BookmarkManager = {})));
    var BookmarkManager$1 = BookmarkManager;

    var isXYWithinRange = function (clientX, clientY, range) {
      if (range.collapsed) {
        return false;
      }
      if (Env.browser.isIE() && range.startOffset === range.endOffset - 1 && range.startContainer === range.endContainer) {
        var elm = range.startContainer.childNodes[range.startOffset];
        if (NodeType.isElement(elm)) {
          return exists(elm.getClientRects(), function (rect) {
            return containsXY(rect, clientX, clientY);
          });
        }
      }
      return exists(range.getClientRects(), function (rect) {
        return containsXY(rect, clientX, clientY);
      });
    };
    var RangePoint = { isXYWithinRange: isXYWithinRange };

    var VK = {
      BACKSPACE: 8,
      DELETE: 46,
      DOWN: 40,
      ENTER: 13,
      LEFT: 37,
      RIGHT: 39,
      SPACEBAR: 32,
      TAB: 9,
      UP: 38,
      END: 35,
      HOME: 36,
      modifierPressed: function (e) {
        return e.shiftKey || e.ctrlKey || e.altKey || this.metaKeyPressed(e);
      },
      metaKeyPressed: function (e) {
        return Env.mac ? e.metaKey : e.ctrlKey && !e.altKey;
      }
    };

    var isContentEditableFalse$6 = NodeType.isContentEditableFalse;
    var isContentEditableTrue$2 = NodeType.isContentEditableTrue;
    var getContentEditableRoot = function (root, node) {
      while (node && node !== root) {
        if (isContentEditableTrue$2(node) || isContentEditableFalse$6(node)) {
          return node;
        }
        node = node.parentNode;
      }
      return null;
    };
    var ControlSelection = function (selection, editor) {
      var dom = editor.dom, each = Tools.each;
      var selectedElm, selectedElmGhost, resizeHelper, resizeHandles, selectedHandle;
      var startX, startY, selectedElmX, selectedElmY, startW, startH, ratio, resizeStarted;
      var width, height;
      var editableDoc = editor.getDoc(), rootDocument = domGlobals.document;
      var abs = Math.abs, round = Math.round, rootElement = editor.getBody();
      var startScrollWidth, startScrollHeight;
      resizeHandles = {
        nw: [
          0,
          0,
          -1,
          -1
        ],
        ne: [
          1,
          0,
          1,
          -1
        ],
        se: [
          1,
          1,
          1,
          1
        ],
        sw: [
          0,
          1,
          -1,
          1
        ]
      };
      var isImage = function (elm) {
        return elm && (elm.nodeName === 'IMG' || editor.dom.is(elm, 'figure.image'));
      };
      var isEventOnImageOutsideRange = function (evt, range) {
        if (evt.type === 'longpress' || evt.type.indexOf('touch') === 0) {
          var touch = evt.touches[0];
          return isImage(evt.target) && !RangePoint.isXYWithinRange(touch.clientX, touch.clientY, range);
        } else {
          return isImage(evt.target) && !RangePoint.isXYWithinRange(evt.clientX, evt.clientY, range);
        }
      };
      var contextMenuSelectImage = function (evt) {
        var target = evt.target;
        if (isEventOnImageOutsideRange(evt, editor.selection.getRng()) && !evt.isDefaultPrevented()) {
          editor.selection.select(target);
        }
      };
      var getResizeTarget = function (elm) {
        return editor.dom.is(elm, 'figure.image') ? elm.querySelector('img') : elm;
      };
      var isResizable = function (elm) {
        var selector = Settings.getObjectResizing(editor);
        if (selector === false || Env.iOS) {
          return false;
        }
        if (typeof selector !== 'string') {
          selector = 'table,img,figure.image,div';
        }
        if (elm.getAttribute('data-mce-resize') === 'false') {
          return false;
        }
        if (elm === editor.getBody()) {
          return false;
        }
        return is(Element.fromDom(elm), selector);
      };
      var resizeGhostElement = function (e) {
        var deltaX, deltaY, proportional;
        var resizeHelperX, resizeHelperY;
        deltaX = e.screenX - startX;
        deltaY = e.screenY - startY;
        width = deltaX * selectedHandle[2] + startW;
        height = deltaY * selectedHandle[3] + startH;
        width = width < 5 ? 5 : width;
        height = height < 5 ? 5 : height;
        if (isImage(selectedElm) && Settings.getResizeImgProportional(editor) !== false) {
          proportional = !VK.modifierPressed(e);
        } else {
          proportional = VK.modifierPressed(e);
        }
        if (proportional) {
          if (abs(deltaX) > abs(deltaY)) {
            height = round(width * ratio);
            width = round(height / ratio);
          } else {
            width = round(height / ratio);
            height = round(width * ratio);
          }
        }
        dom.setStyles(getResizeTarget(selectedElmGhost), {
          width: width,
          height: height
        });
        resizeHelperX = selectedHandle.startPos.x + deltaX;
        resizeHelperY = selectedHandle.startPos.y + deltaY;
        resizeHelperX = resizeHelperX > 0 ? resizeHelperX : 0;
        resizeHelperY = resizeHelperY > 0 ? resizeHelperY : 0;
        dom.setStyles(resizeHelper, {
          left: resizeHelperX,
          top: resizeHelperY,
          display: 'block'
        });
        resizeHelper.innerHTML = width + ' &times; ' + height;
        if (selectedHandle[2] < 0 && selectedElmGhost.clientWidth <= width) {
          dom.setStyle(selectedElmGhost, 'left', selectedElmX + (startW - width));
        }
        if (selectedHandle[3] < 0 && selectedElmGhost.clientHeight <= height) {
          dom.setStyle(selectedElmGhost, 'top', selectedElmY + (startH - height));
        }
        deltaX = rootElement.scrollWidth - startScrollWidth;
        deltaY = rootElement.scrollHeight - startScrollHeight;
        if (deltaX + deltaY !== 0) {
          dom.setStyles(resizeHelper, {
            left: resizeHelperX - deltaX,
            top: resizeHelperY - deltaY
          });
        }
        if (!resizeStarted) {
          fireObjectResizeStart(editor, selectedElm, startW, startH);
          resizeStarted = true;
        }
      };
      var endGhostResize = function () {
        resizeStarted = false;
        var setSizeProp = function (name, value) {
          if (value) {
            if (selectedElm.style[name] || !editor.schema.isValid(selectedElm.nodeName.toLowerCase(), name)) {
              dom.setStyle(getResizeTarget(selectedElm), name, value);
            } else {
              dom.setAttrib(getResizeTarget(selectedElm), name, value);
            }
          }
        };
        setSizeProp('width', width);
        setSizeProp('height', height);
        dom.unbind(editableDoc, 'mousemove', resizeGhostElement);
        dom.unbind(editableDoc, 'mouseup', endGhostResize);
        if (rootDocument !== editableDoc) {
          dom.unbind(rootDocument, 'mousemove', resizeGhostElement);
          dom.unbind(rootDocument, 'mouseup', endGhostResize);
        }
        dom.remove(selectedElmGhost);
        dom.remove(resizeHelper);
        showResizeRect(selectedElm);
        fireObjectResized(editor, selectedElm, width, height);
        dom.setAttrib(selectedElm, 'style', dom.getAttrib(selectedElm, 'style'));
        editor.nodeChanged();
      };
      var showResizeRect = function (targetElm) {
        var position, targetWidth, targetHeight, e, rect;
        hideResizeRect();
        unbindResizeHandleEvents();
        position = dom.getPos(targetElm, rootElement);
        selectedElmX = position.x;
        selectedElmY = position.y;
        rect = targetElm.getBoundingClientRect();
        targetWidth = rect.width || rect.right - rect.left;
        targetHeight = rect.height || rect.bottom - rect.top;
        if (selectedElm !== targetElm) {
          selectedElm = targetElm;
          width = height = 0;
        }
        e = editor.fire('ObjectSelected', { target: targetElm });
        if (isResizable(targetElm) && !e.isDefaultPrevented()) {
          each(resizeHandles, function (handle, name) {
            var handleElm;
            var startDrag = function (e) {
              startX = e.screenX;
              startY = e.screenY;
              startW = getResizeTarget(selectedElm).clientWidth;
              startH = getResizeTarget(selectedElm).clientHeight;
              ratio = startH / startW;
              selectedHandle = handle;
              handle.startPos = {
                x: targetWidth * handle[0] + selectedElmX,
                y: targetHeight * handle[1] + selectedElmY
              };
              startScrollWidth = rootElement.scrollWidth;
              startScrollHeight = rootElement.scrollHeight;
              selectedElmGhost = selectedElm.cloneNode(true);
              dom.addClass(selectedElmGhost, 'mce-clonedresizable');
              dom.setAttrib(selectedElmGhost, 'data-mce-bogus', 'all');
              selectedElmGhost.contentEditable = false;
              selectedElmGhost.unSelectabe = true;
              dom.setStyles(selectedElmGhost, {
                left: selectedElmX,
                top: selectedElmY,
                margin: 0
              });
              selectedElmGhost.removeAttribute('data-mce-selected');
              rootElement.appendChild(selectedElmGhost);
              dom.bind(editableDoc, 'mousemove', resizeGhostElement);
              dom.bind(editableDoc, 'mouseup', endGhostResize);
              if (rootDocument !== editableDoc) {
                dom.bind(rootDocument, 'mousemove', resizeGhostElement);
                dom.bind(rootDocument, 'mouseup', endGhostResize);
              }
              resizeHelper = dom.add(rootElement, 'div', {
                'class': 'mce-resize-helper',
                'data-mce-bogus': 'all'
              }, startW + ' &times; ' + startH);
            };
            handleElm = dom.get('mceResizeHandle' + name);
            if (handleElm) {
              dom.remove(handleElm);
            }
            handleElm = dom.add(rootElement, 'div', {
              'id': 'mceResizeHandle' + name,
              'data-mce-bogus': 'all',
              'class': 'mce-resizehandle',
              'unselectable': true,
              'style': 'cursor:' + name + '-resize; margin:0; padding:0'
            });
            if (Env.ie === 11) {
              handleElm.contentEditable = false;
            }
            dom.bind(handleElm, 'mousedown', function (e) {
              e.stopImmediatePropagation();
              e.preventDefault();
              startDrag(e);
            });
            handle.elm = handleElm;
            dom.setStyles(handleElm, {
              left: targetWidth * handle[0] + selectedElmX - handleElm.offsetWidth / 2,
              top: targetHeight * handle[1] + selectedElmY - handleElm.offsetHeight / 2
            });
          });
        } else {
          hideResizeRect();
        }
        selectedElm.setAttribute('data-mce-selected', '1');
      };
      var hideResizeRect = function () {
        var name, handleElm;
        unbindResizeHandleEvents();
        if (selectedElm) {
          selectedElm.removeAttribute('data-mce-selected');
        }
        for (name in resizeHandles) {
          handleElm = dom.get('mceResizeHandle' + name);
          if (handleElm) {
            dom.unbind(handleElm);
            dom.remove(handleElm);
          }
        }
      };
      var updateResizeRect = function (e) {
        var startElm, controlElm;
        var isChildOrEqual = function (node, parent) {
          if (node) {
            do {
              if (node === parent) {
                return true;
              }
            } while (node = node.parentNode);
          }
        };
        if (resizeStarted || editor.removed) {
          return;
        }
        each(dom.select('img[data-mce-selected],hr[data-mce-selected]'), function (img) {
          img.removeAttribute('data-mce-selected');
        });
        controlElm = e.type === 'mousedown' ? e.target : selection.getNode();
        controlElm = dom.$(controlElm).closest('table,img,figure.image,hr')[0];
        if (isChildOrEqual(controlElm, rootElement)) {
          disableGeckoResize();
          startElm = selection.getStart(true);
          if (isChildOrEqual(startElm, controlElm) && isChildOrEqual(selection.getEnd(true), controlElm)) {
            showResizeRect(controlElm);
            return;
          }
        }
        hideResizeRect();
      };
      var isWithinContentEditableFalse = function (elm) {
        return isContentEditableFalse$6(getContentEditableRoot(editor.getBody(), elm));
      };
      var unbindResizeHandleEvents = function () {
        for (var name_1 in resizeHandles) {
          var handle = resizeHandles[name_1];
          if (handle.elm) {
            dom.unbind(handle.elm);
            delete handle.elm;
          }
        }
      };
      var disableGeckoResize = function () {
        try {
          editor.getDoc().execCommand('enableObjectResizing', false, false);
        } catch (ex) {
        }
      };
      editor.on('init', function () {
        disableGeckoResize();
        if (Env.browser.isIE() || Env.browser.isEdge()) {
          editor.on('mousedown click', function (e) {
            var target = e.target, nodeName = target.nodeName;
            if (!resizeStarted && /^(TABLE|IMG|HR)$/.test(nodeName) && !isWithinContentEditableFalse(target)) {
              if (e.button !== 2) {
                editor.selection.select(target, nodeName === 'TABLE');
              }
              if (e.type === 'mousedown') {
                editor.nodeChanged();
              }
            }
          });
          var handleMSControlSelect_1 = function (e) {
            var delayedSelect = function (node) {
              Delay.setEditorTimeout(editor, function () {
                return editor.selection.select(node);
              });
            };
            if (isWithinContentEditableFalse(e.target)) {
              e.preventDefault();
              delayedSelect(e.target);
              return;
            }
            if (/^(TABLE|IMG|HR)$/.test(e.target.nodeName)) {
              e.preventDefault();
              if (e.target.tagName === 'IMG') {
                delayedSelect(e.target);
              }
            }
          };
          dom.bind(rootElement, 'mscontrolselect', handleMSControlSelect_1);
          editor.on('remove', function () {
            return dom.unbind(rootElement, 'mscontrolselect', handleMSControlSelect_1);
          });
        }
        var throttledUpdateResizeRect = Delay.throttle(function (e) {
          if (!editor.composing) {
            updateResizeRect(e);
          }
        });
        editor.on('nodechange ResizeEditor ResizeWindow drop FullscreenStateChanged', throttledUpdateResizeRect);
        editor.on('keyup compositionend', function (e) {
          if (selectedElm && selectedElm.nodeName === 'TABLE') {
            throttledUpdateResizeRect(e);
          }
        });
        editor.on('hide blur', hideResizeRect);
        editor.on('contextmenu longpress', contextMenuSelectImage, true);
      });
      editor.on('remove', unbindResizeHandleEvents);
      var destroy = function () {
        selectedElm = selectedElmGhost = null;
      };
      return {
        isResizable: isResizable,
        showResizeRect: showResizeRect,
        hideResizeRect: hideResizeRect,
        updateResizeRect: updateResizeRect,
        destroy: destroy
      };
    };

    function Dimension (name, getOffset) {
      var set = function (element, h) {
        if (!isNumber(h) && !h.match(/^[0-9]+$/)) {
          throw new Error(name + '.set accepts only positive integer values. Value was ' + h);
        }
        var dom = element.dom();
        if (isSupported(dom)) {
          dom.style[name] = h + 'px';
        }
      };
      var get = function (element) {
        var r = getOffset(element);
        if (r <= 0 || r === null) {
          var css = get$4(element, name);
          return parseFloat(css) || 0;
        }
        return r;
      };
      var getOuter = get;
      var aggregate = function (element, properties) {
        return foldl(properties, function (acc, property) {
          var val = get$4(element, property);
          var value = val === undefined ? 0 : parseInt(val, 10);
          return isNaN(value) ? acc : acc + value;
        }, 0);
      };
      var max = function (element, value, properties) {
        var cumulativeInclusions = aggregate(element, properties);
        var absoluteMax = value > cumulativeInclusions ? value - cumulativeInclusions : 0;
        return absoluteMax;
      };
      return {
        set: set,
        get: get,
        getOuter: getOuter,
        aggregate: aggregate,
        max: max
      };
    }

    var api$1 = Dimension('height', function (element) {
      var dom = element.dom();
      return inBody(element) ? dom.getBoundingClientRect().height : dom.offsetHeight;
    });
    var get$8 = function (element) {
      return api$1.get(element);
    };

    var walkUp = function (navigation, doc) {
      var frame = navigation.view(doc);
      return frame.fold(constant([]), function (f) {
        var parent = navigation.owner(f);
        var rest = walkUp(navigation, parent);
        return [f].concat(rest);
      });
    };
    var pathTo = function (element, navigation) {
      var d = navigation.owner(element);
      return walkUp(navigation, d);
    };

    var view = function (doc) {
      var element = doc.dom() === domGlobals.document ? Option.none() : Option.from(doc.dom().defaultView.frameElement);
      return element.map(Element.fromDom);
    };
    var owner$1 = function (element) {
      return owner(element);
    };

    var Navigation = /*#__PURE__*/Object.freeze({
        __proto__: null,
        view: view,
        owner: owner$1
    });

    var find$3 = function (element) {
      var doc = Element.fromDom(domGlobals.document);
      var scroll = get$1(doc);
      var frames = pathTo(element, Navigation);
      var offset = viewport(element);
      var r = foldr(frames, function (b, a) {
        var loc = viewport(a);
        return {
          left: b.left + loc.left(),
          top: b.top + loc.top()
        };
      }, {
        left: 0,
        top: 0
      });
      return Position(r.left + offset.left() + scroll.left(), r.top + offset.top() + scroll.top());
    };

    var excludeFromDescend = function (element) {
      return name(element) === 'textarea';
    };
    var fireScrollIntoViewEvent = function (editor, data) {
      var scrollEvent = editor.fire('ScrollIntoView', data);
      return scrollEvent.isDefaultPrevented();
    };
    var fireAfterScrollIntoViewEvent = function (editor, data) {
      editor.fire('AfterScrollIntoView', data);
    };
    var descend = function (element, offset) {
      var children$1 = children(element);
      if (children$1.length === 0 || excludeFromDescend(element)) {
        return {
          element: element,
          offset: offset
        };
      } else if (offset < children$1.length && !excludeFromDescend(children$1[offset])) {
        return {
          element: children$1[offset],
          offset: 0
        };
      } else {
        var last = children$1[children$1.length - 1];
        if (excludeFromDescend(last)) {
          return {
            element: element,
            offset: offset
          };
        } else {
          if (name(last) === 'img') {
            return {
              element: last,
              offset: 1
            };
          } else if (isText(last)) {
            return {
              element: last,
              offset: get$7(last).length
            };
          } else {
            return {
              element: last,
              offset: children(last).length
            };
          }
        }
      }
    };
    var markerInfo = function (element, cleanupFun) {
      var pos = absolute(element);
      var height = get$8(element);
      return {
        element: element,
        bottom: pos.top() + height,
        height: height,
        pos: pos,
        cleanup: cleanupFun
      };
    };
    var createMarker = function (element, offset) {
      var startPoint = descend(element, offset);
      var span = Element.fromHtml('<span data-mce-bogus="all">' + Zwsp.ZWSP + '</span>');
      before(startPoint.element, span);
      return markerInfo(span, function () {
        return remove(span);
      });
    };
    var elementMarker = function (element) {
      return markerInfo(Element.fromDom(element), noop);
    };
    var withMarker = function (editor, f, rng, alignToTop) {
      preserveWith(editor, function (_s, _e) {
        return applyWithMarker(editor, f, rng, alignToTop);
      }, rng);
    };
    var withScrollEvents = function (editor, doc, f, marker, alignToTop) {
      var data = {
        elm: marker.element.dom(),
        alignToTop: alignToTop
      };
      if (fireScrollIntoViewEvent(editor, data)) {
        return;
      }
      var scrollTop = get$1(doc).top();
      f(doc, scrollTop, marker, alignToTop);
      fireAfterScrollIntoViewEvent(editor, data);
    };
    var applyWithMarker = function (editor, f, rng, alignToTop) {
      var body = Element.fromDom(editor.getBody());
      var doc = Element.fromDom(editor.getDoc());
      reflow(body);
      var marker = createMarker(Element.fromDom(rng.startContainer), rng.startOffset);
      withScrollEvents(editor, doc, f, marker, alignToTop);
      marker.cleanup();
    };
    var withElement = function (editor, element, f, alignToTop) {
      var doc = Element.fromDom(editor.getDoc());
      withScrollEvents(editor, doc, f, elementMarker(element), alignToTop);
    };
    var preserveWith = function (editor, f, rng) {
      var startElement = rng.startContainer;
      var startOffset = rng.startOffset;
      var endElement = rng.endContainer;
      var endOffset = rng.endOffset;
      f(Element.fromDom(startElement), Element.fromDom(endElement));
      var newRng = editor.dom.createRng();
      newRng.setStart(startElement, startOffset);
      newRng.setEnd(endElement, endOffset);
      editor.selection.setRng(rng);
    };
    var scrollToMarker = function (marker, viewHeight, alignToTop, doc) {
      var pos = marker.pos;
      if (alignToTop) {
        to(pos.left(), pos.top(), doc);
      } else {
        var y = pos.top() - viewHeight + marker.height;
        to(pos.left(), y, doc);
      }
    };
    var intoWindowIfNeeded = function (doc, scrollTop, viewHeight, marker, alignToTop) {
      var viewportBottom = viewHeight + scrollTop;
      var markerTop = marker.pos.top();
      var markerBottom = marker.bottom;
      var largerThanViewport = markerBottom - markerTop >= viewHeight;
      if (markerTop < scrollTop) {
        scrollToMarker(marker, viewHeight, alignToTop !== false, doc);
      } else if (markerTop > viewportBottom) {
        var align = largerThanViewport ? alignToTop !== false : alignToTop === true;
        scrollToMarker(marker, viewHeight, align, doc);
      } else if (markerBottom > viewportBottom && !largerThanViewport) {
        scrollToMarker(marker, viewHeight, alignToTop === true, doc);
      }
    };
    var intoWindow = function (doc, scrollTop, marker, alignToTop) {
      var viewHeight = doc.dom().defaultView.innerHeight;
      intoWindowIfNeeded(doc, scrollTop, viewHeight, marker, alignToTop);
    };
    var intoFrame = function (doc, scrollTop, marker, alignToTop) {
      var frameViewHeight = doc.dom().defaultView.innerHeight;
      intoWindowIfNeeded(doc, scrollTop, frameViewHeight, marker, alignToTop);
      var op = find$3(marker.element);
      var viewportBounds = getBounds(domGlobals.window);
      if (op.top() < viewportBounds.y()) {
        intoView(marker.element, alignToTop !== false);
      } else if (op.top() > viewportBounds.bottom()) {
        intoView(marker.element, alignToTop === true);
      }
    };
    var rangeIntoWindow = function (editor, rng, alignToTop) {
      return withMarker(editor, intoWindow, rng, alignToTop);
    };
    var elementIntoWindow = function (editor, element, alignToTop) {
      return withElement(editor, element, intoWindow, alignToTop);
    };
    var rangeIntoFrame = function (editor, rng, alignToTop) {
      return withMarker(editor, intoFrame, rng, alignToTop);
    };
    var elementIntoFrame = function (editor, element, alignToTop) {
      return withElement(editor, element, intoFrame, alignToTop);
    };
    var elementIntoView = function (editor, element, alignToTop) {
      var scroller = editor.inline ? elementIntoWindow : elementIntoFrame;
      scroller(editor, element, alignToTop);
    };
    var rangeIntoView = function (editor, rng, alignToTop) {
      var scroller = editor.inline ? rangeIntoWindow : rangeIntoFrame;
      scroller(editor, rng, alignToTop);
    };
    var ScrollIntoView = {
      scrollElementIntoView: elementIntoView,
      scrollRangeIntoView: rangeIntoView
    };

    var hasCeProperty = function (node) {
      return NodeType.isContentEditableTrue(node) || NodeType.isContentEditableFalse(node);
    };
    var findParent = function (node, rootNode, predicate) {
      while (node && node !== rootNode) {
        if (predicate(node)) {
          return node;
        }
        node = node.parentNode;
      }
      return null;
    };
    var findClosestIeRange = function (clientX, clientY, doc) {
      var element, rng, rects;
      element = doc.elementFromPoint(clientX, clientY);
      rng = doc.body.createTextRange();
      if (!element || element.tagName === 'HTML') {
        element = doc.body;
      }
      rng.moveToElementText(element);
      rects = Tools.toArray(rng.getClientRects());
      rects = rects.sort(function (a, b) {
        a = Math.abs(Math.max(a.top - clientY, a.bottom - clientY));
        b = Math.abs(Math.max(b.top - clientY, b.bottom - clientY));
        return a - b;
      });
      if (rects.length > 0) {
        clientY = (rects[0].bottom + rects[0].top) / 2;
        try {
          rng.moveToPoint(clientX, clientY);
          rng.collapse(true);
          return rng;
        } catch (ex) {
        }
      }
      return null;
    };
    var moveOutOfContentEditableFalse = function (rng, rootNode) {
      var parentElement = rng && rng.parentElement ? rng.parentElement() : null;
      return NodeType.isContentEditableFalse(findParent(parentElement, rootNode, hasCeProperty)) ? null : rng;
    };
    var fromPoint$1 = function (clientX, clientY, doc) {
      var rng, point;
      var pointDoc = doc;
      if (pointDoc.caretPositionFromPoint) {
        point = pointDoc.caretPositionFromPoint(clientX, clientY);
        if (point) {
          rng = doc.createRange();
          rng.setStart(point.offsetNode, point.offset);
          rng.collapse(true);
        }
      } else if (doc.caretRangeFromPoint) {
        rng = doc.caretRangeFromPoint(clientX, clientY);
      } else if (pointDoc.body.createTextRange) {
        rng = pointDoc.body.createTextRange();
        try {
          rng.moveToPoint(clientX, clientY);
          rng.collapse(true);
        } catch (ex) {
          rng = findClosestIeRange(clientX, clientY, doc);
        }
        return moveOutOfContentEditableFalse(rng, doc.body);
      }
      return rng;
    };
    var CaretRangeFromPoint = { fromPoint: fromPoint$1 };

    var processRanges = function (editor, ranges) {
      return map(ranges, function (range) {
        var evt = editor.fire('GetSelectionRange', { range: range });
        return evt.range !== range ? evt.range : range;
      });
    };
    var EventProcessRanges = { processRanges: processRanges };

    var fromElements = function (elements, scope) {
      var doc = scope || domGlobals.document;
      var fragment = doc.createDocumentFragment();
      each(elements, function (element) {
        fragment.appendChild(element.dom());
      });
      return Element.fromDom(fragment);
    };

    var dropLast = function (xs) {
      return xs.slice(0, -1);
    };
    var parentsUntil$1 = function (start, root, predicate) {
      if (contains$2(root, start)) {
        return dropLast(parents(start, function (elm) {
          return predicate(elm) || eq(elm, root);
        }));
      } else {
        return [];
      }
    };
    var parents$1 = function (start, root) {
      return parentsUntil$1(start, root, constant(false));
    };
    var parentsAndSelf = function (start, root) {
      return [start].concat(parents$1(start, root));
    };
    var Parents = {
      parentsUntil: parentsUntil$1,
      parents: parents$1,
      parentsAndSelf: parentsAndSelf
    };

    var getStartNode = function (rng) {
      var sc = rng.startContainer, so = rng.startOffset;
      if (NodeType.isText(sc)) {
        return so === 0 ? Option.some(Element.fromDom(sc)) : Option.none();
      } else {
        return Option.from(sc.childNodes[so]).map(Element.fromDom);
      }
    };
    var getEndNode = function (rng) {
      var ec = rng.endContainer, eo = rng.endOffset;
      if (NodeType.isText(ec)) {
        return eo === ec.data.length ? Option.some(Element.fromDom(ec)) : Option.none();
      } else {
        return Option.from(ec.childNodes[eo - 1]).map(Element.fromDom);
      }
    };
    var getFirstChildren = function (node) {
      return firstChild(node).fold(constant([node]), function (child) {
        return [node].concat(getFirstChildren(child));
      });
    };
    var getLastChildren = function (node) {
      return lastChild(node).fold(constant([node]), function (child) {
        if (name(child) === 'br') {
          return prevSibling(child).map(function (sibling) {
            return [node].concat(getLastChildren(sibling));
          }).getOr([]);
        } else {
          return [node].concat(getLastChildren(child));
        }
      });
    };
    var hasAllContentsSelected = function (elm, rng) {
      return lift2(getStartNode(rng), getEndNode(rng), function (startNode, endNode) {
        var start = find(getFirstChildren(elm), curry(eq, startNode));
        var end = find(getLastChildren(elm), curry(eq, endNode));
        return start.isSome() && end.isSome();
      }).getOr(false);
    };
    var moveEndPoint$1 = function (dom, rng, node, start) {
      var root = node, walker = new TreeWalker(node, root);
      var nonEmptyElementsMap = dom.schema.getNonEmptyElements();
      do {
        if (node.nodeType === 3 && Tools.trim(node.nodeValue).length !== 0) {
          if (start) {
            rng.setStart(node, 0);
          } else {
            rng.setEnd(node, node.nodeValue.length);
          }
          return;
        }
        if (nonEmptyElementsMap[node.nodeName] && !/^(TD|TH)$/.test(node.nodeName)) {
          if (start) {
            rng.setStartBefore(node);
          } else {
            if (node.nodeName === 'BR') {
              rng.setEndBefore(node);
            } else {
              rng.setEndAfter(node);
            }
          }
          return;
        }
      } while (node = start ? walker.next() : walker.prev());
      if (root.nodeName === 'BODY') {
        if (start) {
          rng.setStart(root, 0);
        } else {
          rng.setEnd(root, root.childNodes.length);
        }
      }
    };
    var hasAnyRanges = function (editor) {
      var sel = editor.selection.getSel();
      return sel && sel.rangeCount > 0;
    };

    var tableModel = Immutable('element', 'width', 'rows');
    var tableRow = Immutable('element', 'cells');
    var cellPosition = Immutable('x', 'y');
    var getSpan = function (td, key) {
      var value = parseInt(get$3(td, key), 10);
      return isNaN(value) ? 1 : value;
    };
    var fillout = function (table, x, y, tr, td) {
      var rowspan = getSpan(td, 'rowspan');
      var colspan = getSpan(td, 'colspan');
      var rows = table.rows();
      for (var y2 = y; y2 < y + rowspan; y2++) {
        if (!rows[y2]) {
          rows[y2] = tableRow(deep(tr), []);
        }
        for (var x2 = x; x2 < x + colspan; x2++) {
          var cells = rows[y2].cells();
          cells[x2] = y2 === y && x2 === x ? td : shallow(td);
        }
      }
    };
    var cellExists = function (table, x, y) {
      var rows = table.rows();
      var cells = rows[y] ? rows[y].cells() : [];
      return !!cells[x];
    };
    var skipCellsX = function (table, x, y) {
      while (cellExists(table, x, y)) {
        x++;
      }
      return x;
    };
    var getWidth = function (rows) {
      return foldl(rows, function (acc, row) {
        return row.cells().length > acc ? row.cells().length : acc;
      }, 0);
    };
    var findElementPos = function (table, element) {
      var rows = table.rows();
      for (var y = 0; y < rows.length; y++) {
        var cells = rows[y].cells();
        for (var x = 0; x < cells.length; x++) {
          if (eq(cells[x], element)) {
            return Option.some(cellPosition(x, y));
          }
        }
      }
      return Option.none();
    };
    var extractRows = function (table, sx, sy, ex, ey) {
      var newRows = [];
      var rows = table.rows();
      for (var y = sy; y <= ey; y++) {
        var cells = rows[y].cells();
        var slice = sx < ex ? cells.slice(sx, ex + 1) : cells.slice(ex, sx + 1);
        newRows.push(tableRow(rows[y].element(), slice));
      }
      return newRows;
    };
    var subTable = function (table, startPos, endPos) {
      var sx = startPos.x(), sy = startPos.y();
      var ex = endPos.x(), ey = endPos.y();
      var newRows = sy < ey ? extractRows(table, sx, sy, ex, ey) : extractRows(table, sx, ey, ex, sy);
      return tableModel(table.element(), getWidth(newRows), newRows);
    };
    var createDomTable = function (table, rows) {
      var tableElement = shallow(table.element());
      var tableBody = Element.fromTag('tbody');
      append$1(tableBody, rows);
      append(tableElement, tableBody);
      return tableElement;
    };
    var modelRowsToDomRows = function (table) {
      return map(table.rows(), function (row) {
        var cells = map(row.cells(), function (cell) {
          var td = deep(cell);
          remove$1(td, 'colspan');
          remove$1(td, 'rowspan');
          return td;
        });
        var tr = shallow(row.element());
        append$1(tr, cells);
        return tr;
      });
    };
    var fromDom$1 = function (tableElm) {
      var table = tableModel(shallow(tableElm), 0, []);
      each(descendants$1(tableElm, 'tr'), function (tr, y) {
        each(descendants$1(tr, 'td,th'), function (td, x) {
          fillout(table, skipCellsX(table, x, y), y, tr, td);
        });
      });
      return tableModel(table.element(), getWidth(table.rows()), table.rows());
    };
    var toDom = function (table) {
      return createDomTable(table, modelRowsToDomRows(table));
    };
    var subsection = function (table, startElement, endElement) {
      return findElementPos(table, startElement).bind(function (startPos) {
        return findElementPos(table, endElement).map(function (endPos) {
          return subTable(table, startPos, endPos);
        });
      });
    };
    var SimpleTableModel = {
      fromDom: fromDom$1,
      toDom: toDom,
      subsection: subsection
    };

    var getRanges = function (selection) {
      var ranges = [];
      if (selection) {
        for (var i = 0; i < selection.rangeCount; i++) {
          ranges.push(selection.getRangeAt(i));
        }
      }
      return ranges;
    };
    var getSelectedNodes = function (ranges) {
      return bind(ranges, function (range) {
        var node = getSelectedNode(range);
        return node ? [Element.fromDom(node)] : [];
      });
    };
    var hasMultipleRanges = function (selection) {
      return getRanges(selection).length > 1;
    };
    var MultiRange = {
      getRanges: getRanges,
      getSelectedNodes: getSelectedNodes,
      hasMultipleRanges: hasMultipleRanges
    };

    var getCellsFromRanges = function (ranges) {
      return filter(MultiRange.getSelectedNodes(ranges), isTableCell);
    };
    var getCellsFromElement = function (elm) {
      return descendants$1(elm, 'td[data-mce-selected],th[data-mce-selected]');
    };
    var getCellsFromElementOrRanges = function (ranges, element) {
      var selectedCells = getCellsFromElement(element);
      var rangeCells = getCellsFromRanges(ranges);
      return selectedCells.length > 0 ? selectedCells : rangeCells;
    };
    var getCellsFromEditor = function (editor) {
      return getCellsFromElementOrRanges(MultiRange.getRanges(editor.selection.getSel()), Element.fromDom(editor.getBody()));
    };
    var TableCellSelection = {
      getCellsFromRanges: getCellsFromRanges,
      getCellsFromElement: getCellsFromElement,
      getCellsFromElementOrRanges: getCellsFromElementOrRanges,
      getCellsFromEditor: getCellsFromEditor
    };

    var findParentListContainer = function (parents) {
      return find(parents, function (elm) {
        return name(elm) === 'ul' || name(elm) === 'ol';
      });
    };
    var getFullySelectedListWrappers = function (parents, rng) {
      return find(parents, function (elm) {
        return name(elm) === 'li' && hasAllContentsSelected(elm, rng);
      }).fold(constant([]), function (li) {
        return findParentListContainer(parents).map(function (listCont) {
          return [
            Element.fromTag('li'),
            Element.fromTag(name(listCont))
          ];
        }).getOr([]);
      });
    };
    var wrap$2 = function (innerElm, elms) {
      var wrapped = foldl(elms, function (acc, elm) {
        append(elm, acc);
        return elm;
      }, innerElm);
      return elms.length > 0 ? fromElements([wrapped]) : wrapped;
    };
    var directListWrappers = function (commonAnchorContainer) {
      if (isListItem(commonAnchorContainer)) {
        return parent(commonAnchorContainer).filter(isList).fold(constant([]), function (listElm) {
          return [
            commonAnchorContainer,
            listElm
          ];
        });
      } else {
        return isList(commonAnchorContainer) ? [commonAnchorContainer] : [];
      }
    };
    var getWrapElements = function (rootNode, rng) {
      var commonAnchorContainer = Element.fromDom(rng.commonAncestorContainer);
      var parents = Parents.parentsAndSelf(commonAnchorContainer, rootNode);
      var wrapElements = filter(parents, function (elm) {
        return isInline(elm) || isHeading(elm);
      });
      var listWrappers = getFullySelectedListWrappers(parents, rng);
      var allWrappers = wrapElements.concat(listWrappers.length ? listWrappers : directListWrappers(commonAnchorContainer));
      return map(allWrappers, shallow);
    };
    var emptyFragment = function () {
      return fromElements([]);
    };
    var getFragmentFromRange = function (rootNode, rng) {
      return wrap$2(Element.fromDom(rng.cloneContents()), getWrapElements(rootNode, rng));
    };
    var getParentTable = function (rootElm, cell) {
      return ancestor$1(cell, 'table', curry(eq, rootElm));
    };
    var getTableFragment = function (rootNode, selectedTableCells) {
      return getParentTable(rootNode, selectedTableCells[0]).bind(function (tableElm) {
        var firstCell = selectedTableCells[0];
        var lastCell = selectedTableCells[selectedTableCells.length - 1];
        var fullTableModel = SimpleTableModel.fromDom(tableElm);
        return SimpleTableModel.subsection(fullTableModel, firstCell, lastCell).map(function (sectionedTableModel) {
          return fromElements([SimpleTableModel.toDom(sectionedTableModel)]);
        });
      }).getOrThunk(emptyFragment);
    };
    var getSelectionFragment = function (rootNode, ranges) {
      return ranges.length > 0 && ranges[0].collapsed ? emptyFragment() : getFragmentFromRange(rootNode, ranges[0]);
    };
    var read$1 = function (rootNode, ranges) {
      var selectedCells = TableCellSelection.getCellsFromElementOrRanges(ranges, rootNode);
      return selectedCells.length > 0 ? getTableFragment(rootNode, selectedCells) : getSelectionFragment(rootNode, ranges);
    };
    var FragmentReader = { read: read$1 };

    var getTextContent = function (editor) {
      return Option.from(editor.selection.getRng()).map(function (rng) {
        var bin = editor.dom.add(editor.getBody(), 'div', {
          'data-mce-bogus': 'all',
          'style': 'overflow: hidden; opacity: 0;'
        }, rng.cloneContents());
        var text = Zwsp.trim(bin.innerText);
        editor.dom.remove(bin);
        return text;
      }).getOr('');
    };
    var getHtmlContent = function (editor, args) {
      var rng = editor.selection.getRng(), tmpElm = editor.dom.create('body');
      var sel = editor.selection.getSel();
      var fragment;
      var ranges = EventProcessRanges.processRanges(editor, MultiRange.getRanges(sel));
      fragment = args.contextual ? FragmentReader.read(Element.fromDom(editor.getBody()), ranges).dom() : rng.cloneContents();
      if (fragment) {
        tmpElm.appendChild(fragment);
      }
      return editor.selection.serializer.serialize(tmpElm, args);
    };
    var getContent$1 = function (editor, args) {
      if (args === void 0) {
        args = {};
      }
      args.get = true;
      args.format = args.format || 'html';
      args.selection = true;
      args = editor.fire('BeforeGetContent', args);
      if (args.isDefaultPrevented()) {
        editor.fire('GetContent', args);
        return args.content;
      }
      if (args.format === 'text') {
        return getTextContent(editor);
      } else {
        args.getInner = true;
        var content = getHtmlContent(editor, args);
        if (args.format === 'tree') {
          return content;
        } else {
          args.content = editor.selection.isCollapsed() ? '' : content;
          editor.fire('GetContent', args);
          return args.content;
        }
      }
    };
    var GetSelectionContent = { getContent: getContent$1 };

    var isEq$1 = function (rng1, rng2) {
      return rng1 && rng2 && (rng1.startContainer === rng2.startContainer && rng1.startOffset === rng2.startOffset) && (rng1.endContainer === rng2.endContainer && rng1.endOffset === rng2.endOffset);
    };
    var RangeCompare = { isEq: isEq$1 };

    var findParent$1 = function (node, rootNode, predicate) {
      while (node && node !== rootNode) {
        if (predicate(node)) {
          return node;
        }
        node = node.parentNode;
      }
      return null;
    };
    var hasParent = function (node, rootNode, predicate) {
      return findParent$1(node, rootNode, predicate) !== null;
    };
    var hasParentWithName = function (node, rootNode, name) {
      return hasParent(node, rootNode, function (node) {
        return node.nodeName === name;
      });
    };
    var isTable$3 = function (node) {
      return node && node.nodeName === 'TABLE';
    };
    var isTableCell$2 = function (node) {
      return node && /^(TD|TH|CAPTION)$/.test(node.nodeName);
    };
    var isCeFalseCaretContainer = function (node, rootNode) {
      return isCaretContainer(node) && hasParent(node, rootNode, isCaretNode) === false;
    };
    var hasBrBeforeAfter = function (dom, node, left) {
      var walker = new TreeWalker(node, dom.getParent(node.parentNode, dom.isBlock) || dom.getRoot());
      while (node = walker[left ? 'prev' : 'next']()) {
        if (NodeType.isBr(node)) {
          return true;
        }
      }
    };
    var isPrevNode = function (node, name) {
      return node.previousSibling && node.previousSibling.nodeName === name;
    };
    var hasContentEditableFalseParent = function (body, node) {
      while (node && node !== body) {
        if (NodeType.isContentEditableFalse(node)) {
          return true;
        }
        node = node.parentNode;
      }
      return false;
    };
    var findTextNodeRelative = function (dom, isAfterNode, collapsed, left, startNode) {
      var lastInlineElement;
      var body = dom.getRoot();
      var node;
      var nonEmptyElementsMap = dom.schema.getNonEmptyElements();
      var parentBlockContainer = dom.getParent(startNode.parentNode, dom.isBlock) || body;
      if (left && NodeType.isBr(startNode) && isAfterNode && dom.isEmpty(parentBlockContainer)) {
        return Option.some(CaretPosition(startNode.parentNode, dom.nodeIndex(startNode)));
      }
      var walker = new TreeWalker(startNode, parentBlockContainer);
      while (node = walker[left ? 'prev' : 'next']()) {
        if (dom.getContentEditableParent(node) === 'false' || isCeFalseCaretContainer(node, body)) {
          return Option.none();
        }
        if (NodeType.isText(node) && node.nodeValue.length > 0) {
          if (hasParentWithName(node, body, 'A') === false) {
            return Option.some(CaretPosition(node, left ? node.nodeValue.length : 0));
          }
          return Option.none();
        }
        if (dom.isBlock(node) || nonEmptyElementsMap[node.nodeName.toLowerCase()]) {
          return Option.none();
        }
        lastInlineElement = node;
      }
      if (collapsed && lastInlineElement) {
        return Option.some(CaretPosition(lastInlineElement, 0));
      }
      return Option.none();
    };
    var normalizeEndPoint = function (dom, collapsed, start, rng) {
      var container, offset;
      var body = dom.getRoot();
      var node, nonEmptyElementsMap;
      var directionLeft, isAfterNode, normalized = false;
      container = rng[(start ? 'start' : 'end') + 'Container'];
      offset = rng[(start ? 'start' : 'end') + 'Offset'];
      isAfterNode = NodeType.isElement(container) && offset === container.childNodes.length;
      nonEmptyElementsMap = dom.schema.getNonEmptyElements();
      directionLeft = start;
      if (isCaretContainer(container)) {
        return Option.none();
      }
      if (NodeType.isElement(container) && offset > container.childNodes.length - 1) {
        directionLeft = false;
      }
      if (NodeType.isDocument(container)) {
        container = body;
        offset = 0;
      }
      if (container === body) {
        if (directionLeft) {
          node = container.childNodes[offset > 0 ? offset - 1 : 0];
          if (node) {
            if (isCaretContainer(node)) {
              return Option.none();
            }
            if (nonEmptyElementsMap[node.nodeName] || isTable$3(node)) {
              return Option.none();
            }
          }
        }
        if (container.hasChildNodes()) {
          offset = Math.min(!directionLeft && offset > 0 ? offset - 1 : offset, container.childNodes.length - 1);
          container = container.childNodes[offset];
          offset = NodeType.isText(container) && isAfterNode ? container.data.length : 0;
          if (!collapsed && container === body.lastChild && isTable$3(container)) {
            return Option.none();
          }
          if (hasContentEditableFalseParent(body, container) || isCaretContainer(container)) {
            return Option.none();
          }
          if (container.hasChildNodes() && isTable$3(container) === false) {
            node = container;
            var walker = new TreeWalker(container, body);
            do {
              if (NodeType.isContentEditableFalse(node) || isCaretContainer(node)) {
                normalized = false;
                break;
              }
              if (NodeType.isText(node) && node.nodeValue.length > 0) {
                offset = directionLeft ? 0 : node.nodeValue.length;
                container = node;
                normalized = true;
                break;
              }
              if (nonEmptyElementsMap[node.nodeName.toLowerCase()] && !isTableCell$2(node)) {
                offset = dom.nodeIndex(node);
                container = node.parentNode;
                if (!directionLeft) {
                  offset++;
                }
                normalized = true;
                break;
              }
            } while (node = directionLeft ? walker.next() : walker.prev());
          }
        }
      }
      if (collapsed) {
        if (NodeType.isText(container) && offset === 0) {
          findTextNodeRelative(dom, isAfterNode, collapsed, true, container).each(function (pos) {
            container = pos.container();
            offset = pos.offset();
            normalized = true;
          });
        }
        if (NodeType.isElement(container)) {
          node = container.childNodes[offset];
          if (!node) {
            node = container.childNodes[offset - 1];
          }
          if (node && NodeType.isBr(node) && !isPrevNode(node, 'A') && !hasBrBeforeAfter(dom, node, false) && !hasBrBeforeAfter(dom, node, true)) {
            findTextNodeRelative(dom, isAfterNode, collapsed, true, node).each(function (pos) {
              container = pos.container();
              offset = pos.offset();
              normalized = true;
            });
          }
        }
      }
      if (directionLeft && !collapsed && NodeType.isText(container) && offset === container.nodeValue.length) {
        findTextNodeRelative(dom, isAfterNode, collapsed, false, container).each(function (pos) {
          container = pos.container();
          offset = pos.offset();
          normalized = true;
        });
      }
      return normalized ? Option.some(CaretPosition(container, offset)) : Option.none();
    };
    var normalize = function (dom, rng) {
      var collapsed = rng.collapsed, normRng = rng.cloneRange();
      var startPos = CaretPosition.fromRangeStart(rng);
      normalizeEndPoint(dom, collapsed, true, normRng).each(function (pos) {
        if (!collapsed || !CaretPosition.isAbove(startPos, pos)) {
          normRng.setStart(pos.container(), pos.offset());
        }
      });
      if (!collapsed) {
        normalizeEndPoint(dom, collapsed, false, normRng).each(function (pos) {
          normRng.setEnd(pos.container(), pos.offset());
        });
      }
      if (collapsed) {
        normRng.collapse(true);
      }
      return RangeCompare.isEq(rng, normRng) ? Option.none() : Option.some(normRng);
    };
    var NormalizeRange = { normalize: normalize };

    var prependData = function (target, data) {
      target.insertData(0, data);
    };
    var removeEmpty = function (text) {
      if (text.dom().length === 0) {
        remove(text);
        return Option.none();
      }
      return Option.some(text);
    };
    var rngSetContent = function (rng, fragment) {
      var firstChild = Option.from(fragment.firstChild).map(Element.fromDom);
      var lastChild = Option.from(fragment.lastChild).map(Element.fromDom);
      rng.deleteContents();
      rng.insertNode(fragment);
      var prevText = firstChild.bind(prevSibling).filter(isText).bind(removeEmpty);
      var nextText = lastChild.bind(nextSibling).filter(isText).bind(removeEmpty);
      lift2(prevText, firstChild.filter(isText), function (prev, start) {
        prependData(start.dom(), prev.dom().data);
        remove(prev);
      });
      lift2(nextText, lastChild.filter(isText), function (next, end) {
        var oldLength = end.dom().length;
        end.dom().appendData(next.dom().data);
        rng.setEnd(end.dom(), oldLength);
        remove(next);
      });
      rng.collapse(false);
    };
    var setupArgs = function (args, content) {
      args = args || { format: 'html' };
      args.set = true;
      args.selection = true;
      args.content = content;
      return args;
    };
    var setContent$1 = function (editor, content, args) {
      args = setupArgs(args, content);
      if (!args.no_events) {
        args = editor.fire('BeforeSetContent', args);
        if (args.isDefaultPrevented()) {
          editor.fire('SetContent', args);
          return;
        }
      }
      var rng = editor.selection.getRng();
      rngSetContent(rng, rng.createContextualFragment(args.content));
      editor.selection.setRng(rng);
      ScrollIntoView.scrollRangeIntoView(editor, rng);
      if (!args.no_events) {
        editor.fire('SetContent', args);
      }
    };
    var SetSelectionContent = { setContent: setContent$1 };

    var getEndpointElement = function (root, rng, start, real, resolve) {
      var container = start ? rng.startContainer : rng.endContainer;
      var offset = start ? rng.startOffset : rng.endOffset;
      return Option.from(container).map(Element.fromDom).map(function (elm) {
        return !real || !rng.collapsed ? child(elm, resolve(elm, offset)).getOr(elm) : elm;
      }).bind(function (elm) {
        return isElement(elm) ? Option.some(elm) : parent(elm);
      }).map(function (elm) {
        return elm.dom();
      }).getOr(root);
    };
    var getStart$2 = function (root, rng, real) {
      return getEndpointElement(root, rng, true, real, function (elm, offset) {
        return Math.min(childNodesCount(elm), offset);
      });
    };
    var getEnd = function (root, rng, real) {
      return getEndpointElement(root, rng, false, real, function (elm, offset) {
        return offset > 0 ? offset - 1 : offset;
      });
    };
    var skipEmptyTextNodes = function (node, forwards) {
      var orig = node;
      while (node && NodeType.isText(node) && node.length === 0) {
        node = forwards ? node.nextSibling : node.previousSibling;
      }
      return node || orig;
    };
    var getNode$1 = function (root, rng) {
      var elm, startContainer, endContainer, startOffset, endOffset;
      if (!rng) {
        return root;
      }
      startContainer = rng.startContainer;
      endContainer = rng.endContainer;
      startOffset = rng.startOffset;
      endOffset = rng.endOffset;
      elm = rng.commonAncestorContainer;
      if (!rng.collapsed) {
        if (startContainer === endContainer) {
          if (endOffset - startOffset < 2) {
            if (startContainer.hasChildNodes()) {
              elm = startContainer.childNodes[startOffset];
            }
          }
        }
        if (startContainer.nodeType === 3 && endContainer.nodeType === 3) {
          if (startContainer.length === startOffset) {
            startContainer = skipEmptyTextNodes(startContainer.nextSibling, true);
          } else {
            startContainer = startContainer.parentNode;
          }
          if (endOffset === 0) {
            endContainer = skipEmptyTextNodes(endContainer.previousSibling, false);
          } else {
            endContainer = endContainer.parentNode;
          }
          if (startContainer && startContainer === endContainer) {
            return startContainer;
          }
        }
      }
      if (elm && elm.nodeType === 3) {
        return elm.parentNode;
      }
      return elm;
    };
    var getSelectedBlocks = function (dom, rng, startElm, endElm) {
      var node, root;
      var selectedBlocks = [];
      root = dom.getRoot();
      startElm = dom.getParent(startElm || getStart$2(root, rng, rng.collapsed), dom.isBlock);
      endElm = dom.getParent(endElm || getEnd(root, rng, rng.collapsed), dom.isBlock);
      if (startElm && startElm !== root) {
        selectedBlocks.push(startElm);
      }
      if (startElm && endElm && startElm !== endElm) {
        node = startElm;
        var walker = new TreeWalker(startElm, root);
        while ((node = walker.next()) && node !== endElm) {
          if (dom.isBlock(node)) {
            selectedBlocks.push(node);
          }
        }
      }
      if (endElm && startElm !== endElm && endElm !== root) {
        selectedBlocks.push(endElm);
      }
      return selectedBlocks;
    };
    var select$1 = function (dom, node, content) {
      return Option.from(node).map(function (node) {
        var idx = dom.nodeIndex(node);
        var rng = dom.createRng();
        rng.setStart(node.parentNode, idx);
        rng.setEnd(node.parentNode, idx + 1);
        if (content) {
          moveEndPoint$1(dom, rng, node, true);
          moveEndPoint$1(dom, rng, node, false);
        }
        return rng;
      });
    };

    var deleteFromCallbackMap = function (callbackMap, selector, callback) {
      if (callbackMap && callbackMap.hasOwnProperty(selector)) {
        var newCallbacks = filter(callbackMap[selector], function (cb) {
          return cb !== callback;
        });
        if (newCallbacks.length === 0) {
          delete callbackMap[selector];
        } else {
          callbackMap[selector] = newCallbacks;
        }
      }
    };
    function SelectorChanged (dom, editor) {
      var selectorChangedData;
      var currentSelectors;
      return {
        selectorChangedWithUnbind: function (selector, callback) {
          if (!selectorChangedData) {
            selectorChangedData = {};
            currentSelectors = {};
            editor.on('NodeChange', function (e) {
              var node = e.element, parents = dom.getParents(node, null, dom.getRoot()), matchedSelectors = {};
              Tools.each(selectorChangedData, function (callbacks, selector) {
                Tools.each(parents, function (node) {
                  if (dom.is(node, selector)) {
                    if (!currentSelectors[selector]) {
                      Tools.each(callbacks, function (callback) {
                        callback(true, {
                          node: node,
                          selector: selector,
                          parents: parents
                        });
                      });
                      currentSelectors[selector] = callbacks;
                    }
                    matchedSelectors[selector] = callbacks;
                    return false;
                  }
                });
              });
              Tools.each(currentSelectors, function (callbacks, selector) {
                if (!matchedSelectors[selector]) {
                  delete currentSelectors[selector];
                  Tools.each(callbacks, function (callback) {
                    callback(false, {
                      node: node,
                      selector: selector,
                      parents: parents
                    });
                  });
                }
              });
            });
          }
          if (!selectorChangedData[selector]) {
            selectorChangedData[selector] = [];
          }
          selectorChangedData[selector].push(callback);
          return {
            unbind: function () {
              deleteFromCallbackMap(selectorChangedData, selector, callback);
              deleteFromCallbackMap(currentSelectors, selector, callback);
            }
          };
        }
      };
    }

    var isNativeIeSelection = function (rng) {
      return !!rng.select;
    };
    var isAttachedToDom = function (node) {
      return !!(node && node.ownerDocument) && contains$2(Element.fromDom(node.ownerDocument), Element.fromDom(node));
    };
    var isValidRange = function (rng) {
      if (!rng) {
        return false;
      } else if (isNativeIeSelection(rng)) {
        return true;
      } else {
        return isAttachedToDom(rng.startContainer) && isAttachedToDom(rng.endContainer);
      }
    };
    var Selection$1 = function (dom, win, serializer, editor) {
      var bookmarkManager;
      var controlSelection;
      var selectedRange;
      var explicitRange;
      var selectorChangedWithUnbind = SelectorChanged(dom, editor).selectorChangedWithUnbind;
      var setCursorLocation = function (node, offset) {
        var rng = dom.createRng();
        if (!node) {
          moveEndPoint$1(dom, rng, editor.getBody(), true);
          setRng(rng);
        } else {
          rng.setStart(node, offset);
          rng.setEnd(node, offset);
          setRng(rng);
          collapse(false);
        }
      };
      var getContent = function (args) {
        return GetSelectionContent.getContent(editor, args);
      };
      var setContent = function (content, args) {
        return SetSelectionContent.setContent(editor, content, args);
      };
      var getStart = function (real) {
        return getStart$2(editor.getBody(), getRng(), real);
      };
      var getEnd$1 = function (real) {
        return getEnd(editor.getBody(), getRng(), real);
      };
      var getBookmark = function (type, normalized) {
        return bookmarkManager.getBookmark(type, normalized);
      };
      var moveToBookmark = function (bookmark) {
        return bookmarkManager.moveToBookmark(bookmark);
      };
      var select = function (node, content) {
        select$1(dom, node, content).each(setRng);
        return node;
      };
      var isCollapsed = function () {
        var rng = getRng(), sel = getSel();
        if (!rng || rng.item) {
          return false;
        }
        if (rng.compareEndPoints) {
          return rng.compareEndPoints('StartToEnd', rng) === 0;
        }
        return !sel || rng.collapsed;
      };
      var collapse = function (toStart) {
        var rng = getRng();
        rng.collapse(!!toStart);
        setRng(rng);
      };
      var getSel = function () {
        return win.getSelection ? win.getSelection() : win.document.selection;
      };
      var getRng = function () {
        var selection, rng, elm, doc;
        var tryCompareBoundaryPoints = function (how, sourceRange, destinationRange) {
          try {
            return sourceRange.compareBoundaryPoints(how, destinationRange);
          } catch (ex) {
            return -1;
          }
        };
        if (!win) {
          return null;
        }
        doc = win.document;
        if (typeof doc === 'undefined' || doc === null) {
          return null;
        }
        if (editor.bookmark !== undefined && EditorFocus.hasFocus(editor) === false) {
          var bookmark = SelectionBookmark.getRng(editor);
          if (bookmark.isSome()) {
            return bookmark.map(function (r) {
              return EventProcessRanges.processRanges(editor, [r])[0];
            }).getOr(doc.createRange());
          }
        }
        try {
          if ((selection = getSel()) && !NodeType.isRestrictedNode(selection.anchorNode)) {
            if (selection.rangeCount > 0) {
              rng = selection.getRangeAt(0);
            } else {
              rng = selection.createRange ? selection.createRange() : doc.createRange();
            }
          }
        } catch (ex) {
        }
        rng = EventProcessRanges.processRanges(editor, [rng])[0];
        if (!rng) {
          rng = doc.createRange ? doc.createRange() : doc.body.createTextRange();
        }
        if (rng.setStart && rng.startContainer.nodeType === 9 && rng.collapsed) {
          elm = dom.getRoot();
          rng.setStart(elm, 0);
          rng.setEnd(elm, 0);
        }
        if (selectedRange && explicitRange) {
          if (tryCompareBoundaryPoints(rng.START_TO_START, rng, selectedRange) === 0 && tryCompareBoundaryPoints(rng.END_TO_END, rng, selectedRange) === 0) {
            rng = explicitRange;
          } else {
            selectedRange = null;
            explicitRange = null;
          }
        }
        return rng;
      };
      var setRng = function (rng, forward) {
        var sel, node, evt;
        if (!isValidRange(rng)) {
          return;
        }
        var ieRange = isNativeIeSelection(rng) ? rng : null;
        if (ieRange) {
          explicitRange = null;
          try {
            ieRange.select();
          } catch (ex) {
          }
          return;
        }
        sel = getSel();
        evt = editor.fire('SetSelectionRange', {
          range: rng,
          forward: forward
        });
        rng = evt.range;
        if (sel) {
          explicitRange = rng;
          try {
            sel.removeAllRanges();
            sel.addRange(rng);
          } catch (ex) {
          }
          if (forward === false && sel.extend) {
            sel.collapse(rng.endContainer, rng.endOffset);
            sel.extend(rng.startContainer, rng.startOffset);
          }
          selectedRange = sel.rangeCount > 0 ? sel.getRangeAt(0) : null;
        }
        if (!rng.collapsed && rng.startContainer === rng.endContainer && sel.setBaseAndExtent && !Env.ie) {
          if (rng.endOffset - rng.startOffset < 2) {
            if (rng.startContainer.hasChildNodes()) {
              node = rng.startContainer.childNodes[rng.startOffset];
              if (node && node.tagName === 'IMG') {
                sel.setBaseAndExtent(rng.startContainer, rng.startOffset, rng.endContainer, rng.endOffset);
                if (sel.anchorNode !== rng.startContainer || sel.focusNode !== rng.endContainer) {
                  sel.setBaseAndExtent(node, 0, node, 1);
                }
              }
            }
          }
        }
        editor.fire('AfterSetSelectionRange', {
          range: rng,
          forward: forward
        });
      };
      var setNode = function (elm) {
        setContent(dom.getOuterHTML(elm));
        return elm;
      };
      var getNode = function () {
        return getNode$1(editor.getBody(), getRng());
      };
      var getSelectedBlocks$1 = function (startElm, endElm) {
        return getSelectedBlocks(dom, getRng(), startElm, endElm);
      };
      var isForward = function () {
        var sel = getSel();
        var anchorRange, focusRange;
        if (!sel || !sel.anchorNode || !sel.focusNode) {
          return true;
        }
        anchorRange = dom.createRng();
        anchorRange.setStart(sel.anchorNode, sel.anchorOffset);
        anchorRange.collapse(true);
        focusRange = dom.createRng();
        focusRange.setStart(sel.focusNode, sel.focusOffset);
        focusRange.collapse(true);
        return anchorRange.compareBoundaryPoints(anchorRange.START_TO_START, focusRange) <= 0;
      };
      var normalize = function () {
        var rng = getRng();
        var sel = getSel();
        if (!MultiRange.hasMultipleRanges(sel) && hasAnyRanges(editor)) {
          var normRng = NormalizeRange.normalize(dom, rng);
          normRng.each(function (normRng) {
            setRng(normRng, isForward());
          });
          return normRng.getOr(rng);
        }
        return rng;
      };
      var selectorChanged = function (selector, callback) {
        selectorChangedWithUnbind(selector, callback);
        return exports;
      };
      var getScrollContainer = function () {
        var scrollContainer;
        var node = dom.getRoot();
        while (node && node.nodeName !== 'BODY') {
          if (node.scrollHeight > node.clientHeight) {
            scrollContainer = node;
            break;
          }
          node = node.parentNode;
        }
        return scrollContainer;
      };
      var scrollIntoView = function (elm, alignToTop) {
        return ScrollIntoView.scrollElementIntoView(editor, elm, alignToTop);
      };
      var placeCaretAt = function (clientX, clientY) {
        return setRng(CaretRangeFromPoint.fromPoint(clientX, clientY, editor.getDoc()));
      };
      var getBoundingClientRect = function () {
        var rng = getRng();
        return rng.collapsed ? CaretPosition$1.fromRangeStart(rng).getClientRects()[0] : rng.getBoundingClientRect();
      };
      var destroy = function () {
        win = selectedRange = explicitRange = null;
        controlSelection.destroy();
      };
      var exports = {
        bookmarkManager: null,
        controlSelection: null,
        dom: dom,
        win: win,
        serializer: serializer,
        editor: editor,
        collapse: collapse,
        setCursorLocation: setCursorLocation,
        getContent: getContent,
        setContent: setContent,
        getBookmark: getBookmark,
        moveToBookmark: moveToBookmark,
        select: select,
        isCollapsed: isCollapsed,
        isForward: isForward,
        setNode: setNode,
        getNode: getNode,
        getSel: getSel,
        setRng: setRng,
        getRng: getRng,
        getStart: getStart,
        getEnd: getEnd$1,
        getSelectedBlocks: getSelectedBlocks$1,
        normalize: normalize,
        selectorChanged: selectorChanged,
        selectorChangedWithUnbind: selectorChangedWithUnbind,
        getScrollContainer: getScrollContainer,
        scrollIntoView: scrollIntoView,
        placeCaretAt: placeCaretAt,
        getBoundingClientRect: getBoundingClientRect,
        destroy: destroy
      };
      bookmarkManager = BookmarkManager$1(exports);
      controlSelection = ControlSelection(exports, editor);
      exports.bookmarkManager = bookmarkManager;
      exports.controlSelection = controlSelection;
      return exports;
    };

    var removeAttrs = function (node, names) {
      each(names, function (name) {
        node.attr(name, null);
      });
    };
    var addFontToSpansFilter = function (domParser, styles, fontSizes) {
      domParser.addNodeFilter('font', function (nodes) {
        each(nodes, function (node) {
          var props = styles.parse(node.attr('style'));
          var color = node.attr('color');
          var face = node.attr('face');
          var size = node.attr('size');
          if (color) {
            props.color = color;
          }
          if (face) {
            props['font-family'] = face;
          }
          if (size) {
            props['font-size'] = fontSizes[parseInt(node.attr('size'), 10) - 1];
          }
          node.name = 'span';
          node.attr('style', styles.serialize(props));
          removeAttrs(node, [
            'color',
            'face',
            'size'
          ]);
        });
      });
    };
    var addStrikeToSpanFilter = function (domParser, styles) {
      domParser.addNodeFilter('strike', function (nodes) {
        each(nodes, function (node) {
          var props = styles.parse(node.attr('style'));
          props['text-decoration'] = 'line-through';
          node.name = 'span';
          node.attr('style', styles.serialize(props));
        });
      });
    };
    var addFilters = function (domParser, settings) {
      var styles = Styles();
      if (settings.convert_fonts_to_spans) {
        addFontToSpansFilter(domParser, styles, Tools.explode(settings.font_size_legacy_values));
      }
      addStrikeToSpanFilter(domParser, styles);
    };
    var register$1 = function (domParser, settings) {
      if (settings.inline_styles) {
        addFilters(domParser, settings);
      }
    };
    var LegacyFilter = { register: register$1 };

    var paddEmptyNode = function (settings, args, blockElements, node) {
      var brPreferred = settings.padd_empty_with_br || args.insert;
      if (brPreferred && blockElements[node.name]) {
        node.empty().append(new Node$1('br', 1)).shortEnded = true;
      } else {
        node.empty().append(new Node$1('#text', 3)).value = nbsp;
      }
    };
    var isPaddedWithNbsp = function (node) {
      return hasOnlyChild(node, '#text') && node.firstChild.value === nbsp;
    };
    var hasOnlyChild = function (node, name) {
      return node && node.firstChild && node.firstChild === node.lastChild && node.firstChild.name === name;
    };
    var isPadded = function (schema, node) {
      var rule = schema.getElementRule(node.name);
      return rule && rule.paddEmpty;
    };
    var isEmpty$1 = function (schema, nonEmptyElements, whitespaceElements, node) {
      return node.isEmpty(nonEmptyElements, whitespaceElements, function (node) {
        return isPadded(schema, node);
      });
    };
    var isLineBreakNode = function (node, blockElements) {
      return node && (blockElements[node.name] || node.name === 'br');
    };

    var register$2 = function (parser, settings) {
      var schema = parser.schema;
      if (settings.remove_trailing_brs) {
        parser.addNodeFilter('br', function (nodes, _, args) {
          var i;
          var l = nodes.length;
          var node;
          var blockElements = Tools.extend({}, schema.getBlockElements());
          var nonEmptyElements = schema.getNonEmptyElements();
          var parent, lastParent, prev, prevName;
          var whiteSpaceElements = schema.getNonEmptyElements();
          var elementRule, textNode;
          blockElements.body = 1;
          for (i = 0; i < l; i++) {
            node = nodes[i];
            parent = node.parent;
            if (blockElements[node.parent.name] && node === parent.lastChild) {
              prev = node.prev;
              while (prev) {
                prevName = prev.name;
                if (prevName !== 'span' || prev.attr('data-mce-type') !== 'bookmark') {
                  if (prevName !== 'br') {
                    break;
                  }
                  if (prevName === 'br') {
                    node = null;
                    break;
                  }
                }
                prev = prev.prev;
              }
              if (node) {
                node.remove();
                if (isEmpty$1(schema, nonEmptyElements, whiteSpaceElements, parent)) {
                  elementRule = schema.getElementRule(parent.name);
                  if (elementRule) {
                    if (elementRule.removeEmpty) {
                      parent.remove();
                    } else if (elementRule.paddEmpty) {
                      paddEmptyNode(settings, args, blockElements, parent);
                    }
                  }
                }
              }
            } else {
              lastParent = node;
              while (parent && parent.firstChild === lastParent && parent.lastChild === lastParent) {
                lastParent = parent;
                if (blockElements[parent.name]) {
                  break;
                }
                parent = parent.parent;
              }
              if (lastParent === parent && settings.padd_empty_with_br !== true) {
                textNode = new Node$1('#text', 3);
                textNode.value = nbsp;
                node.replace(textNode);
              }
            }
          }
        });
      }
      parser.addAttributeFilter('href', function (nodes) {
        var i = nodes.length, node;
        var appendRel = function (rel) {
          var parts = rel.split(' ').filter(function (p) {
            return p.length > 0;
          });
          return parts.concat(['noopener']).sort().join(' ');
        };
        var addNoOpener = function (rel) {
          var newRel = rel ? Tools.trim(rel) : '';
          if (!/\b(noopener)\b/g.test(newRel)) {
            return appendRel(newRel);
          } else {
            return newRel;
          }
        };
        if (!settings.allow_unsafe_link_target) {
          while (i--) {
            node = nodes[i];
            if (node.name === 'a' && node.attr('target') === '_blank') {
              node.attr('rel', addNoOpener(node.attr('rel')));
            }
          }
        }
      });
      if (!settings.allow_html_in_named_anchor) {
        parser.addAttributeFilter('id,name', function (nodes) {
          var i = nodes.length, sibling, prevSibling, parent, node;
          while (i--) {
            node = nodes[i];
            if (node.name === 'a' && node.firstChild && !node.attr('href')) {
              parent = node.parent;
              sibling = node.lastChild;
              do {
                prevSibling = sibling.prev;
                parent.insert(sibling, node);
                sibling = prevSibling;
              } while (sibling);
            }
          }
        });
      }
      if (settings.fix_list_elements) {
        parser.addNodeFilter('ul,ol', function (nodes) {
          var i = nodes.length, node, parentNode;
          while (i--) {
            node = nodes[i];
            parentNode = node.parent;
            if (parentNode.name === 'ul' || parentNode.name === 'ol') {
              if (node.prev && node.prev.name === 'li') {
                node.prev.append(node);
              } else {
                var li = new Node$1('li', 1);
                li.attr('style', 'list-style-type: none');
                node.wrap(li);
              }
            }
          }
        });
      }
      if (settings.validate && schema.getValidClasses()) {
        parser.addAttributeFilter('class', function (nodes) {
          var i = nodes.length, node, classList, ci, className, classValue;
          var validClasses = schema.getValidClasses();
          var validClassesMap, valid;
          while (i--) {
            node = nodes[i];
            classList = node.attr('class').split(' ');
            classValue = '';
            for (ci = 0; ci < classList.length; ci++) {
              className = classList[ci];
              valid = false;
              validClassesMap = validClasses['*'];
              if (validClassesMap && validClassesMap[className]) {
                valid = true;
              }
              validClassesMap = validClasses[node.name];
              if (!valid && validClassesMap && validClassesMap[className]) {
                valid = true;
              }
              if (valid) {
                if (classValue) {
                  classValue += ' ';
                }
                classValue += className;
              }
            }
            if (!classValue.length) {
              classValue = null;
            }
            node.attr('class', classValue);
          }
        });
      }
    };

    var makeMap$4 = Tools.makeMap, each$8 = Tools.each, explode$2 = Tools.explode, extend$2 = Tools.extend;
    var DomParser = function (settings, schema) {
      if (schema === void 0) {
        schema = Schema();
      }
      var nodeFilters = {};
      var attributeFilters = [];
      var matchedNodes = {};
      var matchedAttributes = {};
      settings = settings || {};
      settings.validate = 'validate' in settings ? settings.validate : true;
      settings.root_name = settings.root_name || 'body';
      var fixInvalidChildren = function (nodes) {
        var ni, node, parent, parents, newParent, currentNode, tempNode, childNode, i;
        var nonEmptyElements, whitespaceElements, nonSplitableElements, textBlockElements, specialElements, sibling, nextNode;
        nonSplitableElements = makeMap$4('tr,td,th,tbody,thead,tfoot,table');
        nonEmptyElements = schema.getNonEmptyElements();
        whitespaceElements = schema.getWhiteSpaceElements();
        textBlockElements = schema.getTextBlockElements();
        specialElements = schema.getSpecialElements();
        for (ni = 0; ni < nodes.length; ni++) {
          node = nodes[ni];
          if (!node.parent || node.fixed) {
            continue;
          }
          if (textBlockElements[node.name] && node.parent.name === 'li') {
            sibling = node.next;
            while (sibling) {
              if (textBlockElements[sibling.name]) {
                sibling.name = 'li';
                sibling.fixed = true;
                node.parent.insert(sibling, node.parent);
              } else {
                break;
              }
              sibling = sibling.next;
            }
            node.unwrap(node);
            continue;
          }
          parents = [node];
          for (parent = node.parent; parent && !schema.isValidChild(parent.name, node.name) && !nonSplitableElements[parent.name]; parent = parent.parent) {
            parents.push(parent);
          }
          if (parent && parents.length > 1) {
            parents.reverse();
            newParent = currentNode = filterNode(parents[0].clone());
            for (i = 0; i < parents.length - 1; i++) {
              if (schema.isValidChild(currentNode.name, parents[i].name)) {
                tempNode = filterNode(parents[i].clone());
                currentNode.append(tempNode);
              } else {
                tempNode = currentNode;
              }
              for (childNode = parents[i].firstChild; childNode && childNode !== parents[i + 1];) {
                nextNode = childNode.next;
                tempNode.append(childNode);
                childNode = nextNode;
              }
              currentNode = tempNode;
            }
            if (!isEmpty$1(schema, nonEmptyElements, whitespaceElements, newParent)) {
              parent.insert(newParent, parents[0], true);
              parent.insert(node, newParent);
            } else {
              parent.insert(node, parents[0], true);
            }
            parent = parents[0];
            if (isEmpty$1(schema, nonEmptyElements, whitespaceElements, parent) || hasOnlyChild(parent, 'br')) {
              parent.empty().remove();
            }
          } else if (node.parent) {
            if (node.name === 'li') {
              sibling = node.prev;
              if (sibling && (sibling.name === 'ul' || sibling.name === 'ul')) {
                sibling.append(node);
                continue;
              }
              sibling = node.next;
              if (sibling && (sibling.name === 'ul' || sibling.name === 'ul')) {
                sibling.insert(node, sibling.firstChild, true);
                continue;
              }
              node.wrap(filterNode(new Node$1('ul', 1)));
              continue;
            }
            if (schema.isValidChild(node.parent.name, 'div') && schema.isValidChild('div', node.name)) {
              node.wrap(filterNode(new Node$1('div', 1)));
            } else {
              if (specialElements[node.name]) {
                node.empty().remove();
              } else {
                node.unwrap();
              }
            }
          }
        }
      };
      var filterNode = function (node) {
        var i, name, list;
        name = node.name;
        if (name in nodeFilters) {
          list = matchedNodes[name];
          if (list) {
            list.push(node);
          } else {
            matchedNodes[name] = [node];
          }
        }
        i = attributeFilters.length;
        while (i--) {
          name = attributeFilters[i].name;
          if (name in node.attributes.map) {
            list = matchedAttributes[name];
            if (list) {
              list.push(node);
            } else {
              matchedAttributes[name] = [node];
            }
          }
        }
        return node;
      };
      var addNodeFilter = function (name, callback) {
        each$8(explode$2(name), function (name) {
          var list = nodeFilters[name];
          if (!list) {
            nodeFilters[name] = list = [];
          }
          list.push(callback);
        });
      };
      var getNodeFilters = function () {
        var out = [];
        for (var name_1 in nodeFilters) {
          if (nodeFilters.hasOwnProperty(name_1)) {
            out.push({
              name: name_1,
              callbacks: nodeFilters[name_1]
            });
          }
        }
        return out;
      };
      var addAttributeFilter = function (name, callback) {
        each$8(explode$2(name), function (name) {
          var i;
          for (i = 0; i < attributeFilters.length; i++) {
            if (attributeFilters[i].name === name) {
              attributeFilters[i].callbacks.push(callback);
              return;
            }
          }
          attributeFilters.push({
            name: name,
            callbacks: [callback]
          });
        });
      };
      var getAttributeFilters = function () {
        return [].concat(attributeFilters);
      };
      var parse = function (html, args) {
        var parser, nodes, i, l, fi, fl, list, name;
        var blockElements;
        var invalidChildren = [];
        var isInWhiteSpacePreservedElement;
        var node;
        var getRootBlockName = function (name) {
          if (name === false) {
            return '';
          } else if (name === true) {
            return 'p';
          } else {
            return name;
          }
        };
        args = args || {};
        matchedNodes = {};
        matchedAttributes = {};
        blockElements = extend$2(makeMap$4('script,style,head,html,body,title,meta,param'), schema.getBlockElements());
        var nonEmptyElements = schema.getNonEmptyElements();
        var children = schema.children;
        var validate = settings.validate;
        var forcedRootBlockName = 'forced_root_block' in args ? args.forced_root_block : settings.forced_root_block;
        var rootBlockName = getRootBlockName(forcedRootBlockName);
        var whiteSpaceElements = schema.getWhiteSpaceElements();
        var startWhiteSpaceRegExp = /^[ \t\r\n]+/;
        var endWhiteSpaceRegExp = /[ \t\r\n]+$/;
        var allWhiteSpaceRegExp = /[ \t\r\n]+/g;
        var isAllWhiteSpaceRegExp = /^[ \t\r\n]+$/;
        isInWhiteSpacePreservedElement = whiteSpaceElements.hasOwnProperty(args.context) || whiteSpaceElements.hasOwnProperty(settings.root_name);
        var addRootBlocks = function () {
          var node = rootNode.firstChild, next, rootBlockNode;
          var trim = function (rootBlockNode) {
            if (rootBlockNode) {
              node = rootBlockNode.firstChild;
              if (node && node.type === 3) {
                node.value = node.value.replace(startWhiteSpaceRegExp, '');
              }
              node = rootBlockNode.lastChild;
              if (node && node.type === 3) {
                node.value = node.value.replace(endWhiteSpaceRegExp, '');
              }
            }
          };
          if (!schema.isValidChild(rootNode.name, rootBlockName.toLowerCase())) {
            return;
          }
          while (node) {
            next = node.next;
            if (node.type === 3 || node.type === 1 && node.name !== 'p' && !blockElements[node.name] && !node.attr('data-mce-type')) {
              if (!rootBlockNode) {
                rootBlockNode = createNode(rootBlockName, 1);
                rootBlockNode.attr(settings.forced_root_block_attrs);
                rootNode.insert(rootBlockNode, node);
                rootBlockNode.append(node);
              } else {
                rootBlockNode.append(node);
              }
            } else {
              trim(rootBlockNode);
              rootBlockNode = null;
            }
            node = next;
          }
          trim(rootBlockNode);
        };
        var createNode = function (name, type) {
          var node = new Node$1(name, type);
          var list;
          if (name in nodeFilters) {
            list = matchedNodes[name];
            if (list) {
              list.push(node);
            } else {
              matchedNodes[name] = [node];
            }
          }
          return node;
        };
        var removeWhitespaceBefore = function (node) {
          var textNode, textNodeNext, textVal, sibling;
          var blockElements = schema.getBlockElements();
          for (textNode = node.prev; textNode && textNode.type === 3;) {
            textVal = textNode.value.replace(endWhiteSpaceRegExp, '');
            if (textVal.length > 0) {
              textNode.value = textVal;
              return;
            }
            textNodeNext = textNode.next;
            if (textNodeNext) {
              if (textNodeNext.type === 3 && textNodeNext.value.length) {
                textNode = textNode.prev;
                continue;
              }
              if (!blockElements[textNodeNext.name] && textNodeNext.name !== 'script' && textNodeNext.name !== 'style') {
                textNode = textNode.prev;
                continue;
              }
            }
            sibling = textNode.prev;
            textNode.remove();
            textNode = sibling;
          }
        };
        var cloneAndExcludeBlocks = function (input) {
          var name;
          var output = {};
          for (name in input) {
            if (name !== 'li' && name !== 'p') {
              output[name] = input[name];
            }
          }
          return output;
        };
        parser = SaxParser$1({
          validate: validate,
          allow_script_urls: settings.allow_script_urls,
          allow_conditional_comments: settings.allow_conditional_comments,
          preserve_cdata: settings.preserve_cdata,
          self_closing_elements: cloneAndExcludeBlocks(schema.getSelfClosingElements()),
          cdata: function (text) {
            node.append(createNode('#cdata', 4)).value = text;
          },
          text: function (text, raw) {
            var textNode;
            if (!isInWhiteSpacePreservedElement) {
              text = text.replace(allWhiteSpaceRegExp, ' ');
              if (isLineBreakNode(node.lastChild, blockElements)) {
                text = text.replace(startWhiteSpaceRegExp, '');
              }
            }
            if (text.length !== 0) {
              textNode = createNode('#text', 3);
              textNode.raw = !!raw;
              node.append(textNode).value = text;
            }
          },
          comment: function (text) {
            node.append(createNode('#comment', 8)).value = text;
          },
          pi: function (name, text) {
            node.append(createNode(name, 7)).value = text;
            removeWhitespaceBefore(node);
          },
          doctype: function (text) {
            var newNode;
            newNode = node.append(createNode('#doctype', 10));
            newNode.value = text;
            removeWhitespaceBefore(node);
          },
          start: function (name, attrs, empty) {
            var newNode, attrFiltersLen, elementRule, attrName, parent;
            elementRule = validate ? schema.getElementRule(name) : {};
            if (elementRule) {
              newNode = createNode(elementRule.outputName || name, 1);
              newNode.attributes = attrs;
              newNode.shortEnded = empty;
              node.append(newNode);
              parent = children[node.name];
              if (parent && children[newNode.name] && !parent[newNode.name]) {
                invalidChildren.push(newNode);
              }
              attrFiltersLen = attributeFilters.length;
              while (attrFiltersLen--) {
                attrName = attributeFilters[attrFiltersLen].name;
                if (attrName in attrs.map) {
                  list = matchedAttributes[attrName];
                  if (list) {
                    list.push(newNode);
                  } else {
                    matchedAttributes[attrName] = [newNode];
                  }
                }
              }
              if (blockElements[name]) {
                removeWhitespaceBefore(newNode);
              }
              if (!empty) {
                node = newNode;
              }
              if (!isInWhiteSpacePreservedElement && whiteSpaceElements[name]) {
                isInWhiteSpacePreservedElement = true;
              }
            }
          },
          end: function (name) {
            var textNode, elementRule, text, sibling, tempNode;
            elementRule = validate ? schema.getElementRule(name) : {};
            if (elementRule) {
              if (blockElements[name]) {
                if (!isInWhiteSpacePreservedElement) {
                  textNode = node.firstChild;
                  if (textNode && textNode.type === 3) {
                    text = textNode.value.replace(startWhiteSpaceRegExp, '');
                    if (text.length > 0) {
                      textNode.value = text;
                      textNode = textNode.next;
                    } else {
                      sibling = textNode.next;
                      textNode.remove();
                      textNode = sibling;
                      while (textNode && textNode.type === 3) {
                        text = textNode.value;
                        sibling = textNode.next;
                        if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) {
                          textNode.remove();
                          textNode = sibling;
                        }
                        textNode = sibling;
                      }
                    }
                  }
                  textNode = node.lastChild;
                  if (textNode && textNode.type === 3) {
                    text = textNode.value.replace(endWhiteSpaceRegExp, '');
                    if (text.length > 0) {
                      textNode.value = text;
                      textNode = textNode.prev;
                    } else {
                      sibling = textNode.prev;
                      textNode.remove();
                      textNode = sibling;
                      while (textNode && textNode.type === 3) {
                        text = textNode.value;
                        sibling = textNode.prev;
                        if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) {
                          textNode.remove();
                          textNode = sibling;
                        }
                        textNode = sibling;
                      }
                    }
                  }
                }
              }
              if (isInWhiteSpacePreservedElement && whiteSpaceElements[name]) {
                isInWhiteSpacePreservedElement = false;
              }
              if (elementRule.removeEmpty && isEmpty$1(schema, nonEmptyElements, whiteSpaceElements, node)) {
                if (!node.attr('name') && !node.attr('id')) {
                  tempNode = node.parent;
                  if (blockElements[node.name]) {
                    node.empty().remove();
                  } else {
                    node.unwrap();
                  }
                  node = tempNode;
                  return;
                }
              }
              if (elementRule.paddEmpty && (isPaddedWithNbsp(node) || isEmpty$1(schema, nonEmptyElements, whiteSpaceElements, node))) {
                paddEmptyNode(settings, args, blockElements, node);
              }
              node = node.parent;
            }
          }
        }, schema);
        var rootNode = node = new Node$1(args.context || settings.root_name, 11);
        parser.parse(html, args.format);
        if (validate && invalidChildren.length) {
          if (!args.context) {
            fixInvalidChildren(invalidChildren);
          } else {
            args.invalid = true;
          }
        }
        if (rootBlockName && (rootNode.name === 'body' || args.isRootContent)) {
          addRootBlocks();
        }
        if (!args.invalid) {
          for (name in matchedNodes) {
            if (!matchedNodes.hasOwnProperty(name)) {
              continue;
            }
            list = nodeFilters[name];
            nodes = matchedNodes[name];
            fi = nodes.length;
            while (fi--) {
              if (!nodes[fi].parent) {
                nodes.splice(fi, 1);
              }
            }
            for (i = 0, l = list.length; i < l; i++) {
              list[i](nodes, name, args);
            }
          }
          for (i = 0, l = attributeFilters.length; i < l; i++) {
            list = attributeFilters[i];
            if (list.name in matchedAttributes) {
              nodes = matchedAttributes[list.name];
              fi = nodes.length;
              while (fi--) {
                if (!nodes[fi].parent) {
                  nodes.splice(fi, 1);
                }
              }
              for (fi = 0, fl = list.callbacks.length; fi < fl; fi++) {
                list.callbacks[fi](nodes, list.name, args);
              }
            }
          }
        }
        return rootNode;
      };
      var exports = {
        schema: schema,
        addAttributeFilter: addAttributeFilter,
        getAttributeFilters: getAttributeFilters,
        addNodeFilter: addNodeFilter,
        getNodeFilters: getNodeFilters,
        filterNode: filterNode,
        parse: parse
      };
      register$2(exports, settings);
      LegacyFilter.register(exports, settings);
      return exports;
    };

    var register$3 = function (htmlParser, settings, dom) {
      htmlParser.addAttributeFilter('data-mce-tabindex', function (nodes, name) {
        var i = nodes.length, node;
        while (i--) {
          node = nodes[i];
          node.attr('tabindex', node.attr('data-mce-tabindex'));
          node.attr(name, null);
        }
      });
      htmlParser.addAttributeFilter('src,href,style', function (nodes, name) {
        var i = nodes.length, node, value;
        var internalName = 'data-mce-' + name;
        var urlConverter = settings.url_converter;
        var urlConverterScope = settings.url_converter_scope;
        while (i--) {
          node = nodes[i];
          value = node.attr(internalName);
          if (value !== undefined) {
            node.attr(name, value.length > 0 ? value : null);
            node.attr(internalName, null);
          } else {
            value = node.attr(name);
            if (name === 'style') {
              value = dom.serializeStyle(dom.parseStyle(value), node.name);
            } else if (urlConverter) {
              value = urlConverter.call(urlConverterScope, value, name, node.name);
            }
            node.attr(name, value.length > 0 ? value : null);
          }
        }
      });
      htmlParser.addAttributeFilter('class', function (nodes) {
        var i = nodes.length, node, value;
        while (i--) {
          node = nodes[i];
          value = node.attr('class');
          if (value) {
            value = node.attr('class').replace(/(?:^|\s)mce-item-\w+(?!\S)/g, '');
            node.attr('class', value.length > 0 ? value : null);
          }
        }
      });
      htmlParser.addAttributeFilter('data-mce-type', function (nodes, name, args) {
        var i = nodes.length, node;
        while (i--) {
          node = nodes[i];
          if (node.attr('data-mce-type') === 'bookmark' && !args.cleanup) {
            var hasChildren = Option.from(node.firstChild).exists(function (firstChild) {
              return !Zwsp.isZwsp(firstChild.value);
            });
            if (hasChildren) {
              node.unwrap();
            } else {
              node.remove();
            }
          }
        }
      });
      htmlParser.addNodeFilter('noscript', function (nodes) {
        var i = nodes.length, node;
        while (i--) {
          node = nodes[i].firstChild;
          if (node) {
            node.value = Entities.decode(node.value);
          }
        }
      });
      htmlParser.addNodeFilter('script,style', function (nodes, name) {
        var i = nodes.length, node, value, type;
        var trim = function (value) {
          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, '');
        };
        while (i--) {
          node = nodes[i];
          value = node.firstChild ? node.firstChild.value : '';
          if (name === 'script') {
            type = node.attr('type');
            if (type) {
              node.attr('type', type === 'mce-no/type' ? null : type.replace(/^mce\-/, ''));
            }
            if (settings.element_format === 'xhtml' && value.length > 0) {
              node.firstChild.value = '// <![CDATA[\n' + trim(value) + '\n// ]]>';
            }
          } else {
            if (settings.element_format === 'xhtml' && value.length > 0) {
              node.firstChild.value = '<!--\n' + trim(value) + '\n-->';
            }
          }
        }
      });
      htmlParser.addNodeFilter('#comment', function (nodes) {
        var i = nodes.length, node;
        while (i--) {
          node = nodes[i];
          if (settings.preserve_cdata && node.value.indexOf('[CDATA[') === 0) {
            node.name = '#cdata';
            node.type = 4;
            node.value = dom.decode(node.value.replace(/^\[CDATA\[|\]\]$/g, ''));
          } else if (node.value.indexOf('mce:protected ') === 0) {
            node.name = '#text';
            node.type = 3;
            node.raw = true;
            node.value = unescape(node.value).substr(14);
          }
        }
      });
      htmlParser.addNodeFilter('xml:namespace,input', function (nodes, name) {
        var i = nodes.length, node;
        while (i--) {
          node = nodes[i];
          if (node.type === 7) {
            node.remove();
          } else if (node.type === 1) {
            if (name === 'input' && !node.attr('type')) {
              node.attr('type', 'text');
            }
          }
        }
      });
      htmlParser.addAttributeFilter('data-mce-type', function (nodes) {
        each(nodes, function (node) {
          if (node.attr('data-mce-type') === 'format-caret') {
            if (node.isEmpty(htmlParser.schema.getNonEmptyElements())) {
              node.remove();
            } else {
              node.unwrap();
            }
          }
        });
      });
      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) {
        var i = nodes.length;
        while (i--) {
          nodes[i].attr(name, null);
        }
      });
    };
    var trimTrailingBr = function (rootNode) {
      var brNode1, brNode2;
      var isBr = function (node) {
        return node && node.name === 'br';
      };
      brNode1 = rootNode.lastChild;
      if (isBr(brNode1)) {
        brNode2 = brNode1.prev;
        if (isBr(brNode2)) {
          brNode1.remove();
          brNode2.remove();
        }
      }
    };
    var DomSerializerFilters = {
      register: register$3,
      trimTrailingBr: trimTrailingBr
    };

    var preProcess = function (editor, node, args) {
      var impl, doc, oldDoc;
      var dom = editor.dom;
      node = node.cloneNode(true);
      impl = domGlobals.document.implementation;
      if (impl.createHTMLDocument) {
        doc = impl.createHTMLDocument('');
        Tools.each(node.nodeName === 'BODY' ? node.childNodes : [node], function (node) {
          doc.body.appendChild(doc.importNode(node, true));
        });
        if (node.nodeName !== 'BODY') {
          node = doc.body.firstChild;
        } else {
          node = doc.body;
        }
        oldDoc = dom.doc;
        dom.doc = doc;
      }
      firePreProcess(editor, __assign(__assign({}, args), { node: node }));
      if (oldDoc) {
        dom.doc = oldDoc;
      }
      return node;
    };
    var shouldFireEvent = function (editor, args) {
      return editor && editor.hasEventListeners('PreProcess') && !args.no_events;
    };
    var process = function (editor, node, args) {
      return shouldFireEvent(editor, args) ? preProcess(editor, node, args) : node;
    };
    var DomSerializerPreProcess = { process: process };

    var addTempAttr = function (htmlParser, tempAttrs, name) {
      if (Tools.inArray(tempAttrs, name) === -1) {
        htmlParser.addAttributeFilter(name, function (nodes, name) {
          var i = nodes.length;
          while (i--) {
            nodes[i].attr(name, null);
          }
        });
        tempAttrs.push(name);
      }
    };
    var postProcess = function (editor, args, content) {
      if (!args.no_events && editor) {
        var outArgs = firePostProcess(editor, __assign(__assign({}, args), { content: content }));
        return outArgs.content;
      } else {
        return content;
      }
    };
    var getHtmlFromNode = function (dom, node, args) {
      var html = Zwsp.trim(args.getInner ? node.innerHTML : dom.getOuterHTML(node));
      return args.selection || isWsPreserveElement(Element.fromDom(node)) ? html : Tools.trim(html);
    };
    var parseHtml = function (htmlParser, html, args) {
      var parserArgs = args.selection ? __assign({ forced_root_block: false }, args) : args;
      var rootNode = htmlParser.parse(html, parserArgs);
      DomSerializerFilters.trimTrailingBr(rootNode);
      return rootNode;
    };
    var serializeNode = function (settings, schema, node) {
      var htmlSerializer = Serializer(settings, schema);
      return htmlSerializer.serialize(node);
    };
    var toHtml = function (editor, settings, schema, rootNode, args) {
      var content = serializeNode(settings, schema, rootNode);
      return postProcess(editor, args, content);
    };
    var DomSerializer = function (settings, editor) {
      var tempAttrs = ['data-mce-selected'];
      var dom = editor && editor.dom ? editor.dom : DOMUtils$1.DOM;
      var schema = editor && editor.schema ? editor.schema : Schema(settings);
      settings.entity_encoding = settings.entity_encoding || 'named';
      settings.remove_trailing_brs = 'remove_trailing_brs' in settings ? settings.remove_trailing_brs : true;
      var htmlParser = DomParser(settings, schema);
      DomSerializerFilters.register(htmlParser, settings, dom);
      var serialize = function (node, parserArgs) {
        if (parserArgs === void 0) {
          parserArgs = {};
        }
        var args = __assign({ format: 'html' }, parserArgs);
        var targetNode = DomSerializerPreProcess.process(editor, node, args);
        var html = getHtmlFromNode(dom, targetNode, args);
        var rootNode = parseHtml(htmlParser, html, args);
        return args.format === 'tree' ? rootNode : toHtml(editor, settings, schema, rootNode, args);
      };
      return {
        schema: schema,
        addNodeFilter: htmlParser.addNodeFilter,
        addAttributeFilter: htmlParser.addAttributeFilter,
        serialize: serialize,
        addRules: function (rules) {
          schema.addValidElements(rules);
        },
        setRules: function (rules) {
          schema.setValidElements(rules);
        },
        addTempAttr: curry(addTempAttr, htmlParser, tempAttrs),
        getTempAttrs: function () {
          return tempAttrs;
        },
        getNodeFilters: htmlParser.getNodeFilters,
        getAttributeFilters: htmlParser.getAttributeFilters
      };
    };

    var Serializer$1 = function (settings, editor) {
      var domSerializer = DomSerializer(settings, editor);
      return {
        schema: domSerializer.schema,
        addNodeFilter: domSerializer.addNodeFilter,
        addAttributeFilter: domSerializer.addAttributeFilter,
        serialize: domSerializer.serialize,
        addRules: domSerializer.addRules,
        setRules: domSerializer.setRules,
        addTempAttr: domSerializer.addTempAttr,
        getTempAttrs: domSerializer.getTempAttrs,
        getNodeFilters: domSerializer.getNodeFilters,
        getAttributeFilters: domSerializer.getAttributeFilters
      };
    };

    var blobUriToBlob = function (url) {
      return new promiseObj(function (resolve, reject) {
        var rejectWithError = function () {
          reject('Cannot convert ' + url + ' to Blob. Resource might not exist or is inaccessible.');
        };
        try {
          var xhr = new domGlobals.XMLHttpRequest();
          xhr.open('GET', url, true);
          xhr.responseType = 'blob';
          xhr.onload = function () {
            if (this.status === 200) {
              resolve(this.response);
            } else {
              rejectWithError();
            }
          };
          xhr.onerror = rejectWithError;
          xhr.send();
        } catch (ex) {
          rejectWithError();
        }
      });
    };
    var parseDataUri = function (uri) {
      var type, matches;
      var uriParts = decodeURIComponent(uri).split(',');
      matches = /data:([^;]+)/.exec(uriParts[0]);
      if (matches) {
        type = matches[1];
      }
      return {
        type: type,
        data: uriParts[1]
      };
    };
    var dataUriToBlob = function (uri) {
      return new promiseObj(function (resolve) {
        var str, arr, i;
        var uriParts = parseDataUri(uri);
        try {
          str = domGlobals.atob(uriParts.data);
        } catch (e) {
          resolve(new domGlobals.Blob([]));
          return;
        }
        arr = new Uint8Array(str.length);
        for (i = 0; i < arr.length; i++) {
          arr[i] = str.charCodeAt(i);
        }
        resolve(new domGlobals.Blob([arr], { type: uriParts.type }));
      });
    };
    var uriToBlob = function (url) {
      if (url.indexOf('blob:') === 0) {
        return blobUriToBlob(url);
      }
      if (url.indexOf('data:') === 0) {
        return dataUriToBlob(url);
      }
      return null;
    };
    var blobToDataUri = function (blob) {
      return new promiseObj(function (resolve) {
        var reader = new domGlobals.FileReader();
        reader.onloadend = function () {
          resolve(reader.result);
        };
        reader.readAsDataURL(blob);
      });
    };
    var Conversions = {
      uriToBlob: uriToBlob,
      blobToDataUri: blobToDataUri,
      parseDataUri: parseDataUri
    };

    var count = 0;
    var uniqueId = function (prefix) {
      return (prefix || 'blobid') + count++;
    };
    var imageToBlobInfo = function (blobCache, img, resolve, reject) {
      var base64, blobInfo;
      if (img.src.indexOf('blob:') === 0) {
        blobInfo = blobCache.getByUri(img.src);
        if (blobInfo) {
          resolve({
            image: img,
            blobInfo: blobInfo
          });
        } else {
          Conversions.uriToBlob(img.src).then(function (blob) {
            Conversions.blobToDataUri(blob).then(function (dataUri) {
              base64 = Conversions.parseDataUri(dataUri).data;
              blobInfo = blobCache.create(uniqueId(), blob, base64);
              blobCache.add(blobInfo);
              resolve({
                image: img,
                blobInfo: blobInfo
              });
            });
          }, function (err) {
            reject(err);
          });
        }
        return;
      }
      base64 = Conversions.parseDataUri(img.src).data;
      blobInfo = blobCache.findFirst(function (cachedBlobInfo) {
        return cachedBlobInfo.base64() === base64;
      });
      if (blobInfo) {
        resolve({
          image: img,
          blobInfo: blobInfo
        });
      } else {
        Conversions.uriToBlob(img.src).then(function (blob) {
          blobInfo = blobCache.create(uniqueId(), blob, base64);
          blobCache.add(blobInfo);
          resolve({
            image: img,
            blobInfo: blobInfo
          });
        }, function (err) {
          reject(err);
        });
      }
    };
    var getAllImages = function (elm) {
      return elm ? from$1(elm.getElementsByTagName('img')) : [];
    };
    function ImageScanner(uploadStatus, blobCache) {
      var cachedPromises = {};
      var findAll = function (elm, predicate) {
        var images;
        if (!predicate) {
          predicate = constant(true);
        }
        images = filter(getAllImages(elm), function (img) {
          var src = img.src;
          if (!Env.fileApi) {
            return false;
          }
          if (img.hasAttribute('data-mce-bogus')) {
            return false;
          }
          if (img.hasAttribute('data-mce-placeholder')) {
            return false;
          }
          if (!src || src === Env.transparentSrc) {
            return false;
          }
          if (src.indexOf('blob:') === 0) {
            return !uploadStatus.isUploaded(src) && predicate(img);
          }
          if (src.indexOf('data:') === 0) {
            return predicate(img);
          }
          return false;
        });
        var promises = map(images, function (img) {
          if (cachedPromises[img.src]) {
            return new promiseObj(function (resolve) {
              cachedPromises[img.src].then(function (imageInfo) {
                if (typeof imageInfo === 'string') {
                  return imageInfo;
                }
                resolve({
                  image: img,
                  blobInfo: imageInfo.blobInfo
                });
              });
            });
          }
          var newPromise = new promiseObj(function (resolve, reject) {
            imageToBlobInfo(blobCache, img, resolve, reject);
          }).then(function (result) {
            delete cachedPromises[result.image.src];
            return result;
          }).catch(function (error) {
            delete cachedPromises[img.src];
            return error;
          });
          cachedPromises[img.src] = newPromise;
          return newPromise;
        });
        return promiseObj.all(promises);
      };
      return { findAll: findAll };
    }

    function Uploader(uploadStatus, settings) {
      var pendingPromises = {};
      var pathJoin = function (path1, path2) {
        if (path1) {
          return path1.replace(/\/$/, '') + '/' + path2.replace(/^\//, '');
        }
        return path2;
      };
      var defaultHandler = function (blobInfo, success, failure, progress) {
        var xhr, formData;
        xhr = new domGlobals.XMLHttpRequest();
        xhr.open('POST', settings.url);
        xhr.withCredentials = settings.credentials;
        xhr.upload.onprogress = function (e) {
          progress(e.loaded / e.total * 100);
        };
        xhr.onerror = function () {
          failure('Image upload failed due to a XHR Transport error. Code: ' + xhr.status);
        };
        xhr.onload = function () {
          var json;
          if (xhr.status < 200 || xhr.status >= 300) {
            failure('HTTP Error: ' + xhr.status);
            return;
          }
          json = JSON.parse(xhr.responseText);
          if (!json || typeof json.location !== 'string') {
            failure('Invalid JSON: ' + xhr.responseText);
            return;
          }
          success(pathJoin(settings.basePath, json.location));
        };
        formData = new domGlobals.FormData();
        formData.append('file', blobInfo.blob(), blobInfo.filename());
        xhr.send(formData);
      };
      var noUpload = function () {
        return new promiseObj(function (resolve) {
          resolve([]);
        });
      };
      var handlerSuccess = function (blobInfo, url) {
        return {
          url: url,
          blobInfo: blobInfo,
          status: true
        };
      };
      var handlerFailure = function (blobInfo, error) {
        return {
          url: '',
          blobInfo: blobInfo,
          status: false,
          error: error
        };
      };
      var resolvePending = function (blobUri, result) {
        Tools.each(pendingPromises[blobUri], function (resolve) {
          resolve(result);
        });
        delete pendingPromises[blobUri];
      };
      var uploadBlobInfo = function (blobInfo, handler, openNotification) {
        uploadStatus.markPending(blobInfo.blobUri());
        return new promiseObj(function (resolve) {
          var notification, progress;
          var noop = function () {
          };
          try {
            var closeNotification_1 = function () {
              if (notification) {
                notification.close();
                progress = noop;
              }
            };
            var success = function (url) {
              closeNotification_1();
              uploadStatus.markUploaded(blobInfo.blobUri(), url);
              resolvePending(blobInfo.blobUri(), handlerSuccess(blobInfo, url));
              resolve(handlerSuccess(blobInfo, url));
            };
            var failure = function (error) {
              closeNotification_1();
              uploadStatus.removeFailed(blobInfo.blobUri());
              resolvePending(blobInfo.blobUri(), handlerFailure(blobInfo, error));
              resolve(handlerFailure(blobInfo, error));
            };
            progress = function (percent) {
              if (percent < 0 || percent > 100) {
                return;
              }
              if (!notification) {
                notification = openNotification();
              }
              notification.progressBar.value(percent);
            };
            handler(blobInfo, success, failure, progress);
          } catch (ex) {
            resolve(handlerFailure(blobInfo, ex.message));
          }
        });
      };
      var isDefaultHandler = function (handler) {
        return handler === defaultHandler;
      };
      var pendingUploadBlobInfo = function (blobInfo) {
        var blobUri = blobInfo.blobUri();
        return new promiseObj(function (resolve) {
          pendingPromises[blobUri] = pendingPromises[blobUri] || [];
          pendingPromises[blobUri].push(resolve);
        });
      };
      var uploadBlobs = function (blobInfos, openNotification) {
        blobInfos = Tools.grep(blobInfos, function (blobInfo) {
          return !uploadStatus.isUploaded(blobInfo.blobUri());
        });
        return promiseObj.all(Tools.map(blobInfos, function (blobInfo) {
          return uploadStatus.isPending(blobInfo.blobUri()) ? pendingUploadBlobInfo(blobInfo) : uploadBlobInfo(blobInfo, settings.handler, openNotification);
        }));
      };
      var upload = function (blobInfos, openNotification) {
        return !settings.url && isDefaultHandler(settings.handler) ? noUpload() : uploadBlobs(blobInfos, openNotification);
      };
      if (isFunction(settings.handler) === false) {
        settings.handler = defaultHandler;
      }
      return { upload: upload };
    }

    function UploadStatus () {
      var PENDING = 1, UPLOADED = 2;
      var blobUriStatuses = {};
      var createStatus = function (status, resultUri) {
        return {
          status: status,
          resultUri: resultUri
        };
      };
      var hasBlobUri = function (blobUri) {
        return blobUri in blobUriStatuses;
      };
      var getResultUri = function (blobUri) {
        var result = blobUriStatuses[blobUri];
        return result ? result.resultUri : null;
      };
      var isPending = function (blobUri) {
        return hasBlobUri(blobUri) ? blobUriStatuses[blobUri].status === PENDING : false;
      };
      var isUploaded = function (blobUri) {
        return hasBlobUri(blobUri) ? blobUriStatuses[blobUri].status === UPLOADED : false;
      };
      var markPending = function (blobUri) {
        blobUriStatuses[blobUri] = createStatus(PENDING, null);
      };
      var markUploaded = function (blobUri, resultUri) {
        blobUriStatuses[blobUri] = createStatus(UPLOADED, resultUri);
      };
      var removeFailed = function (blobUri) {
        delete blobUriStatuses[blobUri];
      };
      var destroy = function () {
        blobUriStatuses = {};
      };
      return {
        hasBlobUri: hasBlobUri,
        getResultUri: getResultUri,
        isPending: isPending,
        isUploaded: isUploaded,
        markPending: markPending,
        markUploaded: markUploaded,
        removeFailed: removeFailed,
        destroy: destroy
      };
    }

    var count$1 = 0;
    var seed = function () {
      var rnd = function () {
        return Math.round(Math.random() * 4294967295).toString(36);
      };
      var now = new Date().getTime();
      return 's' + now.toString(36) + rnd() + rnd() + rnd();
    };
    var uuid = function (prefix) {
      return prefix + count$1++ + seed();
    };
    var Uuid = { uuid: uuid };

    var BlobCache = function () {
      var cache = [];
      var mimeToExt = function (mime) {
        var mimes = {
          'image/jpeg': 'jpg',
          'image/jpg': 'jpg',
          'image/gif': 'gif',
          'image/png': 'png'
        };
        return mimes[mime.toLowerCase()] || 'dat';
      };
      var create = function (o, blob, base64, filename) {
        if (isString(o)) {
          var id = o;
          return toBlobInfo({
            id: id,
            name: filename,
            blob: blob,
            base64: base64
          });
        } else if (isObject(o)) {
          return toBlobInfo(o);
        } else {
          throw new Error('Unknown input type');
        }
      };
      var toBlobInfo = function (o) {
        var id, name;
        if (!o.blob || !o.base64) {
          throw new Error('blob and base64 representations of the image are required for BlobInfo to be created');
        }
        id = o.id || Uuid.uuid('blobid');
        name = o.name || id;
        return {
          id: constant(id),
          name: constant(name),
          filename: constant(name + '.' + mimeToExt(o.blob.type)),
          blob: constant(o.blob),
          base64: constant(o.base64),
          blobUri: constant(o.blobUri || domGlobals.URL.createObjectURL(o.blob)),
          uri: constant(o.uri)
        };
      };
      var add = function (blobInfo) {
        if (!get(blobInfo.id())) {
          cache.push(blobInfo);
        }
      };
      var get = function (id) {
        return findFirst(function (cachedBlobInfo) {
          return cachedBlobInfo.id() === id;
        });
      };
      var findFirst = function (predicate) {
        return filter(cache, predicate)[0];
      };
      var getByUri = function (blobUri) {
        return findFirst(function (blobInfo) {
          return blobInfo.blobUri() === blobUri;
        });
      };
      var removeByUri = function (blobUri) {
        cache = filter(cache, function (blobInfo) {
          if (blobInfo.blobUri() === blobUri) {
            domGlobals.URL.revokeObjectURL(blobInfo.blobUri());
            return false;
          }
          return true;
        });
      };
      var destroy = function () {
        each(cache, function (cachedBlobInfo) {
          domGlobals.URL.revokeObjectURL(cachedBlobInfo.blobUri());
        });
        cache = [];
      };
      return {
        create: create,
        add: add,
        get: get,
        getByUri: getByUri,
        findFirst: findFirst,
        removeByUri: removeByUri,
        destroy: destroy
      };
    };

    var EditorUpload = function (editor) {
      var blobCache = BlobCache();
      var uploader, imageScanner;
      var uploadStatus = UploadStatus();
      var urlFilters = [];
      var aliveGuard = function (callback) {
        return function (result) {
          if (editor.selection) {
            return callback(result);
          }
          return [];
        };
      };
      var cacheInvalidator = function (url) {
        return url + (url.indexOf('?') === -1 ? '?' : '&') + new Date().getTime();
      };
      var replaceString = function (content, search, replace) {
        var index = 0;
        do {
          index = content.indexOf(search, index);
          if (index !== -1) {
            content = content.substring(0, index) + replace + content.substr(index + search.length);
            index += replace.length - search.length + 1;
          }
        } while (index !== -1);
        return content;
      };
      var replaceImageUrl = function (content, targetUrl, replacementUrl) {
        content = replaceString(content, 'src="' + targetUrl + '"', 'src="' + replacementUrl + '"');
        content = replaceString(content, 'data-mce-src="' + targetUrl + '"', 'data-mce-src="' + replacementUrl + '"');
        return content;
      };
      var replaceUrlInUndoStack = function (targetUrl, replacementUrl) {
        each(editor.undoManager.data, function (level) {
          if (level.type === 'fragmented') {
            level.fragments = map(level.fragments, function (fragment) {
              return replaceImageUrl(fragment, targetUrl, replacementUrl);
            });
          } else {
            level.content = replaceImageUrl(level.content, targetUrl, replacementUrl);
          }
        });
      };
      var openNotification = function () {
        return editor.notificationManager.open({
          text: editor.translate('Image uploading...'),
          type: 'info',
          timeout: -1,
          progressBar: true
        });
      };
      var replaceImageUri = function (image, resultUri) {
        blobCache.removeByUri(image.src);
        replaceUrlInUndoStack(image.src, resultUri);
        editor.$(image).attr({
          'src': Settings.shouldReuseFileName(editor) ? cacheInvalidator(resultUri) : resultUri,
          'data-mce-src': editor.convertURL(resultUri, 'src')
        });
      };
      var uploadImages = function (callback) {
        if (!uploader) {
          uploader = Uploader(uploadStatus, {
            url: Settings.getImageUploadUrl(editor),
            basePath: Settings.getImageUploadBasePath(editor),
            credentials: Settings.getImagesUploadCredentials(editor),
            handler: Settings.getImagesUploadHandler(editor)
          });
        }
        return scanForImages().then(aliveGuard(function (imageInfos) {
          var blobInfos = map(imageInfos, function (imageInfo) {
            return imageInfo.blobInfo;
          });
          return uploader.upload(blobInfos, openNotification).then(aliveGuard(function (result) {
            var filteredResult = map(result, function (uploadInfo, index) {
              var image = imageInfos[index].image;
              if (uploadInfo.status && Settings.shouldReplaceBlobUris(editor)) {
                replaceImageUri(image, uploadInfo.url);
              } else if (uploadInfo.error) {
                ErrorReporter.uploadError(editor, uploadInfo.error);
              }
              return {
                element: image,
                status: uploadInfo.status
              };
            });
            if (callback) {
              callback(filteredResult);
            }
            return filteredResult;
          }));
        }));
      };
      var uploadImagesAuto = function (callback) {
        if (Settings.isAutomaticUploadsEnabled(editor)) {
          return uploadImages(callback);
        }
      };
      var isValidDataUriImage = function (imgElm) {
        if (forall(urlFilters, function (filter) {
            return filter(imgElm);
          }) === false) {
          return false;
        }
        if (imgElm.getAttribute('src').indexOf('data:') === 0) {
          var dataImgFilter = Settings.getImagesDataImgFilter(editor);
          return dataImgFilter(imgElm);
        }
        return true;
      };
      var addFilter = function (filter) {
        urlFilters.push(filter);
      };
      var scanForImages = function () {
        if (!imageScanner) {
          imageScanner = ImageScanner(uploadStatus, blobCache);
        }
        return imageScanner.findAll(editor.getBody(), isValidDataUriImage).then(aliveGuard(function (result) {
          result = filter(result, function (resultItem) {
            if (typeof resultItem === 'string') {
              ErrorReporter.displayError(editor, resultItem);
              return false;
            }
            return true;
          });
          each(result, function (resultItem) {
            replaceUrlInUndoStack(resultItem.image.src, resultItem.blobInfo.blobUri());
            resultItem.image.src = resultItem.blobInfo.blobUri();
            resultItem.image.removeAttribute('data-mce-src');
          });
          return result;
        }));
      };
      var destroy = function () {
        blobCache.destroy();
        uploadStatus.destroy();
        imageScanner = uploader = null;
      };
      var replaceBlobUris = function (content) {
        return content.replace(/src="(blob:[^"]+)"/g, function (match, blobUri) {
          var resultUri = uploadStatus.getResultUri(blobUri);
          if (resultUri) {
            return 'src="' + resultUri + '"';
          }
          var blobInfo = blobCache.getByUri(blobUri);
          if (!blobInfo) {
            blobInfo = foldl(editor.editorManager.get(), function (result, editor) {
              return result || editor.editorUpload && editor.editorUpload.blobCache.getByUri(blobUri);
            }, null);
          }
          if (blobInfo) {
            var blob = blobInfo.blob();
            return 'src="data:' + blob.type + ';base64,' + blobInfo.base64() + '"';
          }
          return match;
        });
      };
      editor.on('SetContent', function () {
        if (Settings.isAutomaticUploadsEnabled(editor)) {
          uploadImagesAuto();
        } else {
          scanForImages();
        }
      });
      editor.on('RawSaveContent', function (e) {
        e.content = replaceBlobUris(e.content);
      });
      editor.on('GetContent', function (e) {
        if (e.source_view || e.format === 'raw') {
          return;
        }
        e.content = replaceBlobUris(e.content);
      });
      editor.on('PostRender', function () {
        editor.parser.addNodeFilter('img', function (images) {
          each(images, function (img) {
            var src = img.attr('src');
            if (blobCache.getByUri(src)) {
              return;
            }
            var resultUri = uploadStatus.getResultUri(src);
            if (resultUri) {
              img.attr('src', resultUri);
            }
          });
        });
      });
      return {
        blobCache: blobCache,
        addFilter: addFilter,
        uploadImages: uploadImages,
        uploadImagesAuto: uploadImagesAuto,
        scanForImages: scanForImages,
        destroy: destroy
      };
    };

    var getLastChildren$1 = function (elm) {
      var children = [];
      var rawNode = elm.dom();
      while (rawNode) {
        children.push(Element.fromDom(rawNode));
        rawNode = rawNode.lastChild;
      }
      return children;
    };
    var removeTrailingBr = function (elm) {
      var allBrs = descendants$1(elm, 'br');
      var brs = filter(getLastChildren$1(elm).slice(-1), isBr$1);
      if (allBrs.length === brs.length) {
        each(brs, remove);
      }
    };
    var fillWithPaddingBr = function (elm) {
      empty(elm);
      append(elm, Element.fromHtml('<br data-mce-bogus="1">'));
    };
    var isPaddingContents = function (elm) {
      return isText(elm) ? get$7(elm) === nbsp : isBr$1(elm);
    };
    var isPaddedElement = function (elm) {
      return filter(children(elm), isPaddingContents).length === 1;
    };
    var trimBlockTrailingBr = function (elm) {
      lastChild(elm).each(function (lastChild) {
        prevSibling(lastChild).each(function (lastChildPrevSibling) {
          if (isBlock(elm) && isBr$1(lastChild) && isBlock(lastChildPrevSibling)) {
            remove(lastChild);
          }
        });
      });
    };
    var PaddingBr = {
      removeTrailingBr: removeTrailingBr,
      fillWithPaddingBr: fillWithPaddingBr,
      isPaddedElement: isPaddedElement,
      trimBlockTrailingBr: trimBlockTrailingBr
    };

    var isEq$2 = isEq;
    var matchesUnInheritedFormatSelector = function (ed, node, name) {
      var formatList = ed.formatter.get(name);
      if (formatList) {
        for (var i = 0; i < formatList.length; i++) {
          if (formatList[i].inherit === false && ed.dom.is(node, formatList[i].selector)) {
            return true;
          }
        }
      }
      return false;
    };
    var matchParents = function (editor, node, name, vars) {
      var root = editor.dom.getRoot();
      if (node === root) {
        return false;
      }
      node = editor.dom.getParent(node, function (node) {
        if (matchesUnInheritedFormatSelector(editor, node, name)) {
          return true;
        }
        return node.parentNode === root || !!matchNode(editor, node, name, vars, true);
      });
      return matchNode(editor, node, name, vars);
    };
    var matchName = function (dom, node, format) {
      if (isEq$2(node, format.inline)) {
        return true;
      }
      if (isEq$2(node, format.block)) {
        return true;
      }
      if (format.selector) {
        return node.nodeType === 1 && dom.is(node, format.selector);
      }
    };
    var matchItems = function (dom, node, format, itemName, similar, vars) {
      var key, value;
      var items = format[itemName];
      var i;
      if (format.onmatch) {
        return format.onmatch(node, format, itemName);
      }
      if (items) {
        if (typeof items.length === 'undefined') {
          for (key in items) {
            if (items.hasOwnProperty(key)) {
              if (itemName === 'attributes') {
                value = dom.getAttrib(node, key);
              } else {
                value = getStyle(dom, node, key);
              }
              if (similar && !value && !format.exact) {
                return;
              }
              if ((!similar || format.exact) && !isEq$2(value, normalizeStyleValue(dom, replaceVars(items[key], vars), key))) {
                return;
              }
            }
          }
        } else {
          for (i = 0; i < items.length; i++) {
            if (itemName === 'attributes' ? dom.getAttrib(node, items[i]) : getStyle(dom, node, items[i])) {
              return format;
            }
          }
        }
      }
      return format;
    };
    var matchNode = function (ed, node, name, vars, similar) {
      var formatList = ed.formatter.get(name);
      var format, i, x, classes;
      var dom = ed.dom;
      if (formatList && node) {
        for (i = 0; i < formatList.length; i++) {
          format = formatList[i];
          if (matchName(ed.dom, node, format) && matchItems(dom, node, format, 'attributes', similar, vars) && matchItems(dom, node, format, 'styles', similar, vars)) {
            if (classes = format.classes) {
              for (x = 0; x < classes.length; x++) {
                if (!ed.dom.hasClass(node, classes[x])) {
                  return;
                }
              }
            }
            return format;
          }
        }
      }
    };
    var match = function (editor, name, vars, node) {
      var startNode;
      if (node) {
        return matchParents(editor, node, name, vars);
      }
      node = editor.selection.getNode();
      if (matchParents(editor, node, name, vars)) {
        return true;
      }
      startNode = editor.selection.getStart();
      if (startNode !== node) {
        if (matchParents(editor, startNode, name, vars)) {
          return true;
        }
      }
      return false;
    };
    var matchAll = function (editor, names, vars) {
      var startElement;
      var matchedFormatNames = [];
      var checkedMap = {};
      startElement = editor.selection.getStart();
      editor.dom.getParent(startElement, function (node) {
        var i, name;
        for (i = 0; i < names.length; i++) {
          name = names[i];
          if (!checkedMap[name] && matchNode(editor, node, name, vars)) {
            checkedMap[name] = true;
            matchedFormatNames.push(name);
          }
        }
      }, editor.dom.getRoot());
      return matchedFormatNames;
    };
    var canApply = function (editor, name) {
      var formatList = editor.formatter.get(name);
      var startNode, parents, i, x, selector;
      var dom = editor.dom;
      if (formatList) {
        startNode = editor.selection.getStart();
        parents = getParents$1(dom, startNode);
        for (x = formatList.length - 1; x >= 0; x--) {
          selector = formatList[x].selector;
          if (!selector || formatList[x].defaultBlock) {
            return true;
          }
          for (i = parents.length - 1; i >= 0; i--) {
            if (dom.is(parents[i], selector)) {
              return true;
            }
          }
        }
      }
      return false;
    };

    var splitText = function (node, offset) {
      return node.splitText(offset);
    };
    var split$1 = function (rng) {
      var startContainer = rng.startContainer, startOffset = rng.startOffset, endContainer = rng.endContainer, endOffset = rng.endOffset;
      if (startContainer === endContainer && NodeType.isText(startContainer)) {
        if (startOffset > 0 && startOffset < startContainer.nodeValue.length) {
          endContainer = splitText(startContainer, startOffset);
          startContainer = endContainer.previousSibling;
          if (endOffset > startOffset) {
            endOffset = endOffset - startOffset;
            startContainer = endContainer = splitText(endContainer, endOffset).previousSibling;
            endOffset = endContainer.nodeValue.length;
            startOffset = 0;
          } else {
            endOffset = 0;
          }
        }
      } else {
        if (NodeType.isText(startContainer) && startOffset > 0 && startOffset < startContainer.nodeValue.length) {
          startContainer = splitText(startContainer, startOffset);
          startOffset = 0;
        }
        if (NodeType.isText(endContainer) && endOffset > 0 && endOffset < endContainer.nodeValue.length) {
          endContainer = splitText(endContainer, endOffset).previousSibling;
          endOffset = endContainer.nodeValue.length;
        }
      }
      return {
        startContainer: startContainer,
        startOffset: startOffset,
        endContainer: endContainer,
        endOffset: endOffset
      };
    };

    var normalizeContent = function (content, isStartOfContent, isEndOfContent) {
      var result = foldl(content, function (acc, c) {
        if (isWhiteSpace$1(c) || isNbsp(c)) {
          if (acc.previousCharIsSpace || acc.str === '' && isStartOfContent || acc.str.length === content.length - 1 && isEndOfContent) {
            return {
              previousCharIsSpace: false,
              str: acc.str + nbsp
            };
          } else {
            return {
              previousCharIsSpace: true,
              str: acc.str + ' '
            };
          }
        } else {
          return {
            previousCharIsSpace: false,
            str: acc.str + c
          };
        }
      }, {
        previousCharIsSpace: false,
        str: ''
      });
      return result.str;
    };
    var normalize$1 = function (node, offset, count) {
      if (count === 0) {
        return;
      }
      var whitespace = node.data.slice(offset, offset + count);
      var isEndOfContent = offset + count >= node.data.length;
      var isStartOfContent = offset === 0;
      node.replaceData(offset, count, normalizeContent(whitespace, isStartOfContent, isEndOfContent));
    };
    var normalizeWhitespaceAfter = function (node, offset) {
      var content = node.data.slice(offset);
      var whitespaceCount = content.length - lTrim(content).length;
      return normalize$1(node, offset, whitespaceCount);
    };
    var normalizeWhitespaceBefore = function (node, offset) {
      var content = node.data.slice(0, offset);
      var whitespaceCount = content.length - rTrim(content).length;
      return normalize$1(node, offset - whitespaceCount, whitespaceCount);
    };
    var mergeTextNodes = function (prevNode, nextNode, normalizeWhitespace) {
      var whitespaceOffset = rTrim(prevNode.data).length;
      prevNode.appendData(nextNode.data);
      remove(Element.fromDom(nextNode));
      if (normalizeWhitespace) {
        normalizeWhitespaceAfter(prevNode, whitespaceOffset);
      }
      return prevNode;
    };

    var ancestor$2 = function (scope, selector, isRoot) {
      return ancestor$1(scope, selector, isRoot).isSome();
    };

    var hasWhitespacePreserveParent = function (rootNode, node) {
      var rootElement = Element.fromDom(rootNode);
      var startNode = Element.fromDom(node);
      return ancestor$2(startNode, 'pre,code', curry(eq, rootElement));
    };
    var isWhitespace = function (rootNode, node) {
      return NodeType.isText(node) && /^[ \t\r\n]*$/.test(node.data) && hasWhitespacePreserveParent(rootNode, node) === false;
    };
    var isNamedAnchor = function (node) {
      return NodeType.isElement(node) && node.nodeName === 'A' && node.hasAttribute('name');
    };
    var isContent$1 = function (rootNode, node) {
      return isCaretCandidate(node) && isWhitespace(rootNode, node) === false || isNamedAnchor(node) || isBookmark(node);
    };
    var isBookmark = NodeType.hasAttribute('data-mce-bookmark');
    var isBogus$2 = NodeType.hasAttribute('data-mce-bogus');
    var isBogusAll$1 = NodeType.hasAttributeValue('data-mce-bogus', 'all');
    var isEmptyNode = function (targetNode, skipBogus) {
      var node, brCount = 0;
      if (isContent$1(targetNode, targetNode)) {
        return false;
      } else {
        node = targetNode.firstChild;
        if (!node) {
          return true;
        }
        var walker = new TreeWalker(node, targetNode);
        do {
          if (skipBogus) {
            if (isBogusAll$1(node)) {
              node = walker.next(true);
              continue;
            }
            if (isBogus$2(node)) {
              node = walker.next();
              continue;
            }
          }
          if (NodeType.isBr(node)) {
            brCount++;
            node = walker.next();
            continue;
          }
          if (isContent$1(targetNode, node)) {
            return false;
          }
          node = walker.next();
        } while (node);
        return brCount <= 1;
      }
    };
    var isEmpty$2 = function (elm, skipBogus) {
      if (skipBogus === void 0) {
        skipBogus = true;
      }
      return isEmptyNode(elm.dom(), skipBogus);
    };
    var Empty = { isEmpty: isEmpty$2 };

    var needsReposition = function (pos, elm) {
      var container = pos.container();
      var offset = pos.offset();
      return CaretPosition$1.isTextPosition(pos) === false && container === elm.parentNode && offset > CaretPosition$1.before(elm).offset();
    };
    var reposition = function (elm, pos) {
      return needsReposition(pos, elm) ? CaretPosition$1(pos.container(), pos.offset() - 1) : pos;
    };
    var beforeOrStartOf = function (node) {
      return NodeType.isText(node) ? CaretPosition$1(node, 0) : CaretPosition$1.before(node);
    };
    var afterOrEndOf = function (node) {
      return NodeType.isText(node) ? CaretPosition$1(node, node.data.length) : CaretPosition$1.after(node);
    };
    var getPreviousSiblingCaretPosition = function (elm) {
      if (isCaretCandidate(elm.previousSibling)) {
        return Option.some(afterOrEndOf(elm.previousSibling));
      } else {
        return elm.previousSibling ? CaretFinder.lastPositionIn(elm.previousSibling) : Option.none();
      }
    };
    var getNextSiblingCaretPosition = function (elm) {
      if (isCaretCandidate(elm.nextSibling)) {
        return Option.some(beforeOrStartOf(elm.nextSibling));
      } else {
        return elm.nextSibling ? CaretFinder.firstPositionIn(elm.nextSibling) : Option.none();
      }
    };
    var findCaretPositionBackwardsFromElm = function (rootElement, elm) {
      var startPosition = CaretPosition$1.before(elm.previousSibling ? elm.previousSibling : elm.parentNode);
      return CaretFinder.prevPosition(rootElement, startPosition).fold(function () {
        return CaretFinder.nextPosition(rootElement, CaretPosition$1.after(elm));
      }, Option.some);
    };
    var findCaretPositionForwardsFromElm = function (rootElement, elm) {
      return CaretFinder.nextPosition(rootElement, CaretPosition$1.after(elm)).fold(function () {
        return CaretFinder.prevPosition(rootElement, CaretPosition$1.before(elm));
      }, Option.some);
    };
    var findCaretPositionBackwards = function (rootElement, elm) {
      return getPreviousSiblingCaretPosition(elm).orThunk(function () {
        return getNextSiblingCaretPosition(elm);
      }).orThunk(function () {
        return findCaretPositionBackwardsFromElm(rootElement, elm);
      });
    };
    var findCaretPositionForward = function (rootElement, elm) {
      return getNextSiblingCaretPosition(elm).orThunk(function () {
        return getPreviousSiblingCaretPosition(elm);
      }).orThunk(function () {
        return findCaretPositionForwardsFromElm(rootElement, elm);
      });
    };
    var findCaretPosition$1 = function (forward, rootElement, elm) {
      return forward ? findCaretPositionForward(rootElement, elm) : findCaretPositionBackwards(rootElement, elm);
    };
    var findCaretPosOutsideElmAfterDelete = function (forward, rootElement, elm) {
      return findCaretPosition$1(forward, rootElement, elm).map(curry(reposition, elm));
    };
    var setSelection = function (editor, forward, pos) {
      pos.fold(function () {
        editor.focus();
      }, function (pos) {
        editor.selection.setRng(pos.toRange(), forward);
      });
    };
    var eqRawNode = function (rawNode) {
      return function (elm) {
        return elm.dom() === rawNode;
      };
    };
    var isBlock$2 = function (editor, elm) {
      return elm && editor.schema.getBlockElements().hasOwnProperty(name(elm));
    };
    var paddEmptyBlock = function (elm) {
      if (Empty.isEmpty(elm)) {
        var br = Element.fromHtml('<br data-mce-bogus="1">');
        empty(elm);
        append(elm, br);
        return Option.some(CaretPosition$1.before(br.dom()));
      } else {
        return Option.none();
      }
    };
    var deleteNormalized = function (elm, afterDeletePosOpt, normalizeWhitespace) {
      var prevTextOpt = prevSibling(elm).filter(isText);
      var nextTextOpt = nextSibling(elm).filter(isText);
      remove(elm);
      return lift3(prevTextOpt, nextTextOpt, afterDeletePosOpt, function (prev, next, pos) {
        var prevNode = prev.dom(), nextNode = next.dom();
        var offset = prevNode.data.length;
        mergeTextNodes(prevNode, nextNode, normalizeWhitespace);
        return pos.container() === nextNode ? CaretPosition$1(prevNode, offset) : pos;
      }).orThunk(function () {
        if (normalizeWhitespace) {
          prevTextOpt.each(function (elm) {
            return normalizeWhitespaceBefore(elm.dom(), elm.dom().length);
          });
          nextTextOpt.each(function (elm) {
            return normalizeWhitespaceAfter(elm.dom(), 0);
          });
        }
        return afterDeletePosOpt;
      });
    };
    var isInlineElement = function (editor, element) {
      return has(editor.schema.getTextInlineElements(), name(element));
    };
    var deleteElement = function (editor, forward, elm, moveCaret) {
      if (moveCaret === void 0) {
        moveCaret = true;
      }
      var afterDeletePos = findCaretPosOutsideElmAfterDelete(forward, editor.getBody(), elm.dom());
      var parentBlock = ancestor(elm, curry(isBlock$2, editor), eqRawNode(editor.getBody()));
      var normalizedAfterDeletePos = deleteNormalized(elm, afterDeletePos, isInlineElement(editor, elm));
      if (editor.dom.isEmpty(editor.getBody())) {
        editor.setContent('');
        editor.selection.setCursorLocation();
      } else {
        parentBlock.bind(paddEmptyBlock).fold(function () {
          if (moveCaret) {
            setSelection(editor, forward, normalizedAfterDeletePos);
          }
        }, function (paddPos) {
          if (moveCaret) {
            setSelection(editor, forward, Option.some(paddPos));
          }
        });
      }
    };
    var DeleteElement = { deleteElement: deleteElement };

    var ZWSP$1 = Zwsp.ZWSP, CARET_ID$1 = '_mce_caret';
    var importNode = function (ownerDocument, node) {
      return ownerDocument.importNode(node, true);
    };
    var getEmptyCaretContainers = function (node) {
      var nodes = [];
      while (node) {
        if (node.nodeType === 3 && node.nodeValue !== ZWSP$1 || node.childNodes.length > 1) {
          return [];
        }
        if (node.nodeType === 1) {
          nodes.push(node);
        }
        node = node.firstChild;
      }
      return nodes;
    };
    var isCaretContainerEmpty = function (node) {
      return getEmptyCaretContainers(node).length > 0;
    };
    var findFirstTextNode = function (node) {
      if (node) {
        var walker = new TreeWalker(node, node);
        for (node = walker.current(); node; node = walker.next()) {
          if (NodeType.isText(node)) {
            return node;
          }
        }
      }
      return null;
    };
    var createCaretContainer = function (fill) {
      var caretContainer = Element.fromTag('span');
      setAll(caretContainer, {
        'id': CARET_ID$1,
        'data-mce-bogus': '1',
        'data-mce-type': 'format-caret'
      });
      if (fill) {
        append(caretContainer, Element.fromText(ZWSP$1));
      }
      return caretContainer;
    };
    var trimZwspFromCaretContainer = function (caretContainerNode) {
      var textNode = findFirstTextNode(caretContainerNode);
      if (textNode && textNode.nodeValue.charAt(0) === ZWSP$1) {
        textNode.deleteData(0, 1);
      }
      return textNode;
    };
    var removeCaretContainerNode = function (editor, node, moveCaret) {
      if (moveCaret === void 0) {
        moveCaret = true;
      }
      var dom = editor.dom, selection = editor.selection;
      if (isCaretContainerEmpty(node)) {
        DeleteElement.deleteElement(editor, false, Element.fromDom(node), moveCaret);
      } else {
        var rng = selection.getRng();
        var block = dom.getParent(node, dom.isBlock);
        var textNode = trimZwspFromCaretContainer(node);
        if (rng.startContainer === textNode && rng.startOffset > 0) {
          rng.setStart(textNode, rng.startOffset - 1);
        }
        if (rng.endContainer === textNode && rng.endOffset > 0) {
          rng.setEnd(textNode, rng.endOffset - 1);
        }
        dom.remove(node, true);
        if (block && dom.isEmpty(block)) {
          PaddingBr.fillWithPaddingBr(Element.fromDom(block));
        }
        selection.setRng(rng);
      }
    };
    var removeCaretContainer = function (editor, node, moveCaret) {
      if (moveCaret === void 0) {
        moveCaret = true;
      }
      var dom = editor.dom, selection = editor.selection;
      if (!node) {
        node = getParentCaretContainer(editor.getBody(), selection.getStart());
        if (!node) {
          while (node = dom.get(CARET_ID$1)) {
            removeCaretContainerNode(editor, node, false);
          }
        }
      } else {
        removeCaretContainerNode(editor, node, moveCaret);
      }
    };
    var insertCaretContainerNode = function (editor, caretContainer, formatNode) {
      var dom = editor.dom, block = dom.getParent(formatNode, curry(isTextBlock$1, editor));
      if (block && dom.isEmpty(block)) {
        formatNode.parentNode.replaceChild(caretContainer, formatNode);
      } else {
        PaddingBr.removeTrailingBr(Element.fromDom(formatNode));
        if (dom.isEmpty(formatNode)) {
          formatNode.parentNode.replaceChild(caretContainer, formatNode);
        } else {
          dom.insertAfter(caretContainer, formatNode);
        }
      }
    };
    var appendNode = function (parentNode, node) {
      parentNode.appendChild(node);
      return node;
    };
    var insertFormatNodesIntoCaretContainer = function (formatNodes, caretContainer) {
      var innerMostFormatNode = foldr(formatNodes, function (parentNode, formatNode) {
        return appendNode(parentNode, formatNode.cloneNode(false));
      }, caretContainer);
      return appendNode(innerMostFormatNode, innerMostFormatNode.ownerDocument.createTextNode(ZWSP$1));
    };
    var applyCaretFormat = function (editor, name, vars) {
      var rng, caretContainer, textNode, offset, bookmark, container, text;
      var selection = editor.selection;
      rng = selection.getRng();
      offset = rng.startOffset;
      container = rng.startContainer;
      text = container.nodeValue;
      caretContainer = getParentCaretContainer(editor.getBody(), selection.getStart());
      if (caretContainer) {
        textNode = findFirstTextNode(caretContainer);
      }
      var wordcharRegex = /[^\s\u00a0\u00ad\u200b\ufeff]/;
      if (text && offset > 0 && offset < text.length && wordcharRegex.test(text.charAt(offset)) && wordcharRegex.test(text.charAt(offset - 1))) {
        bookmark = selection.getBookmark();
        rng.collapse(true);
        rng = expandRng(editor, rng, editor.formatter.get(name));
        rng = split$1(rng);
        editor.formatter.apply(name, vars, rng);
        selection.moveToBookmark(bookmark);
      } else {
        if (!caretContainer || textNode.nodeValue !== ZWSP$1) {
          caretContainer = importNode(editor.getDoc(), createCaretContainer(true).dom());
          textNode = caretContainer.firstChild;
          rng.insertNode(caretContainer);
          offset = 1;
          editor.formatter.apply(name, vars, caretContainer);
        } else {
          editor.formatter.apply(name, vars, caretContainer);
        }
        selection.setCursorLocation(textNode, offset);
      }
    };
    var removeCaretFormat = function (editor, name, vars, similar) {
      var dom = editor.dom, selection = editor.selection;
      var container, offset, bookmark;
      var hasContentAfter, node, formatNode;
      var parents = [], rng = selection.getRng();
      var caretContainer;
      container = rng.startContainer;
      offset = rng.startOffset;
      node = container;
      if (container.nodeType === 3) {
        if (offset !== container.nodeValue.length) {
          hasContentAfter = true;
        }
        node = node.parentNode;
      }
      while (node) {
        if (matchNode(editor, node, name, vars, similar)) {
          formatNode = node;
          break;
        }
        if (node.nextSibling) {
          hasContentAfter = true;
        }
        parents.push(node);
        node = node.parentNode;
      }
      if (!formatNode) {
        return;
      }
      if (hasContentAfter) {
        bookmark = selection.getBookmark();
        rng.collapse(true);
        var expandedRng = expandRng(editor, rng, editor.formatter.get(name), true);
        expandedRng = split$1(expandedRng);
        editor.formatter.remove(name, vars, expandedRng);
        selection.moveToBookmark(bookmark);
      } else {
        caretContainer = getParentCaretContainer(editor.getBody(), formatNode);
        var newCaretContainer = createCaretContainer(false).dom();
        var caretNode = insertFormatNodesIntoCaretContainer(parents, newCaretContainer);
        if (caretContainer) {
          insertCaretContainerNode(editor, newCaretContainer, caretContainer);
        } else {
          insertCaretContainerNode(editor, newCaretContainer, formatNode);
        }
        removeCaretContainerNode(editor, caretContainer, false);
        selection.setCursorLocation(caretNode, 1);
        if (dom.isEmpty(formatNode)) {
          dom.remove(formatNode);
        }
      }
    };
    var disableCaretContainer = function (editor, keyCode) {
      var selection = editor.selection, body = editor.getBody();
      removeCaretContainer(editor, null, false);
      if ((keyCode === 8 || keyCode === 46) && selection.isCollapsed() && selection.getStart().innerHTML === ZWSP$1) {
        removeCaretContainer(editor, getParentCaretContainer(body, selection.getStart()));
      }
      if (keyCode === 37 || keyCode === 39) {
        removeCaretContainer(editor, getParentCaretContainer(body, selection.getStart()));
      }
    };
    var setup$3 = function (editor) {
      editor.on('mouseup keydown', function (e) {
        disableCaretContainer(editor, e.keyCode);
      });
    };
    var replaceWithCaretFormat = function (targetNode, formatNodes) {
      var caretContainer = createCaretContainer(false);
      var innerMost = insertFormatNodesIntoCaretContainer(formatNodes, caretContainer.dom());
      before(Element.fromDom(targetNode), caretContainer);
      remove(Element.fromDom(targetNode));
      return CaretPosition$1(innerMost, 0);
    };
    var isFormatElement = function (editor, element) {
      var inlineElements = editor.schema.getTextInlineElements();
      return inlineElements.hasOwnProperty(name(element)) && !isCaretNode(element.dom()) && !NodeType.isBogus(element.dom());
    };
    var isEmptyCaretFormatElement = function (element) {
      return isCaretNode(element.dom()) && isCaretContainerEmpty(element.dom());
    };

    var postProcessHooks = {}, filter$3 = ArrUtils.filter, each$9 = ArrUtils.each;
    var addPostProcessHook = function (name, hook) {
      var hooks = postProcessHooks[name];
      if (!hooks) {
        postProcessHooks[name] = hooks = [];
      }
      postProcessHooks[name].push(hook);
    };
    var postProcess$1 = function (name, editor) {
      each$9(postProcessHooks[name], function (hook) {
        hook(editor);
      });
    };
    addPostProcessHook('pre', function (editor) {
      var rng = editor.selection.getRng();
      var isPre, blocks;
      var hasPreSibling = function (pre) {
        return isPre(pre.previousSibling) && ArrUtils.indexOf(blocks, pre.previousSibling) !== -1;
      };
      var joinPre = function (pre1, pre2) {
        DomQuery(pre2).remove();
        DomQuery(pre1).append('<br><br>').append(pre2.childNodes);
      };
      isPre = NodeType.matchNodeNames(['pre']);
      if (!rng.collapsed) {
        blocks = editor.selection.getSelectedBlocks();
        each$9(filter$3(filter$3(blocks, isPre), hasPreSibling), function (pre) {
          joinPre(pre.previousSibling, pre);
        });
      }
    });

    var each$a = Tools.each;
    var ElementUtils = function (dom) {
      this.compare = function (node1, node2) {
        if (node1.nodeName !== node2.nodeName) {
          return false;
        }
        var getAttribs = function (node) {
          var attribs = {};
          each$a(dom.getAttribs(node), function (attr) {
            var name = attr.nodeName.toLowerCase();
            if (name.indexOf('_') !== 0 && name !== 'style' && name.indexOf('data-') !== 0) {
              attribs[name] = dom.getAttrib(node, name);
            }
          });
          return attribs;
        };
        var compareObjects = function (obj1, obj2) {
          var value, name;
          for (name in obj1) {
            if (obj1.hasOwnProperty(name)) {
              value = obj2[name];
              if (typeof value === 'undefined') {
                return false;
              }
              if (obj1[name] !== value) {
                return false;
              }
              delete obj2[name];
            }
          }
          for (name in obj2) {
            if (obj2.hasOwnProperty(name)) {
              return false;
            }
          }
          return true;
        };
        if (!compareObjects(getAttribs(node1), getAttribs(node2))) {
          return false;
        }
        if (!compareObjects(dom.parseStyle(dom.getAttrib(node1, 'style')), dom.parseStyle(dom.getAttrib(node2, 'style')))) {
          return false;
        }
        return !Bookmarks.isBookmarkNode(node1) && !Bookmarks.isBookmarkNode(node2);
      };
    };

    var MCE_ATTR_RE = /^(src|href|style)$/;
    var each$b = Tools.each;
    var isEq$3 = isEq;
    var isTableCell$3 = function (node) {
      return /^(TH|TD)$/.test(node.nodeName);
    };
    var isChildOfInlineParent = function (dom, node, parent) {
      return dom.isChildOf(node, parent) && node !== parent && !dom.isBlock(parent);
    };
    var getContainer = function (ed, rng, start) {
      var container, offset;
      container = rng[start ? 'startContainer' : 'endContainer'];
      offset = rng[start ? 'startOffset' : 'endOffset'];
      if (NodeType.isElement(container)) {
        var lastIdx = container.childNodes.length - 1;
        if (!start && offset) {
          offset--;
        }
        container = container.childNodes[offset > lastIdx ? lastIdx : offset];
      }
      if (NodeType.isText(container) && start && offset >= container.nodeValue.length) {
        container = new TreeWalker(container, ed.getBody()).next() || container;
      }
      if (NodeType.isText(container) && !start && offset === 0) {
        container = new TreeWalker(container, ed.getBody()).prev() || container;
      }
      return container;
    };
    var wrap$3 = function (dom, node, name, attrs) {
      var wrapper = dom.create(name, attrs);
      node.parentNode.insertBefore(wrapper, node);
      wrapper.appendChild(node);
      return wrapper;
    };
    var wrapWithSiblings = function (dom, node, next, name, attrs) {
      var start = Element.fromDom(node);
      var wrapper = Element.fromDom(dom.create(name, attrs));
      var siblings = next ? nextSiblings(start) : prevSiblings(start);
      append$1(wrapper, siblings);
      if (next) {
        before(start, wrapper);
        prepend(wrapper, start);
      } else {
        after(start, wrapper);
        append(wrapper, start);
      }
      return wrapper.dom();
    };
    var matchName$1 = function (dom, node, format) {
      if (isEq$3(node, format.inline)) {
        return true;
      }
      if (isEq$3(node, format.block)) {
        return true;
      }
      if (format.selector) {
        return NodeType.isElement(node) && dom.is(node, format.selector);
      }
    };
    var isColorFormatAndAnchor = function (node, format) {
      return format.links && node.nodeName === 'A';
    };
    var find$4 = function (dom, node, next, inc) {
      node = getNonWhiteSpaceSibling(node, next, inc);
      return !node || (node.nodeName === 'BR' || dom.isBlock(node));
    };
    var removeNode$1 = function (ed, node, format) {
      var parentNode = node.parentNode;
      var rootBlockElm;
      var dom = ed.dom, forcedRootBlock = Settings.getForcedRootBlock(ed);
      if (format.block) {
        if (!forcedRootBlock) {
          if (dom.isBlock(node) && !dom.isBlock(parentNode)) {
            if (!find$4(dom, node, false) && !find$4(dom, node.firstChild, true, true)) {
              node.insertBefore(dom.create('br'), node.firstChild);
            }
            if (!find$4(dom, node, true) && !find$4(dom, node.lastChild, false, true)) {
              node.appendChild(dom.create('br'));
            }
          }
        } else {
          if (parentNode === dom.getRoot()) {
            if (!format.list_block || !isEq$3(node, format.list_block)) {
              each$b(Tools.grep(node.childNodes), function (node) {
                if (isValid(ed, forcedRootBlock, node.nodeName.toLowerCase())) {
                  if (!rootBlockElm) {
                    rootBlockElm = wrap$3(dom, node, forcedRootBlock);
                    dom.setAttribs(rootBlockElm, ed.settings.forced_root_block_attrs);
                  } else {
                    rootBlockElm.appendChild(node);
                  }
                } else {
                  rootBlockElm = 0;
                }
              });
            }
          }
        }
      }
      if (format.selector && format.inline && !isEq$3(format.inline, node)) {
        return;
      }
      dom.remove(node, true);
    };
    var removeFormat = function (ed, format, vars, node, compareNode) {
      var stylesModified;
      var dom = ed.dom;
      if (!matchName$1(dom, node, format) && !isColorFormatAndAnchor(node, format)) {
        return false;
      }
      var elm = node;
      if (format.remove !== 'all') {
        each$b(format.styles, function (value, name) {
          value = normalizeStyleValue(dom, replaceVars(value, vars), name);
          if (typeof name === 'number') {
            name = value;
            compareNode = null;
          }
          if (format.remove_similar || (!compareNode || isEq$3(getStyle(dom, compareNode, name), value))) {
            dom.setStyle(elm, name, '');
          }
          stylesModified = true;
        });
        if (stylesModified && dom.getAttrib(elm, 'style') === '') {
          elm.removeAttribute('style');
          elm.removeAttribute('data-mce-style');
        }
        each$b(format.attributes, function (value, name) {
          var valueOut;
          value = replaceVars(value, vars);
          if (typeof name === 'number') {
            name = value;
            compareNode = null;
          }
          if (format.remove_similar || (!compareNode || isEq$3(dom.getAttrib(compareNode, name), value))) {
            if (name === 'class') {
              value = dom.getAttrib(elm, name);
              if (value) {
                valueOut = '';
                each$b(value.split(/\s+/), function (cls) {
                  if (/mce\-\w+/.test(cls)) {
                    valueOut += (valueOut ? ' ' : '') + cls;
                  }
                });
                if (valueOut) {
                  dom.setAttrib(elm, name, valueOut);
                  return;
                }
              }
            }
            if (name === 'class') {
              elm.removeAttribute('className');
            }
            if (MCE_ATTR_RE.test(name)) {
              elm.removeAttribute('data-mce-' + name);
            }
            elm.removeAttribute(name);
          }
        });
        each$b(format.classes, function (value) {
          value = replaceVars(value, vars);
          if (!compareNode || dom.hasClass(compareNode, value)) {
            dom.removeClass(elm, value);
          }
        });
        var attrs = dom.getAttribs(elm);
        for (var i = 0; i < attrs.length; i++) {
          var attrName = attrs[i].nodeName;
          if (attrName.indexOf('_') !== 0 && attrName.indexOf('data-') !== 0) {
            return false;
          }
        }
      }
      if (format.remove !== 'none') {
        removeNode$1(ed, elm, format);
        return true;
      }
    };
    var findFormatRoot = function (editor, container, name, vars, similar) {
      var formatRoot;
      each$b(getParents$1(editor.dom, container.parentNode).reverse(), function (parent) {
        var format;
        if (!formatRoot && parent.id !== '_start' && parent.id !== '_end') {
          format = matchNode(editor, parent, name, vars, similar);
          if (format && format.split !== false) {
            formatRoot = parent;
          }
        }
      });
      return formatRoot;
    };
    var wrapAndSplit = function (editor, formatList, formatRoot, container, target, split, format, vars) {
      var parent, clone, lastClone, firstClone, i, formatRootParent;
      var dom = editor.dom;
      if (formatRoot) {
        formatRootParent = formatRoot.parentNode;
        for (parent = container.parentNode; parent && parent !== formatRootParent; parent = parent.parentNode) {
          clone = dom.clone(parent, false);
          for (i = 0; i < formatList.length; i++) {
            if (removeFormat(editor, formatList[i], vars, clone, clone)) {
              clone = 0;
              break;
            }
          }
          if (clone) {
            if (lastClone) {
              clone.appendChild(lastClone);
            }
            if (!firstClone) {
              firstClone = clone;
            }
            lastClone = clone;
          }
        }
        if (split && (!format.mixed || !dom.isBlock(formatRoot))) {
          container = dom.split(formatRoot, container);
        }
        if (lastClone) {
          target.parentNode.insertBefore(lastClone, target);
          firstClone.appendChild(target);
        }
      }
      return container;
    };
    var remove$7 = function (ed, name, vars, node, similar) {
      var formatList = ed.formatter.get(name), format = formatList[0];
      var bookmark, rng, contentEditable = true;
      var dom = ed.dom;
      var selection = ed.selection;
      var splitToFormatRoot = function (container) {
        var formatRoot = findFormatRoot(ed, container, name, vars, similar);
        return wrapAndSplit(ed, formatList, formatRoot, container, container, true, format, vars);
      };
      var isRemoveBookmarkNode = function (node) {
        return Bookmarks.isBookmarkNode(node) && NodeType.isElement(node) && (node.id === '_start' || node.id === '_end');
      };
      var process = function (node) {
        var children, i, l, lastContentEditable, hasContentEditableState;
        if (NodeType.isElement(node) && dom.getContentEditable(node)) {
          lastContentEditable = contentEditable;
          contentEditable = dom.getContentEditable(node) === 'true';
          hasContentEditableState = true;
        }
        children = Tools.grep(node.childNodes);
        if (contentEditable && !hasContentEditableState) {
          for (i = 0, l = formatList.length; i < l; i++) {
            if (removeFormat(ed, formatList[i], vars, node, node)) {
              break;
            }
          }
        }
        if (format.deep) {
          if (children.length) {
            for (i = 0, l = children.length; i < l; i++) {
              process(children[i]);
            }
            if (hasContentEditableState) {
              contentEditable = lastContentEditable;
            }
          }
        }
      };
      var unwrap = function (start) {
        var node = dom.get(start ? '_start' : '_end');
        var out = node[start ? 'firstChild' : 'lastChild'];
        if (isRemoveBookmarkNode(out)) {
          out = out[start ? 'firstChild' : 'lastChild'];
        }
        if (NodeType.isText(out) && out.data.length === 0) {
          out = start ? node.previousSibling || node.nextSibling : node.nextSibling || node.previousSibling;
        }
        dom.remove(node, true);
        return out;
      };
      var removeRngStyle = function (rng) {
        var startContainer, endContainer;
        var commonAncestorContainer = rng.commonAncestorContainer;
        var expandedRng = expandRng(ed, rng, formatList, true);
        if (format.split) {
          expandedRng = split$1(expandedRng);
          startContainer = getContainer(ed, expandedRng, true);
          endContainer = getContainer(ed, expandedRng);
          if (startContainer !== endContainer) {
            if (/^(TR|TH|TD)$/.test(startContainer.nodeName) && startContainer.firstChild) {
              if (startContainer.nodeName === 'TR') {
                startContainer = startContainer.firstChild.firstChild || startContainer;
              } else {
                startContainer = startContainer.firstChild || startContainer;
              }
            }
            if (commonAncestorContainer && /^T(HEAD|BODY|FOOT|R)$/.test(commonAncestorContainer.nodeName) && isTableCell$3(endContainer) && endContainer.firstChild) {
              endContainer = endContainer.firstChild || endContainer;
            }
            if (isChildOfInlineParent(dom, startContainer, endContainer)) {
              var marker = Option.from(startContainer.firstChild).getOr(startContainer);
              splitToFormatRoot(wrapWithSiblings(dom, marker, true, 'span', {
                'id': '_start',
                'data-mce-type': 'bookmark'
              }));
              unwrap(true);
              return;
            }
            if (isChildOfInlineParent(dom, endContainer, startContainer)) {
              var marker = Option.from(endContainer.lastChild).getOr(endContainer);
              splitToFormatRoot(wrapWithSiblings(dom, marker, false, 'span', {
                'id': '_end',
                'data-mce-type': 'bookmark'
              }));
              unwrap(false);
              return;
            }
            startContainer = wrap$3(dom, startContainer, 'span', {
              'id': '_start',
              'data-mce-type': 'bookmark'
            });
            endContainer = wrap$3(dom, endContainer, 'span', {
              'id': '_end',
              'data-mce-type': 'bookmark'
            });
            var newRng = dom.createRng();
            newRng.setStartAfter(startContainer);
            newRng.setEndBefore(endContainer);
            RangeWalk.walk(dom, newRng, function (nodes) {
              each(nodes, function (n) {
                if (!Bookmarks.isBookmarkNode(n) && !Bookmarks.isBookmarkNode(n.parentNode)) {
                  splitToFormatRoot(n);
                }
              });
            });
            splitToFormatRoot(startContainer);
            splitToFormatRoot(endContainer);
            startContainer = unwrap(true);
            endContainer = unwrap();
          } else {
            startContainer = endContainer = splitToFormatRoot(startContainer);
          }
          expandedRng.startContainer = startContainer.parentNode ? startContainer.parentNode : startContainer;
          expandedRng.startOffset = dom.nodeIndex(startContainer);
          expandedRng.endContainer = endContainer.parentNode ? endContainer.parentNode : endContainer;
          expandedRng.endOffset = dom.nodeIndex(endContainer) + 1;
        }
        RangeWalk.walk(dom, expandedRng, function (nodes) {
          each$b(nodes, function (node) {
            process(node);
            if (NodeType.isElement(node) && ed.dom.getStyle(node, 'text-decoration') === 'underline' && node.parentNode && getTextDecoration(dom, node.parentNode) === 'underline') {
              removeFormat(ed, {
                deep: false,
                exact: true,
                inline: 'span',
                styles: { textDecoration: 'underline' }
              }, null, node);
            }
          });
        });
      };
      if (node) {
        if (isNode(node)) {
          rng = dom.createRng();
          rng.setStartBefore(node);
          rng.setEndAfter(node);
          removeRngStyle(rng);
        } else {
          removeRngStyle(node);
        }
        return;
      }
      if (dom.getContentEditable(selection.getNode()) === 'false') {
        node = selection.getNode();
        for (var i = 0, l = formatList.length; i < l; i++) {
          if (formatList[i].ceFalseOverride) {
            if (removeFormat(ed, formatList[i], vars, node, node)) {
              break;
            }
          }
        }
        return;
      }
      if (!selection.isCollapsed() || !format.inline || dom.select('td[data-mce-selected],th[data-mce-selected]').length) {
        bookmark = GetBookmark.getPersistentBookmark(ed.selection, true);
        removeRngStyle(selection.getRng());
        selection.moveToBookmark(bookmark);
        if (format.inline && match(ed, name, vars, selection.getStart())) {
          moveStart(dom, selection, selection.getRng());
        }
        ed.nodeChanged();
      } else {
        removeCaretFormat(ed, name, vars, similar);
      }
    };

    var each$c = Tools.each;
    var isElementNode = function (node) {
      return NodeType.isElement(node) && !Bookmarks.isBookmarkNode(node) && !isCaretNode(node) && !NodeType.isBogus(node);
    };
    var findElementSibling = function (node, siblingName) {
      var sibling;
      for (sibling = node; sibling; sibling = sibling[siblingName]) {
        if (NodeType.isText(sibling) && sibling.nodeValue.length !== 0) {
          return node;
        }
        if (NodeType.isElement(sibling) && !Bookmarks.isBookmarkNode(sibling)) {
          return sibling;
        }
      }
      return node;
    };
    var mergeSiblingsNodes = function (dom, prev, next) {
      var sibling, tmpSibling;
      var elementUtils = new ElementUtils(dom);
      if (prev && next) {
        prev = findElementSibling(prev, 'previousSibling');
        next = findElementSibling(next, 'nextSibling');
        if (elementUtils.compare(prev, next)) {
          for (sibling = prev.nextSibling; sibling && sibling !== next;) {
            tmpSibling = sibling;
            sibling = sibling.nextSibling;
            prev.appendChild(tmpSibling);
          }
          dom.remove(next);
          Tools.each(Tools.grep(next.childNodes), function (node) {
            prev.appendChild(node);
          });
          return prev;
        }
      }
      return next;
    };
    var processChildElements = function (node, filter, process) {
      each$c(node.childNodes, function (node) {
        if (isElementNode(node)) {
          if (filter(node)) {
            process(node);
          }
          if (node.hasChildNodes()) {
            processChildElements(node, filter, process);
          }
        }
      });
    };
    var hasStyle = function (dom, name) {
      return curry(function (name, node) {
        return !!(node && getStyle(dom, node, name));
      }, name);
    };
    var applyStyle = function (dom, name, value) {
      return curry(function (name, value, node) {
        dom.setStyle(node, name, value);
        if (node.getAttribute('style') === '') {
          node.removeAttribute('style');
        }
        unwrapEmptySpan(dom, node);
      }, name, value);
    };
    var unwrapEmptySpan = function (dom, node) {
      if (node.nodeName === 'SPAN' && dom.getAttribs(node).length === 0) {
        dom.remove(node, true);
      }
    };
    var processUnderlineAndColor = function (dom, node) {
      var textDecoration;
      if (node.nodeType === 1 && node.parentNode && node.parentNode.nodeType === 1) {
        textDecoration = getTextDecoration(dom, node.parentNode);
        if (dom.getStyle(node, 'color') && textDecoration) {
          dom.setStyle(node, 'text-decoration', textDecoration);
        } else if (dom.getStyle(node, 'text-decoration') === textDecoration) {
          dom.setStyle(node, 'text-decoration', null);
        }
      }
    };
    var mergeUnderlineAndColor = function (dom, format, vars, node) {
      if (format.styles.color || format.styles.textDecoration) {
        Tools.walk(node, curry(processUnderlineAndColor, dom), 'childNodes');
        processUnderlineAndColor(dom, node);
      }
    };
    var mergeBackgroundColorAndFontSize = function (dom, format, vars, node) {
      if (format.styles && format.styles.backgroundColor) {
        processChildElements(node, hasStyle(dom, 'fontSize'), applyStyle(dom, 'backgroundColor', replaceVars(format.styles.backgroundColor, vars)));
      }
    };
    var mergeSubSup = function (dom, format, vars, node) {
      if (format.inline === 'sub' || format.inline === 'sup') {
        processChildElements(node, hasStyle(dom, 'fontSize'), applyStyle(dom, 'fontSize', ''));
        dom.remove(dom.select(format.inline === 'sup' ? 'sub' : 'sup', node), true);
      }
    };
    var mergeSiblings = function (dom, format, vars, node) {
      if (node && format.merge_siblings !== false) {
        node = mergeSiblingsNodes(dom, getNonWhiteSpaceSibling(node), node);
        node = mergeSiblingsNodes(dom, node, getNonWhiteSpaceSibling(node, true));
      }
    };
    var clearChildStyles = function (dom, format, node) {
      if (format.clear_child_styles) {
        var selector = format.links ? '*:not(a)' : '*';
        each$c(dom.select(selector, node), function (node) {
          if (isElementNode(node)) {
            each$c(format.styles, function (value, name) {
              dom.setStyle(node, name, '');
            });
          }
        });
      }
    };
    var mergeWithChildren = function (editor, formatList, vars, node) {
      each$c(formatList, function (format) {
        each$c(editor.dom.select(format.inline, node), function (child) {
          if (!isElementNode(child)) {
            return;
          }
          removeFormat(editor, format, vars, child, format.exact ? child : null);
        });
        clearChildStyles(editor.dom, format, node);
      });
    };
    var mergeWithParents = function (editor, format, name, vars, node) {
      if (matchNode(editor, node.parentNode, name, vars)) {
        if (removeFormat(editor, format, vars, node)) {
          return;
        }
      }
      if (format.merge_with_parents) {
        editor.dom.getParent(node.parentNode, function (parent) {
          if (matchNode(editor, parent, name, vars)) {
            removeFormat(editor, format, vars, node);
            return true;
          }
        });
      }
    };

    var createRange$1 = function (sc, so, ec, eo) {
      var rng = domGlobals.document.createRange();
      rng.setStart(sc, so);
      rng.setEnd(ec, eo);
      return rng;
    };
    var normalizeBlockSelectionRange = function (rng) {
      var startPos = CaretPosition$1.fromRangeStart(rng);
      var endPos = CaretPosition$1.fromRangeEnd(rng);
      var rootNode = rng.commonAncestorContainer;
      return CaretFinder.fromPosition(false, rootNode, endPos).map(function (newEndPos) {
        if (!isInSameBlock(startPos, endPos, rootNode) && isInSameBlock(startPos, newEndPos, rootNode)) {
          return createRange$1(startPos.container(), startPos.offset(), newEndPos.container(), newEndPos.offset());
        } else {
          return rng;
        }
      }).getOr(rng);
    };
    var normalize$2 = function (rng) {
      return rng.collapsed ? rng : normalizeBlockSelectionRange(rng);
    };
    var RangeNormalizer = { normalize: normalize$2 };

    var each$d = Tools.each;
    var isElementNode$1 = function (node) {
      return node && node.nodeType === 1 && !Bookmarks.isBookmarkNode(node) && !isCaretNode(node) && !NodeType.isBogus(node);
    };
    var applyFormat = function (ed, name, vars, node) {
      var formatList = ed.formatter.get(name);
      var format = formatList[0];
      var bookmark, rng;
      var isCollapsed = !node && ed.selection.isCollapsed();
      var dom = ed.dom, selection = ed.selection;
      var setElementFormat = function (elm, fmt) {
        fmt = fmt || format;
        if (elm) {
          if (fmt.onformat) {
            fmt.onformat(elm, fmt, vars, node);
          }
          each$d(fmt.styles, function (value, name) {
            dom.setStyle(elm, name, replaceVars(value, vars));
          });
          if (fmt.styles) {
            var styleVal = dom.getAttrib(elm, 'style');
            if (styleVal) {
              dom.setAttrib(elm, 'data-mce-style', styleVal);
            }
          }
          each$d(fmt.attributes, function (value, name) {
            dom.setAttrib(elm, name, replaceVars(value, vars));
          });
          each$d(fmt.classes, function (value) {
            value = replaceVars(value, vars);
            if (!dom.hasClass(elm, value)) {
              dom.addClass(elm, value);
            }
          });
        }
      };
      var applyNodeStyle = function (formatList, node) {
        var found = false;
        if (!format.selector) {
          return false;
        }
        each$d(formatList, function (format) {
          if ('collapsed' in format && format.collapsed !== isCollapsed) {
            return;
          }
          if (dom.is(node, format.selector) && !isCaretNode(node)) {
            setElementFormat(node, format);
            found = true;
            return false;
          }
        });
        return found;
      };
      var applyRngStyle = function (dom, rng, bookmark, nodeSpecific) {
        var newWrappers = [];
        var wrapName, wrapElm, contentEditable = true;
        wrapName = format.inline || format.block;
        wrapElm = dom.create(wrapName);
        setElementFormat(wrapElm);
        RangeWalk.walk(dom, rng, function (nodes) {
          var currentWrapElm;
          var process = function (node) {
            var hasContentEditableState = false;
            var lastContentEditable = contentEditable;
            var nodeName = node.nodeName.toLowerCase();
            var parentName = node.parentNode.nodeName.toLowerCase();
            if (NodeType.isElement(node) && dom.getContentEditable(node)) {
              lastContentEditable = contentEditable;
              contentEditable = dom.getContentEditable(node) === 'true';
              hasContentEditableState = true;
            }
            if (isEq(nodeName, 'br')) {
              currentWrapElm = 0;
              if (format.block) {
                dom.remove(node);
              }
              return;
            }
            if (format.wrapper && matchNode(ed, node, name, vars)) {
              currentWrapElm = 0;
              return;
            }
            if (contentEditable && !hasContentEditableState && format.block && !format.wrapper && isTextBlock$1(ed, nodeName) && isValid(ed, parentName, wrapName)) {
              node = dom.rename(node, wrapName);
              setElementFormat(node);
              newWrappers.push(node);
              currentWrapElm = 0;
              return;
            }
            if (format.selector) {
              var found = applyNodeStyle(formatList, node);
              if (!format.inline || found) {
                currentWrapElm = 0;
                return;
              }
            }
            if (contentEditable && !hasContentEditableState && isValid(ed, wrapName, nodeName) && isValid(ed, parentName, wrapName) && !(!nodeSpecific && node.nodeType === 3 && node.nodeValue.length === 1 && node.nodeValue.charCodeAt(0) === 65279) && !isCaretNode(node) && (!format.inline || !dom.isBlock(node))) {
              if (!currentWrapElm) {
                currentWrapElm = dom.clone(wrapElm, false);
                node.parentNode.insertBefore(currentWrapElm, node);
                newWrappers.push(currentWrapElm);
              }
              currentWrapElm.appendChild(node);
            } else {
              currentWrapElm = 0;
              each$d(Tools.grep(node.childNodes), process);
              if (hasContentEditableState) {
                contentEditable = lastContentEditable;
              }
              currentWrapElm = 0;
            }
          };
          each$d(nodes, process);
        });
        if (format.links === true) {
          each$d(newWrappers, function (node) {
            var process = function (node) {
              if (node.nodeName === 'A') {
                setElementFormat(node, format);
              }
              each$d(Tools.grep(node.childNodes), process);
            };
            process(node);
          });
        }
        each$d(newWrappers, function (node) {
          var childCount;
          var getChildCount = function (node) {
            var count = 0;
            each$d(node.childNodes, function (node) {
              if (!isEmptyTextNode(node) && !Bookmarks.isBookmarkNode(node)) {
                count++;
              }
            });
            return count;
          };
          var getChildElementNode = function (root) {
            var child = false;
            each$d(root.childNodes, function (node) {
              if (isElementNode$1(node)) {
                child = node;
                return false;
              }
            });
            return child;
          };
          var mergeStyles = function (node) {
            var child, clone;
            child = getChildElementNode(node);
            if (child && !Bookmarks.isBookmarkNode(child) && matchName(dom, child, format)) {
              clone = dom.clone(child, false);
              setElementFormat(clone);
              dom.replace(clone, node, true);
              dom.remove(child, true);
            }
            return clone || node;
          };
          childCount = getChildCount(node);
          if ((newWrappers.length > 1 || !dom.isBlock(node)) && childCount === 0) {
            dom.remove(node, true);
            return;
          }
          if (format.inline || format.wrapper) {
            if (!format.exact && childCount === 1) {
              node = mergeStyles(node);
            }
            mergeWithChildren(ed, formatList, vars, node);
            mergeWithParents(ed, format, name, vars, node);
            mergeBackgroundColorAndFontSize(dom, format, vars, node);
            mergeSubSup(dom, format, vars, node);
            mergeSiblings(dom, format, vars, node);
          }
        });
      };
      if (dom.getContentEditable(selection.getNode()) === 'false') {
        node = selection.getNode();
        for (var i = 0, l = formatList.length; i < l; i++) {
          if (formatList[i].ceFalseOverride && dom.is(node, formatList[i].selector)) {
            setElementFormat(node, formatList[i]);
            return;
          }
        }
        return;
      }
      if (format) {
        if (node) {
          if (isNode(node)) {
            if (!applyNodeStyle(formatList, node)) {
              rng = dom.createRng();
              rng.setStartBefore(node);
              rng.setEndAfter(node);
              applyRngStyle(dom, expandRng(ed, rng, formatList), null, true);
            }
          } else {
            applyRngStyle(dom, node, null, true);
          }
        } else {
          if (!isCollapsed || !format.inline || dom.select('td[data-mce-selected],th[data-mce-selected]').length) {
            var curSelNode = ed.selection.getNode();
            if (!ed.settings.forced_root_block && formatList[0].defaultBlock && !dom.getParent(curSelNode, dom.isBlock)) {
              applyFormat(ed, formatList[0].defaultBlock);
            }
            ed.selection.setRng(RangeNormalizer.normalize(ed.selection.getRng()));
            bookmark = GetBookmark.getPersistentBookmark(ed.selection, true);
            applyRngStyle(dom, expandRng(ed, selection.getRng(), formatList));
            if (format.styles) {
              mergeUnderlineAndColor(dom, format, vars, curSelNode);
            }
            selection.moveToBookmark(bookmark);
            moveStart(dom, selection, selection.getRng());
            ed.nodeChanged();
          } else {
            applyCaretFormat(ed, name, vars);
          }
        }
        postProcess$1(name, ed);
      }
    };

    var setup$4 = function (registeredFormatListeners, editor) {
      var currentFormats = Cell({});
      registeredFormatListeners.set({});
      editor.on('NodeChange', function (e) {
        updateAndFireChangeCallbacks(editor, e.element, currentFormats, registeredFormatListeners.get());
      });
    };
    var updateAndFireChangeCallbacks = function (editor, elm, currentFormats, formatChangeData) {
      var formatsList = keys(currentFormats.get());
      var newFormats = {};
      var matchedFormats = {};
      var parents = filter(getParents$1(editor.dom, elm), function (node) {
        return node.nodeType === 1 && !node.getAttribute('data-mce-bogus');
      });
      each$1(formatChangeData, function (data, format) {
        Tools.each(parents, function (node) {
          if (editor.formatter.matchNode(node, format, {}, data.similar)) {
            if (formatsList.indexOf(format) === -1) {
              each(data.callbacks, function (callback) {
                callback(true, {
                  node: node,
                  format: format,
                  parents: parents
                });
              });
              newFormats[format] = data.callbacks;
            }
            matchedFormats[format] = data.callbacks;
            return false;
          }
          if (matchesUnInheritedFormatSelector(editor, node, format)) {
            return false;
          }
        });
      });
      var remainingFormats = filterRemainingFormats(currentFormats.get(), matchedFormats, elm, parents);
      currentFormats.set(__assign(__assign({}, newFormats), remainingFormats));
    };
    var filterRemainingFormats = function (currentFormats, matchedFormats, elm, parents) {
      return bifilter(currentFormats, function (callbacks, format) {
        if (!has(matchedFormats, format)) {
          each(callbacks, function (callback) {
            callback(false, {
              node: elm,
              format: format,
              parents: parents
            });
          });
          return false;
        } else {
          return true;
        }
      }).t;
    };
    var addListeners = function (registeredFormatListeners, formats, callback, similar) {
      var formatChangeItems = registeredFormatListeners.get();
      each(formats.split(','), function (format) {
        if (!formatChangeItems[format]) {
          formatChangeItems[format] = {
            similar: similar,
            callbacks: []
          };
        }
        formatChangeItems[format].callbacks.push(callback);
      });
      registeredFormatListeners.set(formatChangeItems);
    };
    var removeListeners = function (registeredFormatListeners, formats, callback) {
      var formatChangeItems = registeredFormatListeners.get();
      each(formats.split(','), function (format) {
        formatChangeItems[format].callbacks = filter(formatChangeItems[format].callbacks, function (c) {
          return c !== callback;
        });
        if (formatChangeItems[format].callbacks.length === 0) {
          delete formatChangeItems[format];
        }
      });
      registeredFormatListeners.set(formatChangeItems);
    };
    var formatChanged = function (editor, registeredFormatListeners, formats, callback, similar) {
      if (registeredFormatListeners.get() === null) {
        setup$4(registeredFormatListeners, editor);
      }
      addListeners(registeredFormatListeners, formats, callback, similar);
      return {
        unbind: function () {
          return removeListeners(registeredFormatListeners, formats, callback);
        }
      };
    };

    var get$9 = function (dom) {
      var formats = {
        valigntop: [{
            selector: 'td,th',
            styles: { verticalAlign: 'top' }
          }],
        valignmiddle: [{
            selector: 'td,th',
            styles: { verticalAlign: 'middle' }
          }],
        valignbottom: [{
            selector: 'td,th',
            styles: { verticalAlign: 'bottom' }
          }],
        alignleft: [
          {
            selector: 'figure.image',
            collapsed: false,
            classes: 'align-left',
            ceFalseOverride: true,
            preview: 'font-family font-size'
          },
          {
            selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
            styles: { textAlign: 'left' },
            inherit: false,
            preview: false,
            defaultBlock: 'div'
          },
          {
            selector: 'img,table',
            collapsed: false,
            styles: { float: 'left' },
            preview: 'font-family font-size'
          }
        ],
        aligncenter: [
          {
            selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
            styles: { textAlign: 'center' },
            inherit: false,
            preview: 'font-family font-size',
            defaultBlock: 'div'
          },
          {
            selector: 'figure.image',
            collapsed: false,
            classes: 'align-center',
            ceFalseOverride: true,
            preview: 'font-family font-size'
          },
          {
            selector: 'img',
            collapsed: false,
            styles: {
              display: 'block',
              marginLeft: 'auto',
              marginRight: 'auto'
            },
            preview: false
          },
          {
            selector: 'table',
            collapsed: false,
            styles: {
              marginLeft: 'auto',
              marginRight: 'auto'
            },
            preview: 'font-family font-size'
          }
        ],
        alignright: [
          {
            selector: 'figure.image',
            collapsed: false,
            classes: 'align-right',
            ceFalseOverride: true,
            preview: 'font-family font-size'
          },
          {
            selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
            styles: { textAlign: 'right' },
            inherit: false,
            preview: 'font-family font-size',
            defaultBlock: 'div'
          },
          {
            selector: 'img,table',
            collapsed: false,
            styles: { float: 'right' },
            preview: 'font-family font-size'
          }
        ],
        alignjustify: [{
            selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
            styles: { textAlign: 'justify' },
            inherit: false,
            defaultBlock: 'div',
            preview: 'font-family font-size'
          }],
        bold: [
          {
            inline: 'strong',
            remove: 'all'
          },
          {
            inline: 'span',
            styles: { fontWeight: 'bold' }
          },
          {
            inline: 'b',
            remove: 'all'
          }
        ],
        italic: [
          {
            inline: 'em',
            remove: 'all'
          },
          {
            inline: 'span',
            styles: { fontStyle: 'italic' }
          },
          {
            inline: 'i',
            remove: 'all'
          }
        ],
        underline: [
          {
            inline: 'span',
            styles: { textDecoration: 'underline' },
            exact: true
          },
          {
            inline: 'u',
            remove: 'all'
          }
        ],
        strikethrough: [
          {
            inline: 'span',
            styles: { textDecoration: 'line-through' },
            exact: true
          },
          {
            inline: 'strike',
            remove: 'all'
          }
        ],
        forecolor: {
          inline: 'span',
          styles: { color: '%value' },
          links: true,
          remove_similar: true,
          clear_child_styles: true
        },
        hilitecolor: {
          inline: 'span',
          styles: { backgroundColor: '%value' },
          links: true,
          remove_similar: true,
          clear_child_styles: true
        },
        fontname: {
          inline: 'span',
          toggle: false,
          styles: { fontFamily: '%value' },
          clear_child_styles: true
        },
        fontsize: {
          inline: 'span',
          toggle: false,
          styles: { fontSize: '%value' },
          clear_child_styles: true
        },
        fontsize_class: {
          inline: 'span',
          attributes: { class: '%value' }
        },
        blockquote: {
          block: 'blockquote',
          wrapper: true,
          remove: 'all'
        },
        subscript: { inline: 'sub' },
        superscript: { inline: 'sup' },
        code: { inline: 'code' },
        link: {
          inline: 'a',
          selector: 'a',
          remove: 'all',
          split: true,
          deep: true,
          onmatch: function () {
            return true;
          },
          onformat: function (elm, fmt, vars) {
            Tools.each(vars, function (value, key) {
              dom.setAttrib(elm, key, value);
            });
          }
        },
        removeformat: [
          {
            selector: 'b,strong,em,i,font,u,strike,sub,sup,dfn,code,samp,kbd,var,cite,mark,q,del,ins',
            remove: 'all',
            split: true,
            expand: false,
            block_expand: true,
            deep: true
          },
          {
            selector: 'span',
            attributes: [
              'style',
              'class'
            ],
            remove: 'empty',
            split: true,
            expand: false,
            deep: true
          },
          {
            selector: '*',
            attributes: [
              'style',
              'class'
            ],
            split: false,
            expand: false,
            deep: true
          }
        ]
      };
      Tools.each('p h1 h2 h3 h4 h5 h6 div address pre div dt dd samp'.split(/\s/), function (name) {
        formats[name] = {
          block: name,
          remove: 'all'
        };
      });
      return formats;
    };
    var DefaultFormats = { get: get$9 };

    function FormatRegistry(editor) {
      var formats = {};
      var get = function (name) {
        return name ? formats[name] : formats;
      };
      var has$1 = function (name) {
        return has(formats, name);
      };
      var register = function (name, format) {
        if (name) {
          if (typeof name !== 'string') {
            Tools.each(name, function (format, name) {
              register(name, format);
            });
          } else {
            if (!isArray(format)) {
              format = [format];
            }
            Tools.each(format, function (format) {
              if (typeof format.deep === 'undefined') {
                format.deep = !format.selector;
              }
              if (typeof format.split === 'undefined') {
                format.split = !format.selector || format.inline;
              }
              if (typeof format.remove === 'undefined' && format.selector && !format.inline) {
                format.remove = 'none';
              }
              if (format.selector && format.inline) {
                format.mixed = true;
                format.block_expand = true;
              }
              if (typeof format.classes === 'string') {
                format.classes = format.classes.split(/\s+/);
              }
            });
            formats[name] = format;
          }
        }
      };
      var unregister = function (name) {
        if (name && formats[name]) {
          delete formats[name];
        }
        return formats;
      };
      register(DefaultFormats.get(editor.dom));
      register(editor.settings.formats);
      return {
        get: get,
        has: has$1,
        register: register,
        unregister: unregister
      };
    }

    var each$e = Tools.each;
    var dom = DOMUtils$1.DOM;
    var parsedSelectorToHtml = function (ancestry, editor) {
      var elm, item, fragment;
      var schema = editor && editor.schema || Schema({});
      var decorate = function (elm, item) {
        if (item.classes.length) {
          dom.addClass(elm, item.classes.join(' '));
        }
        dom.setAttribs(elm, item.attrs);
      };
      var createElement = function (sItem) {
        var elm;
        item = typeof sItem === 'string' ? {
          name: sItem,
          classes: [],
          attrs: {}
        } : sItem;
        elm = dom.create(item.name);
        decorate(elm, item);
        return elm;
      };
      var getRequiredParent = function (elm, candidate) {
        var name = typeof elm !== 'string' ? elm.nodeName.toLowerCase() : elm;
        var elmRule = schema.getElementRule(name);
        var parentsRequired = elmRule && elmRule.parentsRequired;
        if (parentsRequired && parentsRequired.length) {
          return candidate && Tools.inArray(parentsRequired, candidate) !== -1 ? candidate : parentsRequired[0];
        } else {
          return false;
        }
      };
      var wrapInHtml = function (elm, ancestry, siblings) {
        var parent, parentCandidate, parentRequired;
        var ancestor = ancestry.length > 0 && ancestry[0];
        var ancestorName = ancestor && ancestor.name;
        parentRequired = getRequiredParent(elm, ancestorName);
        if (parentRequired) {
          if (ancestorName === parentRequired) {
            parentCandidate = ancestry[0];
            ancestry = ancestry.slice(1);
          } else {
            parentCandidate = parentRequired;
          }
        } else if (ancestor) {
          parentCandidate = ancestry[0];
          ancestry = ancestry.slice(1);
        } else if (!siblings) {
          return elm;
        }
        if (parentCandidate) {
          parent = createElement(parentCandidate);
          parent.appendChild(elm);
        }
        if (siblings) {
          if (!parent) {
            parent = dom.create('div');
            parent.appendChild(elm);
          }
          Tools.each(siblings, function (sibling) {
            var siblingElm = createElement(sibling);
            parent.insertBefore(siblingElm, elm);
          });
        }
        return wrapInHtml(parent, ancestry, parentCandidate && parentCandidate.siblings);
      };
      if (ancestry && ancestry.length) {
        item = ancestry[0];
        elm = createElement(item);
        fragment = dom.create('div');
        fragment.appendChild(wrapInHtml(elm, ancestry.slice(1), item.siblings));
        return fragment;
      } else {
        return '';
      }
    };
    var parseSelectorItem = function (item) {
      var tagName;
      var obj = {
        classes: [],
        attrs: {}
      };
      item = obj.selector = Tools.trim(item);
      if (item !== '*') {
        tagName = item.replace(/(?:([#\.]|::?)([\w\-]+)|(\[)([^\]]+)\]?)/g, function ($0, $1, $2, $3, $4) {
          switch ($1) {
          case '#':
            obj.attrs.id = $2;
            break;
          case '.':
            obj.classes.push($2);
            break;
          case ':':
            if (Tools.inArray('checked disabled enabled read-only required'.split(' '), $2) !== -1) {
              obj.attrs[$2] = $2;
            }
            break;
          }
          if ($3 === '[') {
            var m = $4.match(/([\w\-]+)(?:\=\"([^\"]+))?/);
            if (m) {
              obj.attrs[m[1]] = m[2];
            }
          }
          return '';
        });
      }
      obj.name = tagName || 'div';
      return obj;
    };
    var parseSelector = function (selector) {
      if (!selector || typeof selector !== 'string') {
        return [];
      }
      selector = selector.split(/\s*,\s*/)[0];
      selector = selector.replace(/\s*(~\+|~|\+|>)\s*/g, '$1');
      return Tools.map(selector.split(/(?:>|\s+(?![^\[\]]+\]))/), function (item) {
        var siblings = Tools.map(item.split(/(?:~\+|~|\+)/), parseSelectorItem);
        var obj = siblings.pop();
        if (siblings.length) {
          obj.siblings = siblings;
        }
        return obj;
      }).reverse();
    };
    var getCssText = function (editor, format) {
      var name, previewFrag, previewElm, items;
      var previewCss = '', parentFontSize, previewStyles;
      previewStyles = editor.settings.preview_styles;
      if (previewStyles === false) {
        return '';
      }
      if (typeof previewStyles !== 'string') {
        previewStyles = 'font-family font-size font-weight font-style text-decoration ' + 'text-transform color background-color border border-radius outline text-shadow';
      }
      var removeVars = function (val) {
        return val.replace(/%(\w+)/g, '');
      };
      if (typeof format === 'string') {
        format = editor.formatter.get(format);
        if (!format) {
          return;
        }
        format = format[0];
      }
      if ('preview' in format) {
        previewStyles = format.preview;
        if (previewStyles === false) {
          return '';
        }
      }
      name = format.block || format.inline || 'span';
      items = parseSelector(format.selector);
      if (items.length) {
        if (!items[0].name) {
          items[0].name = name;
        }
        name = format.selector;
        previewFrag = parsedSelectorToHtml(items, editor);
      } else {
        previewFrag = parsedSelectorToHtml([name], editor);
      }
      previewElm = dom.select(name, previewFrag)[0] || previewFrag.firstChild;
      each$e(format.styles, function (value, name) {
        value = removeVars(value);
        if (value) {
          dom.setStyle(previewElm, name, value);
        }
      });
      each$e(format.attributes, function (value, name) {
        value = removeVars(value);
        if (value) {
          dom.setAttrib(previewElm, name, value);
        }
      });
      each$e(format.classes, function (value) {
        value = removeVars(value);
        if (!dom.hasClass(previewElm, value)) {
          dom.addClass(previewElm, value);
        }
      });
      editor.fire('PreviewFormats');
      dom.setStyles(previewFrag, {
        position: 'absolute',
        left: -65535
      });
      editor.getBody().appendChild(previewFrag);
      parentFontSize = dom.getStyle(editor.getBody(), 'fontSize', true);
      parentFontSize = /px$/.test(parentFontSize) ? parseInt(parentFontSize, 10) : 0;
      each$e(previewStyles.split(' '), function (name) {
        var value = dom.getStyle(previewElm, name, true);
        if (name === 'background-color' && /transparent|rgba\s*\([^)]+,\s*0\)/.test(value)) {
          value = dom.getStyle(editor.getBody(), name, true);
          if (dom.toHex(value).toLowerCase() === '#ffffff') {
            return;
          }
        }
        if (name === 'color') {
          if (dom.toHex(value).toLowerCase() === '#000000') {
            return;
          }
        }
        if (name === 'font-size') {
          if (/em|%$/.test(value)) {
            if (parentFontSize === 0) {
              return;
            }
            var numValue = parseFloat(value) / (/%$/.test(value) ? 100 : 1);
            value = numValue * parentFontSize + 'px';
          }
        }
        if (name === 'border' && value) {
          previewCss += 'padding:0 2px;';
        }
        previewCss += name + ':' + value + ';';
      });
      editor.fire('AfterPreviewFormats');
      dom.remove(previewFrag);
      return previewCss;
    };

    var toggle = function (editor, formats, name, vars, node) {
      var fmt = formats.get(name);
      if (match(editor, name, vars, node) && (!('toggle' in fmt[0]) || fmt[0].toggle)) {
        remove$7(editor, name, vars, node);
      } else {
        applyFormat(editor, name, vars, node);
      }
    };

    var setup$5 = function (editor) {
      editor.addShortcut('meta+b', '', 'Bold');
      editor.addShortcut('meta+i', '', 'Italic');
      editor.addShortcut('meta+u', '', 'Underline');
      for (var i = 1; i <= 6; i++) {
        editor.addShortcut('access+' + i, '', [
          'FormatBlock',
          false,
          'h' + i
        ]);
      }
      editor.addShortcut('access+7', '', [
        'FormatBlock',
        false,
        'p'
      ]);
      editor.addShortcut('access+8', '', [
        'FormatBlock',
        false,
        'div'
      ]);
      editor.addShortcut('access+9', '', [
        'FormatBlock',
        false,
        'address'
      ]);
    };
    var FormatShortcuts = { setup: setup$5 };

    var Formatter = function (editor) {
      var formats = FormatRegistry(editor);
      var formatChangeState = Cell(null);
      FormatShortcuts.setup(editor);
      setup$3(editor);
      return {
        get: formats.get,
        has: formats.has,
        register: formats.register,
        unregister: formats.unregister,
        apply: curry(applyFormat, editor),
        remove: curry(remove$7, editor),
        toggle: curry(toggle, editor, formats),
        match: curry(match, editor),
        matchAll: curry(matchAll, editor),
        matchNode: curry(matchNode, editor),
        canApply: curry(canApply, editor),
        formatChanged: curry(formatChanged, editor, formatChangeState),
        getCssText: curry(getCssText, editor)
      };
    };

    var KEEP = 0, INSERT = 1, DELETE = 2;
    var diff = function (left, right) {
      var size = left.length + right.length + 2;
      var vDown = new Array(size);
      var vUp = new Array(size);
      var snake = function (start, end, diag) {
        return {
          start: start,
          end: end,
          diag: diag
        };
      };
      var buildScript = function (start1, end1, start2, end2, script) {
        var middle = getMiddleSnake(start1, end1, start2, end2);
        if (middle === null || middle.start === end1 && middle.diag === end1 - end2 || middle.end === start1 && middle.diag === start1 - start2) {
          var i = start1;
          var j = start2;
          while (i < end1 || j < end2) {
            if (i < end1 && j < end2 && left[i] === right[j]) {
              script.push([
                KEEP,
                left[i]
              ]);
              ++i;
              ++j;
            } else {
              if (end1 - start1 > end2 - start2) {
                script.push([
                  DELETE,
                  left[i]
                ]);
                ++i;
              } else {
                script.push([
                  INSERT,
                  right[j]
                ]);
                ++j;
              }
            }
          }
        } else {
          buildScript(start1, middle.start, start2, middle.start - middle.diag, script);
          for (var i2 = middle.start; i2 < middle.end; ++i2) {
            script.push([
              KEEP,
              left[i2]
            ]);
          }
          buildScript(middle.end, end1, middle.end - middle.diag, end2, script);
        }
      };
      var buildSnake = function (start, diag, end1, end2) {
        var end = start;
        while (end - diag < end2 && end < end1 && left[end] === right[end - diag]) {
          ++end;
        }
        return snake(start, end, diag);
      };
      var getMiddleSnake = function (start1, end1, start2, end2) {
        var m = end1 - start1;
        var n = end2 - start2;
        if (m === 0 || n === 0) {
          return null;
        }
        var delta = m - n;
        var sum = n + m;
        var offset = (sum % 2 === 0 ? sum : sum + 1) / 2;
        vDown[1 + offset] = start1;
        vUp[1 + offset] = end1 + 1;
        var d, k, i, x, y;
        for (d = 0; d <= offset; ++d) {
          for (k = -d; k <= d; k += 2) {
            i = k + offset;
            if (k === -d || k !== d && vDown[i - 1] < vDown[i + 1]) {
              vDown[i] = vDown[i + 1];
            } else {
              vDown[i] = vDown[i - 1] + 1;
            }
            x = vDown[i];
            y = x - start1 + start2 - k;
            while (x < end1 && y < end2 && left[x] === right[y]) {
              vDown[i] = ++x;
              ++y;
            }
            if (delta % 2 !== 0 && delta - d <= k && k <= delta + d) {
              if (vUp[i - delta] <= vDown[i]) {
                return buildSnake(vUp[i - delta], k + start1 - start2, end1, end2);
              }
            }
          }
          for (k = delta - d; k <= delta + d; k += 2) {
            i = k + offset - delta;
            if (k === delta - d || k !== delta + d && vUp[i + 1] <= vUp[i - 1]) {
              vUp[i] = vUp[i + 1] - 1;
            } else {
              vUp[i] = vUp[i - 1];
            }
            x = vUp[i] - 1;
            y = x - start1 + start2 - k;
            while (x >= start1 && y >= start2 && left[x] === right[y]) {
              vUp[i] = x--;
              y--;
            }
            if (delta % 2 === 0 && -d <= k && k <= d) {
              if (vUp[i] <= vDown[i + delta]) {
                return buildSnake(vUp[i], k + start1 - start2, end1, end2);
              }
            }
          }
        }
      };
      var script = [];
      buildScript(0, left.length, 0, right.length, script);
      return script;
    };
    var Diff = {
      KEEP: KEEP,
      DELETE: DELETE,
      INSERT: INSERT,
      diff: diff
    };

    var getOuterHtml = function (elm) {
      if (NodeType.isElement(elm)) {
        return elm.outerHTML;
      } else if (NodeType.isText(elm)) {
        return Entities.encodeRaw(elm.data, false);
      } else if (NodeType.isComment(elm)) {
        return '<!--' + elm.data + '-->';
      }
      return '';
    };
    var createFragment$1 = function (html) {
      var frag, node, container;
      container = domGlobals.document.createElement('div');
      frag = domGlobals.document.createDocumentFragment();
      if (html) {
        container.innerHTML = html;
      }
      while (node = container.firstChild) {
        frag.appendChild(node);
      }
      return frag;
    };
    var insertAt = function (elm, html, index) {
      var fragment = createFragment$1(html);
      if (elm.hasChildNodes() && index < elm.childNodes.length) {
        var target = elm.childNodes[index];
        target.parentNode.insertBefore(fragment, target);
      } else {
        elm.appendChild(fragment);
      }
    };
    var removeAt = function (elm, index) {
      if (elm.hasChildNodes() && index < elm.childNodes.length) {
        var target = elm.childNodes[index];
        target.parentNode.removeChild(target);
      }
    };
    var applyDiff = function (diff, elm) {
      var index = 0;
      each(diff, function (action) {
        if (action[0] === Diff.KEEP) {
          index++;
        } else if (action[0] === Diff.INSERT) {
          insertAt(elm, action[1], index);
          index++;
        } else if (action[0] === Diff.DELETE) {
          removeAt(elm, index);
        }
      });
    };
    var read$2 = function (elm) {
      return filter(map(from$1(elm.childNodes), getOuterHtml), function (item) {
        return item.length > 0;
      });
    };
    var write = function (fragments, elm) {
      var currentFragments = map(from$1(elm.childNodes), getOuterHtml);
      applyDiff(Diff.diff(currentFragments, fragments), elm);
      return elm;
    };
    var Fragments = {
      read: read$2,
      write: write
    };

    var undoLevelDocument = Cell(Option.none());
    var lazyTempDocument = function () {
      return undoLevelDocument.get().getOrThunk(function () {
        var doc = domGlobals.document.implementation.createHTMLDocument('undo');
        undoLevelDocument.set(Option.some(doc));
        return doc;
      });
    };
    var hasIframes = function (html) {
      return html.indexOf('</iframe>') !== -1;
    };
    var createFragmentedLevel = function (fragments) {
      return {
        type: 'fragmented',
        fragments: fragments,
        content: '',
        bookmark: null,
        beforeBookmark: null
      };
    };
    var createCompleteLevel = function (content) {
      return {
        type: 'complete',
        fragments: null,
        content: content,
        bookmark: null,
        beforeBookmark: null
      };
    };
    var createFromEditor = function (editor) {
      var fragments, content, trimmedFragments;
      fragments = Fragments.read(editor.getBody());
      trimmedFragments = bind(fragments, function (html) {
        var trimmed = TrimHtml.trimInternal(editor.serializer, html);
        return trimmed.length > 0 ? [trimmed] : [];
      });
      content = trimmedFragments.join('');
      return hasIframes(content) ? createFragmentedLevel(trimmedFragments) : createCompleteLevel(content);
    };
    var applyToEditor = function (editor, level, before) {
      if (level.type === 'fragmented') {
        Fragments.write(level.fragments, editor.getBody());
      } else {
        editor.setContent(level.content, { format: 'raw' });
      }
      editor.selection.moveToBookmark(before ? level.beforeBookmark : level.bookmark);
    };
    var getLevelContent = function (level) {
      return level.type === 'fragmented' ? level.fragments.join('') : level.content;
    };
    var getCleanLevelContent = function (level) {
      var elm = Element.fromTag('body', lazyTempDocument());
      set$1(elm, getLevelContent(level));
      each(descendants$1(elm, '*[data-mce-bogus]'), unwrap);
      return get$6(elm);
    };
    var hasEqualContent = function (level1, level2) {
      return getLevelContent(level1) === getLevelContent(level2);
    };
    var hasEqualCleanedContent = function (level1, level2) {
      return getCleanLevelContent(level1) === getCleanLevelContent(level2);
    };
    var isEq$4 = function (level1, level2) {
      if (!level1 || !level2) {
        return false;
      } else if (hasEqualContent(level1, level2)) {
        return true;
      } else {
        return hasEqualCleanedContent(level1, level2);
      }
    };
    var Levels = {
      createFragmentedLevel: createFragmentedLevel,
      createCompleteLevel: createCompleteLevel,
      createFromEditor: createFromEditor,
      applyToEditor: applyToEditor,
      isEq: isEq$4
    };

    var isUnlocked = function (locks) {
      return locks.get() === 0;
    };

    var setTyping = function (undoManager, typing, locks) {
      if (isUnlocked(locks)) {
        undoManager.typing = typing;
      }
    };
    var endTyping = function (undoManager, locks) {
      if (undoManager.typing) {
        setTyping(undoManager, false, locks);
        undoManager.add();
      }
    };
    var endTypingLevelIgnoreLocks = function (undoManager) {
      if (undoManager.typing) {
        undoManager.typing = false;
        undoManager.add();
      }
    };

    var beforeChange = function (editor, locks, beforeBookmark) {
      if (isUnlocked(locks)) {
        beforeBookmark.set(Option.some(GetBookmark.getUndoBookmark(editor.selection)));
      }
    };
    var addUndoLevel = function (editor, undoManager, index, locks, beforeBookmark, level, event) {
      var settings = editor.settings;
      var currentLevel = Levels.createFromEditor(editor);
      level = level || {};
      level = Tools.extend(level, currentLevel);
      if (isUnlocked(locks) === false || editor.removed) {
        return null;
      }
      var lastLevel = undoManager.data[index.get()];
      if (editor.fire('BeforeAddUndo', {
          level: level,
          lastLevel: lastLevel,
          originalEvent: event
        }).isDefaultPrevented()) {
        return null;
      }
      if (lastLevel && Levels.isEq(lastLevel, level)) {
        return null;
      }
      if (undoManager.data[index.get()]) {
        beforeBookmark.get().each(function (bm) {
          undoManager.data[index.get()].beforeBookmark = bm;
        });
      }
      if (settings.custom_undo_redo_levels) {
        if (undoManager.data.length > settings.custom_undo_redo_levels) {
          for (var i = 0; i < undoManager.data.length - 1; i++) {
            undoManager.data[i] = undoManager.data[i + 1];
          }
          undoManager.data.length--;
          index.set(undoManager.data.length);
        }
      }
      level.bookmark = GetBookmark.getUndoBookmark(editor.selection);
      if (index.get() < undoManager.data.length - 1) {
        undoManager.data.length = index.get() + 1;
      }
      undoManager.data.push(level);
      index.set(undoManager.data.length - 1);
      var args = {
        level: level,
        lastLevel: lastLevel,
        originalEvent: event
      };
      editor.fire('AddUndo', args);
      if (index.get() > 0) {
        editor.setDirty(true);
        editor.fire('change', args);
      }
      return level;
    };
    var clear = function (editor, undoManager, index) {
      undoManager.data = [];
      index.set(0);
      undoManager.typing = false;
      editor.fire('ClearUndos');
    };
    var extra = function (editor, undoManager, index, callback1, callback2) {
      if (undoManager.transact(callback1)) {
        var bookmark = undoManager.data[index.get()].bookmark;
        var lastLevel = undoManager.data[index.get() - 1];
        Levels.applyToEditor(editor, lastLevel, true);
        if (undoManager.transact(callback2)) {
          undoManager.data[index.get() - 1].beforeBookmark = bookmark;
        }
      }
    };
    var redo = function (editor, index, data) {
      var level;
      if (index.get() < data.length - 1) {
        index.set(index.get() + 1);
        level = data[index.get()];
        Levels.applyToEditor(editor, level, false);
        editor.setDirty(true);
        editor.fire('Redo', { level: level });
      }
      return level;
    };
    var undo = function (editor, undoManager, locks, index) {
      var level;
      if (undoManager.typing) {
        undoManager.add();
        undoManager.typing = false;
        setTyping(undoManager, false, locks);
      }
      if (index.get() > 0) {
        index.set(index.get() - 1);
        level = undoManager.data[index.get()];
        Levels.applyToEditor(editor, level, true);
        editor.setDirty(true);
        editor.fire('Undo', { level: level });
      }
      return level;
    };
    var reset = function (undoManager) {
      undoManager.clear();
      undoManager.add();
    };
    var hasUndo = function (editor, undoManager, index) {
      return index.get() > 0 || undoManager.typing && undoManager.data[0] && !Levels.isEq(Levels.createFromEditor(editor), undoManager.data[0]);
    };
    var hasRedo = function (undoManager, index) {
      return index.get() < undoManager.data.length - 1 && !undoManager.typing;
    };
    var transact = function (undoManager, locks, callback) {
      endTyping(undoManager, locks);
      undoManager.beforeChange();
      undoManager.ignore(callback);
      return undoManager.add();
    };
    var ignore = function (locks, callback) {
      try {
        locks.set(locks.get() + 1);
        callback();
      } finally {
        locks.set(locks.get() - 1);
      }
    };

    var registerEvents$1 = function (editor, undoManager, locks) {
      var isFirstTypedCharacter = Cell(false);
      var addNonTypingUndoLevel = function (e) {
        setTyping(undoManager, false, locks);
        undoManager.add({}, e);
      };
      editor.on('init', function () {
        undoManager.add();
      });
      editor.on('BeforeExecCommand', function (e) {
        var cmd = e.command;
        if (cmd !== 'Undo' && cmd !== 'Redo' && cmd !== 'mceRepaint') {
          endTyping(undoManager, locks);
          undoManager.beforeChange();
        }
      });
      editor.on('ExecCommand', function (e) {
        var cmd = e.command;
        if (cmd !== 'Undo' && cmd !== 'Redo' && cmd !== 'mceRepaint') {
          addNonTypingUndoLevel(e);
        }
      });
      editor.on('ObjectResizeStart cut', function () {
        undoManager.beforeChange();
      });
      editor.on('SaveContent ObjectResized blur', addNonTypingUndoLevel);
      editor.on('dragend', addNonTypingUndoLevel);
      editor.on('keyup', function (e) {
        var keyCode = e.keyCode;
        if (e.isDefaultPrevented()) {
          return;
        }
        if (keyCode >= 33 && keyCode <= 36 || keyCode >= 37 && keyCode <= 40 || keyCode === 45 || e.ctrlKey) {
          addNonTypingUndoLevel();
          editor.nodeChanged();
        }
        if (keyCode === 46 || keyCode === 8) {
          editor.nodeChanged();
        }
        if (isFirstTypedCharacter.get() && undoManager.typing && Levels.isEq(Levels.createFromEditor(editor), undoManager.data[0]) === false) {
          if (editor.isDirty() === false) {
            editor.setDirty(true);
            editor.fire('change', {
              level: undoManager.data[0],
              lastLevel: null
            });
          }
          editor.fire('TypingUndo');
          isFirstTypedCharacter.set(false);
          editor.nodeChanged();
        }
      });
      editor.on('keydown', function (e) {
        var keyCode = e.keyCode;
        if (e.isDefaultPrevented()) {
          return;
        }
        if (keyCode >= 33 && keyCode <= 36 || keyCode >= 37 && keyCode <= 40 || keyCode === 45) {
          if (undoManager.typing) {
            addNonTypingUndoLevel(e);
          }
          return;
        }
        var modKey = e.ctrlKey && !e.altKey || e.metaKey;
        if ((keyCode < 16 || keyCode > 20) && keyCode !== 224 && keyCode !== 91 && !undoManager.typing && !modKey) {
          undoManager.beforeChange();
          setTyping(undoManager, true, locks);
          undoManager.add({}, e);
          isFirstTypedCharacter.set(true);
        }
      });
      editor.on('mousedown', function (e) {
        if (undoManager.typing) {
          addNonTypingUndoLevel(e);
        }
      });
      var isInsertReplacementText = function (event) {
        return event.inputType === 'insertReplacementText';
      };
      var isInsertTextDataNull = function (event) {
        return event.inputType === 'insertText' && event.data === null;
      };
      editor.on('input', function (e) {
        if (e.inputType && (isInsertReplacementText(e) || isInsertTextDataNull(e))) {
          addNonTypingUndoLevel(e);
        }
      });
      editor.on('AddUndo Undo Redo ClearUndos', function (e) {
        if (!e.isDefaultPrevented()) {
          editor.nodeChanged();
        }
      });
    };
    var addKeyboardShortcuts = function (editor) {
      editor.addShortcut('meta+z', '', 'Undo');
      editor.addShortcut('meta+y,meta+shift+z', '', 'Redo');
    };

    var UndoManager = function (editor) {
      var beforeBookmark = Cell(Option.none());
      var locks = Cell(0);
      var index = Cell(0);
      var undoManager = {
        data: [],
        typing: false,
        beforeChange: function () {
          beforeChange(editor, locks, beforeBookmark);
        },
        add: function (level, event) {
          return addUndoLevel(editor, undoManager, index, locks, beforeBookmark, level, event);
        },
        undo: function () {
          return undo(editor, undoManager, locks, index);
        },
        redo: function () {
          return redo(editor, index, undoManager.data);
        },
        clear: function () {
          clear(editor, undoManager, index);
        },
        reset: function () {
          reset(undoManager);
        },
        hasUndo: function () {
          return hasUndo(editor, undoManager, index);
        },
        hasRedo: function () {
          return hasRedo(undoManager, index);
        },
        transact: function (callback) {
          return transact(undoManager, locks, callback);
        },
        ignore: function (callback) {
          ignore(locks, callback);
        },
        extra: function (callback1, callback2) {
          extra(editor, undoManager, index, callback1, callback2);
        }
      };
      registerEvents$1(editor, undoManager, locks);
      addKeyboardShortcuts(editor);
      return undoManager;
    };

    var nonTypingKeycodes = [
      9,
      27,
      VK.HOME,
      VK.END,
      19,
      20,
      44,
      144,
      145,
      33,
      34,
      45,
      16,
      17,
      18,
      91,
      92,
      93,
      VK.DOWN,
      VK.UP,
      VK.LEFT,
      VK.RIGHT
    ].concat(Env.browser.isFirefox() ? [224] : []);
    var placeholderAttr = 'data-mce-placeholder';
    var isKeyboardEvent = function (e) {
      return e.type === 'keydown' || e.type === 'keyup';
    };
    var isDeleteEvent = function (e) {
      var keyCode = e.keyCode;
      return keyCode === VK.BACKSPACE || keyCode === VK.DELETE;
    };
    var isNonTypingKeyboardEvent = function (e) {
      if (isKeyboardEvent(e)) {
        var keyCode = e.keyCode;
        return !isDeleteEvent(e) && (VK.metaKeyPressed(e) || e.altKey || keyCode >= 112 && keyCode <= 123 || contains(nonTypingKeycodes, keyCode));
      } else {
        return false;
      }
    };
    var isTypingKeyboardEvent = function (e) {
      return isKeyboardEvent(e) && !(isDeleteEvent(e) || e.type === 'keyup' && e.keyCode === 229);
    };
    var isVisuallyEmpty = function (dom, rootElm, forcedRootBlock) {
      if (Empty.isEmpty(Element.fromDom(rootElm), false)) {
        var isForcedRootBlockFalse = forcedRootBlock === '';
        var firstElement = rootElm.firstElementChild;
        if (!firstElement) {
          return true;
        } else if (dom.getStyle(rootElm.firstElementChild, 'padding-left') || dom.getStyle(rootElm.firstElementChild, 'padding-right')) {
          return false;
        } else {
          return isForcedRootBlockFalse ? !dom.isBlock(firstElement) : forcedRootBlock === firstElement.nodeName.toLowerCase();
        }
      } else {
        return false;
      }
    };
    var setup$6 = function (editor) {
      var dom = editor.dom;
      var rootBlock = Settings.getForcedRootBlock(editor);
      var placeholder = Settings.getPlaceholder(editor);
      var updatePlaceholder = function (e, initial) {
        if (isNonTypingKeyboardEvent(e)) {
          return;
        }
        var body = editor.getBody();
        var showPlaceholder = isTypingKeyboardEvent(e) ? false : isVisuallyEmpty(dom, body, rootBlock);
        var isPlaceholderShown = dom.getAttrib(body, placeholderAttr) !== '';
        if (isPlaceholderShown !== showPlaceholder || initial) {
          dom.setAttrib(body, placeholderAttr, showPlaceholder ? placeholder : null);
          dom.setAttrib(body, 'aria-placeholder', showPlaceholder ? placeholder : null);
          firePlaceholderToggle(editor, showPlaceholder);
          editor.on(showPlaceholder ? 'keydown' : 'keyup', updatePlaceholder);
          editor.off(showPlaceholder ? 'keyup' : 'keydown', updatePlaceholder);
        }
      };
      if (placeholder) {
        editor.on('init', function (e) {
          updatePlaceholder(e, true);
          editor.on('change SetContent ExecCommand', updatePlaceholder);
          editor.on('remove', function () {
            var body = editor.getBody();
            dom.setAttrib(body, placeholderAttr, null);
            dom.setAttrib(body, 'aria-placeholder', null);
          });
        });
      }
    };

    var SIGNIFICANT_MOVE = 5;
    var LONGPRESS_DELAY = 400;
    var getTouch = function (event) {
      if (event.touches === undefined || event.touches.length !== 1) {
        return Option.none();
      }
      return Option.some(event.touches[0]);
    };
    var isFarEnough = function (touch, data) {
      var distX = Math.abs(touch.clientX - data.x());
      var distY = Math.abs(touch.clientY - data.y());
      return distX > SIGNIFICANT_MOVE || distY > SIGNIFICANT_MOVE;
    };
    var setup$7 = function (editor) {
      var startData = Cell(Option.none());
      var longpressFired = Cell(false);
      var debounceLongpress = last$2(function (e) {
        editor.fire('longpress', __assign(__assign({}, e), { type: 'longpress' }));
        longpressFired.set(true);
      }, LONGPRESS_DELAY);
      editor.on('touchstart', function (e) {
        getTouch(e).each(function (touch) {
          debounceLongpress.cancel();
          var data = {
            x: constant(touch.clientX),
            y: constant(touch.clientY),
            target: constant(e.target)
          };
          debounceLongpress.throttle(e);
          longpressFired.set(false);
          startData.set(Option.some(data));
        });
      }, true);
      editor.on('touchmove', function (e) {
        debounceLongpress.cancel();
        getTouch(e).each(function (touch) {
          startData.get().each(function (data) {
            if (isFarEnough(touch, data)) {
              startData.set(Option.none());
              longpressFired.set(false);
              editor.fire('longpresscancel');
            }
          });
        });
      }, true);
      editor.on('touchend touchcancel', function (e) {
        debounceLongpress.cancel();
        if (e.type === 'touchcancel') {
          return;
        }
        startData.get().filter(function (data) {
          return data.target().isEqualNode(e.target);
        }).each(function () {
          if (longpressFired.get()) {
            e.preventDefault();
          } else {
            editor.fire('tap', __assign(__assign({}, e), { type: 'tap' }));
          }
        });
      }, true);
    };
    var TouchEvents = { setup: setup$7 };

    var isBlockElement = function (blockElements, node) {
      return blockElements.hasOwnProperty(node.nodeName);
    };
    var isValidTarget = function (blockElements, node) {
      if (NodeType.isText(node)) {
        return true;
      } else if (NodeType.isElement(node)) {
        return !isBlockElement(blockElements, node) && !Bookmarks.isBookmarkNode(node);
      } else {
        return false;
      }
    };
    var hasBlockParent = function (blockElements, root, node) {
      return exists(Parents.parents(Element.fromDom(node), Element.fromDom(root)), function (elm) {
        return isBlockElement(blockElements, elm.dom());
      });
    };
    var shouldRemoveTextNode = function (blockElements, node) {
      if (NodeType.isText(node)) {
        if (node.nodeValue.length === 0) {
          return true;
        } else if (/^\s+$/.test(node.nodeValue) && (!node.nextSibling || isBlockElement(blockElements, node.nextSibling))) {
          return true;
        }
      }
      return false;
    };
    var addRootBlocks = function (editor) {
      var dom = editor.dom, selection = editor.selection;
      var schema = editor.schema, blockElements = schema.getBlockElements();
      var node = selection.getStart();
      var rootNode = editor.getBody();
      var rng;
      var startContainer, startOffset, endContainer, endOffset, rootBlockNode;
      var tempNode, wrapped, restoreSelection;
      var rootNodeName;
      var forcedRootBlock = Settings.getForcedRootBlock(editor);
      if (!node || !NodeType.isElement(node) || !forcedRootBlock) {
        return;
      }
      rootNodeName = rootNode.nodeName.toLowerCase();
      if (!schema.isValidChild(rootNodeName, forcedRootBlock.toLowerCase()) || hasBlockParent(blockElements, rootNode, node)) {
        return;
      }
      rng = selection.getRng();
      startContainer = rng.startContainer;
      startOffset = rng.startOffset;
      endContainer = rng.endContainer;
      endOffset = rng.endOffset;
      restoreSelection = EditorFocus.hasFocus(editor);
      node = rootNode.firstChild;
      while (node) {
        if (isValidTarget(blockElements, node)) {
          if (shouldRemoveTextNode(blockElements, node)) {
            tempNode = node;
            node = node.nextSibling;
            dom.remove(tempNode);
            continue;
          }
          if (!rootBlockNode) {
            rootBlockNode = dom.create(forcedRootBlock, Settings.getForcedRootBlockAttrs(editor));
            node.parentNode.insertBefore(rootBlockNode, node);
            wrapped = true;
          }
          tempNode = node;
          node = node.nextSibling;
          rootBlockNode.appendChild(tempNode);
        } else {
          rootBlockNode = null;
          node = node.nextSibling;
        }
      }
      if (wrapped && restoreSelection) {
        rng.setStart(startContainer, startOffset);
        rng.setEnd(endContainer, endOffset);
        selection.setRng(rng);
        editor.nodeChanged();
      }
    };
    var setup$8 = function (editor) {
      if (Settings.getForcedRootBlock(editor)) {
        editor.on('NodeChange', curry(addRootBlocks, editor));
      }
    };
    var ForceBlocks = { setup: setup$8 };

    var isText$8 = NodeType.isText;
    var startsWithCaretContainer$1 = function (node) {
      return isText$8(node) && node.data[0] === Zwsp.ZWSP;
    };
    var endsWithCaretContainer$1 = function (node) {
      return isText$8(node) && node.data[node.data.length - 1] === Zwsp.ZWSP;
    };
    var createZwsp = function (node) {
      return node.ownerDocument.createTextNode(Zwsp.ZWSP);
    };
    var insertBefore = function (node) {
      if (isText$8(node.previousSibling)) {
        if (endsWithCaretContainer$1(node.previousSibling)) {
          return node.previousSibling;
        } else {
          node.previousSibling.appendData(Zwsp.ZWSP);
          return node.previousSibling;
        }
      } else if (isText$8(node)) {
        if (startsWithCaretContainer$1(node)) {
          return node;
        } else {
          node.insertData(0, Zwsp.ZWSP);
          return node;
        }
      } else {
        var newNode = createZwsp(node);
        node.parentNode.insertBefore(newNode, node);
        return newNode;
      }
    };
    var insertAfter = function (node) {
      if (isText$8(node.nextSibling)) {
        if (startsWithCaretContainer$1(node.nextSibling)) {
          return node.nextSibling;
        } else {
          node.nextSibling.insertData(0, Zwsp.ZWSP);
          return node.nextSibling;
        }
      } else if (isText$8(node)) {
        if (endsWithCaretContainer$1(node)) {
          return node;
        } else {
          node.appendData(Zwsp.ZWSP);
          return node;
        }
      } else {
        var newNode = createZwsp(node);
        if (node.nextSibling) {
          node.parentNode.insertBefore(newNode, node.nextSibling);
        } else {
          node.parentNode.appendChild(newNode);
        }
        return newNode;
      }
    };
    var insertInline$1 = function (before, node) {
      return before ? insertBefore(node) : insertAfter(node);
    };
    var insertInlineBefore = curry(insertInline$1, true);
    var insertInlineAfter = curry(insertInline$1, false);

    var insertInlinePos = function (pos, before) {
      if (NodeType.isText(pos.container())) {
        return insertInline$1(before, pos.container());
      } else {
        return insertInline$1(before, pos.getNode());
      }
    };
    var isPosCaretContainer = function (pos, caret) {
      var caretNode = caret.get();
      return caretNode && pos.container() === caretNode && isCaretContainerInline(caretNode);
    };
    var renderCaret = function (caret, location) {
      return location.fold(function (element) {
        CaretContainerRemove.remove(caret.get());
        var text = insertInlineBefore(element);
        caret.set(text);
        return Option.some(CaretPosition$1(text, text.length - 1));
      }, function (element) {
        return CaretFinder.firstPositionIn(element).map(function (pos) {
          if (!isPosCaretContainer(pos, caret)) {
            CaretContainerRemove.remove(caret.get());
            var text = insertInlinePos(pos, true);
            caret.set(text);
            return CaretPosition$1(text, 1);
          } else {
            return CaretPosition$1(caret.get(), 1);
          }
        });
      }, function (element) {
        return CaretFinder.lastPositionIn(element).map(function (pos) {
          if (!isPosCaretContainer(pos, caret)) {
            CaretContainerRemove.remove(caret.get());
            var text = insertInlinePos(pos, false);
            caret.set(text);
            return CaretPosition$1(text, text.length - 1);
          } else {
            return CaretPosition$1(caret.get(), caret.get().length - 1);
          }
        });
      }, function (element) {
        CaretContainerRemove.remove(caret.get());
        var text = insertInlineAfter(element);
        caret.set(text);
        return Option.some(CaretPosition$1(text, 1));
      });
    };
    var BoundaryCaret = { renderCaret: renderCaret };

    var strongRtl = /[\u0591-\u07FF\uFB1D-\uFDFF\uFE70-\uFEFC]/;
    var hasStrongRtl = function (text) {
      return strongRtl.test(text);
    };

    var isInlineTarget = function (editor, elm) {
      return is(Element.fromDom(elm), Settings.getInlineBoundarySelector(editor));
    };
    var isRtl$1 = function (element) {
      return DOMUtils$1.DOM.getStyle(element, 'direction', true) === 'rtl' || hasStrongRtl(element.textContent);
    };
    var findInlineParents = function (isInlineTarget, rootNode, pos) {
      return filter(DOMUtils$1.DOM.getParents(pos.container(), '*', rootNode), isInlineTarget);
    };
    var findRootInline = function (isInlineTarget, rootNode, pos) {
      var parents = findInlineParents(isInlineTarget, rootNode, pos);
      return Option.from(parents[parents.length - 1]);
    };
    var hasSameParentBlock = function (rootNode, node1, node2) {
      var block1 = getParentBlock(node1, rootNode);
      var block2 = getParentBlock(node2, rootNode);
      return block1 && block1 === block2;
    };
    var isAtZwsp = function (pos) {
      return isBeforeInline(pos) || isAfterInline(pos);
    };
    var normalizePosition = function (forward, pos) {
      if (!pos) {
        return pos;
      }
      var container = pos.container(), offset = pos.offset();
      if (forward) {
        if (isCaretContainerInline(container)) {
          if (NodeType.isText(container.nextSibling)) {
            return CaretPosition$1(container.nextSibling, 0);
          } else {
            return CaretPosition$1.after(container);
          }
        } else {
          return isBeforeInline(pos) ? CaretPosition$1(container, offset + 1) : pos;
        }
      } else {
        if (isCaretContainerInline(container)) {
          if (NodeType.isText(container.previousSibling)) {
            return CaretPosition$1(container.previousSibling, container.previousSibling.data.length);
          } else {
            return CaretPosition$1.before(container);
          }
        } else {
          return isAfterInline(pos) ? CaretPosition$1(container, offset - 1) : pos;
        }
      }
    };
    var normalizeForwards = curry(normalizePosition, true);
    var normalizeBackwards = curry(normalizePosition, false);
    var InlineUtils = {
      isInlineTarget: isInlineTarget,
      findRootInline: findRootInline,
      isRtl: isRtl$1,
      isAtZwsp: isAtZwsp,
      normalizePosition: normalizePosition,
      normalizeForwards: normalizeForwards,
      normalizeBackwards: normalizeBackwards,
      hasSameParentBlock: hasSameParentBlock
    };

    var evaluateUntil = function (fns, args) {
      for (var i = 0; i < fns.length; i++) {
        var result = fns[i].apply(null, args);
        if (result.isSome()) {
          return result;
        }
      }
      return Option.none();
    };
    var LazyEvaluator = { evaluateUntil: evaluateUntil };

    var Location = Adt.generate([
      { before: ['element'] },
      { start: ['element'] },
      { end: ['element'] },
      { after: ['element'] }
    ]);
    var rescope = function (rootNode, node) {
      var parentBlock = getParentBlock(node, rootNode);
      return parentBlock ? parentBlock : rootNode;
    };
    var before$4 = function (isInlineTarget, rootNode, pos) {
      var nPos = InlineUtils.normalizeForwards(pos);
      var scope = rescope(rootNode, nPos.container());
      return InlineUtils.findRootInline(isInlineTarget, scope, nPos).fold(function () {
        return CaretFinder.nextPosition(scope, nPos).bind(curry(InlineUtils.findRootInline, isInlineTarget, scope)).map(function (inline) {
          return Location.before(inline);
        });
      }, Option.none);
    };
    var isNotInsideFormatCaretContainer = function (rootNode, elm) {
      return getParentCaretContainer(rootNode, elm) === null;
    };
    var findInsideRootInline = function (isInlineTarget, rootNode, pos) {
      return InlineUtils.findRootInline(isInlineTarget, rootNode, pos).filter(curry(isNotInsideFormatCaretContainer, rootNode));
    };
    var start = function (isInlineTarget, rootNode, pos) {
      var nPos = InlineUtils.normalizeBackwards(pos);
      return findInsideRootInline(isInlineTarget, rootNode, nPos).bind(function (inline) {
        var prevPos = CaretFinder.prevPosition(inline, nPos);
        return prevPos.isNone() ? Option.some(Location.start(inline)) : Option.none();
      });
    };
    var end = function (isInlineTarget, rootNode, pos) {
      var nPos = InlineUtils.normalizeForwards(pos);
      return findInsideRootInline(isInlineTarget, rootNode, nPos).bind(function (inline) {
        var nextPos = CaretFinder.nextPosition(inline, nPos);
        return nextPos.isNone() ? Option.some(Location.end(inline)) : Option.none();
      });
    };
    var after$3 = function (isInlineTarget, rootNode, pos) {
      var nPos = InlineUtils.normalizeBackwards(pos);
      var scope = rescope(rootNode, nPos.container());
      return InlineUtils.findRootInline(isInlineTarget, scope, nPos).fold(function () {
        return CaretFinder.prevPosition(scope, nPos).bind(curry(InlineUtils.findRootInline, isInlineTarget, scope)).map(function (inline) {
          return Location.after(inline);
        });
      }, Option.none);
    };
    var isValidLocation = function (location) {
      return InlineUtils.isRtl(getElement(location)) === false;
    };
    var readLocation = function (isInlineTarget, rootNode, pos) {
      var location = LazyEvaluator.evaluateUntil([
        before$4,
        start,
        end,
        after$3
      ], [
        isInlineTarget,
        rootNode,
        pos
      ]);
      return location.filter(isValidLocation);
    };
    var getElement = function (location) {
      return location.fold(identity, identity, identity, identity);
    };
    var getName = function (location) {
      return location.fold(constant('before'), constant('start'), constant('end'), constant('after'));
    };
    var outside = function (location) {
      return location.fold(Location.before, Location.before, Location.after, Location.after);
    };
    var inside = function (location) {
      return location.fold(Location.start, Location.start, Location.end, Location.end);
    };
    var isEq$5 = function (location1, location2) {
      return getName(location1) === getName(location2) && getElement(location1) === getElement(location2);
    };
    var betweenInlines = function (forward, isInlineTarget, rootNode, from, to, location) {
      return lift2(InlineUtils.findRootInline(isInlineTarget, rootNode, from), InlineUtils.findRootInline(isInlineTarget, rootNode, to), function (fromInline, toInline) {
        if (fromInline !== toInline && InlineUtils.hasSameParentBlock(rootNode, fromInline, toInline)) {
          return Location.after(forward ? fromInline : toInline);
        } else {
          return location;
        }
      }).getOr(location);
    };
    var skipNoMovement = function (fromLocation, toLocation) {
      return fromLocation.fold(constant(true), function (fromLocation) {
        return !isEq$5(fromLocation, toLocation);
      });
    };
    var findLocationTraverse = function (forward, isInlineTarget, rootNode, fromLocation, pos) {
      var from = InlineUtils.normalizePosition(forward, pos);
      var to = CaretFinder.fromPosition(forward, rootNode, from).map(curry(InlineUtils.normalizePosition, forward));
      var location = to.fold(function () {
        return fromLocation.map(outside);
      }, function (to) {
        return readLocation(isInlineTarget, rootNode, to).map(curry(betweenInlines, forward, isInlineTarget, rootNode, from, to)).filter(curry(skipNoMovement, fromLocation));
      });
      return location.filter(isValidLocation);
    };
    var findLocationSimple = function (forward, location) {
      if (forward) {
        return location.fold(compose(Option.some, Location.start), Option.none, compose(Option.some, Location.after), Option.none);
      } else {
        return location.fold(Option.none, compose(Option.some, Location.before), Option.none, compose(Option.some, Location.end));
      }
    };
    var findLocation = function (forward, isInlineTarget, rootNode, pos) {
      var from = InlineUtils.normalizePosition(forward, pos);
      var fromLocation = readLocation(isInlineTarget, rootNode, from);
      return readLocation(isInlineTarget, rootNode, from).bind(curry(findLocationSimple, forward)).orThunk(function () {
        return findLocationTraverse(forward, isInlineTarget, rootNode, fromLocation, pos);
      });
    };
    var BoundaryLocation = {
      readLocation: readLocation,
      findLocation: findLocation,
      prevLocation: curry(findLocation, false),
      nextLocation: curry(findLocation, true),
      getElement: getElement,
      outside: outside,
      inside: inside
    };

    var hasSelectionModifyApi = function (editor) {
      return isFunction(editor.selection.getSel().modify);
    };
    var moveRel = function (forward, selection, pos) {
      var delta = forward ? 1 : -1;
      selection.setRng(CaretPosition$1(pos.container(), pos.offset() + delta).toRange());
      selection.getSel().modify('move', forward ? 'forward' : 'backward', 'word');
      return true;
    };
    var moveByWord = function (forward, editor) {
      var rng = editor.selection.getRng();
      var pos = forward ? CaretPosition$1.fromRangeEnd(rng) : CaretPosition$1.fromRangeStart(rng);
      if (!hasSelectionModifyApi(editor)) {
        return false;
      } else if (forward && isBeforeInline(pos)) {
        return moveRel(true, editor.selection, pos);
      } else if (!forward && isAfterInline(pos)) {
        return moveRel(false, editor.selection, pos);
      } else {
        return false;
      }
    };
    var WordSelection = {
      hasSelectionModifyApi: hasSelectionModifyApi,
      moveByWord: moveByWord
    };

    var setCaretPosition = function (editor, pos) {
      var rng = editor.dom.createRng();
      rng.setStart(pos.container(), pos.offset());
      rng.setEnd(pos.container(), pos.offset());
      editor.selection.setRng(rng);
    };
    var isFeatureEnabled = function (editor) {
      return editor.settings.inline_boundaries !== false;
    };
    var setSelected = function (state, elm) {
      if (state) {
        elm.setAttribute('data-mce-selected', 'inline-boundary');
      } else {
        elm.removeAttribute('data-mce-selected');
      }
    };
    var renderCaretLocation = function (editor, caret, location) {
      return BoundaryCaret.renderCaret(caret, location).map(function (pos) {
        setCaretPosition(editor, pos);
        return location;
      });
    };
    var findLocation$1 = function (editor, caret, forward) {
      var rootNode = editor.getBody();
      var from = CaretPosition$1.fromRangeStart(editor.selection.getRng());
      var isInlineTarget = curry(InlineUtils.isInlineTarget, editor);
      var location = BoundaryLocation.findLocation(forward, isInlineTarget, rootNode, from);
      return location.bind(function (location) {
        return renderCaretLocation(editor, caret, location);
      });
    };
    var toggleInlines = function (isInlineTarget, dom, elms) {
      var selectedInlines = filter(dom.select('*[data-mce-selected="inline-boundary"]'), isInlineTarget);
      var targetInlines = filter(elms, isInlineTarget);
      each(difference(selectedInlines, targetInlines), curry(setSelected, false));
      each(difference(targetInlines, selectedInlines), curry(setSelected, true));
    };
    var safeRemoveCaretContainer = function (editor, caret) {
      if (editor.selection.isCollapsed() && editor.composing !== true && caret.get()) {
        var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
        if (CaretPosition$1.isTextPosition(pos) && InlineUtils.isAtZwsp(pos) === false) {
          setCaretPosition(editor, CaretContainerRemove.removeAndReposition(caret.get(), pos));
          caret.set(null);
        }
      }
    };
    var renderInsideInlineCaret = function (isInlineTarget, editor, caret, elms) {
      if (editor.selection.isCollapsed()) {
        var inlines = filter(elms, isInlineTarget);
        each(inlines, function (inline) {
          var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
          BoundaryLocation.readLocation(isInlineTarget, editor.getBody(), pos).bind(function (location) {
            return renderCaretLocation(editor, caret, location);
          });
        });
      }
    };
    var move = function (editor, caret, forward) {
      return function () {
        return isFeatureEnabled(editor) ? findLocation$1(editor, caret, forward).isSome() : false;
      };
    };
    var moveWord = function (forward, editor, caret) {
      return function () {
        return isFeatureEnabled(editor) ? WordSelection.moveByWord(forward, editor) : false;
      };
    };
    var setupSelectedState = function (editor) {
      var caret = Cell(null);
      var isInlineTarget = curry(InlineUtils.isInlineTarget, editor);
      editor.on('NodeChange', function (e) {
        if (isFeatureEnabled(editor)) {
          toggleInlines(isInlineTarget, editor.dom, e.parents);
          safeRemoveCaretContainer(editor, caret);
          renderInsideInlineCaret(isInlineTarget, editor, caret, e.parents);
        }
      });
      return caret;
    };
    var moveNextWord = curry(moveWord, true);
    var movePrevWord = curry(moveWord, false);
    var BoundarySelection = {
      move: move,
      moveNextWord: moveNextWord,
      movePrevWord: movePrevWord,
      setupSelectedState: setupSelectedState,
      setCaretPosition: setCaretPosition
    };

    var getNodeClientRects = function (node) {
      var toArrayWithNode = function (clientRects) {
        return map(clientRects, function (clientRect) {
          clientRect = clone$1(clientRect);
          clientRect.node = node;
          return clientRect;
        });
      };
      if (NodeType.isElement(node)) {
        return toArrayWithNode(node.getClientRects());
      }
      if (NodeType.isText(node)) {
        var rng = node.ownerDocument.createRange();
        rng.setStart(node, 0);
        rng.setEnd(node, node.data.length);
        return toArrayWithNode(rng.getClientRects());
      }
    };
    var getClientRects = function (node) {
      return foldl(node, function (result, node) {
        return result.concat(getNodeClientRects(node));
      }, []);
    };

    var VDirection;
    (function (VDirection) {
      VDirection[VDirection['Up'] = -1] = 'Up';
      VDirection[VDirection['Down'] = 1] = 'Down';
    }(VDirection || (VDirection = {})));
    var findUntil = function (direction, root, predicateFn, node) {
      while (node = findNode(node, direction, isEditableCaretCandidate, root)) {
        if (predicateFn(node)) {
          return;
        }
      }
    };
    var walkUntil = function (direction, isAboveFn, isBeflowFn, root, predicateFn, caretPosition) {
      var line = 0, node;
      var result = [];
      var targetClientRect;
      var add = function (node) {
        var i, clientRect, clientRects;
        clientRects = getClientRects([node]);
        if (direction === -1) {
          clientRects = clientRects.reverse();
        }
        for (i = 0; i < clientRects.length; i++) {
          clientRect = clientRects[i];
          if (isBeflowFn(clientRect, targetClientRect)) {
            continue;
          }
          if (result.length > 0 && isAboveFn(clientRect, ArrUtils.last(result))) {
            line++;
          }
          clientRect.line = line;
          if (predicateFn(clientRect)) {
            return true;
          }
          result.push(clientRect);
        }
      };
      targetClientRect = ArrUtils.last(caretPosition.getClientRects());
      if (!targetClientRect) {
        return result;
      }
      node = caretPosition.getNode();
      add(node);
      findUntil(direction, root, add, node);
      return result;
    };
    var aboveLineNumber = function (lineNumber, clientRect) {
      return clientRect.line > lineNumber;
    };
    var isLineNumber = function (lineNumber, clientRect) {
      return clientRect.line === lineNumber;
    };
    var upUntil = curry(walkUntil, VDirection.Up, isAbove, isBelow);
    var downUntil = curry(walkUntil, VDirection.Down, isBelow, isAbove);
    var positionsUntil = function (direction, root, predicateFn, node) {
      var caretWalker = CaretWalker(root);
      var walkFn, isBelowFn, isAboveFn, caretPosition;
      var result = [];
      var line = 0, clientRect, targetClientRect;
      var getClientRect = function (caretPosition) {
        if (direction === 1) {
          return ArrUtils.last(caretPosition.getClientRects());
        }
        return ArrUtils.last(caretPosition.getClientRects());
      };
      if (direction === 1) {
        walkFn = caretWalker.next;
        isBelowFn = isBelow;
        isAboveFn = isAbove;
        caretPosition = CaretPosition$1.after(node);
      } else {
        walkFn = caretWalker.prev;
        isBelowFn = isAbove;
        isAboveFn = isBelow;
        caretPosition = CaretPosition$1.before(node);
      }
      targetClientRect = getClientRect(caretPosition);
      do {
        if (!caretPosition.isVisible()) {
          continue;
        }
        clientRect = getClientRect(caretPosition);
        if (isAboveFn(clientRect, targetClientRect)) {
          continue;
        }
        if (result.length > 0 && isBelowFn(clientRect, ArrUtils.last(result))) {
          line++;
        }
        clientRect = clone$1(clientRect);
        clientRect.position = caretPosition;
        clientRect.line = line;
        if (predicateFn(clientRect)) {
          return result;
        }
        result.push(clientRect);
      } while (caretPosition = walkFn(caretPosition));
      return result;
    };
    var isAboveLine = function (lineNumber) {
      return function (clientRect) {
        return aboveLineNumber(lineNumber, clientRect);
      };
    };
    var isLine = function (lineNumber) {
      return function (clientRect) {
        return isLineNumber(lineNumber, clientRect);
      };
    };

    var isContentEditableFalse$7 = NodeType.isContentEditableFalse;
    var findNode$1 = findNode;
    var distanceToRectLeft = function (clientRect, clientX) {
      return Math.abs(clientRect.left - clientX);
    };
    var distanceToRectRight = function (clientRect, clientX) {
      return Math.abs(clientRect.right - clientX);
    };
    var isInside = function (clientX, clientRect) {
      return clientX >= clientRect.left && clientX <= clientRect.right;
    };
    var findClosestClientRect = function (clientRects, clientX) {
      return ArrUtils.reduce(clientRects, function (oldClientRect, clientRect) {
        var oldDistance, newDistance;
        oldDistance = Math.min(distanceToRectLeft(oldClientRect, clientX), distanceToRectRight(oldClientRect, clientX));
        newDistance = Math.min(distanceToRectLeft(clientRect, clientX), distanceToRectRight(clientRect, clientX));
        if (isInside(clientX, clientRect)) {
          return clientRect;
        }
        if (isInside(clientX, oldClientRect)) {
          return oldClientRect;
        }
        if (newDistance === oldDistance && isContentEditableFalse$7(clientRect.node)) {
          return clientRect;
        }
        if (newDistance < oldDistance) {
          return clientRect;
        }
        return oldClientRect;
      });
    };
    var walkUntil$1 = function (direction, root, predicateFn, node) {
      while (node = findNode$1(node, direction, isEditableCaretCandidate, root)) {
        if (predicateFn(node)) {
          return;
        }
      }
    };
    var findLineNodeRects = function (root, targetNodeRect) {
      var clientRects = [];
      var collect = function (checkPosFn, node) {
        var lineRects;
        lineRects = filter(getClientRects([node]), function (clientRect) {
          return !checkPosFn(clientRect, targetNodeRect);
        });
        clientRects = clientRects.concat(lineRects);
        return lineRects.length === 0;
      };
      clientRects.push(targetNodeRect);
      walkUntil$1(VDirection.Up, root, curry(collect, isAbove), targetNodeRect.node);
      walkUntil$1(VDirection.Down, root, curry(collect, isBelow), targetNodeRect.node);
      return clientRects;
    };
    var getFakeCaretTargets = function (root) {
      return filter(from$1(root.getElementsByTagName('*')), isFakeCaretTarget);
    };
    var caretInfo = function (clientRect, clientX) {
      return {
        node: clientRect.node,
        before: distanceToRectLeft(clientRect, clientX) < distanceToRectRight(clientRect, clientX)
      };
    };
    var closestCaret = function (root, clientX, clientY) {
      var closestNodeRect;
      var contentEditableFalseNodeRects = getClientRects(getFakeCaretTargets(root));
      var targetNodeRects = filter(contentEditableFalseNodeRects, function (rect) {
        return clientY >= rect.top && clientY <= rect.bottom;
      });
      closestNodeRect = findClosestClientRect(targetNodeRects, clientX);
      if (closestNodeRect) {
        closestNodeRect = findClosestClientRect(findLineNodeRects(root, closestNodeRect), clientX);
        if (closestNodeRect && isFakeCaretTarget(closestNodeRect.node)) {
          return caretInfo(closestNodeRect, clientX);
        }
      }
      return null;
    };

    var isContentEditableTrue$3 = NodeType.isContentEditableTrue;
    var isContentEditableFalse$8 = NodeType.isContentEditableFalse;
    var showCaret = function (direction, editor, node, before, scrollIntoView) {
      return editor._selectionOverrides.showCaret(direction, node, before, scrollIntoView);
    };
    var getNodeRange = function (node) {
      var rng = node.ownerDocument.createRange();
      rng.selectNode(node);
      return rng;
    };
    var selectNode = function (editor, node) {
      var e = editor.fire('BeforeObjectSelected', { target: node });
      if (e.isDefaultPrevented()) {
        return null;
      }
      return getNodeRange(node);
    };
    var renderCaretAtRange = function (editor, range, scrollIntoView) {
      var normalizedRange = normalizeRange(1, editor.getBody(), range);
      var caretPosition = CaretPosition$1.fromRangeStart(normalizedRange);
      var caretPositionNode = caretPosition.getNode();
      if (isContentEditableFalse$8(caretPositionNode)) {
        return showCaret(1, editor, caretPositionNode, !caretPosition.isAtEnd(), false);
      }
      var caretPositionBeforeNode = caretPosition.getNode(true);
      if (isContentEditableFalse$8(caretPositionBeforeNode)) {
        return showCaret(1, editor, caretPositionBeforeNode, false, false);
      }
      var ceRoot = editor.dom.getParent(caretPosition.getNode(), function (node) {
        return isContentEditableFalse$8(node) || isContentEditableTrue$3(node);
      });
      if (isContentEditableFalse$8(ceRoot)) {
        return showCaret(1, editor, ceRoot, false, scrollIntoView);
      }
      return null;
    };
    var renderRangeCaret = function (editor, range, scrollIntoView) {
      if (!range || !range.collapsed) {
        return range;
      }
      var caretRange = renderCaretAtRange(editor, range, scrollIntoView);
      if (caretRange) {
        return caretRange;
      }
      return range;
    };

    var isChar = function (forward, predicate, pos) {
      return Option.from(pos.container()).filter(NodeType.isText).exists(function (text) {
        var delta = forward ? 0 : -1;
        return predicate(text.data.charAt(pos.offset() + delta));
      });
    };
    var isBeforeSpace = curry(isChar, true, isWhiteSpace$1);
    var isAfterSpace = curry(isChar, false, isWhiteSpace$1);
    var isEmptyText = function (pos) {
      var container = pos.container();
      return NodeType.isText(container) && container.data.length === 0;
    };
    var matchesElementPosition = function (before, predicate) {
      return function (pos) {
        return Option.from(getChildNodeAtRelativeOffset(before ? 0 : -1, pos)).filter(predicate).isSome();
      };
    };
    var isImageBlock = function (node) {
      return node.nodeName === 'IMG' && get$4(Element.fromDom(node), 'display') === 'block';
    };
    var isCefNode = function (node) {
      return NodeType.isContentEditableFalse(node) && !NodeType.isBogusAll(node);
    };
    var isBeforeImageBlock = matchesElementPosition(true, isImageBlock);
    var isAfterImageBlock = matchesElementPosition(false, isImageBlock);
    var isBeforeTable = matchesElementPosition(true, NodeType.isTable);
    var isAfterTable = matchesElementPosition(false, NodeType.isTable);
    var isBeforeContentEditableFalse = matchesElementPosition(true, isCefNode);
    var isAfterContentEditableFalse = matchesElementPosition(false, isCefNode);

    var BreakType;
    (function (BreakType) {
      BreakType[BreakType['Br'] = 0] = 'Br';
      BreakType[BreakType['Block'] = 1] = 'Block';
      BreakType[BreakType['Wrap'] = 2] = 'Wrap';
      BreakType[BreakType['Eol'] = 3] = 'Eol';
    }(BreakType || (BreakType = {})));
    var flip = function (direction, positions) {
      return direction === HDirection.Backwards ? reverse(positions) : positions;
    };
    var walk$3 = function (direction, caretWalker, pos) {
      return direction === HDirection.Forwards ? caretWalker.next(pos) : caretWalker.prev(pos);
    };
    var getBreakType = function (scope, direction, currentPos, nextPos) {
      if (NodeType.isBr(nextPos.getNode(direction === HDirection.Forwards))) {
        return BreakType.Br;
      } else if (isInSameBlock(currentPos, nextPos) === false) {
        return BreakType.Block;
      } else {
        return BreakType.Wrap;
      }
    };
    var getPositionsUntil = function (predicate, direction, scope, start) {
      var caretWalker = CaretWalker(scope);
      var currentPos = start, nextPos;
      var positions = [];
      while (currentPos) {
        nextPos = walk$3(direction, caretWalker, currentPos);
        if (!nextPos) {
          break;
        }
        if (NodeType.isBr(nextPos.getNode(false))) {
          if (direction === HDirection.Forwards) {
            return {
              positions: flip(direction, positions).concat([nextPos]),
              breakType: BreakType.Br,
              breakAt: Option.some(nextPos)
            };
          } else {
            return {
              positions: flip(direction, positions),
              breakType: BreakType.Br,
              breakAt: Option.some(nextPos)
            };
          }
        }
        if (!nextPos.isVisible()) {
          currentPos = nextPos;
          continue;
        }
        if (predicate(currentPos, nextPos)) {
          var breakType = getBreakType(scope, direction, currentPos, nextPos);
          return {
            positions: flip(direction, positions),
            breakType: breakType,
            breakAt: Option.some(nextPos)
          };
        }
        positions.push(nextPos);
        currentPos = nextPos;
      }
      return {
        positions: flip(direction, positions),
        breakType: BreakType.Eol,
        breakAt: Option.none()
      };
    };
    var getAdjacentLinePositions = function (direction, getPositionsUntilBreak, scope, start) {
      return getPositionsUntilBreak(scope, start).breakAt.map(function (pos) {
        var positions = getPositionsUntilBreak(scope, pos).positions;
        return direction === HDirection.Backwards ? positions.concat(pos) : [pos].concat(positions);
      }).getOr([]);
    };
    var findClosestHorizontalPositionFromPoint = function (positions, x) {
      return foldl(positions, function (acc, newPos) {
        return acc.fold(function () {
          return Option.some(newPos);
        }, function (lastPos) {
          return lift2(head(lastPos.getClientRects()), head(newPos.getClientRects()), function (lastRect, newRect) {
            var lastDist = Math.abs(x - lastRect.left);
            var newDist = Math.abs(x - newRect.left);
            return newDist <= lastDist ? newPos : lastPos;
          }).or(acc);
        });
      }, Option.none());
    };
    var findClosestHorizontalPosition = function (positions, pos) {
      return head(pos.getClientRects()).bind(function (targetRect) {
        return findClosestHorizontalPositionFromPoint(positions, targetRect.left);
      });
    };
    var getPositionsUntilPreviousLine = curry(getPositionsUntil, CaretPosition.isAbove, -1);
    var getPositionsUntilNextLine = curry(getPositionsUntil, CaretPosition.isBelow, 1);
    var isAtFirstLine = function (scope, pos) {
      return getPositionsUntilPreviousLine(scope, pos).breakAt.isNone();
    };
    var isAtLastLine = function (scope, pos) {
      return getPositionsUntilNextLine(scope, pos).breakAt.isNone();
    };
    var getPositionsAbove = curry(getAdjacentLinePositions, -1, getPositionsUntilPreviousLine);
    var getPositionsBelow = curry(getAdjacentLinePositions, 1, getPositionsUntilNextLine);
    var getFirstLinePositions = function (scope) {
      return CaretFinder.firstPositionIn(scope).map(function (pos) {
        return [pos].concat(getPositionsUntilNextLine(scope, pos).positions);
      }).getOr([]);
    };
    var getLastLinePositions = function (scope) {
      return CaretFinder.lastPositionIn(scope).map(function (pos) {
        return getPositionsUntilPreviousLine(scope, pos).positions.concat(pos);
      }).getOr([]);
    };

    var isContentEditableFalse$9 = NodeType.isContentEditableFalse;
    var getSelectedNode$1 = getSelectedNode;
    var moveToCeFalseHorizontally = function (direction, editor, getNextPosFn, range) {
      var forwards = direction === HDirection.Forwards;
      var isBeforeContentEditableFalseFn = forwards ? isBeforeContentEditableFalse : isAfterContentEditableFalse;
      if (!range.collapsed) {
        var node = getSelectedNode$1(range);
        if (isContentEditableFalse$9(node)) {
          return showCaret(direction, editor, node, direction === HDirection.Backwards, true);
        }
      }
      var rangeIsInContainerBlock = isRangeInCaretContainerBlock(range);
      var caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range);
      if (isBeforeContentEditableFalseFn(caretPosition)) {
        return selectNode(editor, caretPosition.getNode(!forwards));
      }
      var nextCaretPosition = InlineUtils.normalizePosition(forwards, getNextPosFn(caretPosition));
      if (!nextCaretPosition) {
        if (rangeIsInContainerBlock) {
          return range;
        }
        return null;
      }
      if (isBeforeContentEditableFalseFn(nextCaretPosition)) {
        return showCaret(direction, editor, nextCaretPosition.getNode(!forwards), forwards, true);
      }
      var peekCaretPosition = getNextPosFn(nextCaretPosition);
      if (peekCaretPosition && isBeforeContentEditableFalseFn(peekCaretPosition)) {
        if (isMoveInsideSameBlock(nextCaretPosition, peekCaretPosition)) {
          return showCaret(direction, editor, peekCaretPosition.getNode(!forwards), forwards, true);
        }
      }
      if (rangeIsInContainerBlock) {
        return renderRangeCaret(editor, nextCaretPosition.toRange(), true);
      }
      return null;
    };
    var moveToCeFalseVertically = function (direction, editor, walkerFn, range) {
      var caretPosition, linePositions, nextLinePositions;
      var closestNextLineRect, caretClientRect, clientX;
      var dist1, dist2, contentEditableFalseNode;
      contentEditableFalseNode = getSelectedNode$1(range);
      caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range);
      linePositions = walkerFn(editor.getBody(), isAboveLine(1), caretPosition);
      nextLinePositions = filter(linePositions, isLine(1));
      caretClientRect = ArrUtils.last(caretPosition.getClientRects());
      if (isBeforeContentEditableFalse(caretPosition) || isBeforeTable(caretPosition)) {
        contentEditableFalseNode = caretPosition.getNode();
      }
      if (isAfterContentEditableFalse(caretPosition) || isAfterTable(caretPosition)) {
        contentEditableFalseNode = caretPosition.getNode(true);
      }
      if (!caretClientRect) {
        return null;
      }
      clientX = caretClientRect.left;
      closestNextLineRect = findClosestClientRect(nextLinePositions, clientX);
      if (closestNextLineRect) {
        if (isContentEditableFalse$9(closestNextLineRect.node)) {
          dist1 = Math.abs(clientX - closestNextLineRect.left);
          dist2 = Math.abs(clientX - closestNextLineRect.right);
          return showCaret(direction, editor, closestNextLineRect.node, dist1 < dist2, true);
        }
      }
      if (contentEditableFalseNode) {
        var caretPositions = positionsUntil(direction, editor.getBody(), isAboveLine(1), contentEditableFalseNode);
        closestNextLineRect = findClosestClientRect(filter(caretPositions, isLine(1)), clientX);
        if (closestNextLineRect) {
          return renderRangeCaret(editor, closestNextLineRect.position.toRange(), true);
        }
        closestNextLineRect = ArrUtils.last(filter(caretPositions, isLine(0)));
        if (closestNextLineRect) {
          return renderRangeCaret(editor, closestNextLineRect.position.toRange(), true);
        }
      }
    };
    var createTextBlock = function (editor) {
      var textBlock = editor.dom.create(Settings.getForcedRootBlock(editor));
      if (!Env.ie || Env.ie >= 11) {
        textBlock.innerHTML = '<br data-mce-bogus="1">';
      }
      return textBlock;
    };
    var exitPreBlock = function (editor, direction, range) {
      var pre, caretPos, newBlock;
      var caretWalker = CaretWalker(editor.getBody());
      var getNextVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.next);
      var getPrevVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.prev);
      if (range.collapsed && editor.settings.forced_root_block) {
        pre = editor.dom.getParent(range.startContainer, 'PRE');
        if (!pre) {
          return;
        }
        if (direction === 1) {
          caretPos = getNextVisualCaretPosition(CaretPosition$1.fromRangeStart(range));
        } else {
          caretPos = getPrevVisualCaretPosition(CaretPosition$1.fromRangeStart(range));
        }
        if (!caretPos) {
          newBlock = createTextBlock(editor);
          if (direction === 1) {
            editor.$(pre).after(newBlock);
          } else {
            editor.$(pre).before(newBlock);
          }
          editor.selection.select(newBlock, true);
          editor.selection.collapse();
        }
      }
    };
    var getHorizontalRange = function (editor, forward) {
      var caretWalker = CaretWalker(editor.getBody());
      var getNextVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.next);
      var getPrevVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.prev);
      var newRange;
      var direction = forward ? HDirection.Forwards : HDirection.Backwards;
      var getNextPosFn = forward ? getNextVisualCaretPosition : getPrevVisualCaretPosition;
      var range = editor.selection.getRng();
      newRange = moveToCeFalseHorizontally(direction, editor, getNextPosFn, range);
      if (newRange) {
        return newRange;
      }
      newRange = exitPreBlock(editor, direction, range);
      if (newRange) {
        return newRange;
      }
      return null;
    };
    var getVerticalRange = function (editor, down) {
      var newRange;
      var direction = down ? 1 : -1;
      var walkerFn = down ? downUntil : upUntil;
      var range = editor.selection.getRng();
      newRange = moveToCeFalseVertically(direction, editor, walkerFn, range);
      if (newRange) {
        return newRange;
      }
      newRange = exitPreBlock(editor, direction, range);
      if (newRange) {
        return newRange;
      }
      return null;
    };
    var moveH = function (editor, forward) {
      return function () {
        var newRng = getHorizontalRange(editor, forward);
        if (newRng) {
          editor.selection.setRng(newRng);
          return true;
        } else {
          return false;
        }
      };
    };
    var moveV = function (editor, down) {
      return function () {
        var newRng = getVerticalRange(editor, down);
        if (newRng) {
          editor.selection.setRng(newRng);
          return true;
        } else {
          return false;
        }
      };
    };
    var isCefPosition = function (forward) {
      return function (pos) {
        return forward ? isAfterContentEditableFalse(pos) : isBeforeContentEditableFalse(pos);
      };
    };
    var moveToLineEndPoint = function (editor, forward) {
      return function () {
        var from = forward ? CaretPosition$1.fromRangeEnd(editor.selection.getRng()) : CaretPosition$1.fromRangeStart(editor.selection.getRng());
        var result = forward ? getPositionsUntilNextLine(editor.getBody(), from) : getPositionsUntilPreviousLine(editor.getBody(), from);
        var to = forward ? last(result.positions) : head(result.positions);
        return to.filter(isCefPosition(forward)).fold(constant(false), function (pos) {
          editor.selection.setRng(pos.toRange());
          return true;
        });
      };
    };

    var deflate = function (rect, delta) {
      return {
        left: rect.left - delta,
        top: rect.top - delta,
        right: rect.right + delta * 2,
        bottom: rect.bottom + delta * 2,
        width: rect.width + delta,
        height: rect.height + delta
      };
    };
    var getCorners = function (getYAxisValue, tds) {
      return bind(tds, function (td) {
        var rect = deflate(clone$1(td.getBoundingClientRect()), -1);
        return [
          {
            x: rect.left,
            y: getYAxisValue(rect),
            cell: td
          },
          {
            x: rect.right,
            y: getYAxisValue(rect),
            cell: td
          }
        ];
      });
    };
    var findClosestCorner = function (corners, x, y) {
      return foldl(corners, function (acc, newCorner) {
        return acc.fold(function () {
          return Option.some(newCorner);
        }, function (oldCorner) {
          var oldDist = Math.sqrt(Math.abs(oldCorner.x - x) + Math.abs(oldCorner.y - y));
          var newDist = Math.sqrt(Math.abs(newCorner.x - x) + Math.abs(newCorner.y - y));
          return Option.some(newDist < oldDist ? newCorner : oldCorner);
        });
      }, Option.none());
    };
    var getClosestCell = function (getYAxisValue, isTargetCorner, table, x, y) {
      var cells = descendants$1(Element.fromDom(table), 'td,th,caption').map(function (e) {
        return e.dom();
      });
      var corners = filter(getCorners(getYAxisValue, cells), function (corner) {
        return isTargetCorner(corner, y);
      });
      return findClosestCorner(corners, x, y).map(function (corner) {
        return corner.cell;
      });
    };
    var getBottomValue = function (rect) {
      return rect.bottom;
    };
    var getTopValue = function (rect) {
      return rect.top;
    };
    var isAbove$1 = function (corner, y) {
      return corner.y < y;
    };
    var isBelow$1 = function (corner, y) {
      return corner.y > y;
    };
    var getClosestCellAbove = curry(getClosestCell, getBottomValue, isAbove$1);
    var getClosestCellBelow = curry(getClosestCell, getTopValue, isBelow$1);
    var findClosestPositionInAboveCell = function (table, pos) {
      return head(pos.getClientRects()).bind(function (rect) {
        return getClosestCellAbove(table, rect.left, rect.top);
      }).bind(function (cell) {
        return findClosestHorizontalPosition(getLastLinePositions(cell), pos);
      });
    };
    var findClosestPositionInBelowCell = function (table, pos) {
      return last(pos.getClientRects()).bind(function (rect) {
        return getClosestCellBelow(table, rect.left, rect.top);
      }).bind(function (cell) {
        return findClosestHorizontalPosition(getFirstLinePositions(cell), pos);
      });
    };

    var moveToRange = function (editor, rng) {
      editor.selection.setRng(rng);
      ScrollIntoView.scrollRangeIntoView(editor, rng);
    };
    var hasNextBreak = function (getPositionsUntil, scope, lineInfo) {
      return lineInfo.breakAt.map(function (breakPos) {
        return getPositionsUntil(scope, breakPos).breakAt.isSome();
      }).getOr(false);
    };
    var startsWithWrapBreak = function (lineInfo) {
      return lineInfo.breakType === BreakType.Wrap && lineInfo.positions.length === 0;
    };
    var startsWithBrBreak = function (lineInfo) {
      return lineInfo.breakType === BreakType.Br && lineInfo.positions.length === 1;
    };
    var isAtTableCellLine = function (getPositionsUntil, scope, pos) {
      var lineInfo = getPositionsUntil(scope, pos);
      if (startsWithWrapBreak(lineInfo) || !NodeType.isBr(pos.getNode()) && startsWithBrBreak(lineInfo)) {
        return !hasNextBreak(getPositionsUntil, scope, lineInfo);
      } else {
        return lineInfo.breakAt.isNone();
      }
    };
    var isAtFirstTableCellLine = curry(isAtTableCellLine, getPositionsUntilPreviousLine);
    var isAtLastTableCellLine = curry(isAtTableCellLine, getPositionsUntilNextLine);
    var isCaretAtStartOrEndOfTable = function (forward, rng, table) {
      var caretPos = CaretPosition$1.fromRangeStart(rng);
      return CaretFinder.positionIn(!forward, table).map(function (pos) {
        return pos.isEqual(caretPos);
      }).getOr(false);
    };
    var navigateHorizontally = function (editor, forward, table, td) {
      var rng = editor.selection.getRng();
      var direction = forward ? 1 : -1;
      if (isFakeCaretTableBrowser() && isCaretAtStartOrEndOfTable(forward, rng, table)) {
        var newRng = showCaret(direction, editor, table, !forward, true);
        moveToRange(editor, newRng);
        return true;
      }
      return false;
    };
    var getClosestAbovePosition = function (root, table, start) {
      return findClosestPositionInAboveCell(table, start).orThunk(function () {
        return head(start.getClientRects()).bind(function (rect) {
          return findClosestHorizontalPositionFromPoint(getPositionsAbove(root, CaretPosition$1.before(table)), rect.left);
        });
      }).getOr(CaretPosition$1.before(table));
    };
    var getClosestBelowPosition = function (root, table, start) {
      return findClosestPositionInBelowCell(table, start).orThunk(function () {
        return head(start.getClientRects()).bind(function (rect) {
          return findClosestHorizontalPositionFromPoint(getPositionsBelow(root, CaretPosition$1.after(table)), rect.left);
        });
      }).getOr(CaretPosition$1.after(table));
    };
    var getTable = function (previous, pos) {
      var node = pos.getNode(previous);
      return NodeType.isElement(node) && node.nodeName === 'TABLE' ? Option.some(node) : Option.none();
    };
    var renderBlock = function (down, editor, table, pos) {
      var forcedRootBlock = Settings.getForcedRootBlock(editor);
      if (forcedRootBlock) {
        editor.undoManager.transact(function () {
          var element = Element.fromTag(forcedRootBlock);
          setAll(element, Settings.getForcedRootBlockAttrs(editor));
          append(element, Element.fromTag('br'));
          if (down) {
            after(Element.fromDom(table), element);
          } else {
            before(Element.fromDom(table), element);
          }
          var rng = editor.dom.createRng();
          rng.setStart(element.dom(), 0);
          rng.setEnd(element.dom(), 0);
          moveToRange(editor, rng);
        });
      } else {
        moveToRange(editor, pos.toRange());
      }
    };
    var moveCaret = function (editor, down, pos) {
      var table = down ? getTable(true, pos) : getTable(false, pos);
      var last = down === false;
      table.fold(function () {
        return moveToRange(editor, pos.toRange());
      }, function (table) {
        return CaretFinder.positionIn(last, editor.getBody()).filter(function (lastPos) {
          return lastPos.isEqual(pos);
        }).fold(function () {
          return moveToRange(editor, pos.toRange());
        }, function (_) {
          return renderBlock(down, editor, table, pos);
        });
      });
    };
    var navigateVertically = function (editor, down, table, td) {
      var rng = editor.selection.getRng();
      var pos = CaretPosition$1.fromRangeStart(rng);
      var root = editor.getBody();
      if (!down && isAtFirstTableCellLine(td, pos)) {
        var newPos = getClosestAbovePosition(root, table, pos);
        moveCaret(editor, down, newPos);
        return true;
      } else if (down && isAtLastTableCellLine(td, pos)) {
        var newPos = getClosestBelowPosition(root, table, pos);
        moveCaret(editor, down, newPos);
        return true;
      } else {
        return false;
      }
    };
    var moveH$1 = function (editor, forward) {
      return function () {
        return Option.from(editor.dom.getParent(editor.selection.getNode(), 'td,th')).bind(function (td) {
          return Option.from(editor.dom.getParent(td, 'table')).map(function (table) {
            return navigateHorizontally(editor, forward, table);
          });
        }).getOr(false);
      };
    };
    var moveV$1 = function (editor, forward) {
      return function () {
        return Option.from(editor.dom.getParent(editor.selection.getNode(), 'td,th')).bind(function (td) {
          return Option.from(editor.dom.getParent(td, 'table')).map(function (table) {
            return navigateVertically(editor, forward, table, td);
          });
        }).getOr(false);
      };
    };

    var isTarget = function (node) {
      return contains(['figcaption'], name(node));
    };
    var rangeBefore = function (target) {
      var rng = domGlobals.document.createRange();
      rng.setStartBefore(target.dom());
      rng.setEndBefore(target.dom());
      return rng;
    };
    var insertElement = function (root, elm, forward) {
      if (forward) {
        append(root, elm);
      } else {
        prepend(root, elm);
      }
    };
    var insertBr = function (root, forward) {
      var br = Element.fromTag('br');
      insertElement(root, br, forward);
      return rangeBefore(br);
    };
    var insertBlock$1 = function (root, forward, blockName, attrs) {
      var block = Element.fromTag(blockName);
      var br = Element.fromTag('br');
      setAll(block, attrs);
      append(block, br);
      insertElement(root, block, forward);
      return rangeBefore(br);
    };
    var insertEmptyLine = function (root, rootBlockName, attrs, forward) {
      if (rootBlockName === '') {
        return insertBr(root, forward);
      } else {
        return insertBlock$1(root, forward, rootBlockName, attrs);
      }
    };
    var getClosestTargetBlock = function (pos, root) {
      var isRoot = curry(eq, root);
      return closest(Element.fromDom(pos.container()), isBlock, isRoot).filter(isTarget);
    };
    var isAtFirstOrLastLine = function (root, forward, pos) {
      return forward ? isAtLastLine(root.dom(), pos) : isAtFirstLine(root.dom(), pos);
    };
    var moveCaretToNewEmptyLine = function (editor, forward) {
      var root = Element.fromDom(editor.getBody());
      var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
      var rootBlock = Settings.getForcedRootBlock(editor);
      var rootBlockAttrs = Settings.getForcedRootBlockAttrs(editor);
      return getClosestTargetBlock(pos, root).exists(function () {
        if (isAtFirstOrLastLine(root, forward, pos)) {
          var rng = insertEmptyLine(root, rootBlock, rootBlockAttrs, forward);
          editor.selection.setRng(rng);
          return true;
        } else {
          return false;
        }
      });
    };
    var moveV$2 = function (editor, forward) {
      return function () {
        if (editor.selection.isCollapsed()) {
          return moveCaretToNewEmptyLine(editor, forward);
        } else {
          return false;
        }
      };
    };

    var defaultPatterns = function (patterns) {
      return map(patterns, function (pattern) {
        return __assign({
          shiftKey: false,
          altKey: false,
          ctrlKey: false,
          metaKey: false,
          keyCode: 0,
          action: noop
        }, pattern);
      });
    };
    var matchesEvent = function (pattern, evt) {
      return evt.keyCode === pattern.keyCode && evt.shiftKey === pattern.shiftKey && evt.altKey === pattern.altKey && evt.ctrlKey === pattern.ctrlKey && evt.metaKey === pattern.metaKey;
    };
    var match$1 = function (patterns, evt) {
      return bind(defaultPatterns(patterns), function (pattern) {
        return matchesEvent(pattern, evt) ? [pattern] : [];
      });
    };
    var action = function (f) {
      var x = [];
      for (var _i = 1; _i < arguments.length; _i++) {
        x[_i - 1] = arguments[_i];
      }
      var args = Array.prototype.slice.call(arguments, 1);
      return function () {
        return f.apply(null, args);
      };
    };
    var execute = function (patterns, evt) {
      return find(match$1(patterns, evt), function (pattern) {
        return pattern.action();
      });
    };
    var MatchKeys = {
      match: match$1,
      action: action,
      execute: execute
    };

    var executeKeydownOverride = function (editor, caret, evt) {
      var os = detect$3().os;
      MatchKeys.execute([
        {
          keyCode: VK.RIGHT,
          action: moveH(editor, true)
        },
        {
          keyCode: VK.LEFT,
          action: moveH(editor, false)
        },
        {
          keyCode: VK.UP,
          action: moveV(editor, false)
        },
        {
          keyCode: VK.DOWN,
          action: moveV(editor, true)
        },
        {
          keyCode: VK.RIGHT,
          action: moveH$1(editor, true)
        },
        {
          keyCode: VK.LEFT,
          action: moveH$1(editor, false)
        },
        {
          keyCode: VK.UP,
          action: moveV$1(editor, false)
        },
        {
          keyCode: VK.DOWN,
          action: moveV$1(editor, true)
        },
        {
          keyCode: VK.RIGHT,
          action: BoundarySelection.move(editor, caret, true)
        },
        {
          keyCode: VK.LEFT,
          action: BoundarySelection.move(editor, caret, false)
        },
        {
          keyCode: VK.RIGHT,
          ctrlKey: !os.isOSX(),
          altKey: os.isOSX(),
          action: BoundarySelection.moveNextWord(editor, caret)
        },
        {
          keyCode: VK.LEFT,
          ctrlKey: !os.isOSX(),
          altKey: os.isOSX(),
          action: BoundarySelection.movePrevWord(editor, caret)
        },
        {
          keyCode: VK.UP,
          action: moveV$2(editor, false)
        },
        {
          keyCode: VK.DOWN,
          action: moveV$2(editor, true)
        }
      ], evt).each(function (_) {
        evt.preventDefault();
      });
    };
    var setup$9 = function (editor, caret) {
      editor.on('keydown', function (evt) {
        if (evt.isDefaultPrevented() === false) {
          executeKeydownOverride(editor, caret, evt);
        }
      });
    };
    var ArrowKeys = { setup: setup$9 };

    var isBeforeRoot = function (rootNode) {
      return function (elm) {
        return eq(rootNode, Element.fromDom(elm.dom().parentNode));
      };
    };
    var getParentBlock$1 = function (rootNode, elm) {
      return contains$2(rootNode, elm) ? closest(elm, function (element) {
        return isTextBlock(element) || isListItem(element);
      }, isBeforeRoot(rootNode)) : Option.none();
    };
    var placeCaretInEmptyBody = function (editor) {
      var body = editor.getBody();
      var node = body.firstChild && editor.dom.isBlock(body.firstChild) ? body.firstChild : body;
      editor.selection.setCursorLocation(node, 0);
    };
    var paddEmptyBody = function (editor) {
      if (editor.dom.isEmpty(editor.getBody())) {
        editor.setContent('');
        placeCaretInEmptyBody(editor);
      }
    };
    var willDeleteLastPositionInElement = function (forward, fromPos, elm) {
      return lift2(CaretFinder.firstPositionIn(elm), CaretFinder.lastPositionIn(elm), function (firstPos, lastPos) {
        var normalizedFirstPos = InlineUtils.normalizePosition(true, firstPos);
        var normalizedLastPos = InlineUtils.normalizePosition(false, lastPos);
        var normalizedFromPos = InlineUtils.normalizePosition(false, fromPos);
        if (forward) {
          return CaretFinder.nextPosition(elm, normalizedFromPos).map(function (nextPos) {
            return nextPos.isEqual(normalizedLastPos) && fromPos.isEqual(normalizedFirstPos);
          }).getOr(false);
        } else {
          return CaretFinder.prevPosition(elm, normalizedFromPos).map(function (prevPos) {
            return prevPos.isEqual(normalizedFirstPos) && fromPos.isEqual(normalizedLastPos);
          }).getOr(false);
        }
      }).getOr(true);
    };
    var DeleteUtils = {
      getParentBlock: getParentBlock$1,
      paddEmptyBody: paddEmptyBody,
      willDeleteLastPositionInElement: willDeleteLastPositionInElement
    };

    var blockPosition = function (block, position) {
      return {
        block: constant(block),
        position: constant(position)
      };
    };
    var blockBoundary = function (from, to) {
      return {
        from: constant(from),
        to: constant(to)
      };
    };
    var getBlockPosition = function (rootNode, pos) {
      var rootElm = Element.fromDom(rootNode);
      var containerElm = Element.fromDom(pos.container());
      return DeleteUtils.getParentBlock(rootElm, containerElm).map(function (block) {
        return blockPosition(block, pos);
      });
    };
    var isDifferentBlocks = function (blockBoundary) {
      return eq(blockBoundary.from().block(), blockBoundary.to().block()) === false;
    };
    var hasSameParent = function (blockBoundary) {
      return parent(blockBoundary.from().block()).bind(function (parent1) {
        return parent(blockBoundary.to().block()).filter(function (parent2) {
          return eq(parent1, parent2);
        });
      }).isSome();
    };
    var isEditable = function (blockBoundary) {
      return NodeType.isContentEditableFalse(blockBoundary.from().block().dom()) === false && NodeType.isContentEditableFalse(blockBoundary.to().block().dom()) === false;
    };
    var skipLastBr = function (rootNode, forward, blockPosition) {
      if (NodeType.isBr(blockPosition.position().getNode()) && Empty.isEmpty(blockPosition.block()) === false) {
        return CaretFinder.positionIn(false, blockPosition.block().dom()).bind(function (lastPositionInBlock) {
          if (lastPositionInBlock.isEqual(blockPosition.position())) {
            return CaretFinder.fromPosition(forward, rootNode, lastPositionInBlock).bind(function (to) {
              return getBlockPosition(rootNode, to);
            });
          } else {
            return Option.some(blockPosition);
          }
        }).getOr(blockPosition);
      } else {
        return blockPosition;
      }
    };
    var readFromRange = function (rootNode, forward, rng) {
      var fromBlockPos = getBlockPosition(rootNode, CaretPosition$1.fromRangeStart(rng));
      var toBlockPos = fromBlockPos.bind(function (blockPos) {
        return CaretFinder.fromPosition(forward, rootNode, blockPos.position()).bind(function (to) {
          return getBlockPosition(rootNode, to).map(function (blockPos) {
            return skipLastBr(rootNode, forward, blockPos);
          });
        });
      });
      return lift2(fromBlockPos, toBlockPos, blockBoundary).filter(function (blockBoundary) {
        return isDifferentBlocks(blockBoundary) && hasSameParent(blockBoundary) && isEditable(blockBoundary);
      });
    };
    var read$3 = function (rootNode, forward, rng) {
      return rng.collapsed ? readFromRange(rootNode, forward, rng) : Option.none();
    };
    var BlockMergeBoundary = { read: read$3 };

    var getChildrenUntilBlockBoundary = function (block) {
      var children$1 = children(block);
      return findIndex(children$1, isBlock).fold(function () {
        return children$1;
      }, function (index) {
        return children$1.slice(0, index);
      });
    };
    var extractChildren = function (block) {
      var children = getChildrenUntilBlockBoundary(block);
      each(children, remove);
      return children;
    };
    var removeEmptyRoot = function (rootNode, block) {
      var parents = Parents.parentsAndSelf(block, rootNode);
      return find(parents.reverse(), function (element) {
        return Empty.isEmpty(element);
      }).each(remove);
    };
    var isEmptyBefore = function (el) {
      return filter(prevSiblings(el), function (el) {
        return !Empty.isEmpty(el);
      }).length === 0;
    };
    var nestedBlockMerge = function (rootNode, fromBlock, toBlock, insertionPoint) {
      if (Empty.isEmpty(toBlock)) {
        PaddingBr.fillWithPaddingBr(toBlock);
        return CaretFinder.firstPositionIn(toBlock.dom());
      }
      if (isEmptyBefore(insertionPoint) && Empty.isEmpty(fromBlock)) {
        before(insertionPoint, Element.fromTag('br'));
      }
      var position = CaretFinder.prevPosition(toBlock.dom(), CaretPosition$1.before(insertionPoint.dom()));
      each(extractChildren(fromBlock), function (child) {
        before(insertionPoint, child);
      });
      removeEmptyRoot(rootNode, fromBlock);
      return position;
    };
    var sidelongBlockMerge = function (rootNode, fromBlock, toBlock) {
      if (Empty.isEmpty(toBlock)) {
        remove(toBlock);
        if (Empty.isEmpty(fromBlock)) {
          PaddingBr.fillWithPaddingBr(fromBlock);
        }
        return CaretFinder.firstPositionIn(fromBlock.dom());
      }
      var position = CaretFinder.lastPositionIn(toBlock.dom());
      each(extractChildren(fromBlock), function (child) {
        append(toBlock, child);
      });
      removeEmptyRoot(rootNode, fromBlock);
      return position;
    };
    var findInsertionPoint = function (toBlock, block) {
      var parentsAndSelf = Parents.parentsAndSelf(block, toBlock);
      return Option.from(parentsAndSelf[parentsAndSelf.length - 1]);
    };
    var getInsertionPoint = function (fromBlock, toBlock) {
      return contains$2(toBlock, fromBlock) ? findInsertionPoint(toBlock, fromBlock) : Option.none();
    };
    var trimBr = function (first, block) {
      CaretFinder.positionIn(first, block.dom()).map(function (position) {
        return position.getNode();
      }).map(Element.fromDom).filter(isBr$1).each(remove);
    };
    var mergeBlockInto = function (rootNode, fromBlock, toBlock) {
      trimBr(true, fromBlock);
      trimBr(false, toBlock);
      return getInsertionPoint(fromBlock, toBlock).fold(curry(sidelongBlockMerge, rootNode, fromBlock, toBlock), curry(nestedBlockMerge, rootNode, fromBlock, toBlock));
    };
    var mergeBlocks = function (rootNode, forward, block1, block2) {
      return forward ? mergeBlockInto(rootNode, block2, block1) : mergeBlockInto(rootNode, block1, block2);
    };
    var MergeBlocks = { mergeBlocks: mergeBlocks };

    var backspaceDelete = function (editor, forward) {
      var rootNode = Element.fromDom(editor.getBody());
      var position = BlockMergeBoundary.read(rootNode.dom(), forward, editor.selection.getRng()).bind(function (blockBoundary) {
        return MergeBlocks.mergeBlocks(rootNode, forward, blockBoundary.from().block(), blockBoundary.to().block());
      });
      position.each(function (pos) {
        editor.selection.setRng(pos.toRange());
      });
      return position.isSome();
    };
    var BlockBoundaryDelete = { backspaceDelete: backspaceDelete };

    var deleteRangeMergeBlocks = function (rootNode, selection) {
      var rng = selection.getRng();
      return lift2(DeleteUtils.getParentBlock(rootNode, Element.fromDom(rng.startContainer)), DeleteUtils.getParentBlock(rootNode, Element.fromDom(rng.endContainer)), function (block1, block2) {
        if (eq(block1, block2) === false) {
          rng.deleteContents();
          MergeBlocks.mergeBlocks(rootNode, true, block1, block2).each(function (pos) {
            selection.setRng(pos.toRange());
          });
          return true;
        } else {
          return false;
        }
      }).getOr(false);
    };
    var isRawNodeInTable = function (root, rawNode) {
      var node = Element.fromDom(rawNode);
      var isRoot = curry(eq, root);
      return ancestor(node, isTableCell, isRoot).isSome();
    };
    var isSelectionInTable = function (root, rng) {
      return isRawNodeInTable(root, rng.startContainer) || isRawNodeInTable(root, rng.endContainer);
    };
    var isEverythingSelected = function (root, rng) {
      var noPrevious = CaretFinder.prevPosition(root.dom(), CaretPosition$1.fromRangeStart(rng)).isNone();
      var noNext = CaretFinder.nextPosition(root.dom(), CaretPosition$1.fromRangeEnd(rng)).isNone();
      return !isSelectionInTable(root, rng) && noPrevious && noNext;
    };
    var emptyEditor = function (editor) {
      editor.setContent('');
      editor.selection.setCursorLocation();
      return true;
    };
    var deleteRange = function (editor) {
      var rootNode = Element.fromDom(editor.getBody());
      var rng = editor.selection.getRng();
      return isEverythingSelected(rootNode, rng) ? emptyEditor(editor) : deleteRangeMergeBlocks(rootNode, editor.selection);
    };
    var backspaceDelete$1 = function (editor, forward) {
      return editor.selection.isCollapsed() ? false : deleteRange(editor);
    };
    var BlockRangeDelete = { backspaceDelete: backspaceDelete$1 };

    var isBr$5 = function (pos) {
      return getElementFromPosition(pos).exists(isBr$1);
    };
    var findBr = function (forward, root, pos) {
      var parentBlocks = filter(Parents.parentsAndSelf(Element.fromDom(pos.container()), root), isBlock);
      var scope = head(parentBlocks).getOr(root);
      return CaretFinder.fromPosition(forward, scope.dom(), pos).filter(isBr$5);
    };
    var isBeforeBr = function (root, pos) {
      return getElementFromPosition(pos).exists(isBr$1) || findBr(true, root, pos).isSome();
    };
    var isAfterBr = function (root, pos) {
      return getElementFromPrevPosition(pos).exists(isBr$1) || findBr(false, root, pos).isSome();
    };
    var findPreviousBr = curry(findBr, false);
    var findNextBr = curry(findBr, true);

    var isCompoundElement = function (node) {
      return isTableCell(Element.fromDom(node)) || isListItem(Element.fromDom(node));
    };
    var DeleteAction = Adt.generate([
      { remove: ['element'] },
      { moveToElement: ['element'] },
      { moveToPosition: ['position'] }
    ]);
    var isAtContentEditableBlockCaret = function (forward, from) {
      var elm = from.getNode(forward === false);
      var caretLocation = forward ? 'after' : 'before';
      return NodeType.isElement(elm) && elm.getAttribute('data-mce-caret') === caretLocation;
    };
    var isDeleteFromCefDifferentBlocks = function (root, forward, from, to) {
      var inSameBlock = function (elm) {
        return isInline(Element.fromDom(elm)) && !isInSameBlock(from, to, root);
      };
      return getRelativeCefElm(!forward, from).fold(function () {
        return getRelativeCefElm(forward, to).fold(constant(false), inSameBlock);
      }, inSameBlock);
    };
    var deleteEmptyBlockOrMoveToCef = function (root, forward, from, to) {
      var toCefElm = to.getNode(forward === false);
      return DeleteUtils.getParentBlock(Element.fromDom(root), Element.fromDom(from.getNode())).map(function (blockElm) {
        return Empty.isEmpty(blockElm) ? DeleteAction.remove(blockElm.dom()) : DeleteAction.moveToElement(toCefElm);
      }).orThunk(function () {
        return Option.some(DeleteAction.moveToElement(toCefElm));
      });
    };
    var findCefPosition = function (root, forward, from) {
      return CaretFinder.fromPosition(forward, root, from).bind(function (to) {
        if (isCompoundElement(to.getNode())) {
          return Option.none();
        } else if (isDeleteFromCefDifferentBlocks(root, forward, from, to)) {
          return Option.none();
        } else if (forward && NodeType.isContentEditableFalse(to.getNode())) {
          return deleteEmptyBlockOrMoveToCef(root, forward, from, to);
        } else if (forward === false && NodeType.isContentEditableFalse(to.getNode(true))) {
          return deleteEmptyBlockOrMoveToCef(root, forward, from, to);
        } else if (forward && isAfterContentEditableFalse(from)) {
          return Option.some(DeleteAction.moveToPosition(to));
        } else if (forward === false && isBeforeContentEditableFalse(from)) {
          return Option.some(DeleteAction.moveToPosition(to));
        } else {
          return Option.none();
        }
      });
    };
    var getContentEditableBlockAction = function (forward, elm) {
      if (forward && NodeType.isContentEditableFalse(elm.nextSibling)) {
        return Option.some(DeleteAction.moveToElement(elm.nextSibling));
      } else if (forward === false && NodeType.isContentEditableFalse(elm.previousSibling)) {
        return Option.some(DeleteAction.moveToElement(elm.previousSibling));
      } else {
        return Option.none();
      }
    };
    var skipMoveToActionFromInlineCefToContent = function (root, from, deleteAction) {
      return deleteAction.fold(function (elm) {
        return Option.some(DeleteAction.remove(elm));
      }, function (elm) {
        return Option.some(DeleteAction.moveToElement(elm));
      }, function (to) {
        if (isInSameBlock(from, to, root)) {
          return Option.none();
        } else {
          return Option.some(DeleteAction.moveToPosition(to));
        }
      });
    };
    var getContentEditableAction = function (root, forward, from) {
      if (isAtContentEditableBlockCaret(forward, from)) {
        return getContentEditableBlockAction(forward, from.getNode(forward === false)).fold(function () {
          return findCefPosition(root, forward, from);
        }, Option.some);
      } else {
        return findCefPosition(root, forward, from).bind(function (deleteAction) {
          return skipMoveToActionFromInlineCefToContent(root, from, deleteAction);
        });
      }
    };
    var read$4 = function (root, forward, rng) {
      var normalizedRange = normalizeRange(forward ? 1 : -1, root, rng);
      var from = CaretPosition$1.fromRangeStart(normalizedRange);
      var rootElement = Element.fromDom(root);
      if (forward === false && isAfterContentEditableFalse(from)) {
        return Option.some(DeleteAction.remove(from.getNode(true)));
      } else if (forward && isBeforeContentEditableFalse(from)) {
        return Option.some(DeleteAction.remove(from.getNode()));
      } else if (forward === false && isBeforeContentEditableFalse(from) && isAfterBr(rootElement, from)) {
        return findPreviousBr(rootElement, from).map(function (br) {
          return DeleteAction.remove(br.getNode());
        });
      } else if (forward && isAfterContentEditableFalse(from) && isBeforeBr(rootElement, from)) {
        return findNextBr(rootElement, from).map(function (br) {
          return DeleteAction.remove(br.getNode());
        });
      } else {
        return getContentEditableAction(root, forward, from);
      }
    };

    var deleteElement$1 = function (editor, forward) {
      return function (element) {
        editor._selectionOverrides.hideFakeCaret();
        DeleteElement.deleteElement(editor, forward, Element.fromDom(element));
        return true;
      };
    };
    var moveToElement = function (editor, forward) {
      return function (element) {
        var pos = forward ? CaretPosition$1.before(element) : CaretPosition$1.after(element);
        editor.selection.setRng(pos.toRange());
        return true;
      };
    };
    var moveToPosition = function (editor) {
      return function (pos) {
        editor.selection.setRng(pos.toRange());
        return true;
      };
    };
    var getAncestorCe = function (editor, node) {
      return Option.from(getContentEditableRoot$1(editor.getBody(), node));
    };
    var backspaceDeleteCaret = function (editor, forward) {
      var selectedNode = editor.selection.getNode();
      return getAncestorCe(editor, selectedNode).filter(NodeType.isContentEditableFalse).fold(function () {
        var result = read$4(editor.getBody(), forward, editor.selection.getRng()).map(function (deleteAction) {
          return deleteAction.fold(deleteElement$1(editor, forward), moveToElement(editor, forward), moveToPosition(editor));
        });
        return result.getOr(false);
      }, function () {
        return true;
      });
    };
    var deleteOffscreenSelection = function (rootElement) {
      each(descendants$1(rootElement, '.mce-offscreen-selection'), remove);
    };
    var backspaceDeleteRange = function (editor, forward) {
      var selectedNode = editor.selection.getNode();
      if (NodeType.isContentEditableFalse(selectedNode)) {
        var hasCefAncestor = getAncestorCe(editor, selectedNode.parentNode).filter(NodeType.isContentEditableFalse);
        return hasCefAncestor.fold(function () {
          deleteOffscreenSelection(Element.fromDom(editor.getBody()));
          DeleteElement.deleteElement(editor, forward, Element.fromDom(editor.selection.getNode()));
          DeleteUtils.paddEmptyBody(editor);
          return true;
        }, function () {
          return true;
        });
      }
      return false;
    };
    var getContentEditableRoot$1 = function (root, node) {
      while (node && node !== root) {
        if (NodeType.isContentEditableTrue(node) || NodeType.isContentEditableFalse(node)) {
          return node;
        }
        node = node.parentNode;
      }
      return null;
    };
    var paddEmptyElement = function (editor) {
      var br;
      var ceRoot = getContentEditableRoot$1(editor.getBody(), editor.selection.getNode());
      if (NodeType.isContentEditableTrue(ceRoot) && editor.dom.isBlock(ceRoot) && editor.dom.isEmpty(ceRoot)) {
        br = editor.dom.create('br', { 'data-mce-bogus': '1' });
        editor.dom.setHTML(ceRoot, '');
        ceRoot.appendChild(br);
        editor.selection.setRng(CaretPosition$1.before(br).toRange());
      }
      return true;
    };
    var backspaceDelete$2 = function (editor, forward) {
      if (editor.selection.isCollapsed()) {
        return backspaceDeleteCaret(editor, forward);
      } else {
        return backspaceDeleteRange(editor, forward);
      }
    };
    var CefDelete = {
      backspaceDelete: backspaceDelete$2,
      paddEmptyElement: paddEmptyElement
    };

    var trimEmptyTextNode$1 = function (dom, node) {
      if (NodeType.isText(node) && node.data.length === 0) {
        dom.remove(node);
      }
    };
    var deleteContentAndShowCaret = function (editor, range, node, direction, forward, peekCaretPosition) {
      var caretRange = showCaret(direction, editor, peekCaretPosition.getNode(!forward), forward, true);
      if (range.collapsed) {
        var deleteRange = range.cloneRange();
        if (forward) {
          deleteRange.setEnd(caretRange.startContainer, caretRange.startOffset);
        } else {
          deleteRange.setStart(caretRange.endContainer, caretRange.endOffset);
        }
        deleteRange.deleteContents();
      } else {
        range.deleteContents();
      }
      editor.selection.setRng(caretRange);
      trimEmptyTextNode$1(editor.dom, node);
      return true;
    };
    var deleteCefBoundaryText = function (editor, forward) {
      var range = editor.selection.getRng();
      if (!NodeType.isText(range.commonAncestorContainer)) {
        return false;
      }
      var direction = forward ? HDirection.Forwards : HDirection.Backwards;
      var caretWalker = CaretWalker(editor.getBody());
      var getNextVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.next);
      var getPrevVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.prev);
      var getNextPosFn = forward ? getNextVisualCaretPosition : getPrevVisualCaretPosition;
      var isBeforeContentEditableFalseFn = forward ? isBeforeContentEditableFalse : isAfterContentEditableFalse;
      var caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range);
      var nextCaretPosition = InlineUtils.normalizePosition(forward, getNextPosFn(caretPosition));
      if (!nextCaretPosition || !isMoveInsideSameBlock(caretPosition, nextCaretPosition)) {
        return false;
      } else if (isBeforeContentEditableFalseFn(nextCaretPosition)) {
        return deleteContentAndShowCaret(editor, range, caretPosition.getNode(), direction, forward, nextCaretPosition);
      }
      var peekCaretPosition = getNextPosFn(nextCaretPosition);
      if (peekCaretPosition && isBeforeContentEditableFalseFn(peekCaretPosition)) {
        if (isMoveInsideSameBlock(nextCaretPosition, peekCaretPosition)) {
          return deleteContentAndShowCaret(editor, range, caretPosition.getNode(), direction, forward, peekCaretPosition);
        }
      }
      return false;
    };
    var backspaceDelete$3 = function (editor, forward) {
      return deleteCefBoundaryText(editor, forward);
    };
    var CefBoundaryDelete = { backspaceDelete: backspaceDelete$3 };

    var isFeatureEnabled$1 = function (editor) {
      return editor.settings.inline_boundaries !== false;
    };
    var rangeFromPositions = function (from, to) {
      var range = domGlobals.document.createRange();
      range.setStart(from.container(), from.offset());
      range.setEnd(to.container(), to.offset());
      return range;
    };
    var hasOnlyTwoOrLessPositionsLeft = function (elm) {
      return lift2(CaretFinder.firstPositionIn(elm), CaretFinder.lastPositionIn(elm), function (firstPos, lastPos) {
        var normalizedFirstPos = InlineUtils.normalizePosition(true, firstPos);
        var normalizedLastPos = InlineUtils.normalizePosition(false, lastPos);
        return CaretFinder.nextPosition(elm, normalizedFirstPos).map(function (pos) {
          return pos.isEqual(normalizedLastPos);
        }).getOr(true);
      }).getOr(true);
    };
    var setCaretLocation = function (editor, caret) {
      return function (location) {
        return BoundaryCaret.renderCaret(caret, location).map(function (pos) {
          BoundarySelection.setCaretPosition(editor, pos);
          return true;
        }).getOr(false);
      };
    };
    var deleteFromTo = function (editor, caret, from, to) {
      var rootNode = editor.getBody();
      var isInlineTarget = curry(InlineUtils.isInlineTarget, editor);
      editor.undoManager.ignore(function () {
        editor.selection.setRng(rangeFromPositions(from, to));
        editor.execCommand('Delete');
        BoundaryLocation.readLocation(isInlineTarget, rootNode, CaretPosition$1.fromRangeStart(editor.selection.getRng())).map(BoundaryLocation.inside).map(setCaretLocation(editor, caret));
      });
      editor.nodeChanged();
    };
    var rescope$1 = function (rootNode, node) {
      var parentBlock = getParentBlock(node, rootNode);
      return parentBlock ? parentBlock : rootNode;
    };
    var backspaceDeleteCollapsed = function (editor, caret, forward, from) {
      var rootNode = rescope$1(editor.getBody(), from.container());
      var isInlineTarget = curry(InlineUtils.isInlineTarget, editor);
      var fromLocation = BoundaryLocation.readLocation(isInlineTarget, rootNode, from);
      return fromLocation.bind(function (location) {
        if (forward) {
          return location.fold(constant(Option.some(BoundaryLocation.inside(location))), Option.none, constant(Option.some(BoundaryLocation.outside(location))), Option.none);
        } else {
          return location.fold(Option.none, constant(Option.some(BoundaryLocation.outside(location))), Option.none, constant(Option.some(BoundaryLocation.inside(location))));
        }
      }).map(setCaretLocation(editor, caret)).getOrThunk(function () {
        var toPosition = CaretFinder.navigate(forward, rootNode, from);
        var toLocation = toPosition.bind(function (pos) {
          return BoundaryLocation.readLocation(isInlineTarget, rootNode, pos);
        });
        if (fromLocation.isSome() && toLocation.isSome()) {
          return InlineUtils.findRootInline(isInlineTarget, rootNode, from).map(function (elm) {
            if (hasOnlyTwoOrLessPositionsLeft(elm)) {
              DeleteElement.deleteElement(editor, forward, Element.fromDom(elm));
              return true;
            } else {
              return false;
            }
          }).getOr(false);
        } else {
          return toLocation.bind(function (_) {
            return toPosition.map(function (to) {
              if (forward) {
                deleteFromTo(editor, caret, from, to);
              } else {
                deleteFromTo(editor, caret, to, from);
              }
              return true;
            });
          }).getOr(false);
        }
      });
    };
    var backspaceDelete$4 = function (editor, caret, forward) {
      if (editor.selection.isCollapsed() && isFeatureEnabled$1(editor)) {
        var from = CaretPosition$1.fromRangeStart(editor.selection.getRng());
        return backspaceDeleteCollapsed(editor, caret, forward, from);
      }
      return false;
    };
    var BoundaryDelete = { backspaceDelete: backspaceDelete$4 };

    var getParentInlines = function (rootElm, startElm) {
      var parents = Parents.parentsAndSelf(startElm, rootElm);
      return findIndex(parents, isBlock).fold(constant(parents), function (index) {
        return parents.slice(0, index);
      });
    };
    var hasOnlyOneChild = function (elm) {
      return children(elm).length === 1;
    };
    var deleteLastPosition = function (forward, editor, target, parentInlines) {
      var isFormatElement$1 = curry(isFormatElement, editor);
      var formatNodes = map(filter(parentInlines, isFormatElement$1), function (elm) {
        return elm.dom();
      });
      if (formatNodes.length === 0) {
        DeleteElement.deleteElement(editor, forward, target);
      } else {
        var pos = replaceWithCaretFormat(target.dom(), formatNodes);
        editor.selection.setRng(pos.toRange());
      }
    };
    var deleteCaret = function (editor, forward) {
      var rootElm = Element.fromDom(editor.getBody());
      var startElm = Element.fromDom(editor.selection.getStart());
      var parentInlines = filter(getParentInlines(rootElm, startElm), hasOnlyOneChild);
      return last(parentInlines).map(function (target) {
        var fromPos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
        if (DeleteUtils.willDeleteLastPositionInElement(forward, fromPos, target.dom()) && !isEmptyCaretFormatElement(target)) {
          deleteLastPosition(forward, editor, target, parentInlines);
          return true;
        } else {
          return false;
        }
      }).getOr(false);
    };
    var backspaceDelete$5 = function (editor, forward) {
      return editor.selection.isCollapsed() ? deleteCaret(editor, forward) : false;
    };
    var InlineFormatDelete = { backspaceDelete: backspaceDelete$5 };

    var tableCellRng = function (start, end) {
      return {
        start: constant(start),
        end: constant(end)
      };
    };
    var tableSelection = function (rng, table, cells) {
      return {
        rng: constant(rng),
        table: constant(table),
        cells: constant(cells)
      };
    };
    var deleteAction = Adt.generate([
      { removeTable: ['element'] },
      { emptyCells: ['cells'] }
    ]);
    var isRootFromElement = function (root) {
      return function (cur) {
        return eq(root, cur);
      };
    };
    var getClosestCell$1 = function (container, isRoot) {
      return closest$1(Element.fromDom(container), 'td,th', isRoot);
    };
    var getClosestTable = function (cell, isRoot) {
      return ancestor$1(cell, 'table', isRoot);
    };
    var isExpandedCellRng = function (cellRng) {
      return eq(cellRng.start(), cellRng.end()) === false;
    };
    var getTableFromCellRng = function (cellRng, isRoot) {
      return getClosestTable(cellRng.start(), isRoot).bind(function (startParentTable) {
        return getClosestTable(cellRng.end(), isRoot).bind(function (endParentTable) {
          return someIf(eq(startParentTable, endParentTable), startParentTable);
        });
      });
    };
    var getTableCells = function (table) {
      return descendants$1(table, 'td,th');
    };
    var getCellRangeFromStartTable = function (cellRng, isRoot) {
      return getClosestTable(cellRng.start(), isRoot).bind(function (table) {
        return last(getTableCells(table)).map(function (endCell) {
          return tableCellRng(cellRng.start(), endCell);
        });
      });
    };
    var partialSelection = function (isRoot, rng) {
      var startCell = getClosestCell$1(rng.startContainer, isRoot);
      var endCell = getClosestCell$1(rng.endContainer, isRoot);
      return rng.collapsed ? Option.none() : lift2(startCell, endCell, tableCellRng).fold(function () {
        return startCell.fold(function () {
          return endCell.bind(function (endCell) {
            return getClosestTable(endCell, isRoot).bind(function (table) {
              return head(getTableCells(table)).map(function (startCell) {
                return tableCellRng(startCell, endCell);
              });
            });
          });
        }, function (startCell) {
          return getClosestTable(startCell, isRoot).bind(function (table) {
            return last(getTableCells(table)).map(function (endCell) {
              return tableCellRng(startCell, endCell);
            });
          });
        });
      }, function (cellRng) {
        return isWithinSameTable(isRoot, cellRng) ? Option.none() : getCellRangeFromStartTable(cellRng, isRoot);
      });
    };
    var isWithinSameTable = function (isRoot, cellRng) {
      return getTableFromCellRng(cellRng, isRoot).isSome();
    };
    var getCellRng = function (rng, isRoot) {
      var startCell = getClosestCell$1(rng.startContainer, isRoot);
      var endCell = getClosestCell$1(rng.endContainer, isRoot);
      return lift2(startCell, endCell, tableCellRng).filter(isExpandedCellRng).filter(function (cellRng) {
        return isWithinSameTable(isRoot, cellRng);
      }).orThunk(function () {
        return partialSelection(isRoot, rng);
      });
    };
    var getTableSelectionFromCellRng = function (cellRng, isRoot) {
      return getTableFromCellRng(cellRng, isRoot).map(function (table) {
        return tableSelection(cellRng, table, getTableCells(table));
      });
    };
    var getTableSelectionFromRng = function (root, rng) {
      var isRoot = isRootFromElement(root);
      return getCellRng(rng, isRoot).bind(function (cellRng) {
        return getTableSelectionFromCellRng(cellRng, isRoot);
      });
    };
    var getCellIndex = function (cells, cell) {
      return findIndex(cells, function (x) {
        return eq(x, cell);
      });
    };
    var getSelectedCells = function (tableSelection) {
      return lift2(getCellIndex(tableSelection.cells(), tableSelection.rng().start()), getCellIndex(tableSelection.cells(), tableSelection.rng().end()), function (startIndex, endIndex) {
        return tableSelection.cells().slice(startIndex, endIndex + 1);
      });
    };
    var getAction = function (tableSelection) {
      return getSelectedCells(tableSelection).map(function (selected) {
        var cells = tableSelection.cells();
        return selected.length === cells.length ? deleteAction.removeTable(tableSelection.table()) : deleteAction.emptyCells(selected);
      });
    };
    var getActionFromRange = function (root, rng) {
      return getTableSelectionFromRng(root, rng).bind(getAction);
    };

    var emptyCells = function (editor, cells) {
      each(cells, PaddingBr.fillWithPaddingBr);
      editor.selection.setCursorLocation(cells[0].dom(), 0);
      return true;
    };
    var deleteTableElement = function (editor, table) {
      DeleteElement.deleteElement(editor, false, table);
      return true;
    };
    var deleteCellRange = function (editor, rootElm, rng) {
      return getActionFromRange(rootElm, rng).map(function (action) {
        return action.fold(curry(deleteTableElement, editor), curry(emptyCells, editor));
      });
    };
    var deleteCaptionRange = function (editor, caption) {
      return emptyElement(editor, caption);
    };
    var deleteTableRange = function (editor, rootElm, rng, startElm) {
      return getParentCaption(rootElm, startElm).fold(function () {
        return deleteCellRange(editor, rootElm, rng);
      }, function (caption) {
        return deleteCaptionRange(editor, caption);
      }).getOr(false);
    };
    var deleteRange$1 = function (editor, startElm) {
      var rootNode = Element.fromDom(editor.getBody());
      var rng = editor.selection.getRng();
      var selectedCells = TableCellSelection.getCellsFromEditor(editor);
      return selectedCells.length !== 0 ? emptyCells(editor, selectedCells) : deleteTableRange(editor, rootNode, rng, startElm);
    };
    var getParentCell = function (rootElm, elm) {
      return find(Parents.parentsAndSelf(elm, rootElm), isTableCell);
    };
    var getParentCaption = function (rootElm, elm) {
      return find(Parents.parentsAndSelf(elm, rootElm), function (elm) {
        return name(elm) === 'caption';
      });
    };
    var deleteBetweenCells = function (editor, rootElm, forward, fromCell, from) {
      return CaretFinder.navigate(forward, editor.getBody(), from).bind(function (to) {
        return getParentCell(rootElm, Element.fromDom(to.getNode())).map(function (toCell) {
          return eq(toCell, fromCell) === false;
        });
      });
    };
    var emptyElement = function (editor, elm) {
      PaddingBr.fillWithPaddingBr(elm);
      editor.selection.setCursorLocation(elm.dom(), 0);
      return Option.some(true);
    };
    var isDeleteOfLastCharPos = function (fromCaption, forward, from, to) {
      return CaretFinder.firstPositionIn(fromCaption.dom()).bind(function (first) {
        return CaretFinder.lastPositionIn(fromCaption.dom()).map(function (last) {
          return forward ? from.isEqual(first) && to.isEqual(last) : from.isEqual(last) && to.isEqual(first);
        });
      }).getOr(true);
    };
    var emptyCaretCaption = function (editor, elm) {
      return emptyElement(editor, elm);
    };
    var validateCaretCaption = function (rootElm, fromCaption, to) {
      return getParentCaption(rootElm, Element.fromDom(to.getNode())).map(function (toCaption) {
        return eq(toCaption, fromCaption) === false;
      });
    };
    var deleteCaretInsideCaption = function (editor, rootElm, forward, fromCaption, from) {
      return CaretFinder.navigate(forward, editor.getBody(), from).bind(function (to) {
        return isDeleteOfLastCharPos(fromCaption, forward, from, to) ? emptyCaretCaption(editor, fromCaption) : validateCaretCaption(rootElm, fromCaption, to);
      }).or(Option.some(true));
    };
    var deleteCaretCells = function (editor, forward, rootElm, startElm) {
      var from = CaretPosition$1.fromRangeStart(editor.selection.getRng());
      return getParentCell(rootElm, startElm).bind(function (fromCell) {
        return Empty.isEmpty(fromCell) ? emptyElement(editor, fromCell) : deleteBetweenCells(editor, rootElm, forward, fromCell, from);
      }).getOr(false);
    };
    var deleteCaretCaption = function (editor, forward, rootElm, fromCaption) {
      var from = CaretPosition$1.fromRangeStart(editor.selection.getRng());
      return Empty.isEmpty(fromCaption) ? emptyElement(editor, fromCaption) : deleteCaretInsideCaption(editor, rootElm, forward, fromCaption, from);
    };
    var isNearTable = function (forward, pos) {
      return forward ? isBeforeTable(pos) : isAfterTable(pos);
    };
    var isBeforeOrAfterTable = function (editor, forward) {
      var fromPos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
      return isNearTable(forward, fromPos) || CaretFinder.fromPosition(forward, editor.getBody(), fromPos).map(function (pos) {
        return isNearTable(forward, pos);
      }).getOr(false);
    };
    var deleteCaret$1 = function (editor, forward, startElm) {
      var rootElm = Element.fromDom(editor.getBody());
      return getParentCaption(rootElm, startElm).fold(function () {
        return deleteCaretCells(editor, forward, rootElm, startElm) || isBeforeOrAfterTable(editor, forward);
      }, function (fromCaption) {
        return deleteCaretCaption(editor, forward, rootElm, fromCaption).getOr(false);
      });
    };
    var backspaceDelete$6 = function (editor, forward) {
      var startElm = Element.fromDom(editor.selection.getStart(true));
      var cells = TableCellSelection.getCellsFromEditor(editor);
      return editor.selection.isCollapsed() && cells.length === 0 ? deleteCaret$1(editor, forward, startElm) : deleteRange$1(editor, startElm);
    };
    var TableDelete = { backspaceDelete: backspaceDelete$6 };

    var deleteCaret$2 = function (editor, forward) {
      var fromPos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
      return CaretFinder.fromPosition(forward, editor.getBody(), fromPos).filter(function (pos) {
        return forward ? isBeforeImageBlock(pos) : isAfterImageBlock(pos);
      }).bind(function (pos) {
        return Option.from(getChildNodeAtRelativeOffset(forward ? 0 : -1, pos));
      }).map(function (elm) {
        editor.selection.select(elm);
        return true;
      }).getOr(false);
    };
    var backspaceDelete$7 = function (editor, forward) {
      return editor.selection.isCollapsed() ? deleteCaret$2(editor, forward) : false;
    };
    var PageBreakDelete = { backspaceDelete: backspaceDelete$7 };

    var isEditable$1 = function (target) {
      return closest(target, function (elm) {
        return NodeType.isContentEditableTrue(elm.dom()) || NodeType.isContentEditableFalse(elm.dom());
      }).exists(function (elm) {
        return NodeType.isContentEditableTrue(elm.dom());
      });
    };
    var parseIndentValue = function (value) {
      var number = parseInt(value, 10);
      return isNaN(number) ? 0 : number;
    };
    var getIndentStyleName = function (useMargin, element) {
      var indentStyleName = useMargin || isTable$1(element) ? 'margin' : 'padding';
      var suffix = get$4(element, 'direction') === 'rtl' ? '-right' : '-left';
      return indentStyleName + suffix;
    };
    var indentElement = function (dom, command, useMargin, value, unit, element) {
      var indentStyleName = getIndentStyleName(useMargin, Element.fromDom(element));
      if (command === 'outdent') {
        var styleValue = Math.max(0, parseIndentValue(element.style[indentStyleName]) - value);
        dom.setStyle(element, indentStyleName, styleValue ? styleValue + unit : '');
      } else {
        var styleValue = parseIndentValue(element.style[indentStyleName]) + value + unit;
        dom.setStyle(element, indentStyleName, styleValue);
      }
    };
    var validateBlocks = function (editor, blocks) {
      return forall(blocks, function (block) {
        var indentStyleName = getIndentStyleName(Settings.shouldIndentUseMargin(editor), block);
        var intentValue = getRaw(block, indentStyleName).map(parseIndentValue).getOr(0);
        var contentEditable = editor.dom.getContentEditable(block.dom());
        return contentEditable !== 'false' && intentValue > 0;
      });
    };
    var canOutdent = function (editor) {
      var blocks = getBlocksToIndent(editor);
      return editor.readonly !== true && (blocks.length > 1 || validateBlocks(editor, blocks));
    };
    var isListComponent = function (el) {
      return isList(el) || isListItem(el);
    };
    var parentIsListComponent = function (el) {
      return parent(el).map(isListComponent).getOr(false);
    };
    var getBlocksToIndent = function (editor) {
      return filter(map(editor.selection.getSelectedBlocks(), Element.fromDom), function (el) {
        return !isListComponent(el) && !parentIsListComponent(el) && isEditable$1(el);
      });
    };
    var handle = function (editor, command) {
      var dom = editor.dom, selection = editor.selection, formatter = editor.formatter;
      var indentation = Settings.getIndentation(editor);
      var indentUnit = /[a-z%]+$/i.exec(indentation)[0];
      var indentValue = parseInt(indentation, 10);
      var useMargin = Settings.shouldIndentUseMargin(editor);
      var forcedRootBlock = Settings.getForcedRootBlock(editor);
      if (!editor.queryCommandState('InsertUnorderedList') && !editor.queryCommandState('InsertOrderedList')) {
        if (forcedRootBlock === '' && !dom.getParent(selection.getNode(), dom.isBlock)) {
          formatter.apply('div');
        }
      }
      each(getBlocksToIndent(editor), function (block) {
        indentElement(dom, command, useMargin, indentValue, indentUnit, block.dom());
      });
    };

    var navigateIgnoreEmptyTextNodes = function (forward, root, from) {
      return CaretFinder.navigateIgnore(forward, root, from, isEmptyText);
    };
    var getClosestBlock = function (root, pos) {
      return find(Parents.parentsAndSelf(Element.fromDom(pos.container()), root), isBlock);
    };
    var isAtBeforeAfterBlockBoundary = function (forward, root, pos) {
      return navigateIgnoreEmptyTextNodes(forward, root.dom(), pos).forall(function (newPos) {
        return getClosestBlock(root, pos).fold(function () {
          return isInSameBlock(newPos, pos, root.dom()) === false;
        }, function (fromBlock) {
          return isInSameBlock(newPos, pos, root.dom()) === false && contains$2(fromBlock, Element.fromDom(newPos.container()));
        });
      });
    };
    var isAtBlockBoundary = function (forward, root, pos) {
      return getClosestBlock(root, pos).fold(function () {
        return navigateIgnoreEmptyTextNodes(forward, root.dom(), pos).forall(function (newPos) {
          return isInSameBlock(newPos, pos, root.dom()) === false;
        });
      }, function (parent) {
        return navigateIgnoreEmptyTextNodes(forward, parent.dom(), pos).isNone();
      });
    };
    var isAtStartOfBlock = curry(isAtBlockBoundary, false);
    var isAtEndOfBlock = curry(isAtBlockBoundary, true);
    var isBeforeBlock = curry(isAtBeforeAfterBlockBoundary, false);
    var isAfterBlock = curry(isAtBeforeAfterBlockBoundary, true);

    var backspaceDelete$8 = function (editor, _caret, _forward) {
      if (editor.selection.isCollapsed() && canOutdent(editor)) {
        var dom = editor.dom;
        var rng = editor.selection.getRng();
        var pos = CaretPosition$1.fromRangeStart(rng);
        var block = dom.getParent(rng.startContainer, dom.isBlock);
        if (block !== null && isAtStartOfBlock(Element.fromDom(block), pos)) {
          handle(editor, 'outdent');
          return true;
        }
      }
      return false;
    };
    var Outdent = { backspaceDelete: backspaceDelete$8 };

    var executeKeydownOverride$1 = function (editor, caret, evt) {
      MatchKeys.execute([
        {
          keyCode: VK.BACKSPACE,
          action: MatchKeys.action(Outdent.backspaceDelete, editor, false)
        },
        {
          keyCode: VK.BACKSPACE,
          action: MatchKeys.action(CefDelete.backspaceDelete, editor, false)
        },
        {
          keyCode: VK.DELETE,
          action: MatchKeys.action(CefDelete.backspaceDelete, editor, true)
        },
        {
          keyCode: VK.BACKSPACE,
          action: MatchKeys.action(CefBoundaryDelete.backspaceDelete, editor, false)
        },
        {
          keyCode: VK.DELETE,
          action: MatchKeys.action(CefBoundaryDelete.backspaceDelete, editor, true)
        },
        {
          keyCode: VK.BACKSPACE,
          action: MatchKeys.action(BoundaryDelete.backspaceDelete, editor, caret, false)
        },
        {
          keyCode: VK.DELETE,
          action: MatchKeys.action(BoundaryDelete.backspaceDelete, editor, caret, true)
        },
        {
          keyCode: VK.BACKSPACE,
          action: MatchKeys.action(TableDelete.backspaceDelete, editor, false)
        },
        {
          keyCode: VK.DELETE,
          action: MatchKeys.action(TableDelete.backspaceDelete, editor, true)
        },
        {
          keyCode: VK.BACKSPACE,
          action: MatchKeys.action(PageBreakDelete.backspaceDelete, editor, false)
        },
        {
          keyCode: VK.DELETE,
          action: MatchKeys.action(PageBreakDelete.backspaceDelete, editor, true)
        },
        {
          keyCode: VK.BACKSPACE,
          action: MatchKeys.action(BlockRangeDelete.backspaceDelete, editor, false)
        },
        {
          keyCode: VK.DELETE,
          action: MatchKeys.action(BlockRangeDelete.backspaceDelete, editor, true)
        },
        {
          keyCode: VK.BACKSPACE,
          action: MatchKeys.action(BlockBoundaryDelete.backspaceDelete, editor, false)
        },
        {
          keyCode: VK.DELETE,
          action: MatchKeys.action(BlockBoundaryDelete.backspaceDelete, editor, true)
        },
        {
          keyCode: VK.BACKSPACE,
          action: MatchKeys.action(InlineFormatDelete.backspaceDelete, editor, false)
        },
        {
          keyCode: VK.DELETE,
          action: MatchKeys.action(InlineFormatDelete.backspaceDelete, editor, true)
        }
      ], evt).each(function (_) {
        evt.preventDefault();
      });
    };
    var executeKeyupOverride = function (editor, evt) {
      MatchKeys.execute([
        {
          keyCode: VK.BACKSPACE,
          action: MatchKeys.action(CefDelete.paddEmptyElement, editor)
        },
        {
          keyCode: VK.DELETE,
          action: MatchKeys.action(CefDelete.paddEmptyElement, editor)
        }
      ], evt);
    };
    var setup$a = function (editor, caret) {
      editor.on('keydown', function (evt) {
        if (evt.isDefaultPrevented() === false) {
          executeKeydownOverride$1(editor, caret, evt);
        }
      });
      editor.on('keyup', function (evt) {
        if (evt.isDefaultPrevented() === false) {
          executeKeyupOverride(editor, evt);
        }
      });
    };
    var DeleteBackspaceKeys = { setup: setup$a };

    var firstNonWhiteSpaceNodeSibling = function (node) {
      while (node) {
        if (node.nodeType === 1 || node.nodeType === 3 && node.data && /[\r\n\s]/.test(node.data)) {
          return node;
        }
        node = node.nextSibling;
      }
    };
    var moveToCaretPosition = function (editor, root) {
      var node, rng, lastNode = root;
      var dom = editor.dom;
      var moveCaretBeforeOnEnterElementsMap = editor.schema.getMoveCaretBeforeOnEnterElements();
      if (!root) {
        return;
      }
      if (/^(LI|DT|DD)$/.test(root.nodeName)) {
        var firstChild = firstNonWhiteSpaceNodeSibling(root.firstChild);
        if (firstChild && /^(UL|OL|DL)$/.test(firstChild.nodeName)) {
          root.insertBefore(dom.doc.createTextNode(nbsp), root.firstChild);
        }
      }
      rng = dom.createRng();
      root.normalize();
      if (root.hasChildNodes()) {
        var walker = new TreeWalker(root, root);
        while (node = walker.current()) {
          if (NodeType.isText(node)) {
            rng.setStart(node, 0);
            rng.setEnd(node, 0);
            break;
          }
          if (moveCaretBeforeOnEnterElementsMap[node.nodeName.toLowerCase()]) {
            rng.setStartBefore(node);
            rng.setEndBefore(node);
            break;
          }
          lastNode = node;
          node = walker.next();
        }
        if (!node) {
          rng.setStart(lastNode, 0);
          rng.setEnd(lastNode, 0);
        }
      } else {
        if (NodeType.isBr(root)) {
          if (root.nextSibling && dom.isBlock(root.nextSibling)) {
            rng.setStartBefore(root);
            rng.setEndBefore(root);
          } else {
            rng.setStartAfter(root);
            rng.setEndAfter(root);
          }
        } else {
          rng.setStart(root, 0);
          rng.setEnd(root, 0);
        }
      }
      editor.selection.setRng(rng);
      ScrollIntoView.scrollRangeIntoView(editor, rng);
    };
    var getEditableRoot = function (dom, node) {
      var root = dom.getRoot();
      var parent, editableRoot;
      parent = node;
      while (parent !== root && dom.getContentEditable(parent) !== 'false') {
        if (dom.getContentEditable(parent) === 'true') {
          editableRoot = parent;
        }
        parent = parent.parentNode;
      }
      return parent !== root ? editableRoot : root;
    };
    var getParentBlock$2 = function (editor) {
      return Option.from(editor.dom.getParent(editor.selection.getStart(true), editor.dom.isBlock));
    };
    var getParentBlockName = function (editor) {
      return getParentBlock$2(editor).fold(constant(''), function (parentBlock) {
        return parentBlock.nodeName.toUpperCase();
      });
    };
    var isListItemParentBlock = function (editor) {
      return getParentBlock$2(editor).filter(function (elm) {
        return isListItem(Element.fromDom(elm));
      }).isSome();
    };
    var NewLineUtils = {
      moveToCaretPosition: moveToCaretPosition,
      getEditableRoot: getEditableRoot,
      getParentBlock: getParentBlock$2,
      getParentBlockName: getParentBlockName,
      isListItemParentBlock: isListItemParentBlock
    };

    var hasFirstChild = function (elm, name) {
      return elm.firstChild && elm.firstChild.nodeName === name;
    };
    var hasParent$1 = function (elm, parentName) {
      return elm && elm.parentNode && elm.parentNode.nodeName === parentName;
    };
    var isListBlock = function (elm) {
      return elm && /^(OL|UL|LI)$/.test(elm.nodeName);
    };
    var isNestedList = function (elm) {
      return isListBlock(elm) && isListBlock(elm.parentNode);
    };
    var getContainerBlock = function (containerBlock) {
      var containerBlockParent = containerBlock.parentNode;
      if (/^(LI|DT|DD)$/.test(containerBlockParent.nodeName)) {
        return containerBlockParent;
      }
      return containerBlock;
    };
    var isFirstOrLastLi = function (containerBlock, parentBlock, first) {
      var node = containerBlock[first ? 'firstChild' : 'lastChild'];
      while (node) {
        if (NodeType.isElement(node)) {
          break;
        }
        node = node[first ? 'nextSibling' : 'previousSibling'];
      }
      return node === parentBlock;
    };
    var insert = function (editor, createNewBlock, containerBlock, parentBlock, newBlockName) {
      var dom = editor.dom;
      var rng = editor.selection.getRng();
      if (containerBlock === editor.getBody()) {
        return;
      }
      if (isNestedList(containerBlock)) {
        newBlockName = 'LI';
      }
      var newBlock = newBlockName ? createNewBlock(newBlockName) : dom.create('BR');
      if (isFirstOrLastLi(containerBlock, parentBlock, true) && isFirstOrLastLi(containerBlock, parentBlock, false)) {
        if (hasParent$1(containerBlock, 'LI')) {
          dom.insertAfter(newBlock, getContainerBlock(containerBlock));
        } else {
          dom.replace(newBlock, containerBlock);
        }
      } else if (isFirstOrLastLi(containerBlock, parentBlock, true)) {
        if (hasParent$1(containerBlock, 'LI')) {
          dom.insertAfter(newBlock, getContainerBlock(containerBlock));
          newBlock.appendChild(dom.doc.createTextNode(' '));
          newBlock.appendChild(containerBlock);
        } else {
          containerBlock.parentNode.insertBefore(newBlock, containerBlock);
        }
      } else if (isFirstOrLastLi(containerBlock, parentBlock, false)) {
        dom.insertAfter(newBlock, getContainerBlock(containerBlock));
      } else {
        containerBlock = getContainerBlock(containerBlock);
        var tmpRng = rng.cloneRange();
        tmpRng.setStartAfter(parentBlock);
        tmpRng.setEndAfter(containerBlock);
        var fragment = tmpRng.extractContents();
        if (newBlockName === 'LI' && hasFirstChild(fragment, 'LI')) {
          newBlock = fragment.firstChild;
          dom.insertAfter(fragment, containerBlock);
        } else {
          dom.insertAfter(fragment, containerBlock);
          dom.insertAfter(newBlock, containerBlock);
        }
      }
      dom.remove(parentBlock);
      NewLineUtils.moveToCaretPosition(editor, newBlock);
    };
    var InsertLi = { insert: insert };

    var trimZwsp = function (fragment) {
      each(descendants(Element.fromDom(fragment), isText), function (text) {
        var rawNode = text.dom();
        rawNode.nodeValue = Zwsp.trim(rawNode.nodeValue);
      });
    };
    var isEmptyAnchor = function (dom, elm) {
      return elm && elm.nodeName === 'A' && dom.isEmpty(elm);
    };
    var isTableCell$4 = function (node) {
      return node && /^(TD|TH|CAPTION)$/.test(node.nodeName);
    };
    var emptyBlock = function (elm) {
      elm.innerHTML = '<br data-mce-bogus="1">';
    };
    var containerAndSiblingName = function (container, nodeName) {
      return container.nodeName === nodeName || container.previousSibling && container.previousSibling.nodeName === nodeName;
    };
    var canSplitBlock = function (dom, node) {
      return node && dom.isBlock(node) && !/^(TD|TH|CAPTION|FORM)$/.test(node.nodeName) && !/^(fixed|absolute)/i.test(node.style.position) && dom.getContentEditable(node) !== 'true';
    };
    var trimInlineElementsOnLeftSideOfBlock = function (dom, nonEmptyElementsMap, block) {
      var node = block;
      var firstChilds = [];
      var i;
      if (!node) {
        return;
      }
      while (node = node.firstChild) {
        if (dom.isBlock(node)) {
          return;
        }
        if (NodeType.isElement(node) && !nonEmptyElementsMap[node.nodeName.toLowerCase()]) {
          firstChilds.push(node);
        }
      }
      i = firstChilds.length;
      while (i--) {
        node = firstChilds[i];
        if (!node.hasChildNodes() || node.firstChild === node.lastChild && node.firstChild.nodeValue === '') {
          dom.remove(node);
        } else {
          if (isEmptyAnchor(dom, node)) {
            dom.remove(node);
          }
        }
      }
    };
    var normalizeZwspOffset = function (start, container, offset) {
      if (NodeType.isText(container) === false) {
        return offset;
      } else if (start) {
        return offset === 1 && container.data.charAt(offset - 1) === Zwsp.ZWSP ? 0 : offset;
      } else {
        return offset === container.data.length - 1 && container.data.charAt(offset) === Zwsp.ZWSP ? container.data.length : offset;
      }
    };
    var includeZwspInRange = function (rng) {
      var newRng = rng.cloneRange();
      newRng.setStart(rng.startContainer, normalizeZwspOffset(true, rng.startContainer, rng.startOffset));
      newRng.setEnd(rng.endContainer, normalizeZwspOffset(false, rng.endContainer, rng.endOffset));
      return newRng;
    };
    var trimLeadingLineBreaks = function (node) {
      do {
        if (NodeType.isText(node)) {
          node.nodeValue = node.nodeValue.replace(/^[\r\n]+/, '');
        }
        node = node.firstChild;
      } while (node);
    };
    var getEditableRoot$1 = function (dom, node) {
      var root = dom.getRoot();
      var parent, editableRoot;
      parent = node;
      while (parent !== root && dom.getContentEditable(parent) !== 'false') {
        if (dom.getContentEditable(parent) === 'true') {
          editableRoot = parent;
        }
        parent = parent.parentNode;
      }
      return parent !== root ? editableRoot : root;
    };
    var setForcedBlockAttrs = function (editor, node) {
      var forcedRootBlockName = Settings.getForcedRootBlock(editor);
      if (forcedRootBlockName && forcedRootBlockName.toLowerCase() === node.tagName.toLowerCase()) {
        editor.dom.setAttribs(node, Settings.getForcedRootBlockAttrs(editor));
      }
    };
    var wrapSelfAndSiblingsInDefaultBlock = function (editor, newBlockName, rng, container, offset) {
      var newBlock, parentBlock, startNode, node, next, rootBlockName;
      var blockName = newBlockName || 'P';
      var dom = editor.dom, editableRoot = getEditableRoot$1(dom, container);
      parentBlock = dom.getParent(container, dom.isBlock);
      if (!parentBlock || !canSplitBlock(dom, parentBlock)) {
        parentBlock = parentBlock || editableRoot;
        if (parentBlock === editor.getBody() || isTableCell$4(parentBlock)) {
          rootBlockName = parentBlock.nodeName.toLowerCase();
        } else {
          rootBlockName = parentBlock.parentNode.nodeName.toLowerCase();
        }
        if (!parentBlock.hasChildNodes()) {
          newBlock = dom.create(blockName);
          setForcedBlockAttrs(editor, newBlock);
          parentBlock.appendChild(newBlock);
          rng.setStart(newBlock, 0);
          rng.setEnd(newBlock, 0);
          return newBlock;
        }
        node = container;
        while (node.parentNode !== parentBlock) {
          node = node.parentNode;
        }
        while (node && !dom.isBlock(node)) {
          startNode = node;
          node = node.previousSibling;
        }
        if (startNode && editor.schema.isValidChild(rootBlockName, blockName.toLowerCase())) {
          newBlock = dom.create(blockName);
          setForcedBlockAttrs(editor, newBlock);
          startNode.parentNode.insertBefore(newBlock, startNode);
          node = startNode;
          while (node && !dom.isBlock(node)) {
            next = node.nextSibling;
            newBlock.appendChild(node);
            node = next;
          }
          rng.setStart(container, offset);
          rng.setEnd(container, offset);
        }
      }
      return container;
    };
    var addBrToBlockIfNeeded = function (dom, block) {
      var lastChild;
      block.normalize();
      lastChild = block.lastChild;
      if (!lastChild || /^(left|right)$/gi.test(dom.getStyle(lastChild, 'float', true))) {
        dom.add(block, 'br');
      }
    };
    var insert$1 = function (editor, evt) {
      var tmpRng, editableRoot, container, offset, parentBlock, shiftKey;
      var newBlock, fragment, containerBlock, parentBlockName, containerBlockName, newBlockName, isAfterLastNodeInContainer;
      var dom = editor.dom;
      var schema = editor.schema, nonEmptyElementsMap = schema.getNonEmptyElements();
      var rng = editor.selection.getRng();
      var createNewBlock = function (name) {
        var node = container, block, clonedNode, caretNode;
        var textInlineElements = schema.getTextInlineElements();
        if (name || parentBlockName === 'TABLE' || parentBlockName === 'HR') {
          block = dom.create(name || newBlockName);
          setForcedBlockAttrs(editor, block);
        } else {
          block = parentBlock.cloneNode(false);
        }
        caretNode = block;
        if (Settings.shouldKeepStyles(editor) === false) {
          dom.setAttrib(block, 'style', null);
          dom.setAttrib(block, 'class', null);
        } else {
          do {
            if (textInlineElements[node.nodeName]) {
              if (isCaretNode(node) || Bookmarks.isBookmarkNode(node)) {
                continue;
              }
              clonedNode = node.cloneNode(false);
              dom.setAttrib(clonedNode, 'id', '');
              if (block.hasChildNodes()) {
                clonedNode.appendChild(block.firstChild);
                block.appendChild(clonedNode);
              } else {
                caretNode = clonedNode;
                block.appendChild(clonedNode);
              }
            }
          } while ((node = node.parentNode) && node !== editableRoot);
        }
        emptyBlock(caretNode);
        return block;
      };
      var isCaretAtStartOrEndOfBlock = function (start) {
        var node, name;
        var normalizedOffset = normalizeZwspOffset(start, container, offset);
        if (NodeType.isText(container) && (start ? normalizedOffset > 0 : normalizedOffset < container.nodeValue.length)) {
          return false;
        }
        if (container.parentNode === parentBlock && isAfterLastNodeInContainer && !start) {
          return true;
        }
        if (start && NodeType.isElement(container) && container === parentBlock.firstChild) {
          return true;
        }
        if (containerAndSiblingName(container, 'TABLE') || containerAndSiblingName(container, 'HR')) {
          return isAfterLastNodeInContainer && !start || !isAfterLastNodeInContainer && start;
        }
        var walker = new TreeWalker(container, parentBlock);
        if (NodeType.isText(container)) {
          if (start && normalizedOffset === 0) {
            walker.prev();
          } else if (!start && normalizedOffset === container.nodeValue.length) {
            walker.next();
          }
        }
        while (node = walker.current()) {
          if (NodeType.isElement(node)) {
            if (!node.getAttribute('data-mce-bogus')) {
              name = node.nodeName.toLowerCase();
              if (nonEmptyElementsMap[name] && name !== 'br') {
                return false;
              }
            }
          } else if (NodeType.isText(node) && !/^[ \t\r\n]*$/.test(node.nodeValue)) {
            return false;
          }
          if (start) {
            walker.prev();
          } else {
            walker.next();
          }
        }
        return true;
      };
      var insertNewBlockAfter = function () {
        if (/^(H[1-6]|PRE|FIGURE)$/.test(parentBlockName) && containerBlockName !== 'HGROUP') {
          newBlock = createNewBlock(newBlockName);
        } else {
          newBlock = createNewBlock();
        }
        if (Settings.shouldEndContainerOnEmptyBlock(editor) && canSplitBlock(dom, containerBlock) && dom.isEmpty(parentBlock)) {
          newBlock = dom.split(containerBlock, parentBlock);
        } else {
          dom.insertAfter(newBlock, parentBlock);
        }
        NewLineUtils.moveToCaretPosition(editor, newBlock);
      };
      NormalizeRange.normalize(dom, rng).each(function (normRng) {
        rng.setStart(normRng.startContainer, normRng.startOffset);
        rng.setEnd(normRng.endContainer, normRng.endOffset);
      });
      container = rng.startContainer;
      offset = rng.startOffset;
      newBlockName = Settings.getForcedRootBlock(editor);
      shiftKey = !!(evt && evt.shiftKey);
      var ctrlKey = !!(evt && evt.ctrlKey);
      if (NodeType.isElement(container) && container.hasChildNodes()) {
        isAfterLastNodeInContainer = offset > container.childNodes.length - 1;
        container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;
        if (isAfterLastNodeInContainer && NodeType.isText(container)) {
          offset = container.nodeValue.length;
        } else {
          offset = 0;
        }
      }
      editableRoot = getEditableRoot$1(dom, container);
      if (!editableRoot) {
        return;
      }
      if (newBlockName && !shiftKey || !newBlockName && shiftKey) {
        container = wrapSelfAndSiblingsInDefaultBlock(editor, newBlockName, rng, container, offset);
      }
      parentBlock = dom.getParent(container, dom.isBlock);
      containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null;
      parentBlockName = parentBlock ? parentBlock.nodeName.toUpperCase() : '';
      containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : '';
      if (containerBlockName === 'LI' && !ctrlKey) {
        parentBlock = containerBlock;
        containerBlock = containerBlock.parentNode;
        parentBlockName = containerBlockName;
      }
      if (/^(LI|DT|DD)$/.test(parentBlockName)) {
        if (dom.isEmpty(parentBlock)) {
          InsertLi.insert(editor, createNewBlock, containerBlock, parentBlock, newBlockName);
          return;
        }
      }
      if (newBlockName && parentBlock === editor.getBody()) {
        return;
      }
      newBlockName = newBlockName || 'P';
      if (isCaretContainerBlock(parentBlock)) {
        newBlock = showCaretContainerBlock(parentBlock);
        if (dom.isEmpty(parentBlock)) {
          emptyBlock(parentBlock);
        }
        NewLineUtils.moveToCaretPosition(editor, newBlock);
      } else if (isCaretAtStartOrEndOfBlock()) {
        insertNewBlockAfter();
      } else if (isCaretAtStartOrEndOfBlock(true)) {
        newBlock = parentBlock.parentNode.insertBefore(createNewBlock(), parentBlock);
        NewLineUtils.moveToCaretPosition(editor, containerAndSiblingName(parentBlock, 'HR') ? newBlock : parentBlock);
      } else {
        tmpRng = includeZwspInRange(rng).cloneRange();
        tmpRng.setEndAfter(parentBlock);
        fragment = tmpRng.extractContents();
        trimZwsp(fragment);
        trimLeadingLineBreaks(fragment);
        newBlock = fragment.firstChild;
        dom.insertAfter(fragment, parentBlock);
        trimInlineElementsOnLeftSideOfBlock(dom, nonEmptyElementsMap, newBlock);
        addBrToBlockIfNeeded(dom, parentBlock);
        if (dom.isEmpty(parentBlock)) {
          emptyBlock(parentBlock);
        }
        newBlock.normalize();
        if (dom.isEmpty(newBlock)) {
          dom.remove(newBlock);
          insertNewBlockAfter();
        } else {
          NewLineUtils.moveToCaretPosition(editor, newBlock);
        }
      }
      dom.setAttrib(newBlock, 'id', '');
      editor.fire('NewBlock', { newBlock: newBlock });
    };
    var InsertBlock = { insert: insert$1 };

    var hasRightSideContent = function (schema, container, parentBlock) {
      var walker = new TreeWalker(container, parentBlock);
      var node;
      var nonEmptyElementsMap = schema.getNonEmptyElements();
      while (node = walker.next()) {
        if (nonEmptyElementsMap[node.nodeName.toLowerCase()] || node.length > 0) {
          return true;
        }
      }
    };
    var scrollToBr = function (dom, selection, brElm) {
      var marker = dom.create('span', {}, '&nbsp;');
      brElm.parentNode.insertBefore(marker, brElm);
      selection.scrollIntoView(marker);
      dom.remove(marker);
    };
    var moveSelectionToBr = function (dom, selection, brElm, extraBr) {
      var rng = dom.createRng();
      if (!extraBr) {
        rng.setStartAfter(brElm);
        rng.setEndAfter(brElm);
      } else {
        rng.setStartBefore(brElm);
        rng.setEndBefore(brElm);
      }
      selection.setRng(rng);
    };
    var insertBrAtCaret = function (editor, evt) {
      var selection = editor.selection;
      var dom = editor.dom;
      var rng = selection.getRng();
      var brElm;
      var extraBr;
      NormalizeRange.normalize(dom, rng).each(function (normRng) {
        rng.setStart(normRng.startContainer, normRng.startOffset);
        rng.setEnd(normRng.endContainer, normRng.endOffset);
      });
      var offset = rng.startOffset;
      var container = rng.startContainer;
      if (container.nodeType === 1 && container.hasChildNodes()) {
        var isAfterLastNodeInContainer = offset > container.childNodes.length - 1;
        container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;
        if (isAfterLastNodeInContainer && container.nodeType === 3) {
          offset = container.nodeValue.length;
        } else {
          offset = 0;
        }
      }
      var parentBlock = dom.getParent(container, dom.isBlock);
      var containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null;
      var containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : '';
      var isControlKey = !!(evt && evt.ctrlKey);
      if (containerBlockName === 'LI' && !isControlKey) {
        parentBlock = containerBlock;
      }
      if (container && container.nodeType === 3 && offset >= container.nodeValue.length) {
        if (!hasRightSideContent(editor.schema, container, parentBlock)) {
          brElm = dom.create('br');
          rng.insertNode(brElm);
          rng.setStartAfter(brElm);
          rng.setEndAfter(brElm);
          extraBr = true;
        }
      }
      brElm = dom.create('br');
      rangeInsertNode(dom, rng, brElm);
      scrollToBr(dom, selection, brElm);
      moveSelectionToBr(dom, selection, brElm, extraBr);
      editor.undoManager.add();
    };
    var insertBrBefore = function (editor, inline) {
      var br = Element.fromTag('br');
      before(Element.fromDom(inline), br);
      editor.undoManager.add();
    };
    var insertBrAfter = function (editor, inline) {
      if (!hasBrAfter(editor.getBody(), inline)) {
        after(Element.fromDom(inline), Element.fromTag('br'));
      }
      var br = Element.fromTag('br');
      after(Element.fromDom(inline), br);
      scrollToBr(editor.dom, editor.selection, br.dom());
      moveSelectionToBr(editor.dom, editor.selection, br.dom(), false);
      editor.undoManager.add();
    };
    var isBeforeBr$1 = function (pos) {
      return NodeType.isBr(pos.getNode());
    };
    var hasBrAfter = function (rootNode, startNode) {
      if (isBeforeBr$1(CaretPosition$1.after(startNode))) {
        return true;
      } else {
        return CaretFinder.nextPosition(rootNode, CaretPosition$1.after(startNode)).map(function (pos) {
          return NodeType.isBr(pos.getNode());
        }).getOr(false);
      }
    };
    var isAnchorLink = function (elm) {
      return elm && elm.nodeName === 'A' && 'href' in elm;
    };
    var isInsideAnchor = function (location) {
      return location.fold(constant(false), isAnchorLink, isAnchorLink, constant(false));
    };
    var readInlineAnchorLocation = function (editor) {
      var isInlineTarget = curry(InlineUtils.isInlineTarget, editor);
      var position = CaretPosition$1.fromRangeStart(editor.selection.getRng());
      return BoundaryLocation.readLocation(isInlineTarget, editor.getBody(), position).filter(isInsideAnchor);
    };
    var insertBrOutsideAnchor = function (editor, location) {
      location.fold(noop, curry(insertBrBefore, editor), curry(insertBrAfter, editor), noop);
    };
    var insert$2 = function (editor, evt) {
      var anchorLocation = readInlineAnchorLocation(editor);
      if (anchorLocation.isSome()) {
        anchorLocation.each(curry(insertBrOutsideAnchor, editor));
      } else {
        insertBrAtCaret(editor, evt);
      }
    };
    var InsertBr = { insert: insert$2 };

    var matchesSelector = function (editor, selector) {
      return NewLineUtils.getParentBlock(editor).filter(function (parentBlock) {
        return selector.length > 0 && is(Element.fromDom(parentBlock), selector);
      }).isSome();
    };
    var shouldInsertBr = function (editor) {
      return matchesSelector(editor, Settings.getBrNewLineSelector(editor));
    };
    var shouldBlockNewLine = function (editor) {
      return matchesSelector(editor, Settings.getNoNewLineSelector(editor));
    };
    var ContextSelectors = {
      shouldInsertBr: shouldInsertBr,
      shouldBlockNewLine: shouldBlockNewLine
    };

    var newLineAction = Adt.generate([
      { br: [] },
      { block: [] },
      { none: [] }
    ]);
    var shouldBlockNewLine$1 = function (editor, shiftKey) {
      return ContextSelectors.shouldBlockNewLine(editor);
    };
    var isBrMode = function (requiredState) {
      return function (editor, shiftKey) {
        var brMode = Settings.getForcedRootBlock(editor) === '';
        return brMode === requiredState;
      };
    };
    var inListBlock = function (requiredState) {
      return function (editor, shiftKey) {
        return NewLineUtils.isListItemParentBlock(editor) === requiredState;
      };
    };
    var inBlock = function (blockName, requiredState) {
      return function (editor, shiftKey) {
        var state = NewLineUtils.getParentBlockName(editor) === blockName.toUpperCase();
        return state === requiredState;
      };
    };
    var inPreBlock = function (requiredState) {
      return inBlock('pre', requiredState);
    };
    var inSummaryBlock = function () {
      return inBlock('summary', true);
    };
    var shouldPutBrInPre$1 = function (requiredState) {
      return function (editor, shiftKey) {
        return Settings.shouldPutBrInPre(editor) === requiredState;
      };
    };
    var inBrContext = function (editor, shiftKey) {
      return ContextSelectors.shouldInsertBr(editor);
    };
    var hasShiftKey = function (editor, shiftKey) {
      return shiftKey;
    };
    var canInsertIntoEditableRoot = function (editor) {
      var forcedRootBlock = Settings.getForcedRootBlock(editor);
      var rootEditable = NewLineUtils.getEditableRoot(editor.dom, editor.selection.getStart());
      return rootEditable && editor.schema.isValidChild(rootEditable.nodeName, forcedRootBlock ? forcedRootBlock : 'P');
    };
    var match$2 = function (predicates, action) {
      return function (editor, shiftKey) {
        var isMatch = foldl(predicates, function (res, p) {
          return res && p(editor, shiftKey);
        }, true);
        return isMatch ? Option.some(action) : Option.none();
      };
    };
    var getAction$1 = function (editor, evt) {
      return LazyEvaluator.evaluateUntil([
        match$2([shouldBlockNewLine$1], newLineAction.none()),
        match$2([inSummaryBlock()], newLineAction.br()),
        match$2([
          inPreBlock(true),
          shouldPutBrInPre$1(false),
          hasShiftKey
        ], newLineAction.br()),
        match$2([
          inPreBlock(true),
          shouldPutBrInPre$1(false)
        ], newLineAction.block()),
        match$2([
          inPreBlock(true),
          shouldPutBrInPre$1(true),
          hasShiftKey
        ], newLineAction.block()),
        match$2([
          inPreBlock(true),
          shouldPutBrInPre$1(true)
        ], newLineAction.br()),
        match$2([
          inListBlock(true),
          hasShiftKey
        ], newLineAction.br()),
        match$2([inListBlock(true)], newLineAction.block()),
        match$2([
          isBrMode(true),
          hasShiftKey,
          canInsertIntoEditableRoot
        ], newLineAction.block()),
        match$2([isBrMode(true)], newLineAction.br()),
        match$2([inBrContext], newLineAction.br()),
        match$2([
          isBrMode(false),
          hasShiftKey
        ], newLineAction.br()),
        match$2([canInsertIntoEditableRoot], newLineAction.block())
      ], [
        editor,
        !!(evt && evt.shiftKey)
      ]).getOr(newLineAction.none());
    };
    var NewLineAction = { getAction: getAction$1 };

    var insert$3 = function (editor, evt) {
      NewLineAction.getAction(editor, evt).fold(function () {
        InsertBr.insert(editor, evt);
      }, function () {
        InsertBlock.insert(editor, evt);
      }, noop);
    };
    var InsertNewLine = { insert: insert$3 };

    var handleEnterKeyEvent = function (editor, event) {
      if (event.isDefaultPrevented()) {
        return;
      }
      event.preventDefault();
      endTypingLevelIgnoreLocks(editor.undoManager);
      editor.undoManager.transact(function () {
        if (editor.selection.isCollapsed() === false) {
          editor.execCommand('Delete');
        }
        InsertNewLine.insert(editor, event);
      });
    };
    var setup$b = function (editor) {
      editor.on('keydown', function (event) {
        if (event.keyCode === VK.ENTER) {
          handleEnterKeyEvent(editor, event);
        }
      });
    };
    var EnterKey = { setup: setup$b };

    var insertTextAtPosition = function (text, pos) {
      var container = pos.container();
      var offset = pos.offset();
      if (NodeType.isText(container)) {
        container.insertData(offset, text);
        return Option.some(CaretPosition(container, offset + text.length));
      } else {
        return getElementFromPosition(pos).map(function (elm) {
          var textNode = Element.fromText(text);
          if (pos.isAtEnd()) {
            after(elm, textNode);
          } else {
            before(elm, textNode);
          }
          return CaretPosition(textNode.dom(), text.length);
        });
      }
    };
    var insertNbspAtPosition = curry(insertTextAtPosition, nbsp);
    var insertSpaceAtPosition = curry(insertTextAtPosition, ' ');

    var isInMiddleOfText = function (pos) {
      return CaretPosition.isTextPosition(pos) && !pos.isAtStart() && !pos.isAtEnd();
    };
    var getClosestBlock$1 = function (root, pos) {
      var parentBlocks = filter(Parents.parentsAndSelf(Element.fromDom(pos.container()), root), isBlock);
      return head(parentBlocks).getOr(root);
    };
    var hasSpaceBefore = function (root, pos) {
      if (isInMiddleOfText(pos)) {
        return isAfterSpace(pos);
      } else {
        return isAfterSpace(pos) || CaretFinder.prevPosition(getClosestBlock$1(root, pos).dom(), pos).exists(isAfterSpace);
      }
    };
    var hasSpaceAfter = function (root, pos) {
      if (isInMiddleOfText(pos)) {
        return isBeforeSpace(pos);
      } else {
        return isBeforeSpace(pos) || CaretFinder.nextPosition(getClosestBlock$1(root, pos).dom(), pos).exists(isBeforeSpace);
      }
    };
    var isPreValue = function (value) {
      return contains([
        'pre',
        'pre-wrap'
      ], value);
    };
    var isInPre = function (pos) {
      return getElementFromPosition(pos).bind(function (elm) {
        return closest(elm, isElement);
      }).exists(function (elm) {
        return isPreValue(get$4(elm, 'white-space'));
      });
    };
    var isAtBeginningOfBody = function (root, pos) {
      return CaretFinder.prevPosition(root.dom(), pos).isNone();
    };
    var isAtEndOfBody = function (root, pos) {
      return CaretFinder.nextPosition(root.dom(), pos).isNone();
    };
    var isAtLineBoundary = function (root, pos) {
      return isAtBeginningOfBody(root, pos) || isAtEndOfBody(root, pos) || isAtStartOfBlock(root, pos) || isAtEndOfBlock(root, pos) || isAfterBr(root, pos) || isBeforeBr(root, pos);
    };
    var needsToHaveNbsp = function (root, pos) {
      if (isInPre(pos)) {
        return false;
      } else {
        return isAtLineBoundary(root, pos) || hasSpaceBefore(root, pos) || hasSpaceAfter(root, pos);
      }
    };
    var needsToBeNbspLeft = function (root, pos) {
      if (isInPre(pos)) {
        return false;
      } else {
        return isAtStartOfBlock(root, pos) || isBeforeBlock(root, pos) || isAfterBr(root, pos) || hasSpaceBefore(root, pos);
      }
    };
    var leanRight = function (pos) {
      var container = pos.container();
      var offset = pos.offset();
      if (NodeType.isText(container) && offset < container.data.length) {
        return CaretPosition(container, offset + 1);
      } else {
        return pos;
      }
    };
    var needsToBeNbspRight = function (root, pos) {
      var afterPos = leanRight(pos);
      if (isInPre(afterPos)) {
        return false;
      } else {
        return isAtEndOfBlock(root, afterPos) || isAfterBlock(root, afterPos) || isBeforeBr(root, afterPos) || hasSpaceAfter(root, afterPos);
      }
    };
    var needsToBeNbsp = function (root, pos) {
      return needsToBeNbspLeft(root, pos) || needsToBeNbspRight(root, pos);
    };
    var isNbspAt = function (text, offset) {
      return isNbsp(text.charAt(offset));
    };
    var hasNbsp = function (pos) {
      var container = pos.container();
      return NodeType.isText(container) && contains$1(container.data, nbsp);
    };
    var normalizeNbspMiddle = function (text) {
      var chars = text.split('');
      return map(chars, function (chr, i) {
        if (isNbsp(chr) && i > 0 && i < chars.length - 1 && isContent(chars[i - 1]) && isContent(chars[i + 1])) {
          return ' ';
        } else {
          return chr;
        }
      }).join('');
    };
    var normalizeNbspAtStart = function (root, node) {
      var text = node.data;
      var firstPos = CaretPosition(node, 0);
      if (isNbspAt(text, 0) && !needsToBeNbsp(root, firstPos)) {
        node.data = ' ' + text.slice(1);
        return true;
      } else {
        return false;
      }
    };
    var normalizeNbspInMiddleOfTextNode = function (node) {
      var text = node.data;
      var newText = normalizeNbspMiddle(text);
      if (newText !== text) {
        node.data = newText;
        return true;
      } else {
        return false;
      }
    };
    var normalizeNbspAtEnd = function (root, node) {
      var text = node.data;
      var lastPos = CaretPosition(node, text.length - 1);
      if (isNbspAt(text, text.length - 1) && !needsToBeNbsp(root, lastPos)) {
        node.data = text.slice(0, -1) + ' ';
        return true;
      } else {
        return false;
      }
    };
    var normalizeNbsps = function (root, pos) {
      return Option.some(pos).filter(hasNbsp).bind(function (pos) {
        var container = pos.container();
        var normalized = normalizeNbspAtStart(root, container) || normalizeNbspInMiddleOfTextNode(container) || normalizeNbspAtEnd(root, container);
        return normalized ? Option.some(pos) : Option.none();
      });
    };
    var normalizeNbspsInEditor = function (editor) {
      var root = Element.fromDom(editor.getBody());
      if (editor.selection.isCollapsed()) {
        normalizeNbsps(root, CaretPosition.fromRangeStart(editor.selection.getRng())).each(function (pos) {
          editor.selection.setRng(pos.toRange());
        });
      }
    };

    var locationToCaretPosition = function (root) {
      return function (location) {
        return location.fold(function (element) {
          return CaretFinder.prevPosition(root.dom(), CaretPosition$1.before(element));
        }, function (element) {
          return CaretFinder.firstPositionIn(element);
        }, function (element) {
          return CaretFinder.lastPositionIn(element);
        }, function (element) {
          return CaretFinder.nextPosition(root.dom(), CaretPosition$1.after(element));
        });
      };
    };
    var insertInlineBoundarySpaceOrNbsp = function (root, pos) {
      return function (checkPos) {
        return needsToHaveNbsp(root, checkPos) ? insertNbspAtPosition(pos) : insertSpaceAtPosition(pos);
      };
    };
    var setSelection$1 = function (editor) {
      return function (pos) {
        editor.selection.setRng(pos.toRange());
        editor.nodeChanged();
        return true;
      };
    };
    var insertSpaceOrNbspAtSelection = function (editor) {
      var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
      var root = Element.fromDom(editor.getBody());
      if (editor.selection.isCollapsed()) {
        var isInlineTarget = curry(InlineUtils.isInlineTarget, editor);
        var caretPosition = CaretPosition$1.fromRangeStart(editor.selection.getRng());
        return BoundaryLocation.readLocation(isInlineTarget, editor.getBody(), caretPosition).bind(locationToCaretPosition(root)).bind(insertInlineBoundarySpaceOrNbsp(root, pos)).exists(setSelection$1(editor));
      } else {
        return false;
      }
    };

    var executeKeydownOverride$2 = function (editor, evt) {
      MatchKeys.execute([{
          keyCode: VK.SPACEBAR,
          action: MatchKeys.action(insertSpaceOrNbspAtSelection, editor)
        }], evt).each(function (_) {
        evt.preventDefault();
      });
    };
    var setup$c = function (editor) {
      editor.on('keydown', function (evt) {
        if (evt.isDefaultPrevented() === false) {
          executeKeydownOverride$2(editor, evt);
        }
      });
    };
    var SpaceKey = { setup: setup$c };

    var findBlockCaretContainer = function (editor) {
      return descendant(Element.fromDom(editor.getBody()), '*[data-mce-caret]').fold(constant(null), function (elm) {
        return elm.dom();
      });
    };
    var removeIeControlRect = function (editor) {
      editor.selection.setRng(editor.selection.getRng());
    };
    var showBlockCaretContainer = function (editor, blockCaretContainer) {
      if (blockCaretContainer.hasAttribute('data-mce-caret')) {
        showCaretContainerBlock(blockCaretContainer);
        removeIeControlRect(editor);
        editor.selection.scrollIntoView(blockCaretContainer);
      }
    };
    var handleBlockContainer = function (editor, e) {
      var blockCaretContainer = findBlockCaretContainer(editor);
      if (!blockCaretContainer) {
        return;
      }
      if (e.type === 'compositionstart') {
        e.preventDefault();
        e.stopPropagation();
        showBlockCaretContainer(editor, blockCaretContainer);
        return;
      }
      if (hasContent(blockCaretContainer)) {
        showBlockCaretContainer(editor, blockCaretContainer);
        editor.undoManager.add();
      }
    };
    var setup$d = function (editor) {
      editor.on('keyup compositionstart', curry(handleBlockContainer, editor));
    };
    var CaretContainerInput = { setup: setup$d };

    var browser$5 = detect$3().browser;
    var setupIeInput = function (editor) {
      var keypressThrotter = first(function () {
        if (!editor.composing) {
          normalizeNbspsInEditor(editor);
        }
      }, 0);
      if (browser$5.isIE()) {
        editor.on('keypress', function (e) {
          keypressThrotter.throttle();
        });
        editor.on('remove', function (e) {
          keypressThrotter.cancel();
        });
      }
    };
    var setup$e = function (editor) {
      setupIeInput(editor);
      editor.on('input', function (e) {
        if (e.isComposing === false) {
          normalizeNbspsInEditor(editor);
        }
      });
    };

    var executeKeydownOverride$3 = function (editor, evt) {
      MatchKeys.execute([
        {
          keyCode: VK.END,
          action: moveToLineEndPoint(editor, true)
        },
        {
          keyCode: VK.HOME,
          action: moveToLineEndPoint(editor, false)
        }
      ], evt).each(function (_) {
        evt.preventDefault();
      });
    };
    var setup$f = function (editor) {
      editor.on('keydown', function (evt) {
        if (evt.isDefaultPrevented() === false) {
          executeKeydownOverride$3(editor, evt);
        }
      });
    };
    var HomeEndKeys = { setup: setup$f };

    var setup$g = function (editor) {
      var caret = BoundarySelection.setupSelectedState(editor);
      CaretContainerInput.setup(editor);
      ArrowKeys.setup(editor, caret);
      DeleteBackspaceKeys.setup(editor, caret);
      EnterKey.setup(editor);
      SpaceKey.setup(editor);
      setup$e(editor);
      HomeEndKeys.setup(editor);
    };
    var KeyboardOverrides = { setup: setup$g };

    var NodeChange = function () {
      function NodeChange(editor) {
        this.lastPath = [];
        this.editor = editor;
        var lastRng;
        var self = this;
        if (!('onselectionchange' in editor.getDoc())) {
          editor.on('NodeChange click mouseup keyup focus', function (e) {
            var nativeRng, fakeRng;
            nativeRng = editor.selection.getRng();
            fakeRng = {
              startContainer: nativeRng.startContainer,
              startOffset: nativeRng.startOffset,
              endContainer: nativeRng.endContainer,
              endOffset: nativeRng.endOffset
            };
            if (e.type === 'nodechange' || !RangeCompare.isEq(fakeRng, lastRng)) {
              editor.fire('SelectionChange');
            }
            lastRng = fakeRng;
          });
        }
        editor.on('contextmenu', function () {
          editor.fire('SelectionChange');
        });
        editor.on('SelectionChange', function () {
          var startElm = editor.selection.getStart(true);
          if (!startElm || !Env.range && editor.selection.isCollapsed()) {
            return;
          }
          if (hasAnyRanges(editor) && !self.isSameElementPath(startElm) && editor.dom.isChildOf(startElm, editor.getBody())) {
            editor.nodeChanged({ selectionChange: true });
          }
        });
        editor.on('mouseup', function (e) {
          if (!e.isDefaultPrevented() && hasAnyRanges(editor)) {
            if (editor.selection.getNode().nodeName === 'IMG') {
              Delay.setEditorTimeout(editor, function () {
                editor.nodeChanged();
              });
            } else {
              editor.nodeChanged();
            }
          }
        });
      }
      NodeChange.prototype.nodeChanged = function (args) {
        var selection = this.editor.selection;
        var node, parents, root;
        if (this.editor.initialized && selection && !this.editor.settings.disable_nodechange && !this.editor.readonly) {
          root = this.editor.getBody();
          node = selection.getStart(true) || root;
          if (node.ownerDocument !== this.editor.getDoc() || !this.editor.dom.isChildOf(node, root)) {
            node = root;
          }
          parents = [];
          this.editor.dom.getParent(node, function (node) {
            if (node === root) {
              return true;
            }
            parents.push(node);
          });
          args = args || {};
          args.element = node;
          args.parents = parents;
          this.editor.fire('NodeChange', args);
        }
      };
      NodeChange.prototype.isSameElementPath = function (startElm) {
        var i, currentPath;
        currentPath = this.editor.$(startElm).parentsUntil(this.editor.getBody()).add(startElm);
        if (currentPath.length === this.lastPath.length) {
          for (i = currentPath.length; i >= 0; i--) {
            if (currentPath[i] !== this.lastPath[i]) {
              break;
            }
          }
          if (i === -1) {
            this.lastPath = currentPath;
            return true;
          }
        }
        this.lastPath = currentPath;
        return false;
      };
      return NodeChange;
    }();

    var preventSummaryToggle = function (editor) {
      editor.on('click', function (e) {
        if (editor.dom.getParent(e.target, 'details')) {
          e.preventDefault();
        }
      });
    };
    var filterDetails = function (editor) {
      editor.parser.addNodeFilter('details', function (elms) {
        each(elms, function (details) {
          details.attr('data-mce-open', details.attr('open'));
          details.attr('open', 'open');
        });
      });
      editor.serializer.addNodeFilter('details', function (elms) {
        each(elms, function (details) {
          var open = details.attr('data-mce-open');
          details.attr('open', isString(open) ? open : null);
          details.attr('data-mce-open', null);
        });
      });
    };
    var setup$h = function (editor) {
      preventSummaryToggle(editor);
      filterDetails(editor);
    };

    var isTextBlockNode = function (node) {
      return NodeType.isElement(node) && isTextBlock(Element.fromDom(node));
    };
    var normalizeSelection$1 = function (editor) {
      var rng = editor.selection.getRng();
      var startPos = CaretPosition.fromRangeStart(rng);
      var endPos = CaretPosition.fromRangeEnd(rng);
      if (CaretPosition.isElementPosition(startPos)) {
        var container = startPos.container();
        if (isTextBlockNode(container)) {
          CaretFinder.firstPositionIn(container).each(function (pos) {
            return rng.setStart(pos.container(), pos.offset());
          });
        }
      }
      if (CaretPosition.isElementPosition(endPos)) {
        var container = startPos.container();
        if (isTextBlockNode(container)) {
          CaretFinder.lastPositionIn(container).each(function (pos) {
            return rng.setEnd(pos.container(), pos.offset());
          });
        }
      }
      editor.selection.setRng(RangeNormalizer.normalize(rng));
    };
    var setup$i = function (editor) {
      editor.on('click', function (e) {
        if (e.detail >= 3) {
          normalizeSelection$1(editor);
        }
      });
    };

    var getAbsolutePosition = function (elm) {
      var doc, docElem, win, clientRect;
      clientRect = elm.getBoundingClientRect();
      doc = elm.ownerDocument;
      docElem = doc.documentElement;
      win = doc.defaultView;
      return {
        top: clientRect.top + win.pageYOffset - docElem.clientTop,
        left: clientRect.left + win.pageXOffset - docElem.clientLeft
      };
    };
    var getBodyPosition = function (editor) {
      return editor.inline ? getAbsolutePosition(editor.getBody()) : {
        left: 0,
        top: 0
      };
    };
    var getScrollPosition = function (editor) {
      var body = editor.getBody();
      return editor.inline ? {
        left: body.scrollLeft,
        top: body.scrollTop
      } : {
        left: 0,
        top: 0
      };
    };
    var getBodyScroll = function (editor) {
      var body = editor.getBody(), docElm = editor.getDoc().documentElement;
      var inlineScroll = {
        left: body.scrollLeft,
        top: body.scrollTop
      };
      var iframeScroll = {
        left: body.scrollLeft || docElm.scrollLeft,
        top: body.scrollTop || docElm.scrollTop
      };
      return editor.inline ? inlineScroll : iframeScroll;
    };
    var getMousePosition = function (editor, event) {
      if (event.target.ownerDocument !== editor.getDoc()) {
        var iframePosition = getAbsolutePosition(editor.getContentAreaContainer());
        var scrollPosition = getBodyScroll(editor);
        return {
          left: event.pageX - iframePosition.left + scrollPosition.left,
          top: event.pageY - iframePosition.top + scrollPosition.top
        };
      }
      return {
        left: event.pageX,
        top: event.pageY
      };
    };
    var calculatePosition = function (bodyPosition, scrollPosition, mousePosition) {
      return {
        pageX: mousePosition.left - bodyPosition.left + scrollPosition.left,
        pageY: mousePosition.top - bodyPosition.top + scrollPosition.top
      };
    };
    var calc = function (editor, event) {
      return calculatePosition(getBodyPosition(editor), getScrollPosition(editor), getMousePosition(editor, event));
    };
    var MousePosition = { calc: calc };

    var isContentEditableFalse$a = NodeType.isContentEditableFalse, isContentEditableTrue$4 = NodeType.isContentEditableTrue;
    var isDraggable = function (rootElm, elm) {
      return isContentEditableFalse$a(elm) && elm !== rootElm;
    };
    var isValidDropTarget = function (editor, targetElement, dragElement) {
      if (targetElement === dragElement || editor.dom.isChildOf(targetElement, dragElement)) {
        return false;
      }
      return !isContentEditableFalse$a(targetElement);
    };
    var cloneElement = function (elm) {
      var cloneElm = elm.cloneNode(true);
      cloneElm.removeAttribute('data-mce-selected');
      return cloneElm;
    };
    var createGhost = function (editor, elm, width, height) {
      var clonedElm = elm.cloneNode(true);
      editor.dom.setStyles(clonedElm, {
        width: width,
        height: height
      });
      editor.dom.setAttrib(clonedElm, 'data-mce-selected', null);
      var ghostElm = editor.dom.create('div', {
        'class': 'mce-drag-container',
        'data-mce-bogus': 'all',
        'unselectable': 'on',
        'contenteditable': 'false'
      });
      editor.dom.setStyles(ghostElm, {
        position: 'absolute',
        opacity: 0.5,
        overflow: 'hidden',
        border: 0,
        padding: 0,
        margin: 0,
        width: width,
        height: height
      });
      editor.dom.setStyles(clonedElm, {
        margin: 0,
        boxSizing: 'border-box'
      });
      ghostElm.appendChild(clonedElm);
      return ghostElm;
    };
    var appendGhostToBody = function (ghostElm, bodyElm) {
      if (ghostElm.parentNode !== bodyElm) {
        bodyElm.appendChild(ghostElm);
      }
    };
    var moveGhost = function (ghostElm, position, width, height, maxX, maxY) {
      var overflowX = 0, overflowY = 0;
      ghostElm.style.left = position.pageX + 'px';
      ghostElm.style.top = position.pageY + 'px';
      if (position.pageX + width > maxX) {
        overflowX = position.pageX + width - maxX;
      }
      if (position.pageY + height > maxY) {
        overflowY = position.pageY + height - maxY;
      }
      ghostElm.style.width = width - overflowX + 'px';
      ghostElm.style.height = height - overflowY + 'px';
    };
    var removeElement = function (elm) {
      if (elm && elm.parentNode) {
        elm.parentNode.removeChild(elm);
      }
    };
    var isLeftMouseButtonPressed = function (e) {
      return e.button === 0;
    };
    var hasDraggableElement = function (state) {
      return state.element;
    };
    var applyRelPos = function (state, position) {
      return {
        pageX: position.pageX - state.relX,
        pageY: position.pageY + 5
      };
    };
    var start$1 = function (state, editor) {
      return function (e) {
        if (isLeftMouseButtonPressed(e)) {
          var ceElm = find(editor.dom.getParents(e.target), Predicate.or(isContentEditableFalse$a, isContentEditableTrue$4)).getOr(null);
          if (isDraggable(editor.getBody(), ceElm)) {
            var elmPos = editor.dom.getPos(ceElm);
            var bodyElm = editor.getBody();
            var docElm = editor.getDoc().documentElement;
            state.element = ceElm;
            state.screenX = e.screenX;
            state.screenY = e.screenY;
            state.maxX = (editor.inline ? bodyElm.scrollWidth : docElm.offsetWidth) - 2;
            state.maxY = (editor.inline ? bodyElm.scrollHeight : docElm.offsetHeight) - 2;
            state.relX = e.pageX - elmPos.x;
            state.relY = e.pageY - elmPos.y;
            state.width = ceElm.offsetWidth;
            state.height = ceElm.offsetHeight;
            state.ghost = createGhost(editor, ceElm, state.width, state.height);
          }
        }
      };
    };
    var move$1 = function (state, editor) {
      var throttledPlaceCaretAt = Delay.throttle(function (clientX, clientY) {
        editor._selectionOverrides.hideFakeCaret();
        editor.selection.placeCaretAt(clientX, clientY);
      }, 0);
      return function (e) {
        var movement = Math.max(Math.abs(e.screenX - state.screenX), Math.abs(e.screenY - state.screenY));
        if (hasDraggableElement(state) && !state.dragging && movement > 10) {
          var args = editor.fire('dragstart', { target: state.element });
          if (args.isDefaultPrevented()) {
            return;
          }
          state.dragging = true;
          editor.focus();
        }
        if (state.dragging) {
          var targetPos = applyRelPos(state, MousePosition.calc(editor, e));
          appendGhostToBody(state.ghost, editor.getBody());
          moveGhost(state.ghost, targetPos, state.width, state.height, state.maxX, state.maxY);
          throttledPlaceCaretAt(e.clientX, e.clientY);
        }
      };
    };
    var getRawTarget = function (selection) {
      var rng = selection.getSel().getRangeAt(0);
      var startContainer = rng.startContainer;
      return startContainer.nodeType === 3 ? startContainer.parentNode : startContainer;
    };
    var drop = function (state, editor) {
      return function (e) {
        if (state.dragging) {
          if (isValidDropTarget(editor, getRawTarget(editor.selection), state.element)) {
            var targetClone_1 = cloneElement(state.element);
            var args = editor.fire('drop', {
              targetClone: targetClone_1,
              clientX: e.clientX,
              clientY: e.clientY
            });
            if (!args.isDefaultPrevented()) {
              targetClone_1 = args.targetClone;
              editor.undoManager.transact(function () {
                removeElement(state.element);
                editor.insertContent(editor.dom.getOuterHTML(targetClone_1));
                editor._selectionOverrides.hideFakeCaret();
              });
            }
          }
        }
        removeDragState(state);
      };
    };
    var stop = function (state, editor) {
      return function () {
        if (state.dragging) {
          editor.fire('dragend');
        }
        removeDragState(state);
      };
    };
    var removeDragState = function (state) {
      state.dragging = false;
      state.element = null;
      removeElement(state.ghost);
    };
    var bindFakeDragEvents = function (editor) {
      var state = {};
      var pageDom, dragStartHandler, dragHandler, dropHandler, dragEndHandler, rootDocument;
      pageDom = DOMUtils$1.DOM;
      rootDocument = domGlobals.document;
      dragStartHandler = start$1(state, editor);
      dragHandler = move$1(state, editor);
      dropHandler = drop(state, editor);
      dragEndHandler = stop(state, editor);
      editor.on('mousedown', dragStartHandler);
      editor.on('mousemove', dragHandler);
      editor.on('mouseup', dropHandler);
      pageDom.bind(rootDocument, 'mousemove', dragHandler);
      pageDom.bind(rootDocument, 'mouseup', dragEndHandler);
      editor.on('remove', function () {
        pageDom.unbind(rootDocument, 'mousemove', dragHandler);
        pageDom.unbind(rootDocument, 'mouseup', dragEndHandler);
      });
    };
    var blockIeDrop = function (editor) {
      editor.on('drop', function (e) {
        var realTarget = typeof e.clientX !== 'undefined' ? editor.getDoc().elementFromPoint(e.clientX, e.clientY) : null;
        if (isContentEditableFalse$a(realTarget) || isContentEditableFalse$a(editor.dom.getContentEditableParent(realTarget))) {
          e.preventDefault();
        }
      });
    };
    var init = function (editor) {
      bindFakeDragEvents(editor);
      blockIeDrop(editor);
    };
    var DragDropOverrides = { init: init };

    var setup$j = function (editor) {
      var renderFocusCaret = first(function () {
        if (!editor.removed && editor.getBody().contains(domGlobals.document.activeElement)) {
          var rng = editor.selection.getRng();
          if (rng.collapsed) {
            var caretRange = renderRangeCaret(editor, editor.selection.getRng(), false);
            editor.selection.setRng(caretRange);
          }
        }
      }, 0);
      editor.on('focus', function () {
        renderFocusCaret.throttle();
      });
      editor.on('blur', function () {
        renderFocusCaret.cancel();
      });
    };
    var CefFocus = { setup: setup$j };

    var isContentEditableTrue$5 = NodeType.isContentEditableTrue;
    var isContentEditableFalse$b = NodeType.isContentEditableFalse;
    var getContentEditableRoot$2 = function (editor, node) {
      var root = editor.getBody();
      while (node && node !== root) {
        if (isContentEditableTrue$5(node) || isContentEditableFalse$b(node)) {
          return node;
        }
        node = node.parentNode;
      }
      return null;
    };
    var SelectionOverrides = function (editor) {
      var isBlock = function (node) {
        return editor.dom.isBlock(node);
      };
      var rootNode = editor.getBody();
      var fakeCaret = FakeCaret(editor, rootNode, isBlock, function () {
        return EditorFocus.hasFocus(editor);
      });
      var realSelectionId = 'sel-' + editor.dom.uniqueId();
      var selectedContentEditableNode;
      var isFakeSelectionElement = function (elm) {
        return editor.dom.hasClass(elm, 'mce-offscreen-selection');
      };
      var getRealSelectionElement = function () {
        var container = editor.dom.get(realSelectionId);
        return container ? container.getElementsByTagName('*')[0] : container;
      };
      var setRange = function (range) {
        if (range) {
          editor.selection.setRng(range);
        }
      };
      var getRange = function () {
        return editor.selection.getRng();
      };
      var showCaret = function (direction, node, before, scrollIntoView) {
        if (scrollIntoView === void 0) {
          scrollIntoView = true;
        }
        var e;
        e = editor.fire('ShowCaret', {
          target: node,
          direction: direction,
          before: before
        });
        if (e.isDefaultPrevented()) {
          return null;
        }
        if (scrollIntoView) {
          editor.selection.scrollIntoView(node, direction === -1);
        }
        return fakeCaret.show(before, node);
      };
      var showBlockCaretContainer = function (blockCaretContainer) {
        if (blockCaretContainer.hasAttribute('data-mce-caret')) {
          showCaretContainerBlock(blockCaretContainer);
          setRange(getRange());
          editor.selection.scrollIntoView(blockCaretContainer);
        }
      };
      var registerEvents = function () {
        editor.on('mouseup', function (e) {
          var range = getRange();
          if (range.collapsed && EditorView.isXYInContentArea(editor, e.clientX, e.clientY)) {
            setRange(renderCaretAtRange(editor, range, false));
          }
        });
        editor.on('click', function (e) {
          var contentEditableRoot;
          contentEditableRoot = getContentEditableRoot$2(editor, e.target);
          if (contentEditableRoot) {
            if (isContentEditableFalse$b(contentEditableRoot)) {
              e.preventDefault();
              editor.focus();
            }
            if (isContentEditableTrue$5(contentEditableRoot)) {
              if (editor.dom.isChildOf(contentEditableRoot, editor.selection.getNode())) {
                removeContentEditableSelection();
              }
            }
          }
        });
        editor.on('blur NewBlock', function () {
          removeContentEditableSelection();
        });
        editor.on('ResizeWindow FullscreenStateChanged', function () {
          return fakeCaret.reposition();
        });
        var handleTouchSelect = function (editor) {
          editor.on('tap', function (e) {
            var contentEditableRoot = getContentEditableRoot$2(editor, e.target);
            if (isContentEditableFalse$b(contentEditableRoot)) {
              e.preventDefault();
              setContentEditableSelection(selectNode(editor, contentEditableRoot));
            }
          }, true);
        };
        var hasNormalCaretPosition = function (elm) {
          var caretWalker = CaretWalker(elm);
          if (!elm.firstChild) {
            return false;
          }
          var startPos = CaretPosition$1.before(elm.firstChild);
          var newPos = caretWalker.next(startPos);
          return newPos && !isBeforeContentEditableFalse(newPos) && !isAfterContentEditableFalse(newPos);
        };
        var isInSameBlock = function (node1, node2) {
          var block1 = editor.dom.getParent(node1, editor.dom.isBlock);
          var block2 = editor.dom.getParent(node2, editor.dom.isBlock);
          return block1 === block2;
        };
        var hasBetterMouseTarget = function (targetNode, caretNode) {
          var targetBlock = editor.dom.getParent(targetNode, editor.dom.isBlock);
          var caretBlock = editor.dom.getParent(caretNode, editor.dom.isBlock);
          if (targetBlock && editor.dom.isChildOf(targetBlock, caretBlock) && isContentEditableFalse$b(getContentEditableRoot$2(editor, targetBlock)) === false) {
            return true;
          }
          return targetBlock && !isInSameBlock(targetBlock, caretBlock) && hasNormalCaretPosition(targetBlock);
        };
        handleTouchSelect(editor);
        editor.on('mousedown', function (e) {
          var contentEditableRoot;
          var targetElm = e.target;
          if (targetElm !== rootNode && targetElm.nodeName !== 'HTML' && !editor.dom.isChildOf(targetElm, rootNode)) {
            return;
          }
          if (EditorView.isXYInContentArea(editor, e.clientX, e.clientY) === false) {
            return;
          }
          contentEditableRoot = getContentEditableRoot$2(editor, targetElm);
          if (contentEditableRoot) {
            if (isContentEditableFalse$b(contentEditableRoot)) {
              e.preventDefault();
              setContentEditableSelection(selectNode(editor, contentEditableRoot));
            } else {
              removeContentEditableSelection();
              if (!(isContentEditableTrue$5(contentEditableRoot) && e.shiftKey) && !RangePoint.isXYWithinRange(e.clientX, e.clientY, editor.selection.getRng())) {
                hideFakeCaret();
                editor.selection.placeCaretAt(e.clientX, e.clientY);
              }
            }
          } else if (isFakeCaretTarget(targetElm) === false) {
            removeContentEditableSelection();
            hideFakeCaret();
            var caretInfo = closestCaret(rootNode, e.clientX, e.clientY);
            if (caretInfo) {
              if (!hasBetterMouseTarget(e.target, caretInfo.node)) {
                e.preventDefault();
                var range = showCaret(1, caretInfo.node, caretInfo.before, false);
                editor.getBody().focus();
                setRange(range);
              }
            }
          }
        });
        editor.on('keypress', function (e) {
          if (VK.modifierPressed(e)) {
            return;
          }
          switch (e.keyCode) {
          default:
            if (isContentEditableFalse$b(editor.selection.getNode())) {
              e.preventDefault();
            }
            break;
          }
        });
        editor.on('GetSelectionRange', function (e) {
          var rng = e.range;
          if (selectedContentEditableNode) {
            if (!selectedContentEditableNode.parentNode) {
              selectedContentEditableNode = null;
              return;
            }
            rng = rng.cloneRange();
            rng.selectNode(selectedContentEditableNode);
            e.range = rng;
          }
        });
        editor.on('SetSelectionRange', function (e) {
          e.range = normalizeShortEndedElementSelection(e.range);
          var rng = setContentEditableSelection(e.range, e.forward);
          if (rng) {
            e.range = rng;
          }
        });
        var isPasteBin = function (node) {
          return node.id === 'mcepastebin';
        };
        editor.on('AfterSetSelectionRange', function (e) {
          var rng = e.range;
          if (!isRangeInCaretContainer(rng) && !isPasteBin(rng.startContainer.parentNode)) {
            hideFakeCaret();
          }
          if (!isFakeSelectionElement(rng.startContainer.parentNode)) {
            removeContentEditableSelection();
          }
        });
        editor.on('copy', function (e) {
          var clipboardData = e.clipboardData;
          if (!e.isDefaultPrevented() && e.clipboardData && !Env.ie) {
            var realSelectionElement = getRealSelectionElement();
            if (realSelectionElement) {
              e.preventDefault();
              clipboardData.clearData();
              clipboardData.setData('text/html', realSelectionElement.outerHTML);
              clipboardData.setData('text/plain', realSelectionElement.outerText);
            }
          }
        });
        DragDropOverrides.init(editor);
        CefFocus.setup(editor);
      };
      var isWithinCaretContainer = function (node) {
        return isCaretContainer(node) || startsWithCaretContainer(node) || endsWithCaretContainer(node);
      };
      var isRangeInCaretContainer = function (rng) {
        return isWithinCaretContainer(rng.startContainer) || isWithinCaretContainer(rng.endContainer);
      };
      var normalizeShortEndedElementSelection = function (rng) {
        var shortEndedElements = editor.schema.getShortEndedElements();
        var newRng = editor.dom.createRng();
        var startContainer = rng.startContainer;
        var startOffset = rng.startOffset;
        var endContainer = rng.endContainer;
        var endOffset = rng.endOffset;
        if (has(shortEndedElements, startContainer.nodeName.toLowerCase())) {
          if (startOffset === 0) {
            newRng.setStartBefore(startContainer);
          } else {
            newRng.setStartAfter(startContainer);
          }
        } else {
          newRng.setStart(startContainer, startOffset);
        }
        if (has(shortEndedElements, endContainer.nodeName.toLowerCase())) {
          if (endOffset === 0) {
            newRng.setEndBefore(endContainer);
          } else {
            newRng.setEndAfter(endContainer);
          }
        } else {
          newRng.setEnd(endContainer, endOffset);
        }
        return newRng;
      };
      var setContentEditableSelection = function (range, forward) {
        var node;
        var $ = editor.$;
        var dom = editor.dom;
        var $realSelectionContainer, sel, startContainer, startOffset, endOffset, e, caretPosition, targetClone, origTargetClone;
        if (!range) {
          return null;
        }
        if (range.collapsed) {
          if (!isRangeInCaretContainer(range)) {
            if (forward === false) {
              caretPosition = getNormalizedRangeEndPoint(-1, rootNode, range);
              if (isFakeCaretTarget(caretPosition.getNode(true))) {
                return showCaret(-1, caretPosition.getNode(true), false, false);
              }
              if (isFakeCaretTarget(caretPosition.getNode())) {
                return showCaret(-1, caretPosition.getNode(), !caretPosition.isAtEnd(), false);
              }
            } else {
              caretPosition = getNormalizedRangeEndPoint(1, rootNode, range);
              if (isFakeCaretTarget(caretPosition.getNode())) {
                return showCaret(1, caretPosition.getNode(), !caretPosition.isAtEnd(), false);
              }
              if (isFakeCaretTarget(caretPosition.getNode(true))) {
                return showCaret(1, caretPosition.getNode(true), false, false);
              }
            }
          }
          return null;
        }
        startContainer = range.startContainer;
        startOffset = range.startOffset;
        endOffset = range.endOffset;
        if (startContainer.nodeType === 3 && startOffset === 0 && isContentEditableFalse$b(startContainer.parentNode)) {
          startContainer = startContainer.parentNode;
          startOffset = dom.nodeIndex(startContainer);
          startContainer = startContainer.parentNode;
        }
        if (startContainer.nodeType !== 1) {
          return null;
        }
        if (endOffset === startOffset + 1 && startContainer === range.endContainer) {
          node = startContainer.childNodes[startOffset];
        }
        if (!isContentEditableFalse$b(node)) {
          return null;
        }
        targetClone = origTargetClone = node.cloneNode(true);
        e = editor.fire('ObjectSelected', {
          target: node,
          targetClone: targetClone
        });
        if (e.isDefaultPrevented()) {
          return null;
        }
        $realSelectionContainer = descendant(Element.fromDom(editor.getBody()), '#' + realSelectionId).fold(function () {
          return $([]);
        }, function (elm) {
          return $([elm.dom()]);
        });
        targetClone = e.targetClone;
        if ($realSelectionContainer.length === 0) {
          $realSelectionContainer = $('<div data-mce-bogus="all" class="mce-offscreen-selection"></div>').attr('id', realSelectionId);
          $realSelectionContainer.appendTo(editor.getBody());
        }
        range = editor.dom.createRng();
        if (targetClone === origTargetClone && Env.ie) {
          $realSelectionContainer.empty().append('<p style="font-size: 0" data-mce-bogus="all">\xA0</p>').append(targetClone);
          range.setStartAfter($realSelectionContainer[0].firstChild.firstChild);
          range.setEndAfter(targetClone);
        } else {
          $realSelectionContainer.empty().append(nbsp).append(targetClone).append(nbsp);
          range.setStart($realSelectionContainer[0].firstChild, 1);
          range.setEnd($realSelectionContainer[0].lastChild, 0);
        }
        $realSelectionContainer.css({ top: dom.getPos(node, editor.getBody()).y });
        $realSelectionContainer[0].focus();
        sel = editor.selection.getSel();
        sel.removeAllRanges();
        sel.addRange(range);
        var nodeElm = Element.fromDom(node);
        each(descendants$1(Element.fromDom(editor.getBody()), '*[data-mce-selected]'), function (elm) {
          if (!eq(nodeElm, elm)) {
            remove$1(elm, 'data-mce-selected');
          }
        });
        if (!editor.dom.getAttrib(node, 'data-mce-selected')) {
          node.setAttribute('data-mce-selected', '1');
        }
        selectedContentEditableNode = node;
        hideFakeCaret();
        return range;
      };
      var removeContentEditableSelection = function () {
        if (selectedContentEditableNode) {
          selectedContentEditableNode.removeAttribute('data-mce-selected');
          descendant(Element.fromDom(editor.getBody()), '#' + realSelectionId).each(remove);
          selectedContentEditableNode = null;
        }
        descendant(Element.fromDom(editor.getBody()), '#' + realSelectionId).each(remove);
        selectedContentEditableNode = null;
      };
      var destroy = function () {
        fakeCaret.destroy();
        selectedContentEditableNode = null;
      };
      var hideFakeCaret = function () {
        fakeCaret.hide();
      };
      if (Env.ceFalse) {
        registerEvents();
      }
      return {
        showCaret: showCaret,
        showBlockCaretContainer: showBlockCaretContainer,
        hideFakeCaret: hideFakeCaret,
        destroy: destroy
      };
    };

    var Quirks = function (editor) {
      var each = Tools.each;
      var BACKSPACE = VK.BACKSPACE, DELETE = VK.DELETE, dom = editor.dom, selection = editor.selection, settings = editor.settings, parser = editor.parser;
      var isGecko = Env.gecko, isIE = Env.ie, isWebKit = Env.webkit;
      var mceInternalUrlPrefix = 'data:text/mce-internal,';
      var mceInternalDataType = isIE ? 'Text' : 'URL';
      var setEditorCommandState = function (cmd, state) {
        try {
          editor.getDoc().execCommand(cmd, false, state);
        } catch (ex) {
        }
      };
      var isDefaultPrevented = function (e) {
        return e.isDefaultPrevented();
      };
      var setMceInternalContent = function (e) {
        var selectionHtml, internalContent;
        if (e.dataTransfer) {
          if (editor.selection.isCollapsed() && e.target.tagName === 'IMG') {
            selection.select(e.target);
          }
          selectionHtml = editor.selection.getContent();
          if (selectionHtml.length > 0) {
            internalContent = mceInternalUrlPrefix + escape(editor.id) + ',' + escape(selectionHtml);
            e.dataTransfer.setData(mceInternalDataType, internalContent);
          }
        }
      };
      var getMceInternalContent = function (e) {
        var internalContent;
        if (e.dataTransfer) {
          internalContent = e.dataTransfer.getData(mceInternalDataType);
          if (internalContent && internalContent.indexOf(mceInternalUrlPrefix) >= 0) {
            internalContent = internalContent.substr(mceInternalUrlPrefix.length).split(',');
            return {
              id: unescape(internalContent[0]),
              html: unescape(internalContent[1])
            };
          }
        }
        return null;
      };
      var insertClipboardContents = function (content, internal) {
        if (editor.queryCommandSupported('mceInsertClipboardContent')) {
          editor.execCommand('mceInsertClipboardContent', false, {
            content: content,
            internal: internal
          });
        } else {
          editor.execCommand('mceInsertContent', false, content);
        }
      };
      var emptyEditorWhenDeleting = function () {
        var serializeRng = function (rng) {
          var body = dom.create('body');
          var contents = rng.cloneContents();
          body.appendChild(contents);
          return selection.serializer.serialize(body, { format: 'html' });
        };
        var allContentsSelected = function (rng) {
          var selection = serializeRng(rng);
          var allRng = dom.createRng();
          allRng.selectNode(editor.getBody());
          var allSelection = serializeRng(allRng);
          return selection === allSelection;
        };
        editor.on('keydown', function (e) {
          var keyCode = e.keyCode;
          var isCollapsed, body;
          if (!isDefaultPrevented(e) && (keyCode === DELETE || keyCode === BACKSPACE)) {
            isCollapsed = editor.selection.isCollapsed();
            body = editor.getBody();
            if (isCollapsed && !dom.isEmpty(body)) {
              return;
            }
            if (!isCollapsed && !allContentsSelected(editor.selection.getRng())) {
              return;
            }
            e.preventDefault();
            editor.setContent('');
            if (body.firstChild && dom.isBlock(body.firstChild)) {
              editor.selection.setCursorLocation(body.firstChild, 0);
            } else {
              editor.selection.setCursorLocation(body, 0);
            }
            editor.nodeChanged();
          }
        });
      };
      var selectAll = function () {
        editor.shortcuts.add('meta+a', null, 'SelectAll');
      };
      var inputMethodFocus = function () {
        if (!editor.inline) {
          dom.bind(editor.getDoc(), 'mousedown mouseup', function (e) {
            var rng;
            if (e.target === editor.getDoc().documentElement) {
              rng = selection.getRng();
              editor.getBody().focus();
              if (e.type === 'mousedown') {
                if (isCaretContainer(rng.startContainer)) {
                  return;
                }
                selection.placeCaretAt(e.clientX, e.clientY);
              } else {
                selection.setRng(rng);
              }
            }
          });
        }
      };
      var removeHrOnBackspace = function () {
        editor.on('keydown', function (e) {
          if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) {
            if (!editor.getBody().getElementsByTagName('hr').length) {
              return;
            }
            if (selection.isCollapsed() && selection.getRng().startOffset === 0) {
              var node = selection.getNode();
              var previousSibling = node.previousSibling;
              if (node.nodeName === 'HR') {
                dom.remove(node);
                e.preventDefault();
                return;
              }
              if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === 'hr') {
                dom.remove(previousSibling);
                e.preventDefault();
              }
            }
          }
        });
      };
      var focusBody = function () {
        if (!domGlobals.Range.prototype.getClientRects) {
          editor.on('mousedown', function (e) {
            if (!isDefaultPrevented(e) && e.target.nodeName === 'HTML') {
              var body_1 = editor.getBody();
              body_1.blur();
              Delay.setEditorTimeout(editor, function () {
                body_1.focus();
              });
            }
          });
        }
      };
      var selectControlElements = function () {
        editor.on('click', function (e) {
          var target = e.target;
          if (/^(IMG|HR)$/.test(target.nodeName) && dom.getContentEditableParent(target) !== 'false') {
            e.preventDefault();
            editor.selection.select(target);
            editor.nodeChanged();
          }
          if (target.nodeName === 'A' && dom.hasClass(target, 'mce-item-anchor')) {
            e.preventDefault();
            selection.select(target);
          }
        });
      };
      var removeStylesWhenDeletingAcrossBlockElements = function () {
        var getAttributeApplyFunction = function () {
          var template = dom.getAttribs(selection.getStart().cloneNode(false));
          return function () {
            var target = selection.getStart();
            if (target !== editor.getBody()) {
              dom.setAttrib(target, 'style', null);
              each(template, function (attr) {
                target.setAttributeNode(attr.cloneNode(true));
              });
            }
          };
        };
        var isSelectionAcrossElements = function () {
          return !selection.isCollapsed() && dom.getParent(selection.getStart(), dom.isBlock) !== dom.getParent(selection.getEnd(), dom.isBlock);
        };
        editor.on('keypress', function (e) {
          var applyAttributes;
          if (!isDefaultPrevented(e) && (e.keyCode === 8 || e.keyCode === 46) && isSelectionAcrossElements()) {
            applyAttributes = getAttributeApplyFunction();
            editor.getDoc().execCommand('delete', false, null);
            applyAttributes();
            e.preventDefault();
            return false;
          }
        });
        dom.bind(editor.getDoc(), 'cut', function (e) {
          var applyAttributes;
          if (!isDefaultPrevented(e) && isSelectionAcrossElements()) {
            applyAttributes = getAttributeApplyFunction();
            Delay.setEditorTimeout(editor, function () {
              applyAttributes();
            });
          }
        });
      };
      var disableBackspaceIntoATable = function () {
        editor.on('keydown', function (e) {
          if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) {
            if (selection.isCollapsed() && selection.getRng().startOffset === 0) {
              var previousSibling = selection.getNode().previousSibling;
              if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === 'table') {
                e.preventDefault();
                return false;
              }
            }
          }
        });
      };
      var removeBlockQuoteOnBackSpace = function () {
        editor.on('keydown', function (e) {
          var rng, container, offset, root, parent;
          if (isDefaultPrevented(e) || e.keyCode !== VK.BACKSPACE) {
            return;
          }
          rng = selection.getRng();
          container = rng.startContainer;
          offset = rng.startOffset;
          root = dom.getRoot();
          parent = container;
          if (!rng.collapsed || offset !== 0) {
            return;
          }
          while (parent && parent.parentNode && parent.parentNode.firstChild === parent && parent.parentNode !== root) {
            parent = parent.parentNode;
          }
          if (parent.tagName === 'BLOCKQUOTE') {
            editor.formatter.toggle('blockquote', null, parent);
            rng = dom.createRng();
            rng.setStart(container, 0);
            rng.setEnd(container, 0);
            selection.setRng(rng);
          }
        });
      };
      var setGeckoEditingOptions = function () {
        var setOpts = function () {
          setEditorCommandState('StyleWithCSS', false);
          setEditorCommandState('enableInlineTableEditing', false);
          if (!settings.object_resizing) {
            setEditorCommandState('enableObjectResizing', false);
          }
        };
        if (!settings.readonly) {
          editor.on('BeforeExecCommand mousedown', setOpts);
        }
      };
      var addBrAfterLastLinks = function () {
        var fixLinks = function () {
          each(dom.select('a'), function (node) {
            var parentNode = node.parentNode;
            var root = dom.getRoot();
            if (parentNode.lastChild === node) {
              while (parentNode && !dom.isBlock(parentNode)) {
                if (parentNode.parentNode.lastChild !== parentNode || parentNode === root) {
                  return;
                }
                parentNode = parentNode.parentNode;
              }
              dom.add(parentNode, 'br', { 'data-mce-bogus': 1 });
            }
          });
        };
        editor.on('SetContent ExecCommand', function (e) {
          if (e.type === 'setcontent' || e.command === 'mceInsertLink') {
            fixLinks();
          }
        });
      };
      var setDefaultBlockType = function () {
        if (settings.forced_root_block) {
          editor.on('init', function () {
            setEditorCommandState('DefaultParagraphSeparator', Settings.getForcedRootBlock(editor));
          });
        }
      };
      var normalizeSelection = function () {
        editor.on('keyup focusin mouseup', function (e) {
          if (!VK.modifierPressed(e)) {
            selection.normalize();
          }
        }, true);
      };
      var showBrokenImageIcon = function () {
        editor.contentStyles.push('img:-moz-broken {' + '-moz-force-broken-image-icon:1;' + 'min-width:24px;' + 'min-height:24px' + '}');
      };
      var restoreFocusOnKeyDown = function () {
        if (!editor.inline) {
          editor.on('keydown', function () {
            if (domGlobals.document.activeElement === domGlobals.document.body) {
              editor.getWin().focus();
            }
          });
        }
      };
      var bodyHeight = function () {
        if (!editor.inline) {
          editor.contentStyles.push('body {min-height: 150px}');
          editor.on('click', function (e) {
            var rng;
            if (e.target.nodeName === 'HTML') {
              if (Env.ie > 11) {
                editor.getBody().focus();
                return;
              }
              rng = editor.selection.getRng();
              editor.getBody().focus();
              editor.selection.setRng(rng);
              editor.selection.normalize();
              editor.nodeChanged();
            }
          });
        }
      };
      var blockCmdArrowNavigation = function () {
        if (Env.mac) {
          editor.on('keydown', function (e) {
            if (VK.metaKeyPressed(e) && !e.shiftKey && (e.keyCode === 37 || e.keyCode === 39)) {
              e.preventDefault();
              var selection_1 = editor.selection.getSel();
              selection_1.modify('move', e.keyCode === 37 ? 'backward' : 'forward', 'lineboundary');
            }
          });
        }
      };
      var disableAutoUrlDetect = function () {
        setEditorCommandState('AutoUrlDetect', false);
      };
      var tapLinksAndImages = function () {
        editor.on('click', function (e) {
          var elm = e.target;
          do {
            if (elm.tagName === 'A') {
              e.preventDefault();
              return;
            }
          } while (elm = elm.parentNode);
        });
        editor.contentStyles.push('.mce-content-body {-webkit-touch-callout: none}');
      };
      var blockFormSubmitInsideEditor = function () {
        editor.on('init', function () {
          editor.dom.bind(editor.getBody(), 'submit', function (e) {
            e.preventDefault();
          });
        });
      };
      var removeAppleInterchangeBrs = function () {
        parser.addNodeFilter('br', function (nodes) {
          var i = nodes.length;
          while (i--) {
            if (nodes[i].attr('class') === 'Apple-interchange-newline') {
              nodes[i].remove();
            }
          }
        });
      };
      var ieInternalDragAndDrop = function () {
        editor.on('dragstart', function (e) {
          setMceInternalContent(e);
        });
        editor.on('drop', function (e) {
          if (!isDefaultPrevented(e)) {
            var internalContent = getMceInternalContent(e);
            if (internalContent && internalContent.id !== editor.id) {
              e.preventDefault();
              var rng = CaretRangeFromPoint.fromPoint(e.x, e.y, editor.getDoc());
              selection.setRng(rng);
              insertClipboardContents(internalContent.html, true);
            }
          }
        });
      };
      var refreshContentEditable = function () {
      };
      var isHidden = function () {
        var sel;
        if (!isGecko || editor.removed) {
          return false;
        }
        sel = editor.selection.getSel();
        return !sel || !sel.rangeCount || sel.rangeCount === 0;
      };
      removeBlockQuoteOnBackSpace();
      emptyEditorWhenDeleting();
      if (!Env.windowsPhone) {
        normalizeSelection();
      }
      if (isWebKit) {
        inputMethodFocus();
        selectControlElements();
        setDefaultBlockType();
        blockFormSubmitInsideEditor();
        disableBackspaceIntoATable();
        removeAppleInterchangeBrs();
        if (Env.iOS) {
          restoreFocusOnKeyDown();
          bodyHeight();
          tapLinksAndImages();
        } else {
          selectAll();
        }
      }
      if (Env.ie >= 11) {
        bodyHeight();
        disableBackspaceIntoATable();
      }
      if (Env.ie) {
        selectAll();
        disableAutoUrlDetect();
        ieInternalDragAndDrop();
      }
      if (isGecko) {
        removeHrOnBackspace();
        focusBody();
        removeStylesWhenDeletingAcrossBlockElements();
        setGeckoEditingOptions();
        addBrAfterLastLinks();
        showBrokenImageIcon();
        blockCmdArrowNavigation();
        disableBackspaceIntoATable();
      }
      return {
        refreshContentEditable: refreshContentEditable,
        isHidden: isHidden
      };
    };

    var DOM$4 = DOMUtils$1.DOM;
    var appendStyle = function (editor, text) {
      var head = Element.fromDom(editor.getDoc().head);
      var tag = Element.fromTag('style');
      set(tag, 'type', 'text/css');
      append(tag, Element.fromText(text));
      append(head, tag);
    };
    var createParser = function (editor) {
      var parser = DomParser(editor.settings, editor.schema);
      parser.addAttributeFilter('src,href,style,tabindex', function (nodes, name) {
        var i = nodes.length, node;
        var dom = editor.dom;
        var value, internalName;
        while (i--) {
          node = nodes[i];
          value = node.attr(name);
          internalName = 'data-mce-' + name;
          if (!node.attr(internalName)) {
            if (value.indexOf('data:') === 0 || value.indexOf('blob:') === 0) {
              continue;
            }
            if (name === 'style') {
              value = dom.serializeStyle(dom.parseStyle(value), node.name);
              if (!value.length) {
                value = null;
              }
              node.attr(internalName, value);
              node.attr(name, value);
            } else if (name === 'tabindex') {
              node.attr(internalName, value);
              node.attr(name, null);
            } else {
              node.attr(internalName, editor.convertURL(value, name, node.name));
            }
          }
        }
      });
      parser.addNodeFilter('script', function (nodes) {
        var i = nodes.length, node, type;
        while (i--) {
          node = nodes[i];
          type = node.attr('type') || 'no/type';
          if (type.indexOf('mce-') !== 0) {
            node.attr('type', 'mce-' + type);
          }
        }
      });
      if (editor.settings.preserve_cdata) {
        parser.addNodeFilter('#cdata', function (nodes) {
          var i = nodes.length, node;
          while (i--) {
            node = nodes[i];
            node.type = 8;
            node.name = '#comment';
            node.value = '[CDATA[' + editor.dom.encode(node.value) + ']]';
          }
        });
      }
      parser.addNodeFilter('p,h1,h2,h3,h4,h5,h6,div', function (nodes) {
        var i = nodes.length, node;
        var nonEmptyElements = editor.schema.getNonEmptyElements();
        while (i--) {
          node = nodes[i];
          if (node.isEmpty(nonEmptyElements) && node.getAll('br').length === 0) {
            node.append(new Node$1('br', 1)).shortEnded = true;
          }
        }
      });
      return parser;
    };
    var autoFocus = function (editor) {
      if (editor.settings.auto_focus) {
        Delay.setEditorTimeout(editor, function () {
          var focusEditor;
          if (editor.settings.auto_focus === true) {
            focusEditor = editor;
          } else {
            focusEditor = editor.editorManager.get(editor.settings.auto_focus);
          }
          if (!focusEditor.destroyed) {
            focusEditor.focus();
          }
        }, 100);
      }
    };
    var moveSelectionToFirstCaretPosition = function (editor) {
      var root = editor.dom.getRoot();
      if (!editor.inline && (!hasAnyRanges(editor) || editor.selection.getStart(true) === root)) {
        CaretFinder.firstPositionIn(root).each(function (pos) {
          var node = pos.getNode();
          var caretPos = NodeType.isTable(node) ? CaretFinder.firstPositionIn(node).getOr(pos) : pos;
          editor.selection.setRng(caretPos.toRange());
        });
      }
    };
    var initEditor = function (editor) {
      editor.bindPendingEventDelegates();
      editor.initialized = true;
      fireInit(editor);
      editor.focus(true);
      moveSelectionToFirstCaretPosition(editor);
      editor.nodeChanged({ initial: true });
      editor.execCallback('init_instance_callback', editor);
      autoFocus(editor);
    };
    var getStyleSheetLoader = function (editor) {
      return editor.inline ? DOM$4.styleSheetLoader : editor.dom.styleSheetLoader;
    };
    var initContentBody = function (editor, skipWrite) {
      var settings = editor.settings;
      var targetElm = editor.getElement();
      var doc = editor.getDoc(), body, contentCssText;
      if (!settings.inline) {
        editor.getElement().style.visibility = editor.orgVisibility;
      }
      if (!skipWrite && !editor.inline) {
        doc.open();
        doc.write(editor.iframeHTML);
        doc.close();
      }
      if (editor.inline) {
        editor.on('remove', function () {
          var bodyEl = this.getBody();
          DOM$4.removeClass(bodyEl, 'mce-content-body');
          DOM$4.removeClass(bodyEl, 'mce-edit-focus');
          DOM$4.setAttrib(bodyEl, 'contentEditable', null);
        });
        DOM$4.addClass(targetElm, 'mce-content-body');
        editor.contentDocument = doc = domGlobals.document;
        editor.contentWindow = domGlobals.window;
        editor.bodyElement = targetElm;
        editor.contentAreaContainer = targetElm;
        settings.root_name = targetElm.nodeName.toLowerCase();
      }
      body = editor.getBody();
      body.disabled = true;
      editor.readonly = settings.readonly;
      if (!editor.readonly) {
        if (editor.inline && DOM$4.getStyle(body, 'position', true) === 'static') {
          body.style.position = 'relative';
        }
        body.contentEditable = editor.getParam('content_editable_state', true);
      }
      body.disabled = false;
      editor.editorUpload = EditorUpload(editor);
      editor.schema = Schema(settings);
      editor.dom = DOMUtils$1(doc, {
        keep_values: true,
        url_converter: editor.convertURL,
        url_converter_scope: editor,
        hex_colors: settings.force_hex_style_colors,
        update_styles: true,
        root_element: editor.inline ? editor.getBody() : null,
        collect: function () {
          return editor.inline;
        },
        schema: editor.schema,
        contentCssCors: Settings.shouldUseContentCssCors(editor),
        referrerPolicy: Settings.getReferrerPolicy(editor),
        onSetAttrib: function (e) {
          editor.fire('SetAttrib', e);
        }
      });
      editor.parser = createParser(editor);
      editor.serializer = Serializer$1(settings, editor);
      editor.selection = Selection$1(editor.dom, editor.getWin(), editor.serializer, editor);
      editor.annotator = Annotator(editor);
      editor.formatter = Formatter(editor);
      editor.undoManager = UndoManager(editor);
      editor._nodeChangeDispatcher = new NodeChange(editor);
      editor._selectionOverrides = SelectionOverrides(editor);
      TouchEvents.setup(editor);
      setup$h(editor);
      setup$i(editor);
      KeyboardOverrides.setup(editor);
      ForceBlocks.setup(editor);
      setup$6(editor);
      firePreInit(editor);
      if (!settings.browser_spellcheck && !settings.gecko_spellcheck) {
        doc.body.spellcheck = false;
        DOM$4.setAttrib(body, 'spellcheck', 'false');
      }
      editor.quirks = Quirks(editor);
      firePostRender(editor);
      var directionality = Settings.getDirectionality(editor);
      if (directionality !== undefined) {
        body.dir = directionality;
      }
      if (settings.protect) {
        editor.on('BeforeSetContent', function (e) {
          Tools.each(settings.protect, function (pattern) {
            e.content = e.content.replace(pattern, function (str) {
              return '<!--mce:protected ' + escape(str) + '-->';
            });
          });
        });
      }
      editor.on('SetContent', function () {
        editor.addVisual(editor.getBody());
      });
      editor.load({
        initial: true,
        format: 'html'
      });
      editor.startContent = editor.getContent({ format: 'raw' });
      editor.on('compositionstart compositionend', function (e) {
        editor.composing = e.type === 'compositionstart';
      });
      if (editor.contentStyles.length > 0) {
        contentCssText = '';
        Tools.each(editor.contentStyles, function (style) {
          contentCssText += style + '\r\n';
        });
        editor.dom.addStyle(contentCssText);
      }
      getStyleSheetLoader(editor).loadAll(editor.contentCSS, function (_) {
        initEditor(editor);
      }, function (urls) {
        initEditor(editor);
      });
      if (settings.content_style) {
        appendStyle(editor, settings.content_style);
      }
    };
    var InitContentBody = { initContentBody: initContentBody };

    var DOM$5 = DOMUtils$1.DOM;
    var relaxDomain = function (editor, ifr) {
      if (domGlobals.document.domain !== domGlobals.window.location.hostname && Env.browser.isIE()) {
        var bodyUuid = Uuid.uuid('mce');
        editor[bodyUuid] = function () {
          InitContentBody.initContentBody(editor);
        };
        var domainRelaxUrl = 'javascript:(function(){' + 'document.open();document.domain="' + domGlobals.document.domain + '";' + 'var ed = window.parent.tinymce.get("' + editor.id + '");document.write(ed.iframeHTML);' + 'document.close();ed.' + bodyUuid + '(true);})()';
        DOM$5.setAttrib(ifr, 'src', domainRelaxUrl);
        return true;
      }
      return false;
    };
    var createIframeElement = function (id, title, height, customAttrs) {
      var iframe = Element.fromTag('iframe');
      setAll(iframe, customAttrs);
      setAll(iframe, {
        id: id + '_ifr',
        frameBorder: '0',
        allowTransparency: 'true',
        title: title
      });
      add$3(iframe, 'tox-edit-area__iframe');
      return iframe;
    };
    var getIframeHtml = function (editor) {
      var bodyId, bodyClass, iframeHTML;
      iframeHTML = Settings.getDocType(editor) + '<html><head>';
      if (Settings.getDocumentBaseUrl(editor) !== editor.documentBaseUrl) {
        iframeHTML += '<base href="' + editor.documentBaseURI.getURI() + '" />';
      }
      iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';
      bodyId = Settings.getBodyId(editor);
      bodyClass = Settings.getBodyClass(editor);
      if (Settings.getContentSecurityPolicy(editor)) {
        iframeHTML += '<meta http-equiv="Content-Security-Policy" content="' + Settings.getContentSecurityPolicy(editor) + '" />';
      }
      iframeHTML += '</head><body id="' + bodyId + '" class="mce-content-body ' + bodyClass + '" data-id="' + editor.id + '"><br></body></html>';
      return iframeHTML;
    };
    var createIframe = function (editor, o) {
      var title = editor.editorManager.translate('Rich Text Area. Press ALT-0 for help.');
      var ifr = createIframeElement(editor.id, title, o.height, Settings.getIframeAttrs(editor)).dom();
      ifr.onload = function () {
        ifr.onload = null;
        editor.fire('load');
      };
      var isDomainRelaxed = relaxDomain(editor, ifr);
      editor.contentAreaContainer = o.iframeContainer;
      editor.iframeElement = ifr;
      editor.iframeHTML = getIframeHtml(editor);
      DOM$5.add(o.iframeContainer, ifr);
      return isDomainRelaxed;
    };
    var init$1 = function (editor, boxInfo) {
      var isDomainRelaxed = createIframe(editor, boxInfo);
      if (boxInfo.editorContainer) {
        DOM$5.get(boxInfo.editorContainer).style.display = editor.orgDisplay;
        editor.hidden = DOM$5.isHidden(boxInfo.editorContainer);
      }
      editor.getElement().style.display = 'none';
      DOM$5.setAttrib(editor.id, 'aria-hidden', 'true');
      if (!isDomainRelaxed) {
        InitContentBody.initContentBody(editor);
      }
    };
    var InitIframe = { init: init$1 };

    var DOM$6 = DOMUtils$1.DOM;
    var initPlugin = function (editor, initializedPlugins, plugin) {
      var Plugin = PluginManager.get(plugin);
      var pluginUrl = PluginManager.urls[plugin] || editor.documentBaseUrl.replace(/\/$/, '');
      plugin = Tools.trim(plugin);
      if (Plugin && Tools.inArray(initializedPlugins, plugin) === -1) {
        Tools.each(PluginManager.dependencies(plugin), function (dep) {
          initPlugin(editor, initializedPlugins, dep);
        });
        if (editor.plugins[plugin]) {
          return;
        }
        try {
          var pluginInstance = new Plugin(editor, pluginUrl, editor.$);
          editor.plugins[plugin] = pluginInstance;
          if (pluginInstance.init) {
            pluginInstance.init(editor, pluginUrl);
            initializedPlugins.push(plugin);
          }
        } catch (e) {
          ErrorReporter.pluginInitError(editor, plugin, e);
        }
      }
    };
    var trimLegacyPrefix = function (name) {
      return name.replace(/^\-/, '');
    };
    var initPlugins = function (editor) {
      var initializedPlugins = [];
      Tools.each(editor.settings.plugins.split(/[ ,]/), function (name) {
        initPlugin(editor, initializedPlugins, trimLegacyPrefix(name));
      });
    };
    var initIcons = function (editor) {
      var iconPackName = Tools.trim(editor.settings.icons);
      var currentIcons = editor.ui.registry.getAll().icons;
      var defaultIcons = getAll();
      var loadIcons = __assign(__assign({}, defaultIcons), IconManager.get(iconPackName).icons);
      each$1(loadIcons, function (svgData, icon) {
        if (!has(currentIcons, icon)) {
          editor.ui.registry.addIcon(icon, svgData);
        }
      });
    };
    var initTheme = function (editor) {
      var theme = editor.settings.theme;
      if (isString(theme)) {
        editor.settings.theme = trimLegacyPrefix(theme);
        var Theme = ThemeManager.get(theme);
        editor.theme = new Theme(editor, ThemeManager.urls[theme]);
        if (editor.theme.init) {
          editor.theme.init(editor, ThemeManager.urls[theme] || editor.documentBaseUrl.replace(/\/$/, ''), editor.$);
        }
      } else {
        editor.theme = {};
      }
    };
    var renderFromLoadedTheme = function (editor) {
      return editor.theme.renderUI();
    };
    var renderFromThemeFunc = function (editor) {
      var elm = editor.getElement();
      var theme = editor.settings.theme;
      var info = theme(editor, elm);
      if (info.editorContainer.nodeType) {
        info.editorContainer.id = info.editorContainer.id || editor.id + '_parent';
      }
      if (info.iframeContainer && info.iframeContainer.nodeType) {
        info.iframeContainer.id = info.iframeContainer.id || editor.id + '_iframecontainer';
      }
      info.height = info.iframeHeight ? info.iframeHeight : elm.offsetHeight;
      return info;
    };
    var createThemeFalseResult = function (element) {
      return {
        editorContainer: element,
        iframeContainer: element
      };
    };
    var renderThemeFalseIframe = function (targetElement) {
      var iframeContainer = DOM$6.create('div');
      DOM$6.insertAfter(iframeContainer, targetElement);
      return createThemeFalseResult(iframeContainer);
    };
    var renderThemeFalse = function (editor) {
      var targetElement = editor.getElement();
      return editor.inline ? createThemeFalseResult(null) : renderThemeFalseIframe(targetElement);
    };
    var renderThemeUi = function (editor) {
      var elm = editor.getElement();
      editor.orgDisplay = elm.style.display;
      if (isString(editor.settings.theme)) {
        return renderFromLoadedTheme(editor);
      } else if (isFunction(editor.settings.theme)) {
        return renderFromThemeFunc(editor);
      } else {
        return renderThemeFalse(editor);
      }
    };
    var init$2 = function (editor) {
      editor.fire('ScriptsLoaded');
      initIcons(editor);
      initTheme(editor);
      initPlugins(editor);
      var boxInfo = renderThemeUi(editor);
      editor.editorContainer = boxInfo.editorContainer ? boxInfo.editorContainer : null;
      appendContentCssFromSettings(editor);
      if (editor.inline) {
        return InitContentBody.initContentBody(editor);
      } else {
        return InitIframe.init(editor, boxInfo);
      }
    };
    var Init = { init: init$2 };

    var DOM$7 = DOMUtils$1.DOM;
    var hasSkipLoadPrefix = function (name) {
      return name.charAt(0) === '-';
    };
    var loadLanguage = function (scriptLoader, editor) {
      var languageCode = Settings.getLanguageCode(editor);
      var languageUrl = Settings.getLanguageUrl(editor);
      if (I18n.hasCode(languageCode) === false && languageCode !== 'en') {
        var url_1 = languageUrl !== '' ? languageUrl : editor.editorManager.baseURL + '/langs/' + languageCode + '.js';
        scriptLoader.add(url_1, noop, undefined, function () {
          ErrorReporter.languageLoadError(editor, url_1, languageCode);
        });
      }
    };
    var loadTheme = function (scriptLoader, editor, suffix, callback) {
      var settings = editor.settings, theme = settings.theme;
      if (isString(theme)) {
        if (!hasSkipLoadPrefix(theme) && !ThemeManager.urls.hasOwnProperty(theme)) {
          var themeUrl = settings.theme_url;
          if (themeUrl) {
            ThemeManager.load(theme, editor.documentBaseURI.toAbsolute(themeUrl));
          } else {
            ThemeManager.load(theme, 'themes/' + theme + '/theme' + suffix + '.js');
          }
        }
        scriptLoader.loadQueue(function () {
          ThemeManager.waitFor(theme, callback);
        });
      } else {
        callback();
      }
    };
    var getIconsUrlMetaFromUrl = function (editor) {
      return Option.from(Settings.getIconsUrl(editor)).filter(function (url) {
        return url.length > 0;
      }).map(function (url) {
        return {
          url: url,
          name: Option.none()
        };
      });
    };
    var getIconsUrlMetaFromName = function (editor) {
      return Option.from(Settings.getIconPackName(editor)).filter(function (name) {
        return name.length > 0 && !IconManager.has(name);
      }).map(function (name) {
        return {
          url: editor.editorManager.baseURL + '/icons/' + name + '/icons.js',
          name: Option.some(name)
        };
      });
    };
    var loadIcons = function (scriptLoader, editor) {
      getIconsUrlMetaFromUrl(editor).orThunk(function () {
        return getIconsUrlMetaFromName(editor);
      }).each(function (urlMeta) {
        scriptLoader.add(urlMeta.url, noop, undefined, function () {
          ErrorReporter.iconsLoadError(editor, urlMeta.url, urlMeta.name.getOrUndefined());
        });
      });
    };
    var loadPlugins = function (editor, settings, suffix) {
      if (isArray(settings.plugins)) {
        settings.plugins = settings.plugins.join(' ');
      }
      Tools.each(settings.external_plugins, function (url, name) {
        PluginManager.load(name, url, noop, undefined, function () {
          ErrorReporter.pluginLoadError(editor, url, name);
        });
        settings.plugins += ' ' + name;
      });
      Tools.each(settings.plugins.split(/[ ,]/), function (plugin) {
        plugin = Tools.trim(plugin);
        if (plugin && !PluginManager.urls[plugin]) {
          if (hasSkipLoadPrefix(plugin)) {
            plugin = plugin.substr(1, plugin.length);
            var dependencies = PluginManager.dependencies(plugin);
            Tools.each(dependencies, function (depPlugin) {
              var defaultSettings = {
                prefix: 'plugins/',
                resource: depPlugin,
                suffix: '/plugin' + suffix + '.js'
              };
              var dep = PluginManager.createUrl(defaultSettings, depPlugin);
              PluginManager.load(dep.resource, dep, noop, undefined, function () {
                ErrorReporter.pluginLoadError(editor, dep.prefix + dep.resource + dep.suffix, dep.resource);
              });
            });
          } else {
            var url_2 = {
              prefix: 'plugins/',
              resource: plugin,
              suffix: '/plugin' + suffix + '.js'
            };
            PluginManager.load(plugin, url_2, noop, undefined, function () {
              ErrorReporter.pluginLoadError(editor, url_2.prefix + url_2.resource + url_2.suffix, plugin);
            });
          }
        }
      });
    };
    var loadScripts = function (editor, suffix) {
      var scriptLoader = ScriptLoader.ScriptLoader;
      loadTheme(scriptLoader, editor, suffix, function () {
        loadLanguage(scriptLoader, editor);
        loadIcons(scriptLoader, editor);
        loadPlugins(editor, editor.settings, suffix);
        scriptLoader.loadQueue(function () {
          if (!editor.removed) {
            Init.init(editor);
          }
        }, editor, function () {
          if (!editor.removed) {
            Init.init(editor);
          }
        });
      });
    };
    var render = function (editor) {
      var settings = editor.settings, id = editor.id;
      I18n.setCode(Settings.getLanguageCode(editor));
      var readyHandler = function () {
        DOM$7.unbind(domGlobals.window, 'ready', readyHandler);
        editor.render();
      };
      if (!EventUtils.Event.domLoaded) {
        DOM$7.bind(domGlobals.window, 'ready', readyHandler);
        return;
      }
      if (!editor.getElement()) {
        return;
      }
      if (!Env.contentEditable) {
        return;
      }
      if (!settings.inline) {
        editor.orgVisibility = editor.getElement().style.visibility;
        editor.getElement().style.visibility = 'hidden';
      } else {
        editor.inline = true;
      }
      var form = editor.getElement().form || DOM$7.getParent(id, 'form');
      if (form) {
        editor.formElement = form;
        if (settings.hidden_input && !NodeType.isTextareaOrInput(editor.getElement())) {
          DOM$7.insertAfter(DOM$7.create('input', {
            type: 'hidden',
            name: id
          }), id);
          editor.hasHiddenInput = true;
        }
        editor.formEventDelegate = function (e) {
          editor.fire(e.type, e);
        };
        DOM$7.bind(form, 'submit reset', editor.formEventDelegate);
        editor.on('reset', function () {
          editor.resetContent();
        });
        if (settings.submit_patch && !form.submit.nodeType && !form.submit.length && !form._mceOldSubmit) {
          form._mceOldSubmit = form.submit;
          form.submit = function () {
            editor.editorManager.triggerSave();
            editor.setDirty(false);
            return form._mceOldSubmit(form);
          };
        }
      }
      editor.windowManager = WindowManager(editor);
      editor.notificationManager = NotificationManager(editor);
      if (settings.encoding === 'xml') {
        editor.on('GetContent', function (e) {
          if (e.save) {
            e.content = DOM$7.encode(e.content);
          }
        });
      }
      if (settings.add_form_submit_trigger) {
        editor.on('submit', function () {
          if (editor.initialized) {
            editor.save();
          }
        });
      }
      if (settings.add_unload_trigger) {
        editor._beforeUnload = function () {
          if (editor.initialized && !editor.destroyed && !editor.isHidden()) {
            editor.save({
              format: 'raw',
              no_events: true,
              set_dirty: false
            });
          }
        };
        editor.editorManager.on('BeforeUnload', editor._beforeUnload);
      }
      editor.editorManager.add(editor);
      loadScripts(editor, editor.suffix);
    };
    var Render = { render: render };

    var hasOnlyOneChild$1 = function (node) {
      return node.firstChild && node.firstChild === node.lastChild;
    };
    var isPaddingNode = function (node) {
      return node.name === 'br' || node.value === nbsp;
    };
    var isPaddedEmptyBlock = function (schema, node) {
      var blockElements = schema.getBlockElements();
      return blockElements[node.name] && hasOnlyOneChild$1(node) && isPaddingNode(node.firstChild);
    };
    var isEmptyFragmentElement = function (schema, node) {
      var nonEmptyElements = schema.getNonEmptyElements();
      return node && (node.isEmpty(nonEmptyElements) || isPaddedEmptyBlock(schema, node));
    };
    var isListFragment = function (schema, fragment) {
      var firstChild = fragment.firstChild;
      var lastChild = fragment.lastChild;
      if (firstChild && firstChild.name === 'meta') {
        firstChild = firstChild.next;
      }
      if (lastChild && lastChild.attr('id') === 'mce_marker') {
        lastChild = lastChild.prev;
      }
      if (isEmptyFragmentElement(schema, lastChild)) {
        lastChild = lastChild.prev;
      }
      if (!firstChild || firstChild !== lastChild) {
        return false;
      }
      return firstChild.name === 'ul' || firstChild.name === 'ol';
    };
    var cleanupDomFragment = function (domFragment) {
      var firstChild = domFragment.firstChild;
      var lastChild = domFragment.lastChild;
      if (firstChild && firstChild.nodeName === 'META') {
        firstChild.parentNode.removeChild(firstChild);
      }
      if (lastChild && lastChild.id === 'mce_marker') {
        lastChild.parentNode.removeChild(lastChild);
      }
      return domFragment;
    };
    var toDomFragment = function (dom, serializer, fragment) {
      var html = serializer.serialize(fragment);
      var domFragment = dom.createFragment(html);
      return cleanupDomFragment(domFragment);
    };
    var listItems$1 = function (elm) {
      return Tools.grep(elm.childNodes, function (child) {
        return child.nodeName === 'LI';
      });
    };
    var isPadding = function (node) {
      return node.data === nbsp || NodeType.isBr(node);
    };
    var isListItemPadded = function (node) {
      return node && node.firstChild && node.firstChild === node.lastChild && isPadding(node.firstChild);
    };
    var isEmptyOrPadded = function (elm) {
      return !elm.firstChild || isListItemPadded(elm);
    };
    var trimListItems = function (elms) {
      return elms.length > 0 && isEmptyOrPadded(elms[elms.length - 1]) ? elms.slice(0, -1) : elms;
    };
    var getParentLi = function (dom, node) {
      var parentBlock = dom.getParent(node, dom.isBlock);
      return parentBlock && parentBlock.nodeName === 'LI' ? parentBlock : null;
    };
    var isParentBlockLi = function (dom, node) {
      return !!getParentLi(dom, node);
    };
    var getSplit = function (parentNode, rng) {
      var beforeRng = rng.cloneRange();
      var afterRng = rng.cloneRange();
      beforeRng.setStartBefore(parentNode);
      afterRng.setEndAfter(parentNode);
      return [
        beforeRng.cloneContents(),
        afterRng.cloneContents()
      ];
    };
    var findFirstIn = function (node, rootNode) {
      var caretPos = CaretPosition$1.before(node);
      var caretWalker = CaretWalker(rootNode);
      var newCaretPos = caretWalker.next(caretPos);
      return newCaretPos ? newCaretPos.toRange() : null;
    };
    var findLastOf = function (node, rootNode) {
      var caretPos = CaretPosition$1.after(node);
      var caretWalker = CaretWalker(rootNode);
      var newCaretPos = caretWalker.prev(caretPos);
      return newCaretPos ? newCaretPos.toRange() : null;
    };
    var insertMiddle = function (target, elms, rootNode, rng) {
      var parts = getSplit(target, rng);
      var parentElm = target.parentNode;
      parentElm.insertBefore(parts[0], target);
      Tools.each(elms, function (li) {
        parentElm.insertBefore(li, target);
      });
      parentElm.insertBefore(parts[1], target);
      parentElm.removeChild(target);
      return findLastOf(elms[elms.length - 1], rootNode);
    };
    var insertBefore$1 = function (target, elms, rootNode) {
      var parentElm = target.parentNode;
      Tools.each(elms, function (elm) {
        parentElm.insertBefore(elm, target);
      });
      return findFirstIn(target, rootNode);
    };
    var insertAfter$1 = function (target, elms, rootNode, dom) {
      dom.insertAfter(elms.reverse(), target);
      return findLastOf(elms[0], rootNode);
    };
    var insertAtCaret = function (serializer, dom, rng, fragment) {
      var domFragment = toDomFragment(dom, serializer, fragment);
      var liTarget = getParentLi(dom, rng.startContainer);
      var liElms = trimListItems(listItems$1(domFragment.firstChild));
      var BEGINNING = 1, END = 2;
      var rootNode = dom.getRoot();
      var isAt = function (location) {
        var caretPos = CaretPosition$1.fromRangeStart(rng);
        var caretWalker = CaretWalker(dom.getRoot());
        var newPos = location === BEGINNING ? caretWalker.prev(caretPos) : caretWalker.next(caretPos);
        return newPos ? getParentLi(dom, newPos.getNode()) !== liTarget : true;
      };
      if (isAt(BEGINNING)) {
        return insertBefore$1(liTarget, liElms, rootNode);
      } else if (isAt(END)) {
        return insertAfter$1(liTarget, liElms, rootNode, dom);
      }
      return insertMiddle(liTarget, liElms, rootNode, rng);
    };
    var InsertList = {
      isListFragment: isListFragment,
      insertAtCaret: insertAtCaret,
      isParentBlockLi: isParentBlockLi,
      trimListItems: trimListItems,
      listItems: listItems$1
    };

    var isAfterNbsp = function (container, offset) {
      return NodeType.isText(container) && container.nodeValue[offset - 1] === nbsp;
    };
    var trimOrPadLeftRight = function (rng, html) {
      var container, offset;
      container = rng.startContainer;
      offset = rng.startOffset;
      var hasSiblingText = function (siblingName) {
        return container[siblingName] && container[siblingName].nodeType === 3;
      };
      if (container.nodeType === 3) {
        if (offset > 0) {
          html = html.replace(/^&nbsp;/, ' ');
        } else if (!hasSiblingText('previousSibling')) {
          html = html.replace(/^ /, '&nbsp;');
        }
        if (offset < container.length) {
          html = html.replace(/&nbsp;(<br>|)$/, ' ');
        } else if (!hasSiblingText('nextSibling')) {
          html = html.replace(/(&nbsp;| )(<br>|)$/, '&nbsp;');
        }
      }
      return html;
    };
    var trimNbspAfterDeleteAndPadValue = function (rng, value) {
      var container, offset;
      container = rng.startContainer;
      offset = rng.startOffset;
      if (container.nodeType === 3 && rng.collapsed) {
        if (container.data[offset] === nbsp) {
          container.deleteData(offset, 1);
          if (!/[\u00a0| ]$/.test(value)) {
            value += ' ';
          }
        } else if (container.data[offset - 1] === nbsp) {
          container.deleteData(offset - 1, 1);
          if (!/[\u00a0| ]$/.test(value)) {
            value = ' ' + value;
          }
        }
      }
      return value;
    };

    var isTableCell$5 = NodeType.matchNodeNames([
      'td',
      'th'
    ]);
    var selectionSetContent = function (editor, content) {
      var rng = editor.selection.getRng();
      var container = rng.startContainer;
      var offset = rng.startOffset;
      if (rng.collapsed && isAfterNbsp(container, offset) && NodeType.isText(container)) {
        container.insertData(offset - 1, ' ');
        container.deleteData(offset, 1);
        rng.setStart(container, offset);
        rng.setEnd(container, offset);
        editor.selection.setRng(rng);
      }
      editor.selection.setContent(content);
    };
    var validInsertion = function (editor, value, parentNode) {
      if (parentNode.getAttribute('data-mce-bogus') === 'all') {
        parentNode.parentNode.insertBefore(editor.dom.createFragment(value), parentNode);
      } else {
        var node = parentNode.firstChild;
        var node2 = parentNode.lastChild;
        if (!node || node === node2 && node.nodeName === 'BR') {
          editor.dom.setHTML(parentNode, value);
        } else {
          selectionSetContent(editor, value);
        }
      }
    };
    var trimBrsFromTableCell = function (dom, elm) {
      Option.from(dom.getParent(elm, 'td,th')).map(Element.fromDom).each(PaddingBr.trimBlockTrailingBr);
    };
    var reduceInlineTextElements = function (editor, merge) {
      var textInlineElements = editor.schema.getTextInlineElements();
      var dom = editor.dom;
      if (merge) {
        var root_1 = editor.getBody(), elementUtils_1 = new ElementUtils(dom);
        Tools.each(dom.select('*[data-mce-fragment]'), function (node) {
          for (var testNode = node.parentNode; testNode && testNode !== root_1; testNode = testNode.parentNode) {
            if (textInlineElements[node.nodeName.toLowerCase()] && elementUtils_1.compare(testNode, node)) {
              dom.remove(node, true);
            }
          }
        });
      }
    };
    var markFragmentElements = function (fragment) {
      var node = fragment;
      while (node = node.walk()) {
        if (node.type === 1) {
          node.attr('data-mce-fragment', '1');
        }
      }
    };
    var umarkFragmentElements = function (elm) {
      Tools.each(elm.getElementsByTagName('*'), function (elm) {
        elm.removeAttribute('data-mce-fragment');
      });
    };
    var isPartOfFragment = function (node) {
      return !!node.getAttribute('data-mce-fragment');
    };
    var canHaveChildren = function (editor, node) {
      return node && !editor.schema.getShortEndedElements()[node.nodeName];
    };
    var moveSelectionToMarker = function (editor, marker) {
      var parentEditableFalseElm, parentBlock, nextRng;
      var dom = editor.dom, selection = editor.selection;
      var node, node2;
      var getContentEditableFalseParent = function (node) {
        var root = editor.getBody();
        for (; node && node !== root; node = node.parentNode) {
          if (editor.dom.getContentEditable(node) === 'false') {
            return node;
          }
        }
        return null;
      };
      if (!marker) {
        return;
      }
      editor.selection.scrollIntoView(marker);
      parentEditableFalseElm = getContentEditableFalseParent(marker);
      if (parentEditableFalseElm) {
        dom.remove(marker);
        selection.select(parentEditableFalseElm);
        return;
      }
      var rng = dom.createRng();
      node = marker.previousSibling;
      if (node && node.nodeType === 3) {
        rng.setStart(node, node.nodeValue.length);
        if (!Env.ie) {
          node2 = marker.nextSibling;
          if (node2 && node2.nodeType === 3) {
            node.appendData(node2.data);
            node2.parentNode.removeChild(node2);
          }
        }
      } else {
        rng.setStartBefore(marker);
        rng.setEndBefore(marker);
      }
      var findNextCaretRng = function (rng) {
        var caretPos = CaretPosition$1.fromRangeStart(rng);
        var caretWalker = CaretWalker(editor.getBody());
        caretPos = caretWalker.next(caretPos);
        if (caretPos) {
          return caretPos.toRange();
        }
      };
      parentBlock = dom.getParent(marker, dom.isBlock);
      dom.remove(marker);
      if (parentBlock && dom.isEmpty(parentBlock)) {
        editor.$(parentBlock).empty();
        rng.setStart(parentBlock, 0);
        rng.setEnd(parentBlock, 0);
        if (!isTableCell$5(parentBlock) && !isPartOfFragment(parentBlock) && (nextRng = findNextCaretRng(rng))) {
          rng = nextRng;
          dom.remove(parentBlock);
        } else {
          dom.add(parentBlock, dom.create('br', { 'data-mce-bogus': '1' }));
        }
      }
      selection.setRng(rng);
    };
    var insertHtmlAtCaret = function (editor, value, details) {
      var parser, serializer, parentNode, rootNode, fragment, args;
      var marker, rng, node, bookmarkHtml, merge;
      var selection = editor.selection, dom = editor.dom;
      if (/^ | $/.test(value)) {
        value = trimOrPadLeftRight(selection.getRng(), value);
      }
      parser = editor.parser;
      merge = details.merge;
      serializer = Serializer({ validate: editor.settings.validate }, editor.schema);
      bookmarkHtml = '<span id="mce_marker" data-mce-type="bookmark">&#xFEFF;&#x200B;</span>';
      args = {
        content: value,
        format: 'html',
        selection: true,
        paste: details.paste
      };
      args = editor.fire('BeforeSetContent', args);
      if (args.isDefaultPrevented()) {
        editor.fire('SetContent', {
          content: args.content,
          format: 'html',
          selection: true,
          paste: details.paste
        });
        return;
      }
      value = args.content;
      if (value.indexOf('{$caret}') === -1) {
        value += '{$caret}';
      }
      value = value.replace(/\{\$caret\}/, bookmarkHtml);
      rng = selection.getRng();
      var caretElement = rng.startContainer || (rng.parentElement ? rng.parentElement() : null);
      var body = editor.getBody();
      if (caretElement === body && selection.isCollapsed()) {
        if (dom.isBlock(body.firstChild) && canHaveChildren(editor, body.firstChild) && dom.isEmpty(body.firstChild)) {
          rng = dom.createRng();
          rng.setStart(body.firstChild, 0);
          rng.setEnd(body.firstChild, 0);
          selection.setRng(rng);
        }
      }
      if (!selection.isCollapsed()) {
        editor.selection.setRng(RangeNormalizer.normalize(editor.selection.getRng()));
        editor.getDoc().execCommand('Delete', false, null);
        value = trimNbspAfterDeleteAndPadValue(editor.selection.getRng(), value);
      }
      parentNode = selection.getNode();
      var parserArgs = {
        context: parentNode.nodeName.toLowerCase(),
        data: details.data,
        insert: true
      };
      fragment = parser.parse(value, parserArgs);
      if (details.paste === true && InsertList.isListFragment(editor.schema, fragment) && InsertList.isParentBlockLi(dom, parentNode)) {
        rng = InsertList.insertAtCaret(serializer, dom, editor.selection.getRng(), fragment);
        editor.selection.setRng(rng);
        editor.fire('SetContent', args);
        return;
      }
      markFragmentElements(fragment);
      node = fragment.lastChild;
      if (node.attr('id') === 'mce_marker') {
        marker = node;
        for (node = node.prev; node; node = node.walk(true)) {
          if (node.type === 3 || !dom.isBlock(node.name)) {
            if (editor.schema.isValidChild(node.parent.name, 'span')) {
              node.parent.insert(marker, node, node.name === 'br');
            }
            break;
          }
        }
      }
      editor._selectionOverrides.showBlockCaretContainer(parentNode);
      if (!parserArgs.invalid) {
        value = serializer.serialize(fragment);
        validInsertion(editor, value, parentNode);
      } else {
        selectionSetContent(editor, bookmarkHtml);
        parentNode = selection.getNode();
        rootNode = editor.getBody();
        if (parentNode.nodeType === 9) {
          parentNode = node = rootNode;
        } else {
          node = parentNode;
        }
        while (node !== rootNode) {
          parentNode = node;
          node = node.parentNode;
        }
        value = parentNode === rootNode ? rootNode.innerHTML : dom.getOuterHTML(parentNode);
        value = serializer.serialize(parser.parse(value.replace(/<span (id="mce_marker"|id=mce_marker).+?<\/span>/i, function () {
          return serializer.serialize(fragment);
        })));
        if (parentNode === rootNode) {
          dom.setHTML(rootNode, value);
        } else {
          dom.setOuterHTML(parentNode, value);
        }
      }
      reduceInlineTextElements(editor, merge);
      moveSelectionToMarker(editor, dom.get('mce_marker'));
      umarkFragmentElements(editor.getBody());
      trimBrsFromTableCell(editor.dom, editor.selection.getStart());
      editor.fire('SetContent', args);
      editor.addVisual();
    };
    var processValue = function (value) {
      var details;
      if (typeof value !== 'string') {
        details = Tools.extend({
          paste: value.paste,
          data: { paste: value.paste }
        }, value);
        return {
          content: value.content,
          details: details
        };
      }
      return {
        content: value,
        details: {}
      };
    };
    var insertAtCaret$1 = function (editor, value) {
      var result = processValue(value);
      insertHtmlAtCaret(editor, result.content, result.details);
    };
    var InsertContent = { insertAtCaret: insertAtCaret$1 };

    var nativeCommand = function (editor, command) {
      editor.getDoc().execCommand(command, false, null);
    };
    var deleteCommand = function (editor) {
      if (Outdent.backspaceDelete(editor, false)) {
        return;
      } else if (CefDelete.backspaceDelete(editor, false)) {
        return;
      } else if (CefBoundaryDelete.backspaceDelete(editor, false)) {
        return;
      } else if (BoundaryDelete.backspaceDelete(editor, false)) {
        return;
      } else if (BlockBoundaryDelete.backspaceDelete(editor, false)) {
        return;
      } else if (TableDelete.backspaceDelete(editor)) {
        return;
      } else if (BlockRangeDelete.backspaceDelete(editor, false)) {
        return;
      } else if (InlineFormatDelete.backspaceDelete(editor, false)) {
        return;
      } else {
        nativeCommand(editor, 'Delete');
        DeleteUtils.paddEmptyBody(editor);
      }
    };
    var forwardDeleteCommand = function (editor) {
      if (CefDelete.backspaceDelete(editor, true)) {
        return;
      } else if (CefBoundaryDelete.backspaceDelete(editor, true)) {
        return;
      } else if (BoundaryDelete.backspaceDelete(editor, true)) {
        return;
      } else if (BlockBoundaryDelete.backspaceDelete(editor, true)) {
        return;
      } else if (TableDelete.backspaceDelete(editor)) {
        return;
      } else if (BlockRangeDelete.backspaceDelete(editor, true)) {
        return;
      } else if (InlineFormatDelete.backspaceDelete(editor, true)) {
        return;
      } else {
        nativeCommand(editor, 'ForwardDelete');
      }
    };
    var DeleteCommands = {
      deleteCommand: deleteCommand,
      forwardDeleteCommand: forwardDeleteCommand
    };

    var ancestor$3 = function (scope, transform, isRoot) {
      var element = scope.dom();
      var stop = isFunction(isRoot) ? isRoot : constant(false);
      while (element.parentNode) {
        element = element.parentNode;
        var el = Element.fromDom(element);
        var transformed = transform(el);
        if (transformed.isSome()) {
          return transformed;
        } else if (stop(el)) {
          break;
        }
      }
      return Option.none();
    };
    var closest$2 = function (scope, transform, isRoot) {
      var current = transform(scope);
      return current.orThunk(function () {
        return isRoot(scope) ? Option.none() : ancestor$3(scope, transform, isRoot);
      });
    };

    var legacyPropNames = {
      'font-size': 'size',
      'font-family': 'face'
    };
    var getSpecifiedFontProp = function (propName, rootElm, elm) {
      var getProperty = function (elm) {
        return getRaw(elm, propName).orThunk(function () {
          if (name(elm) === 'font') {
            return get(legacyPropNames, propName).bind(function (legacyPropName) {
              return getOpt(elm, legacyPropName);
            });
          } else {
            return Option.none();
          }
        });
      };
      var isRoot = function (elm) {
        return eq(Element.fromDom(rootElm), elm);
      };
      return closest$2(Element.fromDom(elm), function (elm) {
        return getProperty(elm);
      }, isRoot);
    };
    var round$1 = function (number, precision) {
      var factor = Math.pow(10, precision);
      return Math.round(number * factor) / factor;
    };
    var toPt = function (fontSize, precision) {
      if (/[0-9.]+px$/.test(fontSize)) {
        return round$1(parseInt(fontSize, 10) * 72 / 96, precision || 0) + 'pt';
      }
      return fontSize;
    };
    var normalizeFontFamily = function (fontFamily) {
      return fontFamily.replace(/[\'\"\\]/g, '').replace(/,\s+/g, ',');
    };
    var getComputedFontProp = function (propName, elm) {
      return Option.from(DOMUtils$1.DOM.getStyle(elm, propName, true));
    };
    var getFontProp = function (propName) {
      return function (rootElm, elm) {
        return Option.from(elm).map(Element.fromDom).filter(isElement).bind(function (element) {
          return getSpecifiedFontProp(propName, rootElm, element.dom()).or(getComputedFontProp(propName, element.dom()));
        }).getOr('');
      };
    };
    var FontInfo = {
      getFontSize: getFontProp('font-size'),
      getFontFamily: compose(normalizeFontFamily, getFontProp('font-family')),
      toPt: toPt
    };

    var findFirstCaretElement = function (editor) {
      return CaretFinder.firstPositionIn(editor.getBody()).map(function (caret) {
        var container = caret.container();
        return NodeType.isText(container) ? container.parentNode : container;
      });
    };
    var isRangeAtStartOfNode = function (rng, root) {
      return rng.startContainer === root && rng.startOffset === 0;
    };
    var getCaretElement = function (editor) {
      return Option.from(editor.selection.getRng()).bind(function (rng) {
        var root = editor.getBody();
        return isRangeAtStartOfNode(rng, root) ? Option.none() : Option.from(editor.selection.getStart(true));
      });
    };
    var fromFontSizeNumber = function (editor, value) {
      if (/^[0-9\.]+$/.test(value)) {
        var fontSizeNumber = parseInt(value, 10);
        if (fontSizeNumber >= 1 && fontSizeNumber <= 7) {
          var fontSizes = Settings.getFontStyleValues(editor);
          var fontClasses = Settings.getFontSizeClasses(editor);
          if (fontClasses) {
            return fontClasses[fontSizeNumber - 1] || value;
          } else {
            return fontSizes[fontSizeNumber - 1] || value;
          }
        } else {
          return value;
        }
      } else {
        return value;
      }
    };
    var normalizeFontNames = function (font) {
      var fonts = font.split(/\s*,\s*/);
      return map(fonts, function (font) {
        if (font.indexOf(' ') !== -1 && !(startsWith(font, '"') || startsWith(font, '\''))) {
          return '\'' + font + '\'';
        } else {
          return font;
        }
      }).join(',');
    };
    var fontNameAction = function (editor, value) {
      var font = fromFontSizeNumber(editor, value);
      editor.formatter.toggle('fontname', { value: normalizeFontNames(font) });
      editor.nodeChanged();
    };
    var fontNameQuery = function (editor) {
      return getCaretElement(editor).fold(function () {
        return findFirstCaretElement(editor).map(function (caretElement) {
          return FontInfo.getFontFamily(editor.getBody(), caretElement);
        }).getOr('');
      }, function (caretElement) {
        return FontInfo.getFontFamily(editor.getBody(), caretElement);
      });
    };
    var fontSizeAction = function (editor, value) {
      editor.formatter.toggle('fontsize', { value: fromFontSizeNumber(editor, value) });
      editor.nodeChanged();
    };
    var fontSizeQuery = function (editor) {
      return getCaretElement(editor).fold(function () {
        return findFirstCaretElement(editor).map(function (caretElement) {
          return FontInfo.getFontSize(editor.getBody(), caretElement);
        }).getOr('');
      }, function (caretElement) {
        return FontInfo.getFontSize(editor.getBody(), caretElement);
      });
    };

    var each$f = Tools.each;
    var map$3 = Tools.map, inArray$2 = Tools.inArray;
    var EditorCommands = function () {
      function EditorCommands(editor) {
        this.commands = {
          state: {},
          exec: {},
          value: {}
        };
        this.editor = editor;
        this.setupCommands(editor);
      }
      EditorCommands.prototype.execCommand = function (command, ui, value, args) {
        var func, customCommand, state = false;
        var self = this;
        if (self.editor.removed) {
          return;
        }
        if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint)$/.test(command) && (!args || !args.skip_focus)) {
          self.editor.focus();
        } else {
          SelectionBookmark.restore(self.editor);
        }
        args = self.editor.fire('BeforeExecCommand', {
          command: command,
          ui: ui,
          value: value
        });
        if (args.isDefaultPrevented()) {
          return false;
        }
        customCommand = command.toLowerCase();
        if (func = self.commands.exec[customCommand]) {
          func(customCommand, ui, value);
          self.editor.fire('ExecCommand', {
            command: command,
            ui: ui,
            value: value
          });
          return true;
        }
        each$f(this.editor.plugins, function (p) {
          if (p.execCommand && p.execCommand(command, ui, value)) {
            self.editor.fire('ExecCommand', {
              command: command,
              ui: ui,
              value: value
            });
            state = true;
            return false;
          }
        });
        if (state) {
          return state;
        }
        if (self.editor.theme && self.editor.theme.execCommand && self.editor.theme.execCommand(command, ui, value)) {
          self.editor.fire('ExecCommand', {
            command: command,
            ui: ui,
            value: value
          });
          return true;
        }
        try {
          state = self.editor.getDoc().execCommand(command, ui, value);
        } catch (ex) {
        }
        if (state) {
          self.editor.fire('ExecCommand', {
            command: command,
            ui: ui,
            value: value
          });
          return true;
        }
        return false;
      };
      EditorCommands.prototype.queryCommandState = function (command) {
        var func;
        if (this.editor.quirks.isHidden() || this.editor.removed) {
          return;
        }
        command = command.toLowerCase();
        if (func = this.commands.state[command]) {
          return func(command);
        }
        try {
          return this.editor.getDoc().queryCommandState(command);
        } catch (ex) {
        }
        return false;
      };
      EditorCommands.prototype.queryCommandValue = function (command) {
        var func;
        if (this.editor.quirks.isHidden() || this.editor.removed) {
          return;
        }
        command = command.toLowerCase();
        if (func = this.commands.value[command]) {
          return func(command);
        }
        try {
          return this.editor.getDoc().queryCommandValue(command);
        } catch (ex) {
        }
      };
      EditorCommands.prototype.addCommands = function (commandList, type) {
        var self = this;
        type = type || 'exec';
        each$f(commandList, function (callback, command) {
          each$f(command.toLowerCase().split(','), function (command) {
            self.commands[type][command] = callback;
          });
        });
      };
      EditorCommands.prototype.addCommand = function (command, callback, scope) {
        var _this = this;
        command = command.toLowerCase();
        this.commands.exec[command] = function (command, ui, value, args) {
          return callback.call(scope || _this.editor, ui, value, args);
        };
      };
      EditorCommands.prototype.queryCommandSupported = function (command) {
        command = command.toLowerCase();
        if (this.commands.exec[command]) {
          return true;
        }
        try {
          return this.editor.getDoc().queryCommandSupported(command);
        } catch (ex) {
        }
        return false;
      };
      EditorCommands.prototype.addQueryStateHandler = function (command, callback, scope) {
        var _this = this;
        command = command.toLowerCase();
        this.commands.state[command] = function () {
          return callback.call(scope || _this.editor);
        };
      };
      EditorCommands.prototype.addQueryValueHandler = function (command, callback, scope) {
        var _this = this;
        command = command.toLowerCase();
        this.commands.value[command] = function () {
          return callback.call(scope || _this.editor);
        };
      };
      EditorCommands.prototype.hasCustomCommand = function (command) {
        command = command.toLowerCase();
        return !!this.commands.exec[command];
      };
      EditorCommands.prototype.execNativeCommand = function (command, ui, value) {
        if (ui === undefined) {
          ui = false;
        }
        if (value === undefined) {
          value = null;
        }
        return this.editor.getDoc().execCommand(command, ui, value);
      };
      EditorCommands.prototype.isFormatMatch = function (name) {
        return this.editor.formatter.match(name);
      };
      EditorCommands.prototype.toggleFormat = function (name, value) {
        this.editor.formatter.toggle(name, value ? { value: value } : undefined);
        this.editor.nodeChanged();
      };
      EditorCommands.prototype.storeSelection = function (type) {
        this.selectionBookmark = this.editor.selection.getBookmark(type);
      };
      EditorCommands.prototype.restoreSelection = function () {
        this.editor.selection.moveToBookmark(this.selectionBookmark);
      };
      EditorCommands.prototype.setupCommands = function (editor) {
        var self = this;
        this.addCommands({
          'mceResetDesignMode,mceBeginUndoLevel': function () {
          },
          'mceEndUndoLevel,mceAddUndoLevel': function () {
            editor.undoManager.add();
          },
          'Cut,Copy,Paste': function (command) {
            var doc = editor.getDoc();
            var failed;
            try {
              self.execNativeCommand(command);
            } catch (ex) {
              failed = true;
            }
            if (command === 'paste' && !doc.queryCommandEnabled(command)) {
              failed = true;
            }
            if (failed || !doc.queryCommandSupported(command)) {
              var msg = editor.translate('Your browser doesn\'t support direct access to the clipboard. ' + 'Please use the Ctrl+X/C/V keyboard shortcuts instead.');
              if (Env.mac) {
                msg = msg.replace(/Ctrl\+/g, '\u2318+');
              }
              editor.notificationManager.open({
                text: msg,
                type: 'error'
              });
            }
          },
          'unlink': function () {
            if (editor.selection.isCollapsed()) {
              var elm = editor.dom.getParent(editor.selection.getStart(), 'a');
              if (elm) {
                editor.dom.remove(elm, true);
              }
              return;
            }
            editor.formatter.remove('link');
          },
          'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull,JustifyNone': function (command) {
            var align = command.substring(7);
            if (align === 'full') {
              align = 'justify';
            }
            each$f('left,center,right,justify'.split(','), function (name) {
              if (align !== name) {
                editor.formatter.remove('align' + name);
              }
            });
            if (align !== 'none') {
              self.toggleFormat('align' + align);
            }
          },
          'InsertUnorderedList,InsertOrderedList': function (command) {
            var listElm, listParent;
            self.execNativeCommand(command);
            listElm = editor.dom.getParent(editor.selection.getNode(), 'ol,ul');
            if (listElm) {
              listParent = listElm.parentNode;
              if (/^(H[1-6]|P|ADDRESS|PRE)$/.test(listParent.nodeName)) {
                self.storeSelection();
                editor.dom.split(listParent, listElm);
                self.restoreSelection();
              }
            }
          },
          'Bold,Italic,Underline,Strikethrough,Superscript,Subscript': function (command) {
            self.toggleFormat(command);
          },
          'ForeColor,HiliteColor': function (command, ui, value) {
            self.toggleFormat(command, value);
          },
          'FontName': function (command, ui, value) {
            fontNameAction(editor, value);
          },
          'FontSize': function (command, ui, value) {
            fontSizeAction(editor, value);
          },
          'RemoveFormat': function (command) {
            editor.formatter.remove(command);
          },
          'mceBlockQuote': function () {
            self.toggleFormat('blockquote');
          },
          'FormatBlock': function (command, ui, value) {
            return self.toggleFormat(value || 'p');
          },
          'mceCleanup': function () {
            var bookmark = editor.selection.getBookmark();
            editor.setContent(editor.getContent());
            editor.selection.moveToBookmark(bookmark);
          },
          'mceRemoveNode': function (command, ui, value) {
            var node = value || editor.selection.getNode();
            if (node !== editor.getBody()) {
              self.storeSelection();
              editor.dom.remove(node, true);
              self.restoreSelection();
            }
          },
          'mceSelectNodeDepth': function (command, ui, value) {
            var counter = 0;
            editor.dom.getParent(editor.selection.getNode(), function (node) {
              if (node.nodeType === 1 && counter++ === value) {
                editor.selection.select(node);
                return false;
              }
            }, editor.getBody());
          },
          'mceSelectNode': function (command, ui, value) {
            editor.selection.select(value);
          },
          'mceInsertContent': function (command, ui, value) {
            InsertContent.insertAtCaret(editor, value);
          },
          'mceInsertRawHTML': function (command, ui, value) {
            editor.selection.setContent('tiny_mce_marker');
            var content = editor.getContent();
            editor.setContent(content.replace(/tiny_mce_marker/g, function () {
              return value;
            }));
          },
          'mceInsertNewLine': function (command, ui, value) {
            InsertNewLine.insert(editor, value);
          },
          'mceToggleFormat': function (command, ui, value) {
            self.toggleFormat(value);
          },
          'mceSetContent': function (command, ui, value) {
            editor.setContent(value);
          },
          'Indent,Outdent': function (command) {
            handle(editor, command);
          },
          'mceRepaint': function () {
          },
          'InsertHorizontalRule': function () {
            editor.execCommand('mceInsertContent', false, '<hr />');
          },
          'mceToggleVisualAid': function () {
            editor.hasVisual = !editor.hasVisual;
            editor.addVisual();
          },
          'mceReplaceContent': function (command, ui, value) {
            editor.execCommand('mceInsertContent', false, value.replace(/\{\$selection\}/g, editor.selection.getContent({ format: 'text' })));
          },
          'mceInsertLink': function (command, ui, value) {
            var anchor;
            if (typeof value === 'string') {
              value = { href: value };
            }
            anchor = editor.dom.getParent(editor.selection.getNode(), 'a');
            value.href = value.href.replace(/ /g, '%20');
            if (!anchor || !value.href) {
              editor.formatter.remove('link');
            }
            if (value.href) {
              editor.formatter.apply('link', value, anchor);
            }
          },
          'selectAll': function () {
            var editingHost = editor.dom.getParent(editor.selection.getStart(), NodeType.isContentEditableTrue);
            if (editingHost) {
              var rng = editor.dom.createRng();
              rng.selectNodeContents(editingHost);
              editor.selection.setRng(rng);
            }
          },
          'delete': function () {
            DeleteCommands.deleteCommand(editor);
          },
          'forwardDelete': function () {
            DeleteCommands.forwardDeleteCommand(editor);
          },
          'mceNewDocument': function () {
            editor.setContent('');
          },
          'InsertLineBreak': function (command, ui, value) {
            InsertBr.insert(editor, value);
            return true;
          }
        });
        var alignStates = function (name) {
          return function () {
            var nodes = editor.selection.isCollapsed() ? [editor.dom.getParent(editor.selection.getNode(), editor.dom.isBlock)] : editor.selection.getSelectedBlocks();
            var matches = map$3(nodes, function (node) {
              return !!editor.formatter.matchNode(node, name);
            });
            return inArray$2(matches, true) !== -1;
          };
        };
        self.addCommands({
          'JustifyLeft': alignStates('alignleft'),
          'JustifyCenter': alignStates('aligncenter'),
          'JustifyRight': alignStates('alignright'),
          'JustifyFull': alignStates('alignjustify'),
          'Bold,Italic,Underline,Strikethrough,Superscript,Subscript': function (command) {
            return self.isFormatMatch(command);
          },
          'mceBlockQuote': function () {
            return self.isFormatMatch('blockquote');
          },
          'Outdent': function () {
            return canOutdent(editor);
          },
          'InsertUnorderedList,InsertOrderedList': function (command) {
            var list = editor.dom.getParent(editor.selection.getNode(), 'ul,ol');
            return list && (command === 'insertunorderedlist' && list.tagName === 'UL' || command === 'insertorderedlist' && list.tagName === 'OL');
          }
        }, 'state');
        self.addCommands({
          Undo: function () {
            editor.undoManager.undo();
          },
          Redo: function () {
            editor.undoManager.redo();
          }
        });
        self.addQueryValueHandler('FontName', function () {
          return fontNameQuery(editor);
        }, this);
        self.addQueryValueHandler('FontSize', function () {
          return fontSizeQuery(editor);
        }, this);
      };
      return EditorCommands;
    }();

    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', ' ');
    var EventDispatcher = function () {
      function EventDispatcher(settings) {
        this.bindings = {};
        this.settings = settings || {};
        this.scope = this.settings.scope || this;
        this.toggleEvent = this.settings.toggleEvent || never;
      }
      EventDispatcher.isNative = function (name) {
        return !!nativeEvents[name.toLowerCase()];
      };
      EventDispatcher.prototype.fire = function (name, args) {
        var handlers, i, l, callback;
        name = name.toLowerCase();
        args = args || {};
        args.type = name;
        if (!args.target) {
          args.target = this.scope;
        }
        if (!args.preventDefault) {
          args.preventDefault = function () {
            args.isDefaultPrevented = always;
          };
          args.stopPropagation = function () {
            args.isPropagationStopped = always;
          };
          args.stopImmediatePropagation = function () {
            args.isImmediatePropagationStopped = always;
          };
          args.isDefaultPrevented = never;
          args.isPropagationStopped = never;
          args.isImmediatePropagationStopped = never;
        }
        if (this.settings.beforeFire) {
          this.settings.beforeFire(args);
        }
        handlers = this.bindings[name];
        if (handlers) {
          for (i = 0, l = handlers.length; i < l; i++) {
            callback = handlers[i];
            if (callback.once) {
              this.off(name, callback.func);
            }
            if (args.isImmediatePropagationStopped()) {
              args.stopPropagation();
              return args;
            }
            if (callback.func.call(this.scope, args) === false) {
              args.preventDefault();
              return args;
            }
          }
        }
        return args;
      };
      EventDispatcher.prototype.on = function (name, callback, prepend, extra) {
        var handlers, names, i;
        if (callback === false) {
          callback = never;
        }
        if (callback) {
          var wrappedCallback = { func: callback };
          if (extra) {
            Tools.extend(wrappedCallback, extra);
          }
          names = name.toLowerCase().split(' ');
          i = names.length;
          while (i--) {
            name = names[i];
            handlers = this.bindings[name];
            if (!handlers) {
              handlers = this.bindings[name] = [];
              this.toggleEvent(name, true);
            }
            if (prepend) {
              handlers.unshift(wrappedCallback);
            } else {
              handlers.push(wrappedCallback);
            }
          }
        }
        return this;
      };
      EventDispatcher.prototype.off = function (name, callback) {
        var i, handlers, bindingName, names, hi;
        if (name) {
          names = name.toLowerCase().split(' ');
          i = names.length;
          while (i--) {
            name = names[i];
            handlers = this.bindings[name];
            if (!name) {
              for (bindingName in this.bindings) {
                this.toggleEvent(bindingName, false);
                delete this.bindings[bindingName];
              }
              return this;
            }
            if (handlers) {
              if (!callback) {
                handlers.length = 0;
              } else {
                hi = handlers.length;
                while (hi--) {
                  if (handlers[hi].func === callback) {
                    handlers = handlers.slice(0, hi).concat(handlers.slice(hi + 1));
                    this.bindings[name] = handlers;
                  }
                }
              }
              if (!handlers.length) {
                this.toggleEvent(name, false);
                delete this.bindings[name];
              }
            }
          }
        } else {
          for (name in this.bindings) {
            this.toggleEvent(name, false);
          }
          this.bindings = {};
        }
        return this;
      };
      EventDispatcher.prototype.once = function (name, callback, prepend) {
        return this.on(name, callback, prepend, { once: true });
      };
      EventDispatcher.prototype.has = function (name) {
        name = name.toLowerCase();
        return !(!this.bindings[name] || this.bindings[name].length === 0);
      };
      return EventDispatcher;
    }();

    var getEventDispatcher = function (obj) {
      if (!obj._eventDispatcher) {
        obj._eventDispatcher = new EventDispatcher({
          scope: obj,
          toggleEvent: function (name, state) {
            if (EventDispatcher.isNative(name) && obj.toggleNativeEvent) {
              obj.toggleNativeEvent(name, state);
            }
          }
        });
      }
      return obj._eventDispatcher;
    };
    var Observable = {
      fire: function (name, args, bubble) {
        var self = this;
        if (self.removed && name !== 'remove' && name !== 'detach') {
          return args;
        }
        var dispatcherArgs = getEventDispatcher(self).fire(name, args);
        if (bubble !== false && self.parent) {
          var parent_1 = self.parent();
          while (parent_1 && !dispatcherArgs.isPropagationStopped()) {
            parent_1.fire(name, dispatcherArgs, false);
            parent_1 = parent_1.parent();
          }
        }
        return dispatcherArgs;
      },
      on: function (name, callback, prepend) {
        return getEventDispatcher(this).on(name, callback, prepend);
      },
      off: function (name, callback) {
        return getEventDispatcher(this).off(name, callback);
      },
      once: function (name, callback) {
        return getEventDispatcher(this).once(name, callback);
      },
      hasEventListeners: function (name) {
        return getEventDispatcher(this).has(name);
      }
    };

    var internalContentEditableAttr = 'data-mce-contenteditable';
    var toggleClass = function (elm, cls, state) {
      if (has$2(elm, cls) && state === false) {
        remove$4(elm, cls);
      } else if (state) {
        add$3(elm, cls);
      }
    };
    var setEditorCommandState = function (editor, cmd, state) {
      try {
        editor.getDoc().execCommand(cmd, false, state);
      } catch (ex) {
      }
    };
    var setContentEditable = function (elm, state) {
      elm.dom().contentEditable = state ? 'true' : 'false';
    };
    var switchOffContentEditableTrue = function (elm) {
      each(descendants$1(elm, '*[contenteditable="true"]'), function (elm) {
        set(elm, internalContentEditableAttr, 'true');
        setContentEditable(elm, false);
      });
    };
    var switchOnContentEditableTrue = function (elm) {
      each(descendants$1(elm, '*[' + internalContentEditableAttr + '="true"]'), function (elm) {
        remove$1(elm, internalContentEditableAttr);
        setContentEditable(elm, true);
      });
    };
    var removeFakeSelection = function (editor) {
      Option.from(editor.selection.getNode()).each(function (elm) {
        elm.removeAttribute('data-mce-selected');
      });
    };
    var restoreFakeSelection = function (editor) {
      editor.selection.setRng(editor.selection.getRng());
    };
    var toggleReadOnly = function (editor, state) {
      var body = Element.fromDom(editor.getBody());
      toggleClass(body, 'mce-content-readonly', state);
      if (state) {
        editor.selection.controlSelection.hideResizeRect();
        editor._selectionOverrides.hideFakeCaret();
        removeFakeSelection(editor);
        editor.readonly = true;
        setContentEditable(body, false);
        switchOffContentEditableTrue(body);
      } else {
        editor.readonly = false;
        setContentEditable(body, true);
        switchOnContentEditableTrue(body);
        setEditorCommandState(editor, 'StyleWithCSS', false);
        setEditorCommandState(editor, 'enableInlineTableEditing', false);
        setEditorCommandState(editor, 'enableObjectResizing', false);
        if (EditorFocus.hasEditorOrUiFocus(editor)) {
          editor.focus();
        }
        restoreFakeSelection(editor);
        editor.nodeChanged();
      }
    };
    var isReadOnly = function (editor) {
      return editor.readonly === true;
    };
    var registerFilters = function (editor) {
      editor.parser.addAttributeFilter('contenteditable', function (nodes) {
        if (isReadOnly(editor)) {
          each(nodes, function (node) {
            node.attr(internalContentEditableAttr, node.attr('contenteditable'));
            node.attr('contenteditable', 'false');
          });
        }
      });
      editor.serializer.addAttributeFilter(internalContentEditableAttr, function (nodes) {
        if (isReadOnly(editor)) {
          each(nodes, function (node) {
            node.attr('contenteditable', node.attr(internalContentEditableAttr));
          });
        }
      });
      editor.serializer.addTempAttr(internalContentEditableAttr);
    };
    var registerReadOnlyContentFilters = function (editor) {
      if (editor.serializer) {
        registerFilters(editor);
      } else {
        editor.on('PreInit', function () {
          registerFilters(editor);
        });
      }
    };
    var isClickEvent = function (e) {
      return e.type === 'click';
    };
    var isInAnchor = function (editor, target) {
      return editor.dom.getParent(target, 'a') !== null;
    };
    var preventReadOnlyEvents = function (editor, e) {
      var target = e.target;
      if (isClickEvent(e) && !VK.metaKeyPressed(e) && isInAnchor(editor, target)) {
        e.preventDefault();
      }
    };
    var registerReadOnlySelectionBlockers = function (editor) {
      editor.on('ShowCaret', function (e) {
        if (isReadOnly(editor)) {
          e.preventDefault();
        }
      });
      editor.on('ObjectSelected', function (e) {
        if (isReadOnly(editor)) {
          e.preventDefault();
        }
      });
    };

    var DOM$8 = DOMUtils$1.DOM;
    var customEventRootDelegates;
    var getEventTarget = function (editor, eventName) {
      if (eventName === 'selectionchange') {
        return editor.getDoc();
      }
      if (!editor.inline && /^mouse|touch|click|contextmenu|drop|dragover|dragend/.test(eventName)) {
        return editor.getDoc().documentElement;
      }
      if (editor.settings.event_root) {
        if (!editor.eventRoot) {
          editor.eventRoot = DOM$8.select(editor.settings.event_root)[0];
        }
        return editor.eventRoot;
      }
      return editor.getBody();
    };
    var isListening = function (editor) {
      return !editor.hidden && !isReadOnly(editor);
    };
    var fireEvent = function (editor, eventName, e) {
      if (isListening(editor)) {
        editor.fire(eventName, e);
      } else if (isReadOnly(editor)) {
        preventReadOnlyEvents(editor, e);
      }
    };
    var bindEventDelegate = function (editor, eventName) {
      var eventRootElm, delegate;
      if (!editor.delegates) {
        editor.delegates = {};
      }
      if (editor.delegates[eventName] || editor.removed) {
        return;
      }
      eventRootElm = getEventTarget(editor, eventName);
      if (editor.settings.event_root) {
        if (!customEventRootDelegates) {
          customEventRootDelegates = {};
          editor.editorManager.on('removeEditor', function () {
            var name;
            if (!editor.editorManager.activeEditor) {
              if (customEventRootDelegates) {
                for (name in customEventRootDelegates) {
                  editor.dom.unbind(getEventTarget(editor, name));
                }
                customEventRootDelegates = null;
              }
            }
          });
        }
        if (customEventRootDelegates[eventName]) {
          return;
        }
        delegate = function (e) {
          var target = e.target;
          var editors = editor.editorManager.get();
          var i = editors.length;
          while (i--) {
            var body = editors[i].getBody();
            if (body === target || DOM$8.isChildOf(target, body)) {
              fireEvent(editors[i], eventName, e);
            }
          }
        };
        customEventRootDelegates[eventName] = delegate;
        DOM$8.bind(eventRootElm, eventName, delegate);
      } else {
        delegate = function (e) {
          fireEvent(editor, eventName, e);
        };
        DOM$8.bind(eventRootElm, eventName, delegate);
        editor.delegates[eventName] = delegate;
      }
    };
    var EditorObservable = __assign(__assign({}, Observable), {
      bindPendingEventDelegates: function () {
        var self = this;
        Tools.each(self._pendingNativeEvents, function (name) {
          bindEventDelegate(self, name);
        });
      },
      toggleNativeEvent: function (name, state) {
        var self = this;
        if (name === 'focus' || name === 'blur') {
          return;
        }
        if (state) {
          if (self.initialized) {
            bindEventDelegate(self, name);
          } else {
            if (!self._pendingNativeEvents) {
              self._pendingNativeEvents = [name];
            } else {
              self._pendingNativeEvents.push(name);
            }
          }
        } else if (self.initialized) {
          self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]);
          delete self.delegates[name];
        }
      },
      unbindAllNativeEvents: function () {
        var self = this;
        var body = self.getBody();
        var dom = self.dom;
        var name;
        if (self.delegates) {
          for (name in self.delegates) {
            self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]);
          }
          delete self.delegates;
        }
        if (!self.inline && body && dom) {
          body.onload = null;
          dom.unbind(self.getWin());
          dom.unbind(self.getDoc());
        }
        if (dom) {
          dom.unbind(body);
          dom.unbind(self.getContainer());
        }
      }
    });

    var defaultModes = [
      'design',
      'readonly'
    ];
    var switchToMode = function (editor, activeMode, availableModes, mode) {
      var oldMode = availableModes[activeMode.get()];
      var newMode = availableModes[mode];
      try {
        newMode.activate();
      } catch (e) {
        domGlobals.console.error('problem while activating editor mode ' + mode + ':', e);
        return;
      }
      oldMode.deactivate();
      if (oldMode.editorReadOnly !== newMode.editorReadOnly) {
        toggleReadOnly(editor, newMode.editorReadOnly);
      }
      activeMode.set(mode);
      fireSwitchMode(editor, mode);
    };
    var setMode = function (editor, availableModes, activeMode, mode) {
      if (mode === activeMode.get()) {
        return;
      } else if (!has(availableModes, mode)) {
        throw new Error('Editor mode \'' + mode + '\' is invalid');
      }
      if (editor.initialized) {
        switchToMode(editor, activeMode, availableModes, mode);
      } else {
        editor.on('init', function () {
          return switchToMode(editor, activeMode, availableModes, mode);
        });
      }
    };
    var registerMode = function (availableModes, mode, api) {
      var _a;
      if (contains(defaultModes, mode)) {
        throw new Error('Cannot override default mode ' + mode);
      }
      return __assign(__assign({}, availableModes), (_a = {}, _a[mode] = __assign(__assign({}, api), {
        deactivate: function () {
          try {
            api.deactivate();
          } catch (e) {
            domGlobals.console.error('problem while deactivating editor mode ' + mode + ':', e);
          }
        }
      }), _a));
    };

    var create$4 = function (editor) {
      var activeMode = Cell('design');
      var availableModes = Cell({
        design: {
          activate: noop,
          deactivate: noop,
          editorReadOnly: false
        },
        readonly: {
          activate: noop,
          deactivate: noop,
          editorReadOnly: true
        }
      });
      registerReadOnlyContentFilters(editor);
      registerReadOnlySelectionBlockers(editor);
      return {
        isReadOnly: function () {
          return isReadOnly(editor);
        },
        set: function (mode) {
          return setMode(editor, availableModes.get(), activeMode, mode);
        },
        get: function () {
          return activeMode.get();
        },
        register: function (mode, api) {
          availableModes.set(registerMode(availableModes.get(), mode, api));
        }
      };
    };

    var each$g = Tools.each, explode$3 = Tools.explode;
    var keyCodeLookup = {
      f1: 112,
      f2: 113,
      f3: 114,
      f4: 115,
      f5: 116,
      f6: 117,
      f7: 118,
      f8: 119,
      f9: 120,
      f10: 121,
      f11: 122,
      f12: 123
    };
    var modifierNames = Tools.makeMap('alt,ctrl,shift,meta,access');
    var Shortcuts = function () {
      function Shortcuts(editor) {
        this.shortcuts = {};
        this.pendingPatterns = [];
        this.editor = editor;
        var self = this;
        editor.on('keyup keypress keydown', function (e) {
          if ((self.hasModifier(e) || self.isFunctionKey(e)) && !e.isDefaultPrevented()) {
            each$g(self.shortcuts, function (shortcut) {
              if (self.matchShortcut(e, shortcut)) {
                self.pendingPatterns = shortcut.subpatterns.slice(0);
                if (e.type === 'keydown') {
                  self.executeShortcutAction(shortcut);
                }
                return true;
              }
            });
            if (self.matchShortcut(e, self.pendingPatterns[0])) {
              if (self.pendingPatterns.length === 1) {
                if (e.type === 'keydown') {
                  self.executeShortcutAction(self.pendingPatterns[0]);
                }
              }
              self.pendingPatterns.shift();
            }
          }
        });
      }
      Shortcuts.prototype.add = function (pattern, desc, cmdFunc, scope) {
        var self = this;
        var cmd;
        cmd = cmdFunc;
        if (typeof cmdFunc === 'string') {
          cmdFunc = function () {
            self.editor.execCommand(cmd, false, null);
          };
        } else if (Tools.isArray(cmd)) {
          cmdFunc = function () {
            self.editor.execCommand(cmd[0], cmd[1], cmd[2]);
          };
        }
        each$g(explode$3(Tools.trim(pattern)), function (pattern) {
          var shortcut = self.createShortcut(pattern, desc, cmdFunc, scope);
          self.shortcuts[shortcut.id] = shortcut;
        });
        return true;
      };
      Shortcuts.prototype.remove = function (pattern) {
        var shortcut = this.createShortcut(pattern);
        if (this.shortcuts[shortcut.id]) {
          delete this.shortcuts[shortcut.id];
          return true;
        }
        return false;
      };
      Shortcuts.prototype.parseShortcut = function (pattern) {
        var id, key;
        var shortcut = {};
        each$g(explode$3(pattern.toLowerCase(), '+'), function (value) {
          if (value in modifierNames) {
            shortcut[value] = true;
          } else {
            if (/^[0-9]{2,}$/.test(value)) {
              shortcut.keyCode = parseInt(value, 10);
            } else {
              shortcut.charCode = value.charCodeAt(0);
              shortcut.keyCode = keyCodeLookup[value] || value.toUpperCase().charCodeAt(0);
            }
          }
        });
        id = [shortcut.keyCode];
        for (key in modifierNames) {
          if (shortcut[key]) {
            id.push(key);
          } else {
            shortcut[key] = false;
          }
        }
        shortcut.id = id.join(',');
        if (shortcut.access) {
          shortcut.alt = true;
          if (Env.mac) {
            shortcut.ctrl = true;
          } else {
            shortcut.shift = true;
          }
        }
        if (shortcut.meta) {
          if (Env.mac) {
            shortcut.meta = true;
          } else {
            shortcut.ctrl = true;
            shortcut.meta = false;
          }
        }
        return shortcut;
      };
      Shortcuts.prototype.createShortcut = function (pattern, desc, cmdFunc, scope) {
        var shortcuts;
        shortcuts = Tools.map(explode$3(pattern, '>'), this.parseShortcut);
        shortcuts[shortcuts.length - 1] = Tools.extend(shortcuts[shortcuts.length - 1], {
          func: cmdFunc,
          scope: scope || this.editor
        });
        return Tools.extend(shortcuts[0], {
          desc: this.editor.translate(desc),
          subpatterns: shortcuts.slice(1)
        });
      };
      Shortcuts.prototype.hasModifier = function (e) {
        return e.altKey || e.ctrlKey || e.metaKey;
      };
      Shortcuts.prototype.isFunctionKey = function (e) {
        return e.type === 'keydown' && e.keyCode >= 112 && e.keyCode <= 123;
      };
      Shortcuts.prototype.matchShortcut = function (e, shortcut) {
        if (!shortcut) {
          return false;
        }
        if (shortcut.ctrl !== e.ctrlKey || shortcut.meta !== e.metaKey) {
          return false;
        }
        if (shortcut.alt !== e.altKey || shortcut.shift !== e.shiftKey) {
          return false;
        }
        if (e.keyCode === shortcut.keyCode || e.charCode && e.charCode === shortcut.charCode) {
          e.preventDefault();
          return true;
        }
        return false;
      };
      Shortcuts.prototype.executeShortcutAction = function (shortcut) {
        return shortcut.func ? shortcut.func.call(shortcut.scope) : null;
      };
      return Shortcuts;
    }();

    var create$5 = function () {
      var buttons = {};
      var menuItems = {};
      var popups = {};
      var icons = {};
      var contextMenus = {};
      var contextToolbars = {};
      var sidebars = {};
      var add = function (collection, type) {
        return function (name, spec) {
          return collection[name.toLowerCase()] = __assign(__assign({}, spec), { type: type });
        };
      };
      var addIcon = function (name, svgData) {
        return icons[name.toLowerCase()] = svgData;
      };
      return {
        addButton: add(buttons, 'button'),
        addGroupToolbarButton: add(buttons, 'grouptoolbarbutton'),
        addToggleButton: add(buttons, 'togglebutton'),
        addMenuButton: add(buttons, 'menubutton'),
        addSplitButton: add(buttons, 'splitbutton'),
        addMenuItem: add(menuItems, 'menuitem'),
        addNestedMenuItem: add(menuItems, 'nestedmenuitem'),
        addToggleMenuItem: add(menuItems, 'togglemenuitem'),
        addAutocompleter: add(popups, 'autocompleter'),
        addContextMenu: add(contextMenus, 'contextmenu'),
        addContextToolbar: add(contextToolbars, 'contexttoolbar'),
        addContextForm: add(contextToolbars, 'contextform'),
        addSidebar: add(sidebars, 'sidebar'),
        addIcon: addIcon,
        getAll: function () {
          return {
            buttons: buttons,
            menuItems: menuItems,
            icons: icons,
            popups: popups,
            contextMenus: contextMenus,
            contextToolbars: contextToolbars,
            sidebars: sidebars
          };
        }
      };
    };

    var registry = function () {
      var bridge = create$5();
      return {
        addAutocompleter: bridge.addAutocompleter,
        addButton: bridge.addButton,
        addContextForm: bridge.addContextForm,
        addContextMenu: bridge.addContextMenu,
        addContextToolbar: bridge.addContextToolbar,
        addIcon: bridge.addIcon,
        addMenuButton: bridge.addMenuButton,
        addMenuItem: bridge.addMenuItem,
        addNestedMenuItem: bridge.addNestedMenuItem,
        addSidebar: bridge.addSidebar,
        addSplitButton: bridge.addSplitButton,
        addToggleButton: bridge.addToggleButton,
        addGroupToolbarButton: bridge.addGroupToolbarButton,
        addToggleMenuItem: bridge.addToggleMenuItem,
        getAll: bridge.getAll
      };
    };

    var each$h = Tools.each, trim$4 = Tools.trim;
    var queryParts = 'source protocol authority userInfo user password host port relative path directory file query anchor'.split(' ');
    var DEFAULT_PORTS = {
      ftp: 21,
      http: 80,
      https: 443,
      mailto: 25
    };
    var URI = function () {
      function URI(url, settings) {
        url = trim$4(url);
        this.settings = settings || {};
        var baseUri = this.settings.base_uri;
        var self = this;
        if (/^([\w\-]+):([^\/]{2})/i.test(url) || /^\s*#/.test(url)) {
          self.source = url;
          return;
        }
        var isProtocolRelative = url.indexOf('//') === 0;
        if (url.indexOf('/') === 0 && !isProtocolRelative) {
          url = (baseUri ? baseUri.protocol || 'http' : 'http') + '://mce_host' + url;
        }
        if (!/^[\w\-]*:?\/\//.test(url)) {
          var baseUrl = this.settings.base_uri ? this.settings.base_uri.path : new URI(domGlobals.document.location.href).directory;
          if (this.settings.base_uri && this.settings.base_uri.protocol == '') {
            url = '//mce_host' + self.toAbsPath(baseUrl, url);
          } else {
            var match = /([^#?]*)([#?]?.*)/.exec(url);
            url = (baseUri && baseUri.protocol || 'http') + '://mce_host' + self.toAbsPath(baseUrl, match[1]) + match[2];
          }
        }
        url = url.replace(/@@/g, '(mce_at)');
        var urlMatch = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(url);
        each$h(queryParts, function (v, i) {
          var part = urlMatch[i];
          if (part) {
            part = part.replace(/\(mce_at\)/g, '@@');
          }
          self[v] = part;
        });
        if (baseUri) {
          if (!self.protocol) {
            self.protocol = baseUri.protocol;
          }
          if (!self.userInfo) {
            self.userInfo = baseUri.userInfo;
          }
          if (!self.port && self.host === 'mce_host') {
            self.port = baseUri.port;
          }
          if (!self.host || self.host === 'mce_host') {
            self.host = baseUri.host;
          }
          self.source = '';
        }
        if (isProtocolRelative) {
          self.protocol = '';
        }
      }
      URI.parseDataUri = function (uri) {
        var type;
        var uriComponents = decodeURIComponent(uri).split(',');
        var matches = /data:([^;]+)/.exec(uriComponents[0]);
        if (matches) {
          type = matches[1];
        }
        return {
          type: type,
          data: uriComponents[1]
        };
      };
      URI.getDocumentBaseUrl = function (loc) {
        var baseUrl;
        if (loc.protocol.indexOf('http') !== 0 && loc.protocol !== 'file:') {
          baseUrl = loc.href;
        } else {
          baseUrl = loc.protocol + '//' + loc.host + loc.pathname;
        }
        if (/^[^:]+:\/\/\/?[^\/]+\//.test(baseUrl)) {
          baseUrl = baseUrl.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');
          if (!/[\/\\]$/.test(baseUrl)) {
            baseUrl += '/';
          }
        }
        return baseUrl;
      };
      URI.prototype.setPath = function (path) {
        var pathMatch = /^(.*?)\/?(\w+)?$/.exec(path);
        this.path = pathMatch[0];
        this.directory = pathMatch[1];
        this.file = pathMatch[2];
        this.source = '';
        this.getURI();
      };
      URI.prototype.toRelative = function (uri) {
        var output;
        if (uri === './') {
          return uri;
        }
        var relativeUri = new URI(uri, { base_uri: this });
        if (relativeUri.host !== 'mce_host' && this.host !== relativeUri.host && relativeUri.host || this.port !== relativeUri.port || this.protocol !== relativeUri.protocol && relativeUri.protocol !== '') {
          return relativeUri.getURI();
        }
        var tu = this.getURI(), uu = relativeUri.getURI();
        if (tu === uu || tu.charAt(tu.length - 1) === '/' && tu.substr(0, tu.length - 1) === uu) {
          return tu;
        }
        output = this.toRelPath(this.path, relativeUri.path);
        if (relativeUri.query) {
          output += '?' + relativeUri.query;
        }
        if (relativeUri.anchor) {
          output += '#' + relativeUri.anchor;
        }
        return output;
      };
      URI.prototype.toAbsolute = function (uri, noHost) {
        var absoluteUri = new URI(uri, { base_uri: this });
        return absoluteUri.getURI(noHost && this.isSameOrigin(absoluteUri));
      };
      URI.prototype.isSameOrigin = function (uri) {
        if (this.host == uri.host && this.protocol == uri.protocol) {
          if (this.port == uri.port) {
            return true;
          }
          var defaultPort = DEFAULT_PORTS[this.protocol];
          if (defaultPort && (this.port || defaultPort) == (uri.port || defaultPort)) {
            return true;
          }
        }
        return false;
      };
      URI.prototype.toRelPath = function (base, path) {
        var items, breakPoint = 0, out = '', i, l;
        var normalizedBase = base.substring(0, base.lastIndexOf('/')).split('/');
        items = path.split('/');
        if (normalizedBase.length >= items.length) {
          for (i = 0, l = normalizedBase.length; i < l; i++) {
            if (i >= items.length || normalizedBase[i] !== items[i]) {
              breakPoint = i + 1;
              break;
            }
          }
        }
        if (normalizedBase.length < items.length) {
          for (i = 0, l = items.length; i < l; i++) {
            if (i >= normalizedBase.length || normalizedBase[i] !== items[i]) {
              breakPoint = i + 1;
              break;
            }
          }
        }
        if (breakPoint === 1) {
          return path;
        }
        for (i = 0, l = normalizedBase.length - (breakPoint - 1); i < l; i++) {
          out += '../';
        }
        for (i = breakPoint - 1, l = items.length; i < l; i++) {
          if (i !== breakPoint - 1) {
            out += '/' + items[i];
          } else {
            out += items[i];
          }
        }
        return out;
      };
      URI.prototype.toAbsPath = function (base, path) {
        var i, nb = 0, o = [], tr, outPath;
        tr = /\/$/.test(path) ? '/' : '';
        var normalizedBase = base.split('/');
        var normalizedPath = path.split('/');
        each$h(normalizedBase, function (k) {
          if (k) {
            o.push(k);
          }
        });
        normalizedBase = o;
        for (i = normalizedPath.length - 1, o = []; i >= 0; i--) {
          if (normalizedPath[i].length === 0 || normalizedPath[i] === '.') {
            continue;
          }
          if (normalizedPath[i] === '..') {
            nb++;
            continue;
          }
          if (nb > 0) {
            nb--;
            continue;
          }
          o.push(normalizedPath[i]);
        }
        i = normalizedBase.length - nb;
        if (i <= 0) {
          outPath = reverse(o).join('/');
        } else {
          outPath = normalizedBase.slice(0, i).join('/') + '/' + reverse(o).join('/');
        }
        if (outPath.indexOf('/') !== 0) {
          outPath = '/' + outPath;
        }
        if (tr && outPath.lastIndexOf('/') !== outPath.length - 1) {
          outPath += tr;
        }
        return outPath;
      };
      URI.prototype.getURI = function (noProtoHost) {
        if (noProtoHost === void 0) {
          noProtoHost = false;
        }
        var s;
        if (!this.source || noProtoHost) {
          s = '';
          if (!noProtoHost) {
            if (this.protocol) {
              s += this.protocol + '://';
            } else {
              s += '//';
            }
            if (this.userInfo) {
              s += this.userInfo + '@';
            }
            if (this.host) {
              s += this.host;
            }
            if (this.port) {
              s += ':' + this.port;
            }
          }
          if (this.path) {
            s += this.path;
          }
          if (this.query) {
            s += '?' + this.query;
          }
          if (this.anchor) {
            s += '#' + this.anchor;
          }
          this.source = s;
        }
        return this.source;
      };
      return URI;
    }();

    var DOM$9 = DOMUtils$1.DOM;
    var extend$3 = Tools.extend, each$i = Tools.each;
    var resolve$3 = Tools.resolve;
    var ie$1 = Env.ie;
    var Editor = function () {
      function Editor(id, settings, editorManager) {
        var _this = this;
        this.plugins = {};
        this.contentCSS = [];
        this.contentStyles = [];
        this.loadedCSS = {};
        this.isNotDirty = false;
        this.editorManager = editorManager;
        this.documentBaseUrl = editorManager.documentBaseURL;
        extend$3(this, EditorObservable);
        this.settings = getEditorSettings(this, id, this.documentBaseUrl, editorManager.defaultSettings, settings);
        if (this.settings.suffix) {
          editorManager.suffix = this.settings.suffix;
        }
        this.suffix = editorManager.suffix;
        if (this.settings.base_url) {
          editorManager._setBaseUrl(this.settings.base_url);
        }
        this.baseUri = editorManager.baseURI;
        if (this.settings.referrer_policy) {
          ScriptLoader.ScriptLoader._setReferrerPolicy(this.settings.referrer_policy);
          DOMUtils$1.DOM.styleSheetLoader._setReferrerPolicy(this.settings.referrer_policy);
        }
        AddOnManager$1.languageLoad = this.settings.language_load;
        AddOnManager$1.baseURL = editorManager.baseURL;
        this.id = id;
        this.setDirty(false);
        this.documentBaseURI = new URI(this.settings.document_base_url, { base_uri: this.baseUri });
        this.baseURI = this.baseUri;
        this.inline = !!this.settings.inline;
        this.shortcuts = new Shortcuts(this);
        this.editorCommands = new EditorCommands(this);
        if (this.settings.cache_suffix) {
          Env.cacheSuffix = this.settings.cache_suffix.replace(/^[\?\&]+/, '');
        }
        this.ui = { registry: registry() };
        var self = this;
        var modeInstance = create$4(self);
        this.mode = modeInstance;
        this.setMode = modeInstance.set;
        editorManager.fire('SetupEditor', { editor: this });
        this.execCallback('setup', this);
        this.$ = DomQuery.overrideDefaults(function () {
          return {
            context: _this.inline ? _this.getBody() : _this.getDoc(),
            element: _this.getBody()
          };
        });
      }
      Editor.prototype.render = function () {
        Render.render(this);
      };
      Editor.prototype.focus = function (skipFocus) {
        EditorFocus.focus(this, skipFocus);
      };
      Editor.prototype.hasFocus = function () {
        return EditorFocus.hasFocus(this);
      };
      Editor.prototype.execCallback = function (name) {
        var x = [];
        for (var _i = 1; _i < arguments.length; _i++) {
          x[_i - 1] = arguments[_i];
        }
        var self = this;
        var callback = self.settings[name], scope;
        if (!callback) {
          return;
        }
        if (self.callbackLookup && (scope = self.callbackLookup[name])) {
          callback = scope.func;
          scope = scope.scope;
        }
        if (typeof callback === 'string') {
          scope = callback.replace(/\.\w+$/, '');
          scope = scope ? resolve$3(scope) : 0;
          callback = resolve$3(callback);
          self.callbackLookup = self.callbackLookup || {};
          self.callbackLookup[name] = {
            func: callback,
            scope: scope
          };
        }
        return callback.apply(scope || self, Array.prototype.slice.call(arguments, 1));
      };
      Editor.prototype.translate = function (text) {
        return I18n.translate(text);
      };
      Editor.prototype.getParam = function (name, defaultVal, type) {
        return getParam(this, name, defaultVal, type);
      };
      Editor.prototype.nodeChanged = function (args) {
        this._nodeChangeDispatcher.nodeChanged(args);
      };
      Editor.prototype.addCommand = function (name, callback, scope) {
        this.editorCommands.addCommand(name, callback, scope);
      };
      Editor.prototype.addQueryStateHandler = function (name, callback, scope) {
        this.editorCommands.addQueryStateHandler(name, callback, scope);
      };
      Editor.prototype.addQueryValueHandler = function (name, callback, scope) {
        this.editorCommands.addQueryValueHandler(name, callback, scope);
      };
      Editor.prototype.addShortcut = function (pattern, desc, cmdFunc, scope) {
        this.shortcuts.add(pattern, desc, cmdFunc, scope);
      };
      Editor.prototype.execCommand = function (cmd, ui, value, args) {
        return this.editorCommands.execCommand(cmd, ui, value, args);
      };
      Editor.prototype.queryCommandState = function (cmd) {
        return this.editorCommands.queryCommandState(cmd);
      };
      Editor.prototype.queryCommandValue = function (cmd) {
        return this.editorCommands.queryCommandValue(cmd);
      };
      Editor.prototype.queryCommandSupported = function (cmd) {
        return this.editorCommands.queryCommandSupported(cmd);
      };
      Editor.prototype.show = function () {
        var self = this;
        if (self.hidden) {
          self.hidden = false;
          if (self.inline) {
            self.getBody().contentEditable = 'true';
          } else {
            DOM$9.show(self.getContainer());
            DOM$9.hide(self.id);
          }
          self.load();
          self.fire('show');
        }
      };
      Editor.prototype.hide = function () {
        var self = this, doc = self.getDoc();
        if (!self.hidden) {
          if (ie$1 && doc && !self.inline) {
            doc.execCommand('SelectAll');
          }
          self.save();
          if (self.inline) {
            self.getBody().contentEditable = 'false';
            if (self === self.editorManager.focusedEditor) {
              self.editorManager.focusedEditor = null;
            }
          } else {
            DOM$9.hide(self.getContainer());
            DOM$9.setStyle(self.id, 'display', self.orgDisplay);
          }
          self.hidden = true;
          self.fire('hide');
        }
      };
      Editor.prototype.isHidden = function () {
        return !!this.hidden;
      };
      Editor.prototype.setProgressState = function (state, time) {
        this.fire('ProgressState', {
          state: state,
          time: time
        });
      };
      Editor.prototype.load = function (args) {
        var self = this;
        var elm = self.getElement(), html;
        if (self.removed) {
          return '';
        }
        if (elm) {
          args = args || {};
          args.load = true;
          var value = NodeType.isTextareaOrInput(elm) ? elm.value : elm.innerHTML;
          html = self.setContent(value, args);
          args.element = elm;
          if (!args.no_events) {
            self.fire('LoadContent', args);
          }
          args.element = elm = null;
          return html;
        }
      };
      Editor.prototype.save = function (args) {
        var self = this;
        var elm = self.getElement(), html, form;
        if (!elm || !self.initialized || self.removed) {
          return;
        }
        args = args || {};
        args.save = true;
        args.element = elm;
        html = args.content = self.getContent(args);
        if (!args.no_events) {
          self.fire('SaveContent', args);
        }
        if (args.format === 'raw') {
          self.fire('RawSaveContent', args);
        }
        html = args.content;
        if (!NodeType.isTextareaOrInput(elm)) {
          if (args.is_removing || !self.inline) {
            elm.innerHTML = html;
          }
          if (form = DOM$9.getParent(self.id, 'form')) {
            each$i(form.elements, function (elm) {
              if (elm.name === self.id) {
                elm.value = html;
                return false;
              }
            });
          }
        } else {
          elm.value = html;
        }
        args.element = elm = null;
        if (args.set_dirty !== false) {
          self.setDirty(false);
        }
        return html;
      };
      Editor.prototype.setContent = function (content, args) {
        return setContent(this, content, args);
      };
      Editor.prototype.getContent = function (args) {
        return getContent(this, args);
      };
      Editor.prototype.insertContent = function (content, args) {
        if (args) {
          content = extend$3({ content: content }, args);
        }
        this.execCommand('mceInsertContent', false, content);
      };
      Editor.prototype.resetContent = function (initialContent) {
        if (initialContent === undefined) {
          setContent(this, this.startContent, { format: 'raw' });
        } else {
          setContent(this, initialContent);
        }
        this.undoManager.reset();
        this.setDirty(false);
        this.nodeChanged();
      };
      Editor.prototype.isDirty = function () {
        return !this.isNotDirty;
      };
      Editor.prototype.setDirty = function (state) {
        var oldState = !this.isNotDirty;
        this.isNotDirty = !state;
        if (state && state !== oldState) {
          this.fire('dirty');
        }
      };
      Editor.prototype.getContainer = function () {
        var self = this;
        if (!self.container) {
          self.container = DOM$9.get(self.editorContainer || self.id + '_parent');
        }
        return self.container;
      };
      Editor.prototype.getContentAreaContainer = function () {
        return this.contentAreaContainer;
      };
      Editor.prototype.getElement = function () {
        if (!this.targetElm) {
          this.targetElm = DOM$9.get(this.id);
        }
        return this.targetElm;
      };
      Editor.prototype.getWin = function () {
        var self = this;
        var elm;
        if (!self.contentWindow) {
          elm = self.iframeElement;
          if (elm) {
            self.contentWindow = elm.contentWindow;
          }
        }
        return self.contentWindow;
      };
      Editor.prototype.getDoc = function () {
        var self = this;
        var win;
        if (!self.contentDocument) {
          win = self.getWin();
          if (win) {
            self.contentDocument = win.document;
          }
        }
        return self.contentDocument;
      };
      Editor.prototype.getBody = function () {
        var doc = this.getDoc();
        return this.bodyElement || (doc ? doc.body : null);
      };
      Editor.prototype.convertURL = function (url, name, elm) {
        var self = this, settings = self.settings;
        if (settings.urlconverter_callback) {
          return self.execCallback('urlconverter_callback', url, elm, true, name);
        }
        if (!settings.convert_urls || elm && elm.nodeName === 'LINK' || url.indexOf('file:') === 0 || url.length === 0) {
          return url;
        }
        if (settings.relative_urls) {
          return self.documentBaseURI.toRelative(url);
        }
        url = self.documentBaseURI.toAbsolute(url, settings.remove_script_host);
        return url;
      };
      Editor.prototype.addVisual = function (elm) {
        var self = this;
        var settings = self.settings;
        var dom = self.dom;
        var cls;
        elm = elm || self.getBody();
        if (self.hasVisual === undefined) {
          self.hasVisual = settings.visual;
        }
        each$i(dom.select('table,a', elm), function (elm) {
          var value;
          switch (elm.nodeName) {
          case 'TABLE':
            cls = settings.visual_table_class || 'mce-item-table';
            value = dom.getAttrib(elm, 'border');
            if ((!value || value === '0') && self.hasVisual) {
              dom.addClass(elm, cls);
            } else {
              dom.removeClass(elm, cls);
            }
            return;
          case 'A':
            if (!dom.getAttrib(elm, 'href')) {
              value = dom.getAttrib(elm, 'name') || elm.id;
              cls = settings.visual_anchor_class || 'mce-item-anchor';
              if (value && self.hasVisual) {
                dom.addClass(elm, cls);
              } else {
                dom.removeClass(elm, cls);
              }
            }
            return;
          }
        });
        self.fire('VisualAid', {
          element: elm,
          hasVisual: self.hasVisual
        });
      };
      Editor.prototype.remove = function () {
        remove$6(this);
      };
      Editor.prototype.destroy = function (automatic) {
        destroy(this, automatic);
      };
      Editor.prototype.uploadImages = function (callback) {
        return this.editorUpload.uploadImages(callback);
      };
      Editor.prototype._scanForImages = function () {
        return this.editorUpload.scanForImages();
      };
      Editor.prototype.addButton = function () {
        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');
      };
      Editor.prototype.addSidebar = function () {
        throw new Error('editor.addSidebar has been removed in tinymce 5x, use editor.ui.registry.addSidebar instead');
      };
      Editor.prototype.addMenuItem = function () {
        throw new Error('editor.addMenuItem has been removed in tinymce 5x, use editor.ui.registry.addMenuItem instead');
      };
      Editor.prototype.addContextToolbar = function () {
        throw new Error('editor.addContextToolbar has been removed in tinymce 5x, use editor.ui.registry.addContextToolbar instead');
      };
      return Editor;
    }();

    var DOM$a = DOMUtils$1.DOM;
    var explode$4 = Tools.explode, each$j = Tools.each, extend$4 = Tools.extend;
    var instanceCounter = 0, boundGlobalEvents = false;
    var beforeUnloadDelegate;
    var legacyEditors = [];
    var editors = [];
    var isValidLegacyKey = function (id) {
      return id !== 'length';
    };
    var globalEventDelegate = function (e) {
      var type = e.type;
      each$j(EditorManager.get(), function (editor) {
        switch (type) {
        case 'scroll':
          editor.fire('ScrollWindow', e);
          break;
        case 'resize':
          editor.fire('ResizeWindow', e);
          break;
        }
      });
    };
    var toggleGlobalEvents = function (state) {
      if (state !== boundGlobalEvents) {
        if (state) {
          DomQuery(window).on('resize scroll', globalEventDelegate);
        } else {
          DomQuery(window).off('resize scroll', globalEventDelegate);
        }
        boundGlobalEvents = state;
      }
    };
    var removeEditorFromList = function (targetEditor) {
      var oldEditors = editors;
      delete legacyEditors[targetEditor.id];
      for (var i = 0; i < legacyEditors.length; i++) {
        if (legacyEditors[i] === targetEditor) {
          legacyEditors.splice(i, 1);
          break;
        }
      }
      editors = filter(editors, function (editor) {
        return targetEditor !== editor;
      });
      if (EditorManager.activeEditor === targetEditor) {
        EditorManager.activeEditor = editors.length > 0 ? editors[0] : null;
      }
      if (EditorManager.focusedEditor === targetEditor) {
        EditorManager.focusedEditor = null;
      }
      return oldEditors.length !== editors.length;
    };
    var purgeDestroyedEditor = function (editor) {
      if (editor && editor.initialized && !(editor.getContainer() || editor.getBody()).parentNode) {
        removeEditorFromList(editor);
        editor.unbindAllNativeEvents();
        editor.destroy(true);
        editor.removed = true;
        editor = null;
      }
      return editor;
    };
    var isQuirksMode = domGlobals.document.compatMode !== 'CSS1Compat';
    var EditorManager = __assign(__assign({}, Observable), {
      baseURI: null,
      baseURL: null,
      defaultSettings: {},
      documentBaseURL: null,
      suffix: null,
      $: DomQuery,
      majorVersion: '5',
      minorVersion: '2.0',
      releaseDate: '2020-02-13',
      editors: legacyEditors,
      i18n: I18n,
      activeEditor: null,
      focusedEditor: null,
      settings: {},
      setup: function () {
        var self = this;
        var baseURL, documentBaseURL, suffix = '';
        documentBaseURL = URI.getDocumentBaseUrl(domGlobals.document.location);
        if (/^[^:]+:\/\/\/?[^\/]+\//.test(documentBaseURL)) {
          documentBaseURL = documentBaseURL.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');
          if (!/[\/\\]$/.test(documentBaseURL)) {
            documentBaseURL += '/';
          }
        }
        var preInit = window.tinymce || window.tinyMCEPreInit;
        if (preInit) {
          baseURL = preInit.base || preInit.baseURL;
          suffix = preInit.suffix;
        } else {
          var scripts = domGlobals.document.getElementsByTagName('script');
          for (var i = 0; i < scripts.length; i++) {
            var src = scripts[i].src || '';
            if (src === '') {
              continue;
            }
            var srcScript = src.substring(src.lastIndexOf('/'));
            if (/tinymce(\.full|\.jquery|)(\.min|\.dev|)\.js/.test(src)) {
              if (srcScript.indexOf('.min') !== -1) {
                suffix = '.min';
              }
              baseURL = src.substring(0, src.lastIndexOf('/'));
              break;
            }
          }
          if (!baseURL && domGlobals.document.currentScript) {
            var src = domGlobals.document.currentScript.src;
            if (src.indexOf('.min') !== -1) {
              suffix = '.min';
            }
            baseURL = src.substring(0, src.lastIndexOf('/'));
          }
        }
        self.baseURL = new URI(documentBaseURL).toAbsolute(baseURL);
        self.documentBaseURL = documentBaseURL;
        self.baseURI = new URI(self.baseURL);
        self.suffix = suffix;
        FocusController.setup(self);
      },
      overrideDefaults: function (defaultSettings) {
        var baseUrl, suffix;
        baseUrl = defaultSettings.base_url;
        if (baseUrl) {
          this._setBaseUrl(baseUrl);
        }
        suffix = defaultSettings.suffix;
        if (defaultSettings.suffix) {
          this.suffix = suffix;
        }
        this.defaultSettings = defaultSettings;
        var pluginBaseUrls = defaultSettings.plugin_base_urls;
        for (var name_1 in pluginBaseUrls) {
          AddOnManager$1.PluginManager.urls[name_1] = pluginBaseUrls[name_1];
        }
      },
      init: function (settings) {
        var self = this;
        var result, invalidInlineTargets;
        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', ' ');
        var isInvalidInlineTarget = function (settings, elm) {
          return settings.inline && elm.tagName.toLowerCase() in invalidInlineTargets;
        };
        var createId = function (elm) {
          var id = elm.id;
          if (!id) {
            id = elm.name;
            if (id && !DOM$a.get(id)) {
              id = elm.name;
            } else {
              id = DOM$a.uniqueId();
            }
            elm.setAttribute('id', id);
          }
          return id;
        };
        var execCallback = function (name) {
          var callback = settings[name];
          if (!callback) {
            return;
          }
          return callback.apply(self, Array.prototype.slice.call(arguments, 2));
        };
        var hasClass = function (elm, className) {
          return className.constructor === RegExp ? className.test(elm.className) : DOM$a.hasClass(elm, className);
        };
        var findTargets = function (settings) {
          var l, targets = [];
          if (Env.browser.isIE() && Env.browser.version.major < 11) {
            ErrorReporter.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/');
            return [];
          } else if (isQuirksMode) {
            ErrorReporter.initError('Failed to initialize the editor as the document is not in standards mode. ' + 'TinyMCE requires standards mode.');
            return [];
          }
          if (settings.types) {
            each$j(settings.types, function (type) {
              targets = targets.concat(DOM$a.select(type.selector));
            });
            return targets;
          } else if (settings.selector) {
            return DOM$a.select(settings.selector);
          } else if (settings.target) {
            return [settings.target];
          }
          switch (settings.mode) {
          case 'exact':
            l = settings.elements || '';
            if (l.length > 0) {
              each$j(explode$4(l), function (id) {
                var elm;
                if (elm = DOM$a.get(id)) {
                  targets.push(elm);
                } else {
                  each$j(domGlobals.document.forms, function (f) {
                    each$j(f.elements, function (e) {
                      if (e.name === id) {
                        id = 'mce_editor_' + instanceCounter++;
                        DOM$a.setAttrib(e, 'id', id);
                        targets.push(e);
                      }
                    });
                  });
                }
              });
            }
            break;
          case 'textareas':
          case 'specific_textareas':
            each$j(DOM$a.select('textarea'), function (elm) {
              if (settings.editor_deselector && hasClass(elm, settings.editor_deselector)) {
                return;
              }
              if (!settings.editor_selector || hasClass(elm, settings.editor_selector)) {
                targets.push(elm);
              }
            });
            break;
          }
          return targets;
        };
        var provideResults = function (editors) {
          result = editors;
        };
        var initEditors = function () {
          var initCount = 0;
          var editors = [];
          var targets;
          var createEditor = function (id, settings, targetElm) {
            var editor = new Editor(id, settings, self);
            editors.push(editor);
            editor.on('init', function () {
              if (++initCount === targets.length) {
                provideResults(editors);
              }
            });
            editor.targetElm = editor.targetElm || targetElm;
            editor.render();
          };
          DOM$a.unbind(window, 'ready', initEditors);
          execCallback('onpageload');
          targets = DomQuery.unique(findTargets(settings));
          if (settings.types) {
            each$j(settings.types, function (type) {
              Tools.each(targets, function (elm) {
                if (DOM$a.is(elm, type.selector)) {
                  createEditor(createId(elm), extend$4({}, settings, type), elm);
                  return false;
                }
                return true;
              });
            });
            return;
          }
          Tools.each(targets, function (elm) {
            purgeDestroyedEditor(self.get(elm.id));
          });
          targets = Tools.grep(targets, function (elm) {
            return !self.get(elm.id);
          });
          if (targets.length === 0) {
            provideResults([]);
          } else {
            each$j(targets, function (elm) {
              if (isInvalidInlineTarget(settings, elm)) {
                ErrorReporter.initError('Could not initialize inline editor on invalid inline target element', elm);
              } else {
                createEditor(createId(elm), settings, elm);
              }
            });
          }
        };
        self.settings = settings;
        DOM$a.bind(window, 'ready', initEditors);
        return new promiseObj(function (resolve) {
          if (result) {
            resolve(result);
          } else {
            provideResults = function (editors) {
              resolve(editors);
            };
          }
        });
      },
      get: function (id) {
        if (arguments.length === 0) {
          return editors.slice(0);
        } else if (isString(id)) {
          return find(editors, function (editor) {
            return editor.id === id;
          }).getOr(null);
        } else if (isNumber(id)) {
          return editors[id] ? editors[id] : null;
        } else {
          return null;
        }
      },
      add: function (editor) {
        var self = this;
        var existingEditor;
        existingEditor = legacyEditors[editor.id];
        if (existingEditor === editor) {
          return editor;
        }
        if (self.get(editor.id) === null) {
          if (isValidLegacyKey(editor.id)) {
            legacyEditors[editor.id] = editor;
          }
          legacyEditors.push(editor);
          editors.push(editor);
        }
        toggleGlobalEvents(true);
        self.activeEditor = editor;
        self.fire('AddEditor', { editor: editor });
        if (!beforeUnloadDelegate) {
          beforeUnloadDelegate = function (e) {
            var event = self.fire('BeforeUnload');
            if (event.returnValue) {
              e.preventDefault();
              e.returnValue = event.returnValue;
              return event.returnValue;
            }
          };
          window.addEventListener('beforeunload', beforeUnloadDelegate);
        }
        return editor;
      },
      createEditor: function (id, settings) {
        return this.add(new Editor(id, settings, this));
      },
      remove: function (selector) {
        var self = this;
        var i, editor;
        if (!selector) {
          for (i = editors.length - 1; i >= 0; i--) {
            self.remove(editors[i]);
          }
          return;
        }
        if (isString(selector)) {
          each$j(DOM$a.select(selector), function (elm) {
            editor = self.get(elm.id);
            if (editor) {
              self.remove(editor);
            }
          });
          return;
        }
        editor = selector;
        if (isNull(self.get(editor.id))) {
          return null;
        }
        if (removeEditorFromList(editor)) {
          self.fire('RemoveEditor', { editor: editor });
        }
        if (editors.length === 0) {
          window.removeEventListener('beforeunload', beforeUnloadDelegate);
        }
        editor.remove();
        toggleGlobalEvents(editors.length > 0);
        return editor;
      },
      execCommand: function (cmd, ui, value) {
        var self = this, editor = self.get(value);
        switch (cmd) {
        case 'mceAddEditor':
          if (!self.get(value)) {
            new Editor(value, self.settings, self).render();
          }
          return true;
        case 'mceRemoveEditor':
          if (editor) {
            editor.remove();
          }
          return true;
        case 'mceToggleEditor':
          if (!editor) {
            self.execCommand('mceAddEditor', 0, value);
            return true;
          }
          if (editor.isHidden()) {
            editor.show();
          } else {
            editor.hide();
          }
          return true;
        }
        if (self.activeEditor) {
          return self.activeEditor.execCommand(cmd, ui, value);
        }
        return false;
      },
      triggerSave: function () {
        each$j(editors, function (editor) {
          editor.save();
        });
      },
      addI18n: function (code, items) {
        I18n.add(code, items);
      },
      translate: function (text) {
        return I18n.translate(text);
      },
      setActive: function (editor) {
        var activeEditor = this.activeEditor;
        if (this.activeEditor !== editor) {
          if (activeEditor) {
            activeEditor.fire('deactivate', { relatedTarget: editor });
          }
          editor.fire('activate', { relatedTarget: activeEditor });
        }
        this.activeEditor = editor;
      },
      _setBaseUrl: function (baseUrl) {
        this.baseURL = new URI(this.documentBaseURL).toAbsolute(baseUrl.replace(/\/+$/, ''));
        this.baseURI = new URI(this.baseURL);
      }
    });
    EditorManager.setup();

    function RangeUtils(dom) {
      var walk = function (rng, callback) {
        return RangeWalk.walk(dom, rng, callback);
      };
      var split = split$1;
      var normalize = function (rng) {
        return NormalizeRange.normalize(dom, rng).fold(constant(false), function (normalizedRng) {
          rng.setStart(normalizedRng.startContainer, normalizedRng.startOffset);
          rng.setEnd(normalizedRng.endContainer, normalizedRng.endOffset);
          return true;
        });
      };
      return {
        walk: walk,
        split: split,
        normalize: normalize
      };
    }
    (function (RangeUtils) {
      RangeUtils.compareRanges = RangeCompare.isEq;
      RangeUtils.getCaretRangeFromPoint = CaretRangeFromPoint.fromPoint;
      RangeUtils.getSelectedNode = getSelectedNode;
      RangeUtils.getNode = getNode;
    }(RangeUtils || (RangeUtils = {})));
    var RangeUtils$1 = RangeUtils;

    var awaiter = function (resolveCb, rejectCb, timeout) {
      if (timeout === void 0) {
        timeout = 1000;
      }
      var done = false;
      var timer = null;
      var complete = function (completer) {
        return function () {
          var args = [];
          for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
          }
          if (!done) {
            done = true;
            if (timer !== null) {
              domGlobals.clearTimeout(timer);
              timer = null;
            }
            completer.apply(null, args);
          }
        };
      };
      var resolve = complete(resolveCb);
      var reject = complete(rejectCb);
      var start = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
          args[_i] = arguments[_i];
        }
        if (!done && timer === null) {
          timer = domGlobals.setTimeout(function () {
            return reject.apply(null, args);
          }, timeout);
        }
      };
      return {
        start: start,
        resolve: resolve,
        reject: reject
      };
    };
    var create$6 = function () {
      var tasks = {};
      var resultFns = {};
      var load = function (id, url) {
        var loadErrMsg = 'Script at URL "' + url + '" failed to load';
        var runErrMsg = 'Script at URL "' + url + '" did not call `tinymce.Resource.add(\'' + id + '\', data)` within 1 second';
        if (tasks[id] !== undefined) {
          return tasks[id];
        } else {
          var task = new promiseObj(function (resolve, reject) {
            var waiter = awaiter(resolve, reject);
            resultFns[id] = waiter.resolve;
            ScriptLoader.ScriptLoader.loadScript(url, function () {
              return waiter.start(runErrMsg);
            }, function () {
              return waiter.reject(loadErrMsg);
            });
          });
          tasks[id] = task;
          return task;
        }
      };
      var add = function (id, data) {
        if (resultFns[id] !== undefined) {
          resultFns[id](data);
          delete resultFns[id];
        }
        tasks[id] = promiseObj.resolve(data);
      };
      return {
        load: load,
        add: add
      };
    };
    var Resource = create$6();

    var min = Math.min, max = Math.max, round$2 = Math.round;
    var relativePosition = function (rect, targetRect, rel) {
      var x, y, w, h, targetW, targetH;
      x = targetRect.x;
      y = targetRect.y;
      w = rect.w;
      h = rect.h;
      targetW = targetRect.w;
      targetH = targetRect.h;
      rel = (rel || '').split('');
      if (rel[0] === 'b') {
        y += targetH;
      }
      if (rel[1] === 'r') {
        x += targetW;
      }
      if (rel[0] === 'c') {
        y += round$2(targetH / 2);
      }
      if (rel[1] === 'c') {
        x += round$2(targetW / 2);
      }
      if (rel[3] === 'b') {
        y -= h;
      }
      if (rel[4] === 'r') {
        x -= w;
      }
      if (rel[3] === 'c') {
        y -= round$2(h / 2);
      }
      if (rel[4] === 'c') {
        x -= round$2(w / 2);
      }
      return create$7(x, y, w, h);
    };
    var findBestRelativePosition = function (rect, targetRect, constrainRect, rels) {
      var pos, i;
      for (i = 0; i < rels.length; i++) {
        pos = relativePosition(rect, targetRect, rels[i]);
        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) {
          return rels[i];
        }
      }
      return null;
    };
    var inflate = function (rect, w, h) {
      return create$7(rect.x - w, rect.y - h, rect.w + w * 2, rect.h + h * 2);
    };
    var intersect = function (rect, cropRect) {
      var x1, y1, x2, y2;
      x1 = max(rect.x, cropRect.x);
      y1 = max(rect.y, cropRect.y);
      x2 = min(rect.x + rect.w, cropRect.x + cropRect.w);
      y2 = min(rect.y + rect.h, cropRect.y + cropRect.h);
      if (x2 - x1 < 0 || y2 - y1 < 0) {
        return null;
      }
      return create$7(x1, y1, x2 - x1, y2 - y1);
    };
    var clamp$1 = function (rect, clampRect, fixedSize) {
      var underflowX1, underflowY1, overflowX2, overflowY2, x1, y1, x2, y2, cx2, cy2;
      x1 = rect.x;
      y1 = rect.y;
      x2 = rect.x + rect.w;
      y2 = rect.y + rect.h;
      cx2 = clampRect.x + clampRect.w;
      cy2 = clampRect.y + clampRect.h;
      underflowX1 = max(0, clampRect.x - x1);
      underflowY1 = max(0, clampRect.y - y1);
      overflowX2 = max(0, x2 - cx2);
      overflowY2 = max(0, y2 - cy2);
      x1 += underflowX1;
      y1 += underflowY1;
      if (fixedSize) {
        x2 += underflowX1;
        y2 += underflowY1;
        x1 -= overflowX2;
        y1 -= overflowY2;
      }
      x2 -= overflowX2;
      y2 -= overflowY2;
      return create$7(x1, y1, x2 - x1, y2 - y1);
    };
    var create$7 = function (x, y, w, h) {
      return {
        x: x,
        y: y,
        w: w,
        h: h
      };
    };
    var fromClientRect = function (clientRect) {
      return create$7(clientRect.left, clientRect.top, clientRect.width, clientRect.height);
    };
    var Rect = {
      inflate: inflate,
      relativePosition: relativePosition,
      findBestRelativePosition: findBestRelativePosition,
      intersect: intersect,
      clamp: clamp$1,
      create: create$7,
      fromClientRect: fromClientRect
    };

    var each$k = Tools.each, extend$5 = Tools.extend;
    var extendClass, initializing;
    var Class = function () {
    };
    Class.extend = extendClass = function (prop) {
      var self = this;
      var _super = self.prototype;
      var prototype, name, member;
      var Class = function () {
        var i, mixins, mixin;
        var self = this;
        if (!initializing) {
          if (self.init) {
            self.init.apply(self, arguments);
          }
          mixins = self.Mixins;
          if (mixins) {
            i = mixins.length;
            while (i--) {
              mixin = mixins[i];
              if (mixin.init) {
                mixin.init.apply(self, arguments);
              }
            }
          }
        }
      };
      var dummy = function () {
        return this;
      };
      var createMethod = function (name, fn) {
        return function () {
          var self = this;
          var tmp = self._super;
          var ret;
          self._super = _super[name];
          ret = fn.apply(self, arguments);
          self._super = tmp;
          return ret;
        };
      };
      initializing = true;
      prototype = new self();
      initializing = false;
      if (prop.Mixins) {
        each$k(prop.Mixins, function (mixin) {
          for (var name_1 in mixin) {
            if (name_1 !== 'init') {
              prop[name_1] = mixin[name_1];
            }
          }
        });
        if (_super.Mixins) {
          prop.Mixins = _super.Mixins.concat(prop.Mixins);
        }
      }
      if (prop.Methods) {
        each$k(prop.Methods.split(','), function (name) {
          prop[name] = dummy;
        });
      }
      if (prop.Properties) {
        each$k(prop.Properties.split(','), function (name) {
          var fieldName = '_' + name;
          prop[name] = function (value) {
            var self = this;
            if (value !== undefined) {
              self[fieldName] = value;
              return self;
            }
            return self[fieldName];
          };
        });
      }
      if (prop.Statics) {
        each$k(prop.Statics, function (func, name) {
          Class[name] = func;
        });
      }
      if (prop.Defaults && _super.Defaults) {
        prop.Defaults = extend$5({}, _super.Defaults, prop.Defaults);
      }
      for (name in prop) {
        member = prop[name];
        if (typeof member === 'function' && _super[name]) {
          prototype[name] = createMethod(name, member);
        } else {
          prototype[name] = member;
        }
      }
      Class.prototype = prototype;
      Class.constructor = Class;
      Class.extend = extendClass;
      return Class;
    };

    var min$1 = Math.min, max$1 = Math.max, round$3 = Math.round;
    var Color = function (value) {
      var self = {};
      var r = 0, g = 0, b = 0;
      var rgb2hsv = function (r, g, b) {
        var h, s, v, d, minRGB, maxRGB;
        h = 0;
        s = 0;
        v = 0;
        r = r / 255;
        g = g / 255;
        b = b / 255;
        minRGB = min$1(r, min$1(g, b));
        maxRGB = max$1(r, max$1(g, b));
        if (minRGB === maxRGB) {
          v = minRGB;
          return {
            h: 0,
            s: 0,
            v: v * 100
          };
        }
        d = r === minRGB ? g - b : b === minRGB ? r - g : b - r;
        h = r === minRGB ? 3 : b === minRGB ? 1 : 5;
        h = 60 * (h - d / (maxRGB - minRGB));
        s = (maxRGB - minRGB) / maxRGB;
        v = maxRGB;
        return {
          h: round$3(h),
          s: round$3(s * 100),
          v: round$3(v * 100)
        };
      };
      var hsvToRgb = function (hue, saturation, brightness) {
        var side, chroma, x, match;
        hue = (parseInt(hue, 10) || 0) % 360;
        saturation = parseInt(saturation, 10) / 100;
        brightness = parseInt(brightness, 10) / 100;
        saturation = max$1(0, min$1(saturation, 1));
        brightness = max$1(0, min$1(brightness, 1));
        if (saturation === 0) {
          r = g = b = round$3(255 * brightness);
          return;
        }
        side = hue / 60;
        chroma = brightness * saturation;
        x = chroma * (1 - Math.abs(side % 2 - 1));
        match = brightness - chroma;
        switch (Math.floor(side)) {
        case 0:
          r = chroma;
          g = x;
          b = 0;
          break;
        case 1:
          r = x;
          g = chroma;
          b = 0;
          break;
        case 2:
          r = 0;
          g = chroma;
          b = x;
          break;
        case 3:
          r = 0;
          g = x;
          b = chroma;
          break;
        case 4:
          r = x;
          g = 0;
          b = chroma;
          break;
        case 5:
          r = chroma;
          g = 0;
          b = x;
          break;
        default:
          r = g = b = 0;
        }
        r = round$3(255 * (r + match));
        g = round$3(255 * (g + match));
        b = round$3(255 * (b + match));
      };
      var toHex = function () {
        var hex = function (val) {
          val = parseInt(val, 10).toString(16);
          return val.length > 1 ? val : '0' + val;
        };
        return '#' + hex(r) + hex(g) + hex(b);
      };
      var toRgb = function () {
        return {
          r: r,
          g: g,
          b: b
        };
      };
      var toHsv = function () {
        return rgb2hsv(r, g, b);
      };
      var parse = function (value) {
        var matches;
        if (typeof value === 'object') {
          if ('r' in value) {
            r = value.r;
            g = value.g;
            b = value.b;
          } else if ('v' in value) {
            hsvToRgb(value.h, value.s, value.v);
          }
        } else {
          if (matches = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)[^\)]*\)/gi.exec(value)) {
            r = parseInt(matches[1], 10);
            g = parseInt(matches[2], 10);
            b = parseInt(matches[3], 10);
          } else if (matches = /#([0-F]{2})([0-F]{2})([0-F]{2})/gi.exec(value)) {
            r = parseInt(matches[1], 16);
            g = parseInt(matches[2], 16);
            b = parseInt(matches[3], 16);
          } else if (matches = /#([0-F])([0-F])([0-F])/gi.exec(value)) {
            r = parseInt(matches[1] + matches[1], 16);
            g = parseInt(matches[2] + matches[2], 16);
            b = parseInt(matches[3] + matches[3], 16);
          }
        }
        r = r < 0 ? 0 : r > 255 ? 255 : r;
        g = g < 0 ? 0 : g > 255 ? 255 : g;
        b = b < 0 ? 0 : b > 255 ? 255 : b;
        return self;
      };
      if (value) {
        parse(value);
      }
      self.toRgb = toRgb;
      self.toHsv = toHsv;
      self.toHex = toHex;
      self.parse = parse;
      return self;
    };

    var serialize = function (obj) {
      var data = JSON.stringify(obj);
      if (!isString(data)) {
        return data;
      }
      return data.replace(/[\u0080-\uFFFF]/g, function (match) {
        var hexCode = match.charCodeAt(0).toString(16);
        return '\\u' + '0000'.substring(hexCode.length) + hexCode;
      });
    };
    var JSONUtils = {
      serialize: serialize,
      parse: function (text) {
        try {
          return JSON.parse(text);
        } catch (ex) {
        }
      }
    };

    var JSONP = {
      callbacks: {},
      count: 0,
      send: function (settings) {
        var self = this, dom = DOMUtils$1.DOM, count = settings.count !== undefined ? settings.count : self.count;
        var id = 'tinymce_jsonp_' + count;
        self.callbacks[count] = function (json) {
          dom.remove(id);
          delete self.callbacks[count];
          settings.callback(json);
        };
        dom.add(dom.doc.body, 'script', {
          id: id,
          src: settings.url,
          type: 'text/javascript'
        });
        self.count++;
      }
    };

    var XHR = __assign(__assign({}, Observable), {
      send: function (settings) {
        var xhr, count = 0;
        var ready = function () {
          if (!settings.async || xhr.readyState === 4 || count++ > 10000) {
            if (settings.success && count < 10000 && xhr.status === 200) {
              settings.success.call(settings.success_scope, '' + xhr.responseText, xhr, settings);
            } else if (settings.error) {
              settings.error.call(settings.error_scope, count > 10000 ? 'TIMED_OUT' : 'GENERAL', xhr, settings);
            }
            xhr = null;
          } else {
            Delay.setTimeout(ready, 10);
          }
        };
        settings.scope = settings.scope || this;
        settings.success_scope = settings.success_scope || settings.scope;
        settings.error_scope = settings.error_scope || settings.scope;
        settings.async = settings.async !== false;
        settings.data = settings.data || '';
        XHR.fire('beforeInitialize', { settings: settings });
        xhr = new domGlobals.XMLHttpRequest();
        if (xhr) {
          if (xhr.overrideMimeType) {
            xhr.overrideMimeType(settings.content_type);
          }
          xhr.open(settings.type || (settings.data ? 'POST' : 'GET'), settings.url, settings.async);
          if (settings.crossDomain) {
            xhr.withCredentials = true;
          }
          if (settings.content_type) {
            xhr.setRequestHeader('Content-Type', settings.content_type);
          }
          if (settings.requestheaders) {
            Tools.each(settings.requestheaders, function (header) {
              xhr.setRequestHeader(header.key, header.value);
            });
          }
          xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
          xhr = XHR.fire('beforeSend', {
            xhr: xhr,
            settings: settings
          }).xhr;
          xhr.send(settings.data);
          if (!settings.async) {
            return ready();
          }
          Delay.setTimeout(ready, 10);
        }
      }
    });

    var extend$6 = Tools.extend;
    var JSONRequest = function () {
      function JSONRequest(settings) {
        this.settings = extend$6({}, settings);
        this.count = 0;
      }
      JSONRequest.sendRPC = function (o) {
        return new JSONRequest().send(o);
      };
      JSONRequest.prototype.send = function (args) {
        var ecb = args.error, scb = args.success;
        var xhrArgs = extend$6(this.settings, args);
        xhrArgs.success = function (c, x) {
          c = JSONUtils.parse(c);
          if (typeof c === 'undefined') {
            c = { error: 'JSON Parse error.' };
          }
          if (c.error) {
            ecb.call(xhrArgs.error_scope || xhrArgs.scope, c.error, x);
          } else {
            scb.call(xhrArgs.success_scope || xhrArgs.scope, c.result);
          }
        };
        xhrArgs.error = function (ty, x) {
          if (ecb) {
            ecb.call(xhrArgs.error_scope || xhrArgs.scope, ty, x);
          }
        };
        xhrArgs.data = JSONUtils.serialize({
          id: args.id || 'c' + this.count++,
          method: args.method,
          params: args.params
        });
        xhrArgs.content_type = 'application/json';
        XHR.send(xhrArgs);
      };
      return JSONRequest;
    }();

    var create$8 = function () {
      return function () {
        var data = {};
        var keys = [];
        var storage = {
          getItem: function (key) {
            var item = data[key];
            return item ? item : null;
          },
          setItem: function (key, value) {
            keys.push(key);
            data[key] = String(value);
          },
          key: function (index) {
            return keys[index];
          },
          removeItem: function (key) {
            keys = keys.filter(function (k) {
              return k === key;
            });
            delete data[key];
          },
          clear: function () {
            keys = [];
            data = {};
          },
          length: 0
        };
        Object.defineProperty(storage, 'length', {
          get: function () {
            return keys.length;
          },
          configurable: false,
          enumerable: false
        });
        return storage;
      }();
    };

    var localStorage;
    try {
      localStorage = domGlobals.window.localStorage;
    } catch (e) {
      localStorage = create$8();
    }
    var LocalStorage = localStorage;

    var publicApi = {
      geom: { Rect: Rect },
      util: {
        Promise: promiseObj,
        Delay: Delay,
        Tools: Tools,
        VK: VK,
        URI: URI,
        Class: Class,
        EventDispatcher: EventDispatcher,
        Observable: Observable,
        I18n: I18n,
        XHR: XHR,
        JSON: JSONUtils,
        JSONRequest: JSONRequest,
        JSONP: JSONP,
        LocalStorage: LocalStorage,
        Color: Color
      },
      dom: {
        EventUtils: EventUtils,
        Sizzle: Sizzle,
        DomQuery: DomQuery,
        TreeWalker: TreeWalker,
        TextSeeker: TextSeeker,
        DOMUtils: DOMUtils$1,
        ScriptLoader: ScriptLoader,
        RangeUtils: RangeUtils$1,
        Serializer: Serializer$1,
        ControlSelection: ControlSelection,
        BookmarkManager: BookmarkManager$1,
        Selection: Selection$1,
        Event: EventUtils.Event
      },
      html: {
        Styles: Styles,
        Entities: Entities,
        Node: Node$1,
        Schema: Schema,
        SaxParser: SaxParser$1,
        DomParser: DomParser,
        Writer: Writer,
        Serializer: Serializer
      },
      Env: Env,
      AddOnManager: AddOnManager$1,
      Annotator: Annotator,
      Formatter: Formatter,
      UndoManager: UndoManager,
      EditorCommands: EditorCommands,
      WindowManager: WindowManager,
      NotificationManager: NotificationManager,
      EditorObservable: EditorObservable,
      Shortcuts: Shortcuts,
      Editor: Editor,
      FocusManager: FocusManager,
      EditorManager: EditorManager,
      DOM: DOMUtils$1.DOM,
      ScriptLoader: ScriptLoader.ScriptLoader,
      PluginManager: AddOnManager$1.PluginManager,
      ThemeManager: AddOnManager$1.ThemeManager,
      IconManager: IconManager,
      Resource: Resource,
      trim: Tools.trim,
      isArray: Tools.isArray,
      is: Tools.is,
      toArray: Tools.toArray,
      makeMap: Tools.makeMap,
      each: Tools.each,
      map: Tools.map,
      grep: Tools.grep,
      inArray: Tools.inArray,
      extend: Tools.extend,
      create: Tools.create,
      walk: Tools.walk,
      createNS: Tools.createNS,
      resolve: Tools.resolve,
      explode: Tools.explode,
      _addCacheSuffix: Tools._addCacheSuffix,
      isOpera: Env.opera,
      isWebKit: Env.webkit,
      isIE: Env.ie,
      isGecko: Env.gecko,
      isMac: Env.mac
    };
    var tinymce = Tools.extend(EditorManager, publicApi);

    var exportToModuleLoaders = function (tinymce) {
      if (typeof module === 'object') {
        try {
          module.exports = tinymce;
        } catch (_) {
        }
      }
    };
    var exportToWindowGlobal = function (tinymce) {
      window.tinymce = tinymce;
      window.tinyMCE = tinymce;
    };
    exportToWindowGlobal(tinymce);
    exportToModuleLoaders(tinymce);

}(window));
Hacker Blog, Shell İndir, Sql İnjection, XSS Attacks, LFI Attacks, Social Hacking, Exploit Bot, Proxy Tools, Web Shell, PHP Shell, Alfa Shell İndir, Hacking Training Set, DDoS Script, Denial Of Service, Botnet, RFI Attacks, Encryption
Telegram @BIBIL_0DAY