YUI.add('widget-child', function (Y, NAME) {

/**
 * Extension enabling a Widget to be a child of another Widget.
 *
 * @module widget-child
 */

var Lang = Y.Lang;

/**
 * Widget extension providing functionality enabling a Widget to be a
 * child of another Widget.
 *
 * @class WidgetChild
 * @param {Object} config User configuration object.
*/
function Child() {

    //  Widget method overlap
    Y.after(this._syncUIChild, this, "syncUI");
    Y.after(this._bindUIChild, this, "bindUI");

}

Child.ATTRS = {

    /**
     * @attribute selected
     * @type Number
     * @default 0
     *
     * @description Number indicating if the Widget is selected.  Possible
     * values are:
     * <dl>
     * <dt>0</dt> <dd>(Default) Not selected</dd>
     * <dt>1</dt> <dd>Fully selected</dd>
     * <dt>2</dt> <dd>Partially selected</dd>
     * </dl>
    */
    selected: {
        value: 0,
        validator: Lang.isNumber
    },


    /**
     * @attribute index
     * @type Number
     * @readOnly
     *
     * @description Number representing the Widget's ordinal position in its
     * parent Widget.
     */
    index: {
        readOnly: true,
        getter: function () {

            var parent = this.get("parent"),
                index = -1;

            if (parent) {
                index = parent.indexOf(this);
            }

            return index;

        }
    },


    /**
     * @attribute parent
     * @type Widget
     * @readOnly
     *
     * @description Retrieves the parent of the Widget in the object hierarchy.
    */
    parent: {
        readOnly: true
    },


    /**
     * @attribute depth
     * @type Number
     * @default -1
     * @readOnly
     *
     * @description Number representing the depth of this Widget relative to
     * the root Widget in the object heirarchy.
     */
    depth: {
        readOnly: true,
        getter: function () {

            var parent = this.get("parent"),
                root = this.get("root"),
                depth = -1;

            while (parent) {

                depth = (depth + 1);

                if (parent == root) {
                    break;
                }

                parent = parent.get("parent");

            }

            return depth;

        }
    },

    /**
     * @attribute root
     * @type Widget
     * @readOnly
     *
     * @description Returns the root Widget in the object hierarchy.  If the
     * ROOT_TYPE property is set, the search for the root Widget will be
     * constrained to parent Widgets of the specified type.
     */
    root: {
        readOnly: true,
        getter: function () {

            var getParent = function (child) {

                var parent = child.get("parent"),
                    FnRootType = child.ROOT_TYPE,
                    criteria = parent;

                if (FnRootType) {
                    criteria = (parent && Y.instanceOf(parent, FnRootType));
                }

                return (criteria ? getParent(parent) : child);

            };

            return getParent(this);

        }
    }

};

Child.prototype = {

    /**
     * Constructor reference used to determine the root of a Widget-based
     * object tree.
     * <p>
     * Currently used to control the behavior of the <code>root</code>
     * attribute so that recursing up the object heirarchy can be constrained
     * to a specific type of Widget.  Widget authors should set this property
     * to the constructor function for a given Widget implementation.
     * </p>
     *
     * @property ROOT_TYPE
     * @type Object
     */
    ROOT_TYPE: null,

    /**
     * Returns the node on which to bind delegate listeners.
     *
     * Override of Widget's implementation of _getUIEventNode() to ensure that
     * all event listeners are bound to the Widget's topmost DOM element.
     * This ensures that the firing of each type of Widget UI event (click,
     * mousedown, etc.) is facilitated by a single, top-level, delegated DOM
     * event listener.
     *
     * @method _getUIEventNode
     * @for Widget
     * @protected
     */
    _getUIEventNode: function () {
        var root = this.get("root"),
            returnVal;

        if (root) {
            returnVal = root.get("boundingBox");
        }

        return returnVal;
    },

    /**
    * @method next
    * @description Returns the Widget's next sibling.
    * @param {Boolean} circular Boolean indicating if the parent's first child
    * should be returned if the child has no next sibling.
    * @return {Widget} Widget instance.
    */
    next: function (circular) {

        var parent = this.get("parent"),
            sibling;

        if (parent) {
            sibling = parent.item((this.get("index")+1));
        }

        if (!sibling && circular) {
            sibling = parent.item(0);
        }

        return sibling;

    },


    /**
    * @method previous
    * @description Returns the Widget's previous sibling.
    * @param {Boolean} circular Boolean indicating if the parent's last child
    * should be returned if the child has no previous sibling.
    * @return {Widget} Widget instance.
    */
    previous: function (circular) {

        var parent = this.get("parent"),
            index = this.get("index"),
            sibling;

        if (parent && index > 0) {
            sibling = parent.item([(index-1)]);
        }

        if (!sibling && circular) {
            sibling = parent.item((parent.size() - 1));
        }

        return sibling;

    },


    //  Override of Y.WidgetParent.remove()
    //  Sugar implementation allowing a child to remove itself from its parent.
    remove: function (index) {

        var parent,
            removed;

        if (Lang.isNumber(index)) {
            removed = Y.WidgetParent.prototype.remove.apply(this, arguments);
        }
        else {

            parent = this.get("parent");

            if (parent) {
                removed = parent.remove(this.get("index"));
            }

        }

        return removed;

    },


    /**
    * @method isRoot
    * @description Determines if the Widget is the root Widget in the
    * object hierarchy.
    * @return {Boolean} Boolean indicating if Widget is the root Widget in the
    * object hierarchy.
    */
    isRoot: function () {
        return (this == this.get("root"));
    },


    /**
    * @method ancestor
    * @description Returns the Widget instance at the specified depth.
    * @param {number} depth Number representing the depth of the ancestor.
    * @return {Widget} Widget instance.
    */
    ancestor: function (depth) {

        var root = this.get("root"),
            parent;

        if (this.get("depth") > depth)  {

            parent = this.get("parent");

            while (parent != root && parent.get("depth") > depth) {
                parent = parent.get("parent");
            }

        }

        return parent;

    },


    /**
     * Updates the UI to reflect the <code>selected</code> attribute value.
     *
     * @method _uiSetChildSelected
     * @protected
     * @param {number} selected The selected value to be reflected in the UI.
     */
    _uiSetChildSelected: function (selected) {

        var box = this.get("boundingBox"),
            sClassName = this.getClassName("selected");

        if (selected === 0) {
            box.removeClass(sClassName);
        }
        else {
            box.addClass(sClassName);
        }

    },


    /**
     * Default attribute change listener for the <code>selected</code>
     * attribute, responsible for updating the UI, in response to
     * attribute changes.
     *
     * @method _afterChildSelectedChange
     * @protected
     * @param {EventFacade} event The event facade for the attribute change.
     */
    _afterChildSelectedChange: function (event) {
        this._uiSetChildSelected(event.newVal);
    },


    /**
     * Synchronizes the UI to match the WidgetChild state.
     * <p>
     * This method is invoked after bindUI is invoked for the Widget class
     * using YUI's aop infrastructure.
     * </p>
     *
     * @method _syncUIChild
     * @protected
     */
    _syncUIChild: function () {
        this._uiSetChildSelected(this.get("selected"));
    },


    /**
     * Binds event listeners responsible for updating the UI state in response
     * to WidgetChild related state changes.
     * <p>
     * This method is invoked after bindUI is invoked for the Widget class
     * using YUI's aop infrastructure.
     * </p>
     * @method _bindUIChild
     * @protected
     */
    _bindUIChild: function () {
        this.after("selectedChange", this._afterChildSelectedChange);
    }

};

Y.WidgetChild = Child;


}, 'patched-v3.18.1', {"requires": ["base-build", "widget"]});

YUI.add('widget-position-align', function (Y, NAME) {

/**
Provides extended/advanced XY positioning support for Widgets, through an
extension.

It builds on top of the `widget-position` module, to provide alignment and
centering support. Future releases aim to add constrained and fixed positioning
support.

@module widget-position-align
**/
var Lang = Y.Lang,

    ALIGN        = 'align',
    ALIGN_ON     = 'alignOn',

    VISIBLE      = 'visible',
    BOUNDING_BOX = 'boundingBox',

    OFFSET_WIDTH    = 'offsetWidth',
    OFFSET_HEIGHT   = 'offsetHeight',
    REGION          = 'region',
    VIEWPORT_REGION = 'viewportRegion';

/**
Widget extension, which can be used to add extended XY positioning support to
the base Widget class, through the `Base.create` method.

**Note:** This extension requires that the `WidgetPosition` extension be added
to the Widget (before `WidgetPositionAlign`, if part of the same extension list
passed to `Base.build`).

@class WidgetPositionAlign
@param {Object} config User configuration object.
@constructor
**/
function PositionAlign (config) {}

PositionAlign.ATTRS = {

    /**
    The alignment configuration for this widget.

    The `align` attribute is used to align a reference point on the widget, with
    the reference point on another `Node`, or the viewport. The object which
    `align` expects has the following properties:

      * __`node`__: The `Node` to which the widget is to be aligned. If set to
        `null`, or not provided, the widget is aligned to the viewport.

      * __`points`__: A two element Array, defining the two points on the widget
        and `Node`/viewport which are to be aligned. The first element is the
        point on the widget, and the second element is the point on the
        `Node`/viewport. Supported alignment points are defined as static
        properties on `WidgetPositionAlign`.

    @example Aligns the top-right corner of the widget with the top-left corner
    of the viewport:

        myWidget.set('align', {
            points: [Y.WidgetPositionAlign.TR, Y.WidgetPositionAlign.TL]
        });

    @attribute align
    @type Object
    @default null
    **/
    align: {
        value: null
    },

    /**
    A convenience Attribute, which can be used as a shortcut for the `align`
    Attribute.

    If set to `true`, the widget is centered in the viewport. If set to a `Node`
    reference or valid selector String, the widget will be centered within the
    `Node`. If set to `false`, no center positioning is applied.

    @attribute centered
    @type Boolean|Node
    @default false
    **/
    centered: {
        setter : '_setAlignCenter',
        lazyAdd:false,
        value  :false
    },

    /**
    An Array of Objects corresponding to the `Node`s and events that will cause
    the alignment of this widget to be synced to the DOM.

    The `alignOn` Attribute is expected to be an Array of Objects with the
    following properties:

      * __`eventName`__: The String event name to listen for.

      * __`node`__: The optional `Node` that will fire the event, it can be a
        `Node` reference or a selector String. This will default to the widget's
        `boundingBox`.

    @example Sync this widget's alignment on window resize:

        myWidget.set('alignOn', [
            {
                node     : Y.one('win'),
                eventName: 'resize'
            }
        ]);

    @attribute alignOn
    @type Array
    @default []
    **/
    alignOn: {
        value    : [],
        validator: Y.Lang.isArray
    }
};

/**
Constant used to specify the top-left corner for alignment

@property TL
@type String
@value 'tl'
@static
**/
PositionAlign.TL = 'tl';

/**
Constant used to specify the top-right corner for alignment

@property TR
@type String
@value 'tr'
@static
**/
PositionAlign.TR = 'tr';

/**
Constant used to specify the bottom-left corner for alignment

@property BL
@type String
@value 'bl'
@static
**/
PositionAlign.BL = 'bl';

/**
Constant used to specify the bottom-right corner for alignment

@property BR
@type String
@value 'br'
@static
**/
PositionAlign.BR = 'br';

/**
Constant used to specify the top edge-center point for alignment

@property TC
@type String
@value 'tc'
@static
**/
PositionAlign.TC = 'tc';

/**
Constant used to specify the right edge, center point for alignment

@property RC
@type String
@value 'rc'
@static
**/
PositionAlign.RC = 'rc';

/**
Constant used to specify the bottom edge, center point for alignment

@property BC
@type String
@value 'bc'
@static
**/
PositionAlign.BC = 'bc';

/**
Constant used to specify the left edge, center point for alignment

@property LC
@type String
@value 'lc'
@static
**/
PositionAlign.LC = 'lc';

/**
Constant used to specify the center of widget/node/viewport for alignment

@property CC
@type String
@value 'cc'
@static
*/
PositionAlign.CC = 'cc';

PositionAlign.prototype = {
    // -- Protected Properties -------------------------------------------------


    initializer : function() {
        if (!this._posNode) {
            Y.error('WidgetPosition needs to be added to the Widget, ' +
                'before WidgetPositionAlign is added');
        }

        Y.after(this._bindUIPosAlign, this, 'bindUI');
        Y.after(this._syncUIPosAlign, this, 'syncUI');
    },

    /**
    Holds the alignment-syncing event handles.

    @property _posAlignUIHandles
    @type Array
    @default null
    @protected
    **/
    _posAlignUIHandles: null,

    // -- Lifecycle Methods ----------------------------------------------------

    initializer: function() {
        if ( ! this._posNode) {
            Y.error('WidgetPosition needs to be added to the Widget, ' +
                'before WidgetPositionAlign is added');
        }

        Y.after(this._bindUIPosAlign, this, 'bindUI');
        Y.after(this._syncUIPosAlign, this, 'syncUI');
    },

    destructor: function () {
        this._detachPosAlignUIHandles();
    },

    /**
    Bind event listeners responsible for updating the UI state in response to
    the widget's position-align related state changes.

    This method is invoked after `bindUI` has been invoked for the `Widget`
    class using the AOP infrastructure.

    @method _bindUIPosAlign
    @protected
    **/
    _bindUIPosAlign: function () {
        this.after('alignChange', this._afterAlignChange);
        this.after('alignOnChange', this._afterAlignOnChange);
        this.after('visibleChange', this._syncUIPosAlign);
    },

    /**
    Synchronizes the current `align` Attribute value to the DOM.

    This method is invoked after `syncUI` has been invoked for the `Widget`
    class using the AOP infrastructure.

    @method _syncUIPosAlign
    @protected
    **/
    _syncUIPosAlign: function () {
        var align = this.get(ALIGN);

        this._uiSetVisiblePosAlign(this.get(VISIBLE));

        if (align) {
            this._uiSetAlign(align.node, align.points);
        }
    },

    // -- Public Methods -------------------------------------------------------

    /**
    Aligns this widget to the provided `Node` (or viewport) using the provided
    points. This method can be invoked with no arguments which will cause the
    widget's current `align` Attribute value to be synced to the DOM.

    @example Aligning to the top-left corner of the `<body>`:

        myWidget.align('body',
            [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.TR]);

    @method align
    @param {Node|String|null} [node] A reference (or selector String) for the
      `Node` which with the widget is to be aligned. If null is passed in, the
      widget will be aligned with the viewport.
    @param {Array[2]} [points] A two item array specifying the points on the
      widget and `Node`/viewport which will to be aligned. The first entry is
      the point on the widget, and the second entry is the point on the
      `Node`/viewport. Valid point references are defined as static constants on
      the `WidgetPositionAlign` extension.
    @chainable
    **/
    align: function (node, points) {
        if (arguments.length) {
            // Set the `align` Attribute.
            this.set(ALIGN, {
                node  : node,
                points: points
            });
        } else {
            // Sync the current `align` Attribute value to the DOM.
            this._syncUIPosAlign();
        }

        return this;
    },

    /**
    Centers the widget in the viewport, or if a `Node` is passed in, it will
    be centered to that `Node`.

    @method centered
    @param {Node|String} [node] A `Node` reference or selector String defining
      the `Node` which the widget should be centered. If a `Node` is not  passed
      in, then the widget will be centered to the viewport.
    @chainable
    **/
    centered: function (node) {
        return this.align(node, [PositionAlign.CC, PositionAlign.CC]);
    },

    // -- Protected Methods ----------------------------------------------------

    /**
    Returns coordinates realative to the passed `Node` alignment.

    @method _getAlignToXY
    @param {Node} 'Node' The node to align to.
    @param {Array} [point] The node alignment points.
    @param {Number} 'Node' x coordinate.
    @param {Number} 'Node' y coordinate.
    @return {Array} the coordinates.
    @private
    **/
    _getAlignToXY: function (node, point, x, y) {
        var xy;

        switch (point) {
        case PositionAlign.TL:
            xy = [x, y];
            break;

        case PositionAlign.TR:
            xy = [
                x - node.get(OFFSET_WIDTH),
                y
            ];
            break;

        case PositionAlign.BL:
            xy = [
                x,
                y - node.get(OFFSET_HEIGHT)
            ];
            break;

        case PositionAlign.BR:
            xy = [
                x - node.get(OFFSET_WIDTH),
                y - node.get(OFFSET_HEIGHT)
            ];
            break;

        case PositionAlign.TC:
            xy = [
                x - (node.get(OFFSET_WIDTH) / 2),
                y
            ];
            break;

        case PositionAlign.BC:
            xy = [
                x - (node.get(OFFSET_WIDTH) / 2),
                y - node.get(OFFSET_HEIGHT)
            ];
            break;

        case PositionAlign.LC:
            xy = [
                x,
                y - (node.get(OFFSET_HEIGHT) / 2)
            ];
            break;

        case PositionAlign.RC:
            xy = [
                x - node.get(OFFSET_WIDTH),
                y - (node.get(OFFSET_HEIGHT) / 2)
            ];
            break;

        case PositionAlign.CC:
            xy = [
                x - (node.get(OFFSET_WIDTH) / 2),
                y - (node.get(OFFSET_HEIGHT) / 2)
            ];
            break;

        default:
            break;

        }

        return xy;
    },

    /**
    Returns `Widget` alignment coordinates realative to the given `Node`.

    @method _getAlignedXY
    @param {Node|String|null} [node] The node to align to, or null to indicate
      the viewport.
    @param {Array} points The alignment points.
    @return {Array} the coordinates.
    @protected
    **/
    _getAlignedXY: function (node, points) {
        if ( ! Lang.isArray(points) || points.length !== 2) {
            Y.error('align: Invalid Points Arguments');
            return;
        }

        var nodeRegion = this._getRegion(node), nodePoint, xy;

        if ( ! nodeRegion) {
            // No-op, nothing to align to.
            return;
        }

        nodePoint   = points[1];

        // TODO: Optimize KWeight - Would lookup table help?
        switch (nodePoint) {
        case PositionAlign.TL:
            xy = [nodeRegion.left, nodeRegion.top];
            break;

        case PositionAlign.TR:
            xy = [nodeRegion.right, nodeRegion.top];
            break;

        case PositionAlign.BL:
            xy = [nodeRegion.left, nodeRegion.bottom];
            break;

        case PositionAlign.BR:
            xy = [nodeRegion.right, nodeRegion.bottom];
            break;

        case PositionAlign.TC:
            xy = [
                nodeRegion.left + Math.floor(nodeRegion.width / 2),
                nodeRegion.top
            ];
            break;

        case PositionAlign.BC:
            xy = [
                nodeRegion.left + Math.floor(nodeRegion.width / 2),
                nodeRegion.bottom
            ];
            break;

        case PositionAlign.LC:
            xy = [
                nodeRegion.left,
                nodeRegion.top + Math.floor(nodeRegion.height / 2)
            ];
            break;

        case PositionAlign.RC:
            xy = [
                nodeRegion.right,
                nodeRegion.top + Math.floor(nodeRegion.height / 2)
            ];
            break;

        case PositionAlign.CC:
            xy = [
                nodeRegion.left + Math.floor(nodeRegion.width / 2),
                nodeRegion.top + Math.floor(nodeRegion.height / 2)
            ];
            break;

        default:
            break;

        }

        return this._getAlignToXY(this._posNode, points[0], xy[0], xy[1]);
    },

    /**
    Default setter for `center` Attribute changes. Sets up the appropriate
    value, and passes it through the to the align attribute.

    @method _setAlignCenter
    @param {Boolean|Node} val The Attribute value being set.
    @return {Boolean|Node} the value passed in.
    @protected
    **/
    _setAlignCenter: function (val) {
        if (val) {
            this.set(ALIGN, {
                node  : val === true ? null : val,
                points: [PositionAlign.CC, PositionAlign.CC]
            });
        }

        return val;
    },

    /**
    Updates the UI to reflect the `align` value passed in.

    **Note:** See the `align` Attribute documentation, for the Object structure
    expected.

    @method _uiSetAlign
    @param {Node|String|null} [node] The node to align to, or null to indicate
      the viewport.
    @param {Array} points The alignment points.
    @protected
    **/
    _uiSetAlign: function (node, points) {
        var xy = this._getAlignedXY(node, points);

        if (xy) {
            this._doAlign(xy);
        }
    },

    /**
    Attaches or detaches alignment-syncing event handlers based on the widget's
    `visible` Attribute state.

    @method _uiSetVisiblePosAlign
    @param {Boolean} visible The current value of the widget's `visible`
      Attribute.
    @protected
    **/
    _uiSetVisiblePosAlign: function (visible) {
        if (visible) {
            this._attachPosAlignUIHandles();
        } else {
            this._detachPosAlignUIHandles();
        }
    },

    /**
    Attaches the alignment-syncing event handlers.

    @method _attachPosAlignUIHandles
    @protected
    **/
    _attachPosAlignUIHandles: function () {
        if (this._posAlignUIHandles) {
            // No-op if we have already setup the event handlers.
            return;
        }

        var bb        = this.get(BOUNDING_BOX),
            syncAlign = Y.bind(this._syncUIPosAlign, this),
            handles   = [];

        Y.Array.each(this.get(ALIGN_ON), function (o) {
            var event = o.eventName,
                node  = Y.one(o.node) || bb;

            if (event) {
                handles.push(node.on(event, syncAlign));
            }
        });

        this._posAlignUIHandles = handles;
    },

    /**
    Detaches the alignment-syncing event handlers.

    @method _detachPosAlignUIHandles
    @protected
    **/
    _detachPosAlignUIHandles: function () {
        var handles = this._posAlignUIHandles;
        if (handles) {
            new Y.EventHandle(handles).detach();
            this._posAlignUIHandles = null;
        }
    },

    // -- Private Methods ------------------------------------------------------

    /**
    Helper method, used to align the given point on the widget, with the XY page
    coordinates provided.

    @method _doAlign
    @param {Array} xy XY page coordinates to align to.
    @private
    **/
    _doAlign: function(xy) {
        if (xy) {
            this.move(xy);
        }
    },

    /**
    Returns the region of the passed-in `Node`, or the viewport region if
    calling with passing in a `Node`.

    @method _getRegion
    @param {Node} [node] The node to get the region of.
    @return {Object} The node's region.
    @private
    **/
    _getRegion: function (node) {
        var nodeRegion;

        if ( ! node) {
            nodeRegion = this._posNode.get(VIEWPORT_REGION);
        } else {
            node = Y.Node.one(node);
            if (node) {
                nodeRegion = node.get(REGION);
            }
        }

        return nodeRegion;
    },

    // -- Protected Event Handlers ---------------------------------------------

    /**
    Handles `alignChange` events by updating the UI in response to `align`
    Attribute changes.

    @method _afterAlignChange
    @param {EventFacade} e
    @protected
    **/
    _afterAlignChange: function (e) {
        var align = e.newVal;
        if (align) {
            this._uiSetAlign(align.node, align.points);
        }
    },

    /**
    Handles `alignOnChange` events by updating the alignment-syncing event
    handlers.

    @method _afterAlignOnChange
    @param {EventFacade} e
    @protected
    **/
    _afterAlignOnChange: function(e) {
        this._detachPosAlignUIHandles();

        if (this.get(VISIBLE)) {
            this._attachPosAlignUIHandles();
        }
    }
};

Y.WidgetPositionAlign = PositionAlign;


}, 'patched-v3.18.1', {"requires": ["widget-position"]});

YUI.add('widget-position-constrain', function (Y, NAME) {

/**
 * Provides constrained xy positioning support for Widgets, through an extension.
 *
 * It builds on top of the widget-position module, to provide constrained positioning support.
 *
 * @module widget-position-constrain
 */
var CONSTRAIN = "constrain",
    CONSTRAIN_XYCHANGE = "constrain|xyChange",
    CONSTRAIN_CHANGE = "constrainChange",

    PREVENT_OVERLAP = "preventOverlap",
    ALIGN = "align",

    EMPTY_STR = "",

    BINDUI = "bindUI",

    XY = "xy",
    X_COORD = "x",
    Y_COORD = "y",

    Node = Y.Node,

    VIEWPORT_REGION = "viewportRegion",
    REGION = "region",

    PREVENT_OVERLAP_MAP;

/**
 * A widget extension, which can be used to add constrained xy positioning support to the base Widget class,
 * through the <a href="Base.html#method_build">Base.build</a> method. This extension requires that
 * the WidgetPosition extension be added to the Widget (before WidgetPositionConstrain, if part of the same
 * extension list passed to Base.build).
 *
 * @class WidgetPositionConstrain
 * @param {Object} User configuration object
 */
function PositionConstrain(config) {}

/**
 * Static property used to define the default attribute
 * configuration introduced by WidgetPositionConstrain.
 *
 * @property ATTRS
 * @type Object
 * @static
 */
PositionConstrain.ATTRS = {

    /**
     * @attribute constrain
     * @type boolean | Node
     * @default null
     * @description The node to constrain the widget's bounding box to, when setting xy. Can also be
     * set to true, to constrain to the viewport.
     */
    constrain : {
        value: null,
        setter: "_setConstrain"
    },

    /**
     * @attribute preventOverlap
     * @type boolean
     * @description If set to true, and WidgetPositionAlign is also added to the Widget,
     * constrained positioning will attempt to prevent the widget's bounding box from overlapping
     * the element to which it has been aligned, by flipping the orientation of the alignment
     * for corner based alignments
     */
    preventOverlap : {
        value:false
    }
};

/**
 * @property _PREVENT_OVERLAP
 * @static
 * @protected
 * @type Object
 * @description The set of positions for which to prevent
 * overlap.
 */
PREVENT_OVERLAP_MAP = PositionConstrain._PREVENT_OVERLAP = {
    x: {
        "tltr": 1,
        "blbr": 1,
        "brbl": 1,
        "trtl": 1
    },
    y : {
        "trbr": 1,
        "tlbl": 1,
        "bltl": 1,
        "brtr": 1
    }
};

PositionConstrain.prototype = {

    initializer : function() {
        if (!this._posNode) {
            Y.error("WidgetPosition needs to be added to the Widget, before WidgetPositionConstrain is added");
        }
        Y.after(this._bindUIPosConstrained, this, BINDUI);
    },

    /**
     * Calculates the constrained positions for the XY positions provided, using
     * the provided node argument is passed in. If no node value is passed in, the value of
     * the "constrain" attribute is used.
     *
     * @method getConstrainedXY
     * @param {Array} xy The xy values to constrain
     * @param {Node | boolean} node Optional. The node to constrain to, or true for the viewport
     * @return {Array} The constrained xy values
     */
    getConstrainedXY : function(xy, node) {
        node = node || this.get(CONSTRAIN);

        var constrainingRegion = this._getRegion((node === true) ? null : node),
            nodeRegion = this._posNode.get(REGION);

        return [
            this._constrain(xy[0], X_COORD, nodeRegion, constrainingRegion),
            this._constrain(xy[1], Y_COORD, nodeRegion, constrainingRegion)
        ];
    },

    /**
     * Constrains the widget's bounding box to a node (or the viewport). If xy or node are not
     * passed in, the current position and the value of "constrain" will be used respectively.
     *
     * The widget's position will be changed to the constrained position.
     *
     * @method constrain
     * @param {Array} xy Optional. The xy values to constrain
     * @param {Node | boolean} node Optional. The node to constrain to, or true for the viewport
     */
    constrain : function(xy, node) {
        var currentXY,
            constrainedXY,
            constraint = node || this.get(CONSTRAIN);

        if (constraint) {
            currentXY = xy || this.get(XY);
            constrainedXY = this.getConstrainedXY(currentXY, constraint);

            if (constrainedXY[0] !== currentXY[0] || constrainedXY[1] !== currentXY[1]) {
                this.set(XY, constrainedXY, { constrained:true });
            }
        }
    },

    /**
     * The setter implementation for the "constrain" attribute.
     *
     * @method _setConstrain
     * @protected
     * @param {Node | boolean} val The attribute value
     */
    _setConstrain : function(val) {
        return (val === true) ? val : Node.one(val);
    },

    /**
     * The method which performs the actual constrain calculations for a given axis ("x" or "y") based
     * on the regions provided.
     *
     * @method _constrain
     * @protected
     *
     * @param {Number} val The value to constrain
     * @param {String} axis The axis to use for constrainment
     * @param {Region} nodeRegion The region of the node to constrain
     * @param {Region} constrainingRegion The region of the node (or viewport) to constrain to
     *
     * @return {Number} The constrained value
     */
    _constrain: function(val, axis, nodeRegion, constrainingRegion) {
        if (constrainingRegion) {

            if (this.get(PREVENT_OVERLAP)) {
                val = this._preventOverlap(val, axis, nodeRegion, constrainingRegion);
            }

            var x = (axis == X_COORD),

                regionSize    = (x) ? constrainingRegion.width : constrainingRegion.height,
                nodeSize      = (x) ? nodeRegion.width : nodeRegion.height,
                minConstraint = (x) ? constrainingRegion.left : constrainingRegion.top,
                maxConstraint = (x) ? constrainingRegion.right - nodeSize : constrainingRegion.bottom - nodeSize;

            if (val < minConstraint || val > maxConstraint) {
                if (nodeSize < regionSize) {
                    if (val < minConstraint) {
                        val = minConstraint;
                    } else if (val > maxConstraint) {
                        val = maxConstraint;
                    }
                } else {
                    val = minConstraint;
                }
            }
        }

        return val;
    },

    /**
     * The method which performs the preventOverlap calculations for a given axis ("x" or "y") based
     * on the value and regions provided.
     *
     * @method _preventOverlap
     * @protected
     *
     * @param {Number} val The value being constrain
     * @param {String} axis The axis to being constrained
     * @param {Region} nodeRegion The region of the node being constrained
     * @param {Region} constrainingRegion The region of the node (or viewport) we need to constrain to
     *
     * @return {Number} The constrained value
     */
    _preventOverlap : function(val, axis, nodeRegion, constrainingRegion) {

        var align = this.get(ALIGN),
            x = (axis === X_COORD),
            nodeSize,
            alignRegion,
            nearEdge,
            farEdge,
            spaceOnNearSide,
            spaceOnFarSide;

        if (align && align.points && PREVENT_OVERLAP_MAP[axis][align.points.join(EMPTY_STR)]) {

            alignRegion = this._getRegion(align.node);

            if (alignRegion) {
                nodeSize        = (x) ? nodeRegion.width : nodeRegion.height;
                nearEdge        = (x) ? alignRegion.left : alignRegion.top;
                farEdge         = (x) ? alignRegion.right : alignRegion.bottom;
                spaceOnNearSide = (x) ? alignRegion.left - constrainingRegion.left : alignRegion.top - constrainingRegion.top;
                spaceOnFarSide  = (x) ? constrainingRegion.right - alignRegion.right : constrainingRegion.bottom - alignRegion.bottom;
            }

            if (val > nearEdge) {
                if (spaceOnFarSide < nodeSize && spaceOnNearSide > nodeSize) {
                    val = nearEdge - nodeSize;
                }
            } else {
                if (spaceOnNearSide < nodeSize && spaceOnFarSide > nodeSize) {
                    val = farEdge;
                }
            }
        }

        return val;
    },

    /**
     * Binds event listeners responsible for updating the UI state in response to
     * Widget constrained positioning related state changes.
     * <p>
     * This method is invoked after bindUI is invoked for the Widget class
     * using YUI's aop infrastructure.
     * </p>
     *
     * @method _bindUIPosConstrained
     * @protected
     */
    _bindUIPosConstrained : function() {
        this.after(CONSTRAIN_CHANGE, this._afterConstrainChange);
        this._enableConstraints(this.get(CONSTRAIN));
    },

    /**
     * After change listener for the "constrain" attribute, responsible
     * for updating the UI, in response to attribute changes.
     *
     * @method _afterConstrainChange
     * @protected
     * @param {EventFacade} e The event facade
     */
    _afterConstrainChange : function(e) {
        this._enableConstraints(e.newVal);
    },

    /**
     * Updates the UI if enabling constraints, and sets up the xyChange event listeners
     * to constrain whenever the widget is moved. Disabling constraints removes the listeners.
     *
     * @method _enableConstraints
     * @private
     * @param {boolean} enable Enable or disable constraints
     */
    _enableConstraints : function(enable) {
        if (enable) {
            this.constrain();
            this._cxyHandle = this._cxyHandle || this.on(CONSTRAIN_XYCHANGE, this._constrainOnXYChange);
        } else if (this._cxyHandle) {
            this._cxyHandle.detach();
            this._cxyHandle = null;
        }
    },

    /**
     * The on change listener for the "xy" attribute. Modifies the event facade's
     * newVal property with the constrained XY value.
     *
     * @method _constrainOnXYChange
     * @protected
     * @param {EventFacade} e The event facade for the attribute change
     */
    _constrainOnXYChange : function(e) {
        if (!e.constrained) {
            e.newVal = this.getConstrainedXY(e.newVal);
        }
    },

    /**
     * Utility method to normalize region retrieval from a node instance,
     * or the viewport, if no node is provided.
     *
     * @method _getRegion
     * @private
     * @param {Node} node Optional.
     */
    _getRegion : function(node) {
        var region;
        if (!node) {
            region = this._posNode.get(VIEWPORT_REGION);
        } else {
            node = Node.one(node);
            if (node) {
                region = node.get(REGION);
            }
        }
        return region;
    }
};

Y.WidgetPositionConstrain = PositionConstrain;


}, 'patched-v3.18.1', {"requires": ["widget-position"]});

YUI.add('widget-position', function (Y, NAME) {

/**
 * Provides basic XY positioning support for Widgets, though an extension
 *
 * @module widget-position
 */
    var Lang = Y.Lang,
        Widget = Y.Widget,

        XY_COORD = "xy",

        POSITION = "position",
        POSITIONED = "positioned",
        BOUNDING_BOX = "boundingBox",
        RELATIVE = "relative",

        RENDERUI = "renderUI",
        BINDUI = "bindUI",
        SYNCUI = "syncUI",

        UI = Widget.UI_SRC,

        XYChange = "xyChange";

    /**
     * Widget extension, which can be used to add positioning support to the base Widget class,
     * through the <a href="Base.html#method_build">Base.build</a> method.
     *
     * @class WidgetPosition
     * @param {Object} config User configuration object
     */
    function Position(config) {
    }

    /**
     * Static property used to define the default attribute
     * configuration introduced by WidgetPosition.
     *
     * @property ATTRS
     * @static
     * @type Object
     */
    Position.ATTRS = {

        /**
         * @attribute x
         * @type number
         * @default 0
         *
         * @description Page X co-ordinate for the widget. This attribute acts as a facade for the
         * xy attribute. Changes in position can be monitored by listening for xyChange events.
         */
        x: {
            setter: function(val) {
                this._setX(val);
            },
            getter: function() {
                return this._getX();
            },
            lazyAdd:false
        },

        /**
         * @attribute y
         * @type number
         * @default 0
         *
         * @description Page Y co-ordinate for the widget. This attribute acts as a facade for the
         * xy attribute. Changes in position can be monitored by listening for xyChange events.
         */
        y: {
            setter: function(val) {
                this._setY(val);
            },
            getter: function() {
                return this._getY();
            },
            lazyAdd: false
        },

        /**
         * @attribute xy
         * @type Array
         * @default [0,0]
         *
         * @description Page XY co-ordinate pair for the widget.
         */
        xy: {
            value:[0,0],
            validator: function(val) {
                return this._validateXY(val);
            }
        }
    };

    /**
     * Default class used to mark the boundingBox of a positioned widget.
     *
     * @property POSITIONED_CLASS_NAME
     * @type String
     * @default "yui-widget-positioned"
     * @static
     */
    Position.POSITIONED_CLASS_NAME = Widget.getClassName(POSITIONED);

    Position.prototype = {

        initializer : function() {
            this._posNode = this.get(BOUNDING_BOX);

            // WIDGET METHOD OVERLAP
            Y.after(this._renderUIPosition, this, RENDERUI);
            Y.after(this._syncUIPosition, this, SYNCUI);
            Y.after(this._bindUIPosition, this, BINDUI);
        },

        /**
         * Creates/Initializes the DOM to support xy page positioning.
         * <p>
         * This method in invoked after renderUI is invoked for the Widget class
         * using YUI's aop infrastructure.
         * </p>
         * @method _renderUIPosition
         * @protected
         */
        _renderUIPosition : function() {
            this._posNode.addClass(Position.POSITIONED_CLASS_NAME);
        },

        /**
         * Synchronizes the UI to match the Widgets xy page position state.
         * <p>
         * This method in invoked after syncUI is invoked for the Widget class
         * using YUI's aop infrastructure.
         * </p>
         * @method _syncUIPosition
         * @protected
         */
        _syncUIPosition : function() {
            var posNode = this._posNode;
            if (posNode.getStyle(POSITION) === RELATIVE) {
                this.syncXY();
            }
            this._uiSetXY(this.get(XY_COORD));
        },

        /**
         * Binds event listeners responsible for updating the UI state in response to
         * Widget position related state changes.
         * <p>
         * This method in invoked after bindUI is invoked for the Widget class
         * using YUI's aop infrastructure.
         * </p>
         * @method _bindUIPosition
         * @protected
         */
        _bindUIPosition :function() {
            this.after(XYChange, this._afterXYChange);
        },

        /**
         * Moves the Widget to the specified page xy co-ordinate position.
         *
         * @method move
         *
         * @param {Number|Number[]} x The new x position or [x, y] values passed
         * as an array to support simple pass through of Node.getXY results
         * @param {Number} [y] The new y position
         */
        move: function () {
            var args = arguments,
                coord = (Lang.isArray(args[0])) ? args[0] : [args[0], args[1]];
                this.set(XY_COORD, coord);
        },

        /**
         * Synchronizes the Panel's "xy", "x", and "y" properties with the
         * Widget's position in the DOM.
         *
         * @method syncXY
         */
        syncXY : function () {
            this.set(XY_COORD, this._posNode.getXY(), {src: UI});
        },

        /**
         * Default validator for the XY attribute
         *
         * @method _validateXY
         * @protected
         * @param {Array} val The XY page co-ordinate value which is being set.
         * @return {boolean} true if valid, false if not.
         */
        _validateXY : function(val) {
            return (Lang.isArray(val) && Lang.isNumber(val[0]) && Lang.isNumber(val[1]));
        },

        /**
         * Default setter for the X attribute. The setter passes the X value through
         * to the XY attribute, which is the sole store for the XY state.
         *
         * @method _setX
         * @protected
         * @param {Number} val The X page co-ordinate value
         */
        _setX : function(val) {
            this.set(XY_COORD, [val, this.get(XY_COORD)[1]]);
        },

        /**
         * Default setter for the Y attribute. The setter passes the Y value through
         * to the XY attribute, which is the sole store for the XY state.
         *
         * @method _setY
         * @protected
         * @param {Number} val The Y page co-ordinate value
         */
        _setY : function(val) {
            this.set(XY_COORD, [this.get(XY_COORD)[0], val]);
        },

        /**
         * Default getter for the X attribute. The value is retrieved from
         * the XY attribute, which is the sole store for the XY state.
         *
         * @method _getX
         * @protected
         * @return {Number} The X page co-ordinate value
         */
        _getX : function() {
            return this.get(XY_COORD)[0];
        },

        /**
         * Default getter for the Y attribute. The value is retrieved from
         * the XY attribute, which is the sole store for the XY state.
         *
         * @method _getY
         * @protected
         * @return {Number} The Y page co-ordinate value
         */
        _getY : function() {
            return this.get(XY_COORD)[1];
        },

        /**
         * Default attribute change listener for the xy attribute, responsible
         * for updating the UI, in response to attribute changes.
         *
         * @method _afterXYChange
         * @protected
         * @param {EventFacade} e The event facade for the attribute change
         */
        _afterXYChange : function(e) {
            if (e.src != UI) {
                this._uiSetXY(e.newVal);
            }
        },

        /**
         * Updates the UI to reflect the XY page co-ordinates passed in.
         *
         * @method _uiSetXY
         * @protected
         * @param {String} val The XY page co-ordinates value to be reflected in the UI
         */
        _uiSetXY : function(val) {
            this._posNode.setXY(val);
        }
    };

    Y.WidgetPosition = Position;


}, 'patched-v3.18.1', {"requires": ["base-build", "node-screen", "widget"]});

YUI.add('widget-stack', function (Y, NAME) {

/**
 * Provides stackable (z-index) support for Widgets through an extension.
 *
 * @module widget-stack
 */
    var L = Y.Lang,
        UA = Y.UA,
        Node = Y.Node,
        Widget = Y.Widget,

        ZINDEX = "zIndex",
        SHIM = "shim",
        VISIBLE = "visible",

        BOUNDING_BOX = "boundingBox",

        RENDER_UI = "renderUI",
        BIND_UI = "bindUI",
        SYNC_UI = "syncUI",

        OFFSET_WIDTH = "offsetWidth",
        OFFSET_HEIGHT = "offsetHeight",
        PARENT_NODE = "parentNode",
        FIRST_CHILD = "firstChild",
        OWNER_DOCUMENT = "ownerDocument",

        WIDTH = "width",
        HEIGHT = "height",
        PX = "px",

        // HANDLE KEYS
        SHIM_DEFERRED = "shimdeferred",
        SHIM_RESIZE = "shimresize",

        // Events
        VisibleChange = "visibleChange",
        WidthChange = "widthChange",
        HeightChange = "heightChange",
        ShimChange = "shimChange",
        ZIndexChange = "zIndexChange",
        ContentUpdate = "contentUpdate",

        // CSS
        STACKED = "stacked";

    /**
     * Widget extension, which can be used to add stackable (z-index) support to the
     * base Widget class along with a shimming solution, through the
     * <a href="Base.html#method_build">Base.build</a> method.
     *
     * @class WidgetStack
     * @param {Object} User configuration object
     */
    function Stack(config) {}

    // Static Properties
    /**
     * Static property used to define the default attribute
     * configuration introduced by WidgetStack.
     *
     * @property ATTRS
     * @type Object
     * @static
     */
    Stack.ATTRS = {
        /**
         * @attribute shim
         * @type boolean
         * @default false, for all browsers other than IE6, for which a shim is enabled by default.
         *
         * @description Boolean flag to indicate whether or not a shim should be added to the Widgets
         * boundingBox, to protect it from select box bleedthrough.
         */
        shim: {
            value: (UA.ie == 6)
        },

        /**
         * @attribute zIndex
         * @type number
         * @default 0
         * @description The z-index to apply to the Widgets boundingBox. Non-numerical values for
         * zIndex will be converted to 0
         */
        zIndex: {
            value : 0,
            setter: '_setZIndex'
        }
    };

    /**
     * The HTML parsing rules for the WidgetStack class.
     *
     * @property HTML_PARSER
     * @static
     * @type Object
     */
    Stack.HTML_PARSER = {
        zIndex: function (srcNode) {
            return this._parseZIndex(srcNode);
        }
    };

    /**
     * Default class used to mark the shim element
     *
     * @property SHIM_CLASS_NAME
     * @type String
     * @static
     * @default "yui3-widget-shim"
     */
    Stack.SHIM_CLASS_NAME = Widget.getClassName(SHIM);

    /**
     * Default class used to mark the boundingBox of a stacked widget.
     *
     * @property STACKED_CLASS_NAME
     * @type String
     * @static
     * @default "yui3-widget-stacked"
     */
    Stack.STACKED_CLASS_NAME = Widget.getClassName(STACKED);

    /**
     * Default markup template used to generate the shim element.
     *
     * @property SHIM_TEMPLATE
     * @type String
     * @static
     */
    Stack.SHIM_TEMPLATE = '<iframe class="' + Stack.SHIM_CLASS_NAME + '" frameborder="0" title="Widget Stacking Shim" src="javascript:false" tabindex="-1" role="presentation"></iframe>';

    Stack.prototype = {

        initializer : function() {
            this._stackNode = this.get(BOUNDING_BOX);
            this._stackHandles = {};

            // WIDGET METHOD OVERLAP
            Y.after(this._renderUIStack, this, RENDER_UI);
            Y.after(this._syncUIStack, this, SYNC_UI);
            Y.after(this._bindUIStack, this, BIND_UI);
        },

        /**
         * Synchronizes the UI to match the Widgets stack state. This method in
         * invoked after syncUI is invoked for the Widget class using YUI's aop infrastructure.
         *
         * @method _syncUIStack
         * @protected
         */
        _syncUIStack: function() {
            this._uiSetShim(this.get(SHIM));
            this._uiSetZIndex(this.get(ZINDEX));
        },

        /**
         * Binds event listeners responsible for updating the UI state in response to
         * Widget stack related state changes.
         * <p>
         * This method is invoked after bindUI is invoked for the Widget class
         * using YUI's aop infrastructure.
         * </p>
         * @method _bindUIStack
         * @protected
         */
        _bindUIStack: function() {
            this.after(ShimChange, this._afterShimChange);
            this.after(ZIndexChange, this._afterZIndexChange);
        },

        /**
         * Creates/Initializes the DOM to support stackability.
         * <p>
         * This method in invoked after renderUI is invoked for the Widget class
         * using YUI's aop infrastructure.
         * </p>
         * @method _renderUIStack
         * @protected
         */
        _renderUIStack: function() {
            this._stackNode.addClass(Stack.STACKED_CLASS_NAME);
        },

        /**
        Parses a `zIndex` attribute value from this widget's `srcNode`.

        @method _parseZIndex
        @param {Node} srcNode The node to parse a `zIndex` value from.
        @return {Mixed} The parsed `zIndex` value.
        @protected
        **/
        _parseZIndex: function (srcNode) {
            var zIndex;

            // Prefers how WebKit handles `z-index` which better matches the
            // spec:
            //
            // * http://www.w3.org/TR/CSS2/visuren.html#z-index
            // * https://bugs.webkit.org/show_bug.cgi?id=15562
            //
            // When a node isn't rendered in the document, and/or when a
            // node is not positioned, then it doesn't have a context to derive
            // a valid `z-index` value from.
            if (!srcNode.inDoc() || srcNode.getStyle('position') === 'static') {
                zIndex = 'auto';
            } else {
                // Uses `getComputedStyle()` because it has greater accuracy in
                // more browsers than `getStyle()` does for `z-index`.
                zIndex = srcNode.getComputedStyle('zIndex');
            }

            // This extension adds a stacking context to widgets, therefore a
            // `srcNode` witout a stacking context (i.e. "auto") will return
            // `null` from this DOM parser. This way the widget's default or
            // user provided value for `zIndex` will be used.
            return zIndex === 'auto' ? null : zIndex;
        },

        /**
         * Default setter for zIndex attribute changes. Normalizes zIndex values to
         * numbers, converting non-numerical values to 0.
         *
         * @method _setZIndex
         * @protected
         * @param {String | Number} zIndex
         * @return {Number} Normalized zIndex
         */
        _setZIndex: function(zIndex) {
            if (L.isString(zIndex)) {
                zIndex = parseInt(zIndex, 10);
            }
            if (!L.isNumber(zIndex)) {
                zIndex = 0;
            }
            return zIndex;
        },

        /**
         * Default attribute change listener for the shim attribute, responsible
         * for updating the UI, in response to attribute changes.
         *
         * @method _afterShimChange
         * @protected
         * @param {EventFacade} e The event facade for the attribute change
         */
        _afterShimChange : function(e) {
            this._uiSetShim(e.newVal);
        },

        /**
         * Default attribute change listener for the zIndex attribute, responsible
         * for updating the UI, in response to attribute changes.
         *
         * @method _afterZIndexChange
         * @protected
         * @param {EventFacade} e The event facade for the attribute change
         */
        _afterZIndexChange : function(e) {
            this._uiSetZIndex(e.newVal);
        },

        /**
         * Updates the UI to reflect the zIndex value passed in.
         *
         * @method _uiSetZIndex
         * @protected
         * @param {number} zIndex The zindex to be reflected in the UI
         */
        _uiSetZIndex: function (zIndex) {
            this._stackNode.setStyle(ZINDEX, zIndex);
        },

        /**
         * Updates the UI to enable/disable the shim. If the widget is not currently visible,
         * creation of the shim is deferred until it is made visible, for performance reasons.
         *
         * @method _uiSetShim
         * @protected
         * @param {boolean} enable If true, creates/renders the shim, if false, removes it.
         */
        _uiSetShim: function (enable) {
            if (enable) {
                // Lazy creation
                if (this.get(VISIBLE)) {
                    this._renderShim();
                } else {
                    this._renderShimDeferred();
                }

                // Eagerly attach resize handlers
                //
                // Required because of Event stack behavior, commit ref: cd8dddc
                // Should be revisted after Ticket #2531067 is resolved.
                if (UA.ie == 6) {
                    this._addShimResizeHandlers();
                }
            } else {
                this._destroyShim();
            }
        },

        /**
         * Sets up change handlers for the visible attribute, to defer shim creation/rendering
         * until the Widget is made visible.
         *
         * @method _renderShimDeferred
         * @private
         */
        _renderShimDeferred : function() {

            this._stackHandles[SHIM_DEFERRED] = this._stackHandles[SHIM_DEFERRED] || [];

            var handles = this._stackHandles[SHIM_DEFERRED],
                createBeforeVisible = function(e) {
                    if (e.newVal) {
                        this._renderShim();
                    }
                };

            handles.push(this.on(VisibleChange, createBeforeVisible));
            // Depending how how Ticket #2531067 is resolved, a reversal of
            // commit ref: cd8dddc could lead to a more elagent solution, with
            // the addition of this line here:
            //
            // handles.push(this.after(VisibleChange, this.sizeShim));
        },

        /**
         * Sets up event listeners to resize the shim when the size of the Widget changes.
         * <p>
         * NOTE: This method is only used for IE6 currently, since IE6 doesn't support a way to
         * resize the shim purely through CSS, when the Widget does not have an explicit width/height
         * set.
         * </p>
         * @method _addShimResizeHandlers
         * @private
         */
        _addShimResizeHandlers : function() {

            this._stackHandles[SHIM_RESIZE] = this._stackHandles[SHIM_RESIZE] || [];

            var sizeShim = this.sizeShim,
                handles = this._stackHandles[SHIM_RESIZE];

            handles.push(this.after(VisibleChange, sizeShim));
            handles.push(this.after(WidthChange, sizeShim));
            handles.push(this.after(HeightChange, sizeShim));
            handles.push(this.after(ContentUpdate, sizeShim));
        },

        /**
         * Detaches any handles stored for the provided key
         *
         * @method _detachStackHandles
         * @param String handleKey The key defining the group of handles which should be detached
         * @private
         */
        _detachStackHandles : function(handleKey) {
            var handles = this._stackHandles[handleKey],
                handle;

            if (handles && handles.length > 0) {
                while((handle = handles.pop())) {
                    handle.detach();
                }
            }
        },

        /**
         * Creates the shim element and adds it to the DOM
         *
         * @method _renderShim
         * @private
         */
        _renderShim : function() {
            var shimEl = this._shimNode,
                stackEl = this._stackNode;

            if (!shimEl) {
                shimEl = this._shimNode = this._getShimTemplate();
                stackEl.insertBefore(shimEl, stackEl.get(FIRST_CHILD));

                this._detachStackHandles(SHIM_DEFERRED);
                this.sizeShim();
            }
        },

        /**
         * Removes the shim from the DOM, and detaches any related event
         * listeners.
         *
         * @method _destroyShim
         * @private
         */
        _destroyShim : function() {
            if (this._shimNode) {
                this._shimNode.get(PARENT_NODE).removeChild(this._shimNode);
                this._shimNode = null;

                this._detachStackHandles(SHIM_DEFERRED);
                this._detachStackHandles(SHIM_RESIZE);
            }
        },

        /**
         * For IE6, synchronizes the size and position of iframe shim to that of
         * Widget bounding box which it is protecting. For all other browsers,
         * this method does not do anything.
         *
         * @method sizeShim
         */
        sizeShim: function () {
            var shim = this._shimNode,
                node = this._stackNode;

            if (shim && UA.ie === 6 && this.get(VISIBLE)) {
                shim.setStyle(WIDTH, node.get(OFFSET_WIDTH) + PX);
                shim.setStyle(HEIGHT, node.get(OFFSET_HEIGHT) + PX);
            }
        },

        /**
         * Creates a cloned shim node, using the SHIM_TEMPLATE html template, for use on a new instance.
         *
         * @method _getShimTemplate
         * @private
         * @return {Node} node A new shim Node instance.
         */
        _getShimTemplate : function() {
            return Node.create(Stack.SHIM_TEMPLATE, this._stackNode.get(OWNER_DOCUMENT));
        }
    };

    Y.WidgetStack = Stack;


}, 'patched-v3.18.1', {"requires": ["base-build", "widget"], "skinnable": true});

YUI.add('widget-stdmod', function (Y, NAME) {

/**
 * Provides standard module support for Widgets through an extension.
 *
 * @module widget-stdmod
 */
    var L = Y.Lang,
        Node = Y.Node,
        UA = Y.UA,
        Widget = Y.Widget,

        EMPTY = "",
        HD = "hd",
        BD = "bd",
        FT = "ft",
        HEADER = "header",
        BODY = "body",
        FOOTER = "footer",
        FILL_HEIGHT = "fillHeight",
        STDMOD = "stdmod",

        NODE_SUFFIX = "Node",
        CONTENT_SUFFIX = "Content",

        FIRST_CHILD = "firstChild",
        CHILD_NODES = "childNodes",
        OWNER_DOCUMENT = "ownerDocument",

        CONTENT_BOX = "contentBox",

        HEIGHT = "height",
        OFFSET_HEIGHT = "offsetHeight",
        AUTO = "auto",

        HeaderChange = "headerContentChange",
        BodyChange = "bodyContentChange",
        FooterChange = "footerContentChange",
        FillHeightChange = "fillHeightChange",
        HeightChange = "heightChange",
        ContentUpdate = "contentUpdate",

        RENDERUI = "renderUI",
        BINDUI = "bindUI",
        SYNCUI = "syncUI",

        APPLY_PARSED_CONFIG = "_applyParsedConfig",

        UI = Y.Widget.UI_SRC;

    /**
     * Widget extension, which can be used to add Standard Module support to the
     * base Widget class, through the <a href="Base.html#method_build">Base.build</a>
     * method.
     * <p>
     * The extension adds header, body and footer sections to the Widget's content box and
     * provides the corresponding methods and attributes to modify the contents of these sections.
     * </p>
     * @class WidgetStdMod
     * @param {Object} The user configuration object
     */
    function StdMod(config) {}

    /**
     * Constant used to refer the the standard module header, in methods which expect a section specifier
     *
     * @property HEADER
     * @static
     * @type String
     */
    StdMod.HEADER = HEADER;

    /**
     * Constant used to refer the the standard module body, in methods which expect a section specifier
     *
     * @property BODY
     * @static
     * @type String
     */
    StdMod.BODY = BODY;

    /**
     * Constant used to refer the the standard module footer, in methods which expect a section specifier
     *
     * @property FOOTER
     * @static
     * @type String
     */
    StdMod.FOOTER = FOOTER;

    /**
     * Constant used to specify insertion position, when adding content to sections of the standard module in
     * methods which expect a "where" argument.
     * <p>
     * Inserts new content <em>before</em> the sections existing content.
     * </p>
     * @property AFTER
     * @static
     * @type String
     */
    StdMod.AFTER = "after";

    /**
     * Constant used to specify insertion position, when adding content to sections of the standard module in
     * methods which expect a "where" argument.
     * <p>
     * Inserts new content <em>before</em> the sections existing content.
     * </p>
     * @property BEFORE
     * @static
     * @type String
     */
    StdMod.BEFORE = "before";
    /**
     * Constant used to specify insertion position, when adding content to sections of the standard module in
     * methods which expect a "where" argument.
     * <p>
     * <em>Replaces</em> the sections existing content, with new content.
     * </p>
     * @property REPLACE
     * @static
     * @type String
     */
    StdMod.REPLACE = "replace";

    var STD_HEADER = StdMod.HEADER,
        STD_BODY = StdMod.BODY,
        STD_FOOTER = StdMod.FOOTER,

        HEADER_CONTENT = STD_HEADER + CONTENT_SUFFIX,
        FOOTER_CONTENT = STD_FOOTER + CONTENT_SUFFIX,
        BODY_CONTENT = STD_BODY + CONTENT_SUFFIX;

    /**
     * Static property used to define the default attribute
     * configuration introduced by WidgetStdMod.
     *
     * @property ATTRS
     * @type Object
     * @static
     */
    StdMod.ATTRS = {

        /**
         * @attribute headerContent
         * @type HTML
         * @default undefined
         * @description The content to be added to the header section. This will replace any existing content
         * in the header. If you want to append, or insert new content, use the <a href="#method_setStdModContent">setStdModContent</a> method.
         */
        headerContent: {
            value:null
        },

        /**
         * @attribute footerContent
         * @type HTML
         * @default undefined
         * @description The content to be added to the footer section. This will replace any existing content
         * in the footer. If you want to append, or insert new content, use the <a href="#method_setStdModContent">setStdModContent</a> method.
         */
        footerContent: {
            value:null
        },

        /**
         * @attribute bodyContent
         * @type HTML
         * @default undefined
         * @description The content to be added to the body section. This will replace any existing content
         * in the body. If you want to append, or insert new content, use the <a href="#method_setStdModContent">setStdModContent</a> method.
         */
        bodyContent: {
            value:null
        },

        /**
         * @attribute fillHeight
         * @type {String}
         * @default WidgetStdMod.BODY
         * @description The section (WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER) which should be resized to fill the height of the standard module, when a
         * height is set on the Widget. If a height is not set on the widget, then all sections are sized based on
         * their content.
         */
        fillHeight: {
            value: StdMod.BODY,
            validator: function(val) {
                 return this._validateFillHeight(val);
            }
        }
    };

    /**
     * The HTML parsing rules for the WidgetStdMod class.
     *
     * @property HTML_PARSER
     * @static
     * @type Object
     */
    StdMod.HTML_PARSER = {
        headerContent: function(contentBox) {
            return this._parseStdModHTML(STD_HEADER);
        },

        bodyContent: function(contentBox) {
            return this._parseStdModHTML(STD_BODY);
        },

        footerContent : function(contentBox) {
            return this._parseStdModHTML(STD_FOOTER);
        }
    };

    /**
     * Static hash of default class names used for the header,
     * body and footer sections of the standard module, keyed by
     * the section identifier (WidgetStdMod.STD_HEADER, WidgetStdMod.STD_BODY, WidgetStdMod.STD_FOOTER)
     *
     * @property SECTION_CLASS_NAMES
     * @static
     * @type Object
     */
    StdMod.SECTION_CLASS_NAMES = {
        header: Widget.getClassName(HD),
        body: Widget.getClassName(BD),
        footer: Widget.getClassName(FT)
    };

    /**
     * The template HTML strings for each of the standard module sections. Section entries are keyed by the section constants,
     * WidgetStdMod.HEADER, WidgetStdMod.BODY, WidgetStdMod.FOOTER, and contain the HTML to be added for each section.
     * e.g.
     * <pre>
     *    {
     *       header : '&lt;div class="yui-widget-hd"&gt;&lt;/div&gt;',
     *       body : '&lt;div class="yui-widget-bd"&gt;&lt;/div&gt;',
     *       footer : '&lt;div class="yui-widget-ft"&gt;&lt;/div&gt;'
     *    }
     * </pre>
     * @property TEMPLATES
     * @type Object
     * @static
     */
    StdMod.TEMPLATES = {
        header : '<div class="' + StdMod.SECTION_CLASS_NAMES[STD_HEADER] + '"></div>',
        body : '<div class="' + StdMod.SECTION_CLASS_NAMES[STD_BODY] + '"></div>',
        footer : '<div class="' + StdMod.SECTION_CLASS_NAMES[STD_FOOTER] + '"></div>'
    };

    StdMod.prototype = {

        initializer : function() {
            this._stdModNode = this.get(CONTENT_BOX);

            Y.before(this._renderUIStdMod, this, RENDERUI);
            Y.before(this._bindUIStdMod, this, BINDUI);
            Y.before(this._syncUIStdMod, this, SYNCUI);
        },

        /**
         * Synchronizes the UI to match the Widgets standard module state.
         * <p>
         * This method is invoked after syncUI is invoked for the Widget class
         * using YUI's aop infrastructure.
         * </p>
         * @method _syncUIStdMod
         * @protected
         */
        _syncUIStdMod : function() {
            var stdModParsed = this._stdModParsed;

            if (!stdModParsed || !stdModParsed[HEADER_CONTENT]) {
                this._uiSetStdMod(STD_HEADER, this.get(HEADER_CONTENT));
            }

            if (!stdModParsed || !stdModParsed[BODY_CONTENT]) {
                this._uiSetStdMod(STD_BODY, this.get(BODY_CONTENT));
            }

            if (!stdModParsed || !stdModParsed[FOOTER_CONTENT]) {
                this._uiSetStdMod(STD_FOOTER, this.get(FOOTER_CONTENT));
            }

            this._uiSetFillHeight(this.get(FILL_HEIGHT));
        },

        /**
         * Creates/Initializes the DOM for standard module support.
         * <p>
         * This method is invoked after renderUI is invoked for the Widget class
         * using YUI's aop infrastructure.
         * </p>
         * @method _renderUIStdMod
         * @protected
         */
        _renderUIStdMod : function() {
            this._stdModNode.addClass(Widget.getClassName(STDMOD));
            this._renderStdModSections();

            //This normally goes in bindUI but in order to allow setStdModContent() to work before renderUI
            //stage, these listeners should be set up at the earliest possible time.
            this.after(HeaderChange, this._afterHeaderChange);
            this.after(BodyChange, this._afterBodyChange);
            this.after(FooterChange, this._afterFooterChange);
        },

        _renderStdModSections : function() {
            if (L.isValue(this.get(HEADER_CONTENT))) { this._renderStdMod(STD_HEADER); }
            if (L.isValue(this.get(BODY_CONTENT))) { this._renderStdMod(STD_BODY); }
            if (L.isValue(this.get(FOOTER_CONTENT))) { this._renderStdMod(STD_FOOTER); }
        },

        /**
         * Binds event listeners responsible for updating the UI state in response to
         * Widget standard module related state changes.
         * <p>
         * This method is invoked after bindUI is invoked for the Widget class
         * using YUI's aop infrastructure.
         * </p>
         * @method _bindUIStdMod
         * @protected
         */
        _bindUIStdMod : function() {
            // this.after(HeaderChange, this._afterHeaderChange);
            // this.after(BodyChange, this._afterBodyChange);
            // this.after(FooterChange, this._afterFooterChange);

            this.after(FillHeightChange, this._afterFillHeightChange);
            this.after(HeightChange, this._fillHeight);
            this.after(ContentUpdate, this._fillHeight);
        },

        /**
         * Default attribute change listener for the headerContent attribute, responsible
         * for updating the UI, in response to attribute changes.
         *
         * @method _afterHeaderChange
         * @protected
         * @param {EventFacade} e The event facade for the attribute change
         */
        _afterHeaderChange : function(e) {
            if (e.src !== UI) {
                this._uiSetStdMod(STD_HEADER, e.newVal, e.stdModPosition);
            }
        },

        /**
         * Default attribute change listener for the bodyContent attribute, responsible
         * for updating the UI, in response to attribute changes.
         *
         * @method _afterBodyChange
         * @protected
         * @param {EventFacade} e The event facade for the attribute change
         */
        _afterBodyChange : function(e) {
            if (e.src !== UI) {
                this._uiSetStdMod(STD_BODY, e.newVal, e.stdModPosition);
            }
        },

        /**
         * Default attribute change listener for the footerContent attribute, responsible
         * for updating the UI, in response to attribute changes.
         *
         * @method _afterFooterChange
         * @protected
         * @param {EventFacade} e The event facade for the attribute change
         */
        _afterFooterChange : function(e) {
            if (e.src !== UI) {
                this._uiSetStdMod(STD_FOOTER, e.newVal, e.stdModPosition);
            }
        },

        /**
         * Default attribute change listener for the fillHeight attribute, responsible
         * for updating the UI, in response to attribute changes.
         *
         * @method _afterFillHeightChange
         * @protected
         * @param {EventFacade} e The event facade for the attribute change
         */
        _afterFillHeightChange: function (e) {
            this._uiSetFillHeight(e.newVal);
        },

        /**
         * Default validator for the fillHeight attribute. Verifies that the
         * value set is a valid section specifier - one of WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER,
         * or a falsey value if fillHeight is to be disabled.
         *
         * @method _validateFillHeight
         * @protected
         * @param {String} val The section which should be setup to fill height, or false/null to disable fillHeight
         * @return true if valid, false if not
         */
        _validateFillHeight : function(val) {
            return !val || val == StdMod.BODY || val == StdMod.HEADER || val == StdMod.FOOTER;
        },

        /**
         * Updates the rendered UI, to resize the provided section so that the standard module fills out
         * the specified widget height. Note: This method does not check whether or not a height is set
         * on the Widget.
         *
         * @method _uiSetFillHeight
         * @protected
         * @param {String} fillSection A valid section specifier - one of WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER
         */
        _uiSetFillHeight : function(fillSection) {
            var fillNode = this.getStdModNode(fillSection);
            var currNode = this._currFillNode;

            if (currNode && fillNode !== currNode){
                currNode.setStyle(HEIGHT, EMPTY);
            }

            if (fillNode) {
                this._currFillNode = fillNode;
            }

            this._fillHeight();
        },

        /**
         * Updates the rendered UI, to resize the current section specified by the fillHeight attribute, so
         * that the standard module fills out the Widget height. If a height has not been set on Widget,
         * the section is not resized (height is set to "auto").
         *
         * @method _fillHeight
         * @private
         */
        _fillHeight : function() {
            if (this.get(FILL_HEIGHT)) {
                var height = this.get(HEIGHT);
                if (height != EMPTY && height != AUTO) {
                    this.fillHeight(this.getStdModNode(this.get(FILL_HEIGHT)));
                }
            }
        },

        /**
         * Updates the rendered UI, adding the provided content (either an HTML string, or node reference),
         * to the specified section. The content is either added before, after or replaces existing content
         * in the section, based on the value of the <code>where</code> argument.
         *
         * @method _uiSetStdMod
         * @protected
         *
         * @param {String} section The section to be updated. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER.
         * @param {String | Node} content The new content (either as an HTML string, or Node reference) to add to the section
         * @param {String} where Optional. Either WidgetStdMod.AFTER, WidgetStdMod.BEFORE or WidgetStdMod.REPLACE.
         * If not provided, the content will replace existing content in the section.
         */
        _uiSetStdMod : function(section, content, where) {
            // Using isValue, so that "" is valid content
            if (L.isValue(content)) {
                var node = this.getStdModNode(section, true);

                this._addStdModContent(node, content, where);

                this.set(section + CONTENT_SUFFIX, this._getStdModContent(section), {src:UI});
            } else {
                this._eraseStdMod(section);
            }
            this.fire(ContentUpdate);
        },

        /**
         * Creates the DOM node for the given section, and inserts it into the correct location in the contentBox.
         *
         * @method _renderStdMod
         * @protected
         * @param {String} section The section to create/render. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER.
         * @return {Node} A reference to the added section node
         */
        _renderStdMod : function(section) {

            var contentBox = this.get(CONTENT_BOX),
                sectionNode = this._findStdModSection(section);

            if (!sectionNode) {
                sectionNode = this._getStdModTemplate(section);
            }

            this._insertStdModSection(contentBox, section, sectionNode);

            this[section + NODE_SUFFIX] = sectionNode;
            return this[section + NODE_SUFFIX];
        },

        /**
         * Removes the DOM node for the given section.
         *
         * @method _eraseStdMod
         * @protected
         * @param {String} section The section to remove. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER.
         */
        _eraseStdMod : function(section) {
            var sectionNode = this.getStdModNode(section);
            if (sectionNode) {
                sectionNode.remove(true);
                delete this[section + NODE_SUFFIX];
            }
        },

        /**
         * Helper method to insert the Node for the given section into the correct location in the contentBox.
         *
         * @method _insertStdModSection
         * @private
         * @param {Node} contentBox A reference to the Widgets content box.
         * @param {String} section The section to create/render. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER.
         * @param {Node} sectionNode The Node for the section.
         */
        _insertStdModSection : function(contentBox, section, sectionNode) {
            var fc = contentBox.get(FIRST_CHILD);

            if (section === STD_FOOTER || !fc) {
                contentBox.appendChild(sectionNode);
            } else {
                if (section === STD_HEADER) {
                    contentBox.insertBefore(sectionNode, fc);
                } else {
                    var footer = this[STD_FOOTER + NODE_SUFFIX];
                    if (footer) {
                        contentBox.insertBefore(sectionNode, footer);
                    } else {
                        contentBox.appendChild(sectionNode);
                    }
                }
            }
        },

        /**
         * Gets a new Node reference for the given standard module section, by cloning
         * the stored template node.
         *
         * @method _getStdModTemplate
         * @protected
         * @param {String} section The section to create a new node for. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER.
         * @return {Node} The new Node instance for the section
         */
        _getStdModTemplate : function(section) {
            return Node.create(StdMod.TEMPLATES[section], this._stdModNode.get(OWNER_DOCUMENT));
        },

        /**
         * Helper method to add content to a StdMod section node.
         * The content is added either before, after or replaces the existing node content
         * based on the value of the <code>where</code> argument.
         *
         * @method _addStdModContent
         * @private
         *
         * @param {Node} node The section Node to be updated.
         * @param {Node|NodeList|String} children The new content Node, NodeList or String to be added to section Node provided.
         * @param {String} where Optional. Either WidgetStdMod.AFTER, WidgetStdMod.BEFORE or WidgetStdMod.REPLACE.
         * If not provided, the content will replace existing content in the Node.
         */
        _addStdModContent : function(node, children, where) {

            // StdMod where to Node where
            switch (where) {
                case StdMod.BEFORE:  // 0 is before fistChild
                    where = 0;
                    break;
                case StdMod.AFTER:   // undefined is appendChild
                    where = undefined;
                    break;
                default:            // replace is replace, not specified is replace
                    where = StdMod.REPLACE;
            }

            node.insert(children, where);
        },

        /**
         * Helper method to obtain the precise height of the node provided, including padding and border.
         * The height could be a sub-pixel value for certain browsers, such as Firefox 3.
         *
         * @method _getPreciseHeight
         * @private
         * @param {Node} node The node for which the precise height is required.
         * @return {Number} The height of the Node including borders and padding, possibly a float.
         */
        _getPreciseHeight : function(node) {
            var height = (node) ? node.get(OFFSET_HEIGHT) : 0,
                getBCR = "getBoundingClientRect";

            if (node && node.hasMethod(getBCR)) {
                var preciseRegion = node.invoke(getBCR);
                if (preciseRegion) {
                    height = preciseRegion.bottom - preciseRegion.top;
                }
            }

            return height;
        },

        /**
         * Helper method to to find the rendered node for the given section,
         * if it exists.
         *
         * @method _findStdModSection
         * @private
         * @param {String} section The section for which the render Node is to be found. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER.
         * @return {Node} The rendered node for the given section, or null if not found.
         */
        _findStdModSection: function(section) {
            return this.get(CONTENT_BOX).one("> ." + StdMod.SECTION_CLASS_NAMES[section]);
        },

        /**
         * Utility method, used by WidgetStdMods HTML_PARSER implementation
         * to extract data for each section from markup.
         *
         * @method _parseStdModHTML
         * @private
         * @param {String} section
         * @return {String} Inner HTML string with the contents of the section
         */
        _parseStdModHTML : function(section) {

            var node = this._findStdModSection(section);

            if (node) {
                if (!this._stdModParsed) {
                    this._stdModParsed = {};
                    Y.before(this._applyStdModParsedConfig, this, APPLY_PARSED_CONFIG);
                }
                this._stdModParsed[section + CONTENT_SUFFIX] = 1;

                return node.get("innerHTML");
            }

            return null;
        },

        /**
         * This method is injected before the _applyParsedConfig step in
         * the application of HTML_PARSER, and sets up the state to
         * identify whether or not we should remove the current DOM content
         * or not, based on whether or not the current content attribute value
         * was extracted from the DOM, or provided by the user configuration
         *
         * @method _applyStdModParsedConfig
         * @private
         */
        _applyStdModParsedConfig : function(node, cfg, parsedCfg) {
            var parsed = this._stdModParsed;
            if (parsed) {
                parsed[HEADER_CONTENT] = !(HEADER_CONTENT in cfg) && (HEADER_CONTENT in parsed);
                parsed[BODY_CONTENT] = !(BODY_CONTENT in cfg) && (BODY_CONTENT in parsed);
                parsed[FOOTER_CONTENT] = !(FOOTER_CONTENT in cfg) && (FOOTER_CONTENT in parsed);
            }
        },

        /**
         * Retrieves the child nodes (content) of a standard module section
         *
         * @method _getStdModContent
         * @private
         * @param {String} section The standard module section whose child nodes are to be retrieved. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER.
         * @return {Node} The child node collection of the standard module section.
         */
        _getStdModContent : function(section) {
            return (this[section + NODE_SUFFIX]) ? this[section + NODE_SUFFIX].get(CHILD_NODES) : null;
        },

        /**
         * Updates the body section of the standard module with the content provided (either an HTML string, or node reference).
         * <p>
         * This method can be used instead of the corresponding section content attribute if you'd like to retain the current content of the section,
         * and insert content before or after it, by specifying the <code>where</code> argument.
         * </p>
         * @method setStdModContent
         * @param {String} section The standard module section whose content is to be updated. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER.
         * @param {String | Node} content The content to be added, either an HTML string or a Node reference.
         * @param {String} where Optional. Either WidgetStdMod.AFTER, WidgetStdMod.BEFORE or WidgetStdMod.REPLACE.
         * If not provided, the content will replace existing content in the section.
         */
        setStdModContent : function(section, content, where) {
            //var node = this.getStdModNode(section) || this._renderStdMod(section);
            this.set(section + CONTENT_SUFFIX, content, {stdModPosition:where});
            //this._addStdModContent(node, content, where);
        },

        /**
        Returns the node reference for the specified `section`.

        **Note:** The DOM is not queried for the node reference. The reference
        stored by the widget instance is returned if it was set. Passing a
        truthy for `forceCreate` will create the section node if it does not
        already exist.

        @method getStdModNode
        @param {String} section The section whose node reference is required.
            Either `WidgetStdMod.HEADER`, `WidgetStdMod.BODY`, or
            `WidgetStdMod.FOOTER`.
        @param {Boolean} forceCreate Whether the section node should be created
            if it does not already exist.
        @return {Node} The node reference for the `section`, or null if not set.
        **/
        getStdModNode : function(section, forceCreate) {
            var node = this[section + NODE_SUFFIX] || null;

            if (!node && forceCreate) {
                node = this._renderStdMod(section);
            }

            return node;
        },

        /**
         * Sets the height on the provided header, body or footer element to
         * fill out the height of the Widget. It determines the height of the
         * widgets bounding box, based on it's configured height value, and
         * sets the height of the provided section to fill out any
         * space remaining after the other standard module section heights
         * have been accounted for.
         *
         * <p><strong>NOTE:</strong> This method is not designed to work if an explicit
         * height has not been set on the Widget, since for an "auto" height Widget,
         * the heights of the header/body/footer will drive the height of the Widget.</p>
         *
         * @method fillHeight
         * @param {Node} node The node which should be resized to fill out the height
         * of the Widget bounding box. Should be a standard module section node which belongs
         * to the widget.
         */
        fillHeight : function(node) {
            if (node) {
                var contentBox = this.get(CONTENT_BOX),
                    stdModNodes = [this.headerNode, this.bodyNode, this.footerNode],
                    stdModNode,
                    cbContentHeight,
                    filled = 0,
                    remaining = 0,

                    validNode = false;

                for (var i = 0, l = stdModNodes.length; i < l; i++) {
                    stdModNode = stdModNodes[i];
                    if (stdModNode) {
                        if (stdModNode !== node) {
                            filled += this._getPreciseHeight(stdModNode);
                        } else {
                            validNode = true;
                        }
                    }
                }

                if (validNode) {
                    if (UA.ie || UA.opera) {
                        // Need to set height to 0, to allow height to be reduced
                        node.set(OFFSET_HEIGHT, 0);
                    }

                    cbContentHeight = contentBox.get(OFFSET_HEIGHT) -
                            parseInt(contentBox.getComputedStyle("paddingTop"), 10) -
                            parseInt(contentBox.getComputedStyle("paddingBottom"), 10) -
                            parseInt(contentBox.getComputedStyle("borderBottomWidth"), 10) -
                            parseInt(contentBox.getComputedStyle("borderTopWidth"), 10);

                    if (L.isNumber(cbContentHeight)) {
                        remaining = cbContentHeight - filled;
                        if (remaining >= 0) {
                            node.set(OFFSET_HEIGHT, remaining);
                        }
                    }
                }
            }
        }
    };

    Y.WidgetStdMod = StdMod;


}, 'patched-v3.18.1', {"requires": ["base-build", "widget"]});

YUI.add('aui-aria', function (A, NAME) {

/**
 * The Aria Component.
 *
 * @module aui-aria
 */

var Lang = A.Lang,
    isBoolean = Lang.isBoolean,
    isFunction = Lang.isFunction,
    isObject = Lang.isObject,
    isString = Lang.isString,
    STR_REGEX = /([^a-z])/ig,

    _toAriaRole = A.cached(function(str) {
        return str.replace(STR_REGEX, function() {
            return '';
        }).toLowerCase();
    });

/**
 * A base class for Aria.
 *
 * @class A.Plugin.Aria
 * @extends Plugin.Base
 * @param {Object} config Object literal specifying widget configuration
 *     properties.
 * @constructor
 */
var Aria = A.Component.create({

    /**
     * Static property provides a string to identify the class.
     *
     * @property NAME
     * @type String
     * @static
     */
    NAME: 'aria',

    /**
     * Static property provides a string to identify the namespace.
     *
     * @property NS
     * @type String
     * @static
     */
    NS: 'aria',

    /**
     * Static property used to define the default attribute configuration for
     * the `A.Aria`.
     *
     * @property ATTRS
     * @type Object
     * @static
     */
    ATTRS: {

        /**
         * The ARIA attributes collection.
         *
         * @attribute attributes
         * @default {}
         * @type Object
         */
        attributes: {
            value: {},
            validator: isObject
        },

        /**
         * The ARIA attribute value format.
         *
         * @attribute attributeValueFormat
         * @type Function
         */
        attributeValueFormat: {
            value: function(val) {
                return val;
            },
            validator: isFunction
        },

        /**
         * Node container for the ARIA attribute.
         *
         * @attribute attributeNode
         * @writeOnce
         */
        attributeNode: {
            writeOnce: true,
            setter: A.one,
            valueFn: function() {
                return this.get('host').get('boundingBox');
            }
        },

        /**
         * The ARIA role name.
         *
         * @attribute roleName
         * @type String
         */
        roleName: {
            valueFn: function() {
                var instance = this;
                var host = instance.get('host');
                var roleName = _toAriaRole(host.constructor.NAME || '');

                return (instance.isValidRole(roleName) ? roleName : '');
            },
            validator: isString
        },

        /**
         * Node container for the ARIA role.
         *
         * @attribute roleNode
         * @writeOnce
         */
        roleNode: {
            writeOnce: true,
            setter: A.one,
            valueFn: function() {
                return this.get('host').get('boundingBox');
            }
        },

        /**
         * Checks if the attribute is valid with W3C rules.
         *
         * @attribute validateW3C
         * @default true
         * @type Boolean
         */
        validateW3C: {
            value: true,
            validator: isBoolean
        }
    },

    /**
     * Static property used to define which component it extends.
     *
     * @property EXTENDS
     * @type Object
     * @static
     */
    EXTENDS: A.Plugin.Base,

    prototype: {

        /**
         * Construction logic executed during Aria instantiation. Lifecycle.
         *
         * @method initializer
         * @protected
         */
        initializer: function() {
            var instance = this;

            instance.publish('aria:processAttribute', {
                defaultFn: instance._defProcessFn,
                queuable: false,
                emitFacade: true,
                bubbles: true,
                prefix: 'aria'
            });

            instance._uiSetRoleName(
                instance.get('roleName')
            );

            instance.after('roleNameChange', instance._afterRoleNameChange);

            instance._bindHostAttributes();
        },

        /**
         * Checks if the ARIA attribute is valid.
         *
         * @method isValidAttribute
         * @param attrName
         * @return {Boolean}
         */
        isValidAttribute: function(attrName) {
            var instance = this;

            return (instance.get('validateW3C') ? A.Plugin.Aria.W3C_ATTRIBUTES[attrName] : true);
        },

        /**
         * Checks if the ARIA role is valid.
         *
         * @method isValidRole
         * @param roleName
         * @return {Boolean}
         */
        isValidRole: function(roleName) {
            var instance = this;

            return (instance.get('validateW3C') ? A.Plugin.Aria.W3C_ROLES[roleName] : true);
        },

        /**
         * Set a single ARIA attribute.
         *
         * @method setAttribute
         * @param attrName
         * @param attrValue
         * @param node
         * @return {Boolean}
         */
        setAttribute: function(attrName, attrValue, node) {
            var instance = this;

            if (instance.isValidAttribute(attrName)) {
                (node || instance.get('attributeNode')).set('aria-' + attrName, attrValue);

                return true;
            }

            return false;
        },

        /**
         * Set a list of ARIA attributes.
         *
         * @method setAttributes
         * @param attributes
         */
        setAttributes: function(attributes) {
            var instance = this;

            A.Array.each(attributes, function(attribute) {
                instance.setAttribute(attribute.name, attribute.value, attribute.node);
            });
        },

        /**
         * Set a single ARIA role.
         *
         * @method setRole
         * @param roleName
         * @param node
         * @return {Boolean}
         */
        setRole: function(roleName, node) {
            var instance = this;

            if (instance.isValidRole(roleName)) {
                (node || instance.get('roleNode')).set('role', roleName);

                return true;
            }

            return false;
        },

        /**
         * Set a list of ARIA roles.
         *
         * @method setRoles
         * @param roles
         */
        setRoles: function(roles) {
            var instance = this;

            A.Array.each(roles, function(role) {
                instance.setRole(role.name, role.node);
            });
        },

        /**
         * Fires after a host attribute change.
         *
         * @method _afterHostAttributeChange
         * @param event
         * @protected
         */
        _afterHostAttributeChange: function(event) {
            var instance = this;

            instance._handleProcessAttribute(event);
        },

        /**
         * Triggers after `roleName` attribute change.
         *
         * @method _afterRoleNameChange
         * @param event
         * @protected
         */
        _afterRoleNameChange: function(event) {
            var instance = this;

            instance._uiSetRoleName(event.newVal);
        },

        /**
         * Bind the list of host attributes.
         *
         * @method _bindHostAttributes
         * @protected
         */
        _bindHostAttributes: function() {
            var instance = this;
            var attributes = instance.get('attributes');

            A.each(attributes, function(aria, attrName) {
                var ariaAttr = instance._getAriaAttribute(aria, attrName);

                instance._handleProcessAttribute({
                    aria: ariaAttr
                });

                instance.afterHostEvent(attrName + 'Change', function(event) {
                    event.aria = ariaAttr;
                    instance._afterHostAttributeChange(event);
                });
            });
        },

        /**
         * Calls the `_setAttribute` method.
         *
         * @method _defProcessFn
         * @param event
         * @protected
         */
        _defProcessFn: function(event) {
            var instance = this;

            instance._setAttribute(event.aria);
        },

        /**
         * Get the ARIA attribute.
         *
         * @method _getAriaAttribute
         * @param aria
         * @param attrName
         * @protected
         * @return {Object}
         */
        _getAriaAttribute: function(aria, attrName) {
            var instance = this;
            var attributeValueFormat = instance.get('attributeValueFormat');
            var prepared = {};

            if (isString(aria)) {
                prepared = A.merge(prepared, {
                    ariaName: aria,
                    attrName: attrName,
                    format: attributeValueFormat,
                    node: null
                });
            }
            else if (isObject(aria)) {
                prepared = A.mix(aria, {
                    ariaName: '',
                    attrName: attrName,
                    format: attributeValueFormat,
                    node: null
                });
            }

            return prepared;
        },

        /**
         * Fires ARIA process attribute event handle.
         *
         * @method _handleProcessAttribute
         * @param event
         * @protected
         */
        _handleProcessAttribute: function(event) {
            var instance = this;

            instance.fire('aria:processAttribute', {
                aria: event.aria
            });
        },

        /**
         * Set the attribute in the DOM.
         *
         * @method _setAttribute
         * @param ariaAttr
         * @protected
         */
        _setAttribute: function(ariaAttr) {
            var instance = this;
            var host = instance.get('host');
            var attrValue = host.get(ariaAttr.attrName);
            var attrNode = ariaAttr.node;

            if (isFunction(attrNode)) {
                attrNode = attrNode.apply(instance, [ariaAttr]);
            }

            instance.setAttribute(
                ariaAttr.ariaName,
                ariaAttr.format.apply(instance, [attrValue, ariaAttr]),
                attrNode
            );
        },

        /**
         * Set the `roleName` attribute on the UI.
         *
         * @method _uiSetRoleName
         * @param val
         * @protected
         */
        _uiSetRoleName: function(val) {
            var instance = this;

            instance.setRole(val);
        }
    }
});

A.Plugin.Aria = Aria;
/**
 * Static property used to define [W3C's Roles Model](http://www.w3.org/TR/wai-
 * aria/roles).
 *
 * @property W3C_ROLES
 * @type Object
 * @static
 */
A.Plugin.Aria.W3C_ROLES = {
    'alert': 1,
    'alertdialog': 1,
    'application': 1,
    'article': 1,
    'banner': 1,
    'button': 1,
    'checkbox': 1,
    'columnheader': 1,
    'combobox': 1,
    'command': 1,
    'complementary': 1,
    'composite': 1,
    'contentinfo': 1,
    'definition': 1,
    'dialog': 1,
    'directory': 1,
    'document': 1,
    'form': 1,
    'grid': 1,
    'gridcell': 1,
    'group': 1,
    'heading': 1,
    'img': 1,
    'input': 1,
    'landmark': 1,
    'link': 1,
    'list': 1,
    'listbox': 1,
    'listitem': 1,
    'log': 1,
    'main': 1,
    'marquee': 1,
    'math': 1,
    'menu': 1,
    'menubar': 1,
    'menuitem': 1,
    'menuitemcheckbox': 1,
    'menuitemradio': 1,
    'navigation': 1,
    'note': 1,
    'option': 1,
    'presentation': 1,
    'progressbar': 1,
    'radio': 1,
    'radiogroup': 1,
    'range': 1,
    'region': 1,
    'roletype': 1,
    'row': 1,
    'rowheader': 1,
    'scrollbar': 1,
    'search': 1,
    'section': 1,
    'sectionhead': 1,
    'select': 1,
    'separator': 1,
    'slider': 1,
    'spinbutton': 1,
    'status': 1,
    'structure': 1,
    'tab': 1,
    'tablist': 1,
    'tabpanel': 1,
    'textbox': 1,
    'timer': 1,
    'toolbar': 1,
    'tooltip': 1,
    'tree': 1,
    'treegrid': 1,
    'treeitem': 1,
    'widget': 1,
    'window': 1
};
/**
 * Static property used to define [W3C's Supported States and
 * Properties](http://www.w3.org/TR/wai-aria/states_and_properties).
 *
 * @property W3C_ATTRIBUTES
 * @type Object
 * @static
 */
A.Plugin.Aria.W3C_ATTRIBUTES = {
    'activedescendant': 1,
    'atomic': 1,
    'autocomplete': 1,
    'busy': 1,
    'checked': 1,
    'controls': 1,
    'describedby': 1,
    'disabled': 1,
    'dropeffect': 1,
    'expanded': 1,
    'flowto': 1,
    'grabbed': 1,
    'haspopup': 1,
    'hidden': 1,
    'invalid': 1,
    'label': 1,
    'labelledby': 1,
    'level': 1,
    'live': 1,
    'multiline': 1,
    'multiselectable': 1,
    'orientation': 1,
    'owns': 1,
    'posinset': 1,
    'pressed': 1,
    'readonly': 1,
    'relevant': 1,
    'required': 1,
    'selected': 1,
    'setsize': 1,
    'sort': 1,
    'valuemax': 1,
    'valuemin': 1,
    'valuenow': 1,
    'valuetext': 1
};


}, '3.1.0-deprecated.52', {"requires": ["plugin", "aui-component"]});

YUI.add('aui-io-plugin-deprecated', function (A, NAME) {

/**
 * The IOPlugin Utility - When plugged to a Node or Widget loads the content
 * of a URI and set as its content, parsing the <code>script</code> tags if
 * present on the code.
 *
 * @module aui-io
 * @submodule aui-io-plugin
 */

var L = A.Lang,
    isBoolean = L.isBoolean,
    isString = L.isString,

    isNode = function(v) {
        return (v instanceof A.Node);
    },

    StdMod = A.WidgetStdMod,

    TYPE_NODE = 'Node',
    TYPE_WIDGET = 'Widget',

    EMPTY = '',
    FAILURE = 'failure',
    FAILURE_MESSAGE = 'failureMessage',
    HOST = 'host',
    ICON = 'icon',
    IO = 'io',
    IO_PLUGIN = 'IOPlugin',
    LOADING = 'loading',
    LOADING_MASK = 'loadingMask',
    NODE = 'node',
    OUTER = 'outer',
    PARSE_CONTENT = 'parseContent',
    QUEUE = 'queue',
    RENDERED = 'rendered',
    SECTION = 'section',
    SHOW_LOADING = 'showLoading',
    SUCCESS = 'success',
    TYPE = 'type',
    WHERE = 'where',

    getCN = A.getClassName,

    CSS_ICON_LOADING = getCN(ICON, LOADING);

/**
 * A base class for IOPlugin, providing:
 * <ul>
 *    <li>Loads the content of a URI as content of a Node or Widget</li>
 *    <li>Use <a href="ParseContent.html">ParseContent</a> to parse the JavaScript tags from the content and evaluate them</li>
 * </ul>
 *
 * Quick Example:<br/>
 *
 * <pre><code>A.one('#content').plug(A.Plugin.IO, { uri: 'assets/content.html', method: 'GET' });</code></pre>
 *
 * Check the list of <a href="A.Plugin.IO.html#configattributes">Configuration Attributes</a> available for
 * IOPlugin.
 *
 * @param config {Object} Object literal specifying widget configuration properties.
 *
 * @class A.Plugin.IO
 * @constructor
 * @extends IORequest
 */
var IOPlugin = A.Component.create({
    /**
     * Static property provides a string to identify the class.
     *
     * @property A.Plugin.IO.NAME
     * @type String
     * @static
     */
    NAME: IO_PLUGIN,

    /**
     * Static property provides a string to identify the namespace.
     *
     * @property A.Plugin.IO.NS
     * @type String
     * @static
     */
    NS: IO,

    /**
     * Static property used to define the default attribute
     * configuration for the A.Plugin.IO.
     *
     * @property A.Plugin.IO.ATTRS
     * @type Object
     * @static
     */
    ATTRS: {
        /**
         * Plug IO in any object we want, the setContent will use the node to
         * set the content.
         *
         * @attribute node
         * @default null
         * @type Node | String
         */
        node: {
            value: null,
            getter: function(value) {
                var instance = this;

                if (!value) {
                    var host = instance.get(HOST);
                    var type = instance.get(TYPE);

                    if (type == TYPE_NODE) {
                        value = host;
                    }
                    else if (type == TYPE_WIDGET) {
                        var section = instance.get(SECTION);

                        // if there is no node for the SECTION, forces creation
                        if (!host.getStdModNode(section)) {
                            host.setStdModContent(section, EMPTY);
                        }

                        value = host.getStdModNode(section);
                    }
                }

                return A.one(value);
            },
            validator: isNode
        },

        /**
         * Message to be set on the content when the transaction fails.
         *
         * @attribute failureMessage
         * @default 'Failed to retrieve content'
         * @type String
         */
        failureMessage: {
            value: 'Failed to retrieve content',
            validator: isString
        },

        /**
         * Options passed to the <a href="LoadingMask.html">LoadingMask</a>.
         *
         * @attribute loadingMask
         * @default {}
         * @type Object
         */
        loadingMask: {
            value: {}
        },

        /**
         * If true the <a href="ParseContent.html">ParseContent</a> plugin
         * will be plugged to the <a href="A.Plugin.IO.html#config_node">node</a>.
         *
         * @attribute parseContent
         * @default true
         * @type boolean
         */
        parseContent: {
            value: true,
            validator: isBoolean
        },

        /**
         * Show the <a href="LoadingMask.html">LoadingMask</a> covering the <a
         * href="A.Plugin.IO.html#config_node">node</a> while loading.
         *
         * @attribute showLoading
         * @default true
         * @type boolean
         */
        showLoading: {
            value: true,
            validator: isBoolean
        },

        /**
         * Section where the content will be set in case you are plugging it
         * on a instace of <a href="WidgetStdMod.html">WidgetStdMod</a>.
         *
         * @attribute section
         * @default StdMod.BODY
         * @type String
         */
        section: {
            value: StdMod.BODY,
            validator: function(val) {
                return (!val || val == StdMod.BODY || val == StdMod.HEADER || val == StdMod.FOOTER);
            }
        },

        /**
         * Type of the <code>instance</code> we are pluggin the A.Plugin.IO.
         * Could be a Node, or a Widget.
         *
         * @attribute type
         * @default 'Node'
         * @readOnly
         * @type String
         */
        type: {
            readOnly: true,
            valueFn: function() {
                var instance = this;
                // NOTE: default type
                var type = TYPE_NODE;

                if (instance.get(HOST) instanceof A.Widget) {
                    type = TYPE_WIDGET;
                }

                return type;
            },
            validator: isString
        },

        /**
         * Where to insert the content, AFTER, BEFORE or REPLACE. If you're plugging a Node, there is a fourth option called OUTER that will not only replace the entire node itself. This is different from REPLACE, in that REPLACE will replace the *contents* of the node, OUTER will replace the entire Node itself.
         *
         * @attribute where
         * @default StdMod.REPLACE
         * @type String
         */
        where: {
            value: StdMod.REPLACE,
            validator: function(val) {
                return (!val || val == StdMod.AFTER || val == StdMod.BEFORE || val == StdMod.REPLACE || val ==
                    OUTER);
            }
        }
    },

    EXTENDS: A.IORequest,

    prototype: {
        /**
         * Bind the events on the A.Plugin.IO UI. Lifecycle.
         *
         * @method bindUI
         * @protected
         */
        bindUI: function() {
            var instance = this;

            instance.on('activeChange', instance._onActiveChange);

            instance.on(SUCCESS, instance._successHandler);
            instance.on(FAILURE, instance._failureHandler);

            if ((instance.get(TYPE) == TYPE_WIDGET) && instance.get(SHOW_LOADING)) {
                var host = instance.get(HOST);

                host.after('heightChange', instance._syncLoadingMaskUI, instance);
                host.after('widthChange', instance._syncLoadingMaskUI, instance);
            }
        },

        /**
         * Invoke the <code>start</code> method (autoLoad attribute).
         *
         * @method _autoStart
         * @protected
         */
        _autoStart: function() {
            var instance = this;

            instance.bindUI();

            IOPlugin.superclass._autoStart.apply(this, arguments);
        },

        /**
         * Bind the ParseContent plugin on the <code>instance</code>.
         *
         * @method _bindParseContent
         * @protected
         */
        _bindParseContent: function() {
            var instance = this;
            var node = instance.get(NODE);

            if (node && !node.ParseContent && instance.get(PARSE_CONTENT)) {
                node.plug(A.Plugin.ParseContent);
            }
        },

        /**
         * Invoke the <a href="OverlayMask.html#method_hide">OverlayMask hide</a> method.
         *
         * @method hideLoading
         */
        hideLoading: function() {
            var instance = this;

            var node = instance.get(NODE);

            if (node.loadingmask) {
                node.loadingmask.hide();
            }
        },

        /**
         * Set the content of the <a href="A.Plugin.IO.html#config_node">node</a>.
         *
         * @method setContent
         */
        setContent: function(content) {
            var instance = this;

            instance._bindParseContent();

            instance._getContentSetterByType().apply(instance, [content]);

            if (instance.overlayMaskBoundingBox) {
                instance.overlayMaskBoundingBox.remove();
            }
        },

        /**
         * Invoke the <a href="OverlayMask.html#method_show">OverlayMask show</a> method.
         *
         * @method showLoading
         */
        showLoading: function() {
            var instance = this;
            var node = instance.get(NODE);

            if (node.loadingmask) {
                if (instance.overlayMaskBoundingBox) {
                    node.append(instance.overlayMaskBoundingBox);
                }
            }
            else {
                node.plug(
                    A.LoadingMask,
                    instance.get(LOADING_MASK)
                );

                instance.overlayMaskBoundingBox = node.loadingmask.overlayMask.get('boundingBox');
            }

            node.loadingmask.show();
        },

        /**
         * Overload to the <a href="IORequest.html#method_start">IORequest
         * start</a> method. Check if the <code>host</code> is already rendered,
         * otherwise wait to after render phase and to show the LoadingMask.
         *
         * @method start
         */
        start: function() {
            var instance = this;
            var host = instance.get(HOST);

            if (!host.get(RENDERED)) {
                host.after('render', function() {
                    instance._setLoadingUI(true);
                });
            }

            IOPlugin.superclass.start.apply(instance, arguments);
        },

        /**
         * Get the appropriated <a
         * href="A.Plugin.IO.html#method_setContent">setContent</a> function
         * implementation for each <a href="A.Plugin.IO.html#config_type">type</a>.
         *
         * @method _getContentSetterByType
         * @protected
         * @return {function}
         */
        _getContentSetterByType: function() {
            var instance = this;

            var setters = {
                // NOTE: default setter, see 'type' attribute definition
                Node: function(content) {
                    var instance = this;
                    // when this.get(HOST) is a Node instance the NODE is the host
                    var node = instance.get(NODE);

                    if (content instanceof A.NodeList) {
                        content = content.toFrag();
                    }

                    if (content instanceof A.Node) {
                        content = content._node;
                    }

                    var where = instance.get(WHERE);

                    if (where == OUTER) {
                        node.replace(content);
                    }
                    else {
                        node.insert(content, where);
                    }
                },

                // Widget forces set the content on the SECTION node using setStdModContent method
                Widget: function(content) {
                    var instance = this;
                    var host = instance.get(HOST);

                    host.setStdModContent.apply(host, [
       instance.get(SECTION),
       content,
       instance.get(WHERE)
      ]);
                }
            };

            return setters[this.get(TYPE)];
        },

        /**
         * Whether the <code>show</code> is true show the LoadingMask.
         *
         * @method _setLoadingUI
         * @param {boolean} show
         * @protected
         */
        _setLoadingUI: function(show) {
            var instance = this;

            if (instance.get(SHOW_LOADING)) {
                if (show) {
                    instance.showLoading();
                }
                else {
                    instance.hideLoading();
                }
            }
        },

        /**
         * Sync the loading mask UI.
         *
         * @method _syncLoadingMaskUI
         * @protected
         */
        _syncLoadingMaskUI: function() {
            var instance = this;

            instance.get(NODE).loadingmask.refreshMask();
        },

        /**
         * Internal success callback for the IO transaction.
         *
         * @method _successHandler
         * @param {EventFavade} event
         * @param {String} id Id of the IO transaction.
         * @param {Object} obj XHR transaction Object.
         * @protected
         */
        _successHandler: function(event, id, xhr) {
            var instance = this;

            instance.setContent(
                this.get('responseData')
            );
        },

        /**
         * Internal failure callback for the IO transaction.
         *
         * @method _failureHandler
         * @param {EventFavade} event
         * @param {String} id Id of the IO transaction.
         * @param {Object} obj XHR transaction Object.
         * @protected
         */
        _failureHandler: function(event, id, xhr) {
            var instance = this;

            instance.setContent(
                instance.get(FAILURE_MESSAGE)
            );
        },

        /**
         * Fires after the value of the
         * <a href="A.Plugin.IO.html#config_active">active</a> attribute change.
         *
         * @method _onActiveChange
         * @param {EventFacade} event
         * @protected
         */
        _onActiveChange: function(event) {
            var instance = this;
            var host = instance.get(HOST);
            var widget = instance.get(TYPE) == TYPE_WIDGET;

            if (!widget || (widget && host && host.get(RENDERED))) {
                instance._setLoadingUI(event.newVal);
            }
        }
    }
});

A.Node.prototype.load = function(uri, config, callback) {
    var instance = this;

    var index = uri.indexOf(' ');
    var selector;

    if (index > 0) {
        selector = uri.slice(index, uri.length);

        uri = uri.slice(0, index);
    }

    if (L.isFunction(config)) {
        callback = config;
        config = null;
    }

    config = config || {};

    if (callback) {
        config.after = config.after || {};

        config.after.success = callback;
    }

    var where = config.where;

    config.uri = uri;
    config.where = where;

    if (selector) {
        config.selector = selector;
        config.where = where || 'replace';
    }

    instance.plug(A.Plugin.IO, config);

    return instance;
};

A.namespace('Plugin').IO = IOPlugin;


}, '3.1.0-deprecated.52', {
    "requires": [
        "aui-overlay-base-deprecated",
        "aui-parse-content",
        "aui-io-request",
        "aui-loading-mask-deprecated"
    ]
});

YUI.add('aui-io-request', function (A, NAME) {

/**
 * The IORequest Utility - Provides response data normalization for 'xml', 'json',
 * JavaScript and cache option.
 *
 * @module aui-io
 * @submodule aui-io-request
 */

var L = A.Lang,
    isBoolean = L.isBoolean,
    isFunction = L.isFunction,
    isString = L.isString,

    defaults = A.namespace('config.io'),

    getDefault = function(attr) {
        return function() {
            return defaults[attr];
        };
    },

    ACCEPTS = {
        all: '*/*',
        html: 'text/html',
        json: 'application/json, text/javascript',
        text: 'text/plain',
        xml: 'application/xml, text/xml'
    };

/**
 * A base class for IORequest, providing:
 *
 * - Response data normalization for XML, JSON, JavaScript
 * - Cache options
 *
 * Check the [live demo](http://alloyui.com/examples/io/).
 *
 * @class A.IORequest
 * @extends Plugin.Base
 * @param {Object} config Object literal specifying widget configuration
 *     properties.
 * @uses io
 * @constructor
 * @include http://alloyui.com/examples/io/basic.js
 */
var IORequest = A.Component.create({
    /**
     * Static property provides a string to identify the class.
     *
     * @property NAME
     * @type String
     * @static
     */
    NAME: 'IORequest',

    /**
     * Static property used to define the default attribute
     * configuration for the IORequest.
     *
     * @property ATTRS
     * @type Object
     * @static
     */
    ATTRS: {

        /**
         * If `true` invoke the [start](A.IORequest.html#method_start) method
         * automatically, initializing the IO transaction.
         *
         * @attribute autoLoad
         * @default true
         * @type Boolean
         */
        autoLoad: {
            value: true,
            validator: isBoolean
        },

        /**
         * If `false` the current timestamp will be appended to the
         * url, avoiding the url to be cached.
         *
         * @attribute cache
         * @default true
         * @type Boolean
         */
        cache: {
            value: true,
            validator: isBoolean
        },

        /**
         * The type of the request (i.e., could be xml, json, javascript, text).
         *
         * @attribute dataType
         * @default null
         * @type String
         */
        dataType: {
            setter: function(v) {
                return (v || '').toLowerCase();
            },
            value: null,
            validator: isString
        },

        /**
         * This is a normalized attribute for the response data. It's useful to
         * retrieve the correct type for the
         * [dataType](A.IORequest.html#attr_dataType) (i.e., in json requests
         * the `responseData`) is a JSONObject.
         *
         * @attribute responseData
         * @default null
         * @type String | JSONObject | XMLDocument
         */
        responseData: {
            setter: function(v) {
                return this._setResponseData(v);
            },
            value: null
        },

        /**
         * URI to be requested using AJAX.
         *
         * @attribute uri
         * @default null
         * @type String
         */
        uri: {
            setter: function(v) {
                return this._parseURL(v);
            },
            value: null,
            validator: isString
        },

        // User readOnly variables

        /**
         * Whether the transaction is active or not.
         *
         * @attribute active
         * @default false
         * @type Boolean
         */
        active: {
            value: false,
            validator: isBoolean
        },

        /**
         * Object containing all the [IO Configuration Attributes](A.io.html).
         * This Object is passed to the `A.io` internally.
         *
         * @attribute cfg
         * @default Object containing all the [IO Configuration
         *     Attributes](A.io.html).
         * @readOnly
         * @type String
         */
        cfg: {
            getter: function() {
                var instance = this;

                // keep the current cfg object always synchronized with the
                // mapped public attributes when the user call .start() it
                // always retrieve the last set values for each mapped attr
                return {
                    arguments: instance.get('arguments'),
                    context: instance.get('context'),
                    data: instance.getFormattedData(),
                    form: instance.get('form'),
                    headers: instance.get('headers'),
                    method: instance.get('method'),
                    on: {
                        complete: A.bind(instance.fire, instance, 'complete'),
                        end: A.bind(instance._end, instance),
                        failure: A.bind(instance.fire, instance, 'failure'),
                        start: A.bind(instance.fire, instance, 'start'),
                        success: A.bind(instance._success, instance)
                    },
                    sync: instance.get('sync'),
                    timeout: instance.get('timeout'),
                    xdr: instance.get('xdr')
                };
            },
            readOnly: true
        },

        /**
         * Stores the IO Object of the current transaction.
         *
         * @attribute transaction
         * @default null
         * @type Object
         */
        transaction: {
            value: null
        },

        // Configuration Object mapping
        // To take advantages of the Attribute listeners of A.Base
        // See: http://yuilibrary.com/yui/docs/io/

        /**
         * See [IO
         * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
         *
         * @attribute arguments
         * @default Value mapped on YUI.AUI.defaults.io.
         * @type Object
         */
        arguments: {
            valueFn: getDefault('arguments')
        },

        /**
         * See [IO
         * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
         *
         * @attribute context
         * @default Value mapped on YUI.AUI.defaults.io.
         * @type Object
         */
        context: {
            valueFn: getDefault('context')
        },

        /**
         * See [IO
         * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
         *
         * @attribute data
         * @default Value mapped on YUI.AUI.defaults.io.
         * @type Object
         */
        data: {
            valueFn: getDefault('data')
        },

        /**
         * See [IO
         * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
         *
         * @attribute form
         * @default Value mapped on YUI.AUI.defaults.io.
         * @type Object
         */
        form: {
            valueFn: getDefault('form')
        },

        /**
         * Set the correct ACCEPT header based on the dataType.
         *
         * @attribute headers
         * @default Object
         * @type Object
         */
        headers: {
            getter: function(value) {
                var header = [];
                var instance = this;
                var dataType = instance.get('dataType');

                if (dataType) {
                    header.push(
                        ACCEPTS[dataType]
                    );
                }

                // always add *.* to the accept header
                header.push(
                    ACCEPTS.all
                );

                return A.merge(
                    value, {
                        Accept: header.join(', ')
                    }
                );
            },
            valueFn: getDefault('headers')
        },

        /**
         * See [IO
         * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
         *
         * @attribute method
         * @default Value mapped on YUI.AUI.defaults.io.
         * @type String
         */
        method: {
            setter: function(val) {
                return val.toLowerCase();
            },
            valueFn: getDefault('method')
        },

        /**
         * A selector to be used to query against the response of the
         * request. Only works if the response is XML or HTML.
         *
         * @attribute selector
         * @default null
         * @type String
         */
        selector: {
            value: null
        },

        /**
         * See [IO
         * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
         *
         * @attribute sync
         * @default Value mapped on YUI.AUI.defaults.io.
         * @type Boolean
         */
        sync: {
            valueFn: getDefault('sync')
        },

        /**
         * See [IO
         * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
         *
         * @attribute timeout
         * @default Value mapped on YUI.AUI.defaults.io.
         * @type Number
         */
        timeout: {
            valueFn: getDefault('timeout')
        },

        /**
         * See [IO
         * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
         *
         * @attribute xdr
         * @default Value mapped on YUI.AUI.defaults.io.
         * @type Object
         */
        xdr: {
            valueFn: getDefault('xdr')
        }
    },

    /**
     * Static property used to define which component it extends.
     *
     * @property EXTENDS
     * @type Object
     * @static
     */
    EXTENDS: A.Plugin.Base,

    prototype: {

        /**
         * Construction logic executed during IORequest instantiation.
         * Lifecycle.
         *
         * @method initializer
         * @param config
         * @protected
         */
        init: function() {
            var instance = this;

            IORequest.superclass.init.apply(this, arguments);

            instance._autoStart();
        },

        /**
         * Destructor lifecycle implementation for the `IORequest` class.
         * Purges events attached to the node (and all child nodes).
         *
         * @method destructor
         * @protected
         */
        destructor: function() {
            var instance = this;

            instance.stop();

            instance.set('transaction', null);
        },

        /**
         * Applies the `YUI.AUI.defaults.io.dataFormatter` if
         * defined and return the formatted data.
         *
         * @method getFormattedData
         * @return {String}
         */
        getFormattedData: function() {
            var instance = this;
            var value = instance.get('data');
            var dataFormatter = defaults.dataFormatter;

            if (isFunction(dataFormatter)) {
                value = dataFormatter.call(instance, value);
            }

            return value;
        },

        /**
         * Starts the IO transaction. Used to refresh the content also.
         *
         * @method start
         */
        start: function() {
            var instance = this;

            instance.destructor();

            instance.set('active', true);

            var ioObj = instance._yuiIOObj;

            if (!ioObj) {
                ioObj = new A.IO();

                instance._yuiIOObj = ioObj;
            }

            var transaction = ioObj.send(
                instance.get('uri'),
                instance.get('cfg')
            );

            instance.set('transaction', transaction);
        },

        /**
         * Stops the IO transaction.
         *
         * @method stop
         */
        stop: function() {
            var instance = this;
            var transaction = instance.get('transaction');

            if (transaction) {
                transaction.abort();
            }
        },

        /**
         * Invoke the `start` method (autoLoad attribute).
         *
         * @method _autoStart
         * @protected
         */
        _autoStart: function() {
            var instance = this;

            if (instance.get('autoLoad')) {
                instance.start();
            }
        },

        /**
         * Parse the [uri](A.IORequest.html#attr_uri) to add a
         * timestamp if [cache](A.IORequest.html#attr_cache) is
         * `true`. Also applies the `YUI.AUI.defaults.io.uriFormatter`.
         *
         * @method _parseURL
         * @param {String} url
         * @protected
         * @return {String}
         */
        _parseURL: function(url) {
            var instance = this;
            var cache = instance.get('cache');
            var method = instance.get('method');

            // reusing logic to add a timestamp on the url from jQuery 1.3.2
            if ((cache === false) && (method === 'get')) {
                var ts = +new Date();
                // try replacing _= if it is there
                var ret = url.replace(/(\?|&)_=.*?(&|$)/, '$1_=' + ts + '$2');
                // if nothing was replaced, add timestamp to the end
                url = ret + ((ret === url) ? (url.match(/\?/) ? '&' : '?') + '_=' + ts : '');
            }

            // formatting the URL with the default uriFormatter after the cache
            // timestamp was added
            var uriFormatter = defaults.uriFormatter;

            if (isFunction(uriFormatter)) {
                url = uriFormatter.apply(instance, [url]);
            }

            return url;
        },

        /**
         * Internal end callback for the IO transaction.
         *
         * @method _end
         * @param {Number} id ID of the IO transaction.
         * @param {Object} args Custom arguments, passed to the event handler.
         *     See [IO](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
         * @protected
         */
        _end: function(id, args) {
            var instance = this;

            instance.set('active', false);
            instance.set('transaction', null);

            instance.fire('end', id, args);
        },

        /**
         * Internal success callback for the IO transaction.
         *
         * @method _success
         * @param {Number} id ID of the IO transaction.
         * @param {Object} obj IO transaction Object.
         * @param {Object} args Custom arguments, passed to the event handler.
         *     See [IO](http://yuilibrary.com/yui/docs/io/#the-configuration-object).
         * @protected
         */
        _success: function(id, obj, args) {
            var instance = this;

            // update the responseData attribute with the new data from xhr
            instance.set('responseData', obj);

            instance.fire('success', id, obj, args);
        },

        /**
         * Setter for [responseData](A.IORequest.html#attr_responseData).
         *
         * @method _setResponseData
         * @protected
         * @param {Object} xhr XHR Object.
         * @return {Object}
         */
        _setResponseData: function(xhr) {
            var data = null;
            var instance = this;

            if (xhr) {
                var dataType = instance.get('dataType');
                var contentType = xhr.getResponseHeader('content-type') || '';

                // if the dataType or the content-type is XML...
                if ((dataType === 'xml') ||
                    (!dataType && contentType.indexOf('xml') >= 0)) {

                    // use responseXML
                    data = xhr.responseXML;

                    // check if the XML was parsed correctly
                    if (data.documentElement.tagName === 'parsererror') {
                        throw 'Parser error: IO dataType is not correctly parsing';
                    }
                }
                else {
                    // otherwise use the responseText
                    data = xhr.responseText;
                }

                // empty string is not a valid 'json', convert it to null
                if (data === '') {
                    data = null;
                }

                // trying to parse to JSON if dataType is a valid json
                if (dataType === 'json') {
                    try {
                        data = A.JSON.parse(data);
                    }
                    catch (e) {
                        // throw 'Parser error: IO dataType is not correctly parsing';
                    }
                }
                else {
                    var selector = instance.get('selector');

                    if (data && selector) {
                        var tempRoot;

                        if (data.documentElement) {
                            tempRoot = A.one(data);
                        }
                        else {
                            tempRoot = A.Node.create(data);
                        }

                        data = tempRoot.all(selector);
                    }
                }
            }

            return data;
        }
    }
});

A.IORequest = IORequest;

/**
 * Alloy IO extension
 *
 * @class A.io
 * @static
 */

/**
 * Static method to invoke the [IORequest](A.IORequest.html).
 * Likewise [IO](A.io.html).
 *
 * @method A.io.request
 * @for A.io
 * @param {String} uri URI to be requested.
 * @param {Object} config Configuration Object for the [IO](A.io.html).
 * @return {IORequest}
 */
A.io.request = function(uri, config) {
    return new A.IORequest(
        A.merge(config, {
            uri: uri
        })
    );
};


}, '3.1.0-deprecated.52', {"requires": ["io-base", "json", "plugin", "querystring-stringify", "aui-component"]});

YUI.add('aui-loading-mask-deprecated', function (A, NAME) {

/**
 * The LoadingMask Utility
 *
 * @module aui-loading-mask
 */

var Lang = A.Lang,

    BOUNDING_BOX = 'boundingBox',
    CONTENT_BOX = 'contentBox',
    HIDE = 'hide',
    HOST = 'host',
    MESSAGE_EL = 'messageEl',
    NAME = 'loadingmask',
    POSITION = 'position',
    SHOW = 'show',
    STATIC = 'static',
    STRINGS = 'strings',
    TARGET = 'target',
    TOGGLE = 'toggle',

    getClassName = A.getClassName,

    CSS_LOADINGMASK = getClassName(NAME),
    CSS_MASKED = getClassName(NAME, 'masked'),
    CSS_MASKED_RELATIVE = getClassName(NAME, 'masked', 'relative'),
    CSS_MESSAGE_LOADING = getClassName(NAME, 'message'),
    CSS_MESSAGE_LOADING_CONTENT = getClassName(NAME, 'message', 'content'),

    TPL_MESSAGE_LOADING = '<div class="' + CSS_MESSAGE_LOADING + '"><div class="' + CSS_MESSAGE_LOADING_CONTENT +
        '">{0}</div></div>';

/**
 * <p><img src="assets/images/aui-loading-mask/main.png"/></p>
 *
 * A base class for LoadingMask, providing:
 * <ul>
 *    <li>Cross browser mask functionality to cover an element or the entire page</li>
 *    <li>Customizable mask (i.e., background, opacity)</li>
 *    <li>Display a centered "loading" message on the masked node</li>
 * </ul>
 *
 * Quick Example:<br/>
 *
 * <pre><code>node.plug(A.LoadingMask, { background: '#000' });</code></pre>
 *
 * Check the list of <a href="LoadingMask.html#configattributes">Configuration Attributes</a> available for
 * LoadingMask.
 *
 * @param config {Object} Object literal specifying widget configuration properties.
 *
 * @class LoadingMask
 * @constructor
 * @extends Plugin.Base
 */
var LoadingMask = A.Component.create({

    /**
     * Static property provides a string to identify the class.
     *
     * @property LoadingMask.NAME
     * @type String
     * @static
     */
    NAME: NAME,

    /**
     * Static property provides a string to identify the namespace.
     *
     * @property LoadingMask.NS
     * @type String
     * @static
     */
    NS: NAME,

    /**
     * Static property used to define the default attribute
     * configuration for the LoadingMask.
     *
     * @property LoadingMask.ATTRS
     * @type Object
     * @static
     */
    ATTRS: {
        /**
         * Node element to display the message.
         *
         * @attribute messageEl
         * @default Generated HTML div element.
         * @type String
         */
        messageEl: {
            valueFn: function(val) {
                var instance = this;
                var strings = instance.get(STRINGS);

                return A.Node.create(
                    Lang.sub(TPL_MESSAGE_LOADING, [strings.loading])
                );
            }
        },

        /**
         * Strings used on the LoadingMask. See
         * <a href="Widget.html#method_strings">strings</a>.
         *
         * @attribute strings
         * @default { loading: 'Loading&hellip;' }
         * @type Object
         */
        strings: {
            value: {
                loading: 'Loading&hellip;'
            }
        },

        /**
         * Node where the mask will be positioned and re-dimensioned.
         *
         * @attribute target
         * @default null
         * @type Node | Widget
         */
        target: {
            setter: function() {
                var instance = this;
                var target = instance.get(HOST);

                if (target instanceof A.Widget) {
                    target = target.get(CONTENT_BOX);
                }

                return target;
            },
            value: null
        }
    },

    EXTENDS: A.Plugin.Base,

    prototype: {
        /**
         * Construction logic executed during LoadingMask instantiation. Lifecycle.
         *
         * @method initializer
         * @protected
         */
        initializer: function(config) {
            var instance = this;

            instance.IGNORED_ATTRS = A.merge({
                    host: true
                },
                LoadingMask.ATTRS
            );

            instance.renderUI();
            instance.bindUI();

            instance._createDynamicAttrs(config);
        },

        /**
         * Create the DOM structure for the LoadingMask. Lifecycle.
         *
         * @method renderUI
         * @protected
         */
        renderUI: function() {
            var instance = this;
            var strings = instance.get(STRINGS);

            instance._renderOverlayMask();

            instance.overlayMask.get(BOUNDING_BOX).append(
                instance.get(MESSAGE_EL)
            );
        },

        /**
         * Bind the events on the LoadingMask UI. Lifecycle.
         *
         * @method bindUI
         * @protected
         */
        bindUI: function() {
            var instance = this;

            instance._bindOverlayMaskUI();
        },

        destructor: function() {
            var instance = this;

            instance.overlayMask.destroy();

            instance._visibleChangeHandle.detach();
        },

        /**
         * Bind events to the
         * <a href="LoadingMask.html#property_overlayMask">overlayMask</a>.
         *
         * @method _bindOverlayMaskUI
         * @protected
         */
        _bindOverlayMaskUI: function() {
            var instance = this;

            instance._visibleChangeHandle = instance.overlayMask.after('visibleChange', instance._afterVisibleChange, instance);
        },

        /**
         * Center the
         * <a href="LoadingMask.html#config_messageEl">messageEl</a> with the
         * <a href="LoadingMask.html#config_target">target</a> node.
         *
         * @method centerMessage
         */
        centerMessage: function() {
            var instance = this;

            instance.get(MESSAGE_EL).center(
                instance.overlayMask.get(BOUNDING_BOX)
            );
        },

        /**
         * Invoke the
         * <a href="LoadingMask.html#property_overlayMask">overlayMask</a>
         * <code>refreshMask</code> method.
         *
         * @method refreshMask
         */
        refreshMask: function() {
            var instance = this;

            instance.overlayMask.refreshMask();

            instance.centerMessage();
        },

        /**
         * Fires after the value of the
         * <a href="LoadingMask.html#config_visible">visible</a> attribute change.
         *
         * @method _afterVisibleChange
         * @param {EventFacade} event
         * @protected
         */
        _afterVisibleChange: function(event) {
            var instance = this;
            var target = instance.get(TARGET);
            var isStaticPositioned = (target.getStyle(POSITION) == STATIC);

            target.toggleClass(CSS_MASKED, (event.newVal));
            target.toggleClass(CSS_MASKED_RELATIVE, (event.newVal && isStaticPositioned));

            if (event.newVal) {
                instance.refreshMask();
            }
        },

        /**
         * Render
         * <a href="LoadingMask.html#property_overlayMask">overlayMask</a>
         * instance.
         *
         * @method _renderOverlayMask
         * @protected
         */
        _renderOverlayMask: function() {
            var instance = this;
            var target = instance.get(TARGET);

            /**
             * Stores the <a href="OverlayMask.html">OverlayMask</a> used
             * internally.
             *
             * @property overlayMask
             * @type OverlayMask
             * @protected
             */
            instance.overlayMask = new A.OverlayMask({
                target: target,
                cssClass: CSS_LOADINGMASK
            }).render(target);
        },

        /**
         * Create dynamic attributes listeners to invoke the setter on
         * <a href="LoadingMask.html#property_overlayMask">overlayMask</a> after
         * the attribute is set on the LoadingMask instance.
         *
         * @method _createDynamicAttrs
         * @param {Object} config Object literal specifying widget configuration properties.
         * @protected
         */
        _createDynamicAttrs: function(config) {
            var instance = this;

            A.each(config, function(value, key) {
                var ignoredAttr = instance.IGNORED_ATTRS[key];

                if (!ignoredAttr) {
                    instance.addAttr(key, {
                        setter: function(val) {
                            this.overlayMask.set(key, val);

                            return val;
                        },
                        value: value
                    });
                }
            });
        }
    }
});

A.each([HIDE, SHOW, TOGGLE], function(method) {
    /**
     * Invoke the
     * <a href="LoadingMask.html#property_overlayMask">overlayMask</a>
     * <code>hide</code> method.
     *
     * @method hide
     */

    /**
     * Invoke the
     * <a href="LoadingMask.html#property_overlayMask">overlayMask</a>
     * <code>show</code> method.
     *
     * @method show
     */

    /**
     * Invoke the
     * <a href="LoadingMask.html#property_overlayMask">overlayMask</a>
     * <code>toggle</code> method.
     *
     * @method toggle
     */
    LoadingMask.prototype[method] = function() {
        this.overlayMask[method]();
    };
});

A.LoadingMask = LoadingMask;


}, '3.1.0-deprecated.52', {"requires": ["plugin", "aui-overlay-mask-deprecated"], "skinnable": true});

YUI.add('aui-overlay-base-deprecated', function (A, NAME) {

/**
 * Provides a basic Overlay widget, with Standard Module content support. The Overlay widget
 * provides Page XY positioning support, alignment and centering support along with basic
 * stackable support (z-index and shimming).
 *
 * @module aui-overlay
 * @submodule aui-overlay-base
 */

/**
 * A basic Overlay Widget, which can be positioned based on Page XY co-ordinates and is stackable (z-index support).
 * It also provides alignment and centering support and uses a standard module format for it's content, with header,
 * body and footer section support.
 *
 * @class OverlayBase
 * @constructor
 * @extends Component
 * @uses WidgetStdMod
 * @uses WidgetPosition
 * @uses WidgetStack
 * @uses WidgetPositionAlign
 * @uses WidgetPositionConstrain
 * @param {Object} object The user configuration for the instance.
 */
A.OverlayBase = A.Component.create({
    NAME: 'overlay',
    ATTRS: {
        hideClass: {
            value: false
        }
    },
    AUGMENTS: [A.WidgetPosition, A.WidgetStack, A.WidgetPositionAlign, A.WidgetPositionConstrain, A.WidgetStdMod]
});


}, '3.1.0-deprecated.52', {
    "requires": [
        "widget-position",
        "widget-stack",
        "widget-position-align",
        "widget-position-constrain",
        "widget-stdmod",
        "aui-component"
    ]
});

YUI.add('aui-overlay-context-deprecated', function (A, NAME) {

/**
 * The OverlayContext Utility
 *
 * @module aui-overlay
 * @submodule aui-overlay-context
 */

var L = A.Lang,
    isString = L.isString,
    isNumber = L.isNumber,
    isObject = L.isObject,
    isBoolean = L.isBoolean,

    isNodeList = function(v) {
        return (v instanceof A.NodeList);
    },

    ALIGN = 'align',
    BL = 'bl',
    BOUNDING_BOX = 'boundingBox',
    CANCELLABLE_HIDE = 'cancellableHide',
    OVERLAY_CONTEXT = 'overlaycontext',
    CURRENT_NODE = 'currentNode',
    FOCUSED = 'focused',
    HIDE = 'hide',
    HIDE_DELAY = 'hideDelay',
    HIDE_ON = 'hideOn',
    HIDE_ON_DOCUMENT_CLICK = 'hideOnDocumentClick',
    MOUSEDOWN = 'mousedown',
    SHOW = 'show',
    SHOW_DELAY = 'showDelay',
    SHOW_ON = 'showOn',
    TL = 'tl',
    TRIGGER = 'trigger',
    USE_ARIA = 'useARIA',
    VISIBLE = 'visible';

/**
 * <p><img src="assets/images/aui-overlay-context/main.png"/></p>
 *
 * A base class for OverlayContext, providing:
 * <ul>
 *    <li>Widget Lifecycle (initializer, renderUI, bindUI, syncUI, destructor)</li>
 *    <li>Able to display an <a href="Overlay.html">Overlay</a> at a specified corner of an element <a href="OverlayContext.html#config_trigger">trigger</a></li>
 * </ul>
 *
 * Quick Example:<br/>
 *
 * <pre><code>var instance = new A.OverlayContext({
 *  boundingBox: '#OverlayBoundingBox',
 *  hideOn: 'mouseleave',
 *  showOn: 'mouseenter',
 *	trigger: '.menu-trigger'
 * }).render();
 * </code></pre>
 *
 * Check the list of <a href="OverlayContext.html#configattributes">Configuration Attributes</a> available for
 * OverlayContext.
 *
 * @class OverlayContext
 * @constructor
 * @extends OverlayBase
 * @param config {Object} Object literal specifying widget configuration properties.
 */
var OverlayContext = A.Component.create({
    /**
     * Static property provides a string to identify the class.
     *
     * @property OverlayContext.NAME
     * @type String
     * @static
     */
    NAME: OVERLAY_CONTEXT,

    /**
     * Static property used to define the default attribute
     * configuration for the OverlayContext.
     *
     * @property OverlayContext.ATTRS
     * @type Object
     * @static
     */
    ATTRS: {
        /**
         * Inherited from <a href="Overlay.html#config_align">Overlay</a>.
         *
         * @attribute align
         * @default { node: null, points: [ TL, BL ] }
         * @type Object
         */
        align: {
            value: {
                node: null,
                points: [TL, BL]
            }
        },

        /**
         * Cancel auto hide delay if the user interact with the Overlay
         * (focus, click, mouseover)
         *
         * @attribute cancellableHide
         * @default true
         * @type boolean
         */
        cancellableHide: {
            value: true,
            validator: isBoolean
        },

        /**
         * OverlayContext allow multiple elements to be the
         * <a href="OverlayContext.html#config_trigger">trigger</a>, the
         * currentNode stores the current active one.
         *
         * @attribute currentNode
         * @default First item of the
         * <a href="OverlayContext.html#config_trigger">trigger</a> NodeList.
         * @type Node
         */
        currentNode: {
            valueFn: function() {
                // define default currentNode as the first item from trigger
                return this.get(TRIGGER).item(0);
            }
        },

        delay: {
            value: null,
            validator: isObject
        },

        /**
         * The event which is responsible to hide the OverlayContext.
         *
         * @attribute hideOn
         * @default mouseout
         * @type String
         */
        hideOn: {
            lazyAdd: false,
            value: 'mouseout',
            setter: function(v) {
                return this._setHideOn(v);
            }
        },

        /**
         * If true the instance is registered on the
         * <a href="OverlayContextManager.html">OverlayContextManager</a> static
         * class and will be hide when the user click on document.
         *
         * @attribute hideOnDocumentClick
         * @default true
         * @type boolean
         */
        hideOnDocumentClick: {
            lazyAdd: false,
            setter: function(v) {
                return this._setHideOnDocumentClick(v);
            },
            value: true,
            validator: isBoolean
        },

        /**
         * Number of milliseconds after the hide method is invoked to hide the
         * OverlayContext.
         *
         * @attribute hideDelay
         * @default 0
         * @type Number
         */
        hideDelay: {
            lazyAdd: false,
            setter: '_setHideDelay',
            value: 0,
            validator: isNumber
        },

        /**
         * The event which is responsible to show the OverlayContext.
         *
         * @attribute showOn
         * @default mouseover
         * @type String
         */
        showOn: {
            lazyAdd: false,
            value: 'mouseover',
            setter: function(v) {
                return this._setShowOn(v);
            }
        },

        /**
         * Number of milliseconds after the show method is invoked to show the
         * OverlayContext.
         *
         * @attribute showDelay
         * @default 0
         * @type Number
         */
        showDelay: {
            lazyAdd: false,
            setter: '_setShowDelay',
            value: 0,
            validator: isNumber
        },

        /**
         * Node, NodeList or Selector which will be used as trigger elements
         * to show or hide the OverlayContext.
         *
         * @attribute trigger
         * @default null
         * @type {Node | NodeList | String}
         */
        trigger: {
            lazyAdd: false,
            setter: function(v) {
                if (isNodeList(v)) {
                    return v;
                }
                else if (isString(v)) {
                    return A.all(v);
                }

                return new A.NodeList([v]);
            }
        },

        /**
         * True if Overlay should use ARIA plugin
         *
         * @attribute useARIA
         * @default true
         * @type Boolean
         */
        useARIA: {
            value: true
        },

        /**
         * If true the OverlayContext is visible by default after the render phase.
         * Inherited from <a href="Overlay.html">Overlay</a>.
         *
         * @attribute visible
         * @default false
         * @type boolean
         */
        visible: {
            value: false
        }
    },

    EXTENDS: A.OverlayBase,

    constructor: function(config) {
        var instance = this;

        instance._showCallback = null;
        instance._hideCallback = null;

        OverlayContext.superclass.constructor.apply(this, arguments);
    },

    prototype: {
        /**
         * Construction logic executed during OverlayContext instantiation. Lifecycle.
         *
         * @method initializer
         * @protected
         */
        initializer: function() {
            var instance = this;

            var trigger = instance.get(TRIGGER);

            if (trigger && trigger.size()) {
                instance.set('align.node', trigger.item(0));
            }
        },

        /**
         * Bind the events on the OverlayContext UI. Lifecycle.
         *
         * @method bindUI
         * @protected
         */
        bindUI: function() {
            var instance = this;
            var boundingBox = instance.get(BOUNDING_BOX);

            boundingBox.on(MOUSEDOWN, instance._stopTriggerEventPropagation);

            instance.before('triggerChange', instance._beforeTriggerChange);
            instance.before('showOnChange', instance._beforeShowOnChange);
            instance.before('hideOnChange', instance._beforeHideOnChange);

            instance.after('triggerChange', instance._afterTriggerChange);
            instance.after('showOnChange', instance._afterShowOnChange);
            instance.after('hideOnChange', instance._afterHideOnChange);

            boundingBox.on('click', A.bind(instance._cancelAutoHide, instance));
            boundingBox.on('mouseenter', A.bind(instance._cancelAutoHide, instance));
            boundingBox.on('mouseleave', A.bind(instance._invokeHideTaskOnInteraction, instance));
            instance.after('focusedChange', A.bind(instance._invokeHideTaskOnInteraction, instance));

            instance.on('visibleChange', instance._onVisibleChangeOverlayContext);
        },

        /**
         * Hides the OverlayContext.
         *
         * @method hide
         */
        hide: function() {
            var instance = this;

            instance.clearIntervals();

            instance.fire('hide');

            OverlayContext.superclass.hide.apply(instance, arguments);
        },

        /**
         * Shows the OverlayContext.
         *
         * @method hide
         */
        show: function(event) {
            var instance = this;

            instance.clearIntervals();

            instance.updateCurrentNode(event);

            instance.fire('show');

            OverlayContext.superclass.show.apply(instance, arguments);

            instance.refreshAlign();
        },

        /**
         * Refreshes the rendered UI, based on Widget State
         *
         * @method syncUI
         * @protected
         *
         */
        syncUI: function() {
            var instance = this;

            if (instance.get(USE_ARIA)) {
                instance.plug(A.Plugin.Aria, {
                    attributes: {
                        trigger: {
                            ariaName: 'controls',
                            format: function(value) {
                                var id = instance.get(BOUNDING_BOX).generateID();

                                return id;
                            },
                            node: function() {
                                return instance.get(TRIGGER);
                            }
                        },
                        visible: {
                            ariaName: 'hidden',
                            format: function(value) {
                                return !value;
                            }
                        }
                    },
                    roleName: 'dialog'
                });
            }
        },

        /**
         * Toggles visibility of the OverlayContext.
         *
         * @method toggle
         * @param {EventFacade} event
         */
        toggle: function(event) {
            var instance = this;

            if (instance.get(VISIBLE)) {
                instance._hideTask(event);
            }
            else {
                instance._showTask(event);
            }
        },

        /**
         * Clear the intervals to show or hide the OverlayContext. See
         * <a href="OverlayContext.html#config_hideDelay">hideDelay</a> and
         * <a href="OverlayContext.html#config_showDelay">showDelay</a>.
         *
         * @method clearIntervals
         */
        clearIntervals: function() {
            this._hideTask.cancel();
            this._showTask.cancel();
        },

        /**
         * Refreshes the alignment of the OverlayContext with the
         * <a href="OverlayContext.html#config_currentNode">currentNode</a>. See
         * also <a href="OverlayContext.html#config_align">align</a>.
         *
         * @method refreshAlign
         */
        refreshAlign: function() {
            var instance = this;
            var align = instance.get(ALIGN);
            var currentNode = instance.get(CURRENT_NODE);

            if (currentNode) {
                instance._uiSetAlign(currentNode, align.points);
            }
        },

        /**
         * Update the
         * <a href="OverlayContext.html#config_currentNode">currentNode</a> with the
         * <a href="OverlayContext.html#config_align">align</a> node or the
         * event.currentTarget and in last case with the first item of the
         * <a href="OverlayContext.html#config_trigger">trigger</a>.
         *
         * @method updateCurrentNode
         * @param {EventFacade} event
         */
        updateCurrentNode: function(event) {
            var instance = this;
            var align = instance.get(ALIGN);
            var trigger = instance.get(TRIGGER);
            var currentTarget = null;

            if (event) {
                currentTarget = event.currentTarget;
            }

            var node = currentTarget || trigger.item(0) || align.node;

            if (node) {
                instance.set(CURRENT_NODE, node);
            }
        },

        /**
         * Handles the logic for the
         * <a href="OverlayContext.html#method_toggle">toggle</a>.
         *
         * @method _toggle
         * @param {EventFacade} event
         * @protected
         */
        _toggle: function(event) {
            var instance = this;

            if (instance.get('disabled')) {
                return;
            }

            var currentTarget = event.currentTarget;

            // check if the target is different and simulate a .hide() before toggle
            if (instance._lastTarget != currentTarget) {
                instance.hide();
            }

            instance.toggle(event);

            event.stopPropagation();

            instance._lastTarget = currentTarget;
        },

        /**
         * Fires after the <a href="OverlayContext.html#config_showOn">showOn</a>
         * attribute change.
         *
         * @method _afterShowOnChange
         * @param {EventFacade} event
         * @protected
         */
        _afterShowOnChange: function(event) {
            var instance = this;
            var wasToggle = event.prevVal == instance.get(HIDE_ON);

            if (wasToggle) {
                var trigger = instance.get(TRIGGER);

                // if wasToggle remove the toggle callback
                trigger.detach(event.prevVal, instance._hideCallback);
                // and re attach the hide event
                instance._setHideOn(instance.get(HIDE_ON));
            }
        },

        /**
         * Fires after the <a href="OverlayContext.html#config_hideOn">hideOn</a>
         * attribute change.
         *
         * @method _afterHideOnChange
         * @param {EventFacade} event
         * @protected
         */
        _afterHideOnChange: function(event) {
            var instance = this;
            var wasToggle = event.prevVal == instance.get(SHOW_ON);

            if (wasToggle) {
                var trigger = instance.get(TRIGGER);

                // if wasToggle remove the toggle callback
                trigger.detach(event.prevVal, instance._showCallback);
                // and re attach the show event
                instance._setShowOn(instance.get(SHOW_ON));
            }
        },

        /**
         * Fires after the <a href="OverlayContext.html#config_trigger">trigger</a>
         * attribute change.
         *
         * @method _afterTriggerChange
         * @param {EventFacade} event
         * @protected
         */
        _afterTriggerChange: function(event) {
            var instance = this;

            instance._setShowOn(instance.get(SHOW_ON));
            instance._setHideOn(instance.get(HIDE_ON));
        },

        /**
         * Fires before the <a href="OverlayContext.html#config_showOn">showOn</a>
         * attribute change.
         *
         * @method _beforeShowOnChange
         * @param {EventFacade} event
         * @protected
         */
        _beforeShowOnChange: function(event) {
            var instance = this;
            var trigger = instance.get(TRIGGER);

            // detach the old callback
            trigger.detach(event.prevVal, instance._showCallback);
        },

        /**
         * Fires before the <a href="OverlayContext.html#config_hideOn">hideOn</a>
         * attribute change.
         *
         * @method _beforeHideOnChange
         * @param {EventFacade} event
         * @protected
         */
        _beforeHideOnChange: function(event) {
            var instance = this;
            var trigger = instance.get(TRIGGER);

            // detach the old callback
            trigger.detach(event.prevVal, instance._hideCallback);
        },

        /**
         * Fires before the <a href="OverlayContext.html#config_trigger">trigger</a>
         * attribute change.
         *
         * @method _beforeTriggerChange
         * @param {EventFacade} event
         * @protected
         */
        _beforeTriggerChange: function(event) {
            var instance = this;
            var trigger = instance.get(TRIGGER);
            var showOn = instance.get(SHOW_ON);
            var hideOn = instance.get(HIDE_ON);

            trigger.detach(showOn, instance._showCallback);
            trigger.detach(hideOn, instance._hideCallback);
            trigger.detach(MOUSEDOWN, instance._stopTriggerEventPropagation);
        },

        /**
         * Cancel hide event if the user does some interaction with the
         * OverlayContext (focus, click or mouseover).
         *
         * @method _cancelAutoHide
         * @param {EventFacade} event
         * @protected
         */
        _cancelAutoHide: function(event) {
            var instance = this;

            if (instance.get(CANCELLABLE_HIDE)) {
                instance.clearIntervals();
            }

            event.stopPropagation();
        },

        /**
         * Invoke the hide event when the OverlayContext looses the focus.
         *
         * @method _invokeHideTaskOnInteraction
         * @param {EventFacade} event
         * @protected
         */
        _invokeHideTaskOnInteraction: function(event) {
            var instance = this;
            var cancellableHide = instance.get(CANCELLABLE_HIDE);
            var focused = instance.get(FOCUSED);

            if (!focused && !cancellableHide) {
                instance._hideTask();
            }
        },

        /**
         * Fires when the <a href="OverlayContext.html#config_visible">visible</a>
         * attribute changes.
         *
         * @method _onVisibleChangeOverlayContext
         * @param {EventFacade} event
         * @protected
         */
        _onVisibleChangeOverlayContext: function(event) {
            var instance = this;

            if (event.newVal && instance.get('disabled')) {
                event.preventDefault();
            }
        },

        /**
         * Helper method to invoke event.stopPropagation().
         *
         * @method _stopTriggerEventPropagation
         * @param {EventFacade} event
         * @protected
         */
        _stopTriggerEventPropagation: function(event) {
            event.stopPropagation();
        },

        /**
         * Setter for the
         * <a href="OverlayContext.html#config_hideDelay">hideDelay</a>
         * attribute.
         *
         * @method _setHideDelay
         * @param {number} val
         * @protected
         * @return {number}
         */
        _setHideDelay: function(val) {
            var instance = this;

            instance._hideTask = A.debounce(instance.hide, val, instance);

            return val;
        },

        /**
         * Setter for the <a href="OverlayContext.html#config_hideOn">hideOn</a>
         * attribute.
         *
         * @method _setHideOn
         * @param {String} eventType Event type
         * @protected
         * @return {String}
         */
        _setHideOn: function(eventType) {
            var instance = this;
            var trigger = instance.get(TRIGGER);
            var toggle = eventType == instance.get(SHOW_ON);

            if (toggle) {
                instance._hideCallback = A.bind(instance._toggle, instance);

                // only one attached event is enough for toggle
                trigger.detach(eventType, instance._showCallback);
            }
            else {
                var delay = instance.get(HIDE_DELAY);

                instance._hideCallback = function(event) {
                    instance._hideTask(event);

                    event.stopPropagation();
                };
            }

            trigger.on(eventType, instance._hideCallback);

            return eventType;
        },

        /**
         * Setter for the
         * <a href="OverlayContext.html#config_hideOnDocumentClick">hideOnDocumentClick</a>
         * attribute.
         *
         * @method _setHideOn
         * @param {boolean} value
         * @protected
         * @return {boolean}
         */
        _setHideOnDocumentClick: function(value) {
            var instance = this;

            if (value) {
                A.OverlayContextManager.register(instance);
            }
            else {
                A.OverlayContextManager.remove(instance);
            }

            return value;
        },

        /**
         * Setter for the
         * <a href="OverlayContext.html#config_showDelay">showDelay</a>
         * attribute.
         *
         * @method _setShowDelay
         * @param {number} val
         * @protected
         * @return {number}
         */
        _setShowDelay: function(val) {
            var instance = this;

            instance._showTask = A.debounce(instance.show, val, instance);

            return val;
        },

        /**
         * Setter for the <a href="OverlayContext.html#config_showOn">showOn</a>
         * attribute.
         *
         * @method _setShowOn
         * @param {String} eventType Event type
         * @protected
         * @return {String}
         */
        _setShowOn: function(eventType) {
            var instance = this;
            var trigger = instance.get(TRIGGER);
            var toggle = eventType == instance.get(HIDE_ON);

            if (toggle) {
                instance._showCallback = A.bind(instance._toggle, instance);

                // only one attached event is enough for toggle
                trigger.detach(eventType, instance._hideCallback);
            }
            else {
                var delay = instance.get(SHOW_DELAY);

                instance._showCallback = function(event) {
                    instance._showTask(event);

                    event.stopPropagation();
                };
            }

            if (eventType != MOUSEDOWN) {
                trigger.on(MOUSEDOWN, instance._stopTriggerEventPropagation);
            }
            else {
                trigger.detach(MOUSEDOWN, instance._stopTriggerEventPropagation);
            }

            trigger.on(eventType, instance._showCallback);

            return eventType;
        }
    }
});

A.OverlayContext = OverlayContext;

/**
 * A base class for OverlayContextManager:
 *
 * @param config {Object} Object literal specifying widget configuration properties.
 *
 * @class OverlayContextManager
 * @constructor
 * @extends OverlayManager
 * @static
 */
A.OverlayContextManager = new A.OverlayManager({});

A.on(MOUSEDOWN, function() {
    A.OverlayContextManager.hideAll();
}, A.getDoc());


}, '3.1.0-deprecated.52', {"requires": ["aui-overlay-manager-deprecated", "aui-delayed-task-deprecated", "aui-aria"]});

YUI.add('aui-overlay-manager-deprecated', function (A, NAME) {

/**
 * The OverlayManager Utility
 *
 * @module aui-overlay
 * @submodule aui-overlay-manager
 */

var Lang = A.Lang,
    isArray = Lang.isArray,
    isBoolean = Lang.isBoolean,
    isNumber = Lang.isNumber,
    isString = Lang.isString,

    BOUNDING_BOX = 'boundingBox',
    DEFAULT = 'default',
    HOST = 'host',
    OVERLAY_MANAGER = 'OverlayManager',
    GROUP = 'group',
    Z_INDEX = 'zIndex',
    Z_INDEX_BASE = 'zIndexBase';

/**
 * <p><img src="assets/images/aui-overlay-manager/main.png"/></p>
 *
 * A base class for OverlayManager, providing:
 * <ul>
 *    <li>Grouping overlays</li>
 *    <li>Show or hide the entire group of registered overlays</li>
 *    <li>Basic Overlay Stackability (zIndex support)</li>
 * </ul>
 *
 * Quick Example:<br/>
 *
 * <pre><code>var groupOverlayManager = new A.OverlayManager();
 * groupOverlayManager.register([overlay1, overlay2, overlay3]);
 * groupOverlayManager.hideAll();
 * </code></pre>
 *
 * Check the list of <a href="OverlayManager.html#configattributes">Configuration Attributes</a> available for
 * OverlayManager.
 *
 * @param config {Object} Object literal specifying widget configuration properties.
 *
 * @class OverlayManager
 * @constructor
 * @extends Base
 */
var OverlayManager = A.Component.create({
    /**
     * Static property provides a string to identify the class.
     *
     * @property OverlayManager.NAME
     * @type String
     * @static
     */
    NAME: OVERLAY_MANAGER.toLowerCase(),

    /**
     * Static property used to define the default attribute
     * configuration for the OverlayManager.
     *
     * @property OverlayManager.ATTRS
     * @type Object
     * @static
     */
    ATTRS: {
        /**
         * The zIndex base to be used on the stacking for all overlays
         * registered on the OverlayManager.
         *
         * @attribute zIndexBase
         * @default 1000
         * @type Number
         */
        zIndexBase: {
            value: 1000,
            validator: isNumber,
            setter: Lang.toInt
        }
    },

    EXTENDS: A.Base,

    prototype: {
        /**
         * Construction logic executed during OverlayManager instantiation. Lifecycle.
         *
         * @method initializer
         * @protected
         */
        initializer: function() {
            var instance = this;

            instance._overlays = [];
        },

        /**
         * Set the passed overlay zIndex to the highest value.
         *
         * @method bringToTop
         * @param {Overlay} overlay Instance of
         * <a href="Overlay.html">Overlay</a>.
         */
        bringToTop: function(overlay) {
            var instance = this;

            var overlays = instance._overlays.sort(instance.sortByZIndexDesc);

            var highest = overlays[0];

            if (highest !== overlay) {
                var overlayZ = overlay.get(Z_INDEX);
                var highestZ = highest.get(Z_INDEX);

                overlay.set(Z_INDEX, highestZ + 1);

                overlay.set('focused', true);
            }
        },

        /**
         * Destructor lifecycle implementation for the OverlayManager class.
         * Purges events attached to the node (and all child nodes).
         *
         * @method destructor
         * @protected
         */
        destructor: function() {
            var instance = this;

            instance._overlays = [];
        },

        /**
         * Register the passed <a href="Overlay.html">Overlay</a> to this
         * OverlayManager.
         *
         * @method register
         * @param {Overlay} overlay <a href="Overlay.html">Overlay</a> instance to be registered
         * @return {Array} Registered overlays
         */
        register: function(overlay) {
            var instance = this;

            var overlays = instance._overlays;

            if (isArray(overlay)) {
                A.Array.each(overlay, function(o) {
                    instance.register(o);
                });
            }
            else {
                var zIndexBase = instance.get(Z_INDEX_BASE);
                var registered = instance._registered(overlay);

                if (!registered && overlay &&
                    ((overlay instanceof A.Overlay) ||
                        (A.Component && overlay instanceof A.Component))
                ) {
                    var boundingBox = overlay.get(BOUNDING_BOX);

                    overlays.push(overlay);

                    var zIndex = overlay.get(Z_INDEX) || 0;
                    var newZIndex = overlays.length + zIndex + zIndexBase;

                    overlay.set(Z_INDEX, newZIndex);

                    overlay.on('focusedChange', instance._onFocusedChange, instance);
                    boundingBox.on('mousedown', instance._onMouseDown, instance);
                }
            }

            return overlays;
        },

        /**
         * Remove the passed <a href="Overlay.html">Overlay</a> from this
         * OverlayManager.
         *
         * @method remove
         * @param {Overlay} overlay <a href="Overlay.html">Overlay</a> instance to be removed
         * @return {null}
         */
        remove: function(overlay) {
            var instance = this;

            var overlays = instance._overlays;

            if (overlays.length) {
                return A.Array.removeItem(overlays, overlay);
            }

            return null;
        },

        /**
         * Loop through all registered <a href="Overlay.html">Overlay</a> and
         * execute a callback.
         *
         * @method each
         * @param {function} fn Callback to be executed on the
         * <a href="Array.html#method_each">Array.each</a>
         * @return {null}
         */
        each: function(fn) {
            var instance = this;

            var overlays = instance._overlays;

            A.Array.each(overlays, fn);
        },

        /**
         * Invoke the <a href="Overlay.html#method_show">show</a> method from
         * all registered Overlays.
         *
         * @method showAll
         */
        showAll: function() {
            this.each(
                function(overlay) {
                    overlay.show();
                }
            );
        },

        /**
         * Invoke the <a href="Overlay.html#method_hide">hide</a> method from
         * all registered Overlays.
         *
         * @method hideAll
         */
        hideAll: function() {
            this.each(
                function(overlay) {
                    overlay.hide();
                }
            );
        },

        /**
         * zIndex comparator. Used on Array.sort.
         *
         * @method sortByZIndexDesc
         * @param {Overlay} a Overlay
         * @param {Overlay} b Overlay
         * @return {Number}
         */
        sortByZIndexDesc: function(a, b) {
            if (!a || !b || !a.hasImpl(A.WidgetStack) || !b.hasImpl(A.WidgetStack)) {
                return 0;
            }
            else {
                var aZ = a.get(Z_INDEX);
                var bZ = b.get(Z_INDEX);

                if (aZ > bZ) {
                    return -1;
                }
                else if (aZ < bZ) {
                    return 1;
                }
                else {
                    return 0;
                }
            }
        },

        /**
         * Check if the overlay is registered.
         *
         * @method _registered
         * @param {Overlay} overlay Overlay
         * @protected
         * @return {boolean}
         */
        _registered: function(overlay) {
            var instance = this;

            return A.Array.indexOf(instance._overlays, overlay) != -1;
        },

        /**
         * Mousedown event handler, used to invoke
         * <a href="OverlayManager.html#method_bringToTop">bringToTop</a>.
         *
         * @method _onMouseDown
         * @param {EventFacade} event
         * @protected
         */
        _onMouseDown: function(event) {
            var instance = this;
            var overlay = A.Widget.getByNode(event.currentTarget || event.target);
            var registered = instance._registered(overlay);

            if (overlay && registered) {
                instance.bringToTop(overlay);
            }
        },

        /**
         * Fires when the <a href="Widget.html#config_focused">focused</a>
         * attribute change. Used to invoke
         * <a href="OverlayManager.html#method_bringToTop">bringToTop</a>.
         *
         * @method _onFocusedChange
         * @param {EventFacade} event
         * @protected
         */
        _onFocusedChange: function(event) {
            var instance = this;

            if (event.newVal) {
                var overlay = event.currentTarget || event.target;
                var registered = instance._registered(overlay);

                if (overlay && registered) {
                    instance.bringToTop(overlay);
                }
            }
        }
    }
});

A.OverlayManager = OverlayManager;


}, '3.1.0-deprecated.52', {"requires": ["overlay", "plugin", "aui-base-deprecated", "aui-overlay-base-deprecated"]});

YUI.add('aui-overlay-mask-deprecated', function (A, NAME) {

/**
 * The OverlayMask Utility
 *
 * @module aui-overlay
 * @submodule aui-overlay-mask
 */

var L = A.Lang,
    isArray = L.isArray,
    isString = L.isString,
    isNumber = L.isNumber,
    isValue = L.isValue,

    CONFIG = A.config,

    UA = A.UA,

    IE6 = (UA.ie <= 6),

    ABSOLUTE = 'absolute',
    ALIGN_POINTS = 'alignPoints',
    BACKGROUND = 'background',
    BOUNDING_BOX = 'boundingBox',
    CONTENT_BOX = 'contentBox',
    FIXED = 'fixed',
    HEIGHT = 'height',
    OFFSET_HEIGHT = 'offsetHeight',
    OFFSET_WIDTH = 'offsetWidth',
    OPACITY = 'opacity',
    OVERLAY_MASK = 'overlaymask',
    POSITION = 'position',
    TARGET = 'target',
    WIDTH = 'width';

/**
 * A base class for OverlayMask, providing:
 * <ul>
 *    <li>Widget Lifecycle (initializer, renderUI, bindUI, syncUI, destructor)</li>
 *    <li>Cross browser mask functionality to cover an element or the entire page</li>
 *    <li>Customizable mask (i.e., background, opacity)</li>
 * </ul>
 *
 * Quick Example:<br/>
 *
 * <pre><code>var instance = new A.OverlayMask().render();</code></pre>
 *
 * Check the list of <a href="OverlayMask.html#configattributes">Configuration Attributes</a> available for
 * OverlayMask.
 *
 * @param config {Object} Object literal specifying widget configuration properties.
 *
 * @class OverlayMask
 * @constructor
 * @extends OverlayBase
 */
var OverlayMask = A.Component.create({
    /**
     * Static property provides a string to identify the class.
     *
     * @property OverlayMask.NAME
     * @type String
     * @static
     */
    NAME: OVERLAY_MASK,

    /**
     * Static property used to define the default attribute
     * configuration for the OverlayMask.
     *
     * @property OverlayMask.ATTRS
     * @type Object
     * @static
     */
    ATTRS: {
        /**
         * Points to align the <a href="Overlay.html">Overlay</a> used as
         * mask.
         *
         * @attribute alignPoints
         * @default [ 'tl', 'tl' ]
         * @type Array
         */
        alignPoints: {
            value: ['tl', 'tl'],
            validator: isArray
        },

        /**
         * Background color of the mask.
         *
         * @attribute background
         * @default null
         * @type String
         */
        background: {
            lazyAdd: false,
            value: null,
            validator: isString,
            setter: function(v) {
                if (v) {
                    this.get(CONTENT_BOX).setStyle(BACKGROUND, v);
                }

                return v;
            }
        },

        /**
         * Node where the mask will be positioned and re-dimensioned. The
         * default is the document, which means that if not specified the mask
         * takes the full screen.
         *
         * @attribute target
         * @default document
         * @type Node | String
         */
        target: {
            cloneDefaultValue: false,
            lazyAdd: false,
            value: CONFIG.doc,
            setter: function(v) {
                var instance = this;

                var target = A.one(v);

                var isDoc = instance._isDoc = target.compareTo(CONFIG.doc);
                var isWin = instance._isWin = target.compareTo(CONFIG.win);

                instance._fullPage = isDoc || isWin;

                return target;
            }
        },

        /**
         * CSS opacity of the mask.
         *
         * @attribute opacity
         * @default .5
         * @type Number
         */
        opacity: {
            value: 0.5,
            validator: isNumber,
            setter: function(v) {
                return this._setOpacity(v);
            }
        },

        /**
         * Use shim option.
         *
         * @attribute shim
         * @default True on IE.
         * @type boolean
         */
        shim: {
            value: A.UA.ie
        },

        /**
         * If true the Overlay is visible by default after the render phase.
         * Inherited from <a href="Overlay.html">Overlay</a>.
         *
         * @attribute visible
         * @default false
         * @type boolean
         */
        visible: {
            value: false
        },

        /**
         * zIndex of the OverlayMask.
         *
         * @attribute zIndex
         * @default 1000
         * @type Number
         */
        zIndex: {
            value: 1000
        }
    },

    EXTENDS: A.OverlayBase,

    prototype: {
        /**
         * Bind the events on the OverlayMask UI. Lifecycle.
         *
         * @method bindUI
         * @protected
         */
        bindUI: function() {
            var instance = this;

            OverlayMask.superclass.bindUI.apply(this, arguments);

            instance._eventHandles = [
                instance.after('targetChange', instance._afterTargetChange),
                instance.after('visibleChange', instance._afterVisibleChange),

                // window:resize YUI normalized event is not working, bug?
                A.on('windowresize', A.bind(instance.refreshMask, instance))
            ];
        },

        /**
         * Sync the OverlayMask UI. Lifecycle.
         *
         * @method syncUI
         * @protected
         */
        syncUI: function() {
            var instance = this;

            instance.refreshMask();
        },

        destructor: function() {
            var instance = this;

            (new A.EventHandle(instance._eventHandles)).detach();
        },

        /**
         * Get the size of the
         * <a href="OverlayMask.html#config_target">target</a>. Used to dimension
         * the mask node.
         *
         * @method getTargetSize
         * @return {Object} Object containing the { height: height, width: width }.
         */
        getTargetSize: function() {
            var instance = this;
            var target = instance.get(TARGET);

            var isDoc = instance._isDoc;
            var isWin = instance._isWin;

            var height = target.get(OFFSET_HEIGHT);
            var width = target.get(OFFSET_WIDTH);

            if (IE6) {
                // IE6 doesn't support height/width 100% on doc/win
                if (isWin) {
                    width = A.DOM.winWidth();
                    height = A.DOM.winHeight();
                }
                else if (isDoc) {
                    width = A.DOM.docWidth();
                    height = A.DOM.docHeight();
                }
            }
            // good browsers...
            else if (instance._fullPage) {
                height = '100%';
                width = '100%';
            }

            return {
                height: height,
                width: width
            };
        },

        /**
         * Repaint the OverlayMask UI, respecting the
         * <a href="OverlayMask.html#config_target">target</a> size and the
         * <a href="OverlayMask.html#config_alignPoints">alignPoints</a>.
         *
         * @method refreshMask
         */
        refreshMask: function() {
            var instance = this;
            var alignPoints = instance.get(ALIGN_POINTS);
            var target = instance.get(TARGET);
            var boundingBox = instance.get(BOUNDING_BOX);
            var targetSize = instance.getTargetSize();

            var fullPage = instance._fullPage;

            boundingBox.setStyles({
                position: (IE6 || !fullPage) ? ABSOLUTE : FIXED,
                left: 0,
                top: 0
            });

            var height = targetSize.height;
            var width = targetSize.width;

            if (isValue(height)) {
                instance.set(HEIGHT, height);
            }

            if (isValue(width)) {
                instance.set(WIDTH, width);
            }

            // if its not a full mask...
            if (!fullPage) {
                // if the target is not document|window align the overlay
                instance.align(target, alignPoints);
            }
        },

        /**
         * Setter for <a href="Paginator.html#config_opacity">opacity</a>.
         *
         * @method _setOpacity
         * @protected
         * @param {Number} v
         * @return {Number}
         */
        _setOpacity: function(v) {
            var instance = this;

            instance.get(CONTENT_BOX).setStyle(OPACITY, v);

            return v;
        },

        /**
         * Invoke the <code>OverlayMask.superclass._uiSetVisible</code>. Used to
         * reset the <code>opacity</code> to work around IE bugs when set opacity
         * of hidden elements.
         *
         * @method _uiSetVisible
         * @param {boolean} val
         * @protected
         */
        _uiSetVisible: function(val) {
            var instance = this;

            OverlayMask.superclass._uiSetVisible.apply(this, arguments);

            if (val) {
                instance._setOpacity(
                    instance.get(OPACITY)
                );
            }
        },

        /**
         * Fires after the value of the
         * <a href="Paginator.html#config_target">target</a> attribute change.
         *
         * @method _afterTargetChange
         * @param {EventFacade} event
         * @protected
         */
        _afterTargetChange: function(event) {
            var instance = this;

            instance.refreshMask();
        },

        /**
         * Fires after the value of the
         * <a href="Paginator.html#config_visible">visible</a> attribute change.
         *
         * @method _afterVisibleChange
         * @param {EventFacade} event
         * @protected
         */
        _afterVisibleChange: function(event) {
            var instance = this;

            instance._uiSetVisible(event.newVal);
        },

        /**
         * UI Setter for the
         * <a href="Paginator.html#config_xy">XY</a> attribute.
         *
         * @method _uiSetXY
         * @param {EventFacade} event
         * @protected
         */
        _uiSetXY: function() {
            var instance = this;

            if (!instance._fullPage || IE6) {
                OverlayMask.superclass._uiSetXY.apply(instance, arguments);
            }
        }
    }
});

A.OverlayMask = OverlayMask;


}, '3.1.0-deprecated.52', {"requires": ["event-resize", "aui-base-deprecated", "aui-overlay-base-deprecated"], "skinnable": true});

YUI.add('aui-parse-content', function (A, NAME) {

/**
 * The ParseContent Utility - Parse the content of a Node so that all of the
 * javascript contained in that Node will be executed according to the order
 * that it appears.
 *
 * @module aui-parse-content
 */

/*
 * NOTE: The inspiration of ParseContent cames from the "Caridy Patino" Node
 *       Dispatcher Plugin http://github.com/caridy/yui3-gallery/blob/master/src
 *       /gallery-dispatcher/
 */

var L = A.Lang,
    isString = L.isString,

    DOC = A.config.doc,
    PADDING_NODE = '<div>_</div>',

    SCRIPT_TYPES = {
        '': 1,
        'text/javascript': 1,
        'text/parsed': 1
    };

/**
 * A base class for ParseContent, providing:
 *
 * - After plug ParseContent on a A.Node instance the javascript chunks will be
 *   executed (remote and inline scripts)
 * - All the javascripts within a content will be executed according to the
 *   order of apparition
 *
 * **NOTE:** For performance reasons on DOM manipulation,
 * ParseContent only parses the content passed to the
 * [setContent](Node.html#method_setContent),
 * [prepend](Node.html#method_prepend) and
 * [append](Node.html#method_append) methods.
 *
 * Quick Example:
 *
 * ```
 * node.plug(A.Plugin.ParseContent);
 * ```
 *
 * @class A.ParseContent
 * @extends Plugin.Base
 * @param {Object} config Object literal specifying widget configuration
 *     properties.
 * @constructor
 */
var ParseContent = A.Component.create({
    /**
     * Static property provides a string to identify the class.
     *
     * @property NAME
     * @type String
     * @static
     */
    NAME: 'ParseContent',

    /**
     * Static property provides a string to identify the namespace.
     *
     * @property NS
     * @type String
     * @static
     */
    NS: 'ParseContent',

    /**
     * Static property used to define the default attribute
     * configuration for the ParseContent.
     *
     * @property ATTRS
     * @type Object
     * @static
     */
    ATTRS: {
        /**
         * A queue of elements to be parsed.
         *
         * @attribute queue
         * @default null
         */
        queue: {
            value: null
        },

        /**
         * When true, script nodes will not be removed from original content,
         * instead the script type attribute will be set to `text/plain`.
         *
         * @attribute preserveScriptNodes
         * @default false
         */
        preserveScriptNodes: {
            validator: L.isBoolean,
            value: false
        }
    },

    /**
     * Static property used to define which component it extends.
     *
     * @property EXTENDS
     * @type Object
     * @static
     */
    EXTENDS: A.Plugin.Base,

    prototype: {

        /**
         * Construction logic executed during ParseContent instantiation.
         * Lifecycle.
         *
         * @method initializer
         * @protected
         */
        initializer: function() {
            var instance = this;

            ParseContent.superclass.initializer.apply(this, arguments);

            instance.set(
                'queue',
                new A.AsyncQueue()
            );

            instance._bindAOP();
        },

        /**
         * Global eval the <data>data</data> passed.
         *
         * @method globalEval
         * @param {String} data JavaScript String.
         */
        globalEval: function(data) {
            var doc = A.getDoc();
            var head = doc.one('head') || doc.get('documentElement');

            // NOTE: A.Node.create('<script></script>') doesn't work correctly
            // on Opera
            var newScript = DOC.createElement('script');

            newScript.type = 'text/javascript';

            if (data) {
                // NOTE: newScript.set(TEXT, data) breaks on IE, YUI BUG.
                newScript.text = L.trim(data);
            }

            //removes the script node immediately after executing it
            head.appendChild(newScript).remove();
        },

        /**
         * Extract the `script` tags from the string content and
         * evaluate the chunks.
         *
         * @method parseContent
         * @param {String} content HTML string
         * @return {String}
         */
        parseContent: function(content) {
            var instance = this;

            var output = instance._extractScripts(content);

            instance._dispatch(output);

            return output;
        },

        /**
         * Add inline script data to the queue.
         *
         * @method _addInlineScript
         * @param {String} data The script content which should be added to the
         *     queue
         * @protected
         */
        _addInlineScript: function(data) {
            var instance = this;

            instance.get('queue').add({
                args: data,
                context: instance,
                fn: instance.globalEval,
                timeout: 0
            });
        },

        /**
         * Bind listeners on the `insert` and `setContent` methods of the Node
         * instance where you are plugging the ParseContent. These listeners are
         * responsible for intercept the HTML passed and parse them.
         *
         * @method _bindAOP
         * @protected
         */
        _bindAOP: function() {
            var instance = this;

            var cleanFirstArg = function(content) {
                var args = Array.prototype.slice.call(arguments);
                var output = instance.parseContent(content);

                // replace the first argument with the clean fragment
                args.splice(0, 1, output.fragment);

                return new A.Do.AlterArgs(null, args);
            };

            this.doBefore('insert', cleanFirstArg);
            this.doBefore('replaceChild', cleanFirstArg);

            var cleanArgs = function(content) {
                var output = instance.parseContent(content);

                return new A.Do.AlterArgs(null, [output.fragment]);
            };

            this.doBefore('replace', cleanArgs);
            this.doBefore('setContent', cleanArgs);
        },

        /**
         * Create an HTML fragment with the String passed, extract all the
         * script tags and return an Object with a reference for the extracted
         * scripts and the fragment.
         *
         * @method clean
         * @param {String} content HTML content.
         * @protected
         * @return {Object}
         */
        _extractScripts: function(content) {
            var instance = this,
                fragment = A.Node.create('<div></div>'),
                output = {},
                preserveScriptNodes = instance.get('preserveScriptNodes');

            // For PADDING_NODE, instead of fixing all tags in the content to be
            // "XHTML"-style, we make the firstChild be a valid non-empty tag,
            // then we remove it later

            if (isString(content)) {
                content = PADDING_NODE + content;

                // create fragment from {String}
                A.DOM.addHTML(fragment, content, 'append');
            }
            else {
                fragment.append(PADDING_NODE);

                // create fragment from {Y.Node | HTMLElement}
                fragment.append(content);
            }

            output.js = fragment.all('script').filter(function(script) {
                var includeScript = SCRIPT_TYPES[script.getAttribute('type').toLowerCase()];
                if (preserveScriptNodes) {
                    script.setAttribute('type', 'text/parsed');
                }
                return includeScript;
            });

            if (!preserveScriptNodes) {
                output.js.each(
                    function(node) {
                        node.remove();
                    }
                );
            }

            // remove PADDING_NODE
            fragment.get('firstChild').remove();

            output.fragment = fragment.get('childNodes').toFrag();

            return output;
        },

        /**
         * Loop trough all extracted `script` tags and evaluate them.
         *
         * @method _dispatch
         * @param {Object} output Object containing the reference for the
         *     fragment and the extracted `script` tags.
         * @protected
         * @return {String}
         */
        _dispatch: function(output) {
            var instance = this;

            var queue = instance.get('queue');

            var scriptContent = [];

            output.js.each(function(node) {
                var src = node.get('src');

                if (src) {
                    if (scriptContent.length) {
                        instance._addInlineScript(scriptContent.join(';'));

                        scriptContent.length = 0;
                    }

                    queue.add({
                        autoContinue: false,
                        fn: function() {
                            A.Get.script(src, {
                                onEnd: function(o) {
                                    //removes the script node immediately after
                                    //executing it
                                    o.purge();
                                    queue.run();
                                }
                            });
                        },
                        timeout: 0
                    });
                }
                else {
                    var dom = node._node;

                    scriptContent.push(dom.text || dom.textContent || dom.innerHTML || '');
                }
            });

            if (scriptContent.length) {
                instance._addInlineScript(scriptContent.join(';'));
            }

            queue.run();
        }
    }
});

A.namespace('Plugin').ParseContent = ParseContent;


}, '3.1.0-deprecated.52', {"requires": ["async-queue", "plugin", "io-base", "aui-component", "aui-node-base"]});

'use strict';

;(function (A, Liferay) {
	var LayoutExporter = {
		icons: {
			minus: themeDisplay.getPathThemeImages() + '/arrows/01_minus.png',
			plus: themeDisplay.getPathThemeImages() + '/arrows/01_plus.png'
		},

		publishToLive: function publishToLive(options) {
			options = options || {};

			Liferay.Util.openWindow({
				dialog: {
					constrain: true,
					modal: true,
					on: {
						visibleChange: function visibleChange(event) {
							var instance = this;

							if (!event.newVal) {
								instance.destroy();
							}
						}
					}
				},
				title: options.title,
				uri: options.url
			});
		}
	};

	Liferay.provide(LayoutExporter, 'all', function (options) {
		options = options || {};

		var obj = options.obj;
		var pane = options.pane;

		if (obj && obj.checked) {
			pane = A.one(pane);

			if (pane) {
				pane.hide();
			}
		}
	}, ['aui-base']);

	Liferay.provide(LayoutExporter, 'details', function (options) {
		options = options || {};

		var detail = A.one(options.detail);
		var img = A.one(options.toggle);

		if (detail && img) {
			var icon = LayoutExporter.icons.plus;

			if (detail.hasClass('hide')) {
				detail.show();
				icon = LayoutExporter.icons.minus;
			} else {
				detail.hide();
			}

			img.attr('src', icon);
		}
	}, ['aui-base']);

	Liferay.provide(LayoutExporter, 'proposeLayout', function (options) {
		options = options || {};

		var namespace = options.namespace;
		var reviewers = options.reviewers;

		var contents = '<div>' + '<form action="' + options.url + '" method="post">';

		if (reviewers.length > 0) {
			contents += '<textarea name="' + namespace + 'description" style="height: 100px; width: 284px;"></textarea><br /><br />' + 'Рецензент' + ' <select name="' + namespace + 'reviewUserId">';

			for (var i = 0; i < reviewers.length; i++) {
				contents += '<option value="' + reviewers[i].userId + '">' + reviewers[i].fullName + '</option>';
			}

			contents += '</select><br /><br />' + '<input type="submit" value="' + 'Дальше' + '" />';
		} else {
			contents += 'Рецензентов\x20не\x20найдено\x2e' + '<br />' + 'Пожалуйста\x2c\x20свяжитесь\x20с\x20администратором\x20для\x20назначения\x20рецензента\x2e' + '<br /><br />';
		}

		contents += '</form>' + '</div>';

		Liferay.Util.openWindow({
			dialog: {
				destroyOnHide: true
			},
			title: contents
		});
	}, ['liferay-util-window']);

	Liferay.provide(LayoutExporter, 'selected', function (options) {
		options = options || {};

		var obj = options.obj;
		var pane = options.pane;

		if (obj && obj.checked) {
			pane = A.one(pane);

			if (pane) {
				pane.show();
			}
		}
	}, ['aui-base']);

	Liferay.LayoutExporter = LayoutExporter;
})(AUI(), Liferay);
AUI.add(
  'liferay-session',
  function (A) {
    var Lang = A.Lang;

    var BUFFER_TIME = [];

    var CONFIG = A.config;

    var DOC = CONFIG.doc;

    var MAP_SESSION_STATE_EVENTS = {
      active: 'activated'
    };

    var SRC = {};

    var SRC_EVENT_OBJ = {
      src: SRC
    };

    var URL_BASE = themeDisplay.getPathMain() + '/portal/';

    var SessionBase = A.Component.create(
      {
        ATTRS: {
          autoExtend: {
            value: false
          },
          redirectOnExpire: {
            value: true
          },
          redirectUrl: {
            value: ''
          },
          sessionLength: {
            getter: '_getLengthInMillis',
            value: 0
          },
          sessionState: {
            value: 'active'
          },
          timestamp: {
            getter: '_getTimestamp',
            setter: '_setTimestamp',
            value: 0
          },
          warningLength: {
            getter: '_getLengthInMillis',
            setter: '_setWarningLength',
            value: 0
          },
          warningTime: {
            getter: '_getWarningTime',
            value: 0
          }
        },
        EXTENDS: A.Base,
        NAME: 'liferaysession',
        prototype: {
          initializer: function (config) {
            var instance = this;

            instance._cookieOptions = {
              path: '/',
              secure: A.UA.secure
            };

            instance._registered = {};
            instance.set('timestamp');
            instance._initEvents();
            instance._startTimer();
          },

          destructor: function () {
            var instance = this;

            (new A.EventHandle(instance._eventHandlers)).detach();

            instance._stopTimer();
          },

          expire: function () {
            var instance = this;

            instance.set('sessionState', 'expired', SRC_EVENT_OBJ);
          },

          extend: function () {
            var instance = this;

            instance.set('sessionState', 'active', SRC_EVENT_OBJ);
          },

          registerInterval: function (fn) {
            var instance = this;

            var fnId;
            var registered = instance._registered;

            if (Lang.isFunction(fn)) {
              fnId = A.stamp(fn);

              registered[fnId] = fn;
            }

            return fnId;
          },

          resetInterval: function () {
            var instance = this;

            instance._stopTimer();
            instance._startTimer();
          },

          unregisterInterval: function (fnId) {
            var instance = this;

            var registered = instance._registered;

            if (registered.hasOwnProperty(fnId)) {
              delete registered[fnId];
            }

            return fnId;
          },

          warn: function () {
            var instance = this;

            instance.set('sessionState', 'warned', SRC_EVENT_OBJ);
          },

          _afterSessionStateChange: function (event) {
            var instance = this;

            var details = event.details;
            var newVal = event.newVal;

            var src = null;

            if ('src' in event && details.length) {
              src = details[0];
            }

            instance.fire(MAP_SESSION_STATE_EVENTS[newVal] || newVal, src);
          },

          _defActivatedFn: function (event) {
            var instance = this;

            instance.set('timestamp');

            if (event.src == SRC) {
              instance._getExtendIO().start();
            }
          },

          _defExpiredFn: function (event) {
            var instance = this;

            A.clearInterval(instance._intervalId);

            instance.set('timestamp', 'expired');

            if (event.src === SRC) {
              instance._getExpireIO().start();
            }
          },

          _getExpireIO: function () {
            var instance = this;

            var expireIO = instance._expireIO;

            if (!expireIO) {
              expireIO = A.io.request(
                URL_BASE + 'expire_session',
                {
                  autoLoad: false,
                  on: {
                    failure: function (event, id, obj) {
                      instance._expireIO = null;

                      A.setTimeout(
                        function () {
                          instance._getExpireIO().start();
                        },
                        1000
                      );
                    },
                    success: function (event, id, obj) {
                      Liferay.fire('sessionExpired');

                      if (instance.get('redirectOnExpire')) {
                        location.href = instance.get('redirectUrl');
                      }
                    }
                  }
                }
              );

              instance._expireIO = expireIO;
            }

            return expireIO;
          },

          _getExtendIO: function () {
            var instance = this;

            var extendIO = instance._extendIO;

            if (!extendIO) {
              extendIO = A.io.request(
                URL_BASE + 'extend_session',
                {
                  autoLoad: false
                }
              );

              instance._extendIO = extendIO;
            }

            return extendIO;
          },

          _getLengthInMillis: function (value) {
            var instance = this;

            return value * 1000;
          },

          _getTimestamp: function (value) {
            var instance = this;

            return A.Cookie.get(instance._cookieKey, instance._cookieOptions) || instance._initTimestamp;
          },

          _getWarningTime: function () {
            var instance = this;

            return instance.get('sessionLength') - instance.get('warningLength');
          },

          _initEvents: function () {
            var instance = this;

            instance.publish(
              'activated',
              {
                defaultFn: A.bind('_defActivatedFn', instance)
              }
            );

            instance.publish(
              'expired',
              {
                defaultFn: A.bind('_defExpiredFn', instance)
              }
            );

            instance.publish('warned');

            instance._eventHandlers = [
              instance.on('sessionStateChange', instance._onSessionStateChange),
              instance.after('sessionStateChange', instance._afterSessionStateChange),
              A.on(
                'io:complete',
                function (transactionId, response, args) {
                  if (!args || args && args.sessionExtend || !Lang.isBoolean(args.sessionExtend)) {
                    instance.resetInterval();
                  }
                }
              ),
              Liferay.once(
                'screenLoad',
                function () {
                  instance.destroy();
                }
              )
            ];
          },

          _onSessionStateChange: function (event) {
            var instance = this;

            var newVal = event.newVal;
            var prevVal = event.prevVal;

            if (prevVal == 'expired' && prevVal != newVal) {
              event.preventDefault();
            } else if (prevVal == 'active' && prevVal == newVal) {
              instance._afterSessionStateChange(event);
            }
          },

          _setTimestamp: function (value) {
            var instance = this;

            value = String(value || Date.now());

            instance._initTimestamp = value;

            if (navigator.cookieEnabled) {
              A.Cookie.set(instance._cookieKey, value, instance._cookieOptions);
            }
          },

          _setWarningLength: function (value) {
            var instance = this;

            return Math.min(instance.get('sessionLength'), value);
          },

          _startTimer: function () {
            var instance = this;

            var sessionLength = instance.get('sessionLength');
            var warningTime = instance.get('warningTime');

            var registered = instance._registered;

            var interval = 1000;

            instance._intervalId = A.setInterval(
              function () {
                var timeOffset;

                var timestamp = instance.get('timestamp');

                var elapsed = sessionLength;

                if (Lang.toInt(timestamp)) {
                  timeOffset = Math.floor((Date.now() - timestamp) / 1000) * 1000;

                  elapsed = timeOffset;

                  if (instance._initTimestamp !== timestamp) {
                    instance.set('timestamp', timestamp);

                    var sessionState = instance.get('sessionState');

                    if (sessionState != 'active') {
                      instance.set('sessionState', 'active', SRC_EVENT_OBJ);
                    }
                  }
                } else {
                  timestamp = 'expired';
                }

                var extend = instance.get('autoExtend');

                var expirationMoment = false;
                var warningMoment = false;

                var hasExpired = elapsed >= sessionLength;
                var hasWarned = elapsed >= warningTime;

                if (hasWarned) {
                  if (timestamp == 'expired') {
                    expirationMoment = true;
                    extend = false;
                    hasExpired = true;
                  }

                  var sessionState = instance.get('sessionState');

                  if (hasExpired && sessionState != 'expired') {
                    if (extend) {
                      expirationMoment = false;
                      hasExpired = false;
                      hasWarned = false;
                      warningMoment = false;

                      instance.extend();
                    } else {
                      instance.expire();

                      expirationMoment = true;
                    }
                  } else if (hasWarned && !hasExpired && !extend && sessionState != 'warned') {
                    instance.warn();

                    warningMoment = true;
                  }
                }

                for (var i in registered) {
                  registered[i](elapsed, interval, hasWarned, hasExpired, warningMoment, expirationMoment);
                }
              },
              interval
            );
          },

          _stopTimer: function () {
            var instance = this;

            A.clearInterval(instance._intervalId);
          },

          _cookieKey: 'LFR_SESSION_STATE_' + themeDisplay.getUserId()
        }
      }
    );

    SessionBase.SRC = SRC;

    var SessionDisplay = A.Component.create(
      {
        ATTRS: {},
        EXTENDS: A.Plugin.Base,
        NAME: 'liferaysessiondisplay',
        NS: 'display',
        prototype: {
          initializer: function (config) {
            var instance = this;

            var host = instance.get('host');

            if (Liferay.Util.getTop() == CONFIG.win) {
              instance._host = host;

              instance._toggleText = {
                hide: 'Скрыть',
                show: 'Показать'
              };

              instance._expiredText = '\xa0\x20Из-за\x20отсутствия\x20активности\x20на\x20портале\x20Ваша\x20сессия\x20истекла\x2e';

              instance._warningText = 'Из-за\x20отсутствия\x20активности\x20Ваша\x20сессия\x20истекает\x20через\x20\x7b0\x7d\x2e\x20Для\x20продления\x20сессии\x20еще\x20на\x20\x7b1\x7d\x20минут\x20нажмите\x20\xabПродолжить\xbb';
              instance._warningText = Lang.sub(
                instance._warningText,
                [
                  '<span class="countdown-timer">{0}</span>',
                  host.get('sessionLength') / 60000,
                  '<a class="alert-link" href="#">' + 'Расширить' + '</a>'
                ]
              );

              host.on('sessionStateChange', instance._onHostSessionStateChange, instance);

              instance.afterHostMethod('_defActivatedFn', instance._afterDefActivatedFn);
              instance.afterHostMethod('_defExpiredFn', instance._afterDefExpiredFn);
            } else {
              host.unplug(instance);
            }
          },

          destructor: function () {
            var instance = this;

            if (instance._banner) {
              instance._banner.destroy();
            }
          },

          _afterDefActivatedFn: function (event) {
            var instance = this;

            instance._uiSetActivated();
          },

          _afterDefExpiredFn: function (event) {
            var instance = this;

            instance._host.unregisterInterval(instance._intervalId);

            instance._uiSetExpired();
          },

          _beforeHostWarned: function (event) {
            var instance = this;

            var host = instance._host;

            var sessionLength = host.get('sessionLength');
            var timestamp = host.get('timestamp');
            var warningLength = host.get('warningLength');

            var elapsed = sessionLength;

            if (Lang.toInt(timestamp)) {
              elapsed = Math.floor((Date.now() - timestamp) / 1000) * 1000;
            }

            var remainingTime = sessionLength - elapsed;

            if (remainingTime > warningLength) {
              remainingTime = warningLength;
            }

            var banner = instance._getBanner();

            var counterTextNode = banner.one('.countdown-timer');

            instance._uiSetRemainingTime(remainingTime, counterTextNode);

            banner.show();

            instance._intervalId = host.registerInterval(
              function (elapsed, interval, hasWarned, hasExpired, warningMoment, expirationMoment) {
                if (!hasWarned) {
                  instance._uiSetActivated();
                } else if (!hasExpired) {
                  if (warningMoment) {
                    if (remainingTime <= 0) {
                      remainingTime = warningLength;
                    }

                    banner.show();
                  }

                  elapsed = Math.floor((Date.now() - timestamp) / 1000) * 1000;

                  remainingTime = sessionLength - elapsed;

                  instance._uiSetRemainingTime(remainingTime, counterTextNode);

                }

                remainingTime -= interval;
              }
            );
          },

          _destroyBanner: function () {
            var instance = this;

            instance._banner = false;

            var notificationContainer = A.one('.lfr-notification-container');

            if (notificationContainer) {
              notificationContainer.remove();
            }
          },

          _formatNumber: function (value) {
            var instance = this;

            return Lang.String.padNumber(Math.floor(value), 2);
          },

          _formatTime: function (time) {
            var instance = this;

            time = Number(time);

            if (Lang.isNumber(time) && time > 0) {
              time /= 1000;

              BUFFER_TIME[0] = instance._formatNumber(time / 3600);

              time %= 3600;

              BUFFER_TIME[1] = instance._formatNumber(time / 60);

              time %= 60;

              BUFFER_TIME[2] = instance._formatNumber(time);

              time = BUFFER_TIME.join(':');
            } else {
              time = 0;
            }

            return time;
          },

          _getBanner: function () {
            var instance = this;
            var banner = instance._banner;

            var $warappers = $('.lfr-notification-container > div');
            if (banner && $warappers.length > 1 || !banner && $warappers.length > 0) {
              $warappers.remove();
              banner = null;
            }

            if (!banner) {
              banner = new Liferay.Notification(
                {
                  closeable: true,
                  delay: {
                    hide: 0,
                    show: 0
                  },
                  duration: 500,
                  message: instance._warningText,
                  on: {
                    click: function (event) {
                      if (event.domEvent.target.test('.alert-link')) {
                        event.domEvent.preventDefault();
                        instance._host.extend();
                      } else if (event.domEvent.target.test('.close')) {
                        instance._destroyBanner();
                        instance._alertClosed = true;
                      }
                    }
                  },
                  title: 'Уважаемый\x20пользователь\x21',
                  type: 'warning'
                }
              ).render('body');

              instance._banner = banner;
            }

            return banner;
          },

          _onHostSessionStateChange: function (event) {
            var instance = this;

            if (event.newVal == 'warned') {
              instance._beforeHostWarned(event);
            }
          },

          _uiSetActivated: function () {
            var instance = this;

            instance._host.unregisterInterval(instance._intervalId);

            var banner = instance._getBanner();

            if (banner) {
              instance._destroyBanner();
            }
          },

          _uiSetExpired: function () {
            var instance = this;

            var banner = instance._getBanner();

            banner.setAttrs(
              {
                message: instance._expiredText,
                title: 'Уважаемый\x20пользователь\x21',
                type: 'danger'
              }
            );
          },

          _uiSetRemainingTime: function (remainingTime) {
            var instance = this;

            remainingTime = instance._formatTime(remainingTime);

            if (!instance._alertClosed) {
              var banner = instance._getBanner();

              banner.set(
                'message',
                Lang.sub(
                  instance._warningText,
                  [
                    remainingTime
                  ]
                )
              );
            }
          }
        }
      }
    );

    Liferay.SessionBase = SessionBase;
    Liferay.SessionDisplay = SessionDisplay;
  },
  '',
  {
    requires: ['aui-io-request', 'aui-timer', 'cookie', 'liferay-notification']
  }
);

// For details about this file see: LPS-2155

;(function(A, Liferay) {
	var Util = Liferay.namespace('Util');

	var Lang = A.Lang;

	var AArray = A.Array;
	var AObject = A.Object;
	var AString = A.Lang.String;

	var htmlEscapedValues = [];
	var htmlUnescapedValues = [];

	var MAP_HTML_CHARS_ESCAPED = {
		'"': '&#034;',
		'&': '&amp;',
		'\'': '&#039;',
		'/': '&#047;',
		'<': '&lt;',
		'>': '&gt;',
		'`': '&#096;'
	};

	var MAP_HTML_CHARS_UNESCAPED = {};

	AObject.each(
		MAP_HTML_CHARS_ESCAPED,
		function(item, index) {
			MAP_HTML_CHARS_UNESCAPED[item] = index;

			htmlEscapedValues.push(item);
			htmlUnescapedValues.push(index);
		}
	);

	var REGEX_DASH = /-([a-z])/gi;

	var STR_LEFT_SQUARE_BRACKET = '[';

	var STR_RIGHT_SQUARE_BRACKET = ']';

	var REGEX_HTML_ESCAPE = new RegExp(STR_LEFT_SQUARE_BRACKET + htmlUnescapedValues.join('') + STR_RIGHT_SQUARE_BRACKET, 'g');

	var REGEX_HTML_UNESCAPE = new RegExp(htmlEscapedValues.join('|'), 'gi');

	Util.MAP_HTML_CHARS_ESCAPED = MAP_HTML_CHARS_ESCAPED;

	Util.actsAsAspect = function(object) {
		object.yield = null;
		object.rv = {};

		object.before = function(method, f) {
			var original = eval('this.' + method);

			this[method] = function() {
				f.apply(this, arguments);

				return original.apply(this, arguments);
			};
		};

		object.after = function(method, f) {
			var original = eval('this.' + method);

			this[method] = function() {
				this.rv[method] = original.apply(this, arguments);

				return f.apply(this, arguments);
			};
		};

		object.around = function(method, f) {
			var original = eval('this.' + method);

			this[method] = function() {
				this.yield = original;

				return f.apply(this, arguments);
			};
		};
	};

	Util.addInputFocus = function() {
		A.use(
			'aui-base',
			function(A) {
				var handleFocus = function(event) {
					var target = event.target;

					var tagName = target.get('tagName');

					if (tagName) {
						tagName = tagName.toLowerCase();
					}

					var nodeType = target.get('type');

					if (tagName == 'input' && (/text|password/).test(nodeType) || tagName == 'textarea') {
						var action = 'addClass';

						if (/blur|focusout/.test(event.type)) {
							action = 'removeClass';
						}

						target[action]('focus');
					}
				};

				A.on('focus', handleFocus, document);
				A.on('blur', handleFocus, document);
			}
		);

		Util.addInputFocus = function() {
		};
	};

	Util.addInputType = function(el) {
		Util.addInputType = Lang.emptyFn;

		if (Liferay.Browser.isIe() && Liferay.Browser.getMajorVersion() < 7) {
			Util.addInputType = function(el) {
				if (el) {
					el = A.one(el);
				}
				else {
					el = A.one(document.body);
				}

				var defaultType = 'text';

				el.all('input').each(
					function(item, index) {
						var type = item.get('type') || defaultType;

						item.addClass(type);
					}
				);
			};
		}

		return Util.addInputType(el);
	};

	Util.camelize = function(value, separator) {
		var regex = REGEX_DASH;

		if (separator) {
			regex = new RegExp(separator + '([a-z])', 'gi');
		}

		value = value.replace(
			regex,
			function(match0, match1) {
				return match1.toUpperCase();
			}
		);

		return value;
	};

	Util.clamp = function(value, min, max) {
		return Math.min(Math.max(value, min), max);
	};

	Util.escapeHTML = function(str, preventDoubleEscape, entities) {
		var regex = REGEX_HTML_ESCAPE;

		var entitiesList = [];

		var entitiesValues;

		if (Lang.isObject(entities)) {
			entitiesValues = [];

			AObject.each(
				entities,
				function(item, index) {
					entitiesList.push(index);

					entitiesValues.push(item);
				}
			);

			regex = new RegExp(STR_LEFT_SQUARE_BRACKET + AString.escapeRegEx(entitiesList.join('')) + STR_RIGHT_SQUARE_BRACKET, 'g');
		}
		else {
			entities = MAP_HTML_CHARS_ESCAPED;

			entitiesValues = htmlEscapedValues;
		}

		return str.replace(regex, A.bind('_escapeHTML', Util, !!preventDoubleEscape, entities, entitiesValues));
	};

	Util.isEditorPresent = function(editorName) {
		return Liferay.EDITORS && Liferay.EDITORS[editorName];
	};

	Util.randomMinMax = function(min, max) {
		return Math.round(Math.random() * (max - min)) + min;
	};

	Util.selectAndCopy = function(el) {
		el.focus();
		el.select();

		if (document.all) {
			var textRange = el.createTextRange();

			textRange.execCommand('copy');
		}
	};

	Util.setBox = function(oldBox, newBox) {
		for (var i = oldBox.length - 1; i > -1; i--) {
			oldBox.options[i] = null;
		}

		for (i = 0; i < newBox.length; i++) {
			oldBox.options[i] = new Option(newBox[i].value, i);
		}

		oldBox.options[0].selected = true;
	};

	Util.startsWith = function(str, x) {
		return str.indexOf(x) === 0;
	};

	Util.textareaTabs = function(event) {
		var el = event.currentTarget.getDOM();

		if (event.isKey('TAB')) {
			event.halt();

			var oldscroll = el.scrollTop;

			if (el.setSelectionRange) {
				var caretPos = el.selectionStart + 1;
				var elValue = el.value;

				el.value = elValue.substring(0, el.selectionStart) + '\t' + elValue.substring(el.selectionEnd, elValue.length);

				setTimeout(
					function() {
						el.focus();
						el.setSelectionRange(caretPos, caretPos);
					},
					0
				);

			}
			else {
				document.selection.createRange().text = '\t';
			}

			el.scrollTop = oldscroll;

			return false;
		}
	};

	Util.uncamelize = function(value, separator) {
		separator = separator || ' ';

		value = value.replace(/([a-zA-Z][a-zA-Z])([A-Z])([a-z])/g, '$1' + separator + '$2$3');
		value = value.replace(/([a-z])([A-Z])/g, '$1' + separator + '$2');

		return value;
	};

	Util.unescapeHTML = function(str, entities) {
		var regex = REGEX_HTML_UNESCAPE;

		var entitiesMap = MAP_HTML_CHARS_UNESCAPED;

		if (entities) {
			var entitiesValues = [];

			entitiesMap = {};

			AObject.each(
				entities,
				function(item, index) {
					entitiesMap[item] = index;

					entitiesValues.push(item);
				}
			);

			regex = new RegExp(entitiesValues.join('|'), 'gi');
		}

		return str.replace(regex, A.bind('_unescapeHTML', Util, entitiesMap));
	};

	Util._escapeHTML = function(preventDoubleEscape, entities, entitiesValues, match) {
		var result;

		if (preventDoubleEscape) {
			var arrayArgs = AArray(arguments);

			var length = arrayArgs.length;

			var offset = arrayArgs[length - 2];
			var string = arrayArgs[length - 1];

			var nextSemicolonIndex = string.indexOf(';', offset);

			if (nextSemicolonIndex >= 0) {
				var entity = string.substring(offset, nextSemicolonIndex + 1);

				if (entitiesValues.indexOf(entity) >= 0) {
					result = match;
				}
			}
		}

		if (!result) {
			result = entities[match];
		}

		return result;
	};

	Util._unescapeHTML = function(entities, match) {
		return entities[match];
	};

	Liferay.provide(
		Util,
		'check',
		function(form, name, checked) {
			var checkbox = A.one(form[name]);

			if (checkbox) {
				checkbox.attr('checked', checked);
			}
		},
		['aui-base']
	);

	Liferay.provide(
		Util,
		'disableSelectBoxes',
		function(toggleBoxId, value, selectBoxId) {
			var selectBox = A.one('#' + selectBoxId);
			var toggleBox = A.one('#' + toggleBoxId);

			if (selectBox && toggleBox) {
				var dynamicValue = Lang.isFunction(value);

				var disabled = function() {
					var currentValue = selectBox.val();

					var visible = value == currentValue;

					if (dynamicValue) {
						visible = value(currentValue, value);
					}

					toggleBox.attr('disabled', !visible);
				};

				disabled();

				selectBox.on('change', disabled);
			}
		},
		['aui-base']
	);

	Liferay.provide(
		Util,
		'disableTextareaTabs',
		function(textarea) {
			textarea = A.one(textarea);

			if (textarea && textarea.attr('textareatabs') != 'enabled') {
				textarea.attr('textareatabs', 'disabled');

				textarea.detach('keydown', Util.textareaTabs);
			}
		},
		['aui-base']
	);

	Liferay.provide(
		Util,
		'enableTextareaTabs',
		function(textarea) {
			textarea = A.one(textarea);

			if (textarea && textarea.attr('textareatabs') != 'enabled') {
				textarea.attr('textareatabs', 'disabled');

				textarea.on('keydown', Util.textareaTabs);
			}
		},
		['aui-base']
	);

	Liferay.provide(
		Util,
		'removeItem',
		function(box, value) {
			box = A.one(box);

			var selectedIndex = box.get('selectedIndex');

			if (!value) {
				box.all('option').item(selectedIndex).remove(true);
			}
			else {
				box.all('option[value=' + value + STR_RIGHT_SQUARE_BRACKET).item(selectedIndex).remove(true);
			}
		},
		['aui-base']
	);

	Liferay.provide(
		Util,
		'resizeTextarea',
		function(elString, usingRichEditor) {
			var el = A.one('#' + elString);

			if (!el) {
				el = A.one('textarea[name=' + elString + STR_RIGHT_SQUARE_BRACKET);
			}

			if (el) {
				var pageBody = A.getBody();

				var diff;

				var resize = function(event) {
					var pageBodyHeight = pageBody.get('winHeight');

					if (usingRichEditor) {
						try {
							if (el.get('nodeName').toLowerCase() != 'iframe') {
								el = window[elString];
							}
						}
						catch (e) {
						}
					}

					if (!diff) {
						var buttonRow = pageBody.one('.button-holder');
						var templateEditor = pageBody.one('.lfr-template-editor');

						if (buttonRow && templateEditor) {
							var region = templateEditor.getXY();

							diff = buttonRow.outerHeight(true) + region[1] + 25;
						}
						else {
							diff = 170;
						}
					}

					el = A.one(el);

					var styles = {
						width: '98%'
					};

					if (event) {
						styles.height = pageBodyHeight - diff;
					}

					if (usingRichEditor) {
						if (!el || !A.DOM.inDoc(el)) {
							A.on(
								'available',
								function(event) {
									el = A.one(window[elString]);

									if (el) {
										el.setStyles(styles);
									}
								},
								'#' + elString + '_cp'
							);

							return;
						}
					}

					if (el) {
						el.setStyles(styles);
					}
				};

				resize();

				var dialog = Liferay.Util.getWindow();

				if (dialog) {
					var resizeEventHandle = dialog.iframe.after('resizeiframe:heightChange', resize);

					A.getWin().on('unload', resizeEventHandle.detach, resizeEventHandle);
				}
			}
		},
		['aui-base']
	);

	Liferay.provide(
		Util,
		'setSelectedValue',
		function(col, value) {
			var option = A.one(col).one('option[value=' + value + STR_RIGHT_SQUARE_BRACKET);

			if (option) {
				option.attr('selected', true);
			}
		},
		['aui-base']
	);

	Liferay.provide(
		Util,
		'switchEditor',
		function(options) {
			var uri = options.uri;

			var windowName = Liferay.Util.getWindowName();

			var dialog = Liferay.Util.getWindow(windowName);

			if (dialog) {
				dialog.iframe.set('uri', uri);
			}
		},
		['aui-io']
	);
})(AUI(), Liferay);
