Wrapping 'div' element around appropriate blocks among the selected ranges. @param {Object} editor
197033
function createDiv( editor ) {
			// new adding containers OR detected pre-existed containers.
			var containers = [];
			// node markers store.
			var database = {};
			// All block level elements which contained by the ranges.
			var containedBlocks = [],
				block;

			// Get all ranges from the selection.
			var selection = editor.getSelection(),
				ranges = selection.getRanges();
			var bookmarks = selection.createBookmarks();
			var i, iterator;

			// Calcualte a default block tag if we need to create blocks.
			var blockTag = editor.config.enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p';

			// collect all included elements from dom-iterator
			for ( i = 0; i < ranges.length; i++ ) {
				iterator = ranges[ i ].createIterator();
				while ( ( block = iterator.getNextParagraph() ) ) {
					// include contents of blockLimit elements.
					if ( block.getName() in divLimitDefinition && !block.isReadOnly() ) {
						var j,
							childNodes = block.getChildren();
						for ( j = 0; j < childNodes.count(); j++ )
							addSafely( containedBlocks, childNodes.getItem( j ), database );
					} else {
						while ( !dtd[ block.getName() ] && !block.equals( ranges[ i ].root ) )
							block = block.getParent();
						addSafely( containedBlocks, block, database );
					}
				}
			}

			CKEDITOR.dom.element.clearAllMarkers( database );

			var blockGroups = groupByDivLimit( containedBlocks );
			var ancestor, blockEl, divElement;

			for ( i = 0; i < blockGroups.length; i++ ) {
				var currentNode = blockGroups[ i ][ 0 ];

				// Calculate the common parent node of all contained elements.
				ancestor = currentNode.getParent();
				for ( j = 1; j < blockGroups[ i ].length; j++ )
					ancestor = ancestor.getCommonAncestor( blockGroups[ i ][ j ] );

				divElement = new CKEDITOR.dom.element( 'div', editor.document );

				// Normalize the blocks in each group to a common parent.
				for ( j = 0; j < blockGroups[ i ].length; j++ ) {
					currentNode = blockGroups[ i ][ j ];

					while ( !currentNode.getParent().equals( ancestor ) )
						currentNode = currentNode.getParent();

					// This could introduce some duplicated elements in array.
					blockGroups[ i ][ j ] = currentNode;
				}

				// Wrapped blocks counting
				var fixedBlock = null;
				for ( j = 0; j < blockGroups[ i ].length; j++ ) {
					currentNode = blockGroups[ i ][ j ];

					// Avoid DUP elements introduced by grouping.
					if ( !( currentNode.getCustomData && currentNode.getCustomData( 'block_processed' ) ) ) {
						currentNode.is && CKEDITOR.dom.element.setMarker( database, currentNode, 'block_processed', true );

						// Establish new container, wrapping all elements in this group.
						if ( !j )
							divElement.insertBefore( currentNode );

						divElement.append( currentNode );
					}
				}

				CKEDITOR.dom.element.clearAllMarkers( database );
				containers.push( divElement );
			}

			selection.selectBookmarks( bookmarks );
			return containers;
		}
319614
function() {
			var startContainer = this.startContainer,
				startOffset = this.startOffset;

			// [IE] Special handling for range start in text with a leading NBSP,
			// we it to be isolated, for bogus check.
			if ( CKEDITOR.env.ie && startOffset && startContainer.type == CKEDITOR.NODE_TEXT )
			{
				var textBefore = CKEDITOR.tools.ltrim( startContainer.substring( 0, startOffset ) );
				if ( nbspRegExp.test( textBefore ) )
					this.trim( 0, 1 );
			}

			// Antecipate the trim() call here, so the walker will not make
			// changes to the DOM, which would not get reflected into this
			// range otherwise.
			this.trim();

			// We need to grab the block element holding the start boundary, so
			// let's use an element path for it.
			var path = new CKEDITOR.dom.elementPath( this.startContainer, this.root );

			// Creates a range starting at the block start until the range start.
			var walkerRange = this.clone();
			walkerRange.collapse( true );
			walkerRange.setStartAt( path.block || path.blockLimit, CKEDITOR.POSITION_AFTER_START );

			var walker = new CKEDITOR.dom.walker( walkerRange );
			walker.evaluator = getCheckStartEndBlockEvalFunction();

			return walker.checkBackward();
		}
1279370
function( editor, output ) {
			this.getHolderElement = function() {
				var holder = this._.holder;

				if ( !holder ) {
					if ( this.isFramed ) {
						var iframe = this.document.getById( this.id + '_frame' ),
							parentDiv = iframe.getParent(),
							doc = iframe.getFrameDocument();

						// Make it scrollable on iOS. (#8308)
						CKEDITOR.env.iOS && parentDiv.setStyles( {
							'overflow': 'scroll',
							'-webkit-overflow-scrolling': 'touch'
						} );

						var onLoad = CKEDITOR.tools.addFunction( CKEDITOR.tools.bind( function( ev ) {
							this.isLoaded = true;
							if ( this.onLoad )
								this.onLoad();
						}, this ) );

						doc.write( frameDocTpl.output( CKEDITOR.tools.extend( {
							css: CKEDITOR.tools.buildStyleHtml( this.css ),
							onload: 'window.parent.CKEDITOR.tools.callFunction(' + onLoad + ');'
						}, data ) ) );

						var win = doc.getWindow();

						// Register the CKEDITOR global.
						win.$.CKEDITOR = CKEDITOR;

						// Arrow keys for scrolling is only preventable with 'keypress' event in Opera (#4534).
						doc.on( 'keydown', function( evt ) {
							var keystroke = evt.data.getKeystroke(),
								dir = this.document.getById( this.id ).getAttribute( 'dir' );

							// Delegate key processing to block.
							if ( this._.onKeyDown && this._.onKeyDown( keystroke ) === false ) {
								evt.data.preventDefault();
								return;
							}

							// ESC/ARROW-LEFT(ltr) OR ARROW-RIGHT(rtl)
							if ( keystroke == 27 || keystroke == ( dir == 'rtl' ? 39 : 37 ) ) {
								if ( this.onEscape && this.onEscape( keystroke ) === false )
									evt.data.preventDefault();
							}
						}, this );

						holder = doc.getBody();
						holder.unselectable();
						CKEDITOR.env.air && CKEDITOR.tools.callFunction( onLoad );
					} else
						holder = this.document.getById( this.id );

					this._.holder = holder;
				}

				return holder;
			};

			var data = {
				editorId: editor.id,
				id: this.id,
				langCode: editor.langCode,
				dir: editor.lang.dir,
				cls: this.className,
				frame: '',
				env: CKEDITOR.env.cssClass,
				'z-index': editor.config.baseFloatZIndex + 1
			};

			if ( this.isFramed ) {
				// With IE, the custom domain has to be taken care at first,
				// for other browers, the 'src' attribute should be left empty to
				// trigger iframe's 'load' event.
				var src =
					CKEDITOR.env.air ? 'javascript:void(0)' :
					CKEDITOR.env.ie ? 'javascript:void(function(){' + encodeURIComponent(
						'document.open();' +
						// In IE, the document domain must be set any time we call document.open().
						'(' + CKEDITOR.tools.fixDomain + ')();' +
						'document.close();'
					) + '}())' :
					'';

				data.frame = frameTpl.output( {
					id: this.id + '_frame',
					src: src
				} );
			}

			var html = panelTpl.output( data );

			if ( output )
				output.push( html );

			return html;
		}
1319135
function() {
			var children = this.parent.children,
				index = CKEDITOR.tools.indexOf( children, this ),
				previous = this.previous,
				next = this.next;

			previous && ( previous.next = next );
			next && ( next.previous = previous );
			children.splice( index, 1 );
			this.parent = null;
		}
104737
function Editor(options) {
    this.options = options;
    window.indentUnit = options.indentUnit;
    this.parent = parent;
    this.doc = document;
    var container = this.container = this.doc.body;
    this.win = window;
    this.history = new History(container, options.undoDepth, options.undoDelay, this);
    var self = this;

    if (!Editor.Parser)
      throw "No parser loaded.";
    if (options.parserConfig && Editor.Parser.configure)
      Editor.Parser.configure(options.parserConfig);

    if (!options.readOnly)
      select.setCursorPos(container, {node: null, offset: 0});

    this.dirty = [];
    this.importCode(options.content || "");
    this.history.onChange = options.onChange;

    if (!options.readOnly) {
      if (options.continuousScanning !== false) {
        this.scanner = this.documentScanner(options.passTime);
        this.delayScanning();
      }

      function setEditable() {
        // In IE, designMode frames can not run any scripts, so we use
        // contentEditable instead.
        if (document.body.contentEditable != undefined && internetExplorer)
          document.body.contentEditable = "true";
        else
          document.designMode = "on";

        document.documentElement.style.borderWidth = "0";
        if (!options.textWrapping)
          container.style.whiteSpace = "nowrap";
      }

      // If setting the frame editable fails, try again when the user
      // focus it (happens when the frame is not visible on
      // initialisation, in Firefox).
      try {
        setEditable();
      }
      catch(e) {
        var focusEvent = addEventHandler(document, "focus", function() {
          focusEvent();
          setEditable();
        }, true);
      }

      addEventHandler(document, "keydown", method(this, "keyDown"));
      addEventHandler(document, "keypress", method(this, "keyPress"));
      addEventHandler(document, "keyup", method(this, "keyUp"));

      function cursorActivity() {self.cursorActivity(false);}
      addEventHandler(document.body, "mouseup", cursorActivity);
      addEventHandler(document.body, "cut", cursorActivity);

      // workaround for a gecko bug [?] where going forward and then
      // back again breaks designmode (no more cursor)
      if (gecko)
        addEventHandler(this.win, "pagehide", function(){self.unloaded = true;});

      addEventHandler(document.body, "paste", function(event) {
        cursorActivity();
        var text = null;
        try {
          var clipboardData = event.clipboardData || window.clipboardData;
          if (clipboardData) text = clipboardData.getData('Text');
        }
        catch(e) {}
        if (text !== null) {
          event.stop();
          self.replaceSelection(text);
          select.scrollToCursor(self.container);
        }
      });

      if (this.options.autoMatchParens)
        addEventHandler(document.body, "click", method(this, "scheduleParenHighlight"));
    }
    else if (!options.textWrapping) {
      container.style.whiteSpace = "nowrap";
    }
  }
815584
function() {
					var range = editor.createRange();
					var cursors = this._.cursors;
					if ( cursors.length < 1 ) {
						var textNode = this._.walker.textNode;
						if ( textNode )
							range.setStartAfter( textNode );
						else
							return null;
					} else {
						var first = cursors[ 0 ],
							last = cursors[ cursors.length - 1 ];

						range.setStart( first.textNode, first.offset );
						range.setEnd( last.textNode, last.offset + 1 );
					}

					return range;
				}
780193
function toggleFullScreen(editor) {
    // Set fullscreen
    var cm = editor.codemirror;
    cm.setOption('fullScreen', !cm.getOption('fullScreen'));


    // Prevent scrolling on body during fullscreen active
    if (cm.getOption('fullScreen')) {
        saved_overflow = document.body.style.overflow;
        document.body.style.overflow = 'hidden';
    } else {
        document.body.style.overflow = saved_overflow;
    }


    // Update toolbar class
    var wrap = cm.getWrapperElement();

    if (!/fullscreen/.test(wrap.previousSibling.className)) {
        wrap.previousSibling.className += ' fullscreen';
    } else {
        wrap.previousSibling.className = wrap.previousSibling.className.replace(/\s*fullscreen\b/, '');
    }


    // Update toolbar button
    if (editor.toolbarElements.fullscreen) {
        var toolbarButton = editor.toolbarElements.fullscreen;

        if (!/active/.test(toolbarButton.className)) {
            toolbarButton.className += ' active';
        } else {
            toolbarButton.className = toolbarButton.className.replace(/\s*active\s*/g, '');
        }
    }


    // Hide side by side if needed
    var sidebyside = cm.getWrapperElement().nextSibling;
    if (/editor-preview-active-side/.test(sidebyside.className))
        toggleSideBySide(editor);
}
755660
function initPlugin( editor ) {
		// Configurables
		var config = editor.config,
			triggerOffset = config.magicline_triggerOffset || 30,
			enterMode = config.enterMode,
			that = {
				// Global stuff is being initialized here.
				editor: editor,
				enterMode: enterMode,
				triggerOffset: triggerOffset,
				holdDistance: 0 | triggerOffset * ( config.magicline_holdDistance || 0.5 ),
				boxColor: config.magicline_color || '#ff0000',
				rtl: config.contentsLangDirection == 'rtl',
				tabuList: [ 'data-cke-hidden-sel' ].concat( config.magicline_tabuList || [] ),
				triggers: config.magicline_everywhere ? DTD_BLOCK : { table: 1, hr: 1, div: 1, ul: 1, ol: 1, dl: 1, form: 1, blockquote: 1 }
			},
			scrollTimeout, checkMouseTimeoutPending, checkMouseTimeout, checkMouseTimer;

		// %REMOVE_START%
		// Internal DEBUG uses tools located in the topmost window.

		// (#9701) Due to security limitations some browsers may throw
		// errors when accessing window.top object. Do it safely first then.
		try {
			that.debug = window.top.DEBUG;
		}
		catch ( e ) {}

		that.debug = that.debug || {
			groupEnd: function() {},
			groupStart: function() {},
			log: function() {},
			logElements: function() {},
			logElementsEnd: function() {},
			logEnd: function() {},
			mousePos: function() {},
			showHidden: function() {},
			showTrigger: function() {},
			startTimer: function() {},
			stopTimer: function() {}
		};
		// %REMOVE_END%

		// Simple irrelevant elements filter.
		that.isRelevant = function( node ) {
			return isHtml( node ) 			// 	-> Node must be an existing HTML element.
				&& !isLine( that, node ) 	// 	-> Node can be neither the box nor its child.
				&& !isFlowBreaker( node ); 	// 	-> Node can be neither floated nor positioned nor aligned.
		};

		editor.on( 'contentDom', addListeners, this );

		function addListeners() {
			var editable = editor.editable(),
				doc = editor.document,
				win = editor.window,
				listener;

			// Global stuff is being initialized here.
			extend( that, {
				editable: editable,
				inInlineMode: editable.isInline(),
				doc: doc,
				win: win,
				hotNode: null
			}, true );

			// This is the boundary of the editor. For inline the boundary is editable itself.
			// For classic (`iframe`-based) editor, the HTML element is a real boundary.
			that.boundary = that.inInlineMode ? that.editable : that.doc.getDocumentElement();

			// Enabling the box inside of inline editable is pointless.
			// There's no need to access spaces inside paragraphs, links, spans, etc.
			if ( editable.is( dtd.$inline ) )
				return;

			// Handle in-line editing by setting appropriate position.
			// If current position is static, make it relative and clear top/left coordinates.
			if ( that.inInlineMode && !isPositioned( editable ) ) {
				editable.setStyles( {
					position: 'relative',
					top: null,
					left: null
				} );
			}
			// Enable the box. Let it produce children elements, initialize
			// event handlers and own methods.
			initLine.call( this, that );

			// Get view dimensions and scroll positions.
			// At this stage (before any checkMouse call) it is used mostly
			// by tests. Nevertheless it a crucial thing.
			updateWindowSize( that );

			// Remove the box before an undo image is created.
			// This is important. If we didn't do that, the *undo thing* would revert the box into an editor.
			// Thanks to that, undo doesn't even know about the existence of the box.
			editable.attachListener( editor, 'beforeUndoImage', function() {
				that.line.detach();
			} );

			// Removes the box HTML from editor data string if getData is called.
			// Thanks to that, an editor never yields data polluted by the box.
			// Listen with very high priority, so line will be removed before other
			// listeners will see it.
			editable.attachListener( editor, 'beforeGetData', function() {
				// If the box is in editable, remove it.
				if ( that.line.wrap.getParent() ) {
					that.line.detach();

					// Restore line in the last listener for 'getData'.
					editor.once( 'getData', function() {
						that.line.attach();
					}, null, null, 1000 );
				}
			}, null, null, 0 );

			// Hide the box on mouseout if mouse leaves document.
			editable.attachListener( that.inInlineMode ? doc : doc.getWindow().getFrame(), 'mouseout', function( event ) {
				if ( editor.mode != 'wysiwyg' )
					return;

				// Check for inline-mode editor. If so, check mouse position
				// and remove the box if mouse outside of an editor.
				if ( that.inInlineMode ) {
					var mouse = {
						x: event.data.$.clientX,
						y: event.data.$.clientY
					};

					updateWindowSize( that );
					updateEditableSize( that, true );

					var size = that.view.editable,
						scroll = that.view.scroll;

					// If outside of an editor...
					if ( !inBetween( mouse.x, size.left - scroll.x, size.right - scroll.x ) || !inBetween( mouse.y, size.top - scroll.y, size.bottom - scroll.y ) ) {
						clearTimeout( checkMouseTimer );
						checkMouseTimer = null;
						that.line.detach();
					}
				}

				else {
					clearTimeout( checkMouseTimer );
					checkMouseTimer = null;
					that.line.detach();
				}
			} );

			// This one deactivates hidden mode of an editor which
			// prevents the box from being shown.
			editable.attachListener( editable, 'keyup', function( event ) {
				that.hiddenMode = 0;
				that.debug.showHidden( that.hiddenMode ); // %REMOVE_LINE%
			} );

			editable.attachListener( editable, 'keydown', function( event ) {
				if ( editor.mode != 'wysiwyg' )
					return;

				var keyStroke = event.data.getKeystroke(),
					selection = editor.getSelection(),
					selected = selection.getStartElement();

				switch ( keyStroke ) {
					// Shift pressed
					case 2228240: // IE
					case 16:
						that.hiddenMode = 1;
						that.line.detach();
				}

				that.debug.showHidden( that.hiddenMode ); // %REMOVE_LINE%
			} );

			// This method ensures that checkMouse aren't executed
			// in parallel and no more frequently than specified in timeout function.
			// In classic (`iframe`-based) editor, document is used as a trigger, to provide magicline
			// functionality when mouse is below the body (short content, short body).
			editable.attachListener( that.inInlineMode ? editable : doc, 'mousemove', function( event ) {
				checkMouseTimeoutPending = true;

				if ( editor.mode != 'wysiwyg' || editor.readOnly || checkMouseTimer )
					return;

				// IE<9 requires this event-driven object to be created
				// outside of the setTimeout statement.
				// Otherwise it loses the event object with its properties.
				var mouse = {
					x: event.data.$.clientX,
					y: event.data.$.clientY
				};

				checkMouseTimer = setTimeout( function() {
					checkMouse( mouse );
				}, 30 ); // balances performance and accessibility
			} );

			// This one removes box on scroll event.
			// It is to avoid box displacement.
			editable.attachListener( win, 'scroll', function( event ) {
				if ( editor.mode != 'wysiwyg' )
					return;

				that.line.detach();

				// To figure this out just look at the mouseup
				// event handler below.
				if ( env.webkit ) {
					that.hiddenMode = 1;

					clearTimeout( scrollTimeout );
					scrollTimeout = setTimeout( function() {
						// Don't leave hidden mode until mouse remains pressed and
						// scroll is being used, i.e. when dragging something.
						if ( !that.mouseDown )
							that.hiddenMode = 0;
						that.debug.showHidden( that.hiddenMode ); // %REMOVE_LINE%
					}, 50 );

					that.debug.showHidden( that.hiddenMode ); // %REMOVE_LINE%
				}
			} );

			// Those event handlers remove the box on mousedown
			// and don't reveal it until the mouse is released.
			// It is to prevent box insertion e.g. while scrolling
			// (w/ scrollbar), selecting and so on.
			editable.attachListener( env_ie8 ? doc : win, 'mousedown', function( event ) {
				if ( editor.mode != 'wysiwyg' )
					return;

				that.line.detach();
				that.hiddenMode = 1;
				that.mouseDown = 1;

				that.debug.showHidden( that.hiddenMode ); // %REMOVE_LINE%
			} );

			// Google Chrome doesn't trigger this on the scrollbar (since 2009...)
			// so it is totally useless to check for scroll finish
			// see: http://code.google.com/p/chromium/issues/detail?id=14204
			editable.attachListener( env_ie8 ? doc : win, 'mouseup', function( event ) {
				that.hiddenMode = 0;
				that.mouseDown = 0;
				that.debug.showHidden( that.hiddenMode ); // %REMOVE_LINE%
			} );

			// Editor commands for accessing difficult focus spaces.
			editor.addCommand( 'accessPreviousSpace', accessFocusSpaceCmd( that ) );
			editor.addCommand( 'accessNextSpace', accessFocusSpaceCmd( that, true ) );

			editor.setKeystroke( [
				[ config.magicline_keystrokePrevious, 'accessPreviousSpace' ],
				[ config.magicline_keystrokeNext, 'accessNextSpace' ]
			] );

			// Revert magicline hot node on undo/redo.
			editor.on( 'loadSnapshot', function( event ) {
				var elements, element, i;

				for ( var t in { p: 1, br: 1, div: 1 } ) {
					// document.find is not available in QM (#11149).
					elements = editor.document.getElementsByTag( t );

					for ( i = elements.count(); i--; ) {
						if ( ( element = elements.getItem( i ) ).data( 'cke-magicline-hot' ) ) {
							// Restore hotNode
							that.hotNode = element;
							// Restore last access direction
							that.lastCmdDirection = element.data( 'cke-magicline-dir' ) === 'true' ? true : false;

							return;
						}
					}
				}
			} );

			// This method handles mousemove mouse for box toggling.
			// It uses mouse position to determine underlying element, then
			// it tries to use different trigger type in order to place the box
			// in correct place. The following procedure is executed periodically.
			function checkMouse( mouse ) {
				that.debug.groupStart( 'CheckMouse' ); // %REMOVE_LINE%
				that.debug.startTimer(); // %REMOVE_LINE%

				that.mouse = mouse;
				that.trigger = null;

				checkMouseTimer = null;
				updateWindowSize( that );

				if ( checkMouseTimeoutPending 								//	-> There must be an event pending.
					&& !that.hiddenMode 									// 	-> Can't be in hidden mode.
					&& editor.focusManager.hasFocus 						// 	-> Editor must have focus.
					&& !that.line.mouseNear() 								// 	-> Mouse pointer can't be close to the box.
					&& ( that.element = elementFromMouse( that, true ) ) ) 	// 	-> There must be valid element.
				{
					// If trigger exists, and trigger is correct -> show the box.
					// Don't show the line if trigger is a descendant of some tabu-list element.
					if ( ( that.trigger = triggerEditable( that ) || triggerEdge( that ) || triggerExpand( that ) ) &&
						!isInTabu( that, that.trigger.upper || that.trigger.lower ) ) {
						that.line.attach().place();
					}

					// Otherwise remove the box
					else {
						that.trigger = null;
						that.line.detach();
					}

					that.debug.showTrigger( that.trigger ); // %REMOVE_LINE%
					that.debug.mousePos( mouse.y, that.element ); // %REMOVE_LINE%

					checkMouseTimeoutPending = false;
				}

				that.debug.stopTimer(); // %REMOVE_LINE%
				that.debug.groupEnd(); // %REMOVE_LINE%
			}

			// This one allows testing and debugging. It reveals some
			// inner methods to the world.
			this.backdoor = {
				accessFocusSpace: accessFocusSpace,
				boxTrigger: boxTrigger,
				isLine: isLine,
				getAscendantTrigger: getAscendantTrigger,
				getNonEmptyNeighbour: getNonEmptyNeighbour,
				getSize: getSize,
				that: that,
				triggerEdge: triggerEdge,
				triggerEditable: triggerEditable,
				triggerExpand: triggerExpand
			};
		}
	}
941316
function applyJsdomWorkaround(window) {
    Object.defineProperties(window.HTMLElement.prototype, {
        offsetLeft: {
            get: function () {
                return parseFloat(window.getComputedStyle(this).marginLeft) || 0;
            }
        },
        offsetTop: {
            get: function () {
                return parseFloat(window.getComputedStyle(this).marginTop) || 0;
            }
        },
        offsetHeight: {
            get: function () {
                return parseFloat(window.getComputedStyle(this).height) || 0;
            }
        },
        offsetWidth: {
            get: function () {
                return parseFloat(window.getComputedStyle(this).width) || 0;
            }
        }
    });
}
112423
function(nodeOptions) {
      var ranges = this.getOwnRanges(),
          node, nodes = [];
      if (ranges.length == 0) {
        return nodes;
      }

      for (var i = ranges.length; i--;) {
        node = this.doc.createElement(nodeOptions.nodeName);
        nodes.push(node);
        if (nodeOptions.className) {
          node.className = nodeOptions.className;
        }
        if (nodeOptions.cssStyle) {
          node.setAttribute('style', nodeOptions.cssStyle);
        }
        try {
          // This only works when the range boundaries are not overlapping other elements
          ranges[i].surroundContents(node);
          this.selectNode(node);
        } catch(e) {
          // fallback
          node.appendChild(ranges[i].extractContents());
          ranges[i].insertNode(node);
        }
      }
      return nodes;
    }
840901
function ( event ) {
			if ( ! focusArea ) {
				return;
			}
			var style = myStyles [ event.target.styleRange ];
			var bDouble = style.HTMLAfter && 0 < style.HTMLAfter.length;
			var selectionStart = focusArea.selectionStart;
			var selectionEnd = focusArea.selectionEnd;
			var oldText = focusArea.value;
			focusArea.value = oldText.substring ( 0, selectionStart ) + 
				( bDouble ? style.HTMLBefore + oldText.substring ( selectionStart, selectionEnd ) + style.HTMLAfter : style.HTMLBefore ) + 
				oldText.substring ( selectionEnd );
			focusArea.setSelectionRange ( 
				bDouble || selectionStart === selectionEnd ? selectionStart + style.HTMLBefore.length : selectionStart,
				( bDouble ? selectionEnd : selectionStart ) + style.HTMLBefore.length );
			focusArea.focus ( );
		}
1145370
function hideSelection( editor ) {
		var style = CKEDITOR.env.ie ? 'display:none' : 'position:fixed;top:0;left:-1000px',
			hiddenEl = CKEDITOR.dom.element.createFromHtml(
				'<div data-cke-hidden-sel="1" data-cke-temp="1" style="' + style + '">&nbsp;</div>',
				editor.document );

		editor.fire( 'lockSnapshot' );

		editor.editable().append( hiddenEl );

			// Always use real selection to avoid overriding locked one (http://dev.ckeditor.com/ticket/11104#comment:13).
		var sel = editor.getSelection( 1 ),
			range = editor.createRange(),
			// Cancel selectionchange fired by selectRanges - prevent from firing selectionChange.
			listener = sel.root.on( 'selectionchange', function( evt ) {
				evt.cancel();
			}, null, null, 0 );

		range.setStartAt( hiddenEl, CKEDITOR.POSITION_AFTER_START );
		range.setEndAt( hiddenEl, CKEDITOR.POSITION_BEFORE_END );
		sel.selectRanges( [ range ] );

		listener.removeListener();

		editor.fire( 'unlockSnapshot' );

		// Set this value at the end, so reset() executed by selectRanges()
		// will clean up old hidden selection container.
		editor._.hiddenSelectionContainer = hiddenEl;
	}
1218072
function boundingBoxImpl(ele, options) {
  var cy = ele._private.cy;
  var styleEnabled = cy.styleEnabled();
  var headless = cy.headless();
  var bounds = makeBoundingBox();
  var _p = ele._private;
  var display = styleEnabled ? ele.pstyle('display').value : 'element';
  var isNode = ele.isNode();
  var isEdge = ele.isEdge();
  var ex1, ex2, ey1, ey2; // extrema of body / lines

  var x, y; // node pos

  var displayed = display !== 'none';
  var rstyle = _p.rstyle;
  var manualExpansion = isNode && styleEnabled ? ele.pstyle('bounds-expansion').pfValue : 0;

  if (displayed) {
    var overlayOpacity = 0;
    var overlayPadding = 0;

    if (styleEnabled && options.includeOverlays) {
      overlayOpacity = ele.pstyle('overlay-opacity').value;

      if (overlayOpacity !== 0) {
        overlayPadding = ele.pstyle('overlay-padding').value;
      }
    }

    var w = 0;
    var wHalf = 0;

    if (styleEnabled) {
      w = ele.pstyle('width').pfValue;
      wHalf = w / 2;
    }

    if (isNode && options.includeNodes) {
      var pos = ele.position();
      x = pos.x;
      y = pos.y;

      var _w = ele.outerWidth();

      var halfW = _w / 2;
      var h = ele.outerHeight();
      var halfH = h / 2; // handle node dimensions
      /////////////////////////

      ex1 = x - halfW;
      ex2 = x + halfW;
      ey1 = y - halfH;
      ey2 = y + halfH;
      updateBounds(bounds, ex1, ey1, ex2, ey2);
    } else if (isEdge && options.includeEdges) {
      // handle edge dimensions (rough box estimate)
      //////////////////////////////////////////////
      if (styleEnabled && !headless) {
        ex1 = Math.min(rstyle.srcX, rstyle.midX, rstyle.tgtX);
        ex2 = Math.max(rstyle.srcX, rstyle.midX, rstyle.tgtX);
        ey1 = Math.min(rstyle.srcY, rstyle.midY, rstyle.tgtY);
        ey2 = Math.max(rstyle.srcY, rstyle.midY, rstyle.tgtY); // take into account edge width

        ex1 -= wHalf;
        ex2 += wHalf;
        ey1 -= wHalf;
        ey2 += wHalf;
        updateBounds(bounds, ex1, ey1, ex2, ey2);
      } // precise haystacks
      ////////////////////


      if (styleEnabled && !headless && ele.pstyle('curve-style').strValue === 'haystack') {
        var hpts = rstyle.haystackPts || [];
        ex1 = hpts[0].x;
        ey1 = hpts[0].y;
        ex2 = hpts[1].x;
        ey2 = hpts[1].y;

        if (ex1 > ex2) {
          var temp = ex1;
          ex1 = ex2;
          ex2 = temp;
        }

        if (ey1 > ey2) {
          var _temp = ey1;
          ey1 = ey2;
          ey2 = _temp;
        }

        updateBounds(bounds, ex1 - wHalf, ey1 - wHalf, ex2 + wHalf, ey2 + wHalf); // handle points along edge
        ///////////////////////////
      } else {
        var pts = rstyle.bezierPts || rstyle.linePts || [];

        for (var j = 0; j < pts.length; j++) {
          var pt = pts[j];
          ex1 = pt.x - wHalf;
          ex2 = pt.x + wHalf;
          ey1 = pt.y - wHalf;
          ey2 = pt.y + wHalf;
          updateBounds(bounds, ex1, ey1, ex2, ey2);
        } // fallback on source and target positions
        //////////////////////////////////////////


        if (pts.length === 0) {
          var n1 = ele.source();
          var n1pos = n1.position();
          var n2 = ele.target();
          var n2pos = n2.position();
          ex1 = n1pos.x;
          ex2 = n2pos.x;
          ey1 = n1pos.y;
          ey2 = n2pos.y;

          if (ex1 > ex2) {
            var _temp2 = ex1;
            ex1 = ex2;
            ex2 = _temp2;
          }

          if (ey1 > ey2) {
            var _temp3 = ey1;
            ey1 = ey2;
            ey2 = _temp3;
          } // take into account edge width


          ex1 -= wHalf;
          ex2 += wHalf;
          ey1 -= wHalf;
          ey2 += wHalf;
          updateBounds(bounds, ex1, ey1, ex2, ey2);
        }
      }
    } // edges
    // handle edge arrow size
    /////////////////////////


    if (styleEnabled && options.includeEdges && isEdge) {
      updateBoundsFromArrow(bounds, ele, 'mid-source', options);
      updateBoundsFromArrow(bounds, ele, 'mid-target', options);
      updateBoundsFromArrow(bounds, ele, 'source', options);
      updateBoundsFromArrow(bounds, ele, 'target', options);
    } // ghost
    ////////


    if (styleEnabled) {
      var ghost = ele.pstyle('ghost').value === 'yes';

      if (ghost) {
        var gx = ele.pstyle('ghost-offset-x').pfValue;
        var gy = ele.pstyle('ghost-offset-y').pfValue;
        updateBounds(bounds, bounds.x1 + gx, bounds.y1 + gy, bounds.x2 + gx, bounds.y2 + gy);
      }
    } // always store the body bounds separately from the labels


    var bbBody = _p.bodyBounds = _p.bodyBounds || {};
    assignBoundingBox(bbBody, bounds);
    expandBoundingBox(bbBody, manualExpansion);
    expandBoundingBox(bbBody, 1); // expand to work around browser dimension inaccuracies
    // overlay
    //////////

    if (styleEnabled) {
      ex1 = bounds.x1;
      ex2 = bounds.x2;
      ey1 = bounds.y1;
      ey2 = bounds.y2;
      updateBounds(bounds, ex1 - overlayPadding, ey1 - overlayPadding, ex2 + overlayPadding, ey2 + overlayPadding);
    } // always store the body bounds separately from the labels


    var bbOverlay = _p.overlayBounds = _p.overlayBounds || {};
    assignBoundingBox(bbOverlay, bounds);
    expandBoundingBox(bbOverlay, manualExpansion);
    expandBoundingBox(bbOverlay, 1); // expand to work around browser dimension inaccuracies
    // handle label dimensions
    //////////////////////////

    var bbLabels = _p.labelBounds = _p.labelBounds || {};

    if (bbLabels.all != null) {
      clearBoundingBox(bbLabels.all);
    } else {
      bbLabels.all = makeBoundingBox();
    }

    if (styleEnabled && options.includeLabels) {
      updateBoundsFromLabel(bounds, ele, null, options);

      if (isEdge) {
        updateBoundsFromLabel(bounds, ele, 'source', options);
        updateBoundsFromLabel(bounds, ele, 'target', options);
      }
    } // style enabled for labels

  } // if displayed


  bounds.x1 = noninf(bounds.x1);
  bounds.y1 = noninf(bounds.y1);
  bounds.x2 = noninf(bounds.x2);
  bounds.y2 = noninf(bounds.y2);
  bounds.w = noninf(bounds.x2 - bounds.x1);
  bounds.h = noninf(bounds.y2 - bounds.y1);

  if (bounds.w > 0 && bounds.h > 0 && displayed) {
    expandBoundingBox(bounds, manualExpansion); // expand bounds by 1 because antialiasing can increase the visual/effective size by 1 on all sides

    expandBoundingBox(bounds, 1);
  }

  return bounds;
}
383487
function( editor, parentElement, definition, level ) {
			definition.forceIFrame = 1;

			// In case of editor with floating toolbar append panels that should float
			// to the main UI element.
			if ( definition.toolbarRelated && editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE )
				parentElement = CKEDITOR.document.getById( 'cke_' + editor.name );

			var doc = parentElement.getDocument(),
				panel = getPanel( editor, doc, parentElement, definition, level || 0 ),
				element = panel.element,
				iframe = element.getFirst(),
				that = this;

			// Disable native browser menu. (#4825)
			element.disableContextMenu();

			this.element = element;

			this._ = {
				editor: editor,
				// The panel that will be floating.
				panel: panel,
				parentElement: parentElement,
				definition: definition,
				document: doc,
				iframe: iframe,
				children: [],
				dir: editor.lang.dir
			};

			editor.on( 'mode', hide );
			editor.on( 'resize', hide );

			// Window resize doesn't cause hide on blur. (#9800)
			// [iOS] Poping up keyboard triggers window resize
			// which leads to undesired panel hides.
			if ( !CKEDITOR.env.iOS )
				doc.getWindow().on( 'resize', hide );

			// We need a wrapper because events implementation doesn't allow to attach
			// one listener more than once for the same event on the same object.
			// Remember that floatPanel#hide is shared between all instances.
			function hide() {
				that.hide();
			}
		}
48444
function( element ) {
				// Prepare for the insertion. For example - focus editor (#11848).
				beforeInsert( this );

				var editor = this.editor,
					enterMode = editor.activeEnterMode,
					selection = editor.getSelection(),
					range = selection.getRanges()[ 0 ],
					elementName = element.getName(),
					isBlock = CKEDITOR.dtd.$block[ elementName ];

				// Insert element into first range only and ignore the rest (#11183).
				if ( this.insertElementIntoRange( element, range ) ) {
					range.moveToPosition( element, CKEDITOR.POSITION_AFTER_END );

					// If we're inserting a block element, the new cursor position must be
					// optimized. (#3100,#5436,#8950)
					if ( isBlock ) {
						// Find next, meaningful element.
						var next = element.getNext( function( node ) {
							return isNotEmpty( node ) && !isBogus( node );
						} );

						if ( next && next.type == CKEDITOR.NODE_ELEMENT && next.is( CKEDITOR.dtd.$block ) ) {
							// If the next one is a text block, move cursor to the start of it's content.
							if ( next.getDtd()[ '#' ] )
								range.moveToElementEditStart( next );
							// Otherwise move cursor to the before end of the last element.
							else
								range.moveToElementEditEnd( element );
						}
						// Open a new line if the block is inserted at the end of parent.
						else if ( !next && enterMode != CKEDITOR.ENTER_BR ) {
							next = range.fixBlock( true, enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p' );
							range.moveToElementEditStart( next );
						}
					}
				}

				// Set up the correct selection.
				selection.selectRanges( [ range ] );

				afterInsert( this );
			}
979457
function(editorUi)
{
	var graph = editorUi.editor.graph;
	var row, td;

	var table = document.createElement('table');
	table.style.width = '100%';
	table.style.height = '100%';
	var tbody = document.createElement('tbody');
	
	row = document.createElement('tr');
	
	td = document.createElement('td');
	td.style.verticalAlign = 'top';
	td.style.fontSize = '10pt';
	mxUtils.write(td, mxResources.get('paperSize') + ':');
	
	row.appendChild(td);
	
	td = document.createElement('td');
	td.style.verticalAlign = 'top';
	td.style.fontSize = '10pt';
	
	var accessor = PageSetupDialog.addPageFormatPanel(td, 'pagesetupdialog', graph.pageFormat);

	row.appendChild(td);
	tbody.appendChild(row);
	
	row = document.createElement('tr');
	
	td = document.createElement('td');
	mxUtils.write(td, mxResources.get('background') + ':');
	
	row.appendChild(td);
	
	td = document.createElement('td');
	td.style.whiteSpace = 'nowrap';
	
	var backgroundInput = document.createElement('input');
	backgroundInput.setAttribute('type', 'text');
	var backgroundButton = document.createElement('button');
	
	backgroundButton.style.width = '18px';
	backgroundButton.style.height = '18px';
	backgroundButton.style.marginRight = '20px';
	backgroundButton.style.backgroundPosition = 'center center';
	backgroundButton.style.backgroundRepeat = 'no-repeat';
	
	var newBackgroundColor = graph.background;
	
	function updateBackgroundColor()
	{
		if (newBackgroundColor == null || newBackgroundColor == mxConstants.NONE)
		{
			backgroundButton.style.backgroundColor = '';
			backgroundButton.style.backgroundImage = 'url(\'' + Dialog.prototype.noColorImage + '\')';
		}
		else
		{
			backgroundButton.style.backgroundColor = newBackgroundColor;
			backgroundButton.style.backgroundImage = '';
		}
	};
	
	updateBackgroundColor();

	mxEvent.addListener(backgroundButton, 'click', function(evt)
	{
		editorUi.pickColor(newBackgroundColor || 'none', function(color)
		{
			newBackgroundColor = color;
			updateBackgroundColor();
		});
		mxEvent.consume(evt);
	});
	
	td.appendChild(backgroundButton);
	
	mxUtils.write(td, mxResources.get('gridSize') + ':');
	
	var gridSizeInput = document.createElement('input');
	gridSizeInput.setAttribute('type', 'number');
	gridSizeInput.setAttribute('min', '0');
	gridSizeInput.style.width = '40px';
	gridSizeInput.style.marginLeft = '6px';
	
	gridSizeInput.value = graph.getGridSize();
	td.appendChild(gridSizeInput);
	
	mxEvent.addListener(gridSizeInput, 'change', function()
	{
		var value = parseInt(gridSizeInput.value);
		gridSizeInput.value = Math.max(1, (isNaN(value)) ? graph.getGridSize() : value);
	});
	
	row.appendChild(td);
	tbody.appendChild(row);
	
	row = document.createElement('tr');
	td = document.createElement('td');
	
	mxUtils.write(td, mxResources.get('image') + ':');
	
	row.appendChild(td);
	td = document.createElement('td');
	
	var changeImageLink = document.createElement('a');
	changeImageLink.style.textDecoration = 'underline';
	changeImageLink.style.cursor = 'pointer';
	changeImageLink.style.color = '#a0a0a0';
	
	var newBackgroundImage = graph.backgroundImage;
	
	function updateBackgroundImage()
	{
		if (newBackgroundImage == null)
		{
			changeImageLink.removeAttribute('title');
			changeImageLink.style.fontSize = '';
			changeImageLink.innerHTML = mxResources.get('change') + '...';
		}
		else
		{
			changeImageLink.setAttribute('title', newBackgroundImage.src);
			changeImageLink.style.fontSize = '11px';
			changeImageLink.innerHTML = newBackgroundImage.src.substring(0, 42) + '...';
		}
	};
	
	mxEvent.addListener(changeImageLink, 'click', function(evt)
	{
		editorUi.showBackgroundImageDialog(function(image)
		{
			newBackgroundImage = image;
			updateBackgroundImage();
		});
		
		mxEvent.consume(evt);
	});
	
	updateBackgroundImage();

	td.appendChild(changeImageLink);
	
	row.appendChild(td);
	tbody.appendChild(row);
	
	row = document.createElement('tr');
	td = document.createElement('td');
	td.colSpan = 2;
	td.style.paddingTop = '16px';
	td.setAttribute('align', 'right');

	var cancelBtn = mxUtils.button(mxResources.get('cancel'), function()
	{
		editorUi.hideDialog();
	});
	cancelBtn.className = 'geBtn';
	
	if (editorUi.editor.cancelFirst)
	{
		td.appendChild(cancelBtn);
	}
	
	var applyBtn = mxUtils.button(mxResources.get('apply'), function()
	{
		editorUi.hideDialog();
		
		if (graph.gridSize !== gridSizeInput.value)
		{
			graph.setGridSize(parseInt(gridSizeInput.value));
		}

		var change = new ChangePageSetup(editorUi, newBackgroundColor,
			newBackgroundImage, accessor.get());
		change.ignoreColor = graph.background == newBackgroundColor;
		
		var oldSrc = (graph.backgroundImage != null) ? graph.backgroundImage.src : null;
		var newSrc = (newBackgroundImage != null) ? newBackgroundImage.src : null;
		
		change.ignoreImage = oldSrc === newSrc;

		if (graph.pageFormat.width != change.previousFormat.width ||
			graph.pageFormat.height != change.previousFormat.height ||
			!change.ignoreColor || !change.ignoreImage)
		{
			graph.model.execute(change);
		}
	});
	applyBtn.className = 'geBtn gePrimaryBtn';
	td.appendChild(applyBtn);

	if (!editorUi.editor.cancelFirst)
	{
		td.appendChild(cancelBtn);
	}
	
	row.appendChild(td);
	tbody.appendChild(row);
	
	table.appendChild(tbody);
	this.container = table;
}
594905
function (editor, size) {
      var toolbars = [], settings = editor.settings;

      var addToolbar = function (items) {
        if (items) {
          toolbars.push(createToolbar(editor, items, size));
          return true;
        }
      };

      // Convert toolbar array to multiple options
      if (Tools.isArray(settings.toolbar)) {
        // Empty toolbar array is the same as a disabled toolbar
        if (settings.toolbar.length === 0) {
          return;
        }

        Tools.each(settings.toolbar, function (toolbar, i) {
          settings["toolbar" + (i + 1)] = toolbar;
        });

        delete settings.toolbar;
      }

      // Generate toolbar<n>
      for (var i = 1; i < 10; i++) {
        if (!addToolbar(settings["toolbar" + i])) {
          break;
        }
      }

      // Generate toolbar or default toolbar unless it's disabled
      if (!toolbars.length && settings.toolbar !== false) {
        addToolbar(settings.toolbar || defaultToolbar);
      }

      if (toolbars.length) {
        return {
          type: 'panel',
          layout: 'stack',
          classes: "toolbar-grp",
          ariaRoot: true,
          ariaRemember: true,
          items: toolbars
        };
      }
    }