var TreeUtil={prune:function(B,A){this.each(B,function(D,C){if(C==A&&D.children){delete D.children;D.children=[]}})},getParent:function(A,E){if(A.id==E){return false}var D=A.children;if(D&&D.length>0){for(var C=0;C<D.length;C++){if(D[C].id==E){return A}else{var B=this.getParent(D[C],E);if(B){return B}}}}return false},getSubtree:function(A,E){if(A.id==E){return A}for(var C=0,D=A.children;C<D.length;C++){var B=this.getSubtree(D[C],E);if(B!=null){return B}}return null},getLeaves:function(C,A){var D=[],B=A||Number.MAX_VALUE;this.each(C,function(F,E){if(E<=B&&(!F.children||F.children.length==0)){D.push({node:F,level:B-E})}});return D},eachLevel:function(A,F,C,E){if(F<=C){E(A,F);for(var B=0,D=A.children;B<D.length;B++){this.eachLevel(D[B],F+1,C,E)}}},each:function(A,B){this.eachLevel(A,0,Number.MAX_VALUE,B)},loadSubtrees:function(I,D){var E=this.getLeaves(I),G=E.length,F={};if(G==0){D.onComplete()}for(var C=0,A=0;C<G;C++){var H=E[C],B=H.node.id;F[B]=H;D.request(B,H.level,{onComplete:function(L,J){var K=J.children;F[L].children=K;if(++A==G){complete.onComplete()}}})}}};var TM={layout:{orientation:"h",vertical:function(){return this.orientation=="v"},horizontal:function(){return this.orientation=="h"},change:function(){this.orientation=this.vertical()?"h":"v"}},innerController:{onBeforeCompute:$empty,onAfterCompute:$empty,onCreateLabel:$empty,onPlaceLabel:$empty,onComplete:$empty,onBeforePlotLine:$empty,onAfterPlotLine:$empty,request:false},config:{orientation:"h",tips:false,titleHeight:13,rootId:"infovis",offset:4,levelsToShow:3,Color:{allow:false,minValue:-100,maxValue:100,minColorValue:[255,0,50],maxColorValue:[0,255,50]}},initialize:function(A){this.tree=null;this.shownTree=null;this.tips=null;this.controller=this.config=$merge(this.config,this.innerController,A);this.rootId=this.config.rootId;this.layout.orientation=this.config.orientation},toStyle:function(C){var A="";for(var B in C){A+=B+":"+C[B]+";"}return A},leaf:function(A){return A.children==0},createBox:function(B,D,A){if(!this.leaf(B)){var C=this.headBox(B,D)+this.bodyBox(A,D)}else{var C=this.leafBox(B,D)}return this.contentBox(B,D,C)},plot:function(C){var E=C.coord,B="";if(this.leaf(C)){return this.createBox(C,E,null)}for(var A=0,D=C.children;A<D.length;A++){B+=this.plot(D[A])}return this.createBox(C,E,B)},headBox:function(B,E){var A=this.config,D=A.offset;var C={height:A.titleHeight+"px",width:(E.width-D)+"px",left:D/2+"px"};return'<div class="head" style="'+this.toStyle(C)+'">'+B.name+"</div>"},bodyBox:function(B,F){var A=this.config,C=A.titleHeight,E=A.offset;var D={width:(F.width-E)+"px",height:(F.height-E-C)+"px",top:(C+E/2)+"px",left:(E/2)+"px"};return'<div class="body" style="'+this.toStyle(D)+'">'+B+"</div>"},contentBox:function(C,E,B){var D={};for(var A in E){D[A]=E[A]+"px"}return'<div class="content" style="'+this.toStyle(D)+'" id="'+C.id+'">'+B+"</div>"},leafBox:function(D,H){var C=this.config;var B=C.Color.allow&&this.setColor(D),G=C.offset,E=H.width-G,A=H.height-G;var F={top:(G/2)+"px",height:A+"px",width:E+"px",left:(G/2)+"px"};if(B){F["background-color"]=B}return'<div class="leaf" style="'+this.toStyle(F)+'">'+D.name+"</div>"},setColor:function(H){var C=this.config.Color,D=C.maxColorValue,A=C.minColorValue,E=C.maxValue,I=C.minValue,G=E-I,F=H.data[1].value.toFloat();var B=function(K,J){return(((D[K]-A[K])/G)*(J-I)+A[K]).toInt()};return[B(0,F),B(1,F),B(2,F)].rgbToHex()},enter:function(A){this.view(A.getParent().id)},out:function(){var A=TreeUtil.getParent(this.tree,this.shownTree.id);if(A){if(this.controller.request){TreeUtil.prune(A,this.config.levelsToShow)}this.view(A.id)}},view:function(E){var A=this.config,C=this;if(A.tips){this.tips.hide()}var B={onComplete:function(){C.loadTree(E);$(A.rootId).focus()}};if(this.controller.request){var D=TreeUtil;D.loadSubtrees(D.getSubtree(this.tree,E),$merge(this.controller,B))}else{B.onComplete()}},resetPath:function(B){var D=this.rootId;var A="#"+D+" .in-path";$$(A).each(function(G){G.removeClass("in-path")});var C=$(B.id);var E=function(H){var G=H.getParent();return G&&(G.id!=D)&&G};var F=(B)?E(C):false;while(F){F.getFirst().addClass("in-path");F=E(F)}},initializeBehavior:function(){var A=$$(".leaf",".head"),B=this;if(this.config.tips){this.tips=new Tips(A,{className:"tool-tip",showDelay:0,hideDelay:0})}A.each(function(C){C.oncontextmenu=$lambda(false);C.addEvents({mouseenter:function(E){var F=C.getParent().id;if(C.hasClass("leaf")){C.addClass("over-leaf")}else{if(C.hasClass("head")){C.addClass("over-head");C.getParent().addClass("over-content")}}if(F){var D=TreeUtil.getSubtree(B.tree,F);B.resetPath(D)}E.stopPropagation()},mouseleave:function(D){if(C.hasClass("over-leaf")){C.removeClass("over-leaf")}else{if(C.getParent().hasClass("over-content")){C.removeClass("over-head");C.getParent().removeClass("over-content")}}B.resetPath(false);D.stopPropagation()},mouseup:function(D){if(D.rightClick){B.out()}else{B.enter(C)}D.preventDefault();return false}})})},loadTree:function(A){$(this.rootId).empty();this.loadFromJSON(TreeUtil.getSubtree(this.tree,A))}};TM.SliceAndDice=new Class({Implements:TM,loadFromJSON:function(D){this.controller.onBeforeCompute(D);var B=$(this.rootId),C=this.config,E=B.offsetWidth,A=B.offsetHeight;var F={coord:{top:0,left:0,width:E,height:A+C.titleHeight+C.offset}};if(this.tree==null){this.tree=D}this.shownTree=D;this.compute(F,D,this.layout.orientation);B.set("html",this.plot(D));this.initializeBehavior();this.controller.onAfterCompute(D)},compute:function(G,P,E){var R=this.config,L=G.coord,O=R.offset,K=L.width-O,I=L.height-O-R.titleHeight,B=G.data,A=(B&&B.length>0)?P.data[0].value/B[0].value:1;var Q=(E=="h");if(Q){E="v";var H=(K*A).round(),J=I,N="height",F="top",D="left"}else{E="h";var J=(I*A).round(),H=K,N="width",F="left",D="top"}P.coord={width:H,height:J,top:0,left:0};var M=0,C=this;P.children.each(function(S){C.compute(P,S,E);S.coord[F]=M;S.coord[D]=0;M+=S.coord[N].toInt()})}});TM.Area=new Class({loadFromJSON:function(C){this.controller.onBeforeCompute(C);var B=$(this.rootId),D=B.offsetWidth,A=B.offsetHeight,H=this.config.offset,F=D-H,E=A-H-this.config.titleHeight;C.coord={height:A,width:D,top:0,left:0};var G=$merge(C.coord,{width:F,height:E});this.compute(C,G);B.set("html",this.plot(C));if(this.tree==null){this.tree=C}this.shownTree=C;this.initializeBehavior();this.controller.onAfterCompute(C)},computeDim:function(D,H,B,G,C){if(D.length+H.length==1){var A=(D.length==1)?D:H;this.layoutLast(A,B,G);return}if(D.length>=2&&H.length==0){H=[D[0]];D=D.slice(1)}if(D.length==0){if(H.length>0){this.layoutRow(H,B,G)}return}var F=D[0];if(C(H,B)>=C([F].concat(H),B)){this.computeDim(D.slice(1),H.concat([F]),B,G,C)}else{var E=this.layoutRow(H,B,G);this.computeDim(D,[],E.dim,E,C)}},worstAspectRatio:function(A,H){if(!A||A.length==0){return Number.MAX_VALUE}var B=0,I=0,E=Number.MAX_VALUE;for(var F=0;F<A.length;F++){var C=A[F]._area;B+=C;E=(E<C)?E:C;I=(I>C)?I:C}var G=H*H,D=B*B;return Math.max(G*I/D,D/(G*E))},avgAspectRatio:function(D,A){if(!D||D.length==0){return Number.MAX_VALUE}var F=0;for(var B=0;B<D.length;B++){var E=D[B]._area;var C=E/A;F+=(A>C)?A/C:C/A}return F/D.length},layoutLast:function(B,A,C){B[0].coord=C}});TM.Squarified=new Class({Implements:[TM,TM.Area],compute:function(I,F){if(!(F.width>=F.height&&this.layout.horizontal())){this.layout.change()}var A=I.children,C=this.config;if(A.length>0){this.processChildrenLayout(I,A,F);for(var E=0;E<A.length;E++){var D=A[E].coord,G=C.offset,H=D.height-(C.titleHeight+G),B=D.width-G;var F={width:B,height:H,top:0,left:0};this.compute(A[E],F)}}},processChildrenLayout:function(H,A,E){var B=E.width*E.height;var I=H.data[0].value.toFloat();for(var D=0;D<A.length;D++){A[D]._area=B*A[D].data[0].value.toFloat()/I}var C=(this.layout.horizontal())?E.height:E.width;A.sort(function(K,J){return(K._area<=J._area)-(K._area>=J._area)});var G=[A[0]];var F=A.slice(1);this.squarify(F,G,C,E)},squarify:function(B,D,A,C){this.computeDim(B,D,A,C,this.worstAspectRatio)},layoutRow:function(B,A,C){if(this.layout.horizontal()){return this.layoutV(B,A,C)}else{return this.layoutH(B,A,C)}},layoutV:function(A,H,E){var I=0;A.each(function(J){I+=J._area});var B=I/H,F=0;for(var C=0;C<A.length;C++){var D=A[C]._area/B;A[C].coord={height:D,width:B,top:E.top+(H-D-F),left:E.left};F+=D}var G={height:E.height,width:E.width-B,top:E.top,left:E.left+B};G.dim=Math.min(G.width,G.height);if(G.dim!=G.height){this.layout.change()}return G},layoutH:function(A,G,D){var I=0;A.each(function(J){I+=J._area});var H=I/G,E=D.height-H,B=0;for(var C=0;C<A.length;C++){A[C].coord={height:H,width:A[C]._area/H,top:E,left:D.left+B};B+=A[C].coord.width}var F={height:D.height-H,width:D.width,top:D.top,left:D.left};F.dim=Math.min(F.width,F.height);if(F.dim!=F.width){this.layout.change()}return F}});TM.Strip=new Class({Implements:[TM,TM.Area],compute:function(I,F){var A=I.children,C=this.config;if(A.length>0){this.processChildrenLayout(I,A,F);for(var E=0;E<A.length;E++){var D=A[E].coord,G=C.offset,H=D.height-(C.titleHeight+G),B=D.width-G;var F={width:B,height:H,top:0,left:0};this.compute(A[E],F)}}},processChildrenLayout:function(D,C,H){var E=H.width*H.height;var F=D.data[0].value.toFloat();C.each(function(I){I._area=E*I.data[0].value.toFloat()/F});var B=(this.layout.horizontal())?H.width:H.height;var G=[C[0]];var A=C.slice(1);this.stripify(A,G,B,H)},stripify:function(B,D,A,C){this.computeDim(B,D,A,C,this.avgAspectRatio)},layoutRow:function(B,A,C){if(this.layout.horizontal()){return this.layoutH(B,A,C)}else{return this.layoutV(B,A,C)}},layoutV:function(A,H,E){var I=0;A.each(function(J){I+=J._area});var B=(I/H),F=0;for(var C=0;C<A.length;C++){var D=(A[C]._area/B);A[C].coord={height:D,width:B,top:E.top+(H-D-F),left:E.left};F+=D}var G={height:E.height,width:E.width-B,top:E.top,left:E.left+B,dim:H};return G},layoutH:function(A,G,D){var I=0;A.each(function(J){I+=J._area});var H=I/G,E=D.height-H,B=0;for(var C=0;C<A.length;C++){A[C].coord={height:H,width:A[C]._area/H,top:E,left:D.left+B};B+=A[C].coord.width}var F={height:D.height-H,width:D.width,top:D.top,left:D.left,dim:G};return F}});