[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

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

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