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

/**
 * Support for Widget UI Events (Custom Events fired by the widget, which wrap the underlying DOM events - e.g. widget:click, widget:mousedown)
 *
 * @module widget
 * @submodule widget-uievents
 */

var BOUNDING_BOX = "boundingBox",
    Widget = Y.Widget,
    RENDER = "render",
    L = Y.Lang,
    EVENT_PREFIX_DELIMITER = ":",

    //  Map of Node instances serving as a delegation containers for a specific
    //  event type to Widget instances using that delegation container.
    _uievts = Y.Widget._uievts = Y.Widget._uievts || {};

Y.mix(Widget.prototype, {

    /**
     * Destructor logic for UI event infrastructure,
     * invoked during Widget destruction.
     *
     * @method _destroyUIEvents
     * @for Widget
     * @private
     */
    _destroyUIEvents: function() {

        var widgetGuid = Y.stamp(this, true);

        Y.each(_uievts, function (info, key) {
            if (info.instances[widgetGuid]) {
                //  Unregister this Widget instance as needing this delegated
                //  event listener.
                delete info.instances[widgetGuid];

                //  There are no more Widget instances using this delegated
                //  event listener, so detach it.

                if (Y.Object.isEmpty(info.instances)) {
                    info.handle.detach();

                    if (_uievts[key]) {
                        delete _uievts[key];
                    }
                }
            }
        });
    },

    /**
     * Map of DOM events that should be fired as Custom Events by the
     * Widget instance.
     *
     * @property UI_EVENTS
     * @for Widget
     * @type Object
     */
    UI_EVENTS: Y.Node.DOM_EVENTS,

    /**
     * Returns the node on which to bind delegate listeners.
     *
     * @method _getUIEventNode
     * @for Widget
     * @protected
     */
    _getUIEventNode: function () {
        return this.get(BOUNDING_BOX);
    },

    /**
     * Binds a delegated DOM event listener of the specified type to the
     * Widget's outtermost DOM element to facilitate the firing of a Custom
     * Event of the same type for the Widget instance.
     *
     * @method _createUIEvent
     * @for Widget
     * @param type {String} String representing the name of the event
     * @private
     */
    _createUIEvent: function (type) {

        var uiEvtNode = this._getUIEventNode(),
            key = (Y.stamp(uiEvtNode) + type),
            info = _uievts[key],
            handle;

        //  For each Node instance: Ensure that there is only one delegated
        //  event listener used to fire Widget UI events.

        if (!info) {

            handle = uiEvtNode.delegate(type, function (evt) {

                var widget = Widget.getByNode(this);

                // Widget could be null if node instance belongs to
                // another Y instance.

                if (widget) {
                    if (widget._filterUIEvent(evt)) {
                        widget.fire(evt.type, { domEvent: evt });
                    }
                }

            }, "." + Y.Widget.getClassName());

            _uievts[key] = info = { instances: {}, handle: handle };
        }

        //  Register this Widget as using this Node as a delegation container.
        info.instances[Y.stamp(this)] = 1;
    },

    /**
     * This method is used to determine if we should fire
     * the UI Event or not. The default implementation makes sure
     * that for nested delegates (nested unrelated widgets), we don't
     * fire the UI event listener more than once at each level.
     *
     * <p>For example, without the additional filter, if you have nested
     * widgets, each widget will have a delegate listener. If you
     * click on the inner widget, the inner delegate listener's
     * filter will match once, but the outer will match twice
     * (based on delegate's design) - once for the inner widget,
     * and once for the outer.</p>
     *
     * @method _filterUIEvent
     * @for Widget
     * @param {DOMEventFacade} evt
     * @return {boolean} true if it's OK to fire the custom UI event, false if not.
     * @private
     *
     */
    _filterUIEvent: function(evt) {
        // Either it's hitting this widget's delegate container (and not some other widget's),
        // or the container it's hitting is handling this widget's ui events.
        return (evt.currentTarget.compareTo(evt.container) || evt.container.compareTo(this._getUIEventNode()));
    },

    /**
     * Determines if the specified event is a UI event.
     *
     * @private
     * @method _isUIEvent
     * @for Widget
     * @param type {String} String representing the name of the event
     * @return {String} Event Returns the name of the UI Event, otherwise
     * undefined.
     */
    _getUIEvent: function (type) {

        if (L.isString(type)) {
            var sType = this.parseType(type)[1],
                iDelim,
                returnVal;

            if (sType) {
                // TODO: Get delimiter from ET, or have ET support this.
                iDelim = sType.indexOf(EVENT_PREFIX_DELIMITER);
                if (iDelim > -1) {
                    sType = sType.substring(iDelim + EVENT_PREFIX_DELIMITER.length);
                }

                if (this.UI_EVENTS[sType]) {
                    returnVal = sType;
                }
            }

            return returnVal;
        }
    },

    /**
     * Sets up infrastructure required to fire a UI event.
     *
     * @private
     * @method _initUIEvent
     * @for Widget
     * @param type {String} String representing the name of the event
     * @return {String}
     */
    _initUIEvent: function (type) {
        var sType = this._getUIEvent(type),
            queue = this._uiEvtsInitQueue || {};

        if (sType && !queue[sType]) {

            this._uiEvtsInitQueue = queue[sType] = 1;

            this.after(RENDER, function() {
                this._createUIEvent(sType);
                delete this._uiEvtsInitQueue[sType];
            });
        }
    },

    //  Override of "on" from Base to facilitate the firing of Widget events
    //  based on DOM events of the same name/type (e.g. "click", "mouseover").
    //  Temporary solution until we have the ability to listen to when
    //  someone adds an event listener (bug 2528230)
    on: function (type) {
        this._initUIEvent(type);
        return Widget.superclass.on.apply(this, arguments);
    },

    //  Override of "publish" from Base to facilitate the firing of Widget events
    //  based on DOM events of the same name/type (e.g. "click", "mouseover").
    //  Temporary solution until we have the ability to listen to when
    //  someone publishes an event (bug 2528230)
    publish: function (type, config) {
        var sType = this._getUIEvent(type);
        if (sType && config && config.defaultFn) {
            this._initUIEvent(sType);
        }
        return Widget.superclass.publish.apply(this, arguments);
    }

}, true); // overwrite existing EventTarget methods


}, 'patched-v3.18.3', {"requires": ["node-event-delegate", "widget-base"]});

YUI.add('yui-throttle', function (Y, NAME) {

/**
Throttles a call to a method based on the time between calls. This method is attached
to the `Y` object and is <a href="../classes/YUI.html#method_throttle">documented there</a>.

    var fn = Y.throttle(function() {
        counter++;
    });

    for (i; i< 35000; i++) {
        out++;
        fn();
    }


@module yui
@submodule yui-throttle
*/

/*! Based on work by Simon Willison: http://gist.github.com/292562 */
/**
 * Throttles a call to a method based on the time between calls.
 * @method throttle
 * @for YUI
 * @param fn {function} The function call to throttle.
 * @param ms {Number} The number of milliseconds to throttle the method call.
 * Can set globally with Y.config.throttleTime or by call. Passing a -1 will
 * disable the throttle. Defaults to 150.
 * @return {function} Returns a wrapped function that calls fn throttled.
 * @since 3.1.0
 */
Y.throttle = function(fn, ms) {
    ms = (ms) ? ms : (Y.config.throttleTime || 150);

    if (ms === -1) {
        return function() {
            fn.apply(this, arguments);
        };
    }

    var last = Y.Lang.now();

    return function() {
        var now = Y.Lang.now();
        if (now - last > ms) {
            last = now;
            fn.apply(this, arguments);
        }
    };
};


}, 'patched-v3.18.3', {"requires": ["yui-base"]});

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

var Y = A;
YUI.Env.aliases = YUI.Env.aliases || {};
Y.mix(YUI.Env.aliases, {
    "aui-autosize": ["aui-autosize-iframe"],
    "aui-base": ["oop","yui-throttle","aui-classnamemanager","aui-debounce","aui-base-core","aui-base-lang","aui-node-base"],
    "aui-base-deprecated": ["aui-base","aui-node","aui-component","aui-delayed-task-deprecated","aui-selector","aui-event-base"],
    "aui-button": ["aui-button-core"],
    "aui-collection": ["aui-map","aui-set","aui-linkedset"],
    "aui-color-picker-deprecated": ["aui-color-picker-base-deprecated","aui-color-picker-grid-plugin-deprecated"],
    "aui-datasource-control-deprecated": ["aui-datasource-control-base-deprecated","aui-input-text-control-deprecated"],
    "aui-datatable": ["aui-datatable-edit","aui-datatable-highlight","aui-datatable-selection","aui-datatable-property-list"],
    "aui-datatable-edit": ["datatable-base","calendar","overlay","sortable","aui-datatype","aui-toolbar","aui-form-validator","aui-datatable-base-cell-editor","aui-datatable-base-options-cell-editor","aui-datatable-cell-editor-support","aui-datatable-core","aui-datatable-checkbox-cell-editor","aui-datatable-date-cell-editor","aui-datatable-dropdown-cell-editor","aui-datatable-radio-cell-editor","aui-datatable-text-cell-editor","aui-datatable-text-area-cell-editor"],
    "aui-datepicker-deprecated": ["aui-datepicker-base-deprecated","aui-datepicker-select-deprecated"],
    "aui-event": ["aui-event-base"],
    "aui-form-deprecated": ["aui-form-base-deprecated","aui-form-combobox-deprecated","aui-form-field-deprecated","aui-form-select-deprecated","aui-form-textarea-deprecated","aui-form-textfield-deprecated"],
    "aui-io": ["aui-io-request"],
    "aui-io-deprecated": ["aui-io-request","aui-io-plugin-deprecated"],
    "aui-node": ["aui-node-base"],
    "aui-overlay-deprecated": ["aui-overlay-base-deprecated","aui-overlay-context-deprecated","aui-overlay-context-panel-deprecated","aui-overlay-manager-deprecated","aui-overlay-mask-deprecated"],
    "aui-rating": ["aui-rating-base","aui-rating-thumb"],
    "aui-resize-deprecated": ["aui-resize-base-deprecated","aui-resize-constrain-deprecated"],
    "aui-scheduler": ["event-gestures","aui-scheduler-base","aui-scheduler-event-recorder","aui-scheduler-view-agenda","aui-scheduler-view-day","aui-scheduler-view-month","aui-scheduler-view-table-dd","aui-scheduler-view-table","aui-scheduler-view-week","aui-viewport"],
    "aui-search": ["aui-search-tst"],
    "aui-sortable": ["aui-sortable-layout","aui-sortable-list"],
    "aui-surface": ["aui-surface-app","aui-surface-screen"],
    "aui-toggler": ["aui-toggler-base","aui-toggler-delegate"],
    "aui-tooltip": ["aui-tooltip-base","aui-tooltip-delegate"],
    "aui-tpl-snippets-deprecated": ["aui-tpl-snippets-base-deprecated","aui-tpl-snippets-checkbox-deprecated","aui-tpl-snippets-input-deprecated","aui-tpl-snippets-select-deprecated","aui-tpl-snippets-textarea-deprecated"],
    "aui-tree": ["aui-tree-data","aui-tree-io","aui-tree-node","aui-tree-paginator","aui-tree-view"],
    "aui-widget": ["aui-widget-cssclass","aui-widget-toolbars"],
    "aui-widget-core": ["aui-widget-cssclass"]
});
/* This file is auto-generated by (yogi loader --yes --mix --js js/aui-loader.js --json js/aui-loader.json --start ../) */

/*jshint maxlen:900, eqeqeq: false */

/**
 * YUI 3 module metadata
 * @module loader
 * @submodule loader-yui3
 */
YUI.Env[Y.version].modules = YUI.Env[Y.version].modules || {};
Y.mix(YUI.Env[Y.version].modules, {
    "aui-ace-autocomplete-base": {
        "requires": [
            "aui-ace-editor"
        ]
    },
    "aui-ace-autocomplete-freemarker": {
        "requires": [
            "aui-ace-autocomplete-templateprocessor"
        ]
    },
    "aui-ace-autocomplete-list": {
        "requires": [
            "aui-ace-autocomplete-base",
            "overlay",
            "widget-autohide"
        ],
        "skinnable": true
    },
    "aui-ace-autocomplete-plugin": {
        "requires": [
            "aui-ace-autocomplete-list",
            "plugin"
        ]
    },
    "aui-ace-autocomplete-templateprocessor": {
        "requires": [
            "aui-ace-autocomplete-base"
        ]
    },
    "aui-ace-autocomplete-velocity": {
        "requires": [
            "aui-ace-autocomplete-templateprocessor"
        ]
    },
    "aui-ace-editor": {
        "requires": [
            "aui-node",
            "aui-component"
        ]
    },
    "aui-affix": {
        "requires": [
            "base",
            "node-screen",
            "aui-node"
        ]
    },
    "aui-alert": {
        "requires": [
            "aui-aria",
            "aui-classnamemanager",
            "aui-widget-cssclass",
            "aui-widget-transition",
            "timers",
            "widget",
            "widget-stdmod"
        ],
        "skinnable": true
    },
    "aui-aria": {
        "requires": [
            "plugin",
            "aui-component"
        ]
    },
    "aui-aria-table-sortable": {
        "requires": [
            "aui-aria"
        ]
    },
    "aui-arraysort": {
        "requires": [
            "arraysort"
        ]
    },
    "aui-audio": {
        "requires": [
            "aui-aria",
            "aui-node",
            "aui-component",
            "node-event-html5",
            "querystring-stringify-simple"
        ],
        "skinnable": true
    },
    "aui-autocomplete-deprecated": {
        "requires": [
            "aui-base-deprecated",
            "aui-overlay-base-deprecated",
            "datasource",
            "dataschema",
            "aui-form-combobox-deprecated"
        ],
        "skinnable": true
    },
    "aui-autosize": {
        "use": [
            "aui-autosize-iframe"
        ]
    },
    "aui-autosize-deprecated": {
        "requires": [
            "event-valuechange",
            "plugin",
            "aui-base-deprecated"
        ],
        "skinnable": true
    },
    "aui-autosize-iframe": {
        "requires": [
            "plugin",
            "aui-component",
            "aui-timer",
            "aui-node-base"
        ]
    },
    "aui-base": {
        "use": [
            "oop",
            "yui-throttle",
            "aui-classnamemanager",
            "aui-debounce",
            "aui-base-core",
            "aui-base-lang",
            "aui-node-base"
        ]
    },
    "aui-base-core": {},
    "aui-base-deprecated": {
        "use": [
            "aui-base",
            "aui-node",
            "aui-component",
            "aui-delayed-task-deprecated",
            "aui-selector",
            "aui-event-base"
        ]
    },
    "aui-base-html5-shiv": {
        "condition": {
            "name": "aui-base-html5-shiv",
            "trigger": "node-base",
            "ua": "ie"
        }
    },
    "aui-base-lang": {},
    "aui-boolean-data-editor": {
        "requires": [
            "aui-button-switch",
            "aui-data-editor"
        ]
    },
    "aui-button": {
        "use": [
            "aui-button-core"
        ]
    },
    "aui-button-core": {
        "requires": [
            "button",
            "button-group",
            "button-plugin",
            "aui-component",
            "aui-widget-cssclass",
            "aui-widget-toggle"
        ],
        "skinnable": true
    },
    "aui-button-item-deprecated": {
        "requires": [
            "aui-base-deprecated",
            "aui-state-interaction-deprecated",
            "widget-child"
        ],
        "skinnable": true
    },
    "aui-button-search-cancel": {
        "requires": [
            "array-invoke",
            "base",
            "base-build",
            "event-focus",
            "event-move",
            "event-resize",
            "node-screen",
            "node-event-delegate",
            "aui-node-base",
            "aui-classnamemanager",
            "aui-event-input"
        ]
    },
    "aui-button-switch": {
        "requires": [
            "aui-node-base",
            "base-build",
            "event-key",
            "transition",
            "widget"
        ],
        "skinnable": true
    },
    "aui-carousel": {
        "requires": [
            "anim",
            "aui-event",
            "aui-image-viewer-base",
            "aui-image-viewer-slideshow",
            "node-event-delegate",
            "node-focusmanager"
        ],
        "skinnable": true
    },
    "aui-carousel-mobile-touch": {
        "condition": {
            "name": "aui-carousel-mobile-touch",
            "test": function(A) {
    return A.UA.mobile && A.UA.touchEnabled;
},
            "trigger": "aui-carousel"
        },
        "requires": [
            "base-build",
            "aui-carousel"
        ]
    },
    "aui-carousel-swipe": {
        "condition": {
            "name": "aui-carousel-swipe",
            "trigger": "aui-carousel",
            "ua": "touchEnabled"
        },
        "requires": [
            "aui-carousel",
            "aui-widget-swipe",
            "base-build"
        ],
        "skinnable": true
    },
    "aui-char-counter": {
        "requires": [
            "aui-aria",
            "aui-node",
            "aui-event-input",
            "aui-component"
        ]
    },
    "aui-chart-deprecated": {
        "requires": [
            "datasource",
            "json",
            "aui-swf-deprecated"
        ]
    },
    "aui-classnamemanager": {
        "requires": [
            "classnamemanager"
        ]
    },
    "aui-collection": {
        "use": [
            "aui-map",
            "aui-set",
            "aui-linkedset"
        ]
    },
    "aui-color-palette": {
        "requires": [
            "array-extras",
            "aui-palette",
            "color-base",
            "node-core",
            "aui-widget-cssclass",
            "aui-widget-toggle"
        ],
        "skinnable": true
    },
    "aui-color-picker-base": {
        "requires": [
            "aui-color-palette",
            "aui-hsva-palette-modal",
            "event-outside"
        ],
        "skinnable": true
    },
    "aui-color-picker-base-deprecated": {
        "requires": [
            "dd-drag",
            "panel",
            "slider",
            "aui-button-item-deprecated",
            "aui-color-util-deprecated",
            "aui-form-base-deprecated",
            "aui-overlay-context-deprecated"
        ],
        "skinnable": true
    },
    "aui-color-picker-deprecated": {
        "use": [
            "aui-color-picker-base-deprecated",
            "aui-color-picker-grid-plugin-deprecated"
        ]
    },
    "aui-color-picker-grid-plugin-deprecated": {
        "requires": [
            "plugin",
            "aui-color-picker-base-deprecated"
        ],
        "skinnable": true
    },
    "aui-color-picker-popover": {
        "requires": [
            "aui-color-picker-base",
            "aui-popover",
            "aui-widget-cssclass",
            "aui-widget-toggle"
        ],
        "skinnable": true
    },
    "aui-color-util-deprecated": {
        "requires": []
    },
    "aui-component": {
        "requires": [
            "aui-classnamemanager",
            "aui-widget-cssclass",
            "aui-widget-toggle",
            "base-build",
            "widget-base"
        ]
    },
    "aui-css": {
        "type": "css"
    },
    "aui-data-editor": {
        "requires": [
            "aui-classnamemanager",
            "base-build",
            "node-base"
        ],
        "skinnable": true
    },
    "aui-data-set-deprecated": {
        "requires": [
            "oop",
            "collection",
            "base"
        ]
    },
    "aui-datasource-control-base-deprecated": {
        "requires": [
            "datasource",
            "dataschema",
            "aui-base-deprecated"
        ]
    },
    "aui-datasource-control-deprecated": {
        "use": [
            "aui-datasource-control-base-deprecated",
            "aui-input-text-control-deprecated"
        ]
    },
    "aui-datatable": {
        "use": [
            "aui-datatable-edit",
            "aui-datatable-highlight",
            "aui-datatable-selection",
            "aui-datatable-property-list"
        ]
    },
    "aui-datatable-base-cell-editor": {
        "requires": [
            "datatable-base",
            "overlay"
        ],
        "skinnable": true
    },
    "aui-datatable-base-options-cell-editor": {
        "requires": [
            "aui-datatable-base-cell-editor",
            "escape"
        ],
        "skinnable": true
    },
    "aui-datatable-body": {
        "requires": [
            "aui-classnamemanager",
            "datatable-base",
            "event-key",
            "aui-event-base"
        ]
    },
    "aui-datatable-cell-editor-support": {
        "requires": [
            "datatable-base"
        ]
    },
    "aui-datatable-checkbox-cell-editor": {
        "requires": [
            "aui-datatable-base-options-cell-editor"
        ]
    },
    "aui-datatable-core": {
        "requires": [
            "aui-datatable-body",
            "datatable-base",
            "event-key",
            "aui-event-base"
        ],
        "skinnable": true
    },
    "aui-datatable-date-cell-editor": {
        "requires": [
            "aui-datatable-base-options-cell-editor"
        ]
    },
    "aui-datatable-dropdown-cell-editor": {
        "requires": [
            "aui-datatable-base-options-cell-editor"
        ]
    },
    "aui-datatable-edit": {
        "use": [
            "datatable-base",
            "calendar",
            "overlay",
            "sortable",
            "aui-datatype",
            "aui-toolbar",
            "aui-form-validator",
            "aui-datatable-base-cell-editor",
            "aui-datatable-base-options-cell-editor",
            "aui-datatable-cell-editor-support",
            "aui-datatable-core",
            "aui-datatable-checkbox-cell-editor",
            "aui-datatable-date-cell-editor",
            "aui-datatable-dropdown-cell-editor",
            "aui-datatable-radio-cell-editor",
            "aui-datatable-text-cell-editor",
            "aui-datatable-text-area-cell-editor"
        ]
    },
    "aui-datatable-highlight": {
        "requires": [
            "aui-datatable-selection"
        ],
        "skinnable": true
    },
    "aui-datatable-property-list": {
        "requires": [
            "datatable-scroll",
            "datatable-sort",
            "aui-datatable-core",
            "aui-datatable-edit",
            "aui-datatable-highlight",
            "aui-datatable-selection",
            "aui-widget-cssclass",
            "aui-widget-toggle"
        ],
        "skinnable": true
    },
    "aui-datatable-radio-cell-editor": {
        "requires": [
            "aui-datatable-base-options-cell-editor"
        ]
    },
    "aui-datatable-selection": {
        "requires": [
            "aui-datatable-core"
        ],
        "skinnable": true
    },
    "aui-datatable-text-area-cell-editor": {
        "requires": [
            "aui-datatable-base-options-cell-editor"
        ]
    },
    "aui-datatable-text-cell-editor": {
        "requires": [
            "aui-datatable-base-options-cell-editor"
        ]
    },
    "aui-datatype": {
        "requires": [
            "datatype",
            "aui-datatype-date-parse"
        ]
    },
    "aui-datatype-date-parse": {
        "requires": [
            "aui-base-lang",
            "datatype-date-format",
            "datatype-date-parse",
            "intl"
        ]
    },
    "aui-datepicker": {
        "requires": [
            "aui-aria",
            "aui-datepicker-delegate",
            "aui-datepicker-popover",
            "base",
            "base-build",
            "calendar"
        ],
        "skinnable": true
    },
    "aui-datepicker-base-deprecated": {
        "requires": [
            "calendar",
            "aui-datatype",
            "aui-overlay-context-deprecated"
        ],
        "skinnable": true
    },
    "aui-datepicker-delegate": {
        "requires": [
            "aui-datatype-date-parse",
            "aui-event-input",
            "event-focus",
            "node-event-delegate"
        ]
    },
    "aui-datepicker-deprecated": {
        "skinnable": true,
        "use": [
            "aui-datepicker-base-deprecated",
            "aui-datepicker-select-deprecated"
        ]
    },
    "aui-datepicker-native": {
        "requires": [
            "aui-datepicker-delegate",
            "aui-node-base",
            "base",
            "base-build"
        ]
    },
    "aui-datepicker-popover": {
        "requires": [
            "aui-classnamemanager",
            "aui-popover"
        ]
    },
    "aui-datepicker-select-deprecated": {
        "requires": [
            "aui-datepicker-base-deprecated",
            "aui-button-item-deprecated"
        ],
        "skinnable": true
    },
    "aui-debounce": {},
    "aui-delayed-task-deprecated": {
        "requires": [
            "yui-base"
        ]
    },
    "aui-diagram-builder": {
        "requires": [
            "aui-aria",
            "aui-map",
            "aui-property-builder",
            "aui-diagram-builder-connector",
            "aui-property-builder-settings",
            "aui-diagram-node-condition",
            "aui-diagram-node-end",
            "aui-diagram-node-fork",
            "aui-diagram-node-join",
            "aui-diagram-node-start",
            "aui-diagram-node-state",
            "aui-diagram-node-task",
            "overlay"
        ],
        "skinnable": true
    },
    "aui-diagram-builder-connector": {
        "requires": [
            "arraylist-add",
            "arraylist-filter",
            "escape",
            "json",
            "graphics",
            "dd"
        ],
        "skinnable": true
    },
    "aui-diagram-node": {
        "requires": [
            "aui-aria",
            "aui-diagram-node-manager-base",
            "escape",
            "overlay"
        ]
    },
    "aui-diagram-node-condition": {
        "requires": [
            "aui-diagram-node-state"
        ]
    },
    "aui-diagram-node-end": {
        "requires": [
            "aui-diagram-node-state"
        ]
    },
    "aui-diagram-node-fork": {
        "requires": [
            "aui-diagram-node-state"
        ]
    },
    "aui-diagram-node-join": {
        "requires": [
            "aui-diagram-node-state"
        ]
    },
    "aui-diagram-node-manager-base": {
        "requires": [
            "base"
        ]
    },
    "aui-diagram-node-start": {
        "requires": [
            "aui-diagram-node-state"
        ]
    },
    "aui-diagram-node-state": {
        "requires": [
            "aui-diagram-node"
        ]
    },
    "aui-diagram-node-task": {
        "requires": [
            "aui-diagram-node-state"
        ]
    },
    "aui-dialog-iframe-deprecated": {
        "requires": [
            "plugin",
            "array-invoke",
            "aui-base-deprecated",
            "aui-loading-mask-deprecated"
        ],
        "skinnable": true
    },
    "aui-dropdown": {
        "requires": [
            "event-delegate",
            "event-key",
            "event-outside",
            "node-focusmanager",
            "widget",
            "widget-stack",
            "aui-classnamemanager",
            "aui-node",
            "aui-widget-cssclass",
            "aui-widget-toggle",
            "aui-widget-trigger"
        ],
        "skinnable": true
    },
    "aui-editable-deprecated": {
        "requires": [
            "aui-base-deprecated",
            "aui-form-combobox-deprecated",
            "escape",
            "event-resize"
        ],
        "skinnable": true
    },
    "aui-event": {
        "use": [
            "aui-event-base"
        ]
    },
    "aui-event-base": {
        "requires": [
            "event-base"
        ]
    },
    "aui-event-delegate-change": {
        "condition": {
            "name": "aui-event-delegate-change",
            "trigger": "event-base-ie",
            "ua": "ie"
        },
        "requires": [
            "aui-event-base",
            "event-delegate",
            "event-synthetic"
        ]
    },
    "aui-event-delegate-submit": {
        "condition": {
            "name": "aui-event-delegate-submit",
            "trigger": "event-base-ie",
            "ua": "ie"
        },
        "requires": [
            "aui-event-base",
            "event-delegate",
            "event-synthetic"
        ]
    },
    "aui-event-input": {
        "condition": {
            "name": "aui-event-input",
            "test": function(A) {
    var supportsDOMEvent = A.supportsDOMEvent,
        testFeature = A.Features.test,
        addFeature = A.Features.add;

    if (testFeature('event', 'input') === undefined) {
        addFeature('event', 'input', {
            test: function() {
                return supportsDOMEvent(document.createElement('textarea'), 'input') && (!A.UA.ie || A.UA.ie > 9);
            }
        });
    }

    return !testFeature('event', 'input');
},
            "trigger": "aui-event-base"
        },
        "requires": [
            "aui-event-base",
            "event-delegate",
            "event-synthetic",
            "timers"
        ]
    },
    "aui-form-base-deprecated": {
        "requires": [
            "io-form",
            "querystring-parse",
            "aui-base-deprecated",
            "aui-data-set-deprecated",
            "aui-form-field-deprecated"
        ]
    },
    "aui-form-builder": {
        "requires": [
            "aui-modal",
            "aui-layout",
            "aui-form-builder-field-list",
            "aui-form-builder-field-toolbar",
            "aui-form-builder-field-type",
            "aui-form-builder-field-types",
            "aui-form-builder-layout-builder",
            "aui-form-builder-page-manager",
            "aui-form-builder-settings-modal",
            "event-focus",
            "event-tap"
        ],
        "skinnable": true
    },
    "aui-form-builder-available-field-deprecated": {
        "requires": [
            "aui-property-builder-available-field"
        ]
    },
    "aui-form-builder-deprecated": {
        "requires": [
            "aui-button",
            "aui-collection",
            "aui-form-builder-available-field-deprecated",
            "aui-form-builder-field-deprecated",
            "aui-form-builder-field-button-deprecated",
            "aui-form-builder-field-checkbox-deprecated",
            "aui-form-builder-field-fieldset-deprecated",
            "aui-form-builder-field-file-upload-deprecated",
            "aui-form-builder-field-multiple-choice-deprecated",
            "aui-form-builder-field-radio-deprecated",
            "aui-form-builder-field-select-deprecated",
            "aui-form-builder-field-text-deprecated",
            "aui-form-builder-field-textarea-deprecated",
            "aui-property-builder",
            "aui-property-builder-settings",
            "aui-sortable-list",
            "aui-tabview",
            "aui-tooltip-base",
            "escape",
            "transition"
        ],
        "skinnable": true
    },
    "aui-form-builder-field-base": {
        "requires": [
            "aui-classnamemanager",
            "aui-node-base",
            "aui-text-data-editor",
            "aui-toggler",
            "base",
            "node-base"
        ],
        "skinnable": true
    },
    "aui-form-builder-field-button-deprecated": {
        "requires": [
            "aui-form-builder-field-deprecated"
        ]
    },
    "aui-form-builder-field-checkbox-deprecated": {
        "requires": [
            "aui-form-builder-field-deprecated"
        ]
    },
    "aui-form-builder-field-choice": {
        "requires": [
            "aui-boolean-data-editor",
            "aui-options-data-editor",
            "aui-tabs-data-editor",
            "aui-form-builder-field-base",
            "aui-form-field-choice"
        ]
    },
    "aui-form-builder-field-deprecated": {
        "requires": [
            "panel",
            "aui-datatype",
            "aui-datatable-edit",
            "aui-property-builder-field-support"
        ],
        "skinnable": true
    },
    "aui-form-builder-field-fieldset-deprecated": {
        "requires": [
            "aui-form-builder-field-deprecated"
        ]
    },
    "aui-form-builder-field-file-upload-deprecated": {
        "requires": [
            "aui-form-builder-field-deprecated"
        ]
    },
    "aui-form-builder-field-list": {
        "requires": [
            "aui-form-builder-field-type",
            "aui-form-builder-field-types",
            "aui-form-builder-layout-builder"
        ],
        "skinnable": true
    },
    "aui-form-builder-field-multiple-choice-deprecated": {
        "requires": [
            "aui-form-builder-field-deprecated"
        ]
    },
    "aui-form-builder-field-radio-deprecated": {
        "requires": [
            "aui-form-builder-field-deprecated"
        ]
    },
    "aui-form-builder-field-select-deprecated": {
        "requires": [
            "aui-form-builder-field-deprecated"
        ]
    },
    "aui-form-builder-field-sentence": {
        "requires": [
            "aui-form-builder-field-base",
            "aui-form-field"
        ]
    },
    "aui-form-builder-field-text": {
        "requires": [
            "aui-boolean-data-editor",
            "aui-radio-group-data-editor",
            "aui-form-builder-field-base",
            "aui-form-field-text"
        ]
    },
    "aui-form-builder-field-text-deprecated": {
        "requires": [
            "aui-form-builder-field-deprecated"
        ]
    },
    "aui-form-builder-field-textarea-deprecated": {
        "requires": [
            "aui-form-builder-field-deprecated"
        ]
    },
    "aui-form-builder-field-toolbar": {
        "requires": [
            "aui-classnamemanager",
            "base",
            "node-base"
        ],
        "skinnable": true
    },
    "aui-form-builder-field-type": {
        "requires": [
            "base",
            "node-base"
        ],
        "skinnable": true
    },
    "aui-form-builder-field-types": {
        "requires": [
            "aui-classnamemanager",
            "aui-form-builder-field-types-modal",
            "base",
            "node-base"
        ],
        "skinnable": true
    },
    "aui-form-builder-field-types-modal": {
        "requires": [
            "aui-modal"
        ],
        "skinnable": true
    },
    "aui-form-builder-layout-builder": {
        "requires": [
            "aui-classnamemanager",
            "aui-layout-builder",
            "aui-modal",
            "base",
            "node-base"
        ],
        "skinnable": true
    },
    "aui-form-builder-page-manager": {
        "requires": [
            "aui-pagination",
            "aui-popover",
            "aui-tabview",
            "base",
            "event-valuechange",
            "node-base"
        ],
        "skinnable": true
    },
    "aui-form-builder-settings-modal": {
        "requires": [
            "aui-classnamemanager",
            "aui-modal",
            "base",
            "node-base"
        ],
        "skinnable": true
    },
    "aui-form-combobox-deprecated": {
        "requires": [
            "aui-form-textarea-deprecated",
            "aui-toolbar"
        ],
        "skinnable": true
    },
    "aui-form-deprecated": {
        "use": [
            "aui-form-base-deprecated",
            "aui-form-combobox-deprecated",
            "aui-form-field-deprecated",
            "aui-form-select-deprecated",
            "aui-form-textarea-deprecated",
            "aui-form-textfield-deprecated"
        ]
    },
    "aui-form-field": {
        "requires": [
            "aui-classnamemanager",
            "aui-node-base",
            "base-build"
        ],
        "skinnable": true
    },
    "aui-form-field-choice": {
        "requires": [
            "aui-form-field-required"
        ],
        "skinnable": true
    },
    "aui-form-field-deprecated": {
        "requires": [
            "aui-base-deprecated",
            "aui-component"
        ]
    },
    "aui-form-field-required": {
        "requires": [
            "aui-form-field"
        ]
    },
    "aui-form-field-text": {
        "requires": [
            "aui-form-field-required"
        ],
        "skinnable": true
    },
    "aui-form-select-deprecated": {
        "requires": [
            "aui-form-field-deprecated"
        ]
    },
    "aui-form-textarea-deprecated": {
        "requires": [
            "node-pluginhost",
            "aui-autosize-deprecated",
            "aui-form-textfield-deprecated"
        ]
    },
    "aui-form-textfield-deprecated": {
        "requires": [
            "aui-form-field-deprecated"
        ]
    },
    "aui-form-validator": {
        "requires": [
            "escape",
            "selector-css3",
            "node-event-delegate",
            "aui-node",
            "aui-component",
            "aui-event-input"
        ]
    },
    "aui-hsv-palette": {
        "requires": [
            "aui-classnamemanager",
            "aui-widget-cssclass",
            "aui-widget-toggle",
            "aui-event-input",
            "base-build",
            "clickable-rail",
            "color-hsv",
            "dd-constrain",
            "slider",
            "widget"
        ],
        "skinnable": true
    },
    "aui-hsva-palette": {
        "requires": [
            "aui-hsv-palette"
        ],
        "skinnable": true
    },
    "aui-hsva-palette-modal": {
        "requires": [
            "aui-hsva-palette",
            "aui-modal"
        ],
        "skinnable": true
    },
    "aui-image-cropper": {
        "requires": [
            "resize-base",
            "resize-constrain",
            "dd-constrain",
            "aui-node-base",
            "aui-component"
        ],
        "skinnable": true
    },
    "aui-image-viewer": {
        "requires": [
            "widget",
            "widget-modality",
            "widget-position",
            "widget-position-align",
            "widget-position-constrain",
            "widget-stack",
            "widget-stdmod",
            "aui-event",
            "aui-image-viewer-base",
            "aui-image-viewer-multiple",
            "aui-image-viewer-slideshow",
            "aui-node-base",
            "aui-widget-cssclass",
            "aui-widget-toggle"
        ],
        "skinnable": true
    },
    "aui-image-viewer-base": {
        "requires": [
            "anim",
            "aui-aria",
            "aui-classnamemanager",
            "aui-node",
            "aui-widget-responsive",
            "base-build",
            "imageloader",
            "node-base",
            "widget",
            "widget-stack"
        ],
        "skinnable": true
    },
    "aui-image-viewer-media": {
        "requires": [
            "plugin",
            "aui-component",
            "aui-image-viewer"
        ]
    },
    "aui-image-viewer-multiple": {
        "requires": [
            "base-build",
            "node-base",
            "aui-classnamemanager",
            "aui-image-viewer-base"
        ],
        "skinnable": true
    },
    "aui-image-viewer-multiple-swipe": {
        "condition": {
            "name": "aui-image-viewer-multiple-swipe",
            "trigger": "aui-image-viewer-multiple",
            "ua": "touchEnabled"
        },
        "requires": [
            "aui-image-viewer-multiple",
            "aui-image-viewer-swipe"
        ]
    },
    "aui-image-viewer-slideshow": {
        "requires": [
            "node",
            "aui-classnamemanager"
        ]
    },
    "aui-image-viewer-swipe": {
        "condition": {
            "name": "aui-image-viewer-swipe",
            "trigger": "aui-image-viewer-base",
            "ua": "touchEnabled"
        },
        "requires": [
            "event-resize",
            "aui-image-viewer-base",
            "aui-widget-swipe"
        ]
    },
    "aui-input-text-control-deprecated": {
        "requires": [
            "aui-base-deprecated",
            "aui-datasource-control-base-deprecated",
            "aui-form-combobox-deprecated"
        ]
    },
    "aui-io": {
        "use": [
            "aui-io-request"
        ]
    },
    "aui-io-deprecated": {
        "use": [
            "aui-io-request",
            "aui-io-plugin-deprecated"
        ]
    },
    "aui-io-plugin-deprecated": {
        "requires": [
            "aui-overlay-base-deprecated",
            "aui-parse-content",
            "aui-io-request",
            "aui-loading-mask-deprecated"
        ]
    },
    "aui-io-request": {
        "requires": [
            "io-base",
            "json",
            "plugin",
            "querystring-stringify",
            "aui-component"
        ]
    },
    "aui-io-request-deprecated": {
        "requires": [
            "io-base",
            "json",
            "plugin",
            "querystring-stringify",
            "aui-base-deprecated"
        ]
    },
    "aui-layout": {
        "requires": [
            "aui-layout-col",
            "aui-layout-row",
            "aui-node-base",
            "base-build",
            "datatype-number-parse",
            "event-resize"
        ]
    },
    "aui-layout-builder": {
        "requires": [
            "aui-classnamemanager",
            "aui-layout",
            "aui-layout-builder-add-col",
            "aui-layout-builder-add-row",
            "aui-layout-builder-move",
            "aui-layout-builder-remove-row",
            "aui-layout-builder-resize-col",
            "aui-node-base",
            "base-build",
            "node-event-delegate",
            "node-screen",
            "node-style"
        ]
    },
    "aui-layout-builder-add-col": {
        "requires": [
            "event-key",
            "node-base"
        ],
        "skinnable": true
    },
    "aui-layout-builder-add-row": {
        "requires": [
            "aui-node-base",
            "base-build",
            "node-scroll-info"
        ],
        "skinnable": true
    },
    "aui-layout-builder-move": {
        "requires": [
            "aui-node-base",
            "base-build"
        ],
        "skinnable": true
    },
    "aui-layout-builder-remove-row": {
        "requires": [
            "aui-node-base",
            "base-build"
        ],
        "skinnable": true
    },
    "aui-layout-builder-resize-col": {
        "requires": [
            "dd-constrain",
            "dd-delegate",
            "dd-drop-plugin",
            "dd-proxy",
            "event-mouseenter",
            "node-base"
        ],
        "skinnable": true
    },
    "aui-layout-col": {
        "requires": [
            "aui-classnamemanager",
            "aui-node-base",
            "base-build"
        ],
        "skinnable": true
    },
    "aui-layout-row": {
        "requires": [
            "array-invoke",
            "aui-node-base",
            "base-build"
        ],
        "skinnable": true
    },
    "aui-linkedset": {
        "requires": [
            "aui-set"
        ]
    },
    "aui-live-search-deprecated": {
        "requires": [
            "aui-base-deprecated"
        ]
    },
    "aui-loading-mask-deprecated": {
        "requires": [
            "plugin",
            "aui-overlay-mask-deprecated"
        ],
        "skinnable": true
    },
    "aui-map": {
        "requires": [
            "base-build"
        ]
    },
    "aui-menu": {
        "requires": [
            "base-build",
            "event-mouseenter",
            "event-resize",
            "widget",
            "widget-position",
            "widget-position-align",
            "widget-position-constrain",
            "widget-stack",
            "aui-classnamemanager",
            "aui-debounce",
            "aui-dropdown",
            "aui-menu-item"
        ],
        "skinnable": true
    },
    "aui-menu-item": {
        "requires": [
            "base-build",
            "node-base",
            "aui-classnamemanager",
            "aui-node",
            "aui-widget-shortcut"
        ]
    },
    "aui-messaging": {
        "requires": [
            "querystring",
            "aui-timer"
        ]
    },
    "aui-modal": {
        "requires": [
            "widget",
            "widget-autohide",
            "widget-buttons",
            "widget-modality",
            "widget-position",
            "widget-position-align",
            "widget-position-constrain",
            "widget-stack",
            "widget-stdmod",
            "dd-plugin",
            "dd-constrain",
            "timers",
            "aui-classnamemanager",
            "aui-widget-cssclass",
            "aui-widget-toggle",
            "aui-widget-toolbars"
        ],
        "skinnable": true
    },
    "aui-modal-resize": {
        "condition": {
            "name": "aui-modal-resize",
            "test": function(A) {
    return !A.UA.mobile;
},
            "trigger": "aui-modal"
        },
        "requires": [
            "aui-modal",
            "resize-plugin"
        ]
    },
    "aui-node": {
        "use": [
            "aui-node-base"
        ]
    },
    "aui-node-accessible": {
        "requires": [
            "aui-node-base",
            "event-custom-base"
        ]
    },
    "aui-node-base": {
        "requires": [
            "array-extras",
            "aui-base-lang",
            "aui-classnamemanager",
            "aui-debounce",
            "node"
        ]
    },
    "aui-node-html5": {
        "condition": {
            "name": "aui-node-html5",
            "trigger": "aui-node",
            "ua": "ie"
        },
        "requires": [
            "collection",
            "aui-node-base"
        ]
    },
    "aui-options-data-editor": {
        "requires": [
            "aui-data-editor",
            "dd-constrain",
            "dd-delegate",
            "dd-drop-plugin",
            "dd-proxy",
            "event-valuechange",
            "node-event-delegate"
        ],
        "skinnable": true
    },
    "aui-overlay-base-deprecated": {
        "requires": [
            "widget-position",
            "widget-stack",
            "widget-position-align",
            "widget-position-constrain",
            "widget-stdmod",
            "aui-component"
        ]
    },
    "aui-overlay-context-deprecated": {
        "requires": [
            "aui-overlay-manager-deprecated",
            "aui-delayed-task-deprecated",
            "aui-aria"
        ]
    },
    "aui-overlay-context-panel-deprecated": {
        "requires": [
            "anim",
            "aui-overlay-context-deprecated"
        ],
        "skinnable": true
    },
    "aui-overlay-deprecated": {
        "use": [
            "aui-overlay-base-deprecated",
            "aui-overlay-context-deprecated",
            "aui-overlay-context-panel-deprecated",
            "aui-overlay-manager-deprecated",
            "aui-overlay-mask-deprecated"
        ]
    },
    "aui-overlay-manager-deprecated": {
        "requires": [
            "overlay",
            "plugin",
            "aui-base-deprecated",
            "aui-overlay-base-deprecated"
        ]
    },
    "aui-overlay-mask-deprecated": {
        "requires": [
            "event-resize",
            "aui-base-deprecated",
            "aui-overlay-base-deprecated"
        ],
        "skinnable": true
    },
    "aui-pagination": {
        "requires": [
            "node-event-delegate",
            "aui-node",
            "aui-component",
            "widget-htmlparser"
        ],
        "skinnable": true
    },
    "aui-palette": {
        "requires": [
            "base-build",
            "event-hover",
            "widget",
            "aui-classnamemanager",
            "aui-base",
            "aui-widget-cssclass",
            "aui-widget-toggle"
        ],
        "skinnable": true
    },
    "aui-parse-content": {
        "requires": [
            "async-queue",
            "plugin",
            "io-base",
            "aui-component",
            "aui-node-base"
        ]
    },
    "aui-popover": {
        "requires": [
            "event-resize",
            "widget",
            "widget-autohide",
            "widget-buttons",
            "widget-modality",
            "widget-position",
            "widget-position-align",
            "widget-position-constrain",
            "widget-stack",
            "widget-stdmod",
            "aui-classnamemanager",
            "aui-widget-cssclass",
            "aui-widget-toggle",
            "aui-widget-toolbars",
            "aui-widget-transition",
            "aui-widget-trigger",
            "aui-widget-position-align-suggestion",
            "aui-component",
            "aui-node-base"
        ],
        "skinnable": true
    },
    "aui-progressbar": {
        "requires": [
            "aui-node",
            "aui-component",
            "aui-aria"
        ],
        "skinnable": true
    },
    "aui-promise": {
        "requires": [
            "array-invoke",
            "promise",
            "oop"
        ]
    },
    "aui-property-builder": {
        "requires": [
            "dd",
            "collection",
            "aui-property-builder-available-field",
            "aui-property-builder-field-support",
            "aui-property-builder-settings",
            "aui-tabview"
        ],
        "skinnable": true
    },
    "aui-property-builder-available-field": {
        "requires": [
            "base",
            "aui-component",
            "aui-node"
        ]
    },
    "aui-property-builder-field-support": {},
    "aui-property-builder-settings": {
        "requires": [
            "aui-tabview",
            "aui-datatable-property-list"
        ]
    },
    "aui-radio-group-data-editor": {
        "requires": [
            "aui-data-editor",
            "node-event-delegate"
        ],
        "skinnable": true
    },
    "aui-rating": {
        "use": [
            "aui-rating-base",
            "aui-rating-thumb"
        ]
    },
    "aui-rating-base": {
        "requires": [
            "aui-component",
            "aui-node-base",
            "widget-htmlparser",
            "widget-uievents"
        ],
        "skinnable": true
    },
    "aui-rating-thumb": {
        "requires": [
            "aui-rating-base"
        ]
    },
    "aui-resize-base-deprecated": {
        "requires": [
            "dd-drag",
            "dd-delegate",
            "dd-drop",
            "aui-base-deprecated"
        ],
        "skinnable": true
    },
    "aui-resize-constrain-deprecated": {
        "requires": [
            "dd-constrain",
            "plugin",
            "aui-resize-base-deprecated"
        ]
    },
    "aui-resize-deprecated": {
        "skinnable": true,
        "use": [
            "aui-resize-base-deprecated",
            "aui-resize-constrain-deprecated"
        ]
    },
    "aui-scale-data-editor": {
        "requires": [
            "aui-classnamemanager",
            "aui-data-editor",
            "event-valuechange"
        ]
    },
    "aui-scheduler": {
        "use": [
            "event-gestures",
            "aui-scheduler-base",
            "aui-scheduler-event-recorder",
            "aui-scheduler-view-agenda",
            "aui-scheduler-view-day",
            "aui-scheduler-view-month",
            "aui-scheduler-view-table-dd",
            "aui-scheduler-view-table",
            "aui-scheduler-view-week",
            "aui-viewport"
        ]
    },
    "aui-scheduler-base": {
        "requires": [
            "model",
            "model-list",
            "widget-stdmod",
            "color-hsl",
            "aui-event-base",
            "aui-node-base",
            "aui-component",
            "aui-datatype",
            "aui-button",
            "node-focusmanager"
        ],
        "skinnable": true
    },
    "aui-scheduler-event-recorder": {
        "requires": [
            "querystring",
            "io-form",
            "overlay",
            "aui-scheduler-base",
            "aui-popover"
        ],
        "skinnable": true
    },
    "aui-scheduler-touch": {
        "condition": {
            "name": "aui-scheduler-touch",
            "trigger": "aui-scheduler",
            "ua": "touchEnabled"
        },
        "requires": [
            "base-build",
            "aui-scheduler"
        ],
        "skinnable": true
    },
    "aui-scheduler-view-agenda": {
        "requires": [
            "aui-scheduler-base"
        ],
        "skinnable": true
    },
    "aui-scheduler-view-day": {
        "requires": [
            "dd-drag",
            "dd-delegate",
            "dd-drop",
            "dd-constrain",
            "aui-scheduler-view-table"
        ],
        "skinnable": true
    },
    "aui-scheduler-view-month": {
        "requires": [
            "aui-scheduler-view-table"
        ],
        "skinnable": true
    },
    "aui-scheduler-view-table": {
        "requires": [
            "overlay",
            "aui-scheduler-base"
        ],
        "skinnable": true
    },
    "aui-scheduler-view-table-dd": {
        "requires": [
            "dd-drag",
            "dd-delegate",
            "dd-drop",
            "aui-scheduler-view-table"
        ]
    },
    "aui-scheduler-view-week": {
        "requires": [
            "aui-scheduler-view-day"
        ],
        "skinnable": true
    },
    "aui-scroller-deprecated": {
        "requires": [
            "event-mouseenter",
            "aui-base-deprecated",
            "aui-simple-anim-deprecated"
        ],
        "skinnable": true
    },
    "aui-scrollspy": {
        "requires": [
            "base-build",
            "node-screen",
            "aui-classnamemanager"
        ]
    },
    "aui-search": {
        "use": [
            "aui-search-tst"
        ]
    },
    "aui-search-tst": {
        "requires": [
            "aui-component"
        ]
    },
    "aui-selector": {
        "requires": [
            "selector-css3",
            "aui-classnamemanager"
        ]
    },
    "aui-set": {
        "requires": [
            "aui-map"
        ]
    },
    "aui-simple-anim-deprecated": {
        "requires": [
            "aui-base-deprecated"
        ]
    },
    "aui-skin-deprecated": {
        "type": "css"
    },
    "aui-sortable": {
        "use": [
            "aui-sortable-layout",
            "aui-sortable-list"
        ]
    },
    "aui-sortable-layout": {
        "requires": [
            "dd-delegate",
            "dd-drag",
            "dd-drop",
            "dd-proxy",
            "aui-node",
            "aui-component"
        ],
        "skinnable": true
    },
    "aui-sortable-list": {
        "requires": [
            "dd-drag",
            "dd-drop",
            "dd-proxy",
            "dd-scroll",
            "aui-node",
            "aui-component"
        ]
    },
    "aui-state-interaction-deprecated": {
        "requires": [
            "aui-base-deprecated",
            "plugin"
        ]
    },
    "aui-surface": {
        "use": [
            "aui-surface-app",
            "aui-surface-screen"
        ]
    },
    "aui-surface-app": {
        "requires": [
            "event-delegate",
            "node-event-html5",
            "aui-surface-base",
            "aui-surface-screen",
            "aui-surface-screen-route"
        ]
    },
    "aui-surface-base": {
        "requires": [
            "base-build",
            "node-style",
            "timers",
            "aui-debounce",
            "aui-promise",
            "aui-parse-content"
        ]
    },
    "aui-surface-screen": {
        "requires": [
            "base-build"
        ]
    },
    "aui-surface-screen-html": {
        "requires": [
            "aui-base",
            "aui-io-request",
            "aui-promise",
            "aui-surface-screen",
            "aui-url"
        ]
    },
    "aui-surface-screen-route": {
        "requires": [
            "base-build"
        ]
    },
    "aui-swf-deprecated": {
        "requires": [
            "querystring-parse-simple",
            "querystring-stringify-simple",
            "aui-base-deprecated"
        ]
    },
    "aui-tabs-data-editor": {
        "requires": [
            "aui-data-editor",
            "aui-tabview"
        ]
    },
    "aui-tabview": {
        "requires": [
            "selector-css3",
            "tabview",
            "aui-component",
            "aui-widget-css"
        ],
        "skinnable": true
    },
    "aui-template-deprecated": {
        "requires": [
            "aui-base-deprecated"
        ]
    },
    "aui-text-data-editor": {
        "requires": [
            "aui-data-editor",
            "event-valuechange"
        ],
        "skinnable": true
    },
    "aui-text-data-unicode": {
        "requires": [
            "text"
        ]
    },
    "aui-text-unicode": {
        "requires": [
            "aui-text-data-unicode"
        ]
    },
    "aui-textboxlist-deprecated": {
        "requires": [
            "anim-node-plugin",
            "aui-autocomplete-deprecated",
            "aui-button-item-deprecated",
            "aui-data-set-deprecated",
            "escape",
            "node-focusmanager"
        ],
        "skinnable": true
    },
    "aui-timepicker": {
        "requires": [
            "autocomplete",
            "aui-datepicker-delegate",
            "aui-datepicker-popover"
        ],
        "skinnable": true
    },
    "aui-timepicker-native": {
        "requires": [
            "base",
            "base-build",
            "aui-node-base",
            "aui-datepicker-delegate",
            "aui-datepicker-native"
        ]
    },
    "aui-timer": {
        "requires": [
            "oop"
        ]
    },
    "aui-toggler": {
        "use": [
            "aui-toggler-base",
            "aui-toggler-delegate"
        ]
    },
    "aui-toggler-accessibility": {
        "requires": [
            "aui-toggler-base"
        ]
    },
    "aui-toggler-base": {
        "requires": [
            "transition",
            "aui-selector",
            "aui-event-base",
            "aui-node",
            "aui-component",
            "event-tap"
        ],
        "skinnable": true
    },
    "aui-toggler-delegate": {
        "requires": [
            "array-invoke",
            "node-event-delegate",
            "aui-toggler-base"
        ]
    },
    "aui-toolbar": {
        "requires": [
            "arraylist",
            "arraylist-add",
            "aui-component",
            "aui-button-core"
        ]
    },
    "aui-tooltip": {
        "use": [
            "aui-tooltip-base",
            "aui-tooltip-delegate"
        ]
    },
    "aui-tooltip-base": {
        "requires": [
            "aui-aria",
            "aui-classnamemanager",
            "aui-component",
            "aui-debounce",
            "aui-node-base",
            "aui-widget-cssclass",
            "aui-widget-toggle",
            "aui-widget-transition",
            "aui-widget-trigger",
            "aui-widget-position-align-suggestion",
            "event-hover",
            "event-resize",
            "escape",
            "widget",
            "widget-autohide",
            "widget-position",
            "widget-position-align",
            "widget-position-constrain",
            "widget-stack",
            "widget-stdmod"
        ],
        "skinnable": true
    },
    "aui-tooltip-delegate": {
        "requires": [
            "aui-tooltip-base",
            "node-event-delegate"
        ]
    },
    "aui-tooltip-deprecated": {
        "requires": [
            "aui-overlay-context-panel-deprecated"
        ],
        "skinnable": true
    },
    "aui-tpl-snippets-base-deprecated": {
        "requires": [
            "aui-template-deprecated"
        ]
    },
    "aui-tpl-snippets-checkbox-deprecated": {
        "requires": [
            "aui-tpl-snippets-base-deprecated"
        ]
    },
    "aui-tpl-snippets-deprecated": {
        "use": [
            "aui-tpl-snippets-base-deprecated",
            "aui-tpl-snippets-checkbox-deprecated",
            "aui-tpl-snippets-input-deprecated",
            "aui-tpl-snippets-select-deprecated",
            "aui-tpl-snippets-textarea-deprecated"
        ]
    },
    "aui-tpl-snippets-input-deprecated": {
        "requires": [
            "aui-tpl-snippets-base-deprecated"
        ]
    },
    "aui-tpl-snippets-select-deprecated": {
        "requires": [
            "aui-tpl-snippets-base-deprecated"
        ]
    },
    "aui-tpl-snippets-textarea-deprecated": {
        "requires": [
            "aui-tpl-snippets-base-deprecated"
        ]
    },
    "aui-tree": {
        "use": [
            "aui-tree-data",
            "aui-tree-io",
            "aui-tree-node",
            "aui-tree-paginator",
            "aui-tree-view"
        ]
    },
    "aui-tree-data": {
        "requires": [
            "aui-base-core",
            "aui-base-lang",
            "aui-node-base",
            "aui-timer",
            "aui-component"
        ]
    },
    "aui-tree-io": {
        "requires": [
            "aui-component",
            "aui-io"
        ]
    },
    "aui-tree-node": {
        "requires": [
            "json",
            "querystring-stringify",
            "aui-tree-data",
            "aui-tree-io",
            "aui-tree-paginator",
            "event-key"
        ]
    },
    "aui-tree-paginator": {
        "requires": [
            "yui-base"
        ]
    },
    "aui-tree-view": {
        "requires": [
            "dd-delegate",
            "dd-proxy",
            "widget",
            "aui-tree-node",
            "aui-tree-paginator",
            "aui-tree-io"
        ],
        "skinnable": true
    },
    "aui-undo-redo": {
        "requires": [
            "aui-base",
            "base",
            "base-build",
            "event-key",
            "promise"
        ]
    },
    "aui-url": {
        "requires": [
            "oop",
            "querystring-parse",
            "querystring-stringify"
        ]
    },
    "aui-video": {
        "requires": [
            "event-resize",
            "node-event-html5",
            "querystring-stringify-simple",
            "aui-aria",
            "aui-node",
            "aui-component",
            "aui-debounce"
        ],
        "skinnable": true
    },
    "aui-viewport": {
        "requires": [
            "aui-node",
            "aui-component"
        ]
    },
    "aui-widget": {
        "use": [
            "aui-widget-cssclass",
            "aui-widget-toolbars"
        ]
    },
    "aui-widget-core": {
        "use": [
            "aui-widget-cssclass"
        ]
    },
    "aui-widget-cssclass": {
        "requires": [
            "widget-base"
        ]
    },
    "aui-widget-position-align-suggestion": {
        "requires": [
            "widget-position-align",
            "widget-stdmod"
        ]
    },
    "aui-widget-responsive": {
        "requires": [
            "event-resize",
            "widget-base"
        ]
    },
    "aui-widget-shortcut": {
        "requires": [
            "base"
        ]
    },
    "aui-widget-swipe": {
        "requires": [
            "classnamemanager",
            "scrollview-base",
            "scrollview-paginator",
            "timers"
        ]
    },
    "aui-widget-toggle": {},
    "aui-widget-toolbars": {
        "requires": [
            "widget-stdmod",
            "aui-toolbar"
        ]
    },
    "aui-widget-transition": {
        "requires": [
            "transition"
        ]
    },
    "aui-widget-trigger": {
        "requires": [
            "node"
        ]
    }
});
YUI.Env[Y.version].md5 = 'd7c627eb00edd6b6f054d8f6e7147480';
/*
 * Alloy JavaScript Library
 * http://alloy.liferay.com/
 *
 * Copyright (c) 2010 Liferay Inc.
 * http://alloy.liferay.com/LICENSE.txt
 *
 * Nate Cavanaugh (nathan.cavanaugh@liferay.com)
 * Eduardo Lundgren (eduardo.lundgren@liferay.com)
 *
 * Attribution/Third-party licenses
 * http://alloy.liferay.com/ATTRIBUTION.txt
 */

// Simple version of
// http://perfectionkills.com/detecting-event-support-without-browser-sniffing/

A.UA.edge = (function() {
    var edgeVersion = A.UA.userAgent.match(/Edge\/(.[0-9.]+)/);

    if (edgeVersion) {
        return edgeVersion[1];
    }

    return 0;
})();

A.supportsDOMEvent = function(domNode, eventName) {
    eventName = 'on' + eventName;

    if (!(eventName in domNode)) {
        if (!domNode.setAttribute) {
            domNode = A.config.doc.createElement('div');
        }

        if (domNode.setAttribute) {
            domNode.setAttribute(eventName, '');
            return (typeof domNode[eventName] === 'function');
        }
    }

    domNode = null;

    return true;
};
(function() {
    var slice = Array.prototype.slice;

    YUI.prototype.ready = function() {
        var instance = this,
            xargs = arguments,
            index = xargs.length - 1,
            modules = slice.call(arguments, 0, index);

        modules.unshift('event-base');
        modules.push(function(instance) {
            var args = arguments;

            instance.on('domready', function() {
                xargs[index].apply(this, args);
            });
        });
        instance.use.apply(instance, modules);
    };
}());


}, '3.1.0-deprecated.95');

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

(function() {
    var Lang = A.Lang,
        aArray = A.Array,
        AObject = A.Object,

        isArray = Lang.isArray,
        isNumber = Lang.isNumber,
        isString = Lang.isString,
        isUndefined = Lang.isUndefined,

        owns = AObject.owns;

    A.fn = function(fn, context, args) {
        var wrappedFn,
            dynamicLookup;

        // Explicitly set function arguments
        if (!isNumber(fn)) {
            var xargs = arguments;

            if (xargs.length > 2) {
                xargs = aArray(xargs, 2, true);
            }

            dynamicLookup = (isString(fn) && context);

            wrappedFn = function() {
                var method = (!dynamicLookup) ? fn : context[fn];

                return method.apply(context || fn, xargs);
            };
        }
        else {
            // Set function arity
            var argLength = fn;

            fn = context;
            context = args;
            dynamicLookup = (isString(fn) && context);

            wrappedFn = function() {
                var method = (!dynamicLookup) ? fn : context[fn],
                    returnValue;

                context = context || method;

                if (argLength > 0) {
                    returnValue = method.apply(context, aArray(arguments, 0, true).slice(0, argLength));
                }
                else {
                    returnValue = method.call(context);
                }

                return returnValue;
            };
        }

        return wrappedFn;
    };

    A.mix(Lang, {
        constrain: function(num, min, max) {
            return Math.min(Math.max(num, min), max);
        },

        emptyFn: function() {},

        emptyFnFalse: function() {
            return false;
        },

        emptyFnTrue: function() {
            return true;
        },

        isGuid: function(id) {
            return String(id).indexOf(A.Env._guidp) === 0;
        },

        isInteger: function(val) {
            return typeof val === 'number' &&
                isFinite(val) &&
                val > -9007199254740992 &&
                val < 9007199254740992 &&
                Math.floor(val) === val;
        },

        isNode: function(val) {
            return A.instanceOf(val, A.Node);
        },

        isNodeList: function(val) {
            return A.instanceOf(val, A.NodeList);
        },

        toFloat: function(value, defaultValue) {
            return parseFloat(value) || defaultValue || 0;
        },

        toInt: function(value, radix, defaultValue) {
            return parseInt(value, radix || 10) || defaultValue || 0;
        }
    });

    A.mix(aArray, {
        remove: function(a, from, to) {
            var rest = a.slice((to || from) + 1 || a.length);
            a.length = (from < 0) ? (a.length + from) : from;

            return a.push.apply(a, rest);
        },

        removeItem: function(a, item) {
            var index = aArray.indexOf(a, item);

            if (index > -1) {
                return aArray.remove(a, index);
            }

            return a;
        }
    });

    var LString = A.namespace('Lang.String'),

        DOC = A.config.doc,
        REGEX_DASH = /-([a-z])/gi,
        REGEX_ESCAPE_REGEX = /([.*+?^$(){}|[\]\/\\])/g,
        REGEX_NL2BR = /\r?\n/g,
        REGEX_STRIP_SCRIPTS = /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/gi,
        REGEX_STRIP_TAGS = /<\/?[^>]+>/gi,
        REGEX_UNCAMELIZE = /([a-zA-Z][a-zA-Z])([A-Z])([a-z])/g,
        REGEX_UNCAMELIZE_REPLACE_SEPARATOR = /([a-z])([A-Z])/g,
        STR_ELLIPSIS = '...',

        htmlUnescapedValues = [],

        MAP_HTML_CHARS_ESCAPED = {
            '&': '&amp;',
            '<': '&lt;',
            '>': '&gt;',
            '"': '&#034;',
            '\'': '&#039;',
            '/': '&#047;',
            '`': '&#096;'
        },
        htmlChar,
        MAP_HTML_CHARS_UNESCAPED = {};

    for (htmlChar in MAP_HTML_CHARS_ESCAPED) {
        if (MAP_HTML_CHARS_ESCAPED.hasOwnProperty(htmlChar)) {
            var escapedValue = MAP_HTML_CHARS_ESCAPED[htmlChar];

            MAP_HTML_CHARS_UNESCAPED[escapedValue] = htmlChar;

            htmlUnescapedValues.push(htmlChar);
        }
    }

    var REGEX_HTML_ESCAPE = new RegExp('[' + htmlUnescapedValues.join('') + ']', 'g'),
        REGEX_HTML_UNESCAPE = /&([^;]+);/g;

    A.mix(LString, {
        camelize: A.cached(
            function(str, separator) {
                var regex = REGEX_DASH;

                str = String(str);

                if (separator) {
                    regex = new RegExp(separator + '([a-z])', 'gi');
                }

                return str.replace(regex, LString._camelize);
            }
        ),

        capitalize: A.cached(
            function(str) {
                if (str) {
                    str = String(str);

                    str = str.charAt(0).toUpperCase() + str.substr(1).toLowerCase();
                }

                return str;
            }
        ),

        contains: function(str, searchString) {
            return str.indexOf(searchString) !== -1;
        },

        defaultValue: function(str, defaultValue) {
            if (isUndefined(str) || str === '') {
                if (isUndefined(defaultValue)) {
                    defaultValue = '';
                }

                str = defaultValue;
            }

            return str;
        },

        endsWith: function(str, suffix) {
            var length = (str.length - suffix.length);

            return ((length >= 0) && (str.indexOf(suffix, length) === length));
        },

        escapeHTML: function(str) {
            return str.replace(REGEX_HTML_ESCAPE, LString._escapeHTML);
        },

        // Courtesy of: http://simonwillison.net/2006/Jan/20/escape/
        escapeRegEx: function(str) {
            return str.replace(REGEX_ESCAPE_REGEX, '\\$1');
        },

        nl2br: function(str) {
            return String(str).replace(REGEX_NL2BR, '<br />');
        },

        padNumber: function(num, length, precision) {
            var str = precision ? Number(num).toFixed(precision) : String(num);
            var index = str.indexOf('.');

            if (index === -1) {
                index = str.length;
            }

            return LString.repeat('0', Math.max(0, length - index)) + str;
        },

        pluralize: function(count, singularVersion, pluralVersion) {
            var suffix;

            if (count === 1) {
                suffix = singularVersion;
            }
            else {
                suffix = pluralVersion || singularVersion + 's';
            }

            return count + ' ' + suffix;
        },

        prefix: function(prefix, str) {
            str = String(str);

            if (str.indexOf(prefix) !== 0) {
                str = prefix + str;
            }

            return str;
        },

        remove: function(str, substitute, all) {
            var re = new RegExp(LString.escapeRegEx(substitute), all ? 'g' : '');

            return str.replace(re, '');
        },

        removeAll: function(str, substitute) {
            return LString.remove(str, substitute, true);
        },

        repeat: function(str, length) {
            return new Array(length + 1).join(str);
        },

        round: function(value, precision) {
            value = Number(value);

            if (isNumber(precision)) {
                precision = Math.pow(10, precision);
                value = Math.round(value * precision) / precision;
            }

            return value;
        },

        startsWith: function(str, prefix) {
            return (str.lastIndexOf(prefix, 0) === 0);
        },

        stripScripts: function(str) {
            if (str) {
                str = String(str).replace(REGEX_STRIP_SCRIPTS, '');
            }

            return str;
        },

        stripTags: function(str) {
            if (str) {
                str = String(str).replace(REGEX_STRIP_TAGS, '');
            }

            return str;
        },

        substr: function(str, start, length) {
            return String(str).substr(start, length);
        },

        uncamelize: A.cached(
            function(str, separator) {
                separator = separator || ' ';

                str = String(str);

                str = str.replace(REGEX_UNCAMELIZE, '$1' + separator + '$2$3');
                str = str.replace(REGEX_UNCAMELIZE_REPLACE_SEPARATOR, '$1' + separator + '$2');

                return str;
            }
        ),

        toLowerCase: function(str) {
            return String(str).toLowerCase();
        },

        toUpperCase: function(str) {
            return String(str).toUpperCase();
        },

        trim: Lang.trim,

        truncate: function(str, length, where) {
            str = String(str);

            var ellipsisLength = STR_ELLIPSIS.length,
                strLength = str.length;

            if (length > 3) {
                if (str && (strLength > length)) {
                    where = where || 'end';

                    if (where === 'end') {
                        str = str.substr(0, (length - ellipsisLength)) + STR_ELLIPSIS;
                    }
                    else if (where === 'middle') {
                        var middlePointA = Math.floor((length - ellipsisLength) / 2),
                            middlePointB = middlePointA;

                        if (length % 2 === 0) {
                            middlePointA = Math.ceil((length - ellipsisLength) / 2);
                            middlePointB = Math.floor((length - ellipsisLength) / 2);
                        }

                        str = str.substr(0, middlePointA) + STR_ELLIPSIS + str.substr(strLength - middlePointB);
                    }
                    else if (where === 'start') {
                        str = STR_ELLIPSIS + str.substr(strLength - length + ellipsisLength);
                    }
                }
            }
            else {
                str = STR_ELLIPSIS;
            }

            return str;
        },

        undef: function(str) {
            if (isUndefined(str)) {
                str = '';
            }

            return str;
        },

        // inspired from Google unescape entities
        unescapeEntities: function(str) {
            if (LString.contains(str, '&')) {
                if (DOC && !LString.contains(str, '<')) {
                    str = LString._unescapeEntitiesUsingDom(str);
                }
                else {
                    str = LString.unescapeHTML(str);
                }
            }

            return str;
        },

        unescapeHTML: function(str) {
            return str.replace(REGEX_HTML_UNESCAPE, LString._unescapeHTML);
        },

        _camelize: function(match0, match1) {
            return match1.toUpperCase();
        },

        _escapeHTML: function(match) {
            return MAP_HTML_CHARS_ESCAPED[match];
        },

        _unescapeHTML: function(match, entity) {
            var value = MAP_HTML_CHARS_UNESCAPED[match] || match;

            if (!value && entity.charAt(0) === '#') {
                var charCode = Number('0' + value.substr(1));

                if (!isNaN(charCode)) {
                    value = String.fromCharCode(charCode);
                }
            }

            return value;
        },

        _unescapeEntitiesUsingDom: function(str) {
            var el = DOC.createElement('a');

            el.innerHTML = str;

            if (el.normalize) {
                el.normalize();
            }

            str = el.firstChild.nodeValue;

            el.innerHTML = '';

            return str;
        }
    });

    /*
     * Maps an object to an array, using the return value of fn as the values
     * for the new array.
     */
    AObject.map = function(obj, fn, context) {
        var map = [],
            i;

        for (i in obj) {
            if (owns(obj, i)) {
                map[map.length] = fn.call(context, obj[i], i, obj);
            }
        }

        return map;
    };

    /*
     * Maps an array or object to a resulting array, using the return value of
     * fn as the values for the new array. Like A.each, this function can accept
     * an object or an array.
     */
    A.map = function(obj) {
        var module = AObject;

        if (isArray(obj)) {
            module = aArray;
        }

        return module.map.apply(this, arguments);
    };
}());


}, '3.1.0-deprecated.95');

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

var ClassNameManager = A.ClassNameManager,
    _getClassName = ClassNameManager.getClassName;

A.getClassName = A.cached(
    function() {
        var args = A.Array(arguments, 0, true);

        args[args.length] = true;

        return _getClassName.apply(ClassNameManager, args);
    }
);


}, '3.1.0-deprecated.95', {"requires": ["classnamemanager"]});

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

/**
 * The Component Utility
 *
 * @module aui-component
 */

var Lang = A.Lang,
    AArray = A.Array,

    concat = function(arr, arr2) {
        return (arr || []).concat(arr2 || []);
    },

    _INSTANCES = {},
    _CONSTRUCTOR_OBJECT = A.config.win.Object.prototype.constructor,

    ClassNameManager = A.ClassNameManager,

    _getClassName = ClassNameManager.getClassName,
    _getWidgetClassName = A.Widget.getClassName,

    getClassName = A.getClassName,

    CSS_HIDE = getClassName('hide');

/**
 * A base class for `A.Component`, providing:
 *
 * - Widget Lifecycle (initializer, renderUI, bindUI, syncUI, destructor)
 *
 * @class A.Component
 * @extends Widget
 * @uses A.WidgetCssClass, A.WidgetToggle
 * @param {Object} config Object literal specifying widget configuration
 *     properties.
 * @constructor
 */
var Component = A.Base.create('component', A.Widget, [
        A.WidgetCssClass,
        A.WidgetToggle
    ], {
    initializer: function(config) {
        var instance = this;

        instance._originalConfig = config;

        instance._setRender(config);

        _INSTANCES[instance.get('id')] = instance;
    },

    /**
     * Clone the current `A.Component`.
     *
     * @method clone
     * @param {Object} config
     * @return {Widget} Cloned instance.
     */
    clone: function(config) {
        var instance = this;

        config = config || {};

        config.id = config.id || A.guid();

        A.mix(config, instance._originalConfig);

        return new instance.constructor(config);
    },

    /**
     * Set the visibility on the UI.
     *
     * @method _uiSetVisible
     * @param value
     * @protected
     */
    _uiSetVisible: function(value) {
        var instance = this;

        var superUISetVisible = Component.superclass._uiSetVisible;

        if (superUISetVisible) {
            superUISetVisible.apply(instance, arguments);
        }

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

        if (hideClass !== false) {
            var boundingBox = instance.get('boundingBox');

            boundingBox.toggleClass(hideClass || CSS_HIDE, !value);
        }
    },

    /**
     * Applies standard class names to the `boundingBox` and `contentBox`.
     *
     * @method _renderBoxClassNames
     * @protected
     */
    _renderBoxClassNames: function() {
        var instance = this;

        var boundingBoxNode = instance.get('boundingBox')._node;
        var contentBoxNode = instance.get('contentBox')._node;

        var boundingBoxNodeClassName = boundingBoxNode.className;
        var contentBoxNodeClassName = contentBoxNode.className;

        var boundingBoxBuffer = (boundingBoxNodeClassName) ? boundingBoxNodeClassName.split(' ') : [];
        var contentBoxBuffer = (contentBoxNodeClassName) ? contentBoxNodeClassName.split(' ') : [];

        var classes = instance._getClasses();

        var classLength = classes.length;

        var auiClassesLength = classLength - 4;

        var classItem;
        var classItemName;

        boundingBoxBuffer.push(_getWidgetClassName());

        for (var i = classLength - 3; i >= 0; i--) {
            classItem = classes[i];

            classItemName = String(classItem.NAME).toLowerCase();

            boundingBoxBuffer.push(classItem.CSS_PREFIX || _getClassName(classItemName));

            if (i <= auiClassesLength) {
                classItemName = classItemName;

                contentBoxBuffer.push(getClassName(classItemName, 'content'));
            }
        }

        contentBoxBuffer.push(instance.getClassName('content'));

        if (boundingBoxNode === contentBoxNode) {
            contentBoxNodeClassName = AArray.dedupe(contentBoxBuffer.concat(boundingBoxBuffer)).join(' ');
        }
        else {
            boundingBoxNode.className = AArray.dedupe(boundingBoxBuffer).join(' ');

            contentBoxNodeClassName = AArray.dedupe(contentBoxBuffer).join(' ');
        }

        contentBoxNode.className = contentBoxNodeClassName;
    },

    /**
     * Renders the `A.Component` based upon a passed in interaction.
     *
     * @method _renderInteraction
     * @param event
     * @param parentNode
     * @protected
     */
    _renderInteraction: function(event, parentNode) {
        var instance = this;

        instance.render(parentNode);

        var renderHandles = instance._renderHandles;

        for (var i = renderHandles.length - 1; i >= 0; i--) {
            var handle = renderHandles.pop();

            handle.detach();
        }
    },

    /**
     * Sets the interaction and render behavior based upon an object (intercepts
     * the default rendering behavior).
     *
     * @method _setRender
     * @param config
     * @protected
     */
    _setRender: function(config) {
        var instance = this;

        var render = config && config.render;

        if (render && render.constructor === _CONSTRUCTOR_OBJECT) {
            var eventType = render.eventType || 'mousemove';
            var parentNode = render.parentNode;
            var selector = render.selector || parentNode;

            if (selector) {
                instance._renderHandles = [];

                var renderHandles = instance._renderHandles;

                if (!Lang.isArray(eventType)) {
                    eventType = [eventType];
                }

                var renderInteraction = A.rbind(instance._renderInteraction, instance, parentNode);

                var interactionNode = A.one(selector);

                for (var i = eventType.length - 1; i >= 0; i--) {
                    renderHandles[i] = interactionNode.once(eventType[i], renderInteraction);
                }

                delete config.render;
            }
        }
    }
}, {
    /**
     * Static property used to define the default attribute configuration for
     * the Component.
     *
     * @property ATTRS
     * @type Object
     * @static
     */
    ATTRS: {
        /**
         * Indicates if use of the WAI-ARIA Roles and States should be enabled
         * for the Widget.
         *
         * @attribute useARIA
         * @default false
         * @type Boolean
         * @writeOnce
         */
        useARIA: {
            writeOnce: true,
            value: false,
            validator: Lang.isBoolean
        },

        /**
         * CSS class added to hide the `boundingBox` when
         * [visible](A.Component.html#attr_visible) is set to `false`.
         *
         * @attribute hideClass
         * @default 'aui-hide'
         * @type String
         */
        hideClass: {
            value: CSS_HIDE
        },

        /**
         * If `true` the render phase will be autimatically invoked preventing
         * the `.render()` manual call.
         *
         * @attribute render
         * @default false
         * @type Boolean | Node
         * @writeOnce
         */
        render: {
            value: false,
            writeOnce: true
        }
    }
});

/**
 * Static property used to define the map to store Component instances by id.
 *
 * @property _INSTANCES
 * @type Object
 * @static
 */
Component._INSTANCES = _INSTANCES;

/**
 * Gets component's instance by id.
 *
 * @method getById
 * @param id
 */
Component.getById = function(id) {
    return _INSTANCES[id];
};

var DEFAULT_UI_ATTRS = A.Widget.prototype._UI_ATTRS;

/**
 * Applies a CSS prefix on a component.
 *
 * @method _applyCssPrefix
 * @param component
 * @protected
 */
Component._applyCssPrefix = function(component) {
    if (component && component.NAME && !('CSS_PREFIX' in component)) {
        component.CSS_PREFIX = A.getClassName(String(component.NAME).toLowerCase());
    }

    return component;
};

/**
 * Applies standard extensions from a given config to create a new class using
 * the static `Base.build` method.
 *
 * @method create
 * @param config
 */
Component.create = function(config) {
    config = config || {};

    var extendsClass = config.EXTENDS || A.Component;

    var component = config.constructor;

    if (!A.Object.owns(config, 'constructor')) {
        component = function() {
            component.superclass.constructor.apply(this, arguments);
        };
    }

    var configProto = config.prototype;

    if (configProto) {
        if (config.UI_ATTRS || config.BIND_UI_ATTRS || config.SYNC_UI_ATTRS) {
            var BIND_UI_ATTRS = concat(config.BIND_UI_ATTRS, config.UI_ATTRS);
            var SYNC_UI_ATTRS = concat(config.SYNC_UI_ATTRS, config.UI_ATTRS);

            var extendsProto = extendsClass.prototype;
            var extendsUIAttrs = (extendsProto && extendsProto._UI_ATTRS) || DEFAULT_UI_ATTRS;

            BIND_UI_ATTRS = concat(extendsUIAttrs.BIND, BIND_UI_ATTRS);
            SYNC_UI_ATTRS = concat(extendsUIAttrs.SYNC, SYNC_UI_ATTRS);

            var configProtoUIAttrs = configProto._UI_ATTRS;

            if (!configProtoUIAttrs) {
                configProtoUIAttrs = configProto._UI_ATTRS = {};
            }

            if (BIND_UI_ATTRS.length) {
                configProtoUIAttrs.BIND = BIND_UI_ATTRS;
            }

            if (SYNC_UI_ATTRS.length) {
                configProtoUIAttrs.SYNC = SYNC_UI_ATTRS;
            }
        }
    }

    var augmentsClasses = config.AUGMENTS;

    if (augmentsClasses && !Lang.isArray(augmentsClasses)) {
        augmentsClasses = [augmentsClasses];
    }

    A.mix(component, config);

    delete component.prototype;

    A.extend(component, extendsClass, configProto);

    if (augmentsClasses) {
        component = A.Base.build(config.NAME, component, augmentsClasses, {
            dynamic: false
        });
    }

    Component._applyCssPrefix(component);

    return component;
};

/**
 * Static property provides a string to identify the CSS prefix.
 *
 * @property CSS_PREFIX
 * @type String
 * @static
 */
Component.CSS_PREFIX = getClassName('component');

var Base = A.Base;

/**
 * Applies extensions to a class using the static `Base.build` method.
 *
 * @method build
 */
Component.build = function() {
    var component = Base.build.apply(Base, arguments);

    Component._applyCssPrefix(component);

    return component;
};

A.Component = Component;


}, '3.1.0-deprecated.95', {
    "requires": [
        "aui-classnamemanager",
        "aui-widget-cssclass",
        "aui-widget-toggle",
        "base-build",
        "widget-base"
    ]
});

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

var Lang = A.Lang,
    aArray = A.Array,
    isString = Lang.isString,
    isUndefined = Lang.isUndefined,

    DEFAULT_ARGS = [];

var toArray = function(arr, fallback, index, arrayLike) {
    return !isUndefined(arr) ? aArray(arr, index || 0, (arrayLike !== false)) : fallback;
};

A.debounce = function(fn, delay, context, args) {
    var id;
    var tempArgs;
    var wrapped;

    if (isString(fn) && context) {
        fn = A.bind(fn, context);
    }

    delay = delay || 0;

    args = toArray(arguments, DEFAULT_ARGS, 3);

    var clearFn = function() {
        clearInterval(id);

        id = null;
    };

    var base = function() {
        clearFn();

        var result = fn.apply(context, tempArgs || args || DEFAULT_ARGS);

        tempArgs = null;

        return result;
    };

    var delayFn = function(delayTime, newArgs, newContext, newFn) {
        wrapped.cancel();

        delayTime = !isUndefined(delayTime) ? delayTime : delay;

        fn = newFn || fn;
        context = newContext || context;

        if (newArgs !== args) {
            tempArgs = toArray(newArgs, DEFAULT_ARGS, 0, false).concat(args);
        }

        if (delayTime > 0) {
            id = setInterval(base, delayTime);
        }
        else {
            return base();
        }
    };

    var cancelFn = function() {
        if (id) {
            clearFn();
        }
    };

    var setDelay = function(delay) {
        cancelFn();

        delay = delay || 0;
    };

    wrapped = function() {
        var currentArgs = arguments.length ? arguments : args;

        return wrapped.delay(delay, currentArgs, context || this);
    };

    wrapped.cancel = cancelFn;
    wrapped.delay = delayFn;
    wrapped.setDelay = setDelay;

    return wrapped;
};


}, '3.1.0-deprecated.95');

YUI.add('aui-delayed-task-deprecated', function (A, NAME) {

/**
 * The DelayedTask Utility - Executes the supplied function in the context of
 * the supplied object 'when' milliseconds later
 *
 * @module aui-delayed-task
 */

/**
 * A base class for DelayedTask, providing:
 * <ul>
 *    <li>Executes the supplied function in the context of the supplied object 'when' milliseconds later</li>
 * </ul>
 *
 * Quick Example:<br/>
 *
 * <pre><code>var delayed = new A.DelayedTask({
 *	 function() {
 *     // This callback will be executed when the <code>DelayedTask</code> be invoked
 *	 },
 *	 scope
 *  });
 *
 * 	// executes after 1000ms the callback
 *  delayed.delay(1000);
 * </code></pre>
 *
 * Check the list of <a href="DelayedTask.html#configattributes">Configuration Attributes</a> available for
 * DelayedTask.
 *
 * @param config {Object} Object literal specifying widget configuration properties.
 *
 * @class DelayedTask
 * @param {function} fn Callback
 * @param {Object} scope Context object. Optional.
 * @param args 0..n additional arguments that should be provided to the listener.
 * @constructor
 */
var DelayedTask = function(fn, scope, args) {
    var instance = this;

    /**
     * Stores the passed <code>args</code> attribute.
     *
     * @property _args
     * @type Object
     * @protected
     */
    instance._args = args;

    /**
     * Stores the passed <code>delay</code> attribute.
     *
     * @property _delay
     * @default 0
     * @type Number
     * @protected
     */
    instance._delay = 0;

    /**
     * Stores the passed <code>fn</code> attribute.
     *
     * @property _fn
     * @type function
     * @protected
     */
    instance._fn = fn;

    /**
     * Stores the timer <code>id</code> given from the <code>setInterval</code>.
     *
     * @property _id
     * @default null
     * @type Number
     * @protected
     */
    instance._id = null;

    /**
     * Stores the passed <code>scope</code> attribute.
     *
     * @property _scope
     * @default instance
     * @type Object
     * @protected
     */
    instance._scope = scope || instance;

    /**
     * Stores the current timestamp given from
     * <a href="DelayedTask.html#method__getTime">_getTime</a>.
     *
     * @property _time
     * @default 0
     * @type Number
     * @protected
     */
    instance._time = 0;

    instance._base = function() {
        var now = instance._getTime();

        if (now - instance._time >= instance._delay) {
            clearInterval(instance._id);

            instance._id = null;

            instance._fn.apply(instance._scope, instance._args || []);
        }
    };
};

DelayedTask.prototype = {
    /**
     * <p>This function is responsible to execute the user callback, passed in
     * the <code>constructor</code> after <code>delay</code> milliseconds.</p>
     *
     * Example:
     *
     * <pre><code>// executes after 1000ms the callback
     * delayed.delay(1000);</code></pre>
     *
     * @method delay
     * @param {Number} delay Delay in milliseconds.
     * @param {function} newFn Callback.
     * @param {Object} newScope Context object. Optional.
     * @param newArgs 0..n additional arguments that should be provided to the listener.
     */
    delay: function(delay, newFn, newScope, newArgs) {
        var instance = this;

        if (instance._id && instance._delay != delay) {
            instance.cancel();
        }

        instance._delay = delay || instance._delay;
        instance._time = instance._getTime();

        instance._fn = newFn || instance._fn;
        instance._scope = newScope || instance._scope;
        instance._args = newArgs || instance._args;

        if (!A.Lang.isArray(instance._args)) {
            instance._args = [instance._args];
        }

        if (!instance._id) {
            if (instance._delay > 0) {
                instance._id = setInterval(instance._base, instance._delay);
            }
            else {
                instance._base();
            }
        }
    },

    /**
     * Cancel the delayed task in case it's running (i.e., clearInterval from
     * the current running <a href="DelayedTask.html#property__id">_id</a>).
     *
     * @method cancel
     */
    cancel: function() {
        var instance = this;

        if (instance._id) {
            clearInterval(instance._id);

            instance._id = null;
        }
    },

    /**
     * Get the current timestamp (i.e., now).
     *
     * @method _getTime
     * @protected
     * @return {Number} Current timestamp
     */
    _getTime: function() {
        var instance = this;

        return (+new Date());
    }
};

A.DelayedTask = DelayedTask;


}, '3.1.0-deprecated.95', {"requires": ["yui-base"]});

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

/**
 * The Event Base.
 *
 * @module aui-event
 * @submodule aui-event-base
 */

var aArray = A.Array,
    DOMEventFacade = A.DOMEventFacade,
    DOMEventFacadeProto = DOMEventFacade.prototype;

var KeyMap = {
    BACKSPACE: 8,
    TAB: 9,
    NUM_CENTER: 12,

    ENTER: 13,
    RETURN: 13,

    SHIFT: 16,
    CTRL: 17,
    ALT: 18,

    PAUSE: 19,
    CAPS_LOCK: 20,
    ESC: 27,
    SPACE: 32,

    PAGE_UP: 33,
    PAGE_DOWN: 34,

    END: 35,
    HOME: 36,

    LEFT: 37,
    UP: 38,
    RIGHT: 39,
    DOWN: 40,

    PRINT_SCREEN: 44,
    INSERT: 45,
    DELETE: 46,

    ZERO: 48,
    ONE: 49,
    TWO: 50,
    THREE: 51,
    FOUR: 52,
    FIVE: 53,
    SIX: 54,
    SEVEN: 55,
    EIGHT: 56,
    NINE: 57,

    A: 65,
    B: 66,
    C: 67,
    D: 68,
    E: 69,
    F: 70,
    G: 71,
    H: 72,
    I: 73,
    J: 74,
    K: 75,
    L: 76,
    M: 77,
    N: 78,
    O: 79,
    P: 80,
    Q: 81,
    R: 82,
    S: 83,
    T: 84,
    U: 85,
    V: 86,
    W: 87,
    X: 88,
    Y: 89,
    Z: 90,

    CONTEXT_MENU: 93,

    NUM_ZERO: 96,
    NUM_ONE: 97,
    NUM_TWO: 98,
    NUM_THREE: 99,
    NUM_FOUR: 100,
    NUM_FIVE: 101,
    NUM_SIX: 102,
    NUM_SEVEN: 103,
    NUM_EIGHT: 104,
    NUM_NINE: 105,

    NUM_MULTIPLY: 106,
    NUM_PLUS: 107,
    NUM_MINUS: 109,
    NUM_PERIOD: 110,
    NUM_DIVISION: 111,

    F1: 112,
    F2: 113,
    F3: 114,
    F4: 115,
    F5: 116,
    F6: 117,
    F7: 118,
    F8: 119,
    F9: 120,
    F10: 121,
    F11: 122,
    F12: 123,

    NUM_LOCK: 144,

    WIN_KEY: 224,
    WIN_IME: 229,

    NON_MODIFYING_KEYS: [
        'ALT',
        'CAPS_LOCK',
        'CTRL',
        'DOWN',
        'END',
        'ESC',
        'F1',
        'F10',
        'F11',
        'F12',
        'F2',
        'F3',
        'F4',
        'F5',
        'F6',
        'F7',
        'F8',
        'F9',
        'HOME',
        'LEFT',
        'NUM_LOCK',
        'PAGE_DOWN',
        'PAGE_UP',
        'PAUSE',
        'PRINT_SCREEN',
        'RIGHT',
        'SHIFT',
        'SPACE',
        'UP',
        'WIN_KEY'
    ],

    hasModifier: function(event) {
        return event &&
            (event.ctrlKey ||
            event.altKey ||
            event.shiftKey ||
            event.metaKey);
    },

    isKey: function(keyCode, name) {
        var instance = this;

        return name && ((instance[name] || instance[name.toUpperCase()]) === keyCode);
    },

    isKeyInRange: function(keyCode, start, end) {
        var instance = this;

        var result = false;

        if (start && end) {
            var startKey = instance[start] || instance[start.toUpperCase()];
            var endKey = instance[end] || instance[end.toUpperCase()];

            result = startKey && endKey &&
                (keyCode >= startKey && keyCode <= endKey);
        }

        return result;
    },

    isKeyInSet: function(keyCode) {
        var instance = this;

        var args = aArray(arguments, 1, true);

        return instance._isKeyInSet(keyCode, args);
    },

    isNavKey: function(keyCode) {
        var instance = this;

        return instance.isKeyInRange(keyCode, 'PAGE_UP', 'DOWN') || instance.isKeyInSet(keyCode, 'ENTER', 'TAB', 'ESC');
    },

    isSpecialKey: function(keyCode, eventType) {
        var instance = this;

        var isCtrlPress = (eventType === 'keypress' && instance.ctrlKey);

        return isCtrlPress ||
            instance.isNavKey(keyCode) ||
            instance.isKeyInRange(keyCode, 'SHIFT', 'CAPS_LOCK') ||
            instance.isKeyInSet(keyCode, 'BACKSPACE', 'PRINT_SCREEN', 'INSERT', 'WIN_IME');
    },

    isModifyingKey: function(keyCode) {
        var instance = this;

        return !instance._isKeyInSet(keyCode, instance.NON_MODIFYING_KEYS);
    },

    _isKeyInSet: function(keyCode, arr) {
        var instance = this;

        var i = arr.length;

        var result = false;

        var keyName;
        var key;

        while (i--) {
            keyName = arr[i];
            key = keyName && (instance[keyName] || instance[String(keyName).toUpperCase()]);

            if (keyCode === key) {
                result = true;

                break;
            }
        }

        return result;
    }
};

A.mix(
    DOMEventFacadeProto, {
        /**
         * Checks if an event is triggered by a keyboard key like `CTRL`, `ALT`
         * or `SHIFT`.
         *
         * @method hasModifier
         * @return {Boolean}
         */
        hasModifier: function() {
            var instance = this;

            return KeyMap.hasModifier(instance);
        },

        /**
         * Checks if an event is triggered by a keyboard key.
         *
         * @method isKey
         * @param name
         * @return {Boolean}
         */
        isKey: function(name) {
            var instance = this;

            return KeyMap.isKey(instance.keyCode, name);
        },

        /**
         * Checks if an event is triggered by a keyboard key located between two
         * other keys.
         *
         * @method isKeyInRange
         * @param start
         * @param end
         * @return {Boolean}
         */
        isKeyInRange: function(start, end) {
            var instance = this;

            return KeyMap.isKeyInRange(instance.keyCode, start, end);
        },

        /**
         * Checks if an event is triggered by a keyboard key contained in the
         * key set.
         *
         * @method isKeyInSet
         * @return {Boolean}
         */
        isKeyInSet: function() {
            var instance = this;

            var args = aArray(arguments, 0, true);

            return KeyMap._isKeyInSet(instance.keyCode, args);
        },

        /**
         * Checks if an event is triggered by `ENTER`, `TAB`, `ESC` keyboard
         * keys or by a key located between `PAGE UP` and `DOWN`.
         *
         * @method isModifyingKey
         */
        isModifyingKey: function() {
            var instance = this;

            return KeyMap.isModifyingKey(instance.keyCode);
        },

        /**
         * Checks if an event is triggered by navigation keys like `PAGE UP`
         * and `DOWN` keys.
         *
         * @method isNavKey
         * @return {Boolean}
         */
        isNavKey: function() {
            var instance = this;

            return KeyMap.isNavKey(instance.keyCode);
        },

        /**
         * Checks if an event is triggered by a special keyboard key like
         * `SHIFT`, `CAPS LOCK`, etc.
         *
         * @method isSpecialKey
         * @return {Boolean}
         */
        isSpecialKey: function() {
            var instance = this;

            return KeyMap.isSpecialKey(instance.keyCode, instance.type);
        }
    }
);

A.Event.KeyMap = KeyMap;

A.Event.supportsDOMEvent = A.supportsDOMEvent;


}, '3.1.0-deprecated.95', {"requires": ["event-base"]});

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

/**
 * An object that encapsulates text changed events for textareas and input
 * element of type text and password. This event only occurs when the element
 * is focused.
 *
 * @module aui-event
 * @submodule aui-event-input
 */

var DOM_EVENTS = A.Node.DOM_EVENTS;

// Input event feature check should be done on textareas. WebKit before
// version 531 (3.0.182.2) did not support input events for textareas.
// See http://dev.chromium.org/developers/webkit-version-table
if (A.Features.test('event', 'input')) {
    // http://yuilibrary.com/projects/yui3/ticket/2533063
    DOM_EVENTS.input = 1;
    return;
}

DOM_EVENTS.cut = 1;
DOM_EVENTS.dragend = 1;
DOM_EVENTS.paste = 1;

var KeyMap = A.Event.KeyMap,

    _HANDLER_DATA_KEY = '~~aui|input|event~~',
    _INPUT_EVENT_TYPE = ['keydown', 'paste', 'drop', 'cut'],
    _SKIP_FOCUS_CHECK_MAP = {
        cut: 1,
        drop: 1,
        paste: 1
    };

/**
 * Defines a new `input` event in the DOM event system.
 *
 * @event input
 */
A.Event.define('input', {

    /**
     * Implementation logic for event subscription.
     *
     * @method on
     * @param node
     * @param subscription
     * @param notifier
     */
    on: function(node, subscription, notifier) {
        var instance = this;

        subscription._handler = node.on(
            _INPUT_EVENT_TYPE, A.bind(instance._dispatchEvent, instance, subscription, notifier));
    },

    /**
     * Implementation logic for subscription via `node.delegate`.
     *
     * @method delegate
     * @param node
     * @param subscription
     * @param notifier
     * @param filter
     */
    delegate: function(node, subscription, notifier, filter) {
        var instance = this;

        subscription._handles = [];
        subscription._handler = node.delegate('focus', function(event) {
            var element = event.target,
                handler = element.getData(_HANDLER_DATA_KEY);

            if (!handler) {
                handler = element.on(
                    _INPUT_EVENT_TYPE,
                    A.bind(instance._dispatchEvent, instance, subscription, notifier));

                subscription._handles.push(handler);
                element.setData(_HANDLER_DATA_KEY, handler);
            }
        }, filter);
    },

    /**
     * Implementation logic for cleaning up a detached subscription.
     *
     * @method detach
     * @param node
     * @param subscription
     * @param notifier
     */
    detach: function(node, subscription) {
        subscription._handler.detach();
    },

    /**
     * Implementation logic for cleaning up a detached delegate subscription.
     *
     * @method detachDelegate
     * @param node
     * @param subscription
     * @param notifier
     */
    detachDelegate: function(node, subscription) {
        A.Array.each(subscription._handles, function(handle) {
            var element = A.one(handle.evt.el);
            if (element) {
                element.setData(_HANDLER_DATA_KEY, null);
            }
            handle.detach();
        });
        subscription._handler.detach();
    },

    /**
     * Dispatches an `input` event.
     *
     * @method _dispatchEvent
     * @param subscription
     * @param notifier
     * @param event
     * @protected
     */
    _dispatchEvent: function(subscription, notifier, event) {
        var instance = this,
            input,
            valueBeforeKey;

        input = event.target;

        // Since cut, drop and paste events fires before the element is focused,
        // skip focus checking.
        if (_SKIP_FOCUS_CHECK_MAP[event.type] ||
            (input.get('ownerDocument').get('activeElement') === input)) {

            if (KeyMap.isModifyingKey(event.keyCode)) {
                if (subscription._timer) {
                    subscription._timer.cancel();
                    subscription._timer = null;
                }

                valueBeforeKey = KeyMap.isKey(event.keyCode, 'WIN_IME') ? null : input.get('value');

                subscription._timer = A.soon(
                    A.bind('_fireEvent', instance, subscription, notifier, event, valueBeforeKey)
                );
            }
        }
    },

    /**
     * Fires an event.
     *
     * @method _fireEvent
     * @param subscription
     * @param notifier
     * @param event
     * @param valueBeforeKey
     * @protected
     */
    _fireEvent: function(subscription, notifier, event, valueBeforeKey) {
        var input = event.target;

        subscription._timer = null;

        if (input.get('value') !== valueBeforeKey) {
            notifier.fire(event);
        }
    }
});


}, '3.1.0-deprecated.95', {"requires": ["aui-event-base", "event-delegate", "event-synthetic", "timers"]});

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

/**
 * The Form Validator Component
 *
 * @module aui-form-validator
 */

// API inspired on the amazing jQuery Form Validation -
// http://jquery.bassistance.de/validate/

var Lang = A.Lang,
    AObject = A.Object,
    isBoolean = Lang.isBoolean,
    isDate = Lang.isDate,
    isEmpty = AObject.isEmpty,
    isFunction = Lang.isFunction,
    isNode = Lang.isNode,
    isObject = Lang.isObject,
    isString = Lang.isString,
    trim = Lang.trim,

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

    getRegExp = A.DOM._getRegExp,

    getCN = A.getClassName,

    CSS_FORM_GROUP = getCN('form', 'group'),
    CSS_HAS_ERROR = getCN('has', 'error'),
    CSS_ERROR_FIELD = getCN('error', 'field'),
    CSS_HAS_SUCCESS = getCN('has', 'success'),
    CSS_SUCCESS_FIELD = getCN('success', 'field'),
    CSS_HELP_BLOCK = getCN('help', 'block'),
    CSS_STACK = getCN('form-validator', 'stack'),

    TPL_MESSAGE = '<div role="alert"></div>',
    TPL_STACK_ERROR = '<div class="' + [CSS_STACK, CSS_HELP_BLOCK].join(' ') + '"></div>';

if (!Element.prototype.matches) {
    Element.prototype.matches = Element.prototype.msMatchesSelector;
}

A.mix(defaults, {
    STRINGS: {
        DEFAULT: 'Please fix {field}.',
        acceptFiles: 'Please enter a value with a valid extension ({0}) in {field}.',
        alpha: 'Please enter only alpha characters in {field}.',
        alphanum: 'Please enter only alphanumeric characters in {field}.',
        date: 'Please enter a valid date in {field}.',
        digits: 'Please enter only digits in {field}.',
        email: 'Please enter a valid email address in {field}.',
        equalTo: 'Please enter the same value again in {field}.',
        iri: 'Please enter a valid IRI in {field}.',
        max: 'Please enter a value less than or equal to {0} in {field}.',
        maxLength: 'Please enter no more than {0} characters in {field}.',
        min: 'Please enter a value greater than or equal to {0} in {field}.',
        minLength: 'Please enter at least {0} characters in {field}.',
        number: 'Please enter a valid number in {field}.',
        range: 'Please enter a value between {0} and {1} in {field}.',
        rangeLength: 'Please enter a value between {0} and {1} characters long in {field}.',
        required: '{field} is required.',
        url: 'Please enter a valid URL in {field}.'
    },

    REGEX: {
        alpha: /^[a-z_]+$/i,

        alphanum: /^\w+$/,

        digits: /^\d+$/,

        // Regex from Scott Gonzalez Email Address Validation:
        // http://projects.scottsplayground.com/email_address_validation/
        email: new RegExp('^((([a-z]|\\d|[!#\\$%&\'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|' +
            '[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#' +
            '\\$%&\'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF' +
            '\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20' +
            '|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\' +
            'x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])' +
            '|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-' +
            '\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\' +
            'x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\' +
            'uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\' +
            'uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\' +
            'uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\' +
            'uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\' +
            'uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\' +
            'uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\' +
            'u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\' +
            'u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?$', 'i'),

        // Regex from Scott Gonzalez IRI:
        // http://projects.scottsplayground.com/iri/demo/
        iri: new RegExp('^([a-z]([a-z]|\\d|\\+|-|\\.)*):(\\/\\/(((([a-z]|\\d|' +
            '-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[' +
            '\\da-f]{2})|[!\\$&\'\\(\\)\\*\\+,;=]|:)*@)?((\\[(|(v[\\da-f]{1' +
            ',}\\.(([a-z]|\\d|-|\\.|_|~)|[!\\$&\'\\(\\)\\*\\+,;=]|:)+))\\])' +
            '|((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1' +
            '\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d' +
            '|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|' +
            '(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-' +
            '\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\(\\)\\*\\+,;=])*)(:\\d*)?)' +
            '(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\' +
            'uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\(\\)\\*\\+,;=]|:|@)*)' +
            '*|(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\' +
            'uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\(\\)\\*\\+,;=]|:|@)+' +
            '(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\' +
            'uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\(\\)\\*\\+,;=]|:|' +
            '@)*)*)?)|((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\' +
            'uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\(\\)\\*\\' +
            '+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\' +
            'uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\' +
            '(\\)\\*\\+,;=]|:|@)*)*)|((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\' +
            'uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\' +
            '$&\'\\(\\)\\*\\+,;=]|:|@)){0})(\\?((([a-z]|\\d|-|\\.|_|~|' +
            '[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]' +
            '{2})|[!\\$&\'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|' +
            '\\?)*)?(\\#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\' +
            'uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\(\\)\\*\\' +
            '+,;=]|:|@)|\\/|\\?)*)?$', 'i'),

        number: /^[+\-]?(\d+([.,]\d+)?)+([eE][+-]?\d+)?$/,

        // Regex from Scott Gonzalez Common URL:
        // http://projects.scottsplayground.com/iri/demo/common.html
        url: new RegExp('^(https?|ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\' +
            'u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})' +
            '|[!\\$&\'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|' +
            '2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25' +
            '[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.' +
            '(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d' +
            '|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\' +
            'd|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|' +
            '-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*' +
            '([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\' +
            '.)*(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|' +
            '(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]' +
            '|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])' +
            '*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)' +
            '(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\' +
            'uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\(\\)\\*\\+,;=]' +
            '|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF' +
            '\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\(\\)\\*\\+,;=]|:|@)*)' +
            '*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\' +
            'uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\(\\)\\*\\+,;=]|' +
            ':|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(\\#((([a-z]|\\d|-|\\.|_|~|' +
            '[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})' +
            '|[!\\$&\'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$', 'i')
    },

    RULES: {
        acceptFiles: function(val, node, ruleValue) {
            var regex = null;

            if (isString(ruleValue)) {
                var extensions = ruleValue.replace(/\./g, '').split(/,\s*|\b\s*/);

                extensions = A.Array.map(extensions, A.Escape.regex);

                regex = getRegExp('[.](' + extensions.join('|') + ')$', 'i');
            }

            return regex && regex.test(val);
        },

        date: function(val) {
            var date = new Date(val);

            return (isDate(date) && (date !== 'Invalid Date') && !isNaN(date));
        },

        equalTo: function(val, node, ruleValue) {
            var comparator = A.one(ruleValue);

            return comparator && (trim(comparator.val()) === val);
        },

        hasValue: function(val, node) {
            var instance = this;

            if (A.FormValidator.isCheckable(node)) {
                var name = node.get('name'),
                    elements = A.all(instance.getFieldsByName(name));

                return (elements.filter(':checked').size() > 0);
            }
            else {
                return !!val;
            }
        },

        max: function(val, node, ruleValue) {
            return (Lang.toFloat(val) <= ruleValue);
        },

        maxLength: function(val, node, ruleValue) {
            return (val.length <= ruleValue);
        },

        min: function(val, node, ruleValue) {
            return (Lang.toFloat(val) >= ruleValue);
        },

        minLength: function(val, node, ruleValue) {
            return (val.length >= ruleValue);
        },

        range: function(val, node, ruleValue) {
            var num = Lang.toFloat(val);

            return (num >= ruleValue[0]) && (num <= ruleValue[1]);
        },

        rangeLength: function(val, node, ruleValue) {
            var length = val.length;

            return (length >= ruleValue[0]) && (length <= ruleValue[1]);
        },

        required: function(val, node, ruleValue) {
            var instance = this;

            if (ruleValue === true) {
                return defaults.RULES.hasValue.apply(instance, [val, node]);
            }
            else {
                return true;
            }
        }
    }
});

/**
 * A base class for `A.FormValidator`.
 *
 * @class A.FormValidator
 * @extends Base
 * @param {Object} config Object literal specifying widget configuration
 *     properties.
 * @constructor
 * @include http://alloyui.com/examples/form-validator/basic-markup.html
 * @include http://alloyui.com/examples/form-validator/basic.js
 */
var FormValidator = A.Component.create({

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

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

        /**
         * The widget's outermost node, used for sizing and positioning.
         *
         * @attribute boundingBox
         */
        boundingBox: {
            setter: A.one
        },

        /**
         * Container for the CSS error class.
         *
         * @attribute containerErrorClass
         * @type String
         */
        containerErrorClass: {
            value: CSS_HAS_ERROR,
            validator: isString
        },

        /**
         * Container for the CSS valid class.
         *
         * @attribute containerValidClass
         * @type String
         */
        containerValidClass: {
            value: CSS_HAS_SUCCESS,
            validator: isString
        },

        /**
         * Defines the CSS error class.
         *
         * @attribute errorClass
         * @type String
         */
        errorClass: {
            value: CSS_ERROR_FIELD,
            validator: isString
        },

        /**
         * If `true` the validation rules are extracted from the DOM.
         *
         * @attribute extractRules
         * @default true
         * @type Boolean
         */
        extractRules: {
            value: true,
            validator: isBoolean
        },

        /**
         * Container for a field.
         *
         * @attribute fieldContainer
         * @type String
         */
        fieldContainer: {
            value: '.' + CSS_FORM_GROUP
        },

        /**
         * Collection of strings used on a field.
         *
         * @attribute fieldStrings
         * @default {}
         * @type Object
         */
        fieldStrings: {
            value: {},
            validator: isObject
        },

        /**
         * The CSS class for `<label>`.
         *
         * @attribute labelCssClass
         * @default 'control-label'
         * @type String
         */
        labelCssClass: {
            validator: isString,
            value: 'control-label'
        },

        /**
         * Container for the form message.
         *
         * @attribute messageContainer
         * @default '<div role="alert"></div>'
         */
        messageContainer: {
            getter: function(val) {
                return A.Node.create(val).clone();
            },
            value: TPL_MESSAGE
        },

        /**
         * Collection of rules to validate fields.
         *
         * @attribute rules
         * @default {}
         * @type Object
         */
        rules: {
            getter: function(val) {
                var instance = this;
                if (!instance._rulesAlreadyExtracted) {
                    instance._extractRulesFromMarkup(val);
                }
                return val;
            },
            validator: isObject,
            value: {}
        },

        /**
         * Defines if the text will be selected or not after validation.
         *
         * @attribute selectText
         * @default true
         * @type Boolean
         */
        selectText: {
            value: true,
            validator: isBoolean
        },

        /**
         * Defines if the validation messages will be showed or not.
         *
         * @attribute showMessages
         * @default true
         * @type Boolean
         */
        showMessages: {
            value: true,
            validator: isBoolean
        },

        /**
         * Defines if all validation messages will be showed or not.
         *
         * @attribute showAllMessages
         * @default false
         * @type Boolean
         */
        showAllMessages: {
            value: false,
            validator: isBoolean
        },

        /**
         * List of CSS selectors for targets that will not get validated
         *
         * @attribute skipValidationTargetSelectors
         * @default 'a[class=btn-cancel'
         */
        skipValidationTargetSelector: {
            value: 'a[class~=btn-cancel]'
        },

        /**
         * Defines a container for the stack errors.
         *
         * @attribute stackErrorContainer
         */
        stackErrorContainer: {
            getter: function(val) {
                return A.Node.create(val).clone();
            },
            value: TPL_STACK_ERROR
        },

        /**
         * Collection of strings used to label elements of the UI.
         *
         * @attribute strings
         * @type Object
         */
        strings: {
            valueFn: function() {
                return defaults.STRINGS;
            }
        },

        /**
         * If `true` the field will be validated on blur event.
         *
         * @attribute validateOnBlur
         * @default true
         * @type Boolean
         */
        validateOnBlur: {
            value: true,
            validator: isBoolean
        },

        /**
         * If `true` the field will be validated on input event.
         *
         * @attribute validateOnInput
         * @default false
         * @type Boolean
         */
        validateOnInput: {
            value: false,
            validator: isBoolean
        },

        /**
         * Defines the CSS valid class.
         *
         * @attribute validClass
         * @type String
         */
        validClass: {
            value: CSS_SUCCESS_FIELD,
            validator: isString
        }
    },

    /**
     * Creates custom rules from user input.
     *
     * @method _setCustomRules
     * @param object
     * @protected
     */
    _setCustomRules: function(object) {
        A.each(
            object,
            function(rule, fieldName) {
                A.config.FormValidator.RULES[fieldName] = rule.condition;
                A.config.FormValidator.STRINGS[fieldName] = rule.errorMessage;
            }
        );
    },

    /**
     * Ability to add custom validation rules.
     *
     * @method customRules
     * @param object
     * @public
     * @static
     */
    addCustomRules: function(object) {
        var instance = this;

        if (isObject(object)) {
            instance._setCustomRules(object);
        }
    },

    /**
     * Checks if a node is a checkbox or radio input.
     *
     * @method isCheckable
     * @param node
     * @private
     * @return {Boolean}
     */
    isCheckable: function(node) {
        var nodeType = node.get('type').toLowerCase();

        return (nodeType === 'checkbox' || nodeType === 'radio');
    },

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

    prototype: {

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

            instance.errors = {};
            instance._blurHandlers = null;
            instance._fileBlurHandlers = null;
            instance._fileInputHandlers = null;
            instance._inputHandlers = null;
            instance._rulesAlreadyExtracted = false;
            instance._stackErrorContainers = {};

            instance.bindUI();
            instance._uiSetValidateOnBlur(instance.get('validateOnBlur'));
            instance._uiSetValidateOnInput(instance.get('validateOnInput'));
        },

        /**
         * Bind the events on the `A.FormValidator` UI. Lifecycle.
         *
         * @method bindUI
         * @protected
         */
        bindUI: function() {
            var instance = this,
                boundingBox = instance.get('boundingBox');

            var onceFocusHandler = boundingBox.delegate('focus', function() {
                instance._setARIARoles();
                onceFocusHandler.detach();
            }, 'input,select,textarea,button');

            instance.publish({
                errorField: {
                    defaultFn: instance._defErrorFieldFn
                },
                validField: {
                    defaultFn: instance._defValidFieldFn
                },
                validateField: {
                    defaultFn: instance._defValidateFieldFn
                }
            });

            boundingBox.on({
                reset: A.bind(instance._onFormReset, instance),
                submit: A.bind(instance._onFormSubmit, instance)
            });

            instance.after({
                extractRulesChange: instance._afterExtractRulesChange,
                validateOnBlurChange: instance._afterValidateOnBlurChange,
                validateOnInputChange: instance._afterValidateOnInputChange
            });
        },

        /**
         * Adds a validation error in the field.
         *
         * @method addFieldError
         * @param {Node} field
         * @param ruleName
         */
        addFieldError: function(field, ruleName) {
            var instance = this,
                errors = instance.errors,
                name = field.get('name');

            if (!errors[name]) {
                errors[name] = [];
            }

            errors[name].push(ruleName);
        },

        /**
         * Deletes the field from the errors property object.
         *
         * @method clearFieldError
         * @param {Node|String} field
         */
        clearFieldError: function(field) {
            var fieldName = isNode(field) ? field.get('name') : field;

            if (isString(fieldName)) {
                delete this.errors[fieldName];
            }
        },

        /**
         * Executes a function to each rule.
         *
         * @method eachRule
         * @param fn
         */
        eachRule: function(fn) {
            var instance = this;

            A.each(
                instance.get('rules'),
                function(rule, fieldName) {
                    if (isFunction(fn)) {
                        fn.apply(instance, [rule, fieldName]);
                    }
                }
            );
        },

        /**
         * Gets the ancestor of a given field.
         *
         * @method findFieldContainer
         * @param {Node} field
         * @return {Node}
         */
        findFieldContainer: function(field) {
            var instance = this,
                fieldContainer = instance.get('fieldContainer'),
                retVal = field.ancestor();

            if (fieldContainer && field.ancestor(fieldContainer)) {
                retVal = field.ancestor(fieldContainer);
            }

            return retVal;
        },

        /**
         * Focus on the invalid field.
         *
         * @method focusInvalidField
         */
        focusInvalidField: function() {
            var instance = this,
                boundingBox = instance.get('boundingBox'),
                field = boundingBox.one('.' + CSS_ERROR_FIELD);

            if (field) {
                field = instance.findFieldContainer(field);

                if (instance.get('selectText')) {
                    field.selectText();
                }

                field.focus();

                field.scrollIntoView(false);

                window.scrollBy(0, field.getDOM().scrollHeight);
            }
        },

        /**
         * Gets a field from the form.
         *
         * @method getField
         * @param {Node|String} field
         * @return {Node}
         */
        getField: function(field) {
            var instance = this;

            if (isString(field)) {
                field = instance.getFieldsByName(field);

                if (field && field.length && !field.name) {
                    field = field[0];
                }
            }

            return A.one(field);
        },

        /**
         * Gets a list of fields based on its name.
         *
         * @method getFieldsByName
         * @param fieldName
         * @return {NodeList}
         */
        getFieldsByName: function(fieldName) {
            var instance = this,
                domBoundingBox = instance.get('boundingBox').getDOM();

            return domBoundingBox.elements[fieldName];
        },

        /**
         * Gets a list of fields with errors.
         *
         * @method getFieldError
         * @param {Node} field
         * @return {String}
         */
        getFieldError: function(field) {
            var instance = this;

            return instance.errors[field.get('name')];
        },

        /**
         * Gets the stack error container of a field.
         *
         * @method getFieldStackErrorContainer
         * @param {Node|String} field
         * @return {Node}
         */
        getFieldStackErrorContainer: function(field) {
            var instance = this,
                name = isNode(field) ? field.get('name') : field,
                stackContainers = instance._stackErrorContainers;

            if (!stackContainers[name]) {
                stackContainers[name] = instance.get('stackErrorContainer');
            }

            return stackContainers[name];
        },

        /**
         * Gets the error message of a field.
         *
         * @method getFieldErrorMessage
         * @param {Node} field
         * @param rule
         * @return {String}
         */
        getFieldErrorMessage: function(field, rule) {
            var instance = this,
                fieldName = field.get('name'),
                fieldStrings = instance.get('fieldStrings')[fieldName] || {},
                fieldRules = instance.get('rules')[fieldName],
                fieldLabel = instance._findFieldLabel(field),
                strings = instance.get('strings'),
                substituteRulesMap = {};

            if (fieldLabel) {
                substituteRulesMap.field = fieldLabel;
            }

            if (rule in fieldRules) {
                var ruleValue = A.Array(fieldRules[rule]);

                A.each(
                    ruleValue,
                    function(value, index) {
                        substituteRulesMap[index] = [value].join('');
                    }
                );
            }

            var message = (fieldStrings[rule] || strings[rule] || strings.DEFAULT);

            return Lang.sub(message, substituteRulesMap);
        },

        /**
         * Returns `true` if there are errors.
         *
         * @method hasErrors
         * @return {Boolean}
         */
        hasErrors: function() {
            var instance = this;

            return !isEmpty(instance.errors);
        },

        /**
         * Highlights a field with error or success.
         *
         * @method highlight
         * @param {Node} field
         * @param valid
         */
        highlight: function(field, valid) {
            var instance = this,
                fieldContainer,
                fieldName,
                namedFieldNodes;

            if (field) {
                fieldContainer = instance.findFieldContainer(field);

                fieldName = field.get('name');

                if (this.validatable(field)) {
                    namedFieldNodes = A.all(instance.getFieldsByName(fieldName));

                    namedFieldNodes.each(
                        function(node) {
                            instance._highlightHelper(
                                node,
                                instance.get('errorClass'),
                                instance.get('validClass'),
                                valid
                            );
                        }
                    );

                    if (fieldContainer) {
                        instance._highlightHelper(
                            fieldContainer,
                            instance.get('containerErrorClass'),
                            instance.get('containerValidClass'),
                            valid
                        );
                    }
                }
                else if (!field.val()) {
                    instance.resetField(fieldName);
                }
            }
        },

        /**
         * Normalizes rule value.
         *
         * @method normalizeRuleValue
         * @param ruleValue
         * @param {Node} field
         */
        normalizeRuleValue: function(ruleValue, field) {
            var instance = this;

            return isFunction(ruleValue) ? ruleValue.apply(instance, [field]) : ruleValue;
        },

        /**
         * Removes the highlight of a field.
         *
         * @method unhighlight
         * @param {Node} field
         */
        unhighlight: function(field) {
            var instance = this;

            instance.highlight(field, true);
        },

        /**
         * Prints the stack error messages into a container.
         *
         * @method printStackError
         * @param {Node} field
         * @param {Node} container
         * @param {Array} errors
         */
        printStackError: function(field, container, errors) {
            var instance = this;

            if (!instance.get('showAllMessages')) {
                if (A.Array.indexOf(errors, 'required') !== -1) {
                    errors = ['required'];
                }
                else {
                    errors = errors.slice(0, 1);
                }
            }

            container.empty();

            A.Array.each(
                errors,
                function(error) {
                    var message = instance.getFieldErrorMessage(field, error),
                        messageEl = instance.get('messageContainer').addClass(error);

                    container.append(
                        messageEl.html(message)
                    );
                }
            );
        },

        /**
         * Resets the CSS class and content of all fields.
         *
         * @method resetAllFields
         */
        resetAllFields: function() {
            var instance = this;

            instance.eachRule(
                function(rule, fieldName) {
                    instance.resetField(fieldName);
                }
            );
        },

        /**
         * Resets the CSS class and error status of a field.
         *
         * @method resetField
         * @param {Node|String} field
         */
        resetField: function(field) {
            var instance = this,
                fieldName,
                fieldRules,
                namedFieldNodes,
                stackContainer;

            fieldName = isNode(field) ? field.get('name') : field;

            if (fieldName) {
                fieldRules = instance.get('rules')[fieldName];

                if (fieldRules) {
                    instance.clearFieldError(fieldName);

                    stackContainer = instance.getFieldStackErrorContainer(fieldName);

                    stackContainer.remove();

                    namedFieldNodes = A.all(instance.getFieldsByName(fieldName));

                    namedFieldNodes.each(
                        function(node) {
                            instance.resetFieldCss(node);
                            node.removeAttribute('aria-errormessage');
                            node.removeAttribute('aria-invalid');
                        }
                    );
                }
            }
        },

        /**
         * Removes the CSS classes of a field.
         *
         * @method resetFieldCss
         * @param {Node} field
         */
        resetFieldCss: function(field) {
            var instance = this,
                fieldContainer = instance.findFieldContainer(field);

            var removeClasses = function(elem, classAttrs) {
                if (elem) {
                    A.each(classAttrs, function(attrName) {
                        elem.removeClass(
                            instance.get(attrName)
                        );
                    });
                }
            };

            removeClasses(field, ['validClass', 'errorClass']);
            removeClasses(fieldContainer, ['containerValidClass', 'containerErrorClass']);
        },

        /**
         * Checks if a field can be validated or not.
         *
         * @method validatable
         * @param {Node} field
         * @return {Boolean}
         */
        validatable: function(field) {
            var instance = this,
                validatable = false,
                fieldRules = instance.get('rules')[field.get('name')];

            if (fieldRules) {
                validatable = instance.normalizeRuleValue(fieldRules.required, field) ||
                    defaults.RULES.hasValue.apply(instance, [field.val(), field]);
            }

            return !!validatable;
        },

        /**
         * Validates all fields.
         *
         * @method validate
         */
        validate: function() {
            var instance = this;

            instance.eachRule(
                function(rule, fieldName) {
                    instance.validateField(fieldName);
                }
            );

            instance.focusInvalidField();
        },

        /**
         * Validates a single field.
         *
         * @method validateField
         * @param {Node|String} field
         */
        validateField: function(field) {
            var fieldNode,
                validatable;

            this.resetField(field);
            fieldNode = isString(field) ? this.getField(field) : field;

            if (isNode(fieldNode)) {
                validatable = this.validatable(fieldNode);

                if (validatable) {
                    this.fire('validateField', {
                        validator: {
                            field: fieldNode
                        }
                    });
                }
            }
        },

        /**
         * Fires after `extractRules` attribute change.
         *
         * @method _afterExtractRulesChange
         * @param event
         * @protected
         */
        _afterExtractRulesChange: function(event) {
            var instance = this;

            instance._uiSetExtractRules(event.newVal);
        },

        /**
         * Fires after `validateOnBlur` attribute change.
         *
         * @method _afterValidateOnBlurChange
         * @param event
         * @protected
         */
        _afterValidateOnBlurChange: function(event) {
            var instance = this;

            instance._uiSetValidateOnBlur(event.newVal);
        },

        /**
         * Fires after `validateOnInput` attribute change.
         *
         * @method _afterValidateOnInputChange
         * @param event
         * @protected
         */
        _afterValidateOnInputChange: function(event) {
            var instance = this;

            instance._uiSetValidateOnInput(event.newVal);
        },

        /**
         * Defines an error field.
         *
         * @method _defErrorFieldFn
         * @param event
         * @protected
         */
        _defErrorFieldFn: function(event) {
            var instance = this,
                field,
                label,
                stackContainer,
                target,
                validator;

            label = instance.get('labelCssClass');
            validator = event.validator;
            field = validator.field;

            instance.highlight(field);

            if (instance.get('showMessages')) {
                target = field;

                stackContainer = instance.getFieldStackErrorContainer(field);

                if (A.FormValidator.isCheckable(target)) {
                    target = field.ancestor('.' + CSS_HAS_ERROR).get('lastChild');
                }

                var id = field.get('id') + 'Helper';

                stackContainer.set('id', id);

                target.placeAfter(stackContainer);

                instance.printStackError(
                    field,
                    stackContainer,
                    validator.errors
                );
            }
        },

        /**
         * Defines a valid field.
         *
         * @method _defValidFieldFn
         * @param event
         * @protected
         */
        _defValidFieldFn: function(event) {
            var instance = this;

            var field = event.validator.field;

            instance.unhighlight(field);
        },

        /**
         * Defines the validation of a field.
         *
         * @method _defValidateFieldFn
         * @param event
         * @protected
         */
        _defValidateFieldFn: function(event) {
            var instance = this;

            var field = event.validator.field;
            var fieldRules = instance.get('rules')[field.get('name')];

            A.each(
                fieldRules,
                function(ruleValue, ruleName) {
                    var rule = defaults.RULES[ruleName];
                    var fieldValue = trim(field.val());

                    ruleValue = instance.normalizeRuleValue(ruleValue, field);

                    if (isFunction(rule) && !rule.apply(instance, [fieldValue, field, ruleValue])) {

                        instance.addFieldError(field, ruleName);
                    }
                }
            );

            var fieldErrors = instance.getFieldError(field);

            if (fieldErrors) {
                instance.fire('errorField', {
                    validator: {
                        field: field,
                        errors: fieldErrors
                    }
                });
            }
            else {
                instance.fire('validField', {
                    validator: {
                        field: field
                    }
                });
            }
        },

        /**
         * Finds the label text of a field if existing.
         *
         * @method _findFieldLabel
         * @param {Node} field
         * @return {String}
         */
        _findFieldLabel: function(field) {
            var labelCssClass = '.' + this.get('labelCssClass'),
                label = A.one('label[for=' + field.get('id') + ']') ||
                    field.ancestor().previous(labelCssClass);

            if (!label) {
                label = field.ancestor('.' + CSS_HAS_ERROR);

                if (label) {
                    label = label.one(labelCssClass);
                }
            }

            if (label) {
                return label.get('text');
            }
        },

        /**
         * Sets the error/success CSS classes based on the validation of a
         * field.
         *
         * @method _highlightHelper
         * @param {Node} field
         * @param {String} errorClass
         * @param {String} validClass
         * @param {Boolean} valid
         * @protected
         */
        _highlightHelper: function(field, errorClass, validClass, valid) {
            var instance = this;

            if (valid) {
                field.removeClass(errorClass).addClass(validClass);

                if (validClass === CSS_SUCCESS_FIELD) {
                    field.removeAttribute('aria-errormessage');
                    field.removeAttribute('aria-invalid');
                }
            }
            else {
                field.removeClass(validClass).addClass(errorClass);

                if (errorClass === CSS_ERROR_FIELD) {
                    field.set('aria-errormessage', field.get('id') + 'Helper');
                    field.set('aria-invalid', true);
                }
            }
        },

        /**
         * Extracts form rules from the DOM.
         *
         * @method _extractRulesFromMarkup
         * @param rules
         * @protected
         */
        _extractRulesFromMarkup: function(rules) {
            var instance = this,
                domBoundingBox = instance.get('boundingBox').getDOM(),
                elements = domBoundingBox.elements,
                defaultRulesKeys = AObject.keys(defaults.RULES),
                defaultRulesJoin = defaultRulesKeys.join('|'),
                regex = getRegExp('field-(' + defaultRulesJoin + ')', 'g'),
                i,
                length,
                ruleNameMatch = [],
                ruleMatcher = function(m1, m2) {
                    ruleNameMatch.push(m2);
                };

            for (i = 0, length = elements.length; i < length; i++) {
                var el = elements[i],
                    fieldName = el.name;

                el.className.replace(regex, ruleMatcher);

                if (ruleNameMatch.length) {
                    var fieldRules = rules[fieldName],
                        j,
                        ruleNameLength;

                    if (!fieldRules) {
                        fieldRules = {};
                        rules[fieldName] = fieldRules;
                    }
                    for (j = 0, ruleNameLength = ruleNameMatch.length; j < ruleNameLength; j++) {
                        var rule = ruleNameMatch[j];

                        if (!(rule in fieldRules)) {
                            fieldRules[rule] = true;
                        }
                    }
                    ruleNameMatch.length = 0;
                }
            }

            instance._rulesAlreadyExtracted = true;
        },

        /**
         * Triggers when there's an input in the field.
         *
         * @method _onFieldInput
         * @param event
         * @protected
         */
        _onFieldInput: function(event) {
            var instance = this;

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

            if (!event.relatedTarget || !event.relatedTarget.getDOMNode().matches(skipValidationTargetSelector)) {
                setTimeout(
                    function() {
                        instance.validateField(event.target);
                    },
                    300
                );
            }
        },

        /**
         * Triggers when the form is submitted.
         *
         * @method _onFormSubmit
         * @param event
         * @protected
         */
        _onFormSubmit: function(event) {
            var instance = this;

            var data = {
                validator: {
                    formEvent: event
                }
            };

            instance.validate();

            if (instance.hasErrors()) {
                data.validator.errors = instance.errors;

                instance.fire('submitError', data);

                event.halt();
            }
            else {
                instance.fire('submit', data);
            }
        },

        /**
         * Triggers when the form is reseted.
         *
         * @method _onFormReset
         * @param event
         * @protected
         */
        _onFormReset: function() {
            var instance = this;

            instance.resetAllFields();
        },

        /**
         * Sets the aria roles.
         *
         * @method _setARIARoles
         * @protected
         */
        _setARIARoles: function() {
            var instance = this;

            instance.eachRule(
                function(rule, fieldName) {
                    var field = instance.getField(fieldName);

                    var required = instance.normalizeRuleValue(rule.required, field);

                    if (required) {
                        if (field && !field.attr('aria-required')) {
                            field.attr('aria-required', true);
                        }
                    }
                }
            );
        },

        /**
         * Sets the `extractRules` attribute on the UI.
         *
         * @method _uiSetExtractRules
         * @param val
         * @protected
         */
        _uiSetExtractRules: function(val) {
            var instance = this;
            if (val) {
                instance._extractRulesFromMarkup(instance.get('rules'));
            }
        },

        /**
         * Sets the `validateOnInput` attribute on the UI.
         *
         * @method _uiSetValidateOnInput
         * @param val
         * @protected
         */
        _uiSetValidateOnInput: function(val) {
            var instance = this,
                boundingBox = instance.get('boundingBox');

            if (val) {
                if (!instance._inputHandlers) {
                    instance._inputHandlers = boundingBox.delegate('input', instance._onFieldInput,
                        'input:not([type="file"]),select,textarea,button', instance);
                }

                if (!instance._fileInputHandlers) {
                    instance._fileInputHandlers = boundingBox.delegate('change', instance._onFieldInput,
                        'input[type="file"]', instance);
                }
            }
            else {
                if (instance._inputHandlers) {
                    instance._inputHandlers.detach();
                }

                if (instance._fileInputHandlers) {
                    instance._fileInputHandlers.detach();
                }
            }
        },

        /**
         * Sets the `validateOnBlur` attribute on the UI.
         *
         * @method _uiSetValidateOnBlur
         * @param val
         * @protected
         */
        _uiSetValidateOnBlur: function(val) {
            var instance = this,
                boundingBox = instance.get('boundingBox');

            if (val) {
                if (!instance._blurHandlers) {
                    instance._blurHandlers = boundingBox.delegate('blur', instance._onFieldInput,
                        'input:not([type="file"]),select,textarea,button', instance);
                }

                if (!instance._fileBlurHandlers) {
                    instance._fileBlurHandlers = boundingBox.delegate('change', instance._onFieldInput,
                        'input[type="file"]', instance);
                }
            }
            else {
                if (instance._blurHandlers) {
                    instance._blurHandlers.detach();
                }

                if (instance._fileBlurHandlers) {
                    instance._fileBlurHandlers.detach();
                }
            }
        }
    }
});

A.each(
    defaults.REGEX,
    function(regex, key) {
        defaults.RULES[key] = function(val) {
            return defaults.REGEX[key].test(val);
        };
    }
);

A.FormValidator = FormValidator;

}, '3.1.0-deprecated.95', {
    "requires": [
        "escape",
        "selector-css3",
        "node-event-delegate",
        "aui-node",
        "aui-component",
        "aui-event-input"
    ]
});

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

/**
 * A set of utility methods to the Node.
 *
 * @module aui-node
 * @submodule aui-node-base
 */

var Lang = A.Lang,
    isArray = Lang.isArray,
    isFunction = Lang.isFunction,
    isObject = Lang.isObject,
    isString = Lang.isString,
    isUndefined = Lang.isUndefined,
    isValue = Lang.isValue,

    AArray = A.Array,
    ANode = A.Node,
    ANodeList = A.NodeList,

    getClassName = A.getClassName,
    getRegExp = A.DOM._getRegExp,

    CONFIG = A.config,
    DOC = CONFIG.doc,
    WIN = CONFIG.win,

    NODE_PROTO = ANode.prototype,
    NODE_PROTO_HIDE = NODE_PROTO._hide,
    NODE_PROTO_SHOW = NODE_PROTO._show,
    NODELIST_PROTO = ANodeList.prototype,

    ARRAY_EMPTY_STRINGS = ['', ''],

    CSS_HIDE = getClassName('hide'),
    CSS_UNSELECTABLE_VALUE = 'none',
    CSS_SELECTABLE_VALUE = 'text',

    SUPPORT_CLONED_EVENTS = false,

    MAP_BORDER = {
        b: 'borderBottomWidth',
        l: 'borderLeftWidth',
        r: 'borderRightWidth',
        t: 'borderTopWidth'
    },
    MAP_MARGIN = {
        b: 'marginBottom',
        l: 'marginLeft',
        r: 'marginRight',
        t: 'marginTop'
    },
    MAP_PADDING = {
        b: 'paddingBottom',
        l: 'paddingLeft',
        r: 'paddingRight',
        t: 'paddingTop'
    };

/* Parts of this file are used from jQuery (http://jquery.com)
 * Dual-licensed under MIT/GPL
 */
var div = DOC.createElement('div');

div.style.display = 'none';
div.innerHTML = '   <table></table>&nbsp;';

if (div.attachEvent && div.fireEvent) {
    div.attachEvent(
        'onclick',
        function detach() {
            SUPPORT_CLONED_EVENTS = true;

            div.detachEvent('onclick', detach);
        }
    );

    div.cloneNode(true).fireEvent('onclick');
}

var SUPPORT_OPTIONAL_TBODY = !div.getElementsByTagName('tbody').length;

var REGEX_LEADING_WHITE_SPACE = /^\s+/,
    REGEX_IE8_ACTION = /\=([^=\x27\x22>\s]+\/)>/g,
    REGEX_TAGNAME = /<([\w:]+)/;

div = null;

var _setUnselectable = function(element, unselectable, noRecurse) {
    var descendants,
        value = unselectable ? 'on' : '',
        i,
        descendant;

    element.setAttribute('unselectable', value);

    if (!noRecurse) {
        descendants = element.getElementsByTagName('*');

        for (i = 0;
            (descendant = descendants[i]); i++) {
            descendant.setAttribute('unselectable', value);
        }
    }
};

/**
 * Augments the [YUI3 Node](Node.html) with more util methods.
 *
 * Check the [live demo](http://alloyui.com/examples/node/).
 *
 * @class A.Node
 * @uses Node
 * @constructor
 * @include http://alloyui.com/examples/node/basic-markup.html
 * @include http://alloyui.com/examples/node/basic.js
 */
A.mix(NODE_PROTO, {

    /**
     * Returns the current ancestors of the node element filtered by a
     * className. This is an optimized method for finding ancestors by a
     * specific CSS class name.
     *
     * Example:
     *
     * ```
     * A.one('#nodeId').ancestorsByClassName('aui-hide');
     * ```
     *
     * @method ancestorsByClassName
     * @param {String} className A selector to filter the ancestor elements
     *     against.
     * @param {Boolean} testSelf optional Whether or not to include the element
     * in the scan
     * @return {NodeList}
     */
    ancestorsByClassName: function(className, testSelf) {
        var instance = this;

        var ancestors = [];
        var cssRE = new RegExp('\\b' + className + '\\b');
        var currentEl = instance.getDOM();

        if (!testSelf) {
            currentEl = currentEl.parentNode;
        }

        while (currentEl && currentEl.nodeType !== 9) {
            if (currentEl.nodeType === 1 && cssRE.test(currentEl.className)) {
                ancestors.push(currentEl);
            }

            currentEl = currentEl.parentNode;
        }

        return A.all(ancestors);
    },

    /**
     * Gets or sets the value of an attribute for the first element in the set
     * of matched elements. If only the `name` is passed it works as a getter.
     *
     * Example:
     *
     * ```
     * var node = A.one('#nodeId');
     * node.attr('title', 'Setting a new title attribute');
     * // Alert the value of the title attribute: 'Setting a new title attribute'
     * alert( node.attr('title') );
     * ```
     *
     * @method attr
     * @param {String} name The name of the attribute
     * @param {String} value The value of the attribute to be set. Optional.
     * @return {String}
     */
    attr: function(name, value) {
        var instance = this,
            i;

        if (!isUndefined(value)) {
            var el = instance.getDOM();

            if (name in el) {
                instance.set(name, value);
            }
            else {
                instance.setAttribute(name, value);
            }

            return instance;
        }
        else {
            if (isObject(name)) {
                for (i in name) {
                    if (name.hasOwnProperty(i)) {
                        instance.attr(i, name[i]);
                    }
                }

                return instance;
            }

            var currentValue = instance.get(name);

            if (!Lang.isValue(currentValue)) {
                currentValue = instance.getAttribute(name);
            }

            return currentValue;
        }
    },

    /**
     * Normalizes the behavior of cloning a node, which by default should not
     * clone the events that are attached to it.
     *
     * Example:
     *
     * ```
     * var node = A.one('#nodeId');
     * node.clone().appendTo('body');
     * ```
     *
     * @method clone
     * @return {Node}
     */
    clone: (function() {
        var clone;

        if (SUPPORT_CLONED_EVENTS) {
            clone = function() {
                var el = this.getDOM();
                var clone;

                if (el.nodeType !== 3) {
                    var outerHTML = this.outerHTML();

                    outerHTML = outerHTML.replace(REGEX_IE8_ACTION, '="$1">').replace(REGEX_LEADING_WHITE_SPACE,
                        '');

                    clone = ANode.create(outerHTML);
                }
                else {
                    clone = A.one(el.cloneNode());
                }

                return clone;
            };
        }
        else {
            clone = function() {
                return this.cloneNode(true);
            };
        }

        return clone;
    }()),

    /**
     * Centralizes the current Node instance with the passed `val` Array, Node,
     * String, or Region, if not specified, the body will be used.
     *
     * Example:
     *
     * ```
     * var node = A.one('#nodeId');
     * // Center the `node` with the `#container`.
     * node.center('#container');
     * ```
     *
     * @method center
     * @chainable
     * @param {Array|Node|Region|String} val Array, Node, String, or Region to
     *     center with.
     */
    center: function(val) {
        var instance = this,
            nodeRegion = instance.get('region'),
            x,
            y;

        if (isArray(val)) {
            x = val[0];
            y = val[1];
        }
        else {
            var region;

            if (isObject(val) && !A.instanceOf(val, ANode)) {
                region = val;
            }
            else {
                region = (A.one(val) || A.getBody()).get('region');
            }

            x = region.left + (region.width / 2);
            y = region.top + (region.height / 2);
        }

        instance.setXY([x - (nodeRegion.width / 2), y - (nodeRegion.height / 2)]);
    },

    /**
     * Removes not only child (and other descendant) elements, but also any text
     * within the set of matched elements. This is because, according to the DOM
     * specification, any string of text within an element is considered a child
     * node of that element.
     *
     * Example:
     *
     * ```
     * var node = A.one('#nodeId');
     * node.empty();
     * ```
     *
     * @method empty
     * @chainable
     */
    empty: function() {
        var instance = this;

        instance.all('>*').remove().purge();

        var el = ANode.getDOMNode(instance);

        while (el.firstChild) {
            el.removeChild(el.firstChild);
        }

        return instance;
    },

    /**
     * Retrieves the DOM node bound to a Node instance. See
     * [getDOMNode](Node.html#method_getDOMNode).
     *
     * @method getDOM
     * @return {HTMLNode} The DOM node bound to the Node instance.
     */
    getDOM: function() {
        var instance = this;

        return ANode.getDOMNode(instance);
    },

    /**
     * Returns the combined width of the border for the specified sides.
     *
     * @method getBorderWidth
     * @param {String} sides Can be t, r, b, l or any combination of those to
     *     represent the top, right, bottom, or left sides.
     * @return {Number}
     */
    getBorderWidth: function(sides) {
        var instance = this;

        return instance._getBoxStyleAsNumber(sides, MAP_BORDER);
    },

    /**
     * Gets the current center position of the node in page coordinates.
     *
     * @method getCenterXY
     * @for Node
     * @return {Array} The XY position of the node
     */
    getCenterXY: function() {
        var instance = this;
        var region = instance.get('region');

        return [(region.left + region.width / 2), (region.top + region.height / 2)];
    },

    /**
     * Returns the combined size of the margin for the specified sides.
     *
     * @method getMargin
     * @param {String} sides Can be t, r, b, l or any combination of those to
     *     represent the top, right, bottom, or left sides.
     * @return {Number}
     */
    getMargin: function(sides) {
        var instance = this;

        return instance._getBoxStyleAsNumber(sides, MAP_MARGIN);
    },

    /**
     * Returns the combined width of the border for the specified sides.
     *
     * @method getPadding
     * @param {String} sides Can be t, r, b, l or any combination of those to
     *     represent the top, right, bottom, or left sides.
     * @return {Number}
     */
    getPadding: function(sides) {
        var instance = this;

        return instance._getBoxStyleAsNumber(sides, MAP_PADDING);
    },

    /**
     * Sets the id of the Node instance if the object does not have one. The
     * generated id is based on a guid created by the
     * [stamp](YUI.html#method_stamp) method.
     *
     * @method guid
     * @return {String} The current id of the node
     */
    guid: function() {
        var instance = this;
        var currentId = instance.get('id');

        if (!currentId) {
            currentId = A.stamp(instance);

            instance.set('id', currentId);
        }

        return currentId;
    },

    /**
     * Creates a hover interaction.
     *
     * @method hover
     * @param {String} overFn
     * @param {String} outFn
     * @return {Node} The current Node instance
     */
    hover: function(overFn, outFn) {
        var instance = this;

        var hoverOptions;
        var defaultHoverOptions = instance._defaultHoverOptions;

        if (isObject(overFn, true)) {
            hoverOptions = overFn;

            hoverOptions = A.mix(hoverOptions, defaultHoverOptions);

            overFn = hoverOptions.over;
            outFn = hoverOptions.out;
        }
        else {
            hoverOptions = A.mix({
                    over: overFn,
                    out: outFn
                },
                defaultHoverOptions
            );
        }

        instance._hoverOptions = hoverOptions;

        hoverOptions.overTask = A.debounce(instance._hoverOverTaskFn, null, instance);
        hoverOptions.outTask = A.debounce(instance._hoverOutTaskFn, null, instance);

        return new A.EventHandle(
   [
    instance.on(hoverOptions.overEventType, instance._hoverOverHandler, instance),
    instance.on(hoverOptions.outEventType, instance._hoverOutHandler, instance)
   ]
        );
    },

    /**
     * Gets or sets the HTML contents of the node. If the `value` is passed it's
     * set the content of the element, otherwise it works as a getter for the
     * current content.
     *
     * Example:
     *
     * ```
     * var node = A.one('#nodeId');
     * node.html('Setting new HTML');
     * // Alert the value of the current content
     * alert( node.html() );
     * ```
     *
     * @method html
     * @param {String} value A string of html to set as the content of the node
     *     instance.
     */
    html: function() {
        var args = arguments,
            length = args.length;

        if (length) {
            this.set('innerHTML', args[0]);
        }
        else {
            return this.get('innerHTML');
        }

        return this;
    },

    /**
     * Gets the outerHTML of a node, which islike innerHTML, except that it
     * actually contains the HTML of the node itself.
     *
     * @method outerHTML
     * @return {string} The outerHTML of the given element.
     */
    outerHTML: function() {
        var instance = this;
        var domEl = instance.getDOM();

        // IE, Opera and WebKit all have outerHTML.
        if ('outerHTML' in domEl) {
            return domEl.outerHTML;
        }

        var temp = ANode.create('<div></div>').append(
            this.clone()
        );

        try {
            return temp.html();
        }
        catch (e) {}
        finally {
            temp = null;
        }
    },

    /**
     * Inserts a `newNode` after the node instance (i.e., as the next sibling).
     * If the reference node has no parent, then does nothing.
     *
     * Example:
     *
     * ```
     * var titleNode = A.one('#titleNode');
     * var descriptionNode = A.one('#descriptionNode');
     * // the description is usually shown after the title
     * titleNode.placeAfter(descriptionNode);
     * ```
     *
     * @method placeAfter
     * @chainable
     * @param {Node} newNode Node to insert.
     */
    placeAfter: function(newNode) {
        var instance = this;

        return instance._place(newNode, instance.get('nextSibling'));
    },

    /**
     * Inserts a `newNode` before the node instance (i.e., as the previous
     * sibling). If the reference node has no parent, then does nothing.
     *
     * Example:
     *
     * ```
     * var descriptionNode = A.one('#descriptionNode');
     * var titleNode = A.one('#titleNode');
     * // the title is usually shown before the description
     * descriptionNode.placeBefore(titleNode);
     * ```
     *
     * @method placeBefore
     * @chainable
     * @param {Node} newNode Node to insert.
     */
    placeBefore: function(newNode) {
        var instance = this;

        return instance._place(newNode, instance);
    },

    /**
     * Inserts the node instance to the begining of the `selector` node (i.e.,
     * insert before the `firstChild` of the `selector`).
     *
     * Example:
     *
     * ```
     * var node = A.one('#nodeId');
     * node.prependTo('body');
     * ```
     *
     * @method prependTo
     * @chainable
     * @param {Node|String} selector A selector, element, HTML string, Node
     */
    prependTo: function(selector) {
        var instance = this;

        A.one(selector).prepend(instance);

        return instance;
    },

    /**
     * Adds one or more CSS classes to an element and remove the class(es) from
     * the siblings of the element.
     *
     * @method radioClass
     * @chainable
     * @param {String} cssClass
     */
    radioClass: function(cssClass) {
        var instance = this;

        var siblings = instance.siblings();

        if (isString(cssClass)) {
            siblings.removeClass(cssClass);

            instance.addClass(cssClass);
        }
        else if (isArray(cssClass)) {
            var siblingNodes = siblings.getDOM();

            var regex = getRegExp('(?:^|\\s+)(?:' + cssClass.join('|') + ')(?=\\s+|$)', 'g'),
                node,
                i;

            for (i = siblingNodes.length - 1; i >= 0; i--) {
                node = siblingNodes[i];
                node.className = node.className.replace(regex, '');
            }

            instance.addClass(cssClass.join(' '));
        }

        return instance;
    },

    /**
     * Generates an unique identifier and reset the id attribute of the node
     * instance using the new value. Invokes the [guid](Node.html#method_guid).
     *
     * @method resetId
     * @chainable
     * @param {String} prefix Optional prefix for the guid.
     */
    resetId: function(prefix) {
        var instance = this;

        instance.attr('id', A.guid(prefix));

        return instance;
    },

    /**
     * Selects a substring of text inside of the input element.
     *
     * @method selectText
     * @param {Number} start The index to start the selection range from
     * @param {Number} end The index to end the selection range at
     */
    selectText: function(start, end) {
        var instance = this;

        var textField = instance.getDOM();
        var length = instance.val().length;

        end = isValue(end) ? end : length;
        start = isValue(start) ? start : 0;

        // Some form elements could throw a (NS_ERROR_FAILURE)
        // [nsIDOMNSHTMLInputElement.setSelectionRange] error when invoke the
        // setSelectionRange on firefox. Wrapping in a try/catch to prevent the
        // error be thrown
        try {
            if (textField.setSelectionRange) {
                textField.setSelectionRange(start, end);
            }
            else if (textField.createTextRange) {
                var range = textField.createTextRange();

                range.moveStart('character', start);
                range.moveEnd('character', end - length);

                range.select();
            }
            else {
                textField.select();
            }

            if (textField !== DOC.activeElement) {
                textField.focus();
            }
        }
        catch (e) {}

        return instance;
    },

    /**
     * Enables text selection for this element (normalized across browsers).
     *
     * @method selectable
     * @param noRecurse
     * @chainable
     */
    selectable: function(noRecurse) {
        var instance = this;

        instance.setStyles({
            '-webkit-user-select': CSS_SELECTABLE_VALUE,
            '-khtml-user-select': CSS_SELECTABLE_VALUE,
            '-moz-user-select': CSS_SELECTABLE_VALUE,
            '-ms-user-select': CSS_SELECTABLE_VALUE,
            '-o-user-select': CSS_SELECTABLE_VALUE,
            'user-select': CSS_SELECTABLE_VALUE
        });

        if (A.UA.ie || A.UA.opera) {
            _setUnselectable(instance._node, false, noRecurse);
        }

        return instance;
    },

    /**
     * Stops the specified event(s) from bubbling and optionally prevents the
     * default action.
     *
     * Example:
     *
     * ```
     * var anchor = A.one('a#anchorId');
     * anchor.swallowEvent('click');
     * ```
     *
     * @method swallowEvent
     * @chainable
     * @param {String|Array} eventName An event or array of events to stop from
     *     bubbling
     * @param {Boolean} preventDefault (optional) true to prevent the default
     *     action too
     */
    swallowEvent: function(eventName, preventDefault) {
        var instance = this;

        var fn = function(event) {
            event.stopPropagation();

            if (preventDefault) {
                event.preventDefault();

                event.halt();
            }

            return false;
        };

        if (isArray(eventName)) {
            AArray.each(
                eventName,
                function(name) {
                    instance.on(name, fn);
                }
            );

            return this;
        }
        else {
            instance.on(eventName, fn);
        }

        return instance;
    },

    /**
     * Gets or sets the combined text contents of the node instance, including
     * it's descendants. If the `text` is passed it's set the content of the
     * element, otherwise it works as a getter for the current content.
     *
     * Example:
     *
     * ```
     * var node = A.one('#nodeId');
     * node.text('Setting new text content');
     * // Alert the value of the current content
     * alert( node.text() );
     * ```
     *
     * @method text
     * @param {String} text A string of text to set as the content of the node
     *     instance.
     */
    text: function(text) {
        var instance = this;
        var el = instance.getDOM();

        if (!isUndefined(text)) {
            text = A.DOM._getDoc(el).createTextNode(text);

            return instance.empty().append(text);
        }

        return instance._getText(el.childNodes);
    },

    /**
     * Displays or hide the node instance.
     *
     * NOTE: This method assume that your node were hidden because of the
     * 'aui-hide' css class were being used. This won't manipulate the inline
     * `style.display` property.
     *
     * @method toggle
     * @chainable
     * @param {Boolean} on Whether to force the toggle. Optional.
     * @param {Function} callback A function to run after the visibility change.
     *     Optional.
     */
    toggle: function() {
        var instance = this;

        instance._toggleView.apply(instance, arguments);

        return instance;
    },

    /**
     * Disables text selection for this element (normalized across browsers).
     *
     * @method unselectable
     * @param noRecurse
     * @chainable
     */
    unselectable: function(noRecurse) {
        var instance = this;

        instance.setStyles({
            '-webkit-user-select': CSS_UNSELECTABLE_VALUE,
            '-khtml-user-select': CSS_UNSELECTABLE_VALUE,
            '-moz-user-select': CSS_UNSELECTABLE_VALUE,
            '-ms-user-select': CSS_UNSELECTABLE_VALUE,
            '-o-user-select': CSS_UNSELECTABLE_VALUE,
            'user-select': CSS_UNSELECTABLE_VALUE
        });

        if (A.UA.ie || A.UA.opera) {
            _setUnselectable(instance._node, true, noRecurse);
        }

        return instance;
    },

    /**
     * Gets or sets the value attribute of the node instance. If the `value` is
     * passed it's set the value of the element, otherwise it works as a getter
     * for the current value.
     *
     * Example:
     *
     * ```
     * var input = A.one('#inputId');
     * input.val('Setting new input value');
     * // Alert the value of the input
     * alert( input.val() );
     * ```
     *
     * @method val
     * @param {String} value Value to be set. Optional.
     */
    val: function(value) {
        var instance = this;

        if (isUndefined(value)) {
            return instance.get('value');
        }
        else {
            return instance.set('value', value);
        }
    },

    /**
     * Returns the combined size of the box style for the specified sides.
     *
     * @method _getBoxStyleAsNumber
     * @param {String} sides Can be t, r, b, l or any combination of
     * those to represent the top, right, bottom, or left sides.
     * @param {String} map An object mapping mapping the "sides" param to the a
     *     CSS value to retrieve
     * @return {Number}
     * @private
     */
    _getBoxStyleAsNumber: function(sides, map) {
        var instance = this;

        var sidesArray = sides.match(/\w/g),
            value = 0,
            side,
            sideKey,
            i;

        for (i = sidesArray.length - 1; i >= 0; i--) {
            sideKey = sidesArray[i];
            side = 0;

            if (sideKey) {
                side = parseFloat(instance.getComputedStyle(map[sideKey]));
                side = Math.abs(side);

                value += side || 0;
            }
        }

        return value;
    },

    /**
     * Extracts text content from the passed nodes.
     *
     * @method _getText
     * @private
     * @param {Native NodeList} childNodes
     */
    _getText: function(childNodes) {
        var instance = this;

        var length = childNodes.length,
            childNode,
            str = [],
            i;

        for (i = 0; i < length; i++) {
            childNode = childNodes[i];

            if (childNode && childNode.nodeType !== 8) {
                if (childNode.nodeType !== 1) {
                    str.push(childNode.nodeValue);
                }

                if (childNode.childNodes) {
                    str.push(instance._getText(childNode.childNodes));
                }
            }
        }

        return str.join('');
    },

    /**
     * Overrides Y.Node._hide. Adds aui-hide to the node's cssClass
     *
     * @method _hide
     * @private
     */
    _hide: function() {
        var instance = this;

        instance.addClass(CSS_HIDE);

        return NODE_PROTO_HIDE.apply(instance, arguments);
    },

    /**
     * The event handler for the "out" function that is fired for events
     * attached via the hover method.
     *
     * @method _hoverOutHandler
     * @private
     * @param {EventFacade} event
     */
    _hoverOutHandler: function(event) {
        var instance = this;

        var hoverOptions = instance._hoverOptions;

        hoverOptions.outTask.delay(hoverOptions.outDelay, event);
    },

    /**
     * The event handler for the "over" function that is fired for events
     * attached via the hover method.
     *
     * @method _hoverOverHandler
     * @private
     * @param {EventFacade} event
     */
    _hoverOverHandler: function(event) {
        var instance = this;

        var hoverOptions = instance._hoverOptions;

        hoverOptions.overTask.delay(hoverOptions.overDelay, event);
    },

    /**
     * Cancels the over task, and fires the users custom "out" function for the
     * hover method
     *
     * @method _hoverOverHandler
     * @private
     * @param {EventFacade} event
     */
    _hoverOutTaskFn: function(event) {
        var instance = this;

        var hoverOptions = instance._hoverOptions;

        hoverOptions.overTask.cancel();

        hoverOptions.out.apply(hoverOptions.context || event.currentTarget, arguments);
    },

    /**
     * Cancels the out task, and fires the users custom "over" function for the
     * hover method
     *
     * @method _hoverOverHandler
     * @private
     * @param {EventFacade} event
     */
    _hoverOverTaskFn: function(event) {
        var instance = this;

        var hoverOptions = instance._hoverOptions;

        hoverOptions.outTask.cancel();

        hoverOptions.over.apply(hoverOptions.context || event.currentTarget, arguments);
    },

    /**
     * Places a node or html string at a specific location
     *
     * @method _place
     * @private
     * @param {Node|String} newNode
     * @param {Node} refNode
     */
    _place: function(newNode, refNode) {
        var instance = this;

        var parent = instance.get('parentNode');

        if (parent) {
            if (isString(newNode)) {
                newNode = ANode.create(newNode);
            }

            parent.insertBefore(newNode, refNode);
        }

        return instance;
    },

    /**
     * Overrides Y.Node._show. Removes aui-hide from the node's cssClass
     *
     * @method _show
     * @private
     */
    _show: function() {
        var instance = this;

        instance.removeClass(CSS_HIDE);

        return NODE_PROTO_SHOW.apply(instance, arguments);
    },

    _defaultHoverOptions: {
        overEventType: 'mouseenter',
        outEventType: 'mouseleave',
        overDelay: 0,
        outDelay: 0,
        over: Lang.emptyFn,
        out: Lang.emptyFn
    }
}, true);

NODE_PROTO.__isHidden = NODE_PROTO._isHidden;

NODE_PROTO._isHidden = function() {
    var instance = this;

    return NODE_PROTO.__isHidden.call(instance) || instance.hasClass(instance._hideClass || CSS_HIDE);
};

/**
 * Returns the width of the content, not including the padding, border or
 * margin. If a width is passed, the node's overall width is set to that size.
 *
 * Example:
 *
 * ```
 * var node = A.one('#nodeId');
 * node.width(); //return content width
 * node.width(100); // sets box width
 * ```
 *
 * @method width
 * @return {number}
 */

/**
 * Returns the height of the content, not including the padding, border or
 * margin. If a height is passed, the node's overall height is set to that size.
 *
 * Example:
 *
 * ```
 * var node = A.one('#nodeId');
 * node.height(); //return content height
 * node.height(100); // sets box height
 * ```
 *
 * @method height
 * @return {number}
 */

/**
 * Returns the size of the box from inside of the border, which is the
 * `offsetWidth` plus the padding on the left and right.
 *
 * Example:
 *
 * ```
 * var node = A.one('#nodeId');
 * node.innerWidth();
 * ```
 *
 * @method innerWidth
 * @return {number}
 */

/**
 * Returns the size of the box from inside of the border, which is offsetHeight
 * plus the padding on the top and bottom.
 *
 * Example:
 *
 * ```
 * var node = A.one('#nodeId');
 * node.innerHeight();
 * ```
 *
 * @method innerHeight
 * @return {number}
 */

/**
 * Returns the outer width of the box including the border, if true is passed as
 * the first argument, the margin is included.
 *
 * Example:
 *
 * ```
 * var node = A.one('#nodeId');
 * node.outerWidth();
 * node.outerWidth(true); // includes margin
 * ```
 *
 * @method outerWidth
 * @return {number}
 */

/**
 * Returns the outer height of the box including the border, if true is passed
 * as the first argument, the margin is included.
 *
 * Example:
 *
 * ```
 * var node = A.one('#nodeId');
 * node.outerHeight();
 * node.outerHeight(true); // includes margin
 * ```
 *
 * @method outerHeight
 * @return {number}
 */

A.each(
 ['Height', 'Width'],
    function(item, index) {
        var sides = index ? 'lr' : 'tb';

        var dimensionType = item.toLowerCase();

        NODE_PROTO[dimensionType] = function(size) {
            var instance = this;

            var returnValue = instance;

            if (isUndefined(size)) {
                var node = instance._node;
                var dimension;

                if (node) {
                    if ((!node.tagName && node.nodeType === 9) || node.alert) {
                        dimension = instance.get('region')[dimensionType];
                    }
                    else {
                        dimension = instance.get('offset' + item);

                        if (!dimension) {
                            var originalDisplay = instance.getStyle('display');
                            var originalPosition = instance.getStyle('position');
                            var originalVisibility = instance.getStyle('visibility');

                            instance.setStyles({
                                display: 'block !important',
                                position: 'absolute !important',
                                visibility: 'hidden !important'
                            });

                            dimension = instance.get('offset' + item);

                            instance.setStyles({
                                display: originalDisplay,
                                position: originalPosition,
                                visibility: originalVisibility
                            });
                        }

                        if (dimension) {
                            dimension -= (instance.getPadding(sides) + instance.getBorderWidth(sides));
                        }
                    }
                }

                returnValue = dimension;
            }
            else {
                instance.setStyle(dimensionType, size);
            }

            return returnValue;
        };

        NODE_PROTO['inner' + item] = function() {
            var instance = this;

            return instance[dimensionType]() + instance.getPadding(sides);
        };

        NODE_PROTO['outer' + item] = function(margin) {
            var instance = this;

            var innerSize = instance['inner' + item]();
            var borderSize = instance.getBorderWidth(sides);

            var size = innerSize + borderSize;

            if (margin) {
                size += instance.getMargin(sides);
            }

            return size;
        };
    }
);

if (!SUPPORT_OPTIONAL_TBODY) {
    A.DOM._ADD_HTML = A.DOM.addHTML;

    A.DOM.addHTML = function(node, content, where) {
        var nodeName = (node.nodeName && node.nodeName.toLowerCase()) || '';

        var tagName = '';

        if (!isUndefined(content)) {
            if (isString(content)) {
                tagName = (REGEX_TAGNAME.exec(content) || ARRAY_EMPTY_STRINGS)[1];
            }
            else if (content.nodeType && content.nodeType === 11 && content.childNodes.length) { // a doc frag
                tagName = content.childNodes[0].nodeName;
            }
            else if (content.nodeName) { // a node
                tagName = content.nodeName;
            }

            tagName = tagName && tagName.toLowerCase();
        }

        if (nodeName === 'table' && tagName === 'tr') {
            node = node.getElementsByTagName('tbody')[0] || node.appendChild(node.ownerDocument.createElement('tbody'));

            var whereNodeName = ((where && where.nodeName) || '').toLowerCase();

            // Assuming if the "where" is a tbody node,
            // we're trying to prepend to a table. Attempt to
            // grab the first child of the tbody.
            if (whereNodeName === 'tbody' && where.childNodes.length > 0) {
                where = where.firstChild;
            }
        }

        return A.DOM._ADD_HTML(node, content, where);
    };
}

/**
 * Augments the [YUI3 NodeList](NodeList.html) with more util methods.
 *
 * Checks the list of [Methods](NodeList.html#methods) available for AUI
 * NodeList.
 *
 * @class A.NodeList
 * @constructor
 * @uses A.Node
 */
ANodeList.importMethod(
    NODE_PROTO, [
  'after',

  'appendTo',

  'attr',

  'before',

  'empty',

  'getX',

  'getXY',

  'getY',

  'hover',

  'html',

  'innerHeight',

  'innerWidth',

  'outerHeight',

  'outerHTML',

  'outerWidth',

  'prepend',

  'prependTo',

  'purge',

  'selectText',

  'selectable',

  'setX',

  'setXY',

  'setY',

  'text',

  'toggle',

  'unselectable',

  'val'
 ]
);

A.mix(
    NODELIST_PROTO, {
        /**
         * See [Node all](Node.html#method_all).
         *
         * @method all
         */
        all: function(selector) {
            var instance = this,
                newNodeList = [],
                nodes = instance._nodes,
                length = nodes.length,
                subList,
                i;

            for (i = 0; i < length; i++) {
                subList = A.Selector.query(selector, nodes[i]);

                if (subList && subList.length) {
                    newNodeList.push.apply(newNodeList, subList);
                }
            }

            newNodeList = AArray.unique(newNodeList);

            return A.all(newNodeList);
        },

        /**
         * Returns the first element in the node list collection.
         *
         * @method first
         * @return {Node}
         */
        first: function() {
            var instance = this;

            return instance.item(0);
        },

        /**
         * See [Node getDOMNode](Node.html#method_getDOMNode).
         *
         * @method getDOM
         */
        getDOM: function() {
            return ANodeList.getDOMNodes(this);
        },

        /**
         * Returns the last element in the node list collection.
         *
         * @method last
         * @return {Node}
         */
        last: function() {
            var instance = this;

            return instance.item(instance._nodes.length - 1);
        },

        /**
         * See [Node one](Node.html#method_one).
         *
         * @method one
         */
        one: function(selector) {
            var instance = this,
                newNode = null,
                nodes = instance._nodes,
                length = nodes.length,
                i;

            for (i = 0; i < length; i++) {
                newNode = A.Selector.query(selector, nodes[i], true);

                if (newNode) {
                    newNode = A.one(newNode);

                    break;
                }
            }

            return newNode;
        }
    }
);

NODELIST_PROTO.__filter = NODELIST_PROTO.filter;

NODELIST_PROTO.filter = function(value, context) {
    var instance = this;

    var newNodeList;

    if (isFunction(value)) {
        var nodes = [];

        instance.each(
            function(item, index, collection) {
                if (value.call(context || item, item, index, collection)) {
                    nodes.push(item._node);
                }
            }
        );

        newNodeList = A.all(nodes);
    }
    else {
        newNodeList = NODELIST_PROTO.__filter.call(instance, value);
    }

    return newNodeList;
};

A.mix(
    ANodeList, {
        /**
         * Converts the passed `html` into a `NodeList` and returns the result.
         *
         * @method create
         * @param {String} html
         * @return {NodeList}
         */
        create: function(html) {
            var docFrag = A.getDoc().invoke('createDocumentFragment');

            return docFrag.append(html).get('childNodes');
        }
    }
);

A.mix(
    A, {
        /**
         * Gets the body node. Shortcut to `A.one('body')`.
         *
         * @method getBody
         */
        getBody: function() {
            var instance = this;

            if (!instance._bodyNode) {
                instance._bodyNode = A.one(DOC.body);
            }

            return instance._bodyNode;
        },

        /**
         * Gets the document node. Shortcut to `A.one(document)`.
         *
         * @method getDoc
         */
        getDoc: function() {
            var instance = this;

            if (!instance._documentNode) {
                instance._documentNode = A.one(DOC);
            }

            return instance._documentNode;
        },

        /**
         * Gets the window node. Shortcut to `A.one(window)`.
         *
         * @method getWin
         */
        getWin: function() {
            var instance = this;

            if (!instance._windowNode) {
                instance._windowNode = A.one(WIN);
            }

            return instance._windowNode;
        }
    }
);


}, '3.1.0-deprecated.95', {"requires": ["array-extras", "aui-base-lang", "aui-classnamemanager", "aui-debounce", "node"]});

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

/**
 * Provides support for HTML shiv natively on the Alloy DOM methods. The HTML5
 * shiv just affects IE.
 *
 * @module aui-node
 * @submodule aui-node-html5
 */

if (A.UA.ie) {
    /**
     * An object that encapsulates util methods for HTML5 shiving.
     *
     * **What is a "shiv"?**
     *
     * To the world, a shiv is a slang term for a sharp object used as a
     * knife-like weapon. To Internet Explorer, a shiv is a script that, when
     * executed, forces the browser to recognize HTML5 elements.
     *
     * @class A.HTML5
     */
    var HTML5 = A.namespace('HTML5'),
        DOM_create = A.DOM._create;

    if (!HTML5._fragHTML5Shived) {
        /**
         * A global DocumentFragment already HTML5 shived, for performance
         * reasons. (i.e., all nodes and its HTML5 children appended to this
         * fragment iherits the styles on IE).
         *
         * @property _fragHTML5Shived
         * @type {DocumentFragment}
         * @protected
         */
        HTML5._fragHTML5Shived = A.html5shiv(
            A.config.doc.createDocumentFragment()
        );
    }

    A.mix(
        HTML5, {
            /**
             * Receives a `frag` and a HTML content. This method shivs the HTML5
             * nodes appended to a Node or fragment which is not on the document
             * yet.
             *
             * @method IECreateFix
             * @param {Node|DocumentFragment} frag Fragment to be fixed.
             * @param {String} content HTML to be set (using innerHTML) on the
             *     `frag`.
             * @return {Node|DocumentFragment}
             */
            IECreateFix: function(frag, content) {
                var shivedFrag = HTML5._fragHTML5Shived;

                shivedFrag.appendChild(frag);

                frag.innerHTML = content;

                shivedFrag.removeChild(frag);

                return frag;
            },

            /**
             * AOP listener to the A.DOM._create method. This method intercepts
             * all the calls to the A.DOM._create and append the generated
             * fragment to [A.HTML._fragHTML5Shived](A.HTML5.html#property__frag
             * HTML5Shived), this fixes the IE bug for painting the HTML5 nodes
             * on the HTML fragment.
             *
             * @method _doBeforeCreate
             * @param {String} html HTML content
             * @param {String} doc
             * @param {String} tag
             * @protected
             * @return {DocumentFragment}
             */
            _doBeforeCreate: function(html) {
                var createdFrag = DOM_create.apply(this, arguments);

                var shivedFrag = HTML5.IECreateFix(createdFrag, html);

                return new A.Do.Halt(null, shivedFrag);
            }
        }
    );

    A.Do.before(HTML5._doBeforeCreate, A.DOM, '_create', A.DOM);
}
/**
 * The Node Utility.
 *
 * @module aui-node
 * @submodule aui-node-html5-print
 */

var CONFIG = A.config,
    DOC = CONFIG.doc,
    WIN = CONFIG.win,
    UA = A.UA,
    IE = UA.ie,

    isShivDisabled = function() {
        return WIN.AUI_HTML5_IE === false;
    };

if (!IE || IE >= 9 || isShivDisabled()) {
    return;
}

var BUFFER_CSS_TEXT = [],

    LOCATION = WIN.location,

    DOMAIN = LOCATION.protocol + '//' + LOCATION.host,

    HTML = DOC.documentElement,

    HTML5_ELEMENTS = A.HTML5_ELEMENTS,
    HTML5_ELEMENTS_LENGTH = HTML5_ELEMENTS.length,
    HTML5_ELEMENTS_LIST = HTML5_ELEMENTS.join('|'),

    REGEX_CLONE_NODE_CLEANUP = new RegExp('<(/?):(' + HTML5_ELEMENTS_LIST + ')', 'gi'),
    REGEX_ELEMENTS = new RegExp('(' + HTML5_ELEMENTS_LIST + ')', 'gi'),
    REGEX_ELEMENTS_FAST = new RegExp('\\b(' + HTML5_ELEMENTS_LIST + ')\\b', 'i'),

    REGEX_PRINT_MEDIA = /print|all/,

    REGEX_RULE = new RegExp('(^|[^\\n{}]*?\\s)(' + HTML5_ELEMENTS_LIST + ').*?{([^}]*)}', 'gim'),
    REGEX_TAG = new RegExp('<(\/*)(' + HTML5_ELEMENTS_LIST + ')', 'gi'),

    SELECTOR_REPLACE_RULE = '.' + 'printfix-' + '$1',

    STR_EMPTY = '',

    STR_URL_DOMAIN = 'url(' + DOMAIN,

    TAG_REPLACE_ORIGINAL = '<$1$2',
    TAG_REPLACE_FONT = '<$1font';

var html5shiv = A.html5shiv,
    // Yes, IE does this wackiness; converting an object
    // to a string should never result in undefined, but
    // IE's styleSheet object sometimes becomes inaccessible
    // after trying to print the second time
    isStylesheetDefined = function(obj) {
        return obj && (obj + STR_EMPTY !== undefined);
    },

    toggleNode = function(node, origNode, prop) {
        var state = origNode[prop];

        if (state) {
            node.setAttribute(prop, state);
        }
        else {
            node.removeAttribute(prop);
        }
    };

html5shiv(DOC);

var printFix = function() {
    var destroy;

    var afterPrint = function() {
        if (isShivDisabled()) {
            destroy();
        }
        else {
            printFix.onAfterPrint();
        }
    };

    var beforePrint = function() {
        if (isShivDisabled()) {
            destroy();
        }
        else {
            printFix.onBeforePrint();
        }
    };

    destroy = function() {
        WIN.detachEvent('onafterprint', afterPrint);
        WIN.detachEvent('onbeforeprint', beforePrint);
    };

    var init = function() {
        WIN.attachEvent('onafterprint', afterPrint);
        WIN.attachEvent('onbeforeprint', beforePrint);
    };

    init();

    printFix.destroy = destroy;
    printFix.init = init;
};

A.mix(
    printFix, {
        /**
         * Fires after a print.
         *
         * @method onAfterPrint
         */
        onAfterPrint: function() {
            var instance = this;

            instance.restoreHTML();

            var styleSheet = instance._getStyleSheet();

            styleSheet.styleSheet.cssText = '';
        },

        /**
         * Fires before a print.
         *
         * @method onBeforePrint
         */
        onBeforePrint: function() {
            var instance = this;

            var styleSheet = instance._getStyleSheet();
            var cssRules = instance._getAllCSSText();

            styleSheet.styleSheet.cssText = instance.parseCSS(cssRules);

            instance.writeHTML();
        },

        /**
         * Navigates through the CSS joining rules and replacing content.
         *
         * @method parseCSS
         * @param cssText
         * @return {String}
         */
        parseCSS: function(cssText) {
            var css = '';
            var rules = cssText.match(REGEX_RULE);

            if (rules) {
                css = rules.join('\n').replace(REGEX_ELEMENTS, SELECTOR_REPLACE_RULE);
            }

            return css;
        },

        /**
         * Restores the HTML from the `bodyClone` and `bodyEl` attributes.
         *
         * @method restoreHTML
         */
        restoreHTML: function() {
            var instance = this;

            var bodyClone = instance._getBodyClone();
            var bodyEl = instance._getBodyEl();

            var newNodes = bodyClone.getElementsByTagName('IFRAME');
            var originalNodes = bodyEl.getElementsByTagName('IFRAME');

            var length = originalNodes.length;

            // Moving IFRAME nodes back to their original position
            if (length === newNodes.length) {
                while (length--) {
                    var newNode = newNodes[length];
                    var originalNode = originalNodes[length];

                    originalNode.swapNode(newNode);
                }
            }

            bodyClone.innerHTML = '';

            HTML.removeChild(bodyClone);
            HTML.appendChild(bodyEl);
        },

        /**
         * Generates the HTML for print.
         *
         * @method writeHTML
         */
        writeHTML: function() {
            var instance = this;

            var i = -1;
            var j;

            var bodyEl = instance._getBodyEl();

            var html5Element;

            var cssClass;

            var nodeList;
            var nodeListLength;
            var node;
            var buffer = [];

            while (++i < HTML5_ELEMENTS_LENGTH) {
                html5Element = HTML5_ELEMENTS[i];

                nodeList = DOC.getElementsByTagName(html5Element);
                nodeListLength = nodeList.length;

                j = -1;

                while (++j < nodeListLength) {
                    node = nodeList[j];

                    cssClass = node.className;

                    if (cssClass.indexOf('printfix-') === -1) {
                        buffer[0] = 'printfix-' + html5Element;
                        buffer[1] = cssClass;

                        node.className = buffer.join(' ');
                    }
                }
            }

            var docFrag = instance._getDocFrag();
            var bodyClone = instance._getBodyClone();

            docFrag.appendChild(bodyEl);
            HTML.appendChild(bodyClone);

            bodyClone.className = bodyEl.className;
            bodyClone.id = bodyEl.id;

            var originalNodes = bodyEl.getElementsByTagName('*');
            var length = originalNodes.length;

            // IE will throw a mixed content warning when using https
            // and calling clone node if the body contains elements with
            // an inline background-image style that is relative to the domain.
            if (UA.secure) {
                var bodyElStyle = bodyEl.style;

                var elStyle;
                var backgroundImage;

                bodyElStyle.display = 'none';

                for (i = 0; i < length; i++) {
                    elStyle = originalNodes[i].style;

                    backgroundImage = elStyle.backgroundImage;

                    if (backgroundImage &&
                        backgroundImage.indexOf('url(') > -1 &&
                        backgroundImage.indexOf('https') === -1) {

                        elStyle.backgroundImage = backgroundImage.replace('url(', STR_URL_DOMAIN);
                    }
                }

                bodyElStyle.display = '';
            }

            var bodyElClone = bodyEl.cloneNode(true);

            var newNodes = bodyElClone.getElementsByTagName('*');

            if (length === newNodes.length) {
                while (length--) {
                    var newNode = newNodes[length];
                    var newNodeName = newNode.nodeName;

                    if (newNodeName === 'INPUT' || newNodeName === 'OPTION' || newNodeName === 'IFRAME') {
                        var originalNode = originalNodes[length];
                        var originalNodeName = originalNode.nodeName;

                        if (originalNodeName === newNodeName) {
                            var prop = null;

                            if (newNodeName === 'OPTION') {
                                prop = 'selected';
                            }
                            else if (newNodeName === 'INPUT' && (newNode.type === 'checkbox' || newNode.type ===
                                'radio')) {
                                prop = 'checked';
                            }
                            else if (newNodeName === 'IFRAME') {
                                newNode.src = '';
                            }

                            if (prop !== null) {
                                toggleNode(newNode, originalNode, prop);
                            }
                        }
                    }
                }
            }

            var bodyHTML = bodyElClone.innerHTML;

            bodyHTML = bodyHTML.replace(REGEX_CLONE_NODE_CLEANUP, TAG_REPLACE_ORIGINAL).replace(REGEX_TAG,
                TAG_REPLACE_FONT);

            bodyClone.innerHTML = bodyHTML;

            // Post processing the DOM in order to move IFRAME nodes

            newNodes = bodyClone.getElementsByTagName('IFRAME');
            originalNodes = bodyEl.getElementsByTagName('IFRAME');

            length = originalNodes.length;

            if (length === newNodes.length) {
                while (length--) {
                    var newNodeIframe = newNodes[length];
                    var originalNodeIframe = originalNodes[length];

                    // According to quirksmode.org, swapNode is supported on all major IE versions
                    originalNodeIframe.swapNode(newNodeIframe);
                }
            }
        },

        /**
         * Gets all CSS text from all stylesheets.
         *
         * @method _getAllCSSText
         * @protected
         * @return {Array}
         */
        _getAllCSSText: function() {
            var instance = this;

            var buffer = [];
            var styleSheets = instance._getAllStyleSheets(DOC.styleSheets, 'all');
            var rule;
            var cssText;
            var styleSheet;

            for (var i = 0; styleSheet = styleSheets[i]; i++) {
                var rules = styleSheet.rules;

                if (rules && rules.length) {
                    for (var j = 0, ruleLength = rules.length; j < ruleLength; j++) {
                        rule = rules[j];

                        if (!rule.href) {
                            cssText = instance._getCSSTextFromRule(rule);

                            buffer.push(cssText);
                        }
                    }
                }
            }

            return buffer.join(' ');
        },

        /**
         * Extracts the CSS text from a rule.
         *
         * @method _getCSSTextFromRule
         * @param rule
         * @protected
         * @return {String}
         */
        _getCSSTextFromRule: function(rule) {
            var cssText = '';

            var ruleStyle = rule.style;
            var ruleCSSText;
            var ruleSelectorText;

            if (ruleStyle && (ruleCSSText = ruleStyle.cssText) && (ruleSelectorText = rule.selectorText) &&
                REGEX_ELEMENTS_FAST.test(ruleSelectorText)) {
                BUFFER_CSS_TEXT.length = 0;

                BUFFER_CSS_TEXT.push(ruleSelectorText, '{', ruleCSSText, '}');

                cssText = BUFFER_CSS_TEXT.join(' ');
            }

            return cssText;
        },

        /**
         * Gets all stylesheets from a page.
         *
         * @method _getAllStyleSheets
         * @param styleSheet, mediaType, level, buffer
         * @protected
         * @return {Array}
         */
        _getAllStyleSheets: function(styleSheet, mediaType, level, buffer) {
            var instance = this;

            level = level || 1;

            buffer = buffer || [];

            var i;

            if (isStylesheetDefined(styleSheet)) {
                var imports = styleSheet.imports;

                mediaType = styleSheet.mediaType || mediaType;

                if (REGEX_PRINT_MEDIA.test(mediaType)) {
                    var length;

                    // IE can crash when trying to access imports more than 3 levels deep
                    if (level <= 3 && isStylesheetDefined(imports) && imports.length) {
                        for (i = 0, length = imports.length; i < length; i++) {
                            instance._getAllStyleSheets(imports[i], mediaType, level + 1, buffer);
                        }
                    }
                    else if (styleSheet.length) {
                        for (i = 0, length = styleSheet.length; i < length; i++) {
                            instance._getAllStyleSheets(styleSheet[i], mediaType, level, buffer);
                        }
                    }
                    else {
                        var rules = styleSheet.rules;
                        var ruleStyleSheet;

                        if (rules && rules.length) {
                            for (i = 0, length = rules.length; i < length; i++) {
                                ruleStyleSheet = rules[i].styleSheet;

                                if (ruleStyleSheet) {
                                    instance._getAllStyleSheets(ruleStyleSheet, mediaType, level, buffer);
                                }
                            }
                        }
                    }

                    if (!styleSheet.disabled && styleSheet.rules) {
                        buffer.push(styleSheet);
                    }
                }
            }

            mediaType = 'all';

            return buffer;
        },

        /**
         * Gets the `<body>` element.
         *
         * @method _getBodyEl
         * @protected
         * @return {Element}
         */
        _getBodyEl: function() {
            var instance = this;

            var bodyEl = instance._bodyEl;

            if (!bodyEl) {
                bodyEl = DOC.body;

                instance._bodyEl = bodyEl;
            }

            return bodyEl;
        },

        /**
         * Gets a clone of the `<body>` element.
         *
         * @method _getBodyClone
         * @protected
         * @return {Element}
         */
        _getBodyClone: function() {
            var instance = this;

            var bodyClone = instance._bodyClone;

            if (!bodyClone) {
                bodyClone = DOC.createElement('body');

                instance._bodyClone = bodyClone;
            }

            return bodyClone;
        },

        /**
         * Gets a document fragment object.
         *
         * @method _getDocFrag
         * @protected
         * @return {DocumentFragment}
         */
        _getDocFrag: function() {
            var instance = this;

            var docFrag = instance._docFrag;

            if (!docFrag) {
                docFrag = DOC.createDocumentFragment();

                html5shiv(docFrag);

                instance._docFrag = docFrag;
            }

            return docFrag;
        },

        /**
         * Gets the stylesheet from the DOM.
         *
         * @method _getStyleSheet
         * @protected
         * @return {Node}
         */
        _getStyleSheet: function() {
            var instance = this;

            var styleSheet = instance._styleSheet;

            if (!styleSheet) {
                styleSheet = DOC.createElement('style');

                var head = DOC.documentElement.firstChild;

                head.insertBefore(styleSheet, head.firstChild);

                styleSheet.media = 'print';
                styleSheet.className = 'printfix';

                instance._styleSheet = styleSheet;
            }

            return styleSheet;
        }
    }
);

A.namespace('HTML5').printFix = printFix;

printFix();


}, '3.1.0-deprecated.95', {"requires": ["collection", "aui-node-base"]});

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

/**
 * The Selector Utility.
 *
 * @module aui-selector
 */

var SELECTOR = A.Selector,

    CSS_BOOTSTRAP_SR_ONLY = A.getClassName('sr-only'),
    CSS_HIDE = A.getClassName('hide'),
    REGEX_CLIP_RECT_ZERO = new RegExp(/rect\((0(px)?(,)?(\s)?){4}\)/i),
    REGEX_HIDDEN_CLASSNAMES = new RegExp(CSS_HIDE),
    REGEX_SR_ONLY_CLASSNAMES = new RegExp(CSS_BOOTSTRAP_SR_ONLY);

SELECTOR._isNodeHidden = function(node) {
    var width = node.offsetWidth;
    var height = node.offsetHeight;
    var ignore = node.nodeName.toLowerCase() === 'tr';
    var className = node.className;
    var nodeStyle = node.style;

    var hidden = false;

    if (!ignore) {
        if (width === 0 && height === 0) {
            hidden = true;
        }
        else if (width > 0 && height > 0) {
            hidden = false;
        }
    }

    hidden = hidden || (nodeStyle.display === 'none' || nodeStyle.visibility === 'hidden') ||
        (nodeStyle.position === 'absolute' && REGEX_CLIP_RECT_ZERO.test(nodeStyle.clip)) ||
        REGEX_HIDDEN_CLASSNAMES.test(className) || REGEX_SR_ONLY_CLASSNAMES.test(className);

    return hidden;
};

var testNodeType = function(type) {
    return function(node) {
        return node.type === type;
    };
};

/**
 * Augment the [YUI3 Selector](Selector.html) with more util methods.
 *
 * @class A.Selector
 * @uses Selector
 * @constructor
 */
A.mix(
    SELECTOR.pseudos, {
        /**
         * Checks if the node is a button element or contains `type="button"`.
         *
         * @method button
         * @param node
         * @return {Boolean}
         */
        button: function(node) {
            return node.type === 'button' || node.nodeName.toLowerCase() === 'button';
        },

        /**
         * Checks if the node contains `type="checkbox"`.
         *
         * @method checkbox
         * @return {Boolean}
         */
        checkbox: testNodeType('checkbox'),

        /**
         * Checks if the node is checked or not.
         *
         * @method checked
         * @param node
         * @return {Boolean}
         */
        checked: function(node) {
            return node.checked === true;
        },

        /**
         * Checks if the node is disabled or not.
         *
         * @method disabled
         * @param node
         * @return {Boolean}
         */
        disabled: function(node) {
            return node.disabled === true;
        },

        /**
         * Checks if the node is empty or not.
         *
         * @method empty
         * @param node
         * @return {Boolean}
         */
        empty: function(node) {
            return !node.firstChild;
        },

        /**
         * Checks if the node is enabled or not.
         *
         * @method enabled
         * @param node
         * @return {Boolean}
         */
        enabled: function(node) {
            return node.disabled === false && node.type !== 'hidden';
        },

        /**
         * Checks if the node contains `type="file"`.
         *
         * @method file
         * @return {Boolean}
         */
        file: testNodeType('file'),

        /**
         * Checks if the node is a header (e.g. `<h1>`, `<h2>`, ...) or not.
         *
         * @method header
         * @param node
         * @return {Boolean}
         */
        header: function(node) {
            return /h\d/i.test(node.nodeName);
        },

        /**
         * Checks if the node is hidden or not.
         *
         * @method hidden
         * @param node
         * @return {Boolean}
         */
        hidden: function(node) {
            return SELECTOR._isNodeHidden(node);
        },

        /**
         * Checks if the node contains `type="image"`.
         *
         * @method image
         * @return {Boolean}
         */
        image: testNodeType('image'),

        /**
         * Checks if the node is an input (e.g. `<textarea>`, `<input>`, ...) or not.
         *
         * @method input
         * @param node
         * @return {Boolean}
         */
        input: function(node) {
            return /input|select|textarea|button/i.test(node.nodeName);
        },

        /**
         * Checks if the node contains a child or not.
         *
         * @method parent
         * @param node
         * @return {Boolean}
         */
        parent: function(node) {
            return !!node.firstChild;
        },

        /**
         * Checks if the node contains `type="password"`.
         *
         * @method password
         * @return {Boolean}
         */
        password: testNodeType('password'),

        /**
         * Checks if the node contains `type="radio"`.
         *
         * @method radio
         * @return {Boolean}
         */
        radio: testNodeType('radio'),

        /**
         * Checks if the node contains `type="reset"`.
         *
         * @method reset
         * @return {Boolean}
         */
        reset: testNodeType('reset'),

        /**
         * Checks if the node is selected or not.
         *
         * @method selected
         * @param node
         * @return {Boolean}
         */
        selected: function(node) {
            node.parentNode.selectedIndex;
            return node.selected === true;
        },

        /**
         * Checks if the node contains `type="submit"`.
         *
         * @method submit
         * @return {Boolean}
         */
        submit: testNodeType('submit'),

        /**
         * Checks if the node contains `type="text"`.
         *
         * @method text
         * @return {Boolean}
         */
        text: testNodeType('text'),

        /**
         * Checks if the node is visible or not.
         *
         * @method visible
         * @param node
         * @return {Boolean}
         */
        visible: function(node) {
            return !SELECTOR._isNodeHidden(node);
        }
    }
);


}, '3.1.0-deprecated.95', {"requires": ["selector-css3", "aui-classnamemanager"]});

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

/**
 * Utility for timing logics used to manage [JavaScript Timer
 * Congestion](http://fitzgeraldnick.com/weblog/40/) problems.
 *
 * @module aui-timer
 */

var Lang = A.Lang,
    now = Lang.now,
    isEmpty = A.Object.isEmpty,

    aArray = A.Array;

/**
 * A base class for Timer.
 *
 * @class A.Timer
 * @constructor
 */
var Timer = {

    /**
     * Cancels repeated action which was set up using `setInterval` function.
     *
     * @method clearInterval
     * @param id
     */
    clearInterval: function(id) {
        var instance = Timer;

        instance.unregister(true, id);
    },

    /**
     * Clears the delay set by `setTimeout` function.
     *
     * @method clearTimeout
     * @param id
     */
    clearTimeout: function(id) {
        var instance = Timer;

        instance.unregister(false, id);
    },

    /**
     * Defines the fixed time delay between each interval.
     *
     * @method intervalTime
     * @param newInterval
     * @return {Number}
     */
    intervalTime: function(newInterval) {
        var instance = Timer;

        if (arguments.length) {
            instance._INTERVAL = newInterval;
        }

        return instance._INTERVAL;
    },

    /**
     * Checks if the task is repeatable or not.
     *
     * @method isRepeatable
     * @param task
     * @return {Boolean}
     */
    isRepeatable: function(task) {
        return task.repeats;
    },

    /**
     * Calls a function after a specified delay.
     *
     * @method setTimeout
     * @param fn
     * @param ms
     * @param context
     */
    setTimeout: function(fn, ms, context) {
        var instance = Timer;

        var args = aArray(arguments, 3, true);

        return instance.register(false, fn, ms, context, args);
    },

    /**
     * Calls a function repeatedly, with a fixed time delay between each call to
     * that function.
     *
     * @method setInterval
     * @param fn
     * @param ms
     * @param context
     */
    setInterval: function(fn, ms, context) {
        var instance = Timer;

        var args = aArray(arguments, 3, true);

        return instance.register(true, fn, ms, context, args);
    },

    /**
     * Adds a new task to the timer.
     *
     * @method register
     * @param repeats
     * @param fn
     * @param ms
     * @param context
     * @param args
     */
    register: function(repeats, fn, ms, context, args) {
        var instance = Timer;

        var id = (++A.Env._uidx);

        args = args || [];

        args.unshift(fn, context);

        instance._TASKS[id] = instance._create(
            repeats, instance._getNearestInterval(ms), A.rbind.apply(A, args)
        );

        instance._lazyInit();

        return id;
    },

    /**
     * Runs the task function.
     *
     * @method run
     * @param task
     */
    run: function(task) {
        task.lastRunTime = now();

        return task.fn();
    },

    /**
     * Removes a task from the timer.
     *
     * @method unregister
     * @param repeats
     * @param id
     */
    unregister: function(repeats, id) {
        var instance = Timer;

        var tasks = instance._TASKS;

        var task = tasks[id];

        instance._lazyDestroy();

        return task && task.repeats === repeats && delete tasks[id];
    },

    /**
     * Creates a collection of timer definitions.
     *
     * @method _create
     * @param repeats
     * @param ms
     * @param fn
     * @protected
     * @return {Object}
     */
    _create: function(repeats, ms, fn) {
        return {
            fn: fn,
            lastRunTime: now(),
            next: ms,
            repeats: repeats,
            timeout: ms
        };
    },

    /**
     * Subtracts the current time with the last run time. The result of this
     * operation is subtracted with the task timeout.
     *
     * @method _decrementNextRunTime
     * @param tasks
     * @protected
     */
    _decrementNextRunTime: function(task) {
        return task.next = task.timeout - (now() - task.lastRunTime);
    },

    /**
     * Calculates the nearest interval by using the modulus of the argument with
     * the interval as reference.
     *
     * @method _getNearestInterval
     * @param num
     * @protected
     * @return {Number}
     */
    _getNearestInterval: function(num) {
        var instance = Timer;

        var interval = instance._INTERVAL;

        var delta = num % interval;

        var nearestInterval;

        if (delta < interval / 2) {
            nearestInterval = num - delta;
        }
        else {
            nearestInterval = num + interval - delta;
        }

        return nearestInterval;
    },

    /**
     * Checks if the timer is initialized and empty, then calls the
     * `clearTimeout` function using the global interval id.
     *
     * @method _lazyDestroy
     * @protected
     */
    _lazyDestroy: function() {
        var instance = Timer;

        if (instance._initialized && isEmpty(instance._TASKS)) {
            clearTimeout(instance._globalIntervalId);

            instance._initialized = false;
        }
    },

    /**
     * Checks if the timer is initialized and contains a task, then calls the
     * `setTimeout` function and stores the global interval id.
     *
     * @method _lazyInit
     * @protected
     */
    _lazyInit: function() {
        var instance = Timer;

        if (!instance._initialized && !isEmpty(instance._TASKS)) {
            instance._lastRunTime = now();

            instance._globalIntervalId = setTimeout(
                instance._runner, instance._INTERVAL
            );

            instance._initialized = true;
        }
    },

    /**
     * Goes through all pending tasks and initializes its timer or unregisters
     * it depending on the task status.
     *
     * @method _loop
     * @param i
     * @param pendingTasks
     * @param length
     * @protected
     */
    _loop: function(i, pendingTasks, length) {
        var instance = Timer;

        var interval = instance._INTERVAL;
        var tasks = instance._TASKS;

        var halfInterval = interval / 2;

        for (var start = now(); i < length && now() - start < 50; i++) {
            var taskId = pendingTasks[i];
            var task = tasks[taskId];

            if (task && instance._decrementNextRunTime(task) < halfInterval) {
                instance.run(task);

                if (instance.isRepeatable(task)) {
                    instance._resetNextRunTime(task);
                }
                else {
                    instance.unregister(false, taskId);
                }
            }
        }

        if (instance._initialized) {
            if (i < length) {
                instance._globalIntervalId = setTimeout(instance._loop, 10);
            }
            else {
                instance._globalIntervalId = setTimeout(
                    instance._runner, interval
                );
            }
        }
    },

    /**
     * Gets the arguments to call the `_loop` method.
     *
     * @method _runner
     * @protected
     */
    _runner: function() {
        var instance = Timer;

        var i = 0;
        var pendingTasks = A.Object.keys(instance._TASKS);
        var length = pendingTasks.length;

        instance._loop(i, pendingTasks, length);
    },

    /**
     * Resets the next run time.
     *
     * @method _resetNextRunTime
     * @param task
     * @protected
     */
    _resetNextRunTime: function(task) {
        return task.next = task.timeout;
    },

    _INTERVAL: 50,
    _TASKS: {},

    _lastRunTime: 0,
    _globalIntervalId: 0,
    _initialized: false
};

/**
 * Cancels repeated action which was set up using `setInterval` function.
 *
 * @method A.clearInterval
 * @static
 * @param id
 */
A.clearInterval = Timer.clearInterval;

/**
 * Clears the delay set by `setTimeout` function.
 *
 * @method A.clearTimeout
 * @static
 * @param id
 */
A.clearTimeout = Timer.clearTimeout;

/**
 * Calls a function repeatedly, with a fixed time delay between each call to
 * that function.
 *
 * @method A.setInterval
 * @static
 * @param fn
 * @param ms
 * @param context
 */
A.setInterval = Timer.setInterval;

/**
 * Calls a function after a specified delay.
 *
 * @method A.setTimeout
 * @static
 * @param fn
 * @param ms
 * @param context
 */
A.setTimeout = Timer.setTimeout;

A.Timer = Timer;


}, '3.1.0-deprecated.95', {"requires": ["oop"]});

(function() {
	var A = AUI().use('oop');

	var usedModules = {};

	var Dependency = {
		provide: function(obj, methodName, methodFn, modules, proto) {
			if (!Array.isArray(modules)) {
				modules = [modules];
			}

			var before;

			var guid = A.guid();

			if (A.Lang.isObject(methodFn, true)) {
				var config = methodFn;

				methodFn = config.fn;
				before = config.before;

				if (!A.Lang.isFunction(before)) {
					before = null;
				}
			}

			if (proto && A.Lang.isFunction(obj)) {
				obj = obj.prototype;
			}

			var AOP = Dependency._getAOP(obj, methodName);

			if (AOP) {
				delete obj._yuiaop[methodName];
			}

			var proxy = function() {
				var args = arguments;

				var context = obj;

				if (proto) {
					context = this;
				}

				if (modules.length == 1) {
					if (modules[0] in usedModules) {
						Dependency._replaceMethod(obj, methodName, methodFn, context);

						methodFn.apply(context, args);

						return;
					}
				}

				var firstLoad = false;

				var queue = Dependency._proxyLoaders[guid];

				if (!queue) {
					firstLoad = true;

					Dependency._proxyLoaders[guid] = new A.Queue();

					queue = Dependency._proxyLoaders[guid];
				}

				queue.add(args);

				if (firstLoad) {
					modules.push(A.bind(Dependency._proxy, Liferay, obj, methodName, methodFn, context, guid, modules));

					A.use.apply(A, modules);
				}
			};

			proxy.toString = function() {
				return methodFn.toString();
			};

			obj[methodName] = proxy;
		},

		_getAOP: function(obj, methodName) {
			var instance = this;

			return obj._yuiaop && obj._yuiaop[methodName];
		},

		_proxy: function(obj, methodName, methodFn, context, guid, modules, A) {
			var args;

			var queue = Dependency._proxyLoaders[guid];

			Dependency._replaceMethod(obj, methodName, methodFn, context);

			while ((args = queue.next())) {
				methodFn.apply(context, args);
			}

			for (var i = modules.length - 1; i >= 0; i--) {
				usedModules[modules[i]] = true;
			}
		},

		_replaceMethod: function(obj, methodName, methodFn, context) {
			var instance = this;

			var AOP = Dependency._getAOP(obj, methodName);

			var proxy = obj[methodName];

			if (AOP) {
				proxy = AOP.method;

				AOP.method = methodFn;
			}
			else {
				obj[methodName] = methodFn;
			}

			A.mix(methodFn, proxy);
		},

		_proxyLoaders: {}
	};

	Liferay.Dependency = Dependency;

	Liferay.provide = Dependency.provide;
})();
;

(function (Liferay) {
  var DOMTaskRunner = {
    addTask: function addTask(task) {
      var instance = this;

      instance._scheduledTasks.push(task);
    },
    addTaskState: function addTaskState(state) {
      var instance = this;

      instance._taskStates.push(state);
    },
    reset: function reset() {
      var instance = this;
      instance._taskStates.length = 0;
      instance._scheduledTasks.length = 0;
    },
    runTasks: function runTasks(node) {
      var instance = this;
      var scheduledTasks = instance._scheduledTasks;
      var taskStates = instance._taskStates;
      var tasksLength = scheduledTasks.length;
      var taskStatesLength = taskStates.length;

      for (var i = 0; i < tasksLength; i++) {
        var task = scheduledTasks[i];
        var taskParams = task.params;

        for (var j = 0; j < taskStatesLength; j++) {
          var state = taskStates[j];

          if (task.condition(state, taskParams, node)) {
            task.action(state, taskParams, node);
          }
        }
      }
    },
    _scheduledTasks: [],
    _taskStates: []
  };
  Liferay.DOMTaskRunner = DOMTaskRunner;
})(Liferay);
//# sourceMappingURL=dom_task_runner.js.map
Liferay.on = function () {};

Liferay.fire = function () {};

Liferay.detach = function () {};

;

(function (A, Liferay) {
  var CLICK_EVENTS = {};
  var DOC = A.config.doc;
  Liferay.provide(Liferay, 'delegateClick', function (id, fn) {
    var el = DOC.getElementById(id);

    if (!el || el.id != id) {
      return;
    }

    var guid = A.one(el).addClass('lfr-delegate-click').guid();
    CLICK_EVENTS[guid] = fn;

    if (!Liferay._baseDelegateHandle) {
      Liferay._baseDelegateHandle = A.getBody().delegate('click', Liferay._baseDelegate, '.lfr-delegate-click');
    }
  }, ['aui-base']);

  Liferay._baseDelegate = function (event) {
    var id = event.currentTarget.attr('id');
    var fn = CLICK_EVENTS[id];

    if (fn) {
      fn.apply(this, arguments);
    }
  };

  Liferay._CLICK_EVENTS = CLICK_EVENTS;
  A.use('attribute', 'oop', function (A) {
    A.augment(Liferay, A.Attribute, true);
  });
})(AUI(), Liferay);
//# sourceMappingURL=events.js.map
;(function(A, Liferay) {
	var Language = {};

	Language.get = function(key) {
		return key;
	};

	A.use(
		'io-base',
		function(A) {
			Language.get = A.cached(
				function(key, extraParams) {
					var instance = this;

					var url = themeDisplay.getPathContext() + '/language/' + themeDisplay.getLanguageId() + '/' + key + '/';

					if (extraParams) {
						if (typeof extraParams == 'string') {
							url += extraParams;
						}
						else if (Array.isArray(extraParams)) {
							url += extraParams.join('/');
						}
					}

					var headers = {
						'X-CSRF-Token': Liferay.authToken
					};

					var value = '';

					A.io(
						url,
						{
							headers: headers,
							method: 'GET',
							on: {
								complete: function(i, o) {
									value = o.responseText;
								}
							},
							sync: true
						}
					);

					return value;
				}
			);
		}
	);

	Liferay.Language = Language;
})(AUI(), Liferay);
(function (Liferay) {
  Liferay.lazyLoad = function () {
    var failureCallback;

    var isFunction = function isFunction(val) {
      return typeof val === 'function';
    };

    var modules;
    var successCallback;

    if (Array.isArray(arguments[0])) {
      modules = arguments[0];
      successCallback = isFunction(arguments[1]) ? arguments[1] : null;
      failureCallback = isFunction(arguments[2]) ? arguments[2] : null;
    } else {
      modules = [];

      for (var i = 0; i < arguments.length; ++i) {
        if (typeof arguments[i] === 'string') {
          modules[i] = arguments[i];
        } else if (isFunction(arguments[i])) {
          successCallback = arguments[i];
          failureCallback = isFunction(arguments[++i]) ? arguments[i] : null;
          break;
        }
      }
    }

    return function () {
      var args = [];

      for (var i = 0; i < arguments.length; ++i) {
        args.push(arguments[i]);
      }

      Liferay.Loader.require(modules, function () {
        for (var i = 0; i < arguments.length; ++i) {
          args.splice(i, 0, arguments[i]);
        }

        successCallback.apply(successCallback, args);
      }, failureCallback);
    };
  };
})(Liferay);
//# sourceMappingURL=lazy_load.js.map
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

Liferay = window.Liferay || {};

(function ($, Liferay) {
  var isFunction = function isFunction(val) {
    return typeof val === 'function';
  };

  var isNode = function isNode(node) {
    return node && (node._node || node.jquery || node.nodeType);
  };

  var REGEX_METHOD_GET = /^get$/i;
  var STR_MULTIPART = 'multipart/form-data';

  Liferay.namespace = function namespace(obj, path) {
    if (path === undefined) {
      path = obj;
      obj = this;
    }

    var parts = path.split('.');

    for (var part; parts.length && (part = parts.shift());) {
      if (obj[part] && obj[part] !== Object.prototype[part]) {
        obj = obj[part];
      } else {
        obj = obj[part] = {};
      }
    }

    return obj;
  };

  $.ajaxSetup({
    data: {},
    type: 'POST'
  });
  $.ajaxPrefilter(function (options) {
    if (options.crossDomain) {
      options.contents.script = false;
    }

    if (options.url) {
      options.url = Liferay.Util.getURLWithSessionId(options.url);
    }
  });
  var jqueryInit = $.prototype.init;

  $.prototype.init = function (selector, context, root) {
    if (selector === '#') {
      selector = '';
    }

    return new jqueryInit(selector, context, root);
  };

  $(document).on('show.bs.collapse', function (event) {
    var target = $(event.target);
    var ancestor = target.parents('.panel-group');

    if (target.hasClass('panel-collapse') && ancestor.length) {
      var openChildren = ancestor.find('.panel-collapse.in').not(target);

      if (openChildren.length && ancestor.find('[data-parent="#' + ancestor.attr('id') + '"]').length) {
        openChildren.removeClass('in');
      }
    }

    if (target.hasClass('in')) {
      target.addClass('show');
      target.removeClass('in');
      target.collapse('hide');
      return false;
    }
  });
  $(document).on('show.bs.dropdown', function () {
    Liferay.fire('dropdownShow', {
      src: 'BootstrapDropdown'
    });
  });
  Liferay.on('dropdownShow', function (event) {
    if (event.src !== 'BootstrapDropdown') {
      $('.dropdown.show .dropdown-toggle').dropdown('toggle');
    }
  });
  $(document).on('shown.bs.dropdown', function () {
    var dropdown = document.querySelector('.dropdown-menu.show');
    var parent = dropdown.parentElement;

    if (dropdown && (parent.classList.contains('dropdown-action') || parent.nodeName === 'BODY')) {
      var _dropdown$getBounding = dropdown.getBoundingClientRect(),
          x = _dropdown$getBounding.x,
          y = _dropdown$getBounding.y;

      dropdown.style.left = x + 'px';
      dropdown.style.top = y + 'px';
      dropdown.style.transform = '';
      document.body.appendChild(dropdown);
    }
  });
  /**
   * OPTIONS
   *
   * Required
   * service {string|object}: Either the service name, or an object with the keys as the service to call, and the value as the service configuration object.
   *
   * Optional
   * data {object|node|string}: The data to send to the service. If the object passed is the ID of a form or a form element, the form fields will be serialized and used as the data.
   * successCallback {function}: A function to execute when the server returns a response. It receives a JSON object as it's first parameter.
   * exceptionCallback {function}: A function to execute when the response from the server contains a service exception. It receives a the exception message as it's first parameter.
   */

  var Service = function Service() {
    var instance = this;
    var args = Service.parseInvokeArgs(Array.prototype.slice.call(arguments, 0));
    return Service.invoke.apply(Service, args);
  };

  Service.URL_INVOKE = themeDisplay.getPathContext() + '/api/jsonws/invoke';

  Service.bind = function () {
    var args = Array.prototype.slice.call(arguments, 0);
    return function () {
      var newArgs = Array.prototype.slice.call(arguments, 0);
      return Service.apply(Service, args.concat(newArgs));
    };
  };

  Service.parseInvokeArgs = function (args) {
    var instance = this;
    var payload = args[0];
    var ioConfig = instance.parseIOConfig(args);

    if (typeof payload === 'string') {
      payload = instance.parseStringPayload(args);
      instance.parseIOFormConfig(ioConfig, args);
      var lastArg = args[args.length - 1];

      if (_typeof(lastArg) === 'object' && lastArg.method) {
        ioConfig.method = lastArg.method;
      }
    }

    return [payload, ioConfig];
  };

  Service.parseIOConfig = function (args) {
    var instance = this;
    var payload = args[0];
    var ioConfig = payload.io || {};
    delete payload.io;

    if (!ioConfig.success) {
      var callbacks = args.filter(isFunction);
      var callbackException = callbacks[1];
      var callbackSuccess = callbacks[0];

      if (!callbackException) {
        callbackException = callbackSuccess;
      }

      ioConfig.complete = function (xhr) {
        var response = xhr.responseJSON;

        if (response !== null && !response.hasOwnProperty('exception')) {
          if (callbackSuccess) {
            callbackSuccess.call(this, response);
          }
        } else if (callbackException) {
          var exception = response ? response.exception : 'The server returned an empty response';
          callbackException.call(this, exception, response);
        }
      };
    }

    if (!ioConfig.hasOwnProperty('cache') && REGEX_METHOD_GET.test(ioConfig.type)) {
      ioConfig.cache = false;
    }

    if (Liferay.PropsValues.NTLM_AUTH_ENABLED && Liferay.Browser.isIe()) {
      ioConfig.type = 'GET';
    }

    return ioConfig;
  };

  Service.parseIOFormConfig = function (ioConfig, args) {
    var instance = this;
    var form = args[1];

    if (isNode(form)) {
      ioConfig.form = form;

      if (ioConfig.form.enctype == STR_MULTIPART) {
        ioConfig.contentType = false;
        ioConfig.processData = false;
      }
    }
  };

  Service.parseStringPayload = function (args) {
    var params = {};
    var payload = {};
    var config = args[1];

    if (!isFunction(config) && !isNode(config)) {
      params = config;
    }

    payload[args[0]] = params;
    return payload;
  };

  Service.invoke = function (payload, ioConfig) {
    var instance = this;
    var cmd = JSON.stringify(payload);
    var p_auth = Liferay.authToken;
    ioConfig = Object.assign({
      data: {
        cmd: cmd,
        p_auth: p_auth
      },
      dataType: 'JSON'
    }, ioConfig);

    if (ioConfig.form) {
      if (ioConfig.form.enctype == STR_MULTIPART && isFunction(window.FormData)) {
        ioConfig.data = new FormData(ioConfig.form);
        ioConfig.data.append('cmd', cmd);
        ioConfig.data.append('p_auth', p_auth);
      } else {
        $(ioConfig.form).serializeArray().forEach(function (item) {
          ioConfig.data[item.name] = item.value;
        });
      }

      delete ioConfig.form;
    }

    return $.ajax(instance.URL_INVOKE, ioConfig);
  };

  ['get', 'delete', 'post', 'put', 'update'].forEach(function (item) {
    var methodName = item;

    if (item === 'delete') {
      methodName = 'del';
    }

    Service[methodName] = function () {
      var args = Array.prototype.slice.call(arguments, 0);
      var method = {
        method: item
      };
      args.push(method);
      return Service.apply(Service, args);
    };
  });
  Liferay.Service = Service;
  var componentDestroyConfigs = {};
  var componentPromiseWrappers = {};
  var components = {};
  var componentsFn = {};

  var _createPromiseWrapper = function _createPromiseWrapper(value) {
    var promiseWrapper;

    if (value) {
      promiseWrapper = {
        promise: Promise.resolve(value),
        resolve: function resolve() {}
      };
    } else {
      var promiseResolve;
      var promise = new Promise(function (resolve) {
        promiseResolve = resolve;
      });
      promiseWrapper = {
        promise: promise,
        resolve: promiseResolve
      };
    }

    return promiseWrapper;
  };

  Liferay.component = function (id, value, destroyConfig) {
    var retVal;

    if (arguments.length === 1) {
      var component = components[id];

      if (component && isFunction(component)) {
        componentsFn[id] = component;
        component = component();
        components[id] = component;
      }

      retVal = component;
    } else {
      if (components[id] && value !== null) {
        delete componentDestroyConfigs[id];
        delete componentPromiseWrappers[id];
        console.warn('Component with id "' + id + '" is being registered twice. This can lead to unexpected behaviour in the "Liferay.component" and "Liferay.componentReady" APIs, as well as in the "*:registered" events.');
      }

      retVal = components[id] = value;

      if (value === null) {
        delete componentDestroyConfigs[id];
        delete componentPromiseWrappers[id];
      } else {
        componentDestroyConfigs[id] = destroyConfig;
        Liferay.fire(id + ':registered');
        var componentPromiseWrapper = componentPromiseWrappers[id];

        if (componentPromiseWrapper) {
          componentPromiseWrapper.resolve(value);
        } else {
          componentPromiseWrappers[id] = _createPromiseWrapper(value);
        }
      }
    }

    return retVal;
  };
  /**
   * Retrieves a list of component instances after they've been registered.
   *
   * @param {...string} componentId The ids of the components to be received
   * @return {Promise} A promise to be resolved with all the requested component
   * instances after they've been successfully registered
   * @review
   */


  Liferay.componentReady = function () {
    var component;
    var componentPromise;

    if (arguments.length === 1) {
      component = arguments[0];
    } else {
      component = [];

      for (var i = 0; i < arguments.length; i++) {
        component[i] = arguments[i];
      }
    }

    if (Array.isArray(component)) {
      componentPromise = Promise.all(component.map(function (id) {
        return Liferay.componentReady(id);
      }));
    } else {
      var componentPromiseWrapper = componentPromiseWrappers[component];

      if (!componentPromiseWrapper) {
        componentPromiseWrappers[component] = componentPromiseWrapper = _createPromiseWrapper();
      }

      componentPromise = componentPromiseWrapper.promise;
    }

    return componentPromise;
  };
  /**
   * Destroys the component registered by the provided component id. Invokes the
   * component's own destroy lifecycle methods (destroy or dispose) and deletes
   * the internal references to the component in the component registry.
   *
   * @param {string} componentId The id of the component to destroy
   * @review
   */


  Liferay.destroyComponent = function (componentId) {
    var component = components[componentId];

    if (component) {
      var destroyFn = component.destroy || component.dispose;

      if (destroyFn) {
        destroyFn.call(component);
      }

      delete componentDestroyConfigs[componentId];
      delete componentPromiseWrappers[componentId];
      delete componentsFn[componentId];
      delete components[componentId];
    }
  };
  /**
   * Destroys registered components matching the provided filter function. If
   * no filter function is provided, it will destroy all registered components.
   *
   * @param {Function} filterFn A method that receives a component destroy options
   * and the component itself and returns true if the component should be destroyed
   * @review
   */


  Liferay.destroyComponents = function (filterFn) {
    var componentIds = Object.keys(components);

    if (filterFn) {
      componentIds = componentIds.filter(function (componentId) {
        return filterFn(components[componentId], componentDestroyConfigs[componentId] || {});
      });
    }

    componentIds.forEach(Liferay.destroyComponent);
  };
  /**
   * Clears the component promises map to make sure pending promises won't get
   * accidentally resolved at a later stage if a component with the same id appears
   * causing stale code to run.
   */


  Liferay.destroyUnfulfilledPromises = function () {
    componentPromiseWrappers = {};
  };

  Liferay._components = components;
  Liferay._componentsFn = components;
  Liferay.Template = {
    PORTLET: '<div class="portlet"><div class="portlet-topper"><div class="portlet-title"></div></div><div class="portlet-content"></div><div class="forbidden-action"></div></div>'
  };
})(AUI.$, Liferay);

(function (A, Liferay) {
  A.mix(A.namespace('config.io'), {
    method: 'POST',
    uriFormatter: function uriFormatter(value) {
      return Liferay.Util.getURLWithSessionId(value);
    }
  }, true);
})(AUI(), Liferay);
//# sourceMappingURL=liferay.js.map
;(function(A, $, Liferay) {
	A.use('aui-base-lang');

	var AArray = A.Array;

	var Lang = A.Lang;

	var EVENT_CLICK = 'click';

	var MAP_TOGGLE_STATE = {
		false: {
			cssClass: 'controls-hidden',
			iconCssClass: 'hidden',
			state: 'hidden'
		},
		true: {
			cssClass: 'controls-visible',
			iconCssClass: 'view',
			state: 'visible'
		}
	};

	var REGEX_PORTLET_ID = /^(?:p_p_id)?_(.*)_.*$/;

	var REGEX_SUB = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g;

	var SRC_HIDE_LINK = {
		src: 'hideLink'
	};

	var STR_CHECKED = 'checked';

	var STR_RIGHT_SQUARE_BRACKET = ']';

	var TPL_LEXICON_ICON = '<svg class="lexicon-icon lexicon-icon-{0} {1}" focusable="false" role="image">' +
			'<use data-href="' + themeDisplay.getPathThemeImages() + '/lexicon/icons.svg#{0}" />' +
			'<title>{0}</title>' +
		'</svg>';

	var Window = {
		getById: function(id) {
			var instance = this;

			return instance._map[id];
		},

		_map: {}
	};

	var Util = {
		submitCountdown: 0,

		addInputCancel: function() {
			A.use(
				'aui-button-search-cancel',
				function(A) {
					new A.ButtonSearchCancel(
						{
							trigger: 'input[type=password], input[type=search], input.clearable, input.search-query'
						}
					);
				}
			);

			Util.addInputCancel = function() {
			};
		},

		addParams: function(params, url) {
			if (typeof params === 'object') {
				params = $.param(params, true);
			}
			else {
				params = String(params).trim();
			}

			var loc = url || location.href;

			var finalUrl = loc;

			if (params) {
				var anchorHash;

				if (loc.indexOf('#') > -1) {
					var locationPieces = loc.split('#');

					loc = locationPieces[0];
					anchorHash = locationPieces[1];
				}

				if (loc.indexOf('?') == -1) {
					params = '?' + params;
				}
				else {
					params = '&' + params;
				}

				if (loc.indexOf(params) == -1) {
					finalUrl = loc + params;

					if (anchorHash) {
						finalUrl += '#' + anchorHash;
					}
					if (!url) {
						location.href = finalUrl;
					}

				}
			}

			return finalUrl;
		},

		checkAll: function(form, name, allBox, selectClassName) {
			if (form) {
				form = Util.getDOM(form);
				allBox = Util.getDOM(allBox);

				var selector;

				if (Array.isArray(name)) {
					selector = 'input[name=' + name.join('], input[name=') + STR_RIGHT_SQUARE_BRACKET;
				}
				else {
					selector = 'input[name=' + name + STR_RIGHT_SQUARE_BRACKET;
				}

				form = $(form);

				var allBoxChecked = $(allBox).prop(STR_CHECKED);

				form.find(selector).each(
					function(index, item) {
						item = $(item);

						if (!item.prop('disabled')) {
							item.prop(STR_CHECKED, allBoxChecked);
						}
					}
				);

				if (selectClassName) {
					form.find(selectClassName).toggleClass('info', allBoxChecked);
				}
			}
		},

		checkAllBox: function(form, name, allBox) {
			var totalOn = 0;

			if (form) {
				form = Util.getDOM(form);
				allBox = Util.getDOM(allBox);

				form = $(form);

				var allBoxNodes = $(allBox);

				if (!allBoxNodes.length) {
					allBoxNodes = form.find('input[name="' + allBox + '"]');
				}

				var totalBoxes = 0;

				var inputs = form.find('input[type=checkbox]');

				if (!Array.isArray(name)) {
					name = [name];
				}

				inputs.each(
					function(index, item) {
						item = $(item);

						if (!item.is(allBoxNodes) && name.indexOf(item.attr('name')) > -1) {
							totalBoxes++;

							if (item.prop(STR_CHECKED)) {
								totalOn++;
							}
						}
					}
				);

				allBoxNodes.prop(STR_CHECKED, totalBoxes == totalOn);
			}

			return totalOn;
		},

		checkTab: function(box) {
			if (document.all && window.event.keyCode == 9) {
				box.selection = document.selection.createRange();

				setTimeout(
					function() {
						Util.processTab(box.id);
					},
					0
				);
			}
		},

		disableElements: function(el) {
			var currentElement = $(el)[0];

			if (currentElement) {
				var children = currentElement.getElementsByTagName('*');

				var emptyFnFalse = function() {
					return false;
				};

				for (var i = children.length - 1; i >= 0; i--) {
					var item = children[i];

					item.style.cursor = 'default';

					item.onclick = emptyFnFalse;
					item.onmouseover = emptyFnFalse;
					item.onmouseout = emptyFnFalse;
					item.onmouseenter = emptyFnFalse;
					item.onmouseleave = emptyFnFalse;

					item.action = '';
					item.disabled = true;
					item.href = 'javascript:;';
					item.onsubmit = emptyFnFalse;

					$(item).off();
				}
			}
		},

		disableEsc: function() {
			if (document.all && window.event.keyCode == 27) {
				window.event.returnValue = false;
			}
		},

		disableFormButtons: function(inputs, form) {
			inputs.attr('disabled', true);
			inputs.setStyle('opacity', 0.5);

			if (A.UA.gecko) {
				A.getWin().on(
					'unload',
					function(event) {
						inputs.attr('disabled', false);
					}
				);
			}
			else if (A.UA.safari) {
				A.use(
					'node-event-html5',
					function(A) {
						A.getWin().on(
							'pagehide',
							function(event) {
								Util.enableFormButtons(inputs, form);
							}
						);
					}
				);
			}
		},

		disableToggleBoxes: function(checkBoxId, toggleBoxId, checkDisabled) {
			var checkBox = $('#' + checkBoxId);
			var toggleBox = $('#' + toggleBoxId);

			toggleBox.prop('disabled', checkDisabled && checkBox.prop(STR_CHECKED));

			checkBox.on(
				EVENT_CLICK,
				function() {
					toggleBox.prop('disabled', !toggleBox.prop('disabled'));
				}
			);
		},

		enableFormButtons: function(inputs) {
			Util._submitLocked = null;

			Util.toggleDisabled(inputs, false);
		},

		escapeCDATA: function(str) {
			return str.replace(
				/<!\[CDATA\[|\]\]>/gi,
				function(match) {
					var str = '';

					if (match == ']]>') {
						str = ']]&gt;';
					}
					else if (match == '<![CDATA[') {
						str = '&lt;![CDATA[';
					}

					return str;
				}
			);
		},

		focusFormField: function(el) {
			var doc = $(document);

			var interacting = false;

			el = Util.getDOM(el);

			el = $(el);

			doc.on(
				'click.focusFormField',
				function(event) {
					interacting = true;

					doc.off('click.focusFormField');
				}
			);

			if (!interacting && Util.inBrowserView(el)) {
				var form = el.closest('form');

				var focusable = !el.is(':disabled') && !el.is(':hidden') && !el.parents(':disabled').length;

				if (!form.length || focusable) {
					el.focus();
				}
				else {
					var portletName = form.data('fm-namespace');

					var formReadyEventName = portletName + 'formReady';

					var formReadyHandler = function(event) {
						var elFormName = form.attr('name');
						var formName = event.formName;

						if (elFormName === formName) {
							el.focus();

							Liferay.detach(formReadyEventName, formReadyHandler);
						}
					};

					Liferay.on(formReadyEventName, formReadyHandler);
				}
			}
		},

		forcePost: function(link) {
			link = Util.getDOM(link);

			link = $(link);

			if (link.length) {
				var url = link.attr('href');

				// LPS-127302

				if (url === 'javascript:;') {
					return;
				}

				var newWindow = link.attr('target') == '_blank';

				var hrefFm = $(document.hrefFm);

				if (newWindow) {
					hrefFm.attr('target', '_blank');
				}

				submitForm(hrefFm, url, !newWindow);

				Util._submitLocked = null;
			}
		},

		getAttributes: function(el, attributeGetter) {
			var instance = this;

			var result = null;

			if (el) {
				el = Util.getDOM(el);

				if (el.jquery) {
					el = el[0];
				}

				result = {};

				var getterFn = this.isFunction(attributeGetter);
				var getterString = typeof attributeGetter === 'string';

				var attrs = el.attributes;
				var length = attrs.length;

				while (length--) {
					var attr = attrs[length];
					var name = attr.nodeName.toLowerCase();
					var value = attr.nodeValue;

					if (getterString) {
						if (name.indexOf(attributeGetter) === 0) {
							name = name.substr(attributeGetter.length);
						}
						else {
							continue;
						}
					}
					else if (getterFn) {
						value = attributeGetter(value, name, attrs);

						if (value === false) {
							continue;
						}
					}

					result[name] = value;
				}
			}

			return result;
		},

		getColumnId: function(str) {
			var columnId = str.replace(/layout-column_/, '');

			return columnId;
		},

		getDOM: function(el) {
			if (el._node || el._nodes) {
				el = el.getDOM();
			}

			return el;
		},

		getGeolocation: function(success, fallback, options) {
			if (success && navigator.geolocation) {
				navigator.geolocation.getCurrentPosition(
					function(position) {
						success(
							position.coords.latitude,
							position.coords.longitude,
							position
						);
					},
					fallback,
					options
				);
			}
			else if (fallback) {
				fallback();
			}
		},

		getLexiconIcon: function(icon, cssClass) {
			var instance = this;

			return $(instance.getLexiconIconTpl(icon, cssClass))[0];
		},

		getLexiconIconTpl: function(icon, cssClass) {
			var instance = this;

			return Liferay.Util.sub(TPL_LEXICON_ICON, icon, cssClass || '');
		},

		getOpener: function() {
			var openingWindow = Window._opener;

			if (!openingWindow) {
				var topUtil = Liferay.Util.getTop().Liferay.Util;

				var windowName = Liferay.Util.getWindowName();

				var dialog = topUtil.Window.getById(windowName);

				if (dialog) {
					openingWindow = dialog._opener;

					Window._opener = openingWindow;
				}
			}

			return openingWindow || window.opener || window.parent;
		},

		getPortletId: function(portletId) {
			return String(portletId).replace(REGEX_PORTLET_ID, '$1');
		},

		getPortletNamespace: function(portletId) {
			return '_' + portletId + '_';
		},

		getTop: function() {
			var topWindow = Util._topWindow;

			if (!topWindow) {
				var parentWindow = window.parent;

				var parentThemeDisplay;

				while (parentWindow != window) {
					try {
						if (typeof parentWindow.location.href == 'undefined') {
							break;
						}

						parentThemeDisplay = parentWindow.themeDisplay;
					}
					catch (e) {
						break;
					}

					if (!parentThemeDisplay || window.name === 'simulationDeviceIframe') {
						break;
					}
					else if (!parentThemeDisplay.isStatePopUp() || parentWindow == parentWindow.parent) {
						topWindow = parentWindow;

						break;
					}

					parentWindow = parentWindow.parent;
				}

				if (!topWindow) {
					topWindow = window;
				}

				Util._topWindow = topWindow;
			}

			return topWindow;
		},

		getURLWithSessionId: function(url) {
			if (!themeDisplay.isAddSessionIdToURL()) {
				return url;
			}

			// LEP-4787

			var x = url.indexOf(';');

			if (x > -1) {
				return url;
			}

			var sessionId = ';jsessionid=' + themeDisplay.getSessionId();

			x = url.indexOf('?');

			if (x > -1) {
				return url.substring(0, x) + sessionId + url.substring(x);
			}

			// In IE6, http://www.abc.com;jsessionid=XYZ does not work, but
			// http://www.abc.com/;jsessionid=XYZ does work.

			x = url.indexOf('//');

			if (x > -1) {
				var y = url.lastIndexOf('/');

				if (x + 1 == y) {
					return url + '/' + sessionId;
				}
			}

			return url + sessionId;
		},

		getWindow: function(id) {
			if (!id) {
				id = Util.getWindowName();
			}

			return Util.getTop().Liferay.Util.Window.getById(id);
		},

		getWindowName: function() {
			return window.name || Window._name || '';
		},

		getWindowWidth: function() {
			return window.innerWidth > 0 ? window.innerWidth : screen.width;
		},

		inBrowserView: function(node, win, nodeRegion) {
			var viewable = false;

			node = $(node);

			if (node.length) {
				if (!nodeRegion) {
					nodeRegion = node.offset();

					nodeRegion.bottom = nodeRegion.top + node.outerHeight();
					nodeRegion.right = nodeRegion.left + node.outerWidth();
				}

				if (!win) {
					win = window;
				}

				win = $(win);

				var winRegion = {};

				winRegion.left = win.scrollLeft();
				winRegion.right = winRegion.left + win.width();

				winRegion.top = win.scrollTop();
				winRegion.bottom = winRegion.top + win.height();

				viewable = nodeRegion.bottom <= winRegion.bottom &&
					nodeRegion.left >= winRegion.left &&
					nodeRegion.right <= winRegion.right &&
					nodeRegion.top >= winRegion.top;

				if (viewable) {
					var frameEl = $(win.prop('frameElement'));

					if (frameEl.length) {
						var frameOffset = frameEl.offset();

						var xOffset = frameOffset.left - winRegion.left;

						nodeRegion.left += xOffset;
						nodeRegion.right += xOffset;

						var yOffset = frameOffset.top - winRegion.top;

						nodeRegion.top += yOffset;
						nodeRegion.bottom += yOffset;

						viewable = Util.inBrowserView(node, win.prop('parent'), nodeRegion);
					}
				}
			}

			return viewable;
		},

		isFunction: function(val) {
			return typeof val === 'function';
		},

		isPhone: function() {
			var instance = this;

			return instance.getWindowWidth() < Liferay.BREAKPOINTS.PHONE;
		},

		isTablet: function() {
			var instance = this;

			return instance.getWindowWidth() < Liferay.BREAKPOINTS.TABLET;
		},

		listCheckboxesExcept: function(form, except, name, checked) {
			form = Util.getDOM(form);

			var selector = 'input[type=checkbox]';

			if (name) {
				selector += '[name=' + name + ']';
			}

			return $(form).find(selector).toArray().reduce(
				function(prev, item, index) {
					item = $(item);

					var val = item.val();

					if (val && item.attr('name') != except && item.prop('checked') == checked && !item.prop('disabled')) {
						prev.push(val);
					}

					return prev;
				},
				[]
			).join();
		},

		listCheckedExcept: function(form, except, name) {
			return Util.listCheckboxesExcept(form, except, name, true);
		},

		listSelect: function(select, delimeter) {
			select = Util.getDOM(select);

			return $(select).find('option').toArray().reduce(
				function(prev, item, index) {
					var val = $(item).val();

					if (val) {
						prev.push(val);
					}

					return prev;
				},
				[]
			).join(delimeter || ',');
		},

		listUncheckedExcept: function(form, except, name) {
			return Util.listCheckboxesExcept(form, except, name, false);
		},

		normalizeFriendlyURL: function(text) {
			var newText = text.replace(/[^a-zA-Z0-9_-]/g, '-');

			if (newText[0] === '-') {
				newText = newText.replace(/^-+/, '');
			}

			newText = newText.replace(/--+/g, '-');

			return newText.toLowerCase();
		},

		openInDialog: function(event, config) {
			event.preventDefault();

			var currentTarget = Util.getDOM(event.currentTarget);

			currentTarget = $(currentTarget);

			config = A.mix(A.merge({}, currentTarget.data()), config);

			if (!config.uri) {
				config.uri = currentTarget.data('href') || currentTarget.attr('href');
			}

			if (!config.title) {
				config.title = currentTarget.attr('title');
			}

			Liferay.Util.openWindow(config);
		},

		openWindow: function(config, callback) {
			config.openingWindow = window;

			var top = Util.getTop();

			var topUtil = top.Liferay.Util;

			topUtil._openWindowProvider(config, callback);
		},

		processTab: function(id) {
			document.all[id].selection.text = String.fromCharCode(9);
			document.all[id].focus();
		},

		randomInt: function() {
			return Math.ceil(Math.random() * (new Date()).getTime());
		},

		removeEntitySelection: function(entityIdString, entityNameString, removeEntityButton, namespace) {
			$('#' + namespace + entityIdString).val(0);

			$('#' + namespace + entityNameString).val('');

			Liferay.Util.toggleDisabled(removeEntityButton, true);

			Liferay.fire('entitySelectionRemoved');
		},

		reorder: function(box, down) {
			box = Util.getDOM(box);

			box = $(box);

			if (box.prop('selectedIndex') == -1) {
				box.prop('selectedIndex', 0);
			}
			else {
				var selectedItems = box.find('option:selected');

				if (down) {
					selectedItems.get().reverse().forEach(
						function(item, index) {
							item = $(item);

							var itemIndex = item.prop('index');

							var lastIndex = box.find('option').length - 1;

							if (itemIndex === lastIndex) {
								box.prepend(item);
							}
							else {
								item.insertAfter(item.next());
							}
						}
					);
				}
				else {
					selectedItems.get().forEach(
						function(item, index) {
							item = $(item);

							var itemIndex = item.prop('index');

							if (itemIndex === 0) {
								box.append(item);
							}
							else {
								item.insertBefore(item.prev());
							}
						}
					);
				}
			}
		},

		rowCheckerCheckAllBox: function(ancestorTable, ancestorRow, checkboxesIds, checkboxAllIds, cssClass) {
			Util.checkAllBox(ancestorTable, checkboxesIds, checkboxAllIds);

			if (ancestorRow) {
				ancestorRow.toggleClass(cssClass);
			}
		},

		savePortletTitle: function(params) {
			params = Object.assign(
				{
					doAsUserId: 0,
					plid: 0,
					portletId: 0,
					title: '',
					url: themeDisplay.getPathMain() + '/portal/update_portlet_title'
				},
				params
			);

			$.ajax(
				params.url,
				{
					data: {
						doAsUserId: params.doAsUserId,
						p_auth: Liferay.authToken,
						p_l_id: params.plid,
						portletId: params.portletId,
						title: params.title
					}
				}
			);
		},

		selectEntityHandler: function(container, selectEventName, disableButton) {
			container = $(container);

			var openingLiferay = Util.getOpener().Liferay;

			var selectorButtons = container.find('.selector-button');

			container.on(
				'click',
				'.selector-button',
				function(event) {
					var target = $(event.target);

					if (!target.attr('data-prevent-selection')) {
						var currentTarget = $(event.currentTarget);

						var confirmSelection = currentTarget.attr('data-confirm-selection') === 'true';
						var confirmSelectionMessage = currentTarget.attr('data-confirm-selection-message');

						if (!confirmSelection || confirm(confirmSelectionMessage)) {
							if (disableButton !== false) {
								selectorButtons.prop('disabled', false);

								currentTarget.prop('disabled', true);
							}

							var result = Util.getAttributes(currentTarget, 'data-');

							openingLiferay.fire(selectEventName, result);

							Util.getWindow().hide();
						}
					}
				}
			);

			openingLiferay.on(
				'entitySelectionRemoved',
				function(event) {
					selectorButtons.prop('disabled', false);
				}
			);
		},

		selectFolder: function(folderData, namespace) {
			$('#' + namespace + folderData.idString).val(folderData.idValue);

			var name = Liferay.Util.unescape(folderData.nameValue);

			$('#' + namespace + folderData.nameString).val(name);

			var button = $('#' + namespace + 'removeFolderButton');

			Liferay.Util.toggleDisabled(button, false);
		},

		setCursorPosition: function(el, position) {
			var instance = this;

			instance.setSelectionRange(el, position, position);
		},

		setSelectionRange: function(el, selectionStart, selectionEnd) {
			var instance = this;

			el = Util.getDOM(el);

			if (el.jquery) {
				el = el[0];
			}

			if (el.setSelectionRange) {
				el.focus();

				el.setSelectionRange(selectionStart, selectionEnd);
			}
			else if (el.createTextRange) {
				var textRange = el.createTextRange();

				textRange.collapse(true);

				textRange.moveEnd('character', selectionEnd);
				textRange.moveEnd('character', selectionStart);

				textRange.select();
			}
		},

		showCapsLock: function(event, span) {
			var keyCode = event.keyCode ? event.keyCode : event.which;

			var shiftKeyCode = keyCode === 16;

			var shiftKey = event.shiftKey ? event.shiftKey : shiftKeyCode;

			var display = 'none';

			if (keyCode >= 65 && keyCode <= 90 && !shiftKey || keyCode >= 97 && keyCode <= 122 && shiftKey) {
				display = '';
			}

			$('#' + span).css('display', display);
		},

		sortByAscending: function(a, b) {
			a = a[1].toLowerCase();
			b = b[1].toLowerCase();

			if (a > b) {
				return 1;
			}

			if (a < b) {
				return -1;
			}

			return 0;
		},

		sub: function(string, data) {
			if (arguments.length > 2 || (typeof data !== 'object' && typeof data !== 'function')) {
				data = Array.prototype.slice.call(arguments, 1);
			}

			return string.replace ? string.replace(
				REGEX_SUB,
				function(match, key) {
					return data[key] === undefined ? match : data[key];
				}
			) : string;
		},

		submitForm: function(form) {
			form.submit();
		},

		toggleBoxes: function(checkBoxId, toggleBoxId, displayWhenUnchecked, toggleChildCheckboxes) {
			var checkBox = $('#' + checkBoxId);
			var toggleBox = $('#' + toggleBoxId);

			var checked = checkBox.prop(STR_CHECKED);

			if (displayWhenUnchecked) {
				checked = !checked;
			}

			toggleBox.toggleClass('hide', !checked);

			checkBox.on(
				EVENT_CLICK,
				function() {
					toggleBox.toggleClass('hide');

					if (toggleChildCheckboxes) {
						var childCheckboxes = toggleBox.find('input[type=checkbox]');

						childCheckboxes.prop(STR_CHECKED, checkBox.prop(STR_CHECKED));
					}
				}
			);
		},

		toggleDisabled: function(button, state) {
			button = Util.getDOM(button);

			button = $(button);

			button.each(
				function(index, item) {
					item = $(item);

					item.prop('disabled', state);

					item.toggleClass('disabled', state);
				}
			);
		},

		toggleRadio: function(radioId, showBoxIds, hideBoxIds) {
			var radioButton = $('#' + radioId);

			var showBoxes;

			if (showBoxIds) {
				if (Array.isArray(showBoxIds)) {
					showBoxIds = showBoxIds.join(',#');
				}

				showBoxes = $('#' + showBoxIds);

				showBoxes.toggleClass('hide', !radioButton.prop(STR_CHECKED));
			}

			radioButton.on(
				'change',
				function() {
					if (showBoxes) {
						showBoxes.removeClass('hide');
					}

					if (hideBoxIds) {
						if (Array.isArray(hideBoxIds)) {
							hideBoxIds = hideBoxIds.join(',#');
						}

						$('#' + hideBoxIds).addClass('hide');
					}
				}
			);
		},

		toggleSearchContainerButton: function(buttonId, searchContainerId, form, ignoreFieldName) {
			$(searchContainerId).on(
				EVENT_CLICK,
				'input[type=checkbox]',
				function() {
					Util.toggleDisabled(buttonId, !Util.listCheckedExcept(form, ignoreFieldName));
				}
			);
		},

		toggleSelectBox: function(selectBoxId, value, toggleBoxId) {
			var selectBox = $('#' + selectBoxId);
			var toggleBox = $('#' + toggleBoxId);

			var dynamicValue = this.isFunction(value);

			var toggle = function() {
				var currentValue = selectBox.val();

				var visible = value == currentValue;

				if (dynamicValue) {
					visible = value(currentValue, value);
				}

				toggleBox.toggleClass('hide', !visible);
			};

			toggle();

			selectBox.on('change', toggle);
		},

		toNumber: function(value) {
			return parseInt(value, 10) || 0;
		},

		_defaultPreviewArticleFn: function(event) {
			var instance = this;

			event.preventDefault();

			Util.defaultPreviewArticleFn(event);
		},

		_defaultSubmitFormFn: function(event) {
			var form = event.form;

			var hasErrors = false;

			if (event.validate) {
				var liferayForm = Liferay.Form.get(form.attr('id'));

				if (liferayForm) {
					var validator = liferayForm.formValidator;

					if (A.instanceOf(validator, A.FormValidator)) {
						validator.validate();

						hasErrors = validator.hasErrors();

						if (hasErrors) {
							validator.focusInvalidField();
						}
					}
				}
			}

			if (!hasErrors) {
				var action = event.action || form.getAttribute('action');

				var singleSubmit = event.singleSubmit;

				var inputs = form.all('button[type=submit], input[type=button], input[type=image], input[type=reset], input[type=submit]');

				Util.disableFormButtons(inputs, form);

				if (singleSubmit === false) {
					Util._submitLocked = A.later(
						1000,
						Util,
						Util.enableFormButtons,
						[inputs, form]
					);
				}
				else {
					Util._submitLocked = true;
				}

				var actionURL = new A.Url(action);

				var authToken = actionURL.getParameter('p_auth') || '';

				form.append('<input name="p_auth" type="hidden" value="' + authToken + '" />');

				if (authToken) {
					actionURL.removeParameter('p_auth');

					action = actionURL.toString();
				}

				form.attr('action', action);

				Util.submitForm(form);

				form.attr('target', '');

				Util._submitLocked = null;
			}
		},

		_getEditableInstance: function(title) {
			var editable = Util._EDITABLE;

			if (!editable) {
				editable = new A.Editable(
					{
						after: {
							contentTextChange: function(event) {
								var instance = this;

								if (!event.initial) {
									var title = instance.get('node');

									var portletTitleEditOptions = title.getData('portletTitleEditOptions');

									Util.savePortletTitle(
										{
											doAsUserId: portletTitleEditOptions.doAsUserId,
											plid: portletTitleEditOptions.plid,
											portletId: portletTitleEditOptions.portletId,
											title: event.newVal
										}
									);
								}
							},
							startEditing: function(event) {
								var instance = this;

								var Layout = Liferay.Layout;

								if (Layout) {
									instance._dragListener = Layout.getLayoutHandler().on(
										'drag:start',
										function(event) {
											instance.fire('save');
										}
									);
								}
							},
							stopEditing: function(event) {
								var instance = this;

								if (instance._dragListener) {
									instance._dragListener.detach();
								}
							}
						},
						cssClass: 'lfr-portlet-title-editable',
						node: title
					}
				);

				Util._EDITABLE = editable;
			}

			return editable;
		}
	};

	Liferay.provide(
		Util,
		'afterIframeLoaded',
		function(event) {
			var nodeInstances = A.Node._instances;

			var docEl = event.doc;

			var docUID = docEl._yuid;

			if (docUID in nodeInstances) {
				delete nodeInstances[docUID];
			}

			var iframeDocument = A.one(docEl);

			var iframeBody = iframeDocument.one('body');

			var dialog = event.dialog;

			var lfrFormContent = iframeBody.one('.lfr-form-content');

			iframeBody.addClass('dialog-iframe-popup');

			if (lfrFormContent && iframeBody.one('.button-holder.dialog-footer')) {
				iframeBody.addClass('dialog-with-footer');

				var stagingAlert = iframeBody.one('.portlet-body > .lfr-portlet-message-staging-alert');

				if (stagingAlert) {
					stagingAlert.remove();

					lfrFormContent.prepend(stagingAlert);
				}
			}

			iframeBody.addClass(dialog.iframeConfig.bodyCssClass);

			event.win.focus();

			var detachEventHandles = function() {
				AArray.invoke(eventHandles, 'detach');

				iframeDocument.purge(true);
			};

			var eventHandles = [
				iframeBody.delegate('submit', detachEventHandles, 'form'),

				iframeBody.delegate(
					EVENT_CLICK,
					function(event) {
						dialog.set(
							'visible',
							false,
							event.currentTarget.hasClass('lfr-hide-dialog') ? SRC_HIDE_LINK : null
						);

						detachEventHandles();
					},
					'.btn-cancel,.lfr-hide-dialog'
				)
			];
		},
		['aui-base']
	);

	Liferay.provide(
		Util,
		'openDDMPortlet',
		function(config, callback) {
			var instance = this;

			var defaultValues = {
				eventName: 'selectStructure'
			};

			config = A.merge(defaultValues,	config);

			var ddmURL;

			if (config.basePortletURL) {
				ddmURL = Liferay.PortletURL.createURL(config.basePortletURL);
			}
			else {
				ddmURL = Liferay.PortletURL.createRenderURL();
			}

			ddmURL.setEscapeXML(false);

			ddmURL.setDoAsGroupId(config.doAsGroupId || themeDisplay.getScopeGroupId());

			ddmURL.setParameter('classNameId', config.classNameId);
			ddmURL.setParameter('classPK', config.classPK);
			ddmURL.setParameter('resourceClassNameId', config.resourceClassNameId);
			ddmURL.setParameter('eventName', config.eventName);
			ddmURL.setParameter('groupId', config.groupId);
			ddmURL.setParameter('mode', config.mode);

			if (config.mvcPath) {
				ddmURL.setParameter('mvcPath', config.mvcPath);
			}
			else {
				ddmURL.setParameter('mvcPath', '/view.jsp');
			}

			if ('navigationStartsOn' in config) {
				ddmURL.setParameter('navigationStartsOn', config.navigationStartsOn);
			}

			ddmURL.setParameter('portletResourceNamespace', config.portletResourceNamespace);

			if ('redirect' in config) {
				ddmURL.setParameter('redirect', config.redirect);
			}

			if ('refererPortletName' in config) {
				ddmURL.setParameter('refererPortletName', config.refererPortletName);
			}

			if ('refererWebDAVToken' in config) {
				ddmURL.setParameter('refererWebDAVToken', config.refererWebDAVToken);
			}

			ddmURL.setParameter('scopeTitle', config.title);

			if ('searchRestriction' in config) {
				ddmURL.setParameter('searchRestriction', config.searchRestriction);
				ddmURL.setParameter('searchRestrictionClassNameId', config.searchRestrictionClassNameId);
				ddmURL.setParameter('searchRestrictionClassPK', config.searchRestrictionClassPK);
			}

			if ('showAncestorScopes' in config) {
				ddmURL.setParameter('showAncestorScopes', config.showAncestorScopes);
			}

			if ('showBackURL' in config) {
				ddmURL.setParameter('showBackURL', config.showBackURL);
			}

			if ('showCacheableInput' in config) {
				ddmURL.setParameter('showCacheableInput', config.showCacheableInput);
			}

			if ('showHeader' in config) {
				ddmURL.setParameter('showHeader', config.showHeader);
			}

			if ('showManageTemplates' in config) {
				ddmURL.setParameter('showManageTemplates', config.showManageTemplates);
			}

			ddmURL.setParameter('structureAvailableFields', config.structureAvailableFields);
			ddmURL.setParameter('templateId', config.templateId);

			ddmURL.setPortletId(Liferay.PortletKeys.DYNAMIC_DATA_MAPPING);
			ddmURL.setWindowState('pop_up');

			config.uri = ddmURL.toString();

			var dialogConfig = config.dialog;

			if (!dialogConfig) {
				dialogConfig = {};

				config.dialog = dialogConfig;
			}

			var eventHandles = [];

			if (callback) {
				eventHandles.push(Liferay.once(config.eventName, callback));
			}

			var detachSelectionOnHideFn = function(event) {
				Liferay.fire(config.eventName);

				if (!event.newVal) {
					(new A.EventHandle(eventHandles)).detach();
				}
			};

			Util.openWindow(
				config,
				function(dialogWindow) {
					eventHandles.push(dialogWindow.after(['destroy', 'visibleChange'], detachSelectionOnHideFn));
				}
			);
		},
		['liferay-portlet-url']
	);

	Liferay.provide(
		Util,
		'openDocument',
		function(webDavUrl, onSuccess, onError) {
			if (A.UA.ie) {
				try {
					var executor = new A.config.win.ActiveXObject('SharePoint.OpenDocuments');

					executor.EditDocument(webDavUrl);

					if (Lang.isFunction(onSuccess)) {
						onSuccess();
					}

				}
				catch (e) {
					if (Lang.isFunction(onError)) {
						onError(e);
					}
				}
			}
		},
		['aui-base']
	);

	Liferay.provide(
		Util,
		'portletTitleEdit',
		function(options) {
			var obj = options.obj;

			if (obj) {
				var title = obj.one('.portlet-title-text');

				if (title && !title.hasClass('not-editable')) {
					title.addClass('portlet-title-editable');

					title.on(
						EVENT_CLICK,
						function(event) {
							var editable = Util._getEditableInstance(title);

							var rendered = editable.get('rendered');

							if (rendered) {
								editable.fire('stopEditing');
							}

							editable.set('node', event.currentTarget);

							if (rendered) {
								editable.syncUI();
							}

							editable._startEditing(event);
						}
					);

					title.setData('portletTitleEditOptions', options);
				}
			}
		},
		['aui-editable-deprecated']
	);

	Liferay.provide(
		Util,
		'editEntity',
		function(config, callback) {
			var dialog = Util.getWindow(config.id);

			var eventName = config.eventName || config.id;

			var eventHandles = [Liferay.on(eventName, callback)];

			var detachSelectionOnHideFn = function(event) {
				if (!event.newVal) {
					(new A.EventHandle(eventHandles)).detach();
				}
			};

			if (dialog) {
				eventHandles.push(dialog.after(['destroy', 'visibleChange'], detachSelectionOnHideFn));

				dialog.show();
			}
			else {
				var destroyDialog = function(event) {
					var dialogId = config.id;

					var dialogWindow = Util.getWindow(dialogId);

					if (dialogWindow && Util.getPortletId(dialogId) === event.portletId) {
						dialogWindow.destroy();

						Liferay.detach('destroyPortlet', destroyDialog);
					}
				};

				var editURL = new Liferay.PortletURL.createURL(
					config.uri,
					A.merge(
						{
							eventName: eventName
						},
						config.urlParams
					)
				);

				config.uri = editURL.toString();

				config.dialogIframe = A.merge(
					{
						bodyCssClass: 'dialog-with-footer'
					},
					config.dialogIframe || {}
				);

				Util.openWindow(
					config,
					function(dialogWindow) {
						eventHandles.push(
							dialogWindow.after(['destroy', 'visibleChange'], detachSelectionOnHideFn)
						);

						Liferay.on('destroyPortlet', destroyDialog);
					}
				);
			}
		},
		['aui-base', 'liferay-portlet-url', 'liferay-util-window']
	);

	Liferay.provide(
		Util,
		'selectEntity',
		function(config, callback) {
			var dialog = Util.getWindow(config.id);

			var eventName = config.eventName || config.id;

			var eventHandles = [Liferay.on(eventName, callback)];

			var selectedData = config.selectedData;

			if (selectedData) {
				config.dialog.destroyOnHide = true;
			}

			var detachSelectionOnHideFn = function(event) {
				if (!event.newVal) {
					(new A.EventHandle(eventHandles)).detach();
				}
			};

			var disableSelectedAssets = function(event) {
				if (selectedData && selectedData.length) {
					var currentWindow = event.currentTarget.node.get('contentWindow.document');

					var selectorButtons = currentWindow.all('.lfr-search-container-wrapper .selector-button');

					A.some(
						selectorButtons,
						function(item, index) {
							var assetEntryId = item.attr('data-entityid') || item.attr('data-entityname');

							var assetEntryIndex = selectedData.indexOf(assetEntryId);

							if (assetEntryIndex > -1) {
								item.attr('data-prevent-selection', true);
								item.attr('disabled', true);

								selectedData.splice(assetEntryIndex, 1);
							}

							return !selectedData.length;
						}
					);
				}
			};

			if (dialog) {
				eventHandles.push(dialog.after(['destroy', 'visibleChange'], detachSelectionOnHideFn));

				dialog.show();
			}
			else {
				var destroyDialog = function(event) {
					var dialogId = config.id;

					var dialogWindow = Util.getWindow(dialogId);

					if (dialogWindow && Util.getPortletId(dialogId) === event.portletId) {
						dialogWindow.destroy();

						Liferay.detach('destroyPortlet', destroyDialog);
					}
				};

				Util.openWindow(
					config,
					function(dialogWindow) {
						eventHandles.push(
							dialogWindow.after(['destroy', 'visibleChange'], detachSelectionOnHideFn),
							dialogWindow.iframe.after(['load'], disableSelectedAssets)
						);

						Liferay.on('destroyPortlet', destroyDialog);
					}
				);
			}
		},
		['aui-base', 'liferay-util-window']
	);

	Liferay.provide(
		Util,
		'toggleControls',
		function(node) {
			var docBody = A.getBody();

			node = node || docBody;

			var trigger = node.one('.toggle-controls');

			if (trigger) {
				var controlsVisible = Liferay._editControlsState === 'visible';

				var currentState = MAP_TOGGLE_STATE[controlsVisible];

				var icon = trigger.one('.lexicon-icon');

				if (icon) {
					currentState.icon = icon;
				}

				docBody.addClass(currentState.cssClass);

				Liferay.fire(
					'toggleControls',
					{
						enabled: controlsVisible
					}
				);

				trigger.on(
					'tap',
					function(event) {
						controlsVisible = !controlsVisible;

						var prevState = currentState;

						currentState = MAP_TOGGLE_STATE[controlsVisible];

						docBody.toggleClass(prevState.cssClass);
						docBody.toggleClass(currentState.cssClass);

						var editControlsIconClass = currentState.iconCssClass;
						var editControlsState = currentState.state;

						if (icon) {
							var newIcon = currentState.icon;

							if (!newIcon) {
								newIcon = Util.getLexiconIcon(editControlsIconClass);

								newIcon = A.one(newIcon);

								currentState.icon = newIcon;
							}

							icon.replace(newIcon);

							icon = newIcon;
						}

						Liferay._editControlsState = editControlsState;

						Liferay.Store('com.liferay.frontend.js.web_toggleControls', editControlsState);

						Liferay.fire(
							'toggleControls',
							{
								enabled: controlsVisible,
								src: 'ui'
							}
						);
					}
				);
			}
		},
		['event-tap', 'liferay-store']
	);

	Liferay.provide(
		window,
		'submitForm',
		function(form, action, singleSubmit, validate) {
			if (!Util._submitLocked) {
				if (form.jquery) {
					form = form[0];
				}

				Liferay.fire(
					'submitForm',
					{
						action: action,
						form: A.one(form),
						singleSubmit: singleSubmit,
						validate: validate !== false
					}
				);
			}
		},
		['aui-base', 'aui-form-validator', 'aui-url', 'liferay-form']
	);

	Liferay.publish(
		'submitForm',
		{
			defaultFn: Util._defaultSubmitFormFn
		}
	);

	Liferay.provide(
		Util,
		'defaultPreviewArticleFn',
		function(event) {
			var instance = this;

			var urlPreview = instance._urlPreview;

			if (!urlPreview) {
				urlPreview = new Liferay.UrlPreview(
					{
						title: Util.escapeHTML(event.title),
						url: event.uri
					}
				);

				instance._urlPreview = urlPreview;
			}
			else {
				urlPreview.set('title', Util.escapeHTML(event.title));
				urlPreview.set('url', event.uri);
			}

			urlPreview.open();
		},
		['liferay-url-preview']
	);

	Liferay.publish(
		'previewArticle',
		{
			defaultFn: Util._defaultPreviewArticleFn
		}
	);

	Liferay.provide(
		Util,
		'_openWindowProvider',
		function(config, callback) {
			var dialog = Window.getWindow(config);

			if (Lang.isFunction(callback)) {
				callback(dialog);
			}
		},
		['liferay-util-window']
	);

	Liferay.after(
		'closeWindow',
		function(event) {
			var id = event.id;

			var dialog = Liferay.Util.getTop().Liferay.Util.Window.getById(id);

			if (dialog && dialog.iframe) {
				var dialogWindow = dialog.iframe.node.get('contentWindow').getDOM();

				var openingWindow = dialogWindow.Liferay.Util.getOpener();
				var redirect = event.redirect;

				if (redirect) {
					openingWindow.Liferay.Util.navigate(redirect);
				}
				else {
					var refresh = event.refresh;

					if (refresh && openingWindow) {
						var data;

						if (!event.portletAjaxable) {
							data = {
								portletAjaxable: false
							};
						}

						openingWindow.Liferay.Portlet.refresh('#p_p_id_' + refresh + '_', data);
					}
				}

				dialog.hide();
			}
		}
	);

	Util.Window = Window;

	Liferay.Util = Util;

	Liferay.BREAKPOINTS = {
		PHONE: 768,
		TABLET: 980
	};

	Liferay.STATUS_CODE = {
		BAD_REQUEST: 400,
		INTERNAL_SERVER_ERROR: 500,
		OK: 200,
		SC_DUPLICATE_FILE_EXCEPTION: 490,
		SC_FILE_ANTIVIRUS_EXCEPTION: 494,
		SC_FILE_EXTENSION_EXCEPTION: 491,
		SC_FILE_NAME_EXCEPTION: 492,
		SC_FILE_SIZE_EXCEPTION: 493,
		SC_UPLOAD_REQUEST_SIZE_EXCEPTION: 495
	};

	// 0-200: Theme Developer
	// 200-400: Portlet Developer
	// 400+: Liferay

	Liferay.zIndex = {
		ALERT: 430,
		DOCK: 10,
		DOCK_PARENT: 20,
		DRAG_ITEM: 460,
		DROP_AREA: 440,
		DROP_POSITION: 450,
		MENU: 5000,
		OVERLAY: 1000,
		POPOVER: 1600,
		TOOLTIP: 10000,
		WINDOW: 1200
	};
})(AUI(), AUI.$, Liferay);
!function(t,e){for(var n in e)t[n]=e[n]}(window,function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/o/frontend-js-web/liferay/",n(n.s=8)}([function(t,e){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(t){"object"==typeof window&&(n=window)}t.exports=n},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.string=e.object=e.Disposable=e.async=e.array=void 0;var r=n(12);Object.keys(r).forEach(function(t){"default"!==t&&"__esModule"!==t&&Object.defineProperty(e,t,{enumerable:!0,get:function(){return r[t]}})});var o=s(r),a=s(n(13)),i=s(n(14)),u=s(n(17)),c=s(n(18)),l=s(n(19));function s(t){return t&&t.__esModule?t:{default:t}}e.array=a.default,e.async=i.default,e.Disposable=u.default,e.object=c.default,e.string=l.default,e.default=o.default},function(t,e,n){"use strict";(function(t){Object.defineProperty(e,"__esModule",{value:!0});var n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};e.abstractMethod=function(){throw Error("Unimplemented abstract method")},e.disableCompatibilityMode=function(){r=void 0},e.enableCompatibilityMode=i,e.getCompatibilityModeData=function(){void 0===r&&"undefined"!=typeof window&&window.__METAL_COMPATIBILITY__&&i(window.__METAL_COMPATIBILITY__);return r},e.getFunctionName=function(t){if(!t.name){var e=t.toString();t.name=e.substring(9,e.indexOf("("))}return t.name},e.getStaticProperty=function t(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:u;var o=n+"_MERGED";if(!e.hasOwnProperty(o)){var a=e.hasOwnProperty(n)?e[n]:null;e.__proto__&&!e.__proto__.isPrototypeOf(Function)&&(a=r(a,t(e.__proto__,n,r))),e[o]=a}return e[o]},e.getUid=function(t,e){if(t){var n=t[a];return e&&!t.hasOwnProperty(a)&&(n=null),n||(t[a]=o++)}return o++},e.identityFunction=function(t){return t},e.isBoolean=function(t){return"boolean"==typeof t},e.isDef=c,e.isDefAndNotNull=function(t){return c(t)&&!l(t)},e.isDocument=function(t){return t&&"object"===(void 0===t?"undefined":n(t))&&9===t.nodeType},e.isDocumentFragment=function(t){return t&&"object"===(void 0===t?"undefined":n(t))&&11===t.nodeType},e.isElement=function(t){return t&&"object"===(void 0===t?"undefined":n(t))&&1===t.nodeType},e.isFunction=function(t){return"function"==typeof t},e.isNull=l,e.isNumber=function(t){return"number"==typeof t},e.isWindow=function(t){return null!==t&&t===t.window},e.isObject=function(t){var e=void 0===t?"undefined":n(t);return"object"===e&&null!==t||"function"===e},e.isPromise=function(t){return t&&"object"===(void 0===t?"undefined":n(t))&&"function"==typeof t.then},e.isString=function(t){return"string"==typeof t||t instanceof String},e.isServerSide=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{checkEnv:!0},n=void 0!==t&&!t.browser;n&&e.checkEnv&&(n=void 0!==t.env&&!0);return n},e.nullFunction=function(){};var r=void 0,o=1,a=e.UID_PROPERTY="core_"+(1e9*Math.random()>>>0);function i(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};r=t}function u(t,e){return t||e}function c(t){return void 0!==t}function l(t){return null===t}}).call(this,n(3))},function(t,e){var n,r,o=t.exports={};function a(){throw new Error("setTimeout has not been defined")}function i(){throw new Error("clearTimeout has not been defined")}function u(t){if(n===setTimeout)return setTimeout(t,0);if((n===a||!n)&&setTimeout)return n=setTimeout,setTimeout(t,0);try{return n(t,0)}catch(e){try{return n.call(null,t,0)}catch(e){return n.call(this,t,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:a}catch(t){n=a}try{r="function"==typeof clearTimeout?clearTimeout:i}catch(t){r=i}}();var c,l=[],s=!1,f=-1;function p(){s&&c&&(s=!1,c.length?l=c.concat(l):f=-1,l.length&&d())}function d(){if(!s){var t=u(p);s=!0;for(var e=l.length;e;){for(c=l,l=[];++f<e;)c&&c[f].run();f=-1,e=l.length}c=null,s=!1,function(t){if(r===clearTimeout)return clearTimeout(t);if((r===i||!r)&&clearTimeout)return r=clearTimeout,clearTimeout(t);try{r(t)}catch(e){try{return r.call(null,t)}catch(e){return r.call(this,t)}}}(t)}}function h(t,e){this.fun=t,this.array=e}function v(){}o.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)e[n-1]=arguments[n];l.push(new h(t,e)),1!==l.length||s||u(d)},h.prototype.run=function(){this.fun.apply(null,this.array)},o.title="browser",o.browser=!0,o.env={},o.argv=[],o.version="",o.versions={},o.on=v,o.addListener=v,o.once=v,o.off=v,o.removeListener=v,o.removeAllListeners=v,o.emit=v,o.prependListener=v,o.prependOnceListener=v,o.listeners=function(t){return[]},o.binding=function(t){throw new Error("process.binding is not supported")},o.cwd=function(){return"/"},o.chdir=function(t){throw new Error("process.chdir is not supported")},o.umask=function(){return 0}},function(t,e){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children||(t.children=[]),Object.defineProperty(t,"loaded",{enumerable:!0,get:function(){return t.l}}),Object.defineProperty(t,"id",{enumerable:!0,get:function(){return t.i}}),t.webpackPolyfill=1),t}},function(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=e.PortletConstants=void 0;var n={EDIT:"edit",HELP:"help",VIEW:"view",MAXIMIZED:"maximized",MINIMIZED:"minimized",NORMAL:"normal",FULL:"cacheLevelFull",PAGE:"cacheLevelPage",PORTLET:"cacheLevelPortlet"};e.PortletConstants=n;var r=n;e.default=r},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0}),e.validateState=e.validatePortletId=e.validateParameters=e.validateForm=e.validateArguments=e.getUrl=e.getUpdatedPublicRenderParameters=e.generatePortletModeAndWindowStateString=e.generateActionUrl=e.encodeFormAsString=e.decodeUpdateString=void 0;var r=n(1);function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(t){return function(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);e<t.length;e++)n[e]=t[e];return n}}(t)||function(t){if(Symbol.iterator in Object(t)||"[object Arguments]"===Object.prototype.toString.call(t))return Array.from(t)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}e.decodeUpdateString=function(t,e){var n=t&&t.portlets?t.portlets:{};try{var r=JSON.parse(e);if(r.portlets)for(var o=Object.keys(n),a=0,i=o;a<i.length;a++){var u=i[a],c=r.portlets[u].state,l=n[u].state;if(!c||!l)throw new Error("Invalid update string.\nold state=".concat(l,"\nnew state=").concat(c));d(t,c,u)&&(n[u]=r.portlets[u])}}catch(t){}return n};var i=function(t,e){for(var n=[],r=function(r){var o=e.elements[r],i=o.name,u=o.nodeName.toUpperCase(),c="INPUT"===u?o.type.toUpperCase():"",l=o.value;if(i&&!o.disabled&&"FILE"!==c)if("SELECT"===u&&o.multiple)a(o.options).forEach(function(e){if(e.checked){var r=e.value,o=encodeURIComponent(t+i)+"="+encodeURIComponent(r);n.push(o)}});else if("CHECKBOX"!==c&&"RADIO"!==c||o.checked){var s=encodeURIComponent(t+i)+"="+encodeURIComponent(l);n.push(s)}},o=0;o<e.elements.length;o++)r(o);return n.join("&")};e.encodeFormAsString=i;var u=function(t,e){var n="";if(Array.isArray(e))if(0===e.length)n+="&"+encodeURIComponent(t)+"=";else{var r=!0,o=!1,a=void 0;try{for(var i,u=e[Symbol.iterator]();!(r=(i=u.next()).done);r=!0){var c=i.value;n+="&"+encodeURIComponent(t),n+=null===c?"=":"="+encodeURIComponent(c)}}catch(t){o=!0,a=t}finally{try{r||null==u.return||u.return()}finally{if(o)throw a}}}return n};e.generateActionUrl=function(t,e,n){var r={credentials:"same-origin",method:"POST",url:e};if(n)if("multipart/form-data"===n.enctype){var o=new FormData(n);r.body=o}else{var a=i(t,n);"GET"===(n.method?n.method.toUpperCase():"GET")?(e.indexOf("?")>=0?e+="&".concat(a):e+="?".concat(a),r.url=e):(r.body=a,r.headers={"Content-Type":"application/x-www-form-urlencoded"})}return r};var c=function(t,e,n,r,o){var a="";if(t.portlets&&t.portlets[e]){var i=t.portlets[e];if(i&&i.state&&i.state.parameters){var c=i.state.parameters[n];void 0!==c&&(a+=u("p_r_p_"===r?o:"priv_r_p_"===r?e+"priv_r_p_"+n:e+n,c))}}return a},l=function(t,e){var n="";if(t.portlets){var r=t.portlets[e];if(r.state){var o=r.state;n+="&p_p_mode="+encodeURIComponent(o.portletMode),n+="&p_p_state="+encodeURIComponent(o.windowState)}}return n};e.generatePortletModeAndWindowStateString=l;e.getUpdatedPublicRenderParameters=function(t,e,n){var r={};if(t&&t.portlets){var o=t.portlets[e];if(o&&o.pubParms)for(var a=o.pubParms,i=0,u=Object.keys(a);i<u.length;i++){var c=u[i];if(!f(t,e,n,c))r[a[c]]=n.parameters[c]}}return r};e.getUrl=function(t,e,n,r,o,a){var i="cacheLevelPage",s="",f="";if(t&&t.portlets){"RENDER"===e&&void 0===n&&(n=null);var d=t.portlets[n];if(d&&("RESOURCE"===e?(f=decodeURIComponent(d.encodedResourceURL),o&&(i=o),f+="&p_p_cacheability="+encodeURIComponent(i),a&&(f+="&p_p_resource_id="+encodeURIComponent(a))):"RENDER"===e&&null!==n?f=decodeURIComponent(d.encodedRenderURL):"RENDER"===e?f=decodeURIComponent(t.encodedCurrentURL):"ACTION"===e?(f=decodeURIComponent(d.encodedActionURL),f+="&p_p_hub="+encodeURIComponent("0")):"PARTIAL_ACTION"===e&&(f=decodeURIComponent(d.encodedActionURL),f+="&p_p_hub="+encodeURIComponent("1")),"RESOURCE"!==e||"cacheLevelFull"!==i)){if(n&&(f+=l(t,n)),n&&(s="",d.state&&d.state.parameters)){for(var h=d.state.parameters,v=0,y=Object.keys(h);v<y.length;v++){var _=y[v];p(t,n,_)||(s+=c(t,n,_,"priv_r_p_"))}f+=s}if(t.prpMap){s="";for(var m={},b=0,g=Object.keys(t.prpMap);b<g.length;b++)for(var w=g[b],E=0,j=Object.keys(t.prpMap[w]);E<j.length;E++){var O=j[E],S=t.prpMap[w][O].split("|");m.hasOwnProperty(w)||(m[w]=c(t,S[0],S[1],"p_r_p_",w),s+=m[w])}f+=s}}}if(r){s="";for(var T=0,I=Object.keys(r);T<I.length;T++){var P=I[T];s+=u(n+P,r[P])}f+=s}return Promise.resolve(f)};var s=function(t,e){var n=!1;void 0===t&&void 0===e&&(n=!0),void 0!==t&&void 0!==e||(n=!1),t.length!==e.length&&(n=!1);for(var r=t.length-1;r>=0;r--)t[r]!==e[r]&&(n=!1);return n},f=function(t,e,n,r){var o=!1;if(t&&t.portlets){var a=t.portlets[e];if(n.parameters[r]&&a.state.parameters[r]){var i=n.parameters[r],u=a.state.parameters[r];o=s(i,u)}}return o},p=function(t,e,n){var r=!1;if(t&&t.portlets){var o=t.portlets[e];if(o&&o.pubParms)r=Object.keys(o.pubParms).includes(n)}return r},d=function(t,e,n){var r=!1;if(t&&t.portlets&&t.portlets[n]){var o=t.portlets[n].state;if(!e.portletMode||!e.windowState||!e.parameters)throw new Error("Error decoding state: ".concat(e));if(e.porletMode!==o.portletMode||e.windowState!==o.windowState)r=!0;else{for(var a=0,i=Object.keys(e.parameters);a<i.length;a++){var u=i[a],c=e.parameters[u],l=o.parameters[u];s(c,l)||(r=!0)}for(var f=0,p=Object.keys(o.parameters);f<p.length;f++){var d=p[f];e.parameters[d]||(r=!0)}}}return r};e.validateArguments=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:[];if(t.length<e)throw new TypeError("Too few arguments provided: Number of arguments: ".concat(t.length));if(t.length>n)throw new TypeError("Too many arguments provided: ".concat([].join.call(t,", ")));if(Array.isArray(r))for(var a=Math.min(t.length,r.length)-1;a>=0;a--){if(o(t[a])!==r[a])throw new TypeError("Parameter ".concat(a," is of type ").concat(o(t[a])," rather than the expected type ").concat(r[a]));if(null===t[a]||void 0===t[a])throw new TypeError("Argument is ".concat(o(t[a])))}};e.validateForm=function(t){if(!(t instanceof HTMLFormElement))throw new TypeError("Element must be an HTMLFormElement");var e=t.method?t.method.toUpperCase():void 0;if(e&&"GET"!==e&&"POST"!==e)throw new TypeError("Invalid form method ".concat(e,". Allowed methods are GET & POST"));var n=t.enctype;if(n&&"application/x-www-form-urlencoded"!==n&&"multipart/form-data"!==n)throw new TypeError("Invalid form enctype ".concat(n,". Allowed: 'application/x-www-form-urlencoded' & 'multipart/form-data'"));if(n&&"multipart/form-data"===n&&"POST"!==e)throw new TypeError("Invalid method with multipart/form-data. Must be POST");if(!n||"application/x-www-form-urlencoded"===n)for(var r=t.elements.length,o=0;o<r;o++)if("INPUT"===t.elements[o].nodeName.toUpperCase()&&"FILE"===t.elements[o].type.toUpperCase())throw new TypeError("Must use enctype = 'multipart/form-data' with input type FILE.")};var h=function(t){if(!(0,r.isDefAndNotNull)(t))throw new TypeError("The parameter object is: ".concat(o(t)));for(var e=0,n=Object.keys(t);e<n.length;e++){var a=n[e];if(!Array.isArray(t[a]))throw new TypeError("".concat(a," parameter is not an array"));if(!t[a].length)throw new TypeError("".concat(a," parameter is an empty array"))}};e.validateParameters=h;e.validatePortletId=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return t.portlets&&Object.keys(t.portlets).includes(e)};e.validateState=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};h(t.parameters);var n=t.portletMode;if(!(0,r.isString)(n))throw new TypeError("Invalid parameters. portletMode is ".concat(o(n)));var a=e.allowedPM;if(!a.includes(n.toLowerCase()))throw new TypeError("Invalid portletMode=".concat(n," is not in ").concat(a));var i=t.windowState;if(!(0,r.isString)(i))throw new TypeError("Invalid parameters. windowState is ".concat(o(i)));var u=e.allowedWS;if(!u.includes(i.toLowerCase()))throw new TypeError("Invalid windowState=".concat(i," is not in ").concat(u))}},function(t,e,n){(function(e){var n="Expected a function",r="__lodash_hash_undefined__",o="[object Function]",a="[object GeneratorFunction]",i=/^\[object .+?Constructor\]$/,u="object"==typeof e&&e&&e.Object===Object&&e,c="object"==typeof self&&self&&self.Object===Object&&self,l=u||c||Function("return this")();var s,f=Array.prototype,p=Function.prototype,d=Object.prototype,h=l["__core-js_shared__"],v=(s=/[^.]+$/.exec(h&&h.keys&&h.keys.IE_PROTO||""))?"Symbol(src)_1."+s:"",y=p.toString,_=d.hasOwnProperty,m=d.toString,b=RegExp("^"+y.call(_).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),g=f.splice,w=k(l,"Map"),E=k(Object,"create");function j(t){var e=-1,n=t?t.length:0;for(this.clear();++e<n;){var r=t[e];this.set(r[0],r[1])}}function O(t){var e=-1,n=t?t.length:0;for(this.clear();++e<n;){var r=t[e];this.set(r[0],r[1])}}function S(t){var e=-1,n=t?t.length:0;for(this.clear();++e<n;){var r=t[e];this.set(r[0],r[1])}}function T(t,e){for(var n,r,o=t.length;o--;)if((n=t[o][0])===(r=e)||n!=n&&r!=r)return o;return-1}function I(t){return!(!C(t)||(e=t,v&&v in e))&&(function(t){var e=C(t)?m.call(t):"";return e==o||e==a}(t)||function(t){var e=!1;if(null!=t&&"function"!=typeof t.toString)try{e=!!(t+"")}catch(t){}return e}(t)?b:i).test(function(t){if(null!=t){try{return y.call(t)}catch(t){}try{return t+""}catch(t){}}return""}(t));var e}function P(t,e){var n,r,o=t.__data__;return("string"==(r=typeof(n=e))||"number"==r||"symbol"==r||"boolean"==r?"__proto__"!==n:null===n)?o["string"==typeof e?"string":"hash"]:o.map}function k(t,e){var n=function(t,e){return null==t?void 0:t[e]}(t,e);return I(n)?n:void 0}function A(t,e){if("function"!=typeof t||e&&"function"!=typeof e)throw new TypeError(n);var r=function(){var n=arguments,o=e?e.apply(this,n):n[0],a=r.cache;if(a.has(o))return a.get(o);var i=t.apply(this,n);return r.cache=a.set(o,i),i};return r.cache=new(A.Cache||S),r}function C(t){var e=typeof t;return!!t&&("object"==e||"function"==e)}j.prototype.clear=function(){this.__data__=E?E(null):{}},j.prototype.delete=function(t){return this.has(t)&&delete this.__data__[t]},j.prototype.get=function(t){var e=this.__data__;if(E){var n=e[t];return n===r?void 0:n}return _.call(e,t)?e[t]:void 0},j.prototype.has=function(t){var e=this.__data__;return E?void 0!==e[t]:_.call(e,t)},j.prototype.set=function(t,e){return this.__data__[t]=E&&void 0===e?r:e,this},O.prototype.clear=function(){this.__data__=[]},O.prototype.delete=function(t){var e=this.__data__,n=T(e,t);return!(n<0)&&(n==e.length-1?e.pop():g.call(e,n,1),!0)},O.prototype.get=function(t){var e=this.__data__,n=T(e,t);return n<0?void 0:e[n][1]},O.prototype.has=function(t){return T(this.__data__,t)>-1},O.prototype.set=function(t,e){var n=this.__data__,r=T(n,t);return r<0?n.push([t,e]):n[r][1]=e,this},S.prototype.clear=function(){this.__data__={hash:new j,map:new(w||O),string:new j}},S.prototype.delete=function(t){return P(this,t).delete(t)},S.prototype.get=function(t){return P(this,t).get(t)},S.prototype.has=function(t){return P(this,t).has(t)},S.prototype.set=function(t,e){return P(this,t).set(t,e),this},A.Cache=S,t.exports=A}).call(this,n(0))},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"portlet",{enumerable:!0,get:function(){return c.default}});var r=h(n(9)),o=h(n(10)),a=h(n(11)),i=h(n(20)),u=h(n(21)),c=h(n(22)),l=h(n(30)),s=h(n(31)),f=h(n(32)),p=h(n(33)),d=h(n(34));function h(t){return t&&t.__esModule?t:{default:t}}Liferay.Util.escape=r.default,Liferay.Util.fetch=o.default,Liferay.Util.formatXML=a.default,Liferay.Util.groupBy=i.default,Liferay.Util.isEqual=u.default,Liferay.Util.navigate=l.default,Liferay.Util.ns=s.default,Liferay.Util.objectToFormData=f.default,Liferay.Util.toCharCode=p.default,Liferay.Util.openToast=function(){for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];Liferay.Loader.require("frontend-js-web/liferay/toast/commands/OpenToast.es",function(t){t.openToast.apply(t,e)})},Liferay.Util.unescape=d.default},function(t,e,n){(function(e){var n=1/0,r="[object Symbol]",o=/[&<>"'`]/g,a=RegExp(o.source),i="object"==typeof e&&e&&e.Object===Object&&e,u="object"==typeof self&&self&&self.Object===Object&&self,c=i||u||Function("return this")();var l,s=(l={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","`":"&#96;"},function(t){return null==l?void 0:l[t]}),f=Object.prototype.toString,p=c.Symbol,d=p?p.prototype:void 0,h=d?d.toString:void 0;function v(t){if("string"==typeof t)return t;if(function(t){return"symbol"==typeof t||function(t){return!!t&&"object"==typeof t}(t)&&f.call(t)==r}(t))return h?h.call(t):"";var e=t+"";return"0"==e&&1/t==-n?"-0":e}t.exports=function(t){var e;return(t=null==(e=t)?"":v(e))&&a.test(t)?t.replace(o,s):t}}).call(this,n(0))},function(t,e){function n(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),n.push.apply(n,r)}return n}function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return fetch(t,function(t){for(var e=1;e<arguments.length;e++){var o=null!=arguments[e]?arguments[e]:{};e%2?n(o,!0).forEach(function(e){r(t,e,o[e])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(o)):n(o).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(o,e))})}return t}({},o,{},e))};var o={credentials:"include"}},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=function(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?o(n,!0).forEach(function(e){a(t,e,n[e])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):o(n).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))})}return t}({},T,{},e),P=n.newLine,k=n.tagIndent;if(!(0,r.isString)(t))throw new TypeError("Parameter content must be a string");var A=[];t=(t=(t=(t=(t=(t=t.trim()).replace(i,function(t){return A.push(t),O})).replace(w,"><")).replace(b,j+"<")).replace(_,j+"$1$2")).replace(S,function(){return A.shift()});var C=0,R=!1,L=t.split(j),M=0,D="";return L.forEach(function(t,e){i.test(t)?D+=I(M,P,k)+t:c.test(t)?(D+=I(M,P,k)+t,C++,R=!0,(u.test(t)||s.test(t))&&(R=0!==--C)):u.test(t)?(D+=t,R=0!==--C):f.exec(L[e-1])&&p.exec(t)&&d.exec(L[e-1])==h.exec(t)[0].replace("/",E)?(D+=t,!R&&--M):!v.test(t)||m.test(t)||g.test(t)?v.test(t)&&m.test(t)?D+=R?t:I(M,P,k)+t:m.test(t)?D+=R?t:I(--M,P,k)+t:g.test(t)?D+=R?t:I(M,P,k)+t:l.test(t)?D+=I(M,P,k)+t:D+=y?I(M,P,k)+t:t:D+=R?t:I(M++,P,k)+t,new RegExp("^"+P).test(D)&&(D=D.slice(P.length))}),D};var r=n(1);function o(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),n.push.apply(n,r)}return n}function a(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var i=/<!\[CDATA\[[\0-\uFFFF]*?\]\]>/g,u=/-->|\]>/,c=/<!/,l=/<\?/,s=/!DOCTYPE/,f=/^<\w/,p=/^<\/\w/,d=/^<[\w:\-\.\,]+/,h=/^<\/[\w:\-\.\,]+/,v=/<\w/,y=/xmlns(?:\:|\=)/g,_=/\s*(xmlns)(\:|\=)/g,m=/<\//,b=/</g,g=/\/>/,w=/>\s+</g,E="",j="~::~",O="<"+j+"CDATA"+j+">",S=new RegExp(O,"g"),T={newLine:"\r\n",tagIndent:"\t"};function I(t,e,n){return e+new Array(t+1).join(n)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.core=void 0;var r=n(2);Object.keys(r).forEach(function(t){"default"!==t&&"__esModule"!==t&&Object.defineProperty(e,t,{enumerable:!0,get:function(){return r[t]}})});var o=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e.default=t,e}(r);e.default=o,e.core=o},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}();var o=function(){function t(){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t)}return r(t,null,[{key:"equal",value:function(t,e){if(t===e)return!0;if(t.length!==e.length)return!1;for(var n=0;n<t.length;n++)if(t[n]!==e[n])return!1;return!0}},{key:"firstDefinedValue",value:function(t){for(var e=0;e<t.length;e++)if(void 0!==t[e])return t[e]}},{key:"flatten",value:function(e){for(var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],r=0;r<e.length;r++)Array.isArray(e[r])?t.flatten(e[r],n):n.push(e[r]);return n}},{key:"remove",value:function(e,n){var r,o=e.indexOf(n);return(r=o>=0)&&t.removeAt(e,o),r}},{key:"removeAt",value:function(t,e){return 1===Array.prototype.splice.call(t,e,1).length}},{key:"slice",value:function(t,e){for(var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t.length,r=[],o=e;o<n;o++)r.push(t[o]);return r}}]),t}();e.default=o},function(t,e,n){"use strict";(function(t){Object.defineProperty(e,"__esModule",{value:!0});var r=n(2),o={throwException:function(t){o.nextTick(function(){throw t})},run:function(t,e){o.run.workQueueScheduled_||(o.nextTick(o.run.processWorkQueue),o.run.workQueueScheduled_=!0),o.run.workQueue_.push(new o.run.WorkItem_(t,e))}};o.run.workQueueScheduled_=!1,o.run.workQueue_=[],o.run.processWorkQueue=function(){for(;o.run.workQueue_.length;){var t=o.run.workQueue_;o.run.workQueue_=[];for(var e=0;e<t.length;e++){var n=t[e];try{n.fn.call(n.scope)}catch(t){o.throwException(t)}}}o.run.workQueueScheduled_=!1},o.run.WorkItem_=function(t,e){this.fn=t,this.scope=e},o.nextTick=function(e,n){var a=e;n&&(a=e.bind(n)),a=o.nextTick.wrapCallback_(a),o.nextTick.setImmediate_||("function"==typeof t&&(0,r.isServerSide)({checkEnv:!1})?o.nextTick.setImmediate_=t:o.nextTick.setImmediate_=o.nextTick.getSetImmediateEmulator_()),o.nextTick.setImmediate_(a)},o.nextTick.setImmediate_=null,o.nextTick.getSetImmediateEmulator_=function(){var t=void 0;if("function"==typeof MessageChannel&&(t=MessageChannel),void 0===t&&"undefined"!=typeof window&&window.postMessage&&window.addEventListener&&(t=function(){var t=document.createElement("iframe");t.style.display="none",t.src="",t.title="",document.documentElement.appendChild(t);var e=t.contentWindow,n=e.document;n.open(),n.write(""),n.close();var r="callImmediate"+Math.random(),o=e.location.protocol+"//"+e.location.host,a=function(t){t.origin!==o&&t.data!==r||this.port1.onmessage()}.bind(this);e.addEventListener("message",a,!1),this.port1={},this.port2={postMessage:function(){e.postMessage(r,o)}}}),void 0!==t){var e=new t,n={},r=n;return e.port1.onmessage=function(){var t=(n=n.next).cb;n.cb=null,t()},function(t){r.next={cb:t},r=r.next,e.port2.postMessage(0)}}return"undefined"!=typeof document&&"onreadystatechange"in document.createElement("script")?function(t){var e=document.createElement("script");e.onreadystatechange=function(){e.onreadystatechange=null,e.parentNode.removeChild(e),e=null,t(),t=null},document.documentElement.appendChild(e)}:function(t){setTimeout(t,0)}},o.nextTick.wrapCallback_=function(t){return t},e.default=o}).call(this,n(15).setImmediate)},function(t,e,n){(function(t){var r=void 0!==t&&t||"undefined"!=typeof self&&self||window,o=Function.prototype.apply;function a(t,e){this._id=t,this._clearFn=e}e.setTimeout=function(){return new a(o.call(setTimeout,r,arguments),clearTimeout)},e.setInterval=function(){return new a(o.call(setInterval,r,arguments),clearInterval)},e.clearTimeout=e.clearInterval=function(t){t&&t.close()},a.prototype.unref=a.prototype.ref=function(){},a.prototype.close=function(){this._clearFn.call(r,this._id)},e.enroll=function(t,e){clearTimeout(t._idleTimeoutId),t._idleTimeout=e},e.unenroll=function(t){clearTimeout(t._idleTimeoutId),t._idleTimeout=-1},e._unrefActive=e.active=function(t){clearTimeout(t._idleTimeoutId);var e=t._idleTimeout;e>=0&&(t._idleTimeoutId=setTimeout(function(){t._onTimeout&&t._onTimeout()},e))},n(16),e.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==t&&t.setImmediate||this&&this.setImmediate,e.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==t&&t.clearImmediate||this&&this.clearImmediate}).call(this,n(0))},function(t,e,n){(function(t,e){!function(t,n){"use strict";if(!t.setImmediate){var r,o,a,i,u,c=1,l={},s=!1,f=t.document,p=Object.getPrototypeOf&&Object.getPrototypeOf(t);p=p&&p.setTimeout?p:t,"[object process]"==={}.toString.call(t.process)?r=function(t){e.nextTick(function(){h(t)})}:!function(){if(t.postMessage&&!t.importScripts){var e=!0,n=t.onmessage;return t.onmessage=function(){e=!1},t.postMessage("","*"),t.onmessage=n,e}}()?t.MessageChannel?((a=new MessageChannel).port1.onmessage=function(t){h(t.data)},r=function(t){a.port2.postMessage(t)}):f&&"onreadystatechange"in f.createElement("script")?(o=f.documentElement,r=function(t){var e=f.createElement("script");e.onreadystatechange=function(){h(t),e.onreadystatechange=null,o.removeChild(e),e=null},o.appendChild(e)}):r=function(t){setTimeout(h,0,t)}:(i="setImmediate$"+Math.random()+"$",u=function(e){e.source===t&&"string"==typeof e.data&&0===e.data.indexOf(i)&&h(+e.data.slice(i.length))},t.addEventListener?t.addEventListener("message",u,!1):t.attachEvent("onmessage",u),r=function(e){t.postMessage(i+e,"*")}),p.setImmediate=function(t){"function"!=typeof t&&(t=new Function(""+t));for(var e=new Array(arguments.length-1),n=0;n<e.length;n++)e[n]=arguments[n+1];var o={callback:t,args:e};return l[c]=o,r(c),c++},p.clearImmediate=d}function d(t){delete l[t]}function h(t){if(s)setTimeout(h,0,t);else{var e=l[t];if(e){s=!0;try{!function(t){var e=t.callback,r=t.args;switch(r.length){case 0:e();break;case 1:e(r[0]);break;case 2:e(r[0],r[1]);break;case 3:e(r[0],r[1],r[2]);break;default:e.apply(n,r)}}(e)}finally{d(t),s=!1}}}}}("undefined"==typeof self?void 0===t?this:t:self)}).call(this,n(0),n(3))},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}();var o=function(){function t(){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.disposed_=!1}return r(t,[{key:"dispose",value:function(){this.disposed_||(this.disposeInternal(),this.disposed_=!0)}},{key:"disposeInternal",value:function(){}},{key:"isDisposed",value:function(){return this.disposed_}}]),t}();e.default=o},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}();var o=function(){function t(){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t)}return r(t,null,[{key:"mixin",value:function(t){for(var e=void 0,n=void 0,r=arguments.length,o=Array(r>1?r-1:0),a=1;a<r;a++)o[a-1]=arguments[a];for(var i=0;i<o.length;i++)for(e in n=o[i])t[e]=n[e];return t}},{key:"getObjectByName",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:window,n=t.split(".");return n.reduce(function(t,e){return t[e]},e)}},{key:"map",value:function(t,e){for(var n={},r=Object.keys(t),o=0;o<r.length;o++)n[r[o]]=e(r[o],t[r[o]]);return n}},{key:"shallowEqual",value:function(t,e){if(t===e)return!0;var n=Object.keys(t),r=Object.keys(e);if(n.length!==r.length)return!1;for(var o=0;o<n.length;o++)if(t[n[o]]!==e[n[o]])return!1;return!0}}]),t}();e.default=o},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}();var o=function(){function t(){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t)}return r(t,null,[{key:"caseInsensitiveCompare",value:function(t,e){var n=String(t).toLowerCase(),r=String(e).toLowerCase();return n<r?-1:n===r?0:1}},{key:"collapseBreakingSpaces",value:function(t){return t.replace(/[\t\r\n ]+/g," ").replace(/^[\t\r\n ]+|[\t\r\n ]+$/g,"")}},{key:"escapeRegex",value:function(t){return String(t).replace(/([-()[\]{}+?*.$^|,:#<!\\])/g,"\\$1").replace(/\x08/g,"\\x08")}},{key:"getRandomString",value:function(){var t=2147483648;return Math.floor(Math.random()*t).toString(36)+Math.abs(Math.floor(Math.random()*t)^Date.now()).toString(36)}},{key:"hashCode",value:function(t){for(var e=0,n=0,r=t.length;n<r;n++)e=31*e+t.charCodeAt(n),e%=4294967296;return e}},{key:"replaceInterval",value:function(t,e,n,r){return t.substring(0,e)+r+t.substring(n)}}]),t}();e.default=o},function(t,e,n){(function(t,n){var r=200,o="Expected a function",a="__lodash_hash_undefined__",i=1,u=2,c=1/0,l=9007199254740991,s="[object Arguments]",f="[object Array]",p="[object Boolean]",d="[object Date]",h="[object Error]",v="[object Function]",y="[object GeneratorFunction]",_="[object Map]",m="[object Number]",b="[object Object]",g="[object RegExp]",w="[object Set]",E="[object String]",j="[object Symbol]",O="[object ArrayBuffer]",S="[object DataView]",T=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,I=/^\w*$/,P=/^\./,k=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,A=/\\(\\)?/g,C=/^\[object .+?Constructor\]$/,R=/^(?:0|[1-9]\d*)$/,L={};L["[object Float32Array]"]=L["[object Float64Array]"]=L["[object Int8Array]"]=L["[object Int16Array]"]=L["[object Int32Array]"]=L["[object Uint8Array]"]=L["[object Uint8ClampedArray]"]=L["[object Uint16Array]"]=L["[object Uint32Array]"]=!0,L[s]=L[f]=L[O]=L[p]=L[S]=L[d]=L[h]=L[v]=L[_]=L[m]=L[b]=L[g]=L[w]=L[E]=L["[object WeakMap]"]=!1;var M="object"==typeof t&&t&&t.Object===Object&&t,D="object"==typeof self&&self&&self.Object===Object&&self,U=M||D||Function("return this")(),x=e&&!e.nodeType&&e,N=x&&"object"==typeof n&&n&&!n.nodeType&&n,F=N&&N.exports===x&&M.process,z=function(){try{return F&&F.binding("util")}catch(t){}}(),$=z&&z.isTypedArray;function W(t,e,n,r){for(var o=-1,a=t?t.length:0;++o<a;){var i=t[o];e(r,i,n(i),t)}return r}function B(t,e){for(var n=-1,r=t?t.length:0;++n<r;)if(e(t[n],n,t))return!0;return!1}function H(t){var e=!1;if(null!=t&&"function"!=typeof t.toString)try{e=!!(t+"")}catch(t){}return e}function J(t){var e=-1,n=Array(t.size);return t.forEach(function(t,r){n[++e]=[r,t]}),n}function G(t){var e=-1,n=Array(t.size);return t.forEach(function(t){n[++e]=t}),n}var V,Y,Q,q=Array.prototype,K=Function.prototype,X=Object.prototype,Z=U["__core-js_shared__"],tt=(V=/[^.]+$/.exec(Z&&Z.keys&&Z.keys.IE_PROTO||""))?"Symbol(src)_1."+V:"",et=K.toString,nt=X.hasOwnProperty,rt=X.toString,ot=RegExp("^"+et.call(nt).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),at=U.Symbol,it=U.Uint8Array,ut=X.propertyIsEnumerable,ct=q.splice,lt=(Y=Object.keys,Q=Object,function(t){return Y(Q(t))}),st=Jt(U,"DataView"),ft=Jt(U,"Map"),pt=Jt(U,"Promise"),dt=Jt(U,"Set"),ht=Jt(U,"WeakMap"),vt=Jt(Object,"create"),yt=Zt(st),_t=Zt(ft),mt=Zt(pt),bt=Zt(dt),gt=Zt(ht),wt=at?at.prototype:void 0,Et=wt?wt.valueOf:void 0,jt=wt?wt.toString:void 0;function Ot(t){var e=-1,n=t?t.length:0;for(this.clear();++e<n;){var r=t[e];this.set(r[0],r[1])}}function St(t){var e=-1,n=t?t.length:0;for(this.clear();++e<n;){var r=t[e];this.set(r[0],r[1])}}function Tt(t){var e=-1,n=t?t.length:0;for(this.clear();++e<n;){var r=t[e];this.set(r[0],r[1])}}function It(t){var e=-1,n=t?t.length:0;for(this.__data__=new Tt;++e<n;)this.add(t[e])}function Pt(t){this.__data__=new St(t)}function kt(t,e){var n=ie(t)||ae(t)?function(t,e){for(var n=-1,r=Array(t);++n<t;)r[n]=e(n);return r}(t.length,String):[],r=n.length,o=!!r;for(var a in t)!e&&!nt.call(t,a)||o&&("length"==a||Vt(a,r))||n.push(a);return n}function At(t,e){for(var n=t.length;n--;)if(oe(t[n][0],e))return n;return-1}function Ct(t,e,n,r){return Mt(t,function(t,o,a){e(r,t,n(t),a)}),r}Ot.prototype.clear=function(){this.__data__=vt?vt(null):{}},Ot.prototype.delete=function(t){return this.has(t)&&delete this.__data__[t]},Ot.prototype.get=function(t){var e=this.__data__;if(vt){var n=e[t];return n===a?void 0:n}return nt.call(e,t)?e[t]:void 0},Ot.prototype.has=function(t){var e=this.__data__;return vt?void 0!==e[t]:nt.call(e,t)},Ot.prototype.set=function(t,e){return this.__data__[t]=vt&&void 0===e?a:e,this},St.prototype.clear=function(){this.__data__=[]},St.prototype.delete=function(t){var e=this.__data__,n=At(e,t);return!(n<0)&&(n==e.length-1?e.pop():ct.call(e,n,1),!0)},St.prototype.get=function(t){var e=this.__data__,n=At(e,t);return n<0?void 0:e[n][1]},St.prototype.has=function(t){return At(this.__data__,t)>-1},St.prototype.set=function(t,e){var n=this.__data__,r=At(n,t);return r<0?n.push([t,e]):n[r][1]=e,this},Tt.prototype.clear=function(){this.__data__={hash:new Ot,map:new(ft||St),string:new Ot}},Tt.prototype.delete=function(t){return Ht(this,t).delete(t)},Tt.prototype.get=function(t){return Ht(this,t).get(t)},Tt.prototype.has=function(t){return Ht(this,t).has(t)},Tt.prototype.set=function(t,e){return Ht(this,t).set(t,e),this},It.prototype.add=It.prototype.push=function(t){return this.__data__.set(t,a),this},It.prototype.has=function(t){return this.__data__.has(t)},Pt.prototype.clear=function(){this.__data__=new St},Pt.prototype.delete=function(t){return this.__data__.delete(t)},Pt.prototype.get=function(t){return this.__data__.get(t)},Pt.prototype.has=function(t){return this.__data__.has(t)},Pt.prototype.set=function(t,e){var n=this.__data__;if(n instanceof St){var o=n.__data__;if(!ft||o.length<r-1)return o.push([t,e]),this;n=this.__data__=new Tt(o)}return n.set(t,e),this};var Rt,Lt,Mt=(Rt=function(t,e){return t&&Dt(t,e,he)},function(t,e){if(null==t)return t;if(!ue(t))return Rt(t,e);for(var n=t.length,r=Lt?n:-1,o=Object(t);(Lt?r--:++r<n)&&!1!==e(o[r],r,o););return t}),Dt=function(t){return function(e,n,r){for(var o=-1,a=Object(e),i=r(e),u=i.length;u--;){var c=i[t?u:++o];if(!1===n(a[c],c,a))break}return e}}();function Ut(t,e){for(var n=0,r=(e=Yt(e,t)?[e]:Wt(e)).length;null!=t&&n<r;)t=t[Xt(e[n++])];return n&&n==r?t:void 0}function xt(t,e){return null!=t&&e in Object(t)}function Nt(t,e,n,r,o){return t===e||(null==t||null==e||!se(t)&&!fe(e)?t!=t&&e!=e:function(t,e,n,r,o,a){var c=ie(t),l=ie(e),v=f,y=f;c||(v=(v=Gt(t))==s?b:v);l||(y=(y=Gt(e))==s?b:y);var T=v==b&&!H(t),I=y==b&&!H(e),P=v==y;if(P&&!T)return a||(a=new Pt),c||de(t)?Bt(t,e,n,r,o,a):function(t,e,n,r,o,a,c){switch(n){case S:if(t.byteLength!=e.byteLength||t.byteOffset!=e.byteOffset)return!1;t=t.buffer,e=e.buffer;case O:return!(t.byteLength!=e.byteLength||!r(new it(t),new it(e)));case p:case d:case m:return oe(+t,+e);case h:return t.name==e.name&&t.message==e.message;case g:case E:return t==e+"";case _:var l=J;case w:var s=a&u;if(l||(l=G),t.size!=e.size&&!s)return!1;var f=c.get(t);if(f)return f==e;a|=i,c.set(t,e);var v=Bt(l(t),l(e),r,o,a,c);return c.delete(t),v;case j:if(Et)return Et.call(t)==Et.call(e)}return!1}(t,e,v,n,r,o,a);if(!(o&u)){var k=T&&nt.call(t,"__wrapped__"),A=I&&nt.call(e,"__wrapped__");if(k||A){var C=k?t.value():t,R=A?e.value():e;return a||(a=new Pt),n(C,R,r,o,a)}}if(!P)return!1;return a||(a=new Pt),function(t,e,n,r,o,a){var i=o&u,c=he(t),l=c.length,s=he(e).length;if(l!=s&&!i)return!1;var f=l;for(;f--;){var p=c[f];if(!(i?p in e:nt.call(e,p)))return!1}var d=a.get(t);if(d&&a.get(e))return d==e;var h=!0;a.set(t,e),a.set(e,t);var v=i;for(;++f<l;){p=c[f];var y=t[p],_=e[p];if(r)var m=i?r(_,y,p,e,t,a):r(y,_,p,t,e,a);if(!(void 0===m?y===_||n(y,_,r,o,a):m)){h=!1;break}v||(v="constructor"==p)}if(h&&!v){var b=t.constructor,g=e.constructor;b!=g&&"constructor"in t&&"constructor"in e&&!("function"==typeof b&&b instanceof b&&"function"==typeof g&&g instanceof g)&&(h=!1)}return a.delete(t),a.delete(e),h}(t,e,n,r,o,a)}(t,e,Nt,n,r,o))}function Ft(t){return!(!se(t)||function(t){return!!tt&&tt in t}(t))&&(ce(t)||H(t)?ot:C).test(Zt(t))}function zt(t){return"function"==typeof t?t:null==t?ve:"object"==typeof t?ie(t)?function(t,e){if(Yt(t)&&Qt(e))return qt(Xt(t),e);return function(n){var r=function(t,e,n){var r=null==t?void 0:Ut(t,e);return void 0===r?n:r}(n,t);return void 0===r&&r===e?function(t,e){return null!=t&&function(t,e,n){e=Yt(e,t)?[e]:Wt(e);var r,o=-1,a=e.length;for(;++o<a;){var i=Xt(e[o]);if(!(r=null!=t&&n(t,i)))break;t=t[i]}if(r)return r;return!!(a=t?t.length:0)&&le(a)&&Vt(i,a)&&(ie(t)||ae(t))}(t,e,xt)}(n,t):Nt(e,r,void 0,i|u)}}(t[0],t[1]):function(t){var e=function(t){var e=he(t),n=e.length;for(;n--;){var r=e[n],o=t[r];e[n]=[r,o,Qt(o)]}return e}(t);if(1==e.length&&e[0][2])return qt(e[0][0],e[0][1]);return function(n){return n===t||function(t,e,n,r){var o=n.length,a=o,c=!r;if(null==t)return!a;for(t=Object(t);o--;){var l=n[o];if(c&&l[2]?l[1]!==t[l[0]]:!(l[0]in t))return!1}for(;++o<a;){var s=(l=n[o])[0],f=t[s],p=l[1];if(c&&l[2]){if(void 0===f&&!(s in t))return!1}else{var d=new Pt;if(r)var h=r(f,p,s,t,e,d);if(!(void 0===h?Nt(p,f,r,i|u,d):h))return!1}}return!0}(n,t,e)}}(t):Yt(e=t)?(n=Xt(e),function(t){return null==t?void 0:t[n]}):function(t){return function(e){return Ut(e,t)}}(e);var e,n}function $t(t){if(n=(e=t)&&e.constructor,r="function"==typeof n&&n.prototype||X,e!==r)return lt(t);var e,n,r,o=[];for(var a in Object(t))nt.call(t,a)&&"constructor"!=a&&o.push(a);return o}function Wt(t){return ie(t)?t:Kt(t)}function Bt(t,e,n,r,o,a){var c=o&u,l=t.length,s=e.length;if(l!=s&&!(c&&s>l))return!1;var f=a.get(t);if(f&&a.get(e))return f==e;var p=-1,d=!0,h=o&i?new It:void 0;for(a.set(t,e),a.set(e,t);++p<l;){var v=t[p],y=e[p];if(r)var _=c?r(y,v,p,e,t,a):r(v,y,p,t,e,a);if(void 0!==_){if(_)continue;d=!1;break}if(h){if(!B(e,function(t,e){if(!h.has(e)&&(v===t||n(v,t,r,o,a)))return h.add(e)})){d=!1;break}}else if(v!==y&&!n(v,y,r,o,a)){d=!1;break}}return a.delete(t),a.delete(e),d}function Ht(t,e){var n,r,o=t.__data__;return("string"==(r=typeof(n=e))||"number"==r||"symbol"==r||"boolean"==r?"__proto__"!==n:null===n)?o["string"==typeof e?"string":"hash"]:o.map}function Jt(t,e){var n=function(t,e){return null==t?void 0:t[e]}(t,e);return Ft(n)?n:void 0}var Gt=function(t){return rt.call(t)};function Vt(t,e){return!!(e=null==e?l:e)&&("number"==typeof t||R.test(t))&&t>-1&&t%1==0&&t<e}function Yt(t,e){if(ie(t))return!1;var n=typeof t;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=t&&!pe(t))||(I.test(t)||!T.test(t)||null!=e&&t in Object(e))}function Qt(t){return t==t&&!se(t)}function qt(t,e){return function(n){return null!=n&&(n[t]===e&&(void 0!==e||t in Object(n)))}}(st&&Gt(new st(new ArrayBuffer(1)))!=S||ft&&Gt(new ft)!=_||pt&&"[object Promise]"!=Gt(pt.resolve())||dt&&Gt(new dt)!=w||ht&&"[object WeakMap]"!=Gt(new ht))&&(Gt=function(t){var e=rt.call(t),n=e==b?t.constructor:void 0,r=n?Zt(n):void 0;if(r)switch(r){case yt:return S;case _t:return _;case mt:return"[object Promise]";case bt:return w;case gt:return"[object WeakMap]"}return e});var Kt=re(function(t){var e;t=null==(e=t)?"":function(t){if("string"==typeof t)return t;if(pe(t))return jt?jt.call(t):"";var e=t+"";return"0"==e&&1/t==-c?"-0":e}(e);var n=[];return P.test(t)&&n.push(""),t.replace(k,function(t,e,r,o){n.push(r?o.replace(A,"$1"):e||t)}),n});function Xt(t){if("string"==typeof t||pe(t))return t;var e=t+"";return"0"==e&&1/t==-c?"-0":e}function Zt(t){if(null!=t){try{return et.call(t)}catch(t){}try{return t+""}catch(t){}}return""}var te,ee,ne=(te=function(t,e,n){nt.call(t,n)?t[n].push(e):t[n]=[e]},function(t,e){var n=ie(t)?W:Ct,r=ee?ee():{};return n(t,te,zt(e),r)});function re(t,e){if("function"!=typeof t||e&&"function"!=typeof e)throw new TypeError(o);var n=function(){var r=arguments,o=e?e.apply(this,r):r[0],a=n.cache;if(a.has(o))return a.get(o);var i=t.apply(this,r);return n.cache=a.set(o,i),i};return n.cache=new(re.Cache||Tt),n}function oe(t,e){return t===e||t!=t&&e!=e}function ae(t){return function(t){return fe(t)&&ue(t)}(t)&&nt.call(t,"callee")&&(!ut.call(t,"callee")||rt.call(t)==s)}re.Cache=Tt;var ie=Array.isArray;function ue(t){return null!=t&&le(t.length)&&!ce(t)}function ce(t){var e=se(t)?rt.call(t):"";return e==v||e==y}function le(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=l}function se(t){var e=typeof t;return!!t&&("object"==e||"function"==e)}function fe(t){return!!t&&"object"==typeof t}function pe(t){return"symbol"==typeof t||fe(t)&&rt.call(t)==j}var de=$?function(t){return function(e){return t(e)}}($):function(t){return fe(t)&&le(t.length)&&!!L[rt.call(t)]};function he(t){return ue(t)?kt(t):$t(t)}function ve(t){return t}n.exports=ne}).call(this,n(0),n(4)(t))},function(t,e,n){(function(t,n){var r=200,o="__lodash_hash_undefined__",a=1,i=2,u=9007199254740991,c="[object Arguments]",l="[object Array]",s="[object AsyncFunction]",f="[object Boolean]",p="[object Date]",d="[object Error]",h="[object Function]",v="[object GeneratorFunction]",y="[object Map]",_="[object Number]",m="[object Null]",b="[object Object]",g="[object Proxy]",w="[object RegExp]",E="[object Set]",j="[object String]",O="[object Symbol]",S="[object Undefined]",T="[object ArrayBuffer]",I="[object DataView]",P=/^\[object .+?Constructor\]$/,k=/^(?:0|[1-9]\d*)$/,A={};A["[object Float32Array]"]=A["[object Float64Array]"]=A["[object Int8Array]"]=A["[object Int16Array]"]=A["[object Int32Array]"]=A["[object Uint8Array]"]=A["[object Uint8ClampedArray]"]=A["[object Uint16Array]"]=A["[object Uint32Array]"]=!0,A[c]=A[l]=A[T]=A[f]=A[I]=A[p]=A[d]=A[h]=A[y]=A[_]=A[b]=A[w]=A[E]=A[j]=A["[object WeakMap]"]=!1;var C="object"==typeof t&&t&&t.Object===Object&&t,R="object"==typeof self&&self&&self.Object===Object&&self,L=C||R||Function("return this")(),M=e&&!e.nodeType&&e,D=M&&"object"==typeof n&&n&&!n.nodeType&&n,U=D&&D.exports===M,x=U&&C.process,N=function(){try{return x&&x.binding&&x.binding("util")}catch(t){}}(),F=N&&N.isTypedArray;function z(t,e){for(var n=-1,r=null==t?0:t.length;++n<r;)if(e(t[n],n,t))return!0;return!1}function $(t){var e=-1,n=Array(t.size);return t.forEach(function(t,r){n[++e]=[r,t]}),n}function W(t){var e=-1,n=Array(t.size);return t.forEach(function(t){n[++e]=t}),n}var B,H,J,G=Array.prototype,V=Function.prototype,Y=Object.prototype,Q=L["__core-js_shared__"],q=V.toString,K=Y.hasOwnProperty,X=(B=/[^.]+$/.exec(Q&&Q.keys&&Q.keys.IE_PROTO||""))?"Symbol(src)_1."+B:"",Z=Y.toString,tt=RegExp("^"+q.call(K).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),et=U?L.Buffer:void 0,nt=L.Symbol,rt=L.Uint8Array,ot=Y.propertyIsEnumerable,at=G.splice,it=nt?nt.toStringTag:void 0,ut=Object.getOwnPropertySymbols,ct=et?et.isBuffer:void 0,lt=(H=Object.keys,J=Object,function(t){return H(J(t))}),st=Nt(L,"DataView"),ft=Nt(L,"Map"),pt=Nt(L,"Promise"),dt=Nt(L,"Set"),ht=Nt(L,"WeakMap"),vt=Nt(Object,"create"),yt=Wt(st),_t=Wt(ft),mt=Wt(pt),bt=Wt(dt),gt=Wt(ht),wt=nt?nt.prototype:void 0,Et=wt?wt.valueOf:void 0;function jt(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e<n;){var r=t[e];this.set(r[0],r[1])}}function Ot(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e<n;){var r=t[e];this.set(r[0],r[1])}}function St(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e<n;){var r=t[e];this.set(r[0],r[1])}}function Tt(t){var e=-1,n=null==t?0:t.length;for(this.__data__=new St;++e<n;)this.add(t[e])}function It(t){var e=this.__data__=new Ot(t);this.size=e.size}function Pt(t,e){var n=Jt(t),r=!n&&Ht(t),o=!n&&!r&&Gt(t),a=!n&&!r&&!o&&Kt(t),i=n||r||o||a,u=i?function(t,e){for(var n=-1,r=Array(t);++n<t;)r[n]=e(n);return r}(t.length,String):[],c=u.length;for(var l in t)!e&&!K.call(t,l)||i&&("length"==l||o&&("offset"==l||"parent"==l)||a&&("buffer"==l||"byteLength"==l||"byteOffset"==l)||$t(l,c))||u.push(l);return u}function kt(t,e){for(var n=t.length;n--;)if(Bt(t[n][0],e))return n;return-1}function At(t){return null==t?void 0===t?S:m:it&&it in Object(t)?function(t){var e=K.call(t,it),n=t[it];try{t[it]=void 0;var r=!0}catch(t){}var o=Z.call(t);r&&(e?t[it]=n:delete t[it]);return o}(t):function(t){return Z.call(t)}(t)}function Ct(t){return qt(t)&&At(t)==c}function Rt(t,e,n,r,o){return t===e||(null==t||null==e||!qt(t)&&!qt(e)?t!=t&&e!=e:function(t,e,n,r,o,u){var s=Jt(t),h=Jt(e),v=s?l:zt(t),m=h?l:zt(e),g=(v=v==c?b:v)==b,S=(m=m==c?b:m)==b,P=v==m;if(P&&Gt(t)){if(!Gt(e))return!1;s=!0,g=!1}if(P&&!g)return u||(u=new It),s||Kt(t)?Dt(t,e,n,r,o,u):function(t,e,n,r,o,u,c){switch(n){case I:if(t.byteLength!=e.byteLength||t.byteOffset!=e.byteOffset)return!1;t=t.buffer,e=e.buffer;case T:return!(t.byteLength!=e.byteLength||!u(new rt(t),new rt(e)));case f:case p:case _:return Bt(+t,+e);case d:return t.name==e.name&&t.message==e.message;case w:case j:return t==e+"";case y:var l=$;case E:var s=r&a;if(l||(l=W),t.size!=e.size&&!s)return!1;var h=c.get(t);if(h)return h==e;r|=i,c.set(t,e);var v=Dt(l(t),l(e),r,o,u,c);return c.delete(t),v;case O:if(Et)return Et.call(t)==Et.call(e)}return!1}(t,e,v,n,r,o,u);if(!(n&a)){var k=g&&K.call(t,"__wrapped__"),A=S&&K.call(e,"__wrapped__");if(k||A){var C=k?t.value():t,R=A?e.value():e;return u||(u=new It),o(C,R,n,r,u)}}if(!P)return!1;return u||(u=new It),function(t,e,n,r,o,i){var u=n&a,c=Ut(t),l=c.length,s=Ut(e).length;if(l!=s&&!u)return!1;var f=l;for(;f--;){var p=c[f];if(!(u?p in e:K.call(e,p)))return!1}var d=i.get(t);if(d&&i.get(e))return d==e;var h=!0;i.set(t,e),i.set(e,t);var v=u;for(;++f<l;){p=c[f];var y=t[p],_=e[p];if(r)var m=u?r(_,y,p,e,t,i):r(y,_,p,t,e,i);if(!(void 0===m?y===_||o(y,_,n,r,i):m)){h=!1;break}v||(v="constructor"==p)}if(h&&!v){var b=t.constructor,g=e.constructor;b!=g&&"constructor"in t&&"constructor"in e&&!("function"==typeof b&&b instanceof b&&"function"==typeof g&&g instanceof g)&&(h=!1)}return i.delete(t),i.delete(e),h}(t,e,n,r,o,u)}(t,e,n,r,Rt,o))}function Lt(t){return!(!Qt(t)||function(t){return!!X&&X in t}(t))&&(Vt(t)?tt:P).test(Wt(t))}function Mt(t){if(n=(e=t)&&e.constructor,r="function"==typeof n&&n.prototype||Y,e!==r)return lt(t);var e,n,r,o=[];for(var a in Object(t))K.call(t,a)&&"constructor"!=a&&o.push(a);return o}function Dt(t,e,n,r,o,u){var c=n&a,l=t.length,s=e.length;if(l!=s&&!(c&&s>l))return!1;var f=u.get(t);if(f&&u.get(e))return f==e;var p=-1,d=!0,h=n&i?new Tt:void 0;for(u.set(t,e),u.set(e,t);++p<l;){var v=t[p],y=e[p];if(r)var _=c?r(y,v,p,e,t,u):r(v,y,p,t,e,u);if(void 0!==_){if(_)continue;d=!1;break}if(h){if(!z(e,function(t,e){if(a=e,!h.has(a)&&(v===t||o(v,t,n,r,u)))return h.push(e);var a})){d=!1;break}}else if(v!==y&&!o(v,y,n,r,u)){d=!1;break}}return u.delete(t),u.delete(e),d}function Ut(t){return function(t,e,n){var r=e(t);return Jt(t)?r:function(t,e){for(var n=-1,r=e.length,o=t.length;++n<r;)t[o+n]=e[n];return t}(r,n(t))}(t,Xt,Ft)}function xt(t,e){var n,r,o=t.__data__;return("string"==(r=typeof(n=e))||"number"==r||"symbol"==r||"boolean"==r?"__proto__"!==n:null===n)?o["string"==typeof e?"string":"hash"]:o.map}function Nt(t,e){var n=function(t,e){return null==t?void 0:t[e]}(t,e);return Lt(n)?n:void 0}jt.prototype.clear=function(){this.__data__=vt?vt(null):{},this.size=0},jt.prototype.delete=function(t){var e=this.has(t)&&delete this.__data__[t];return this.size-=e?1:0,e},jt.prototype.get=function(t){var e=this.__data__;if(vt){var n=e[t];return n===o?void 0:n}return K.call(e,t)?e[t]:void 0},jt.prototype.has=function(t){var e=this.__data__;return vt?void 0!==e[t]:K.call(e,t)},jt.prototype.set=function(t,e){var n=this.__data__;return this.size+=this.has(t)?0:1,n[t]=vt&&void 0===e?o:e,this},Ot.prototype.clear=function(){this.__data__=[],this.size=0},Ot.prototype.delete=function(t){var e=this.__data__,n=kt(e,t);return!(n<0)&&(n==e.length-1?e.pop():at.call(e,n,1),--this.size,!0)},Ot.prototype.get=function(t){var e=this.__data__,n=kt(e,t);return n<0?void 0:e[n][1]},Ot.prototype.has=function(t){return kt(this.__data__,t)>-1},Ot.prototype.set=function(t,e){var n=this.__data__,r=kt(n,t);return r<0?(++this.size,n.push([t,e])):n[r][1]=e,this},St.prototype.clear=function(){this.size=0,this.__data__={hash:new jt,map:new(ft||Ot),string:new jt}},St.prototype.delete=function(t){var e=xt(this,t).delete(t);return this.size-=e?1:0,e},St.prototype.get=function(t){return xt(this,t).get(t)},St.prototype.has=function(t){return xt(this,t).has(t)},St.prototype.set=function(t,e){var n=xt(this,t),r=n.size;return n.set(t,e),this.size+=n.size==r?0:1,this},Tt.prototype.add=Tt.prototype.push=function(t){return this.__data__.set(t,o),this},Tt.prototype.has=function(t){return this.__data__.has(t)},It.prototype.clear=function(){this.__data__=new Ot,this.size=0},It.prototype.delete=function(t){var e=this.__data__,n=e.delete(t);return this.size=e.size,n},It.prototype.get=function(t){return this.__data__.get(t)},It.prototype.has=function(t){return this.__data__.has(t)},It.prototype.set=function(t,e){var n=this.__data__;if(n instanceof Ot){var o=n.__data__;if(!ft||o.length<r-1)return o.push([t,e]),this.size=++n.size,this;n=this.__data__=new St(o)}return n.set(t,e),this.size=n.size,this};var Ft=ut?function(t){return null==t?[]:(t=Object(t),function(t,e){for(var n=-1,r=null==t?0:t.length,o=0,a=[];++n<r;){var i=t[n];e(i,n,t)&&(a[o++]=i)}return a}(ut(t),function(e){return ot.call(t,e)}))}:function(){return[]},zt=At;function $t(t,e){return!!(e=null==e?u:e)&&("number"==typeof t||k.test(t))&&t>-1&&t%1==0&&t<e}function Wt(t){if(null!=t){try{return q.call(t)}catch(t){}try{return t+""}catch(t){}}return""}function Bt(t,e){return t===e||t!=t&&e!=e}(st&&zt(new st(new ArrayBuffer(1)))!=I||ft&&zt(new ft)!=y||pt&&"[object Promise]"!=zt(pt.resolve())||dt&&zt(new dt)!=E||ht&&"[object WeakMap]"!=zt(new ht))&&(zt=function(t){var e=At(t),n=e==b?t.constructor:void 0,r=n?Wt(n):"";if(r)switch(r){case yt:return I;case _t:return y;case mt:return"[object Promise]";case bt:return E;case gt:return"[object WeakMap]"}return e});var Ht=Ct(function(){return arguments}())?Ct:function(t){return qt(t)&&K.call(t,"callee")&&!ot.call(t,"callee")},Jt=Array.isArray;var Gt=ct||function(){return!1};function Vt(t){if(!Qt(t))return!1;var e=At(t);return e==h||e==v||e==s||e==g}function Yt(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=u}function Qt(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}function qt(t){return null!=t&&"object"==typeof t}var Kt=F?function(t){return function(e){return t(e)}}(F):function(t){return qt(t)&&Yt(t.length)&&!!A[At(t)]};function Xt(t){return null!=(e=t)&&Yt(e.length)&&!Vt(e)?Pt(t):Mt(t);var e}n.exports=function(t,e){return Rt(t,e)}}).call(this,n(0),n(4)(t))},function(t,e,n){var r;Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var o={register:((r=n(23))&&r.__esModule?r:{default:r}).default};e.default=o},function(t,e,n){(function(t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=e.register=void 0;var r=i(n(24)),o=i(n(25)),a=n(6);function i(t){return t&&t.__esModule?t:{default:t}}var u=function(e){(0,a.validateArguments)(arguments,1,1,["string"]);var n=t.portlet.data.pageRenderState;return new r.default(function(t,r){(0,a.validatePortletId)(n,e)?t(new o.default(e)):r(new Error("Invalid portlet ID"))})};e.register=u;var c=u;e.default=c}).call(this,n(0))},function(t,e,n){"use strict";
/*!
 * Promises polyfill from Google's Closure Library.
 *
 *      Copyright 2013 The Closure Library Authors. All Rights Reserved.
 *
 * NOTE(eduardo): Promise support is not ready on all supported browsers,
 * therefore metal-promise is temporarily using Google's promises as polyfill.
 * It supports cancellable promises and has clean and fast implementation.
 */Object.defineProperty(e,"__esModule",{value:!0}),e.CancellablePromise=void 0;var r=n(1);var o=function(){};o.prototype.then=function(){},o.IMPLEMENTED_BY_PROP="$goog_Thenable",o.addImplementation=function(t){t.prototype.then=t.prototype.then,t.prototype.$goog_Thenable=!0},o.isImplementedBy=function(t){if(!t)return!1;try{return!!t.$goog_Thenable}catch(t){return!1}};var a=function(t){var e=Array.prototype.slice.call(arguments,1);return function(){var n=e.slice();return n.push.apply(n,arguments),t.apply(this,n)}},i=function t(e,n){this.state_=t.State_.PENDING,this.result_=void 0,this.parent_=null,this.callbackEntries_=null,this.executing_=!1,t.UNHANDLED_REJECTION_DELAY>0?this.unhandledRejectionId_=0:0===t.UNHANDLED_REJECTION_DELAY&&(this.hadUnhandledRejection_=!1);try{var r=this;e.call(n,function(e){r.resolve_(t.State_.FULFILLED,e)},function(e){r.resolve_(t.State_.REJECTED,e)})}catch(e){this.resolve_(t.State_.REJECTED,e)}};i.UNHANDLED_REJECTION_DELAY=0,i.State_={PENDING:0,BLOCKED:1,FULFILLED:2,REJECTED:3},i.CallbackEntry_=null,i.resolve=function(t){return new i(function(e){e(t)})},i.reject=function(t){return new i(function(e,n){n(t)})},i.race=function(t){return new i(function(e,n){t.length||e(void 0);for(var r,o=0;r=t[o];o++)r.then(e,n)})},i.all=function(t){return new i(function(e,n){var r=t.length,o=[];if(r)for(var i,u=function(t,n){r--,o[t]=n,0===r&&e(o)},c=function(t){n(t)},l=0;i=t[l];l++)i.then(a(u,l),c);else e(o)})},i.firstFulfilled=function(t){return new i(function(e,n){var r=t.length,o=[];if(r)for(var i,u=function(t){e(t)},c=function(t,e){r--,o[t]=e,0===r&&n(o)},l=0;i=t[l];l++)i.then(u,a(c,l));else e(void 0)})},i.prototype.then=function(t,e,n){return this.addChildPromise_((0,r.isFunction)(t)?t:null,(0,r.isFunction)(e)?e:null,n)},o.addImplementation(i),i.prototype.thenAlways=function(t,e){var n=function(){try{t.call(e)}catch(t){i.handleRejection_.call(null,t)}};return this.addCallbackEntry_({child:null,onRejected:n,onFulfilled:n}),this},i.prototype.thenCatch=function(t,e){return this.addChildPromise_(null,t,e)},i.prototype.catch=i.prototype.thenCatch,i.prototype.cancel=function(t){this.state_===i.State_.PENDING&&r.async.run(function(){var e=new i.CancellationError(t);e.IS_CANCELLATION_ERROR=!0,this.cancelInternal_(e)},this)},i.prototype.cancelInternal_=function(t){this.state_===i.State_.PENDING&&(this.parent_?this.parent_.cancelChild_(this,t):this.resolve_(i.State_.REJECTED,t))},i.prototype.cancelChild_=function(t,e){if(this.callbackEntries_){for(var n,r=0,o=-1,a=0;n=this.callbackEntries_[a];a++){var u=n.child;if(u&&(r++,u===t&&(o=a),o>=0&&r>1))break}if(o>=0)if(this.state_===i.State_.PENDING&&1===r)this.cancelInternal_(e);else{var c=this.callbackEntries_.splice(o,1)[0];this.executeCallback_(c,i.State_.REJECTED,e)}}},i.prototype.addCallbackEntry_=function(t){this.callbackEntries_&&this.callbackEntries_.length||this.state_!==i.State_.FULFILLED&&this.state_!==i.State_.REJECTED||this.scheduleCallbacks_(),this.callbackEntries_||(this.callbackEntries_=[]),this.callbackEntries_.push(t)},i.prototype.addChildPromise_=function(t,e,n){var o={child:null,onFulfilled:null,onRejected:null};return o.child=new i(function(a,i){o.onFulfilled=t?function(e){try{var r=t.call(n,e);a(r)}catch(t){i(t)}}:a,o.onRejected=e?function(t){try{var o=e.call(n,t);!(0,r.isDef)(o)&&t.IS_CANCELLATION_ERROR?i(t):a(o)}catch(t){i(t)}}:i}),o.child.parent_=this,this.addCallbackEntry_(o),o.child},i.prototype.unblockAndFulfill_=function(t){if(this.state_!==i.State_.BLOCKED)throw new Error("CancellablePromise is not blocked.");this.state_=i.State_.PENDING,this.resolve_(i.State_.FULFILLED,t)},i.prototype.unblockAndReject_=function(t){if(this.state_!==i.State_.BLOCKED)throw new Error("CancellablePromise is not blocked.");this.state_=i.State_.PENDING,this.resolve_(i.State_.REJECTED,t)},i.prototype.resolve_=function(t,e){if(this.state_===i.State_.PENDING){if(this===e)t=i.State_.REJECTED,e=new TypeError("CancellablePromise cannot resolve to itself");else{if(o.isImplementedBy(e))return e=e,this.state_=i.State_.BLOCKED,void e.then(this.unblockAndFulfill_,this.unblockAndReject_,this);if((0,r.isObject)(e))try{var n=e.then;if((0,r.isFunction)(n))return void this.tryThen_(e,n)}catch(n){t=i.State_.REJECTED,e=n}}this.result_=e,this.state_=t,this.scheduleCallbacks_(),t!==i.State_.REJECTED||e.IS_CANCELLATION_ERROR||i.addUnhandledRejection_(this,e)}},i.prototype.tryThen_=function(t,e){this.state_=i.State_.BLOCKED;var n=this,r=!1,o=function(t){r||(r=!0,n.unblockAndReject_(t))};try{e.call(t,function(t){r||(r=!0,n.unblockAndFulfill_(t))},o)}catch(t){o(t)}},i.prototype.scheduleCallbacks_=function(){this.executing_||(this.executing_=!0,r.async.run(this.executeCallbacks_,this))},i.prototype.executeCallbacks_=function(){for(;this.callbackEntries_&&this.callbackEntries_.length;){var t=this.callbackEntries_;this.callbackEntries_=[];for(var e=0;e<t.length;e++)this.executeCallback_(t[e],this.state_,this.result_)}this.executing_=!1},i.prototype.executeCallback_=function(t,e,n){e===i.State_.FULFILLED?t.onFulfilled(n):(this.removeUnhandledRejection_(),t.onRejected(n))},i.prototype.removeUnhandledRejection_=function(){var t;if(i.UNHANDLED_REJECTION_DELAY>0)for(t=this;t&&t.unhandledRejectionId_;t=t.parent_)clearTimeout(t.unhandledRejectionId_),t.unhandledRejectionId_=0;else if(0===i.UNHANDLED_REJECTION_DELAY)for(t=this;t&&t.hadUnhandledRejection_;t=t.parent_)t.hadUnhandledRejection_=!1},i.addUnhandledRejection_=function(t,e){i.UNHANDLED_REJECTION_DELAY>0?t.unhandledRejectionId_=setTimeout(function(){i.handleRejection_.call(null,e)},i.UNHANDLED_REJECTION_DELAY):0===i.UNHANDLED_REJECTION_DELAY&&(t.hadUnhandledRejection_=!0,r.async.run(function(){t.hadUnhandledRejection_&&i.handleRejection_.call(null,e)}))},i.handleRejection_=r.async.throwException,i.setUnhandledRejectionHandler=function(t){i.handleRejection_=t},(i.CancellationError=function(t){function e(n){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e);var r=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}(this,t.call(this,n));return n&&(r.message=n),r}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}(e,t),e}(Error)).prototype.name="cancel",e.CancellablePromise=i,e.default=i},function(t,e,n){(function(t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=e.PortletInit=void 0;var r=n(1),o=c(n(26)),a=c(n(5)),i=n(6),u=c(n(29));function c(t){return t&&t.__esModule?t:{default:t}}function l(t){return(l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function s(t){return function(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);e<t.length;e++)n[e]=t[e];return n}}(t)||function(t){if(Symbol.iterator in Object(t)||"[object Arguments]"===Object.prototype.toString.call(t))return Array.from(t)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function f(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}var p,d=window.history&&window.history.pushState,h=!1,v={},y=[],_=function(){function e(n){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e),this._portletId=n,this.constants=Object.assign({},a.default),p||(p=t.portlet.data.pageRenderState,this._updateHistory(!0)),this.portletModes=p.portlets[this._portletId].allowedPM.slice(0),this.windowStates=p.portlets[this._portletId].allowedWS.slice(0)}var n,c,_;return n=e,(c=[{key:"_executeAction",value:function(t,e){var n=this;return new Promise(function(r,o){(0,i.getUrl)(p,"ACTION",n._portletId,t).then(function(t){var a=(0,i.generateActionUrl)(n._portletId,t,e);fetch(a.url,a).then(function(t){return t.text()}).then(function(t){var e=n._updatePageStateFromString(t,n._portletId);r(e)}).catch(function(t){o(t)})})})}},{key:"_hasListener",value:function(t){return Object.keys(v).map(function(t){return v[t].id}).includes(t)}},{key:"_reportError",value:function(t,e){Object.keys(v).map(function(n){var r=v[n];return r.id===t&&"portlet.onError"===r.type&&setTimeout(function(){r.handler("portlet.onError",e)}),!1})}},{key:"_setPageState",value:function(t,e){var n=this;if(!(0,r.isString)(e))throw new TypeError("Invalid update string: ".concat(e));this._updatePageState(e,t).then(function(t){n._updatePortletStates(t)},function(e){h=!1,n._reportError(t,e)})}},{key:"_setState",value:function(t){for(var e=(0,i.getUpdatedPublicRenderParameters)(p,this._portletId,t),n=[],r=0,o=Object.keys(e);r<o.length;r++)for(var a=o[r],u=e[a],c=p.prpMap[a],l=0,f=Object.keys(c);l<f.length;l++){var d=f[l];if(d!==this._portletId){var h=c[d].split("|"),v=h[0],y=h[1];void 0===u?delete p.portlets[v].state.parameters[y]:p.portlets[v].state.parameters[y]=s(u),n.push(v)}}var _=this._portletId;p.portlets[_].state=t,n.push(_);for(var m=0,b=n;m<b.length;m++){var g=b[m];p.portlets[g].renderData.content=null}return this._updateHistory(),Promise.resolve(n)}},{key:"_setupAction",value:function(t,e){var n=this;if(this.isInProgress())throw{message:"Operation is already in progress",name:"AccessDeniedException"};if(!this._hasListener(this._portletId))throw{message:"No onStateChange listener registered for portlet: ".concat(this._portletId),name:"NotInitializedException"};return h=!0,this._executeAction(t,e).then(function(t){return n._updatePortletStates(t).then(function(t){return h=!1,t})},function(t){h=!1,n._reportError(n._portletId,t)})}},{key:"_updateHistory",value:function(t){d&&(0,i.getUrl)(p,"RENDER",null,{}).then(function(e){var n=JSON.stringify(p);if(t)history.replaceState(n,"");else try{history.pushState(n,"",e)}catch(t){}})}},{key:"_updatePageState",value:function(t){var e=this;return new Promise(function(n,r){try{n(e._updatePageStateFromString(t,e._portletId))}catch(t){r(new Error("Partial Action decode status: ".concat(t.message)))}})}},{key:"_updatePageStateFromString",value:function(t,e){for(var n=(0,i.decodeUpdateString)(p,t),r=[],o=!1,a=0,u=Object.keys(n);a<u.length;a++){var c=u[a],l=n[c];p.portlets[c]=l,r.push(c),o=!0}return o&&e&&this._updateHistory(),r}},{key:"_updatePortletStates",value:function(t){var e=this;return new Promise(function(n,r){if(0===t.length)h=!1;else{var o=!0,a=!1,i=void 0;try{for(var u,c=t[Symbol.iterator]();!(o=(u=c.next()).done);o=!0){var l=u.value;e._updateStateForPortlet(l)}}catch(t){a=!0,i=t}finally{try{o||null==c.return||c.return()}finally{if(a)throw i}}}n(t)})}},{key:"_updateState",value:function(t){var e=this;if(h)throw{message:"Operation in progress",name:"AccessDeniedException"};if(!this._hasListener(this._portletId))throw{message:"No onStateChange listener registered for portlet: ".concat(this._portletId),name:"NotInitializedException"};h=!0,this._setState(t).then(function(t){e._updatePortletStates(t)}).catch(function(t){h=!1,e._reportError(e._portletId,t)})}},{key:"_updateStateForPortlet",value:function(t){for(var e=y.map(function(t){return t.handle}),n=0,r=Object.keys(v);n<r.length;n++){var o=r[n],a=v[o];"portlet.onStateChange"===a.type&&(a.id!==t||e.includes(o)||y.push(a))}y.length>0&&setTimeout(function(){for(h=!0;y.length>0;){var t=y.shift(),e=t.handler,n=t.id;if(p.portlets[n]){var r=p.portlets[n].renderData,o=new u.default(p.portlets[n].state);r&&r.content?e("portlet.onStateChange",o,r):e("portlet.onStateChange",o)}}h=!1})}},{key:"action",value:function(){for(var t=null,e=0,n=null,o=arguments.length,a=new Array(o),u=0;u<o;u++)a[u]=arguments[u];for(var c=0,l=a;c<l.length;c++){var s=l[c];if(s instanceof HTMLFormElement){if(null!==n)throw new TypeError("Too many [object HTMLFormElement] arguments: ".concat(s,", ").concat(n));n=s}else if((0,r.isObject)(s)){if((0,i.validateParameters)(s),null!==t)throw new TypeError("Too many parameters arguments");t=s}else if(void 0!==s){var f=Object.prototype.toString.call(s);throw new TypeError("Invalid argument type. Argument ".concat(e+1," is of type ").concat(f))}e++}return n&&(0,i.validateForm)(n),this._setupAction(t,n).then(function(t){Promise.resolve(t)}).catch(function(t){Promise.reject(t)})}},{key:"addEventListener",value:function(t,e){if(arguments.length>2)throw new TypeError("Too many arguments passed to addEventListener");if(!(0,r.isString)(t)||!(0,r.isFunction)(e))throw new TypeError("Invalid arguments passed to addEventListener");var n=this._portletId;if(t.startsWith("portlet.")&&"portlet.onStateChange"!==t&&"portlet.onError"!==t)throw new TypeError("The system event type is invalid: ".concat(t));var a=(0,o.default)(),i={handle:a,handler:e,id:n,type:t};return v[a]=i,"portlet.onStateChange"===t&&this._updateStateForPortlet(this._portletId),a}},{key:"createResourceUrl",value:function(t,e,n){if(arguments.length>3)throw new TypeError("Too many arguments. 3 arguments are allowed.");if(t){if(!(0,r.isObject)(t))throw new TypeError("Invalid argument type. Resource parameters must be a parameters object.");(0,i.validateParameters)(t)}var o=null;if(e){if(!(0,r.isString)(e))throw new TypeError("Invalid argument type. Cacheability argument must be a string.");if("cacheLevelPage"!==e&&"cacheLevelPortlet"!==e&&"cacheLevelFull"!==e)throw new TypeError("Invalid cacheability argument: ".concat(e));o=e}if(o||(o="cacheLevelPage"),n&&!(0,r.isString)(n))throw new TypeError("Invalid argument type. Resource ID argument must be a string.");return(0,i.getUrl)(p,"RESOURCE",this._portletId,t,o,n)}},{key:"dispatchClientEvent",value:function(t,e){if((0,i.validateArguments)(arguments,2,2,["string"]),t.match(new RegExp("^portlet[.].*")))throw new TypeError("The event type is invalid: "+t);return Object.keys(v).reduce(function(n,r){var o=v[r];return t.match(o.type)&&(o.handler(t,e),n++),n},0)}},{key:"isInProgress",value:function(){return h}},{key:"newParameters",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e={};return Object.keys(t).forEach(function(n){Array.isArray(t[n])&&(e[n]=s(t[n]))}),e}},{key:"newState",value:function(t){return new u.default(t)}},{key:"removeEventListener",value:function(t){if(arguments.length>1)throw new TypeError("Too many arguments passed to removeEventListener");if(!(0,r.isDefAndNotNull)(t))throw new TypeError("The event handle provided is ".concat(l(t)));var e=!1;if((0,r.isObject)(v[t])&&v[t].id===this._portletId){delete v[t];for(var n=y.length,o=0;o<n;o++){var a=y[o];a&&a.handle===t&&y.splice(o,1)}e=!0}if(!e)throw new TypeError("The event listener handle doesn't match any listeners.")}},{key:"setRenderState",value:function(t){if((0,i.validateArguments)(arguments,1,1,["object"]),p.portlets&&p.portlets[this._portletId]){var e=p.portlets[this._portletId];(0,i.validateState)(t,e),this._updateState(t)}}},{key:"startPartialAction",value:function(t){var e=this,n=null;if(arguments.length>1)throw new TypeError("Too many arguments. 1 arguments are allowed");if(void 0!==t){if(!(0,r.isObject)(t))throw new TypeError("Invalid argument type. Argument is of type ".concat(l(t)));(0,i.validateParameters)(t),n=t}if(!0===h)throw{message:"Operation in progress",name:"AccessDeniedException"};if(!this._hasListener(this._portletId))throw{message:"No onStateChange listener registered for portlet: ".concat(this._portletId),name:"NotInitializedException"};h=!0;var o={setPageState:function(t){e._setPageState(e._portletId,t)},url:""};return(0,i.getUrl)(p,"PARTIAL_ACTION",this._portletId,n).then(function(t){return o.url=t,o})}}])&&f(n.prototype,c),_&&f(n,_),e}();e.PortletInit=_;var m=_;e.default=m}).call(this,n(0))},function(t,e,n){var r,o,a=n(27),i=n(28),u=0,c=0;t.exports=function(t,e,n){var l=e&&n||0,s=e||[],f=(t=t||{}).node||r,p=void 0!==t.clockseq?t.clockseq:o;if(null==f||null==p){var d=a();null==f&&(f=r=[1|d[0],d[1],d[2],d[3],d[4],d[5]]),null==p&&(p=o=16383&(d[6]<<8|d[7]))}var h=void 0!==t.msecs?t.msecs:(new Date).getTime(),v=void 0!==t.nsecs?t.nsecs:c+1,y=h-u+(v-c)/1e4;if(y<0&&void 0===t.clockseq&&(p=p+1&16383),(y<0||h>u)&&void 0===t.nsecs&&(v=0),v>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");u=h,c=v,o=p;var _=(1e4*(268435455&(h+=122192928e5))+v)%4294967296;s[l++]=_>>>24&255,s[l++]=_>>>16&255,s[l++]=_>>>8&255,s[l++]=255&_;var m=h/4294967296*1e4&268435455;s[l++]=m>>>8&255,s[l++]=255&m,s[l++]=m>>>24&15|16,s[l++]=m>>>16&255,s[l++]=p>>>8|128,s[l++]=255&p;for(var b=0;b<6;++b)s[l+b]=f[b];return e||i(s)}},function(t,e){var n="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof window.msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto);if(n){var r=new Uint8Array(16);t.exports=function(){return n(r),r}}else{var o=new Array(16);t.exports=function(){for(var t,e=0;e<16;e++)0==(3&e)&&(t=4294967296*Math.random()),o[e]=t>>>((3&e)<<3)&255;return o}}},function(t,e){for(var n=[],r=0;r<256;++r)n[r]=(r+256).toString(16).substr(1);t.exports=function(t,e){var r=e||0,o=n;return[o[t[r++]],o[t[r++]],o[t[r++]],o[t[r++]],"-",o[t[r++]],o[t[r++]],"-",o[t[r++]],o[t[r++]],"-",o[t[r++]],o[t[r++]],"-",o[t[r++]],o[t[r++]],o[t[r++]],o[t[r++]],o[t[r++]],o[t[r++]]].join("")}},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=e.RenderState=void 0;var r,o=n(1),a=(r=n(5))&&r.__esModule?r:{default:r};function i(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}var u=function(){function t(e){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),(0,o.isObject)(e)?this.from(e):(this.parameters={},this.portletMode=a.default.VIEW,this.windowState=a.default.NORMAL)}var e,n,r;return e=t,(n=[{key:"clone",value:function(){return new t(this)}},{key:"from",value:function(t){for(var e in this.parameters={},t.parameters)t.parameters.hasOwnProperty(e)&&Array.isArray(t.parameters[e])&&(this.parameters[e]=t.parameters[e].slice(0));this.setPortletMode(t.portletMode),this.setWindowState(t.windowState)}},{key:"getPortletMode",value:function(){return this.portletMode}},{key:"getValue",value:function(t,e){if(!(0,o.isString)(t))throw new TypeError("Parameter name must be a string");var n=this.parameters[t];return Array.isArray(n)&&(n=n[0]),void 0===n&&void 0!==e&&(n=e),n}},{key:"getValues",value:function(t,e){if(!(0,o.isString)(t))throw new TypeError("Parameter name must be a string");var n=this.parameters[t];return n||e}},{key:"getWindowState",value:function(){return this.windowState}},{key:"remove",value:function(t){if(!(0,o.isString)(t))throw new TypeError("Parameter name must be a string");void 0!==this.parameters[t]&&delete this.parameters[t]}},{key:"setPortletMode",value:function(t){if(!(0,o.isString)(t))throw new TypeError("Portlet Mode must be a string");t!==a.default.EDIT&&t!==a.default.HELP&&t!==a.default.VIEW||(this.portletMode=t)}},{key:"setValue",value:function(t,e){if(!(0,o.isString)(t))throw new TypeError("Parameter name must be a string");if(!(0,o.isString)(e)&&null!==e&&!Array.isArray(e))throw new TypeError("Parameter value must be a string, an array or null");Array.isArray(e)||(e=[e]),this.parameters[t]=e}},{key:"setValues",value:function(t,e){this.setValue(t,e)}},{key:"setWindowState",value:function(t){if(!(0,o.isString)(t))throw new TypeError("Window State must be a string");t!==a.default.MAXIMIZED&&t!==a.default.MINIMIZED&&t!==a.default.NORMAL||(this.windowState=t)}}])&&i(e.prototype,n),r&&i(e,r),t}();e.RenderState=u;var c=u;e.default=c},function(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(t,e){Liferay.SPA?(Liferay.SPA.app.navigate(t),e&&Object.keys(e).forEach(function(t){Liferay.once(t,e[t])})):window.location.href=t}},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(t,e){var n;if("object"!==a(e))n=u(t,e);else{n={},Object.keys(e).forEach(function(r){var o=r;r=u(t,r),n[r]=e[o]})}return n};var r,o=(r=n(7))&&r.__esModule?r:{default:r};function a(t){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var i,u=(i=function(t,e){return void 0!==e&&0!==e.lastIndexOf(t,0)&&(e="".concat(t).concat(e)),e},(0,o.default)(i,function(){for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];return e.length>1?Array.prototype.join.call(e,"_"):String(e[0])}))},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:new FormData;var o=arguments.length>2?arguments[2]:void 0;Object.entries(e).forEach(function(e){var a,i,u=(i=2,function(t){if(Array.isArray(t))return t}(a=e)||function(t,e){var n=[],r=!0,o=!1,a=void 0;try{for(var i,u=t[Symbol.iterator]();!(r=(i=u.next()).done)&&(n.push(i.value),!e||n.length!==e);r=!0);}catch(t){o=!0,a=t}finally{try{r||null==u.return||u.return()}finally{if(o)throw a}}return n}(a,i)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()),c=u[0],l=u[1],s=o?"".concat(o,"[").concat(c,"]"):c;Array.isArray(l)?l.forEach(function(e){t(function(t,e,n){e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n;return t}({},s,e),n)}):!(0,r.isObject)(l)||l instanceof File?n.append(s,l):t(l,n,s)});return n};var r=n(1)},function(t,e,n){var r;Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var o=(0,((r=n(7))&&r.__esModule?r:{default:r}).default)(function(t){return t.split("").map(function(t){return t.charCodeAt()}).join("")});e.default=o},function(t,e,n){(function(e){var n=1/0,r="[object Symbol]",o=/&(?:amp|lt|gt|quot|#39|#96);/g,a=RegExp(o.source),i="object"==typeof e&&e&&e.Object===Object&&e,u="object"==typeof self&&self&&self.Object===Object&&self,c=i||u||Function("return this")();var l,s=(l={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'","&#96;":"`"},function(t){return null==l?void 0:l[t]}),f=Object.prototype.toString,p=c.Symbol,d=p?p.prototype:void 0,h=d?d.toString:void 0;function v(t){if("string"==typeof t)return t;if(function(t){return"symbol"==typeof t||function(t){return!!t&&"object"==typeof t}(t)&&f.call(t)==r}(t))return h?h.call(t):"";var e=t+"";return"0"==e&&1/t==-n?"-0":e}t.exports=function(t){var e;return(t=null==(e=t)?"":v(e))&&a.test(t)?t.replace(o,s):t}}).call(this,n(0))}]));
//# sourceMappingURL=global.bundle.js.map
;

(function (A, Liferay) {
  var Tabs = Liferay.namespace('Portal.Tabs');
  var ToolTip = Liferay.namespace('Portal.ToolTip');
  var BODY_CONTENT = 'bodyContent';
  var TRIGGER = 'trigger';

  Liferay.Portal.Tabs._show = function (event) {
    var names = event.names;
    var namespace = event.namespace;
    var selectedIndex = event.selectedIndex;
    var tabItem = event.tabItem;
    var tabSection = event.tabSection;

    if (tabItem) {
      tabItem.radioClass('active');
    }

    if (tabSection) {
      tabSection.show();
    }

    var tabTitle = A.one('#' + event.namespace + 'dropdownTitle');

    if (tabTitle) {
      tabTitle.html(tabItem.one('a').text());
    }

    names.splice(selectedIndex, 1);
    var el;

    for (var i = 0; i < names.length; i++) {
      el = A.one('#' + namespace + Liferay.Util.toCharCode(names[i]) + 'TabsSection');

      if (el) {
        el.hide();
      }
    }
  };

  Liferay.provide(Tabs, 'show', function (namespace, names, id, callback) {
    var namespacedId = namespace + Liferay.Util.toCharCode(id);
    var tab = A.one('#' + namespacedId + 'TabsId');
    var tabSection = A.one('#' + namespacedId + 'TabsSection');
    var details = {
      id: id,
      names: names,
      namespace: namespace,
      selectedIndex: names.indexOf(id),
      tabItem: tab,
      tabSection: tabSection
    };

    if (callback && A.Lang.isFunction(callback)) {
      callback.call(this, namespace, names, id, details);
    }

    Liferay.fire('showTab', details);
  }, ['aui-base']);
  Liferay.publish('showTab', {
    defaultFn: Liferay.Portal.Tabs._show
  });

  ToolTip._getText = function (id) {
    var node = A.one('#' + id);
    var text = '';

    if (node) {
      var toolTipTextNode = node.next('.taglib-text');

      if (toolTipTextNode) {
        text = toolTipTextNode.html();
      }
    }

    return text;
  };

  ToolTip.hide = function () {
    var instance = this;
    var cached = instance._cached;

    if (cached) {
      cached.hide();
    }
  };

  Liferay.provide(ToolTip, 'show', function (obj, text, tooltipConfig) {
    var instance = this;
    var cached = instance._cached;
    var hideTooltipTask = instance._hideTooltipTask;

    if (!cached) {
      var config = A.merge({
        cssClass: 'tooltip-help',
        html: true,
        opacity: 1,
        stickDuration: 100,
        visible: false,
        zIndex: Liferay.zIndex.TOOLTIP
      }, tooltipConfig);
      cached = new A.Tooltip(config).render();
      cached.after('visibleChange', A.bind('_syncUIPosAlign', cached));
      hideTooltipTask = A.debounce('_onBoundingBoxMouseleave', cached.get('stickDuration'), cached);
      instance._hideTooltipTask = hideTooltipTask;
      instance._cached = cached;
    } else {
      cached.setAttrs(tooltipConfig);
    }

    hideTooltipTask.cancel();

    if (obj.jquery) {
      obj = obj[0];
    }

    obj = A.one(obj);

    if (text == null) {
      text = instance._getText(obj.guid());
    }

    cached.set(BODY_CONTENT, text);
    cached.set(TRIGGER, obj);
    var boundingBox = cached.get('boundingBox');
    boundingBox.detach('hover');
    obj.detach('hover');
    obj.on('hover', A.bind('_onBoundingBoxMouseenter', cached), hideTooltipTask);
    boundingBox.on('hover', function (event) {
      hideTooltipTask.cancel();
      obj.once('mouseenter', hideTooltipTask.cancel);
    }, hideTooltipTask);
    cached.show();
  }, ['aui-tooltip-base']);
})(AUI(), Liferay);
//# sourceMappingURL=portal.js.map
;

(function (A, Liferay) {
  var Lang = A.Lang;
  var Util = Liferay.Util;
  var STR_HEAD = 'head';
  var TPL_NOT_AJAXABLE = '<div class="alert alert-info">{0}</div>';
  var Portlet = {
    list: [],
    readyCounter: 0,
    destroyComponents: function destroyComponents(portletId) {
      Liferay.destroyComponents(function (component, destroyConfig) {
        return portletId === destroyConfig.portletId;
      });
    },
    isStatic: function isStatic(portletId) {
      var instance = this;
      var id = Util.getPortletId(portletId.id || portletId);
      return id in instance._staticPortlets;
    },
    refreshLayout: function refreshLayout(portletBoundary) {},
    register: function register(portletId) {
      var instance = this;

      if (instance.list.indexOf(portletId) < 0) {
        instance.list.push(portletId);
      }
    },
    _defCloseFn: function _defCloseFn(event) {
      var instance = this;
      event.portlet.remove(true);

      if (!event.nestedPortlet) {
        A.io.request(themeDisplay.getPathMain() + '/portal/update_layout', {
          after: {
            success: function success() {
              Liferay.fire('updatedLayout');
            }
          },
          data: {
            cmd: 'delete',
            doAsUserId: event.doAsUserId,
            p_auth: Liferay.authToken,
            p_l_id: event.plid,
            p_p_id: event.portletId,
            p_v_l_s_g_id: themeDisplay.getSiteGroupId()
          }
        });
      }
    },
    _loadMarkupHeadElements: function _loadMarkupHeadElements(response, loadHTML) {
      var markupHeadElements = response.markupHeadElements;

      if (markupHeadElements && markupHeadElements.length) {
        var head = A.one(STR_HEAD);
        head.append(markupHeadElements);
        var container = A.Node.create('<div />');
        container.plug(A.Plugin.ParseContent);
        container.setContent(markupHeadElements);
      }
    },
    _loadPortletFiles: function _loadPortletFiles(response, loadHTML) {
      var footerCssPaths = response.footerCssPaths || [];
      var headerCssPaths = response.headerCssPaths || [];
      var javascriptPaths = response.headerJavaScriptPaths || [];
      javascriptPaths = javascriptPaths.concat(response.footerJavaScriptPaths || []);
      var body = A.getBody();
      var head = A.one(STR_HEAD);

      if (headerCssPaths.length) {
        A.Get.css(headerCssPaths, {
          insertBefore: head.get('firstChild').getDOM()
        });
      }

      var lastChild = body.get('lastChild').getDOM();

      if (footerCssPaths.length) {
        A.Get.css(footerCssPaths, {
          insertBefore: lastChild
        });
      }

      var responseHTML = response.portletHTML;

      if (javascriptPaths.length) {
        A.Get.script(javascriptPaths, {
          onEnd: function onEnd(obj) {
            loadHTML(responseHTML);
          }
        });
      } else {
        loadHTML(responseHTML);
      }
    },
    _mergeOptions: function _mergeOptions(portlet, options) {
      options = options || {};
      options.doAsUserId = options.doAsUserId || themeDisplay.getDoAsUserIdEncoded();
      options.plid = options.plid || themeDisplay.getPlid();
      options.portlet = portlet;
      options.portletId = portlet.portletId;
      return options;
    },
    _staticPortlets: {}
  };
  Liferay.provide(Portlet, 'add', function (options) {
    var instance = this;
    Liferay.fire('initLayout');
    var doAsUserId = options.doAsUserId || themeDisplay.getDoAsUserIdEncoded();
    var plid = options.plid || themeDisplay.getPlid();
    var portletData = options.portletData;
    var portletId = options.portletId;
    var portletItemId = options.portletItemId;
    var placeHolder = options.placeHolder;

    if (!placeHolder) {
      placeHolder = A.Node.create('<div class="loading-animation" />');
    } else {
      placeHolder = A.one(placeHolder);
    }

    var beforePortletLoaded = options.beforePortletLoaded;
    var onCompleteFn = options.onComplete;

    var onComplete = function onComplete(portlet, portletId) {
      if (onCompleteFn) {
        onCompleteFn(portlet, portletId);
      }

      instance.list.push(portlet.portletId);

      if (portlet) {
        portlet.attr('data-qa-id', 'app-loaded');
      }

      Liferay.fire('addPortlet', {
        portlet: portlet
      });
    };

    var container = null;

    if (Liferay.Layout && Liferay.Layout.INITIALIZED) {
      container = Liferay.Layout.getActiveDropContainer();
    }

    if (!container) {
      return;
    }

    var currentColumnId = Util.getColumnId(container.attr('id'));
    var portletPosition = 0;

    if (options.placeHolder) {
      var column = placeHolder.get('parentNode');

      if (!column) {
        return;
      }

      placeHolder.addClass('portlet-boundary');
      var columnPortlets = column.all('.portlet-boundary');
      var nestedPortlets = column.all('.portlet-nested-portlets');
      portletPosition = columnPortlets.indexOf(placeHolder);
      var nestedPortletOffset = 0;
      nestedPortlets.some(function (nestedPortlet) {
        var nestedPortletIndex = columnPortlets.indexOf(nestedPortlet);

        if (nestedPortletIndex !== -1 && nestedPortletIndex < portletPosition) {
          nestedPortletOffset += nestedPortlet.all('.portlet-boundary').size();
        } else if (nestedPortletIndex >= portletPosition) {
          return true;
        }
      });
      portletPosition -= nestedPortletOffset;
      currentColumnId = Util.getColumnId(column.attr('id'));
    }

    var url = themeDisplay.getPathMain() + '/portal/update_layout';
    var data = {
      cmd: 'add',
      dataType: 'JSON',
      doAsUserId: doAsUserId,
      p_auth: Liferay.authToken,
      p_l_id: plid,
      p_p_col_id: currentColumnId,
      p_p_col_pos: portletPosition,
      p_p_i_id: portletItemId,
      p_p_id: portletId,
      p_p_isolated: true,
      p_v_l_s_g_id: themeDisplay.getSiteGroupId(),
      portletData: portletData
    };
    var firstPortlet = container.one('.portlet-boundary');
    var hasStaticPortlet = firstPortlet && firstPortlet.isStatic;

    if (!options.placeHolder && !options.plid) {
      if (!hasStaticPortlet) {
        container.prepend(placeHolder);
      } else {
        firstPortlet.placeAfter(placeHolder);
      }
    }

    if (themeDisplay.isFreeformLayout()) {
      container.prepend(placeHolder);
    }

    data.currentURL = Liferay.currentURL;
    instance.addHTML({
      beforePortletLoaded: beforePortletLoaded,
      data: data,
      onComplete: onComplete,
      placeHolder: placeHolder,
      url: url
    });
  }, ['aui-base']);
  Liferay.provide(Portlet, 'addHTML', function (options) {
    var instance = this;
    var portletBoundary = null;
    var beforePortletLoaded = options.beforePortletLoaded;
    var data = options.data;
    var dataType = 'HTML';
    var onComplete = options.onComplete;
    var placeHolder = options.placeHolder;
    var url = options.url;

    if (data && Lang.isString(data.dataType)) {
      dataType = data.dataType;
    }

    dataType = dataType.toUpperCase();

    var addPortletReturn = function addPortletReturn(html) {
      var container = placeHolder.get('parentNode');
      var portletBound = A.Node.create('<div></div>');
      portletBound.plug(A.Plugin.ParseContent);
      portletBound.setContent(html);
      portletBound = portletBound.one('> *');
      var portletId;

      if (portletBound) {
        var id = portletBound.attr('id');
        portletId = Util.getPortletId(id);
        portletBound.portletId = portletId;
        placeHolder.hide();
        placeHolder.placeAfter(portletBound);
        placeHolder.remove();
        instance.refreshLayout(portletBound);

        if (window.location.hash) {
          window.location.href = encodeURI(window.location.hash);
        }

        portletBoundary = portletBound;
        var Layout = Liferay.Layout;

        if (Layout && Layout.INITIALIZED) {
          Layout.updateCurrentPortletInfo(portletBoundary);

          if (container) {
            Layout.syncEmptyColumnClassUI(container);
          }

          Layout.syncDraggableClassUI();
          Layout.updatePortletDropZones(portletBoundary);
        }

        if (onComplete) {
          onComplete(portletBoundary, portletId);
        }
      } else {
        placeHolder.remove();
      }

      return portletId;
    };

    if (beforePortletLoaded) {
      beforePortletLoaded(placeHolder);
    }

    A.io.request(url, {
      after: {
        success: function success() {
          if (!data || !data.preventNotification) {
            Liferay.fire('updatedLayout');
          }
        }
      },
      data: data,
      dataType: dataType,
      on: {
        failure: function failure(event, id, obj) {
          var statusText = obj.statusText;

          if (statusText) {
            var status = 'There\x20was\x20an\x20unexpected\x20error\x2e\x20Please\x20refresh\x20the\x20current\x20page\x2e';

            if (statusText == 'timeout') {
              status = 'Request\x20Timeout';
            }

            placeHolder.hide();
            placeHolder.placeAfter('<div class="alert alert-danger">' + status + '</div>');
          }
        },
        success: function success(event, id, obj) {
          var instance = this;
          var response = instance.get('responseData');

          if (dataType == 'HTML') {
            addPortletReturn(response);
          } else if (response.refresh) {
            addPortletReturn(response.portletHTML);
          } else {
            Portlet._loadMarkupHeadElements(response);

            Portlet._loadPortletFiles(response, addPortletReturn);
          }
        }
      }
    });
  }, ['aui-io-request', 'aui-parse-content']);
  Liferay.provide(Portlet, 'close', function (portlet, skipConfirm, options) {
    var instance = this;
    portlet = A.one(portlet);

    if (portlet && (skipConfirm || confirm('Are\x20you\x20sure\x20you\x20want\x20to\x20remove\x20this\x20component\x3f'))) {
      var portletId = portlet.portletId;
      var portletIndex = instance.list.indexOf(portletId);

      if (portletIndex >= 0) {
        instance.list.splice(portletIndex, 1);
      }

      options = Portlet._mergeOptions(portlet, options);
      Portlet.destroyComponents(portletId);
      Liferay.fire('destroyPortlet', options);
      Liferay.fire('closePortlet', options);
    } else {
      A.config.win.focus();
    }
  }, ['aui-io-request']);
  Liferay.provide(Portlet, 'destroy', function (portlet, options) {
    portlet = A.one(portlet);

    if (portlet) {
      var portletId = portlet.portletId || Util.getPortletId(portlet.attr('id'));
      Portlet.destroyComponents(portletId);
      Liferay.fire('destroyPortlet', Portlet._mergeOptions(portlet, options));
    }
  }, ['aui-node-base']);
  Liferay.provide(Portlet, 'minimize', function (portlet, el, options) {
    var instance = this;
    options = options || {};
    var doAsUserId = options.doAsUserId || themeDisplay.getDoAsUserIdEncoded();
    var plid = options.plid || themeDisplay.getPlid();
    portlet = A.one(portlet);

    if (portlet) {
      var content = portlet.one('.portlet-content-container');

      if (content) {
        var restore = content.hasClass('hide');
        content.toggle();
        portlet.toggleClass('portlet-minimized');
        var link = A.one(el);

        if (link) {
          var title = restore ? 'Minimize' : 'Restore';
          link.attr('alt', title);
          link.attr('title', title);
          var linkText = link.one('.taglib-text-icon');

          if (linkText) {
            linkText.html(title);
          }

          var icon = link.one('i');

          if (icon) {
            icon.removeClass('icon-minus icon-resize-vertical');

            if (restore) {
              icon.addClass('icon-minus');
            } else {
              icon.addClass('icon-resize-vertical');
            }
          }
        }

        A.io.request(themeDisplay.getPathMain() + '/portal/update_layout', {
          after: {
            success: function success() {
              if (restore) {
                var data = {
                  doAsUserId: doAsUserId,
                  p_l_id: plid,
                  p_p_boundary: false,
                  p_p_id: portlet.portletId,
                  p_p_isolated: true
                };
                portlet.plug(A.Plugin.ParseContent);
                portlet.load(themeDisplay.getPathMain() + '/portal/render_portlet?' + A.QueryString.stringify(data));
              }
            }
          },
          data: {
            cmd: 'minimize',
            doAsUserId: doAsUserId,
            p_auth: Liferay.authToken,
            p_l_id: plid,
            p_p_id: portlet.portletId,
            p_p_restore: restore,
            p_v_l_s_g_id: themeDisplay.getSiteGroupId()
          }
        });
      }
    }
  }, ['aui-io', 'aui-parse-content', 'node-load', 'querystring-stringify']);
  Liferay.provide(Portlet, 'onLoad', function (options) {
    var instance = this;
    var canEditTitle = options.canEditTitle;
    var columnPos = options.columnPos;
    var isStatic = options.isStatic == 'no' ? null : options.isStatic;
    var namespacedId = options.namespacedId;
    var portletId = options.portletId;
    var refreshURL = options.refreshURL;
    var refreshURLData = options.refreshURLData;

    if (isStatic) {
      instance.registerStatic(portletId);
    }

    var portlet = A.one('#' + namespacedId);

    if (portlet && !portlet.portletProcessed) {
      portlet.portletProcessed = true;
      portlet.portletId = portletId;
      portlet.columnPos = columnPos;
      portlet.isStatic = isStatic;
      portlet.refreshURL = refreshURL;
      portlet.refreshURLData = refreshURLData; // Functions to run on portlet load

      if (canEditTitle) {
        // https://github.com/yui/yui3/issues/1808
        var events = 'focus';

        if (!A.UA.touch) {
          events = ['focus', 'mousemove'];
        }

        var handle = portlet.on(events, function (event) {
          Util.portletTitleEdit({
            doAsUserId: themeDisplay.getDoAsUserIdEncoded(),
            obj: portlet,
            plid: themeDisplay.getPlid(),
            portletId: portletId
          });
          handle.detach();
        });
      }
    }

    Liferay.fire('portletReady', {
      portlet: portlet,
      portletId: portletId
    });
    instance.readyCounter++;

    if (instance.readyCounter === instance.list.length) {
      Liferay.fire('allPortletsReady', {
        portletId: portletId
      });
    }
  }, ['aui-base', 'aui-timer', 'event-move']);
  Liferay.provide(Portlet, 'refresh', function (portlet, data) {
    var instance = this;
    portlet = A.one(portlet);

    if (portlet) {
      data = data || portlet.refreshURLData || {};

      if (!data.hasOwnProperty('portletAjaxable')) {
        data.portletAjaxable = true;
      }

      var id = portlet.attr('portlet');
      var url = portlet.refreshURL;
      var placeHolder = A.Node.create('<div class="loading-animation" id="p_p_id' + id + '" />');

      if (data.portletAjaxable && url) {
        portlet.placeBefore(placeHolder);
        portlet.remove(true);
        Portlet.destroyComponents(portlet.portletId);
        var params = {};
        var urlPieces = url.split('?');

        if (urlPieces.length > 1) {
          params = A.QueryString.parse(urlPieces[1]);
          delete params.dataType;
          url = urlPieces[0];
        }

        instance.addHTML({
          data: A.mix(params, data, true),
          onComplete: function onComplete(portlet, portletId) {
            portlet.refreshURL = url;

            if (portlet) {
              portlet.attr('data-qa-id', 'app-refreshed');
            }

            Liferay.fire(portlet.portletId + ':portletRefreshed', {
              portlet: portlet,
              portletId: portletId
            });
          },
          placeHolder: placeHolder,
          url: url
        });
      } else if (!portlet.getData('pendingRefresh')) {
        portlet.setData('pendingRefresh', true);
        var nonAjaxableContentMessage = Lang.sub(TPL_NOT_AJAXABLE, ['This\x20change\x20will\x20only\x20be\x20shown\x20after\x20you\x20refresh\x20the\x20current\x20page\x2e']);
        var portletBody = portlet.one('.portlet-body');
        portletBody.placeBefore(nonAjaxableContentMessage);
        portletBody.hide();
      }
    }
  }, ['aui-base', 'querystring-parse']);
  Liferay.provide(Portlet, 'registerStatic', function (portletId) {
    var instance = this;
    var Node = A.Node;

    if (Node && portletId instanceof Node) {
      portletId = portletId.attr('id');
    } else if (portletId.id) {
      portletId = portletId.id;
    }

    var id = Util.getPortletId(portletId);
    instance._staticPortlets[id] = true;
  }, ['aui-base']);
  Liferay.provide(Portlet, 'openWindow', function (options) {
    var instance = this;
    var bodyCssClass = options.bodyCssClass;
    var destroyOnHide = options.destroyOnHide;
    var namespace = options.namespace;
    var portlet = options.portlet;
    var subTitle = options.subTitle;
    var title = options.title;
    var uri = options.uri;
    portlet = A.one(portlet);

    if (portlet && uri) {
      var portletTitle = portlet.one('.portlet-title') || portlet.one('.portlet-title-default');
      var titleHtml = title;

      if (portletTitle) {
        if (portlet.one('#cpPortletTitle')) {
          titleHtml = portletTitle.one('.portlet-title-text').outerHTML() + ' - ' + titleHtml;
        } else {
          titleHtml = portletTitle.text() + ' - ' + titleHtml;
        }
      }

      if (subTitle) {
        titleHtml += '<div class="portlet-configuration-subtitle small"><span class="portlet-configuration-subtitle-text">' + subTitle + '</span></div>';
      }

      Liferay.Util.openWindow({
        cache: false,
        dialog: {
          destroyOnHide: destroyOnHide
        },
        dialogIframe: {
          bodyCssClass: bodyCssClass,
          id: namespace + 'configurationIframe',
          uri: uri
        },
        id: namespace + 'configurationIframeDialog',
        title: titleHtml,
        uri: uri
      }, function (dialog) {
        dialog.once('drag:init', function () {
          dialog.dd.addInvalid('.portlet-configuration-subtitle-text');
        });
      });
    }
  }, ['liferay-util-window']);
  Liferay.publish('closePortlet', {
    defaultFn: Portlet._defCloseFn
  });
  Liferay.publish('allPortletsReady', {
    fireOnce: true
  }); // Backwards compatability

  Portlet.ready = function (fn) {
    Liferay.on('portletReady', function (event) {
      fn(event.portletId, event.portlet);
    });
  };

  Liferay.Portlet = Portlet;
})(AUI(), Liferay);
//# sourceMappingURL=portlet.js.map
Liferay.Workflow = {
  ACTION_PUBLISH: 1,
  ACTION_SAVE_DRAFT: 2,
  STATUS_ANY: -1,
  STATUS_APPROVED: 0,
  STATUS_DENIED: 4,
  STATUS_DRAFT: 2,
  STATUS_EXPIRED: 3,
  STATUS_PENDING: 1
};
//# sourceMappingURL=workflow.js.map
AUI.add(
	'liferay-address',
	function(A) {
		Liferay.Address = {
			getCountries: function(callback) {
				Liferay.Service(
					'/country/get-countries',
					{
						active: true
					},
					callback
				);
			},

			getRegions: function(callback, selectKey) {
				Liferay.Service(
					'/region/get-regions',
					{
						active: true,
						countryId: Number(selectKey)
					},
					callback
				);
			}
		};
	},
	'',
	{
		requires: []
	}
);
AUI.add(
	'liferay-form',
	function(A) {
		var AArray = A.Array;

		var Lang = A.Lang;

		var formConfig;

		var DEFAULTS_FORM_VALIDATOR = A.config.FormValidator;

		var defaultAcceptFiles = DEFAULTS_FORM_VALIDATOR.RULES.acceptFiles;

		var TABS_SECTION_STR = 'TabsSection';

		var REGEX_EMAIL = /^[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:\w(?:[\w-]*\w)?\.)+(\w(?:[\w-]*\w))$/;

		var REGEX_NUMBER = /^[+\-]?(\d+)([.|,]\d+)*([eE][+-]?\d+)?$/;

		var REGEX_URL = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(https?\:\/\/|www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))((.*):(\d*)\/?(.*))?)/;

		var acceptFiles = function(val, node, ruleValue) {
			if (ruleValue == '*') {
				return true;
			}

			return defaultAcceptFiles(val, node, ruleValue);
		};

		var email = function (val) {
			return REGEX_EMAIL.test(val);
		};

		var maxFileSize = function(val, node, ruleValue) {
			var nodeType = node.get('type').toLowerCase();

			if (nodeType === 'file') {
				return (ruleValue === 0 || node._node.files[0].size <= ruleValue);
			}

			return true;
		};

		var number = function(val, node, ruleValue) {
			return REGEX_NUMBER && REGEX_NUMBER.test(val);
		};

		var url = function(val, node, ruleValue) {
			return REGEX_URL && REGEX_URL.test(val);
		};

		A.mix(
			DEFAULTS_FORM_VALIDATOR.RULES,
			{
				acceptFiles: acceptFiles,
				email: email,
				maxFileSize: maxFileSize,
				number: number,
				url: url
			},
			true
		);

		A.mix(
			DEFAULTS_FORM_VALIDATOR.STRINGS,
			{
				DEFAULT: 'Please\x20fix\x20this\x20field\x2e',
				acceptFiles: 'Please\x20enter\x20a\x20file\x20with\x20a\x20valid\x20extension\x20\x28\x7b0\x7d\x29\x2e',
				alpha: 'Please\x20enter\x20only\x20alpha\x20characters\x2e',
				alphanum: 'Please\x20enter\x20only\x20alphanumeric\x20characters\x2e',
				date: 'Please\x20enter\x20a\x20valid\x20date\x2e',
				digits: 'Please\x20enter\x20only\x20digits\x2e',
				email: 'Please\x20enter\x20a\x20valid\x20email\x20address\x2e',
				equalTo: 'Please\x20enter\x20the\x20same\x20value\x20again\x2e',
				max: 'Please\x20enter\x20a\x20value\x20less\x20than\x20or\x20equal\x20to\x20\x7b0\x7d\x2e',
				maxFileSize: 'Please\x20enter\x20a\x20file\x20with\x20a\x20valid\x20file\x20size\x20no\x20larger\x20than\x20\x7b0\x7d\x2e',
				maxLength: 'Please\x20enter\x20no\x20more\x20than\x20\x7b0\x7d\x20characters\x2e',
				min: 'Please\x20enter\x20a\x20value\x20greater\x20than\x20or\x20equal\x20to\x20\x7b0\x7d\x2e',
				minLength: 'Please\x20enter\x20at\x20least\x20\x7b0\x7d\x20characters\x2e',
				number: 'Please\x20enter\x20a\x20valid\x20number\x2e',
				range: 'Please\x20enter\x20a\x20value\x20between\x20\x7b0\x7d\x20and\x20\x7b1\x7d\x2e',
				rangeLength: 'Please\x20enter\x20a\x20value\x20between\x20\x7b0\x7d\x20and\x20\x7b1\x7d\x20characters\x20long\x2e',
				required: 'This\x20field\x20is\x20required\x2e',
				url: 'Please\x20enter\x20a\x20valid\x20URL\x2e'
			},
			true
		);

		var Form = A.Component.create(
			{
				ATTRS: {
					fieldRules: {
						setter: function(val) {
							var instance = this;

							instance._processFieldRules(val);

							return val;
						}
					},
					id: {},
					namespace: {},
					onSubmit: {
						valueFn: function() {
							var instance = this;

							return instance._onSubmit;
						}
					},
					validateOnBlur: {
						validator: Lang.isBoolean,
						value: true
					}
				},

				EXTENDS: A.Base,

				prototype: {
					initializer: function() {
						var instance = this;

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

						var form = document[id];
						var formNode = A.one(form);

						instance.form = form;
						instance.formNode = formNode;

						if (formNode) {
							var formValidator = new A.FormValidator(
								{
									boundingBox: formNode,
									validateOnBlur: instance.get('validateOnBlur')
								}
							);

							A.Do.before('_validatable', formValidator, 'validatable', instance);

							instance.formValidator = formValidator;

							instance._processFieldRules();

							instance._bindForm();
						}
					},

					addRule: function(fieldName, validatorName, errorMessage, body, custom) {
						var instance = this;

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

						var ruleIndex = instance._findRuleIndex(fieldRules, fieldName, validatorName);

						if (ruleIndex == -1) {
							fieldRules.push(
								{
									body: body || '',
									custom: custom || false,
									errorMessage: errorMessage || '',
									fieldName: fieldName,
									validatorName: validatorName
								}
							);

							instance._processFieldRules(fieldRules);
						}
					},

					removeRule: function(fieldName, validatorName) {
						var instance = this;

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

						var ruleIndex = instance._findRuleIndex(fieldRules, fieldName, validatorName);

						if (ruleIndex != -1) {
							var rule = fieldRules[ruleIndex];

							instance.formValidator.resetField(rule.fieldName);

							fieldRules.splice(ruleIndex, 1);

							instance._processFieldRules(fieldRules);
						}
					},

					_afterGetFieldsByName: function(fieldName) {
						var instance = this;

						var editorString = 'Editor';

						if (fieldName.lastIndexOf(editorString) === (fieldName.length - editorString.length)) {
							var formNode = instance.formNode;

							return new A.Do.AlterReturn(
								'Return editor dom element',
								formNode.one('#' + fieldName)
							);
						}
					},

					_bindForm: function() {
						var instance = this;

						var formNode = instance.formNode;
						var formValidator = instance.formValidator;

						formValidator.on('submit', A.bind('_onValidatorSubmit', instance));
						formValidator.on('submitError', A.bind('_onSubmitError', instance));

						formNode.delegate(['blur', 'focus'], A.bind('_onFieldFocusChange', instance), 'button,input,select,textarea');
						formNode.delegate(['blur', 'input'], A.bind('_onEditorBlur', instance), 'div[contenteditable="true"]');

						A.Do.after('_afterGetFieldsByName', formValidator, 'getFieldsByName', instance);
					},

					_defaultSubmitFn: function(event) {
						var instance = this;

						if (!event.stopped) {
							submitForm(instance.form);
						}
					},

					_findRuleIndex: function(fieldRules, fieldName, validatorName) {
						var ruleIndex = -1;

						AArray.some(
							fieldRules,
							function(element, index) {
								if (element.fieldName === fieldName &&
									element.validatorName === validatorName) {
									ruleIndex = index;

									return true;
								}
							}
						);

						return ruleIndex;
					},

					_focusInvalidFieldTab: function() {
						var instance = this;

						var formNode = instance.formNode;

						var field = formNode.one('.' + instance.formValidator.get('errorClass'));

						if (field) {
							var fieldWrapper = field.ancestor('form > div');

							var formTabs = formNode.one('.lfr-nav');

							if (fieldWrapper && formTabs) {
								var tabs = formTabs.all('.tab');
								var tabsNamespace = formTabs.getAttribute('data-tabs-namespace');

								var tabNames = AArray.map(
									tabs._nodes,
									function(tab) {
										return tab.getAttribute('data-tab-name');
									}
								)

								var fieldWrapperId = fieldWrapper.getAttribute('id').slice(0, -TABS_SECTION_STR.length);

								var fieldTabId = AArray.find(
									tabs._nodes,
									function(tab) {
										return tab.getAttribute('id').indexOf(fieldWrapperId) !== -1;
									}
								)

								Liferay.Portal.Tabs.show(tabsNamespace, tabNames, fieldTabId.getAttribute('data-tab-name'));
							}
						}
					},

					_onEditorBlur: function(event) {
						var instance = this;

						var formValidator = instance.formValidator;

						formValidator.validateField(event.target);
					},

					_onFieldFocusChange: function(event) {
						var instance = this;

						var row = event.currentTarget.ancestor('.field');

						if (row) {
							row.toggleClass('field-focused', event.type === 'focus');
						}
					},

					_onSubmit: function(event) {
						var instance = this;

						event.preventDefault();

						setTimeout(
							function() {
								instance._defaultSubmitFn(event);
							},
							0
						);
					},

					_onSubmitError: function(event) {
						var instance = this;

						var collapsiblePanels = instance.formNode.all('.panel-collapse');

						collapsiblePanels.each(
							function(panel) {
								var errorFields = panel.get('children').all('.has-error');

								if (errorFields.size() > 0 && !panel.hasClass('in')) {
									var panelNode = panel.getDOM();

									AUI.$(panelNode).collapse('show');
								}
							}
						);
					},

					_onValidatorSubmit: function(event) {
						var instance = this;

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

						onSubmit.call(instance, event.validator.formEvent);
					},

					_processFieldRule: function(rules, strings, rule) {
						var instance = this;

						var value = true;

						var fieldName = rule.fieldName;
						var validatorName = rule.validatorName;

						var field = this.formValidator.getField(fieldName);

						if (field) {
							var fieldNode = field.getDOMNode();

							A.Do.after('_setFieldAttribute', fieldNode, 'setAttribute', instance, fieldName);
						
							A.Do.after('_removeFieldAttribute', fieldNode, 'removeAttribute', instance, fieldName);
						}

						if ((rule.body || rule.body === 0) && !rule.custom) {
							value = rule.body;
						}

						var fieldRules = rules[fieldName];

						if (!fieldRules) {
							fieldRules = {};

							rules[fieldName] = fieldRules;
						}

						fieldRules[validatorName] = value;

						if (rule.custom) {
							DEFAULTS_FORM_VALIDATOR.RULES[validatorName] = rule.body;
						}

						var errorMessage = rule.errorMessage;

						if (errorMessage) {
							var fieldStrings = strings[fieldName];

							if (!fieldStrings) {
								fieldStrings = {};

								strings[fieldName] = fieldStrings;
							}

							fieldStrings[validatorName] = errorMessage;
						}
					},

					_processFieldRules: function(fieldRules) {
						var instance = this;

						if (!fieldRules) {
							fieldRules = instance.get('fieldRules');
						}

						var fieldStrings = {};
						var rules = {};

						for (var rule in fieldRules) {
							instance._processFieldRule(rules, fieldStrings, fieldRules[rule]);
						}

						var formValidator = instance.formValidator;

						if (formValidator) {
							formValidator.set('fieldStrings', fieldStrings);
							formValidator.set('rules', rules);
						}
					},

					_removeFieldAttribute: function(name, fieldName) {
						var instance = this;

						if (name === 'disabled') {
							this.formValidator.validateField(fieldName);
						}
					},

					_setFieldAttribute: function(name, value, fieldName) {
						var instance = this;

						if (name === 'disabled') {
							this.formValidator.resetField(fieldName);
						}
					},

					_validatable: function(field) {
						var result;

						if (field.test(':disabled')) {
							result = new A.Do.Halt();
						}

						return result;
					}
				},

				get: function(id) {
					var instance = this;

					return instance._INSTANCES[id];
				},

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

					formConfig = config;

					var form = new Liferay.Form(config);

					var formName = config.id || config.namespace;

					instance._INSTANCES[formName] = form;

					Liferay.fire(
						'form:registered',
						{
							form: form,
							formName: formName
						}
					);

					return form;
				},

				_INSTANCES: {}
			}
		);

		Liferay.Form = Form;
	},
	'',
	{
		requires: ['aui-base', 'aui-form-validator']
	}
);
AUI.add(
	'liferay-form-placeholders',
	function(A) {
		var ANode = A.Node;

		var CSS_PLACEHOLDER = 'text-placeholder';

		var MAP_IGNORE_ATTRS = {
			id: 1,
			name: 1,
			type: 1
		};

		var SELECTOR_PLACEHOLDER_INPUTS = 'input[placeholder], textarea[placeholder]';

		var STR_BLANK = '';

		var STR_DATA_TYPE_PASSWORD_PLACEHOLDER = 'data-type-password-placeholder';

		var STR_FOCUS = 'focus';

		var STR_PASSWORD = 'password';

		var STR_PLACEHOLDER = 'placeholder';

		var STR_SPACE = ' ';

		var STR_TYPE = 'type';

		var Placeholders = A.Component.create(
			{
				EXTENDS: A.Plugin.Base,

				NAME: 'placeholders',

				NS: STR_PLACEHOLDER,

				prototype: {
					initializer: function(config) {
						var instance = this;

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

						var formNode = host.formNode;

						if (formNode) {
							var placeholderInputs = formNode.all(SELECTOR_PLACEHOLDER_INPUTS);

							placeholderInputs.each(
								function(item, index) {
									if (!item.val()) {
										if (item.attr(STR_TYPE) === STR_PASSWORD) {
											instance._initializePasswordNode(item);
										}
										else {
											item.addClass(CSS_PLACEHOLDER);

											item.val(item.attr(STR_PLACEHOLDER));
										}
									}
								}
							);

							instance.host = host;

							instance.beforeHostMethod('_onValidatorSubmit', instance._removePlaceholders, instance);
							instance.beforeHostMethod('_onFieldFocusChange', instance._togglePlaceholders, instance);
						}
					},

					_initializePasswordNode: function(field) {
						var placeholder = ANode.create('<input name="' + field.attr('name') + '_pass_placeholder" type="text" />');

						Liferay.Util.getAttributes(
							field,
							function(value, name, attrs) {
								var result = false;

								if (!MAP_IGNORE_ATTRS[name]) {
									if (name === 'class') {
										value += STR_SPACE + CSS_PLACEHOLDER;
									}

									placeholder.setAttribute(name, value);
								}

								return result;
							}
						);

						placeholder.val(field.attr(STR_PLACEHOLDER));

						placeholder.attr(STR_DATA_TYPE_PASSWORD_PLACEHOLDER, true);

						field.placeBefore(placeholder);

						field.hide();
					},

					_removePlaceholders: function() {
						var instance = this;

						var formNode = instance.host.formNode;

						var placeholderInputs = formNode.all(SELECTOR_PLACEHOLDER_INPUTS);

						placeholderInputs.each(
							function(item, index) {
								if (item.val() == item.attr(STR_PLACEHOLDER)) {
									item.val(STR_BLANK);
								}
							}
						);
					},

					_toggleLocalizedPlaceholders: function(event, currentTarget) {
						var placeholder = currentTarget.attr(STR_PLACEHOLDER);

						if (placeholder) {
							var value = currentTarget.val();

							if (event.type === STR_FOCUS) {
								if (value === placeholder) {
									currentTarget.removeClass(CSS_PLACEHOLDER);
								}
							}
							else if (!value) {
								currentTarget.val(placeholder);

								currentTarget.addClass(CSS_PLACEHOLDER);
							}
						}
					},

					_togglePasswordPlaceholders: function(event, currentTarget) {
						var placeholder = currentTarget.attr(STR_PLACEHOLDER);

						if (placeholder) {
							if (event.type === STR_FOCUS) {
								if (currentTarget.hasAttribute(STR_DATA_TYPE_PASSWORD_PLACEHOLDER)) {
									currentTarget.hide();

									var passwordField = currentTarget.next();

									passwordField.show();

									setTimeout(
										function() {
											Liferay.Util.focusFormField(passwordField);
										},
										0
									);
								}
							}
							else if (currentTarget.attr(STR_TYPE) === STR_PASSWORD) {
								var value = currentTarget.val();

								if (!value) {
									currentTarget.hide();

									currentTarget.previous().show();
								}
							}
						}
					},

					_togglePlaceholders: function(event) {
						var instance = this;

						var currentTarget = event.currentTarget;

						if (currentTarget.hasAttribute(STR_DATA_TYPE_PASSWORD_PLACEHOLDER) || currentTarget.attr(STR_TYPE) === STR_PASSWORD) {
							instance._togglePasswordPlaceholders(event, currentTarget);
						}
						else if (currentTarget.hasClass('language-value')) {
							instance._toggleLocalizedPlaceholders(event, currentTarget);
						}
						else {
							var placeholder = currentTarget.attr(STR_PLACEHOLDER);

							if (placeholder) {
								var value = currentTarget.val();

								if (event.type === STR_FOCUS) {
									if (value === placeholder) {
										currentTarget.val(STR_BLANK);

										currentTarget.removeClass(CSS_PLACEHOLDER);
									}
								}
								else if (!value) {
									currentTarget.val(placeholder);

									currentTarget.addClass(CSS_PLACEHOLDER);
								}
							}
						}
					}
				}
			}
		);

		Liferay.Form.Placeholders = Placeholders;

		A.Base.plug(Liferay.Form, Placeholders);
	},
	'',
	{
		requires: ['liferay-form', 'plugin']
	}
);
AUI.add(
	'liferay-icon',
	function(A) {
		var _ICON_REGISTRY = {};

		var Icon = {
			register: function(config) {
				var instance = this;

				var doc = A.one(A.config.doc);

				_ICON_REGISTRY[config.id] = config;

				if (!instance._docClickHandler) {
					instance._docClickHandler = doc.delegate('click', instance._handleDocClick, '.lfr-icon-item', instance);
				}

				if (!instance._docHoverHandler) {
					instance._docHoverHandler = doc.delegate('hover', instance._handleDocMouseOver, instance._handleDocMouseOut, '.lfr-icon-item', instance);
				}

				Liferay.once(
					'screenLoad',
					function() {
						delete _ICON_REGISTRY[config.id];
					}
				);
			},

			_forcePost: function(event) {
				var instance = this;

				if (!Liferay.SPA || !Liferay.SPA.app) {
					Liferay.Util.forcePost(event.currentTarget);

					event.preventDefault();
				}
			},

			_getConfig: function(event) {
				var instance = this;

				return _ICON_REGISTRY[event.currentTarget.attr('id')];
			},

			_handleDocClick: function(event) {
				var instance = this;

				var config = instance._getConfig(event);

				if (config) {
					event.preventDefault();

					if (config.useDialog) {
						instance._useDialog(event);
					}
					else {
						instance._forcePost(event);
					}
				}
			},

			_handleDocMouseOut: function(event) {
				var instance = this;

				var config = instance._getConfig(event);

				if (config && config.srcHover) {
					instance._onMouseHover(event, config.src);
				}
			},

			_handleDocMouseOver: function(event) {
				var instance = this;

				var config = instance._getConfig(event);

				if (config && config.srcHover) {
					instance._onMouseHover(event, config.srcHover);
				}
			},

			_onMouseHover: function(event, src) {
				var instance = this;

				var img = event.currentTarget.one('img');

				if (img) {
					img.attr('src', src);
				}
			},

			_useDialog: function(event) {
				Liferay.Util.openInDialog(
					event,
					{
						dialog: {
							destroyOnHide: true
						},
						dialogIframe: {
							bodyCssClass: 'dialog-with-footer'
						}
					}
				);
			}
		};

		Liferay.Icon = Icon;
	},
	'',
	{
		requires: ['aui-base', 'liferay-util-window']
	}
);
AUI.add(
	'liferay-menu',
	function(A) {
		var Util = Liferay.Util;

		var ARIA_ATTR_ROLE = 'role';

		var ATTR_CLASS_NAME = 'className';

		var AUTO = 'auto';

		var CSS_BTN_PRIMARY = 'btn-primary';

		var CSS_EXTENDED = 'lfr-extended';

		var CSS_OPEN = 'open';

		var CSS_PORTLET = '.portlet';

		var DEFAULT_ALIGN_POINTS = ['tl', 'bl'];

		var EVENT_CLICK = 'click';

		var PARENT_NODE = 'parentNode';

		var STR_BOTTOM = 'b';

		var STR_LEFT = 'l';

		var STR_LTR = 'ltr';

		var STR_RIGHT = 'r';

		var STR_RTL = 'rtl';

		var STR_TOP = 't';

		var MAP_ALIGN_HORIZONTAL_OVERLAY = {
			left: STR_RIGHT,
			right: STR_LEFT
		};

		var MAP_ALIGN_HORIZONTAL_OVERLAY_RTL = {
			left: STR_LEFT,
			right: STR_RIGHT
		};

		var MAP_ALIGN_HORIZONTAL_TRIGGER = {
			left: STR_LEFT,
			right: STR_RIGHT
		};

		var MAP_ALIGN_HORIZONTAL_TRIGGER_RTL = {
			left: STR_RIGHT,
			right: STR_LEFT
		};

		var MAP_ALIGN_VERTICAL_OVERLAY = {
			down: STR_TOP,
			up: STR_BOTTOM
		};

		var MAP_ALIGN_VERTICAL_TRIGGER = {
			down: STR_BOTTOM,
			up: STR_TOP
		};

		var MAP_LIVE_SEARCH = {};

		var REGEX_DIRECTION = /\bdirection-(down|left|right|up)\b/;

		var REGEX_MAX_DISPLAY_ITEMS = /max-display-items-(\d+)/;

		var SELECTOR_ANCHOR = 'a';

		var SELECTOR_LIST_ITEM = 'li';

		var SELECTOR_SEARCH_CONTAINER = '.lfr-menu-list-search-container';

		var TPL_MENU = '<div class="open" />';

		var Menu = function() {
			var instance = this;

			instance._handles = [];

			if (!Menu._INSTANCE) {
				Menu._INSTANCE = instance;
			}
		};

		Menu.prototype = {
			_closeActiveMenu: function() {
				var instance = this;

				var menu = instance._activeMenu;

				if (menu) {
					var handles = instance._handles;

					A.Array.invoke(handles, 'detach');

					handles.length = 0;

					var overlay = instance._overlay;

					if (overlay) {
						overlay.hide();
					}

					var trigger = instance._activeTrigger;

					instance._activeMenu = null;
					instance._activeTrigger = null;

					if (trigger.hasClass(CSS_EXTENDED)) {
						trigger.removeClass(CSS_BTN_PRIMARY);
					}
					else {
						trigger.get(PARENT_NODE).removeClass(CSS_OPEN);

						var portlet = trigger.ancestor(CSS_PORTLET);

						if (portlet) {
							portlet.removeClass(CSS_OPEN);
						}
					}
				}
			},

			_getAlignPoints: A.cached(
				function(cssClass) {
					var instance = this;

					var alignPoints = DEFAULT_ALIGN_POINTS;

					var defaultOverlayHorizontalAlign = STR_RIGHT;

					var defaultTriggerHorizontalAlign = STR_LEFT;

					var mapAlignHorizontalOverlay = MAP_ALIGN_HORIZONTAL_OVERLAY;

					var mapAlignHorizontalTrigger = MAP_ALIGN_HORIZONTAL_TRIGGER;

					var langDir = Liferay.Language.direction[themeDisplay.getLanguageId()] || STR_LTR;

					if (langDir === STR_RTL) {
						defaultOverlayHorizontalAlign = STR_LEFT;
						defaultTriggerHorizontalAlign = STR_RIGHT;

						mapAlignHorizontalOverlay = MAP_ALIGN_HORIZONTAL_OVERLAY_RTL;
						mapAlignHorizontalTrigger = MAP_ALIGN_HORIZONTAL_TRIGGER_RTL;
					}

					if (cssClass.indexOf(AUTO) === -1) {
						var directionMatch = cssClass.match(REGEX_DIRECTION);

						var direction = directionMatch && directionMatch[1] || AUTO;

						if (direction != 'down') {
							var overlayHorizontal = mapAlignHorizontalOverlay[direction] || defaultOverlayHorizontalAlign;
							var overlayVertical = MAP_ALIGN_VERTICAL_OVERLAY[direction] || STR_TOP;

							var triggerHorizontal = mapAlignHorizontalTrigger[direction] || defaultTriggerHorizontalAlign;
							var triggerVertical = MAP_ALIGN_VERTICAL_TRIGGER[direction] || STR_TOP;

							alignPoints = [overlayVertical + overlayHorizontal, triggerVertical + triggerHorizontal];
						}
					}

					return alignPoints;
				}
			),

			_getMenu: function(trigger) {
				var instance = this;

				var overlay = instance._overlay;

				if (!overlay) {
					var MenuOverlay = A.Component.create(
						{
							AUGMENTS: [
								A.WidgetCssClass,
								A.WidgetPosition,
								A.WidgetStdMod,
								A.WidgetModality,
								A.WidgetPositionAlign,
								A.WidgetPositionConstrain,
								A.WidgetStack
							],

							CSS_PREFIX: 'overlay',

							EXTENDS: A.Widget,

							NAME: 'overlay'
						}
					);

					overlay = new MenuOverlay(
						{
							align: {
								node: trigger,
								points: DEFAULT_ALIGN_POINTS
							},
							constrain: true,
							hideClass: false,
							preventOverlap: true,
							zIndex: Liferay.zIndex.MENU
						}
					).render();

					Liferay.once(
						'beforeScreenFlip',
						function() {
							overlay.destroy();

							instance._overlay = null;
						}
					);

					instance._overlay = overlay;
				}
				else {
					overlay.set('align.node', trigger);
				}

				var listContainer = trigger.getData('menuListContainer');
				var menu = trigger.getData('menu');
				var menuHeight = trigger.getData('menuHeight');

				var liveSearch = menu && MAP_LIVE_SEARCH[menu.guid()];

				if (liveSearch) {
					liveSearch.reset();
				}

				var listItems;

				if (!menu || !listContainer) {
					listContainer = trigger.next('ul');

					listItems = listContainer.all(SELECTOR_LIST_ITEM);

					menu = A.Node.create(TPL_MENU);

					listContainer.placeBefore(menu);

					listItems.last().addClass('last');

					menu.append(listContainer);

					trigger.setData('menuListContainer', listContainer);
					trigger.setData('menu', menu);

					instance._setARIARoles(trigger, menu, listContainer);

					if (trigger.hasClass('select')) {
						listContainer.delegate(
							'click',
							function(event) {
								var selectedListItem = event.currentTarget;

								var selectedListItemIcon = selectedListItem.one('i');

								var triggerIcon = trigger.one('i');

								if (selectedListItemIcon && triggerIcon) {
									var selectedListItemIconClass = selectedListItemIcon.attr('class');

									triggerIcon.attr('class', selectedListItemIconClass);
								}

								var selectedListItemMessage = selectedListItem.one('.lfr-icon-menu-text');

								var triggerMessage = trigger.one('.lfr-icon-menu-text');

								if (selectedListItemMessage && triggerMessage) {
									triggerMessage.setContent(selectedListItemMessage.text());
								}
							},
							SELECTOR_LIST_ITEM
						);
					}
				}

				overlay.setStdModContent(A.WidgetStdMod.BODY, menu);

				if (!menuHeight) {
					menuHeight = instance._getMenuHeight(trigger, menu, listItems || listContainer.all(SELECTOR_LIST_ITEM));

					trigger.setData('menuHeight', menuHeight);

					if (menuHeight !== AUTO) {
						listContainer.setStyle('maxHeight', menuHeight);
					}
				}

				instance._getFocusManager();

				return menu;
			},

			_getMenuHeight: function(trigger, menu, listItems) {
				var instance = this;

				var cssClass = trigger.attr(ATTR_CLASS_NAME);

				var height = AUTO;

				if (cssClass.indexOf('lfr-menu-expanded') === -1) {
					var params = REGEX_MAX_DISPLAY_ITEMS.exec(cssClass);

					var maxDisplayItems = params && parseInt(params[1], 10);

					if (maxDisplayItems && listItems.size() > maxDisplayItems) {
						instance._getLiveSearch(trigger, trigger.getData('menu'));

						height = 0;

						var heights = listItems.slice(0, maxDisplayItems).get('offsetHeight');

						for (var i = heights.length - 1; i >= 0; i--) {
							height += heights[i];
						}
					}
				}

				return height;
			},

			_positionActiveMenu: function() {
				var instance = this;

				var menu = instance._activeMenu;
				var trigger = instance._activeTrigger;

				if (menu) {
					var cssClass = trigger.attr(ATTR_CLASS_NAME);

					var overlay = instance._overlay;

					var align = overlay.get('align');

					var listNode = menu.one('ul');

					var listNodeHeight = listNode.get('offsetHeight');
					var listNodeWidth = listNode.get('offsetWidth');

					var modalMask = false;

					align.points = instance._getAlignPoints(cssClass);

					menu.addClass('lfr-icon-menu-open');

					if (Util.isPhone() || Util.isTablet()) {
						overlay.hide();

						modalMask = true;
					}

					overlay.setAttrs(
						{
							align: align,
							centered: false,
							height: listNodeHeight,
							modal: modalMask,
							width: listNodeWidth
						}
					);

					if (!Util.isPhone() && !Util.isTablet()) {
						var focusManager = overlay.bodyNode.focusManager;

						if (focusManager) {
							focusManager.focus(0);
						}
					}

					overlay.show();

					if (cssClass.indexOf(CSS_EXTENDED) > -1) {
						trigger.addClass(CSS_BTN_PRIMARY);
					}
					else {
						trigger.get(PARENT_NODE).addClass(CSS_OPEN);

						var portlet = trigger.ancestor(CSS_PORTLET);

						if (portlet) {
							portlet.addClass(CSS_OPEN);
						}
					}
				}
			},

			_setARIARoles: function(trigger, menu, listContainer) {
				var links = menu.all(SELECTOR_ANCHOR);

				var searchContainer = menu.one(SELECTOR_SEARCH_CONTAINER);

				var listNode = menu.one('ul');

				var ariaLinksAttr = 'menuitem';
				var ariaListNodeAttr = 'menu';

				if (searchContainer) {
					ariaListNodeAttr = 'listbox';
					ariaListNodeAttr = 'option';
				}

				listNode.setAttribute(ARIA_ATTR_ROLE, ariaListNodeAttr);
				links.set(ARIA_ATTR_ROLE, ariaLinksAttr);

				trigger.attr(
					{
						'aria-haspopup': true,
						role: 'button'
					}
				);

				listNode.setAttribute('aria-labelledby', trigger.guid());
			}
		};

		Menu.handleFocus = function(id) {
			var node = A.one(id);

			if (node) {
				node.delegate('mouseenter', A.rbind(Menu._targetLink, node, 'focus'), SELECTOR_LIST_ITEM);
				node.delegate('mouseleave', A.rbind(Menu._targetLink, node, 'blur'), SELECTOR_LIST_ITEM);
			}
		};

		var buffer = [];

		Menu.register = function(id) {
			var menuNode = document.getElementById(id);

			if (menuNode) {
				if (!Menu._INSTANCE) {
					new Menu();
				}

				buffer.push(menuNode);

				Menu._registerTask();
			}
		};

		Menu._registerTask = A.debounce(
			function() {
				if (buffer.length) {
					var nodes = A.all(buffer);

					nodes.on(EVENT_CLICK, A.bind('_registerMenu', Menu));

					buffer.length = 0;
				}
			},
			100
		);

		Menu._targetLink = function(event, action) {
			var anchor = event.currentTarget.one(SELECTOR_ANCHOR);

			if (anchor) {
				anchor[action]();
			}
		};

		Liferay.provide(
			Menu,
			'_getFocusManager',
			function() {
				var menuInstance = Menu._INSTANCE;

				var focusManager = menuInstance._focusManager;

				if (!focusManager) {
					var bodyNode = menuInstance._overlay.bodyNode;

					bodyNode.plug(
						A.Plugin.NodeFocusManager,
						{
							circular: true,
							descendants: 'li:not(.hide) a,input',
							focusClass: 'focus',
							keys: {
								next: 'down:40',
								previous: 'down:38'
							}
						}
					);

					bodyNode.on(
						'key',
						function(event) {
							var activeTrigger = menuInstance._activeTrigger;

							if (activeTrigger) {
								menuInstance._closeActiveMenu();

								activeTrigger.focus();
							}
						},
						'down:27,9'
					);

					focusManager = bodyNode.focusManager;

					bodyNode.delegate(
						'mouseenter',
						function(event) {
							if (focusManager.get('focused')) {
								focusManager.focus(event.currentTarget.one(SELECTOR_ANCHOR));
							}
						},
						SELECTOR_LIST_ITEM
					);

					focusManager.after(
						'activeDescendantChange',
						function(event) {
							var descendants = focusManager.get('descendants');

							var selectedItem = descendants.item(event.newVal);

							if (selectedItem) {
								var overlayList = bodyNode.one('ul');

								if (overlayList) {
									overlayList.setAttribute('aria-activedescendant', selectedItem.guid());
								}
							}
						}
					);

					menuInstance._focusManager = focusManager;
				}

				focusManager.refresh();
			},
			['node-focusmanager'],
			true
		);

		Liferay.provide(
			Menu,
			'_getLiveSearch',
			function(trigger, menu) {
				var instance = this;

				var id = menu.guid();

				var liveSearch = MAP_LIVE_SEARCH[id];

				if (!liveSearch) {
					var listNode = menu.one('ul');

					var results = [];

					listNode.all('li').each(
						function(node) {
							results.push(
								{
									name: node.one('.taglib-text-icon').text().trim(),
									node: node
								}
							);
						}
					);

					liveSearch = new Liferay.MenuFilter(
						{
							content: listNode,
							minQueryLength: 0,
							queryDelay: 0,
							resultFilters: 'phraseMatch',
							resultTextLocator: 'name',
							source: results
						}
					);

					liveSearch.get('inputNode').swallowEvent('click');

					MAP_LIVE_SEARCH[id] = liveSearch;
				}
			},
			['liferay-menu-filter'],
			true
		);

		Liferay.provide(
			Menu,
			'_registerMenu',
			function(event) {
				var menuInstance = Menu._INSTANCE;

				var handles = menuInstance._handles;

				var trigger = event.currentTarget;

				var activeTrigger = menuInstance._activeTrigger;

				if (activeTrigger) {
					if (activeTrigger != trigger) {
						activeTrigger.removeClass(CSS_BTN_PRIMARY);

						activeTrigger.get(PARENT_NODE).removeClass(CSS_OPEN);

						var portlet = activeTrigger.ancestor(CSS_PORTLET);

						if (portlet) {
							portlet.removeClass(CSS_OPEN);
						}
					}
					else {
						menuInstance._closeActiveMenu();

						return;
					}
				}

				if (!trigger.hasClass('disabled')) {
					var menu = menuInstance._getMenu(trigger);

					menuInstance._activeMenu = menu;
					menuInstance._activeTrigger = trigger;

					if (!handles.length) {
						var listContainer = trigger.getData('menuListContainer');

						A.Event.defineOutside('touchend');

						handles.push(
							A.getWin().on('resize', A.debounce(menuInstance._positionActiveMenu, 200, menuInstance)),
							A.getDoc().on(EVENT_CLICK, menuInstance._closeActiveMenu, menuInstance),
							listContainer.on(
								'touchendoutside',
								function(event) {
									event.preventDefault();

									menuInstance._closeActiveMenu();
								},
								menuInstance
							),
							Liferay.on(
								'dropdownShow',
								function(event) {
									if (event.src !== 'LiferayMenu') {
										menuInstance._closeActiveMenu();
									}
								}
							)
						);

						var DDM = A.DD && A.DD.DDM;

						if (DDM) {
							handles.push(DDM.on('ddm:start', menuInstance._closeActiveMenu, menuInstance));
						}
					}

					menuInstance._positionActiveMenu();

					Liferay.fire(
						'dropdownShow',
						{
							src: 'LiferayMenu'
						}
					);

					event.halt();
				}
			},
			['aui-widget-cssclass', 'event-outside', 'event-touch', 'widget', 'widget-modality', 'widget-position', 'widget-position-align', 'widget-position-constrain', 'widget-stack', 'widget-stdmod']
		);

		Liferay.Menu = Menu;
	},
	'',
	{
		requires: ['array-invoke', 'aui-debounce', 'aui-node', 'portal-available-languages']
	}
);
AUI.add(
	'liferay-notice',
	function(A) {
		var ADOM = A.DOM;
		var ANode = A.Node;
		var Do = A.Do;
		var Lang = A.Lang;

		var CSS_ALERTS = 'has-alerts';

		var STR_CLICK = 'click';

		var STR_EMPTY = '';

		var STR_HIDE = 'hide';

		var STR_PX = 'px';

		var STR_SHOW = 'show';

		/**
		 * @deprecated
		 *
		 * OPTIONS
		 *
		 * Required
		 * content {string}: The content of the toolbar.
		 *
		 * Optional
		 * animationConfig {Object}: The Transition config, defaults to {easing: 'ease-out', duration: 2, top: '50px'}. If 'left' property is not specified, it will be automatically calculated.
		 * closeText {string}: Use for the "close" button. Set to false to not have a close button. If set to false but in the provided markup (via content property) there is an element with class "close", a click listener on this element will be added. As result, the notice will be closed.
		 * noticeClass {string}: A class to add to the notice toolbar.
		 * timeout {Number}: The timeout in milliseconds, after it the notice will be automatically closed. Set it to -1, or do not add this property to disable this functionality.
		 * toggleText {object}: The text to use for the "hide" and "show" button. Set to false to not have a hide button.
		 * type {String}: One of 'warning' or 'notice'. If not set, default notice type will be 'notice'
		 * useAnimation {boolean}: To animate show/hide of the notice, defaults to true. If useAnimation is set to true, but there is no timeout, 5000 will be used as timeout.
		 *
		 * Callbacks
		 * onClose {function}: Called when the toolbar is closed.
		 */

		var Notice = function(options) {
			var instance = this;

			options = options || {};

			instance._closeText = options.closeText;
			instance._node = options.node;
			instance._noticeType = options.type || 'notice';
			instance._noticeClass = 'alert-notice';
			instance._onClose = options.onClose;
			instance._useCloseButton = true;

			if (options.useAnimation) {
				instance._noticeClass += ' popup-alert-notice';

				if (!Lang.isNumber(options.timeout)) {
					options.timeout = 5000;
				}
			}

			instance._animationConfig = options.animationConfig || {
				duration: 2,
				easing: 'ease-out',
				top: '50px'
			};

			instance._useAnimation = options.useAnimation;

			instance._timeout = options.timeout;

			instance._body = A.getBody();

			instance._useToggleButton = false;
			instance._hideText = STR_EMPTY;
			instance._showText = STR_EMPTY;

			if (options.toggleText !== false) {
				instance.toggleText = A.mix(
					options.toggleText,
					{
						hide: null,
						show: null
					}
				);

				instance._useToggleButton = true;
			}

			if (instance._noticeType == 'warning') {
				instance._noticeClass = 'alert-danger popup-alert-warning';
			}

			if (options.noticeClass) {
				instance._noticeClass += ' ' + options.noticeClass;
			}

			instance._content = options.content || STR_EMPTY;

			instance._createHTML();

			return instance._notice;
		};

		Notice.prototype = {
			close: function() {
				var instance = this;

				var notice = instance._notice;

				notice.hide();

				instance._body.removeClass(CSS_ALERTS);

				if (instance._onClose) {
					instance._onClose();
				}
			},

			setClosing: function() {
				var instance = this;

				var alerts = A.all('.popup-alert-notice, .popup-alert-warning');

				if (alerts.size()) {
					instance._useCloseButton = true;

					if (!instance._body) {
						instance._body = A.getBody();
					}

					instance._body.addClass(CSS_ALERTS);

					alerts.each(instance._addCloseButton, instance);
				}
			},

			_addCloseButton: function(notice) {
				var instance = this;

				var closeButton;

				if (instance._closeText !== false) {
					instance._closeText = instance._closeText || 'Close';
				}
				else {
					instance._useCloseButton = false;
					instance._closeText = STR_EMPTY;
				}

				if (instance._useCloseButton) {
					var html = '<button class="btn btn-default submit popup-alert-close">' +
							instance._closeText +
						'</button>';

					closeButton = notice.append(html);
				}
				else {
					closeButton = notice.one('.close');
				}

				if (closeButton) {
					closeButton.on(STR_CLICK, instance.close, instance);
				}
			},

			_addToggleButton: function(notice) {
				var instance = this;

				if (instance._useToggleButton) {
					instance._hideText = instance._toggleText.hide || 'Hide';
					instance._showText = instance._toggleText.show || 'Show';

					var toggleButton = ANode.create('<a class="toggle-button" href="javascript:;"><span>' + instance._hideText + '</span></a>');
					var toggleSpan = toggleButton.one('span');

					var visible = 0;

					var hideText = instance._hideText;
					var showText = instance._showText;

					toggleButton.on(
						STR_CLICK,
						function(event) {
							var text = showText;

							if (visible === 0) {
								text = hideText;

								visible = 1;
							}
							else {
								visible = 0;
							}

							notice.toggle();
							toggleSpan.text(text);
						}
					);

					notice.append(toggleButton);
				}
			},

			_afterNoticeShow: function(event) {
				var instance = this;

				instance._preventHide();

				var notice = instance._notice;

				if (instance._useAnimation) {
					var animationConfig = instance._animationConfig;

					var left = animationConfig.left;
					var top = animationConfig.top;

					if (!left) {
						var noticeRegion = ADOM.region(ANode.getDOMNode(notice));

						left = (ADOM.winWidth() / 2) - (noticeRegion.width / 2);

						top = -noticeRegion.height;

						animationConfig.left = left + STR_PX;
					}

					notice.setXY([left, top]);

					notice.transition(
						instance._animationConfig,
						function() {
							instance._hideHandle = A.later(instance._timeout, notice, STR_HIDE);
						}
					);
				}
				else if (instance._timeout > -1) {
					instance._hideHandle = A.later(instance._timeout, notice, STR_HIDE);
				}

				Liferay.fire(
					'noticeShow',
					{
						notice: instance,
						useAnimation: instance._useAnimation
					}
				);
			},

			_beforeNoticeHide: function(event) {
				var instance = this;

				var returnVal;

				if (instance._useAnimation) {
					var animationConfig = A.merge(
						instance._animationConfig,
						{
							top: -instance._notice.get('offsetHeight') + STR_PX
						}
					);

					instance._notice.transition(
						animationConfig,
						function() {
							instance._notice.toggle(false);
						}
					);

					returnVal = new Do.Halt(null);
				}

				Liferay.fire(
					'noticeHide',
					{
						notice: instance,
						useAnimation: instance._useAnimation
					}
				);

				return returnVal;
			},

			_beforeNoticeShow: function(event) {
				var instance = this;

				instance._notice.toggle(true);
			},

			_createHTML: function() {
				var instance = this;

				var content = instance._content;
				var node = A.one(instance._node);

				var notice = node || ANode.create('<div class="alert alert-warning" dynamic="true"></div>');

				if (content) {
					notice.html(content);
				}

				instance._noticeClass.split(' ').forEach(
					function(item, index) {
						notice.addClass(item);
					}
				);

				instance._addCloseButton(notice);
				instance._addToggleButton(notice);

				if (!node || (node && !node.inDoc())) {
					instance._body.prepend(notice);
				}

				instance._body.addClass(CSS_ALERTS);

				Do.before(instance._beforeNoticeHide, notice, STR_HIDE, instance);

				Do.before(instance._beforeNoticeShow, notice, STR_SHOW, instance);

				Do.after(instance._afterNoticeShow, notice, STR_SHOW, instance);

				instance._notice = notice;
			},

			_preventHide: function() {
				var instance = this;

				if (instance._hideHandle) {
					instance._hideHandle.cancel();

					instance._hideHandle = null;
				}
			}
		};

		Liferay.Notice = Notice;
	},
	'',
	{
		requires: ['aui-base']
	}
);
AUI.add(
	'liferay-poller',
	function(A) {
		var AObject = A.Object;

		var _browserKey = Liferay.Util.randomInt();
		var _enabled = false;
		var _encryptedUserId = null;
		var _supportsComet = false;

		var _delayAccessCount = 0;
		var _delayIndex = 0;
		var _delays = [1, 2, 3, 4, 5, 7, 10];

		var _getEncryptedUserId = function() {
			return _encryptedUserId;
		};

		var _frozen = false;
		var _locked = false;

		var _maxDelay = _delays.length - 1;

		var _portletIdsMap = {};

		var _metaData = {
			browserKey: _browserKey,
			companyId: themeDisplay.getCompanyId(),
			portletIdsMap: _portletIdsMap,
			startPolling: true
		};

		var _customDelay = null;
		var _portlets = {};
		var _requestDelay = _delays[0];
		var _sendQueue = [];
		var _suspended = false;
		var _timerId = null;

		var _url = themeDisplay.getPathContext() + '/poller';

		var _receiveChannel = _url + '/receive';
		var _sendChannel = _url + '/send';

		var _closeCurlyBrace = '}';
		var _openCurlyBrace = '{';

		var _escapedCloseCurlyBrace = '[$CLOSE_CURLY_BRACE$]';
		var _escapedOpenCurlyBrace = '[$OPEN_CURLY_BRACE$]';

		var _cancelRequestTimer = function() {
			clearTimeout(_timerId);

			_timerId = null;
		};

		var _createRequestTimer = function() {
			_cancelRequestTimer();

			if (_enabled) {
				if (Poller.isSupportsComet()) {
					_receive();
				}
				else {
					_timerId = setTimeout(_receive, Poller.getDelay());
				}
			}
		};

		var _freezeConnection = function() {
			_frozen = true;

			_cancelRequestTimer();
		};

		var _getReceiveUrl = function() {
			return _receiveChannel;
		};

		var _getSendUrl = function() {
			return _sendChannel;
		};

		var _processResponse = function(id, obj) {
			var response = JSON.parse(obj.responseText);
			var send = false;

			if (Array.isArray(response)) {
				var meta = response.shift();

				for (var i = 0; i < response.length; i++) {
					var chunk = response[i].payload;

					var chunkData = chunk.data;

					var portletId = chunk.portletId;

					var portlet = _portlets[portletId];

					if (portlet) {
						var currentPortletId = _portletIdsMap[portletId];

						if (chunkData && currentPortletId) {
							chunkData.initialRequest = portlet.initialRequest;
						}

						portlet.listener.call(portlet.scope || Poller, chunkData, chunk.chunkId);

						if (chunkData && chunkData.pollerHintHighConnectivity) {
							_requestDelay = _delays[0];
							_delayIndex = 0;
						}

						if (portlet.initialRequest && currentPortletId) {
							send = true;

							portlet.initialRequest = false;
						}
					}
				}

				if ('startPolling' in _metaData) {
					delete _metaData.startPolling;
				}

				if (send) {
					_send();
				}

				if (!meta.suspendPolling) {
					_thawConnection();
				}
				else {
					_freezeConnection();
				}
			}
		};

		var _receive = function() {
			if (!_suspended && !_frozen) {
				_metaData.userId = _getEncryptedUserId();
				_metaData.timestamp = (new Date()).getTime();

				AObject.each(_portlets, _updatePortletIdsMap);

				var requestStr = JSON.stringify([_metaData]);

				A.io(
					_getReceiveUrl(),
					{
						data: {
							pollerRequest: requestStr
						},
						method: A.config.io.method,
						on: {
							success: _processResponse
						}
					}
				);
			}
		};

		var _releaseLock = function() {
			_locked = false;
		};

		var _sendComplete = function() {
			_releaseLock();
			_send();
		};

		var _send = function() {
			if (_enabled && !_locked && _sendQueue.length && !_suspended && !_frozen) {
				_locked = true;

				var data = _sendQueue.shift();

				_metaData.userId = _getEncryptedUserId();
				_metaData.timestamp = (new Date()).getTime();

				AObject.each(_portlets, _updatePortletIdsMap);

				var requestStr = JSON.stringify([_metaData].concat(data));

				A.io(
					_getSendUrl(),
					{
						data: {
							pollerRequest: requestStr
						},
						method: A.config.io.method,
						on: {
							complete: _sendComplete
						}
					}
				);
			}
		};

		var _thawConnection = function() {
			_frozen = false;

			_createRequestTimer();
		};

		var _updatePortletIdsMap = function(item, index) {
			_portletIdsMap[index] = item.initialRequest;
		};

		var Poller = {
			init: function(options) {
				var instance = this;

				instance.setEncryptedUserId(options.encryptedUserId);
				instance.setSupportsComet(options.supportsComet);
			},

			addListener: function(key, listener, scope) {
				_portlets[key] = {
					initialRequest: true,
					listener: listener,
					scope: scope
				};

				if (!_enabled) {
					_enabled = true;

					_receive();
				}
			},

			cancelCustomDelay: function() {
				_customDelay = null;
			},

			getDelay: function() {
				if (_customDelay !== null) {
					_requestDelay = _customDelay;
				}
				else if (_delayIndex <= _maxDelay) {
					_requestDelay = _delays[_delayIndex];
					_delayAccessCount++;

					if (_delayAccessCount == 3) {
						_delayIndex++;
						_delayAccessCount = 0;
					}
				}

				return _requestDelay * 1000;
			},

			getReceiveUrl: _getReceiveUrl,
			getSendUrl: _getSendUrl,

			isSupportsComet: function() {
				return _supportsComet;
			},

			processResponse: _processResponse,

			removeListener: function(key) {
				var instance = this;

				if (key in _portlets) {
					delete _portlets[key];
				}

				if (AObject.keys(_portlets).length === 0) {
					_enabled = false;

					_cancelRequestTimer();
				}
			},

			resume: function() {
				_suspended = false;

				_createRequestTimer();
			},

			setCustomDelay: function(delay) {
				if (delay === null) {
					_customDelay = delay;
				}
				else {
					_customDelay = delay / 1000;
				}
			},

			setDelay: function(delay) {
				_requestDelay = delay / 1000;
			},

			setEncryptedUserId: function(encryptedUserId) {
				_encryptedUserId = encryptedUserId;
			},

			setSupportsComet: function(supportsComet) {
				_supportsComet = supportsComet;
			},

			setUrl: function(url) {
				_url = url;
			},

			submitRequest: function(key, data, chunkId) {
				if (!_frozen && key in _portlets) {
					for (var i in data) {
						if (data.hasOwnProperty(i)) {
							var content = data[i];

							if (content.replace) {
								content = content.replace(_openCurlyBrace, _escapedOpenCurlyBrace);
								content = content.replace(_closeCurlyBrace, _escapedCloseCurlyBrace);

								data[i] = content;
							}
						}
					}

					var requestData = {
						data: data,
						portletId: key
					};

					if (chunkId) {
						requestData.chunkId = chunkId;
					}

					_sendQueue.push(requestData);

					_send();
				}
			},

			suspend: function() {
				_cancelRequestTimer();

				_suspended = true;
			},

			url: _url
		};

		A.getWin().on(
			'focus',
			function(event) {
				_metaData.startPolling = true;

				_thawConnection();
			}
		);

		Liferay.Poller = Poller;
	},
	'',
	{
		requires: ['aui-base', 'io', 'json']
	}
);
YUI.add('async-queue', function (Y, NAME) {

/**
 * <p>AsyncQueue allows you create a chain of function callbacks executed
 * via setTimeout (or synchronously) that are guaranteed to run in order.
 * Items in the queue can be promoted or removed.  Start or resume the
 * execution chain with run().  pause() to temporarily delay execution, or
 * stop() to halt and clear the queue.</p>
 *
 * @module async-queue
 */

/**
 * <p>A specialized queue class that supports scheduling callbacks to execute
 * sequentially, iteratively, even asynchronously.</p>
 *
 * <p>Callbacks can be function refs or objects with the following keys.  Only
 * the <code>fn</code> key is required.</p>
 *
 * <ul>
 * <li><code>fn</code> -- The callback function</li>
 * <li><code>context</code> -- The execution context for the callbackFn.</li>
 * <li><code>args</code> -- Arguments to pass to callbackFn.</li>
 * <li><code>timeout</code> -- Millisecond delay before executing callbackFn.
 *                     (Applies to each iterative execution of callback)</li>
 * <li><code>iterations</code> -- Number of times to repeat the callback.
 * <li><code>until</code> -- Repeat the callback until this function returns
 *                         true.  This setting trumps iterations.</li>
 * <li><code>autoContinue</code> -- Set to false to prevent the AsyncQueue from
 *                        executing the next callback in the Queue after
 *                        the callback completes.</li>
 * <li><code>id</code> -- Name that can be used to get, promote, get the
 *                        indexOf, or delete this callback.</li>
 * </ul>
 *
 * @class AsyncQueue
 * @extends EventTarget
 * @constructor
 * @param callback* {Function|Object} 0..n callbacks to seed the queue
 */
Y.AsyncQueue = function() {
    this._init();
    this.add.apply(this, arguments);
};

var Queue   = Y.AsyncQueue,
    EXECUTE = 'execute',
    SHIFT   = 'shift',
    PROMOTE = 'promote',
    REMOVE  = 'remove',

    isObject   = Y.Lang.isObject,
    isFunction = Y.Lang.isFunction;

/**
 * <p>Static default values used to populate callback configuration properties.
 * Preconfigured defaults include:</p>
 *
 * <ul>
 *  <li><code>autoContinue</code>: <code>true</code></li>
 *  <li><code>iterations</code>: 1</li>
 *  <li><code>timeout</code>: 10 (10ms between callbacks)</li>
 *  <li><code>until</code>: (function to run until iterations &lt;= 0)</li>
 * </ul>
 *
 * @property defaults
 * @type {Object}
 * @static
 */
Queue.defaults = Y.mix({
    autoContinue : true,
    iterations   : 1,
    timeout      : 10,
    until        : function () {
        this.iterations |= 0;
        return this.iterations <= 0;
    }
}, Y.config.queueDefaults || {});

Y.extend(Queue, Y.EventTarget, {
    /**
     * Used to indicate the queue is currently executing a callback.
     *
     * @property _running
     * @type {Boolean|Object} true for synchronous callback execution, the
     *                        return handle from Y.later for async callbacks.
     *                        Otherwise false.
     * @protected
     */
    _running : false,

    /**
     * Initializes the AsyncQueue instance properties and events.
     *
     * @method _init
     * @protected
     */
    _init : function () {
        Y.EventTarget.call(this, { prefix: 'queue', emitFacade: true });

        this._q = [];

        /**
         * Callback defaults for this instance.  Static defaults that are not
         * overridden are also included.
         *
         * @property defaults
         * @type {Object}
         */
        this.defaults = {};

        this._initEvents();
    },

    /**
     * Initializes the instance events.
     *
     * @method _initEvents
     * @protected
     */
    _initEvents : function () {
        this.publish({
            'execute' : { defaultFn : this._defExecFn,    emitFacade: true },
            'shift'   : { defaultFn : this._defShiftFn,   emitFacade: true },
            'add'     : { defaultFn : this._defAddFn,     emitFacade: true },
            'promote' : { defaultFn : this._defPromoteFn, emitFacade: true },
            'remove'  : { defaultFn : this._defRemoveFn,  emitFacade: true }
        });
    },

    /**
     * Returns the next callback needing execution.  If a callback is
     * configured to repeat via iterations or until, it will be returned until
     * the completion criteria is met.
     *
     * When the queue is empty, null is returned.
     *
     * @method next
     * @return {Function} the callback to execute
     */
    next : function () {
        var callback;

        while (this._q.length) {
            callback = this._q[0] = this._prepare(this._q[0]);
            if (callback && callback.until()) {
                this.fire(SHIFT, { callback: callback });
                callback = null;
            } else {
                break;
            }
        }

        return callback || null;
    },

    /**
     * Default functionality for the &quot;shift&quot; event.  Shifts the
     * callback stored in the event object's <em>callback</em> property from
     * the queue if it is the first item.
     *
     * @method _defShiftFn
     * @param e {Event} The event object
     * @protected
     */
    _defShiftFn : function (e) {
        if (this.indexOf(e.callback) === 0) {
            this._q.shift();
        }
    },

    /**
     * Creates a wrapper function to execute the callback using the aggregated
     * configuration generated by combining the static AsyncQueue.defaults, the
     * instance defaults, and the specified callback settings.
     *
     * The wrapper function is decorated with the callback configuration as
     * properties for runtime modification.
     *
     * @method _prepare
     * @param callback {Object|Function} the raw callback
     * @return {Function} a decorated function wrapper to execute the callback
     * @protected
     */
    _prepare: function (callback) {
        if (isFunction(callback) && callback._prepared) {
            return callback;
        }

        var config = Y.merge(
            Queue.defaults,
            { context : this, args: [], _prepared: true },
            this.defaults,
            (isFunction(callback) ? { fn: callback } : callback)),

            wrapper = Y.bind(function () {
                if (!wrapper._running) {
                    wrapper.iterations--;
                }
                if (isFunction(wrapper.fn)) {
                    wrapper.fn.apply(wrapper.context || Y,
                                     Y.Array(wrapper.args));
                }
            }, this);

        return Y.mix(wrapper, config);
    },

    /**
     * Sets the queue in motion.  All queued callbacks will be executed in
     * order unless pause() or stop() is called or if one of the callbacks is
     * configured with autoContinue: false.
     *
     * @method run
     * @return {AsyncQueue} the AsyncQueue instance
     * @chainable
     */
    run : function () {
        var callback,
            cont = true;

        if (this._executing) {
            this._running = true;
            return this;
        }

        for (callback = this.next();
            callback && !this.isRunning();
            callback = this.next())
        {
            cont = (callback.timeout < 0) ?
                this._execute(callback) :
                this._schedule(callback);

            // Break to avoid an extra call to next (final-expression of the
            // 'for' loop), because the until function of the next callback
            // in the queue may return a wrong result if it depends on the
            // not-yet-finished work of the previous callback.
            if (!cont) {
                break;
            }
        }

        if (!callback) {
            /**
             * Event fired when there is no remaining callback in the running queue. Also fired after stop().
             * @event complete
             */
            this.fire('complete');
        }

        return this;
    },

    /**
     * Handles the execution of callbacks. Returns a boolean indicating
     * whether it is appropriate to continue running.
     *
     * @method _execute
     * @param callback {Object} the callback object to execute
     * @return {Boolean} whether the run loop should continue
     * @protected
     */
    _execute : function (callback) {

        this._running   = callback._running = true;
        this._executing = callback;

        callback.iterations--;
        this.fire(EXECUTE, { callback: callback });

        var cont = this._running && callback.autoContinue;

        this._running   = callback._running = false;
        this._executing = false;

        return cont;
    },

    /**
     * Schedules the execution of asynchronous callbacks.
     *
     * @method _schedule
     * @param callback {Object} the callback object to execute
     * @return {Boolean} whether the run loop should continue
     * @protected
     */
    _schedule : function (callback) {
        this._running = Y.later(callback.timeout, this, function () {
            if (this._execute(callback)) {
                this.run();
            }
        });

        return false;
    },

    /**
     * Determines if the queue is waiting for a callback to complete execution.
     *
     * @method isRunning
     * @return {Boolean} true if queue is waiting for a
     *                   from any initiated transactions
     */
    isRunning : function () {
        return !!this._running;
    },

    /**
     * Default functionality for the &quot;execute&quot; event.  Executes the
     * callback function
     *
     * @method _defExecFn
     * @param e {Event} the event object
     * @protected
     */
    _defExecFn : function (e) {
        e.callback();
    },

    /**
     * Add any number of callbacks to the end of the queue. Callbacks may be
     * provided as functions or objects.
     *
     * @method add
     * @param callback* {Function|Object} 0..n callbacks
     * @return {AsyncQueue} the AsyncQueue instance
     * @chainable
     */
    add : function () {
        this.fire('add', { callbacks: Y.Array(arguments,0,true) });

        return this;
    },

    /**
     * Default functionality for the &quot;add&quot; event.  Adds the callbacks
     * in the event facade to the queue. Callbacks successfully added to the
     * queue are present in the event's <code>added</code> property in the
     * after phase.
     *
     * @method _defAddFn
     * @param e {Event} the event object
     * @protected
     */
    _defAddFn : function(e) {
        var _q = this._q,
            added = [];

        Y.Array.each(e.callbacks, function (c) {
            if (isObject(c)) {
                _q.push(c);
                added.push(c);
            }
        });

        e.added = added;
    },

    /**
     * Pause the execution of the queue after the execution of the current
     * callback completes.  If called from code outside of a queued callback,
     * clears the timeout for the pending callback. Paused queue can be
     * restarted with q.run()
     *
     * @method pause
     * @return {AsyncQueue} the AsyncQueue instance
     * @chainable
     */
    pause: function () {
        if (this._running && isObject(this._running)) {
            this._running.cancel();
        }

        this._running = false;

        return this;
    },

    /**
     * Stop and clear the queue after the current execution of the
     * current callback completes.
     *
     * @method stop
     * @return {AsyncQueue} the AsyncQueue instance
     * @chainable
     */
    stop : function () {

        this._q = [];

        if (this._running && isObject(this._running)) {
            this._running.cancel();
            this._running = false;
        }
        // otherwise don't systematically set this._running to false, because if
        // stop has been called from inside a queued callback, the _execute method
        // currenty running needs to call run() one more time for the 'complete'
        // event to be fired.

        // if stop is called from outside a callback, we need to explicitely call
        // run() once again to fire the 'complete' event.
        if (!this._executing) {
            this.run();
        }

        return this;
    },

    /**
     * Returns the current index of a callback.  Pass in either the id or
     * callback function from getCallback.
     *
     * @method indexOf
     * @param callback {String|Function} the callback or its specified id
     * @return {Number} index of the callback or -1 if not found
     */
    indexOf : function (callback) {
        var i = 0, len = this._q.length, c;

        for (; i < len; ++i) {
            c = this._q[i];
            if (c === callback || c.id === callback) {
                return i;
            }
        }

        return -1;
    },

    /**
     * Retrieve a callback by its id.  Useful to modify the configuration
     * while the queue is running.
     *
     * @method getCallback
     * @param id {String} the id assigned to the callback
     * @return {Object} the callback object
     */
    getCallback : function (id) {
        var i = this.indexOf(id);

        return (i > -1) ? this._q[i] : null;
    },

    /**
     * Promotes the named callback to the top of the queue. If a callback is
     * currently executing or looping (via until or iterations), the promotion
     * is scheduled to occur after the current callback has completed.
     *
     * @method promote
     * @param callback {String|Object} the callback object or a callback's id
     * @return {AsyncQueue} the AsyncQueue instance
     * @chainable
     */
    promote : function (callback) {
        var payload = { callback : callback },e;

        if (this.isRunning()) {
            e = this.after(SHIFT, function () {
                    this.fire(PROMOTE, payload);
                    e.detach();
                }, this);
        } else {
            this.fire(PROMOTE, payload);
        }

        return this;
    },

    /**
     * <p>Default functionality for the &quot;promote&quot; event.  Promotes the
     * named callback to the head of the queue.</p>
     *
     * <p>The event object will contain a property &quot;callback&quot;, which
     * holds the id of a callback or the callback object itself.</p>
     *
     * @method _defPromoteFn
     * @param e {Event} the custom event
     * @protected
     */
    _defPromoteFn : function (e) {
        var i = this.indexOf(e.callback),
            promoted = (i > -1) ? this._q.splice(i,1)[0] : null;

        e.promoted = promoted;

        if (promoted) {
            this._q.unshift(promoted);
        }
    },

    /**
     * Removes the callback from the queue.  If the queue is active, the
     * removal is scheduled to occur after the current callback has completed.
     *
     * @method remove
     * @param callback {String|Object} the callback object or a callback's id
     * @return {AsyncQueue} the AsyncQueue instance
     * @chainable
     */
    remove : function (callback) {
        var payload = { callback : callback },e;

        // Can't return the removed callback because of the deferral until
        // current callback is complete
        if (this.isRunning()) {
            e = this.after(SHIFT, function () {
                    this.fire(REMOVE, payload);
                    e.detach();
                },this);
        } else {
            this.fire(REMOVE, payload);
        }

        return this;
    },

    /**
     * <p>Default functionality for the &quot;remove&quot; event.  Removes the
     * callback from the queue.</p>
     *
     * <p>The event object will contain a property &quot;callback&quot;, which
     * holds the id of a callback or the callback object itself.</p>
     *
     * @method _defRemoveFn
     * @param e {Event} the custom event
     * @protected
     */
    _defRemoveFn : function (e) {
        var i = this.indexOf(e.callback);

        e.removed = (i > -1) ? this._q.splice(i,1)[0] : null;
    },

    /**
     * Returns the number of callbacks in the queue.
     *
     * @method size
     * @return {Number}
     */
    size : function () {
        // next() flushes callbacks that have met their until() criteria and
        // therefore shouldn't count since they wouldn't execute anyway.
        if (!this.isRunning()) {
            this.next();
        }

        return this._q.length;
    }
});



}, 'patched-v3.18.3', {"requires": ["event-custom"]});

YUI.add('base-build', function (Y, NAME) {

    /**
     * The base-build submodule provides Base.build functionality, which
     * can be used to create custom classes, by aggregating extensions onto
     * a main class.
     *
     * @module base
     * @submodule base-build
     * @for Base
     */
    var BaseCore = Y.BaseCore,
        Base     = Y.Base,
        L        = Y.Lang,

        INITIALIZER = "initializer",
        DESTRUCTOR  = "destructor",
        AGGREGATES  = ["_PLUG", "_UNPLUG"],

        build;

    // Utility function used in `_buildCfg` to aggregate array values into a new
    // array from the sender constructor to the receiver constructor.
    function arrayAggregator(prop, r, s) {
        if (s[prop]) {
            r[prop] = (r[prop] || []).concat(s[prop]);
        }
    }

    // Utility function used in `_buildCfg` to aggregate `_ATTR_CFG` array
    // values from the sender constructor into a new array on receiver's
    // constructor, and clear the cached hash.
    function attrCfgAggregator(prop, r, s) {
        if (s._ATTR_CFG) {
            // Clear cached hash.
            r._ATTR_CFG_HASH = null;

            arrayAggregator.apply(null, arguments);
        }
    }

    // Utility function used in `_buildCfg` to aggregate ATTRS configs from one
    // the sender constructor to the receiver constructor.
    function attrsAggregator(prop, r, s) {
        BaseCore.modifyAttrs(r, s.ATTRS);
    }

    Base._build = function(name, main, extensions, px, sx, cfg) {

        var build = Base._build,

            builtClass = build._ctor(main, cfg),
            buildCfg = build._cfg(main, cfg, extensions),

            _mixCust = build._mixCust,

            dynamic = builtClass._yuibuild.dynamic,

            i, l, extClass, extProto,
            initializer,
            destructor;

        // Augment/Aggregate
        for (i = 0, l = extensions.length; i < l; i++) {
            extClass = extensions[i];

            extProto = extClass.prototype;

            initializer = extProto[INITIALIZER];
            destructor = extProto[DESTRUCTOR];
            delete extProto[INITIALIZER];
            delete extProto[DESTRUCTOR];

            // Prototype, old non-displacing augment
            Y.mix(builtClass, extClass, true, null, 1);

            // Custom Statics
            _mixCust(builtClass, extClass, buildCfg);

            if (initializer) {
                extProto[INITIALIZER] = initializer;
            }

            if (destructor) {
                extProto[DESTRUCTOR] = destructor;
            }

            builtClass._yuibuild.exts.push(extClass);
        }

        if (px) {
            Y.mix(builtClass.prototype, px, true);
        }

        if (sx) {
            Y.mix(builtClass, build._clean(sx, buildCfg), true);
            _mixCust(builtClass, sx, buildCfg);
        }

        builtClass.prototype.hasImpl = build._impl;

        if (dynamic) {
            builtClass.NAME = name;
            builtClass.prototype.constructor = builtClass;

            // Carry along the reference to `modifyAttrs()` from `main`.
            builtClass.modifyAttrs = main.modifyAttrs;
        }

        return builtClass;
    };

    build = Base._build;

    Y.mix(build, {

        _mixCust: function(r, s, cfg) {

            var aggregates,
                custom,
                statics,
                aggr,
                l,
                i;

            if (cfg) {
                aggregates = cfg.aggregates;
                custom = cfg.custom;
                statics = cfg.statics;
            }

            if (statics) {
                Y.mix(r, s, true, statics);
            }

            if (aggregates) {
                for (i = 0, l = aggregates.length; i < l; i++) {
                    aggr = aggregates[i];
                    if (!r.hasOwnProperty(aggr) && s.hasOwnProperty(aggr)) {
                        r[aggr] = L.isArray(s[aggr]) ? [] : {};
                    }
                    Y.aggregate(r, s, true, [aggr]);
                }
            }

            if (custom) {
                for (i in custom) {
                    if (custom.hasOwnProperty(i)) {
                        custom[i](i, r, s);
                    }
                }
            }

        },

        _tmpl: function(main) {

            function BuiltClass() {
                BuiltClass.superclass.constructor.apply(this, arguments);
            }
            Y.extend(BuiltClass, main);

            return BuiltClass;
        },

        _impl : function(extClass) {
            var classes = this._getClasses(), i, l, cls, exts, ll, j;
            for (i = 0, l = classes.length; i < l; i++) {
                cls = classes[i];
                if (cls._yuibuild) {
                    exts = cls._yuibuild.exts;
                    ll = exts.length;

                    for (j = 0; j < ll; j++) {
                        if (exts[j] === extClass) {
                            return true;
                        }
                    }
                }
            }
            return false;
        },

        _ctor : function(main, cfg) {

           var dynamic = (cfg && false === cfg.dynamic) ? false : true,
               builtClass = (dynamic) ? build._tmpl(main) : main,
               buildCfg = builtClass._yuibuild;

            if (!buildCfg) {
                buildCfg = builtClass._yuibuild = {};
            }

            buildCfg.id = buildCfg.id || null;
            buildCfg.exts = buildCfg.exts || [];
            buildCfg.dynamic = dynamic;

            return builtClass;
        },

        _cfg : function(main, cfg, exts) {
            var aggr = [],
                cust = {},
                statics = [],
                buildCfg,
                cfgAggr = (cfg && cfg.aggregates),
                cfgCustBuild = (cfg && cfg.custom),
                cfgStatics = (cfg && cfg.statics),
                c = main,
                i,
                l;

            // Prototype Chain
            while (c && c.prototype) {
                buildCfg = c._buildCfg;
                if (buildCfg) {
                    if (buildCfg.aggregates) {
                        aggr = aggr.concat(buildCfg.aggregates);
                    }
                    if (buildCfg.custom) {
                        Y.mix(cust, buildCfg.custom, true);
                    }
                    if (buildCfg.statics) {
                        statics = statics.concat(buildCfg.statics);
                    }
                }
                c = c.superclass ? c.superclass.constructor : null;
            }

            // Exts
            if (exts) {
                for (i = 0, l = exts.length; i < l; i++) {
                    c = exts[i];
                    buildCfg = c._buildCfg;
                    if (buildCfg) {
                        if (buildCfg.aggregates) {
                            aggr = aggr.concat(buildCfg.aggregates);
                        }
                        if (buildCfg.custom) {
                            Y.mix(cust, buildCfg.custom, true);
                        }
                        if (buildCfg.statics) {
                            statics = statics.concat(buildCfg.statics);
                        }
                    }
                }
            }

            if (cfgAggr) {
                aggr = aggr.concat(cfgAggr);
            }

            if (cfgCustBuild) {
                Y.mix(cust, cfg.cfgBuild, true);
            }

            if (cfgStatics) {
                statics = statics.concat(cfgStatics);
            }

            return {
                aggregates: aggr,
                custom: cust,
                statics: statics
            };
        },

        _clean : function(sx, cfg) {
            var prop, i, l, sxclone = Y.merge(sx),
                aggregates = cfg.aggregates,
                custom = cfg.custom;

            for (prop in custom) {
                if (sxclone.hasOwnProperty(prop)) {
                    delete sxclone[prop];
                }
            }

            for (i = 0, l = aggregates.length; i < l; i++) {
                prop = aggregates[i];
                if (sxclone.hasOwnProperty(prop)) {
                    delete sxclone[prop];
                }
            }

            return sxclone;
        }
    });

    /**
     * <p>
     * Builds a custom constructor function (class) from the
     * main function, and array of extension functions (classes)
     * provided. The NAME field for the constructor function is
     * defined by the first argument passed in.
     * </p>
     * <p>
     * The cfg object supports the following properties
     * </p>
     * <dl>
     *    <dt>dynamic &#60;boolean&#62;</dt>
     *    <dd>
     *    <p>If true (default), a completely new class
     *    is created which extends the main class, and acts as the
     *    host on which the extension classes are augmented.</p>
     *    <p>If false, the extensions classes are augmented directly to
     *    the main class, modifying the main class' prototype.</p>
     *    </dd>
     *    <dt>aggregates &#60;String[]&#62;</dt>
     *    <dd>An array of static property names, which will get aggregated
     *    on to the built class, in addition to the default properties build
     *    will always aggregate as defined by the main class' static _buildCfg
     *    property.
     *    </dd>
     * </dl>
     *
     * @method build
     * @deprecated Use the more convenient Base.create and Base.mix methods instead
     * @static
     * @param {Function} name The name of the new class. Used to define the NAME property for the new class.
     * @param {Function} main The main class on which to base the built class
     * @param {Function[]} extensions The set of extension classes which will be
     * augmented/aggregated to the built class.
     * @param {Object} cfg Optional. Build configuration for the class (see description).
     * @return {Function} A custom class, created from the provided main and extension classes
     */
    Base.build = function(name, main, extensions, cfg) {
        return build(name, main, extensions, null, null, cfg);
    };

    /**
     * Creates a new class (constructor function) which extends the base class passed in as the second argument,
     * and mixes in the array of extensions provided.
     *
     * Prototype properties or methods can be added to the new class, using the px argument (similar to Y.extend).
     *
     * Static properties or methods can be added to the new class, using the sx argument (similar to Y.extend).
     *
     * **NOTE FOR COMPONENT DEVELOPERS**: Both the `base` class, and `extensions` can define static a `_buildCfg`
     * property, which acts as class creation meta-data, and drives how special static properties from the base
     * class, or extensions should be copied, aggregated or (custom) mixed into the newly created class.
     *
     * The `_buildCfg` property is a hash with 3 supported properties: `statics`, `aggregates` and `custom`, e.g:
     *
     *     // If the Base/Main class is the thing introducing the property:
     *
     *     MyBaseClass._buildCfg = {
     *
     *        // Static properties/methods to copy (Alias) to the built class.
     *        statics: ["CopyThisMethod", "CopyThisProperty"],
     *
     *        // Static props to aggregate onto the built class.
     *        aggregates: ["AggregateThisProperty"],
     *
     *        // Static properties which need custom handling (e.g. deep merge etc.)
     *        custom: {
     *           "CustomProperty" : function(property, Receiver, Supplier) {
     *              ...
     *              var triggers = Receiver.CustomProperty.triggers;
     *              Receiver.CustomProperty.triggers = triggers.concat(Supplier.CustomProperty.triggers);
     *              ...
     *           }
     *        }
     *     };
     *
     *     MyBaseClass.CopyThisMethod = function() {...};
     *     MyBaseClass.CopyThisProperty = "foo";
     *     MyBaseClass.AggregateThisProperty = {...};
     *     MyBaseClass.CustomProperty = {
     *        triggers: [...]
     *     }
     *
     *     // Or, if the Extension is the thing introducing the property:
     *
     *     MyExtension._buildCfg = {
     *         statics : ...
     *         aggregates : ...
     *         custom : ...
     *     }
     *
     * This way, when users pass your base or extension class to `Y.Base.create` or `Y.Base.mix`, they don't need to
     * know which properties need special handling. `Y.Base` has a buildCfg which defines `ATTRS` for custom mix handling
     * (to protect the static config objects), and `Y.Widget` has a buildCfg which specifies `HTML_PARSER` for
     * straight up aggregation.
     *
     * @method create
     * @static
     * @param {String} name The name of the newly created class. Used to define the NAME property for the new class.
     * @param {Function} main The base class which the new class should extend.
     * This class needs to be Base or a class derived from base (e.g. Widget).
     * @param {Function[]} extensions The list of extensions which will be mixed into the built class.
     * @param {Object} px The set of prototype properties/methods to add to the built class.
     * @param {Object} sx The set of static properties/methods to add to the built class.
     * @return {Function} The newly created class.
     */
    Base.create = function(name, base, extensions, px, sx) {
        return build(name, base, extensions, px, sx);
    };

    /**
     * <p>Mixes in a list of extensions to an existing class.</p>
     * @method mix
     * @static
     * @param {Function} main The existing class into which the extensions should be mixed.
     * The class needs to be Base or a class derived from Base (e.g. Widget)
     * @param {Function[]} extensions The set of extension classes which will mixed into the existing main class.
     * @return {Function} The modified main class, with extensions mixed in.
     */
    Base.mix = function(main, extensions) {

        if (main._CACHED_CLASS_DATA) {
            main._CACHED_CLASS_DATA = null;
        }

        return build(null, main, extensions, null, null, {dynamic:false});
    };

    /**
     * The build configuration for the Base class.
     *
     * Defines the static fields which need to be aggregated when the Base class
     * is used as the main class passed to the
     * <a href="#method_Base.build">Base.build</a> method.
     *
     * @property _buildCfg
     * @type Object
     * @static
     * @final
     * @private
     */
    BaseCore._buildCfg = {
        aggregates: AGGREGATES.concat(),

        custom: {
            ATTRS         : attrsAggregator,
            _ATTR_CFG     : attrCfgAggregator,
            _NON_ATTRS_CFG: arrayAggregator
        }
    };

    // Makes sure Base and BaseCore use separate `_buildCfg` objects.
    Base._buildCfg = {
        aggregates: AGGREGATES.concat(),

        custom: {
            ATTRS         : attrsAggregator,
            _ATTR_CFG     : attrCfgAggregator,
            _NON_ATTRS_CFG: arrayAggregator
        }
    };


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

YUI.add('cookie', function (Y, NAME) {

/**
 * Utilities for cookie management
 * @module cookie
 */

    //shortcuts
    var L       = Y.Lang,
        O       = Y.Object,
        NULL    = null,

        //shortcuts to functions
        isString    = L.isString,
        isObject    = L.isObject,
        isUndefined = L.isUndefined,
        isFunction  = L.isFunction,
        encode      = encodeURIComponent,
        decode      = decodeURIComponent,

        //shortcut to document
        doc         = Y.config.doc;

    /*
     * Throws an error message.
     */
    function error(message){
        throw new TypeError(message);
    }

    /*
     * Checks the validity of a cookie name.
     */
    function validateCookieName(name){
        if (!isString(name) || name === ""){
            error("Cookie name must be a non-empty string.");
        }
    }

    /*
     * Checks the validity of a subcookie name.
     */
    function validateSubcookieName(subName){
        if (!isString(subName) || subName === ""){
            error("Subcookie name must be a non-empty string.");
        }
    }

    /**
     * Cookie utility.
     * @class Cookie
     * @static
     */
    Y.Cookie = {

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

        /**
         * Creates a cookie string that can be assigned into document.cookie.
         * @param {String} name The name of the cookie.
         * @param {String} value The value of the cookie.
         * @param {Boolean} encodeValue True to encode the value, false to leave as-is.
         * @param {Object} options (Optional) Options for the cookie.
         * @return {String} The formatted cookie string.
         * @method _createCookieString
         * @private
         * @static
         */
        _createCookieString : function (name /*:String*/, value /*:Variant*/, encodeValue /*:Boolean*/, options /*:Object*/) /*:String*/ {

            options = options || {};

            var text /*:String*/ = encode(name) + "=" + (encodeValue ? encode(value) : value),
                expires = options.expires,
                path    = options.path,
                domain  = options.domain;


            if (isObject(options)){
                //expiration date
                if (expires instanceof Date){
                    text += "; expires=" + expires.toUTCString();
                }

                //path
                if (isString(path) && path !== ""){
                    text += "; path=" + path;
                }

                //domain
                if (isString(domain) && domain !== ""){
                    text += "; domain=" + domain;
                }

                //secure
                if (options.secure === true){
                    text += "; secure";
                }
            }

            return text;
        },

        /**
         * Formats a cookie value for an object containing multiple values.
         * @param {Object} hash An object of key-value pairs to create a string for.
         * @return {String} A string suitable for use as a cookie value.
         * @method _createCookieHashString
         * @private
         * @static
         */
        _createCookieHashString : function (hash /*:Object*/) /*:String*/ {
            if (!isObject(hash)){
                error("Cookie._createCookieHashString(): Argument must be an object.");
            }

            var text /*:Array*/ = [];

            O.each(hash, function(value, key){
                if (!isFunction(value) && !isUndefined(value)){
                    text.push(encode(key) + "=" + encode(String(value)));
                }
            });

            return text.join("&");
        },

        /**
         * Parses a cookie hash string into an object.
         * @param {String} text The cookie hash string to parse (format: n1=v1&n2=v2).
         * @return {Object} An object containing entries for each cookie value.
         * @method _parseCookieHash
         * @private
         * @static
         */
        _parseCookieHash : function (text) {

            var hashParts   = text.split("&"),
                hashPart    = NULL,
                hash        = {};

            if (text.length){
                for (var i=0, len=hashParts.length; i < len; i++){
                    hashPart = hashParts[i].split("=");
                    hash[decode(hashPart[0])] = decode(hashPart[1]);
                }
            }

            return hash;
        },

        /**
         * Parses a cookie string into an object representing all accessible cookies.
         * @param {String} text The cookie string to parse.
         * @param {Boolean} shouldDecode (Optional) Indicates if the cookie values should be decoded or not. Default is true.
         * @param {Object} options (Optional) Contains settings for loading the cookie.
         * @return {Object} An object containing entries for each accessible cookie.
         * @method _parseCookieString
         * @private
         * @static
         */
        _parseCookieString : function (text /*:String*/, shouldDecode /*:Boolean*/, options /*:Object*/) /*:Object*/ {

            var cookies /*:Object*/ = {};

            if (isString(text) && text.length > 0) {

                var decodeValue = (shouldDecode === false ? function(s){return s;} : decode),
                    cookieParts = text.split(/;\s/g),
                    cookieName  = NULL,
                    cookieValue = NULL,
                    cookieNameValue = NULL;

                for (var i=0, len=cookieParts.length; i < len; i++){
                    //check for normally-formatted cookie (name-value)
                    cookieNameValue = cookieParts[i].match(/([^=]+)=/i);
                    if (cookieNameValue instanceof Array){
                        try {
                            cookieName = decode(cookieNameValue[1]);
                            cookieValue = decodeValue(cookieParts[i].substring(cookieNameValue[1].length+1));
                        } catch (ex){
                            //intentionally ignore the cookie - the encoding is wrong
                        }
                    } else {
                        //means the cookie does not have an "=", so treat it as a boolean flag
                        cookieName = decode(cookieParts[i]);
                        cookieValue = "";
                    }
                    // don't overwrite an already loaded cookie if set by option
                    if (!isUndefined(options) && options.reverseCookieLoading) {
                        if (isUndefined(cookies[cookieName])) {
                            cookies[cookieName] = cookieValue;
                        }
                    } else {
                        cookies[cookieName] = cookieValue;
                    }
                }

            }

            return cookies;
        },

        /**
         * Sets the document object that the cookie utility uses for setting
         * cookies. This method is necessary to ensure that the cookie utility
         * unit tests can pass even when run on a domain instead of locally.
         * This method should not be used otherwise; you should use
         * <code>Y.config.doc</code> to change the document that the cookie
         * utility uses for everyday purposes.
         * @param {Object} newDoc The object to use as the document.
         * @method _setDoc
         * @private
         */
        _setDoc: function(newDoc){
            doc = newDoc;
        },

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

        /**
         * Determines if the cookie with the given name exists. This is useful for
         * Boolean cookies (those that do not follow the name=value convention).
         * @param {String} name The name of the cookie to check.
         * @return {Boolean} True if the cookie exists, false if not.
         * @method exists
         * @static
         */
        exists: function(name) {

            validateCookieName(name);   //throws error

            var cookies = this._parseCookieString(doc.cookie, true);

            return cookies.hasOwnProperty(name);
        },

        /**
         * Returns the cookie value for the given name.
         * @param {String} name The name of the cookie to retrieve.
         * @param {Function|Object} options (Optional) An object containing one or more
         *      cookie options: raw (true/false), reverseCookieLoading (true/false)
         *      and converter (a function).
         *      The converter function is run on the value before returning it. The
         *      function is not used if the cookie doesn't exist. The function can be
         *      passed instead of the options object for backwards compatibility. When
         *      raw is set to true, the cookie value is not URI decoded.
         * @return {Any} If no converter is specified, returns a string or null if
         *      the cookie doesn't exist. If the converter is specified, returns the value
         *      returned from the converter or null if the cookie doesn't exist.
         * @method get
         * @static
         */
        get : function (name, options) {

            validateCookieName(name);   //throws error

            var cookies,
                cookie,
                converter;

            //if options is a function, then it's the converter
            if (isFunction(options)) {
                converter = options;
                options = {};
            } else if (isObject(options)) {
                converter = options.converter;
            } else {
                options = {};
            }

            cookies = this._parseCookieString(doc.cookie, !options.raw, options);
            cookie = cookies[name];

            //should return null, not undefined if the cookie doesn't exist
            if (isUndefined(cookie)) {
                return NULL;
            }

            if (!isFunction(converter)){
                return cookie;
            } else {
                return converter(cookie);
            }
        },

        /**
         * Returns the value of a subcookie.
         * @param {String} name The name of the cookie to retrieve.
         * @param {String} subName The name of the subcookie to retrieve.
         * @param {Function} converter (Optional) A function to run on the value before returning
         *      it. The function is not used if the cookie doesn't exist.
         * @param {Object} options (Optional) Containing one or more settings for cookie parsing.
         * @return {Any} If the cookie doesn't exist, null is returned. If the subcookie
         *      doesn't exist, null if also returned. If no converter is specified and the
         *      subcookie exists, a string is returned. If a converter is specified and the
         *      subcookie exists, the value returned from the converter is returned.
         * @method getSub
         * @static
         */
        getSub : function (name /*:String*/, subName /*:String*/, converter /*:Function*/, options /*:Object*/) /*:Variant*/ {

            var hash /*:Variant*/ = this.getSubs(name, options);

            if (hash !== NULL) {

                validateSubcookieName(subName);   //throws error

                if (isUndefined(hash[subName])){
                    return NULL;
                }

                if (!isFunction(converter)){
                    return hash[subName];
                } else {
                    return converter(hash[subName]);
                }
            } else {
                return NULL;
            }

        },

        /**
         * Returns an object containing name-value pairs stored in the cookie with the given name.
         * @param {String} name The name of the cookie to retrieve.
         * @param {Object} options (Optional) Containing one or more settings for cookie parsing.
         * @return {Object} An object of name-value pairs if the cookie with the given name
         *      exists, null if it does not.
         * @method getSubs
         * @static
         */
        getSubs : function (name /*:String*/, options /*:Object*/) {

            validateCookieName(name);   //throws error

            var cookies = this._parseCookieString(doc.cookie, false, options);
            if (isString(cookies[name])){
                return this._parseCookieHash(cookies[name]);
            }
            return NULL;
        },

        /**
         * Removes a cookie from the machine by setting its expiration date to
         * sometime in the past.
         * @param {String} name The name of the cookie to remove.
         * @param {Object} options (Optional) An object containing one or more
         *      cookie options: path (a string), domain (a string),
         *      and secure (true/false). The expires option will be overwritten
         *      by the method.
         * @return {String} The created cookie string.
         * @method remove
         * @static
         */
        remove : function (name, options) {

            validateCookieName(name);   //throws error

            //set options
            options = Y.merge(options || {}, {
                expires: new Date(0)
            });

            //set cookie
            return this.set(name, "", options);
        },

        /**
         * Removes a sub cookie with a given name.
         * @param {String} name The name of the cookie in which the subcookie exists.
         * @param {String} subName The name of the subcookie to remove.
         * @param {Object} options (Optional) An object containing one or more
         *      cookie options: path (a string), domain (a string), expires (a Date object),
         *      removeIfEmpty (true/false), and secure (true/false). This must be the same
         *      settings as the original subcookie.
         * @return {String} The created cookie string.
         * @method removeSub
         * @static
         */
        removeSub : function(name, subName, options) {

            validateCookieName(name);   //throws error

            validateSubcookieName(subName);   //throws error

            options = options || {};

            //get all subcookies for this cookie
            var subs = this.getSubs(name);

            //delete the indicated subcookie
            if (isObject(subs) && subs.hasOwnProperty(subName)){
                delete subs[subName];

                if (!options.removeIfEmpty) {
                    //reset the cookie

                    return this.setSubs(name, subs, options);
                } else {
                    //reset the cookie if there are subcookies left, else remove
                    for (var key in subs){
                        if (subs.hasOwnProperty(key) && !isFunction(subs[key]) && !isUndefined(subs[key])){
                            return this.setSubs(name, subs, options);
                        }
                    }

                    return this.remove(name, options);
                }
            } else {
                return "";
            }

        },

        /**
         * Sets a cookie with a given name and value.
         * @param {String} name The name of the cookie to set.
         * @param {Any} value The value to set for the cookie.
         * @param {Object} options (Optional) An object containing one or more
         *      cookie options: path (a string), domain (a string), expires (a Date object),
         *      secure (true/false), and raw (true/false). Setting raw to true indicates
         *      that the cookie should not be URI encoded before being set.
         * @return {String} The created cookie string.
         * @method set
         * @static
         */
        set : function (name, value, options) {

            validateCookieName(name);   //throws error

            if (isUndefined(value)){
                error("Cookie.set(): Value cannot be undefined.");
            }

            options = options || {};

            var text = this._createCookieString(name, value, !options.raw, options);
            doc.cookie = text;
            return text;
        },

        /**
         * Sets a sub cookie with a given name to a particular value.
         * @param {String} name The name of the cookie to set.
         * @param {String} subName The name of the subcookie to set.
         * @param {Any} value The value to set.
         * @param {Object} options (Optional) An object containing one or more
         *      cookie options: path (a string), domain (a string), expires (a Date object),
         *      and secure (true/false).
         * @return {String} The created cookie string.
         * @method setSub
         * @static
         */
        setSub : function (name, subName, value, options) {

            validateCookieName(name);   //throws error

            validateSubcookieName(subName);   //throws error

            if (isUndefined(value)){
                error("Cookie.setSub(): Subcookie value cannot be undefined.");
            }

            var hash = this.getSubs(name);

            if (!isObject(hash)){
                hash = {};
            }

            hash[subName] = value;

            return this.setSubs(name, hash, options);

        },

        /**
         * Sets a cookie with a given name to contain a hash of name-value pairs.
         * @param {String} name The name of the cookie to set.
         * @param {Object} value An object containing name-value pairs.
         * @param {Object} options (Optional) An object containing one or more
         *      cookie options: path (a string), domain (a string), expires (a Date object),
         *      and secure (true/false).
         * @return {String} The created cookie string.
         * @method setSubs
         * @static
         */
        setSubs : function (name, value, options) {

            validateCookieName(name);   //throws error

            if (!isObject(value)){
                error("Cookie.setSubs(): Cookie value must be an object.");
            }

            var text /*:String*/ = this._createCookieString(name, this._createCookieHashString(value), false, options);
            doc.cookie = text;
            return text;
        }

    };


}, 'patched-v3.18.3', {"requires": ["yui-base"]});

YUI.add('event-touch', function (Y, NAME) {

/**
Adds touch event facade normalization properties (touches, changedTouches, targetTouches etc.) to the DOM event facade. Adds
touch events to the DOM events whitelist.

@example
    YUI().use('event-touch', function (Y) {
        Y.one('#myDiv').on('touchstart', function(e) {
            ...
        });
    });
@module event
@submodule event-touch
 */
var SCALE = "scale",
    ROTATION = "rotation",
    IDENTIFIER = "identifier",
    win = Y.config.win,
    GESTURE_MAP = {};

/**
 * Adds touch event facade normalization properties to the DOM event facade
 *
 * @method _touch
 * @for DOMEventFacade
 * @private
 * @param ev {Event} the DOM event
 * @param currentTarget {HTMLElement} the element the listener was attached to
 * @param wrapper {CustomEvent} the custom event wrapper for this DOM event
 */
Y.DOMEventFacade.prototype._touch = function(e, currentTarget, wrapper) {

    var i,l, etCached, et,touchCache;


    if (e.touches) {

        /**
         * Array of individual touch events for touch points that are still in
         * contact with the touch surface.
         *
         * @property touches
         * @type {DOMEventFacade[]}
         */
        this.touches = [];
        touchCache = {};

        for (i = 0, l = e.touches.length; i < l; ++i) {
            et = e.touches[i];
            touchCache[Y.stamp(et)] = this.touches[i] = new Y.DOMEventFacade(et, currentTarget, wrapper);
        }
    }

    if (e.targetTouches) {

        /**
         * Array of individual touch events still in contact with the touch
         * surface and whose `touchstart` event occurred inside the same taregt
         * element as the current target element.
         *
         * @property targetTouches
         * @type {DOMEventFacade[]}
         */
        this.targetTouches = [];

        for (i = 0, l = e.targetTouches.length; i < l; ++i) {
            et = e.targetTouches[i];
            etCached = touchCache && touchCache[Y.stamp(et, true)];

            this.targetTouches[i] = etCached || new Y.DOMEventFacade(et, currentTarget, wrapper);

        }
    }

    if (e.changedTouches) {

        /**
        An array of event-specific touch events.

        For `touchstart`, the touch points that became active with the current
        event.

        For `touchmove`, the touch points that have changed since the last
        event.

        For `touchend`, the touch points that have been removed from the touch
        surface.

        @property changedTouches
        @type {DOMEventFacade[]}
        **/
        this.changedTouches = [];

        for (i = 0, l = e.changedTouches.length; i < l; ++i) {
            et = e.changedTouches[i];
            etCached = touchCache && touchCache[Y.stamp(et, true)];

            this.changedTouches[i] = etCached || new Y.DOMEventFacade(et, currentTarget, wrapper);

        }
    }

    if (SCALE in e) {
        this[SCALE] = e[SCALE];
    }

    if (ROTATION in e) {
        this[ROTATION] = e[ROTATION];
    }

    if (IDENTIFIER in e) {
        this[IDENTIFIER] = e[IDENTIFIER];
    }
};

//Adding MSPointer events to whitelisted DOM Events. MSPointer event payloads
//have the same properties as mouse events.
if (Y.Node.DOM_EVENTS) {
    Y.mix(Y.Node.DOM_EVENTS, {
        touchstart:1,
        touchmove:1,
        touchend:1,
        touchcancel:1,
        gesturestart:1,
        gesturechange:1,
        gestureend:1,
        MSPointerDown:1,
        MSPointerUp:1,
        MSPointerMove:1,
        MSPointerCancel:1,
        pointerdown:1,
        pointerup:1,
        pointermove:1,
        pointercancel:1
    });
}

//Add properties to Y.EVENT.GESTURE_MAP based on feature detection.
if ((win && ("ontouchstart" in win)) && !(Y.UA.chrome && Y.UA.chrome < 6)) {
    GESTURE_MAP.start = ["touchstart", "mousedown"];
    GESTURE_MAP.end = ["touchend", "mouseup"];
    GESTURE_MAP.move = ["touchmove", "mousemove"];
    GESTURE_MAP.cancel = ["touchcancel", "mousecancel"];
}

else if (win && win.PointerEvent) {
    GESTURE_MAP.start = "pointerdown";
    GESTURE_MAP.end = "pointerup";
    GESTURE_MAP.move = "pointermove";
    GESTURE_MAP.cancel = "pointercancel";
}

else if (win && ("msPointerEnabled" in win.navigator)) {
    GESTURE_MAP.start = "MSPointerDown";
    GESTURE_MAP.end = "MSPointerUp";
    GESTURE_MAP.move = "MSPointerMove";
    GESTURE_MAP.cancel = "MSPointerCancel";
}

else {
    GESTURE_MAP.start = "mousedown";
    GESTURE_MAP.end = "mouseup";
    GESTURE_MAP.move = "mousemove";
    GESTURE_MAP.cancel = "mousecancel";
}

/**
 * A object literal with keys "start", "end", and "move". The value for each key is a
 * string representing the event for that environment. For touch environments, the respective
 * values are "touchstart", "touchend" and "touchmove". Mouse and MSPointer environments are also
 * supported via feature detection.
 *
 * @property _GESTURE_MAP
 * @type Object
 * @static
 */
Y.Event._GESTURE_MAP = GESTURE_MAP;


}, 'patched-v3.18.3', {"requires": ["node-base"]});

YUI.add('overlay', function (Y, 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 overlay
 */

/**
 * 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 Overlay
 * @constructor
 * @extends Widget
 * @uses WidgetStdMod
 * @uses WidgetPosition
 * @uses WidgetStack
 * @uses WidgetPositionAlign
 * @uses WidgetPositionConstrain
 * @param {Object} object The user configuration for the instance.
 */
Y.Overlay = Y.Base.create("overlay", Y.Widget, [Y.WidgetStdMod, Y.WidgetPosition, Y.WidgetStack, Y.WidgetPositionAlign, Y.WidgetPositionConstrain]);


}, 'patched-v3.18.3', {
    "requires": [
        "widget",
        "widget-stdmod",
        "widget-position",
        "widget-position-align",
        "widget-stack",
        "widget-position-constrain"
    ],
    "skinnable": true
});

YUI.add('querystring-stringify', function (Y, NAME) {

/**
 * Provides Y.QueryString.stringify method for converting objects to Query Strings.
 *
 * @module querystring
 * @submodule querystring-stringify
 */

var QueryString = Y.namespace("QueryString"),
    stack = [],
    L = Y.Lang;

/**
 * Provides Y.QueryString.escape method to be able to override default encoding
 * method.  This is important in cases where non-standard delimiters are used, if
 * the delimiters would not normally be handled properly by the builtin
 * (en|de)codeURIComponent functions.
 * Default: encodeURIComponent
 *
 * @method escape
 * @for QueryString
 * @static
 **/
QueryString.escape = encodeURIComponent;

/**
 * <p>Converts an arbitrary value to a Query String representation.</p>
 *
 * <p>Objects with cyclical references will trigger an exception.</p>
 *
 * @method stringify
 * @for QueryString
 * @public
 * @param obj {Any} any arbitrary value to convert to query string
 * @param cfg {Object} (optional) Configuration object.  The three
 * supported configurations are:
 * <ul><li>sep: When defined, the value will be used as the key-value
 * separator.  The default value is "&".</li>
 * <li>eq: When defined, the value will be used to join the key to
 * the value.  The default value is "=".</li>
 * <li>arrayKey: When set to true, the key of an array will have the
 * '[]' notation appended to the key.  The default value is false.
 * </li></ul>
 * @param name {String} (optional) Name of the current key, for handling children recursively.
 * @static
 */
QueryString.stringify = function (obj, c, name) {
    var begin, end, i, l, n, s,
        sep = c && c.sep ? c.sep : "&",
        eq = c && c.eq ? c.eq : "=",
        aK = c && c.arrayKey ? c.arrayKey : false;

    if (L.isNull(obj) || L.isUndefined(obj) || L.isFunction(obj)) {
        return name ? QueryString.escape(name) + eq : '';
    }

    if (L.isBoolean(obj) || Object.prototype.toString.call(obj) === '[object Boolean]') {
        obj =+ obj;
    }

    if (L.isNumber(obj) || L.isString(obj)) {
        return QueryString.escape(name) + eq + QueryString.escape(obj);
    }

    if (L.isArray(obj)) {
        s = [];
        name = aK ? name + '[]' : name;
        l = obj.length;
        for (i = 0; i < l; i++) {
            s.push( QueryString.stringify(obj[i], c, name) );
        }

        return s.join(sep);
    }
    // now we know it's an object.

    // Check for cyclical references in nested objects
    for (i = stack.length - 1; i >= 0; --i) {
        if (stack[i] === obj) {
            throw new Error("QueryString.stringify. Cyclical reference");
        }
    }

    stack.push(obj);
    s = [];
    begin = name ? name + '[' : '';
    end = name ? ']' : '';
    for (i in obj) {
        if (obj.hasOwnProperty(i)) {
            n = begin + i + end;
            s.push(QueryString.stringify(obj[i], c, n));
        }
    }

    stack.pop();
    s = s.join(sep);
    if (!s && name) {
        return name + "=";
    }

    return s;
};


}, 'patched-v3.18.3', {"requires": ["yui-base"]});

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.3', {"requires": ["base-build", "widget"]});

