[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/js/tinymce/themes/inlite/ -> theme.js (source)

   1  (function () {
   2  var inlite = (function (domGlobals) {
   3      'use strict';
   4  
   5      var global = tinymce.util.Tools.resolve('tinymce.ThemeManager');
   6  
   7      var global$1 = tinymce.util.Tools.resolve('tinymce.Env');
   8  
   9      var global$2 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');
  10  
  11      var global$3 = tinymce.util.Tools.resolve('tinymce.util.Delay');
  12  
  13      var flatten = function (arr) {
  14        return arr.reduce(function (results, item) {
  15          return Array.isArray(item) ? results.concat(flatten(item)) : results.concat(item);
  16        }, []);
  17      };
  18      var DeepFlatten = { flatten: flatten };
  19  
  20      var result = function (id, rect) {
  21        return {
  22          id: id,
  23          rect: rect
  24        };
  25      };
  26      var match = function (editor, matchers) {
  27        for (var i = 0; i < matchers.length; i++) {
  28          var f = matchers[i];
  29          var result_1 = f(editor);
  30          if (result_1) {
  31            return result_1;
  32          }
  33        }
  34        return null;
  35      };
  36      var Matcher = {
  37        match: match,
  38        result: result
  39      };
  40  
  41      var fromClientRect = function (clientRect) {
  42        return {
  43          x: clientRect.left,
  44          y: clientRect.top,
  45          w: clientRect.width,
  46          h: clientRect.height
  47        };
  48      };
  49      var toClientRect = function (geomRect) {
  50        return {
  51          left: geomRect.x,
  52          top: geomRect.y,
  53          width: geomRect.w,
  54          height: geomRect.h,
  55          right: geomRect.x + geomRect.w,
  56          bottom: geomRect.y + geomRect.h
  57        };
  58      };
  59      var Convert = {
  60        fromClientRect: fromClientRect,
  61        toClientRect: toClientRect
  62      };
  63  
  64      var toAbsolute = function (rect) {
  65        var vp = global$2.DOM.getViewPort();
  66        return {
  67          x: rect.x + vp.x,
  68          y: rect.y + vp.y,
  69          w: rect.w,
  70          h: rect.h
  71        };
  72      };
  73      var measureElement = function (elm) {
  74        var clientRect = elm.getBoundingClientRect();
  75        return toAbsolute({
  76          x: clientRect.left,
  77          y: clientRect.top,
  78          w: Math.max(elm.clientWidth, elm.offsetWidth),
  79          h: Math.max(elm.clientHeight, elm.offsetHeight)
  80        });
  81      };
  82      var getElementRect = function (editor, elm) {
  83        return measureElement(elm);
  84      };
  85      var getPageAreaRect = function (editor) {
  86        return measureElement(editor.getElement().ownerDocument.body);
  87      };
  88      var getContentAreaRect = function (editor) {
  89        return measureElement(editor.getContentAreaContainer() || editor.getBody());
  90      };
  91      var getSelectionRect = function (editor) {
  92        var clientRect = editor.selection.getBoundingClientRect();
  93        return clientRect ? toAbsolute(Convert.fromClientRect(clientRect)) : null;
  94      };
  95      var Measure = {
  96        getElementRect: getElementRect,
  97        getPageAreaRect: getPageAreaRect,
  98        getContentAreaRect: getContentAreaRect,
  99        getSelectionRect: getSelectionRect
 100      };
 101  
 102      var element = function (element, predicateIds) {
 103        return function (editor) {
 104          for (var i = 0; i < predicateIds.length; i++) {
 105            if (predicateIds[i].predicate(element)) {
 106              var result = Matcher.result(predicateIds[i].id, Measure.getElementRect(editor, element));
 107              return result;
 108            }
 109          }
 110          return null;
 111        };
 112      };
 113      var parent = function (elements, predicateIds) {
 114        return function (editor) {
 115          for (var i = 0; i < elements.length; i++) {
 116            for (var x = 0; x < predicateIds.length; x++) {
 117              if (predicateIds[x].predicate(elements[i])) {
 118                return Matcher.result(predicateIds[x].id, Measure.getElementRect(editor, elements[i]));
 119              }
 120            }
 121          }
 122          return null;
 123        };
 124      };
 125      var ElementMatcher = {
 126        element: element,
 127        parent: parent
 128      };
 129  
 130      var global$4 = tinymce.util.Tools.resolve('tinymce.util.Tools');
 131  
 132      var create = function (id, predicate) {
 133        return {
 134          id: id,
 135          predicate: predicate
 136        };
 137      };
 138      var fromContextToolbars = function (toolbars) {
 139        return global$4.map(toolbars, function (toolbar) {
 140          return create(toolbar.id, toolbar.predicate);
 141        });
 142      };
 143      var PredicateId = {
 144        create: create,
 145        fromContextToolbars: fromContextToolbars
 146      };
 147  
 148      var textSelection = function (id) {
 149        return function (editor) {
 150          if (!editor.selection.isCollapsed()) {
 151            var result = Matcher.result(id, Measure.getSelectionRect(editor));
 152            return result;
 153          }
 154          return null;
 155        };
 156      };
 157      var emptyTextBlock = function (elements, id) {
 158        return function (editor) {
 159          var i;
 160          var textBlockElementsMap = editor.schema.getTextBlockElements();
 161          for (i = 0; i < elements.length; i++) {
 162            if (elements[i].nodeName === 'TABLE') {
 163              return null;
 164            }
 165          }
 166          for (i = 0; i < elements.length; i++) {
 167            if (elements[i].nodeName in textBlockElementsMap) {
 168              if (editor.dom.isEmpty(elements[i])) {
 169                return Matcher.result(id, Measure.getSelectionRect(editor));
 170              }
 171              return null;
 172            }
 173          }
 174          return null;
 175        };
 176      };
 177      var SelectionMatcher = {
 178        textSelection: textSelection,
 179        emptyTextBlock: emptyTextBlock
 180      };
 181  
 182      var fireSkinLoaded = function (editor) {
 183        editor.fire('SkinLoaded');
 184      };
 185      var fireBeforeRenderUI = function (editor) {
 186        return editor.fire('BeforeRenderUI');
 187      };
 188      var Events = {
 189        fireSkinLoaded: fireSkinLoaded,
 190        fireBeforeRenderUI: fireBeforeRenderUI
 191      };
 192  
 193      var global$5 = tinymce.util.Tools.resolve('tinymce.EditorManager');
 194  
 195      var isType = function (type) {
 196        return function (value) {
 197          return typeof value === type;
 198        };
 199      };
 200      var isArray = function (value) {
 201        return Array.isArray(value);
 202      };
 203      var isNull = function (value) {
 204        return value === null;
 205      };
 206      var isObject = function (predicate) {
 207        return function (value) {
 208          return !isNull(value) && !isArray(value) && predicate(value);
 209        };
 210      };
 211      var isString = function (value) {
 212        return isType('string')(value);
 213      };
 214      var isNumber = function (value) {
 215        return isType('number')(value);
 216      };
 217      var isFunction = function (value) {
 218        return isType('function')(value);
 219      };
 220      var isBoolean = function (value) {
 221        return isType('boolean')(value);
 222      };
 223      var Type = {
 224        isString: isString,
 225        isNumber: isNumber,
 226        isBoolean: isBoolean,
 227        isFunction: isFunction,
 228        isObject: isObject(isType('object')),
 229        isNull: isNull,
 230        isArray: isArray
 231      };
 232  
 233      var validDefaultOrDie = function (value, predicate) {
 234        if (predicate(value)) {
 235          return true;
 236        }
 237        throw new Error('Default value doesn\'t match requested type.');
 238      };
 239      var getByTypeOr = function (predicate) {
 240        return function (editor, name, defaultValue) {
 241          var settings = editor.settings;
 242          validDefaultOrDie(defaultValue, predicate);
 243          return name in settings && predicate(settings[name]) ? settings[name] : defaultValue;
 244        };
 245      };
 246      var splitNoEmpty = function (str, delim) {
 247        return str.split(delim).filter(function (item) {
 248          return item.length > 0;
 249        });
 250      };
 251      var itemsToArray = function (value, defaultValue) {
 252        var stringToItemsArray = function (value) {
 253          return typeof value === 'string' ? splitNoEmpty(value, /[ ,]/) : value;
 254        };
 255        var boolToItemsArray = function (value, defaultValue) {
 256          return value === false ? [] : defaultValue;
 257        };
 258        if (Type.isArray(value)) {
 259          return value;
 260        } else if (Type.isString(value)) {
 261          return stringToItemsArray(value);
 262        } else if (Type.isBoolean(value)) {
 263          return boolToItemsArray(value, defaultValue);
 264        }
 265        return defaultValue;
 266      };
 267      var getToolbarItemsOr = function (predicate) {
 268        return function (editor, name, defaultValue) {
 269          var value = name in editor.settings ? editor.settings[name] : defaultValue;
 270          validDefaultOrDie(defaultValue, predicate);
 271          return itemsToArray(value, defaultValue);
 272        };
 273      };
 274      var EditorSettings = {
 275        getStringOr: getByTypeOr(Type.isString),
 276        getBoolOr: getByTypeOr(Type.isBoolean),
 277        getNumberOr: getByTypeOr(Type.isNumber),
 278        getHandlerOr: getByTypeOr(Type.isFunction),
 279        getToolbarItemsOr: getToolbarItemsOr(Type.isArray)
 280      };
 281  
 282      var global$6 = tinymce.util.Tools.resolve('tinymce.geom.Rect');
 283  
 284      var result$1 = function (rect, position) {
 285        return {
 286          rect: rect,
 287          position: position
 288        };
 289      };
 290      var moveTo = function (rect, toRect) {
 291        return {
 292          x: toRect.x,
 293          y: toRect.y,
 294          w: rect.w,
 295          h: rect.h
 296        };
 297      };
 298      var calcByPositions = function (testPositions1, testPositions2, targetRect, contentAreaRect, panelRect) {
 299        var relPos, relRect, outputPanelRect;
 300        var paddedContentRect = {
 301          x: contentAreaRect.x,
 302          y: contentAreaRect.y,
 303          w: contentAreaRect.w + (contentAreaRect.w < panelRect.w + targetRect.w ? panelRect.w : 0),
 304          h: contentAreaRect.h + (contentAreaRect.h < panelRect.h + targetRect.h ? panelRect.h : 0)
 305        };
 306        relPos = global$6.findBestRelativePosition(panelRect, targetRect, paddedContentRect, testPositions1);
 307        targetRect = global$6.clamp(targetRect, paddedContentRect);
 308        if (relPos) {
 309          relRect = global$6.relativePosition(panelRect, targetRect, relPos);
 310          outputPanelRect = moveTo(panelRect, relRect);
 311          return result$1(outputPanelRect, relPos);
 312        }
 313        targetRect = global$6.intersect(paddedContentRect, targetRect);
 314        if (targetRect) {
 315          relPos = global$6.findBestRelativePosition(panelRect, targetRect, paddedContentRect, testPositions2);
 316          if (relPos) {
 317            relRect = global$6.relativePosition(panelRect, targetRect, relPos);
 318            outputPanelRect = moveTo(panelRect, relRect);
 319            return result$1(outputPanelRect, relPos);
 320          }
 321          outputPanelRect = moveTo(panelRect, targetRect);
 322          return result$1(outputPanelRect, relPos);
 323        }
 324        return null;
 325      };
 326      var calcInsert = function (targetRect, contentAreaRect, panelRect) {
 327        return calcByPositions([
 328          'cr-cl',
 329          'cl-cr'
 330        ], [
 331          'bc-tc',
 332          'bl-tl',
 333          'br-tr'
 334        ], targetRect, contentAreaRect, panelRect);
 335      };
 336      var calc = function (targetRect, contentAreaRect, panelRect) {
 337        return calcByPositions([
 338          'tc-bc',
 339          'bc-tc',
 340          'tl-bl',
 341          'bl-tl',
 342          'tr-br',
 343          'br-tr',
 344          'cr-cl',
 345          'cl-cr'
 346        ], [
 347          'bc-tc',
 348          'bl-tl',
 349          'br-tr',
 350          'cr-cl'
 351        ], targetRect, contentAreaRect, panelRect);
 352      };
 353      var userConstrain = function (handler, targetRect, contentAreaRect, panelRect) {
 354        var userConstrainedPanelRect;
 355        if (typeof handler === 'function') {
 356          userConstrainedPanelRect = handler({
 357            elementRect: Convert.toClientRect(targetRect),
 358            contentAreaRect: Convert.toClientRect(contentAreaRect),
 359            panelRect: Convert.toClientRect(panelRect)
 360          });
 361          return Convert.fromClientRect(userConstrainedPanelRect);
 362        }
 363        return panelRect;
 364      };
 365      var defaultHandler = function (rects) {
 366        return rects.panelRect;
 367      };
 368      var Layout = {
 369        calcInsert: calcInsert,
 370        calc: calc,
 371        userConstrain: userConstrain,
 372        defaultHandler: defaultHandler
 373      };
 374  
 375      var toAbsoluteUrl = function (editor, url) {
 376        return editor.documentBaseURI.toAbsolute(url);
 377      };
 378      var urlFromName = function (name) {
 379        var prefix = global$5.baseURL + '/skins/';
 380        return name ? prefix + name : prefix + 'lightgray';
 381      };
 382      var getTextSelectionToolbarItems = function (editor) {
 383        return EditorSettings.getToolbarItemsOr(editor, 'selection_toolbar', [
 384          'bold',
 385          'italic',
 386          '|',
 387          'quicklink',
 388          'h2',
 389          'h3',
 390          'blockquote'
 391        ]);
 392      };
 393      var getInsertToolbarItems = function (editor) {
 394        return EditorSettings.getToolbarItemsOr(editor, 'insert_toolbar', [
 395          'quickimage',
 396          'quicktable'
 397        ]);
 398      };
 399      var getPositionHandler = function (editor) {
 400        return EditorSettings.getHandlerOr(editor, 'inline_toolbar_position_handler', Layout.defaultHandler);
 401      };
 402      var getSkinUrl = function (editor) {
 403        var settings = editor.settings;
 404        return settings.skin_url ? toAbsoluteUrl(editor, settings.skin_url) : urlFromName(settings.skin);
 405      };
 406      var isSkinDisabled = function (editor) {
 407        return editor.settings.skin === false;
 408      };
 409      var Settings = {
 410        getTextSelectionToolbarItems: getTextSelectionToolbarItems,
 411        getInsertToolbarItems: getInsertToolbarItems,
 412        getPositionHandler: getPositionHandler,
 413        getSkinUrl: getSkinUrl,
 414        isSkinDisabled: isSkinDisabled
 415      };
 416  
 417      var fireSkinLoaded$1 = function (editor, callback) {
 418        var done = function () {
 419          editor._skinLoaded = true;
 420          Events.fireSkinLoaded(editor);
 421          callback();
 422        };
 423        if (editor.initialized) {
 424          done();
 425        } else {
 426          editor.on('init', done);
 427        }
 428      };
 429      var load = function (editor, callback) {
 430        var skinUrl = Settings.getSkinUrl(editor);
 431        var done = function () {
 432          fireSkinLoaded$1(editor, callback);
 433        };
 434        if (Settings.isSkinDisabled(editor)) {
 435          done();
 436        } else {
 437          global$2.DOM.styleSheetLoader.load(skinUrl + '/skin.min.css', done);
 438          editor.contentCSS.push(skinUrl + '/content.inline.min.css');
 439        }
 440      };
 441      var SkinLoader = { load: load };
 442  
 443      var getSelectionElements = function (editor) {
 444        var node = editor.selection.getNode();
 445        var elms = editor.dom.getParents(node, '*');
 446        return elms;
 447      };
 448      var createToolbar = function (editor, selector, id, items) {
 449        var selectorPredicate = function (elm) {
 450          return editor.dom.is(elm, selector);
 451        };
 452        return {
 453          predicate: selectorPredicate,
 454          id: id,
 455          items: items
 456        };
 457      };
 458      var getToolbars = function (editor) {
 459        var contextToolbars = editor.contextToolbars;
 460        return DeepFlatten.flatten([
 461          contextToolbars ? contextToolbars : [],
 462          createToolbar(editor, 'img', 'image', 'alignleft aligncenter alignright')
 463        ]);
 464      };
 465      var findMatchResult = function (editor, toolbars) {
 466        var result, elements, contextToolbarsPredicateIds;
 467        elements = getSelectionElements(editor);
 468        contextToolbarsPredicateIds = PredicateId.fromContextToolbars(toolbars);
 469        result = Matcher.match(editor, [
 470          ElementMatcher.element(elements[0], contextToolbarsPredicateIds),
 471          SelectionMatcher.textSelection('text'),
 472          SelectionMatcher.emptyTextBlock(elements, 'insert'),
 473          ElementMatcher.parent(elements, contextToolbarsPredicateIds)
 474        ]);
 475        return result && result.rect ? result : null;
 476      };
 477      var editorHasFocus = function (editor) {
 478        return domGlobals.document.activeElement === editor.getBody();
 479      };
 480      var togglePanel = function (editor, panel) {
 481        var toggle = function () {
 482          var toolbars = getToolbars(editor);
 483          var result = findMatchResult(editor, toolbars);
 484          if (result) {
 485            panel.show(editor, result.id, result.rect, toolbars);
 486          } else {
 487            panel.hide();
 488          }
 489        };
 490        return function () {
 491          if (!editor.removed && editorHasFocus(editor)) {
 492            toggle();
 493          }
 494        };
 495      };
 496      var repositionPanel = function (editor, panel) {
 497        return function () {
 498          var toolbars = getToolbars(editor);
 499          var result = findMatchResult(editor, toolbars);
 500          if (result) {
 501            panel.reposition(editor, result.id, result.rect);
 502          }
 503        };
 504      };
 505      var ignoreWhenFormIsVisible = function (editor, panel, f) {
 506        return function () {
 507          if (!editor.removed && !panel.inForm()) {
 508            f();
 509          }
 510        };
 511      };
 512      var bindContextualToolbarsEvents = function (editor, panel) {
 513        var throttledTogglePanel = global$3.throttle(togglePanel(editor, panel), 0);
 514        var throttledTogglePanelWhenNotInForm = global$3.throttle(ignoreWhenFormIsVisible(editor, panel, togglePanel(editor, panel)), 0);
 515        var reposition = repositionPanel(editor, panel);
 516        editor.on('blur hide ObjectResizeStart', panel.hide);
 517        editor.on('click', throttledTogglePanel);
 518        editor.on('nodeChange mouseup', throttledTogglePanelWhenNotInForm);
 519        editor.on('ResizeEditor keyup', throttledTogglePanel);
 520        editor.on('ResizeWindow', reposition);
 521        global$2.DOM.bind(global$1.container, 'scroll', reposition);
 522        editor.on('remove', function () {
 523          global$2.DOM.unbind(global$1.container, 'scroll', reposition);
 524          panel.remove();
 525        });
 526        editor.shortcuts.add('Alt+F10,F10', '', panel.focus);
 527      };
 528      var overrideLinkShortcut = function (editor, panel) {
 529        editor.shortcuts.remove('meta+k');
 530        editor.shortcuts.add('meta+k', '', function () {
 531          var toolbars = getToolbars(editor);
 532          var result = Matcher.match(editor, [SelectionMatcher.textSelection('quicklink')]);
 533          if (result) {
 534            panel.show(editor, result.id, result.rect, toolbars);
 535          }
 536        });
 537      };
 538      var renderInlineUI = function (editor, panel) {
 539        SkinLoader.load(editor, function () {
 540          bindContextualToolbarsEvents(editor, panel);
 541          overrideLinkShortcut(editor, panel);
 542        });
 543        return {};
 544      };
 545      var fail = function (message) {
 546        throw new Error(message);
 547      };
 548      var renderUI = function (editor, panel) {
 549        return editor.inline ? renderInlineUI(editor, panel) : fail('inlite theme only supports inline mode.');
 550      };
 551      var Render = { renderUI: renderUI };
 552  
 553      var noop = function () {
 554        var args = [];
 555        for (var _i = 0; _i < arguments.length; _i++) {
 556          args[_i] = arguments[_i];
 557        }
 558      };
 559      var constant = function (value) {
 560        return function () {
 561          return value;
 562        };
 563      };
 564      var never = constant(false);
 565      var always = constant(true);
 566  
 567      var never$1 = never;
 568      var always$1 = always;
 569      var none = function () {
 570        return NONE;
 571      };
 572      var NONE = function () {
 573        var eq = function (o) {
 574          return o.isNone();
 575        };
 576        var call = function (thunk) {
 577          return thunk();
 578        };
 579        var id = function (n) {
 580          return n;
 581        };
 582        var noop = function () {
 583        };
 584        var nul = function () {
 585          return null;
 586        };
 587        var undef = function () {
 588          return undefined;
 589        };
 590        var me = {
 591          fold: function (n, s) {
 592            return n();
 593          },
 594          is: never$1,
 595          isSome: never$1,
 596          isNone: always$1,
 597          getOr: id,
 598          getOrThunk: call,
 599          getOrDie: function (msg) {
 600            throw new Error(msg || 'error: getOrDie called on none.');
 601          },
 602          getOrNull: nul,
 603          getOrUndefined: undef,
 604          or: id,
 605          orThunk: call,
 606          map: none,
 607          ap: none,
 608          each: noop,
 609          bind: none,
 610          flatten: none,
 611          exists: never$1,
 612          forall: always$1,
 613          filter: none,
 614          equals: eq,
 615          equals_: eq,
 616          toArray: function () {
 617            return [];
 618          },
 619          toString: constant('none()')
 620        };
 621        if (Object.freeze)
 622          Object.freeze(me);
 623        return me;
 624      }();
 625      var some = function (a) {
 626        var constant_a = function () {
 627          return a;
 628        };
 629        var self = function () {
 630          return me;
 631        };
 632        var map = function (f) {
 633          return some(f(a));
 634        };
 635        var bind = function (f) {
 636          return f(a);
 637        };
 638        var me = {
 639          fold: function (n, s) {
 640            return s(a);
 641          },
 642          is: function (v) {
 643            return a === v;
 644          },
 645          isSome: always$1,
 646          isNone: never$1,
 647          getOr: constant_a,
 648          getOrThunk: constant_a,
 649          getOrDie: constant_a,
 650          getOrNull: constant_a,
 651          getOrUndefined: constant_a,
 652          or: self,
 653          orThunk: self,
 654          map: map,
 655          ap: function (optfab) {
 656            return optfab.fold(none, function (fab) {
 657              return some(fab(a));
 658            });
 659          },
 660          each: function (f) {
 661            f(a);
 662          },
 663          bind: bind,
 664          flatten: constant_a,
 665          exists: bind,
 666          forall: bind,
 667          filter: function (f) {
 668            return f(a) ? me : NONE;
 669          },
 670          equals: function (o) {
 671            return o.is(a);
 672          },
 673          equals_: function (o, elementEq) {
 674            return o.fold(never$1, function (b) {
 675              return elementEq(a, b);
 676            });
 677          },
 678          toArray: function () {
 679            return [a];
 680          },
 681          toString: function () {
 682            return 'some(' + a + ')';
 683          }
 684        };
 685        return me;
 686      };
 687      var from = function (value) {
 688        return value === null || value === undefined ? NONE : some(value);
 689      };
 690      var Option = {
 691        some: some,
 692        none: none,
 693        from: from
 694      };
 695  
 696      var typeOf = function (x) {
 697        if (x === null)
 698          return 'null';
 699        var t = typeof x;
 700        if (t === 'object' && Array.prototype.isPrototypeOf(x))
 701          return 'array';
 702        if (t === 'object' && String.prototype.isPrototypeOf(x))
 703          return 'string';
 704        return t;
 705      };
 706      var isType$1 = function (type) {
 707        return function (value) {
 708          return typeOf(value) === type;
 709        };
 710      };
 711      var isFunction$1 = isType$1('function');
 712      var isNumber$1 = isType$1('number');
 713  
 714      var rawIndexOf = function () {
 715        var pIndexOf = Array.prototype.indexOf;
 716        var fastIndex = function (xs, x) {
 717          return pIndexOf.call(xs, x);
 718        };
 719        var slowIndex = function (xs, x) {
 720          return slowIndexOf(xs, x);
 721        };
 722        return pIndexOf === undefined ? slowIndex : fastIndex;
 723      }();
 724      var indexOf = function (xs, x) {
 725        var r = rawIndexOf(xs, x);
 726        return r === -1 ? Option.none() : Option.some(r);
 727      };
 728      var exists = function (xs, pred) {
 729        return findIndex(xs, pred).isSome();
 730      };
 731      var map = function (xs, f) {
 732        var len = xs.length;
 733        var r = new Array(len);
 734        for (var i = 0; i < len; i++) {
 735          var x = xs[i];
 736          r[i] = f(x, i, xs);
 737        }
 738        return r;
 739      };
 740      var each = function (xs, f) {
 741        for (var i = 0, len = xs.length; i < len; i++) {
 742          var x = xs[i];
 743          f(x, i, xs);
 744        }
 745      };
 746      var filter = function (xs, pred) {
 747        var r = [];
 748        for (var i = 0, len = xs.length; i < len; i++) {
 749          var x = xs[i];
 750          if (pred(x, i, xs)) {
 751            r.push(x);
 752          }
 753        }
 754        return r;
 755      };
 756      var foldl = function (xs, f, acc) {
 757        each(xs, function (x) {
 758          acc = f(acc, x);
 759        });
 760        return acc;
 761      };
 762      var find = function (xs, pred) {
 763        for (var i = 0, len = xs.length; i < len; i++) {
 764          var x = xs[i];
 765          if (pred(x, i, xs)) {
 766            return Option.some(x);
 767          }
 768        }
 769        return Option.none();
 770      };
 771      var findIndex = function (xs, pred) {
 772        for (var i = 0, len = xs.length; i < len; i++) {
 773          var x = xs[i];
 774          if (pred(x, i, xs)) {
 775            return Option.some(i);
 776          }
 777        }
 778        return Option.none();
 779      };
 780      var slowIndexOf = function (xs, x) {
 781        for (var i = 0, len = xs.length; i < len; ++i) {
 782          if (xs[i] === x) {
 783            return i;
 784          }
 785        }
 786        return -1;
 787      };
 788      var push = Array.prototype.push;
 789      var flatten$1 = function (xs) {
 790        var r = [];
 791        for (var i = 0, len = xs.length; i < len; ++i) {
 792          if (!Array.prototype.isPrototypeOf(xs[i]))
 793            throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);
 794          push.apply(r, xs[i]);
 795        }
 796        return r;
 797      };
 798      var slice = Array.prototype.slice;
 799      var from$1 = isFunction$1(Array.from) ? Array.from : function (x) {
 800        return slice.call(x);
 801      };
 802  
 803      var count = 0;
 804      var funcs = {
 805        id: function () {
 806          return 'mceu_' + count++;
 807        },
 808        create: function (name, attrs, children) {
 809          var elm = domGlobals.document.createElement(name);
 810          global$2.DOM.setAttribs(elm, attrs);
 811          if (typeof children === 'string') {
 812            elm.innerHTML = children;
 813          } else {
 814            global$4.each(children, function (child) {
 815              if (child.nodeType) {
 816                elm.appendChild(child);
 817              }
 818            });
 819          }
 820          return elm;
 821        },
 822        createFragment: function (html) {
 823          return global$2.DOM.createFragment(html);
 824        },
 825        getWindowSize: function () {
 826          return global$2.DOM.getViewPort();
 827        },
 828        getSize: function (elm) {
 829          var width, height;
 830          if (elm.getBoundingClientRect) {
 831            var rect = elm.getBoundingClientRect();
 832            width = Math.max(rect.width || rect.right - rect.left, elm.offsetWidth);
 833            height = Math.max(rect.height || rect.bottom - rect.bottom, elm.offsetHeight);
 834          } else {
 835            width = elm.offsetWidth;
 836            height = elm.offsetHeight;
 837          }
 838          return {
 839            width: width,
 840            height: height
 841          };
 842        },
 843        getPos: function (elm, root) {
 844          return global$2.DOM.getPos(elm, root || funcs.getContainer());
 845        },
 846        getContainer: function () {
 847          return global$1.container ? global$1.container : domGlobals.document.body;
 848        },
 849        getViewPort: function (win) {
 850          return global$2.DOM.getViewPort(win);
 851        },
 852        get: function (id) {
 853          return domGlobals.document.getElementById(id);
 854        },
 855        addClass: function (elm, cls) {
 856          return global$2.DOM.addClass(elm, cls);
 857        },
 858        removeClass: function (elm, cls) {
 859          return global$2.DOM.removeClass(elm, cls);
 860        },
 861        hasClass: function (elm, cls) {
 862          return global$2.DOM.hasClass(elm, cls);
 863        },
 864        toggleClass: function (elm, cls, state) {
 865          return global$2.DOM.toggleClass(elm, cls, state);
 866        },
 867        css: function (elm, name, value) {
 868          return global$2.DOM.setStyle(elm, name, value);
 869        },
 870        getRuntimeStyle: function (elm, name) {
 871          return global$2.DOM.getStyle(elm, name, true);
 872        },
 873        on: function (target, name, callback, scope) {
 874          return global$2.DOM.bind(target, name, callback, scope);
 875        },
 876        off: function (target, name, callback) {
 877          return global$2.DOM.unbind(target, name, callback);
 878        },
 879        fire: function (target, name, args) {
 880          return global$2.DOM.fire(target, name, args);
 881        },
 882        innerHtml: function (elm, html) {
 883          global$2.DOM.setHTML(elm, html);
 884        }
 885      };
 886  
 887      var global$7 = tinymce.util.Tools.resolve('tinymce.dom.DomQuery');
 888  
 889      var global$8 = tinymce.util.Tools.resolve('tinymce.util.Class');
 890  
 891      var global$9 = tinymce.util.Tools.resolve('tinymce.util.EventDispatcher');
 892  
 893      var BoxUtils = {
 894        parseBox: function (value) {
 895          var len;
 896          var radix = 10;
 897          if (!value) {
 898            return;
 899          }
 900          if (typeof value === 'number') {
 901            value = value || 0;
 902            return {
 903              top: value,
 904              left: value,
 905              bottom: value,
 906              right: value
 907            };
 908          }
 909          value = value.split(' ');
 910          len = value.length;
 911          if (len === 1) {
 912            value[1] = value[2] = value[3] = value[0];
 913          } else if (len === 2) {
 914            value[2] = value[0];
 915            value[3] = value[1];
 916          } else if (len === 3) {
 917            value[3] = value[1];
 918          }
 919          return {
 920            top: parseInt(value[0], radix) || 0,
 921            right: parseInt(value[1], radix) || 0,
 922            bottom: parseInt(value[2], radix) || 0,
 923            left: parseInt(value[3], radix) || 0
 924          };
 925        },
 926        measureBox: function (elm, prefix) {
 927          function getStyle(name) {
 928            var defaultView = elm.ownerDocument.defaultView;
 929            if (defaultView) {
 930              var computedStyle = defaultView.getComputedStyle(elm, null);
 931              if (computedStyle) {
 932                name = name.replace(/[A-Z]/g, function (a) {
 933                  return '-' + a;
 934                });
 935                return computedStyle.getPropertyValue(name);
 936              } else {
 937                return null;
 938              }
 939            }
 940            return elm.currentStyle[name];
 941          }
 942          function getSide(name) {
 943            var val = parseFloat(getStyle(name));
 944            return isNaN(val) ? 0 : val;
 945          }
 946          return {
 947            top: getSide(prefix + 'TopWidth'),
 948            right: getSide(prefix + 'RightWidth'),
 949            bottom: getSide(prefix + 'BottomWidth'),
 950            left: getSide(prefix + 'LeftWidth')
 951          };
 952        }
 953      };
 954  
 955      function noop$1() {
 956      }
 957      function ClassList(onchange) {
 958        this.cls = [];
 959        this.cls._map = {};
 960        this.onchange = onchange || noop$1;
 961        this.prefix = '';
 962      }
 963      global$4.extend(ClassList.prototype, {
 964        add: function (cls) {
 965          if (cls && !this.contains(cls)) {
 966            this.cls._map[cls] = true;
 967            this.cls.push(cls);
 968            this._change();
 969          }
 970          return this;
 971        },
 972        remove: function (cls) {
 973          if (this.contains(cls)) {
 974            var i = void 0;
 975            for (i = 0; i < this.cls.length; i++) {
 976              if (this.cls[i] === cls) {
 977                break;
 978              }
 979            }
 980            this.cls.splice(i, 1);
 981            delete this.cls._map[cls];
 982            this._change();
 983          }
 984          return this;
 985        },
 986        toggle: function (cls, state) {
 987          var curState = this.contains(cls);
 988          if (curState !== state) {
 989            if (curState) {
 990              this.remove(cls);
 991            } else {
 992              this.add(cls);
 993            }
 994            this._change();
 995          }
 996          return this;
 997        },
 998        contains: function (cls) {
 999          return !!this.cls._map[cls];
1000        },
1001        _change: function () {
1002          delete this.clsValue;
1003          this.onchange.call(this);
1004        }
1005      });
1006      ClassList.prototype.toString = function () {
1007        var value;
1008        if (this.clsValue) {
1009          return this.clsValue;
1010        }
1011        value = '';
1012        for (var i = 0; i < this.cls.length; i++) {
1013          if (i > 0) {
1014            value += ' ';
1015          }
1016          value += this.prefix + this.cls[i];
1017        }
1018        return value;
1019      };
1020  
1021      function unique(array) {
1022        var uniqueItems = [];
1023        var i = array.length, item;
1024        while (i--) {
1025          item = array[i];
1026          if (!item.__checked) {
1027            uniqueItems.push(item);
1028            item.__checked = 1;
1029          }
1030        }
1031        i = uniqueItems.length;
1032        while (i--) {
1033          delete uniqueItems[i].__checked;
1034        }
1035        return uniqueItems;
1036      }
1037      var expression = /^([\w\\*]+)?(?:#([\w\-\\]+))?(?:\.([\w\\\.]+))?(?:\[\@?([\w\\]+)([\^\$\*!~]?=)([\w\\]+)\])?(?:\:(.+))?/i;
1038      var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g;
1039      var whiteSpace = /^\s*|\s*$/g;
1040      var Collection;
1041      var Selector = global$8.extend({
1042        init: function (selector) {
1043          var match = this.match;
1044          function compileNameFilter(name) {
1045            if (name) {
1046              name = name.toLowerCase();
1047              return function (item) {
1048                return name === '*' || item.type === name;
1049              };
1050            }
1051          }
1052          function compileIdFilter(id) {
1053            if (id) {
1054              return function (item) {
1055                return item._name === id;
1056              };
1057            }
1058          }
1059          function compileClassesFilter(classes) {
1060            if (classes) {
1061              classes = classes.split('.');
1062              return function (item) {
1063                var i = classes.length;
1064                while (i--) {
1065                  if (!item.classes.contains(classes[i])) {
1066                    return false;
1067                  }
1068                }
1069                return true;
1070              };
1071            }
1072          }
1073          function compileAttrFilter(name, cmp, check) {
1074            if (name) {
1075              return function (item) {
1076                var value = item[name] ? item[name]() : '';
1077                return !cmp ? !!check : cmp === '=' ? value === check : cmp === '*=' ? value.indexOf(check) >= 0 : cmp === '~=' ? (' ' + value + ' ').indexOf(' ' + check + ' ') >= 0 : cmp === '!=' ? value !== check : cmp === '^=' ? value.indexOf(check) === 0 : cmp === '$=' ? value.substr(value.length - check.length) === check : false;
1078              };
1079            }
1080          }
1081          function compilePsuedoFilter(name) {
1082            var notSelectors;
1083            if (name) {
1084              name = /(?:not\((.+)\))|(.+)/i.exec(name);
1085              if (!name[1]) {
1086                name = name[2];
1087                return function (item, index, length) {
1088                  return name === 'first' ? index === 0 : name === 'last' ? index === length - 1 : name === 'even' ? index % 2 === 0 : name === 'odd' ? index % 2 === 1 : item[name] ? item[name]() : false;
1089                };
1090              }
1091              notSelectors = parseChunks(name[1], []);
1092              return function (item) {
1093                return !match(item, notSelectors);
1094              };
1095            }
1096          }
1097          function compile(selector, filters, direct) {
1098            var parts;
1099            function add(filter) {
1100              if (filter) {
1101                filters.push(filter);
1102              }
1103            }
1104            parts = expression.exec(selector.replace(whiteSpace, ''));
1105            add(compileNameFilter(parts[1]));
1106            add(compileIdFilter(parts[2]));
1107            add(compileClassesFilter(parts[3]));
1108            add(compileAttrFilter(parts[4], parts[5], parts[6]));
1109            add(compilePsuedoFilter(parts[7]));
1110            filters.pseudo = !!parts[7];
1111            filters.direct = direct;
1112            return filters;
1113          }
1114          function parseChunks(selector, selectors) {
1115            var parts = [];
1116            var extra, matches, i;
1117            do {
1118              chunker.exec('');
1119              matches = chunker.exec(selector);
1120              if (matches) {
1121                selector = matches[3];
1122                parts.push(matches[1]);
1123                if (matches[2]) {
1124                  extra = matches[3];
1125                  break;
1126                }
1127              }
1128            } while (matches);
1129            if (extra) {
1130              parseChunks(extra, selectors);
1131            }
1132            selector = [];
1133            for (i = 0; i < parts.length; i++) {
1134              if (parts[i] !== '>') {
1135                selector.push(compile(parts[i], [], parts[i - 1] === '>'));
1136              }
1137            }
1138            selectors.push(selector);
1139            return selectors;
1140          }
1141          this._selectors = parseChunks(selector, []);
1142        },
1143        match: function (control, selectors) {
1144          var i, l, si, sl, selector, fi, fl, filters, index, length, siblings, count, item;
1145          selectors = selectors || this._selectors;
1146          for (i = 0, l = selectors.length; i < l; i++) {
1147            selector = selectors[i];
1148            sl = selector.length;
1149            item = control;
1150            count = 0;
1151            for (si = sl - 1; si >= 0; si--) {
1152              filters = selector[si];
1153              while (item) {
1154                if (filters.pseudo) {
1155                  siblings = item.parent().items();
1156                  index = length = siblings.length;
1157                  while (index--) {
1158                    if (siblings[index] === item) {
1159                      break;
1160                    }
1161                  }
1162                }
1163                for (fi = 0, fl = filters.length; fi < fl; fi++) {
1164                  if (!filters[fi](item, index, length)) {
1165                    fi = fl + 1;
1166                    break;
1167                  }
1168                }
1169                if (fi === fl) {
1170                  count++;
1171                  break;
1172                } else {
1173                  if (si === sl - 1) {
1174                    break;
1175                  }
1176                }
1177                item = item.parent();
1178              }
1179            }
1180            if (count === sl) {
1181              return true;
1182            }
1183          }
1184          return false;
1185        },
1186        find: function (container) {
1187          var matches = [], i, l;
1188          var selectors = this._selectors;
1189          function collect(items, selector, index) {
1190            var i, l, fi, fl, item;
1191            var filters = selector[index];
1192            for (i = 0, l = items.length; i < l; i++) {
1193              item = items[i];
1194              for (fi = 0, fl = filters.length; fi < fl; fi++) {
1195                if (!filters[fi](item, i, l)) {
1196                  fi = fl + 1;
1197                  break;
1198                }
1199              }
1200              if (fi === fl) {
1201                if (index === selector.length - 1) {
1202                  matches.push(item);
1203                } else {
1204                  if (item.items) {
1205                    collect(item.items(), selector, index + 1);
1206                  }
1207                }
1208              } else if (filters.direct) {
1209                return;
1210              }
1211              if (item.items) {
1212                collect(item.items(), selector, index);
1213              }
1214            }
1215          }
1216          if (container.items) {
1217            for (i = 0, l = selectors.length; i < l; i++) {
1218              collect(container.items(), selectors[i], 0);
1219            }
1220            if (l > 1) {
1221              matches = unique(matches);
1222            }
1223          }
1224          if (!Collection) {
1225            Collection = Selector.Collection;
1226          }
1227          return new Collection(matches);
1228        }
1229      });
1230  
1231      var Collection$1, proto;
1232      var push$1 = Array.prototype.push, slice$1 = Array.prototype.slice;
1233      proto = {
1234        length: 0,
1235        init: function (items) {
1236          if (items) {
1237            this.add(items);
1238          }
1239        },
1240        add: function (items) {
1241          var self = this;
1242          if (!global$4.isArray(items)) {
1243            if (items instanceof Collection$1) {
1244              self.add(items.toArray());
1245            } else {
1246              push$1.call(self, items);
1247            }
1248          } else {
1249            push$1.apply(self, items);
1250          }
1251          return self;
1252        },
1253        set: function (items) {
1254          var self = this;
1255          var len = self.length;
1256          var i;
1257          self.length = 0;
1258          self.add(items);
1259          for (i = self.length; i < len; i++) {
1260            delete self[i];
1261          }
1262          return self;
1263        },
1264        filter: function (selector) {
1265          var self = this;
1266          var i, l;
1267          var matches = [];
1268          var item, match;
1269          if (typeof selector === 'string') {
1270            selector = new Selector(selector);
1271            match = function (item) {
1272              return selector.match(item);
1273            };
1274          } else {
1275            match = selector;
1276          }
1277          for (i = 0, l = self.length; i < l; i++) {
1278            item = self[i];
1279            if (match(item)) {
1280              matches.push(item);
1281            }
1282          }
1283          return new Collection$1(matches);
1284        },
1285        slice: function () {
1286          return new Collection$1(slice$1.apply(this, arguments));
1287        },
1288        eq: function (index) {
1289          return index === -1 ? this.slice(index) : this.slice(index, +index + 1);
1290        },
1291        each: function (callback) {
1292          global$4.each(this, callback);
1293          return this;
1294        },
1295        toArray: function () {
1296          return global$4.toArray(this);
1297        },
1298        indexOf: function (ctrl) {
1299          var self = this;
1300          var i = self.length;
1301          while (i--) {
1302            if (self[i] === ctrl) {
1303              break;
1304            }
1305          }
1306          return i;
1307        },
1308        reverse: function () {
1309          return new Collection$1(global$4.toArray(this).reverse());
1310        },
1311        hasClass: function (cls) {
1312          return this[0] ? this[0].classes.contains(cls) : false;
1313        },
1314        prop: function (name, value) {
1315          var self = this;
1316          var item;
1317          if (value !== undefined) {
1318            self.each(function (item) {
1319              if (item[name]) {
1320                item[name](value);
1321              }
1322            });
1323            return self;
1324          }
1325          item = self[0];
1326          if (item && item[name]) {
1327            return item[name]();
1328          }
1329        },
1330        exec: function (name) {
1331          var self = this, args = global$4.toArray(arguments).slice(1);
1332          self.each(function (item) {
1333            if (item[name]) {
1334              item[name].apply(item, args);
1335            }
1336          });
1337          return self;
1338        },
1339        remove: function () {
1340          var i = this.length;
1341          while (i--) {
1342            this[i].remove();
1343          }
1344          return this;
1345        },
1346        addClass: function (cls) {
1347          return this.each(function (item) {
1348            item.classes.add(cls);
1349          });
1350        },
1351        removeClass: function (cls) {
1352          return this.each(function (item) {
1353            item.classes.remove(cls);
1354          });
1355        }
1356      };
1357      global$4.each('fire on off show hide append prepend before after reflow'.split(' '), function (name) {
1358        proto[name] = function () {
1359          var args = global$4.toArray(arguments);
1360          this.each(function (ctrl) {
1361            if (name in ctrl) {
1362              ctrl[name].apply(ctrl, args);
1363            }
1364          });
1365          return this;
1366        };
1367      });
1368      global$4.each('text name disabled active selected checked visible parent value data'.split(' '), function (name) {
1369        proto[name] = function (value) {
1370          return this.prop(name, value);
1371        };
1372      });
1373      Collection$1 = global$8.extend(proto);
1374      Selector.Collection = Collection$1;
1375      var Collection$2 = Collection$1;
1376  
1377      var Binding = function (settings) {
1378        this.create = settings.create;
1379      };
1380      Binding.create = function (model, name) {
1381        return new Binding({
1382          create: function (otherModel, otherName) {
1383            var bindings;
1384            var fromSelfToOther = function (e) {
1385              otherModel.set(otherName, e.value);
1386            };
1387            var fromOtherToSelf = function (e) {
1388              model.set(name, e.value);
1389            };
1390            otherModel.on('change:' + otherName, fromOtherToSelf);
1391            model.on('change:' + name, fromSelfToOther);
1392            bindings = otherModel._bindings;
1393            if (!bindings) {
1394              bindings = otherModel._bindings = [];
1395              otherModel.on('destroy', function () {
1396                var i = bindings.length;
1397                while (i--) {
1398                  bindings[i]();
1399                }
1400              });
1401            }
1402            bindings.push(function () {
1403              model.off('change:' + name, fromSelfToOther);
1404            });
1405            return model.get(name);
1406          }
1407        });
1408      };
1409  
1410      var global$a = tinymce.util.Tools.resolve('tinymce.util.Observable');
1411  
1412      function isNode(node) {
1413        return node.nodeType > 0;
1414      }
1415      function isEqual(a, b) {
1416        var k, checked;
1417        if (a === b) {
1418          return true;
1419        }
1420        if (a === null || b === null) {
1421          return a === b;
1422        }
1423        if (typeof a !== 'object' || typeof b !== 'object') {
1424          return a === b;
1425        }
1426        if (global$4.isArray(b)) {
1427          if (a.length !== b.length) {
1428            return false;
1429          }
1430          k = a.length;
1431          while (k--) {
1432            if (!isEqual(a[k], b[k])) {
1433              return false;
1434            }
1435          }
1436        }
1437        if (isNode(a) || isNode(b)) {
1438          return a === b;
1439        }
1440        checked = {};
1441        for (k in b) {
1442          if (!isEqual(a[k], b[k])) {
1443            return false;
1444          }
1445          checked[k] = true;
1446        }
1447        for (k in a) {
1448          if (!checked[k] && !isEqual(a[k], b[k])) {
1449            return false;
1450          }
1451        }
1452        return true;
1453      }
1454      var ObservableObject = global$8.extend({
1455        Mixins: [global$a],
1456        init: function (data) {
1457          var name, value;
1458          data = data || {};
1459          for (name in data) {
1460            value = data[name];
1461            if (value instanceof Binding) {
1462              data[name] = value.create(this, name);
1463            }
1464          }
1465          this.data = data;
1466        },
1467        set: function (name, value) {
1468          var key, args;
1469          var oldValue = this.data[name];
1470          if (value instanceof Binding) {
1471            value = value.create(this, name);
1472          }
1473          if (typeof name === 'object') {
1474            for (key in name) {
1475              this.set(key, name[key]);
1476            }
1477            return this;
1478          }
1479          if (!isEqual(oldValue, value)) {
1480            this.data[name] = value;
1481            args = {
1482              target: this,
1483              name: name,
1484              value: value,
1485              oldValue: oldValue
1486            };
1487            this.fire('change:' + name, args);
1488            this.fire('change', args);
1489          }
1490          return this;
1491        },
1492        get: function (name) {
1493          return this.data[name];
1494        },
1495        has: function (name) {
1496          return name in this.data;
1497        },
1498        bind: function (name) {
1499          return Binding.create(this, name);
1500        },
1501        destroy: function () {
1502          this.fire('destroy');
1503        }
1504      });
1505  
1506      var dirtyCtrls = {}, animationFrameRequested;
1507      var ReflowQueue = {
1508        add: function (ctrl) {
1509          var parent = ctrl.parent();
1510          if (parent) {
1511            if (!parent._layout || parent._layout.isNative()) {
1512              return;
1513            }
1514            if (!dirtyCtrls[parent._id]) {
1515              dirtyCtrls[parent._id] = parent;
1516            }
1517            if (!animationFrameRequested) {
1518              animationFrameRequested = true;
1519              global$3.requestAnimationFrame(function () {
1520                var id, ctrl;
1521                animationFrameRequested = false;
1522                for (id in dirtyCtrls) {
1523                  ctrl = dirtyCtrls[id];
1524                  if (ctrl.state.get('rendered')) {
1525                    ctrl.reflow();
1526                  }
1527                }
1528                dirtyCtrls = {};
1529              }, domGlobals.document.body);
1530            }
1531          }
1532        },
1533        remove: function (ctrl) {
1534          if (dirtyCtrls[ctrl._id]) {
1535            delete dirtyCtrls[ctrl._id];
1536          }
1537        }
1538      };
1539  
1540      var getUiContainerDelta = function (ctrl) {
1541        var uiContainer = getUiContainer(ctrl);
1542        if (uiContainer && global$2.DOM.getStyle(uiContainer, 'position', true) !== 'static') {
1543          var containerPos = global$2.DOM.getPos(uiContainer);
1544          var dx = uiContainer.scrollLeft - containerPos.x;
1545          var dy = uiContainer.scrollTop - containerPos.y;
1546          return Option.some({
1547            x: dx,
1548            y: dy
1549          });
1550        } else {
1551          return Option.none();
1552        }
1553      };
1554      var setUiContainer = function (editor, ctrl) {
1555        var uiContainer = global$2.DOM.select(editor.settings.ui_container)[0];
1556        ctrl.getRoot().uiContainer = uiContainer;
1557      };
1558      var getUiContainer = function (ctrl) {
1559        return ctrl ? ctrl.getRoot().uiContainer : null;
1560      };
1561      var inheritUiContainer = function (fromCtrl, toCtrl) {
1562        return toCtrl.uiContainer = getUiContainer(fromCtrl);
1563      };
1564      var UiContainer = {
1565        getUiContainerDelta: getUiContainerDelta,
1566        setUiContainer: setUiContainer,
1567        getUiContainer: getUiContainer,
1568        inheritUiContainer: inheritUiContainer
1569      };
1570  
1571      var hasMouseWheelEventSupport = 'onmousewheel' in domGlobals.document;
1572      var hasWheelEventSupport = false;
1573      var classPrefix = 'mce-';
1574      var Control, idCounter = 0;
1575      var proto$1 = {
1576        Statics: { classPrefix: classPrefix },
1577        isRtl: function () {
1578          return Control.rtl;
1579        },
1580        classPrefix: classPrefix,
1581        init: function (settings) {
1582          var self = this;
1583          var classes, defaultClasses;
1584          function applyClasses(classes) {
1585            var i;
1586            classes = classes.split(' ');
1587            for (i = 0; i < classes.length; i++) {
1588              self.classes.add(classes[i]);
1589            }
1590          }
1591          self.settings = settings = global$4.extend({}, self.Defaults, settings);
1592          self._id = settings.id || 'mceu_' + idCounter++;
1593          self._aria = { role: settings.role };
1594          self._elmCache = {};
1595          self.$ = global$7;
1596          self.state = new ObservableObject({
1597            visible: true,
1598            active: false,
1599            disabled: false,
1600            value: ''
1601          });
1602          self.data = new ObservableObject(settings.data);
1603          self.classes = new ClassList(function () {
1604            if (self.state.get('rendered')) {
1605              self.getEl().className = this.toString();
1606            }
1607          });
1608          self.classes.prefix = self.classPrefix;
1609          classes = settings.classes;
1610          if (classes) {
1611            if (self.Defaults) {
1612              defaultClasses = self.Defaults.classes;
1613              if (defaultClasses && classes !== defaultClasses) {
1614                applyClasses(defaultClasses);
1615              }
1616            }
1617            applyClasses(classes);
1618          }
1619          global$4.each('title text name visible disabled active value'.split(' '), function (name) {
1620            if (name in settings) {
1621              self[name](settings[name]);
1622            }
1623          });
1624          self.on('click', function () {
1625            if (self.disabled()) {
1626              return false;
1627            }
1628          });
1629          self.settings = settings;
1630          self.borderBox = BoxUtils.parseBox(settings.border);
1631          self.paddingBox = BoxUtils.parseBox(settings.padding);
1632          self.marginBox = BoxUtils.parseBox(settings.margin);
1633          if (settings.hidden) {
1634            self.hide();
1635          }
1636        },
1637        Properties: 'parent,name',
1638        getContainerElm: function () {
1639          var uiContainer = UiContainer.getUiContainer(this);
1640          return uiContainer ? uiContainer : funcs.getContainer();
1641        },
1642        getParentCtrl: function (elm) {
1643          var ctrl;
1644          var lookup = this.getRoot().controlIdLookup;
1645          while (elm && lookup) {
1646            ctrl = lookup[elm.id];
1647            if (ctrl) {
1648              break;
1649            }
1650            elm = elm.parentNode;
1651          }
1652          return ctrl;
1653        },
1654        initLayoutRect: function () {
1655          var self = this;
1656          var settings = self.settings;
1657          var borderBox, layoutRect;
1658          var elm = self.getEl();
1659          var width, height, minWidth, minHeight, autoResize;
1660          var startMinWidth, startMinHeight, initialSize;
1661          borderBox = self.borderBox = self.borderBox || BoxUtils.measureBox(elm, 'border');
1662          self.paddingBox = self.paddingBox || BoxUtils.measureBox(elm, 'padding');
1663          self.marginBox = self.marginBox || BoxUtils.measureBox(elm, 'margin');
1664          initialSize = funcs.getSize(elm);
1665          startMinWidth = settings.minWidth;
1666          startMinHeight = settings.minHeight;
1667          minWidth = startMinWidth || initialSize.width;
1668          minHeight = startMinHeight || initialSize.height;
1669          width = settings.width;
1670          height = settings.height;
1671          autoResize = settings.autoResize;
1672          autoResize = typeof autoResize !== 'undefined' ? autoResize : !width && !height;
1673          width = width || minWidth;
1674          height = height || minHeight;
1675          var deltaW = borderBox.left + borderBox.right;
1676          var deltaH = borderBox.top + borderBox.bottom;
1677          var maxW = settings.maxWidth || 65535;
1678          var maxH = settings.maxHeight || 65535;
1679          self._layoutRect = layoutRect = {
1680            x: settings.x || 0,
1681            y: settings.y || 0,
1682            w: width,
1683            h: height,
1684            deltaW: deltaW,
1685            deltaH: deltaH,
1686            contentW: width - deltaW,
1687            contentH: height - deltaH,
1688            innerW: width - deltaW,
1689            innerH: height - deltaH,
1690            startMinWidth: startMinWidth || 0,
1691            startMinHeight: startMinHeight || 0,
1692            minW: Math.min(minWidth, maxW),
1693            minH: Math.min(minHeight, maxH),
1694            maxW: maxW,
1695            maxH: maxH,
1696            autoResize: autoResize,
1697            scrollW: 0
1698          };
1699          self._lastLayoutRect = {};
1700          return layoutRect;
1701        },
1702        layoutRect: function (newRect) {
1703          var self = this;
1704          var curRect = self._layoutRect, lastLayoutRect, size, deltaWidth, deltaHeight, repaintControls;
1705          if (!curRect) {
1706            curRect = self.initLayoutRect();
1707          }
1708          if (newRect) {
1709            deltaWidth = curRect.deltaW;
1710            deltaHeight = curRect.deltaH;
1711            if (newRect.x !== undefined) {
1712              curRect.x = newRect.x;
1713            }
1714            if (newRect.y !== undefined) {
1715              curRect.y = newRect.y;
1716            }
1717            if (newRect.minW !== undefined) {
1718              curRect.minW = newRect.minW;
1719            }
1720            if (newRect.minH !== undefined) {
1721              curRect.minH = newRect.minH;
1722            }
1723            size = newRect.w;
1724            if (size !== undefined) {
1725              size = size < curRect.minW ? curRect.minW : size;
1726              size = size > curRect.maxW ? curRect.maxW : size;
1727              curRect.w = size;
1728              curRect.innerW = size - deltaWidth;
1729            }
1730            size = newRect.h;
1731            if (size !== undefined) {
1732              size = size < curRect.minH ? curRect.minH : size;
1733              size = size > curRect.maxH ? curRect.maxH : size;
1734              curRect.h = size;
1735              curRect.innerH = size - deltaHeight;
1736            }
1737            size = newRect.innerW;
1738            if (size !== undefined) {
1739              size = size < curRect.minW - deltaWidth ? curRect.minW - deltaWidth : size;
1740              size = size > curRect.maxW - deltaWidth ? curRect.maxW - deltaWidth : size;
1741              curRect.innerW = size;
1742              curRect.w = size + deltaWidth;
1743            }
1744            size = newRect.innerH;
1745            if (size !== undefined) {
1746              size = size < curRect.minH - deltaHeight ? curRect.minH - deltaHeight : size;
1747              size = size > curRect.maxH - deltaHeight ? curRect.maxH - deltaHeight : size;
1748              curRect.innerH = size;
1749              curRect.h = size + deltaHeight;
1750            }
1751            if (newRect.contentW !== undefined) {
1752              curRect.contentW = newRect.contentW;
1753            }
1754            if (newRect.contentH !== undefined) {
1755              curRect.contentH = newRect.contentH;
1756            }
1757            lastLayoutRect = self._lastLayoutRect;
1758            if (lastLayoutRect.x !== curRect.x || lastLayoutRect.y !== curRect.y || lastLayoutRect.w !== curRect.w || lastLayoutRect.h !== curRect.h) {
1759              repaintControls = Control.repaintControls;
1760              if (repaintControls) {
1761                if (repaintControls.map && !repaintControls.map[self._id]) {
1762                  repaintControls.push(self);
1763                  repaintControls.map[self._id] = true;
1764                }
1765              }
1766              lastLayoutRect.x = curRect.x;
1767              lastLayoutRect.y = curRect.y;
1768              lastLayoutRect.w = curRect.w;
1769              lastLayoutRect.h = curRect.h;
1770            }
1771            return self;
1772          }
1773          return curRect;
1774        },
1775        repaint: function () {
1776          var self = this;
1777          var style, bodyStyle, bodyElm, rect, borderBox;
1778          var borderW, borderH, lastRepaintRect, round, value;
1779          round = !domGlobals.document.createRange ? Math.round : function (value) {
1780            return value;
1781          };
1782          style = self.getEl().style;
1783          rect = self._layoutRect;
1784          lastRepaintRect = self._lastRepaintRect || {};
1785          borderBox = self.borderBox;
1786          borderW = borderBox.left + borderBox.right;
1787          borderH = borderBox.top + borderBox.bottom;
1788          if (rect.x !== lastRepaintRect.x) {
1789            style.left = round(rect.x) + 'px';
1790            lastRepaintRect.x = rect.x;
1791          }
1792          if (rect.y !== lastRepaintRect.y) {
1793            style.top = round(rect.y) + 'px';
1794            lastRepaintRect.y = rect.y;
1795          }
1796          if (rect.w !== lastRepaintRect.w) {
1797            value = round(rect.w - borderW);
1798            style.width = (value >= 0 ? value : 0) + 'px';
1799            lastRepaintRect.w = rect.w;
1800          }
1801          if (rect.h !== lastRepaintRect.h) {
1802            value = round(rect.h - borderH);
1803            style.height = (value >= 0 ? value : 0) + 'px';
1804            lastRepaintRect.h = rect.h;
1805          }
1806          if (self._hasBody && rect.innerW !== lastRepaintRect.innerW) {
1807            value = round(rect.innerW);
1808            bodyElm = self.getEl('body');
1809            if (bodyElm) {
1810              bodyStyle = bodyElm.style;
1811              bodyStyle.width = (value >= 0 ? value : 0) + 'px';
1812            }
1813            lastRepaintRect.innerW = rect.innerW;
1814          }
1815          if (self._hasBody && rect.innerH !== lastRepaintRect.innerH) {
1816            value = round(rect.innerH);
1817            bodyElm = bodyElm || self.getEl('body');
1818            if (bodyElm) {
1819              bodyStyle = bodyStyle || bodyElm.style;
1820              bodyStyle.height = (value >= 0 ? value : 0) + 'px';
1821            }
1822            lastRepaintRect.innerH = rect.innerH;
1823          }
1824          self._lastRepaintRect = lastRepaintRect;
1825          self.fire('repaint', {}, false);
1826        },
1827        updateLayoutRect: function () {
1828          var self = this;
1829          self.parent()._lastRect = null;
1830          funcs.css(self.getEl(), {
1831            width: '',
1832            height: ''
1833          });
1834          self._layoutRect = self._lastRepaintRect = self._lastLayoutRect = null;
1835          self.initLayoutRect();
1836        },
1837        on: function (name, callback) {
1838          var self = this;
1839          function resolveCallbackName(name) {
1840            var callback, scope;
1841            if (typeof name !== 'string') {
1842              return name;
1843            }
1844            return function (e) {
1845              if (!callback) {
1846                self.parentsAndSelf().each(function (ctrl) {
1847                  var callbacks = ctrl.settings.callbacks;
1848                  if (callbacks && (callback = callbacks[name])) {
1849                    scope = ctrl;
1850                    return false;
1851                  }
1852                });
1853              }
1854              if (!callback) {
1855                e.action = name;
1856                this.fire('execute', e);
1857                return;
1858              }
1859              return callback.call(scope, e);
1860            };
1861          }
1862          getEventDispatcher(self).on(name, resolveCallbackName(callback));
1863          return self;
1864        },
1865        off: function (name, callback) {
1866          getEventDispatcher(this).off(name, callback);
1867          return this;
1868        },
1869        fire: function (name, args, bubble) {
1870          var self = this;
1871          args = args || {};
1872          if (!args.control) {
1873            args.control = self;
1874          }
1875          args = getEventDispatcher(self).fire(name, args);
1876          if (bubble !== false && self.parent) {
1877            var parent = self.parent();
1878            while (parent && !args.isPropagationStopped()) {
1879              parent.fire(name, args, false);
1880              parent = parent.parent();
1881            }
1882          }
1883          return args;
1884        },
1885        hasEventListeners: function (name) {
1886          return getEventDispatcher(this).has(name);
1887        },
1888        parents: function (selector) {
1889          var self = this;
1890          var ctrl, parents = new Collection$2();
1891          for (ctrl = self.parent(); ctrl; ctrl = ctrl.parent()) {
1892            parents.add(ctrl);
1893          }
1894          if (selector) {
1895            parents = parents.filter(selector);
1896          }
1897          return parents;
1898        },
1899        parentsAndSelf: function (selector) {
1900          return new Collection$2(this).add(this.parents(selector));
1901        },
1902        next: function () {
1903          var parentControls = this.parent().items();
1904          return parentControls[parentControls.indexOf(this) + 1];
1905        },
1906        prev: function () {
1907          var parentControls = this.parent().items();
1908          return parentControls[parentControls.indexOf(this) - 1];
1909        },
1910        innerHtml: function (html) {
1911          this.$el.html(html);
1912          return this;
1913        },
1914        getEl: function (suffix) {
1915          var id = suffix ? this._id + '-' + suffix : this._id;
1916          if (!this._elmCache[id]) {
1917            this._elmCache[id] = global$7('#' + id)[0];
1918          }
1919          return this._elmCache[id];
1920        },
1921        show: function () {
1922          return this.visible(true);
1923        },
1924        hide: function () {
1925          return this.visible(false);
1926        },
1927        focus: function () {
1928          try {
1929            this.getEl().focus();
1930          } catch (ex) {
1931          }
1932          return this;
1933        },
1934        blur: function () {
1935          this.getEl().blur();
1936          return this;
1937        },
1938        aria: function (name, value) {
1939          var self = this, elm = self.getEl(self.ariaTarget);
1940          if (typeof value === 'undefined') {
1941            return self._aria[name];
1942          }
1943          self._aria[name] = value;
1944          if (self.state.get('rendered')) {
1945            elm.setAttribute(name === 'role' ? name : 'aria-' + name, value);
1946          }
1947          return self;
1948        },
1949        encode: function (text, translate) {
1950          if (translate !== false) {
1951            text = this.translate(text);
1952          }
1953          return (text || '').replace(/[&<>"]/g, function (match) {
1954            return '&#' + match.charCodeAt(0) + ';';
1955          });
1956        },
1957        translate: function (text) {
1958          return Control.translate ? Control.translate(text) : text;
1959        },
1960        before: function (items) {
1961          var self = this, parent = self.parent();
1962          if (parent) {
1963            parent.insert(items, parent.items().indexOf(self), true);
1964          }
1965          return self;
1966        },
1967        after: function (items) {
1968          var self = this, parent = self.parent();
1969          if (parent) {
1970            parent.insert(items, parent.items().indexOf(self));
1971          }
1972          return self;
1973        },
1974        remove: function () {
1975          var self = this;
1976          var elm = self.getEl();
1977          var parent = self.parent();
1978          var newItems, i;
1979          if (self.items) {
1980            var controls = self.items().toArray();
1981            i = controls.length;
1982            while (i--) {
1983              controls[i].remove();
1984            }
1985          }
1986          if (parent && parent.items) {
1987            newItems = [];
1988            parent.items().each(function (item) {
1989              if (item !== self) {
1990                newItems.push(item);
1991              }
1992            });
1993            parent.items().set(newItems);
1994            parent._lastRect = null;
1995          }
1996          if (self._eventsRoot && self._eventsRoot === self) {
1997            global$7(elm).off();
1998          }
1999          var lookup = self.getRoot().controlIdLookup;
2000          if (lookup) {
2001            delete lookup[self._id];
2002          }
2003          if (elm && elm.parentNode) {
2004            elm.parentNode.removeChild(elm);
2005          }
2006          self.state.set('rendered', false);
2007          self.state.destroy();
2008          self.fire('remove');
2009          return self;
2010        },
2011        renderBefore: function (elm) {
2012          global$7(elm).before(this.renderHtml());
2013          this.postRender();
2014          return this;
2015        },
2016        renderTo: function (elm) {
2017          global$7(elm || this.getContainerElm()).append(this.renderHtml());
2018          this.postRender();
2019          return this;
2020        },
2021        preRender: function () {
2022        },
2023        render: function () {
2024        },
2025        renderHtml: function () {
2026          return '<div id="' + this._id + '" class="' + this.classes + '"></div>';
2027        },
2028        postRender: function () {
2029          var self = this;
2030          var settings = self.settings;
2031          var elm, box, parent, name, parentEventsRoot;
2032          self.$el = global$7(self.getEl());
2033          self.state.set('rendered', true);
2034          for (name in settings) {
2035            if (name.indexOf('on') === 0) {
2036              self.on(name.substr(2), settings[name]);
2037            }
2038          }
2039          if (self._eventsRoot) {
2040            for (parent = self.parent(); !parentEventsRoot && parent; parent = parent.parent()) {
2041              parentEventsRoot = parent._eventsRoot;
2042            }
2043            if (parentEventsRoot) {
2044              for (name in parentEventsRoot._nativeEvents) {
2045                self._nativeEvents[name] = true;
2046              }
2047            }
2048          }
2049          bindPendingEvents(self);
2050          if (settings.style) {
2051            elm = self.getEl();
2052            if (elm) {
2053              elm.setAttribute('style', settings.style);
2054              elm.style.cssText = settings.style;
2055            }
2056          }
2057          if (self.settings.border) {
2058            box = self.borderBox;
2059            self.$el.css({
2060              'border-top-width': box.top,
2061              'border-right-width': box.right,
2062              'border-bottom-width': box.bottom,
2063              'border-left-width': box.left
2064            });
2065          }
2066          var root = self.getRoot();
2067          if (!root.controlIdLookup) {
2068            root.controlIdLookup = {};
2069          }
2070          root.controlIdLookup[self._id] = self;
2071          for (var key in self._aria) {
2072            self.aria(key, self._aria[key]);
2073          }
2074          if (self.state.get('visible') === false) {
2075            self.getEl().style.display = 'none';
2076          }
2077          self.bindStates();
2078          self.state.on('change:visible', function (e) {
2079            var state = e.value;
2080            var parentCtrl;
2081            if (self.state.get('rendered')) {
2082              self.getEl().style.display = state === false ? 'none' : '';
2083              self.getEl().getBoundingClientRect();
2084            }
2085            parentCtrl = self.parent();
2086            if (parentCtrl) {
2087              parentCtrl._lastRect = null;
2088            }
2089            self.fire(state ? 'show' : 'hide');
2090            ReflowQueue.add(self);
2091          });
2092          self.fire('postrender', {}, false);
2093        },
2094        bindStates: function () {
2095        },
2096        scrollIntoView: function (align) {
2097          function getOffset(elm, rootElm) {
2098            var x, y, parent = elm;
2099            x = y = 0;
2100            while (parent && parent !== rootElm && parent.nodeType) {
2101              x += parent.offsetLeft || 0;
2102              y += parent.offsetTop || 0;
2103              parent = parent.offsetParent;
2104            }
2105            return {
2106              x: x,
2107              y: y
2108            };
2109          }
2110          var elm = this.getEl(), parentElm = elm.parentNode;
2111          var x, y, width, height, parentWidth, parentHeight;
2112          var pos = getOffset(elm, parentElm);
2113          x = pos.x;
2114          y = pos.y;
2115          width = elm.offsetWidth;
2116          height = elm.offsetHeight;
2117          parentWidth = parentElm.clientWidth;
2118          parentHeight = parentElm.clientHeight;
2119          if (align === 'end') {
2120            x -= parentWidth - width;
2121            y -= parentHeight - height;
2122          } else if (align === 'center') {
2123            x -= parentWidth / 2 - width / 2;
2124            y -= parentHeight / 2 - height / 2;
2125          }
2126          parentElm.scrollLeft = x;
2127          parentElm.scrollTop = y;
2128          return this;
2129        },
2130        getRoot: function () {
2131          var ctrl = this, rootControl;
2132          var parents = [];
2133          while (ctrl) {
2134            if (ctrl.rootControl) {
2135              rootControl = ctrl.rootControl;
2136              break;
2137            }
2138            parents.push(ctrl);
2139            rootControl = ctrl;
2140            ctrl = ctrl.parent();
2141          }
2142          if (!rootControl) {
2143            rootControl = this;
2144          }
2145          var i = parents.length;
2146          while (i--) {
2147            parents[i].rootControl = rootControl;
2148          }
2149          return rootControl;
2150        },
2151        reflow: function () {
2152          ReflowQueue.remove(this);
2153          var parent = this.parent();
2154          if (parent && parent._layout && !parent._layout.isNative()) {
2155            parent.reflow();
2156          }
2157          return this;
2158        }
2159      };
2160      global$4.each('text title visible disabled active value'.split(' '), function (name) {
2161        proto$1[name] = function (value) {
2162          if (arguments.length === 0) {
2163            return this.state.get(name);
2164          }
2165          if (typeof value !== 'undefined') {
2166            this.state.set(name, value);
2167          }
2168          return this;
2169        };
2170      });
2171      Control = global$8.extend(proto$1);
2172      function getEventDispatcher(obj) {
2173        if (!obj._eventDispatcher) {
2174          obj._eventDispatcher = new global$9({
2175            scope: obj,
2176            toggleEvent: function (name, state) {
2177              if (state && global$9.isNative(name)) {
2178                if (!obj._nativeEvents) {
2179                  obj._nativeEvents = {};
2180                }
2181                obj._nativeEvents[name] = true;
2182                if (obj.state.get('rendered')) {
2183                  bindPendingEvents(obj);
2184                }
2185              }
2186            }
2187          });
2188        }
2189        return obj._eventDispatcher;
2190      }
2191      function bindPendingEvents(eventCtrl) {
2192        var i, l, parents, eventRootCtrl, nativeEvents, name;
2193        function delegate(e) {
2194          var control = eventCtrl.getParentCtrl(e.target);
2195          if (control) {
2196            control.fire(e.type, e);
2197          }
2198        }
2199        function mouseLeaveHandler() {
2200          var ctrl = eventRootCtrl._lastHoverCtrl;
2201          if (ctrl) {
2202            ctrl.fire('mouseleave', { target: ctrl.getEl() });
2203            ctrl.parents().each(function (ctrl) {
2204              ctrl.fire('mouseleave', { target: ctrl.getEl() });
2205            });
2206            eventRootCtrl._lastHoverCtrl = null;
2207          }
2208        }
2209        function mouseEnterHandler(e) {
2210          var ctrl = eventCtrl.getParentCtrl(e.target), lastCtrl = eventRootCtrl._lastHoverCtrl, idx = 0, i, parents, lastParents;
2211          if (ctrl !== lastCtrl) {
2212            eventRootCtrl._lastHoverCtrl = ctrl;
2213            parents = ctrl.parents().toArray().reverse();
2214            parents.push(ctrl);
2215            if (lastCtrl) {
2216              lastParents = lastCtrl.parents().toArray().reverse();
2217              lastParents.push(lastCtrl);
2218              for (idx = 0; idx < lastParents.length; idx++) {
2219                if (parents[idx] !== lastParents[idx]) {
2220                  break;
2221                }
2222              }
2223              for (i = lastParents.length - 1; i >= idx; i--) {
2224                lastCtrl = lastParents[i];
2225                lastCtrl.fire('mouseleave', { target: lastCtrl.getEl() });
2226              }
2227            }
2228            for (i = idx; i < parents.length; i++) {
2229              ctrl = parents[i];
2230              ctrl.fire('mouseenter', { target: ctrl.getEl() });
2231            }
2232          }
2233        }
2234        function fixWheelEvent(e) {
2235          e.preventDefault();
2236          if (e.type === 'mousewheel') {
2237            e.deltaY = -1 / 40 * e.wheelDelta;
2238            if (e.wheelDeltaX) {
2239              e.deltaX = -1 / 40 * e.wheelDeltaX;
2240            }
2241          } else {
2242            e.deltaX = 0;
2243            e.deltaY = e.detail;
2244          }
2245          e = eventCtrl.fire('wheel', e);
2246        }
2247        nativeEvents = eventCtrl._nativeEvents;
2248        if (nativeEvents) {
2249          parents = eventCtrl.parents().toArray();
2250          parents.unshift(eventCtrl);
2251          for (i = 0, l = parents.length; !eventRootCtrl && i < l; i++) {
2252            eventRootCtrl = parents[i]._eventsRoot;
2253          }
2254          if (!eventRootCtrl) {
2255            eventRootCtrl = parents[parents.length - 1] || eventCtrl;
2256          }
2257          eventCtrl._eventsRoot = eventRootCtrl;
2258          for (l = i, i = 0; i < l; i++) {
2259            parents[i]._eventsRoot = eventRootCtrl;
2260          }
2261          var eventRootDelegates = eventRootCtrl._delegates;
2262          if (!eventRootDelegates) {
2263            eventRootDelegates = eventRootCtrl._delegates = {};
2264          }
2265          for (name in nativeEvents) {
2266            if (!nativeEvents) {
2267              return false;
2268            }
2269            if (name === 'wheel' && !hasWheelEventSupport) {
2270              if (hasMouseWheelEventSupport) {
2271                global$7(eventCtrl.getEl()).on('mousewheel', fixWheelEvent);
2272              } else {
2273                global$7(eventCtrl.getEl()).on('DOMMouseScroll', fixWheelEvent);
2274              }
2275              continue;
2276            }
2277            if (name === 'mouseenter' || name === 'mouseleave') {
2278              if (!eventRootCtrl._hasMouseEnter) {
2279                global$7(eventRootCtrl.getEl()).on('mouseleave', mouseLeaveHandler).on('mouseover', mouseEnterHandler);
2280                eventRootCtrl._hasMouseEnter = 1;
2281              }
2282            } else if (!eventRootDelegates[name]) {
2283              global$7(eventRootCtrl.getEl()).on(name, delegate);
2284              eventRootDelegates[name] = true;
2285            }
2286            nativeEvents[name] = false;
2287          }
2288        }
2289      }
2290      var Control$1 = Control;
2291  
2292      var isStatic = function (elm) {
2293        return funcs.getRuntimeStyle(elm, 'position') === 'static';
2294      };
2295      var isFixed = function (ctrl) {
2296        return ctrl.state.get('fixed');
2297      };
2298      function calculateRelativePosition(ctrl, targetElm, rel) {
2299        var ctrlElm, pos, x, y, selfW, selfH, targetW, targetH, viewport, size;
2300        viewport = getWindowViewPort();
2301        pos = funcs.getPos(targetElm, UiContainer.getUiContainer(ctrl));
2302        x = pos.x;
2303        y = pos.y;
2304        if (isFixed(ctrl) && isStatic(domGlobals.document.body)) {
2305          x -= viewport.x;
2306          y -= viewport.y;
2307        }
2308        ctrlElm = ctrl.getEl();
2309        size = funcs.getSize(ctrlElm);
2310        selfW = size.width;
2311        selfH = size.height;
2312        size = funcs.getSize(targetElm);
2313        targetW = size.width;
2314        targetH = size.height;
2315        rel = (rel || '').split('');
2316        if (rel[0] === 'b') {
2317          y += targetH;
2318        }
2319        if (rel[1] === 'r') {
2320          x += targetW;
2321        }
2322        if (rel[0] === 'c') {
2323          y += Math.round(targetH / 2);
2324        }
2325        if (rel[1] === 'c') {
2326          x += Math.round(targetW / 2);
2327        }
2328        if (rel[3] === 'b') {
2329          y -= selfH;
2330        }
2331        if (rel[4] === 'r') {
2332          x -= selfW;
2333        }
2334        if (rel[3] === 'c') {
2335          y -= Math.round(selfH / 2);
2336        }
2337        if (rel[4] === 'c') {
2338          x -= Math.round(selfW / 2);
2339        }
2340        return {
2341          x: x,
2342          y: y,
2343          w: selfW,
2344          h: selfH
2345        };
2346      }
2347      var getUiContainerViewPort = function (customUiContainer) {
2348        return {
2349          x: 0,
2350          y: 0,
2351          w: customUiContainer.scrollWidth - 1,
2352          h: customUiContainer.scrollHeight - 1
2353        };
2354      };
2355      var getWindowViewPort = function () {
2356        var win = domGlobals.window;
2357        var x = Math.max(win.pageXOffset, domGlobals.document.body.scrollLeft, domGlobals.document.documentElement.scrollLeft);
2358        var y = Math.max(win.pageYOffset, domGlobals.document.body.scrollTop, domGlobals.document.documentElement.scrollTop);
2359        var w = win.innerWidth || domGlobals.document.documentElement.clientWidth;
2360        var h = win.innerHeight || domGlobals.document.documentElement.clientHeight;
2361        return {
2362          x: x,
2363          y: y,
2364          w: w,
2365          h: h
2366        };
2367      };
2368      var getViewPortRect = function (ctrl) {
2369        var customUiContainer = UiContainer.getUiContainer(ctrl);
2370        return customUiContainer && !isFixed(ctrl) ? getUiContainerViewPort(customUiContainer) : getWindowViewPort();
2371      };
2372      var Movable = {
2373        testMoveRel: function (elm, rels) {
2374          var viewPortRect = getViewPortRect(this);
2375          for (var i = 0; i < rels.length; i++) {
2376            var pos = calculateRelativePosition(this, elm, rels[i]);
2377            if (isFixed(this)) {
2378              if (pos.x > 0 && pos.x + pos.w < viewPortRect.w && pos.y > 0 && pos.y + pos.h < viewPortRect.h) {
2379                return rels[i];
2380              }
2381            } else {
2382              if (pos.x > viewPortRect.x && pos.x + pos.w < viewPortRect.w + viewPortRect.x && pos.y > viewPortRect.y && pos.y + pos.h < viewPortRect.h + viewPortRect.y) {
2383                return rels[i];
2384              }
2385            }
2386          }
2387          return rels[0];
2388        },
2389        moveRel: function (elm, rel) {
2390          if (typeof rel !== 'string') {
2391            rel = this.testMoveRel(elm, rel);
2392          }
2393          var pos = calculateRelativePosition(this, elm, rel);
2394          return this.moveTo(pos.x, pos.y);
2395        },
2396        moveBy: function (dx, dy) {
2397          var self = this, rect = self.layoutRect();
2398          self.moveTo(rect.x + dx, rect.y + dy);
2399          return self;
2400        },
2401        moveTo: function (x, y) {
2402          var self = this;
2403          function constrain(value, max, size) {
2404            if (value < 0) {
2405              return 0;
2406            }
2407            if (value + size > max) {
2408              value = max - size;
2409              return value < 0 ? 0 : value;
2410            }
2411            return value;
2412          }
2413          if (self.settings.constrainToViewport) {
2414            var viewPortRect = getViewPortRect(this);
2415            var layoutRect = self.layoutRect();
2416            x = constrain(x, viewPortRect.w + viewPortRect.x, layoutRect.w);
2417            y = constrain(y, viewPortRect.h + viewPortRect.y, layoutRect.h);
2418          }
2419          var uiContainer = UiContainer.getUiContainer(self);
2420          if (uiContainer && isStatic(uiContainer) && !isFixed(self)) {
2421            x -= uiContainer.scrollLeft;
2422            y -= uiContainer.scrollTop;
2423          }
2424          if (uiContainer) {
2425            x += 1;
2426            y += 1;
2427          }
2428          if (self.state.get('rendered')) {
2429            self.layoutRect({
2430              x: x,
2431              y: y
2432            }).repaint();
2433          } else {
2434            self.settings.x = x;
2435            self.settings.y = y;
2436          }
2437          self.fire('move', {
2438            x: x,
2439            y: y
2440          });
2441          return self;
2442        }
2443      };
2444  
2445      var Tooltip = Control$1.extend({
2446        Mixins: [Movable],
2447        Defaults: { classes: 'widget tooltip tooltip-n' },
2448        renderHtml: function () {
2449          var self = this, prefix = self.classPrefix;
2450          return '<div id="' + self._id + '" class="' + self.classes + '" role="presentation">' + '<div class="' + prefix + 'tooltip-arrow"></div>' + '<div class="' + prefix + 'tooltip-inner">' + self.encode(self.state.get('text')) + '</div>' + '</div>';
2451        },
2452        bindStates: function () {
2453          var self = this;
2454          self.state.on('change:text', function (e) {
2455            self.getEl().lastChild.innerHTML = self.encode(e.value);
2456          });
2457          return self._super();
2458        },
2459        repaint: function () {
2460          var self = this;
2461          var style, rect;
2462          style = self.getEl().style;
2463          rect = self._layoutRect;
2464          style.left = rect.x + 'px';
2465          style.top = rect.y + 'px';
2466          style.zIndex = 65535 + 65535;
2467        }
2468      });
2469  
2470      var Widget = Control$1.extend({
2471        init: function (settings) {
2472          var self = this;
2473          self._super(settings);
2474          settings = self.settings;
2475          self.canFocus = true;
2476          if (settings.tooltip && Widget.tooltips !== false) {
2477            self.on('mouseenter', function (e) {
2478              var tooltip = self.tooltip().moveTo(-65535);
2479              if (e.control === self) {
2480                var rel = tooltip.text(settings.tooltip).show().testMoveRel(self.getEl(), [
2481                  'bc-tc',
2482                  'bc-tl',
2483                  'bc-tr'
2484                ]);
2485                tooltip.classes.toggle('tooltip-n', rel === 'bc-tc');
2486                tooltip.classes.toggle('tooltip-nw', rel === 'bc-tl');
2487                tooltip.classes.toggle('tooltip-ne', rel === 'bc-tr');
2488                tooltip.moveRel(self.getEl(), rel);
2489              } else {
2490                tooltip.hide();
2491              }
2492            });
2493            self.on('mouseleave mousedown click', function () {
2494              self.tooltip().remove();
2495              self._tooltip = null;
2496            });
2497          }
2498          self.aria('label', settings.ariaLabel || settings.tooltip);
2499        },
2500        tooltip: function () {
2501          if (!this._tooltip) {
2502            this._tooltip = new Tooltip({ type: 'tooltip' });
2503            UiContainer.inheritUiContainer(this, this._tooltip);
2504            this._tooltip.renderTo();
2505          }
2506          return this._tooltip;
2507        },
2508        postRender: function () {
2509          var self = this, settings = self.settings;
2510          self._super();
2511          if (!self.parent() && (settings.width || settings.height)) {
2512            self.initLayoutRect();
2513            self.repaint();
2514          }
2515          if (settings.autofocus) {
2516            self.focus();
2517          }
2518        },
2519        bindStates: function () {
2520          var self = this;
2521          function disable(state) {
2522            self.aria('disabled', state);
2523            self.classes.toggle('disabled', state);
2524          }
2525          function active(state) {
2526            self.aria('pressed', state);
2527            self.classes.toggle('active', state);
2528          }
2529          self.state.on('change:disabled', function (e) {
2530            disable(e.value);
2531          });
2532          self.state.on('change:active', function (e) {
2533            active(e.value);
2534          });
2535          if (self.state.get('disabled')) {
2536            disable(true);
2537          }
2538          if (self.state.get('active')) {
2539            active(true);
2540          }
2541          return self._super();
2542        },
2543        remove: function () {
2544          this._super();
2545          if (this._tooltip) {
2546            this._tooltip.remove();
2547            this._tooltip = null;
2548          }
2549        }
2550      });
2551  
2552      var Progress = Widget.extend({
2553        Defaults: { value: 0 },
2554        init: function (settings) {
2555          var self = this;
2556          self._super(settings);
2557          self.classes.add('progress');
2558          if (!self.settings.filter) {
2559            self.settings.filter = function (value) {
2560              return Math.round(value);
2561            };
2562          }
2563        },
2564        renderHtml: function () {
2565          var self = this, id = self._id, prefix = this.classPrefix;
2566          return '<div id="' + id + '" class="' + self.classes + '">' + '<div class="' + prefix + 'bar-container">' + '<div class="' + prefix + 'bar"></div>' + '</div>' + '<div class="' + prefix + 'text">0%</div>' + '</div>';
2567        },
2568        postRender: function () {
2569          var self = this;
2570          self._super();
2571          self.value(self.settings.value);
2572          return self;
2573        },
2574        bindStates: function () {
2575          var self = this;
2576          function setValue(value) {
2577            value = self.settings.filter(value);
2578            self.getEl().lastChild.innerHTML = value + '%';
2579            self.getEl().firstChild.firstChild.style.width = value + '%';
2580          }
2581          self.state.on('change:value', function (e) {
2582            setValue(e.value);
2583          });
2584          setValue(self.state.get('value'));
2585          return self._super();
2586        }
2587      });
2588  
2589      var updateLiveRegion = function (ctx, text) {
2590        ctx.getEl().lastChild.textContent = text + (ctx.progressBar ? ' ' + ctx.progressBar.value() + '%' : '');
2591      };
2592      var Notification = Control$1.extend({
2593        Mixins: [Movable],
2594        Defaults: { classes: 'widget notification' },
2595        init: function (settings) {
2596          var self = this;
2597          self._super(settings);
2598          self.maxWidth = settings.maxWidth;
2599          if (settings.text) {
2600            self.text(settings.text);
2601          }
2602          if (settings.icon) {
2603            self.icon = settings.icon;
2604          }
2605          if (settings.color) {
2606            self.color = settings.color;
2607          }
2608          if (settings.type) {
2609            self.classes.add('notification-' + settings.type);
2610          }
2611          if (settings.timeout && (settings.timeout < 0 || settings.timeout > 0) && !settings.closeButton) {
2612            self.closeButton = false;
2613          } else {
2614            self.classes.add('has-close');
2615            self.closeButton = true;
2616          }
2617          if (settings.progressBar) {
2618            self.progressBar = new Progress();
2619          }
2620          self.on('click', function (e) {
2621            if (e.target.className.indexOf(self.classPrefix + 'close') !== -1) {
2622              self.close();
2623            }
2624          });
2625        },
2626        renderHtml: function () {
2627          var self = this;
2628          var prefix = self.classPrefix;
2629          var icon = '', closeButton = '', progressBar = '', notificationStyle = '';
2630          if (self.icon) {
2631            icon = '<i class="' + prefix + 'ico' + ' ' + prefix + 'i-' + self.icon + '"></i>';
2632          }
2633          notificationStyle = ' style="max-width: ' + self.maxWidth + 'px;' + (self.color ? 'background-color: ' + self.color + ';"' : '"');
2634          if (self.closeButton) {
2635            closeButton = '<button type="button" class="' + prefix + 'close" aria-hidden="true">\xD7</button>';
2636          }
2637          if (self.progressBar) {
2638            progressBar = self.progressBar.renderHtml();
2639          }
2640          return '<div id="' + self._id + '" class="' + self.classes + '"' + notificationStyle + ' role="presentation">' + icon + '<div class="' + prefix + 'notification-inner">' + self.state.get('text') + '</div>' + progressBar + closeButton + '<div style="clip: rect(1px, 1px, 1px, 1px);height: 1px;overflow: hidden;position: absolute;width: 1px;"' + ' aria-live="assertive" aria-relevant="additions" aria-atomic="true"></div>' + '</div>';
2641        },
2642        postRender: function () {
2643          var self = this;
2644          global$3.setTimeout(function () {
2645            self.$el.addClass(self.classPrefix + 'in');
2646            updateLiveRegion(self, self.state.get('text'));
2647          }, 100);
2648          return self._super();
2649        },
2650        bindStates: function () {
2651          var self = this;
2652          self.state.on('change:text', function (e) {
2653            self.getEl().firstChild.innerHTML = e.value;
2654            updateLiveRegion(self, e.value);
2655          });
2656          if (self.progressBar) {
2657            self.progressBar.bindStates();
2658            self.progressBar.state.on('change:value', function (e) {
2659              updateLiveRegion(self, self.state.get('text'));
2660            });
2661          }
2662          return self._super();
2663        },
2664        close: function () {
2665          var self = this;
2666          if (!self.fire('close').isDefaultPrevented()) {
2667            self.remove();
2668          }
2669          return self;
2670        },
2671        repaint: function () {
2672          var self = this;
2673          var style, rect;
2674          style = self.getEl().style;
2675          rect = self._layoutRect;
2676          style.left = rect.x + 'px';
2677          style.top = rect.y + 'px';
2678          style.zIndex = 65535 - 1;
2679        }
2680      });
2681  
2682      function NotificationManagerImpl (editor) {
2683        var getEditorContainer = function (editor) {
2684          return editor.inline ? editor.getElement() : editor.getContentAreaContainer();
2685        };
2686        var getContainerWidth = function () {
2687          var container = getEditorContainer(editor);
2688          return funcs.getSize(container).width;
2689        };
2690        var prePositionNotifications = function (notifications) {
2691          each(notifications, function (notification) {
2692            notification.moveTo(0, 0);
2693          });
2694        };
2695        var positionNotifications = function (notifications) {
2696          if (notifications.length > 0) {
2697            var firstItem = notifications.slice(0, 1)[0];
2698            var container = getEditorContainer(editor);
2699            firstItem.moveRel(container, 'tc-tc');
2700            each(notifications, function (notification, index) {
2701              if (index > 0) {
2702                notification.moveRel(notifications[index - 1].getEl(), 'bc-tc');
2703              }
2704            });
2705          }
2706        };
2707        var reposition = function (notifications) {
2708          prePositionNotifications(notifications);
2709          positionNotifications(notifications);
2710        };
2711        var open = function (args, closeCallback) {
2712          var extendedArgs = global$4.extend(args, { maxWidth: getContainerWidth() });
2713          var notif = new Notification(extendedArgs);
2714          notif.args = extendedArgs;
2715          if (extendedArgs.timeout > 0) {
2716            notif.timer = setTimeout(function () {
2717              notif.close();
2718              closeCallback();
2719            }, extendedArgs.timeout);
2720          }
2721          notif.on('close', function () {
2722            closeCallback();
2723          });
2724          notif.renderTo();
2725          return notif;
2726        };
2727        var close = function (notification) {
2728          notification.close();
2729        };
2730        var getArgs = function (notification) {
2731          return notification.args;
2732        };
2733        return {
2734          open: open,
2735          close: close,
2736          reposition: reposition,
2737          getArgs: getArgs
2738        };
2739      }
2740  
2741      function getDocumentSize(doc) {
2742        var documentElement, body, scrollWidth, clientWidth;
2743        var offsetWidth, scrollHeight, clientHeight, offsetHeight;
2744        var max = Math.max;
2745        documentElement = doc.documentElement;
2746        body = doc.body;
2747        scrollWidth = max(documentElement.scrollWidth, body.scrollWidth);
2748        clientWidth = max(documentElement.clientWidth, body.clientWidth);
2749        offsetWidth = max(documentElement.offsetWidth, body.offsetWidth);
2750        scrollHeight = max(documentElement.scrollHeight, body.scrollHeight);
2751        clientHeight = max(documentElement.clientHeight, body.clientHeight);
2752        offsetHeight = max(documentElement.offsetHeight, body.offsetHeight);
2753        return {
2754          width: scrollWidth < offsetWidth ? clientWidth : scrollWidth,
2755          height: scrollHeight < offsetHeight ? clientHeight : scrollHeight
2756        };
2757      }
2758      function updateWithTouchData(e) {
2759        var keys, i;
2760        if (e.changedTouches) {
2761          keys = 'screenX screenY pageX pageY clientX clientY'.split(' ');
2762          for (i = 0; i < keys.length; i++) {
2763            e[keys[i]] = e.changedTouches[0][keys[i]];
2764          }
2765        }
2766      }
2767      function DragHelper (id, settings) {
2768        var $eventOverlay;
2769        var doc = settings.document || domGlobals.document;
2770        var downButton;
2771        var start, stop, drag, startX, startY;
2772        settings = settings || {};
2773        var handleElement = doc.getElementById(settings.handle || id);
2774        start = function (e) {
2775          var docSize = getDocumentSize(doc);
2776          var handleElm, cursor;
2777          updateWithTouchData(e);
2778          e.preventDefault();
2779          downButton = e.button;
2780          handleElm = handleElement;
2781          startX = e.screenX;
2782          startY = e.screenY;
2783          if (domGlobals.window.getComputedStyle) {
2784            cursor = domGlobals.window.getComputedStyle(handleElm, null).getPropertyValue('cursor');
2785          } else {
2786            cursor = handleElm.runtimeStyle.cursor;
2787          }
2788          $eventOverlay = global$7('<div></div>').css({
2789            position: 'absolute',
2790            top: 0,
2791            left: 0,
2792            width: docSize.width,
2793            height: docSize.height,
2794            zIndex: 2147483647,
2795            opacity: 0.0001,
2796            cursor: cursor
2797          }).appendTo(doc.body);
2798          global$7(doc).on('mousemove touchmove', drag).on('mouseup touchend', stop);
2799          settings.start(e);
2800        };
2801        drag = function (e) {
2802          updateWithTouchData(e);
2803          if (e.button !== downButton) {
2804            return stop(e);
2805          }
2806          e.deltaX = e.screenX - startX;
2807          e.deltaY = e.screenY - startY;
2808          e.preventDefault();
2809          settings.drag(e);
2810        };
2811        stop = function (e) {
2812          updateWithTouchData(e);
2813          global$7(doc).off('mousemove touchmove', drag).off('mouseup touchend', stop);
2814          $eventOverlay.remove();
2815          if (settings.stop) {
2816            settings.stop(e);
2817          }
2818        };
2819        this.destroy = function () {
2820          global$7(handleElement).off();
2821        };
2822        global$7(handleElement).on('mousedown touchstart', start);
2823      }
2824  
2825      var global$b = tinymce.util.Tools.resolve('tinymce.ui.Factory');
2826  
2827      var hasTabstopData = function (elm) {
2828        return elm.getAttribute('data-mce-tabstop') ? true : false;
2829      };
2830      function KeyboardNavigation (settings) {
2831        var root = settings.root;
2832        var focusedElement, focusedControl;
2833        function isElement(node) {
2834          return node && node.nodeType === 1;
2835        }
2836        try {
2837          focusedElement = domGlobals.document.activeElement;
2838        } catch (ex) {
2839          focusedElement = domGlobals.document.body;
2840        }
2841        focusedControl = root.getParentCtrl(focusedElement);
2842        function getRole(elm) {
2843          elm = elm || focusedElement;
2844          if (isElement(elm)) {
2845            return elm.getAttribute('role');
2846          }
2847          return null;
2848        }
2849        function getParentRole(elm) {
2850          var role, parent = elm || focusedElement;
2851          while (parent = parent.parentNode) {
2852            if (role = getRole(parent)) {
2853              return role;
2854            }
2855          }
2856        }
2857        function getAriaProp(name) {
2858          var elm = focusedElement;
2859          if (isElement(elm)) {
2860            return elm.getAttribute('aria-' + name);
2861          }
2862        }
2863        function isTextInputElement(elm) {
2864          var tagName = elm.tagName.toUpperCase();
2865          return tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT';
2866        }
2867        function canFocus(elm) {
2868          if (isTextInputElement(elm) && !elm.hidden) {
2869            return true;
2870          }
2871          if (hasTabstopData(elm)) {
2872            return true;
2873          }
2874          if (/^(button|menuitem|checkbox|tab|menuitemcheckbox|option|gridcell|slider)$/.test(getRole(elm))) {
2875            return true;
2876          }
2877          return false;
2878        }
2879        function getFocusElements(elm) {
2880          var elements = [];
2881          function collect(elm) {
2882            if (elm.nodeType !== 1 || elm.style.display === 'none' || elm.disabled) {
2883              return;
2884            }
2885            if (canFocus(elm)) {
2886              elements.push(elm);
2887            }
2888            for (var i = 0; i < elm.childNodes.length; i++) {
2889              collect(elm.childNodes[i]);
2890            }
2891          }
2892          collect(elm || root.getEl());
2893          return elements;
2894        }
2895        function getNavigationRoot(targetControl) {
2896          var navigationRoot, controls;
2897          targetControl = targetControl || focusedControl;
2898          controls = targetControl.parents().toArray();
2899          controls.unshift(targetControl);
2900          for (var i = 0; i < controls.length; i++) {
2901            navigationRoot = controls[i];
2902            if (navigationRoot.settings.ariaRoot) {
2903              break;
2904            }
2905          }
2906          return navigationRoot;
2907        }
2908        function focusFirst(targetControl) {
2909          var navigationRoot = getNavigationRoot(targetControl);
2910          var focusElements = getFocusElements(navigationRoot.getEl());
2911          if (navigationRoot.settings.ariaRemember && 'lastAriaIndex' in navigationRoot) {
2912            moveFocusToIndex(navigationRoot.lastAriaIndex, focusElements);
2913          } else {
2914            moveFocusToIndex(0, focusElements);
2915          }
2916        }
2917        function moveFocusToIndex(idx, elements) {
2918          if (idx < 0) {
2919            idx = elements.length - 1;
2920          } else if (idx >= elements.length) {
2921            idx = 0;
2922          }
2923          if (elements[idx]) {
2924            elements[idx].focus();
2925          }
2926          return idx;
2927        }
2928        function moveFocus(dir, elements) {
2929          var idx = -1;
2930          var navigationRoot = getNavigationRoot();
2931          elements = elements || getFocusElements(navigationRoot.getEl());
2932          for (var i = 0; i < elements.length; i++) {
2933            if (elements[i] === focusedElement) {
2934              idx = i;
2935            }
2936          }
2937          idx += dir;
2938          navigationRoot.lastAriaIndex = moveFocusToIndex(idx, elements);
2939        }
2940        function left() {
2941          var parentRole = getParentRole();
2942          if (parentRole === 'tablist') {
2943            moveFocus(-1, getFocusElements(focusedElement.parentNode));
2944          } else if (focusedControl.parent().submenu) {
2945            cancel();
2946          } else {
2947            moveFocus(-1);
2948          }
2949        }
2950        function right() {
2951          var role = getRole(), parentRole = getParentRole();
2952          if (parentRole === 'tablist') {
2953            moveFocus(1, getFocusElements(focusedElement.parentNode));
2954          } else if (role === 'menuitem' && parentRole === 'menu' && getAriaProp('haspopup')) {
2955            enter();
2956          } else {
2957            moveFocus(1);
2958          }
2959        }
2960        function up() {
2961          moveFocus(-1);
2962        }
2963        function down() {
2964          var role = getRole(), parentRole = getParentRole();
2965          if (role === 'menuitem' && parentRole === 'menubar') {
2966            enter();
2967          } else if (role === 'button' && getAriaProp('haspopup')) {
2968            enter({ key: 'down' });
2969          } else {
2970            moveFocus(1);
2971          }
2972        }
2973        function tab(e) {
2974          var parentRole = getParentRole();
2975          if (parentRole === 'tablist') {
2976            var elm = getFocusElements(focusedControl.getEl('body'))[0];
2977            if (elm) {
2978              elm.focus();
2979            }
2980          } else {
2981            moveFocus(e.shiftKey ? -1 : 1);
2982          }
2983        }
2984        function cancel() {
2985          focusedControl.fire('cancel');
2986        }
2987        function enter(aria) {
2988          aria = aria || {};
2989          focusedControl.fire('click', {
2990            target: focusedElement,
2991            aria: aria
2992          });
2993        }
2994        root.on('keydown', function (e) {
2995          function handleNonTabOrEscEvent(e, handler) {
2996            if (isTextInputElement(focusedElement) || hasTabstopData(focusedElement)) {
2997              return;
2998            }
2999            if (getRole(focusedElement) === 'slider') {
3000              return;
3001            }
3002            if (handler(e) !== false) {
3003              e.preventDefault();
3004            }
3005          }
3006          if (e.isDefaultPrevented()) {
3007            return;
3008          }
3009          switch (e.keyCode) {
3010          case 37:
3011            handleNonTabOrEscEvent(e, left);
3012            break;
3013          case 39:
3014            handleNonTabOrEscEvent(e, right);
3015            break;
3016          case 38:
3017            handleNonTabOrEscEvent(e, up);
3018            break;
3019          case 40:
3020            handleNonTabOrEscEvent(e, down);
3021            break;
3022          case 27:
3023            cancel();
3024            break;
3025          case 14:
3026          case 13:
3027          case 32:
3028            handleNonTabOrEscEvent(e, enter);
3029            break;
3030          case 9:
3031            tab(e);
3032            e.preventDefault();
3033            break;
3034          }
3035        });
3036        root.on('focusin', function (e) {
3037          focusedElement = e.target;
3038          focusedControl = e.control;
3039        });
3040        return { focusFirst: focusFirst };
3041      }
3042  
3043      var selectorCache = {};
3044      var Container = Control$1.extend({
3045        init: function (settings) {
3046          var self = this;
3047          self._super(settings);
3048          settings = self.settings;
3049          if (settings.fixed) {
3050            self.state.set('fixed', true);
3051          }
3052          self._items = new Collection$2();
3053          if (self.isRtl()) {
3054            self.classes.add('rtl');
3055          }
3056          self.bodyClasses = new ClassList(function () {
3057            if (self.state.get('rendered')) {
3058              self.getEl('body').className = this.toString();
3059            }
3060          });
3061          self.bodyClasses.prefix = self.classPrefix;
3062          self.classes.add('container');
3063          self.bodyClasses.add('container-body');
3064          if (settings.containerCls) {
3065            self.classes.add(settings.containerCls);
3066          }
3067          self._layout = global$b.create((settings.layout || '') + 'layout');
3068          if (self.settings.items) {
3069            self.add(self.settings.items);
3070          } else {
3071            self.add(self.render());
3072          }
3073          self._hasBody = true;
3074        },
3075        items: function () {
3076          return this._items;
3077        },
3078        find: function (selector) {
3079          selector = selectorCache[selector] = selectorCache[selector] || new Selector(selector);
3080          return selector.find(this);
3081        },
3082        add: function (items) {
3083          var self = this;
3084          self.items().add(self.create(items)).parent(self);
3085          return self;
3086        },
3087        focus: function (keyboard) {
3088          var self = this;
3089          var focusCtrl, keyboardNav, items;
3090          if (keyboard) {
3091            keyboardNav = self.keyboardNav || self.parents().eq(-1)[0].keyboardNav;
3092            if (keyboardNav) {
3093              keyboardNav.focusFirst(self);
3094              return;
3095            }
3096          }
3097          items = self.find('*');
3098          if (self.statusbar) {
3099            items.add(self.statusbar.items());
3100          }
3101          items.each(function (ctrl) {
3102            if (ctrl.settings.autofocus) {
3103              focusCtrl = null;
3104              return false;
3105            }
3106            if (ctrl.canFocus) {
3107              focusCtrl = focusCtrl || ctrl;
3108            }
3109          });
3110          if (focusCtrl) {
3111            focusCtrl.focus();
3112          }
3113          return self;
3114        },
3115        replace: function (oldItem, newItem) {
3116          var ctrlElm;
3117          var items = this.items();
3118          var i = items.length;
3119          while (i--) {
3120            if (items[i] === oldItem) {
3121              items[i] = newItem;
3122              break;
3123            }
3124          }
3125          if (i >= 0) {
3126            ctrlElm = newItem.getEl();
3127            if (ctrlElm) {
3128              ctrlElm.parentNode.removeChild(ctrlElm);
3129            }
3130            ctrlElm = oldItem.getEl();
3131            if (ctrlElm) {
3132              ctrlElm.parentNode.removeChild(ctrlElm);
3133            }
3134          }
3135          newItem.parent(this);
3136        },
3137        create: function (items) {
3138          var self = this;
3139          var settings;
3140          var ctrlItems = [];
3141          if (!global$4.isArray(items)) {
3142            items = [items];
3143          }
3144          global$4.each(items, function (item) {
3145            if (item) {
3146              if (!(item instanceof Control$1)) {
3147                if (typeof item === 'string') {
3148                  item = { type: item };
3149                }
3150                settings = global$4.extend({}, self.settings.defaults, item);
3151                item.type = settings.type = settings.type || item.type || self.settings.defaultType || (settings.defaults ? settings.defaults.type : null);
3152                item = global$b.create(settings);
3153              }
3154              ctrlItems.push(item);
3155            }
3156          });
3157          return ctrlItems;
3158        },
3159        renderNew: function () {
3160          var self = this;
3161          self.items().each(function (ctrl, index) {
3162            var containerElm;
3163            ctrl.parent(self);
3164            if (!ctrl.state.get('rendered')) {
3165              containerElm = self.getEl('body');
3166              if (containerElm.hasChildNodes() && index <= containerElm.childNodes.length - 1) {
3167                global$7(containerElm.childNodes[index]).before(ctrl.renderHtml());
3168              } else {
3169                global$7(containerElm).append(ctrl.renderHtml());
3170              }
3171              ctrl.postRender();
3172              ReflowQueue.add(ctrl);
3173            }
3174          });
3175          self._layout.applyClasses(self.items().filter(':visible'));
3176          self._lastRect = null;
3177          return self;
3178        },
3179        append: function (items) {
3180          return this.add(items).renderNew();
3181        },
3182        prepend: function (items) {
3183          var self = this;
3184          self.items().set(self.create(items).concat(self.items().toArray()));
3185          return self.renderNew();
3186        },
3187        insert: function (items, index, before) {
3188          var self = this;
3189          var curItems, beforeItems, afterItems;
3190          items = self.create(items);
3191          curItems = self.items();
3192          if (!before && index < curItems.length - 1) {
3193            index += 1;
3194          }
3195          if (index >= 0 && index < curItems.length) {
3196            beforeItems = curItems.slice(0, index).toArray();
3197            afterItems = curItems.slice(index).toArray();
3198            curItems.set(beforeItems.concat(items, afterItems));
3199          }
3200          return self.renderNew();
3201        },
3202        fromJSON: function (data) {
3203          var self = this;
3204          for (var name in data) {
3205            self.find('#' + name).value(data[name]);
3206          }
3207          return self;
3208        },
3209        toJSON: function () {
3210          var self = this, data = {};
3211          self.find('*').each(function (ctrl) {
3212            var name = ctrl.name(), value = ctrl.value();
3213            if (name && typeof value !== 'undefined') {
3214              data[name] = value;
3215            }
3216          });
3217          return data;
3218        },
3219        renderHtml: function () {
3220          var self = this, layout = self._layout, role = this.settings.role;
3221          self.preRender();
3222          layout.preRender(self);
3223          return '<div id="' + self._id + '" class="' + self.classes + '"' + (role ? ' role="' + this.settings.role + '"' : '') + '>' + '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + (self.settings.html || '') + layout.renderHtml(self) + '</div>' + '</div>';
3224        },
3225        postRender: function () {
3226          var self = this;
3227          var box;
3228          self.items().exec('postRender');
3229          self._super();
3230          self._layout.postRender(self);
3231          self.state.set('rendered', true);
3232          if (self.settings.style) {
3233            self.$el.css(self.settings.style);
3234          }
3235          if (self.settings.border) {
3236            box = self.borderBox;
3237            self.$el.css({
3238              'border-top-width': box.top,
3239              'border-right-width': box.right,
3240              'border-bottom-width': box.bottom,
3241              'border-left-width': box.left
3242            });
3243          }
3244          if (!self.parent()) {
3245            self.keyboardNav = KeyboardNavigation({ root: self });
3246          }
3247          return self;
3248        },
3249        initLayoutRect: function () {
3250          var self = this, layoutRect = self._super();
3251          self._layout.recalc(self);
3252          return layoutRect;
3253        },
3254        recalc: function () {
3255          var self = this;
3256          var rect = self._layoutRect;
3257          var lastRect = self._lastRect;
3258          if (!lastRect || lastRect.w !== rect.w || lastRect.h !== rect.h) {
3259            self._layout.recalc(self);
3260            rect = self.layoutRect();
3261            self._lastRect = {
3262              x: rect.x,
3263              y: rect.y,
3264              w: rect.w,
3265              h: rect.h
3266            };
3267            return true;
3268          }
3269        },
3270        reflow: function () {
3271          var i;
3272          ReflowQueue.remove(this);
3273          if (this.visible()) {
3274            Control$1.repaintControls = [];
3275            Control$1.repaintControls.map = {};
3276            this.recalc();
3277            i = Control$1.repaintControls.length;
3278            while (i--) {
3279              Control$1.repaintControls[i].repaint();
3280            }
3281            if (this.settings.layout !== 'flow' && this.settings.layout !== 'stack') {
3282              this.repaint();
3283            }
3284            Control$1.repaintControls = [];
3285          }
3286          return this;
3287        }
3288      });
3289  
3290      var Scrollable = {
3291        init: function () {
3292          var self = this;
3293          self.on('repaint', self.renderScroll);
3294        },
3295        renderScroll: function () {
3296          var self = this, margin = 2;
3297          function repaintScroll() {
3298            var hasScrollH, hasScrollV, bodyElm;
3299            function repaintAxis(axisName, posName, sizeName, contentSizeName, hasScroll, ax) {
3300              var containerElm, scrollBarElm, scrollThumbElm;
3301              var containerSize, scrollSize, ratio, rect;
3302              var posNameLower, sizeNameLower;
3303              scrollBarElm = self.getEl('scroll' + axisName);
3304              if (scrollBarElm) {
3305                posNameLower = posName.toLowerCase();
3306                sizeNameLower = sizeName.toLowerCase();
3307                global$7(self.getEl('absend')).css(posNameLower, self.layoutRect()[contentSizeName] - 1);
3308                if (!hasScroll) {
3309                  global$7(scrollBarElm).css('display', 'none');
3310                  return;
3311                }
3312                global$7(scrollBarElm).css('display', 'block');
3313                containerElm = self.getEl('body');
3314                scrollThumbElm = self.getEl('scroll' + axisName + 't');
3315                containerSize = containerElm['client' + sizeName] - margin * 2;
3316                containerSize -= hasScrollH && hasScrollV ? scrollBarElm['client' + ax] : 0;
3317                scrollSize = containerElm['scroll' + sizeName];
3318                ratio = containerSize / scrollSize;
3319                rect = {};
3320                rect[posNameLower] = containerElm['offset' + posName] + margin;
3321                rect[sizeNameLower] = containerSize;
3322                global$7(scrollBarElm).css(rect);
3323                rect = {};
3324                rect[posNameLower] = containerElm['scroll' + posName] * ratio;
3325                rect[sizeNameLower] = containerSize * ratio;
3326                global$7(scrollThumbElm).css(rect);
3327              }
3328            }
3329            bodyElm = self.getEl('body');
3330            hasScrollH = bodyElm.scrollWidth > bodyElm.clientWidth;
3331            hasScrollV = bodyElm.scrollHeight > bodyElm.clientHeight;
3332            repaintAxis('h', 'Left', 'Width', 'contentW', hasScrollH, 'Height');
3333            repaintAxis('v', 'Top', 'Height', 'contentH', hasScrollV, 'Width');
3334          }
3335          function addScroll() {
3336            function addScrollAxis(axisName, posName, sizeName, deltaPosName, ax) {
3337              var scrollStart;
3338              var axisId = self._id + '-scroll' + axisName, prefix = self.classPrefix;
3339              global$7(self.getEl()).append('<div id="' + axisId + '" class="' + prefix + 'scrollbar ' + prefix + 'scrollbar-' + axisName + '">' + '<div id="' + axisId + 't" class="' + prefix + 'scrollbar-thumb"></div>' + '</div>');
3340              self.draghelper = new DragHelper(axisId + 't', {
3341                start: function () {
3342                  scrollStart = self.getEl('body')['scroll' + posName];
3343                  global$7('#' + axisId).addClass(prefix + 'active');
3344                },
3345                drag: function (e) {
3346                  var ratio, hasScrollH, hasScrollV, containerSize;
3347                  var layoutRect = self.layoutRect();
3348                  hasScrollH = layoutRect.contentW > layoutRect.innerW;
3349                  hasScrollV = layoutRect.contentH > layoutRect.innerH;
3350                  containerSize = self.getEl('body')['client' + sizeName] - margin * 2;
3351                  containerSize -= hasScrollH && hasScrollV ? self.getEl('scroll' + axisName)['client' + ax] : 0;
3352                  ratio = containerSize / self.getEl('body')['scroll' + sizeName];
3353                  self.getEl('body')['scroll' + posName] = scrollStart + e['delta' + deltaPosName] / ratio;
3354                },
3355                stop: function () {
3356                  global$7('#' + axisId).removeClass(prefix + 'active');
3357                }
3358              });
3359            }
3360            self.classes.add('scroll');
3361            addScrollAxis('v', 'Top', 'Height', 'Y', 'Width');
3362            addScrollAxis('h', 'Left', 'Width', 'X', 'Height');
3363          }
3364          if (self.settings.autoScroll) {
3365            if (!self._hasScroll) {
3366              self._hasScroll = true;
3367              addScroll();
3368              self.on('wheel', function (e) {
3369                var bodyEl = self.getEl('body');
3370                bodyEl.scrollLeft += (e.deltaX || 0) * 10;
3371                bodyEl.scrollTop += e.deltaY * 10;
3372                repaintScroll();
3373              });
3374              global$7(self.getEl('body')).on('scroll', repaintScroll);
3375            }
3376            repaintScroll();
3377          }
3378        }
3379      };
3380  
3381      var Panel = Container.extend({
3382        Defaults: {
3383          layout: 'fit',
3384          containerCls: 'panel'
3385        },
3386        Mixins: [Scrollable],
3387        renderHtml: function () {
3388          var self = this;
3389          var layout = self._layout;
3390          var innerHtml = self.settings.html;
3391          self.preRender();
3392          layout.preRender(self);
3393          if (typeof innerHtml === 'undefined') {
3394            innerHtml = '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + layout.renderHtml(self) + '</div>';
3395          } else {
3396            if (typeof innerHtml === 'function') {
3397              innerHtml = innerHtml.call(self);
3398            }
3399            self._hasBody = false;
3400          }
3401          return '<div id="' + self._id + '" class="' + self.classes + '" hidefocus="1" tabindex="-1" role="group">' + (self._preBodyHtml || '') + innerHtml + '</div>';
3402        }
3403      });
3404  
3405      var Resizable = {
3406        resizeToContent: function () {
3407          this._layoutRect.autoResize = true;
3408          this._lastRect = null;
3409          this.reflow();
3410        },
3411        resizeTo: function (w, h) {
3412          if (w <= 1 || h <= 1) {
3413            var rect = funcs.getWindowSize();
3414            w = w <= 1 ? w * rect.w : w;
3415            h = h <= 1 ? h * rect.h : h;
3416          }
3417          this._layoutRect.autoResize = false;
3418          return this.layoutRect({
3419            minW: w,
3420            minH: h,
3421            w: w,
3422            h: h
3423          }).reflow();
3424        },
3425        resizeBy: function (dw, dh) {
3426          var self = this, rect = self.layoutRect();
3427          return self.resizeTo(rect.w + dw, rect.h + dh);
3428        }
3429      };
3430  
3431      var documentClickHandler, documentScrollHandler, windowResizeHandler;
3432      var visiblePanels = [];
3433      var zOrder = [];
3434      var hasModal;
3435      function isChildOf(ctrl, parent) {
3436        while (ctrl) {
3437          if (ctrl === parent) {
3438            return true;
3439          }
3440          ctrl = ctrl.parent();
3441        }
3442      }
3443      function skipOrHidePanels(e) {
3444        var i = visiblePanels.length;
3445        while (i--) {
3446          var panel = visiblePanels[i], clickCtrl = panel.getParentCtrl(e.target);
3447          if (panel.settings.autohide) {
3448            if (clickCtrl) {
3449              if (isChildOf(clickCtrl, panel) || panel.parent() === clickCtrl) {
3450                continue;
3451              }
3452            }
3453            e = panel.fire('autohide', { target: e.target });
3454            if (!e.isDefaultPrevented()) {
3455              panel.hide();
3456            }
3457          }
3458        }
3459      }
3460      function bindDocumentClickHandler() {
3461        if (!documentClickHandler) {
3462          documentClickHandler = function (e) {
3463            if (e.button === 2) {
3464              return;
3465            }
3466            skipOrHidePanels(e);
3467          };
3468          global$7(domGlobals.document).on('click touchstart', documentClickHandler);
3469        }
3470      }
3471      function bindDocumentScrollHandler() {
3472        if (!documentScrollHandler) {
3473          documentScrollHandler = function () {
3474            var i;
3475            i = visiblePanels.length;
3476            while (i--) {
3477              repositionPanel$1(visiblePanels[i]);
3478            }
3479          };
3480          global$7(domGlobals.window).on('scroll', documentScrollHandler);
3481        }
3482      }
3483      function bindWindowResizeHandler() {
3484        if (!windowResizeHandler) {
3485          var docElm_1 = domGlobals.document.documentElement;
3486          var clientWidth_1 = docElm_1.clientWidth, clientHeight_1 = docElm_1.clientHeight;
3487          windowResizeHandler = function () {
3488            if (!domGlobals.document.all || clientWidth_1 !== docElm_1.clientWidth || clientHeight_1 !== docElm_1.clientHeight) {
3489              clientWidth_1 = docElm_1.clientWidth;
3490              clientHeight_1 = docElm_1.clientHeight;
3491              FloatPanel.hideAll();
3492            }
3493          };
3494          global$7(domGlobals.window).on('resize', windowResizeHandler);
3495        }
3496      }
3497      function repositionPanel$1(panel) {
3498        var scrollY = funcs.getViewPort().y;
3499        function toggleFixedChildPanels(fixed, deltaY) {
3500          var parent;
3501          for (var i = 0; i < visiblePanels.length; i++) {
3502            if (visiblePanels[i] !== panel) {
3503              parent = visiblePanels[i].parent();
3504              while (parent && (parent = parent.parent())) {
3505                if (parent === panel) {
3506                  visiblePanels[i].fixed(fixed).moveBy(0, deltaY).repaint();
3507                }
3508              }
3509            }
3510          }
3511        }
3512        if (panel.settings.autofix) {
3513          if (!panel.state.get('fixed')) {
3514            panel._autoFixY = panel.layoutRect().y;
3515            if (panel._autoFixY < scrollY) {
3516              panel.fixed(true).layoutRect({ y: 0 }).repaint();
3517              toggleFixedChildPanels(true, scrollY - panel._autoFixY);
3518            }
3519          } else {
3520            if (panel._autoFixY > scrollY) {
3521              panel.fixed(false).layoutRect({ y: panel._autoFixY }).repaint();
3522              toggleFixedChildPanels(false, panel._autoFixY - scrollY);
3523            }
3524          }
3525        }
3526      }
3527      function addRemove(add, ctrl) {
3528        var i, zIndex = FloatPanel.zIndex || 65535, topModal;
3529        if (add) {
3530          zOrder.push(ctrl);
3531        } else {
3532          i = zOrder.length;
3533          while (i--) {
3534            if (zOrder[i] === ctrl) {
3535              zOrder.splice(i, 1);
3536            }
3537          }
3538        }
3539        if (zOrder.length) {
3540          for (i = 0; i < zOrder.length; i++) {
3541            if (zOrder[i].modal) {
3542              zIndex++;
3543              topModal = zOrder[i];
3544            }
3545            zOrder[i].getEl().style.zIndex = zIndex;
3546            zOrder[i].zIndex = zIndex;
3547            zIndex++;
3548          }
3549        }
3550        var modalBlockEl = global$7('#' + ctrl.classPrefix + 'modal-block', ctrl.getContainerElm())[0];
3551        if (topModal) {
3552          global$7(modalBlockEl).css('z-index', topModal.zIndex - 1);
3553        } else if (modalBlockEl) {
3554          modalBlockEl.parentNode.removeChild(modalBlockEl);
3555          hasModal = false;
3556        }
3557        FloatPanel.currentZIndex = zIndex;
3558      }
3559      var FloatPanel = Panel.extend({
3560        Mixins: [
3561          Movable,
3562          Resizable
3563        ],
3564        init: function (settings) {
3565          var self = this;
3566          self._super(settings);
3567          self._eventsRoot = self;
3568          self.classes.add('floatpanel');
3569          if (settings.autohide) {
3570            bindDocumentClickHandler();
3571            bindWindowResizeHandler();
3572            visiblePanels.push(self);
3573          }
3574          if (settings.autofix) {
3575            bindDocumentScrollHandler();
3576            self.on('move', function () {
3577              repositionPanel$1(this);
3578            });
3579          }
3580          self.on('postrender show', function (e) {
3581            if (e.control === self) {
3582              var $modalBlockEl_1;
3583              var prefix_1 = self.classPrefix;
3584              if (self.modal && !hasModal) {
3585                $modalBlockEl_1 = global$7('#' + prefix_1 + 'modal-block', self.getContainerElm());
3586                if (!$modalBlockEl_1[0]) {
3587                  $modalBlockEl_1 = global$7('<div id="' + prefix_1 + 'modal-block" class="' + prefix_1 + 'reset ' + prefix_1 + 'fade"></div>').appendTo(self.getContainerElm());
3588                }
3589                global$3.setTimeout(function () {
3590                  $modalBlockEl_1.addClass(prefix_1 + 'in');
3591                  global$7(self.getEl()).addClass(prefix_1 + 'in');
3592                });
3593                hasModal = true;
3594              }
3595              addRemove(true, self);
3596            }
3597          });
3598          self.on('show', function () {
3599            self.parents().each(function (ctrl) {
3600              if (ctrl.state.get('fixed')) {
3601                self.fixed(true);
3602                return false;
3603              }
3604            });
3605          });
3606          if (settings.popover) {
3607            self._preBodyHtml = '<div class="' + self.classPrefix + 'arrow"></div>';
3608            self.classes.add('popover').add('bottom').add(self.isRtl() ? 'end' : 'start');
3609          }
3610          self.aria('label', settings.ariaLabel);
3611          self.aria('labelledby', self._id);
3612          self.aria('describedby', self.describedBy || self._id + '-none');
3613        },
3614        fixed: function (state) {
3615          var self = this;
3616          if (self.state.get('fixed') !== state) {
3617            if (self.state.get('rendered')) {
3618              var viewport = funcs.getViewPort();
3619              if (state) {
3620                self.layoutRect().y -= viewport.y;
3621              } else {
3622                self.layoutRect().y += viewport.y;
3623              }
3624            }
3625            self.classes.toggle('fixed', state);
3626            self.state.set('fixed', state);
3627          }
3628          return self;
3629        },
3630        show: function () {
3631          var self = this;
3632          var i;
3633          var state = self._super();
3634          i = visiblePanels.length;
3635          while (i--) {
3636            if (visiblePanels[i] === self) {
3637              break;
3638            }
3639          }
3640          if (i === -1) {
3641            visiblePanels.push(self);
3642          }
3643          return state;
3644        },
3645        hide: function () {
3646          removeVisiblePanel(this);
3647          addRemove(false, this);
3648          return this._super();
3649        },
3650        hideAll: function () {
3651          FloatPanel.hideAll();
3652        },
3653        close: function () {
3654          var self = this;
3655          if (!self.fire('close').isDefaultPrevented()) {
3656            self.remove();
3657            addRemove(false, self);
3658          }
3659          return self;
3660        },
3661        remove: function () {
3662          removeVisiblePanel(this);
3663          this._super();
3664        },
3665        postRender: function () {
3666          var self = this;
3667          if (self.settings.bodyRole) {
3668            this.getEl('body').setAttribute('role', self.settings.bodyRole);
3669          }
3670          return self._super();
3671        }
3672      });
3673      FloatPanel.hideAll = function () {
3674        var i = visiblePanels.length;
3675        while (i--) {
3676          var panel = visiblePanels[i];
3677          if (panel && panel.settings.autohide) {
3678            panel.hide();
3679            visiblePanels.splice(i, 1);
3680          }
3681        }
3682      };
3683      function removeVisiblePanel(panel) {
3684        var i;
3685        i = visiblePanels.length;
3686        while (i--) {
3687          if (visiblePanels[i] === panel) {
3688            visiblePanels.splice(i, 1);
3689          }
3690        }
3691        i = zOrder.length;
3692        while (i--) {
3693          if (zOrder[i] === panel) {
3694            zOrder.splice(i, 1);
3695          }
3696        }
3697      }
3698  
3699      var windows = [];
3700      var oldMetaValue = '';
3701      function toggleFullScreenState(state) {
3702        var noScaleMetaValue = 'width=device-width,initial-scale=1.0,user-scalable=0,minimum-scale=1.0,maximum-scale=1.0';
3703        var viewport = global$7('meta[name=viewport]')[0], contentValue;
3704        if (global$1.overrideViewPort === false) {
3705          return;
3706        }
3707        if (!viewport) {
3708          viewport = domGlobals.document.createElement('meta');
3709          viewport.setAttribute('name', 'viewport');
3710          domGlobals.document.getElementsByTagName('head')[0].appendChild(viewport);
3711        }
3712        contentValue = viewport.getAttribute('content');
3713        if (contentValue && typeof oldMetaValue !== 'undefined') {
3714          oldMetaValue = contentValue;
3715        }
3716        viewport.setAttribute('content', state ? noScaleMetaValue : oldMetaValue);
3717      }
3718      function toggleBodyFullScreenClasses(classPrefix, state) {
3719        if (checkFullscreenWindows() && state === false) {
3720          global$7([
3721            domGlobals.document.documentElement,
3722            domGlobals.document.body
3723          ]).removeClass(classPrefix + 'fullscreen');
3724        }
3725      }
3726      function checkFullscreenWindows() {
3727        for (var i = 0; i < windows.length; i++) {
3728          if (windows[i]._fullscreen) {
3729            return true;
3730          }
3731        }
3732        return false;
3733      }
3734      function handleWindowResize() {
3735        if (!global$1.desktop) {
3736          var lastSize_1 = {
3737            w: domGlobals.window.innerWidth,
3738            h: domGlobals.window.innerHeight
3739          };
3740          global$3.setInterval(function () {
3741            var w = domGlobals.window.innerWidth, h = domGlobals.window.innerHeight;
3742            if (lastSize_1.w !== w || lastSize_1.h !== h) {
3743              lastSize_1 = {
3744                w: w,
3745                h: h
3746              };
3747              global$7(domGlobals.window).trigger('resize');
3748            }
3749          }, 100);
3750        }
3751        function reposition() {
3752          var i;
3753          var rect = funcs.getWindowSize();
3754          var layoutRect;
3755          for (i = 0; i < windows.length; i++) {
3756            layoutRect = windows[i].layoutRect();
3757            windows[i].moveTo(windows[i].settings.x || Math.max(0, rect.w / 2 - layoutRect.w / 2), windows[i].settings.y || Math.max(0, rect.h / 2 - layoutRect.h / 2));
3758          }
3759        }
3760        global$7(domGlobals.window).on('resize', reposition);
3761      }
3762      var Window = FloatPanel.extend({
3763        modal: true,
3764        Defaults: {
3765          border: 1,
3766          layout: 'flex',
3767          containerCls: 'panel',
3768          role: 'dialog',
3769          callbacks: {
3770            submit: function () {
3771              this.fire('submit', { data: this.toJSON() });
3772            },
3773            close: function () {
3774              this.close();
3775            }
3776          }
3777        },
3778        init: function (settings) {
3779          var self = this;
3780          self._super(settings);
3781          if (self.isRtl()) {
3782            self.classes.add('rtl');
3783          }
3784          self.classes.add('window');
3785          self.bodyClasses.add('window-body');
3786          self.state.set('fixed', true);
3787          if (settings.buttons) {
3788            self.statusbar = new Panel({
3789              layout: 'flex',
3790              border: '1 0 0 0',
3791              spacing: 3,
3792              padding: 10,
3793              align: 'center',
3794              pack: self.isRtl() ? 'start' : 'end',
3795              defaults: { type: 'button' },
3796              items: settings.buttons
3797            });
3798            self.statusbar.classes.add('foot');
3799            self.statusbar.parent(self);
3800          }
3801          self.on('click', function (e) {
3802            var closeClass = self.classPrefix + 'close';
3803            if (funcs.hasClass(e.target, closeClass) || funcs.hasClass(e.target.parentNode, closeClass)) {
3804              self.close();
3805            }
3806          });
3807          self.on('cancel', function () {
3808            self.close();
3809          });
3810          self.on('move', function (e) {
3811            if (e.control === self) {
3812              FloatPanel.hideAll();
3813            }
3814          });
3815          self.aria('describedby', self.describedBy || self._id + '-none');
3816          self.aria('label', settings.title);
3817          self._fullscreen = false;
3818        },
3819        recalc: function () {
3820          var self = this;
3821          var statusbar = self.statusbar;
3822          var layoutRect, width, x, needsRecalc;
3823          if (self._fullscreen) {
3824            self.layoutRect(funcs.getWindowSize());
3825            self.layoutRect().contentH = self.layoutRect().innerH;
3826          }
3827          self._super();
3828          layoutRect = self.layoutRect();
3829          if (self.settings.title && !self._fullscreen) {
3830            width = layoutRect.headerW;
3831            if (width > layoutRect.w) {
3832              x = layoutRect.x - Math.max(0, width / 2);
3833              self.layoutRect({
3834                w: width,
3835                x: x
3836              });
3837              needsRecalc = true;
3838            }
3839          }
3840          if (statusbar) {
3841            statusbar.layoutRect({ w: self.layoutRect().innerW }).recalc();
3842            width = statusbar.layoutRect().minW + layoutRect.deltaW;
3843            if (width > layoutRect.w) {
3844              x = layoutRect.x - Math.max(0, width - layoutRect.w);
3845              self.layoutRect({
3846                w: width,
3847                x: x
3848              });
3849              needsRecalc = true;
3850            }
3851          }
3852          if (needsRecalc) {
3853            self.recalc();
3854          }
3855        },
3856        initLayoutRect: function () {
3857          var self = this;
3858          var layoutRect = self._super();
3859          var deltaH = 0, headEl;
3860          if (self.settings.title && !self._fullscreen) {
3861            headEl = self.getEl('head');
3862            var size = funcs.getSize(headEl);
3863            layoutRect.headerW = size.width;
3864            layoutRect.headerH = size.height;
3865            deltaH += layoutRect.headerH;
3866          }
3867          if (self.statusbar) {
3868            deltaH += self.statusbar.layoutRect().h;
3869          }
3870          layoutRect.deltaH += deltaH;
3871          layoutRect.minH += deltaH;
3872          layoutRect.h += deltaH;
3873          var rect = funcs.getWindowSize();
3874          layoutRect.x = self.settings.x || Math.max(0, rect.w / 2 - layoutRect.w / 2);
3875          layoutRect.y = self.settings.y || Math.max(0, rect.h / 2 - layoutRect.h / 2);
3876          return layoutRect;
3877        },
3878        renderHtml: function () {
3879          var self = this, layout = self._layout, id = self._id, prefix = self.classPrefix;
3880          var settings = self.settings;
3881          var headerHtml = '', footerHtml = '', html = settings.html;
3882          self.preRender();
3883          layout.preRender(self);
3884          if (settings.title) {
3885            headerHtml = '<div id="' + id + '-head" class="' + prefix + 'window-head">' + '<div id="' + id + '-title" class="' + prefix + 'title">' + self.encode(settings.title) + '</div>' + '<div id="' + id + '-dragh" class="' + prefix + 'dragh"></div>' + '<button type="button" class="' + prefix + 'close" aria-hidden="true">' + '<i class="mce-ico mce-i-remove"></i>' + '</button>' + '</div>';
3886          }
3887          if (settings.url) {
3888            html = '<iframe src="' + settings.url + '" tabindex="-1"></iframe>';
3889          }
3890          if (typeof html === 'undefined') {
3891            html = layout.renderHtml(self);
3892          }
3893          if (self.statusbar) {
3894            footerHtml = self.statusbar.renderHtml();
3895          }
3896          return '<div id="' + id + '" class="' + self.classes + '" hidefocus="1">' + '<div class="' + self.classPrefix + 'reset" role="application">' + headerHtml + '<div id="' + id + '-body" class="' + self.bodyClasses + '">' + html + '</div>' + footerHtml + '</div>' + '</div>';
3897        },
3898        fullscreen: function (state) {
3899          var self = this;
3900          var documentElement = domGlobals.document.documentElement;
3901          var slowRendering;
3902          var prefix = self.classPrefix;
3903          var layoutRect;
3904          if (state !== self._fullscreen) {
3905            global$7(domGlobals.window).on('resize', function () {
3906              var time;
3907              if (self._fullscreen) {
3908                if (!slowRendering) {
3909                  time = new Date().getTime();
3910                  var rect = funcs.getWindowSize();
3911                  self.moveTo(0, 0).resizeTo(rect.w, rect.h);
3912                  if (new Date().getTime() - time > 50) {
3913                    slowRendering = true;
3914                  }
3915                } else {
3916                  if (!self._timer) {
3917                    self._timer = global$3.setTimeout(function () {
3918                      var rect = funcs.getWindowSize();
3919                      self.moveTo(0, 0).resizeTo(rect.w, rect.h);
3920                      self._timer = 0;
3921                    }, 50);
3922                  }
3923                }
3924              }
3925            });
3926            layoutRect = self.layoutRect();
3927            self._fullscreen = state;
3928            if (!state) {
3929              self.borderBox = BoxUtils.parseBox(self.settings.border);
3930              self.getEl('head').style.display = '';
3931              layoutRect.deltaH += layoutRect.headerH;
3932              global$7([
3933                documentElement,
3934                domGlobals.document.body
3935              ]).removeClass(prefix + 'fullscreen');
3936              self.classes.remove('fullscreen');
3937              self.moveTo(self._initial.x, self._initial.y).resizeTo(self._initial.w, self._initial.h);
3938            } else {
3939              self._initial = {
3940                x: layoutRect.x,
3941                y: layoutRect.y,
3942                w: layoutRect.w,
3943                h: layoutRect.h
3944              };
3945              self.borderBox = BoxUtils.parseBox('0');
3946              self.getEl('head').style.display = 'none';
3947              layoutRect.deltaH -= layoutRect.headerH + 2;
3948              global$7([
3949                documentElement,
3950                domGlobals.document.body
3951              ]).addClass(prefix + 'fullscreen');
3952              self.classes.add('fullscreen');
3953              var rect = funcs.getWindowSize();
3954              self.moveTo(0, 0).resizeTo(rect.w, rect.h);
3955            }
3956          }
3957          return self.reflow();
3958        },
3959        postRender: function () {
3960          var self = this;
3961          var startPos;
3962          setTimeout(function () {
3963            self.classes.add('in');
3964            self.fire('open');
3965          }, 0);
3966          self._super();
3967          if (self.statusbar) {
3968            self.statusbar.postRender();
3969          }
3970          self.focus();
3971          this.dragHelper = new DragHelper(self._id + '-dragh', {
3972            start: function () {
3973              startPos = {
3974                x: self.layoutRect().x,
3975                y: self.layoutRect().y
3976              };
3977            },
3978            drag: function (e) {
3979              self.moveTo(startPos.x + e.deltaX, startPos.y + e.deltaY);
3980            }
3981          });
3982          self.on('submit', function (e) {
3983            if (!e.isDefaultPrevented()) {
3984              self.close();
3985            }
3986          });
3987          windows.push(self);
3988          toggleFullScreenState(true);
3989        },
3990        submit: function () {
3991          return this.fire('submit', { data: this.toJSON() });
3992        },
3993        remove: function () {
3994          var self = this;
3995          var i;
3996          self.dragHelper.destroy();
3997          self._super();
3998          if (self.statusbar) {
3999            this.statusbar.remove();
4000          }
4001          toggleBodyFullScreenClasses(self.classPrefix, false);
4002          i = windows.length;
4003          while (i--) {
4004            if (windows[i] === self) {
4005              windows.splice(i, 1);
4006            }
4007          }
4008          toggleFullScreenState(windows.length > 0);
4009        },
4010        getContentWindow: function () {
4011          var ifr = this.getEl().getElementsByTagName('iframe')[0];
4012          return ifr ? ifr.contentWindow : null;
4013        }
4014      });
4015      handleWindowResize();
4016  
4017      var MessageBox = Window.extend({
4018        init: function (settings) {
4019          settings = {
4020            border: 1,
4021            padding: 20,
4022            layout: 'flex',
4023            pack: 'center',
4024            align: 'center',
4025            containerCls: 'panel',
4026            autoScroll: true,
4027            buttons: {
4028              type: 'button',
4029              text: 'Ok',
4030              action: 'ok'
4031            },
4032            items: {
4033              type: 'label',
4034              multiline: true,
4035              maxWidth: 500,
4036              maxHeight: 200
4037            }
4038          };
4039          this._super(settings);
4040        },
4041        Statics: {
4042          OK: 1,
4043          OK_CANCEL: 2,
4044          YES_NO: 3,
4045          YES_NO_CANCEL: 4,
4046          msgBox: function (settings) {
4047            var buttons;
4048            var callback = settings.callback || function () {
4049            };
4050            function createButton(text, status, primary) {
4051              return {
4052                type: 'button',
4053                text: text,
4054                subtype: primary ? 'primary' : '',
4055                onClick: function (e) {
4056                  e.control.parents()[1].close();
4057                  callback(status);
4058                }
4059              };
4060            }
4061            switch (settings.buttons) {
4062            case MessageBox.OK_CANCEL:
4063              buttons = [
4064                createButton('Ok', true, true),
4065                createButton('Cancel', false)
4066              ];
4067              break;
4068            case MessageBox.YES_NO:
4069            case MessageBox.YES_NO_CANCEL:
4070              buttons = [
4071                createButton('Yes', 1, true),
4072                createButton('No', 0)
4073              ];
4074              if (settings.buttons === MessageBox.YES_NO_CANCEL) {
4075                buttons.push(createButton('Cancel', -1));
4076              }
4077              break;
4078            default:
4079              buttons = [createButton('Ok', true, true)];
4080              break;
4081            }
4082            return new Window({
4083              padding: 20,
4084              x: settings.x,
4085              y: settings.y,
4086              minWidth: 300,
4087              minHeight: 100,
4088              layout: 'flex',
4089              pack: 'center',
4090              align: 'center',
4091              buttons: buttons,
4092              title: settings.title,
4093              role: 'alertdialog',
4094              items: {
4095                type: 'label',
4096                multiline: true,
4097                maxWidth: 500,
4098                maxHeight: 200,
4099                text: settings.text
4100              },
4101              onPostRender: function () {
4102                this.aria('describedby', this.items()[0]._id);
4103              },
4104              onClose: settings.onClose,
4105              onCancel: function () {
4106                callback(false);
4107              }
4108            }).renderTo(domGlobals.document.body).reflow();
4109          },
4110          alert: function (settings, callback) {
4111            if (typeof settings === 'string') {
4112              settings = { text: settings };
4113            }
4114            settings.callback = callback;
4115            return MessageBox.msgBox(settings);
4116          },
4117          confirm: function (settings, callback) {
4118            if (typeof settings === 'string') {
4119              settings = { text: settings };
4120            }
4121            settings.callback = callback;
4122            settings.buttons = MessageBox.OK_CANCEL;
4123            return MessageBox.msgBox(settings);
4124          }
4125        }
4126      });
4127  
4128      function WindowManagerImpl (editor) {
4129        var open = function (args, params, closeCallback) {
4130          var win;
4131          args.title = args.title || ' ';
4132          args.url = args.url || args.file;
4133          if (args.url) {
4134            args.width = parseInt(args.width || 320, 10);
4135            args.height = parseInt(args.height || 240, 10);
4136          }
4137          if (args.body) {
4138            args.items = {
4139              defaults: args.defaults,
4140              type: args.bodyType || 'form',
4141              items: args.body,
4142              data: args.data,
4143              callbacks: args.commands
4144            };
4145          }
4146          if (!args.url && !args.buttons) {
4147            args.buttons = [
4148              {
4149                text: 'Ok',
4150                subtype: 'primary',
4151                onclick: function () {
4152                  win.find('form')[0].submit();
4153                }
4154              },
4155              {
4156                text: 'Cancel',
4157                onclick: function () {
4158                  win.close();
4159                }
4160              }
4161            ];
4162          }
4163          win = new Window(args);
4164          win.on('close', function () {
4165            closeCallback(win);
4166          });
4167          if (args.data) {
4168            win.on('postRender', function () {
4169              this.find('*').each(function (ctrl) {
4170                var name = ctrl.name();
4171                if (name in args.data) {
4172                  ctrl.value(args.data[name]);
4173                }
4174              });
4175            });
4176          }
4177          win.features = args || {};
4178          win.params = params || {};
4179          win = win.renderTo(domGlobals.document.body).reflow();
4180          return win;
4181        };
4182        var alert = function (message, choiceCallback, closeCallback) {
4183          var win;
4184          win = MessageBox.alert(message, function () {
4185            choiceCallback();
4186          });
4187          win.on('close', function () {
4188            closeCallback(win);
4189          });
4190          return win;
4191        };
4192        var confirm = function (message, choiceCallback, closeCallback) {
4193          var win;
4194          win = MessageBox.confirm(message, function (state) {
4195            choiceCallback(state);
4196          });
4197          win.on('close', function () {
4198            closeCallback(win);
4199          });
4200          return win;
4201        };
4202        var close = function (window) {
4203          window.close();
4204        };
4205        var getParams = function (window) {
4206          return window.params;
4207        };
4208        var setParams = function (window, params) {
4209          window.params = params;
4210        };
4211        return {
4212          open: open,
4213          alert: alert,
4214          confirm: confirm,
4215          close: close,
4216          getParams: getParams,
4217          setParams: setParams
4218        };
4219      }
4220  
4221      var get = function (editor, panel) {
4222        var renderUI = function () {
4223          return Render.renderUI(editor, panel);
4224        };
4225        return {
4226          renderUI: renderUI,
4227          getNotificationManagerImpl: function () {
4228            return NotificationManagerImpl(editor);
4229          },
4230          getWindowManagerImpl: function () {
4231            return WindowManagerImpl(editor);
4232          }
4233        };
4234      };
4235      var ThemeApi = { get: get };
4236  
4237      var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')();
4238  
4239      var path = function (parts, scope) {
4240        var o = scope !== undefined && scope !== null ? scope : Global;
4241        for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i)
4242          o = o[parts[i]];
4243        return o;
4244      };
4245      var resolve = function (p, scope) {
4246        var parts = p.split('.');
4247        return path(parts, scope);
4248      };
4249  
4250      var unsafe = function (name, scope) {
4251        return resolve(name, scope);
4252      };
4253      var getOrDie = function (name, scope) {
4254        var actual = unsafe(name, scope);
4255        if (actual === undefined || actual === null)
4256          throw name + ' not available on this browser';
4257        return actual;
4258      };
4259      var Global$1 = { getOrDie: getOrDie };
4260  
4261      function FileReader () {
4262        var f = Global$1.getOrDie('FileReader');
4263        return new f();
4264      }
4265  
4266      var global$c = tinymce.util.Tools.resolve('tinymce.util.Promise');
4267  
4268      var blobToBase64 = function (blob) {
4269        return new global$c(function (resolve) {
4270          var reader = FileReader();
4271          reader.onloadend = function () {
4272            resolve(reader.result.split(',')[1]);
4273          };
4274          reader.readAsDataURL(blob);
4275        });
4276      };
4277      var Conversions = { blobToBase64: blobToBase64 };
4278  
4279      var pickFile = function () {
4280        return new global$c(function (resolve) {
4281          var fileInput;
4282          fileInput = domGlobals.document.createElement('input');
4283          fileInput.type = 'file';
4284          fileInput.style.position = 'fixed';
4285          fileInput.style.left = 0;
4286          fileInput.style.top = 0;
4287          fileInput.style.opacity = 0.001;
4288          domGlobals.document.body.appendChild(fileInput);
4289          fileInput.onchange = function (e) {
4290            resolve(Array.prototype.slice.call(e.target.files));
4291          };
4292          fileInput.click();
4293          fileInput.parentNode.removeChild(fileInput);
4294        });
4295      };
4296      var Picker = { pickFile: pickFile };
4297  
4298      var count$1 = 0;
4299      var seed = function () {
4300        var rnd = function () {
4301          return Math.round(Math.random() * 4294967295).toString(36);
4302        };
4303        return 's' + Date.now().toString(36) + rnd() + rnd() + rnd();
4304      };
4305      var uuid = function (prefix) {
4306        return prefix + count$1++ + seed();
4307      };
4308      var Uuid = { uuid: uuid };
4309  
4310      var create$1 = function (dom, rng) {
4311        var bookmark = {};
4312        function setupEndPoint(start) {
4313          var offsetNode, container, offset;
4314          container = rng[start ? 'startContainer' : 'endContainer'];
4315          offset = rng[start ? 'startOffset' : 'endOffset'];
4316          if (container.nodeType === 1) {
4317            offsetNode = dom.create('span', { 'data-mce-type': 'bookmark' });
4318            if (container.hasChildNodes()) {
4319              offset = Math.min(offset, container.childNodes.length - 1);
4320              if (start) {
4321                container.insertBefore(offsetNode, container.childNodes[offset]);
4322              } else {
4323                dom.insertAfter(offsetNode, container.childNodes[offset]);
4324              }
4325            } else {
4326              container.appendChild(offsetNode);
4327            }
4328            container = offsetNode;
4329            offset = 0;
4330          }
4331          bookmark[start ? 'startContainer' : 'endContainer'] = container;
4332          bookmark[start ? 'startOffset' : 'endOffset'] = offset;
4333        }
4334        setupEndPoint(true);
4335        if (!rng.collapsed) {
4336          setupEndPoint();
4337        }
4338        return bookmark;
4339      };
4340      var resolve$1 = function (dom, bookmark) {
4341        function restoreEndPoint(start) {
4342          var container, offset, node;
4343          function nodeIndex(container) {
4344            var node = container.parentNode.firstChild, idx = 0;
4345            while (node) {
4346              if (node === container) {
4347                return idx;
4348              }
4349              if (node.nodeType !== 1 || node.getAttribute('data-mce-type') !== 'bookmark') {
4350                idx++;
4351              }
4352              node = node.nextSibling;
4353            }
4354            return -1;
4355          }
4356          container = node = bookmark[start ? 'startContainer' : 'endContainer'];
4357          offset = bookmark[start ? 'startOffset' : 'endOffset'];
4358          if (!container) {
4359            return;
4360          }
4361          if (container.nodeType === 1) {
4362            offset = nodeIndex(container);
4363            container = container.parentNode;
4364            dom.remove(node);
4365          }
4366          bookmark[start ? 'startContainer' : 'endContainer'] = container;
4367          bookmark[start ? 'startOffset' : 'endOffset'] = offset;
4368        }
4369        restoreEndPoint(true);
4370        restoreEndPoint();
4371        var rng = dom.createRng();
4372        rng.setStart(bookmark.startContainer, bookmark.startOffset);
4373        if (bookmark.endContainer) {
4374          rng.setEnd(bookmark.endContainer, bookmark.endOffset);
4375        }
4376        return rng;
4377      };
4378      var Bookmark = {
4379        create: create$1,
4380        resolve: resolve$1
4381      };
4382  
4383      var global$d = tinymce.util.Tools.resolve('tinymce.dom.TreeWalker');
4384  
4385      var global$e = tinymce.util.Tools.resolve('tinymce.dom.RangeUtils');
4386  
4387      var getSelectedElements = function (rootElm, startNode, endNode) {
4388        var walker, node;
4389        var elms = [];
4390        walker = new global$d(startNode, rootElm);
4391        for (node = startNode; node; node = walker.next()) {
4392          if (node.nodeType === 1) {
4393            elms.push(node);
4394          }
4395          if (node === endNode) {
4396            break;
4397          }
4398        }
4399        return elms;
4400      };
4401      var unwrapElements = function (editor, elms) {
4402        var bookmark, dom, selection;
4403        dom = editor.dom;
4404        selection = editor.selection;
4405        bookmark = Bookmark.create(dom, selection.getRng());
4406        global$4.each(elms, function (elm) {
4407          editor.dom.remove(elm, true);
4408        });
4409        selection.setRng(Bookmark.resolve(dom, bookmark));
4410      };
4411      var isLink = function (elm) {
4412        return elm.nodeName === 'A' && elm.hasAttribute('href');
4413      };
4414      var getParentAnchorOrSelf = function (dom, elm) {
4415        var anchorElm = dom.getParent(elm, isLink);
4416        return anchorElm ? anchorElm : elm;
4417      };
4418      var getSelectedAnchors = function (editor) {
4419        var startElm, endElm, rootElm, anchorElms, selection, dom, rng;
4420        selection = editor.selection;
4421        dom = editor.dom;
4422        rng = selection.getRng();
4423        startElm = getParentAnchorOrSelf(dom, global$e.getNode(rng.startContainer, rng.startOffset));
4424        endElm = global$e.getNode(rng.endContainer, rng.endOffset);
4425        rootElm = editor.getBody();
4426        anchorElms = global$4.grep(getSelectedElements(rootElm, startElm, endElm), isLink);
4427        return anchorElms;
4428      };
4429      var unlinkSelection = function (editor) {
4430        unwrapElements(editor, getSelectedAnchors(editor));
4431      };
4432      var Unlink = { unlinkSelection: unlinkSelection };
4433  
4434      var createTableHtml = function (cols, rows) {
4435        var x, y, html;
4436        html = '<table data-mce-id="mce" style="width: 100%">';
4437        html += '<tbody>';
4438        for (y = 0; y < rows; y++) {
4439          html += '<tr>';
4440          for (x = 0; x < cols; x++) {
4441            html += '<td><br></td>';
4442          }
4443          html += '</tr>';
4444        }
4445        html += '</tbody>';
4446        html += '</table>';
4447        return html;
4448      };
4449      var getInsertedElement = function (editor) {
4450        var elms = editor.dom.select('*[data-mce-id]');
4451        return elms[0];
4452      };
4453      var insertTableHtml = function (editor, cols, rows) {
4454        editor.undoManager.transact(function () {
4455          var tableElm, cellElm;
4456          editor.insertContent(createTableHtml(cols, rows));
4457          tableElm = getInsertedElement(editor);
4458          tableElm.removeAttribute('data-mce-id');
4459          cellElm = editor.dom.select('td,th', tableElm);
4460          editor.selection.setCursorLocation(cellElm[0], 0);
4461        });
4462      };
4463      var insertTable = function (editor, cols, rows) {
4464        editor.plugins.table ? editor.plugins.table.insertTable(cols, rows) : insertTableHtml(editor, cols, rows);
4465      };
4466      var formatBlock = function (editor, formatName) {
4467        editor.execCommand('FormatBlock', false, formatName);
4468      };
4469      var insertBlob = function (editor, base64, blob) {
4470        var blobCache, blobInfo;
4471        blobCache = editor.editorUpload.blobCache;
4472        blobInfo = blobCache.create(Uuid.uuid('mceu'), blob, base64);
4473        blobCache.add(blobInfo);
4474        editor.insertContent(editor.dom.createHTML('img', { src: blobInfo.blobUri() }));
4475      };
4476      var collapseSelectionToEnd = function (editor) {
4477        editor.selection.collapse(false);
4478      };
4479      var unlink = function (editor) {
4480        editor.focus();
4481        Unlink.unlinkSelection(editor);
4482        collapseSelectionToEnd(editor);
4483      };
4484      var changeHref = function (editor, elm, url) {
4485        editor.focus();
4486        editor.dom.setAttrib(elm, 'href', url);
4487        collapseSelectionToEnd(editor);
4488      };
4489      var insertLink = function (editor, url) {
4490        editor.execCommand('mceInsertLink', false, { href: url });
4491        collapseSelectionToEnd(editor);
4492      };
4493      var updateOrInsertLink = function (editor, url) {
4494        var elm = editor.dom.getParent(editor.selection.getStart(), 'a[href]');
4495        elm ? changeHref(editor, elm, url) : insertLink(editor, url);
4496      };
4497      var createLink = function (editor, url) {
4498        url.trim().length === 0 ? unlink(editor) : updateOrInsertLink(editor, url);
4499      };
4500      var Actions = {
4501        insertTable: insertTable,
4502        formatBlock: formatBlock,
4503        insertBlob: insertBlob,
4504        createLink: createLink,
4505        unlink: unlink
4506      };
4507  
4508      var addHeaderButtons = function (editor) {
4509        var formatBlock = function (name) {
4510          return function () {
4511            Actions.formatBlock(editor, name);
4512          };
4513        };
4514        for (var i = 1; i < 6; i++) {
4515          var name = 'h' + i;
4516          editor.addButton(name, {
4517            text: name.toUpperCase(),
4518            tooltip: 'Heading ' + i,
4519            stateSelector: name,
4520            onclick: formatBlock(name),
4521            onPostRender: function () {
4522              var span = this.getEl().firstChild.firstChild;
4523              span.style.fontWeight = 'bold';
4524            }
4525          });
4526        }
4527      };
4528      var addToEditor = function (editor, panel) {
4529        editor.addButton('quicklink', {
4530          icon: 'link',
4531          tooltip: 'Insert/Edit link',
4532          stateSelector: 'a[href]',
4533          onclick: function () {
4534            panel.showForm(editor, 'quicklink');
4535          }
4536        });
4537        editor.addButton('quickimage', {
4538          icon: 'image',
4539          tooltip: 'Insert image',
4540          onclick: function () {
4541            Picker.pickFile().then(function (files) {
4542              var blob = files[0];
4543              Conversions.blobToBase64(blob).then(function (base64) {
4544                Actions.insertBlob(editor, base64, blob);
4545              });
4546            });
4547          }
4548        });
4549        editor.addButton('quicktable', {
4550          icon: 'table',
4551          tooltip: 'Insert table',
4552          onclick: function () {
4553            panel.hide();
4554            Actions.insertTable(editor, 2, 2);
4555          }
4556        });
4557        addHeaderButtons(editor);
4558      };
4559      var Buttons = { addToEditor: addToEditor };
4560  
4561      var getUiContainerDelta$1 = function () {
4562        var uiContainer = global$1.container;
4563        if (uiContainer && global$2.DOM.getStyle(uiContainer, 'position', true) !== 'static') {
4564          var containerPos = global$2.DOM.getPos(uiContainer);
4565          var dx = containerPos.x - uiContainer.scrollLeft;
4566          var dy = containerPos.y - uiContainer.scrollTop;
4567          return Option.some({
4568            x: dx,
4569            y: dy
4570          });
4571        } else {
4572          return Option.none();
4573        }
4574      };
4575      var UiContainer$1 = { getUiContainerDelta: getUiContainerDelta$1 };
4576  
4577      var isDomainLike = function (href) {
4578        return /^www\.|\.(com|org|edu|gov|uk|net|ca|de|jp|fr|au|us|ru|ch|it|nl|se|no|es|mil)$/i.test(href.trim());
4579      };
4580      var isAbsolute = function (href) {
4581        return /^https?:\/\//.test(href.trim());
4582      };
4583      var UrlType = {
4584        isDomainLike: isDomainLike,
4585        isAbsolute: isAbsolute
4586      };
4587  
4588      var focusFirstTextBox = function (form) {
4589        form.find('textbox').eq(0).each(function (ctrl) {
4590          ctrl.focus();
4591        });
4592      };
4593      var createForm = function (name, spec) {
4594        var form = global$b.create(global$4.extend({
4595          type: 'form',
4596          layout: 'flex',
4597          direction: 'row',
4598          padding: 5,
4599          name: name,
4600          spacing: 3
4601        }, spec));
4602        form.on('show', function () {
4603          focusFirstTextBox(form);
4604        });
4605        return form;
4606      };
4607      var toggleVisibility = function (ctrl, state) {
4608        return state ? ctrl.show() : ctrl.hide();
4609      };
4610      var askAboutPrefix = function (editor, href) {
4611        return new global$c(function (resolve) {
4612          editor.windowManager.confirm('The URL you entered seems to be an external link. Do you want to add the required http:// prefix?', function (result) {
4613            var output = result === true ? 'http://' + href : href;
4614            resolve(output);
4615          });
4616        });
4617      };
4618      var convertLinkToAbsolute = function (editor, href) {
4619        return !UrlType.isAbsolute(href) && UrlType.isDomainLike(href) ? askAboutPrefix(editor, href) : global$c.resolve(href);
4620      };
4621      var createQuickLinkForm = function (editor, hide) {
4622        var attachState = {};
4623        var unlink = function () {
4624          editor.focus();
4625          Actions.unlink(editor);
4626          hide();
4627        };
4628        var onChangeHandler = function (e) {
4629          var meta = e.meta;
4630          if (meta && meta.attach) {
4631            attachState = {
4632              href: this.value(),
4633              attach: meta.attach
4634            };
4635          }
4636        };
4637        var onShowHandler = function (e) {
4638          if (e.control === this) {
4639            var elm = void 0, linkurl = '';
4640            elm = editor.dom.getParent(editor.selection.getStart(), 'a[href]');
4641            if (elm) {
4642              linkurl = editor.dom.getAttrib(elm, 'href');
4643            }
4644            this.fromJSON({ linkurl: linkurl });
4645            toggleVisibility(this.find('#unlink'), elm);
4646            this.find('#linkurl')[0].focus();
4647          }
4648        };
4649        return createForm('quicklink', {
4650          items: [
4651            {
4652              type: 'button',
4653              name: 'unlink',
4654              icon: 'unlink',
4655              onclick: unlink,
4656              tooltip: 'Remove link'
4657            },
4658            {
4659              type: 'filepicker',
4660              name: 'linkurl',
4661              placeholder: 'Paste or type a link',
4662              filetype: 'file',
4663              onchange: onChangeHandler
4664            },
4665            {
4666              type: 'button',
4667              icon: 'checkmark',
4668              subtype: 'primary',
4669              tooltip: 'Ok',
4670              onclick: 'submit'
4671            }
4672          ],
4673          onshow: onShowHandler,
4674          onsubmit: function (e) {
4675            convertLinkToAbsolute(editor, e.data.linkurl).then(function (url) {
4676              editor.undoManager.transact(function () {
4677                if (url === attachState.href) {
4678                  attachState.attach();
4679                  attachState = {};
4680                }
4681                Actions.createLink(editor, url);
4682              });
4683              hide();
4684            });
4685          }
4686        });
4687      };
4688      var Forms = { createQuickLinkForm: createQuickLinkForm };
4689  
4690      var getSelectorStateResult = function (itemName, item) {
4691        var result = function (selector, handler) {
4692          return {
4693            selector: selector,
4694            handler: handler
4695          };
4696        };
4697        var activeHandler = function (state) {
4698          item.active(state);
4699        };
4700        var disabledHandler = function (state) {
4701          item.disabled(state);
4702        };
4703        if (item.settings.stateSelector) {
4704          return result(item.settings.stateSelector, activeHandler);
4705        }
4706        if (item.settings.disabledStateSelector) {
4707          return result(item.settings.disabledStateSelector, disabledHandler);
4708        }
4709        return null;
4710      };
4711      var bindSelectorChanged = function (editor, itemName, item) {
4712        return function () {
4713          var result = getSelectorStateResult(itemName, item);
4714          if (result !== null) {
4715            editor.selection.selectorChanged(result.selector, result.handler);
4716          }
4717        };
4718      };
4719      var itemsToArray$1 = function (items) {
4720        if (Type.isArray(items)) {
4721          return items;
4722        } else if (Type.isString(items)) {
4723          return items.split(/[ ,]/);
4724        }
4725        return [];
4726      };
4727      var create$2 = function (editor, name, items) {
4728        var toolbarItems = [];
4729        var buttonGroup;
4730        if (!items) {
4731          return;
4732        }
4733        global$4.each(itemsToArray$1(items), function (item) {
4734          if (item === '|') {
4735            buttonGroup = null;
4736          } else {
4737            if (editor.buttons[item]) {
4738              if (!buttonGroup) {
4739                buttonGroup = {
4740                  type: 'buttongroup',
4741                  items: []
4742                };
4743                toolbarItems.push(buttonGroup);
4744              }
4745              var button = editor.buttons[item];
4746              if (Type.isFunction(button)) {
4747                button = button();
4748              }
4749              button.type = button.type || 'button';
4750              button = global$b.create(button);
4751              button.on('postRender', bindSelectorChanged(editor, item, button));
4752              buttonGroup.items.push(button);
4753            }
4754          }
4755        });
4756        return global$b.create({
4757          type: 'toolbar',
4758          layout: 'flow',
4759          name: name,
4760          items: toolbarItems
4761        });
4762      };
4763      var Toolbar = { create: create$2 };
4764  
4765      var create$3 = function () {
4766        var panel, currentRect;
4767        var createToolbars = function (editor, toolbars) {
4768          return global$4.map(toolbars, function (toolbar) {
4769            return Toolbar.create(editor, toolbar.id, toolbar.items);
4770          });
4771        };
4772        var hasToolbarItems = function (toolbar) {
4773          return toolbar.items().length > 0;
4774        };
4775        var create = function (editor, toolbars) {
4776          var items = createToolbars(editor, toolbars).concat([
4777            Toolbar.create(editor, 'text', Settings.getTextSelectionToolbarItems(editor)),
4778            Toolbar.create(editor, 'insert', Settings.getInsertToolbarItems(editor)),
4779            Forms.createQuickLinkForm(editor, hide)
4780          ]);
4781          return global$b.create({
4782            type: 'floatpanel',
4783            role: 'dialog',
4784            classes: 'tinymce tinymce-inline arrow',
4785            ariaLabel: 'Inline toolbar',
4786            layout: 'flex',
4787            direction: 'column',
4788            align: 'stretch',
4789            autohide: false,
4790            autofix: true,
4791            fixed: true,
4792            border: 1,
4793            items: global$4.grep(items, hasToolbarItems),
4794            oncancel: function () {
4795              editor.focus();
4796            }
4797          });
4798        };
4799        var showPanel = function (panel) {
4800          if (panel) {
4801            panel.show();
4802          }
4803        };
4804        var movePanelTo = function (panel, pos) {
4805          panel.moveTo(pos.x, pos.y);
4806        };
4807        var togglePositionClass = function (panel, relPos) {
4808          relPos = relPos ? relPos.substr(0, 2) : '';
4809          global$4.each({
4810            t: 'down',
4811            b: 'up',
4812            c: 'center'
4813          }, function (cls, pos) {
4814            panel.classes.toggle('arrow-' + cls, pos === relPos.substr(0, 1));
4815          });
4816          if (relPos === 'cr') {
4817            panel.classes.toggle('arrow-left', true);
4818            panel.classes.toggle('arrow-right', false);
4819          } else if (relPos === 'cl') {
4820            panel.classes.toggle('arrow-left', false);
4821            panel.classes.toggle('arrow-right', true);
4822          } else {
4823            global$4.each({
4824              l: 'left',
4825              r: 'right'
4826            }, function (cls, pos) {
4827              panel.classes.toggle('arrow-' + cls, pos === relPos.substr(1, 1));
4828            });
4829          }
4830        };
4831        var showToolbar = function (panel, id) {
4832          var toolbars = panel.items().filter('#' + id);
4833          if (toolbars.length > 0) {
4834            toolbars[0].show();
4835            panel.reflow();
4836            return true;
4837          }
4838          return false;
4839        };
4840        var repositionPanelAt = function (panel, id, editor, targetRect) {
4841          var contentAreaRect, panelRect, result, userConstainHandler;
4842          userConstainHandler = Settings.getPositionHandler(editor);
4843          contentAreaRect = Measure.getContentAreaRect(editor);
4844          panelRect = global$2.DOM.getRect(panel.getEl());
4845          if (id === 'insert') {
4846            result = Layout.calcInsert(targetRect, contentAreaRect, panelRect);
4847          } else {
4848            result = Layout.calc(targetRect, contentAreaRect, panelRect);
4849          }
4850          if (result) {
4851            var delta = UiContainer$1.getUiContainerDelta().getOr({
4852              x: 0,
4853              y: 0
4854            });
4855            var transposedPanelRect = {
4856              x: result.rect.x - delta.x,
4857              y: result.rect.y - delta.y,
4858              w: result.rect.w,
4859              h: result.rect.h
4860            };
4861            currentRect = targetRect;
4862            movePanelTo(panel, Layout.userConstrain(userConstainHandler, targetRect, contentAreaRect, transposedPanelRect));
4863            togglePositionClass(panel, result.position);
4864            return true;
4865          } else {
4866            return false;
4867          }
4868        };
4869        var showPanelAt = function (panel, id, editor, targetRect) {
4870          showPanel(panel);
4871          panel.items().hide();
4872          if (!showToolbar(panel, id)) {
4873            hide();
4874            return;
4875          }
4876          if (repositionPanelAt(panel, id, editor, targetRect) === false) {
4877            hide();
4878          }
4879        };
4880        var hasFormVisible = function () {
4881          return panel.items().filter('form:visible').length > 0;
4882        };
4883        var showForm = function (editor, id) {
4884          if (panel) {
4885            panel.items().hide();
4886            if (!showToolbar(panel, id)) {
4887              hide();
4888              return;
4889            }
4890            var contentAreaRect = void 0, panelRect = void 0, result = void 0, userConstainHandler = void 0;
4891            showPanel(panel);
4892            panel.items().hide();
4893            showToolbar(panel, id);
4894            userConstainHandler = Settings.getPositionHandler(editor);
4895            contentAreaRect = Measure.getContentAreaRect(editor);
4896            panelRect = global$2.DOM.getRect(panel.getEl());
4897            result = Layout.calc(currentRect, contentAreaRect, panelRect);
4898            if (result) {
4899              panelRect = result.rect;
4900              movePanelTo(panel, Layout.userConstrain(userConstainHandler, currentRect, contentAreaRect, panelRect));
4901              togglePositionClass(panel, result.position);
4902            }
4903          }
4904        };
4905        var show = function (editor, id, targetRect, toolbars) {
4906          if (!panel) {
4907            Events.fireBeforeRenderUI(editor);
4908            panel = create(editor, toolbars);
4909            panel.renderTo().reflow().moveTo(targetRect.x, targetRect.y);
4910            editor.nodeChanged();
4911          }
4912          showPanelAt(panel, id, editor, targetRect);
4913        };
4914        var reposition = function (editor, id, targetRect) {
4915          if (panel) {
4916            repositionPanelAt(panel, id, editor, targetRect);
4917          }
4918        };
4919        var hide = function () {
4920          if (panel) {
4921            panel.hide();
4922          }
4923        };
4924        var focus = function () {
4925          if (panel) {
4926            panel.find('toolbar:visible').eq(0).each(function (item) {
4927              item.focus(true);
4928            });
4929          }
4930        };
4931        var remove = function () {
4932          if (panel) {
4933            panel.remove();
4934            panel = null;
4935          }
4936        };
4937        var inForm = function () {
4938          return panel && panel.visible() && hasFormVisible();
4939        };
4940        return {
4941          show: show,
4942          showForm: showForm,
4943          reposition: reposition,
4944          inForm: inForm,
4945          hide: hide,
4946          focus: focus,
4947          remove: remove
4948        };
4949      };
4950  
4951      var Layout$1 = global$8.extend({
4952        Defaults: {
4953          firstControlClass: 'first',
4954          lastControlClass: 'last'
4955        },
4956        init: function (settings) {
4957          this.settings = global$4.extend({}, this.Defaults, settings);
4958        },
4959        preRender: function (container) {
4960          container.bodyClasses.add(this.settings.containerClass);
4961        },
4962        applyClasses: function (items) {
4963          var self = this;
4964          var settings = self.settings;
4965          var firstClass, lastClass, firstItem, lastItem;
4966          firstClass = settings.firstControlClass;
4967          lastClass = settings.lastControlClass;
4968          items.each(function (item) {
4969            item.classes.remove(firstClass).remove(lastClass).add(settings.controlClass);
4970            if (item.visible()) {
4971              if (!firstItem) {
4972                firstItem = item;
4973              }
4974              lastItem = item;
4975            }
4976          });
4977          if (firstItem) {
4978            firstItem.classes.add(firstClass);
4979          }
4980          if (lastItem) {
4981            lastItem.classes.add(lastClass);
4982          }
4983        },
4984        renderHtml: function (container) {
4985          var self = this;
4986          var html = '';
4987          self.applyClasses(container.items());
4988          container.items().each(function (item) {
4989            html += item.renderHtml();
4990          });
4991          return html;
4992        },
4993        recalc: function () {
4994        },
4995        postRender: function () {
4996        },
4997        isNative: function () {
4998          return false;
4999        }
5000      });
5001  
5002      var AbsoluteLayout = Layout$1.extend({
5003        Defaults: {
5004          containerClass: 'abs-layout',
5005          controlClass: 'abs-layout-item'
5006        },
5007        recalc: function (container) {
5008          container.items().filter(':visible').each(function (ctrl) {
5009            var settings = ctrl.settings;
5010            ctrl.layoutRect({
5011              x: settings.x,
5012              y: settings.y,
5013              w: settings.w,
5014              h: settings.h
5015            });
5016            if (ctrl.recalc) {
5017              ctrl.recalc();
5018            }
5019          });
5020        },
5021        renderHtml: function (container) {
5022          return '<div id="' + container._id + '-absend" class="' + container.classPrefix + 'abs-end"></div>' + this._super(container);
5023        }
5024      });
5025  
5026      var Button = Widget.extend({
5027        Defaults: {
5028          classes: 'widget btn',
5029          role: 'button'
5030        },
5031        init: function (settings) {
5032          var self = this;
5033          var size;
5034          self._super(settings);
5035          settings = self.settings;
5036          size = self.settings.size;
5037          self.on('click mousedown', function (e) {
5038            e.preventDefault();
5039          });
5040          self.on('touchstart', function (e) {
5041            self.fire('click', e);
5042            e.preventDefault();
5043          });
5044          if (settings.subtype) {
5045            self.classes.add(settings.subtype);
5046          }
5047          if (size) {
5048            self.classes.add('btn-' + size);
5049          }
5050          if (settings.icon) {
5051            self.icon(settings.icon);
5052          }
5053        },
5054        icon: function (icon) {
5055          if (!arguments.length) {
5056            return this.state.get('icon');
5057          }
5058          this.state.set('icon', icon);
5059          return this;
5060        },
5061        repaint: function () {
5062          var btnElm = this.getEl().firstChild;
5063          var btnStyle;
5064          if (btnElm) {
5065            btnStyle = btnElm.style;
5066            btnStyle.width = btnStyle.height = '100%';
5067          }
5068          this._super();
5069        },
5070        renderHtml: function () {
5071          var self = this, id = self._id, prefix = self.classPrefix;
5072          var icon = self.state.get('icon'), image;
5073          var text = self.state.get('text');
5074          var textHtml = '';
5075          var ariaPressed;
5076          var settings = self.settings;
5077          image = settings.image;
5078          if (image) {
5079            icon = 'none';
5080            if (typeof image !== 'string') {
5081              image = domGlobals.window.getSelection ? image[0] : image[1];
5082            }
5083            image = ' style="background-image: url(\'' + image + '\')"';
5084          } else {
5085            image = '';
5086          }
5087          if (text) {
5088            self.classes.add('btn-has-text');
5089            textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>';
5090          }
5091          icon = icon ? prefix + 'ico ' + prefix + 'i-' + icon : '';
5092          ariaPressed = typeof settings.active === 'boolean' ? ' aria-pressed="' + settings.active + '"' : '';
5093          return '<div id="' + id + '" class="' + self.classes + '" tabindex="-1"' + ariaPressed + '>' + '<button id="' + id + '-button" role="presentation" type="button" tabindex="-1">' + (icon ? '<i class="' + icon + '"' + image + '></i>' : '') + textHtml + '</button>' + '</div>';
5094        },
5095        bindStates: function () {
5096          var self = this, $ = self.$, textCls = self.classPrefix + 'txt';
5097          function setButtonText(text) {
5098            var $span = $('span.' + textCls, self.getEl());
5099            if (text) {
5100              if (!$span[0]) {
5101                $('button:first', self.getEl()).append('<span class="' + textCls + '"></span>');
5102                $span = $('span.' + textCls, self.getEl());
5103              }
5104              $span.html(self.encode(text));
5105            } else {
5106              $span.remove();
5107            }
5108            self.classes.toggle('btn-has-text', !!text);
5109          }
5110          self.state.on('change:text', function (e) {
5111            setButtonText(e.value);
5112          });
5113          self.state.on('change:icon', function (e) {
5114            var icon = e.value;
5115            var prefix = self.classPrefix;
5116            self.settings.icon = icon;
5117            icon = icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : '';
5118            var btnElm = self.getEl().firstChild;
5119            var iconElm = btnElm.getElementsByTagName('i')[0];
5120            if (icon) {
5121              if (!iconElm || iconElm !== btnElm.firstChild) {
5122                iconElm = domGlobals.document.createElement('i');
5123                btnElm.insertBefore(iconElm, btnElm.firstChild);
5124              }
5125              iconElm.className = icon;
5126            } else if (iconElm) {
5127              btnElm.removeChild(iconElm);
5128            }
5129            setButtonText(self.state.get('text'));
5130          });
5131          return self._super();
5132        }
5133      });
5134  
5135      var BrowseButton = Button.extend({
5136        init: function (settings) {
5137          var self = this;
5138          settings = global$4.extend({
5139            text: 'Browse...',
5140            multiple: false,
5141            accept: null
5142          }, settings);
5143          self._super(settings);
5144          self.classes.add('browsebutton');
5145          if (settings.multiple) {
5146            self.classes.add('multiple');
5147          }
5148        },
5149        postRender: function () {
5150          var self = this;
5151          var input = funcs.create('input', {
5152            type: 'file',
5153            id: self._id + '-browse',
5154            accept: self.settings.accept
5155          });
5156          self._super();
5157          global$7(input).on('change', function (e) {
5158            var files = e.target.files;
5159            self.value = function () {
5160              if (!files.length) {
5161                return null;
5162              } else if (self.settings.multiple) {
5163                return files;
5164              } else {
5165                return files[0];
5166              }
5167            };
5168            e.preventDefault();
5169            if (files.length) {
5170              self.fire('change', e);
5171            }
5172          });
5173          global$7(input).on('click', function (e) {
5174            e.stopPropagation();
5175          });
5176          global$7(self.getEl('button')).on('click', function (e) {
5177            e.stopPropagation();
5178            input.click();
5179          });
5180          self.getEl().appendChild(input);
5181        },
5182        remove: function () {
5183          global$7(this.getEl('button')).off();
5184          global$7(this.getEl('input')).off();
5185          this._super();
5186        }
5187      });
5188  
5189      var ButtonGroup = Container.extend({
5190        Defaults: {
5191          defaultType: 'button',
5192          role: 'group'
5193        },
5194        renderHtml: function () {
5195          var self = this, layout = self._layout;
5196          self.classes.add('btn-group');
5197          self.preRender();
5198          layout.preRender(self);
5199          return '<div id="' + self._id + '" class="' + self.classes + '">' + '<div id="' + self._id + '-body">' + (self.settings.html || '') + layout.renderHtml(self) + '</div>' + '</div>';
5200        }
5201      });
5202  
5203      var Checkbox = Widget.extend({
5204        Defaults: {
5205          classes: 'checkbox',
5206          role: 'checkbox',
5207          checked: false
5208        },
5209        init: function (settings) {
5210          var self = this;
5211          self._super(settings);
5212          self.on('click mousedown', function (e) {
5213            e.preventDefault();
5214          });
5215          self.on('click', function (e) {
5216            e.preventDefault();
5217            if (!self.disabled()) {
5218              self.checked(!self.checked());
5219            }
5220          });
5221          self.checked(self.settings.checked);
5222        },
5223        checked: function (state) {
5224          if (!arguments.length) {
5225            return this.state.get('checked');
5226          }
5227          this.state.set('checked', state);
5228          return this;
5229        },
5230        value: function (state) {
5231          if (!arguments.length) {
5232            return this.checked();
5233          }
5234          return this.checked(state);
5235        },
5236        renderHtml: function () {
5237          var self = this, id = self._id, prefix = self.classPrefix;
5238          return '<div id="' + id + '" class="' + self.classes + '" unselectable="on" aria-labelledby="' + id + '-al" tabindex="-1">' + '<i class="' + prefix + 'ico ' + prefix + 'i-checkbox"></i>' + '<span id="' + id + '-al" class="' + prefix + 'label">' + self.encode(self.state.get('text')) + '</span>' + '</div>';
5239        },
5240        bindStates: function () {
5241          var self = this;
5242          function checked(state) {
5243            self.classes.toggle('checked', state);
5244            self.aria('checked', state);
5245          }
5246          self.state.on('change:text', function (e) {
5247            self.getEl('al').firstChild.data = self.translate(e.value);
5248          });
5249          self.state.on('change:checked change:value', function (e) {
5250            self.fire('change');
5251            checked(e.value);
5252          });
5253          self.state.on('change:icon', function (e) {
5254            var icon = e.value;
5255            var prefix = self.classPrefix;
5256            if (typeof icon === 'undefined') {
5257              return self.settings.icon;
5258            }
5259            self.settings.icon = icon;
5260            icon = icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : '';
5261            var btnElm = self.getEl().firstChild;
5262            var iconElm = btnElm.getElementsByTagName('i')[0];
5263            if (icon) {
5264              if (!iconElm || iconElm !== btnElm.firstChild) {
5265                iconElm = domGlobals.document.createElement('i');
5266                btnElm.insertBefore(iconElm, btnElm.firstChild);
5267              }
5268              iconElm.className = icon;
5269            } else if (iconElm) {
5270              btnElm.removeChild(iconElm);
5271            }
5272          });
5273          if (self.state.get('checked')) {
5274            checked(true);
5275          }
5276          return self._super();
5277        }
5278      });
5279  
5280      var global$f = tinymce.util.Tools.resolve('tinymce.util.VK');
5281  
5282      var ComboBox = Widget.extend({
5283        init: function (settings) {
5284          var self = this;
5285          self._super(settings);
5286          settings = self.settings;
5287          self.classes.add('combobox');
5288          self.subinput = true;
5289          self.ariaTarget = 'inp';
5290          settings.menu = settings.menu || settings.values;
5291          if (settings.menu) {
5292            settings.icon = 'caret';
5293          }
5294          self.on('click', function (e) {
5295            var elm = e.target;
5296            var root = self.getEl();
5297            if (!global$7.contains(root, elm) && elm !== root) {
5298              return;
5299            }
5300            while (elm && elm !== root) {
5301              if (elm.id && elm.id.indexOf('-open') !== -1) {
5302                self.fire('action');
5303                if (settings.menu) {
5304                  self.showMenu();
5305                  if (e.aria) {
5306                    self.menu.items()[0].focus();
5307                  }
5308                }
5309              }
5310              elm = elm.parentNode;
5311            }
5312          });
5313          self.on('keydown', function (e) {
5314            var rootControl;
5315            if (e.keyCode === 13 && e.target.nodeName === 'INPUT') {
5316              e.preventDefault();
5317              self.parents().reverse().each(function (ctrl) {
5318                if (ctrl.toJSON) {
5319                  rootControl = ctrl;
5320                  return false;
5321                }
5322              });
5323              self.fire('submit', { data: rootControl.toJSON() });
5324            }
5325          });
5326          self.on('keyup', function (e) {
5327            if (e.target.nodeName === 'INPUT') {
5328              var oldValue = self.state.get('value');
5329              var newValue = e.target.value;
5330              if (newValue !== oldValue) {
5331                self.state.set('value', newValue);
5332                self.fire('autocomplete', e);
5333              }
5334            }
5335          });
5336          self.on('mouseover', function (e) {
5337            var tooltip = self.tooltip().moveTo(-65535);
5338            if (self.statusLevel() && e.target.className.indexOf(self.classPrefix + 'status') !== -1) {
5339              var statusMessage = self.statusMessage() || 'Ok';
5340              var rel = tooltip.text(statusMessage).show().testMoveRel(e.target, [
5341                'bc-tc',
5342                'bc-tl',
5343                'bc-tr'
5344              ]);
5345              tooltip.classes.toggle('tooltip-n', rel === 'bc-tc');
5346              tooltip.classes.toggle('tooltip-nw', rel === 'bc-tl');
5347              tooltip.classes.toggle('tooltip-ne', rel === 'bc-tr');
5348              tooltip.moveRel(e.target, rel);
5349            }
5350          });
5351        },
5352        statusLevel: function (value) {
5353          if (arguments.length > 0) {
5354            this.state.set('statusLevel', value);
5355          }
5356          return this.state.get('statusLevel');
5357        },
5358        statusMessage: function (value) {
5359          if (arguments.length > 0) {
5360            this.state.set('statusMessage', value);
5361          }
5362          return this.state.get('statusMessage');
5363        },
5364        showMenu: function () {
5365          var self = this;
5366          var settings = self.settings;
5367          var menu;
5368          if (!self.menu) {
5369            menu = settings.menu || [];
5370            if (menu.length) {
5371              menu = {
5372                type: 'menu',
5373                items: menu
5374              };
5375            } else {
5376              menu.type = menu.type || 'menu';
5377            }
5378            self.menu = global$b.create(menu).parent(self).renderTo(self.getContainerElm());
5379            self.fire('createmenu');
5380            self.menu.reflow();
5381            self.menu.on('cancel', function (e) {
5382              if (e.control === self.menu) {
5383                self.focus();
5384              }
5385            });
5386            self.menu.on('show hide', function (e) {
5387              e.control.items().each(function (ctrl) {
5388                ctrl.active(ctrl.value() === self.value());
5389              });
5390            }).fire('show');
5391            self.menu.on('select', function (e) {
5392              self.value(e.control.value());
5393            });
5394            self.on('focusin', function (e) {
5395              if (e.target.tagName.toUpperCase() === 'INPUT') {
5396                self.menu.hide();
5397              }
5398            });
5399            self.aria('expanded', true);
5400          }
5401          self.menu.show();
5402          self.menu.layoutRect({ w: self.layoutRect().w });
5403          self.menu.moveRel(self.getEl(), self.isRtl() ? [
5404            'br-tr',
5405            'tr-br'
5406          ] : [
5407            'bl-tl',
5408            'tl-bl'
5409          ]);
5410        },
5411        focus: function () {
5412          this.getEl('inp').focus();
5413        },
5414        repaint: function () {
5415          var self = this, elm = self.getEl(), openElm = self.getEl('open'), rect = self.layoutRect();
5416          var width, lineHeight, innerPadding = 0;
5417          var inputElm = elm.firstChild;
5418          if (self.statusLevel() && self.statusLevel() !== 'none') {
5419            innerPadding = parseInt(funcs.getRuntimeStyle(inputElm, 'padding-right'), 10) - parseInt(funcs.getRuntimeStyle(inputElm, 'padding-left'), 10);
5420          }
5421          if (openElm) {
5422            width = rect.w - funcs.getSize(openElm).width - 10;
5423          } else {
5424            width = rect.w - 10;
5425          }
5426          var doc = domGlobals.document;
5427          if (doc.all && (!doc.documentMode || doc.documentMode <= 8)) {
5428            lineHeight = self.layoutRect().h - 2 + 'px';
5429          }
5430          global$7(inputElm).css({
5431            width: width - innerPadding,
5432            lineHeight: lineHeight
5433          });
5434          self._super();
5435          return self;
5436        },
5437        postRender: function () {
5438          var self = this;
5439          global$7(this.getEl('inp')).on('change', function (e) {
5440            self.state.set('value', e.target.value);
5441            self.fire('change', e);
5442          });
5443          return self._super();
5444        },
5445        renderHtml: function () {
5446          var self = this, id = self._id, settings = self.settings, prefix = self.classPrefix;
5447          var value = self.state.get('value') || '';
5448          var icon, text, openBtnHtml = '', extraAttrs = '', statusHtml = '';
5449          if ('spellcheck' in settings) {
5450            extraAttrs += ' spellcheck="' + settings.spellcheck + '"';
5451          }
5452          if (settings.maxLength) {
5453            extraAttrs += ' maxlength="' + settings.maxLength + '"';
5454          }
5455          if (settings.size) {
5456            extraAttrs += ' size="' + settings.size + '"';
5457          }
5458          if (settings.subtype) {
5459            extraAttrs += ' type="' + settings.subtype + '"';
5460          }
5461          statusHtml = '<i id="' + id + '-status" class="mce-status mce-ico" style="display: none"></i>';
5462          if (self.disabled()) {
5463            extraAttrs += ' disabled="disabled"';
5464          }
5465          icon = settings.icon;
5466          if (icon && icon !== 'caret') {
5467            icon = prefix + 'ico ' + prefix + 'i-' + settings.icon;
5468          }
5469          text = self.state.get('text');
5470          if (icon || text) {
5471            openBtnHtml = '<div id="' + id + '-open" class="' + prefix + 'btn ' + prefix + 'open" tabIndex="-1" role="button">' + '<button id="' + id + '-action" type="button" hidefocus="1" tabindex="-1">' + (icon !== 'caret' ? '<i class="' + icon + '"></i>' : '<i class="' + prefix + 'caret"></i>') + (text ? (icon ? ' ' : '') + text : '') + '</button>' + '</div>';
5472            self.classes.add('has-open');
5473          }
5474          return '<div id="' + id + '" class="' + self.classes + '">' + '<input id="' + id + '-inp" class="' + prefix + 'textbox" value="' + self.encode(value, false) + '" hidefocus="1"' + extraAttrs + ' placeholder="' + self.encode(settings.placeholder) + '" />' + statusHtml + openBtnHtml + '</div>';
5475        },
5476        value: function (value) {
5477          if (arguments.length) {
5478            this.state.set('value', value);
5479            return this;
5480          }
5481          if (this.state.get('rendered')) {
5482            this.state.set('value', this.getEl('inp').value);
5483          }
5484          return this.state.get('value');
5485        },
5486        showAutoComplete: function (items, term) {
5487          var self = this;
5488          if (items.length === 0) {
5489            self.hideMenu();
5490            return;
5491          }
5492          var insert = function (value, title) {
5493            return function () {
5494              self.fire('selectitem', {
5495                title: title,
5496                value: value
5497              });
5498            };
5499          };
5500          if (self.menu) {
5501            self.menu.items().remove();
5502          } else {
5503            self.menu = global$b.create({
5504              type: 'menu',
5505              classes: 'combobox-menu',
5506              layout: 'flow'
5507            }).parent(self).renderTo();
5508          }
5509          global$4.each(items, function (item) {
5510            self.menu.add({
5511              text: item.title,
5512              url: item.previewUrl,
5513              match: term,
5514              classes: 'menu-item-ellipsis',
5515              onclick: insert(item.value, item.title)
5516            });
5517          });
5518          self.menu.renderNew();
5519          self.hideMenu();
5520          self.menu.on('cancel', function (e) {
5521            if (e.control.parent() === self.menu) {
5522              e.stopPropagation();
5523              self.focus();
5524              self.hideMenu();
5525            }
5526          });
5527          self.menu.on('select', function () {
5528            self.focus();
5529          });
5530          var maxW = self.layoutRect().w;
5531          self.menu.layoutRect({
5532            w: maxW,
5533            minW: 0,
5534            maxW: maxW
5535          });
5536          self.menu.repaint();
5537          self.menu.reflow();
5538          self.menu.show();
5539          self.menu.moveRel(self.getEl(), self.isRtl() ? [
5540            'br-tr',
5541            'tr-br'
5542          ] : [
5543            'bl-tl',
5544            'tl-bl'
5545          ]);
5546        },
5547        hideMenu: function () {
5548          if (this.menu) {
5549            this.menu.hide();
5550          }
5551        },
5552        bindStates: function () {
5553          var self = this;
5554          self.state.on('change:value', function (e) {
5555            if (self.getEl('inp').value !== e.value) {
5556              self.getEl('inp').value = e.value;
5557            }
5558          });
5559          self.state.on('change:disabled', function (e) {
5560            self.getEl('inp').disabled = e.value;
5561          });
5562          self.state.on('change:statusLevel', function (e) {
5563            var statusIconElm = self.getEl('status');
5564            var prefix = self.classPrefix, value = e.value;
5565            funcs.css(statusIconElm, 'display', value === 'none' ? 'none' : '');
5566            funcs.toggleClass(statusIconElm, prefix + 'i-checkmark', value === 'ok');
5567            funcs.toggleClass(statusIconElm, prefix + 'i-warning', value === 'warn');
5568            funcs.toggleClass(statusIconElm, prefix + 'i-error', value === 'error');
5569            self.classes.toggle('has-status', value !== 'none');
5570            self.repaint();
5571          });
5572          funcs.on(self.getEl('status'), 'mouseleave', function () {
5573            self.tooltip().hide();
5574          });
5575          self.on('cancel', function (e) {
5576            if (self.menu && self.menu.visible()) {
5577              e.stopPropagation();
5578              self.hideMenu();
5579            }
5580          });
5581          var focusIdx = function (idx, menu) {
5582            if (menu && menu.items().length > 0) {
5583              menu.items().eq(idx)[0].focus();
5584            }
5585          };
5586          self.on('keydown', function (e) {
5587            var keyCode = e.keyCode;
5588            if (e.target.nodeName === 'INPUT') {
5589              if (keyCode === global$f.DOWN) {
5590                e.preventDefault();
5591                self.fire('autocomplete');
5592                focusIdx(0, self.menu);
5593              } else if (keyCode === global$f.UP) {
5594                e.preventDefault();
5595                focusIdx(-1, self.menu);
5596              }
5597            }
5598          });
5599          return self._super();
5600        },
5601        remove: function () {
5602          global$7(this.getEl('inp')).off();
5603          if (this.menu) {
5604            this.menu.remove();
5605          }
5606          this._super();
5607        }
5608      });
5609  
5610      var ColorBox = ComboBox.extend({
5611        init: function (settings) {
5612          var self = this;
5613          settings.spellcheck = false;
5614          if (settings.onaction) {
5615            settings.icon = 'none';
5616          }
5617          self._super(settings);
5618          self.classes.add('colorbox');
5619          self.on('change keyup postrender', function () {
5620            self.repaintColor(self.value());
5621          });
5622        },
5623        repaintColor: function (value) {
5624          var openElm = this.getEl('open');
5625          var elm = openElm ? openElm.getElementsByTagName('i')[0] : null;
5626          if (elm) {
5627            try {
5628              elm.style.background = value;
5629            } catch (ex) {
5630            }
5631          }
5632        },
5633        bindStates: function () {
5634          var self = this;
5635          self.state.on('change:value', function (e) {
5636            if (self.state.get('rendered')) {
5637              self.repaintColor(e.value);
5638            }
5639          });
5640          return self._super();
5641        }
5642      });
5643  
5644      var PanelButton = Button.extend({
5645        showPanel: function () {
5646          var self = this, settings = self.settings;
5647          self.classes.add('opened');
5648          if (!self.panel) {
5649            var panelSettings = settings.panel;
5650            if (panelSettings.type) {
5651              panelSettings = {
5652                layout: 'grid',
5653                items: panelSettings
5654              };
5655            }
5656            panelSettings.role = panelSettings.role || 'dialog';
5657            panelSettings.popover = true;
5658            panelSettings.autohide = true;
5659            panelSettings.ariaRoot = true;
5660            self.panel = new FloatPanel(panelSettings).on('hide', function () {
5661              self.classes.remove('opened');
5662            }).on('cancel', function (e) {
5663              e.stopPropagation();
5664              self.focus();
5665              self.hidePanel();
5666            }).parent(self).renderTo(self.getContainerElm());
5667            self.panel.fire('show');
5668            self.panel.reflow();
5669          } else {
5670            self.panel.show();
5671          }
5672          var rtlRels = [
5673            'bc-tc',
5674            'bc-tl',
5675            'bc-tr'
5676          ];
5677          var ltrRels = [
5678            'bc-tc',
5679            'bc-tr',
5680            'bc-tl',
5681            'tc-bc',
5682            'tc-br',
5683            'tc-bl'
5684          ];
5685          var rel = self.panel.testMoveRel(self.getEl(), settings.popoverAlign || (self.isRtl() ? rtlRels : ltrRels));
5686          self.panel.classes.toggle('start', rel.substr(-1) === 'l');
5687          self.panel.classes.toggle('end', rel.substr(-1) === 'r');
5688          var isTop = rel.substr(0, 1) === 't';
5689          self.panel.classes.toggle('bottom', !isTop);
5690          self.panel.classes.toggle('top', isTop);
5691          self.panel.moveRel(self.getEl(), rel);
5692        },
5693        hidePanel: function () {
5694          var self = this;
5695          if (self.panel) {
5696            self.panel.hide();
5697          }
5698        },
5699        postRender: function () {
5700          var self = this;
5701          self.aria('haspopup', true);
5702          self.on('click', function (e) {
5703            if (e.control === self) {
5704              if (self.panel && self.panel.visible()) {
5705                self.hidePanel();
5706              } else {
5707                self.showPanel();
5708                self.panel.focus(!!e.aria);
5709              }
5710            }
5711          });
5712          return self._super();
5713        },
5714        remove: function () {
5715          if (this.panel) {
5716            this.panel.remove();
5717            this.panel = null;
5718          }
5719          return this._super();
5720        }
5721      });
5722  
5723      var DOM = global$2.DOM;
5724      var ColorButton = PanelButton.extend({
5725        init: function (settings) {
5726          this._super(settings);
5727          this.classes.add('splitbtn');
5728          this.classes.add('colorbutton');
5729        },
5730        color: function (color) {
5731          if (color) {
5732            this._color = color;
5733            this.getEl('preview').style.backgroundColor = color;
5734            return this;
5735          }
5736          return this._color;
5737        },
5738        resetColor: function () {
5739          this._color = null;
5740          this.getEl('preview').style.backgroundColor = null;
5741          return this;
5742        },
5743        renderHtml: function () {
5744          var self = this, id = self._id, prefix = self.classPrefix, text = self.state.get('text');
5745          var icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : '';
5746          var image = self.settings.image ? ' style="background-image: url(\'' + self.settings.image + '\')"' : '';
5747          var textHtml = '';
5748          if (text) {
5749            self.classes.add('btn-has-text');
5750            textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>';
5751          }
5752          return '<div id="' + id + '" class="' + self.classes + '" role="button" tabindex="-1" aria-haspopup="true">' + '<button role="presentation" hidefocus="1" type="button" tabindex="-1">' + (icon ? '<i class="' + icon + '"' + image + '></i>' : '') + '<span id="' + id + '-preview" class="' + prefix + 'preview"></span>' + textHtml + '</button>' + '<button type="button" class="' + prefix + 'open" hidefocus="1" tabindex="-1">' + ' <i class="' + prefix + 'caret"></i>' + '</button>' + '</div>';
5753        },
5754        postRender: function () {
5755          var self = this, onClickHandler = self.settings.onclick;
5756          self.on('click', function (e) {
5757            if (e.aria && e.aria.key === 'down') {
5758              return;
5759            }
5760            if (e.control === self && !DOM.getParent(e.target, '.' + self.classPrefix + 'open')) {
5761              e.stopImmediatePropagation();
5762              onClickHandler.call(self, e);
5763            }
5764          });
5765          delete self.settings.onclick;
5766          return self._super();
5767        }
5768      });
5769  
5770      var global$g = tinymce.util.Tools.resolve('tinymce.util.Color');
5771  
5772      var ColorPicker = Widget.extend({
5773        Defaults: { classes: 'widget colorpicker' },
5774        init: function (settings) {
5775          this._super(settings);
5776        },
5777        postRender: function () {
5778          var self = this;
5779          var color = self.color();
5780          var hsv, hueRootElm, huePointElm, svRootElm, svPointElm;
5781          hueRootElm = self.getEl('h');
5782          huePointElm = self.getEl('hp');
5783          svRootElm = self.getEl('sv');
5784          svPointElm = self.getEl('svp');
5785          function getPos(elm, event) {
5786            var pos = funcs.getPos(elm);
5787            var x, y;
5788            x = event.pageX - pos.x;
5789            y = event.pageY - pos.y;
5790            x = Math.max(0, Math.min(x / elm.clientWidth, 1));
5791            y = Math.max(0, Math.min(y / elm.clientHeight, 1));
5792            return {
5793              x: x,
5794              y: y
5795            };
5796          }
5797          function updateColor(hsv, hueUpdate) {
5798            var hue = (360 - hsv.h) / 360;
5799            funcs.css(huePointElm, { top: hue * 100 + '%' });
5800            if (!hueUpdate) {
5801              funcs.css(svPointElm, {
5802                left: hsv.s + '%',
5803                top: 100 - hsv.v + '%'
5804              });
5805            }
5806            svRootElm.style.background = global$g({
5807              s: 100,
5808              v: 100,
5809              h: hsv.h
5810            }).toHex();
5811            self.color().parse({
5812              s: hsv.s,
5813              v: hsv.v,
5814              h: hsv.h
5815            });
5816          }
5817          function updateSaturationAndValue(e) {
5818            var pos;
5819            pos = getPos(svRootElm, e);
5820            hsv.s = pos.x * 100;
5821            hsv.v = (1 - pos.y) * 100;
5822            updateColor(hsv);
5823            self.fire('change');
5824          }
5825          function updateHue(e) {
5826            var pos;
5827            pos = getPos(hueRootElm, e);
5828            hsv = color.toHsv();
5829            hsv.h = (1 - pos.y) * 360;
5830            updateColor(hsv, true);
5831            self.fire('change');
5832          }
5833          self._repaint = function () {
5834            hsv = color.toHsv();
5835            updateColor(hsv);
5836          };
5837          self._super();
5838          self._svdraghelper = new DragHelper(self._id + '-sv', {
5839            start: updateSaturationAndValue,
5840            drag: updateSaturationAndValue
5841          });
5842          self._hdraghelper = new DragHelper(self._id + '-h', {
5843            start: updateHue,
5844            drag: updateHue
5845          });
5846          self._repaint();
5847        },
5848        rgb: function () {
5849          return this.color().toRgb();
5850        },
5851        value: function (value) {
5852          var self = this;
5853          if (arguments.length) {
5854            self.color().parse(value);
5855            if (self._rendered) {
5856              self._repaint();
5857            }
5858          } else {
5859            return self.color().toHex();
5860          }
5861        },
5862        color: function () {
5863          if (!this._color) {
5864            this._color = global$g();
5865          }
5866          return this._color;
5867        },
5868        renderHtml: function () {
5869          var self = this;
5870          var id = self._id;
5871          var prefix = self.classPrefix;
5872          var hueHtml;
5873          var stops = '#ff0000,#ff0080,#ff00ff,#8000ff,#0000ff,#0080ff,#00ffff,#00ff80,#00ff00,#80ff00,#ffff00,#ff8000,#ff0000';
5874          function getOldIeFallbackHtml() {
5875            var i, l, html = '', gradientPrefix, stopsList;
5876            gradientPrefix = 'filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=';
5877            stopsList = stops.split(',');
5878            for (i = 0, l = stopsList.length - 1; i < l; i++) {
5879              html += '<div class="' + prefix + 'colorpicker-h-chunk" style="' + 'height:' + 100 / l + '%;' + gradientPrefix + stopsList[i] + ',endColorstr=' + stopsList[i + 1] + ');' + '-ms-' + gradientPrefix + stopsList[i] + ',endColorstr=' + stopsList[i + 1] + ')' + '"></div>';
5880            }
5881            return html;
5882          }
5883          var gradientCssText = 'background: -ms-linear-gradient(top,' + stops + ');' + 'background: linear-gradient(to bottom,' + stops + ');';
5884          hueHtml = '<div id="' + id + '-h" class="' + prefix + 'colorpicker-h" style="' + gradientCssText + '">' + getOldIeFallbackHtml() + '<div id="' + id + '-hp" class="' + prefix + 'colorpicker-h-marker"></div>' + '</div>';
5885          return '<div id="' + id + '" class="' + self.classes + '">' + '<div id="' + id + '-sv" class="' + prefix + 'colorpicker-sv">' + '<div class="' + prefix + 'colorpicker-overlay1">' + '<div class="' + prefix + 'colorpicker-overlay2">' + '<div id="' + id + '-svp" class="' + prefix + 'colorpicker-selector1">' + '<div class="' + prefix + 'colorpicker-selector2"></div>' + '</div>' + '</div>' + '</div>' + '</div>' + hueHtml + '</div>';
5886        }
5887      });
5888  
5889      var DropZone = Widget.extend({
5890        init: function (settings) {
5891          var self = this;
5892          settings = global$4.extend({
5893            height: 100,
5894            text: 'Drop an image here',
5895            multiple: false,
5896            accept: null
5897          }, settings);
5898          self._super(settings);
5899          self.classes.add('dropzone');
5900          if (settings.multiple) {
5901            self.classes.add('multiple');
5902          }
5903        },
5904        renderHtml: function () {
5905          var self = this;
5906          var attrs, elm;
5907          var cfg = self.settings;
5908          attrs = {
5909            id: self._id,
5910            hidefocus: '1'
5911          };
5912          elm = funcs.create('div', attrs, '<span>' + this.translate(cfg.text) + '</span>');
5913          if (cfg.height) {
5914            funcs.css(elm, 'height', cfg.height + 'px');
5915          }
5916          if (cfg.width) {
5917            funcs.css(elm, 'width', cfg.width + 'px');
5918          }
5919          elm.className = self.classes;
5920          return elm.outerHTML;
5921        },
5922        postRender: function () {
5923          var self = this;
5924          var toggleDragClass = function (e) {
5925            e.preventDefault();
5926            self.classes.toggle('dragenter');
5927            self.getEl().className = self.classes;
5928          };
5929          var filter = function (files) {
5930            var accept = self.settings.accept;
5931            if (typeof accept !== 'string') {
5932              return files;
5933            }
5934            var re = new RegExp('(' + accept.split(/\s*,\s*/).join('|') + ')$', 'i');
5935            return global$4.grep(files, function (file) {
5936              return re.test(file.name);
5937            });
5938          };
5939          self._super();
5940          self.$el.on('dragover', function (e) {
5941            e.preventDefault();
5942          });
5943          self.$el.on('dragenter', toggleDragClass);
5944          self.$el.on('dragleave', toggleDragClass);
5945          self.$el.on('drop', function (e) {
5946            e.preventDefault();
5947            if (self.state.get('disabled')) {
5948              return;
5949            }
5950            var files = filter(e.dataTransfer.files);
5951            self.value = function () {
5952              if (!files.length) {
5953                return null;
5954              } else if (self.settings.multiple) {
5955                return files;
5956              } else {
5957                return files[0];
5958              }
5959            };
5960            if (files.length) {
5961              self.fire('change', e);
5962            }
5963          });
5964        },
5965        remove: function () {
5966          this.$el.off();
5967          this._super();
5968        }
5969      });
5970  
5971      var Path = Widget.extend({
5972        init: function (settings) {
5973          var self = this;
5974          if (!settings.delimiter) {
5975            settings.delimiter = '\xBB';
5976          }
5977          self._super(settings);
5978          self.classes.add('path');
5979          self.canFocus = true;
5980          self.on('click', function (e) {
5981            var index;
5982            var target = e.target;
5983            if (index = target.getAttribute('data-index')) {
5984              self.fire('select', {
5985                value: self.row()[index],
5986                index: index
5987              });
5988            }
5989          });
5990          self.row(self.settings.row);
5991        },
5992        focus: function () {
5993          var self = this;
5994          self.getEl().firstChild.focus();
5995          return self;
5996        },
5997        row: function (row) {
5998          if (!arguments.length) {
5999            return this.state.get('row');
6000          }
6001          this.state.set('row', row);
6002          return this;
6003        },
6004        renderHtml: function () {
6005          var self = this;
6006          return '<div id="' + self._id + '" class="' + self.classes + '">' + self._getDataPathHtml(self.state.get('row')) + '</div>';
6007        },
6008        bindStates: function () {
6009          var self = this;
6010          self.state.on('change:row', function (e) {
6011            self.innerHtml(self._getDataPathHtml(e.value));
6012          });
6013          return self._super();
6014        },
6015        _getDataPathHtml: function (data) {
6016          var self = this;
6017          var parts = data || [];
6018          var i, l, html = '';
6019          var prefix = self.classPrefix;
6020          for (i = 0, l = parts.length; i < l; i++) {
6021            html += (i > 0 ? '<div class="' + prefix + 'divider" aria-hidden="true"> ' + self.settings.delimiter + ' </div>' : '') + '<div role="button" class="' + prefix + 'path-item' + (i === l - 1 ? ' ' + prefix + 'last' : '') + '" data-index="' + i + '" tabindex="-1" id="' + self._id + '-' + i + '" aria-level="' + (i + 1) + '">' + parts[i].name + '</div>';
6022          }
6023          if (!html) {
6024            html = '<div class="' + prefix + 'path-item">\xA0</div>';
6025          }
6026          return html;
6027        }
6028      });
6029  
6030      var ElementPath = Path.extend({
6031        postRender: function () {
6032          var self = this, editor = self.settings.editor;
6033          function isHidden(elm) {
6034            if (elm.nodeType === 1) {
6035              if (elm.nodeName === 'BR' || !!elm.getAttribute('data-mce-bogus')) {
6036                return true;
6037              }
6038              if (elm.getAttribute('data-mce-type') === 'bookmark') {
6039                return true;
6040              }
6041            }
6042            return false;
6043          }
6044          if (editor.settings.elementpath !== false) {
6045            self.on('select', function (e) {
6046              editor.focus();
6047              editor.selection.select(this.row()[e.index].element);
6048              editor.nodeChanged();
6049            });
6050            editor.on('nodeChange', function (e) {
6051              var outParents = [];
6052              var parents = e.parents;
6053              var i = parents.length;
6054              while (i--) {
6055                if (parents[i].nodeType === 1 && !isHidden(parents[i])) {
6056                  var args = editor.fire('ResolveName', {
6057                    name: parents[i].nodeName.toLowerCase(),
6058                    target: parents[i]
6059                  });
6060                  if (!args.isDefaultPrevented()) {
6061                    outParents.push({
6062                      name: args.name,
6063                      element: parents[i]
6064                    });
6065                  }
6066                  if (args.isPropagationStopped()) {
6067                    break;
6068                  }
6069                }
6070              }
6071              self.row(outParents);
6072            });
6073          }
6074          return self._super();
6075        }
6076      });
6077  
6078      var FormItem = Container.extend({
6079        Defaults: {
6080          layout: 'flex',
6081          align: 'center',
6082          defaults: { flex: 1 }
6083        },
6084        renderHtml: function () {
6085          var self = this, layout = self._layout, prefix = self.classPrefix;
6086          self.classes.add('formitem');
6087          layout.preRender(self);
6088          return '<div id="' + self._id + '" class="' + self.classes + '" hidefocus="1" tabindex="-1">' + (self.settings.title ? '<div id="' + self._id + '-title" class="' + prefix + 'title">' + self.settings.title + '</div>' : '') + '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + (self.settings.html || '') + layout.renderHtml(self) + '</div>' + '</div>';
6089        }
6090      });
6091  
6092      var Form = Container.extend({
6093        Defaults: {
6094          containerCls: 'form',
6095          layout: 'flex',
6096          direction: 'column',
6097          align: 'stretch',
6098          flex: 1,
6099          padding: 15,
6100          labelGap: 30,
6101          spacing: 10,
6102          callbacks: {
6103            submit: function () {
6104              this.submit();
6105            }
6106          }
6107        },
6108        preRender: function () {
6109          var self = this, items = self.items();
6110          if (!self.settings.formItemDefaults) {
6111            self.settings.formItemDefaults = {
6112              layout: 'flex',
6113              autoResize: 'overflow',
6114              defaults: { flex: 1 }
6115            };
6116          }
6117          items.each(function (ctrl) {
6118            var formItem;
6119            var label = ctrl.settings.label;
6120            if (label) {
6121              formItem = new FormItem(global$4.extend({
6122                items: {
6123                  type: 'label',
6124                  id: ctrl._id + '-l',
6125                  text: label,
6126                  flex: 0,
6127                  forId: ctrl._id,
6128                  disabled: ctrl.disabled()
6129                }
6130              }, self.settings.formItemDefaults));
6131              formItem.type = 'formitem';
6132              ctrl.aria('labelledby', ctrl._id + '-l');
6133              if (typeof ctrl.settings.flex === 'undefined') {
6134                ctrl.settings.flex = 1;
6135              }
6136              self.replace(ctrl, formItem);
6137              formItem.add(ctrl);
6138            }
6139          });
6140        },
6141        submit: function () {
6142          return this.fire('submit', { data: this.toJSON() });
6143        },
6144        postRender: function () {
6145          var self = this;
6146          self._super();
6147          self.fromJSON(self.settings.data);
6148        },
6149        bindStates: function () {
6150          var self = this;
6151          self._super();
6152          function recalcLabels() {
6153            var maxLabelWidth = 0;
6154            var labels = [];
6155            var i, labelGap, items;
6156            if (self.settings.labelGapCalc === false) {
6157              return;
6158            }
6159            if (self.settings.labelGapCalc === 'children') {
6160              items = self.find('formitem');
6161            } else {
6162              items = self.items();
6163            }
6164            items.filter('formitem').each(function (item) {
6165              var labelCtrl = item.items()[0], labelWidth = labelCtrl.getEl().clientWidth;
6166              maxLabelWidth = labelWidth > maxLabelWidth ? labelWidth : maxLabelWidth;
6167              labels.push(labelCtrl);
6168            });
6169            labelGap = self.settings.labelGap || 0;
6170            i = labels.length;
6171            while (i--) {
6172              labels[i].settings.minWidth = maxLabelWidth + labelGap;
6173            }
6174          }
6175          self.on('show', recalcLabels);
6176          recalcLabels();
6177        }
6178      });
6179  
6180      var FieldSet = Form.extend({
6181        Defaults: {
6182          containerCls: 'fieldset',
6183          layout: 'flex',
6184          direction: 'column',
6185          align: 'stretch',
6186          flex: 1,
6187          padding: '25 15 5 15',
6188          labelGap: 30,
6189          spacing: 10,
6190          border: 1
6191        },
6192        renderHtml: function () {
6193          var self = this, layout = self._layout, prefix = self.classPrefix;
6194          self.preRender();
6195          layout.preRender(self);
6196          return '<fieldset id="' + self._id + '" class="' + self.classes + '" hidefocus="1" tabindex="-1">' + (self.settings.title ? '<legend id="' + self._id + '-title" class="' + prefix + 'fieldset-title">' + self.settings.title + '</legend>' : '') + '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + (self.settings.html || '') + layout.renderHtml(self) + '</div>' + '</fieldset>';
6197        }
6198      });
6199  
6200      var unique$1 = 0;
6201      var generate = function (prefix) {
6202        var date = new Date();
6203        var time = date.getTime();
6204        var random = Math.floor(Math.random() * 1000000000);
6205        unique$1++;
6206        return prefix + '_' + random + unique$1 + String(time);
6207      };
6208  
6209      var fromHtml = function (html, scope) {
6210        var doc = scope || domGlobals.document;
6211        var div = doc.createElement('div');
6212        div.innerHTML = html;
6213        if (!div.hasChildNodes() || div.childNodes.length > 1) {
6214          domGlobals.console.error('HTML does not have a single root node', html);
6215          throw new Error('HTML must have a single root node');
6216        }
6217        return fromDom(div.childNodes[0]);
6218      };
6219      var fromTag = function (tag, scope) {
6220        var doc = scope || domGlobals.document;
6221        var node = doc.createElement(tag);
6222        return fromDom(node);
6223      };
6224      var fromText = function (text, scope) {
6225        var doc = scope || domGlobals.document;
6226        var node = doc.createTextNode(text);
6227        return fromDom(node);
6228      };
6229      var fromDom = function (node) {
6230        if (node === null || node === undefined) {
6231          throw new Error('Node cannot be null or undefined');
6232        }
6233        return { dom: constant(node) };
6234      };
6235      var fromPoint = function (docElm, x, y) {
6236        var doc = docElm.dom();
6237        return Option.from(doc.elementFromPoint(x, y)).map(fromDom);
6238      };
6239      var Element = {
6240        fromHtml: fromHtml,
6241        fromTag: fromTag,
6242        fromText: fromText,
6243        fromDom: fromDom,
6244        fromPoint: fromPoint
6245      };
6246  
6247      var cached = function (f) {
6248        var called = false;
6249        var r;
6250        return function () {
6251          var args = [];
6252          for (var _i = 0; _i < arguments.length; _i++) {
6253            args[_i] = arguments[_i];
6254          }
6255          if (!called) {
6256            called = true;
6257            r = f.apply(null, args);
6258          }
6259          return r;
6260        };
6261      };
6262  
6263      var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE;
6264      var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE;
6265      var COMMENT = domGlobals.Node.COMMENT_NODE;
6266      var DOCUMENT = domGlobals.Node.DOCUMENT_NODE;
6267      var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE;
6268      var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE;
6269      var ELEMENT = domGlobals.Node.ELEMENT_NODE;
6270      var TEXT = domGlobals.Node.TEXT_NODE;
6271      var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE;
6272      var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE;
6273      var ENTITY = domGlobals.Node.ENTITY_NODE;
6274      var NOTATION = domGlobals.Node.NOTATION_NODE;
6275  
6276      var Immutable = function () {
6277        var fields = [];
6278        for (var _i = 0; _i < arguments.length; _i++) {
6279          fields[_i] = arguments[_i];
6280        }
6281        return function () {
6282          var values = [];
6283          for (var _i = 0; _i < arguments.length; _i++) {
6284            values[_i] = arguments[_i];
6285          }
6286          if (fields.length !== values.length) {
6287            throw new Error('Wrong number of arguments to struct. Expected "[' + fields.length + ']", got ' + values.length + ' arguments');
6288          }
6289          var struct = {};
6290          each(fields, function (name, i) {
6291            struct[name] = constant(values[i]);
6292          });
6293          return struct;
6294        };
6295      };
6296  
6297      var node = function () {
6298        var f = Global$1.getOrDie('Node');
6299        return f;
6300      };
6301      var compareDocumentPosition = function (a, b, match) {
6302        return (a.compareDocumentPosition(b) & match) !== 0;
6303      };
6304      var documentPositionPreceding = function (a, b) {
6305        return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_PRECEDING);
6306      };
6307      var documentPositionContainedBy = function (a, b) {
6308        return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_CONTAINED_BY);
6309      };
6310      var Node = {
6311        documentPositionPreceding: documentPositionPreceding,
6312        documentPositionContainedBy: documentPositionContainedBy
6313      };
6314  
6315      var firstMatch = function (regexes, s) {
6316        for (var i = 0; i < regexes.length; i++) {
6317          var x = regexes[i];
6318          if (x.test(s))
6319            return x;
6320        }
6321        return undefined;
6322      };
6323      var find$1 = function (regexes, agent) {
6324        var r = firstMatch(regexes, agent);
6325        if (!r)
6326          return {
6327            major: 0,
6328            minor: 0
6329          };
6330        var group = function (i) {
6331          return Number(agent.replace(r, '$' + i));
6332        };
6333        return nu(group(1), group(2));
6334      };
6335      var detect = function (versionRegexes, agent) {
6336        var cleanedAgent = String(agent).toLowerCase();
6337        if (versionRegexes.length === 0)
6338          return unknown();
6339        return find$1(versionRegexes, cleanedAgent);
6340      };
6341      var unknown = function () {
6342        return nu(0, 0);
6343      };
6344      var nu = function (major, minor) {
6345        return {
6346          major: major,
6347          minor: minor
6348        };
6349      };
6350      var Version = {
6351        nu: nu,
6352        detect: detect,
6353        unknown: unknown
6354      };
6355  
6356      var edge = 'Edge';
6357      var chrome = 'Chrome';
6358      var ie = 'IE';
6359      var opera = 'Opera';
6360      var firefox = 'Firefox';
6361      var safari = 'Safari';
6362      var isBrowser = function (name, current) {
6363        return function () {
6364          return current === name;
6365        };
6366      };
6367      var unknown$1 = function () {
6368        return nu$1({
6369          current: undefined,
6370          version: Version.unknown()
6371        });
6372      };
6373      var nu$1 = function (info) {
6374        var current = info.current;
6375        var version = info.version;
6376        return {
6377          current: current,
6378          version: version,
6379          isEdge: isBrowser(edge, current),
6380          isChrome: isBrowser(chrome, current),
6381          isIE: isBrowser(ie, current),
6382          isOpera: isBrowser(opera, current),
6383          isFirefox: isBrowser(firefox, current),
6384          isSafari: isBrowser(safari, current)
6385        };
6386      };
6387      var Browser = {
6388        unknown: unknown$1,
6389        nu: nu$1,
6390        edge: constant(edge),
6391        chrome: constant(chrome),
6392        ie: constant(ie),
6393        opera: constant(opera),
6394        firefox: constant(firefox),
6395        safari: constant(safari)
6396      };
6397  
6398      var windows$1 = 'Windows';
6399      var ios = 'iOS';
6400      var android = 'Android';
6401      var linux = 'Linux';
6402      var osx = 'OSX';
6403      var solaris = 'Solaris';
6404      var freebsd = 'FreeBSD';
6405      var isOS = function (name, current) {
6406        return function () {
6407          return current === name;
6408        };
6409      };
6410      var unknown$2 = function () {
6411        return nu$2({
6412          current: undefined,
6413          version: Version.unknown()
6414        });
6415      };
6416      var nu$2 = function (info) {
6417        var current = info.current;
6418        var version = info.version;
6419        return {
6420          current: current,
6421          version: version,
6422          isWindows: isOS(windows$1, current),
6423          isiOS: isOS(ios, current),
6424          isAndroid: isOS(android, current),
6425          isOSX: isOS(osx, current),
6426          isLinux: isOS(linux, current),
6427          isSolaris: isOS(solaris, current),
6428          isFreeBSD: isOS(freebsd, current)
6429        };
6430      };
6431      var OperatingSystem = {
6432        unknown: unknown$2,
6433        nu: nu$2,
6434        windows: constant(windows$1),
6435        ios: constant(ios),
6436        android: constant(android),
6437        linux: constant(linux),
6438        osx: constant(osx),
6439        solaris: constant(solaris),
6440        freebsd: constant(freebsd)
6441      };
6442  
6443      var DeviceType = function (os, browser, userAgent) {
6444        var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true;
6445        var isiPhone = os.isiOS() && !isiPad;
6446        var isAndroid3 = os.isAndroid() && os.version.major === 3;
6447        var isAndroid4 = os.isAndroid() && os.version.major === 4;
6448        var isTablet = isiPad || isAndroid3 || isAndroid4 && /mobile/i.test(userAgent) === true;
6449        var isTouch = os.isiOS() || os.isAndroid();
6450        var isPhone = isTouch && !isTablet;
6451        var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false;
6452        return {
6453          isiPad: constant(isiPad),
6454          isiPhone: constant(isiPhone),
6455          isTablet: constant(isTablet),
6456          isPhone: constant(isPhone),
6457          isTouch: constant(isTouch),
6458          isAndroid: os.isAndroid,
6459          isiOS: os.isiOS,
6460          isWebView: constant(iOSwebview)
6461        };
6462      };
6463  
6464      var detect$1 = function (candidates, userAgent) {
6465        var agent = String(userAgent).toLowerCase();
6466        return find(candidates, function (candidate) {
6467          return candidate.search(agent);
6468        });
6469      };
6470      var detectBrowser = function (browsers, userAgent) {
6471        return detect$1(browsers, userAgent).map(function (browser) {
6472          var version = Version.detect(browser.versionRegexes, userAgent);
6473          return {
6474            current: browser.name,
6475            version: version
6476          };
6477        });
6478      };
6479      var detectOs = function (oses, userAgent) {
6480        return detect$1(oses, userAgent).map(function (os) {
6481          var version = Version.detect(os.versionRegexes, userAgent);
6482          return {
6483            current: os.name,
6484            version: version
6485          };
6486        });
6487      };
6488      var UaString = {
6489        detectBrowser: detectBrowser,
6490        detectOs: detectOs
6491      };
6492  
6493      var contains = function (str, substr) {
6494        return str.indexOf(substr) !== -1;
6495      };
6496  
6497      var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/;
6498      var checkContains = function (target) {
6499        return function (uastring) {
6500          return contains(uastring, target);
6501        };
6502      };
6503      var browsers = [
6504        {
6505          name: 'Edge',
6506          versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/],
6507          search: function (uastring) {
6508            var monstrosity = contains(uastring, 'edge/') && contains(uastring, 'chrome') && contains(uastring, 'safari') && contains(uastring, 'applewebkit');
6509            return monstrosity;
6510          }
6511        },
6512        {
6513          name: 'Chrome',
6514          versionRegexes: [
6515            /.*?chrome\/([0-9]+)\.([0-9]+).*/,
6516            normalVersionRegex
6517          ],
6518          search: function (uastring) {
6519            return contains(uastring, 'chrome') && !contains(uastring, 'chromeframe');
6520          }
6521        },
6522        {
6523          name: 'IE',
6524          versionRegexes: [
6525            /.*?msie\ ?([0-9]+)\.([0-9]+).*/,
6526            /.*?rv:([0-9]+)\.([0-9]+).*/
6527          ],
6528          search: function (uastring) {
6529            return contains(uastring, 'msie') || contains(uastring, 'trident');
6530          }
6531        },
6532        {
6533          name: 'Opera',
6534          versionRegexes: [
6535            normalVersionRegex,
6536            /.*?opera\/([0-9]+)\.([0-9]+).*/
6537          ],
6538          search: checkContains('opera')
6539        },
6540        {
6541          name: 'Firefox',
6542          versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/],
6543          search: checkContains('firefox')
6544        },
6545        {
6546          name: 'Safari',
6547          versionRegexes: [
6548            normalVersionRegex,
6549            /.*?cpu os ([0-9]+)_([0-9]+).*/
6550          ],
6551          search: function (uastring) {
6552            return (contains(uastring, 'safari') || contains(uastring, 'mobile/')) && contains(uastring, 'applewebkit');
6553          }
6554        }
6555      ];
6556      var oses = [
6557        {
6558          name: 'Windows',
6559          search: checkContains('win'),
6560          versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/]
6561        },
6562        {
6563          name: 'iOS',
6564          search: function (uastring) {
6565            return contains(uastring, 'iphone') || contains(uastring, 'ipad');
6566          },
6567          versionRegexes: [
6568            /.*?version\/\ ?([0-9]+)\.([0-9]+).*/,
6569            /.*cpu os ([0-9]+)_([0-9]+).*/,
6570            /.*cpu iphone os ([0-9]+)_([0-9]+).*/
6571          ]
6572        },
6573        {
6574          name: 'Android',
6575          search: checkContains('android'),
6576          versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/]
6577        },
6578        {
6579          name: 'OSX',
6580          search: checkContains('os x'),
6581          versionRegexes: [/.*?os\ x\ ?([0-9]+)_([0-9]+).*/]
6582        },
6583        {
6584          name: 'Linux',
6585          search: checkContains('linux'),
6586          versionRegexes: []
6587        },
6588        {
6589          name: 'Solaris',
6590          search: checkContains('sunos'),
6591          versionRegexes: []
6592        },
6593        {
6594          name: 'FreeBSD',
6595          search: checkContains('freebsd'),
6596          versionRegexes: []
6597        }
6598      ];
6599      var PlatformInfo = {
6600        browsers: constant(browsers),
6601        oses: constant(oses)
6602      };
6603  
6604      var detect$2 = function (userAgent) {
6605        var browsers = PlatformInfo.browsers();
6606        var oses = PlatformInfo.oses();
6607        var browser = UaString.detectBrowser(browsers, userAgent).fold(Browser.unknown, Browser.nu);
6608        var os = UaString.detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu);
6609        var deviceType = DeviceType(os, browser, userAgent);
6610        return {
6611          browser: browser,
6612          os: os,
6613          deviceType: deviceType
6614        };
6615      };
6616      var PlatformDetection = { detect: detect$2 };
6617  
6618      var detect$3 = cached(function () {
6619        var userAgent = domGlobals.navigator.userAgent;
6620        return PlatformDetection.detect(userAgent);
6621      });
6622      var PlatformDetection$1 = { detect: detect$3 };
6623  
6624      var ELEMENT$1 = ELEMENT;
6625      var DOCUMENT$1 = DOCUMENT;
6626      var bypassSelector = function (dom) {
6627        return dom.nodeType !== ELEMENT$1 && dom.nodeType !== DOCUMENT$1 || dom.childElementCount === 0;
6628      };
6629      var all = function (selector, scope) {
6630        var base = scope === undefined ? domGlobals.document : scope.dom();
6631        return bypassSelector(base) ? [] : map(base.querySelectorAll(selector), Element.fromDom);
6632      };
6633      var one = function (selector, scope) {
6634        var base = scope === undefined ? domGlobals.document : scope.dom();
6635        return bypassSelector(base) ? Option.none() : Option.from(base.querySelector(selector)).map(Element.fromDom);
6636      };
6637  
6638      var regularContains = function (e1, e2) {
6639        var d1 = e1.dom();
6640        var d2 = e2.dom();
6641        return d1 === d2 ? false : d1.contains(d2);
6642      };
6643      var ieContains = function (e1, e2) {
6644        return Node.documentPositionContainedBy(e1.dom(), e2.dom());
6645      };
6646      var browser = PlatformDetection$1.detect().browser;
6647      var contains$1 = browser.isIE() ? ieContains : regularContains;
6648  
6649      var spot = Immutable('element', 'offset');
6650  
6651      var descendants = function (scope, selector) {
6652        return all(selector, scope);
6653      };
6654  
6655      var trim = global$4.trim;
6656      var hasContentEditableState = function (value) {
6657        return function (node) {
6658          if (node && node.nodeType === 1) {
6659            if (node.contentEditable === value) {
6660              return true;
6661            }
6662            if (node.getAttribute('data-mce-contenteditable') === value) {
6663              return true;
6664            }
6665          }
6666          return false;
6667        };
6668      };
6669      var isContentEditableTrue = hasContentEditableState('true');
6670      var isContentEditableFalse = hasContentEditableState('false');
6671      var create$4 = function (type, title, url, level, attach) {
6672        return {
6673          type: type,
6674          title: title,
6675          url: url,
6676          level: level,
6677          attach: attach
6678        };
6679      };
6680      var isChildOfContentEditableTrue = function (node) {
6681        while (node = node.parentNode) {
6682          var value = node.contentEditable;
6683          if (value && value !== 'inherit') {
6684            return isContentEditableTrue(node);
6685          }
6686        }
6687        return false;
6688      };
6689      var select = function (selector, root) {
6690        return map(descendants(Element.fromDom(root), selector), function (element) {
6691          return element.dom();
6692        });
6693      };
6694      var getElementText = function (elm) {
6695        return elm.innerText || elm.textContent;
6696      };
6697      var getOrGenerateId = function (elm) {
6698        return elm.id ? elm.id : generate('h');
6699      };
6700      var isAnchor = function (elm) {
6701        return elm && elm.nodeName === 'A' && (elm.id || elm.name);
6702      };
6703      var isValidAnchor = function (elm) {
6704        return isAnchor(elm) && isEditable(elm);
6705      };
6706      var isHeader = function (elm) {
6707        return elm && /^(H[1-6])$/.test(elm.nodeName);
6708      };
6709      var isEditable = function (elm) {
6710        return isChildOfContentEditableTrue(elm) && !isContentEditableFalse(elm);
6711      };
6712      var isValidHeader = function (elm) {
6713        return isHeader(elm) && isEditable(elm);
6714      };
6715      var getLevel = function (elm) {
6716        return isHeader(elm) ? parseInt(elm.nodeName.substr(1), 10) : 0;
6717      };
6718      var headerTarget = function (elm) {
6719        var headerId = getOrGenerateId(elm);
6720        var attach = function () {
6721          elm.id = headerId;
6722        };
6723        return create$4('header', getElementText(elm), '#' + headerId, getLevel(elm), attach);
6724      };
6725      var anchorTarget = function (elm) {
6726        var anchorId = elm.id || elm.name;
6727        var anchorText = getElementText(elm);
6728        return create$4('anchor', anchorText ? anchorText : '#' + anchorId, '#' + anchorId, 0, noop);
6729      };
6730      var getHeaderTargets = function (elms) {
6731        return map(filter(elms, isValidHeader), headerTarget);
6732      };
6733      var getAnchorTargets = function (elms) {
6734        return map(filter(elms, isValidAnchor), anchorTarget);
6735      };
6736      var getTargetElements = function (elm) {
6737        var elms = select('h1,h2,h3,h4,h5,h6,a:not([href])', elm);
6738        return elms;
6739      };
6740      var hasTitle = function (target) {
6741        return trim(target.title).length > 0;
6742      };
6743      var find$2 = function (elm) {
6744        var elms = getTargetElements(elm);
6745        return filter(getHeaderTargets(elms).concat(getAnchorTargets(elms)), hasTitle);
6746      };
6747      var LinkTargets = { find: find$2 };
6748  
6749      var getActiveEditor = function () {
6750        return window.tinymce ? window.tinymce.activeEditor : global$5.activeEditor;
6751      };
6752      var history = {};
6753      var HISTORY_LENGTH = 5;
6754      var clearHistory = function () {
6755        history = {};
6756      };
6757      var toMenuItem = function (target) {
6758        return {
6759          title: target.title,
6760          value: {
6761            title: { raw: target.title },
6762            url: target.url,
6763            attach: target.attach
6764          }
6765        };
6766      };
6767      var toMenuItems = function (targets) {
6768        return global$4.map(targets, toMenuItem);
6769      };
6770      var staticMenuItem = function (title, url) {
6771        return {
6772          title: title,
6773          value: {
6774            title: title,
6775            url: url,
6776            attach: noop
6777          }
6778        };
6779      };
6780      var isUniqueUrl = function (url, targets) {
6781        var foundTarget = exists(targets, function (target) {
6782          return target.url === url;
6783        });
6784        return !foundTarget;
6785      };
6786      var getSetting = function (editorSettings, name, defaultValue) {
6787        var value = name in editorSettings ? editorSettings[name] : defaultValue;
6788        return value === false ? null : value;
6789      };
6790      var createMenuItems = function (term, targets, fileType, editorSettings) {
6791        var separator = { title: '-' };
6792        var fromHistoryMenuItems = function (history) {
6793          var historyItems = history.hasOwnProperty(fileType) ? history[fileType] : [];
6794          var uniqueHistory = filter(historyItems, function (url) {
6795            return isUniqueUrl(url, targets);
6796          });
6797          return global$4.map(uniqueHistory, function (url) {
6798            return {
6799              title: url,
6800              value: {
6801                title: url,
6802                url: url,
6803                attach: noop
6804              }
6805            };
6806          });
6807        };
6808        var fromMenuItems = function (type) {
6809          var filteredTargets = filter(targets, function (target) {
6810            return target.type === type;
6811          });
6812          return toMenuItems(filteredTargets);
6813        };
6814        var anchorMenuItems = function () {
6815          var anchorMenuItems = fromMenuItems('anchor');
6816          var topAnchor = getSetting(editorSettings, 'anchor_top', '#top');
6817          var bottomAchor = getSetting(editorSettings, 'anchor_bottom', '#bottom');
6818          if (topAnchor !== null) {
6819            anchorMenuItems.unshift(staticMenuItem('<top>', topAnchor));
6820          }
6821          if (bottomAchor !== null) {
6822            anchorMenuItems.push(staticMenuItem('<bottom>', bottomAchor));
6823          }
6824          return anchorMenuItems;
6825        };
6826        var join = function (items) {
6827          return foldl(items, function (a, b) {
6828            var bothEmpty = a.length === 0 || b.length === 0;
6829            return bothEmpty ? a.concat(b) : a.concat(separator, b);
6830          }, []);
6831        };
6832        if (editorSettings.typeahead_urls === false) {
6833          return [];
6834        }
6835        return fileType === 'file' ? join([
6836          filterByQuery(term, fromHistoryMenuItems(history)),
6837          filterByQuery(term, fromMenuItems('header')),
6838          filterByQuery(term, anchorMenuItems())
6839        ]) : filterByQuery(term, fromHistoryMenuItems(history));
6840      };
6841      var addToHistory = function (url, fileType) {
6842        var items = history[fileType];
6843        if (!/^https?/.test(url)) {
6844          return;
6845        }
6846        if (items) {
6847          if (indexOf(items, url).isNone()) {
6848            history[fileType] = items.slice(0, HISTORY_LENGTH).concat(url);
6849          }
6850        } else {
6851          history[fileType] = [url];
6852        }
6853      };
6854      var filterByQuery = function (term, menuItems) {
6855        var lowerCaseTerm = term.toLowerCase();
6856        var result = global$4.grep(menuItems, function (item) {
6857          return item.title.toLowerCase().indexOf(lowerCaseTerm) !== -1;
6858        });
6859        return result.length === 1 && result[0].title === term ? [] : result;
6860      };
6861      var getTitle = function (linkDetails) {
6862        var title = linkDetails.title;
6863        return title.raw ? title.raw : title;
6864      };
6865      var setupAutoCompleteHandler = function (ctrl, editorSettings, bodyElm, fileType) {
6866        var autocomplete = function (term) {
6867          var linkTargets = LinkTargets.find(bodyElm);
6868          var menuItems = createMenuItems(term, linkTargets, fileType, editorSettings);
6869          ctrl.showAutoComplete(menuItems, term);
6870        };
6871        ctrl.on('autocomplete', function () {
6872          autocomplete(ctrl.value());
6873        });
6874        ctrl.on('selectitem', function (e) {
6875          var linkDetails = e.value;
6876          ctrl.value(linkDetails.url);
6877          var title = getTitle(linkDetails);
6878          if (fileType === 'image') {
6879            ctrl.fire('change', {
6880              meta: {
6881                alt: title,
6882                attach: linkDetails.attach
6883              }
6884            });
6885          } else {
6886            ctrl.fire('change', {
6887              meta: {
6888                text: title,
6889                attach: linkDetails.attach
6890              }
6891            });
6892          }
6893          ctrl.focus();
6894        });
6895        ctrl.on('click', function (e) {
6896          if (ctrl.value().length === 0 && e.target.nodeName === 'INPUT') {
6897            autocomplete('');
6898          }
6899        });
6900        ctrl.on('PostRender', function () {
6901          ctrl.getRoot().on('submit', function (e) {
6902            if (!e.isDefaultPrevented()) {
6903              addToHistory(ctrl.value(), fileType);
6904            }
6905          });
6906        });
6907      };
6908      var statusToUiState = function (result) {
6909        var status = result.status, message = result.message;
6910        if (status === 'valid') {
6911          return {
6912            status: 'ok',
6913            message: message
6914          };
6915        } else if (status === 'unknown') {
6916          return {
6917            status: 'warn',
6918            message: message
6919          };
6920        } else if (status === 'invalid') {
6921          return {
6922            status: 'warn',
6923            message: message
6924          };
6925        } else {
6926          return {
6927            status: 'none',
6928            message: ''
6929          };
6930        }
6931      };
6932      var setupLinkValidatorHandler = function (ctrl, editorSettings, fileType) {
6933        var validatorHandler = editorSettings.filepicker_validator_handler;
6934        if (validatorHandler) {
6935          var validateUrl_1 = function (url) {
6936            if (url.length === 0) {
6937              ctrl.statusLevel('none');
6938              return;
6939            }
6940            validatorHandler({
6941              url: url,
6942              type: fileType
6943            }, function (result) {
6944              var uiState = statusToUiState(result);
6945              ctrl.statusMessage(uiState.message);
6946              ctrl.statusLevel(uiState.status);
6947            });
6948          };
6949          ctrl.state.on('change:value', function (e) {
6950            validateUrl_1(e.value);
6951          });
6952        }
6953      };
6954      var FilePicker = ComboBox.extend({
6955        Statics: { clearHistory: clearHistory },
6956        init: function (settings) {
6957          var self = this, editor = getActiveEditor(), editorSettings = editor.settings;
6958          var actionCallback, fileBrowserCallback, fileBrowserCallbackTypes;
6959          var fileType = settings.filetype;
6960          settings.spellcheck = false;
6961          fileBrowserCallbackTypes = editorSettings.file_picker_types || editorSettings.file_browser_callback_types;
6962          if (fileBrowserCallbackTypes) {
6963            fileBrowserCallbackTypes = global$4.makeMap(fileBrowserCallbackTypes, /[, ]/);
6964          }
6965          if (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[fileType]) {
6966            fileBrowserCallback = editorSettings.file_picker_callback;
6967            if (fileBrowserCallback && (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[fileType])) {
6968              actionCallback = function () {
6969                var meta = self.fire('beforecall').meta;
6970                meta = global$4.extend({ filetype: fileType }, meta);
6971                fileBrowserCallback.call(editor, function (value, meta) {
6972                  self.value(value).fire('change', { meta: meta });
6973                }, self.value(), meta);
6974              };
6975            } else {
6976              fileBrowserCallback = editorSettings.file_browser_callback;
6977              if (fileBrowserCallback && (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[fileType])) {
6978                actionCallback = function () {
6979                  fileBrowserCallback(self.getEl('inp').id, self.value(), fileType, window);
6980                };
6981              }
6982            }
6983          }
6984          if (actionCallback) {
6985            settings.icon = 'browse';
6986            settings.onaction = actionCallback;
6987          }
6988          self._super(settings);
6989          self.classes.add('filepicker');
6990          setupAutoCompleteHandler(self, editorSettings, editor.getBody(), fileType);
6991          setupLinkValidatorHandler(self, editorSettings, fileType);
6992        }
6993      });
6994  
6995      var FitLayout = AbsoluteLayout.extend({
6996        recalc: function (container) {
6997          var contLayoutRect = container.layoutRect(), paddingBox = container.paddingBox;
6998          container.items().filter(':visible').each(function (ctrl) {
6999            ctrl.layoutRect({
7000              x: paddingBox.left,
7001              y: paddingBox.top,
7002              w: contLayoutRect.innerW - paddingBox.right - paddingBox.left,
7003              h: contLayoutRect.innerH - paddingBox.top - paddingBox.bottom
7004            });
7005            if (ctrl.recalc) {
7006              ctrl.recalc();
7007            }
7008          });
7009        }
7010      });
7011  
7012      var FlexLayout = AbsoluteLayout.extend({
7013        recalc: function (container) {
7014          var i, l, items, contLayoutRect, contPaddingBox, contSettings, align, pack, spacing, totalFlex, availableSpace, direction;
7015          var ctrl, ctrlLayoutRect, ctrlSettings, flex;
7016          var maxSizeItems = [];
7017          var size, maxSize, ratio, rect, pos, maxAlignEndPos;
7018          var sizeName, minSizeName, posName, maxSizeName, beforeName, innerSizeName, deltaSizeName, contentSizeName;
7019          var alignAxisName, alignInnerSizeName, alignSizeName, alignMinSizeName, alignBeforeName, alignAfterName;
7020          var alignDeltaSizeName, alignContentSizeName;
7021          var max = Math.max, min = Math.min;
7022          items = container.items().filter(':visible');
7023          contLayoutRect = container.layoutRect();
7024          contPaddingBox = container.paddingBox;
7025          contSettings = container.settings;
7026          direction = container.isRtl() ? contSettings.direction || 'row-reversed' : contSettings.direction;
7027          align = contSettings.align;
7028          pack = container.isRtl() ? contSettings.pack || 'end' : contSettings.pack;
7029          spacing = contSettings.spacing || 0;
7030          if (direction === 'row-reversed' || direction === 'column-reverse') {
7031            items = items.set(items.toArray().reverse());
7032            direction = direction.split('-')[0];
7033          }
7034          if (direction === 'column') {
7035            posName = 'y';
7036            sizeName = 'h';
7037            minSizeName = 'minH';
7038            maxSizeName = 'maxH';
7039            innerSizeName = 'innerH';
7040            beforeName = 'top';
7041            deltaSizeName = 'deltaH';
7042            contentSizeName = 'contentH';
7043            alignBeforeName = 'left';
7044            alignSizeName = 'w';
7045            alignAxisName = 'x';
7046            alignInnerSizeName = 'innerW';
7047            alignMinSizeName = 'minW';
7048            alignAfterName = 'right';
7049            alignDeltaSizeName = 'deltaW';
7050            alignContentSizeName = 'contentW';
7051          } else {
7052            posName = 'x';
7053            sizeName = 'w';
7054            minSizeName = 'minW';
7055            maxSizeName = 'maxW';
7056            innerSizeName = 'innerW';
7057            beforeName = 'left';
7058            deltaSizeName = 'deltaW';
7059            contentSizeName = 'contentW';
7060            alignBeforeName = 'top';
7061            alignSizeName = 'h';
7062            alignAxisName = 'y';
7063            alignInnerSizeName = 'innerH';
7064            alignMinSizeName = 'minH';
7065            alignAfterName = 'bottom';
7066            alignDeltaSizeName = 'deltaH';
7067            alignContentSizeName = 'contentH';
7068          }
7069          availableSpace = contLayoutRect[innerSizeName] - contPaddingBox[beforeName] - contPaddingBox[beforeName];
7070          maxAlignEndPos = totalFlex = 0;
7071          for (i = 0, l = items.length; i < l; i++) {
7072            ctrl = items[i];
7073            ctrlLayoutRect = ctrl.layoutRect();
7074            ctrlSettings = ctrl.settings;
7075            flex = ctrlSettings.flex;
7076            availableSpace -= i < l - 1 ? spacing : 0;
7077            if (flex > 0) {
7078              totalFlex += flex;
7079              if (ctrlLayoutRect[maxSizeName]) {
7080                maxSizeItems.push(ctrl);
7081              }
7082              ctrlLayoutRect.flex = flex;
7083            }
7084            availableSpace -= ctrlLayoutRect[minSizeName];
7085            size = contPaddingBox[alignBeforeName] + ctrlLayoutRect[alignMinSizeName] + contPaddingBox[alignAfterName];
7086            if (size > maxAlignEndPos) {
7087              maxAlignEndPos = size;
7088            }
7089          }
7090          rect = {};
7091          if (availableSpace < 0) {
7092            rect[minSizeName] = contLayoutRect[minSizeName] - availableSpace + contLayoutRect[deltaSizeName];
7093          } else {
7094            rect[minSizeName] = contLayoutRect[innerSizeName] - availableSpace + contLayoutRect[deltaSizeName];
7095          }
7096          rect[alignMinSizeName] = maxAlignEndPos + contLayoutRect[alignDeltaSizeName];
7097          rect[contentSizeName] = contLayoutRect[innerSizeName] - availableSpace;
7098          rect[alignContentSizeName] = maxAlignEndPos;
7099          rect.minW = min(rect.minW, contLayoutRect.maxW);
7100          rect.minH = min(rect.minH, contLayoutRect.maxH);
7101          rect.minW = max(rect.minW, contLayoutRect.startMinWidth);
7102          rect.minH = max(rect.minH, contLayoutRect.startMinHeight);
7103          if (contLayoutRect.autoResize && (rect.minW !== contLayoutRect.minW || rect.minH !== contLayoutRect.minH)) {
7104            rect.w = rect.minW;
7105            rect.h = rect.minH;
7106            container.layoutRect(rect);
7107            this.recalc(container);
7108            if (container._lastRect === null) {
7109              var parentCtrl = container.parent();
7110              if (parentCtrl) {
7111                parentCtrl._lastRect = null;
7112                parentCtrl.recalc();
7113              }
7114            }
7115            return;
7116          }
7117          ratio = availableSpace / totalFlex;
7118          for (i = 0, l = maxSizeItems.length; i < l; i++) {
7119            ctrl = maxSizeItems[i];
7120            ctrlLayoutRect = ctrl.layoutRect();
7121            maxSize = ctrlLayoutRect[maxSizeName];
7122            size = ctrlLayoutRect[minSizeName] + ctrlLayoutRect.flex * ratio;
7123            if (size > maxSize) {
7124              availableSpace -= ctrlLayoutRect[maxSizeName] - ctrlLayoutRect[minSizeName];
7125              totalFlex -= ctrlLayoutRect.flex;
7126              ctrlLayoutRect.flex = 0;
7127              ctrlLayoutRect.maxFlexSize = maxSize;
7128            } else {
7129              ctrlLayoutRect.maxFlexSize = 0;
7130            }
7131          }
7132          ratio = availableSpace / totalFlex;
7133          pos = contPaddingBox[beforeName];
7134          rect = {};
7135          if (totalFlex === 0) {
7136            if (pack === 'end') {
7137              pos = availableSpace + contPaddingBox[beforeName];
7138            } else if (pack === 'center') {
7139              pos = Math.round(contLayoutRect[innerSizeName] / 2 - (contLayoutRect[innerSizeName] - availableSpace) / 2) + contPaddingBox[beforeName];
7140              if (pos < 0) {
7141                pos = contPaddingBox[beforeName];
7142              }
7143            } else if (pack === 'justify') {
7144              pos = contPaddingBox[beforeName];
7145              spacing = Math.floor(availableSpace / (items.length - 1));
7146            }
7147          }
7148          rect[alignAxisName] = contPaddingBox[alignBeforeName];
7149          for (i = 0, l = items.length; i < l; i++) {
7150            ctrl = items[i];
7151            ctrlLayoutRect = ctrl.layoutRect();
7152            size = ctrlLayoutRect.maxFlexSize || ctrlLayoutRect[minSizeName];
7153            if (align === 'center') {
7154              rect[alignAxisName] = Math.round(contLayoutRect[alignInnerSizeName] / 2 - ctrlLayoutRect[alignSizeName] / 2);
7155            } else if (align === 'stretch') {
7156              rect[alignSizeName] = max(ctrlLayoutRect[alignMinSizeName] || 0, contLayoutRect[alignInnerSizeName] - contPaddingBox[alignBeforeName] - contPaddingBox[alignAfterName]);
7157              rect[alignAxisName] = contPaddingBox[alignBeforeName];
7158            } else if (align === 'end') {
7159              rect[alignAxisName] = contLayoutRect[alignInnerSizeName] - ctrlLayoutRect[alignSizeName] - contPaddingBox.top;
7160            }
7161            if (ctrlLayoutRect.flex > 0) {
7162              size += ctrlLayoutRect.flex * ratio;
7163            }
7164            rect[sizeName] = size;
7165            rect[posName] = pos;
7166            ctrl.layoutRect(rect);
7167            if (ctrl.recalc) {
7168              ctrl.recalc();
7169            }
7170            pos += size + spacing;
7171          }
7172        }
7173      });
7174  
7175      var FlowLayout = Layout$1.extend({
7176        Defaults: {
7177          containerClass: 'flow-layout',
7178          controlClass: 'flow-layout-item',
7179          endClass: 'break'
7180        },
7181        recalc: function (container) {
7182          container.items().filter(':visible').each(function (ctrl) {
7183            if (ctrl.recalc) {
7184              ctrl.recalc();
7185            }
7186          });
7187        },
7188        isNative: function () {
7189          return true;
7190        }
7191      });
7192  
7193      var descendant = function (scope, selector) {
7194        return one(selector, scope);
7195      };
7196  
7197      var toggleFormat = function (editor, fmt) {
7198        return function () {
7199          editor.execCommand('mceToggleFormat', false, fmt);
7200        };
7201      };
7202      var addFormatChangedListener = function (editor, name, changed) {
7203        var handler = function (state) {
7204          changed(state, name);
7205        };
7206        if (editor.formatter) {
7207          editor.formatter.formatChanged(name, handler);
7208        } else {
7209          editor.on('init', function () {
7210            editor.formatter.formatChanged(name, handler);
7211          });
7212        }
7213      };
7214      var postRenderFormatToggle = function (editor, name) {
7215        return function (e) {
7216          addFormatChangedListener(editor, name, function (state) {
7217            e.control.active(state);
7218          });
7219        };
7220      };
7221  
7222      var register = function (editor) {
7223        var alignFormats = [
7224          'alignleft',
7225          'aligncenter',
7226          'alignright',
7227          'alignjustify'
7228        ];
7229        var defaultAlign = 'alignleft';
7230        var alignMenuItems = [
7231          {
7232            text: 'Left',
7233            icon: 'alignleft',
7234            onclick: toggleFormat(editor, 'alignleft')
7235          },
7236          {
7237            text: 'Center',
7238            icon: 'aligncenter',
7239            onclick: toggleFormat(editor, 'aligncenter')
7240          },
7241          {
7242            text: 'Right',
7243            icon: 'alignright',
7244            onclick: toggleFormat(editor, 'alignright')
7245          },
7246          {
7247            text: 'Justify',
7248            icon: 'alignjustify',
7249            onclick: toggleFormat(editor, 'alignjustify')
7250          }
7251        ];
7252        editor.addMenuItem('align', {
7253          text: 'Align',
7254          menu: alignMenuItems
7255        });
7256        editor.addButton('align', {
7257          type: 'menubutton',
7258          icon: defaultAlign,
7259          menu: alignMenuItems,
7260          onShowMenu: function (e) {
7261            var menu = e.control.menu;
7262            global$4.each(alignFormats, function (formatName, idx) {
7263              menu.items().eq(idx).each(function (item) {
7264                return item.active(editor.formatter.match(formatName));
7265              });
7266            });
7267          },
7268          onPostRender: function (e) {
7269            var ctrl = e.control;
7270            global$4.each(alignFormats, function (formatName, idx) {
7271              addFormatChangedListener(editor, formatName, function (state) {
7272                ctrl.icon(defaultAlign);
7273                if (state) {
7274                  ctrl.icon(formatName);
7275                }
7276              });
7277            });
7278          }
7279        });
7280        global$4.each({
7281          alignleft: [
7282            'Align left',
7283            'JustifyLeft'
7284          ],
7285          aligncenter: [
7286            'Align center',
7287            'JustifyCenter'
7288          ],
7289          alignright: [
7290            'Align right',
7291            'JustifyRight'
7292          ],
7293          alignjustify: [
7294            'Justify',
7295            'JustifyFull'
7296          ],
7297          alignnone: [
7298            'No alignment',
7299            'JustifyNone'
7300          ]
7301        }, function (item, name) {
7302          editor.addButton(name, {
7303            active: false,
7304            tooltip: item[0],
7305            cmd: item[1],
7306            onPostRender: postRenderFormatToggle(editor, name)
7307          });
7308        });
7309      };
7310      var Align = { register: register };
7311  
7312      var getFirstFont = function (fontFamily) {
7313        return fontFamily ? fontFamily.split(',')[0] : '';
7314      };
7315      var findMatchingValue = function (items, fontFamily) {
7316        var font = fontFamily ? fontFamily.toLowerCase() : '';
7317        var value;
7318        global$4.each(items, function (item) {
7319          if (item.value.toLowerCase() === font) {
7320            value = item.value;
7321          }
7322        });
7323        global$4.each(items, function (item) {
7324          if (!value && getFirstFont(item.value).toLowerCase() === getFirstFont(font).toLowerCase()) {
7325            value = item.value;
7326          }
7327        });
7328        return value;
7329      };
7330      var createFontNameListBoxChangeHandler = function (editor, items) {
7331        return function () {
7332          var self = this;
7333          self.state.set('value', null);
7334          editor.on('init nodeChange', function (e) {
7335            var fontFamily = editor.queryCommandValue('FontName');
7336            var match = findMatchingValue(items, fontFamily);
7337            self.value(match ? match : null);
7338            if (!match && fontFamily) {
7339              self.text(getFirstFont(fontFamily));
7340            }
7341          });
7342        };
7343      };
7344      var createFormats = function (formats) {
7345        formats = formats.replace(/;$/, '').split(';');
7346        var i = formats.length;
7347        while (i--) {
7348          formats[i] = formats[i].split('=');
7349        }
7350        return formats;
7351      };
7352      var getFontItems = function (editor) {
7353        var defaultFontsFormats = 'Andale Mono=andale mono,monospace;' + 'Arial=arial,helvetica,sans-serif;' + 'Arial Black=arial black,sans-serif;' + 'Book Antiqua=book antiqua,palatino,serif;' + 'Comic Sans MS=comic sans ms,sans-serif;' + 'Courier New=courier new,courier,monospace;' + 'Georgia=georgia,palatino,serif;' + 'Helvetica=helvetica,arial,sans-serif;' + 'Impact=impact,sans-serif;' + 'Symbol=symbol;' + 'Tahoma=tahoma,arial,helvetica,sans-serif;' + 'Terminal=terminal,monaco,monospace;' + 'Times New Roman=times new roman,times,serif;' + 'Trebuchet MS=trebuchet ms,geneva,sans-serif;' + 'Verdana=verdana,geneva,sans-serif;' + 'Webdings=webdings;' + 'Wingdings=wingdings,zapf dingbats';
7354        var fonts = createFormats(editor.settings.font_formats || defaultFontsFormats);
7355        return global$4.map(fonts, function (font) {
7356          return {
7357            text: { raw: font[0] },
7358            value: font[1],
7359            textStyle: font[1].indexOf('dings') === -1 ? 'font-family:' + font[1] : ''
7360          };
7361        });
7362      };
7363      var registerButtons = function (editor) {
7364        editor.addButton('fontselect', function () {
7365          var items = getFontItems(editor);
7366          return {
7367            type: 'listbox',
7368            text: 'Font Family',
7369            tooltip: 'Font Family',
7370            values: items,
7371            fixedWidth: true,
7372            onPostRender: createFontNameListBoxChangeHandler(editor, items),
7373            onselect: function (e) {
7374              if (e.control.settings.value) {
7375                editor.execCommand('FontName', false, e.control.settings.value);
7376              }
7377            }
7378          };
7379        });
7380      };
7381      var register$1 = function (editor) {
7382        registerButtons(editor);
7383      };
7384      var FontSelect = { register: register$1 };
7385  
7386      var round = function (number, precision) {
7387        var factor = Math.pow(10, precision);
7388        return Math.round(number * factor) / factor;
7389      };
7390      var toPt = function (fontSize, precision) {
7391        if (/[0-9.]+px$/.test(fontSize)) {
7392          return round(parseInt(fontSize, 10) * 72 / 96, precision || 0) + 'pt';
7393        }
7394        return fontSize;
7395      };
7396      var findMatchingValue$1 = function (items, pt, px) {
7397        var value;
7398        global$4.each(items, function (item) {
7399          if (item.value === px) {
7400            value = px;
7401          } else if (item.value === pt) {
7402            value = pt;
7403          }
7404        });
7405        return value;
7406      };
7407      var createFontSizeListBoxChangeHandler = function (editor, items) {
7408        return function () {
7409          var self = this;
7410          editor.on('init nodeChange', function (e) {
7411            var px, pt, precision, match;
7412            px = editor.queryCommandValue('FontSize');
7413            if (px) {
7414              for (precision = 3; !match && precision >= 0; precision--) {
7415                pt = toPt(px, precision);
7416                match = findMatchingValue$1(items, pt, px);
7417              }
7418            }
7419            self.value(match ? match : null);
7420            if (!match) {
7421              self.text(pt);
7422            }
7423          });
7424        };
7425      };
7426      var getFontSizeItems = function (editor) {
7427        var defaultFontsizeFormats = '8pt 10pt 12pt 14pt 18pt 24pt 36pt';
7428        var fontsizeFormats = editor.settings.fontsize_formats || defaultFontsizeFormats;
7429        return global$4.map(fontsizeFormats.split(' '), function (item) {
7430          var text = item, value = item;
7431          var values = item.split('=');
7432          if (values.length > 1) {
7433            text = values[0];
7434            value = values[1];
7435          }
7436          return {
7437            text: text,
7438            value: value
7439          };
7440        });
7441      };
7442      var registerButtons$1 = function (editor) {
7443        editor.addButton('fontsizeselect', function () {
7444          var items = getFontSizeItems(editor);
7445          return {
7446            type: 'listbox',
7447            text: 'Font Sizes',
7448            tooltip: 'Font Sizes',
7449            values: items,
7450            fixedWidth: true,
7451            onPostRender: createFontSizeListBoxChangeHandler(editor, items),
7452            onclick: function (e) {
7453              if (e.control.settings.value) {
7454                editor.execCommand('FontSize', false, e.control.settings.value);
7455              }
7456            }
7457          };
7458        });
7459      };
7460      var register$2 = function (editor) {
7461        registerButtons$1(editor);
7462      };
7463      var FontSizeSelect = { register: register$2 };
7464  
7465      var hideMenuObjects = function (editor, menu) {
7466        var count = menu.length;
7467        global$4.each(menu, function (item) {
7468          if (item.menu) {
7469            item.hidden = hideMenuObjects(editor, item.menu) === 0;
7470          }
7471          var formatName = item.format;
7472          if (formatName) {
7473            item.hidden = !editor.formatter.canApply(formatName);
7474          }
7475          if (item.hidden) {
7476            count--;
7477          }
7478        });
7479        return count;
7480      };
7481      var hideFormatMenuItems = function (editor, menu) {
7482        var count = menu.items().length;
7483        menu.items().each(function (item) {
7484          if (item.menu) {
7485            item.visible(hideFormatMenuItems(editor, item.menu) > 0);
7486          }
7487          if (!item.menu && item.settings.menu) {
7488            item.visible(hideMenuObjects(editor, item.settings.menu) > 0);
7489          }
7490          var formatName = item.settings.format;
7491          if (formatName) {
7492            item.visible(editor.formatter.canApply(formatName));
7493          }
7494          if (!item.visible()) {
7495            count--;
7496          }
7497        });
7498        return count;
7499      };
7500      var createFormatMenu = function (editor) {
7501        var count = 0;
7502        var newFormats = [];
7503        var defaultStyleFormats = [
7504          {
7505            title: 'Headings',
7506            items: [
7507              {
7508                title: 'Heading 1',
7509                format: 'h1'
7510              },
7511              {
7512                title: 'Heading 2',
7513                format: 'h2'
7514              },
7515              {
7516                title: 'Heading 3',
7517                format: 'h3'
7518              },
7519              {
7520                title: 'Heading 4',
7521                format: 'h4'
7522              },
7523              {
7524                title: 'Heading 5',
7525                format: 'h5'
7526              },
7527              {
7528                title: 'Heading 6',
7529                format: 'h6'
7530              }
7531            ]
7532          },
7533          {
7534            title: 'Inline',
7535            items: [
7536              {
7537                title: 'Bold',
7538                icon: 'bold',
7539                format: 'bold'
7540              },
7541              {
7542                title: 'Italic',
7543                icon: 'italic',
7544                format: 'italic'
7545              },
7546              {
7547                title: 'Underline',
7548                icon: 'underline',
7549                format: 'underline'
7550              },
7551              {
7552                title: 'Strikethrough',
7553                icon: 'strikethrough',
7554                format: 'strikethrough'
7555              },
7556              {
7557                title: 'Superscript',
7558                icon: 'superscript',
7559                format: 'superscript'
7560              },
7561              {
7562                title: 'Subscript',
7563                icon: 'subscript',
7564                format: 'subscript'
7565              },
7566              {
7567                title: 'Code',
7568                icon: 'code',
7569                format: 'code'
7570              }
7571            ]
7572          },
7573          {
7574            title: 'Blocks',
7575            items: [
7576              {
7577                title: 'Paragraph',
7578                format: 'p'
7579              },
7580              {
7581                title: 'Blockquote',
7582                format: 'blockquote'
7583              },
7584              {
7585                title: 'Div',
7586                format: 'div'
7587              },
7588              {
7589                title: 'Pre',
7590                format: 'pre'
7591              }
7592            ]
7593          },
7594          {
7595            title: 'Alignment',
7596            items: [
7597              {
7598                title: 'Left',
7599                icon: 'alignleft',
7600                format: 'alignleft'
7601              },
7602              {
7603                title: 'Center',
7604                icon: 'aligncenter',
7605                format: 'aligncenter'
7606              },
7607              {
7608                title: 'Right',
7609                icon: 'alignright',
7610                format: 'alignright'
7611              },
7612              {
7613                title: 'Justify',
7614                icon: 'alignjustify',
7615                format: 'alignjustify'
7616              }
7617            ]
7618          }
7619        ];
7620        var createMenu = function (formats) {
7621          var menu = [];
7622          if (!formats) {
7623            return;
7624          }
7625          global$4.each(formats, function (format) {
7626            var menuItem = {
7627              text: format.title,
7628              icon: format.icon
7629            };
7630            if (format.items) {
7631              menuItem.menu = createMenu(format.items);
7632            } else {
7633              var formatName = format.format || 'custom' + count++;
7634              if (!format.format) {
7635                format.name = formatName;
7636                newFormats.push(format);
7637              }
7638              menuItem.format = formatName;
7639              menuItem.cmd = format.cmd;
7640            }
7641            menu.push(menuItem);
7642          });
7643          return menu;
7644        };
7645        var createStylesMenu = function () {
7646          var menu;
7647          if (editor.settings.style_formats_merge) {
7648            if (editor.settings.style_formats) {
7649              menu = createMenu(defaultStyleFormats.concat(editor.settings.style_formats));
7650            } else {
7651              menu = createMenu(defaultStyleFormats);
7652            }
7653          } else {
7654            menu = createMenu(editor.settings.style_formats || defaultStyleFormats);
7655          }
7656          return menu;
7657        };
7658        editor.on('init', function () {
7659          global$4.each(newFormats, function (format) {
7660            editor.formatter.register(format.name, format);
7661          });
7662        });
7663        return {
7664          type: 'menu',
7665          items: createStylesMenu(),
7666          onPostRender: function (e) {
7667            editor.fire('renderFormatsMenu', { control: e.control });
7668          },
7669          itemDefaults: {
7670            preview: true,
7671            textStyle: function () {
7672              if (this.settings.format) {
7673                return editor.formatter.getCssText(this.settings.format);
7674              }
7675            },
7676            onPostRender: function () {
7677              var self = this;
7678              self.parent().on('show', function () {
7679                var formatName, command;
7680                formatName = self.settings.format;
7681                if (formatName) {
7682                  self.disabled(!editor.formatter.canApply(formatName));
7683                  self.active(editor.formatter.match(formatName));
7684                }
7685                command = self.settings.cmd;
7686                if (command) {
7687                  self.active(editor.queryCommandState(command));
7688                }
7689              });
7690            },
7691            onclick: function () {
7692              if (this.settings.format) {
7693                toggleFormat(editor, this.settings.format)();
7694              }
7695              if (this.settings.cmd) {
7696                editor.execCommand(this.settings.cmd);
7697              }
7698            }
7699          }
7700        };
7701      };
7702      var registerMenuItems = function (editor, formatMenu) {
7703        editor.addMenuItem('formats', {
7704          text: 'Formats',
7705          menu: formatMenu
7706        });
7707      };
7708      var registerButtons$2 = function (editor, formatMenu) {
7709        editor.addButton('styleselect', {
7710          type: 'menubutton',
7711          text: 'Formats',
7712          menu: formatMenu,
7713          onShowMenu: function () {
7714            if (editor.settings.style_formats_autohide) {
7715              hideFormatMenuItems(editor, this.menu);
7716            }
7717          }
7718        });
7719      };
7720      var register$3 = function (editor) {
7721        var formatMenu = createFormatMenu(editor);
7722        registerMenuItems(editor, formatMenu);
7723        registerButtons$2(editor, formatMenu);
7724      };
7725      var Formats = { register: register$3 };
7726  
7727      var defaultBlocks = 'Paragraph=p;' + 'Heading 1=h1;' + 'Heading 2=h2;' + 'Heading 3=h3;' + 'Heading 4=h4;' + 'Heading 5=h5;' + 'Heading 6=h6;' + 'Preformatted=pre';
7728      var createFormats$1 = function (formats) {
7729        formats = formats.replace(/;$/, '').split(';');
7730        var i = formats.length;
7731        while (i--) {
7732          formats[i] = formats[i].split('=');
7733        }
7734        return formats;
7735      };
7736      var createListBoxChangeHandler = function (editor, items, formatName) {
7737        return function () {
7738          var self = this;
7739          editor.on('nodeChange', function (e) {
7740            var formatter = editor.formatter;
7741            var value = null;
7742            global$4.each(e.parents, function (node) {
7743              global$4.each(items, function (item) {
7744                if (formatName) {
7745                  if (formatter.matchNode(node, formatName, { value: item.value })) {
7746                    value = item.value;
7747                  }
7748                } else {
7749                  if (formatter.matchNode(node, item.value)) {
7750                    value = item.value;
7751                  }
7752                }
7753                if (value) {
7754                  return false;
7755                }
7756              });
7757              if (value) {
7758                return false;
7759              }
7760            });
7761            self.value(value);
7762          });
7763        };
7764      };
7765      var lazyFormatSelectBoxItems = function (editor, blocks) {
7766        return function () {
7767          var items = [];
7768          global$4.each(blocks, function (block) {
7769            items.push({
7770              text: block[0],
7771              value: block[1],
7772              textStyle: function () {
7773                return editor.formatter.getCssText(block[1]);
7774              }
7775            });
7776          });
7777          return {
7778            type: 'listbox',
7779            text: blocks[0][0],
7780            values: items,
7781            fixedWidth: true,
7782            onselect: function (e) {
7783              if (e.control) {
7784                var fmt = e.control.value();
7785                toggleFormat(editor, fmt)();
7786              }
7787            },
7788            onPostRender: createListBoxChangeHandler(editor, items)
7789          };
7790        };
7791      };
7792      var buildMenuItems = function (editor, blocks) {
7793        return global$4.map(blocks, function (block) {
7794          return {
7795            text: block[0],
7796            onclick: toggleFormat(editor, block[1]),
7797            textStyle: function () {
7798              return editor.formatter.getCssText(block[1]);
7799            }
7800          };
7801        });
7802      };
7803      var register$4 = function (editor) {
7804        var blocks = createFormats$1(editor.settings.block_formats || defaultBlocks);
7805        editor.addMenuItem('blockformats', {
7806          text: 'Blocks',
7807          menu: buildMenuItems(editor, blocks)
7808        });
7809        editor.addButton('formatselect', lazyFormatSelectBoxItems(editor, blocks));
7810      };
7811      var FormatSelect = { register: register$4 };
7812  
7813      var createCustomMenuItems = function (editor, names) {
7814        var items, nameList;
7815        if (typeof names === 'string') {
7816          nameList = names.split(' ');
7817        } else if (global$4.isArray(names)) {
7818          return flatten$1(global$4.map(names, function (names) {
7819            return createCustomMenuItems(editor, names);
7820          }));
7821        }
7822        items = global$4.grep(nameList, function (name) {
7823          return name === '|' || name in editor.menuItems;
7824        });
7825        return global$4.map(items, function (name) {
7826          return name === '|' ? { text: '-' } : editor.menuItems[name];
7827        });
7828      };
7829      var isSeparator = function (menuItem) {
7830        return menuItem && menuItem.text === '-';
7831      };
7832      var trimMenuItems = function (menuItems) {
7833        var menuItems2 = filter(menuItems, function (menuItem, i, menuItems) {
7834          return !isSeparator(menuItem) || !isSeparator(menuItems[i - 1]);
7835        });
7836        return filter(menuItems2, function (menuItem, i, menuItems) {
7837          return !isSeparator(menuItem) || i > 0 && i < menuItems.length - 1;
7838        });
7839      };
7840      var createContextMenuItems = function (editor, context) {
7841        var outputMenuItems = [{ text: '-' }];
7842        var menuItems = global$4.grep(editor.menuItems, function (menuItem) {
7843          return menuItem.context === context;
7844        });
7845        global$4.each(menuItems, function (menuItem) {
7846          if (menuItem.separator === 'before') {
7847            outputMenuItems.push({ text: '|' });
7848          }
7849          if (menuItem.prependToContext) {
7850            outputMenuItems.unshift(menuItem);
7851          } else {
7852            outputMenuItems.push(menuItem);
7853          }
7854          if (menuItem.separator === 'after') {
7855            outputMenuItems.push({ text: '|' });
7856          }
7857        });
7858        return outputMenuItems;
7859      };
7860      var createInsertMenu = function (editor) {
7861        var insertButtonItems = editor.settings.insert_button_items;
7862        if (insertButtonItems) {
7863          return trimMenuItems(createCustomMenuItems(editor, insertButtonItems));
7864        } else {
7865          return trimMenuItems(createContextMenuItems(editor, 'insert'));
7866        }
7867      };
7868      var registerButtons$3 = function (editor) {
7869        editor.addButton('insert', {
7870          type: 'menubutton',
7871          icon: 'insert',
7872          menu: [],
7873          oncreatemenu: function () {
7874            this.menu.add(createInsertMenu(editor));
7875            this.menu.renderNew();
7876          }
7877        });
7878      };
7879      var register$5 = function (editor) {
7880        registerButtons$3(editor);
7881      };
7882      var InsertButton = { register: register$5 };
7883  
7884      var registerFormatButtons = function (editor) {
7885        global$4.each({
7886          bold: 'Bold',
7887          italic: 'Italic',
7888          underline: 'Underline',
7889          strikethrough: 'Strikethrough',
7890          subscript: 'Subscript',
7891          superscript: 'Superscript'
7892        }, function (text, name) {
7893          editor.addButton(name, {
7894            active: false,
7895            tooltip: text,
7896            onPostRender: postRenderFormatToggle(editor, name),
7897            onclick: toggleFormat(editor, name)
7898          });
7899        });
7900      };
7901      var registerCommandButtons = function (editor) {
7902        global$4.each({
7903          outdent: [
7904            'Decrease indent',
7905            'Outdent'
7906          ],
7907          indent: [
7908            'Increase indent',
7909            'Indent'
7910          ],
7911          cut: [
7912            'Cut',
7913            'Cut'
7914          ],
7915          copy: [
7916            'Copy',
7917            'Copy'
7918          ],
7919          paste: [
7920            'Paste',
7921            'Paste'
7922          ],
7923          help: [
7924            'Help',
7925            'mceHelp'
7926          ],
7927          selectall: [
7928            'Select all',
7929            'SelectAll'
7930          ],
7931          visualaid: [
7932            'Visual aids',
7933            'mceToggleVisualAid'
7934          ],
7935          newdocument: [
7936            'New document',
7937            'mceNewDocument'
7938          ],
7939          removeformat: [
7940            'Clear formatting',
7941            'RemoveFormat'
7942          ],
7943          remove: [
7944            'Remove',
7945            'Delete'
7946          ]
7947        }, function (item, name) {
7948          editor.addButton(name, {
7949            tooltip: item[0],
7950            cmd: item[1]
7951          });
7952        });
7953      };
7954      var registerCommandToggleButtons = function (editor) {
7955        global