(function () {
var imagetools = (function () {
  'use strict';

  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 global = tinymce.util.Tools.resolve('tinymce.PluginManager');

  var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools');

  function create(width, height) {
    return resize(document.createElement('canvas'), width, height);
  }
  function clone(canvas) {
    var tCanvas, ctx;
    tCanvas = create(canvas.width, canvas.height);
    ctx = get2dContext(tCanvas);
    ctx.drawImage(canvas, 0, 0);
    return tCanvas;
  }
  function get2dContext(canvas) {
    return canvas.getContext('2d');
  }
  function get3dContext(canvas) {
    var gl = null;
    try {
      gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
    } catch (e) {
    }
    if (!gl) {
      gl = null;
    }
    return gl;
  }
  function resize(canvas, width, height) {
    canvas.width = width;
    canvas.height = height;
    return canvas;
  }
  var $_bg99ivd3jfuw8p6o = {
    create: create,
    clone: clone,
    resize: resize,
    get2dContext: get2dContext,
    get3dContext: get3dContext
  };

  function getWidth(image) {
    return image.naturalWidth || image.width;
  }
  function getHeight(image) {
    return image.naturalHeight || image.height;
  }
  var $_29drijd4jfuw8p6p = {
    getWidth: getWidth,
    getHeight: getHeight
  };

  var promise = function () {
    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 setImmediate === 'function' && setImmediate || function (fn) {
      setTimeout(fn, 1);
    };
    function bind(fn, thisArg) {
      return function () {
        fn.apply(thisArg, arguments);
      };
    }
    var isArray = Array.isArray || function (value) {
      return Object.prototype.toString.call(value) === '[object Array]';
    };
    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 Promise = window.Promise ? window.Promise : promise();

  var noop = function () {
    var x = [];
    for (var _i = 0; _i < arguments.length; _i++) {
      x[_i] = arguments[_i];
    }
  };
  var noarg = function (f) {
    return function () {
      var x = [];
      for (var _i = 0; _i < arguments.length; _i++) {
        x[_i] = arguments[_i];
      }
      return f();
    };
  };
  var compose = function (fa, fb) {
    return function () {
      var x = [];
      for (var _i = 0; _i < arguments.length; _i++) {
        x[_i] = arguments[_i];
      }
      return fa(fb.apply(null, arguments));
    };
  };
  var constant = function (value) {
    return function () {
      return value;
    };
  };
  var identity = function (x) {
    return x;
  };
  var tripleEquals = function (a, b) {
    return a === b;
  };
  var curry = function (f) {
    var x = [];
    for (var _i = 1; _i < arguments.length; _i++) {
      x[_i - 1] = arguments[_i];
    }
    var args = new Array(arguments.length - 1);
    for (var i = 1; i < arguments.length; i++)
      args[i - 1] = arguments[i];
    return function () {
      var x = [];
      for (var _i = 0; _i < arguments.length; _i++) {
        x[_i] = arguments[_i];
      }
      var newArgs = new Array(arguments.length);
      for (var j = 0; j < newArgs.length; j++)
        newArgs[j] = arguments[j];
      var all = args.concat(newArgs);
      return f.apply(null, all);
    };
  };
  var not = function (f) {
    return function () {
      var x = [];
      for (var _i = 0; _i < arguments.length; _i++) {
        x[_i] = arguments[_i];
      }
      return !f.apply(null, arguments);
    };
  };
  var die = function (msg) {
    return function () {
      throw new Error(msg);
    };
  };
  var apply = function (f) {
    return f();
  };
  var call = function (f) {
    f();
  };
  var never = constant(false);
  var always = constant(true);
  var $_9jziv0d7jfuw8p6z = {
    noop: noop,
    noarg: noarg,
    compose: compose,
    constant: constant,
    identity: identity,
    tripleEquals: tripleEquals,
    curry: curry,
    not: not,
    die: die,
    apply: apply,
    call: call,
    never: never,
    always: always
  };

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

  var global$2 = typeof window !== 'undefined' ? window : Function('return this;')();

  var path = function (parts, scope) {
    var o = scope !== undefined && scope !== null ? scope : global$2;
    for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i)
      o = o[parts[i]];
    return o;
  };
  var resolve = function (p, scope) {
    var parts = p.split('.');
    return path(parts, scope);
  };
  var step = function (o, part) {
    if (o[part] === undefined || o[part] === null)
      o[part] = {};
    return o[part];
  };
  var forge = function (parts, target) {
    var o = target !== undefined ? target : global$2;
    for (var i = 0; i < parts.length; ++i)
      o = step(o, parts[i]);
    return o;
  };
  var namespace = function (name, target) {
    var parts = name.split('.');
    return forge(parts, target);
  };
  var $_cgya6gdajfuw8p75 = {
    path: path,
    resolve: resolve,
    forge: forge,
    namespace: namespace
  };

  var unsafe = function (name, scope) {
    return $_cgya6gdajfuw8p75.resolve(name, scope);
  };
  var getOrDie = function (name, scope) {
    var actual = unsafe(name, scope);
    if (actual === undefined || actual === null)
      throw name + ' not available on this browser';
    return actual;
  };
  var $_9b4fxbd9jfuw8p72 = { getOrDie: getOrDie };

  function Blob (parts, properties) {
    var f = $_9b4fxbd9jfuw8p72.getOrDie('Blob');
    return new f(parts, properties);
  }

  function FileReader () {
    var f = $_9b4fxbd9jfuw8p72.getOrDie('FileReader');
    return new f();
  }

  function Uint8Array (arr) {
    var f = $_9b4fxbd9jfuw8p72.getOrDie('Uint8Array');
    return new f(arr);
  }

  var requestAnimationFrame = function (callback) {
    var f = $_9b4fxbd9jfuw8p72.getOrDie('requestAnimationFrame');
    f(callback);
  };
  var atob = function (base64) {
    var f = $_9b4fxbd9jfuw8p72.getOrDie('atob');
    return f(base64);
  };
  var $_fg715odejfuw8p79 = {
    atob: atob,
    requestAnimationFrame: requestAnimationFrame
  };

  function imageToBlob(image) {
    var src = image.src;
    if (src.indexOf('data:') === 0) {
      return dataUriToBlob(src);
    }
    return anyUriToBlob(src);
  }
  function blobToImage(blob) {
    return new Promise(function (resolve, reject) {
      var blobUrl = URL.createObjectURL(blob);
      var image = new Image();
      var removeListeners = function () {
        image.removeEventListener('load', loaded);
        image.removeEventListener('error', error);
      };
      function loaded() {
        removeListeners();
        resolve(image);
      }
      function error() {
        removeListeners();
        reject('Unable to load data of type ' + blob.type + ': ' + blobUrl);
      }
      image.addEventListener('load', loaded);
      image.addEventListener('error', error);
      image.src = blobUrl;
      if (image.complete) {
        loaded();
      }
    });
  }
  function anyUriToBlob(url) {
    return new Promise(function (resolve, reject) {
      var xhr = new XMLHttpRequest();
      xhr.open('GET', url, true);
      xhr.responseType = 'blob';
      xhr.onload = function () {
        if (this.status == 200) {
          resolve(this.response);
        }
      };
      xhr.onerror = function () {
        var _this = this;
        var corsError = function () {
          var obj = new Error('No access to download image');
          obj.code = 18;
          obj.name = 'SecurityError';
          return obj;
        };
        var genericError = function () {
          return new Error('Error ' + _this.status + ' downloading image');
        };
        reject(this.status === 0 ? corsError() : genericError());
      };
      xhr.send();
    });
  }
  function dataUriToBlobSync(uri) {
    var data = uri.split(',');
    var matches = /data:([^;]+)/.exec(data[0]);
    if (!matches)
      return Option.none();
    var mimetype = matches[1];
    var base64 = data[1];
    var sliceSize = 1024;
    var byteCharacters = $_fg715odejfuw8p79.atob(base64);
    var bytesLength = byteCharacters.length;
    var slicesCount = Math.ceil(bytesLength / sliceSize);
    var byteArrays = new Array(slicesCount);
    for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
      var begin = sliceIndex * sliceSize;
      var end = Math.min(begin + sliceSize, bytesLength);
      var bytes = new Array(end - begin);
      for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
        bytes[i] = byteCharacters[offset].charCodeAt(0);
      }
      byteArrays[sliceIndex] = Uint8Array(bytes);
    }
    return Option.some(Blob(byteArrays, { type: mimetype }));
  }
  function dataUriToBlob(uri) {
    return new Promise(function (resolve, reject) {
      dataUriToBlobSync(uri).fold(function () {
        reject('uri is not base64: ' + uri);
      }, resolve);
    });
  }
  function uriToBlob(url) {
    if (url.indexOf('blob:') === 0) {
      return anyUriToBlob(url);
    }
    if (url.indexOf('data:') === 0) {
      return dataUriToBlob(url);
    }
    return null;
  }
  function canvasToBlob(canvas, type, quality) {
    type = type || 'image/png';
    if (HTMLCanvasElement.prototype.toBlob) {
      return new Promise(function (resolve) {
        canvas.toBlob(function (blob) {
          resolve(blob);
        }, type, quality);
      });
    } else {
      return dataUriToBlob(canvas.toDataURL(type, quality));
    }
  }
  function canvasToDataURL(getCanvas, type, quality) {
    type = type || 'image/png';
    return getCanvas.then(function (canvas) {
      return canvas.toDataURL(type, quality);
    });
  }
  function blobToCanvas(blob) {
    return blobToImage(blob).then(function (image) {
      revokeImageUrl(image);
      var context, canvas;
      canvas = $_bg99ivd3jfuw8p6o.create($_29drijd4jfuw8p6p.getWidth(image), $_29drijd4jfuw8p6p.getHeight(image));
      context = $_bg99ivd3jfuw8p6o.get2dContext(canvas);
      context.drawImage(image, 0, 0);
      return canvas;
    });
  }
  function blobToDataUri(blob) {
    return new Promise(function (resolve) {
      var reader = new FileReader();
      reader.onloadend = function () {
        resolve(reader.result);
      };
      reader.readAsDataURL(blob);
    });
  }
  function blobToArrayBuffer(blob) {
    return new Promise(function (resolve) {
      var reader = new FileReader();
      reader.onloadend = function () {
        resolve(reader.result);
      };
      reader.readAsArrayBuffer(blob);
    });
  }
  function blobToBase64(blob) {
    return blobToDataUri(blob).then(function (dataUri) {
      return dataUri.split(',')[1];
    });
  }
  function revokeImageUrl(image) {
    URL.revokeObjectURL(image.src);
  }
  var $_7f4olzd2jfuw8p68 = {
    blobToImage: blobToImage,
    imageToBlob: imageToBlob,
    blobToArrayBuffer: blobToArrayBuffer,
    blobToDataUri: blobToDataUri,
    blobToBase64: blobToBase64,
    dataUriToBlobSync: dataUriToBlobSync,
    canvasToBlob: canvasToBlob,
    canvasToDataURL: canvasToDataURL,
    blobToCanvas: blobToCanvas,
    uriToBlob: uriToBlob
  };

  var blobToImage$1 = function (image) {
    return $_7f4olzd2jfuw8p68.blobToImage(image);
  };
  var imageToBlob$1 = function (blob) {
    return $_7f4olzd2jfuw8p68.imageToBlob(blob);
  };
  var blobToDataUri$1 = function (blob) {
    return $_7f4olzd2jfuw8p68.blobToDataUri(blob);
  };
  var blobToBase64$1 = function (blob) {
    return $_7f4olzd2jfuw8p68.blobToBase64(blob);
  };
  var dataUriToBlobSync$1 = function (uri) {
    return $_7f4olzd2jfuw8p68.dataUriToBlobSync(uri);
  };
  var uriToBlob$1 = function (uri) {
    return Option.from($_7f4olzd2jfuw8p68.uriToBlob(uri));
  };
  var $_5ofeufd1jfuw8p63 = {
    blobToImage: blobToImage$1,
    imageToBlob: imageToBlob$1,
    blobToDataUri: blobToDataUri$1,
    blobToBase64: blobToBase64$1,
    dataUriToBlobSync: dataUriToBlobSync$1,
    uriToBlob: uriToBlob$1
  };

  function create$1(getCanvas, blob, uri) {
    var initialType = blob.type;
    var getType = $_9jziv0d7jfuw8p6z.constant(initialType);
    function toBlob() {
      return Promise.resolve(blob);
    }
    function toDataURL() {
      return uri;
    }
    function toBase64() {
      return uri.split(',')[1];
    }
    function toAdjustedBlob(type, quality) {
      return getCanvas.then(function (canvas) {
        return $_7f4olzd2jfuw8p68.canvasToBlob(canvas, type, quality);
      });
    }
    function toAdjustedDataURL(type, quality) {
      return getCanvas.then(function (canvas) {
        return $_7f4olzd2jfuw8p68.canvasToDataURL(canvas, type, quality);
      });
    }
    function toAdjustedBase64(type, quality) {
      return toAdjustedDataURL(type, quality).then(function (dataurl) {
        return dataurl.split(',')[1];
      });
    }
    function toCanvas() {
      return getCanvas.then($_bg99ivd3jfuw8p6o.clone);
    }
    return {
      getType: getType,
      toBlob: toBlob,
      toDataURL: toDataURL,
      toBase64: toBase64,
      toAdjustedBlob: toAdjustedBlob,
      toAdjustedDataURL: toAdjustedDataURL,
      toAdjustedBase64: toAdjustedBase64,
      toCanvas: toCanvas
    };
  }
  function fromBlob(blob) {
    return $_7f4olzd2jfuw8p68.blobToDataUri(blob).then(function (uri) {
      return create$1($_7f4olzd2jfuw8p68.blobToCanvas(blob), blob, uri);
    });
  }
  function fromCanvas(canvas, type) {
    return $_7f4olzd2jfuw8p68.canvasToBlob(canvas, type).then(function (blob) {
      return create$1(Promise.resolve(canvas), blob, canvas.toDataURL());
    });
  }
  function fromImage(image) {
    return $_7f4olzd2jfuw8p68.imageToBlob(image).then(function (blob) {
      return fromBlob(blob);
    });
  }
  var fromBlobAndUrlSync = function (blob, url) {
    return create$1($_7f4olzd2jfuw8p68.blobToCanvas(blob), blob, url);
  };
  var $_au8agadhjfuw8p7k = {
    fromBlob: fromBlob,
    fromCanvas: fromCanvas,
    fromImage: fromImage,
    fromBlobAndUrlSync: fromBlobAndUrlSync
  };

  function clamp(value, min, max) {
    value = parseFloat(value);
    if (value > max) {
      value = max;
    } else if (value < min) {
      value = min;
    }
    return value;
  }
  function identity$1() {
    return [
      1,
      0,
      0,
      0,
      0,
      0,
      1,
      0,
      0,
      0,
      0,
      0,
      1,
      0,
      0,
      0,
      0,
      0,
      1,
      0,
      0,
      0,
      0,
      0,
      1
    ];
  }
  var DELTA_INDEX = [
    0,
    0.01,
    0.02,
    0.04,
    0.05,
    0.06,
    0.07,
    0.08,
    0.1,
    0.11,
    0.12,
    0.14,
    0.15,
    0.16,
    0.17,
    0.18,
    0.2,
    0.21,
    0.22,
    0.24,
    0.25,
    0.27,
    0.28,
    0.3,
    0.32,
    0.34,
    0.36,
    0.38,
    0.4,
    0.42,
    0.44,
    0.46,
    0.48,
    0.5,
    0.53,
    0.56,
    0.59,
    0.62,
    0.65,
    0.68,
    0.71,
    0.74,
    0.77,
    0.8,
    0.83,
    0.86,
    0.89,
    0.92,
    0.95,
    0.98,
    1,
    1.06,
    1.12,
    1.18,
    1.24,
    1.3,
    1.36,
    1.42,
    1.48,
    1.54,
    1.6,
    1.66,
    1.72,
    1.78,
    1.84,
    1.9,
    1.96,
    2,
    2.12,
    2.25,
    2.37,
    2.5,
    2.62,
    2.75,
    2.87,
    3,
    3.2,
    3.4,
    3.6,
    3.8,
    4,
    4.3,
    4.7,
    4.9,
    5,
    5.5,
    6,
    6.5,
    6.8,
    7,
    7.3,
    7.5,
    7.8,
    8,
    8.4,
    8.7,
    9,
    9.4,
    9.6,
    9.8,
    10
  ];
  function multiply(matrix1, matrix2) {
    var i, j, k, val, col = [], out = new Array(10);
    for (i = 0; i < 5; i++) {
      for (j = 0; j < 5; j++) {
        col[j] = matrix2[j + i * 5];
      }
      for (j = 0; j < 5; j++) {
        val = 0;
        for (k = 0; k < 5; k++) {
          val += matrix1[j + k * 5] * col[k];
        }
        out[j + i * 5] = val;
      }
    }
    return out;
  }
  function adjust(matrix, adjustValue) {
    adjustValue = clamp(adjustValue, 0, 1);
    return matrix.map(function (value, index) {
      if (index % 6 === 0) {
        value = 1 - (1 - value) * adjustValue;
      } else {
        value *= adjustValue;
      }
      return clamp(value, 0, 1);
    });
  }
  function adjustContrast(matrix, value) {
    var x;
    value = clamp(value, -1, 1);
    value *= 100;
    if (value < 0) {
      x = 127 + value / 100 * 127;
    } else {
      x = value % 1;
      if (x === 0) {
        x = DELTA_INDEX[value];
      } else {
        x = DELTA_INDEX[Math.floor(value)] * (1 - x) + DELTA_INDEX[Math.floor(value) + 1] * x;
      }
      x = x * 127 + 127;
    }
    return multiply(matrix, [
      x / 127,
      0,
      0,
      0,
      0.5 * (127 - x),
      0,
      x / 127,
      0,
      0,
      0.5 * (127 - x),
      0,
      0,
      x / 127,
      0,
      0.5 * (127 - x),
      0,
      0,
      0,
      1,
      0,
      0,
      0,
      0,
      0,
      1
    ]);
  }
  function adjustSaturation(matrix, value) {
    var x, lumR, lumG, lumB;
    value = clamp(value, -1, 1);
    x = 1 + (value > 0 ? 3 * value : value);
    lumR = 0.3086;
    lumG = 0.6094;
    lumB = 0.082;
    return multiply(matrix, [
      lumR * (1 - x) + x,
      lumG * (1 - x),
      lumB * (1 - x),
      0,
      0,
      lumR * (1 - x),
      lumG * (1 - x) + x,
      lumB * (1 - x),
      0,
      0,
      lumR * (1 - x),
      lumG * (1 - x),
      lumB * (1 - x) + x,
      0,
      0,
      0,
      0,
      0,
      1,
      0,
      0,
      0,
      0,
      0,
      1
    ]);
  }
  function adjustHue(matrix, angle) {
    var cosVal, sinVal, lumR, lumG, lumB;
    angle = clamp(angle, -180, 180) / 180 * Math.PI;
    cosVal = Math.cos(angle);
    sinVal = Math.sin(angle);
    lumR = 0.213;
    lumG = 0.715;
    lumB = 0.072;
    return multiply(matrix, [
      lumR + cosVal * (1 - lumR) + sinVal * -lumR,
      lumG + cosVal * -lumG + sinVal * -lumG,
      lumB + cosVal * -lumB + sinVal * (1 - lumB),
      0,
      0,
      lumR + cosVal * -lumR + sinVal * 0.143,
      lumG + cosVal * (1 - lumG) + sinVal * 0.14,
      lumB + cosVal * -lumB + sinVal * -0.283,
      0,
      0,
      lumR + cosVal * -lumR + sinVal * -(1 - lumR),
      lumG + cosVal * -lumG + sinVal * lumG,
      lumB + cosVal * (1 - lumB) + sinVal * lumB,
      0,
      0,
      0,
      0,
      0,
      1,
      0,
      0,
      0,
      0,
      0,
      1
    ]);
  }
  function adjustBrightness(matrix, value) {
    value = clamp(255 * value, -255, 255);
    return multiply(matrix, [
      1,
      0,
      0,
      0,
      value,
      0,
      1,
      0,
      0,
      value,
      0,
      0,
      1,
      0,
      value,
      0,
      0,
      0,
      1,
      0,
      0,
      0,
      0,
      0,
      1
    ]);
  }
  function adjustColors(matrix, adjustR, adjustG, adjustB) {
    adjustR = clamp(adjustR, 0, 2);
    adjustG = clamp(adjustG, 0, 2);
    adjustB = clamp(adjustB, 0, 2);
    return multiply(matrix, [
      adjustR,
      0,
      0,
      0,
      0,
      0,
      adjustG,
      0,
      0,
      0,
      0,
      0,
      adjustB,
      0,
      0,
      0,
      0,
      0,
      1,
      0,
      0,
      0,
      0,
      0,
      1
    ]);
  }
  function adjustSepia(matrix, value) {
    value = clamp(value, 0, 1);
    return multiply(matrix, adjust([
      0.393,
      0.769,
      0.189,
      0,
      0,
      0.349,
      0.686,
      0.168,
      0,
      0,
      0.272,
      0.534,
      0.131,
      0,
      0,
      0,
      0,
      0,
      1,
      0,
      0,
      0,
      0,
      0,
      1
    ], value));
  }
  function adjustGrayscale(matrix, value) {
    value = clamp(value, 0, 1);
    return multiply(matrix, adjust([
      0.33,
      0.34,
      0.33,
      0,
      0,
      0.33,
      0.34,
      0.33,
      0,
      0,
      0.33,
      0.34,
      0.33,
      0,
      0,
      0,
      0,
      0,
      1,
      0,
      0,
      0,
      0,
      0,
      1
    ], value));
  }
  var $_21dvacdijfuw8p7q = {
    identity: identity$1,
    adjust: adjust,
    multiply: multiply,
    adjustContrast: adjustContrast,
    adjustBrightness: adjustBrightness,
    adjustSaturation: adjustSaturation,
    adjustHue: adjustHue,
    adjustColors: adjustColors,
    adjustSepia: adjustSepia,
    adjustGrayscale: adjustGrayscale
  };

  function colorFilter(ir, matrix) {
    return ir.toCanvas().then(function (canvas) {
      return applyColorFilter(canvas, ir.getType(), matrix);
    });
  }
  function applyColorFilter(canvas, type, matrix) {
    var context = $_bg99ivd3jfuw8p6o.get2dContext(canvas);
    var pixels;
    function applyMatrix(pixels, m) {
      var d = pixels.data, r, g, b, a, i, m0 = m[0], m1 = m[1], m2 = m[2], m3 = m[3], m4 = m[4], m5 = m[5], m6 = m[6], m7 = m[7], m8 = m[8], m9 = m[9], m10 = m[10], m11 = m[11], m12 = m[12], m13 = m[13], m14 = m[14], m15 = m[15], m16 = m[16], m17 = m[17], m18 = m[18], m19 = m[19];
      for (i = 0; i < d.length; i += 4) {
        r = d[i];
        g = d[i + 1];
        b = d[i + 2];
        a = d[i + 3];
        d[i] = r * m0 + g * m1 + b * m2 + a * m3 + m4;
        d[i + 1] = r * m5 + g * m6 + b * m7 + a * m8 + m9;
        d[i + 2] = r * m10 + g * m11 + b * m12 + a * m13 + m14;
        d[i + 3] = r * m15 + g * m16 + b * m17 + a * m18 + m19;
      }
      return pixels;
    }
    pixels = applyMatrix(context.getImageData(0, 0, canvas.width, canvas.height), matrix);
    context.putImageData(pixels, 0, 0);
    return $_au8agadhjfuw8p7k.fromCanvas(canvas, type);
  }
  function convoluteFilter(ir, matrix) {
    return ir.toCanvas().then(function (canvas) {
      return applyConvoluteFilter(canvas, ir.getType(), matrix);
    });
  }
  function applyConvoluteFilter(canvas, type, matrix) {
    var context = $_bg99ivd3jfuw8p6o.get2dContext(canvas);
    var pixelsIn, pixelsOut;
    function applyMatrix(pixelsIn, pixelsOut, matrix) {
      var rgba, drgba, side, halfSide, x, y, r, g, b, cx, cy, scx, scy, offset, wt, w, h;
      function clamp(value, min, max) {
        if (value > max) {
          value = max;
        } else if (value < min) {
          value = min;
        }
        return value;
      }
      side = Math.round(Math.sqrt(matrix.length));
      halfSide = Math.floor(side / 2);
      rgba = pixelsIn.data;
      drgba = pixelsOut.data;
      w = pixelsIn.width;
      h = pixelsIn.height;
      for (y = 0; y < h; y++) {
        for (x = 0; x < w; x++) {
          r = g = b = 0;
          for (cy = 0; cy < side; cy++) {
            for (cx = 0; cx < side; cx++) {
              scx = clamp(x + cx - halfSide, 0, w - 1);
              scy = clamp(y + cy - halfSide, 0, h - 1);
              offset = (scy * w + scx) * 4;
              wt = matrix[cy * side + cx];
              r += rgba[offset] * wt;
              g += rgba[offset + 1] * wt;
              b += rgba[offset + 2] * wt;
            }
          }
          offset = (y * w + x) * 4;
          drgba[offset] = clamp(r, 0, 255);
          drgba[offset + 1] = clamp(g, 0, 255);
          drgba[offset + 2] = clamp(b, 0, 255);
        }
      }
      return pixelsOut;
    }
    pixelsIn = context.getImageData(0, 0, canvas.width, canvas.height);
    pixelsOut = context.getImageData(0, 0, canvas.width, canvas.height);
    pixelsOut = applyMatrix(pixelsIn, pixelsOut, matrix);
    context.putImageData(pixelsOut, 0, 0);
    return $_au8agadhjfuw8p7k.fromCanvas(canvas, type);
  }
  function functionColorFilter(colorFn) {
    var filterImpl = function (canvas, type, value) {
      var context = $_bg99ivd3jfuw8p6o.get2dContext(canvas);
      var pixels, i, lookup = new Array(256);
      function applyLookup(pixels, lookup) {
        var d = pixels.data, i;
        for (i = 0; i < d.length; i += 4) {
          d[i] = lookup[d[i]];
          d[i + 1] = lookup[d[i + 1]];
          d[i + 2] = lookup[d[i + 2]];
        }
        return pixels;
      }
      for (i = 0; i < lookup.length; i++) {
        lookup[i] = colorFn(i, value);
      }
      pixels = applyLookup(context.getImageData(0, 0, canvas.width, canvas.height), lookup);
      context.putImageData(pixels, 0, 0);
      return $_au8agadhjfuw8p7k.fromCanvas(canvas, type);
    };
    return function (ir, value) {
      return ir.toCanvas().then(function (canvas) {
        return filterImpl(canvas, ir.getType(), value);
      });
    };
  }
  function complexAdjustableColorFilter(matrixAdjustFn) {
    return function (ir, adjust) {
      return colorFilter(ir, matrixAdjustFn($_21dvacdijfuw8p7q.identity(), adjust));
    };
  }
  function basicColorFilter(matrix) {
    return function (ir) {
      return colorFilter(ir, matrix);
    };
  }
  function basicConvolutionFilter(kernel) {
    return function (ir) {
      return convoluteFilter(ir, kernel);
    };
  }
  var $_2mb1padgjfuw8p7e = {
    invert: basicColorFilter([
      -1,
      0,
      0,
      0,
      255,
      0,
      -1,
      0,
      0,
      255,
      0,
      0,
      -1,
      0,
      255,
      0,
      0,
      0,
      1,
      0
    ]),
    brightness: complexAdjustableColorFilter($_21dvacdijfuw8p7q.adjustBrightness),
    hue: complexAdjustableColorFilter($_21dvacdijfuw8p7q.adjustHue),
    saturate: complexAdjustableColorFilter($_21dvacdijfuw8p7q.adjustSaturation),
    contrast: complexAdjustableColorFilter($_21dvacdijfuw8p7q.adjustContrast),
    grayscale: complexAdjustableColorFilter($_21dvacdijfuw8p7q.adjustGrayscale),
    sepia: complexAdjustableColorFilter($_21dvacdijfuw8p7q.adjustSepia),
    colorize: function (ir, adjustR, adjustG, adjustB) {
      return colorFilter(ir, $_21dvacdijfuw8p7q.adjustColors($_21dvacdijfuw8p7q.identity(), adjustR, adjustG, adjustB));
    },
    sharpen: basicConvolutionFilter([
      0,
      -1,
      0,
      -1,
      5,
      -1,
      0,
      -1,
      0
    ]),
    emboss: basicConvolutionFilter([
      -2,
      -1,
      0,
      -1,
      1,
      1,
      0,
      1,
      2
    ]),
    gamma: functionColorFilter(function (color, value) {
      return Math.pow(color / 255, 1 - value) * 255;
    }),
    exposure: functionColorFilter(function (color, value) {
      return 255 * (1 - Math.exp(-(color / 255) * value));
    }),
    colorFilter: colorFilter,
    convoluteFilter: convoluteFilter
  };

  function scale(image, dW, dH) {
    var sW = $_29drijd4jfuw8p6p.getWidth(image);
    var sH = $_29drijd4jfuw8p6p.getHeight(image);
    var wRatio = dW / sW;
    var hRatio = dH / sH;
    var scaleCapped = false;
    if (wRatio < 0.5 || wRatio > 2) {
      wRatio = wRatio < 0.5 ? 0.5 : 2;
      scaleCapped = true;
    }
    if (hRatio < 0.5 || hRatio > 2) {
      hRatio = hRatio < 0.5 ? 0.5 : 2;
      scaleCapped = true;
    }
    var scaled = _scale(image, wRatio, hRatio);
    return !scaleCapped ? scaled : scaled.then(function (tCanvas) {
      return scale(tCanvas, dW, dH);
    });
  }
  function _scale(image, wRatio, hRatio) {
    return new Promise(function (resolve) {
      var sW = $_29drijd4jfuw8p6p.getWidth(image);
      var sH = $_29drijd4jfuw8p6p.getHeight(image);
      var dW = Math.floor(sW * wRatio);
      var dH = Math.floor(sH * hRatio);
      var canvas = $_bg99ivd3jfuw8p6o.create(dW, dH);
      var context = $_bg99ivd3jfuw8p6o.get2dContext(canvas);
      context.drawImage(image, 0, 0, sW, sH, 0, 0, dW, dH);
      resolve(canvas);
    });
  }
  var $_asqkcjdkjfuw8p85 = { scale: scale };

  function rotate(ir, angle) {
    return ir.toCanvas().then(function (canvas) {
      return applyRotate(canvas, ir.getType(), angle);
    });
  }
  function applyRotate(image, type, angle) {
    var canvas = $_bg99ivd3jfuw8p6o.create(image.width, image.height);
    var context = $_bg99ivd3jfuw8p6o.get2dContext(canvas);
    var translateX = 0, translateY = 0;
    angle = angle < 0 ? 360 + angle : angle;
    if (angle == 90 || angle == 270) {
      $_bg99ivd3jfuw8p6o.resize(canvas, canvas.height, canvas.width);
    }
    if (angle == 90 || angle == 180) {
      translateX = canvas.width;
    }
    if (angle == 270 || angle == 180) {
      translateY = canvas.height;
    }
    context.translate(translateX, translateY);
    context.rotate(angle * Math.PI / 180);
    context.drawImage(image, 0, 0);
    return $_au8agadhjfuw8p7k.fromCanvas(canvas, type);
  }
  function flip(ir, axis) {
    return ir.toCanvas().then(function (canvas) {
      return applyFlip(canvas, ir.getType(), axis);
    });
  }
  function applyFlip(image, type, axis) {
    var canvas = $_bg99ivd3jfuw8p6o.create(image.width, image.height);
    var context = $_bg99ivd3jfuw8p6o.get2dContext(canvas);
    if (axis == 'v') {
      context.scale(1, -1);
      context.drawImage(image, 0, -canvas.height);
    } else {
      context.scale(-1, 1);
      context.drawImage(image, -canvas.width, 0);
    }
    return $_au8agadhjfuw8p7k.fromCanvas(canvas, type);
  }
  function crop(ir, x, y, w, h) {
    return ir.toCanvas().then(function (canvas) {
      return applyCrop(canvas, ir.getType(), x, y, w, h);
    });
  }
  function applyCrop(image, type, x, y, w, h) {
    var canvas = $_bg99ivd3jfuw8p6o.create(w, h);
    var context = $_bg99ivd3jfuw8p6o.get2dContext(canvas);
    context.drawImage(image, -x, -y);
    return $_au8agadhjfuw8p7k.fromCanvas(canvas, type);
  }
  function resize$1(ir, w, h) {
    return ir.toCanvas().then(function (canvas) {
      return $_asqkcjdkjfuw8p85.scale(canvas, w, h).then(function (newCanvas) {
        return $_au8agadhjfuw8p7k.fromCanvas(newCanvas, ir.getType());
      });
    });
  }
  var $_5so0xfdjjfuw8p82 = {
    rotate: rotate,
    flip: flip,
    crop: crop,
    resize: resize$1
  };

  var invert = function (ir) {
    return $_2mb1padgjfuw8p7e.invert(ir);
  };
  var sharpen = function (ir) {
    return $_2mb1padgjfuw8p7e.sharpen(ir);
  };
  var emboss = function (ir) {
    return $_2mb1padgjfuw8p7e.emboss(ir);
  };
  var gamma = function (ir, value) {
    return $_2mb1padgjfuw8p7e.gamma(ir, value);
  };
  var exposure = function (ir, value) {
    return $_2mb1padgjfuw8p7e.exposure(ir, value);
  };
  var colorize = function (ir, adjustR, adjustG, adjustB) {
    return $_2mb1padgjfuw8p7e.colorize(ir, adjustR, adjustG, adjustB);
  };
  var brightness = function (ir, adjust) {
    return $_2mb1padgjfuw8p7e.brightness(ir, adjust);
  };
  var hue = function (ir, adjust) {
    return $_2mb1padgjfuw8p7e.hue(ir, adjust);
  };
  var saturate = function (ir, adjust) {
    return $_2mb1padgjfuw8p7e.saturate(ir, adjust);
  };
  var contrast = function (ir, adjust) {
    return $_2mb1padgjfuw8p7e.contrast(ir, adjust);
  };
  var grayscale = function (ir, adjust) {
    return $_2mb1padgjfuw8p7e.grayscale(ir, adjust);
  };
  var sepia = function (ir, adjust) {
    return $_2mb1padgjfuw8p7e.sepia(ir, adjust);
  };
  var flip$1 = function (ir, axis) {
    return $_5so0xfdjjfuw8p82.flip(ir, axis);
  };
  var crop$1 = function (ir, x, y, w, h) {
    return $_5so0xfdjjfuw8p82.crop(ir, x, y, w, h);
  };
  var resize$2 = function (ir, w, h) {
    return $_5so0xfdjjfuw8p82.resize(ir, w, h);
  };
  var rotate$1 = function (ir, angle) {
    return $_5so0xfdjjfuw8p82.rotate(ir, angle);
  };
  var $_5r6zxadfjfuw8p7b = {
    invert: invert,
    sharpen: sharpen,
    emboss: emboss,
    brightness: brightness,
    hue: hue,
    saturate: saturate,
    contrast: contrast,
    grayscale: grayscale,
    sepia: sepia,
    colorize: colorize,
    gamma: gamma,
    exposure: exposure,
    flip: flip$1,
    crop: crop$1,
    resize: resize$2,
    rotate: rotate$1
  };

  var blobToImageResult = function (blob) {
    return $_au8agadhjfuw8p7k.fromBlob(blob);
  };
  var fromBlobAndUrlSync$1 = function (blob, uri) {
    return $_au8agadhjfuw8p7k.fromBlobAndUrlSync(blob, uri);
  };
  var imageToImageResult = function (image) {
    return $_au8agadhjfuw8p7k.fromImage(image);
  };
  var imageResultToBlob = function (ir, type, quality) {
    if (type === undefined && quality === undefined) {
      return imageResultToOriginalBlob(ir);
    } else {
      return ir.toAdjustedBlob(type, quality);
    }
  };
  var imageResultToOriginalBlob = function (ir) {
    return ir.toBlob();
  };
  var imageResultToDataURL = function (ir) {
    return ir.toDataURL();
  };
  var $_9ujscsdljfuw8p87 = {
    blobToImageResult: blobToImageResult,
    fromBlobAndUrlSync: fromBlobAndUrlSync$1,
    imageToImageResult: imageToImageResult,
    imageResultToBlob: imageResultToBlob,
    imageResultToOriginalBlob: imageResultToOriginalBlob,
    imageResultToDataURL: imageResultToDataURL
  };

  var url = function () {
    return $_9b4fxbd9jfuw8p72.getOrDie('URL');
  };
  var createObjectURL = function (blob) {
    return url().createObjectURL(blob);
  };
  var revokeObjectURL = function (u) {
    url().revokeObjectURL(u);
  };
  var $_c1346xdmjfuw8p89 = {
    createObjectURL: createObjectURL,
    revokeObjectURL: revokeObjectURL
  };

  var global$3 = tinymce.util.Tools.resolve('tinymce.util.Delay');

  var global$4 = tinymce.util.Tools.resolve('tinymce.util.Promise');

  var global$5 = tinymce.util.Tools.resolve('tinymce.util.URI');

  var getToolbarItems = function (editor) {
    return editor.getParam('imagetools_toolbar', 'rotateleft rotateright | flipv fliph | crop editimage imageoptions');
  };
  var getProxyUrl = function (editor) {
    return editor.getParam('imagetools_proxy');
  };
  var getCorsHosts = function (editor) {
    return editor.getParam('imagetools_cors_hosts', [], 'string[]');
  };
  var getCredentialsHosts = function (editor) {
    return editor.getParam('imagetools_credentials_hosts', [], 'string[]');
  };
  var getApiKey = function (editor) {
    return editor.getParam('api_key', editor.getParam('imagetools_api_key', '', 'string'), 'string');
  };
  var getUploadTimeout = function (editor) {
    return editor.getParam('images_upload_timeout', 30000, 'number');
  };
  var shouldReuseFilename = function (editor) {
    return editor.getParam('images_reuse_filename', false, 'boolean');
  };

  var global$6 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');

  var global$7 = tinymce.util.Tools.resolve('tinymce.ui.Factory');

  function UndoStack () {
    var data = [];
    var index = -1;
    function add(state) {
      var removed;
      removed = data.splice(++index);
      data.push(state);
      return {
        state: state,
        removed: removed
      };
    }
    function undo() {
      if (canUndo()) {
        return data[--index];
      }
    }
    function redo() {
      if (canRedo()) {
        return data[++index];
      }
    }
    function canUndo() {
      return index > 0;
    }
    function canRedo() {
      return index !== -1 && index < data.length - 1;
    }
    return {
      data: data,
      add: add,
      undo: undo,
      redo: redo,
      canUndo: canUndo,
      canRedo: canRedo
    };
  }

  var global$8 = tinymce.util.Tools.resolve('tinymce.geom.Rect');

  var loadImage$1 = function (image) {
    return new global$4(function (resolve) {
      var loaded = function () {
        image.removeEventListener('load', loaded);
        resolve(image);
      };
      if (image.complete) {
        resolve(image);
      } else {
        image.addEventListener('load', loaded);
      }
    });
  };
  var $_e5sosfdxjfuw8p93 = { loadImage: loadImage$1 };

  var global$9 = tinymce.util.Tools.resolve('tinymce.dom.DomQuery');

  var global$10 = tinymce.util.Tools.resolve('tinymce.util.Observable');

  var global$11 = tinymce.util.Tools.resolve('tinymce.util.VK');

  var count = 0;
  function CropRect (currentRect, viewPortRect, clampRect, containerElm, action) {
    var instance;
    var handles;
    var dragHelpers;
    var blockers;
    var prefix = 'mce-';
    var id = prefix + 'crid-' + count++;
    handles = [
      {
        name: 'move',
        xMul: 0,
        yMul: 0,
        deltaX: 1,
        deltaY: 1,
        deltaW: 0,
        deltaH: 0,
        label: 'Crop Mask'
      },
      {
        name: 'nw',
        xMul: 0,
        yMul: 0,
        deltaX: 1,
        deltaY: 1,
        deltaW: -1,
        deltaH: -1,
        label: 'Top Left Crop Handle'
      },
      {
        name: 'ne',
        xMul: 1,
        yMul: 0,
        deltaX: 0,
        deltaY: 1,
        deltaW: 1,
        deltaH: -1,
        label: 'Top Right Crop Handle'
      },
      {
        name: 'sw',
        xMul: 0,
        yMul: 1,
        deltaX: 1,
        deltaY: 0,
        deltaW: -1,
        deltaH: 1,
        label: 'Bottom Left Crop Handle'
      },
      {
        name: 'se',
        xMul: 1,
        yMul: 1,
        deltaX: 0,
        deltaY: 0,
        deltaW: 1,
        deltaH: 1,
        label: 'Bottom Right Crop Handle'
      }
    ];
    blockers = [
      'top',
      'right',
      'bottom',
      'left'
    ];
    function getAbsoluteRect(outerRect, relativeRect) {
      return {
        x: relativeRect.x + outerRect.x,
        y: relativeRect.y + outerRect.y,
        w: relativeRect.w,
        h: relativeRect.h
      };
    }
    function getRelativeRect(outerRect, innerRect) {
      return {
        x: innerRect.x - outerRect.x,
        y: innerRect.y - outerRect.y,
        w: innerRect.w,
        h: innerRect.h
      };
    }
    function getInnerRect() {
      return getRelativeRect(clampRect, currentRect);
    }
    function moveRect(handle, startRect, deltaX, deltaY) {
      var x, y, w, h, rect;
      x = startRect.x;
      y = startRect.y;
      w = startRect.w;
      h = startRect.h;
      x += deltaX * handle.deltaX;
      y += deltaY * handle.deltaY;
      w += deltaX * handle.deltaW;
      h += deltaY * handle.deltaH;
      if (w < 20) {
        w = 20;
      }
      if (h < 20) {
        h = 20;
      }
      rect = currentRect = global$8.clamp({
        x: x,
        y: y,
        w: w,
        h: h
      }, clampRect, handle.name === 'move');
      rect = getRelativeRect(clampRect, rect);
      instance.fire('updateRect', { rect: rect });
      setInnerRect(rect);
    }
    function render() {
      function createDragHelper(handle) {
        var startRect;
        var DragHelper = global$7.get('DragHelper');
        return new DragHelper(id, {
          document: containerElm.ownerDocument,
          handle: id + '-' + handle.name,
          start: function () {
            startRect = currentRect;
          },
          drag: function (e) {
            moveRect(handle, startRect, e.deltaX, e.deltaY);
          }
        });
      }
      global$9('<div id="' + id + '" class="' + prefix + 'croprect-container"' + ' role="grid" aria-dropeffect="execute">').appendTo(containerElm);
      global$1.each(blockers, function (blocker) {
        global$9('#' + id, containerElm).append('<div id="' + id + '-' + blocker + '"class="' + prefix + 'croprect-block" style="display: none" data-mce-bogus="all">');
      });
      global$1.each(handles, function (handle) {
        global$9('#' + id, containerElm).append('<div id="' + id + '-' + handle.name + '" class="' + prefix + 'croprect-handle ' + prefix + 'croprect-handle-' + handle.name + '"' + 'style="display: none" data-mce-bogus="all" role="gridcell" tabindex="-1"' + ' aria-label="' + handle.label + '" aria-grabbed="false">');
      });
      dragHelpers = global$1.map(handles, createDragHelper);
      repaint(currentRect);
      global$9(containerElm).on('focusin focusout', function (e) {
        global$9(e.target).attr('aria-grabbed', e.type === 'focus');
      });
      global$9(containerElm).on('keydown', function (e) {
        var activeHandle;
        global$1.each(handles, function (handle) {
          if (e.target.id === id + '-' + handle.name) {
            activeHandle = handle;
            return false;
          }
        });
        function moveAndBlock(evt, handle, startRect, deltaX, deltaY) {
          evt.stopPropagation();
          evt.preventDefault();
          moveRect(activeHandle, startRect, deltaX, deltaY);
        }
        switch (e.keyCode) {
        case global$11.LEFT:
          moveAndBlock(e, activeHandle, currentRect, -10, 0);
          break;
        case global$11.RIGHT:
          moveAndBlock(e, activeHandle, currentRect, 10, 0);
          break;
        case global$11.UP:
          moveAndBlock(e, activeHandle, currentRect, 0, -10);
          break;
        case global$11.DOWN:
          moveAndBlock(e, activeHandle, currentRect, 0, 10);
          break;
        case global$11.ENTER:
        case global$11.SPACEBAR:
          e.preventDefault();
          action();
          break;
        }
      });
    }
    function toggleVisibility(state) {
      var selectors;
      selectors = global$1.map(handles, function (handle) {
        return '#' + id + '-' + handle.name;
      }).concat(global$1.map(blockers, function (blocker) {
        return '#' + id + '-' + blocker;
      })).join(',');
      if (state) {
        global$9(selectors, containerElm).show();
      } else {
        global$9(selectors, containerElm).hide();
      }
    }
    function repaint(rect) {
      function updateElementRect(name, rect) {
        if (rect.h < 0) {
          rect.h = 0;
        }
        if (rect.w < 0) {
          rect.w = 0;
        }
        global$9('#' + id + '-' + name, containerElm).css({
          left: rect.x,
          top: rect.y,
          width: rect.w,
          height: rect.h
        });
      }
      global$1.each(handles, function (handle) {
        global$9('#' + id + '-' + handle.name, containerElm).css({
          left: rect.w * handle.xMul + rect.x,
          top: rect.h * handle.yMul + rect.y
        });
      });
      updateElementRect('top', {
        x: viewPortRect.x,
        y: viewPortRect.y,
        w: viewPortRect.w,
        h: rect.y - viewPortRect.y
      });
      updateElementRect('right', {
        x: rect.x + rect.w,
        y: rect.y,
        w: viewPortRect.w - rect.x - rect.w + viewPortRect.x,
        h: rect.h
      });
      updateElementRect('bottom', {
        x: viewPortRect.x,
        y: rect.y + rect.h,
        w: viewPortRect.w,
        h: viewPortRect.h - rect.y - rect.h + viewPortRect.y
      });
      updateElementRect('left', {
        x: viewPortRect.x,
        y: rect.y,
        w: rect.x - viewPortRect.x,
        h: rect.h
      });
      updateElementRect('move', rect);
    }
    function setRect(rect) {
      currentRect = rect;
      repaint(currentRect);
    }
    function setViewPortRect(rect) {
      viewPortRect = rect;
      repaint(currentRect);
    }
    function setInnerRect(rect) {
      setRect(getAbsoluteRect(clampRect, rect));
    }
    function setClampRect(rect) {
      clampRect = rect;
      repaint(currentRect);
    }
    function destroy() {
      global$1.each(dragHelpers, function (helper) {
        helper.destroy();
      });
      dragHelpers = [];
    }
    render();
    instance = global$1.extend({
      toggleVisibility: toggleVisibility,
      setClampRect: setClampRect,
      setRect: setRect,
      getInnerRect: getInnerRect,
      setInnerRect: setInnerRect,
      setViewPortRect: setViewPortRect,
      destroy: destroy
    }, global$10);
    return instance;
  }

  var create$2 = function (settings) {
    var Control = global$7.get('Control');
    var ImagePanel = Control.extend({
      Defaults: { classes: 'imagepanel' },
      selection: function (rect) {
        if (arguments.length) {
          this.state.set('rect', rect);
          return this;
        }
        return this.state.get('rect');
      },
      imageSize: function () {
        var viewRect = this.state.get('viewRect');
        return {
          w: viewRect.w,
          h: viewRect.h
        };
      },
      toggleCropRect: function (state) {
        this.state.set('cropEnabled', state);
      },
      imageSrc: function (url) {
        var self = this, img = new Image();
        img.src = url;
        $_e5sosfdxjfuw8p93.loadImage(img).then(function () {
          var rect, $img;
          var lastRect = self.state.get('viewRect');
          $img = self.$el.find('img');
          if ($img[0]) {
            $img.replaceWith(img);
          } else {
            var bg = document.createElement('div');
            bg.className = 'mce-imagepanel-bg';
            self.getEl().appendChild(bg);
            self.getEl().appendChild(img);
          }
          rect = {
            x: 0,
            y: 0,
            w: img.naturalWidth,
            h: img.naturalHeight
          };
          self.state.set('viewRect', rect);
          self.state.set('rect', global$8.inflate(rect, -20, -20));
          if (!lastRect || lastRect.w !== rect.w || lastRect.h !== rect.h) {
            self.zoomFit();
          }
          self.repaintImage();
          self.fire('load');
        });
      },
      zoom: function (value) {
        if (arguments.length) {
          this.state.set('zoom', value);
          return this;
        }
        return this.state.get('zoom');
      },
      postRender: function () {
        this.imageSrc(this.settings.imageSrc);
        return this._super();
      },
      zoomFit: function () {
        var self = this;
        var $img, pw, ph, w, h, zoom, padding;
        padding = 10;
        $img = self.$el.find('img');
        pw = self.getEl().clientWidth;
        ph = self.getEl().clientHeight;
        w = $img[0].naturalWidth;
        h = $img[0].naturalHeight;
        zoom = Math.min((pw - padding) / w, (ph - padding) / h);
        if (zoom >= 1) {
          zoom = 1;
        }
        self.zoom(zoom);
      },
      repaintImage: function () {
        var x, y, w, h, pw, ph, $img, $bg, zoom, rect, elm;
        elm = this.getEl();
        zoom = this.zoom();
        rect = this.state.get('rect');
        $img = this.$el.find('img');
        $bg = this.$el.find('.mce-imagepanel-bg');
        pw = elm.offsetWidth;
        ph = elm.offsetHeight;
        w = $img[0].naturalWidth * zoom;
        h = $img[0].naturalHeight * zoom;
        x = Math.max(0, pw / 2 - w / 2);
        y = Math.max(0, ph / 2 - h / 2);
        $img.css({
          left: x,
          top: y,
          width: w,
          height: h
        });
        $bg.css({
          left: x,
          top: y,
          width: w,
          height: h
        });
        if (this.cropRect) {
          this.cropRect.setRect({
            x: rect.x * zoom + x,
            y: rect.y * zoom + y,
            w: rect.w * zoom,
            h: rect.h * zoom
          });
          this.cropRect.setClampRect({
            x: x,
            y: y,
            w: w,
            h: h
          });
          this.cropRect.setViewPortRect({
            x: 0,
            y: 0,
            w: pw,
            h: ph
          });
        }
      },
      bindStates: function () {
        var self = this;
        function setupCropRect(rect) {
          self.cropRect = CropRect(rect, self.state.get('viewRect'), self.state.get('viewRect'), self.getEl(), function () {
            self.fire('crop');
          });
          self.cropRect.on('updateRect', function (e) {
            var rect = e.rect;
            var zoom = self.zoom();
            rect = {
              x: Math.round(rect.x / zoom),
              y: Math.round(rect.y / zoom),
              w: Math.round(rect.w / zoom),
              h: Math.round(rect.h / zoom)
            };
            self.state.set('rect', rect);
          });
          self.on('remove', self.cropRect.destroy);
        }
        self.state.on('change:cropEnabled', function (e) {
          self.cropRect.toggleVisibility(e.value);
          self.repaintImage();
        });
        self.state.on('change:zoom', function () {
          self.repaintImage();
        });
        self.state.on('change:rect', function (e) {
          var rect = e.value;
          if (!self.cropRect) {
            setupCropRect(rect);
          }
          self.cropRect.setRect(rect);
        });
      }
    });
    return new ImagePanel(settings);
  };
  var $_fyl1tedvjfuw8p8z = { create: create$2 };

  function createState(blob) {
    return {
      blob: blob,
      url: $_c1346xdmjfuw8p89.createObjectURL(blob)
    };
  }
  function destroyState(state) {
    if (state) {
      $_c1346xdmjfuw8p89.revokeObjectURL(state.url);
    }
  }
  function destroyStates(states) {
    global$1.each(states, destroyState);
  }
  function open(editor, currentState, resolve, reject) {
    var win, undoStack = UndoStack(), mainPanel, filtersPanel, tempState, cropPanel, resizePanel, flipRotatePanel, imagePanel, sidePanel, mainViewContainer, invertPanel, brightnessPanel, huePanel, saturatePanel, contrastPanel, grayscalePanel, sepiaPanel, colorizePanel, sharpenPanel, embossPanel, gammaPanel, exposurePanel, panels, width, height, ratioW, ratioH;
    var reverseIfRtl = function (items) {
      return editor.rtl ? items.reverse() : items;
    };
    function recalcSize(e) {
      var widthCtrl, heightCtrl, newWidth, newHeight;
      widthCtrl = win.find('#w')[0];
      heightCtrl = win.find('#h')[0];
      newWidth = parseInt(widthCtrl.value(), 10);
      newHeight = parseInt(heightCtrl.value(), 10);
      if (win.find('#constrain')[0].checked() && width && height && newWidth && newHeight) {
        if (e.control.settings.name === 'w') {
          newHeight = Math.round(newWidth * ratioW);
          heightCtrl.value(newHeight);
        } else {
          newWidth = Math.round(newHeight * ratioH);
          widthCtrl.value(newWidth);
        }
      }
      width = newWidth;
      height = newHeight;
    }
    function floatToPercent(value) {
      return Math.round(value * 100) + '%';
    }
    function updateButtonUndoStates() {
      win.find('#undo').disabled(!undoStack.canUndo());
      win.find('#redo').disabled(!undoStack.canRedo());
      win.statusbar.find('#save').disabled(!undoStack.canUndo());
    }
    function disableUndoRedo() {
      win.find('#undo').disabled(true);
      win.find('#redo').disabled(true);
    }
    function displayState(state) {
      if (state) {
        imagePanel.imageSrc(state.url);
      }
    }
    function switchPanel(targetPanel) {
      return function () {
        var hidePanels = global$1.grep(panels, function (panel) {
          return panel.settings.name !== targetPanel;
        });
        global$1.each(hidePanels, function (panel) {
          panel.hide();
        });
        targetPanel.show();
        targetPanel.focus();
      };
    }
    function addTempState(blob) {
      tempState = createState(blob);
      displayState(tempState);
    }
    function addBlobState(blob) {
      currentState = createState(blob);
      displayState(currentState);
      destroyStates(undoStack.add(currentState).removed);
      updateButtonUndoStates();
    }
    function crop() {
      var rect = imagePanel.selection();
      $_9ujscsdljfuw8p87.blobToImageResult(currentState.blob).then(function (ir) {
        $_5r6zxadfjfuw8p7b.crop(ir, rect.x, rect.y, rect.w, rect.h).then(imageResultToBlob).then(function (blob) {
          addBlobState(blob);
          cancel();
        });
      });
    }
    var tempAction = function (fn) {
      var args = [].slice.call(arguments, 1);
      return function () {
        var state = tempState || currentState;
        $_9ujscsdljfuw8p87.blobToImageResult(state.blob).then(function (ir) {
          fn.apply(this, [ir].concat(args)).then(imageResultToBlob).then(addTempState);
        });
      };
    };
    function action(fn) {
      var arg = [];
      for (var _i = 1; _i < arguments.length; _i++) {
        arg[_i - 1] = arguments[_i];
      }
      var args = [].slice.call(arguments, 1);
      return function () {
        $_9ujscsdljfuw8p87.blobToImageResult(currentState.blob).then(function (ir) {
          fn.apply(this, [ir].concat(args)).then(imageResultToBlob).then(addBlobState);
        });
      };
    }
    function cancel() {
      displayState(currentState);
      destroyState(tempState);
      switchPanel(mainPanel)();
      updateButtonUndoStates();
    }
    function waitForTempState(times, applyCall) {
      if (tempState) {
        applyCall();
      } else {
        setTimeout(function () {
          if (times-- > 0) {
            waitForTempState(times, applyCall);
          } else {
            editor.windowManager.alert('Error: failed to apply image operation.');
          }
        }, 10);
      }
    }
    function applyTempState() {
      if (tempState) {
        addBlobState(tempState.blob);
        cancel();
      } else {
        waitForTempState(100, applyTempState);
      }
    }
    function zoomIn() {
      var zoom = imagePanel.zoom();
      if (zoom < 2) {
        zoom += 0.1;
      }
      imagePanel.zoom(zoom);
    }
    function zoomOut() {
      var zoom = imagePanel.zoom();
      if (zoom > 0.1) {
        zoom -= 0.1;
      }
      imagePanel.zoom(zoom);
    }
    function undo() {
      currentState = undoStack.undo();
      displayState(currentState);
      updateButtonUndoStates();
    }
    function redo() {
      currentState = undoStack.redo();
      displayState(currentState);
      updateButtonUndoStates();
    }
    function save() {
      resolve(currentState.blob);
      win.close();
    }
    function createPanel(items) {
      return global$7.create('Form', {
        layout: 'flex',
        direction: 'row',
        labelGap: 5,
        border: '0 0 1 0',
        align: 'center',
        pack: 'center',
        padding: '0 10 0 10',
        spacing: 5,
        flex: 0,
        minHeight: 60,
        defaults: {
          classes: 'imagetool',
          type: 'button'
        },
        items: items
      });
    }
    var imageResultToBlob = function (ir) {
      return ir.toBlob();
    };
    function createFilterPanel(title, filter) {
      return createPanel(reverseIfRtl([
        {
          text: 'Back',
          onclick: cancel
        },
        {
          type: 'spacer',
          flex: 1
        },
        {
          text: 'Apply',
          subtype: 'primary',
          onclick: applyTempState
        }
      ])).hide().on('show', function () {
        disableUndoRedo();
        $_9ujscsdljfuw8p87.blobToImageResult(currentState.blob).then(function (ir) {
          return filter(ir);
        }).then(imageResultToBlob).then(function (blob) {
          var newTempState = createState(blob);
          displayState(newTempState);
          destroyState(tempState);
          tempState = newTempState;
        });
      });
    }
    function createVariableFilterPanel(title, filter, value, min, max) {
      function update(value) {
        $_9ujscsdljfuw8p87.blobToImageResult(currentState.blob).then(function (ir) {
          return filter(ir, value);
        }).then(imageResultToBlob).then(function (blob) {
          var newTempState = createState(blob);
          displayState(newTempState);
          destroyState(tempState);
          tempState = newTempState;
        });
      }
      return createPanel(reverseIfRtl([
        {
          text: 'Back',
          onclick: cancel
        },
        {
          type: 'spacer',
          flex: 1
        },
        {
          type: 'slider',
          flex: 1,
          ondragend: function (e) {
            update(e.value);
          },
          minValue: editor.rtl ? max : min,
          maxValue: editor.rtl ? min : max,
          value: value,
          previewFilter: floatToPercent
        },
        {
          type: 'spacer',
          flex: 1
        },
        {
          text: 'Apply',
          subtype: 'primary',
          onclick: applyTempState
        }
      ])).hide().on('show', function () {
        this.find('slider').value(value);
        disableUndoRedo();
      });
    }
    function createRgbFilterPanel(title, filter) {
      function update() {
        var r, g, b;
        r = win.find('#r')[0].value();
        g = win.find('#g')[0].value();
        b = win.find('#b')[0].value();
        $_9ujscsdljfuw8p87.blobToImageResult(currentState.blob).then(function (ir) {
          return filter(ir, r, g, b);
        }).then(imageResultToBlob).then(function (blob) {
          var newTempState = createState(blob);
          displayState(newTempState);
          destroyState(tempState);
          tempState = newTempState;
        });
      }
      var min = editor.rtl ? 2 : 0;
      var max = editor.rtl ? 0 : 2;
      return createPanel(reverseIfRtl([
        {
          text: 'Back',
          onclick: cancel
        },
        {
          type: 'spacer',
          flex: 1
        },
        {
          type: 'slider',
          label: 'R',
          name: 'r',
          minValue: min,
          value: 1,
          maxValue: max,
          ondragend: update,
          previewFilter: floatToPercent
        },
        {
          type: 'slider',
          label: 'G',
          name: 'g',
          minValue: min,
          value: 1,
          maxValue: max,
          ondragend: update,
          previewFilter: floatToPercent
        },
        {
          type: 'slider',
          label: 'B',
          name: 'b',
          minValue: min,
          value: 1,
          maxValue: max,
          ondragend: update,
          previewFilter: floatToPercent
        },
        {
          type: 'spacer',
          flex: 1
        },
        {
          text: 'Apply',
          subtype: 'primary',
          onclick: applyTempState
        }
      ])).hide().on('show', function () {
        win.find('#r,#g,#b').value(1);
        disableUndoRedo();
      });
    }
    cropPanel = createPanel(reverseIfRtl([
      {
        text: 'Back',
        onclick: cancel
      },
      {
        type: 'spacer',
        flex: 1
      },
      {
        text: 'Apply',
        subtype: 'primary',
        onclick: crop
      }
    ])).hide().on('show hide', function (e) {
      imagePanel.toggleCropRect(e.type === 'show');
    }).on('show', disableUndoRedo);
    function toggleConstrain(e) {
      if (e.control.value() === true) {
        ratioW = height / width;
        ratioH = width / height;
      }
    }
    resizePanel = createPanel(reverseIfRtl([
      {
        text: 'Back',
        onclick: cancel
      },
      {
        type: 'spacer',
        flex: 1
      },
      {
        type: 'textbox',
        name: 'w',
        label: 'Width',
        size: 4,
        onkeyup: recalcSize
      },
      {
        type: 'textbox',
        name: 'h',
        label: 'Height',
        size: 4,
        onkeyup: recalcSize
      },
      {
        type: 'checkbox',
        name: 'constrain',
        text: 'Constrain proportions',
        checked: true,
        onchange: toggleConstrain
      },
      {
        type: 'spacer',
        flex: 1
      },
      {
        text: 'Apply',
        subtype: 'primary',
        onclick: 'submit'
      }
    ])).hide().on('submit', function (e) {
      var width = parseInt(win.find('#w').value(), 10), height = parseInt(win.find('#h').value(), 10);
      e.preventDefault();
      action($_5r6zxadfjfuw8p7b.resize, width, height)();
      cancel();
    }).on('show', disableUndoRedo);
    flipRotatePanel = createPanel(reverseIfRtl([
      {
        text: 'Back',
        onclick: cancel
      },
      {
        type: 'spacer',
        flex: 1
      },
      {
        icon: 'fliph',
        tooltip: 'Flip horizontally',
        onclick: tempAction($_5r6zxadfjfuw8p7b.flip, 'h')
      },
      {
        icon: 'flipv',
        tooltip: 'Flip vertically',
        onclick: tempAction($_5r6zxadfjfuw8p7b.flip, 'v')
      },
      {
        icon: 'rotateleft',
        tooltip: 'Rotate counterclockwise',
        onclick: tempAction($_5r6zxadfjfuw8p7b.rotate, -90)
      },
      {
        icon: 'rotateright',
        tooltip: 'Rotate clockwise',
        onclick: tempAction($_5r6zxadfjfuw8p7b.rotate, 90)
      },
      {
        type: 'spacer',
        flex: 1
      },
      {
        text: 'Apply',
        subtype: 'primary',
        onclick: applyTempState
      }
    ])).hide().on('show', disableUndoRedo);
    invertPanel = createFilterPanel('Invert', $_5r6zxadfjfuw8p7b.invert);
    sharpenPanel = createFilterPanel('Sharpen', $_5r6zxadfjfuw8p7b.sharpen);
    embossPanel = createFilterPanel('Emboss', $_5r6zxadfjfuw8p7b.emboss);
    brightnessPanel = createVariableFilterPanel('Brightness', $_5r6zxadfjfuw8p7b.brightness, 0, -1, 1);
    huePanel = createVariableFilterPanel('Hue', $_5r6zxadfjfuw8p7b.hue, 180, 0, 360);
    saturatePanel = createVariableFilterPanel('Saturate', $_5r6zxadfjfuw8p7b.saturate, 0, -1, 1);
    contrastPanel = createVariableFilterPanel('Contrast', $_5r6zxadfjfuw8p7b.contrast, 0, -1, 1);
    grayscalePanel = createVariableFilterPanel('Grayscale', $_5r6zxadfjfuw8p7b.grayscale, 0, 0, 1);
    sepiaPanel = createVariableFilterPanel('Sepia', $_5r6zxadfjfuw8p7b.sepia, 0, 0, 1);
    colorizePanel = createRgbFilterPanel('Colorize', $_5r6zxadfjfuw8p7b.colorize);
    gammaPanel = createVariableFilterPanel('Gamma', $_5r6zxadfjfuw8p7b.gamma, 0, -1, 1);
    exposurePanel = createVariableFilterPanel('Exposure', $_5r6zxadfjfuw8p7b.exposure, 1, 0, 2);
    filtersPanel = createPanel(reverseIfRtl([
      {
        text: 'Back',
        onclick: cancel
      },
      {
        type: 'spacer',
        flex: 1
      },
      {
        text: 'hue',
        icon: 'hue',
        onclick: switchPanel(huePanel)
      },
      {
        text: 'saturate',
        icon: 'saturate',
        onclick: switchPanel(saturatePanel)
      },
      {
        text: 'sepia',
        icon: 'sepia',
        onclick: switchPanel(sepiaPanel)
      },
      {
        text: 'emboss',
        icon: 'emboss',
        onclick: switchPanel(embossPanel)
      },
      {
        text: 'exposure',
        icon: 'exposure',
        onclick: switchPanel(exposurePanel)
      },
      {
        type: 'spacer',
        flex: 1
      }
    ])).hide();
    mainPanel = createPanel(reverseIfRtl([
      {
        tooltip: 'Crop',
        icon: 'crop',
        onclick: switchPanel(cropPanel)
      },
      {
        tooltip: 'Resize',
        icon: 'resize2',
        onclick: switchPanel(resizePanel)
      },
      {
        tooltip: 'Orientation',
        icon: 'orientation',
        onclick: switchPanel(flipRotatePanel)
      },
      {
        tooltip: 'Brightness',
        icon: 'sun',
        onclick: switchPanel(brightnessPanel)
      },
      {
        tooltip: 'Sharpen',
        icon: 'sharpen',
        onclick: switchPanel(sharpenPanel)
      },
      {
        tooltip: 'Contrast',
        icon: 'contrast',
        onclick: switchPanel(contrastPanel)
      },
      {
        tooltip: 'Color levels',
        icon: 'drop',
        onclick: switchPanel(colorizePanel)
      },
      {
        tooltip: 'Gamma',
        icon: 'gamma',
        onclick: switchPanel(gammaPanel)
      },
      {
        tooltip: 'Invert',
        icon: 'invert',
        onclick: switchPanel(invertPanel)
      }
    ]));
    imagePanel = $_fyl1tedvjfuw8p8z.create({
      flex: 1,
      imageSrc: currentState.url
    });
    sidePanel = global$7.create('Container', {
      layout: 'flex',
      direction: 'column',
      pack: 'start',
      border: '0 1 0 0',
      padding: 5,
      spacing: 5,
      items: [
        {
          type: 'button',
          icon: 'undo',
          tooltip: 'Undo',
          name: 'undo',
          onclick: undo
        },
        {
          type: 'button',
          icon: 'redo',
          tooltip: 'Redo',
          name: 'redo',
          onclick: redo
        },
        {
          type: 'button',
          icon: 'zoomin',
          tooltip: 'Zoom in',
          onclick: zoomIn
        },
        {
          type: 'button',
          icon: 'zoomout',
          tooltip: 'Zoom out',
          onclick: zoomOut
        }
      ]
    });
    mainViewContainer = global$7.create('Container', {
      type: 'container',
      layout: 'flex',
      direction: 'row',
      align: 'stretch',
      flex: 1,
      items: reverseIfRtl([
        sidePanel,
        imagePanel
      ])
    });
    panels = [
      mainPanel,
      cropPanel,
      resizePanel,
      flipRotatePanel,
      filtersPanel,
      invertPanel,
      brightnessPanel,
      huePanel,
      saturatePanel,
      contrastPanel,
      grayscalePanel,
      sepiaPanel,
      colorizePanel,
      sharpenPanel,
      embossPanel,
      gammaPanel,
      exposurePanel
    ];
    win = editor.windowManager.open({
      layout: 'flex',
      direction: 'column',
      align: 'stretch',
      minWidth: Math.min(global$6.DOM.getViewPort().w, 800),
      minHeight: Math.min(global$6.DOM.getViewPort().h, 650),
      title: 'Edit image',
      items: panels.concat([mainViewContainer]),
      buttons: reverseIfRtl([
        {
          text: 'Save',
          name: 'save',
          subtype: 'primary',
          onclick: save
        },
        {
          text: 'Cancel',
          onclick: 'close'
        }
      ])
    });
    win.on('close', function () {
      reject();
      destroyStates(undoStack.data);
      undoStack = null;
      tempState = null;
    });
    undoStack.add(currentState);
    updateButtonUndoStates();
    imagePanel.on('load', function () {
      width = imagePanel.imageSize().w;
      height = imagePanel.imageSize().h;
      ratioW = height / width;
      ratioH = width / height;
      win.find('#w').value(width);
      win.find('#h').value(height);
    });
    imagePanel.on('crop', crop);
  }
  function edit(editor, imageResult) {
    return new global$4(function (resolve, reject) {
      return imageResult.toBlob().then(function (blob) {
        open(editor, createState(blob), resolve, reject);
      });
    });
  }
  var $_90401edrjfuw8p8h = { edit: edit };

  function getImageSize(img) {
    var width, height;
    function isPxValue(value) {
      return /^[0-9\.]+px$/.test(value);
    }
    width = img.style.width;
    height = img.style.height;
    if (width || height) {
      if (isPxValue(width) && isPxValue(height)) {
        return {
          w: parseInt(width, 10),
          h: parseInt(height, 10)
        };
      }
      return null;
    }
    width = img.width;
    height = img.height;
    if (width && height) {
      return {
        w: parseInt(width, 10),
        h: parseInt(height, 10)
      };
    }
    return null;
  }
  function setImageSize(img, size) {
    var width, height;
    if (size) {
      width = img.style.width;
      height = img.style.height;
      if (width || height) {
        img.style.width = size.w + 'px';
        img.style.height = size.h + 'px';
        img.removeAttribute('data-mce-style');
      }
      width = img.width;
      height = img.height;
      if (width || height) {
        img.setAttribute('width', size.w);
        img.setAttribute('height', size.h);
      }
    }
  }
  function getNaturalImageSize(img) {
    return {
      w: img.naturalWidth,
      h: img.naturalHeight
    };
  }
  var $_8ke5see2jfuw8p9d = {
    getImageSize: getImageSize,
    setImageSize: setImageSize,
    getNaturalImageSize: getNaturalImageSize
  };

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

  var rawIndexOf = function () {
    var pIndexOf = Array.prototype.indexOf;
    var fastIndex = function (xs, x) {
      return pIndexOf.call(xs, x);
    };
    var slowIndex = function (xs, x) {
      return slowIndexOf(xs, x);
    };
    return pIndexOf === undefined ? slowIndex : fastIndex;
  }();
  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) {
    return findIndex(xs, pred).isSome();
  };
  var range = function (num, f) {
    var r = [];
    for (var i = 0; i < num; i++) {
      r.push(f(i));
    }
    return r;
  };
  var chunk = function (array, size) {
    var r = [];
    for (var i = 0; i < array.length; i += size) {
      var s = array.slice(i, i + size);
      r.push(s);
    }
    return r;
  };
  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, xs);
    }
    return r;
  };
  var each = function (xs, f) {
    for (var i = 0, len = xs.length; i < len; i++) {
      var x = xs[i];
      f(x, i, xs);
    }
  };
  var eachr = function (xs, f) {
    for (var i = xs.length - 1; i >= 0; i--) {
      var x = xs[i];
      f(x, i, xs);
    }
  };
  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, xs) ? 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, xs)) {
        r.push(x);
      }
    }
    return r;
  };
  var groupBy = function (xs, f) {
    if (xs.length === 0) {
      return [];
    } else {
      var wasType = f(xs[0]);
      var r = [];
      var group = [];
      for (var i = 0, len = xs.length; i < len; i++) {
        var x = xs[i];
        var type = f(x);
        if (type !== wasType) {
          r.push(group);
          group = [];
        }
        wasType = type;
        group.push(x);
      }
      if (group.length !== 0) {
        r.push(group);
      }
      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, xs)) {
        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, xs)) {
        return Option.some(i);
      }
    }
    return Option.none();
  };
  var slowIndexOf = function (xs, x) {
    for (var i = 0, len = xs.length; i < len; ++i) {
      if (xs[i] === x) {
        return i;
      }
    }
    return -1;
  };
  var push = Array.prototype.push;
  var flatten = function (xs) {
    var r = [];
    for (var i = 0, len = xs.length; i < len; ++i) {
      if (!Array.prototype.isPrototypeOf(xs[i]))
        throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);
      push.apply(r, xs[i]);
    }
    return r;
  };
  var bind = function (xs, f) {
    var output = map(xs, f);
    return flatten(output);
  };
  var forall = function (xs, pred) {
    for (var i = 0, len = xs.length; i < len; ++i) {
      var x = xs[i];
      if (pred(x, i, xs) !== true) {
        return false;
      }
    }
    return true;
  };
  var equal = function (a1, a2) {
    return a1.length === a2.length && forall(a1, function (x, i) {
      return x === a2[i];
    });
  };
  var slice = Array.prototype.slice;
  var reverse = function (xs) {
    var r = slice.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 pure = function (x) {
    return [x];
  };
  var sort = function (xs, comparator) {
    var copy = slice.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 = $_9dbzc3e6jfuw8pa6.isFunction(Array.from) ? Array.from : function (x) {
    return slice.call(x);
  };
  var $_7pcc65e5jfuw8pa0 = {
    map: map,
    each: each,
    eachr: eachr,
    partition: partition,
    filter: filter,
    groupBy: groupBy,
    indexOf: indexOf,
    foldr: foldr,
    foldl: foldl,
    find: find,
    findIndex: findIndex,
    flatten: flatten,
    bind: bind,
    forall: forall,
    exists: exists,
    contains: contains,
    equal: equal,
    reverse: reverse,
    chunk: chunk,
    difference: difference,
    mapToObject: mapToObject,
    pure: pure,
    sort: sort,
    range: range,
    head: head,
    last: last,
    from: from$1
  };

  function XMLHttpRequest$1 () {
    var f = $_9b4fxbd9jfuw8p72.getOrDie('XMLHttpRequest');
    return new f();
  }

  var isValue = function (obj) {
    return obj !== null && obj !== undefined;
  };
  var traverse = function (json, path) {
    var value;
    value = path.reduce(function (result, key) {
      return isValue(result) ? result[key] : undefined;
    }, json);
    return isValue(value) ? value : null;
  };
  var requestUrlAsBlob = function (url, headers, withCredentials) {
    return new global$4(function (resolve) {
      var xhr;
      xhr = new XMLHttpRequest$1();
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
          resolve({
            status: xhr.status,
            blob: this.response
          });
        }
      };
      xhr.open('GET', url, true);
      xhr.withCredentials = withCredentials;
      global$1.each(headers, function (value, key) {
        xhr.setRequestHeader(key, value);
      });
      xhr.responseType = 'blob';
      xhr.send();
    });
  };
  var readBlob = function (blob) {
    return new global$4(function (resolve) {
      var fr = new FileReader();
      fr.onload = function (e) {
        var data = e.target;
        resolve(data.result);
      };
      fr.readAsText(blob);
    });
  };
  var parseJson = function (text) {
    var json;
    try {
      json = JSON.parse(text);
    } catch (ex) {
    }
    return json;
  };
  var $_1782wge7jfuw8pa8 = {
    traverse: traverse,
    readBlob: readBlob,
    requestUrlAsBlob: requestUrlAsBlob,
    parseJson: parseJson
  };

  var friendlyHttpErrors = [
    {
      code: 404,
      message: 'Could not find Image Proxy'
    },
    {
      code: 403,
      message: 'Rejected request'
    },
    {
      code: 0,
      message: 'Incorrect Image Proxy URL'
    }
  ];
  var friendlyServiceErrors = [
    {
      type: 'key_missing',
      message: 'The request did not include an api key.'
    },
    {
      type: 'key_not_found',
      message: 'The provided api key could not be found.'
    },
    {
      type: 'domain_not_trusted',
      message: 'The api key is not valid for the request origins.'
    }
  ];
  var isServiceErrorCode = function (code) {
    return code === 400 || code === 403 || code === 500;
  };
  var getHttpErrorMsg = function (status) {
    var message = $_7pcc65e5jfuw8pa0.find(friendlyHttpErrors, function (error) {
      return status === error.code;
    }).fold($_9jziv0d7jfuw8p6z.constant('Unknown ImageProxy error'), function (error) {
      return error.message;
    });
    return 'ImageProxy HTTP error: ' + message;
  };
  var handleHttpError = function (status) {
    var message = getHttpErrorMsg(status);
    return global$4.reject(message);
  };
  var getServiceErrorMsg = function (type) {
    return $_7pcc65e5jfuw8pa0.find(friendlyServiceErrors, function (error) {
      return error.type === type;
    }).fold($_9jziv0d7jfuw8p6z.constant('Unknown service error'), function (error) {
      return error.message;
    });
  };
  var getServiceError = function (text) {
    var serviceError = $_1782wge7jfuw8pa8.parseJson(text);
    var errorType = $_1782wge7jfuw8pa8.traverse(serviceError, [
      'error',
      'type'
    ]);
    var errorMsg = errorType ? getServiceErrorMsg(errorType) : 'Invalid JSON in service error message';
    return 'ImageProxy Service error: ' + errorMsg;
  };
  var handleServiceError = function (status, blob) {
    return $_1782wge7jfuw8pa8.readBlob(blob).then(function (text) {
      var serviceError = getServiceError(text);
      return global$4.reject(serviceError);
    });
  };
  var handleServiceErrorResponse = function (status, blob) {
    return isServiceErrorCode(status) ? handleServiceError(status, blob) : handleHttpError(status);
  };
  var $_2s68z4e4jfuw8p9j = {
    handleServiceErrorResponse: handleServiceErrorResponse,
    handleHttpError: handleHttpError,
    getHttpErrorMsg: getHttpErrorMsg,
    getServiceErrorMsg: getServiceErrorMsg
  };

  var appendApiKey = function (url, apiKey) {
    var separator = url.indexOf('?') === -1 ? '?' : '&';
    if (/[?&]apiKey=/.test(url) || !apiKey) {
      return url;
    } else {
      return url + separator + 'apiKey=' + encodeURIComponent(apiKey);
    }
  };
  var requestServiceBlob = function (url, apiKey) {
    var headers = {
      'Content-Type': 'application/json;charset=UTF-8',
      'tiny-api-key': apiKey
    };
    return $_1782wge7jfuw8pa8.requestUrlAsBlob(appendApiKey(url, apiKey), headers, false).then(function (result) {
      return result.status < 200 || result.status >= 300 ? $_2s68z4e4jfuw8p9j.handleServiceErrorResponse(result.status, result.blob) : global$4.resolve(result.blob);
    });
  };
  function requestBlob(url, withCredentials) {
    return $_1782wge7jfuw8pa8.requestUrlAsBlob(url, {}, withCredentials).then(function (result) {
      return result.status < 200 || result.status >= 300 ? $_2s68z4e4jfuw8p9j.handleHttpError(result.status) : global$4.resolve(result.blob);
    });
  }
  var getUrl = function (url, apiKey, withCredentials) {
    return apiKey ? requestServiceBlob(url, apiKey) : requestBlob(url, withCredentials);
  };
  var $_e2n1vfe3jfuw8p9h = { getUrl: getUrl };

  var count$1 = 0;
  var isEditableImage = function (editor, img) {
    var selectorMatched = editor.dom.is(img, 'img:not([data-mce-object],[data-mce-placeholder])');
    return selectorMatched && (isLocalImage(editor, img) || isCorsImage(editor, img) || editor.settings.imagetools_proxy);
  };
  var displayError = function (editor, error) {
    editor.notificationManager.open({
      text: error,
      type: 'error'
    });
  };
  var getSelectedImage = function (editor) {
    return editor.selection.getNode();
  };
  var extractFilename = function (editor, url) {
    var m = url.match(/\/([^\/\?]+)?\.(?:jpeg|jpg|png|gif)(?:\?|$)/i);
    if (m) {
      return editor.dom.encode(m[1]);
    }
    return null;
  };
  var createId = function () {
    return 'imagetools' + count$1++;
  };
  var isLocalImage = function (editor, img) {
    var url = img.src;
    return url.indexOf('data:') === 0 || url.indexOf('blob:') === 0 || new global$5(url).host === editor.documentBaseURI.host;
  };
  var isCorsImage = function (editor, img) {
    return global$1.inArray(getCorsHosts(editor), new global$5(img.src).host) !== -1;
  };
  var isCorsWithCredentialsImage = function (editor, img) {
    return global$1.inArray(getCredentialsHosts(editor), new global$5(img.src).host) !== -1;
  };
  var imageToBlob$2 = function (editor, img) {
    var src = img.src, apiKey;
    if (isCorsImage(editor, img)) {
      return $_e2n1vfe3jfuw8p9h.getUrl(img.src, null, isCorsWithCredentialsImage(editor, img));
    }
    if (!isLocalImage(editor, img)) {
      src = getProxyUrl(editor);
      src += (src.indexOf('?') === -1 ? '?' : '&') + 'url=' + encodeURIComponent(img.src);
      apiKey = getApiKey(editor);
      return $_e2n1vfe3jfuw8p9h.getUrl(src, apiKey, false);
    }
    return $_5ofeufd1jfuw8p63.imageToBlob(img);
  };
  var findSelectedBlob = function (editor) {
    var blobInfo;
    blobInfo = editor.editorUpload.blobCache.getByUri(getSelectedImage(editor).src);
    if (blobInfo) {
      return global$4.resolve(blobInfo.blob());
    }
    return imageToBlob$2(editor, getSelectedImage(editor));
  };
  var startTimedUpload = function (editor, imageUploadTimerState) {
    var imageUploadTimer = global$3.setEditorTimeout(editor, function () {
      editor.editorUpload.uploadImagesAuto();
    }, getUploadTimeout(editor));
    imageUploadTimerState.set(imageUploadTimer);
  };
  var cancelTimedUpload = function (imageUploadTimerState) {
    clearTimeout(imageUploadTimerState.get());
  };
  var updateSelectedImage = function (editor, ir, uploadImmediately, imageUploadTimerState, size) {
    return ir.toBlob().then(function (blob) {
      var uri, name, blobCache, blobInfo, selectedImage;
      blobCache = editor.editorUpload.blobCache;
      selectedImage = getSelectedImage(editor);
      uri = selectedImage.src;
      if (shouldReuseFilename(editor)) {
        blobInfo = blobCache.getByUri(uri);
        if (blobInfo) {
          uri = blobInfo.uri();
          name = blobInfo.name();
        } else {
          name = extractFilename(editor, uri);
        }
      }
      blobInfo = blobCache.create({
        id: createId(),
        blob: blob,
        base64: ir.toBase64(),
        uri: uri,
        name: name
      });
      blobCache.add(blobInfo);
      editor.undoManager.transact(function () {
        function imageLoadedHandler() {
          editor.$(selectedImage).off('load', imageLoadedHandler);
          editor.nodeChanged();
          if (uploadImmediately) {
            editor.editorUpload.uploadImagesAuto();
          } else {
            cancelTimedUpload(imageUploadTimerState);
            startTimedUpload(editor, imageUploadTimerState);
          }
        }
        editor.$(selectedImage).on('load', imageLoadedHandler);
        if (size) {
          editor.$(selectedImage).attr({
            width: size.w,
            height: size.h
          });
        }
        editor.$(selectedImage).attr({ src: blobInfo.blobUri() }).removeAttr('data-mce-src');
      });
      return blobInfo;
    });
  };
  var selectedImageOperation = function (editor, imageUploadTimerState, fn, size) {
    return function () {
      return editor._scanForImages().then($_9jziv0d7jfuw8p6z.curry(findSelectedBlob, editor)).then($_9ujscsdljfuw8p87.blobToImageResult).then(fn).then(function (imageResult) {
        return updateSelectedImage(editor, imageResult, false, imageUploadTimerState, size);
      }, function (error) {
        displayError(editor, error);
      });
    };
  };
  var rotate$2 = function (editor, imageUploadTimerState, angle) {
    return function () {
      var size = $_8ke5see2jfuw8p9d.getImageSize(getSelectedImage(editor));
      var flippedSize = size ? {
        w: size.h,
        h: size.w
      } : null;
      return selectedImageOperation(editor, imageUploadTimerState, function (imageResult) {
        return $_5r6zxadfjfuw8p7b.rotate(imageResult, angle);
      }, flippedSize)();
    };
  };
  var flip$2 = function (editor, imageUploadTimerState, axis) {
    return function () {
      return selectedImageOperation(editor, imageUploadTimerState, function (imageResult) {
        return $_5r6zxadfjfuw8p7b.flip(imageResult, axis);
      })();
    };
  };
  var editImageDialog = function (editor, imageUploadTimerState) {
    return function () {
      var img = getSelectedImage(editor), originalSize = $_8ke5see2jfuw8p9d.getNaturalImageSize(img);
      var handleDialogBlob = function (blob) {
        return new global$4(function (resolve) {
          $_5ofeufd1jfuw8p63.blobToImage(blob).then(function (newImage) {
            var newSize = $_8ke5see2jfuw8p9d.getNaturalImageSize(newImage);
            if (originalSize.w !== newSize.w || originalSize.h !== newSize.h) {
              if ($_8ke5see2jfuw8p9d.getImageSize(img)) {
                $_8ke5see2jfuw8p9d.setImageSize(img, newSize);
              }
            }
            $_c1346xdmjfuw8p89.revokeObjectURL(newImage.src);
            resolve(blob);
          });
        });
      };
      var openDialog = function (editor, imageResult) {
        return $_90401edrjfuw8p8h.edit(editor, imageResult).then(handleDialogBlob).then($_9ujscsdljfuw8p87.blobToImageResult).then(function (imageResult) {
          return updateSelectedImage(editor, imageResult, true, imageUploadTimerState);
        }, function () {
        });
      };
      findSelectedBlob(editor).then($_9ujscsdljfuw8p87.blobToImageResult).then($_9jziv0d7jfuw8p6z.curry(openDialog, editor), function (error) {
        displayError(editor, error);
      });
    };
  };
  var $_c2sybyd0jfuw8p5m = {
    rotate: rotate$2,
    flip: flip$2,
    editImageDialog: editImageDialog,
    isEditableImage: isEditableImage,
    cancelTimedUpload: cancelTimedUpload
  };

  var register = function (editor, imageUploadTimerState) {
    global$1.each({
      mceImageRotateLeft: $_c2sybyd0jfuw8p5m.rotate(editor, imageUploadTimerState, -90),
      mceImageRotateRight: $_c2sybyd0jfuw8p5m.rotate(editor, imageUploadTimerState, 90),
      mceImageFlipVertical: $_c2sybyd0jfuw8p5m.flip(editor, imageUploadTimerState, 'v'),
      mceImageFlipHorizontal: $_c2sybyd0jfuw8p5m.flip(editor, imageUploadTimerState, 'h'),
      mceEditImage: $_c2sybyd0jfuw8p5m.editImageDialog(editor, imageUploadTimerState)
    }, function (fn, cmd) {
      editor.addCommand(cmd, fn);
    });
  };
  var $_3c96qdcyjfuw8p5j = { register: register };

  var setup = function (editor, imageUploadTimerState, lastSelectedImageState) {
    editor.on('NodeChange', function (e) {
      var lastSelectedImage = lastSelectedImageState.get();
      if (lastSelectedImage && lastSelectedImage.src !== e.element.src) {
        $_c2sybyd0jfuw8p5m.cancelTimedUpload(imageUploadTimerState);
        editor.editorUpload.uploadImagesAuto();
        lastSelectedImageState.set(null);
      }
      if ($_c2sybyd0jfuw8p5m.isEditableImage(editor, e.element)) {
        lastSelectedImageState.set(e.element);
      }
    });
  };
  var $_ffveg8e9jfuw8pai = { setup: setup };

  var register$1 = function (editor) {
    editor.addButton('rotateleft', {
      title: 'Rotate counterclockwise',
      cmd: 'mceImageRotateLeft'
    });
    editor.addButton('rotateright', {
      title: 'Rotate clockwise',
      cmd: 'mceImageRotateRight'
    });
    editor.addButton('flipv', {
      title: 'Flip vertically',
      cmd: 'mceImageFlipVertical'
    });
    editor.addButton('fliph', {
      title: 'Flip horizontally',
      cmd: 'mceImageFlipHorizontal'
    });
    editor.addButton('editimage', {
      title: 'Edit image',
      cmd: 'mceEditImage'
    });
    editor.addButton('imageoptions', {
      title: 'Image options',
      icon: 'options',
      cmd: 'mceImage'
    });
  };
  var $_d28x8ueajfuw8paj = { register: register$1 };

  var register$2 = function (editor) {
    editor.addContextToolbar($_9jziv0d7jfuw8p6z.curry($_c2sybyd0jfuw8p5m.isEditableImage, editor), getToolbarItems(editor));
  };
  var $_bsi4uuebjfuw8pak = { register: register$2 };

  global.add('imagetools', function (editor) {
    var imageUploadTimerState = Cell(0);
    var lastSelectedImageState = Cell(null);
    $_3c96qdcyjfuw8p5j.register(editor, imageUploadTimerState);
    $_d28x8ueajfuw8paj.register(editor);
    $_bsi4uuebjfuw8pak.register(editor);
    $_ffveg8e9jfuw8pai.setup(editor, imageUploadTimerState, lastSelectedImageState);
  });
  function Plugin () {
  }

  return Plugin;

}());
})();
