[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

title

Body

[close]

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

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