Login

Search Javascript Folder

/ root / Products / Root / AllJavascript

All The Javascript So it is searchable.
  

Get

1    
2   function slideDownTo(key){
3      var node = getNode(key);
4      dispatchOver(node);
5   } 
6    
7    function displaySlideNamed(aName){
8        pinned = null;
9        var node = getNode(aName);
10       dispatchOver(node);
11   
12    }
13    
14    function getNode(nodeName){
15         return view.graph.nodes(nodeName);
16    }
17   
18    function setRatio(node,score){
19        node.data.ratio = score;
20    }
21        
22    function getConferenceKey(slide){
23       return slide.conference.id;
24   }
25   
26    function getConference(slide){
27       return slide.conference;
28   }
29   
30   function localRebuild(){
31        return true;
32     }
33   
34   
35   
36   
37     function getConferenceName(node){
38         if (getClass(node)== 'Conference'){
39             return node.title;
40         }
41         return node.conference.title;
42     }
43     
44   function isRoot(node){
45       if (! ('parent' in node) ||
46          (node.parent === null)){
47           return true;
48       }
49       return false;
50   }
51   
52   
53   
54        
55     function getTitle(item){
56         return item.title;
57     }
58     
59     function getBranchSize(item){
60         return item.branchSize;
61     }
62     
63     
64      function getDescription(item){
65         return item.description;
66     }
67        function getUpVotes(item){
68         return item.upVotes;
69     }
70        function getDownVotes(item){
71         return item.downVotes;
72     }
73     
74     function getClass(slide){
75         return slide.class;
76     }
77     
78     
79    
80    function addChildArray (item,index){
81        item.children = [];
82    }
83    
84    function getKey(item,array){
85        return item.id;
86    }
87     function getClass(item,array){
88        return item.class;
89    }
90    
  

Move Commands For Destkopt

91    function moveUp(){
92               moveTo(homeNode.parent);
93   }
94   
95   function moveDown(childIndex){
96           moveTo (homeNode.children[childIndex]);
97   }
98   
99   function moveToLast(numberOfSiblings){
100           moveTo (homeNode.parent.children[numberOfSiblings -1]);
101   }
102   
103   function moveToFirst(){
104       moveTo (homeNode.preant.children[0]); 
105   }
106   
107   function moveRight(offset){
108           moveTo (homeNode.parent.children[offset+1]); 
109   }
110   
111   function moveLeft(offset){
112        moveTo (homeNode.parent.children[offset-1]);
113   }
  

addDescription

114     
115     /*
116     function addDescription (description){
117        $('#description').remove();
118        var result =' <span id = "description" style= "position:absolute; bottom:10px;'   +
119        'z-index: -1; left: 33%; padding: 20px; ">'+
120        description + 
121        '</span>';
122    
123        $('#graph-container').append(result);
124    }
125    */
  

addList

126     function renderList(node){
127         if (node.children.length ===0){
128             return '';
129         }
130         result = '<center>';
131         result +='<b>SubCategories:</b><br>';
132         for (var i = 0  i< node.children.length; i++){
133             result +=  node.children[i].title + "<br>";
134         }
135         result += '</center>';
136         return result;
137     }
138     
139       function renderList2(node){
140         result ='<ul>';
141         for (var i = 0  i< node.children.length; i++){
142             result += "<li>" + node.children[i].title + "</li>";
143         }
144         result += "</ul>";
145         return result;
146     }
147     /*
148     function deleteNodePlusChildren(){
149              $('#NodePlusChildren').remove();
150     }
151     function renderNodePlusChildren (node){
152        var result ='<div id = "NodePlusChildren" ' +
153        'style= "position:fixed;'+
154        'bottom:' + node.children.length + 'em;  '   +
155        'left: 30%; z-index: -1;">' +
156        "<p>" + node.title + "</p>"+ 
157         renderList(node)+
158        '</div>';
159        $('#graph-container').append(result);
160    }
161    */
  

camera

162    var baseX = 0;
163    var baseY = -($('#graph-container')[0].clientWidth)/4
164   ;
165     function cameraGoToOrigin(){
166    view.cameras[0].goTo({x:baseX, y: baseY, ratio:1, angle: 1.55});
167    }
168    
169    //NOT WORKING
170    function cameraGoToNode(node){
171         view.cameras[0].goTo({x:node.x , y: node.y ,  angle:node.angle});
172        
173    }
174   
  

childFunctions

175    
176   
177   function getChildIndex(node){
178      var childIndex = 0;    
179             if ('previousChildIndex' in node){
180                childIndex = node.previousChildIndex;
181              }
182      return childIndex;
183   }
184    
185        
  

first

186     var view;
187     var homeNode;
188     var root;
189     var landingPage;
190     var lastHover = null;
191     isMobile = false;
192   
193   
194   
195   
196   
197   
198    var mySettings =  {
199          animationsTime: 500,
200        drawLabels: true,
201        drawEdgeLabels: true,
202         zoomMax : 4,
203         singleHover: false,
204       doubleClickEnabled: false,
205       enableNodeHovering: true,
206           labelSizeRatio: 0,
207       labelThreshold: 1,
208       minNodeSize: 1,
209       maxNodeSize: 4
210     };
211     
212    function myCallback(arg){
213        view  = arg;
214        var nodes = view.graph.nodes();
215        nodes.forEach(addChildArray);
216        nodes.forEach (setParent);
217        nodes.forEach(zeroPosition);
218        //nodes.forEach(setLabels);
219        //MUST BE AFTER SET PARENT
220        nodes.forEach(setConferences);
221      
222     
223    
224   
225        
226        
227        root = getNode(rootName);
228        root.x=0; 
229        root.y=0;
230        root.share = 2*Math.PI;
231        root.angle = 0;
232     
233   
234        var row = root.children;
235        var radius = 1;
236        
237        while (row.length > 0){
238            
239            calculateChildPositions(row,radius ); 
240            row = rowItems(row);
241            radius ++ 
242         }
243         cameraGoToOrigin();
244   view.bind('overNode', overNode);
245       view.bind('outNode', outNode);
246   view.bind('overNodes', overNodes);
247       view.bind('outNodes', outNodes);
248       view.bind('clickNode', clickNode);
249       
250        view.refresh();
251            
252           homeNode= getNode(homeNodeKey);
253          landingPage = homeNode;
254       dispatchOver(homeNode);
255            pinned = homeNode;
256   
257    } //END OF CALLBACK
258   
259   
260    sigma.parsers.json(deskTopJson, {
261     container: 'graph-container',
262     settings: mySettings
263   },
264     myCallback);
265    
266    
267   
  

hasChildren

268    function hasChildren(node){
269        if (node.children.length > 0){
270            return true;
271        }
272        return false;
273        
274    }
  

hover

275   var pinned = null;
276   
277   function deletePin(node){
278       delete pinned.data.pinned;
279       pinned = null;
280   }
281   
282      
283    function leavePinnedNode(){
284         var pin = pinned;
285            deletePin (pin);
286            outNodeCore(pin);
287            view.refresh();
288    }  
289    
290    function clickNode(e){
291         var node = e.data.node;
292         clickNodeCore(node);
293    }
294    
295    //was e,bide
296    function clickNodeCore (node){
297         //Clicking on Pinned Node
298        if (node == pinned){
299          deletePin(pinned);
300            node.label = node.title;
301           newHomeNode(node);
302            view.refresh();
303        }
304        // CLICKING ON A DIFFERENT NODE
305        else if (pinned){
306            leavePinnedNode();
307        }
308        else{
309            overNodeCore(node);
310            pinned = node;
311            node.data.pinned = true;
312            node.label = 'PINNED: '+ node.title;
313            view.refresh();
314        }
315        
316    }
317    
318    
319    
320    var hoverNodes= {};
321   
322    function overNode(e) {
323              if (pinned){
324               return;
325           }
326           var node = e.data.node;
327           overNodeCore(node);
328    }
329    
330   function overNodes(e){
331             if (pinned){
332               return;
333           }
334       for (var i = 0; i < e.data.nodes.length; i++){
335           var node = e.data.nodes [i];
336           overNodeCore(node);
337    }
338   }
339   
340   function deleteOldHovers(){
341            for (var key in hoverNodes){
342                var item = hoverNodes[key];
343                 hideLabel(item);
344                 if (item.conference){
345                     hideLabel(item.conference);
346                 }
347               delete hoverNodes[key];
348          }
349   }
350   var lastOverNode=null;
351   var lastOutNode = null;
352   var lastNodeEvent=null;
353   function  overNodeCore(node){
354     
355           showLabel (node);
356          if ((lastOverNode== node)&&
357              (lastNodeEvent =="overNode")){
358                  return;
359              }
360           //if (lastOverNode){
361           //hideLabel(lastOverNode);
362          //}
363           lastOverNode = node;
364           lastNodeEvent = "overNode";
365               deleteOldHovers();
366   
367           showLabel (node);
368           newHomeNode(node);
369           possiblyLoadContent(node);
370           hoverNodes [node.id]= node;
371   }
372    
373    function outNode(e){
374               if (pinned){
375               return;
376           }
377            var node = e.data.node;
378         outNodeCore(node);
379   }
380   
381   function outNodes(e){
382          if (pinned){
383               return;
384           }
385       for (var i = 0; i < e.data.nodes.length; i++){
386            var node = e.data.nodes [i];
387           outNodeCore (node);
388       }
389   }
390   
391   function outNodeCore(node){
392   
393              if ((lastOutNode== node)&&
394              (lastNodeEvent =="outNode")){
395                  return;
396              }
397              hideLabel(node);
398             view.refresh();
399           //deleteOldHovers();
400           if (node.conference){
401                     hideLabel(node.conference);
402                 }
403           lastOutNode = node;
404           lastNodeEvent = "outNode";
405      
406    }
407    
408    
  

initialize

409      
410    function setParent(item,index){
411        item.data= {};
412        var parent = item.parent;
413        if (item.id == rootName){
414            item.parent = null;
415            return;
416        }
417        parent = getNode (item.parent);
418        item.parent = parent;
419        item.parent.children.push (item);
420       view.graph.addEdge({source:parent.id, 
421                      target:item.id,
422                      label:"Hello",
423                 id:(item.id + parent.id), size: 1});
424       if (item.class == 'Conference'){
425           item.data.talks = [];
426       }
427    }
428    function setConferences(node,index){
429        if (getClass(node) == 'Video'){
430           node.conference = getNode(node.conference);
431           node.conference.data.talks.push(node);
432           /*
433           if (node.parent != node.conference){
434               view.graph.addEdge({source:node.id, 
435                         target:node.conference.id, 
436                         id:(node.id + node.conference.id), 
437                         size: 1,
438                         hidden:true
439           });
440          
441           }
442           */
443   
444       }
445   }    
446    function setLabels(item,index){
447      //  item.label = item.title;
448    }
449    
  

loadContent

450   function possiblyLoadContent(node){
451            lastHover = node;
452      setTimeout (maybeLoadContent,400,node);
453   }
454   
455   function maybeLoadContent(node){
456        if (lastHover == node){
457           addLinks(node);
458          loadRemoteContent(node);
459           return;
460       }
461   }
462   
463   var oldVideoNode=null;
464   var oldConferenceNode = null;
465   function addLinks(node){
466       //if ('talks' in node){
467       //    addConferenceLinks(node);
468       //}
469       if ('conference' in node){
470          addVideoLink (node);                    
471       }
472       view.refresh();
473   }
474    
475   function addConferenceLinks(node){
476           dropConferenceLinks (oldVideoNode);
477           oldConferenceNode = node;
478           node.data.hasConferenceLink = true;
479   
480           for (var i = 0  i < node.talks.length; i++){
481               var talk = node.talks[i];
482               var name = node.id + talk.id;
483               if (!view.graph.edges(name)){
484                  view.graph.addEdge({source:node.id, 
485                               target:talk.id, 
486                              id:name, 
487                              size: 1});
488           } 
489           }
490   } 
491   
492   function addVideoLink(node){
493           dropVideoLink (oldVideoNode);
494           oldVideoNode = node;
495           var name = node.id + node.conference.id;
496           if (!view.graph.edges(name)){
497              node.data.hasVideoLink = true;
498              //showLabel(node.conference);
499              view.graph.addEdge({source:node.id, 
500                               target:node.conference.id, 
501                              id:name, size: 1});
502           }      
503   } 
504   
505   function dropConferenceLink(conference){
506       if (! conference){
507           return;
508       }
509       if (conference.data.hasConferenceLink){
510           node.data.hasConferenceLink = false;  
511           for (var i=0; i<conference.talks.length; i++ ){
512              var name = conference.id + conference.talks[i];
513              view.graph.dropEdge(name);
514           }
515           view.refresh();
516   
517       }
518   }
519   
520   
521   function dropVideoLink(node){
522   
523       if (! node){
524           return;
525       }
526       if (node.data.hasVideoLink){
527           node.data.hasVideoLink = false;   
528           var name = node.id + node.conference.id;
529           view.graph.dropEdge(name);
530           view.refresh();
531   
532       }
533   }
534   
535   function newHomeNode (node){
536          homeNode = node;
537          showLabel(node);
538       saveCurrentURL();
539      // $("#arrows").html(arrows(node));
540       $("#text").html(renderSlide(node));
541       //postRender();
542   
543   }
544        
545            
546   
547    function errorF( jqXHR, textStatus, errorThrown ){
548       console.log ("AJAX ERROR", jqXHR, textStatus, errorThrown );
549   }
550   
551   //after slide load
552   function loadRemoteContent(node){
553       var url = "/" + getKey(node) + "/content";
554       divName = "#" + getKey(node) + "-content";
555         $.ajax({url: url, cache: false, 
556         error: errorF,
557         success: function(result){
558           $(divName).html(result);
559           resizeVideos(0,0,"#text");
560       }
561         });
562       
563   }
564    
565   
566      
  

moveTo

567    var currentNode=null;
568   function moveTo(node){
569       pinned = null;
570      
571       if (currentNode){
572               dispatchOut (currentNode);
573       }
574       dispatchOver(node);
575   }
576   
577   function hideLabel(node){
578            node.label = "";
579   }
580   function dispatchOut(node){
581           var data = {};
582           data.node = currentNode;
583          view.renderers[0].dispatchEvent('outNode',data);
584   }
585   function showLabel(node){
586           node.label=node.title;
587   }
588   function dispatchOver(node){
589          view.renderers[0].dispatchEvent('overNode',{node});
590   }
  

positions

591     
592    function nextItem(array,index){
593        if (index == array.length -1){
594            return array[0];
595        }
596        return array[index+1];
597    }
598    function previousItem(array,index){
599        if (index === 0){
600            return array [array.length -1];
601        }
602        return array [index-1];
603   }
604   
605   function average (angle1, angle2,radius){
606           if ((angle1 - angle2) > Math.PI){
607            
608              angle2=angle2 + 2*Math.PI;
609              //return angle1;
610              return average (angle1, angle2, radius);
611           } 
612           
613           if ((angle1 - angle2) > 1){
614              return angle1 - (0.333/radius);
615           }  
616           
617           if ((angle2 - angle1) > Math.PI){
618              
619                angle2= angle2 - 2*Math.PI;
620                return average (angle1, angle2, radius);      
621           }
622           if ((angle2 - angle1) > 1){
623              return angle1 + (0.3333/radius);
624       }
625       return (angle1 + angle2 ) /2.0;
626   }
627   
628   
629   //Furst we sgikd uteratue iver tge cgukdreb, 
630   //tgeb iver tge oarebt arrat,  
631   // So there should be two functions called from the calling function. 
632   //But not that big a priority. 
633    function calculateChildPositions (row,radius){
634        var i, item, arent, siblings, length, offset, share;
635        var angle, parentAngle,itemIndex,  delta;
636        var first, last, previous, previousAngle, next, nextAngle;
637        var j, ratio;
638        var rowLength= row.length;
639        var maxDelta = 0;
640        var minDelta = 0;
641        for (i = 0  i<rowLength;i ++ ){
642             item = row [i]; 
643             parentAngle= item.parent.angle;
644             siblings = item.parent.children;
645             length = siblings.length;
646             offset = length /2;
647             share =  item.parent.share/length;
648             item.share = share;
649             itemIndex = siblings.indexOf(item);
650             delta = (itemIndex -offset) * share 
651             angle = parentAngle + delta;
652             onePosition(item, angle, radius);
653            }
654             
655            if (radius < 2) {
656              return;
657          }
658          
659         for (i = 0  i<rowLength;i ++ ){
660                 item = row [i]; 
661                 siblings = item.parent.children;
662                 length= siblings.length;
663                 itemIndex = siblings.indexOf(item);  
664   
665                 //IF there is nothing on the other side, 
666                 //this grabs an item from this side of the circle
667                 //so the angle is reversed. 
668                 //we need to check that the first item is before the 
669                 //current item. 
670                 //we need to check that the last item, is after the current 
671                 //item.  
672                 if (itemIndex === 0){
673                     previous = previousItem (row,i);
674                     previousAngle = previous.angle;
675                     first = average (item.angle, previousAngle,radius);
676   
677                 }
678                 if (itemIndex == siblings.length -1 ){
679                     next = nextItem(row,i);
680                     nextAngle = next.angle;
681                     last = average (item.angle, nextAngle,radius); 
682                 
683   
684                     for (j=0 j< length; j++){
685                         item = siblings [j];
686                         delta = last - first;
687                         offset = length /2;
688                         ratio = (j) /length;
689                         if (length ==1){
690                             ratio = 0.5;
691                         }
692                         angle = first + (delta * ratio);
693                       onePosition(item, angle, radius);
694                     }
695                 }
696   
697         }
698   
699             
700   }
701   
702     function onePosition( item,angle,radius) {
703        item.angle = angle;
704       item.x=radius * Math.cos(angle);
705       item.y=  radius * Math.sin(angle);
706    } 
707    
708    
709    function randomPosition(item, index) {
710       item.x=Math.random () +1;
711       item.y=Math.random () +1;
712    }
713    function zeroPosition(item, index) {
714       item.x=0;
715       item.y=0;
716    }
  

renderSearchButton

717    function renderSearchOption(node){
718             if (! isMobile){
719             return "" +
720               lili('<a href="https://PythonLinks.info/search">Search</a>');
721             }
722             else{ 
723                 return lili('<a onclick ="showSearch()">Search</a>');
724           
725              }
726              
727    }
728    
  

showsearch

729     function showSearch(){}
  

traverse

730   
731    
732    function rowItems(rowArray){
733        var result = [];
734        for (var i=0  i<rowArray.length;i++){
735            result = result.concat(rowArray[i].children);
736        }
737        return result;
738    } 
  

ChildFunctions

739      
740    
741    function getChildIndex(homeNode){
742      var childIndex = 0;    
743             if (homeNode.hasOwnProperty('previousChildIndex')){
744                childIndex = homeNode.previousChildIndex;
745              }
746      return childIndex;           
747    }           
  

SlideUpOrDown

748    
749      function hideDivLater(){
750       $.fn.fullpage.destroy('all');
751   }   
752   
753    function showSearch(){  
754        loadOneSlide();
755        $("#searchDiv").slideDown(400);
756            $("#browse").slideUp(400);
757        setTimeout(hideDivLater,400);
758        $('body').scrollTop(0);
759       if (homeNode.data.class == 'Conference'){
760            oldSearchString="asdfasdfkjhae";
761            currentSearchString="asdfasdfkjhae";
762            $("input[name=search]").val(homeNode.data.title);
763            myKeyUpCore(homeNode.data.title);
764        } 
765          setFocus();
766    }
767    
768    function setFocus (){ $("#search").focus();}
769      
770     function resetHeight(){
771        searchDiv.style.height="auto";
772   }
773    
774      function showBrowser(){
775       $("#browse").slideDown(400);
776       $("#searchDiv").slideUp(400);
777        setTimeout (resetHeight,400);
778       $('#fullpage').fullpage(fullPageArguments);
779       setTimeout(reload,1000);
780   
781        
782    }
783    
784      function searchClick(aNode){
785          var duration = 400;
786            $("#browse").slideDown(duration);
787       $("#searchDiv").slideUp(duration);
788        homeNode = aNode;
789         saveCurrentURL();
790        displaySlide(homeNode);
791        //setTimeout(reload,duration);
792    }
793    
794   
795         
796   
797         
798    
  

createSlides

799   function renderVerticalSlides(){
800       
801               var i,slide;  
802               var result = "";
803               for (i = 0  i < verticalSlides.length; i++){
804                       slide =renderVerticalSlide (verticalSlides[i],i);
805                        result += slide;
806               }
807               return result;
808               
809   }   
810   
811   function renderHorizontalSlides(){
812        
813               var j;     
814               var result = ""; 
815               for (j = 0  j < horizontalSlides.length; j++){
816                         slide =renderHorizontalSlide (horizontalSlides[j],j);
817                         result += slide;
818                       }
819               return result;            
820       
821               }
822               
823   
  

renderSlides

824    function goToChat(item){
825         
826       var href = "/" + item + "/chat";
827             window.open(href);
828   
829    }
830    
831    
832    
833   
  

renderVerticalSlide

834    function renderHorizontalSlide(slide,index){ 
835       var result = "";
836       result += "<div " +
837       " id = \"slide " + slide.key + "\" "+
838       "class=\"slide";
839       if (slide == homeNode)  {
840               result +=" active";
841           }
842   
843       result +="\">";
844       result += '<div style="width: calc(100% - 20px);"' +
845                 'id="' + slide.key + "-page" + '">';
846                 
847       result += renderSlide(slide,index);
848       result += "</div>";
849       result += "</div>";
850       return result;
851    }
852    
853    
854    function renderVerticalSlide(slide, index){
855           var result = "";
856           result += "<div class=\"section ";
857           if (slide == homeNode)  {
858               result +="active ";
859           }
860          //       result += " style=\"background-color:" +
861          //   (parents(slide).length & 1) ? '#ccc': '#fff'+ ";\"";
862           result +="\">";
863              if (slide == homeNode)  {
864               result += renderHorizontalSlides();  
865            }
866            else {
867               result += renderSlide(slide,0);
868            }
869         
870           result += "</div>";
871           return result;
872    }
873    
  

clickNode

874     function clickNode(webPageName){
875        var key = webPageName.key;
876         homeNode=tree.getNodeByKey(key);
877        popSlides(homeNode);
878    }
879    
880     window.addEventListener('popstate', function(event) {
881   clickNode(event.state);
882     
883   });
  

get

884   function slideDownTo(key){
885       var nextNode=tree.getNodeByKey(key);
886       var index = homeNode.children.indexOf(nextNode);
887       homeNode.previousChildIndex=index;
888      goDown();
889   } 
890   
891    function setRatio(node,score){
892        node.data.ratio = score;
893    }
894        
895    function getConferenceKey(slide){
896       return slide.data.conference;
897   }
898   
899    function getConference(slide){
900       return getNode(slide.data.conference);
901   }
902   
903   function localRebuild(){
904          $.fn.fullpage.reBuild();
905        return true;
906     }
907   
908   
909   function getNode(key){
910          return tree.getNodeByKey(key);
911   }
912   
913     function getConferenceName(node){
914         return node.data.conference;
915     }
916     
917   function isRoot(node){
918       if (getKey(node)==rootName){
919           return true;
920       }
921       return false;
922   }
923        
924     function getTitle(item){
925         return item.data.title;
926     }
927     
928     function getBranchSize(item){
929         return item.data.branchSize;
930     }
931     
932     
933      function getDescription(item){
934         return item.data.description;
935     }
936        function getUpVotes(item){
937         return item.data.upVotes;
938     }
939        function getDownVotes(item){
940         return item.data.downVotes;
941     }
942     
943     function getClass(slide){
944         return slide.data.class;
945     }
946     
947   
948    
949    function getKey(item,array){
950        return item.key;
951    }
952     function getClass(item,array){
953        return item.data.class;
954    }
955     
  

getHorizontalAndVerticalSlides

956   var horizontalSlides, verticalSlides; 
957       var verticalIndex;
958   var horizontalIndex;
959   
960   function setSlides(aNode){
961       setSingleSlide();
962   }    
963   
964   function setSingleSlide(){
965       verticalSlides = [homeNode];
966       horizontalSlides = [homeNode];
967        verticalIndex = 0;
968       horizontalIndex = 0;
969   }
970   function setUpSlides(){
971       verticalSlides = [homeNode.parent,homeNode];
972       horizontalSlides = [homeNode];
973        verticalIndex = 1;
974       horizontalIndex = 0;
975   }
976   function setDownSlides(){
977       var childIndex = getChildIndex(homeNode);
978       verticalSlides = [homeNode,homeNode.children[childIndex]];
979       horizontalSlides = [homeNode];
980        verticalIndex = 0;
981       horizontalIndex = 0;
982   }
983   function setRightSlides(){
984       var hIndex = homeNode.parent.children.indexOf(homeNode);
985       verticalSlides = [homeNode];
986       horizontalSlides = [homeNode, homeNode.parent.children[hIndex+1]];
987        verticalIndex = 0;
988       horizontalIndex = 0;
989   }
990   function setLeftSlides(){
991       var hIndex = homeNode.parent.children.indexOf(homeNode);
992       verticalSlides = [homeNode];
993       horizontalSlides = [homeNode.parent.children[hIndex-1],homeNode];
994        verticalIndex = 0;
995       horizontalIndex = 1;
996   }
997   
998   
999   /*
1000   THis was the old one. 
1001   function setSlides(aNode){
1002       verticalSlides = listOfVerticalSlides(aNode);
1003       horizontalSlides = listOfHorizontalSlides(aNode);
1004    
1005       verticalIndex = verticalSlides.indexOf(homeNode);
1006       horizontalIndex = horizontalSlides.indexOf(homeNode);
1007   }
1008   */
1009   
1010   function listOfVerticalSlides(homeNode){
1011       var result = [];
1012       if (homeNode.parent.parent !== null){
1013           result.push (homeNode.parent);
1014       }
1015       result.push (homeNode);
1016       
1017       if (hasChildren(homeNode)){
1018             var childIndex = getChildIndex(homeNode);
1019             var child=homeNode.children[childIndex];
1020              result.push(child);
1021       }
1022       return result;
1023    }
1024    
1025    
1026    function listOfHorizontalSlides(aNode){
1027        var children = aNode.parent.children;
1028        var index =children.indexOf(aNode);
1029        var result = [];
1030        if (index >0){
1031            result.push (children[index-1]);
1032        }
1033     
1034        result.push (aNode);
1035       
1036        if (index < children.length -1){
1037            result.push (children[index + 1]);
1038        }
1039        return result;
1040    }
1041    
1042   
  

getPage

1043    function getPage(){
1044        handle = '';
1045        var result = $('#' + homeNode.key + "-page" ).html();
1046        handle = 'lozinski';
1047        return result;
1048    }
  

hasChildren

1049     
1050    function hasChildren(homeNode){
1051      
1052       if (homeNode.hasOwnProperty ('children') &&
1053            (homeNode.children !== null) &&
1054           (homeNode.children.length > 0)){
1055               return true;
1056           }
1057        return false;    
1058    }
1059        
  

initialize

1060   var landingPage = null;
1061   
1062   var  parameters =    {
1063          extensions: ["filter"],
1064    quicksearch: true,
1065   
1066    filter: {
1067    autoApply: true,  // Re-apply last filter if lazy data is loaded
1068    counter: true,  // Show a badge with number of matching child nodes near parent icons
1069    fuzzy: false,  // Match single characters in order, e.g. 'fb' will match 'FooBar'
1070    hideExpandedCounter: true,  // Hide counter badge, when parent is expanded
1071    highlight: true,  // Highlight matches by wrapping inside &lt;mark&gt; tags
1072    mode: "hide",  // Grayout unmatched nodes (pass "hide" to remove unmatched node instead)
1073    autoExpand: true,
1074    leavesOnly:false
1075    },
1076   
1077   
1078    treeInit: function(ctx){
1079                this._superApply(ctx);
1080            },
1081    
1082          init:  function(arg1,arg2) {
1083                debugger;
1084                tree=  arg2.tree;
1085     homeNode=arg2.tree.getNodeByKey(webPageName);
1086     tree.homeNode=homeNode;
1087     landingPage = homeNode;
1088     root=arg2.tree.getRootNode().children[0];
1089     saveCurrentURLAndSearch();
1090         displaySlide(homeNode);
1091          },
1092     
1093           source: $.ajax({
1094               url: mobileJson,
1095               dataType: "json"
1096            }),
1097            
1098            
1099             click: function(event, data) {
1100                  var aNode = data.node;
1101                   searchClick(aNode);
1102            return false;
1103            
1104            },
1105    };
1106    
1107   $("#tree").fancytree(parameters);
1108   
  

initializeslides

1109   function pleaseLoadContent (anchorLink, index, slideAnchor, slideIndex){
1110       loadContent ();
1111   }
1112   function smallLoadContent (anchorLink, index, slideAnchor, slideIndex){
1113       loadContent ();
1114   }
1115   
1116   function reloadSection(anchorLink, index){
1117       if (mayLoad){
1118           mayLoad = false;
1119           reload();
1120       }
1121   }
1122   
1123   function reloadSlide(anchorLink, index, slideAnchor, slideIndex){
1124       if (mayLoad){
1125           mayLoad = false;
1126           reload();
1127       }
1128   }
1129   
1130   var fullPageArguments=     {
1131      verticalCentered: false,
1132      //CHROME
1133    scrollOverflow:true,
1134    scrollBar: false,
1135    loopHorizontal: false,
1136    touchSensitivity: 10,
1137           afterResize: resizeVideos, 
1138    css3:false, //JQUERY UI required by Fancytree breaks it
1139         afterRender:pleaseLoadContent,
1140     afterLoad: reloadSection, 
1141     afterSlideLoad: reloadSlide,
1142     onLeave:  leaveSection,
1143       onSlideLeave:  leaveSlide
1144   
1145    };
  

leave

1146   
1147   var mayLoad=false;
1148   
1149    //OLD VERSIONS
1150   function leaveSection (index,nextIndex,direction){
1151           if (! allowScrolling){
1152           return false;
1153       }
1154       mayLoad= true;
1155       homeNode = verticalSlides [nextIndex-1];
1156       saveCurrentURL();
1157       return true;
1158   }
1159   
1160   
1161   function leaveSlide(anchorLink, index, slideIndex, direction, nextSlideIndex){
1162       if (! allowScrolling){
1163           return false;
1164       }
1165       mayLoad= true;
1166       homeNode = horizontalSlides [nextSlideIndex];
1167        saveCurrentURL();
1168   
1169       return true;
1170   
1171   }
1172   
1173   
1174   
1175   function popSlides(aNode){
1176        setSlides(aNode);
1177        reload();
1178   }
1179   
1180   function displaySlideNamed(key){
1181       displaySlide(tree.getNodeByKey(key));
1182       saveCurrentURL();
1183   } 
1184   
1185   function displaySlide(aNode){
1186       homeNode = aNode;
1187        setSlides(aNode);
1188        reload();
1189   }
  

moveMoveCommands

1190   function buildFullPage(){
1191             $('#fullpage').fullpage(fullPageArguments);
1192   }
1193   
1194   function moveDown(){
1195       setDownSlides();
1196       restartFullPage();
1197       reloadCore();
1198       $.fn.fullpage.moveSectionDown();
1199   }
1200   
1201    function moveUp(){
1202        setUpSlides();
1203      restartFullPage();
1204       reloadCore();
1205       $.fn.fullpage.moveSectionUp();
1206        
1207   
1208    }
1209   
1210   
1211   
1212   function moveToLast(numberOfSiblings){
1213        return;
1214   }
1215   
1216   function moveToFirst(){
1217   return 
1218       
1219   }
1220   
1221   function moveRight(){
1222       setRightSlides();
1223      restartFullPage();
1224       reloadCore();
1225       $.fn.fullpage.moveSlideRight();
1226   
1227   }
1228   
1229   function moveLeft(){
1230        setLeftSlides();
1231      restartFullPage();
1232       reloadCore();
1233       $.fn.fullpage.moveSlideLeft();
1234        
1235   }
  

moveToMobile

1236   function MoveTo(){
1237       
1238   }
  

pinchToZoom

1239   var allowScrolling = true;
1240   /*
1241   $(document).ready(function() { 
1242   
1243       var scale = 1.0; // initial-scale
1244       var r = 0.10;
1245       var oldScale = scale;
1246   
1247       $(document).bind('gesturechange',function(event){
1248           allowScrolling = false;
1249           $.fn.fullpage.destroy();
1250            var height = viewport.height;
1251            var halfHeight = height / 2.0;
1252            var  offsetTop = vewport.offsetTop;
1253             var oldHeight = halfHeight + offsetTop;
1254           
1255           var newScale = event.originalEvent.scale;
1256           if(newScale  > 1) scale = scale <2 ?  newScale : 2 
1257           else scale = scale > 0.5 ? newScale : 0.5 
1258   
1259         
1260            var ratio = newScale /oldScale; 
1261            var newHeight = (oldHeight * ratio) -height;
1262            viewport.offsetTop = newHeight;       
1263           $('meta[name=viewport]').attr('content', 'width=device-width, minimum-scale='+ scale.toFixed(2) +', maximum-scale='+ scale.toFixed(2) +', user-scalable=yes'); // 
1264           setTimeout(pleaseAllowScrolling,300);
1265                $.fn.fullpage.reBuild();
1266                
1267           oldScale = newScale;
1268   
1269       });
1270   });
1271   
1272   function pleaseAllowScrolling(){
1273        allowScrolling = true;
1274   }
1275   */
  

reload

1276   var fullPage = false;
1277   var newSlides;
1278   function reload(){
1279      
1280       setChildIndex();
1281        //setSlides(homeNode);
1282        setAndReload();
1283   }     
1284   
1285   function loadOneSlide(){
1286       
1287       verticalSlides=[homeNode];
1288       horizontalSlides=[homeNode];
1289       setAndReload();
1290   }
1291   
1292   function setAndReload(){ 
1293          setSingleSlide();
1294          reloadCore();
1295           destroyFullPage();
1296          }
1297          
1298   function reloadCore(){       
1299          replaceFullPage();
1300          destroyFullPage();
1301          restartFullPage();
1302   }        
1303   
1304   
1305       
1306   function replaceFullPage(){   
1307            document.title=pageTitle(homeNode);
1308        $('#fullpage div').addClass("old");
1309        newSlides = renderVerticalSlides(homeNode);
1310        $(".old").remove();
1311        $('#fullpage').append(newSlides);
1312   }
1313   
1314   function destroyFullPage(){
1315         if (fullPage){
1316          $.fn.fullpage.destroy('all');   
1317        }
1318   }     
1319   
1320   function restartFullPage(){
1321        fullPage = true;
1322        $('#fullpage').fullpage(fullPageArguments);
1323   }
1324   
  

MyFilter

1325    //THS FUNCTION IS A HOOK SO THAT EVERYONE CAN GENERATE THE APPROAPRIATE
1326   //STRING TO SEARCH IN THEIR APPLICATION
1327   function getStringToSearch(node){
1328            var searchString = node.data.title+' '+node.data.description + '';
1329            if (node.data.class == 'Video'){
1330               searchString += tree.getNodeByKey(node.data.conference).title; 
1331            }
1332            return searchString;
1333       }
1334       
1335       
1336   // THIS IS THE FUNCTION WHICH RETURNS TRUE IF ALL THE WORDS ARE FOUND IN THE STRING
1337   //FALSE OTHERWISE
1338   function MyFilter(node,regexpArray){ 
1339       
1340      
1341       var j;
1342       var stringToSearch=getStringToSearch(node);
1343       var result=true;
1344       for (j in regexpArray){
1345            if (!(regexpArray[j].test(stringToSearch))){
1346                result=false;
1347            }
1348       }
1349    
1350       return result;
1351   }
1352   
1353   function formattedTitle(node,coreTitle){
1354     return  "&bull; <a title=\""+node.data.description  +  "\"><b>"+ coreTitle +"</b></a>";
1355       
1356   }  
1357   
1358   
  

applyFilter

1359    //SETS A SHORT TITLE, NO DESCRIPTION, FOR BREADCRUMB NODES
1360   function setShortTitle(node){
1361                            node.title=node.data.title;
1362                            //"<a><b>"+node.data.title +"</b></a>"+
1363                     //" ("+getBranchSize(node)+")";
1364           }
1365           
1366    
1367   $.ui.fancytree._FancytreeClass.prototype._applyFilterImpl = function(filter, branchMode, opts){
1368   
1369       //FIRST DEFINE AND SET SOME VARIABLES   
1370    var leavesOnly,
1371        match, 
1372        re, 
1373        searchString=filter,
1374    filterOpts = this.options.filter,
1375    hideMode = filterOpts.mode === "hide",
1376    regexpArray=getRegxpArray(filter);
1377    re2 = new RegExp(filter, "gi");
1378    tree.enableFilter=true;
1379   
1380   
1381    //SET SOME MORE VARIABLES
1382       count=0;
1383    opts = opts || {};
1384    lavesOnly = !!opts.leavesOnly && !branchMode;
1385   
1386    //NOW CREATE THE FUNCTION TO SEARCH A SINGLE NODE
1387    filter = function(node){
1388            var coreTitle;
1389        var res = MyFilter(node,regexpArray);
1390        if (res){
1391             node.title=formattedTitle(node,node.data.title);
1392             setTitle(node);
1393            }
1394   
1395    // DONT DO THIS IF MULTIPLE SEARCH TERMS    (regexpArray.length>1)
1396    if( res && filterOpts.highlight && (regexpArray.length<2)) {
1397         coreTitle=node.data.title.replace(re2, function(s){
1398    return "<mark>" + s + "</mark>";
1399    });
1400    node.titleWithHighlight = formattedTitle(node,coreTitle);
1401   
1402     } else {
1403      delete node.titleWithHighlight;
1404    }
1405   
1406    return res;
1407    };
1408   
1409   
1410    this.enableFilter = true;
1411    this.lastFilterArgs = arguments;
1412   
1413    this.$div.addClass("fancytree-ext-filter");
1414    if( hideMode ){
1415    this.$div.addClass("fancytree-ext-filter-hide");
1416    } else {
1417    this.$div.addClass("fancytree-ext-filter-dimm");
1418    }
1419   
1420    this.visit(function(node){
1421        node.title = node.data.title + node.match;
1422    delete node.match;
1423    delete node.titleWithHighlight;
1424    node.subMatchCount = 0;
1425    });
1426   
1427    // SEACH THE TREE 
1428    //Adjust node.hide, .match, and .subMatchCount properties
1429    
1430      callVisit(this,function(node){
1431        
1432    if (filter(node)) {
1433    count++;
1434    node.match = true;
1435    node.visitParents(function(p){
1436        //MAKE THE UNMATCHED PARENTS LOOK GOOD
1437       if (!(p.match)){
1438               p.match=true;
1439               p.titleWithHighlight="<span style=\"color:#888;\" >"+p.data.title+"</span>";
1440        }
1441        
1442         if ('subMatchCount' in p) {  
1443              p.subMatchCount += 1;
1444              }
1445             else { 
1446                p.subMatchCount=1;
1447             }
1448         
1449    //if( opts.autoExpand && !p.expanded ) {
1450   
1451    p.setExpanded(true, {noAnimation: true, noEvents: true, scrollIntoView: false});
1452    p._filterAutoExpanded = true;
1453   
1454    });
1455   
1456    }
1457   
1458    });
1459   
1460   
1461   };
1462   
1463   
1464   
  

branchSize

1465     var branchSize;
1466    function getBranchSize(node){
1467       if (node.match || node.unmatchedParent){
1468           return node.subMatchCount;
1469       }
1470       else {
1471           branchSize=node.data.branchSize;
1472           branchSize = parseInt(branchSize);
1473           branchSize = branchSize.toString();
1474           return branchSize;
1475           
1476       }
1477   }
1478   
  

collapseChildren

1479    function collapseChildren(node){
1480       var index;
1481       var item;
1482       var children=node.children;
1483       if((node.isFolder())&&node.hasChildren()){
1484           node.setExpanded(false, {noAnimation: true, noEvents: true, scrollIntoView: false});
1485           for (index=0;index<children.length;index++){
1486               item=children[index]
1487               if (item.isExpanded()){
1488                   collapseChildren(item); 
1489               }
1490           }
1491       }
1492   }
  

gui-functions

1493     
1494   
1495   
1496   
1497   var tree = $("#tree").fancytree("getTree");
1498   
1499    /*
1500     * Event handlers for search
1501     */
1502   var match;
1503   
1504   function searchTheTree(match,opts){
1505               oldSearchString=match;
1506               tree.clearFilter();
1507     tree.filterNodes(match, opts);
1508   }
1509   
1510       
1511   function myKeyUp(e){    
1512        if(e && e.which === $.ui.keyCode.ESCAPE ){
1513    $("button#btnResetSearch").click();
1514    return;
1515    }
1516   
1517    var match=$("input[name=search]").val();
1518               myKeyUpCore(match);
1519   }
1520   
1521   $("input[name=search]").keyup(myKeyUp);
1522   
1523   
1524   function myKeyUpCore(match){
1525    var opts={};
1526    var n;
1527       currentSearchString=match;
1528        
1529        
1530       //IF YOU JUST DELETED THE SEARCH STRING
1531       if (currentSearchString.length===0) {
1532          tree.clearFilter(); 
1533          collapseChildren(root);
1534          root.render();
1535          oldSearchString="";
1536          return;
1537       }
1538       
1539       //IF YOU JUST STARTED SEARCHING
1540       if (oldSearchString===""){
1541           oldSearchString=currentSearchString.slice(1);
1542            root.render();
1543            return;
1544           }
1545                
1546               if (callbackCount===0){
1547                   searchTheTree(match,opts);
1548           
1549               }
1550       
1551   
1552   
1553   }      
1554   
1555     function futureSearch(match,opts){
1556                        searchTheTree(match,opts);
1557                     root.render();
1558                    }
1559   
1560   
1561   
1562   
1563     
1564   $("button#btnResetSearch").click(function(e){
1565    $("input[name=search]").val("");
1566    $("span#matches").text("");
1567    tree.clearFilter();
1568    }).attr("disabled", true);
1569   
1570   
1571   
1572   
1573   
1574   
  

search.js

1575         var callbackCount=0;
1576   var count;
1577   var currentSearchString="";
1578   var oldSearchString="";
1579   
1580   function cleanUp(){
1581        var rootNode=$("#tree").fancytree("getTree").getRootNode();
1582           rootNode.render(true);
1583           $("button#btnResetSearch").attr("disabled", false);
1584        $("span#matches").text("(" + count + " matches)");
1585        $.fn.fullpage.reBuild();
1586   
1587   }
1588   
1589   function reSearch(filterFunction){
1590        var value=$("input[name=search]").val();
1591        if (currentSearchString!=value){
1592             $("input[name=search]").trigger("keyup");
1593   
1594           }
1595        else{
1596   
1597               cleanUp();
1598           }
1599   $.fn.fullpage.reBuild();
1600   
1601    }
1602     
1603   
1604    
1605     
  

setScrolling

1606      function setScrolling(){
1607       if (homeNode.data.class == 'Chat'){
1608         $.fn.fullpage.setAutoScrolling(false);
1609         $.fn.fullpage.setFitToSection(false);
1610       }
1611       else{
1612            $.fn.fullpage.setAutoScrolling(true);
1613            $.fn.fullpage.setFitToSection(true);  
1614   
1615       }
1616   }
1617   
  

ViewCount

1618    function getViewCount(aNode){
1619       if (isMobile){
1620           return aNode.data.viewCount;
1621       }
1622       return aNode.viewCount;
1623   }
1624   
1625   function score (aNode){
1626         var upVotes, downVotes, viewCount, ratio;
1627         upVotes=Number(getUpVotes(aNode));
1628         downVotes= Number(getDownVotes(aNode));
1629         viewCount=Number(getViewCount(aNode));
1630         ratio = (upVotes - (5 * downVotes))/viewCount;
1631         ratio = ratio * 10000;
1632         return ratio;
1633   }
  

Arrows

1634   function oneArrow(direction,x,y,visible, onClick){
1635       var result=''+
1636       '<i style="position:relative;' +
1637       'top:' + y + 'em;'+
1638       'left:' + x + 'em;'+
1639       'opacity:';
1640       if (visible){
1641           result +='1.0;';
1642       }
1643       else{
1644           result += '0.4;';
1645       }
1646       if (visible){
1647          result += 'color:green;';
1648       }
1649       else{
1650          result += 'color:red;';
1651       }
1652       result += '" ' 
1653       result += 'class="fa fa-arrow-circle-' + direction +
1654       '"'+
1655       'onClick="' + onClick + '"' + 
1656       '></i>';
1657       return result;
1658   }
1659   
1660   function addArrows(slide){
1661      
1662       if (isMobile){
1663              return arrowsMobile(slide);
1664       }
1665       else{
1666           return arrowsDesktop(slide);
1667       }
1668        
1669      
1670   }
1671   
1672    
1673   function arrowsDesktop(slide){
1674     var result = "" +
1675   '<div  class = "my-desktop-arrows" >' +
1676   arrows(slide)+
1677   '</div>';  
1678   return result;
1679   }
1680   
1681   //THIS IS WHERE THE 3EM FONT SIZE WAS SET
1682   function arrowsMobile(slide){
1683   
1684     var result = "" +
1685   '<div  class = "my-mobile-arrows" >' +
1686   arrows(slide)+
1687   '</div>';  
1688   return result;
1689   }
1690   
1691   function arrows(slide){
1692     
1693       
1694   var result = "" +
1695   
1696   oneArrow('left',1,1,canGoLeft(slide),'goLeft()') +
1697   oneArrow('up',1,0,canGoUp(slide),'goUp()') +
1698   oneArrow('right',1,1,canGoRight(slide),'goRight()') +
1699   oneArrow('down',-1.0,2,canGoDown(slide),'goDown()') 
1700   
1701   return result;
1702   }
  

MyVideoMenu

1703   //This version of Pug.jsdoesnot interpoate attributes, so here is a workaround. 
1704   function myVideoMenu(){
1705   var result = '' +
1706    `<a class="dropdown-item" href="/person/${userId}/">My Videos </a>` +
1707    
1708   ` <a class="dropdown-item" href="/person/${userId}/addUserLightningTalk">Add Lightning Talk  </a>` +
1709   `<a class="dropdown-item" href="/person/${userId}/addUserVideo">Add Conference Video</a>` +
1710   `<a class="dropdown-item" href="/person/${userId}/edit">Edit User   </a>` 
1711   return result;
1712   }
  

MyVideoMenu1

1713     //This version of Pug.jsdoesnot interpoate attributes, so here is a workaround. 
1714   function myVideoMenu(){
1715   var result = '' +
1716    `<a class="dropdown-item" href="/person/${userId}/">My Videos </a>` +
1717    
1718   ` <a class="dropdown-item" href="/person/${userId}/addUserLightningTalk">Add Lightning Talk  </a>` +
1719   `<a class="dropdown-item" href="/person/${userId}/addUserVideo">Add Conference Video</a>` +
1720   `<a class="dropdown-item" href="/person/${userId}/edit">Edit Profile</a>` 
1721   return result;
1722   }
  

arguments

1723    var urlParams = new URLSearchParams(window.location.search);
1724   var sortBy = 'bestWilsonScore';
1725    
1726   if (urlParams.has('sortBy') ){
1727       sortBy = urlParams.get('sortBy');
1728   }
1729   if (!(['bestWilsonScore','bestMyScore','bestMostRecent'].includes(sortBy))){
1730       sortBy='bestWIlsonScore';
1731   }
1732   
  

arrowKeys

1733   function getChildIndex(aNode){
1734        var childIndex= 0  
1735        if ( 'previousChildIndex' in aNode){
1736         childIndex = homeNode.previousChildIndex;
1737         }
1738        return childIndex; 
1739   }
1740   
1741   function canGoUp(node){
1742       return !isRoot(node);
1743   }
1744   
1745   function goUp (){
1746       if (canGoUp(homeNode)){
1747           var offset = homeNode.parent.children.indexOf(homeNode);
1748           homeNode.parent.previousChildIndex = offset;
1749           moveUp();
1750       }
1751   }
1752   
1753   
1754   function canGoDown(node){
1755    return hasChildren(node);   
1756   }
1757   
1758   function goDown (){
1759       if(! canGoDown(homeNode)){
1760           return;
1761       }
1762       var childIndex=getChildIndex(homeNode);
1763       moveDown(childIndex);
1764   }
1765   
1766   function canGoRight(node){
1767       var siblings= getSiblings(node);
1768       var offset = siblings.indexOf(homeNode);
1769       var numberOfSiblings = siblings.length;
1770       return (offset < numberOfSiblings -1 )
1771   }
1772   
1773   function goRight (){
1774      var siblings = getSiblings(homeNode);
1775       var offset = siblings.indexOf(homeNode);
1776       var numberOfSiblings = siblings.length;
1777       if (canGoRight(homeNode)){
1778          homeNode.parent.previousChildIndex = offset + 1;
1779          moveRight(offset);
1780       }
1781       else {
1782           homeNode.parent.previousChildIndex = 0;
1783            moveToFirst();
1784       }
1785   }
1786   
1787   
1788   function canGoLeft(node){
1789         
1790       var siblings= getSiblings(homeNode);
1791       var offset = siblings.indexOf(homeNode);
1792       var numberOfSiblings = siblings.length;
1793       return  (offset > 0);
1794   
1795   }
1796   function goLeft (){
1797     
1798       var siblings= getSiblings(homeNode);
1799       var offset = siblings.indexOf(homeNode);
1800       var numberOfSiblings = siblings.length;
1801   
1802       if (canGoLeft(homeNode)){
1803           homeNode.parent.previousChildIndex = offset -1;
1804           moveLeft(offset);
1805       }
1806       
1807       else{
1808          homeNode.parent.previousChildIndex = numberOfSiblings -1;
1809          moveToLast(numberOfSiblings); 
1810       }
1811       
1812   }
1813   
1814   
1815   
1816      document.onkeydown = function (e) {
1817     if (e.key=="ArrowUp"){
1818         goUp();
1819         
1820     }
1821       else if (e.key=="ArrowDown"){
1822         goDown();
1823     }
1824       else if (e.key=="ArrowLeft"){
1825         goLeft();
1826     }
1827       else if (e.key=="ArrowRight"){
1828           goRight();
1829         
1830     }
1831      else if (e.key=="PageUp"){
1832         goLeft();
1833     }
1834       else if (e.key=="PageDown"){
1835           goRight();
1836         
1837     }
1838   };
  

arrows

1839    function footer(item,index){
1840        var result = "";
1841                        
1842        if (hasChildren(item)){
1843            result += " &uarr; ";
1844        }
1845           if (isRoot(item) !== null){
1846            result += " &darr; ";
1847        }
1848           if (index > 0){
1849            result += " &rarr; ";
1850        }
1851           if (! isRoot(item)){
1852            result += " &larr; ";
1853        }
1854        return result;
1855    }
  

loadContent

1856   function errorF( jqXHR, textStatus, errorThrown ){
1857       console.log ("AJAX ERROR", jqXHR, textStatus, errorThrown );
1858           // $.fn.fullpage.reBuild();
1859   
1860   }
1861   
1862   
1863   //after slide load
1864   function loadContent(){
1865     
1866       if (homeNode === undefined){
1867           return;
1868       }
1869      
1870       var url = "/" + getKey(homeNode) + "/content";
1871       divName = "#" + getKey(homeNode) + "-content";
1872       console.log("URL", url);
1873       console.log ("sortBy", sortBy);
1874         $.ajax({
1875             type: 'POST',
1876             url: url, 
1877         data: {'sortBy':sortBy},
1878         cache: false, 
1879         error: errorF,
1880         success: function(result){
1881           $(divName).html(result);
1882           resizeVideos(0,0,"body");
1883        localRebuild();
1884       }
1885         });
1886       
1887   }
1888    
1889   
1890      
  

navbar.pug

1891   nav.navbar.navbar-expand-md.navbar-dark.bg-dark
1892     button.navbar-toggler(type='button', data-toggle='collapse', data-target='#navbarsExample04', aria-controls='navbarsExample04', aria-expanded='false', aria-label='Toggle navigation')
1893       span.navbar-toggler-icon 
1894     #navbarsExample04.collapse.navbar-collapse
1895       ul.navbar-nav.mr-auto
1896         li.nav-item.dropdown
1897           a#dropdown04.nav-link.dropdown-toggle(href='https://example.com', data-toggle='dropdown', aria-haspopup='true', aria-expanded='false') Sites
1898           .dropdown-menu(aria-labelledby='dropdown04')
1899             != renderServerOptions(node)        
1900             a.dropdown-item(href='https://PythonLinks.info') Python Videos
1901             a.dropdown-item(href='https://cloud-native.pl') GoLang Videos
1902             a.dropdown-item(href='https://ForestWiki.com') ForestWiki.com
1903             a.dropdown-item(href='https://ClimateVideos.info') Climate Change
1904         if getClass(node)!='Video'       
1905           li.nav-item.dropdown
1906             a#dropdown04.nav-link.dropdown-toggle(href='https://example.com', data-toggle='dropdown', aria-haspopup='true', aria-expanded='false') View
1907             .dropdown-menu(aria-labelledby='dropdown05')
1908               a.dropdown-item(
1909                 href='#'
1910                 onClick='wilsonView()'
1911               ) WIlson Score
1912               a.dropdown-item(
1913                 href='#'
1914                 onClick ='myScoreView()'
1915               ) Votes/View
1916               a.dropdown-item(
1917                 href='#'
1918                 onClick ='mostRecentView()'
1919               ) Most Recent
1920                a.dropdown-item(href='https://PythonLinks.info/wilson-score') Explain
1921         // IF VIDEO
1922         if getClass(node)=='Video'         
1923           li.nav-item.dropdown
1924             a#dropdown04.nav-link.dropdown-toggle(href='https://example.com', data-toggle='dropdown', aria-haspopup='true', aria-expanded='false') Vote
1925             .dropdown-menu(aria-labelledby='dropdown05')
1926               a.dropdown-item(
1927                 href='#'
1928                 onClick = 'upVote()'
1929               ) Up Vote
1930               a.dropdown-item(
1931                 href='#'
1932                 onClick = 'downVote()'
1933               ) Down Vote
1934               a.dropdown-item(href='https://PythonLinks.info/wilson-score') Explain
1935               
1936               
1937         //PER USER
1938         if isAuthenticated         
1939           li.nav-item.dropdown
1940             a#dropdown04.nav-link.dropdown-toggle(href='https://example.com', data-toggle='dropdown', aria-haspopup='true', aria-expanded='false') My Videos
1941             .dropdown-menu(aria-labelledby='dropdown05'
1942             ) !{myVideoMenu()}
1943               
1944         li.nav-item
1945           a.nav-link(
1946           href='https://PythonLinks.info/contact'
1947           ) Contact
1948           span.sr-only (Contact)
1949         if  ! isAuthenticated 
1950           li.nav-item
1951              a.nav-link(
1952              href='./signup'
1953              ) Sign Up
1954              span.sr-only (Subscribe)
1955           
1956         if  ! isAuthenticated 
1957            li.nav-item
1958               a.nav-link(
1959               href='./login'
1960               ) Login
1961               span.sr-only (Login) 
1962           
1963         if  isAuthenticated 
1964            li.nav-item
1965               a.nav-link(
1966               href='/logout'
1967               ) Logout
1968               span.sr-only (Logout) 
1969               
1970                       
1971      
1972          
1973            
1974               
1975       if isMobile            
1976         form.form-inline.my-2.my-md-0
1977           input.form-control(
1978             type='text'
1979             placeholder='Search'  
1980             onFocus = 'showSearch()'
1981           )           
1982       ul.navbar-nav.ml-auto
1983         li.nav-item
1984           a.nav-link(
1985             href='https://twitter.com/intent/follow?screen_name=PythonLinks'
1986             target='_blank' 
1987           )   
1988               != twitterLinkFront()
1989               img(
1990                 alt='Follow to receive video recommendations' 
1991                 style = 'height:  1.5em;'
1992                 src='https://pythonlinks.info/static/graphics/twitter-logo.png'
1993               )
1994               != twitterLinkBack()
1995         li.nav-item
1996           a.nav-link(
1997             href='#' 
1998             onclick='resizeText(-1)'  
1999           ) a
2000             span.sr-only (Make the Font Smaller)
2001         li.nav-item
2002           a.nav-link(
2003             href='#'
2004             onclick='resizeText(+1)'
2005           ) A
2006             span.sr-only (Make the Font larger)
2007        
2008           
2009             
2010            
2011   
2012   
  

breadcrumbs

2013    function oneCrumb(item,step,width,showChildren){
2014           result = '<div style = "margin-left:' + (step).toString() + 'em">' +
2015            getTitle(item).link('/' + getKey(item)) 
2016            if (width > 500){
2017                result +=  ' &nbsp;(' + getBranchSize(item) + ')' 
2018            }
2019            result +=  '</div>';
2020           return result;
2021    }
2022    
2023    
2024    function selectChanged(arg){
2025        if (arg.value===''){
2026            return;
2027        }
2028        displaySlideNamed(arg.value);
2029    }
2030    
2031    
2032    
2033   function setSelectedIndex(s, valsearch){
2034     for (i = 0; i< s.options.length; i++){ 
2035       if (s.options[i].value == valsearch){
2036       s.options[i].selected = true;
2037       break;
2038       }
2039     }
2040   }
2041   
2042    
2043    function onSelectFocus(arg,id){
2044         
2045        arg.selectedIndex = 0;
2046   }
2047   
2048    function onSelectBlur(arg, id){  
2049       setSelectedIndex(arg, arg.id.slice(7));
2050    }
2051    
2052    function selectSiblings (node,step,width,showChildren){
2053        var siblings = getSiblings(node);
2054        var id = 'select-' + getKey(node);
2055        if (showChildren){
2056            siblings = node.children;
2057            id = 'select-child-category';
2058        }
2059       
2060         result = '<div style = "margin-left:' + (step).toString() + 'em">' 
2061       result += '<select style="-webkit-appearance: none; -moz-appearance: none;  appearance:none; ';
2062       result +='width:auto; max-width: 50em; padding: 0; height:1.7em" class= "text-primary form-control" id = "' + id  + '"';
2063       result += ' onchange ="selectChanged(this)" ' 
2064       result += " onfocus =\"onSelectFocus(this,'" + id + "')\"";
2065       result += " onblur =\"onSelectBlur  (this,'" + id + "')\"";
2066       result += ' value="" ';
2067       result += ">";
2068       
2069       if (showChildren){
2070           result += '<option selected value="">Select Sub-Category or Video▼</option>';
2071       }
2072        else{
2073           result += '<option  >Jump To:</option>';
2074     
2075        }
2076       
2077      // AND NOW GENERAT OPTIONS
2078      for ( let index in siblings){
2079         
2080          item = siblings [index];
2081       
2082          result += "<option ";   
2083          
2084          if (item == node){
2085              result += " selected ";
2086          }
2087        result +=' value="'; 
2088        result += getKey(item);
2089        result +='">';
2090       
2091        result += getTitle(item);
2092         if (item == node){
2093              result += " ▼";
2094          }
2095        if (width > 500){
2096           result +=  ' &nbsp;(' + getBranchSize(item) + ')' 
2097        }
2098    
2099         result += "</option>";
2100      }
2101     result += "</select>";
2102       result +=  '</div>';
2103   
2104     return result;
2105    }
2106    
2107    function breadcrumbs(node,index){
2108         var width = $( window ).width();
2109        var result="";
2110        var offset;
2111        var items=parents(node);
2112        var length = items.length;
2113        var step;
2114        result+= "<div style = \"text-align:left; \">";
2115       for (step = 0; step < length-1; step++) {
2116           item=items[step];
2117           result += selectSiblings(item,step,width,false);
2118           }
2119        result += selectSiblings(node,length -1,width,false);  
2120        
2121        if (hasChildren(node)){
2122            result += selectSiblings(node,length,width, true); 
2123        }
2124        result += "</div>";
2125        return result;
2126    }
2127    
  

generateTwitter

2128    function getHashTag(node){
2129       if (isMobile) {
2130           return node.data.hashTag;
2131       }
2132       else {
2133           return node.hashTag;
2134       }
2135   }
2136    function renderTweetForm(node){
2137        if (node != homeNode){
2138            return "";
2139        }
2140        var url =  'https://PythonLinks.info/'+ getKey(node) 
2141       result = "";
2142       result += '<div class="form-group" style = "padding: 20px;">' 
2143       
2144       result += '<form id="messageForm"  action="https://twitter.com/share" method="get">' +
2145        '<label for="comment">Comment on Twitter about:</label><br>' +
2146       '<input type="hidden" name="source" value="tweetbutton"> ' +
2147       '<textarea id="tweet" name= "text"  rows="5"' +
2148       'class="form-control">' + node.title + '\n' +
2149        url  + 
2150       ' via @PythonLinks ' +
2151        getHashTag(node) + ' '  +
2152        '</textarea>' +
2153       '<button type="submit"  formtarget="_blank" class="btn btn-primary">Tweet</button> &nbsp;' +
2154        '<span id="charactersRemaining"></span>' +
2155        '</form>' 
2156        
2157       result += '</div>' 
2158       
2159       return result;
2160   }
2161   
2162   function commentType(node){
2163       if (getClass(node) == 'Conference'){
2164           return 'If you are kind enough to say what you thought about this conference,' + 
2165           'your comments will show up here.';
2166       }
2167           if (getClass(node) == 'Video'){
2168               return 'If you are kind enough to review this video after you watch it,' +
2169               'your review on twitter will be posted here';
2170           }
2171       if (getClass(node) == 'Category'){
2172           return 'If you are kind enough to give me your professional advice on the organization '+
2173           'of this category, I will either make the changes, or post your ocmment here';
2174       }
2175       return '';
2176   
2177   }
2178   
2179   function renderTweet(tweetId){
2180       var result = '<blockquote class="twitter-tweet" data-lang="en"><p lang="en"' +
2181        'dir="ltr">&quot;Data Science Without Borders&quot; is the overall best '+
2182       '<a href="https://twitter.com/hashtag/Python?src=hash&amp;ref_src=' +tweetId +'">#Python</a> video, beating out &quot;Towards Pandas 1.0&quot; by 181 to 119 Youtube up votes. <a href="https://t.co/EXWwvk3BKG">https://t.co/EXWwvk3BKG</a></p>&mdash;' +
2183       ' The Best of 710 Python Conference Videos (@PythonLinks) ' +
2184       '<a href="https://twitter.com/PythonLinks/status/1048163192080404480?ref_src=twsrc%5Etfw">'+
2185       'October 5, 2018</a></blockquote>' +
2186       '<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>';
2187        return result;
2188   }
2189    /*
2190   function notUsed(){
2191     if ('showHashTag' in node){
2192         result +='<a href="https://twitter.com/search?q=' + 
2193         node.hashTag +
2194         '">See the comments on twitter.</a>';
2195     }
2196     else{
2197         result += "<p>If you would be so kind as to post the "+
2198         "first comment on this page, I will go ahead and add a link to the unique hashtag "+
2199         "timeline on Twitter</p>";
2200     }
2201   }
2202     */
2203   
2204   var el;                                                    
2205   
2206   function countCharacters(e) {                                    
2207     var textEntered, countRemaining, counter;          
2208     textEntered = document.getElementById('tweet').value;  
2209     counter = (280 - (textEntered.length));
2210     countRemaining = document.getElementById('charactersRemaining'); 
2211            countRemaining.textContent = ""; 
2212   
2213       if (counter < 20){
2214           countRemaining.textContent = counter.toString() + 
2215           ' Characters Remaining';
2216       }
2217   
2218   }
2219   
2220   function postRender(){
2221       el = document.getElementById('tweet');                   
2222   el.addEventListener('keyup', countCharacters, false);
2223   countCharacters();
2224   }
2225   
  

buttonFunctions

2226    
2227   function editProfile(){
2228       window.location.href = "/person/" + userId + "/editPrincipal";
2229   }
2230   
2231   
2232   function editProfile(){
2233       window.location.href = "/person/" + userId + "/editPrincipal";
2234   }
2235   
2236    function changeView(){
2237           showBest = ! showBest;
2238   
2239        var label = "Best View";
2240        if (showBest){
2241            label = "List View";
2242        }
2243      
2244       $("#viewButton").html(label);
2245       var result = generateLeadersOrContentCore(homeNode);
2246       $("#bestContent" + '-' + getKey(homeNode)).html(result);
2247            localRebuild();   
2248   
2249       }
  

renderButtons

2250   function renderServerOptions(node){
2251       var url ="https://";
2252       if (isMobile) {
2253           url += 'desktop.';
2254           url+=domain;
2255           url += '/';
2256           url += getKey (node);
2257           return '<a class="dropdown-item" href="' + url + '">Desktop (Beta)</a>';
2258       }
2259        if (! isMobile) {
2260            url += domain.slice(8);
2261               url += '/';
2262        url += getKey (node);
2263           return '<a class="dropdown-item"  href="' + url + '">Mobile</a>';
2264       }
2265       
2266   }
2267   
2268   function lili(arg){
2269       return '<li>' + arg + '</li>';
2270   }
2271   
2272    function renderProfileOption(){
2273       if (isAuthenticated){
2274              return lili('<a onclick="editProfile()">Profile</a>');
2275       }
2276       else 
2277       {return "";}
2278   }
2279   
2280   
2281   
2282   function renderSubscribeOption(item){
2283      if ( ! isAuthenticated){
2284              return lili('<a href="./register/user">Get Updates</a>');
2285    }
2286    return '';
2287   }
2288   
2289     
2290   
2291    
2292    
2293    
2294    function renderChatButton(item){
2295        if (getClass(item)=="Video"){
2296            return "<button  onclick=\"goToChat('" +
2297         getKey(item)+ 
2298          "')\" type=\”submit\” class=\”btn btn-primary\”>Chat</button> " 
2299         }
2300         return "";
2301    }
2302    
2303    
2304     function renderRegisterButton(item){
2305            return "<button  onclick=goToRegister(\"" +
2306         getKey(item) + 
2307          "\")  type=\”submit\” class=\”btn btn-primary\”>Register</button> " 
2308    }
2309    
2310    
2311     function renderLoginOption(item){
2312            if ( ! isAuthenticated){    
2313                return lili( '<a  href = "./register/web">Login</a> ') 
2314            }
2315      else {
2316                return "";
2317            }
2318    }
  

renderSearchButton

2319    function renderSearchOption(item){
2320     return  lili ('<a  class="text-primary" onclick="showSearch()"> Search</a>') 
2321    }
  

renderthumbs

2322     function getVoteDivName(item,divName){
2323         return  getKey(item) + "-" + divName;
2324     }
2325     
2326      function renderVoteButton(item,thumb,functionName,votes,divName){
2327        if (getClass(item)!="Video"){
2328                  return "";
2329        }
2330            return "<button  onclick=" + functionName +"('" +
2331         getKey(item)+ 
2332          "')  type=\”submit\” class=\”btn btn-primary\”>" + 
2333           "<span style=\"font-size=3em\"" +
2334          "id =\""+ getVoteDivName(item,divName) + "\">" +
2335          votes + "</span>" + thumb + "</button>" 
2336        
2337    }
2338   
2339     function renderThumbs(slide){
2340        if (getClass(slide) != "Video"){
2341                  return "";
2342     }
2343     
2344    
2345           return   renderVoteButton(slide," 👍 ","upVote", getUpVotes(item),"upVotes") +
2346             renderVoteButton(slide," 👎 ","downVote", getDownVotes (item), "downVotes");
2347           
2348   }
2349   
2350            
2351     
2352     
2353    
  

threeMenuButtons

2354    function visible(){
2355        if ( (userId == 'lozinski') || 
2356          (handle == "ChristopherLozinski") || 
2357          (handle == "JustinMorgan") ||
2358          (handle=="WojtekB.")
2359          ){
2360            return true;
2361        }
2362        else{return false;}
2363    }
2364    
2365     function editMenu(slide){
2366        if (! isAuthenticated)
2367        {
2368            return '';
2369        }
2370      
2371        var result ="" +   
2372        ' <span class="dropdown">' +
2373         '<button class="btn btn-primary dropdown-toggle"'+
2374           'type="button"data-toggle="dropdown">Editor'+
2375          '<span class="caret"></span></button>' 
2376        result +=       '<ul class="dropdown-menu dropdown-menu-right">' +
2377       lili("<a href=\"/" + getKey(homeNode) + "/ckedit\">Ck Edit</a> ") +
2378       lili("<a href=\"/" + getKey(homeNode) + "/aceedit\">Ace Edit</a> ") 
2379       if ((getClass(slide) == 'Category')||
2380           (getClass(slide) == 'HomePage'))
2381       {
2382         result +='' + 
2383         lili("<a href=\"/" + getKey(homeNode) + "/addCategory\">Add Category</a> ");
2384         if (userId == 'lozinski') {
2385             result +='' +  
2386             lili("<a href=\"/" + getKey(homeNode) + "/addConference\">Add Conference</a> ") 
2387         }}
2388       if (getClass(slide) == 'Conference'){
2389         result +='' + 
2390           lili("<a href=\"/" + getKey(homeNode) + "/addVideo\">Add Video</a> "); 
2391       }
2392         if (getClass(slide) == 'Conference'){
2393         result +='' + 
2394           lili("<a href=\"/" + getKey(homeNode) + "/addLightningTalk\">Add Lightning Talk</a> "); 
2395       }
2396          if (getClass(slide) == 'Video'){
2397       result+= lili("<a href=\"/" + getKey(homeNode) + "/starttime\">Edit Start Time</a>") 
2398       //lili("<a href=\"/" + getKey(homeNode) + "/addComment\">Add Comment</a> ") 
2399       } 
2400       
2401      
2402       
2403              if (getClass(slide) != 'Video'){
2404       result+= lili("<a href=\"/" + getKey(homeNode) + '/manage">Manage</a>') 
2405   }
2406      
2407       result += "</ul>  </span> ";
2408   return result;
2409   }
2410   
2411   
2412    function manageMenu(slide){
2413        if (userId != 'lozinski'){
2414            return '';
2415        }
2416      
2417        var result ="" +   
2418        ' <span class="dropdown">' +
2419         '<button class="btn btn-primary dropdown-toggle"'+
2420           'type="button"data-toggle="dropdown">Manage'+
2421          '<span class="caret"></span></button>' 
2422        result +=       '<ul class="dropdown-menu dropdown-menu-right">' 
2423       if (getClass(slide) != 'Video'){
2424         result +='' + 
2425         lili("<a href=\"/" + getKey(homeNode) + '/manage">Manage</a> ') +
2426         lili('<a href=\"' +'/Products/Root/AllJavascript/search">Scripts</a> ') +
2427         lili("<a href=\"/" + getKey(homeNode) + '/addPlayList">Add PlayList</a> ') +
2428         lili("<a href=\"/" + getKey(homeNode) + '/addChannel">Add Channel</a> ') +
2429         lili("<a href=\"/" + getKey(homeNode) + '/addPyVideo">Add PyVideo</a> ') +
2430         lili("<a href=\"/" + getKey(homeNode) + '/editors">Editors</a> ') +
2431         lili("<a href=\"/" + getKey(homeNode) + '/cachedContent">CachedContent</a> ') 
2432       }
2433       if (getClass(slide) == 'Video'){ 
2434        result+=   lili( " <a href=\"/" + getKey(homeNode) + "/move\">Move</a>") 
2435       }
2436      
2437       result += "</ul>  </span> ";
2438   return result;
2439   }
2440   
2441   
2442    function userMenu(slide){
2443        var result ="" +   
2444        ' <span class="dropdown">' +
2445         '<button class="btn btn-primary dropdown-toggle"'+
2446           'type="button"data-toggle="dropdown">Menu'+
2447          '<span class="caret"></span></button>' 
2448        result +=       '<ul class="dropdown-menu dropdown-menu-right">';
2449         result +=renderViewOption(slide) 
2450        result += renderSearchOption(slide) +
2451        renderSubscribeOption(slide) +
2452        renderServerOptions(slide) +
2453        //renderProfileOption (slide) +
2454        lili ('<a href ="/contact">Contact</a>')+
2455        renderLoginOption(slide) +
2456        renderSignOutOption(slide) +
2457       "</ul>  </span>" 
2458   return result;
2459   }
  

whichview

2460     function changeContent(){
2461      
2462        $('#buttons').html(renderButtons(homeNode));
2463         loadContent(homeNode);
2464            saveCurrentURL();
2465    }
2466    
2467    function wilsonView(){
2468        sortBy='bestWilsonScore';
2469        changeContent();
2470    }
2471    
2472    function myScoreView(){
2473        sortBy = 'bestMyScore';
2474            changeContent();
2475    }
2476    
2477    function mostRecentView(){
2478        sortBy =  'bestMostRecent';
2479           changeContent();
2480    }
2481    
2482     function renderViewOption(item){
2483         if (getClass(item) == "Video"){
2484             return "";
2485         }
2486   
2487     var showWilson  = ' <a  class="text-primary" onclick="wilsonView()"> Best Score</a>' 
2488     var showMyScore = ' <a  class="text-primary" onclick="myScoreView()">Score/Views</a>' 
2489     var showRecent  = ' <a  class="text-primary" onclick="recentView()"> Most Recent</a>' 
2490     
2491     var result ='';
2492    
2493     if (sortBy != 'bestWilsonScore'){
2494         result+= lili(showWilson);
2495     }
2496      if (sortBy != 'bestMyScore'){
2497         result+= lili(showMyScore);
2498     }
2499     if (sortBy != 'bestMostRecent'){
2500         result+= lili(showRecent);
2501     }
2502     return result;
2503    }
2504    
  

news

2505    var news = '' //+
2506    //'<b>Nov 27, 2018</b> &nbsp;' +
2507    //'Here are   <a onclick="displaySlideNamed(\'tensorflow-dev-summit-2018\')">' +
2508    //'the best talks from the TensorFlow Dev Summit.</a>' 
2509    
  

renderContetnDiv

2510    function renderContentDiv(slide){
2511        return "<div id=\"" +
2512        getKey(slide) + "-content" +
2513        '"' +
2514        "></div>"  
2515    }
2516    
2517    function debugIt(){
2518        var i,j;
2519        var result ="<br>" 
2520        for (i=0; i<verticalSlides.length; i++){
2521            if (verticalIndex == i){
2522                     for (j=0; j<horizontalSlides.length; j++){
2523                  result += horizontalSlides[j].key;
2524                  result += " ";
2525                 }
2526            }
2527            else{
2528                result += verticalSlides[i].key;
2529            }
2530            result += "<br> \n";
2531        }
2532        return result;
2533    }
  

renderMore

2534    function renderExtra(){
2535       return "<br> <br> <br><br><br><br>";
2536   
2537   }
2538   function renderButtons(slide,index){
2539            var result = "" +
2540            "<center>" +
2541            editMenu(slide) +
2542            manageMenu(slide);
2543           result +=   "</center> <br> " 
2544           return result;
2545   }
2546   
2547   function renderFollowTwitter(){
2548       return '<a style = " padding: 20px;" target="_blank" ' +
2549       'href="https://twitter.com/intent/follow?screen_name=' +
2550       twitterId+ '">' +
2551       '<img alt="Follow to receive video recommendations"' +
2552       'target= "_blank"' +
2553       'src="https://pythonlinks.info/static/graphics/twitter-logo.png"' + 
2554       '></a> ' 
2555   }
2556   
2557       
2558   
2559   function renderDescription (slide){
2560            return  '<p style="text-align:left;">' +
2561           getDescription(slide) + 
2562              "</p>" 
2563   }
2564   
  

renderTitleSubTitle

2565     function getSubTitle(slide){
2566         if (getClass(slide)!='Conference'){
2567             return "";
2568         }
2569         var result = '';
2570         var conferenceName;
2571         var preamble = "Talks at " 
2572         if (slide.key == rootName){
2573             preamble = "at ";
2574         }
2575         if (getClass(slide) == 'Category'){
2576             return '';
2577         }   
2578       
2579         conferenceName = getConferenceName(slide);//WASgetSearchedConferenceName();
2580         if (conferenceName){
2581            result += '<h3 style ="text-align:center;">' + preamble + conferenceName + '</h3>';  
2582         }
2583         return result;
2584    }
2585    
2586    function renderTitle(slide){
2587        var children = '';
2588        var offset = 0;
2589        var siblings =  getSiblings(slide); 
2590        if (siblings.length > 1){
2591           offset = siblings.indexOf(slide);
2592           children = " &nbsp;(" + (offset + 1) + "/" + 
2593                  siblings.length + ')' 
2594         }
2595        var result = '';
2596       
2597        result +=  '<h1  style ="text-align:center;">' + 
2598                      getTitle(slide) +
2599                      children +
2600                     "</h1>" 
2601         return result;
2602    }
2603             
  

socialMediaLinks

2604   // FUNCTION TO GENERATE SOCIAL MEDIA LINKS
2605   
2606   function socialMediaLinks(slide){
2607   
2608   
2609   var title = getTitle(slide);
2610   var encodedTitle = encodeURI(title);
2611   var description = getDescription(slide);
2612   var encodedDescription = encodeURI(description);
2613   var theURL ="https://PythonLinks.info"+ '/' + getKey(slide);
2614   var titlePlusDescription = title + ' ' + description;
2615   var encodedTitlePlusDescription = encodeURI(title + ' ' + description);
2616   var result ="";
2617   
2618   result +='<center><div>' +
2619   //FIRST THE EMAIL LINK
2620    '<a href="mailto:?subject='+ encodedTitle+ '&body=' + 
2621    encodeURI (description + ' ' + theURL) +'"' + 
2622   'class="share-btn email" title="Email">' +
2623   '<i class="fa fa-envelope"></i></a>' 
2624   
2625   
2626   
2627   //NOW THE FACEOOK LINK
2628   result += '<a href="https://www.facebook.com/sharer/sharer.php?u=' +
2629   theURL + '&t=' + encodedTitle +'" class="share-btn facebook"' +
2630   'title="Facebook">' +
2631   '<i class="fab fa-facebook"></i></a>';
2632   
2633   //NOW TWITTER
2634   //result += '<a href="https://twitter.com/share?text=' +
2635   //encodedDescription + '&url=' + theURL +';via=PythonLinks' +  
2636   //'" class="share-btn twitter" title="Twitter">' +
2637   //'<i class="fa fa-twitter"></i></a>' 
2638   
2639   
2640   //AND REDDIT
2641   result += '<a href="http://reddit.com/submit?url=' +
2642   theURL + '&title=' + encodedDescription + '&kind=link" class="share-btn reddit" title="reddit">'+
2643   '<i class="fab fa-reddit"></i></a>';
2644   
2645   //NOW FOR LINKED IN 
2646   result += '<a href="https://www.linkedin.com/shareArticle?url=' +
2647   theURL + '&title=' + encodedTitlePlusDescription +
2648   encodedTitlePlusDescription + 
2649   '" class="share-btn linkedin" title="LinkedIn">' +
2650   '<i class="fab fa-linkedin"></i></a>';
2651   
2652   
2653   result += '</div></center>';
2654   
2655   return result;
2656   }
  

generateLeadersCore

2657    
2658   function generateLeadersOrContentCore(slide){
2659       if (showBest){
2660           return generateLeaders(slide);
2661       }
2662       else{
2663           return generateContent(slide);
2664       }
2665   }
  

generateContents

2666     
2667        function generateContent(rootNode){
2668         if ((getClass(rootNode) === 'Video')){
2669                return "";
2670            }
2671            result ='<div style="margin:auto; max-width: 100vh;">';
2672          
2673           result += generateContentCore(rootNode) 
2674           result +='</div>';
2675           return result;
2676        }        
2677        
2678        
2679        
2680   function tableHead(subTitle){
2681           return    "<tr>" +
2682           TD (' <a href = "https://www.evanmiller.org/how-not-to-sort-by-average-rating.html">Score</a>')+
2683                    
2684                     TD (' Votes ') +
2685                     TD(subTitle ) +
2686                     "</tr>";
2687   }     
2688   function videosInThisFolder(node){
2689       var videos=[];
2690       var video;
2691       var children = node.children;
2692       if (! hasChildren(node)){
2693           return videos;
2694       }
2695       var arrayLength = node.children.length;
2696       for (var i = 0; i < arrayLength; i++) {
2697           video=children[i];
2698           if (getClass(video) =='Video'){
2699           
2700           video.data.ratio =  score (video);        
2701           videos.push(video);
2702           }
2703       }
2704   return videos;
2705   }
2706   
2707   function childCategoriesRow (rootNode){
2708         var text = '<tr><td colspan="4">';
2709              text += renderChildCategories(rootNode);
2710              text += "</td></tr>" 
2711         return text;
2712   }
2713              
2714              
2715           
2716       function generateContentCore(rootNode){
2717   
2718       
2719             var text='';
2720             var i;
2721             var sortedArray = videosInThisFolder(rootNode);
2722             var sortedArrayLength = sortedArray.length;
2723             if (sortedArrayLength === 0){
2724                 return renderChildCategories(rootNode);
2725             }
2726             
2727             text += renderChildCategories(rootNode);
2728             text += "<h3>Videos in this Folder</h3>";
2729             text +='<table class="table table-striped" style = "padding:20px;">';
2730             text += "<thead>";   
2731            
2732             text += tableHead("Talk Title");
2733             text += "</thead>";
2734             text += "<tbody>";          
2735             for (i = sortedArrayLength-1; i >= 0; i--) { 
2736                     item=sortedArray[i];
2737                     text += '<tr>' 
2738                     text+= '<td align="left"> ' + 
2739                     item.data.ratio.toFixed(0) +
2740                     '% </td>';
2741                    
2742                     votes = '';
2743                     if (getUpVotes(item) >0){
2744                        votes += getUpVotes(item) + '👍 ';
2745                     }
2746                     if (getDownVotes(item) >0){
2747                        votes+= '<br>' + getDownVotes(item) + '👎 ';
2748                     }
2749                     text+= TD(' ' + votes + ' ');
2750                     
2751                     text+=TD(' ' + generateLink(item));
2752                     
2753                 
2754                     text +='</tr>'  
2755                     }
2756           
2757               text += "</tbody>"; 
2758              text +='</table>'     
2759               //text += '</div>';   //TABLE-RESPONSIVE
2760   
2761   
2762              return text;
2763              }
2764        
2765   
2766       
  

generateLeaders

2767    
2768        function generateLeaders(rootNode){
2769         if ((getClass(rootNode) === 'Video')){
2770                return "";
2771            }
2772       
2773            
2774            // FOR THE LIST OF CHANNELS DO NOT SHOW THE BEST VIDEOS
2775            if (getKey(rootNode) == 'conferences-and-channels'){
2776                   return generateContent(rootNode);
2777            }
2778             
2779             if (getKey(rootNode) == 'devops'){
2780                   return generateContent(rootNode);
2781            }
2782       
2783          if (getKey(rootNode) == 'data-science-software'){
2784                   return generateContent(rootNode);
2785            }
2786       
2787            
2788            var result ="";
2789            var text2 =  generateLeadersCore(rootNode) 
2790            result +=  "<center>" +  text2 + "</center> <br>";
2791         
2792            return result;
2793        }
2794        
2795        
2796                 //FIRST GENERATES A SORTED LIST OF ITEMS IN THIS BRANCH OF THE TREE
2797           //AND THEN PRINTS OUT THE SORTED HISTORY 
2798       function generateLeadersCore(rootNode){
2799             var text='';
2800             var i;
2801             var subTitle = " Best Videos Overall ";
2802             var sortedArray = generateTop10(rootNode);
2803          
2804             var sortedArrayLength = sortedArray.length;
2805             if (sortedArrayLength === 0 ){
2806                 return "";
2807                 }
2808            
2809           text +='<table class="table table-striped" style = "padding:20px;">';
2810                   
2811             text += "<tr>" +
2812                   TD (' <a href = "https://www.evanmiller.org/how-not-to-sort-by-average-rating.html">Score</a>')+
2813   
2814                     TD (' Votes ') 
2815                     if (getKey(rootNode) != rootName){
2816                         subTitle = ' Best Videos on ' + getTitle(rootNode);
2817                     }
2818                     
2819               text+=  TD( sortedArrayLength.toString() + subTitle ) +
2820                 
2821                     
2822                     "</tr>";
2823             for (i = sortedArrayLength-1; i >= 0; i--) { 
2824                     item=sortedArray[i];
2825                     text += '<tr>' 
2826                     text+= '<td align="left"> ' + 
2827                     item.data.ratio.toFixed(0) +
2828                     '% </td>';
2829                    
2830                     votes = '';
2831                     if (getUpVotes(item) >0){
2832                        votes += getUpVotes(item) + '👍 ';
2833                     }
2834                     if (getDownVotes(item) >0){
2835                        votes+= '<br>' + getDownVotes(item) + '👎 ';
2836                     }
2837                     text+= TD(' ' + votes + ' ');
2838                     
2839                     text+=TD(' ' + generateLink(item));
2840                     
2841                 
2842                     text +='</tr>'  
2843                     }
2844            
2845              text +='</table>'     
2846            
2847   
2848              return text;
2849              }
2850        
2851   
2852       
  

generateTop10Array

2853    
2854       function generateTop10(rootNode){
2855           if ( (getClass(rootNode) == 'Category') 
2856           &&
2857               (! hasChildren(rootNode))
2858           ){
2859               return "";
2860           }
2861           if (rootNode.data.hasOwnProperty('best')){
2862                 return rootNode.data.best;
2863             }
2864            var item;
2865             var i;
2866             var rootNodeChildren=rootNode.children;
2867            
2868             //IF IT IS A CONFERENCE, Just show the 
2869             //Conference Videos
2870             if (getClass(rootNode)=='Conference'){
2871                  var allVideos = [];
2872                 getConferenceVideos(getKey(rootNode),root,allVideos);
2873               rootNodeChildren =  allVideos;
2874             }
2875             sortedTree=buckets.BSTree(compare);
2876             for (k=0;k<rootNodeChildren.length;k++){
2877                 var aChild = rootNodeChildren[k];
2878                 sortNodes(aChild);
2879             }
2880                 
2881             var sortedArray=sortedTree.toArray();
2882             
2883             //FOR CONFERENCES SHOW ALL THE TALKS, SORTED.
2884             if (getClass (rootNode)== 'Conference'){
2885                 return sortedArray;
2886             }
2887             
2888             //OTHERWISE RETURN THE FIRST 10 ITEMS
2889             var sortedArrayLength=sortedArray.length;
2890             var lowerBound=sortedArrayLength-10;
2891             if (lowerBound<0) lowerBound=0;
2892         
2893             
2894             var shortArray = sortedArray.slice(lowerBound);
2895             rootNode.data.best = shortArray;  
2896             return shortArray;
2897        }
2898    
2899        
2900     
2901      
  

getConferenceVideos

2902    function getConferenceVideos(conferenceName,aNode,allVideos){
2903            var i;
2904            var thisNode;
2905            var children;
2906             if ((getClass(aNode) =="Video")&&
2907                (getConferenceKey(aNode)==conferenceName)){
2908                allVideos.push(aNode);
2909            }
2910            //COULD RETURN IF IT IS A VIDEO.
2911            
2912            if (! hasChildren(aNode)){
2913                return;
2914            }
2915            children=aNode.children;
2916             
2917             if (children && children.length){
2918                for (i in children){
2919                   thisNode=children[i];
2920                   getConferenceVideos(conferenceName,thisNode,allVideos);
2921                }
2922             }
2923        }
  

historyScripts

2924   function generateLink(item){
2925       return "<a onClick=\"displaySlideNamed('" + 
2926       getKey(item) + 
2927       "')\">"+ 
2928       getTitle(item)+"</a>";
2929   }
2930   
2931   function openWindow (key){
2932       window.open("/" + key);
2933   }
2934   
2935      //TO GENERATE HISTORY HAVE TO SORT ITEMS BY EDIT DATE
2936   //THIS COMPARE FUNCTION DOES THAT
2937   function compareLOG(a,b){
2938   
2939       var result = compare2(a,b);
2940       var aRatio = a.data.ratio; 
2941       var bRatio = b.data.ratio;
2942       return result;
2943   }
2944   function compare(a, b) {
2945     var aRatio = a.data.ratio; 
2946     var bRatio = b.data.ratio;
2947       
2948    if (aRatio < bRatio) {
2949       return -1;
2950    } if (aRatio > bRatio) {
2951       return 1;
2952    }
2953     //SAME Ratio, CHECK Totals
2954    if (Number(getUpVotes(a)) < Number(getUpVotes(b))) {
2955       return -1;
2956    } if (Number(getUpVotes(a)) > Number(getUpVotes(b))) {
2957       return 1;
2958    }
2959    
2960    //SAME Ratio, same upVotes, CHECK URLS
2961    if (getKey(a) < getKey(b)) {
2962       return 1;
2963    } if (getKey(a) > getKey(b)) {
2964       return -1;
2965    }
2966    
2967    // a must be equal to b
2968    
2969    return 0; 
2970   }
2971   
2972   var sortedTree;
2973   
2974   function TD(text){
2975       return '<td>' + text + '</td>';
2976   }
2977   
2978   
2979   //THIS FUNCTION ACTUALLY CREATES A BINARY TREE OF NODES SORTED BY EDIT DATE
2980   //USED TO GENERATE HISTORY
2981   function sortNodes(aNode){
2982        
2983            //IF IT IS A VIDEO
2984            if (getClass(aNode) =="Video" ){
2985                aNode.data.ratio = score(aNode);
2986                sortedTree.add(aNode);
2987                return;
2988            }
2989            //NOT A VIDEO?  CARRY ON
2990           var i;
2991            //SETS THE RATIO
2992            var children=aNode.children;
2993             
2994             if (children && children.length){
2995                for (i in children){
2996                   var thisNode=children[i];
2997                   sortNodes(thisNode);
2998                }
2999             }
3000                 
3001        }
  

score

3002   //THIS IS THE WILSON SCORE
3003    function  aScore (positiveScore, total) {
3004   
3005       if (total === 0) {
3006           return {
3007               left: 0,
3008               right: 0
3009           };
3010       }
3011   
3012       // phat is the proportion of successes
3013       // in a Bernoulli trial process
3014       const phat = positiveScore / total;
3015   
3016       // z is 1-alpha/2 percentile of a standard
3017       // normal distribution for error alpha=5%
3018       const z = 1.96;
3019   
3020       // implement the algorithm
3021       // (http://goo.gl/kgmV3g)
3022       const a = phat + z * z / (2 * total);
3023       const b = z * Math.sqrt((phat * (1 - phat) + z * z / (4 * total)) / total);
3024       const c = 1 + z * z / total;
3025   
3026       return {
3027           left: (a - b) / c,
3028           right: (a + b) / c
3029       };
3030   }
3031   
3032   
3033   function score (aNode){
3034         var upVotes, downVotes, total,wilsonScore;
3035         upVotes=Number(getUpVotes(aNode));
3036         downVotes= Number(getDownVotes(aNode));
3037         totalVotes = upVotes + downVotes;
3038        
3039         wilson =   aScore (upVotes, totalVotes);
3040         return wilson.left* 100;
3041         
3042   }
  

renderChildCategories

3043    function renderChildLink(item){
3044       return "<a onClick=\"slideDownTo('" + 
3045       getKey(item) + 
3046       "')\">"+ 
3047       getTitle(item)+"</a>" +
3048       ' (' + getBranchSize(item) + ')';
3049   }
3050   
3051   function slideDownTo(key){
3052       var nextNode=tree.getNodeByKey(key);
3053       var index = homeNode.children.indexOf(nextNode);
3054       homeNode.previousChildIndex=index;
3055       setSlides(homeNode);
3056       reload();
3057       $.fn.fullpage.moveSectionDown();
3058   
3059   } 
3060   
3061   
3062   function displayChildCategories (slide){
3063       var child;
3064       var  children = slide.children;
3065       if ((! children) || (children.length===0)){
3066           return "";
3067       }
3068       var result = "<h3>Child Categories</h3><br>";
3069       if (getKey(slide) == 'conferences-and-channels'){
3070           result = "<h3>Conferences Indexed</h3><br>";
3071       }
3072       
3073       for (var i in slide.children) {
3074           child = slide.children[i];
3075            if (getClass(child) != "Video"){
3076               result += renderChildLink(child) + "<br><br>";
3077          }
3078           
3079       }
3080       //result += "</div>";
3081       return result;
3082       
3083   }
3084   
3085   
3086   //IF ANY CHILD IS A CONFERENCE OR CATEGORY
3087   //DISPLAY THE LIST
3088   function renderChildCategories(slide){
3089       var child;
3090       if (slide.children === null){
3091           return "";
3092       }
3093           if (slide.children.length === 0){
3094           return "";
3095       }
3096       for (var i in slide.children) {
3097            child = slide.children[i];
3098          if (getClass(child) != "Video"){
3099              return  displayChildCategories(slide);
3100          }
3101       }
3102        return "";  
3103   }
3104   
  

renderSlide

3105     var showBest = true;
3106    
3107   
3108   
3109   function generateLeadersOrContent(slide){
3110        return '<div  id = "bestContent' + 
3111        '-' + getKey(slide) + '" >'+
3112             generateLeadersOrContentCore(slide) +
3113         "</div>";
3114   }
3115    var isMobile = true;
3116    function renderSlide(slide,index){ 
3117            var result = "" 
3118             
3119             result += template(
3120                 {'showSearch':showSearch,
3121                  'node':slide,
3122                  'upVote':upVote,
3123                  'downVote': downVote,
3124                  'getClass': getClass,
3125                  'renderServerOptions': renderServerOptions,
3126                  'isAuthenticated': isAuthenticated, 
3127                  'twitterLinkFront': twitterLinkFront,
3128                  'twitterLinkBack': twitterLinkBack, 
3129                  'twitterId': twitterId
3130             });
3131     
3132           result += addArrows(slide);
3133   
3134           result +='<div style = "padding-left: 20px">';
3135   
3136                result +=  breadcrumbs(slide,index) 
3137            
3138            result += renderTitle(slide) +
3139            "<br>" //+
3140           getSubTitle(slide) 
3141       
3142         
3143           if ((getClass(slide) == 'Video')){
3144               
3145               var conference = getConference(slide);
3146               result += '<h5 class="text-primary" style = "margin-left:50%">-'+ 
3147               '<a onClick="displaySlideNamed(' + "'" + getConferenceKey(slide) + "')" +'">'+ 
3148               getTitle(conference) +'</a></h5>';
3149           }
3150   
3151           
3152            if (isMobile){
3153              result+= "<center>";
3154            }
3155              result +=renderDescription (slide);
3156           if (isMobile){
3157   
3158               result+= "</center>";
3159           }
3160         result += '<div id="buttons">';
3161               result += renderButtons(slide,index);
3162          result +='</div>';
3163           result += renderContentDiv(slide) 
3164        
3165        
3166       result += socialMediaLinks(slide);
3167       result += renderExtra();  
3168       result += '</div>';
3169       return result; 
3170       }
  

rootname

3171    var rootName='';  
3172    var mobileJson ='';
3173    var deskTopJson ='';
3174    var domain= window.location.hostname.toLowerCase();
3175    var searchURL = "/search";
3176    var contactURL = "/contact";
3177    var twitterId ="men_are_human ";
3178    
3179    if (domain=='pythonlinks.info'){
3180       mobileJson='https://json.PythonLinks.info/python/json';
3181       rootName ='python';
3182       twitterId ="PythonLinks";
3183   }
3184   
3185   else if (domain=='desktop.pythonlinks.info'){
3186       deskTopJson= 'https://json.PythonLinks.info/python/tree.json';
3187       rootName ='python';
3188       twitterId ="PythonLinks";
3189   }
3190   
3191   else if (domain=='climatevideos.info'){
3192       mobileJson='https://json.PythonLinks.info/climate-change/json';
3193       rootName='climate-change';
3194       contactURL = "/contact2";
3195       searchURL = "/search2";
3196        twitterId ="ChangeClimate";
3197   }
3198   
3199   
3200   else if (domain=='desktop.climatevideos.info'){
3201       deskTopJson='https://json.PythonLinks.info/climate-change/tree.json';
3202       rootName='climate-change';
3203       contactURL = "/contact2";
3204       searchURL = "/search2";
3205        twitterId ="ChangeClimate";
3206   }
3207   
3208   
3209   else if (domain=='forestwiki.com'){
3210       mobileJson='/forestwiki/json';
3211       rootName='forestwiki';
3212       contactURL = "/golang-contact";
3213       searchURL = "/golang-search";
3214       twitterId ="forestwiki";
3215   }
3216   
3217   
3218   else if (domain=='cloud-native.pl'){
3219       mobileJson='/golang/json';
3220       rootName='golang';
3221       contactURL = "/golang-contact";
3222       searchURL = "/golang-search";
3223       twitterId ="PythonLinks";
3224   }
3225   else if (domain=='rights.men'){
3226       mobileJson='/mens-rights/json';
3227       rootName='mens-rights';
3228       contactURL = "/mens-contact";
3229       searchURL = "/mens-search";
3230       twitterId ="men_are_human";
3231   }
3232   
3233   else if (domain=='desktop.cloud-native.com'){
3234       deskTopJson='https://json.PythonLinks.info/golang/tree.json';
3235       rootName='golang';
3236       contactURL = "/golang-contact";
3237       searchURL = "/golang-search";
3238       twitterId ="PythonLinks";
3239   }
3240   
3241   
3242   
3243   else if (domain=='desktop.forestwiki.com'){
3244       deskTopJson='https://json.PythonLinks.info/forestwiki/tree.json';
3245       rootName='forestwiki';
3246       contactURL = "/golang-contact";
3247       searchURL = "/golang-search";
3248       twitterId ="forestwiki";
3249   }
3250   
3251   
3252   else if (domain=='dev.pythonlinks.info'){
3253       rootName ='python';
3254       mobileJson='/python/json';
3255       deskTopJson='/python/tree.json';
3256       var twitterId ="PythonLinks";   
3257       //rootName ='climate-change';
3258       //mobileJson='/climate-change/json';
3259       //deskTopJson='/climate-change/tree.json';
3260       //searchURL = "/search2";
3261       //contactURL = "/contact2";
3262   
3263   }
3264    
3265   
  

callbackVisit

3266     
3267    /** Call fn(node) for all child nodes.<br>
3268     * Stop iteration, if fn() returns false. Skip current branch, if fn() returns "skip".<br>
3269     * Return false if iteration was stopped.
3270     *
3271     * @param {function} fn the callback function.
3272     *     Return false to stop iteration, return "skip" to skip this node and
3273     *     its children only.
3274     * @param {boolean} [includeSelf=false]
3275     * @returns {boolean}
3276     */
3277     
3278   
3279     function callbackVisit(item,fn, includeSelf) {
3280    var i, 
3281        l,
3282    res = true,
3283    children = item.children;
3284    if( includeSelf === true ) {
3285    res = fn(item);
3286    if( res === false || res === "skip" ){
3287    return res;
3288    }
3289    }
3290    if(children&&(children.length>0)){
3291        callbackCount++;
3292    
3293        aFunction = function(){
3294        for(i=0, l=children.length; i<l; i++){
3295         callbackVisit(children[i],fn, true);
3296        }
3297        callbackCount--;
3298        if (callbackCount===0){
3299                   reSearch(fn);
3300                   }
3301        };   
3302        setTimeout(aFunction, 1);
3303    }
3304   
3305   
3306    
3307     }
3308   
3309   
3310     
3311            
3312            
3313    function callVisit(item,fn) {
3314    return callbackVisit(item.rootNode,fn, false);
3315    }
  

childrenFunctions

3316   
3317   function getSiblings (item){
3318       if (isRoot(item)){
3319           return [item];
3320       }
3321       return item.parent.children;
3322   }
3323       
  

parent-functions

3324    function pageTitle(node){
3325       var nodeParents= parents(node);
3326       var arrayLength = nodeParents.length;
3327       var result =[];
3328       for (var i = 0; i < arrayLength; i++) {
3329          result.push (getTitle(nodeParents[i]));
3330       }
3331        return result.join(' -> ');
3332       
3333   }
3334   
3335   //Starting with parent
3336   function reversedParents(node){
3337          var result=[];
3338        while (true){
3339            result.push(node);
3340            if (isRoot(node)){
3341                return result;
3342            }
3343            node=node.parent;
3344        }
3345   }
3346   
3347   //Starting with first ancenstor
3348   function parents(node){
3349       return reversedParents(node).reverse();
3350   }
  

pushpopstate

3351   function addSortBy(){
3352       return '?sortBy=' + sortBy;
3353   }
3354   function saveCurrentURL(){
3355      
3356       var domain= window.location.hostname;
3357       var location=getKey(homeNode);
3358   
3359       var url="https://" + domain + "/" + location + addSortBy();
3360       
3361   
3362       var title=getTitle(homeNode);
3363       var data={key:getKey(homeNode)};
3364    
3365    
3366   history.pushState(data, title, url);
3367       
3368   }
3369   
3370   function saveCurrentURLAndSearch(){
3371      
3372       var domain= window.location.hostname;
3373       var location=homeNode.key;
3374       var search=window.location.search;
3375   
3376       var url="https://" + domain + "/" + location;
3377       if (search){
3378           url+= search;
3379       }
3380       var title=homeNode.title;
3381       var data={key:homeNode.key};
3382    
3383    
3384   history.pushState(data, title, url);
3385       
3386   }
  

regexp

3387     
3388   
3389   //FUNCTION TO SPLIT A SEARCH STRING INTO W LIST OF WORDS, 
3390   // AND THEN CREATRE A LIST OF REGEXP
3391   // FROM IT.  This is needed to implement "SearchTermm1" and "SearchTerm2"
3392   
3393   
3394    function _escapeRegex(str){
3395    /*jshint regexdash:true */
3396    return (str + "").replace(/([.?*+\^\$\[\]\\(){}|-])/g, "\\$1");
3397   }
3398   
3399   
3400   //FUNCTION TO SPLIT A SEARCH STRING INTO W LIST OF WORDS, 
3401   // AND THEN CREATRE A LIST OF REGEXP
3402   // FROM IT.  This is needed to implement "SearchTermm1" and "SearchTerm2"
3403   
3404   function getRegxpArray(match) {
3405                   if (match=="all"){
3406                       return [new RegExp(".")];
3407                   }
3408                   if (match=="All"){
3409                       return [new RegExp(".")];
3410                   }
3411            var regexpArray=[]; 
3412            var i;
3413            var input;
3414            var k=0;
3415            var subStrings=match.split(/\s+/i);
3416            for (i in subStrings){
3417                if (subStrings[i]!==""){
3418                   input= _escapeRegex(subStrings[i]);
3419                   regexpArray[k]=new RegExp(input, "i");
3420                   k++;
3421                }
3422            }
3423            return regexpArray;
3424    }
3425   
  

resizeText

3426    function resizeText(multiplier) {
3427     if (document.body.style.fontSize === "") {
3428       document.body.style.fontSize = "2.0em";
3429     }
3430     document.body.style.fontSize = parseFloat(document.body.style.fontSize) + (multiplier * 0.2) + "em";
3431     localRebuild();
3432        
3433    }
3434   
  

scaleVideos

3435   function resizeVideos( arg1, arg2, containerQuery){
3436     //should be "body"
3437   // Find all YouTube videos
3438   var $allVideos = $("iframe[src^='https://www.youtube.com']"),
3439   
3440       // The element that is fluid width
3441       $fluidEl = $(containerQuery);
3442   
3443   // Figure out and save aspect ratio for each video
3444   $allVideos.each(function() {
3445   
3446     $(this)
3447       .data('aspectRatio', this.height / this.width)
3448       .data('width', this.width)
3449   
3450       // and remove the hard coded width/height
3451       .removeAttr('height')
3452       .removeAttr('width');
3453   
3454   });
3455   
3456   function resize () {
3457   
3458     var newWidth = $fluidEl.width();
3459     if (newWidth > 800){
3460         newWidth = 0.8 * newWidth;
3461     } 
3462     // Resize all videos according to their own aspect ratio
3463     $allVideos.each(function() {
3464   
3465       var $el = $(this);
3466       $el
3467         .width(newWidth)
3468         .height(newWidth * $el.data('aspectRatio'));
3469   
3470     });
3471     localRebuild();
3472    
3473   // Kick off one resize to fix all videos on page load
3474   }
3475   resize();
3476   }
  

setChildINdex

3477    //onSLideLeave
3478   function setChildIndex(){
3479           if (homeNode.parent!== null)
3480              homeNode.parent.previousChildIndex = getSiblings(homeNode).indexOf(homeNode);
3481   }
  

setTitle

3482    function setTitle(node){
3483        if (node.data.class == 'Video'){
3484            node.title =  score(node).toFixed(0) + '% ' 
3485            + node.data.upVotes + '👍 ' + 
3486            node.data.downVotes + '👎 '+
3487            node.title;
3488        }
3489        return true;
3490    }
  

showRedirect

3491    function showRedirect(node){
3492        if ((isMobile && (node==landingPage))) {
3493              var url = "https://" +
3494              "desktop." + domain + '/' + getKey(node);
3495              return '<center> <a href="' + url +
3496              '">Desktop Site (Beta)</a></center>';
3497        }
3498           return "";
3499    }
  

signout

3500    function renderSignOutOption(){
3501       if (isAuthenticated){
3502              return lili( '<a class="text-primary" onclick="signOut()">Sign Out</a>');
3503       }
3504       else 
3505       {return "";}
3506   }
3507   
3508   function signOut(){
3509       window.location.href = "/" + getKey(homeNode) + "/logout2";
3510   }
  

vote

3511   function registerVoter(){
3512        window.location.href="/" + homeNode.key + "/signup";
3513   }
3514   //"/register/voter"
3515   
3516   
3517   function recordVotes(responseText,itemName){
3518       var result = responseText.split (" , ");
3519        document.getElementById(itemName + "-" + "upVotes").innerHTML = result [0]; 
3520         document.getElementById(itemName + "-" + "downVotes").innerHTML = result [1];
3521   }
3522   
3523   function upVote(){
3524       var itemName = getKey(homeNode);
3525   
3526       if (isAuthenticated){
3527          var xhttp = new XMLHttpRequest();
3528          xhttp.onreadystatechange = function() {
3529              if (this.readyState == 4 && this.status == 200) {
3530                  recordVotes(this.responseText,itemName);
3531              }
3532          };
3533          var url = "/" + homeNode.key + "/upVote";
3534          xhttp.open("GET", url, true);
3535          xhttp.send();
3536          return;
3537          }
3538       registerVoter();
3539   }
3540   
3541   function downVote(){
3542         var itemName = getKey(homeNode);
3543   
3544       if (isAuthenticated){
3545           var xhttp = new XMLHttpRequest();
3546           xhttp.onreadystatechange = function() {
3547              if (this.readyState == 4 && this.status == 200) {
3548                 recordVotes(this.responseText,itemName);
3549              }
3550           };
3551           var url = "/" + homeNode.key + "/downVote";
3552           xhttp.open("GET", url, true);
3553           xhttp.send();
3554           return;
3555        }
3556            registerVoter();
3557   
3558   }
3559   
3560   
3561   
3562   
  

twitterImage

3563      var showBest = true;
3564    
3565    function renderTwitterImage(){
3566         return '' + 
3567         '<img src="https://pythonlinks.info//static/graphics/Tweet.png" '+ 
3568         'alt="I wanted to add users tweets to my website, but Twitter'+
3569         'would then track every page that you visit.  Not good for privacy. ' +
3570         'So if you are kind enough to tweet comments, I will link to them."'+
3571          'style = "max-width:100%;" onload="localRebuild">' +
3572           '<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Privacy Protecting Tweet Image';
3573   
3574        
3575    }
3576            
3577   function showIntroductoryVideo(slide){         
3578           if ((slide == landingPage)&&isMobile&& (rootName == 'python')) 
3579                {    
3580           return '<h3 style = "text-align:center;">'+
3581           '<a onClick="displaySlideNamed('+
3582           "'introductory-video')"+ '">' + 
3583           'Introductory Video</a></h3>'+
3584           '<p style="text-align:center">' + news + "</p>"; 
3585           }
3586           else {
3587          return '';
3588           }
3589   } 
3590   
3591   function generateLeadersOrContent(slide){
3592        return '<div  id = "bestContent' + 
3593        '-' + getKey(slide) + '" >'+
3594             generateLeadersOrContentCore(slide) +
3595         "</div>";
3596   }
  

twitterlink

3597   function twitterLinkFront(){
3598       var result ="";
3599       var base = 'https://twitter.com/intent/follow?screen_name=';
3600       result +=  '<a href="' + base +
3601       twitterId +
3602       '">' 
3603       return result;
3604   }
3605   function twitterLinkBack(){
3606       return  '</a>';
3607   }
3608