if (!window.ibre) {
  var _handlers = {
    HR : function(node) {
      var menu = node.parentNode;
      if (menu.tagName == "MENU") {
        var table = menu.refNode;
        var td;
        if (menu._type == "toolbar") {
          td = table.rows[0].insertCell(-1);
          td.style.padding = "0px 1px";
          td.innerHTML = "<div style='background-color: #ddd; width: 2px; height: "
              + Element.getHeight(td) * 0.8 + "px'></div>";
          td.style.width = "2px";
        }
        else {
          td = table.insertCell(-1);
          td.colSpan = 3;
          td.style.padding = "1px 0px";
          td.innerHTML = "<div style='background-color: #ddd; width: " + Element.getWidth(td) * 0.8
              + "px; height: 2px'></div>";
          td.style.height = "2px";
        }
      }
    },
    COMMAND : function(node, root, vars) {
      var menu = node.parentNode;
      if (menu.tagName == "MENU") {
        var table = menu.refNode;
        var command;
        node.label = node.getAttribute("label") || "";
        node.icon = node.getAttribute("icon");
        var disabled = Prototype.Browser.IE? node.disabled: node.getAttribute("disabled") != null;
        node.type = ibre.util.filterValue(node.getAttribute("type"), [ "checkbox", "radio" ],
            "default");
        var checked = node.type != "default"? node.getAttribute("checked") != null: false;
        if (menu._type == "toolbar") {
          command = table.rows[0].insertCell(-1);
          command.className = "ibre-toolitem";
          if (node.icon && node.label) command.innerHTML = "<table cellpadding='0' cellspacing='0'><tr><td class='ibre-toolitem-icon'><img src='"
              + node.icon
              + "'></td><td class='ibre-menuitem-label'>"
              + node.label.escapeHTML()
              + "</td></tr></table>";
          else if (node.icon) {
            command.innerHTML = "<img src='" + node.icon + "'>";
            Element.addClassName(command, "ibre-toolitem-icon");
          }
          else {
            Element.setInnerText(command, node.label);
            Element.addClassName(command, "ibre-toolitem-label");
          }
        }
        else {
          command = table.insertRow(-1);
          command.className = "ibre-menuitem";
          var td1 = command.insertCell(0);
          if (node.icon) Element.build("img", {
            src :node.icon
          }, null, td1);
          td1.className = "ibre-menuitem-icon";
          Element.setInnerText(command.insertCell(1), node.label);
          command.cells[1].className = "ibre-menuitem-label";
          var td3 = command.insertCell(2);
          td3.className = "ibre-menuitem-accesskey";
        }
        Event.observe(command, "mouseover", ibre._methods.commandMouseOver);
        Event.observe(command, "mouseout", ibre._methods.commandMouseOut);
        Event.observe(command, "mousedown", ibre._methods.commandMouseDown);
        Event.observe(command, "mouseup", ibre._methods.commandMouseUp);
        var onclick = node.getAttribute("onclick");
        command.onclick = ibre._methods.commandClick.bind(node, onclick? ibre._methods
            .makeEventHandler(onclick, command): null);
        command.title = node.getAttribute("title");
        command.command = node;
        node.element = command;
        node.disabled = false;
        if (disabled) Node.setAttribute(node, "disabled", true);
        if (checked) Node.setAttribute(node, "checked", true);
        ibre._methods.checkDisabledWhen(node, vars);
      }
    },
    MENU : function(node, root) {
      var carry;
      var parent = node.parentNode;
      if (parent.tagName == "MENU") {
        node.label = node.getAttribute("label");
        node.icon = node.getAttribute("icon");
        node.showMenu = ibre._methods.showMenu;
        node.hideMenu = ibre._methods.hideMenu;
        if (node.label) {
          var table = parent.refNode;
          node._type = ibre.util.filterValue(node.getAttribute("type"), [ "context", "toolbar" ],
              "list");
          node.refNode = Element.build("table", {
            cellpadding :"0",
            cellspacing :"0"
          });
          node.refNode.className = "ibre-menu ibre-submenu";
          Element.hide(node.refNode);
          table.parentNode.appendChild(node.refNode);
          var command;
          if (parent._type == "toolbar") {
            command = table.rows[0].insertCell(-1);
            command.className = "ibre-submenu-label";
            if (node.icon) command.innerHTML = "<table cellpadding='0' cellspacing='0'><tr><td style='padding-right: 2px'><img src='"
                + node.icon + "'></td><td>" + node.label.escapeHTML() + "</td></tr></table>";
            else Element.setInnerText(command, node.label);
          }
          else {
            command = table.insertRow(-1);
            var td1 = command.insertCell(0);
            if (node.icon) Element.build("img", {
              src :node.icon
            }, null, td1);
            td1.className = "ibre-menuitem-icon";
            Element.setInnerText(command.insertCell(1), node.label);
            var td3 = command.insertCell(2);
            td3.className = "ibre-submenu-accesskey";
          }
          command.command = node;
          node.element = command;
          var mainMenu = Element.parentElement(parent);
          if (!mainMenu || mainMenu.tagName != "MENU") {
            Event.observe(command, "click", ibre._methods.submenuClick);
            Event.observe(command, "mouseover", ibre._methods.submenuMouseOver);
          }
          else {
            Event.observe(command, "mouseover", node.showMenu.bind(node));
            Event.observe(command, "click", ibre._methods.menuClick);
          }
        }
        else node.refNode = parent.refNode;
      }
      else {
        carry = Node.nextSiblingOnTree(node, root);
        Element.hide(node);
        var menu = Element.build("table", {
          cellpadding :"2",
          cellspacing :"0"
        });
        menu.className = "ibre-menu ibre-menubar";
        node.refNode = menu;
        node._type = ibre.util.filterValue(node.getAttribute("type"), [ "context", "toolbar" ],
            "list");
        if (node._type != "context") node.parentNode.insertBefore(menu, node);
        if (node._type == "toolbar") menu.insertRow(-1);
        ibre.parseChilds(node);
      }
      return carry;
    },
    OBJECT : function(node, root) {
      return Node.nextSiblingOnTree(node, root);
    },
    EMBED : function(node, root) {
      return Node.nextSiblingOnTree(node, root);
    },
    FORM : function(node) {
      if (node.onsubmit) node._onsubmit = node.onsubmit;
      node.onsubmit = ibre._methods.formSubmit;
      ibre._methods.checkEventHandler(node, "received");
    },
    INPUT : function(node, root, vars) {
      var carry;
      var button;
      switch (node.getAttribute("type")) {
        case "number":
          Event.observe(node, "keypress", ibre._methods.numberKeyPress.bind(node));
          Event.observe(node, "focus", ibre._methods.numberFocus.bind(node));
          Event.observe(node, "blur", ibre._methods.numberBlur.bind(node));
          if (!node.style.textAlign) node.style.textAlign = "right";
          break;
        case "date":
          carry = Node.nextSiblingOnTree(node, root);
          Element
              .insert(
                  node,
                  {
                    before :"<table cellspacing='0' cellpadding='0'><tr><td></td><td><input type='image' src='"
                        + ibre.basePath + "jscalendar/img.gif'></td></tr></table>"
                  });
          var cells = node.previousSibling.rows[0].cells;
          cells[0].appendChild(node);
          node.button = cells[1].firstChild;
          Calendar.setup( {
            inputField :node,
            ifFormat :"%Y-%m-%d",
            button :node.button,
            singleClick :false,
            firstDay :0,
            showOthers :true,
            onUpdate :ibre._methods.calendarUpdate.bind(node)
          });
          if (node.disabled) {
            node.button.disabled = true;
            Element.addClassName(node.button, "disabled");
          }
          Event.observe(node, "keypress", ibre._methods.dateKeyPress);
          break;
        case "add":
          carry = Node.nextSiblingOnTree(node, root);
          button = Element.build("input", {
            type :"button",
            value :node.value
          }, null, node.ownerDocument);
          if (node.onclick) button._nativeOnclick = node.onclick;
          button.template = node.getAttribute("template");
          node.parentNode.replaceChild(button, node);
          node = button;
          Event.observe(node, "click", ibre._methods.addClick.bind(node));
          break;
        case "remove":
          carry = Node.nextSiblingOnTree(node, root);
          button = Element.build("input", {
            type :"button",
            value :node.value
          }, null, node.ownerDocument);
          node.parentNode.replaceChild(button, node);
          if (node.onclick) button._nativeOnclick = node.onclick;
          node = button;
          Event.observe(node, "click", ibre._methods.removeClick.bind(node));
          break;
        case "cancel":
          carry = Node.nextSiblingOnTree(node, root);
          button = Element.build("input", {
            type :"button",
            value :node.value
          }, null, node.ownerDocument);
          if (node.onclick) {
            var popup = Popup.getParentPopup(node);
            if (popup.oncancel) button._nativeOnclick = node.onclick;
            else popup.oncancel = node.onclick;
          }
          node.parentNode.replaceChild(button, node);
          node = button;
          Event.observe(node, "click", ibre._methods.cancelClick);
          break;
        case "checkall":
          carry = Node.nextSiblingOnTree(node, root);
          button = Element.build("input", {
            type :"checkbox",
            title :node.title
          }, null, node.ownerDocument);
          node.parentNode.replaceChild(button, node);
          var elements = node.getAttribute("target-elements");
          node = button;
          Event.observe(node, "change", ibre._methods.meCheckAllInputChange);
          node.vars = vars || {};
          var funct = ibre._methods.checkAllInputChange.bind(node);
          if (elements) {
            node.elements = ibre._methods.evalHandler("[" + elements + "]", node).flatten();
            node.elements.each( function(item) {
              Event.observe(item, "change", funct);
            });
          }
          else node.elements = [];
          funct();
          break;
      }
      return carry;
    },
    OPTION : function(node) {
      var selectedValue = node.parentNode.getAttribute("selected-value");
      if (selectedValue != null && selectedValue == node.value) node.selected = true;
    },
    TEXTAREA : function(node, root, vars) {
      var result = ibre._methods.parseText(node.value, node.parentNode, vars);
      if (result != null) node.value = result;
      node.maxLength = node.getAttribute("maxlength");
      if (node.maxLength != null) {
        Event.observe(node, "keypress", ibre._methods.maxLengthKeyPress);
        Event.observe(node, "focus", ibre._methods.maxLengthFocus);
        Event.observe(node, "blur", ibre._methods.maxLengthBlur);
      }
    }
  };
  _handlersTags = {
    tree : function(node, root, vars) {
      var carry = Node.nextSiblingOnTree(node, root);
      ibre._methods.checkEventHandler(node, "change");
      var columns = Element.childElements(node).selectFirst("getAttribute('tag') == 'columns'");
      var bodies = [];
      if (columns) {
        var ths = [ {
          tagName :"th"
        } ];
        columns.childElements().each( function(item) {
          ths.push( {
            tagName :"th",
            children :item
          });
        });
        bodies.push( {
          tagName :"thead",
          children : {
            tagName :"tr",
            children :ths
          }
        });
      }
      bodies.push( {
        tagName :"tbody"
      });
      var tree = Element.build("table", {
        className :"tree"
      }, bodies);
      node._table = tree;
      node.addNode = ibre._methods.treeAddNode;
      node.expandAll = ibre._methods.treeExpandAll;
      node.collapseAll = ibre._methods.treeCollapseAll;
      node.tree = node;
      node.nodes = [];
      node.level = 0;
      function processNodes(node, tree) {
        var nodes = Element.childElements(node).selectFirst("getAttribute('tag') == 'nodes'");
        if (nodes) {
          nodes.childElements().each(
              function(item) {
                var columns = Element.childElements(item).selectFirst(
                    "getAttribute('tag') == 'columns'");
                var tds = [];
                if (columns) {
                  columns.childElements().each( function(item) {
                    tds.push(item);
                  });
                }
                var nodeTree = tree.addNode(item.getAttribute("label"), item.getAttribute("value"),
                    item.getAttribute("icon"), tds);
                var data = item.getAttribute("js-data");
                if (data) nodeTree.jsData = ibre._methods.evalHandler(data, item, vars);
                processNodes(item, nodeTree);
                if (item.getAttribute("closed") != null) nodeTree.toogle();
                if (item.getAttribute("unselectable") != null) Node.setAttribute(nodeTree,
                    "unselectable", true);
              });
        }
      }
      processNodes(node, node);
      Element.replace(node, tree);
      return carry;
    },
    splitter : function(node, root, vars) {
      var carry = Node.nextSiblingOnTree(node, root);
      var table = Element.build("table", {
        cellpadding :"0",
        cellspacing :"0"
      });
      table.style.borderCollapse = "collapse";
      node.orientation = ibre.util.filterValue(node.getAttribute("orientation"), [ "horizontal" ],
          "vertical");
      var isVertical = node.orientation == "vertical";
      table.style.border = node.style.border;
      if (isVertical) {
        table.insertRow(0);
        table.style.height = node.style.height;
      }
      else table.style.width = node.style.width;
      node.parentNode.replaceChild(table, node);
      var items = Element.children(node);
      items.each( function(item, index) {
        var splitter = null;
        var section;
        var div;
        if (isVertical) {
          if (index > 0) {
            splitter = table.rows[0].insertCell(-1);
            splitter.minWidth1 = items[index - 1].getAttribute("min-width") || 50;
            splitter.minWidth2 = item.getAttribute("min-width") || 50;
            Element.addClassName(splitter, "vsplitter");
          }
          section = table.rows[0].insertCell(-1);
          div = Element.build("div", null, item, section);
          var width = item.getAttribute("width");
          // section.vAlign = item.getAttribute("valign");
          if (width) section.style.width = div.style.width = width + "px";
          else table.style.width = "100%";
          div.style.height = table.style.height;
          item.removeAttribute("width");
        }
        else {
          if (index > 0) {
            splitter = table.insertRow(-1);
            splitter.insertCell(-1);
            splitter.minHeight1 = items[index - 1].getAttribute("min-height") || 10;
            splitter.minHeight2 = item.getAttribute("min-height") || 10;
            Element.addClassName(splitter, "hsplitter");
          }
          section = table.insertRow(-1);
          div = Element.build("div", null, item, section.insertCell(0));
          var height = item.getAttribute("height");
          if (height) section.style.height = div.style.height = height + "px";
          else table.style.height = "100%";
          div.style.width = table.style.width;
          item.removeAttribute("height");
        }
        div.style.overflow = "auto";
        if (splitter) {
          splitter.isVertical = isVertical;
          Element.addClassName(splitter, "splitter");
          Event.observe(splitter, "mousedown", ibre._methods.splitterMouseDown);
          var container = Prototype.Browser.IE? document.body: window;
          Event.observe(container, "mouseup", ibre._methods.splitterMouseUp.bind(splitter));
          Event.observe(container, "mousemove", ibre._methods.splitterMouseMove.bind(splitter));
        }
      });
      ibre.parseChilds(table);
      return carry;
    },
    popup : function(node, root, vars) {
      var carry = Node.nextSiblingOnTree(node, root);
      var win;
      var target = node.getAttribute("target");
      switch (target) {
        case "_top":
          win = top;
          break;
        case "_parent":
          win = parent;
          break;
        default:
          win = window;
      }
      var popup = win.ibre._methods.preparePopup();
      var oncancel = node.getAttribute("oncancel");
      if (oncancel) popup.oncancel = win.ibre._methods.makeEventHandler(oncancel, popup);
      if (node.id) document.popups[node.id] = popup;
      if (win != window) {
        var prev = node;
        node = win.document.importNode(prev, true);
        if (node.id) node.id = null;
        Element.remove(prev);
      }
      win.ibre._methods.installPopup(popup, node);
      return carry;
    },
    "switch" : function(node, root, vars) {
      var carry;
      node.activeNext = ibre._methods.switchActiveNext;
      node.activePrevious = ibre._methods.switchActivePrevious;
      node.activeFirst = ibre._methods.switchActiveFirst;
      node.activeLast = ibre._methods.switchActiveLast;
      node.addSection = ibre._methods.switchAddSection;
      node.sections = Element.childElements(node);
      node.activeSection = node.sections[0];
      node.sections.each( function(item, index) {
        item.parent = node;
        item.sectionIndex = index;
        item.setActive = ibre._methods.switchSectionSetActive;
        item.delSection = ibre._methods.switchDelSection;
        if (index > 0) item.hide();
      });
      var label = node.activeSection.down();
      if (label && label.getAttribute("tag") == "legend") {
        carry = Node.nextSiblingOnTree(node, root);
        node.position = node.getAttribute("position") || "top";
        var trs = [];
        var horiz = node.position == "top" || node.position == "bottom";
        var td = {
          tagName :"td",
          attrs : {
            className :"switch-tab-header"
          },
          children : {
            tagName :"img",
            attrs : {
              src :ibre.basePath + "images/spacer.gif"
            }
          }
        };
        if (!horiz) td = {
          tagName :"tr",
          children :td
        };
        var tds = [ td ];
        node.sections.each( function(item, index) {
          var label = item.down();
          td = Element.build("td", {
            className :(index == 0? "switch-tab-sel": "switch-tab-nosel") + " switch-tab",
            onclick :item.setActive.bind(item)
          }, label && label.getAttribute("tag") == "legend" && label || null);
          item.tab = td;
          if (!horiz) td = {
            tagName :"tr",
            children :td
          };
          tds.push(td);
        });
        td = {
          tagName :"td",
          attrs : {
            className :"switch-tab-footer"
          },
          children : {
            tagName :"img",
            attrs : {
              src :ibre.basePath + "images/spacer.gif"
            }
          }
        };
        if (!horiz) td = {
          tagName :"tr",
          children :td
        };
        tds.push(td);
        if (horiz) tds = {
          tagName :"tr",
          children :tds
        };
        tds = {
          tagName :"td",
          attrs : {
            vAlign :node.getAttribute("valign") || "top"
          },
          children : {
            tagName :"table",
            attrs : {
              cellpadding :0,
              cellspacing :0,
              className :"switch-tabs"
            },
            children : {
              tagName :"tbody",
              children :tds
            }
          }
        };
        if (!horiz) tds.attrs.width = 10;
        td = {
          tagName :"td",
          attrs : {
            className :"switch-body"
          },
          children :node.sections
        };
        var bodySeparator = {
          tagName :"td",
          attrs : {
            className :"switch-body-header"
          },
          children : {
            tagName :"img",
            attrs : {
              src :ibre.basePath + "images/spacer.gif"
            }
          }
        };
        if (horiz) {
          trs[node.position == "top"? 0: 2] = {
            tagName :"tr",
            attrs : {
              height :"10"
            },
            children :tds
          };
          trs[node.position == "top"? 2: 0] = {
            tagName :"tr",
            children :td
          };
          trs[1] = {
            tagName :"tr",
            children :bodySeparator
          };
        }
        else {
          var cols = [];
          cols[node.position == "left"? 0: 2] = tds;
          cols[node.position == "left"? 2: 0] = td;
          cols[1] = bodySeparator;
          trs[0] = {
            tagName :"tr",
            children :cols
          };
        }
        ibre.parseChilds(Element.build("table", {
          cellpadding :0,
          cellspacing :0,
          className :"switch"
        }, {
          tagName :"tbody",
          children :trs
        }, node).firstChild);
      }
      return carry;
    },
    datagrid : function(node, root, vars) {
      if (node.tagName == "TABLE" && node.tHead && node.tHead.rows.length) {
        node.isDatagrid = true;
        node.rememberState = node.id && node.getAttribute("remember-state") != null;
        node._changeEvents = [];
        node.firstPage = ibre._methods.datagridFirstPage;
        node.prevPage = ibre._methods.datagridPrevPage;
        node.nextPage = ibre._methods.datagridNextPage;
        node.lastPage = ibre._methods.datagridLastPage;
        node.goPage = ibre._methods.datagridGoPage;
        node.go = ibre._methods.datagridGo;
        node.dataRows = ibre._methods.datagridRows;
        node.length = node.getAttribute("length") * 1 || 0;
        var dataRows = node.dataRows();
        node.position = 0;
        if (node.length > 0) {
          if (node.rememberState) {
            cookieValue = ibre.cookie.get("_1ibre_position_" + node.id);
            if (cookieValue) {
              node.position = parseInt(cookieValue);
              for (i = 0; i < node.position; i++)
                Element.hide(dataRows[i]);
            }
          }
          for (i = node.length + node.position; i < dataRows.length; i++)
            Element.hide(dataRows[i]);
        }
        Element.addClassName(node, "datagrid");
        node.toggleSortState = ibre._methods.tableToggleSortState;
        var cells = $A(node.tHead.rows[0].cells);
        var noSorted = true;
        var cookieValue;
        if (node.rememberState) {
          cookieValue = ibre.cookie.get("_1ibre_sorter_" + node.id);
          if (cookieValue) {
            var column = parseInt(cookieValue.substring(1));
            if (cookieValue.charAt(0) == "1") cells[column].sorted = true;
            node.toggleSortState(column);
            noSorted = false;
          }
        }
        for (i = 0; i < cells.length; i++) {
          var cell = cells[i];
          cell.style.width = Element.getWidth(cell) + "px";
          ibre._methods.checkEventHandler(cell, "sort");
          var classes = cell.className.split(" ");
          if (classes.contains("sortable")) {
            Event.observe(cell, "click", ibre._methods.cellToggleSortState
                .bindAsEventListener(cell));
            if (noSorted && classes.contains("sorted")) {
              if (classes.contains("reversed")) cell.sorted = true;
              node.toggleSortState(cell.cellIndex);
            }
          }
          if (classes.contains("filterable") || classes.contains("searchable")) {
            cell.innerHTML = "<table cellpadding='0' cellspacing='0' class='filterable'><tr><td class='filterable'>"
                + cell.innerHTML
                + "</td><td class='filter-active' style='display: none'></td><td class='icon-filterable' onmouseover='Element.addClassName(this, &quot;icon-filterable-hover&quot;)' onmouseout='Element.removeClassName(this, &quot;icon-filterable-hover&quot;); Element.removeClassName(this, &quot;icon-filterable-pressed&quot;)' onmousedown='Element.addClassName(this, &quot;icon-filterable-pressed&quot;); ibre._methods.clickFilter(parentNode.parentNode.parentNode.parentNode)' onclick='Event.stop(event)' onmouseup='Element.removeClassName(this, &quot;icon-filterable-pressed&quot;)'><img class='icon-filterable' src='"
                + ibre.basePath + "images/spacer.gif'></td></tr></table>";
            if (node.rememberState) {
              cookieValue = ibre.cookie.get("_1ibre_filter_" + node.id
                  + (cell.id? cell.id: cell.cellIndex));
              if (cookieValue) {
                cell._currentPartial = cookieValue.charAt(0) == "1";
                cell._currentFilter = cookieValue.substring(1);
                (ibre._methods.datagridFilter.bind(cell, cell._currentFilter, cell._currentPartial))
                    ();
              }
            }
          }
          if (classes.contains("resizable")) {
            var resizable = Element.build("td", {
              className :"resizable",
              ondblclick :ibre._methods.datagridResizableDblClick
            }, {
              tagName :"img",
              attrs : {
                width :1,
                height :1,
                src :ibre.basePath + "images/spacer.gif"
              }
            });
            Element.insert(cell, {
              after :resizable
            });
            var k, rows;
            for (j = 0; j < node.tBodies.length; j++) {
              rows = node.tBodies[j].rows;
              for (k = 0; k < rows.length; k++)
                Element.insert(rows[k].cells[cell.cellIndex], {
                  after :Element.build("td", {
                    className :"resizable-separator"
                  })
                });
            }
            Event.observe(resizable, "mousedown", ibre._methods.datagridResizableMouseDown);
          }
        }
        node.style.width = Element.getWidth(node) + "px";
      }
    }
  };
  ibre = {};
  if (!window.Node) Node = {};
  if (!window.Attr) Attr = {};
  if (!window.Event) Event = {};
  if (!window.Form) Form = {};
  Popup = {};
  document.elementsById = {};
  document.popups = {};
  document.visiblePopups = [];
  document.templates = {};
  document.clearSelection = function() {
    if (document.selection) document.selection.empty();
    else if (window.getSelection) window.getSelection().removeAllRanges();
  };
  _$ = window.$;
  $ = function(id) {
    var element = _$(id);
    if (!element && typeof id == "string") element = ibre.elements[id] || null;
    return element;
  };
  $A = function(iterable) {
    if (!iterable) return [];
    if (iterable.toArray) return iterable.toArray();
    if (iterable.length == null) return [ iterable ];
    var length = iterable.length, results = new Array(length);
    while (length--)
      results[length] = iterable[length];
    return results;
  };
  Node.ELEMENT_NODE = 1;
  Node.ATTRIBUTE_NODE = 2;
  Node.TEXT_NODE = 3;
  Node.CDATA_SECTION_NODE = 4;
  Node.ENTITY_REFERENCE_NODE = 5;
  Node.ENTITY_NODE = 6;
  Node.PROCESSING_INSTRUCTION_NODE = 7;
  Node.COMMENT_NODE = 8;
  Node.DOCUMENT_NODE = 9;
  Node.DOCUMENT_TYPE_NODE = 10;
  Node.DOCUMENT_FRAGMENT_NODE = 11;
  Node.NOTATION_NODE = 12;
  Node.nextSiblingOnTree = function(node, root) {
    if (!root) root = node.ownerDocument;
    while (node != root) {
      while (node.nextSibling) {
        node = node.nextSibling;
        if (node.nodeType == Node.ELEMENT_NODE || node.nodeType == Node.TEXT_NODE
            && !ibre.test.isWhiteSpace(node.nodeValue)) return node;
      }
      node = node.parentNode;
      if (!node) return null;
    }
    return null;
  };
  Node.nextDescendantOnTree = function(node, root) {
    if (node.firstChild) {
      var first = node.firstChild;
      if (first.nodeType == Node.ELEMENT_NODE || first.nodeType == Node.TEXT_NODE
          && !ibre.test.isWhiteSpace(first.nodeValue)) return first;
      first = Node.nextSiblingOnTree(first);
      if (first) return first;
    }
    return Node.nextSiblingOnTree(node, root);
  };
  Node.getContent = function(node) {
    var fragment = node.ownerDocument.createDocumentFragment();
    while (node.firstChild)
      fragment.appendChild(node.firstChild);
    return fragment;
  };
  Node.toDocument = function(node) {
    if (node.nodeType == Node.DOCUMENT_NODE) return node;
    var doc = node.ownerDocument;
    if (doc.firstChild) {
      if (doc.childNodes.length == 1 && doc.firstChild == node) return doc;
      doc = Node.createDocument();
      node = doc.importNode(node);
    }
    doc.appendChild(node);
    return doc;
  };
  Node.createDocument = function() {
    return document.implementation.createDocument(null, null, null);
  };
  Node.toDocumentFragment = function(node) {
    if (node.nodeType == Node.DOCUMENT_FRAGMENT_NODE) return node;
    if (node.nodeType == Node.DOCUMENT_NODE) return Node.getContent(node);
    var fragment = node.ownerDocument.createDocumentFragment();
    fragment.appendChild(node);
    return fragment;
  };
  Node.isNode = function(node) {
    return !!node.nodeType;
  };
  Node.remove = function(node) {
    node.parentNode.removeChild(node);
  };
  Node.document = function(node) {
    return node.ownerDocument || node;
  };
  Node.setAttribute = function(node, attr, value) {
    if (node[attr] == value) return;
    var prevVal = node[attr];
    node[attr] = value;
    switch (node.nodeType) {
      case Node.ELEMENT_NODE:
        var prev;
        var i;
        if (attr == "disabled") try {
          Element[node.disabled? "addClassName": "removeClassName"](node, "disabled");
        }
        catch (e) {
        }
        switch (node.tagName) {
          case "COMMAND":
            var className;
            switch (attr) {
              case "checked":
                if (node.type == "checkbox" || node.type == "radio") {
                  className = "ibre-" + (node.parentNode._type == "toolbar"? "tool": "menu")
                      + "item-checked";
                  if (value) {
                    Element.addClassName(node.element, className);
                    if (node.type == "radio") {
                      prev = node.parentNode.currentRadio;
                      if (prev != null && prev != node) Node.setAttribute(prev, "checked", false);
                      node.parentNode.currentRadio = node;
                    }
                  }
                  else Element.removeClassName(node.element, className);
                }
                break;
              case "disabled":
                className = "ibre-" + (node.parentNode._type == "toolbar"? "tool": "menu")
                    + "item-disabled";
                if (value) Element.addClassName(node.element, className);
                else Element.removeClassName(node.element, className);
                break;
            }
            break;
          case "TD":
            switch (attr) {
              case "checked":
                if (node.type == "checkbox" || node.type == "radio") {
                  if (value) {
                    node.style.padding = "4px";
                    node.style.borderWidth = "2px";
                    node.style.borderStyle = "inset";
                    if (node.type == "radio") {
                      prev = node.parentNode._radiogroups[node.radiogroup];
                      if (prev != null && prev != node) {
                        prev.style.padding = "6px";
                        prev.style.borderWidth = "0px";
                        prev.checked = false;
                      }
                      node.parentNode._radiogroups[node.radiogroup] = node;
                    }
                  }
                  else {
                    node.style.borderWidth = "0px";
                    node.style.padding = "6px";
                  }
                }
                break;
              case "disabled":
                if (node.type) {
                  if (value) {
                    node.style.borderWidth = "0px";
                    node.style.padding = "6px";
                    node.style.opacity = "0.2";
                    node.style.filter = "alpha(opacity=20)";
                  }
                  else {
                    node.style.opacity = "";
                    node.style.filter = "";
                  }
                }
                break;
            }
            break;
          case "SELECT":
            switch (attr) {
              case "selectedValue":
                for (i = 0; i < node.options.length; i++)
                  if (node.options[i].value == value) {
                    if (!node.options[i].selected) node.selectedIndex = i;
                    break;
                  }
                break;
            }
            break;
          case "OPTION":
            switch (attr) {
              case "selected":
                Event.fireEvent(node.parentNode, "change");
                break;
            }
            break;
          case "FIELDSET":
            switch (attr) {
              case "disabled":
                var elements = $A(node.getElementsByTagName("INPUT")).concat(
                    $A(node.getElementsByTagName("SELECT"))).concat(
                    $A(node.getElementsByTagName("TEXTAREA")));
                for (i = 0; i < elements.length; i++)
                  elements[i].disabled = value;
                break;
            }
            break;
          case "FORM":
            switch (attr) {
              case "readOnly":
                for (i = 0; i < node.elements.length; i++)
                  node.elements[i].readOnly = value;
                break;
            }
            break;
          case "INPUT":
            switch (attr) {
              case "disabled":
                if (node.getAttribute("type") == "date") {
                  node.button.disabled = value;
                  if (value) Element.addClassName(node.button, "disabled");
                  else Element.removeClassName(node.button, "disabled");
                }
                break;
            }
            break;
          case "TREEROW":
            switch (attr) {
              case "label":
                Element.setInnerText(node._row.cells[0].firstChild.rows[0].lastChild, value);
                break;
              case "columns":
                $A(value).each( function(item, i) {
                  node._row.replaceChild(Element.build("td", null, item), node._row.cells[i + 1]);
                });
                break;
              case "unselectable":
                var cells = node._row.cells[0].firstChild.rows[0].cells;
                var td = cells[cells.length - 1];
                if (value) {
                  td.onmouseover = null;
                  td.onmouseout = null;
                  td.onclick = null;
                }
                else {
                  td.onmouseover = ibre._methods.hoverMouseOver;
                  td.onmouseout = ibre._methods.hoverMouseOut;
                  td.onclick = node.select;
                }
                break;
            }
            break;
          case "TABLE":
            if (node.isDatagrid) {
              switch (attr) {
                case "length":
                  var dataRows = node.dataRows();
                  if (value == 0 || value > dataRows.length) {
                    for (i = 0; i < node.position; i++)
                      Element.show(dataRows[i]);
                    for (i = node.position + prevVal; i < dataRows.length; i++)
                      Element.show(dataRows[i]);
                    node.position = 0;
                    if (node.rememberState) ibre.cookie.set("_1ibre_position_" + node.id, "0");
                  }
                  else if (prevVal == 0) {
                    for (i = value; i < dataRows.length; i++)
                      Element.hide(dataRows[i]);
                  }
                  else {
                    var n;
                    if (value > prevVal) {
                      n = Math.min(dataRows.length, node.position + value);
                      for (i = prevVal + node.position; i < n; i++)
                        Element.show(dataRows[i]);
                    }
                    else {
                      n = Math.min(dataRows.length, node.position + prevVal);
                      for (i = value + node.position; i < n; i++)
                        Element.hide(dataRows[i]);
                    }
                  }
                  Event.fireEvent(node, "change");
                  break;
              }
            }
            break;
        }
        if (node.tagName == "INPUT" || node.tagName == "TEXTAREA" || node.tagName == "SELECT") {
          var disabled = node.disabled;
          if (disabled) node.disabled = false;
          Event.fireEvent(node, "change");
          if (disabled) node.disabled = true;
        }
        break;
    }
  };
  Attr.set = function(element, name, value) {
    if (name.length > 2 && name.startsWith("on")) element[name] = ibre._methods.makeEventHandler(
        value, element);
    else if (element[name] != undefined) element[name] = value;
    else element.setAttribute(name, value);
  };
  Element.getElementByTagName = function(element, tagName) {
    var list = element.getElementsByTagName(tagName);
    if (!list.length) return null;
    return list[0];
  };
  Element.build = function(tagName, attrs, children, parent) {
    var doc;
    if (parent) doc = parent.ownerDocument || parent;
    else doc = document;
    var element = doc.createElement(tagName);
    for ( var attr in attrs) {
      if (attr == "style") for ( var style in attrs[attr])
        element.style[style] = attrs[attr][style];
      else if (attr.startsWith("on") || element[attr] !== undefined) element[attr] = attrs[attr];
      else element.setAttribute(attr, attrs[attr]);
    }
    $A(children).each( function(item) {
      if (typeof item != "object") element.appendChild(doc.createTextNode(item.toString()));
      else if (Node.isNode(item)) element.appendChild(item);
      else Element.build(item.tagName, item.attrs, item.children, element);
    });
    if (parent && !parent.documentElement) parent.appendChild(element);
    return element;
  };
  Element.getInnerText = function(element) {
    if (element.nodeType == Node.DOCUMENT_NODE) element = element.documentElement;
    if (element.tagName == "HTML") {
      var body = element.ownerDocument.body;
      if (body) element = body;
    }
    if (element.innerText != null) return element.innerText;
    var r = element.ownerDocument.createRange();
    r.selectNodeContents(element);
    return r.toString();
  };
  Element.setInnerText = function(element, text) {
    if (element.innerText != null) element.innerText = text;
    else {
      Element.clear(element);
      element.appendChild(element.ownerDocument.createTextNode(text));
    }
  }
  Element.clear = function(element) {
    while (element.lastChild)
      element.removeChild(element.lastChild);
  };
  Element.moveChilds = function(src, target) {
    while (src.firstChild)
      target.appendChild(src.firstChild);
  };
  Element.insertCSSRule = function(sheet, selector, declarations) {
    if (sheet.addRule) sheet.addRule(selector, declarations);
    else sheet.insertRule(selector + "{" + declarations + "}", sheet.cssRules.length);
  };
  Element.styleSheet = function(element) {
    return element.styleSheet || element.sheet;
  };
  Element.isVisible = function(element) {
    var parent = Element.parentElement(element);
    return Element.visible(element) && (!parent || Element.isVisible(parent));
  };
  Element.parentElement = function(element) {
    if (element.parentNode && element.parentNode.nodeType == 1) return element.parentNode;
    return null;
  };
  Element.children = function(element) {
    var children = [];
    var list = element.childNodes;
    for ( var i = 0; i < list.length; i++)
      if (list[i].nodeType == Node.ELEMENT_NODE) children.push(list[i]);
    return children;
  };
  Element.print = function(element) {
    ibre.printLoad = function(win) {
      var doc = win.document;
      var head = doc.getElementsByTagName("head")[0];
      $$("link").each( function(item) {
        if (item.type == "text/css") {
          var link = doc.createElement("link");
          link.type = "text/css";
          link.rel = "stylesheet";
          link.href = item.href;
          head.appendChild(link);
        }
      });
      if (Prototype.Browser.IE) doc.body.innerHTML = element.outerHTML;
      else doc.body.appendChild(doc.importNode(element, true));
      win.print();
      win.close();
    };
    open(ibre.basePath + "print.html", "", "menubar=no,width=1,height=1");
  };
  Element.preview = function(element) {
    ibre.previewLoad = function(win) {
      var doc = win.document;
      var head = doc.getElementsByTagName("head")[0];
      $$("link").each( function(item) {
        if (item.type == "text/css") {
          var link = doc.createElement("link");
          link.type = "text/css";
          link.rel = "stylesheet";
          link.href = item.href;
          head.appendChild(link);
        }
      });
      if (Prototype.Browser.IE) doc.body.innerHTML = element.outerHTML;
      else doc.body.appendChild(doc.importNode(element, true));
    };
    open(ibre.basePath + "preview.html", "", "menubar=yes,toolbar=no,width=" + screen.width
        + ",height=" + screen.height);
  };
  Element.isFormElement = function(element) {
    return element.tagName == "INPUT" || element.tagName == "SELECT"
        || element.tagName == "TEXTAREA" || element.tagName == "FIELDSET"
        || element.tagName == "BUTTON";
  };
  Element.setInnerHTML = function(element, text) {
    if (Prototype.Browser.IE && element.tagName == "SELECT") {
      Element.clear(element);
      var div = element.ownerDocument.createElement("div");
      div.innerHTML = "<select>" + text + "</select>";
      Element.moveChilds(div.firstChild, element);
    }
    else element.innerHTML = text;
    $A(element.getElementsByTagName("script")).each( function(item) {
      var _currentScript = ibre._currentScript;
      ibre._currentScript = item;
      ibre._methods.eval(item.src? ibre.ajax.getText(item.src): item.innerHTML);
      ibre._currentScript = _currentScript;
    });
    ibre.initParse(element);
    ibre._util.loadListeners.each( function(item) {
      item();
    });
    ibre._util.loadListeners = [];
  };
  Form.submit = function(form) {
    if (form.onsubmit() !== false) form.submit();
  };
  Form.validate = function(form) {
    form._noSubmit = true;
    var res = form.onsubmit() !== false;
    form._noSubmit = false;
    return res;
  };
  Form.getElementsByName = function(form, name) {
    var elements = [];
    $A(form.elements).each( function(item) {
      if (item.name == name) elements.push(item);
    });
    return elements;
  };
  Form.addInputData = function(form, formData, prefix, sufix) {
    var span = Element.build("span", null, null, form);
    $A(formData.elements).each(
        function(item) {
          switch (item.tagName) {
            case "INPUT":
              if (item.type != "text" && item.type != "hidden"
                  && (item.type != "radio" && item.type != "checkbox" || !item.checked)) break;
            case "TEXTAREA":
            case "SELECT":
              var name = (prefix? prefix: "") + item.name;
              if (sufix) name += sufix;
              Element.build("input", {
                type :"hidden",
                name :name,
                value :item.value
              }, null, span)._name = item.name;
              break;
          }
        });
    return span;
  };
  Form.rewindInputData = function(data, form) {
    $A(data.childNodes).each(
        function(item) {
          var input = form[item._name];
          if (input) {
            if (!Node.isNode(input)) input = input[Form.getElementsByName(item.form, item.name)
                .indexOf(item)];
            if (input) switch (input.tagName) {
              case "INPUT":
                if (input.type == "text") input.value = item.value;
                else if (input.type == "radio" || input.type == "checkbox") input.checked = true;
                else break;
                Event.fireEvent(input, "change");
              case "TEXTAREA":
                input.value = item.value;
                Event.fireEvent(input, "change");
                break;
              case "SELECT":
                Node.setAttribute(input, "selectedValue", item.value);
                break;
            }
          }
        });
  };
  Radio = {
    checkedElement : function(form, group) {
      var list = $A(form[group]);
      for ( var i = 0; i < list.length; i++)
        if (list[i].checked) return list[i];
      return null;
    }
  };
  Select = {
    selectedOption : function(sel) {
      return sel.options[sel.selectedIndex];
    },
    selectedOptions : function(sel) {
      return $A(sel.options).select("selected");
    }
  };
  Popup.getParentPopup = function(element) {
    if (element.showPopup) return element;
    var parent = Element.parentElement(element);
    return parent? Popup.getParentPopup(parent): null;
  };
  Position.scrollOffset = function() {
    var x, y;
    if (self.pageYOffset) {
      x = self.pageXOffset;
      y = self.pageYOffset;
    }
    else if (document.documentElement && document.documentElement.scrollTop) {
      x = document.documentElement.scrollLeft;
      y = document.documentElement.scrollTop;
    }
    else if (document.body) {
      x = document.body.scrollLeft;
      y = document.body.scrollTop;
    }
    return [ x, y ];
  };
  Position.clientSize = function() {
    var x, y;
    if (self.innerHeight) {
      x = self.innerWidth;
      y = self.innerHeight;
    }
    else if (document.documentElement && document.documentElement.clientHeight) {
      x = document.documentElement.clientWidth;
      y = document.documentElement.clientHeight;
    }
    else if (document.body) {
      x = document.body.clientWidth;
      y = document.body.clientHeight;
    }
    return [ x, y ];
  };
  Position.pageSize = function() {
    var x, y;
    var test1 = document.body.scrollHeight;
    var test2 = document.body.offsetHeight
    if (test1 > test2) {
      x = document.body.scrollWidth;
      y = document.body.scrollHeight;
    }
    else {
      x = document.body.offsetWidth;
      y = document.body.offsetHeight;
    }
    return [ x, y ];
  };
  Event.createEvent = function(type, bubbles, cancelable, windowObject, detail, screenX, screenY,
      clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget) {
    var evObj;
    if (document.createEvent) {
      if (screenX || type == "click") {
        evObj = document.createEvent("MouseEvents");
        evObj.initMouseEvent(type, bubbles, cancelable, windowObject, detail, screenX, screenY,
            clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget);
      }
      else if (windowObject) {
        evObj = document.createEvent("UIEvents");
        evObj.initUIEvent(type, bubbles, cancelable, windowObject, detail);
      }
      else {
        evObj = document.createEvent("HTMLEvents");
        evObj.initEvent(type, bubbles, cancelable);
      }
    }
    else if (document.createEventObject) {
      evObj = document.createEventObject();
      evObj.detail = detail;
      evObj.screenX = screenX;
      evObj.screenY = screenY;
      evObj.clientX = clientX;
      evObj.clientY = clientY;
      evObj.ctrlKey = ctrlKey;
      evObj.altKey = altKey;
      evObj.shiftKey = shiftKey;
      evObj.metaKey = metaKey;
      evObj.button = button;
      evObj.relatedTarget = relatedTarget;
    }
    return evObj;
  };
  Event.fireEvent = function(element, type, bubbles, cancelable, windowObject, detail, screenX,
      screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget) {
    if (element.isDatagrid && type == "change") element._changeEvents.each( function(item) {
      item();
    });
    else {
      if (element.tagName == "INPUT"
          && (element.type == "radio" || element.type == "checkbox" && Prototype.Browser.IE)
          && type == "change") type = "click";
      var evObj = Event.createEvent(type, bubbles, cancelable, windowObject, detail, screenX,
          screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget);
      if (document.createEvent) {
        element.dispatchEvent(evObj);
      }
      else if (document.createEventObject) {
        element.fireEvent("on" + type, evObj);
      }
    }
  };
  Function.prototype.bindArgs = function() {
    return this.bind.apply(this, [ window ].concat($A(arguments)));
  };
  Array.prototype.remove = function(index) {
    return this.splice(index, 1);
  };
  Array.prototype.removeValue = function(value) {
    return this.splice(this.indexOf(value), 1);
  };
  Array.prototype.contains = function(value) {
    return this.indexOf(value) != -1;
  };
  Array.prototype.select = function(expression) {
    var res = [];
    for ( var i = 0; i < this.length; i++)
      if (eval("(function () { with (this) { return " + expression + "; } }.bind(this[i]))()")) res
          .push(this[i]);
    return res;
  };
  Array.prototype.selectFirst = function(expression) {
    var res = [];
    for ( var i = 0; i < this.length; i++)
      if (eval("(function () { with (this) { return " + expression + "; } }.bind(this[i]))()")) return this[i];
    return null;
  };
  Array.prototype.insert = function(element, index) {
    if (index > this.length || index < 0) index = this.length;
    for ( var i = this.length; i > index; i--)
      this[i] = this[i - 1];
    this[index] = element;
  };
  Array.prototype.insertAll = function(elements, index) {
    elements = $A(elements);
    if (index > this.length || index < 0) index = this.length;
    var i;
    for (i = this.length - 1; i >= index; i--)
      this[i + elements.length] = this[i];
    for (i = 0; i < elements.length; i++)
      this[i + index] = elements[i];
  };
  Array.prototype.pushAll = function(elements) {
    this.insertAll(elements, -1);
  };
  Array.prototype.sortIgnoreCase = function() {
    this.sort( function(x, y) {
      var a = String(x).toUpperCase();
      var b = String(y).toUpperCase();
      return a > b? 1: a < b? -1: 0;
    });
  };
  String.prototype.contains = function(value) {
    return this.indexOf(value) != -1;
  };
  String.prototype.substringBefore = function(str) {
    var index = this.indexOf(str);
    return index == -1? "": this.substring(0, index);
  };
  String.prototype.substringAfter = function(str) {
    var index = this.indexOf(str);
    return index == -1? "": this.substring(index + 1);
  };
  String.prototype.leftPad = function(size, char) {
    return Array(size - this.length + 1).join(char) + this;
  };
  Event.observe(window, "load", function() {
    Event.observe(document, "keypress", ibre._methods.documentKeyPress);
    Event.observe(document, "click", ibre._methods.windowClick);
    document.head = document.getElementsByTagName("head")[0];
    var scripts = document.getElementsByTagName("script");
    var commonFile = "1ibre.js";
    for ( var i = 0; i < scripts.length; i++) {
      var src = scripts[i].src;
      if (src) {
        var pos = src.indexOf("?");
        if (pos != -1) src = src.substring(0, pos);
        if (src.endsWith(commonFile)) {
          ibre.basePath = src.substring(0, src.length - commonFile.length);
          break;
        }
      }
    }
    ibre._defaultCSS = Element.styleSheet(Element.build("link", {
      type :"text/css",
      rel :"stylesheet",
      href :ibre.basePath + "1ibre.css"
    }, null, document.head));
    ibre.initParse(document.documentElement);
    ibre._util.loadListeners.each( function(item) {
      item();
    });
    ibre._util.loadListeners = [];
    /*Event.observe(document.body, "click", function(event) {
      if (event.ctrlKey && event.altKey && event.shiftKey) {
        if (!ibre.console) ibre.console = open(ibre.basePath + "console.html", "console1ibre",
            "menubar=no,width=600,height=500");
        ibre.console.focus();
      }
    });*/
  });
  ibre = {
    _cacheUris : {},
    elements : {},
    initParse : function(element, self) {
      var _pendingEvents = ibre._pendingEvents;
      ibre._pendingEvents = [];
      if (self) ibre.parse(element);
      else ibre.parseChilds(element);
      ibre._pendingEvents.each( function(item) {
        Event.observe(item.input, "change", item.handler);
      });
      ibre._pendingEvents = _pendingEvents;
    },
    parse : function(element, vars) {
      if (ibre.parseChild(element, element, vars) === false) ibre.parseChilds(element, vars);
    },
    parseChilds : function(element, vars) {
      var child = Node.nextDescendantOnTree(element, element);
      while (child) {
        var res = ibre.parseChild(child, element, vars);
        child = res === false? Node.nextDescendantOnTree(child, element): res;
      }
    },
    parseChild : function(node, root, vars) {
      var carry = false;
      if (node.nodeType == Node.ELEMENT_NODE) {
        var elements;
        var i;
        if (node.getAttribute("ignore") != null) return Node.nextSiblingOnTree(node, root);
        var parse = node.getAttribute("parse");
        if (parse != null) {
          ibre._methods.evalHandler("[" + parse + "]", node).flatten().each( function(item) {
            ibre.parse(item);
          });
          return Node.nextSiblingOnTree(node, root);
        }
        var forEachValue = node.getAttribute("for-each");
        if (!forEachValue) {
          var isDinamic = false;
          node.dinamicAttrs = [];
          for (i = 0; i < node.attributes.length; i++) {
            var attr = node.attributes[i];
            if (attr.nodeValue && typeof attr.nodeValue == "string") {
              var attrValue = attr.nodeValue;
              if (node.tagName == "IMG" && attr.name == "src") attrValue = unescape(attrValue);
              var result = ibre._methods.parseText(attrValue, node, vars);
              if (result != null) {
                if (!node.attrs) node.attrs = {};
                node.dinamicAttrs.push( {
                  name :attr.name,
                  value :attr.nodeValue
                });
                Attr.set(node, attr.name, result);
                if (!isDinamic) isDinamic = true;
              }
            }
          }
          if (isDinamic) {
            node.vars = vars || {};
            if (node.tagName != "FORM") {
              elements = node.getAttribute("elements");
              var f = ibre._methods.updateDinamicAttr.bind(node);
              if (elements) ibre._methods.evalHandler("[" + elements + "]", node).flatten().each(
                  function(item) {
                    Event.observe(item, "change", f);
                  });
            }
          }
        }
        if (node.id) document.elementsById[node.id] = node;
        if (forEachValue) {
          node.vars = vars || {};
          node.items = [];
          if (node.getAttribute("cache") != null) {
            node._cache = true;
            node.removeAttribute("cache");
          }
          elements = node.getAttribute("elements");
          node.evalForEach = ibre._methods.forEachInputChange.bind(node);
          ibre._methods.checkEventHandler(node, "received");
          if (elements) ibre._methods.evalHandler("[" + elements + "]", node).flatten().each(
              function(item) {
                Event.observe(item, "change", node.evalForEach);
              });
          node._refNode = document.createTextNode("");
          node.parentNode.replaceChild(node._refNode, node);
          node.evalForEach();
          return Node.nextSiblingOnTree(node._refNode, root);
        }
        var ifValue = node.getAttribute("if");
        if (ifValue != null) {
          node.vars = vars || {};
          elements = node.getAttribute("elements");
          node.removeAttribute("if");
          node.removeAttribute("elements");
          node.evalIf = ibre._methods.ifInputChange.bind(node);
          if (elements) ibre._methods.evalHandler("[" + elements + "]", node).flatten().each(
              function(item) {
                Event.observe(item, "change", node.evalIf);
              });
          var next = Element.next(node);
          if (next && next.getAttribute("else") != null) {
            node.elseNode = node._refNode = next;
            ibre.parse(next, vars);
            if (Element.parentElement(next)) next.remove();
          }
          else node._refNode = document.createTextNode("");
          carry = Node.nextSiblingOnTree(node, root);
          ibre.parse(node, vars);
          node.ifValue = ifValue;
          if (node.getAttribute("else") == null) node.evalIf();
          return carry;
        }
        var visibleWhen = node.getAttribute("visible-when");
        if (visibleWhen != null) {
          node.vars = vars || {};
          elements = node.getAttribute("elements");
          node.removeAttribute("visible-when");
          node.removeAttribute("elements");
          var funct = ibre._methods.visibleWhenInputChange.bind(node);
          if (elements) ibre._methods.evalHandler("[" + elements + "]", node).flatten().each(
              function(item) {
                Event.observe(item, "change", funct);
              });
          node.visibleWhen = visibleWhen;
          funct();
        }
        var repeat = node.getAttribute("repeat");
        if (repeat == "template") {
          node.repetitionBlocks = [];
          var prev = Element.previous(node);
          if (prev && typeof prev.repetitionIndex == "number") {
            node.repetitionIndex = prev.repetitionIndex + 1;
            do {
              node.repetitionBlocks.insert(prev, 0);
              prev.repetitionTemplate = node;
              prev = Element.previous(prev);
            } while (prev && typeof prev.repetitionIndex == "number");
          }
          else node.repetitionIndex = 0;
          node._refNode = document.createTextNode("");
          node.parentNode.replaceChild(node._refNode, node);
          if (node.id) ibre.elements[node.id] = document.templates[node.id] = node;
          node.addRepetitionBlock = ibre._methods.templateAddRepetitionBlock.bind(node);
          node.removeRepetitionBlocks = ibre._methods.templateRemoveRepetitionBlocks.bind(node);
          ibre._methods.checkEventHandler(node, "add");
          return Node.nextSiblingOnTree(node._refNode, root);
        }
        else if (repeat) {
          node.repetitionIndex = repeat * 1;
          node.removeRepetitionBlock = ibre._methods.templateRemoveRepetitionBlock;
          node.moveRepetitionBlock = ibre._methods.templateMoveRepetitionBlock;
        }
        var hover = node.getAttribute("hover");
        if (hover != null) {
          Event.observe(node, "mouseover", ibre._methods.hoverMouseOver);
          Event.observe(node, "mouseout", ibre._methods.hoverMouseOut);
        }
        if (node.getAttribute("checked-class")) {
          node.inputRef = Element.select(node, "input[type=radio]", "input[type=checkbox]")[0];
          Event.observe(node, "click", ibre._methods.checkedClick);
          ibre._pendingEvents.push( {
            input :node.inputRef,
            handler :ibre._methods.checkedChange.bind(node)
          });
        }
        if (node.tagName != "A" && node.tagName != "LINK" && node.tagName != "IMG") {
          var href = node.getAttribute("href");
          if (href != null) {
            Event.observe(node, "click", ibre._methods.hrefClick);
            node.style.cursor = "pointer";
          }
        }
        var tag = node.getAttribute("tag");
        if (tag != null) {
          node.removeAttribute("tag");
          var handlerTag = _handlersTags[tag];
          if (handlerTag) {
            var carryRes = handlerTag(node, root, vars);
            if (carryRes !== undefined) carry = carryRes;
          }
        }
        if (node.getAttribute("draggable") == "true") {
          ibre._methods.checkEventHandler(node, "dragstart");
          ibre._methods.checkEventHandler(node, "drag", [ "droppable" ]);
          ibre._methods.checkEventHandler(node, "dragend", [ "droppable" ]);
          var revert = false;
          node.droppables = node.getAttribute("droppables");
          if (node.droppables != null) {
            revert = true;
            var dragClassName = ibre.makeId();
            Element.addClassName(node, dragClassName);
            node.droppables.split(" ").each( function(className) {
              $$("." + className).each( function(item) {
                Droppables.add(item, {
                  accept :dragClassName,
                  hoverclass :node.getAttribute("hoverclass"),
                  onDrop :node.ondragend? ibre._methods.draggableDrop: null,
                  onHover :node.ondrag? ibre._methods.draggableHover: null
                });
              });
            });
          }
          var draggables = node.getElementsByClassName? node.getElementsByClassName("draggable")
              : Element.getElementsByClassName(node, "draggable");
          if (!draggables.length) Element.addClassName(node, "draggable");
          var draggable = new Draggable(node, {
            handle :"draggable",
            ghosting :!revert,
            revert :revert
          });
          var events = {};
          if (node.ondragstart) events.onStart = ibre._methods.draggableDragStart.bind(node,
              draggable);
          if (!node.droppables) {
            if (node.ondrag) events.onDrag = ibre._methods.draggableDrag.bind(node, draggable);
            if (node.ondragend) events.onEnd = ibre._methods.draggableDragEnd.bind(node, draggable);
          }
          if (node.ondragstart || events.ondrag || node.ondragend) Draggables.addObserver(events);
        }
        if (Element.hasClassName(node, "draggable")) {
          var popup = Popup.getParentPopup(node);
          if (popup) {
            if (popup._draggable) {
              popup._draggable.destroy();
              popup._draggableElement.style.cursor = "";
            }
            var table = popup._draggableTable;
            popup._draggable = new Draggable(table, {
              handle :"draggable"
            });
            var draggables = table.getElementsByClassName? table
                .getElementsByClassName("draggable"): Element.getElementsByClassName(table,
                "draggable");
            popup._draggableElement = draggables.length? draggables[0]: table;
          }
        }
        var handler = _handlers[node.tagName];
        if (handler) {
          var carryRes = handler(node, root, vars);
          if (carryRes !== undefined) carry = carryRes;
        }
        if (Element.isFormElement(node)) {
          node.required = node.getAttribute("required") != null;
          if (node.required) Element.addClassName(node, "required");
          ibre._methods.checkEventHandler(node, "validate");
          node.checkValidity = ibre._methods.checkValidity;
          node.validity = {
            valid :true
          };
          Event.observe(node, "change", node.checkValidity.bind(node));
          node.checkValidity();
          if (Prototype.Browser.IE) {
            ibre._methods.checkEventHandler(node, "input");
            if (node.oninput) {
              Event.observe(node, "focus", ibre._methods.elementInputFocus.bind(node));
              Event.observe(node, "blur", ibre._methods.elementInputBlur.bind(node));
            }
          }
          if (node.getAttribute("autofocus") != null) {
            var popup = Popup.getParentPopup(node);
            if (popup) popup.firstActive = node;
            else node.focus();
          }
          ibre._methods.checkDisabledWhen(node, vars);
        }
        ibre._methods.checkEventHandler(node, "parse");
        if (node.onparse) setTimeout( function() {
          node.onparse();
        }, 1);
        if (carry === false && node.getAttribute("ignore-childs") != null) return Node
            .nextSiblingOnTree(node, root);
      }
      else {
        if (node.parentNode.tagName != "TEXTAREA") {
          var result = ibre._methods.parseText(node.nodeValue, node.parentNode, vars);
          if (result != null) {
            if (!node.parentNode.isDinamic) {
              node.parentNode.dinamicTexts = [];
              node.parentNode.isDinamic = true;
              node.parentNode.vars = Object.extend(node.parentNode.vars || {}, vars || {});
              elements = node.parentNode.getAttribute("elements");
              var f = ibre._methods.updateDinamicText.bind(node.parentNode);
              if (elements) ibre._methods.evalHandler("[" + elements + "]", node.parentNode)
                  .flatten().each( function(item) {
                    Event.observe(item, "change", f);
                  });
            }
            node.parentNode.dinamicTexts.push( {
              node :node,
              text :node.nodeValue
            });
            node.nodeValue = result;
          }
        }
      }
      return carry;
    },
    _xslts : {},
    _methods : {
      draggableDrop : function(node, droppable, event) {
        node.ondragend(droppable, event);
      },
      draggableHover : function(node, droppable, overlap, event) {
        node.ondrag(droppable, event);
      },
      calendarUpdate : function name() {
        Event.fireEvent(this, "change");
      },
      splitterMouseUp : function() {
        if (!this.active) return;
        this.active = false;
      },
      splitterMouseDown : function(event) {
        this.active = true;
        if (this.isVertical) {
          this._pointerX = Event.pointerX(event);
          this._originalWidth1 = Element
              .getWidth(this.parentNode.cells[this.cellIndex - 1].firstChild);
          this._originalWidth2 = Element
              .getWidth(this.parentNode.cells[this.cellIndex + 1].firstChild);
        }
        else {
          this._pointerY = Event.pointerY(event);
          this._originalHeight1 = Element
              .getHeight(this.parentNode.rows[this.rowIndex - 1].firstChild);
          this._originalHeight2 = Element
              .getHeight(this.parentNode.rows[this.rowIndex + 1].firstChild);
        }
      },
      splitterMouseMove : function(event) {
        if (!this.active) return;
        if (this.isVertical) {
          var offset = Event.pointerX(event) - this._pointerX;
          var cells = this.parentNode.cells;
          var parent1 = cells[this.cellIndex - 1];
          var child1 = parent1.firstChild;
          var parent2 = cells[this.cellIndex + 1];
          var child2 = parent2.firstChild;
          if (this._originalWidth1 + offset < this.minWidth1) offset = this.minWidth1
              - this._originalWidth1;
          else if (this._originalWidth2 - offset < this.minWidth2) offset = this._originalWidth2
              - this.minWidth2;
          parent1.style.width = child1.style.width = (this._originalWidth1 + offset) + "px";
          parent2.style.width = child2.style.width = (this._originalWidth2 - offset) + "px";
        }
        else {
          var offset = Event.pointerY(event) - this._pointerY;
          var cells = this.parentNode.rows;
          var parent1 = rows[this.rowIndex - 1];
          var child1 = parent1.cells[0].firstChild;
          var parent2 = rows[this.rowIndex + 1];
          var child2 = parent2.cells[0].firstChild;
          if (this._originalHeight1 + offset < this.minHeight1) offset = this.minHeight1
              - this._originalHeight1;
          else if (this._originalHeight2 - offset < this.minHeight2) offset = this._originalHeight2
              - this.minHeight2;
          parent1.style.height = child1.style.height = (this._originalHeight1 + offset) + "px";
          parent2.style.height = child2.style.height = (this._originalHeight2 - offset) + "px";
        }
        Event.stop(event);
        document.clearSelection();
      },
      clickFilter : function(cell) {
        if (!cell._filterableElement) {
          cell._filterableElement = Element.build("div", {
            style : {
              position :"absolute"
            },
            onclick : function(event) {
              Event.stop(event);
            }.bindAsEventListener(),
            className :"popup-filterable"
          }, {
            tagName :"table",
            attrs : {
              width :"100%"
            },
            children : {
              tagName :"tbody",
              children : {
                tagName :"tr",
                children : [ {
                  tagName :"td",
                  children : {
                    tagName :"div",
                    attrs : {
                      className :"popup-items-filterable"
                    },
                    children : {
                      tagName :"table",
                      attrs : {
                        width :"100%"
                      },
                      children : {
                        tagName :"tbody",
                        children : {
                          tagName :"tr",
                          attrs : {
                            className :"datagrid-filter-all"
                          },
                          children : {
                            tagName :"td",
                            attrs : {
                              onclick :ibre._methods.datagridFilter.bind(cell, null, false),
                              onmouseover : function() {
                                Element.addClassName(this, "datagrid-item-filter-hover");
                              },
                              onmouseout : function() {
                                Element.removeClassName(this, "datagrid-item-filter-hover");
                              }
                            },
                            children :ibre.labels.filterAll
                          }
                        }
                      }
                    }
                  }
                }, {
                  tagName :"td",
                  attrs : {
                    className :"drag-filterable draggable"
                  },
                  children : {
                    tagName :"img",
                    attrs : {
                      src :ibre.basePath + "images/spacer.gif",
                      className :"drag-filterable"
                    }
                  }
                } ]
              }
            }
          }, cell);
          var trs = cell._filterableElement.firstChild.rows[0].cells[0].firstChild.firstChild.firstChild;
          new Draggable(cell._filterableElement, {
            handle :"draggable"
          });
          if (Element.hasClassName(cell, "searchable")) {
            var tr = Element
                .build(
                    "tr",
                    null,
                    {
                      tagName :"td",
                      children : {
                        tagName :"input",
                        attrs : {
                          style : {
                            width :"100%"
                          },
                          oninput : function() {
                            (ibre._methods.datagridFilter.bind(cell))(this.value == ""? null
                                : this.value, true);
                          },
                          onkeypress : function(event) {
                            if (event.keyCode == Event.KEY_RETURN) {
                              Event.stop(event);
                              Element.hide(document.activeLayer);
                              document.activeLayer = null;
                              this._currentFilter = Element.down(this._filterableElement, "input").value;
                              this._currentPartial = true;
                            }
                            else if (event.keyCode == Event.KEY_ESC) {
                              (ibre._methods.datagridFilter.bind(cell))(this._currentFilter,
                                  this._currentPartial);
                              setTimeout(
                                  function() {
                                    Element.down(this._filterableElement, "input").value = this._currentPartial? this._currentFilter
                                        : "";
                                  }.bind(this), 10);
                            }
                          }.bindAsEventListener(cell),
                          value :cell._currentPartial? cell._currentFilter: ""
                        }
                      }
                    }, trs);
            Event
                .observe(trs.rows[1].cells[0].firstChild, "focus", ibre._methods.elementInputFocus);
            Event.observe(trs.rows[1].cells[0].firstChild, "blur", ibre._methods.elementInputBlur);
          }
          if (Element.hasClassName(cell, "filterable")) {
            var options = [];
            var keys = {};
            var j, k, rows;
            var tBodies = cell.parentNode.parentNode.parentNode.tBodies;
            for (j = 0; j < tBodies.length; j++) {
              rows = tBodies[j].rows;
              for (k = 0; k < rows.length; k++) {
                var row = rows[k];
                if (!row.activeFilters) row.activeFilters = [];
                var key = row.cells[cell.cellIndex].innerHTML.toLowerCase().strip();
                if (key == "") continue;
                if (keys[key]) {
                  keys[key]++;
                  continue;
                }
                keys[key] = 1;
                options.push(row.cells[cell.cellIndex].cloneNode(true));
              }
            }
            options.sort( function(v1, v2) {
              v1 = v1.innerHTML.toString().strip();
              v2 = v2.innerHTML.toString().strip();
              if (v1 == v2) return 0;
              if (v1 < v2) return -1;
              return 1;
            });
            for (j = 0; j < options.length; j++)
              Element.build("tr", {
                className :"datagrid-item-filter",
                onmouseover : function() {
                  Element.addClassName(this, "datagrid-item-filter-hover");
                },
                onmouseout : function() {
                  Element.removeClassName(this, "datagrid-item-filter-hover");
                }
              }, {
                tagName :"td",
                attrs : {
                  onclick :ibre._methods.datagridFilter.bind(cell, options[j].innerHTML, false)
                },
                children :options[j].childNodes
              }, trs);
          }
        }
        else if (document.activeLayer == cell._filterableElement) {
          Element.hide(document.activeLayer);
          document.activeLayer = null;
          return;
        }
        else {
          cell._filterableElement.style.left = "";
          cell._filterableElement.style.top = "";
        }
        if (Element.hasClassName(cell, "searchable")) {
          setTimeout(
              function() {
                this.focus();
              }
                  .bind(cell._filterableElement.firstChild.rows[0].cells[0].firstChild.firstChild.rows[1].cells[0].firstChild),
              10);
        }
        if (document.activeLayer) Element.hide(document.activeLayer);
        Element.show(cell._filterableElement);
        document.activeLayer = cell._filterableElement;
      },
      treeDelNode : function() {
        if (this.tree.currentNode == this) this.tree.currentNode = null;
        for ( var i = this.nodes.length - 1; i >= 0; i--)
          this.nodes[i].delNode();
        Element.remove(this._row);
        this.parent.nodes.removeValue(this);
        if (this.parent._row && !this.parent.nodes.length) {
          this.parent.opened = true;
          this.parent._row.cells[0].firstChild.rows[0].cells[this.parent.level > 1? 1: 0].firstChild.src = ibre.basePath
              + "images/spacer.gif";
        }
      },
      treeMoveNode : function(parent, index) {
        this.parent.nodes.removeValue(this);
        if (index == undefined || index < 0 || index > parent.nodes.length) index = parent.nodes.length;
        if (parent != this.parent) {
          if (this.parent._row && !this.parent.nodes.length) {
            this.parent.opened = true;
            this.parent._row.cells[0].firstChild.rows[0].cells[this.parent.level > 1? 1: 0].firstChild.src = ibre.basePath
                + "images/spacer.gif";
          }
          this.parent = parent;
          if (this.level != parent.level + 1) {
            this.level = parent.level + 1;
            var level = function(node) {
              for ( var i = 0; i < node.nodes.length; i++) {
                node.nodes[i].level = node.level + 1;
                level(node.nodes[i]);
              }
            };
            level(this);
          }
          if (parent._row && !parent.nodes.length) {
            var img = parent._row.cells[0].firstChild.rows[0].cells[parent.level > 1? 1: 0].firstChild;
            img.src = ibre.basePath + "images/minus.gif";
            img.style.width = "auto";
            img.style.height = "auto";
          }
          var p = parent;
          var hide = false;
          while (p._row) {
            if (!p.opened) {
              hide = true;
              break;
            }
            p = p.parent;
          }
          if (hide) Element.hide(this._row);
        }
        var parentN = this.tree._table.tBodies[0];
        var brother = null;
        if (parent.nodes[index]) brother = parent.nodes[index]._row;
        if (!brother) {
          var item = parent;
          while (item.parent) {
            var next = item.parent.nodes[item.parent.nodes.indexOf(item) + 1];
            if (next) {
              brother = next._row;
              break;
            }
            item = item.parent;
          }
        }
        var childs = function(node) {
          var res = [];
          for ( var i = 0; i < node.nodes.length; i++) {
            res.push(node.nodes[i]._row);
            res.pushAll(childs(node.nodes[i]));
          }
          return res;
        };
        var i;
        var trs = childs(this);
        if (brother) {
          parentN.insertBefore(this._row, brother);
          for (i = 0; i < trs.length; i++)
            parentN.insertBefore(trs[i], brother);
        }
        else {
          parentN.appendChild(this._row);
          for (i = 0; i < trs.length; i++)
            parentN.appendChild(trs[i]);
        }
        parent.nodes.insert(this, index);
      },
      treeExpandAll : function() {
        if (this.nodes.length) {
          if (this._row && !this.opened) this.toogle();
          this.nodes.invoke("expandAll");
        }
      },
      treeCollapseAll : function() {
        if (this.nodes.length) {
          if (this._row && this.opened) this.toogle();
          this.nodes.invoke("collapseAll");
        }
      },
      treeDblClick : function() {
        document.clearSelection();
        this.toogle();
      },
      treeAddNode : function(label, value, icon, columns, index) {
        if (index == undefined || index < 0 || index > this.nodes.length) index = this.nodes.length;
        var node = {
          addNode :ibre._methods.treeAddNode,
          moveNode :ibre._methods.treeMoveNode,
          delNode :ibre._methods.treeDelNode,
          expandAll :ibre._methods.treeExpandAll,
          collapseAll :ibre._methods.treeCollapseAll,
          nodes : [],
          parent :this,
          level :this.level + 1,
          tree :this.tree,
          opened :true,
          value :value,
          label :label,
          icon :icon,
          columns :$A(columns),
          nodeType :Node.ELEMENT_NODE,
          tagName :"TREEROW"
        };
        if (this._row && !this.nodes.length) {
          var img = this._row.cells[0].firstChild.rows[0].cells[this.level > 1? 1: 0].firstChild;
          img.src = ibre.basePath + "images/minus.gif";
          img.style.width = "auto";
          img.style.height = "auto";
        }
        node.select = ibre._methods.selectTree.bind(node);
        node.toogle = ibre._methods.toogleTree.bind(node);
        node._toogle = ibre._methods.toogleTreeChildren.bind(node);
        var tds = [];
        if (!this._table) tds.push( {
          tagName :"td",
          attrs : {
            width :(node.level - 1) * 18
          },
          children : {
            tagName :"img",
            attrs : {
              src :ibre.basePath + "images/spacer.gif",
              onclick :node.toogle,
              width :(node.level - 1) * 18,
              height :1
            }
          }
        });
        tds.push( {
          tagName :"td",
          attrs : {
            width :18
          },
          children : {
            tagName :"img",
            attrs : {
              src :ibre.basePath + "images/spacer.gif",
              onclick :node.toogle,
              width :18,
              height :1
            }
          }
        });
        if (icon) tds.push( {
          tagName :"td",
          children : {
            tagName :"img",
            attrs : {
              src :icon
            }
          }
        });
        tds.push( {
          tagName :"td",
          attrs : {
            hover :"tree-hover",
            onmouseover :ibre._methods.hoverMouseOver,
            onmouseout :ibre._methods.hoverMouseOut,
            onclick :node.select,
            ondblclick :ibre._methods.treeDblClick.bind(node),
            className :"tree-node"
          },
          children :label
        });
        tds = [ {
          tagName :"td",
          children : {
            tagName :"table",
            attrs : {
              cellpadding :1,
              cellspacing :0
            },
            children : {
              tagName :"tbody",
              children : {
                tagName :"tr",
                children :tds
              }
            }
          }
        } ];
        node.columns.each( function(item) {
          tds.push( {
            tagName :"td",
            children :item
          });
        });
        node._row = Element.build("tr", null, tds);
        var p = this;
        var hide = false;
        while (p._row) {
          if (!p.opened) {
            hide = true;
            break;
          }
          p = p.parent;
        }
        if (hide) Element.hide(node._row);
        var parent = this.tree._table.tBodies[0];
        var brother = null;
        if (this.nodes[index]) brother = this.nodes[index]._row;
        if (!brother) {
          var item = this;
          while (item.parent) {
            var next = item.parent.nodes[item.parent.nodes.indexOf(item) + 1];
            if (next) {
              brother = next._row;
              break;
            }
            item = item.parent;
          }
        }
        if (brother) parent.insertBefore(node._row, brother);
        else parent.appendChild(node._row);
        this.nodes.insert(node, index);
        return node;
      },
      toogleTreeChildren : function(method) {
        this.nodes.each( function(item) {
          Element[method](item._row);
          if (item.opened) item._toogle(method);
        });
      },
      toogleTree : function() {
        if (this.nodes.length) {
          this.opened = !this.opened;
          this._row.cells[0].firstChild.rows[0].cells[this.level > 1? 1: 0].firstChild.src = ibre.basePath
              + "images/" + (this.opened? "minus.gif": "plus.gif");
          this._toogle(this.opened? "show": "hide");
        }
      },
      selectTree : function() {
        var tree = this.tree;
        if (this != tree.currentNode) {
          var cells;
          if (tree.currentNode) {
            cells = tree.currentNode._row.cells[0].firstChild.rows[0].cells;
            Element.removeClassName(cells[cells.length - 1], "tree-selected");
          }
          tree.currentNode = this;
          cells = this._row.cells[0].firstChild.rows[0].cells;
          Element.addClassName(cells[cells.length - 1], "tree-selected");
          if (tree.onchange) tree.onchange();
        }
      },
      meCheckAllInputChange : function() {
        var me = this;
        this._updating = true;
        this.elements.each( function(item) {
          if (Element.isVisible(item)) Node.setAttribute(item, "checked", me.checked);
        });
        this._updating = false;
      },
      checkAllInputChange : function() {
        if (this._updating) return;
        var check = false;
        for ( var i = 0; i < this.elements.length; i++) {
          var item = this.elements[i];
          if (!Element.isVisible(item)) continue;
          if (!item.checked) {
            if (this.checked) this.checked = false;
            return;
          }
          if (!check) check = true;
        }
        if (!this.checked) this.checked = check;
      },
      datagridFirstPage : function() {
        this.go(0);
      },
      datagridPrevPage : function() {
        this.go(this.position - this.length);
      },
      datagridNextPage : function() {
        this.go(this.position + this.length);
      },
      datagridLastPage : function() {
        this.go((Math.ceil(this.dataRows().length / this.length) - 1) * this.length);
      },
      datagridGoPage : function(index) {
        this.go(this.length * index);
      },
      datagridGo : function(index) {
        var rows = this.dataRows();
        if (index >= rows.length) return;
        if (index < 0) index = 0;
        var n = Math.min(this.position + this.length, rows.length);
        var i;
        for (i = this.position; i < n; i++)
          Element.hide(rows[i]);
        this.position = index;
        n = Math.min(this.position + this.length, rows.length);
        for (i = this.position; i < n; i++)
          Element.show(rows[i]);
        Event.fireEvent(this, "change");
        if (this.rememberState) ibre.cookie.set("_1ibre_position_" + datagrid.id, index);
      },
      datagridRows : function() {
        return $A(this.tBodies).collect( function(item) {
          return $A(item.rows).findAll( function(item) {
            return !item.activeFilters || !item.activeFilters.length;
          });
        }).flatten();
      },
      cellToggleSortState : function(event) {
        if (!Element.isFormElement(Event.element(event))) this.parentNode.parentNode.parentNode
            .toggleSortState(this.cellIndex);
      },
      datagridResizableDblClick : function() {
        var max = 0;
        var parent = this.parentNode.parentNode.parentNode;
        var rows = parent.rows;
        for ( var k = 0; k < rows.length; k++) {
          if (!Element.isVisible(rows[k])) continue;
          var ele = Element.build("div", {
            style : {
              position :"absolute",
              display :"none",
              whiteSpace :"nowrap"
            }
          }, rows[k].cells[this.cellIndex - 1].cloneNode(true).childNodes,
              rows[k].cells[this.cellIndex - 1]);
          var width = Element.getWidth(ele);
          Element.remove(ele);
          if (width > max) max = width;
        }
        var previous = Element.previous(this);
        var prevWidth = Element.getWidth(previous);
        previous.style.width = max + "px";
        parent.style.width = (Element.getWidth(parent) + max - prevWidth) + "px";
      },
      datagridResizableMouseDown : function(event) {
        var previous = Element.previous(this);
        var width = previous.style.width.toString();
        width = width.substring(0, width.length - 2);
        var parent = this.parentNode.parentNode.parentNode;
        var width2 = parent.style.width.toString();
        width2 = width2.substring(0, width2.length - 2);
        this._offset = Event.pointerX(event) - width
        this._offsetTable = Event.pointerX(event) - width2;
        document.onmousemove = function(event) {
          previous.style.width = (Event.pointerX(event) - this._offset) + "px";
          this.parentNode.parentNode.parentNode.style.width = (Event.pointerX(event) - this._offsetTable)
              + "px";
          document.clearSelection();
        }.bindAsEventListener(this);
        document.onmouseup = function() {
          document.onmousemove = null;
          document.onmouseup = null;
          for (j = 0; j < parent.tBodies.length; j++) {
            rows = parent.tBodies[j].rows;
            for (k = 0; k < rows.length; k++)
              Element.removeClassName(rows[k].cells[this.cellIndex], "resizabling");
          }
        }.bind(this);
        for (j = 0; j < parent.tBodies.length; j++) {
          rows = parent.tBodies[j].rows;
          for (k = 0; k < rows.length; k++)
            Element.addClassName(rows[k].cells[this.cellIndex], "resizabling");
        }
      },
      datagridFilter : function(filterText, partial) {
        var datagrid = this.parentNode.parentNode.parentNode;
        var hasPages = datagrid.length > 0
            && datagrid.length < datagrid.rows.length - datagrid.tHead.rows.length
                - (datagrid.tFoot? datagrid.tFoot.rows.length: 0);
        if (datagrid.rememberState) {
          var cookieName = "_1ibre_filter_" + datagrid.id + (this.id? this.id: this.cellIndex);
          if (filterText) ibre.cookie.set(cookieName, (partial? "1": "0") + filterText);
          else ibre.cookie.remove(cookieName);
        }
        var table = Element.down(this);
        if (filterText != null) {
          table.rows[0].cells[1].innerHTML = filterText;
          Element.show(table.rows[0].cells[1]);
          filterText = filterText.toLowerCase();
        }
        else Element.hide(table.rows[0].cells[1]);
        if (!partial) {
          this._currentFilter = filterText;
          this._currentPartial = false;
          if (document.activeLayer) {
            Element.hide(document.activeLayer);
            document.activeLayer = null;
            if (Element.hasClassName(this, "searchable")) Element.down(this, "input").value = "";
          }
        }
        var index = this.cellIndex;
        var tBodies = this.parentNode.parentNode.parentNode.tBodies;
        var length = 0;
        for ( var i = 0; i < tBodies.length; i++) {
          var rows = tBodies[i].rows;
          for ( var j = 0; j < rows.length; j++) {
            var row = rows[j];
            if (!row.activeFilters) row.activeFilters = [];
            if (hasPages && !row.activeFilters.length) Element.show(row);
            var contains = row.activeFilters.contains(index);
            if (filterText != null
                && (partial && !row.cells[index].innerHTML.toLowerCase().contains(filterText) || !partial
                    && row.cells[index].innerHTML.toLowerCase() != filterText)) {
              if (!row.activeFilters.length) Element.hide(row);
              if (!contains) row.activeFilters.push(index);
            }
            else if (contains) {
              row.activeFilters.removeValue(index);
              if (!row.activeFilters.length) Element.show(row);
            }
            if (datagrid.length && !row.activeFilters.length && ++length > datagrid.length) Element
                .hide(row);
          }
        }
        datagrid.position = 0;
        Event.fireEvent(datagrid, "change");
      },
      tableToggleSortState : function(column) {
        var th = this.tHead.rows[0].cells[column];
        if (th.onsort && th.onsort() === false) return;
        var rows = this.dataRows();
        var i, n;
        if (this.length > 0 && this.length < rows.length) {
          n = Math.min(this.position + this.length, rows.length);
          for (i = this.position; i < n; i++)
            Element.hide(rows[i]);
        }
        if (th.sorted) th.reversed = !th.reversed;
        else {
          th.sorted = true;
          th.reversed = false;
        }
        var currentColumn = this.currentSortedColumn;
        if (currentColumn != th) {
          if (currentColumn) {
            currentColumn.sorted = false;
            currentColumn.reversed = false;
            for (i = 0; i < this.rows.length; i++) {
              Element.removeClassName(this.rows[i].cells[currentColumn.cellIndex], "sorted");
              Element.removeClassName(this.rows[i].cells[currentColumn.cellIndex], "reversed");
            }
          }
          this.currentSortedColumn = th;
        }
        for (i = 0; i < this.rows.length; i++) {
          Element.addClassName(this.rows[i].cells[column], "sorted");
          Element[th.reversed? "addClassName": "removeClassName"](this.rows[i].cells[column],
              "reversed");
        }
        var tBodies = this.tBodies;
        var sortColumnFunction;
        function getCellValue(row) {
          var cell = row.cells[column];
          var data = cell.getAttribute("value");
          return data == null? cell.innerHTML: data;
        }
        switch (th.getAttribute("type")) {
          case "number":
          case "currency":
            sortColumnFunction = function(r1, r2) {
              var d1 = parseFloat(getCellValue(r1));
              var d2 = parseFloat(getCellValue(r2));
              if (isNaN(d1)) d1 = 0;
              if (isNaN(d2)) d2 = 0;
              return th.reversed? d2 - d1: d1 - d2;
            };
            break;
          default:
            sortColumnFunction = function(r1, r2) {
              var d1 = getCellValue(r1).toLowerCase();
              var d2 = getCellValue(r2).toLowerCase();
              if (d1 == d2) return 0;
              if (d1 < d2) return th.reversed? 1: -1
              return th.reversed? -1: 1
            };
        }
        for (i = 0; i < tBodies.length; i++) {
          var tBody = tBodies[i];
          var list = $A(tBody.rows);
          list.sort(sortColumnFunction);
          for ( var j = 0; j < list.length; j++)
            tBody.appendChild(list[j]);
        }
        rows = this.dataRows();
        if (this.length > 0 && this.length < rows.length) {
          n = Math.min(this.position + this.length, rows.length);
          for (i = this.position; i < n; i++)
            Element.show(rows[i]);
        }
        if (this.rememberState) ibre.cookie.set("_1ibre_sorter_" + datagrid.id, (th.reversed? "1"
            : "0")
            + column);
      },
      checkDisabledWhen : function(node, vars) {
        var disabledWhen = node.getAttribute("disabled-when");
        if (disabledWhen != null) {
          node.vars = vars || {};
          var elements = node.getAttribute("elements");
          var funct = ibre._methods.disabledWhenInputChange.bind(node);
          if (elements) ibre._methods.evalHandler("[" + elements + "]", node).flatten().each(
              function(item) {
                Event.observe(item, "change", funct);
              });
          funct();
        }
      },
      switchActiveNext : function() {
        this.sections[this.activeSection.sectionIndex + 1].setActive();
      },
      switchActivePrevious : function() {
        this.sections[this.activeSection.sectionIndex - 1].setActive();
      },
      switchActiveFirst : function() {
        this.sections[0].setActive();
      },
      switchActiveLast : function() {
        this.sections[this.sections.length - 1].setActive();
      },
      switchAddSection : function(section, index) {
        if (index == undefined || index < 0 || index > this.sections.length) index = this.sections.length;
        section.parent = this;
        section.sectionIndex = index;
        section.setActive = ibre._methods.switchSectionSetActive;
        section.delSection = ibre._methods.switchDelSection;
        section.hide();
        var p = this.sections[0].parentNode;
        if (index < this.sections.length) p.insertBefore(section, this.sections[index]);
        else p.appendChild(section);
        this.sections.insert(section, index);
        var label = Element.down(section);
        if (label && label.getAttribute("tag") == "legend") {
          td = Element.build("td", {
            className :"switch-tab-nosel switch-tab",
            onclick :section.setActive.bind(section)
          }, label);
          section.tab = td;
          var vert = this.position == "left" || this.position == "right";
          if (vert) td = {
            tagName :"tr",
            children :td
          };
          var tabs = this.sections[0].tab.parentNode;
          if (vert) tabs = tabs.parentNode;
          tabs.insertBefore(td, Element.childElements(tabs)[index + 1]);
        }
        return section;
      },
      switchSectionSetActive : function() {
        var parent = this.parent;
        if (parent.activeSection != this) {
          var notIE = !Prototype.Browser.IE;
          if (notIE) this.parent.style.visibility = "hidden";
          parent.activeSection.hide();
          if (parent.activeSection.tab) {
            Element.addClassName(parent.activeSection.tab, "switch-tab-nosel");
            Element.removeClassName(parent.activeSection.tab, "switch-tab-sel");
          }
          parent.activeSection = parent.sections[this.sectionIndex];
          if (parent.activeSection.tab) {
            if (notIE) Element.hide(parent.activeSection.tab);
            Element.addClassName(parent.activeSection.tab, "switch-tab-sel");
            Element.removeClassName(parent.activeSection.tab, "switch-tab-nosel");
          }
          parent.activeSection.show();
          if (notIE) setTimeout( function() {
            if (this.parent.activeSection.tab) Element.show(this.parent.activeSection.tab);
            this.parent.style.visibility = "visible";
          }.bind(this), 1);
        }
      },
      switchDelSection : function() {
        var p = this.parent;
        if (p.activeSection == this) p.activePrevious();
        for ( var i = this.sectionIndex + 1; i < p.sections.length; i++)
          p.sections[i].sectionIndex = i - 1;
        p.sections.removeValue(this);
        if (this.tab) Element
            .remove(p.position == "left" || p.position == "right"? this.tab.parentNode: this.tab);
        Element.remove(this);
      },
      updateDinamicText : function() {
        for ( var i = 0; i < this.dinamicTexts.length; i++) {
          var text = this.dinamicTexts[i];
          text.node.nodeValue = ibre._methods.parseText(text.text, this, this.vars);
        }
      },
      updateDinamicAttr : function() {
        for ( var i = 0; i < this.dinamicAttrs.length; i++) {
          var attr = this.dinamicAttrs[i];
          Attr.set(this, attr.name, ibre._methods.parseText(attr.value, this, this.vars));
        }
      },
      parseText : function(text, element, vars) {
        if (text.indexOf("`") != -1) {
          var tokens = text.split("`");
          var result = tokens[0];
          for ( var i = 1; i < tokens.length; i++)
            if (i % 2) {
              var str = ibre._methods.evalHandler(tokens[i], element, vars);
              result += str == null? "": str;
            }
            else result += tokens[i];
          return result;
        }
        return null;
      },
      disabledWhenInputChange : function() {
        Node.setAttribute(this, "disabled", ibre._methods.evalHandler(this
            .getAttribute("disabled-when"), this, this.vars));
      },
      ifInputChange : function() {
        var parent = Element.parentElement(this);
        var noParent = !parent;
        var visible;
        if (noParent) {
          var elseNode = this;
          var refNode;
          do {
            refNode = elseNode._refNode;
            if (!refNode) return;
            parent = Element.parentElement(refNode);
            elseNode = elseNode.elseNode;
          } while (!parent && elseNode);
          if (!parent) return;
          visible = this.tagName != "OPTION" && Element.visible(this);
          if (visible) Element.hide(this);
          parent.replaceChild(this, refNode);
        }
        else visible = false;
        if (!ibre._methods.evalHandler(this.ifValue, this, this.vars)) {
          parent.replaceChild(this._refNode, this);
          if (!noParent && parent.tagName == "SELECT" && this.selected) Event.fireEvent(parent,
              "change");
        }
        else if (noParent && parent.tagName == "SELECT" && this.selected) Event.fireEvent(parent,
            "change");
        if (noParent && visible) Element.show(this);
      },
      visibleWhenInputChange : function() {
        Element[ibre._methods.evalHandler(this.visibleWhen, this, this.vars)? "show": "hide"](this);
      },
      forEachInputChange : function() {
        this.items.each( function(item) {
          if (!Element.parentElement(item)) return;
          var parent = item.parentNode;
          var index = item.index;
          Element.remove(item);
          if (item.tagName == "OPTION" && index == parent.selectedIndex) {
            parent.selectedIndex = parent.multiple? -1: 0;
            Event.fireEvent(parent, "change");
          }
        });
        this.items = [];
        var res = ibre._methods.evalHandler(this.getAttribute("for-each"), this, this.vars);
        var f = function(item, key) {
          var element = this.cloneNode(true);
          this.items.push(element);
          if (Prototype.Browser.IE && element.tagName == "OPTION") {
            element["for-each"] = "";
            element.item = "";
            element.key = "";
            element.id = "";
          }
          else {
            element.removeAttribute("for-each");
            element.removeAttribute("item");
            element.removeAttribute("key");
            element.removeAttribute("id");
          }
          this._refNode.parentNode.insertBefore(element, this._refNode);
          var itemName = this.getAttribute("item");
          if (itemName) this.vars[itemName] = item;
          var keyName = this.getAttribute("key");
          if (keyName) this.vars[keyName] = key;
          ibre.parse(element, this.vars);
        }.bind(this);
        var parse = true;
        if (res && res.datasource) {
          if (!this._cache || !ibre._cacheUris[res.datasource]) {
            if (this._cache) ibre._cacheUris[res.datasource] = [];
            parse = false;
            this._request = ibre.ajax.getJSON(res.datasource, function(uri, f, value) {
              this._request = null;
              if (this._cache) ibre._cacheUris[uri] = value;
              $A(value).each(f, this);
              var parent = this.items[0] && this.items[0].parentNode;
              if (Prototype.Browser.IE && parent && parent.tagName == "SELECT") {
                var up = parent.parentNode;
                var next = parent.nextSibling;
                Element.remove(parent);
                if (next) up.insertBefore(parent, next);
                else up.appendChild(parent);
              }
              if (this.onreceived) this.onreceived();
            }.bind(this, res.datasource, f), function() {
              this._request = null;
              if (this._cache) ibre._cacheUris[res.datasource] = null;
            }.bind(this));
          }
          else res = ibre._cacheUris[res.datasource];
        }
        if (parse) {
          $A(res).each(f, this);
          var parent = this.items[0] && this.items[0].parentNode;
          if (Prototype.Browser.IE && parent && parent.tagName == "SELECT") {
            var up = parent.parentNode;
            var next = parent.nextSibling;
            Element.remove(parent);
            if (next) up.insertBefore(parent, next);
            else up.appendChild(parent);
          }
          if (this.onreceived) this.onreceived();
        }
      },
      templateAddRepetitionBlock : function(node) {
        var index = ++this.repetitionIndex;
        var block = this.cloneNode(true);
        if (Prototype.Browser.IE) block.repeat = null;
        else block.removeAttribute("repeat");
        if (block.id) {
          var list = block.getElementsByTagName("*");
          var regex = new RegExp("\\[" + block.id + "\\]", "g");
          for ( var i = 0; i < list.length; i++) {
            $A(list[i].attributes).each(
                function(attr) {
                  if (typeof attr.nodeValue == "string"
                      && attr.nodeValue.contains("[" + block.id + "]")) Attr.set(list[i],
                      attr.name, attr.nodeValue.replace(regex, index));
                });
          }
          block.removeAttribute("id");
        }
        this._refNode.parentNode.insertBefore(block, this._refNode);
        ibre.initParse(block, true);
        block.removeRepetitionBlock = ibre._methods.templateRemoveRepetitionBlock;
        block.moveRepetitionBlock = ibre._methods.templateMoveRepetitionBlock;
        block.repetitionIndex = index;
        block.repetitionTemplate = this;
        this.repetitionBlocks.push(block);
        return block;
      },
      templateRemoveRepetitionBlocks : function() {
        var change = false;
        var parent;
        if (this.repetitionBlocks.length) {
          parent = this.repetitionBlocks[0].parentNode;
          if (parent.tagName == "SELECT") {
            for ( var i = 0; i < this.repetitionBlocks.length; i++)
              if (this.repetitionBlocks[i].selected) {
                change = true;
                break;
              }
          }
        }
        this.repetitionBlocks.each(Element.remove);
        this.repetitionBlocks = [];
        this.repetitionIndex = 0;
        if (change) Event.fireEvent(parent, "change");
      },
      templateRemoveRepetitionBlock : function() {
        var parent = this.parentNode;
        Element.remove(this);
        var blocks = this.repetitionTemplate.repetitionBlocks;
        blocks.splice(blocks.indexOf(this), 1);
        if (parent.tagName == "SELECT" && this.selected) Event.fireEvent(parent, "change");
      },
      addClick : function() {
        if (!this._nativeOnclick || this._nativeOnclick() !== false) {
          var element = document.templates[this.template].addRepetitionBlock(null);
          if (this.onadd) this.onadd( {
            element :element
          });
        }
      },
      removeClick : function() {
        if (!this._nativeOnclick || this._nativeOnclick() !== false) {
          var parent = this.parentNode;
          while (typeof parent.repetitionIndex != "number")
            parent = parent.parentNode;
          parent.removeRepetitionBlock();
        }
      },
      cancelClick : function() {
        if (!this._nativeOnclick || this._nativeOnclick() !== false) {
          var popup = Popup.getParentPopup(this);
          if (!popup.oncancel || popup.oncancel() !== false) popup.hidePopup();
        }
      },
      documentKeyPress : function(event) {
        if (event.keyCode == Event.KEY_ESC) {
          if (document.activeLayer) {
            Element.hide(document.activeLayer);
            document.activeLayer = null;
          }
          else if (document.activeMenu) {
            var menu = document.activeMenu;
            while (menu.activeElement)
              menu = menu.activeElement;
            menu.hideMenu();
          }
          else if (document.visiblePopups.length) {
            var popup = document.visiblePopups.last();
            if (!popup.oncancel || popup.oncancel() !== false) popup.hidePopup();
          }
        }
      },
      windowClick : function() {
        if (document.activeLayer) {
          Element.hide(document.activeLayer);
          document.activeLayer = null;
        }
        if (document.activeMenu) {
          document.activeMenu.hideMenu();
          document.activeMenu = null;
        }
      },
      commandClick : function(handler) {
        if (!this.disabled) {
          var result, error;
          try {
            if (handler) result = handler();
          }
          catch (e) {
            error = e;
          }
          if (result !== false && this.type == "checkbox" || this.type == "radio") Node
              .setAttribute(this, "checked", !this.checked);
          if (error) throw error;
        }
      },
      commandMouseOver : function(element) {
        if (!this.command.disabled && !this.command.checked) Element.addClassName(this, "ibre-"
            + (this.command.parentNode._type == "toolbar"? "tool": "menu") + "item-active");
        if (this.command.parentNode.activeElement) this.command.parentNode.activeElement.hideMenu();
      },
      commandMouseOut : function(element) {
        if (!this.command.disabled) {
          var className = (this.command.parentNode._type == "toolbar"? "tool": "menu") + "item-";
          Element.removeClassName(this, "ibre-" + className + "active");
          Element.removeClassName(this, "ibre-" + className + "pressed");
        }
      },
      commandMouseDown : function(element) {
        if (!this.command.disabled) Element.addClassName(this, "ibre-"
            + (this.command.parentNode._type == "toolbar"? "tool": "menu") + "item-pressed");
      },
      commandMouseUp : function(element) {
        if (!this.command.disabled) Element.removeClassName(this, "ibre-"
            + (this.command.parentNode._type == "toolbar"? "tool": "menu") + "item-pressed");
      },
      xsltToNode : function(source, doc) {
        var processor = this;
        if (!doc) doc = document;
        if (processor.transformToFragment) {
          var fragment = processor.transformToFragment(source, doc);
          if (fragment.childNodes.length == 1) return fragment.firstChild;
          return fragment;
        }
        processor.processor.input = source;
        processor.processor.transform();
        var s = processor.processor.output;
        if (processor._outputMethod == "text") return doc.createTextNode(s);
        var fragment = doc.createDocumentFragment();
        if (doc.body && doc.body.innerHTML) {
          var container = doc.createElement("div");
          container.innerHTML = s;
          Element.moveChilds(container, fragment);
          return fragment;
        }
        var oDoc = new ActiveXObject("Msxml2.DOMDocument.6.0");
        if (s.substring(0, 5) == "<?xml") s = s.substring(s.indexOf("?>") + 2);
        oDoc.loadXML("<my>".concat(s, "</my>"));
        Element.moveChilds(oDoc.documentElement, fragment);
        return fragment;
      },
      xsltSetInnerHTMLFromURI : function(uri, target) {
        return this.setInnerHTML(ibre.xml.load(uri), target);
      },
      xsltSetInnerHTML : function(source, target) {
        var list = $A(target.childNodes);
        if (target.nodeType != Node.DOCUMENT_NODE) target.appendChild(this.toNode(source,
            target.ownerDocument));
        list.each(Element.remove);
        if (target.nodeType == Node.DOCUMENT_NODE) target.appendChild(this.toNode(source, target));
        ibre.initParse(target);
      },
      xsltSetParam : function(name, value) {
        if (this.setParameter) this.setParameter("", name, value);
        else this.processor.addParameter(name, value);
      },
      draggableDragStart : function(current, eventName, draggable, event) {
        if (current == draggable) this.ondragstart(event);
      },
      draggableDrag : function(current, eventName, draggable, event) {
        if (current == draggable) this.ondrag(null, event);
      },
      draggableDragEnd : function(current, eventName, draggable, event) {
        if (current == draggable) this.ondragend(null, event);
      },
      evalHandler : function(expression, element, vars) {
        if (!vars) vars = {};
        return eval("(function () { with (this) { with (vars) { return " + expression
            + "; } } }.bind(element))()");
      },
      makeEventHandler : function(script, element, args) {
        if (!args) args = [];
        args.push("event");
        return eval("(function (" + args.join(", ") + ") { with (this) { " + script
            + " } }.bind(element))");
      },
      checkEventHandler : function(element, name, args) {
        name = "on" + name;
        if (typeof element[name] != "function") {
          var script = element.getAttribute(name);
          if (script) element[name] = ibre._methods.makeEventHandler(script, element, args);
        }
      },
      eval : function(code) {
        code = code.replace(/^\s*<!--/g, "");
        if (window.execScript) window.execScript(code);
        else if (window.eval) window.eval(code);
        else eval(code);
      },
      hoverMouseOver : function(event) {
        Element.addClassName(this, this.getAttribute("hover"));
      },
      hoverMouseOut : function(event) {
        Element.removeClassName(this, this.getAttribute("hover"));
      },
      checkedClick : function(event) {
        if (Event.element(event).tagName != 'INPUT'
            && (this.inputRef.type != "radio" || !this.inputRef.checked)) Node.setAttribute(
            this.inputRef, 'checked', !this.inputRef.checked);
      },
      checkedChange : function() {
        Element[this.inputRef.checked? "addClassName": "removeClassName"](this, this
            .getAttribute("checked-class"));
      },
      pressedMouseDown : function(event) {
        this.addClassName(this.getAttribute("pressed"));
        Event.stop(event);
      },
      pressedMouseUp : function(event) {
        this.removeClassName(this.getAttribute("pressed"));
        Event.stop(event);
      },
      hrefClick : function(event) {
        var href = this.getAttribute("href");
        var target = this.getAttribute("target");
        if (target) switch (target) {
          case "_popup":
            break;
          case "_top":
            top.location.href = href;
            break;
          case "_self":
            location.href = href;
            break;
          case "_parent":
            parent.location.href = href;
            break;
          case "_blank":
            open(href);
            break;
          default:
            if (window.frames[target] && window.frames[target].contentWindow) window.frames[target].contentWindow.location.href = href;
            else if ($(target)) ibre.ajax.getInnerHTML($(target), href);
            else open(href, target);
        }
        else location.href = href;
      },
      formSubmit : function() {
        var elements = $A(this.elements);
        var msg = "";
        var firstElement = null;
        var skipNonVisibleElements = this.getAttribute("skip-non-visible-elements") != null;
        var skipNonChangedElements = this.getAttribute("skip-non-changed-elements") != null;
        var noValidateNonVisibleElements = this.getAttribute("no-validate-non-visible-elements") != null;
        //var noValidateNonChangedElements = this.getAttribute("no-validate-non-changed-elements") != null;
        var noSubmitNonVisibleElements = this.getAttribute("no-submit-non-visible-elements") != null;
        //var noSubmitNonChangedElements = this.getAttribute("no-submit-non-changed-elements") != null;
        var elementsToSkip = [];
        function restoreElements() {
          elementsToSkip.each( function(item) {
            item._replaceNode.parentNode.replaceChild(item, item._replaceNode);
          });
        }
        for ( var i = 0; i < elements.length; i++)
          elements[i]._tested = false;
        for ( var i = 0; i < elements.length; i++) {
          var element = elements[i];
          var invisible = !Element.isVisible(element);
          if (skipNonVisibleElements && invisible && element.tagName != "FIELDSET") {
            elementsToSkip.push(element);
            continue;
          }
          if (noSubmitNonVisibleElements && invisible && element.tagName != "FIELDSET") elementsToSkip
              .push(element);
          if (noValidateNonVisibleElements && invisible) continue;
          if (skipNonChangedElements) {
            var skip = false;
            switch (element.tagName) {
              case "SELECT":
                for ( var j = 0; j < elements.options.length; j++)
                  if (elements.options[j].selected != elements.options[j].defaultSelected) break;
                if (j == elements.options.length) skip = true;
                break;
              case "TEXTAREA":
                skip = element.value == element.defaultValue;
                break;
              case "INPUT":
                switch (element.type) {
                  case "text":
                    skip = element.value == element.defaultValue;
                    break;
                  case "radio":
                    if (element.name) {
                      var radios = $A(this[element.name]);
                      for ( var j = 0; j < radios.length; j++)
                        if (radios[j].checked != radios[j].defaultChecked) break;
                      if (j == radios.length) skip = true;
                    }
                    break;
                }
                break;
            }
            if (skip) {
              elementsToSkip.push(element);
              continue;
            }
          }
          if (element.disabled || element.tagName == "INPUT" && element.type == "hidden") continue;
          element._tested = true;
          if (element.checkValidity && !element.checkValidity()) {
            if (!firstElement) firstElement = element;
            msg += ibre.labels.fieldError;
            var label = element.getAttribute("label");
            if (label) msg += " '" + label + "'";
            msg += "\n";
            msg += element.validationMessage;
            msg += "\n\n";
          }
        }
        elementsToSkip.each( function(item) {
          item._replaceNode = document.createTextNode("");
          item.parentNode.replaceChild(item._replaceNode, item);
        });
        if (msg) {
          alert(msg);
          firstElement.focus();
          restoreElements();
          return false;
        }
        if (this._onsubmit && this._onsubmit() === false) {
          restoreElements();
          return false;
        }
        if (!this._noSubmit && this.onreceived || this.target
            && (this.target == "_popup" || $(this.target))) {
          new Insertion.Bottom(document.body,
              "<iframe name='_tempHTML5Frame' style='display: none'></iframe>");
          var frame = document.body.lastChild;
          frame._target = this.target;
          this.target = "_tempHTML5Frame";
          Event
              .observe(
                  frame,
                  "load",
                  function onload() {
                    var doc = frame.contentWindow.document;
                    if (doc.location == "about:blank") return;
                    if (doc.XMLDocument) doc = doc.XMLDocument;
                    this.target = frame._target;
                    if (!this.onreceived || this.onreceived( {
                      receivedDocument :doc,
                      target :this
                    }) !== false) {
                      var target = this.target;
                      var targetDoc = null, targetNode = null;
                      if (target) {
                        switch (target) {
                          case "_popup":
                            break;
                          case "_top":
                            targetDoc = targetNode = top.document;
                            break;
                          case "_self":
                            targetDoc = targetNode = document;
                            break;
                          case "_parent":
                            targetDoc = targetNode = parent.document;
                            break;
                          case "_blank":
                            break;
                          default:
                            if ($(target)) {
                              targetDoc = document;
                              targetNode = $(target);
                            }
                            else if (window.frames[target]) targetDoc = targetNode = window.frames[target].contentWindow.document;
                        }
                      }
                      else targetDoc = targetNode = document;
                      if (targetDoc) {
                        Element.clear(targetNode);
                        if (targetNode.nodeType == Node.ELEMENT_NODE && doc.body) {
                          targetNode.innerHTML = doc.body.innerHTML;
                        }
                        else targetNode
                            .appendChild(targetDoc.importNode(doc.documentElement, true));
                        ibre.initParse(targetNode, true);
                      }
                    }
                    setTimeout( function() {
                      Element.remove(frame);
                    }, 200);
                  }.bind(this));
        }
        if (elementsToSkip.length) {
          if (!this._noSubmit) this.submit();
          restoreElements();
          return !!this._noSubmit;
        }
      },
      verifyLength : function(element) {
        if (element.value.length > element.maxLength) element.value = element.value.substring(0,
            element.maxLength);
        element._timer = ibre.runtime.setTimeout(ibre._methods.verifyLength, 200, element);
      },
      verifyNumbers : function(element) {
        if (element.value != element._oldValue) {
          if (element.value != "." && element.value != "-" && element.value != "-."
              && isNaN(element.value * 1)) element.value = element._oldValue;
          else element._oldValue = element.value;
        }
        element._timer = ibre.runtime.setTimeout(ibre._methods.verifyNumbers, 200, element);
      },
      verifyChange : function(element) {
        if (element.value != element._oldValue && Element.isVisible(element)) {
          element._oldValue = element.value;
          element.oninput();
        }
        element._timer = ibre.runtime.setTimeout(ibre._methods.verifyChange, 200, element);
      },
      elementInputFocus : function() {
        this._oldValue = this.value;
        ibre._methods.verifyChange(this);
      },
      elementInputBlur : function() {
        clearTimeout(this._timer);
      },
      numberKeyPress : function(event) {
        var code = Prototype.Browser.IE? event.keyCode: event.charCode;
        if (code != 45 && code != 46 && (code < 48 || code > 57)
            && (Prototype.Browser.IE || !event.keyCode)) Event.stop(event);
      },
      dateKeyPress : function(event) {
        if (event.keyCode == Event.KEY_DOWN) this.button.click();
      },
      numberFocus : function() {
        this._oldValue = this.value;
        ibre._methods.verifyNumbers(this);
      },
      numberBlur : function() {
        clearTimeout(this._timer);
      },
      maxLengthKeyPress : function(event) {
        var code = Prototype.Browser.IE? event.keyCode: event.charCode;
        if (this.value.length == this.maxLength && (Prototype.Browser.IE || !event.keyCode)) Event
            .stop(event);
      },
      maxLengthFocus : function() {
        ibre._methods.verifyLength(this);
      },
      maxLengthBlur : function() {
        clearTimeout(this._timer);
      },
      preparePopup : function() {
        var body = document.body;
        new Insertion.Bottom(
            body,
            "<table cellpadding='0' cellspacing='0' style='position: "
                + (Prototype.Browser.IE? "absolute": "fixed")
                + "; top: 0px; margin: 0px; padding: 0px; border-width: 0px; width: 100%; height: 100%;'><tr><td valign='top'><table style='position: relative; margin: 0px; padding: 0px; width: 100%; height: 100%' border='0'><tr><td align='center'><table><tr><td></td></tr></table></td></tr></table></td></tr></table>");
        var popup = body.lastChild;
        var firstTable = popup.rows[0].cells[0].firstChild;
        var table = Element.firstDescendant(firstTable.rows[0].cells[0]);
        popup._draggableTable = table;
        var container = table.rows[0].cells[0];
        popup.container = container;
        container.popup = popup;
        Element.addClassName(container, "popup");
        popup.selects = [];
        popup.showPopup = function() {
          if (Element.parentElement(this)) this.hidePopup();
          if (Prototype.Browser.IE) {
            var selects = document.getElementsByTagName("select");
            for ( var i = 0; i < selects.length; i++) {
              if (selects[i]._popups) selects[i]._popups++;
              else selects[i]._popups = 1;
              if (selects[i].style.visibility != "hidden") selects[i].style.visibility = "hidden";
              this.selects.push(selects[i]);
            }
          }
          body.appendChild(this);
          if (Prototype.Browser.IE) {
            var size = Position.pageSize();
            var size2 = Position.clientSize();
            var offset = Position.scrollOffset();
            firstTable.style.left = offset[0] + "px";
            firstTable.style.top = offset[1] + "px";
            firstTable.style.width = size2[0] + "px";
            firstTable.style.height = size2[1] + "px";
            this.style.width = size[0] + "px";
            this.style.height = size[1] + "px";
          }
          Element.show(this);
          if (this.firstActive) this.firstActive.focus();
          else {
            var elements = this.getElementsByTagName("input");
            for ( var j = 0; j < elements.length; j++) {
              var element = elements[j];
              if (element.type == "text" && !element.disabled && !element.readOnly
                  && Element.isVisible(element)) {
                element.focus();
                break;
              }
            }
          }
          document.visiblePopups.push(this);
        };
        popup.hidePopup = function() {
          if (Element.parentElement(this)) Element.remove(this);
          if (Prototype.Browser.IE) {
            for ( var i = 0; i < this.selects.length; i++) {
              this.selects[i]._popups--;
              if (!this.selects[i]._popups) this.selects[i].style.visibility = "";
            }
            this.selects = [];
          }
          document.visiblePopups.removeValue(this);
        };
        popup.isVisible = function() {
          return this.parentNode != null;
        };
        return popup;
      },
      installPopup : function(popup, html) {
        Element.clear(popup.container);
        Element.hide(popup.container);
        if (typeof html != "string") {
          Element.insert(popup.container, html);
          ibre.initParse(popup.container);
        }
        else Element.setInnerHTML(popup.container, html);
        if (!popup._draggable) {
          var table = popup._draggableTable;
          popup._draggableElement = table;
          popup._draggable = new Draggable(table);
        }
        Element.remove(popup);
        Element.show(popup.container);
      },
      checkValidity : function() {
        var validity = {
          typeMismatch :false,
          stepMismatch :false,
          rangeUnderflow :false,
          rangeOverflow :false,
          tooLong :false,
          patternMismatch :false,
          valueMissing :false,
          customError :false,
          minLengthError :false
        };
        var value = this.value;
        if (this.required && (this.type == "checkbox" || this.type == "radio")) {
          if (this.form && this.name) {
            var list = $A(this.form[this.name]);
            var test = true;
            for ( var i = 0; list[i] != this; i++)
              if (list[i].required && list[i]._tested) {
                test = false;
                break;
              }
            if (test) {
              for ( var i = 0; i < list.length; i++)
                if (list[i].checked) break;
              if (i == list.length) validity.valueMissing = true;
            }
          }
          else if (!this.checked) validity.valueMissing = true;
        }
        else if (value == "") {
          if (this.required) validity.valueMissing = true;
        }
        else switch (this.tagName) {
          case "INPUT":
            switch (this.getAttribute("type")) {
              case "number":
                value = value.strip();
                if (!value || isNaN(value * 1)) validity.typeMismatch = true;
                else {
                  value *= 1;
                  var min = this.getAttribute("min");
                  var max = this.getAttribute("max");
                  if (min && !isNaN(min * 1) && value < min) validity.rangeUnderflow = true;
                  else if (max && !isNaN(max * 1) && value > max) validity.rangeOverflow = true;
                  var step = this.getAttribute("step");
                  if (step != "any") {
                    step = parseFloat(step);
                    if (isNaN(step)) step = 1;
                    if (value % step != 0) this.value = value - value % step
                        + (step / 2 < value % step? step: 0);
                  }
                }
                break;
              case "date":
                validity.typeMismatch = !/^[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$/
                    .test(value);
                break;
              case "email":
                var atext = "[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+";
                // var atext = "[a-zA-Z0-9]+";
                var dotAtom = atext + "([.]" + atext + ")*";
                var cr = "\\x0d";
                var lf = "\\x0a";
                var crlf = cr + lf;
                var fws = "(( *" + crlf + ")? +)?";
                var noWsCtl = "\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f";
                var quotedPair = "\\\\[\\x01-\\x09\\x0b\\x0c\\x1e-\\x7f]";
                var quotedString = "\"(" + fws + "([" + noWsCtl + "\\x21\\x23-\\x5b\\x5d-\\x7e]|"
                    + quotedPair + "))*" + fws + "\"";
                var addrSpec = "^(" + dotAtom + "|" + quotedString + ")@(" + dotAtom + "|\\[((["
                    + noWsCtl + "\\x21-\\x5a\\x5e-\\x7e])|" + quotedPair + ")*\\])$";
                validity.typeMismatch = !new RegExp(addrSpec).test(value);
                break;
              case "image":
              case "button":
              case "hidden":
              case "submit":
              case "file":
                break;
              default:
                var minLength = this.getAttribute("minlength") * 1;
                if (minLength && value.length < minLength) validity.minLengthError = true;
                var pattern = this.getAttribute("pattern");
                if (pattern != null && !new RegExp("^" + pattern + "$").test(value)) validity.patternMismatch = true;
            }
            break;
        }
        validity.valid = !(validity.typeMismatch || validity.stepMismatch
            || validity.rangeUnderflow || validity.rangeOverflow || validity.tooLong
            || validity.patternMismatch || validity.valueMissing || validity.minLengthError);
        this.validationMessage = null;
        if (validity.valid && this.onvalidate) {
          validity.customError = !this.onvalidate();
          validity.valid = !validity.customError;
          this.validationMessage = this.getAttribute("validation-message");
        }
        this.validity = validity;
        if (this.validationMessage == null) {
          if (validity.typeMismatch) this.validationMessage = ibre.labels.typeMismatch;
          else if (validity.rangeUnderflow) this.validationMessage = ibre.labels.rangeUnderflow
              + "\n" + ibre.labels.minRequired + ": " + this.getAttribute("min");
          else if (validity.rangeOverflow) this.validationMessage = ibre.labels.rangeOverflow
              + "\n" + ibre.labels.maxRequired + ": " + this.getAttribute("max");
          else if (validity.stepMismatch) this.validationMessage = ibre.labels.stepMismatch;
          else if (validity.valueMissing) this.validationMessage = ibre.labels.valueMissing;
          else if (validity.minLengthError) this.validationMessage = ibre.labels.minLengthError
              + ": " + this.getAttribute("minlength");
          else if (validity.patternMismatch) this.validationMessage = this
              .getAttribute("validation-message");
        }
        return validity.valid;
      },
      menuClick : function(event) {
        Event.stop(event);
      },
      submenuClick : function(event) {
        this.command.showMenu();
        Event.stop(event);
      },
      submenuMouseOver : function() {
        if (this.command.parentNode.activeElement) this.command.showMenu();
      },
      showMenu : function() {
        if (this.parentNode.activeElement) this.parentNode.activeElement.hideMenu();
        var options = {
          setWidth :false,
          setHeight :false
        };
        var submenu = this.refNode;
        if (this.element.tagName == "TR") options.offsetLeft = Element.getWidth(this.element) - 2;
        else options.offsetTop = Element.getHeight(this.element);
        if (Prototype.Browser.IE) submenu.style.position = "absolute";
        Element.clonePosition(submenu, this.element, options);
        if (!Prototype.Browser.IE) submenu.style.position = "absolute";
        Element.show(submenu);
        Element.addClassName(this.element, "ibre-submenu-active");
        this.parentNode.activeElement = this;
        var mainMenu = Element.parentElement(this.parentNode);
        if (!mainMenu || mainMenu.tagName != "MENU") document.activeMenu = this;
      },
      hideMenu : function() {
        if (this.parentNode.activeElement != this) return;
        this.parentNode.activeElement = null;
        this.refNode.style.position = "";
        Element.hide(this.refNode);
        Element.removeClassName(this.element, "ibre-submenu-active");
        if (this.activeElement) this.activeElement.hideMenu();
      }
    },
    debug : {
      print : function(text) {
      },
      inspect : function(obj) {
      }
    },
    load : function(href) {
    },
    runtime : {
      setTimeout : function(func, milliseconds) {
        if (Prototype.Browser.IE) {
          var args = $A(arguments);
          args.splice(0, 2);
          setTimeout( function() {
            func.apply(null, args);
          }, milliseconds);
        }
        else setTimeout.apply(window, arguments);
      },
      exec : function(process) {
        var args = $A(arguments);
        args.shift();
        ibre.runtime.setTimeout.apply(null, [ process, 0 ].concat(args));
      }
    },
    datasource : {
      update : function(element) {
      },
      getNodes : function() {
        return $$("link[rel='datasource']");
      },
      values : {}
    },
    ajax : {
      request : function(uri, method, data, handler, errorHandler, headers) {
        var asyn = !!handler;
        var request = new Ajax.Request(
            uri,
            {
              method :method,
              asynchronous :asyn,
              postBody :data,
              onSuccess : function(transport) {
                if (transport.status != 200) (errorHandler || ibre.ajax.errorHandler || Protoype.emptyFunction)
                    (transport);
                else if (typeof handler == "function") handler(transport);
              },
              onFailure :errorHandler || ibre.ajax.errorHandler,
              onException : function(req, exception) {
                throw exception;
              },
              encoding :"ISO-8859-1",
              requestHeaders :headers,
              evalJS :false,
              evalJSON :false
            });
        return request.transport;
      },
      requestDOMDocument : function(uri, method, data, handler, errorHandler, headers) {
        if (!errorHandler) errorHandler = ibre.ajax.errorHandler;
        var transport = ibre.ajax
            .request(
                uri,
                method,
                data,
                handler? function(transport) {
                  var doc = transport.responseXML;
                  if (Prototype.Browser.IE && doc.documentElement == null) doc = ibre.xml
                      .make(transport.responseText);
                  if (doc
                      && (!Prototype.Browser.Gecko || doc.documentElement.tagName != "parsererror")) handler(doc);
                  else if (errorHandler) errorHandler(transport);
                }
                    : false, errorHandler, headers);
        if (!handler) {
          var doc = transport.responseXML;
          if (Prototype.Browser.IE && doc.documentElement == null) doc = ibre.xml
              .make(transport.responseText);
          if (doc && (!Prototype.Browser.Gecko || doc.documentElement.tagName != "parsererror")) return doc;
          if (errorHandler) errorHandler(transport);
          return null;
        }
        return transport;
      },
      requestDOMNode : function(uri, method, data, handler, errorHandler, headers) {
        if (!errorHandler) errorHandler = ibre.ajax.errorHandler;
        var transport = ibre.ajax
            .request(
                uri,
                method,
                data,
                handler? function(transport) {
                  var doc = transport.responseXML;
                  var node = null;
                  if (!doc) {
                    try {
                      node = Node.createDocument().createRange().createContextualFragment(
                          transport.responseText);
                    }
                    catch (e) {
                    }
                  }
                  else if (!Prototype.Browser.Gecko || doc.documentElement.tagName != "parsererror") node = doc;
                  if (node) {
                    if (node.childNodes.length == 1) node = Element.remove(node.firstChild);
                    handler(node);
                  }
                  else if (errorHandler) errorHandler(transport);
                }
                    : false, errorHandler, headers);
        if (!handler) {
          var doc = transport.responseXML;
          if (!doc) {
            try {
              return document.implementation.createDocument(null, null, null).createRange()
                  .createContextualFragment(transport.responseText);
            }
            catch (e) {
            }
          }
          else if (!Prototype.Browser.Gecko || doc.documentElement.tagName != "parsererror") return Node
              .getContent(doc);
          if (errorHandler) errorHandler(transport);
          return null;
        }
        return transport;
      },
      requestDOMFragment : function(uri, method, data, handler, errorHandler, headers) {
        var node = ibre.ajax.requestDOMNode(uri, method, data, handler? function(node) {
          handler(Node.toDocumentFragment(node));
        }: false, errorHandler, headers);
        if (!handler) {
          if (node) return Node.toDocumentFragment(node);
          return null;
        }
        return transport;
      },
      requestDOMElement : function(uri, method, data, handler, errorHandler, headers) {
        if (!errorHandler) errorHandler = ibre.ajax.errorHandler;
        var node = ibre.ajax.requestDOMNode(uri, method, data, handler? function(node) {
          if (node.nodeType == Node.ELEMENT_NODE) handler(node);
          else if (errorHandler) errorHandler( {});
        }: false, errorHandler, headers);
        if (!handler) {
          if (node) return node.nodeType == Node.ELEMENT_NODE? node: null;
          return null;
        }
        return transport;
      },
      requestHTML : function(uri, method, data, handler, errorHandler, headers) {
        if (!errorHandler) errorHandler = ibre.ajax.errorHandler;
        var transport = ibre.ajax
            .request(
                uri,
                method,
                data,
                handler? function(transport) {
                  var doc = transport.responseXML;
                  var node = null;
                  if (!doc) {
                    try {
                      var range = document.createRange();
                      range.selectNode(document.body);
                      node = range.createContextualFragment(transport.responseText);
                    }
                    catch (e) {
                    }
                  }
                  else if (!Prototype.Browser.Gecko || doc.documentElement.tagName != "parsererror") node = document
                      .importNode(Element.getContent(doc), true);
                  if (node) handler(node);
                  else if (errorHandler) errorHandler(transport);
                }
                    : false, errorHandler, headers);
        if (!handler) {
          var doc = transport.responseXML;
          if (!doc) {
            try {
              return document.createRange().createContextualFragment(transport.responseText);
            }
            catch (e) {
            }
          }
          else if (!Prototype.Browser.Gecko || doc.documentElement.tagName != "parsererror") return document
              .importNode(Element.getContent(doc), true);
          if (errorHandler) errorHandler(transport);
          return null;
        }
        return transport;
      },
      requestText : function(uri, method, data, handler, errorHandler, headers) {
        var transport = ibre.ajax.request(uri, method, data, handler? function(transport) {
          handler(transport.responseText);
        }: false, errorHandler, headers);
        return handler? transport: transport.responseText;
      },
      requestJSON : function(uri, method, data, handler, errorHandler, headers) {
        if (!errorHandler) errorHandler = ibre.ajax.errorHandler;
        var transport = ibre.ajax.request(uri, method, data, handler? function(transport) {
          var json;
          try {
            json = transport.responseText.evalJSON();
          }
          catch (e) {
            if (errorHandler) errorHandler(transport);
          }
          if (json !== undefined) handler(json);
        }: false, errorHandler, Object.extend(headers || {}, {
          "Accept" :"application/jsonrequest"
        }));
        if (!handler) {
          try {
            return transport.responseText.evalJSON();
          }
          catch (e) {
            if (errorHandler) errorHandler(transport);
          }
        }
        return transport;
      },
      requestInnerHTML : function(element, uri, method, data, handler, errorHandler, headers) {
        var asyn = handler !== false;
        var transport = ibre.ajax.requestText(uri, method, data, asyn? function(text) {
          Element.setInnerHTML(element, text);
          if (typeof handler == "function") handler();
        }: false, errorHandler, headers);
        if (!asyn) Element.setInnerHTML(element, transport);
        return transport;
      },
      requestPopup : function(uri, method, data, handler, errorHandler, headers) {
        if (!errorHandler) errorHandler = ibre.ajax.errorHandler;
        var popup = ibre._methods.preparePopup();
        var asyn = handler !== false;
        var text = ibre.ajax.requestText(uri, method, data, asyn? function(text) {
          ibre._methods.installPopup(popup, text);
          var node = Element.down(popup.container);
          if (node) {
            var oncancel = node.getAttribute("oncancel");
            if (oncancel) popup.oncancel = ibre._methods.makeEventHandler(oncancel, popup);
          }
          popup.showPopup();
          if (typeof handler == "function") handler(popup);
        }: false, function(transport) {
          popup.hidePopup();
          if (errorHandler) errorHandler(transport);
        });
        if (!asyn) {
          ibre._methods.installPopup(popup, text);
          var node = Element.down(popup.container);
          if (node) {
            var oncancel = node.getAttribute("oncancel");
            if (oncancel) popup.oncancel = ibre._methods.makeEventHandler(oncancel, popup);
          }
          popup.showPopup();
        }
        return popup;
      },
      get : function(uri, handler, errorHandler, headers) {
        return ibre.ajax.request(uri, "GET", null, handler, errorHandler, headers);
      },
      getDOMDocument : function(uri, handler, errorHandler, headers) {
        return ibre.ajax.requestDOMDocument(uri, "GET", null, handler, errorHandler, headers);
      },
      getDOMNode : function(uri, handler, errorHandler, headers) {
        return ibre.ajax.requestDOMNode(uri, "GET", null, handler, errorHandler, headers);
      },
      getDOMFragment : function(uri, handler, errorHandler, headers) {
        return ibre.ajax.requestDOMFragment(uri, "GET", null, handler, errorHandler, headers);
      },
      getDOMElement : function(uri, handler, errorHandler, headers) {
        return ibre.ajax.requestDOMElement(uri, "GET", null, handler, errorHandler, headers);
      },
      getHTML : function(uri, handler, errorHandler, headers) {
        return ibre.ajax.requestHTML(uri, "GET", null, handler, errorHandler, headers);
      },
      getText : function(uri, handler, errorHandler, headers) {
        return ibre.ajax.requestText(uri, "GET", null, handler, errorHandler, headers);
      },
      getJSON : function(uri, handler, errorHandler, headers) {
        return ibre.ajax.requestJSON(uri, "GET", null, handler, errorHandler, headers);
      },
      getInnerHTML : function(element, uri, handler, errorHandler, headers) {
        return ibre.ajax
            .requestInnerHTML(element, uri, "GET", null, handler, errorHandler, headers);
      },
      getPopup : function(uri, handler, errorHandler, headers) {
        return ibre.ajax.requestPopup(uri, "GET", null, handler, errorHandler, headers);
      },
      post : function(uri, data, handler, errorHandler, headers) {
        return ibre.ajax.request(uri, "POST", data, handler, errorHandler, headers);
      },
      postDOMDocument : function(uri, data, handler, errorHandler, headers) {
        return ibre.ajax.requestDOMDocument(uri, "POST", data, handler, errorHandler, headers);
      },
      postDOMNode : function(uri, data, handler, errorHandler, headers) {
        return ibre.ajax.requestDOMNode(uri, "POST", data, handler, errorHandler, headers);
      },
      postDOMElement : function(uri, data, handler, errorHandler, headers) {
        return ibre.ajax.requestDOMElement(uri, "POST", data, handler, errorHandler, headers);
      },
      postDOMFragment : function(uri, data, handler, errorHandler, headers) {
        return ibre.ajax.requestDOMFragment(uri, "POST", data, handler, errorHandler, headers);
      },
      postHTML : function(uri, data, handler, errorHandler, headers) {
        return ibre.ajax.requestHTML(uri, "POST", data, handler, errorHandler, headers);
      },
      postText : function(uri, data, handler, errorHandler, headers) {
        return ibre.ajax.requestText(uri, "POST", data, handler, errorHandler, headers);
      },
      postJSON : function(uri, data, handler, errorHandler, headers) {
        return ibre.ajax.requestJSON(uri, "POST", data, handler, errorHandler, headers);
      },
      postInnerHTML : function(element, uri, data, handler, errorHandler, headers) {
        return ibre.ajax.requestInnerHTML(element, uri, "POST", data, handler, errorHandler,
            headers);
      },
      postPopup : function(uri, data, handler, errorHandler, headers) {
        return ibre.ajax.requestPopup(uri, "POST", data, handler, errorHandler, headers);
      }
    },
    xslt : {
      setInnerHTML : function(xml, xsl, target, params) {
        var processor = ibre.xslt.create(xsl, params);
        processor.setInnerHTML(xml, target);
      },
      load : function(uri, params) {
        return ibre.xslt.create(ibre.xml.load(uri), params);
      },
      create : function(xsl, params) {
        var processor;
        Try
            .these(
                function() {
                  processor = new XSLTProcessor();
                  processor.importStylesheet(xsl);
                },
                function() {
                  var template = Try.these( function() {
                    return new ActiveXObject("Msxml2.XSLTemplate.6.0");
                  }, function() {
                    return new ActiveXObject("MSXML2.XSLTemplate.3.0");
                  });
                  xsl.setProperty("SelectionLanguage", "XPath");
                  xsl.setProperty("SelectionNamespaces",
                      "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
                  var converted = Try.these( function() {
                    return new ActiveXObject("MSXML2.FreeThreadedDOMDocument.6.0");
                  }, function() {
                    return new ActiveXObject("MSXML2.FreeThreadedDOMDocument.3.0");
                  });
                  try {
                    converted.resolveExternals = true;
                    converted.setProperty("AllowDocumentFunction", true);
                  }
                  catch (e) {
                  }
                  if (xsl.url
                      && xsl
                          .selectSingleNode("//xsl:*[local-name() = 'import' or local-name() = 'include']") != null) {
                    converted.async = false;
                    converted.load(xsl.url);
                  }
                  else converted.loadXML(xsl.xml);
                  converted.setProperty("SelectionNamespaces",
                      "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
                  var output = converted.selectSingleNode("//xsl:output");
                  template.stylesheet = converted;
                  processor = {
                    outputMethod :output? output.getAttribute("method"): "html"
                  };
                  processor.processor = template.createProcessor();
                });
        processor.setParam = ibre._methods.xsltSetParam;
        processor.setInnerHTML = ibre._methods.xsltSetInnerHTML;
        processor.setInnerHTMLFromURI = ibre._methods.xsltSetInnerHTMLFromURI;
        processor.toNode = ibre._methods.xsltToNode;
        if (params) {
          for ( var paramName in params) {
            var paramValue = params[paramName];
            if (typeof paramValue != "function") processor.setParam(paramName, paramValue);
          }
        }
        return processor;
      }
    },
    xml : {
      load : function(uri) {
        return Try.these( function() {
          return ibre.ajax.getDOMDocument(uri);
        }, function() {
        });
      },
      make : function(text) {
        if (typeof DOMParser != "undefined") return (new DOMParser()).parseFromString(text,
            "application/xml");
        if (typeof ActiveXObject != "undefined") {
          var doc = new ActiveXObject("MSXML.DOMDocument");
          doc.loadXML(text);
          return doc;
        }
        var url = "data:text/xml;charset=utf-8," + encodeURIComponent(text);
        var request = new XMLHttpRequest();
        request.open("GET", url, false);
        request.send(null);
        return request.responseXML;
      },
      create : function() {
        return Try.these( function() {
          return document.implementation.createDocument("", "", null);
        }, function() {
          return new ActiveXObject("MSXML.DOMDocument");
        });
      },
      serialize : function(node) {
        return Try.these( function() {
          return new XMLSerializer().serializeToString(node);
        }, function() {
          return node.xml || node.outerHTML;
        });
      }
    },
    xpath : {
      select : function(expr, context) {
        var doc = Node.document(context);
        if (Prototype.Browser.IE) {
          doc.setProperty("SelectionLanguage", "XPath");
          doc
              .setProperty("SelectionNamespaces",
                  "xmlns:xhtml='http://www.w3.org/1999/xhtml' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
          if (context == doc) context = doc.documentElement;
          return $A(context.selectNodes(expr));
        }
        var result = doc.evaluate(expr, context, null, XPathResult.ANY_TYPE, null);
        var list = [];
        var node;
        while (node = result.iterateNext())
          list.push(node);
        return list;
      },
      selectOne : function(expr, context, resultType) {
        var doc = Node.document(context);
        if (Prototype.Browser.IE) {
          doc.setProperty("SelectionLanguage", "XPath");
          doc
              .setProperty("SelectionNamespaces",
                  "xmlns:xhtml='http://www.w3.org/1999/xhtml' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
          if (context == doc) context = doc.documentElement;
          return context.selectSingleNode(expr);
        }
        var result = doc.evaluate(expr, context, null, resultType || XPathResult.ANY_TYPE, null);
        switch (result.resultType) {
          case XPathResult.NUMBER_TYPE:
            return result.numberValue;
          case XPathResult.STRING_TYPE:
            return result.stringValue;
          case XPathResult.BOOLEAN_TYPE:
            return result.booleanValue;
          default:
            return result.iterateNext();
        }
      },
      remove : function(expr, context) {
        ibre.xpath.select(expr, context).each( function(item) {
          Node.remove(item);
        });
      }
    },
    labels : {
      fieldError :"Error en el campo",
      typeMismatch :"No es un valor valido",
      rangeUnderflow :"El valor es menor al m\xEDnimo requerido",
      rangeOverflow :"El valor es mayor al m\xE1ximo requerido",
      valueMissing :"El campo es requerido",
      minRequired :"M\xEDnimo requerido",
      maxRequired :"M\xE1ximo requerido",
      minLengthError :"M\xEDnimo de caracteres requerido",
      filterAll :"MOSTRAR TODOS"
    },
    makeId : function() {
      return "_" + new Date().getTime();
    },
    util : {
      filterValue : function(value, options, def) {
        if (options.contains(value)) return value;
        return def;
      }
    },
    _util : {
      eventObserve :Event.observe,
      loadListeners : []
    },
    sign : {
      signData : function(data) {
        var signer = new ActiveXObject("CAPICOM.Signer");
        var signedData = new ActiveXObject("CAPICOM.SignedData");
        var timeAttribute = new ActiveXObject("CAPICOM.Attribute");
        signedData.Content = data;
        timeAttribute.Name = 0;
        timeAttribute.Value = new Date().getVarDate();
        signer.AuthenticatedAttributes.Add(timeAttribute);
        return signedData.Sign(signer, false, 0);
      }
    },
    cookie : {
      set : function(cookieName, cookieValue, expires, path, domain, secure) {
        document.cookie = escape(cookieName) + '=' + escape(cookieValue)
            + (expires? '; expires=' + expires.toGMTString(): '') + (path? '; path=' + path: '')
            + (domain? '; domain=' + domain: '') + (secure? '; secure': '');
      },
      get : function(cookieName) {
        var cookieValue = '';
        var posName = document.cookie.indexOf(escape(cookieName) + '=');
        if (posName != -1) {
          var posValue = posName + (escape(cookieName) + '=').length;
          var endPos = document.cookie.indexOf(';', posValue);
          if (endPos != -1) cookieValue = unescape(document.cookie.substring(posValue, endPos));
          else cookieValue = unescape(document.cookie.substring(posValue));
        }
        return cookieValue;
      },
      remove : function(cookieName) {
        document.cookie = escape(cookieName) + '=; expires=' + new Date().toGMTString();
      }
    },
    test : {
      isWhiteSpace : function(str) {
        return ibre.test._isWhiteSpace.test(str);
      },
      _isWhiteSpace :/^\s*$/g
    }
  };
  Event.observe = function(node, name, observer, useCapture) {
    if (name == "load" && node == window) ibre._util.loadListeners.push(observer);
    else if (node.isDatagrid && name == "change") node._changeEvents.push(observer);
    else {
      if (node.tagName == "INPUT" && name == "change") {
        if (Prototype.Browser.IE && node.type == "checkbox") name = "click";
        else if (node.type == "radio") {
          if (node.name && node.form) {
            $A(node.form[node.name]).each( function(item) {
              ibre._util.eventObserve(item, "click", observer, useCapture);
            });
            return;
          }
          else name = "click";
        }
      }
      ibre._util.eventObserve(node, name, observer, useCapture);
    }
  };
  JSONRequest = {
    _requests : [],
    _open : function(url, method, done, data) {
      var req = Ajax.getTransport();
      var requestNumber = this._requests.length;
      this._requests.push(req);
      req.open(method, url, true);
      req.setRequestHeader("Content-Type", "application/jsonrequest");
      var alive = true;
      req.onreadystatechange = function() {
        if (req.readyState == 4) {
          alive = false;
          var isOK;
          try {
            isOK = req.status == 200;
          }
          catch (e) {
            return;
          }
          if (isOK) {
            var contentType = req.getResponseHeader("Content-Type");
            if (contentType && contentType.startsWith("application/jsonrequest")) done(
                requestNumber, req.responseText.evalJSON());
            else {
              done(requestNumber, null, {
                name :"JSONRequestError",
                message :"bad response",
                "native" :req
              });
            }
          }
          else {
            done(requestNumber, null, {
              name :"JSONRequestError",
              message :"not ok",
              "native" :req
            });
          }
        }
      };
      setTimeout( function() {
        if (alive) {
          req.abort();
          done(requestNumber, null, {
            name :"JSONRequestError",
            message :"no response",
            "native" :req
          });
        }
      }, 1000 * timeout);
      req.send(data);
      return requestNumber;
    },
    post : function(url, send, done, timeout) {
      return this._open(url, "POST", done, send == null? "null": Object.toJSON(send));
    },
    get : function(url, done) {
      return this._open(url, "GET", done, null);
    },
    cancel : function(requestNumber) {
      this._requests[requestNumber].abort();
    }
  };
}
