text: YUI.add('dom-screen', function(Y) {
  
  (function(Y) {
  
  /**
   * Adds position and region management functionality to DOM.
   * @module dom
   * @submodule dom-screen
   * @for DOM
   */
  
  var DOCUMENT_ELEMENT = 'documentElement',
      COMPAT_MODE = 'compatMode',
      POSITION = 'position',
      FIXED = 'fixed',
      RELATIVE = 'relative',
      LEFT = 'left',
      TOP = 'top',
      _BACK_COMPAT = 'BackCompat',
      MEDIUM = 'medium',
      BORDER_LEFT_WIDTH = 'borderLeftWidth',
      BORDER_TOP_WIDTH = 'borderTopWidth',
      GET_BOUNDING_CLIENT_RECT = 'getBoundingClientRect',
      GET_COMPUTED_STYLE = 'getComputedStyle',
  
      Y_DOM = Y.DOM,
  
      // TODO: how about thead/tbody/tfoot/tr?
      // TODO: does caption matter?
      RE_TABLE = /^t(?:able|d|h)$/i,
  
      SCROLL_NODE;
  
  if (Y.UA.ie) {
      if (Y.config.doc[COMPAT_MODE] !== 'quirks') {
          SCROLL_NODE = DOCUMENT_ELEMENT; 
      } else {
          SCROLL_NODE = 'body';
      }
  }
  
  Y.mix(Y_DOM, {
      /**
       * Returns the inner height of the viewport (exludes scrollbar). 
       * @method winHeight
       * @return {Number} The current height of the viewport.
       */
      winHeight: function(node) {
          var h = Y_DOM._getWinSize(node).height;
          Y.log('winHeight returning ' + h, 'info', 'dom-screen');
          return h;
      },
  
      /**
       * Returns the inner width of the viewport (exludes scrollbar). 
       * @method winWidth
       * @return {Number} The current width of the viewport.
       */
      winWidth: function(node) {
          var w = Y_DOM._getWinSize(node).width;
          Y.log('winWidth returning ' + w, 'info', 'dom-screen');
          return w;
      },
  
      /**
       * Document height 
       * @method docHeight
       * @return {Number} The current height of the document.
       */
      docHeight:  function(node) {
          var h = Y_DOM._getDocSize(node).height;
          Y.log('docHeight returning ' + h, 'info', 'dom-screen');
          return Math.max(h, Y_DOM._getWinSize(node).height);
      },
  
      /**
       * Document width 
       * @method docWidth
       * @return {Number} The current width of the document.
       */
      docWidth:  function(node) {
          var w = Y_DOM._getDocSize(node).width;
          Y.log('docWidth returning ' + w, 'info', 'dom-screen');
          return Math.max(w, Y_DOM._getWinSize(node).width);
      },
  
      /**
       * Amount page has been scroll horizontally 
       * @method docScrollX
       * @return {Number} The current amount the screen is scrolled horizontally.
       */
      docScrollX: function(node, doc) {
          doc = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc; // perf optimization
          var dv = doc.defaultView,
              pageOffset = (dv) ? dv.pageXOffset : 0;
          return Math.max(doc[DOCUMENT_ELEMENT].scrollLeft, doc.body.scrollLeft, pageOffset);
      },
  
      /**
       * Amount page has been scroll vertically 
       * @method docScrollY
       * @return {Number} The current amount the screen is scrolled vertically.
       */
      docScrollY:  function(node, doc) {
          doc = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc; // perf optimization
          var dv = doc.defaultView,
              pageOffset = (dv) ? dv.pageYOffset : 0;
          return Math.max(doc[DOCUMENT_ELEMENT].scrollTop, doc.body.scrollTop, pageOffset);
      },
  
      /**
       * Gets the current position of an element based on page coordinates. 
       * Element must be part of the DOM tree to have page coordinates
       * (display:none or elements not appended return false).
       * @method getXY
       * @param element The target element
       * @return {Array} The XY position of the element
  
       TODO: test inDocument/display?
       */
      getXY: function() {
          if (Y.config.doc[DOCUMENT_ELEMENT][GET_BOUNDING_CLIENT_RECT]) {
              return function(node) {
                  var xy = null,
                      scrollLeft,
                      scrollTop,
                      box,
                      off1, off2,
                      bLeft, bTop,
                      mode,
                      doc,
                      inDoc,
                      rootNode;
  
                  if (node && node.tagName) {
                      doc = node.ownerDocument;
                      rootNode = doc[DOCUMENT_ELEMENT];
  
                      // inline inDoc check for perf
                      if (rootNode.contains) {
                          inDoc = rootNode.contains(node); 
                      } else {
                          inDoc = Y.DOM.contains(rootNode, node);
                      }
  
                      if (inDoc) {
                          scrollLeft = (SCROLL_NODE) ? doc[SCROLL_NODE].scrollLeft : Y_DOM.docScrollX(node, doc);
                          scrollTop = (SCROLL_NODE) ? doc[SCROLL_NODE].scrollTop : Y_DOM.docScrollY(node, doc);
                          box = node[GET_BOUNDING_CLIENT_RECT]();
                          xy = [box.left, box.top];
  
                              if (Y.UA.ie) {
                                  off1 = 2;
                                  off2 = 2;
                                  mode = doc[COMPAT_MODE];
                                  bLeft = Y_DOM[GET_COMPUTED_STYLE](doc[DOCUMENT_ELEMENT], BORDER_LEFT_WIDTH);
                                  bTop = Y_DOM[GET_COMPUTED_STYLE](doc[DOCUMENT_ELEMENT], BORDER_TOP_WIDTH);
  
                                  if (Y.UA.ie === 6) {
                                      if (mode !== _BACK_COMPAT) {
                                          off1 = 0;
                                          off2 = 0;
                                      }
                                  }
                                  
                                  if ((mode == _BACK_COMPAT)) {
                                      if (bLeft !== MEDIUM) {
                                          off1 = parseInt(bLeft, 10);
                                      }
                                      if (bTop !== MEDIUM) {
                                          off2 = parseInt(bTop, 10);
                                      }
                                  }
                                  
                                  xy[0] -= off1;
                                  xy[1] -= off2;
  
                              }
  
                          if ((scrollTop || scrollLeft)) {
                              if (!Y.UA.ios) {
                                  xy[0] += scrollLeft;
                                  xy[1] += scrollTop;
                              }
                              
                          }
                      } else {
                          xy = Y_DOM._getOffset(node);       
                      }
                  }
                  return xy;                   
              }
          } else {
              return function(node) { // manually calculate by crawling up offsetParents
                  //Calculate the Top and Left border sizes (assumes pixels)
                  var xy = null,
                      doc,
                      parentNode,
                      bCheck,
                      scrollTop,
                      scrollLeft;
  
                  if (node) {
                      if (Y_DOM.inDoc(node)) {
                          xy = [node.offsetLeft, node.offsetTop];
                          doc = node.ownerDocument;
                          parentNode = node;
                          // TODO: refactor with !! or just falsey
                          bCheck = ((Y.UA.gecko || Y.UA.webkit > 519) ? true : false);
  
                          // TODO: worth refactoring for TOP/LEFT only?
                          while ((parentNode = parentNode.offsetParent)) {
                              xy[0] += parentNode.offsetLeft;
                              xy[1] += parentNode.offsetTop;
                              if (bCheck) {
                                  xy = Y_DOM._calcBorders(parentNode, xy);
                              }
                          }
  
                          // account for any scrolled ancestors
                          if (Y_DOM.getStyle(node, POSITION) != FIXED) {
                              parentNode = node;
  
                              while ((parentNode = parentNode.parentNode)) {
                                  scrollTop = parentNode.scrollTop;
                                  scrollLeft = parentNode.scrollLeft;
  
                                  //Firefox does something funky with borders when overflow is not visible.
                                  if (Y.UA.gecko && (Y_DOM.getStyle(parentNode, 'overflow') !== 'visible')) {
                                          xy = Y_DOM._calcBorders(parentNode, xy);
                                  }
                                  
  
                                  if (scrollTop || scrollLeft) {
                                      xy[0] -= scrollLeft;
                                      xy[1] -= scrollTop;
                                  }
                              }
                              xy[0] += Y_DOM.docScrollX(node, doc);
                              xy[1] += Y_DOM.docScrollY(node, doc);
  
                          } else {
                              //Fix FIXED position -- add scrollbars
                              xy[0] += Y_DOM.docScrollX(node, doc);
                              xy[1] += Y_DOM.docScrollY(node, doc);
                          }
                      } else {
                          xy = Y_DOM._getOffset(node);
                      }
                  }
  
                  return xy;                
              };
          }
      }(),// NOTE: Executing for loadtime branching
  
      /**
       * Gets the current X position of an element based on page coordinates. 
       * Element must be part of the DOM tree to have page coordinates
       * (display:none or elements not appended return false).
       * @method getX
       * @param element The target element
       * @return {Int} The X position of the element
       */
  
      getX: function(node) {
          return Y_DOM.getXY(node)[0];
      },
  
      /**
       * Gets the current Y position of an element based on page coordinates. 
       * Element must be part of the DOM tree to have page coordinates
       * (display:none or elements not appended return false).
       * @method getY
       * @param element The target element
       * @return {Int} The Y position of the element
       */
  
      getY: function(node) {
          return Y_DOM.getXY(node)[1];
      },
  
      /**
       * Set the position of an html element in page coordinates.
       * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
       * @method setXY
       * @param element The target element
       * @param {Array} xy Contains X & Y values for new position (coordinates are page-based)
       * @param {Boolean} noRetry By default we try and set the position a second time if the first fails
       */
      setXY: function(node, xy, noRetry) {
          var setStyle = Y_DOM.setStyle,
              pos,
              delta,
              newXY,
              currentXY;
  
          if (node && xy) {
              pos = Y_DOM.getStyle(node, POSITION);
  
              delta = Y_DOM._getOffset(node);       
              if (pos == 'static') { // default to relative
                  pos = RELATIVE;
                  setStyle(node, POSITION, pos);
              }
              currentXY = Y_DOM.getXY(node);
  
              if (xy[0] !== null) {
                  setStyle(node, LEFT, xy[0] - currentXY[0] + delta[0] + 'px');
              }
  
              if (xy[1] !== null) {
                  setStyle(node, TOP, xy[1] - currentXY[1] + delta[1] + 'px');
              }
  
              if (!noRetry) {
                  newXY = Y_DOM.getXY(node);
                  if (newXY[0] !== xy[0] || newXY[1] !== xy[1]) {
                      Y_DOM.setXY(node, xy, true); 
                  }
              }
            
              Y.log('setXY setting position to ' + xy, 'info', 'dom-screen');
          } else {
              Y.log('setXY failed to set ' + node + ' to ' + xy, 'info', 'dom-screen');
          }
      },
  
      /**
       * Set the X position of an html element in page coordinates, regardless of how the element is positioned.
       * The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
       * @method setX
       * @param element The target element
       * @param {Int} x The X values for new position (coordinates are page-based)
       */
      setX: function(node, x) {
          return Y_DOM.setXY(node, [x, null]);
      },
  
      /**
       * Set the Y position of an html element in page coordinates, regardless of how the element is positioned.
       * The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
       * @method setY
       * @param element The target element
       * @param {Int} y The Y values for new position (coordinates are page-based)
       */
      setY: function(node, y) {
          return Y_DOM.setXY(node, [null, y]);
      },
  
      /**
       * @method swapXY
       * @description Swap the xy position with another node
       * @param {Node} node The node to swap with
       * @param {Node} otherNode The other node to swap with
       * @return {Node}
       */
      swapXY: function(node, otherNode) {
          var xy = Y_DOM.getXY(node);
          Y_DOM.setXY(node, Y_DOM.getXY(otherNode));
          Y_DOM.setXY(otherNode, xy);
      },
  
      _calcBorders: function(node, xy2) {
          var t = parseInt(Y_DOM[GET_COMPUTED_STYLE](node, BORDER_TOP_WIDTH), 10) || 0,
              l = parseInt(Y_DOM[GET_COMPUTED_STYLE](node, BORDER_LEFT_WIDTH), 10) || 0;
          if (Y.UA.gecko) {
              if (RE_TABLE.test(node.tagName)) {
                  t = 0;
                  l = 0;
              }
          }
          xy2[0] += l;
          xy2[1] += t;
          return xy2;
      },
  
      _getWinSize: function(node, doc) {
          doc  = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc;
          var win = doc.defaultView || doc.parentWindow,
              mode = doc[COMPAT_MODE],
              h = win.innerHeight,
              w = win.innerWidth,
              root = doc[DOCUMENT_ELEMENT];
  
          if ( mode && !Y.UA.opera ) { // IE, Gecko
              if (mode != 'CSS1Compat') { // Quirks
                  root = doc.body; 
              }
              h = root.clientHeight;
              w = root.clientWidth;
          }
          return { height: h, width: w };
      },
  
      _getDocSize: function(node) {
          var doc = (node) ? Y_DOM._getDoc(node) : Y.config.doc,
              root = doc[DOCUMENT_ELEMENT];
  
          if (doc[COMPAT_MODE] != 'CSS1Compat') {
              root = doc.body;
          }
  
          return { height: root.scrollHeight, width: root.scrollWidth };
      }
  });
  
  })(Y);
  (function(Y) {
  var TOP = 'top',
      RIGHT = 'right',
      BOTTOM = 'bottom',
      LEFT = 'left',
  
      getOffsets = function(r1, r2) {
          var t = Math.max(r1[TOP], r2[TOP]),
              r = Math.min(r1[RIGHT], r2[RIGHT]),
              b = Math.min(r1[BOTTOM], r2[BOTTOM]),
              l = Math.max(r1[LEFT], r2[LEFT]),
              ret = {};
          
          ret[TOP] = t;
          ret[RIGHT] = r;
          ret[BOTTOM] = b;
          ret[LEFT] = l;
          return ret;
      },
  
      DOM = Y.DOM;
  
  Y.mix(DOM, {
      /**
       * Returns an Object literal containing the following about this element: (top, right, bottom, left)
       * @for DOM
       * @method region
       * @param {HTMLElement} element The DOM element. 
       @return {Object} Object literal containing the following about this element: (top, right, bottom, left)
       */
      region: function(node) {
          var xy = DOM.getXY(node),
              ret = false;
          
          if (node && xy) {
              ret = DOM._getRegion(
                  xy[1], // top
                  xy[0] + node.offsetWidth, // right
                  xy[1] + node.offsetHeight, // bottom
                  xy[0] // left
              );
          }
  
          return ret;
      },
  
      /**
       * Find the intersect information for the passes nodes.
       * @method intersect
       * @for DOM
       * @param {HTMLElement} element The first element 
       * @param {HTMLElement | Object} element2 The element or region to check the interect with
       * @param {Object} altRegion An object literal containing the region for the first element if we already have the data (for performance i.e. DragDrop)
       @return {Object} Object literal containing the following intersection data: (top, right, bottom, left, area, yoff, xoff, inRegion)
       */
      intersect: function(node, node2, altRegion) {
          var r = altRegion || DOM.region(node), region = {},
              n = node2,
              off;
  
          if (n.tagName) {
              region = DOM.region(n);
          } else if (Y.Lang.isObject(node2)) {
              region = node2;
          } else {
              return false;
          }
          
          off = getOffsets(region, r);
          return {
              top: off[TOP],
              right: off[RIGHT],
              bottom: off[BOTTOM],
              left: off[LEFT],
              area: ((off[BOTTOM] - off[TOP]) * (off[RIGHT] - off[LEFT])),
              yoff: ((off[BOTTOM] - off[TOP])),
              xoff: (off[RIGHT] - off[LEFT]),
              inRegion: DOM.inRegion(node, node2, false, altRegion)
          };
          
      },
      /**
       * Check if any part of this node is in the passed region
       * @method inRegion
       * @for DOM
       * @param {Object} node2 The node to get the region from or an Object literal of the region
       * $param {Boolean} all Should all of the node be inside the region
       * @param {Object} altRegion An object literal containing the region for this node if we already have the data (for performance i.e. DragDrop)
       * @return {Boolean} True if in region, false if not.
       */
      inRegion: function(node, node2, all, altRegion) {
          var region = {},
              r = altRegion || DOM.region(node),
              n = node2,
              off;
  
          if (n.tagName) {
              region = DOM.region(n);
          } else if (Y.Lang.isObject(node2)) {
              region = node2;
          } else {
              return false;
          }
              
          if (all) {
              return (
                  r[LEFT]   >= region[LEFT]   &&
                  r[RIGHT]  <= region[RIGHT]  && 
                  r[TOP]    >= region[TOP]    && 
                  r[BOTTOM] <= region[BOTTOM]  );
          } else {
              off = getOffsets(region, r);
              if (off[BOTTOM] >= off[TOP] && off[RIGHT] >= off[LEFT]) {
                  return true;
              } else {
                  return false;
              }
              
          }
      },
  
      /**
       * Check if any part of this element is in the viewport
       * @method inViewportRegion
       * @for DOM
       * @param {HTMLElement} element The DOM element. 
       * @param {Boolean} all Should all of the node be inside the region
       * @param {Object} altRegion An object literal containing the region for this node if we already have the data (for performance i.e. DragDrop)
       * @return {Boolean} True if in region, false if not.
       */
      inViewportRegion: function(node, all, altRegion) {
          return DOM.inRegion(node, DOM.viewportRegion(node), all, altRegion);
              
      },
  
      _getRegion: function(t, r, b, l) {
          var region = {};
  
          region[TOP] = region[1] = t;
          region[LEFT] = region[0] = l;
          region[BOTTOM] = b;
          region[RIGHT] = r;
          region.width = region[RIGHT] - region[LEFT];
          region.height = region[BOTTOM] - region[TOP];
  
          return region;
      },
  
      /**
       * Returns an Object literal containing the following about the visible region of viewport: (top, right, bottom, left)
       * @method viewportRegion
       * @for DOM
       * @return {Object} Object literal containing the following about the visible region of the viewport: (top, right, bottom, left)
       */
      viewportRegion: function(node) {
          node = node || Y.config.doc.documentElement;
          var ret = false,
              scrollX,
              scrollY;
  
          if (node) {
              scrollX = DOM.docScrollX(node);
              scrollY = DOM.docScrollY(node);
  
              ret = DOM._getRegion(scrollY, // top
                  DOM.winWidth(node) + scrollX, // right
                  scrollY + DOM.winHeight(node), // bottom
                  scrollX); // left
          }
  
          return ret;
      }
  });
  })(Y);
  
  
  }, '@VERSION@' ,{requires:['dom-base', 'dom-style', 'event-base']});
  