text: /*
  This file is part of Ext JS 3.4
  
  Copyright (c) 2011-2013 Sencha Inc
  
  Contact:  http://www.sencha.com/contact
  
  GNU General Public License Usage
  This file may be used under the terms of the GNU General Public License version 3.0 as
  published by the Free Software Foundation and appearing in the file LICENSE included in the
  packaging of this file.
  
  Please review the following information to ensure the GNU General Public License version 3.0
  requirements will be met: http://www.gnu.org/copyleft/gpl.html.
  
  If you are unsure which license is appropriate for your use, please contact the sales department
  at http://www.sencha.com/contact.
  
  Build date: 2013-04-03 15:07:25
  */
  Ext.debug = {};
  
  (function(){
  
  var cp;
  
  function createConsole(){
  
      var scriptPanel = new Ext.debug.ScriptsPanel();
      var logView = new Ext.debug.LogPanel();
      var tree = new Ext.debug.DomTree();
      var compInspector = new Ext.debug.ComponentInspector();
      var compInfoPanel = new Ext.debug.ComponentInfoPanel();
      var storeInspector = new Ext.debug.StoreInspector();
      var objInspector = new Ext.debug.ObjectInspector();
  
      var tabs = new Ext.TabPanel({
          activeTab: 0,
          border: false,
          tabPosition: 'bottom',
          items: [{
              title: 'Debug Console',
              layout:'border',
              items: [logView, scriptPanel]
          },{
              title: 'HTML Inspector',
              layout:'border',
              items: [tree]
          },{
              title: 'Component Inspector',
              layout: 'border',
              items: [compInspector,compInfoPanel]
          },{
              title: 'Object Inspector',
              layout: 'border',
              items: [objInspector]
          },{
              title: 'Data Stores',
              layout: 'border',
              items: [storeInspector]
          }]
      });
  
      cp = new Ext.Panel({
          id: 'x-debug-browser',
          title: 'Console',
          collapsible: true,
          animCollapse: false,
          style: 'position:absolute;left:0;bottom:0;z-index:101',
          height:200,
          logView: logView,
          layout: 'fit',
  
          tools:[{
              id: 'close',
              handler: function(){
                  cp.destroy();
                  cp = null;
                  Ext.EventManager.removeResizeListener(handleResize);
              }
          }],
  
          items: tabs
      });
  
      cp.render(Ext.getBody());
  
      cp.resizer = new Ext.Resizable(cp.el, {
          minHeight:50,
          handles: "n",
          pinned: true,
          transparent:true,
          resizeElement : function(){
              var box = this.proxy.getBox();
              this.proxy.hide();
              cp.setHeight(box.height);
              return box;
          }
      });
  
  //     function handleResize(){
  //         cp.setWidth(Ext.getBody().getViewSize().width);
  //     }
  //     Ext.EventManager.onWindowResize(handleResize);
  //
  //     handleResize();
  
      function handleResize(){
          var b = Ext.getBody();
          var size = b.getViewSize();
          if(size.height < b.dom.scrollHeight) {
              size.width -= 18;
          }
          cp.setWidth(size.width);
      }
      Ext.EventManager.onWindowResize(handleResize);
      handleResize();
  }
  
  
  Ext.apply(Ext, {
      log : function(){
          if(!cp){
              createConsole();
          }
          cp.logView.log.apply(cp.logView, arguments);
      },
  
      logf : function(format, arg1, arg2, etc){
          Ext.log(String.format.apply(String, arguments));
      },
  
      dump : function(o){
          if(typeof o == 'string' || typeof o == 'number' || typeof o == 'undefined' || Ext.isDate(o)){
              Ext.log(o);
          }else if(!o){
              Ext.log("null");
          }else if(typeof o != "object"){
              Ext.log('Unknown return type');
          }else if(Ext.isArray(o)){
              Ext.log('['+o.join(',')+']');
          }else{
              var b = ["{\n"];
              for(var key in o){
                  var to = typeof o[key];
                  if(to != "function" && to != "object"){
                      b.push(String.format("  {0}: {1},\n", key, o[key]));
                  }
              }
              var s = b.join("");
              if(s.length > 3){
                  s = s.substr(0, s.length-2);
              }
              Ext.log(s + "\n}");
          }
      },
  
      _timers : {},
  
      time : function(name){
          name = name || "def";
          Ext._timers[name] = new Date().getTime();
      },
  
      timeEnd : function(name, printResults){
          var t = new Date().getTime();
          name = name || "def";
          var v = String.format("{0} ms", t-Ext._timers[name]);
          Ext._timers[name] = new Date().getTime();
          if(printResults !== false){
              Ext.log('Timer ' + (name == "def" ? v : name + ": " + v));
          }
          return v;
      }
  });
  
  })();
  
  
  Ext.debug.ScriptsPanel = Ext.extend(Ext.Panel, {
      id:'x-debug-scripts',
      region: 'east',
      minWidth: 200,
      split: true,
      width: 350,
      border: false,
      layout:'anchor',
      style:'border-width:0 0 0 1px;',
  
      initComponent : function(){
  
          this.scriptField = new Ext.form.TextArea({
              anchor: '100% -26',
              style:'border-width:0;'
          });
  
          this.trapBox = new Ext.form.Checkbox({
              id: 'console-trap',
              boxLabel: 'Trap Errors',
              checked: true
          });
  
          this.toolbar = new Ext.Toolbar([{
                  text: 'Run',
                  scope: this,
                  handler: this.evalScript
              },{
                  text: 'Clear',
                  scope: this,
                  handler: this.clear
              },
              '->',
              this.trapBox,
              ' ', ' '
          ]);
  
          this.items = [this.toolbar, this.scriptField];
  
          Ext.debug.ScriptsPanel.superclass.initComponent.call(this);
      },
  
      evalScript : function(){
          var s = this.scriptField.getValue();
          if(this.trapBox.getValue()){
              try{
                  var rt = eval(s);
                  Ext.dump(rt === undefined? '(no return)' : rt);
              }catch(e){
                  Ext.log(e.message || e.descript);
              }
          }else{
              var rt = eval(s);
              Ext.dump(rt === undefined? '(no return)' : rt);
          }
      },
  
      clear : function(){
          this.scriptField.setValue('');
          this.scriptField.focus();
      }
  
  });
  
  Ext.debug.LogPanel = Ext.extend(Ext.Panel, {
      autoScroll: true,
      region: 'center',
      border: false,
      style:'border-width:0 1px 0 0',
  
      log : function(){
          var markup = [  '<div style="padding:5px !important;border-bottom:1px solid #ccc;">',
                      Ext.util.Format.htmlEncode(Array.prototype.join.call(arguments, ', ')).replace(/\n/g, '<br/>').replace(/\s/g, '&#160;'),
                      '</div>'].join(''),
              bd = this.body.dom;
  
          this.body.insertHtml('beforeend', markup);
          bd.scrollTop = bd.scrollHeight;
      },
  
      clear : function(){
          this.body.update('');
          this.body.dom.scrollTop = 0;
      }
  });
  
  Ext.debug.DomTree = Ext.extend(Ext.tree.TreePanel, {
      enableDD:false ,
      lines:false,
      rootVisible:false,
      animate:false,
      hlColor:'ffff9c',
      autoScroll: true,
      region:'center',
      border:false,
  
      initComponent : function(){
  
  
          Ext.debug.DomTree.superclass.initComponent.call(this);
  
          // tree related stuff
          var styles = false, hnode;
          var nonSpace = /^\s*$/;
          var html = Ext.util.Format.htmlEncode;
          var ellipsis = Ext.util.Format.ellipsis;
          var styleRe = /\s?([a-z\-]*)\:([^;]*)(?:[;\s\n\r]*)/gi;
  
          function findNode(n){
              if(!n || n.nodeType != 1 || n == document.body || n == document){
                  return false;
              }
              var pn = [n], p = n;
              while((p = p.parentNode) && p.nodeType == 1 && p.tagName.toUpperCase() != 'HTML'){
                  pn.unshift(p);
              }
              var cn = hnode;
              for(var i = 0, len = pn.length; i < len; i++){
                  cn.expand();
                  cn = cn.findChild('htmlNode', pn[i]);
                  if(!cn){ // in this dialog?
                      return false;
                  }
              }
              cn.select();
              var a = cn.ui.anchor;
              this.getTreeEl().dom.scrollTop = Math.max(0 ,a.offsetTop-10);
              //treeEl.dom.scrollLeft = Math.max(0 ,a.offsetLeft-10); no likey
              cn.highlight();
              return true;
          }
  
          function nodeTitle(n){
              var s = n.tagName;
              if(n.id){
                  s += '#'+n.id;
              }else if(n.className){
                  s += '.'+n.className;
              }
              return s;
          }
  
          /*
          function onNodeSelect(t, n, last){
              return;
              if(last && last.unframe){
                  last.unframe();
              }
              var props = {};
              if(n && n.htmlNode){
                  if(frameEl.pressed){
                      n.frame();
                  }
                  if(inspecting){
                      return;
                  }
                  addStyle.enable();
                  reload.setDisabled(n.leaf);
                  var dom = n.htmlNode;
                  stylePanel.setTitle(nodeTitle(dom));
                  if(styles && !showAll.pressed){
                      var s = dom.style ? dom.style.cssText : '';
                      if(s){
                          var m;
                          while ((m = styleRe.exec(s)) != null){
                              props[m[1].toLowerCase()] = m[2];
                          }
                      }
                  }else if(styles){
                      var cl = Ext.debug.cssList;
                      var s = dom.style, fly = Ext.fly(dom);
                      if(s){
                          for(var i = 0, len = cl.length; i<len; i++){
                              var st = cl[i];
                              var v = s[st] || fly.getStyle(st);
                              if(v != undefined && v !== null && v !== ''){
                                  props[st] = v;
                              }
                          }
                      }
                  }else{
                      for(var a in dom){
                          var v = dom[a];
                          if((isNaN(a+10)) && v != undefined && v !== null && v !== '' && !(Ext.isGecko && a[0] == a[0].toUpperCase())){
                              props[a] = v;
                          }
                      }
                  }
              }else{
                  if(inspecting){
                      return;
                  }
                  addStyle.disable();
                  reload.disabled();
              }
              stylesGrid.setSource(props);
              stylesGrid.treeNode = n;
              stylesGrid.view.fitColumns();
          }
          */
  
          this.loader = new Ext.tree.TreeLoader();
          this.loader.load = function(n, cb){
              var isBody = n.htmlNode == document.body;
              var cn = n.htmlNode.childNodes;
              for(var i = 0, c; c = cn[i]; i++){
                  if(isBody && c.id == 'x-debug-browser'){
                      continue;
                  }
                  if(c.nodeType == 1){
                      n.appendChild(new Ext.debug.HtmlNode(c));
                  }else if(c.nodeType == 3 && !nonSpace.test(c.nodeValue)){
                      n.appendChild(new Ext.tree.TreeNode({
                          text:'<em>' + ellipsis(html(String(c.nodeValue)), 35) + '</em>',
                          cls: 'x-tree-noicon'
                      }));
                  }
              }
              cb();
          };
  
          //tree.getSelectionModel().on('selectionchange', onNodeSelect, null, {buffer:250});
  
          this.root = this.setRootNode(new Ext.tree.TreeNode('Ext'));
  
          hnode = this.root.appendChild(new Ext.debug.HtmlNode(
                  document.getElementsByTagName('html')[0]
          ));
  
      }
  });
  
  Ext.debug.ComponentNodeUI = Ext.extend(Ext.tree.TreeNodeUI,{
      onOver : function(e){
          Ext.debug.ComponentNodeUI.superclass.onOver.call(this);
          var cmp = this.node.attributes.component;
          if (cmp.el && cmp.el.mask && cmp.id !='x-debug-browser') {
              try { // Oddly bombs on some elements in IE, gets any we care about though
                  cmp.el.mask();
              } catch(e) {}
          }
      },
  
      onOut : function(e){
          Ext.debug.ComponentNodeUI.superclass.onOut.call(this);
          var cmp = this.node.attributes.component;
          if (cmp.el && cmp.el.unmask && cmp.id !='x-debug-browser') {
              try {
                  cmp.el.unmask();
              } catch(e) {}
          }
      }
  });
  
  Ext.debug.ComponentInspector = Ext.extend(Ext.tree.TreePanel, {
      enableDD:false ,
      lines:false,
      rootVisible:false,
      animate:false,
      hlColor:'ffff9c',
      autoScroll: true,
      region:'center',
      border:false,
  
      initComponent : function(){
          this.loader = new Ext.tree.TreeLoader();
          this.bbar = new Ext.Toolbar([{
              text: 'Refresh',
              handler: this.refresh,
              scope: this
          }]);
          Ext.debug.ComponentInspector.superclass.initComponent.call(this);
  
          this.root = this.setRootNode(new Ext.tree.TreeNode({
              text: 'Ext Components',
              component: Ext.ComponentMgr.all,
              leaf: false
          }));
          this.parseRootNode();
  
          this.on('click', this.onClick, this);
      },
  
      createNode: function(n,c) {
          var leaf = (c.items && c.items.length > 0);
          return n.appendChild(new Ext.tree.TreeNode({
              text: c.id + (c.getXType() ? ' [ ' + c.getXType() + ' ]': '' ),
              component: c,
              uiProvider:Ext.debug.ComponentNodeUI,
              leaf: !leaf
          }));
      },
  
      parseChildItems: function(n) {
          var cn = n.attributes.component.items;
          if (cn) {
              for (var i = 0;i < cn.length; i++) {
                  var c = cn.get(i);
                  if (c.id != this.id && c.id != this.bottomToolbar.id) {
                      var newNode = this.createNode(n,c);
                      if (!newNode.leaf) {
                          this.parseChildItems(newNode);
                      }
                  }
              }
          }
      },
  
      parseRootNode: function() {
          var n = this.root;
          var cn = n.attributes.component.items;
          for (var i = 0,c;c = cn[i];i++) {
              if (c.id != this.id && c.id != this.bottomToolbar.id) {
                  if (!c.ownerCt) {
                      var newNode = this.createNode(n,c);
                      if (!newNode.leaf) {
                          this.parseChildItems(newNode);
                      }
                  }
              }
          }
      },
  
      onClick: function(node, e) {
          var oi = Ext.getCmp('x-debug-objinspector');
          oi.refreshNodes(node.attributes.component);
          oi.ownerCt.show();
      },
  
      refresh: function() {
          while (this.root.firstChild) {
              this.root.removeChild(this.root.firstChild);
          }
          this.parseRootNode();
          var ci = Ext.getCmp('x-debug-compinfo');
          if (ci) {
              ci.message('refreshed component tree - '+Ext.ComponentMgr.all.length);
          }
      }
  });
  
  Ext.debug.ComponentInfoPanel = Ext.extend(Ext.Panel,{
      id:'x-debug-compinfo',
      region: 'east',
      minWidth: 200,
      split: true,
      width: 350,
      border: false,
      autoScroll: true,
      layout:'anchor',
      style:'border-width:0 0 0 1px;',
  
      initComponent: function() {
          this.watchBox = new Ext.form.Checkbox({
              id: 'x-debug-watchcomp',
              boxLabel: 'Watch ComponentMgr',
              listeners: {
                  check: function(cb, val) {
                      if (val) {
                          Ext.ComponentMgr.all.on('add', this.onAdd, this);
                          Ext.ComponentMgr.all.on('remove', this.onRemove, this);
                      } else {
                          Ext.ComponentMgr.all.un('add', this.onAdd, this);
                          Ext.ComponentMgr.all.un('remove', this.onRemove, this);
                      }
                  },
                  scope: this
              }
          });
  
          this.tbar = new Ext.Toolbar([{
              text: 'Clear',
              handler: this.clear,
              scope: this
          },'->',this.watchBox
          ]);
          Ext.debug.ComponentInfoPanel.superclass.initComponent.call(this);
      },
  
      onAdd: function(i, o, key) {
          var markup = ['<div style="padding:5px !important;border-bottom:1px solid #ccc;">',
                      'Added: '+o.id,
                      '</div>'].join('');
          this.insertMarkup(markup);
      },
  
      onRemove: function(o, key) {
          var markup = ['<div style="padding:5px !important;border-bottom:1px solid #ccc;">',
                      'Removed: '+o.id,
                      '</div>'].join('');
          this.insertMarkup(markup);
      },
  
      message: function(msg) {
          var markup = ['<div style="padding:5px !important;border-bottom:1px solid #ccc;">',
                      msg,
                      '</div>'].join('');
          this.insertMarkup(markup);
      },
      insertMarkup: function(markup) {
          this.body.insertHtml('beforeend', markup);
          this.body.scrollTo('top', 100000);
      },
      clear : function(){
          this.body.update('');
          this.body.dom.scrollTop = 0;
      }
  });
  
  Ext.debug.ColumnNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
      focus: Ext.emptyFn, // prevent odd scrolling behavior
  
      renderElements : function(n, a, targetNode, bulkRender){
          this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
  
          var t = n.getOwnerTree();
          var cols = t.columns;
          var bw = t.borderWidth;
          var c = cols[0];
  
          var buf = [
               '<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf ', a.cls,'">',
                  '<div class="x-tree-col" style="width:',c.width-bw,'px;">',
                      '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
                      '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow"/>',
                      '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on"/>',
                      '<a hidefocus="on" class="x-tree-node-anchor" href="',a.href ? a.href : "#",'" tabIndex="1" ',
                      a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '>',
                      '<span unselectable="on">', n.text || (c.renderer ? c.renderer(a[c.dataIndex], n, a) : a[c.dataIndex]),"</span></a>",
                  "</div>"];
           for(var i = 1, len = cols.length; i < len; i++){
               c = cols[i];
  
               buf.push('<div class="x-tree-col ',(c.cls?c.cls:''),'" style="width:',c.width-bw,'px;">',
                          '<div class="x-tree-col-text">',(c.renderer ? c.renderer(a[c.dataIndex], n, a) : a[c.dataIndex]),"</div>",
                        "</div>");
           }
           buf.push(
              '<div class="x-clear"></div></div>',
              '<ul class="x-tree-node-ct" style="display:none;"></ul>',
              "</li>");
  
          if(bulkRender !== true && n.nextSibling && n.nextSibling.ui.getEl()){
              this.wrap = Ext.DomHelper.insertHtml("beforeBegin",
                                  n.nextSibling.ui.getEl(), buf.join(""));
          }else{
              this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf.join(""));
          }
  
          this.elNode = this.wrap.childNodes[0];
          this.ctNode = this.wrap.childNodes[1];
          var cs = this.elNode.firstChild.childNodes;
          this.indentNode = cs[0];
          this.ecNode = cs[1];
          this.iconNode = cs[2];
          this.anchor = cs[3];
          this.textNode = cs[3].firstChild;
      }
  });
  
  Ext.debug.ObjectInspector = Ext.extend(Ext.tree.TreePanel, {
      id: 'x-debug-objinspector',
      enableDD:false ,
      lines:false,
      rootVisible:false,
      animate:false,
      hlColor:'ffff9c',
      autoScroll: true,
      region:'center',
      border:false,
      lines:false,
      borderWidth: Ext.isBorderBox ? 0 : 2, // the combined left/right border for each cell
      cls:'x-column-tree',
  
      initComponent : function(){
          this.showFunc = false;
          this.toggleFunc = function() {
              this.showFunc = !this.showFunc;
              this.refreshNodes(this.currentObject);
          };
          this.bbar = new Ext.Toolbar([{
              text: 'Show Functions',
              enableToggle: true,
              pressed: false,
              handler: this.toggleFunc,
              scope: this
          }]);
  
          Ext.apply(this,{
              title: ' ',
              loader: new Ext.tree.TreeLoader(),
              columns:[{
                  header:'Property',
                  width: 300,
                  dataIndex:'name'
              },{
                  header:'Value',
                  width: 900,
                  dataIndex:'value'
              }]
          });
  
          Ext.debug.ObjectInspector.superclass.initComponent.call(this);
  
          this.root = this.setRootNode(new Ext.tree.TreeNode({
              text: 'Dummy Node',
              leaf: false
          }));
  
          if (this.currentObject) {
              this.parseNodes();
          }
      },
  
      refreshNodes: function(newObj) {
          this.currentObject = newObj;
          var node = this.root;
          while(node.firstChild){
              node.removeChild(node.firstChild);
          }
          this.parseNodes();
      },
  
      parseNodes: function() {
          for (var o in this.currentObject) {
              if (!this.showFunc) {
                  if (Ext.isFunction(this.currentObject[o])) {
                      continue;
                  }
              }
              this.createNode(o);
          }
      },
  
      createNode: function(o) {
          return this.root.appendChild(new Ext.tree.TreeNode({
              name: o,
              value: this.currentObject[o],
              uiProvider:Ext.debug.ColumnNodeUI,
              iconCls: 'x-debug-node',
              leaf: true
          }));
      },
  
      onRender : function(){
          Ext.debug.ObjectInspector.superclass.onRender.apply(this, arguments);
          this.headers = this.header.createChild({cls:'x-tree-headers'});
  
          var cols = this.columns, c;
          var totalWidth = 0;
  
          for(var i = 0, len = cols.length; i < len; i++){
               c = cols[i];
               totalWidth += c.width;
               this.headers.createChild({
                   cls:'x-tree-hd ' + (c.cls?c.cls+'-hd':''),
                   cn: {
                       cls:'x-tree-hd-text',
                       html: c.header
                   },
                   style:'width:'+(c.width-this.borderWidth)+'px;'
               });
          }
          this.headers.createChild({cls:'x-clear'});
          // prevent floats from wrapping when clipped
          this.headers.setWidth(totalWidth);
          this.innerCt.setWidth(totalWidth);
      }
  });
  
  
  Ext.debug.StoreInspector = Ext.extend(Ext.tree.TreePanel, {
      enableDD:false ,
      lines:false,
      rootVisible:false,
      animate:false,
      hlColor:'ffff9c',
      autoScroll: true,
      region:'center',
      border:false,
  
      initComponent: function() {
          this.bbar = new Ext.Toolbar([{
              text: 'Refresh',
              handler: this.refresh,
              scope: this
          }]);
          Ext.debug.StoreInspector.superclass.initComponent.call(this);
  
          this.root = this.setRootNode(new Ext.tree.TreeNode({
              text: 'Data Stores',
              leaf: false
          }));
          this.on('click', this.onClick, this);
  
          this.parseStores();
      },
  
      parseStores: function() {
          var cn = Ext.StoreMgr.items;
          for (var i = 0,c;c = cn[i];i++) {
              this.root.appendChild({
                  text: c.storeId + ' - ' + c.totalLength + ' records',
                  component: c,
                  leaf: true
              });
          }
      },
  
      onClick: function(node, e) {
          var oi = Ext.getCmp('x-debug-objinspector');
          oi.refreshNodes(node.attributes.component);
          oi.ownerCt.show();
      },
  
      refresh: function() {
          while (this.root.firstChild) {
              this.root.removeChild(this.root.firstChild);
          }
          this.parseStores();
      }
  });
  
  // highly unusual class declaration
  Ext.debug.HtmlNode = function(){
      var html = Ext.util.Format.htmlEncode;
      var ellipsis = Ext.util.Format.ellipsis;
      var nonSpace = /^\s*$/;
  
      var attrs = [
          {n: 'id', v: 'id'},
          {n: 'className', v: 'class'},
          {n: 'name', v: 'name'},
          {n: 'type', v: 'type'},
          {n: 'src', v: 'src'},
          {n: 'href', v: 'href'}
      ];
  
      function hasChild(n){
          for(var i = 0, c; c = n.childNodes[i]; i++){
              if(c.nodeType == 1){
                  return true;
              }
          }
          return false;
      }
  
      function renderNode(n, leaf){
          var tag = n.tagName.toLowerCase();
          var s = '&lt;' + tag;
          for(var i = 0, len = attrs.length; i < len; i++){
              var a = attrs[i];
              var v = n[a.n];
              if(v && !nonSpace.test(v)){
                  s += ' ' + a.v + '=&quot;<i>' + html(v) +'</i>&quot;';
              }
          }
          var style = n.style ? n.style.cssText : '';
          if(style){
              s += ' style=&quot;<i>' + html(style.toLowerCase()) +'</i>&quot;';
          }
          if(leaf && n.childNodes.length > 0){
              s+='&gt;<em>' + ellipsis(html(String(n.innerHTML)), 35) + '</em>&lt;/'+tag+'&gt;';
          }else if(leaf){
              s += ' /&gt;';
          }else{
              s += '&gt;';
          }
          return s;
      }
  
      var HtmlNode = function(n){
          var leaf = !hasChild(n);
          this.htmlNode = n;
          this.tagName = n.tagName.toLowerCase();
          var attr = {
              text : renderNode(n, leaf),
              leaf : leaf,
              cls: 'x-tree-noicon'
          };
          HtmlNode.superclass.constructor.call(this, attr);
          this.attributes.htmlNode = n; // for searching
          if(!leaf){
              this.on('expand', this.onExpand,  this);
              this.on('collapse', this.onCollapse,  this);
          }
      };
  
  
      Ext.extend(HtmlNode, Ext.tree.AsyncTreeNode, {
          cls: 'x-tree-noicon',
          preventHScroll: true,
          refresh : function(highlight){
              var leaf = !hasChild(this.htmlNode);
              this.setText(renderNode(this.htmlNode, leaf));
              if(highlight){
                  Ext.fly(this.ui.textNode).highlight();
              }
          },
  
          onExpand : function(){
              if(!this.closeNode && this.parentNode){
                  this.closeNode = this.parentNode.insertBefore(new Ext.tree.TreeNode({
                      text:'&lt;/' + this.tagName + '&gt;',
                      cls: 'x-tree-noicon'
                  }), this.nextSibling);
              }else if(this.closeNode){
                  this.closeNode.ui.show();
              }
          },
  
          onCollapse : function(){
              if(this.closeNode){
                  this.closeNode.ui.hide();
              }
          },
  
          render : function(bulkRender){
              HtmlNode.superclass.render.call(this, bulkRender);
          },
  
          highlightNode : function(){
              //Ext.fly(this.htmlNode).highlight();
          },
  
          highlight : function(){
              //Ext.fly(this.ui.textNode).highlight();
          },
  
          frame : function(){
              this.htmlNode.style.border = '1px solid #0000ff';
              //this.highlightNode();
          },
  
          unframe : function(){
              //Ext.fly(this.htmlNode).removeClass('x-debug-frame');
              this.htmlNode.style.border = '';
          }
      });
  
      return HtmlNode;
  }();
  