<commit_before>'use strict';

//animate the logos in the opening splash modal
function splashAnimation() {
	var animateTicTacToe;
	var animationInterval = 674; //674 is beat of opening music
	var logoStates = ["board","tic","tac","toe"];
	var i = 1;

	function animateTicTacToeFn() {
		$("#ttt-logo__element").addClass("ttt-logo__element--" + logoStates[i]).removeClass("ttt-logo__element--" + logoStates[i-1]);
        console.log(("#ttt-logo__element--" + logoStates[i]),("#ttt-logo__element--" + logoStates[i-1]));
        console.log($("#ttt-logo__element").attr("class"));
		if (i == 3) {
			clearInterval(animateTicTacToe);
		}
		i++;
	}

	$("#ttt-logo__element").slideDown(animationInterval / 4, function() {

		animateTicTacToe = window.setInterval(animateTicTacToeFn, animationInterval);

		setTimeout(function() {
			$('#pokemon-logo').removeClass('u-hidden').addClass('animated rubberBand').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
				$(this).removeClass("animated rubberBand");
			});
		}, animationInterval * 4);

	});
}

$(function() {
    var isMobile = false;

    // Music and sound effects settings
    var soundEffectsOn = true;
    function toggleSound() {
        if (soundEffectsOn) {
          soundEffectsOn = false;
          $("#controls__toggle--sound").addClass("controls__toggle--off").attr("title", "Sound Effects On");
      } else {
          soundEffectsOn = true;
          $("#controls__toggle--sound").removeClass("controls__toggle--off").attr("title", "Sound Effects Off");
          if (isMobile && !document.getElementById('music').paused) {
              toggleMusic();
          }
      }
    }

    //set music toggle functionality
    function toggleMusic() {
        var music =document.getElementById('music');
      if (music.paused == false) {
          music.pause();
          $("#controls__toggle--music").addClass("controls__toggle--off").attr("title", "Music On");
      } else {
          music.play();
          $("#controls__toggle--music").removeClass("controls__toggle--off").attr("title", "Music Off");
          if (isMobile && soundEffectsOn) {
              toggleSound();
          }
      }
    }
    $("#controls__toggle--music").click(toggleMusic);
    $("#controls__toggle--sound").click(toggleSound);

    function setMobileSettings() {
        if (!isMobile) { //if this is the first time tapping the page
            document.getElementById('music').play();
            toggleSound();
        }

        isMobile = true;

        var el = document.documentElement,
          rfs = el.requestFullscreen
            || el.webkitRequestFullScreen
            || el.mozRequestFullScreen
            || el.msRequestFullscreen
        ;

        rfs.call(el);

        //lock portrait orientation on mobile
        screen.orientation.lock("portrait");
        screen.lockOrientationUniversal = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation;
        screen.lockOrientationUniversal("portrait");
    }

    // for mobile, activate music, set fullscreen, lock portrait orientation
    $('#view').bind("touchstart tap", setMobileSettings);

    //load background map image
    new Promise(function(resolve) {
        var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);

        if (viewHeight > 1080) {
            var backgroundSource = "./img/johto-kanto-map-3000x1316.jpg";
        } else if (viewHeight > 680) {
            var backgroundSource = "./img/johto-kanto-map-3000x1062.jpg";
        } else {
            var backgroundSource = "./img/johto-kanto-map-1921x680.jpg";
        }

        var background = document.createElement('img') ;
        background.src = backgroundSource;
        background.id = "background";
        background.className = "background";
        background.onload = resolve;
        $("#view").prepend(background);
        $("#background").attr('alt', "A map of the Pokemon world in the background")

    }) // then set horizontal scrolling animation
        .then(function() {

    	var backgroundScrollSpeed = 150;//higher number is slower
    	var backgroundTiming; //time in ms for full scroll of one direction
    	var backgroundTransition; //css transition value used for animation
    	var backgroundMargin; //number of horizontal pixels to scroll each direction
    	var animateBackground; //a setInterval function

    	function updateBackgroundTiming() {	//triggered on load and resize.  also starts/restarts animation
    		backgroundMargin = Math.floor($("#background").width() - document.documentElement.clientWidth);
    		backgroundTiming = backgroundMargin * backgroundScrollSpeed;

    		var backgroundTransition = "transform "+backgroundTiming+"ms linear"
    		var backgroundTransitionObj = {
    			transition: backgroundTransition,
    			"-webkit-transition": backgroundTransition
    		};

    		$("#background").css(backgroundTransitionObj);

    		clearInterval(animateBackground);
    		animateBackgroundFn()
    		animateBackground = window.setInterval(animateBackgroundFn, backgroundTiming * 2);
    	}

    	function animateBackgroundFn(reverse) {
    		var backgroundTranslate = "translate3d(-"+backgroundMargin+"px, 0px, 0px)"
    		if (reverse) {
    			var backgroundTransform = {
    				transform: "",
    				"-webkit-transform": ""
    			}
    		} else {
    			var backgroundTransform = {
    				transform: backgroundTranslate,
    				"-webkit-transform": backgroundTranslate
    			}
    		}
    		$("#background").css(backgroundTransform)

    		if (!reverse) {
    			setTimeout(function() {
    				animateBackgroundFn(true);
    			}, backgroundTiming)

    		}

    	} // end animateBackgroundFn

    	updateBackgroundTiming()
    	$(window).on("resize", updateBackgroundTiming);

    }); // end "then" attached to background image load promise

    splashAnimation();

})
<commit_msg>add delay to beginning splash animation<commit_after>'use strict';

//animate the logos in the opening splash modal
function splashAnimation() {
	var animateTicTacToe;
	var animationInterval = 674; //674 is beat of opening music
	var logoStates = ["board","tic","tac","toe"];
	var i = 1;

	function animateTicTacToeFn() {
		$("#ttt-logo__element").addClass("ttt-logo__element--" + logoStates[i]).removeClass("ttt-logo__element--" + logoStates[i-1]);
        console.log(("#ttt-logo__element--" + logoStates[i]),("#ttt-logo__element--" + logoStates[i-1]));
        console.log($("#ttt-logo__element").attr("class"));
		if (i == 3) {
			clearInterval(animateTicTacToe);
		}
		i++;
	}

    setTimeout(function() {
    	$("#ttt-logo__element").slideDown(animationInterval / 4, function() {

    		animateTicTacToe = window.setInterval(animateTicTacToeFn, animationInterval);

    		setTimeout(function() {
    			$('#pokemon-logo').removeClass('u-hidden').addClass('animated rubberBand').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
    				$(this).removeClass("animated rubberBand");
    			});
    		}, animationInterval * 4);

    	});
    }, animationInterval * 2);
}

$(function() {
    var isMobile = false;

    // Music and sound effects settings
    var soundEffectsOn = true;
    function toggleSound() {
        if (soundEffectsOn) {
          soundEffectsOn = false;
          $("#controls__toggle--sound").addClass("controls__toggle--off").attr("title", "Sound Effects On");
      } else {
          soundEffectsOn = true;
          $("#controls__toggle--sound").removeClass("controls__toggle--off").attr("title", "Sound Effects Off");
          if (isMobile && !document.getElementById('music').paused) {
              toggleMusic();
          }
      }
    }

    //set music toggle functionality
    function toggleMusic() {
        var music =document.getElementById('music');
      if (music.paused == false) {
          music.pause();
          $("#controls__toggle--music").addClass("controls__toggle--off").attr("title", "Music On");
      } else {
          music.play();
          $("#controls__toggle--music").removeClass("controls__toggle--off").attr("title", "Music Off");
          if (isMobile && soundEffectsOn) {
              toggleSound();
          }
      }
    }
    $("#controls__toggle--music").click(toggleMusic);
    $("#controls__toggle--sound").click(toggleSound);

    function setMobileSettings() {
        if (!isMobile) { //if this is the first time tapping the page
            document.getElementById('music').play();
            toggleSound();
        }

        isMobile = true;

        var el = document.documentElement,
          rfs = el.requestFullscreen
            || el.webkitRequestFullScreen
            || el.mozRequestFullScreen
            || el.msRequestFullscreen
        ;

        rfs.call(el);

        //lock portrait orientation on mobile
        screen.orientation.lock("portrait");
        screen.lockOrientationUniversal = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation;
        screen.lockOrientationUniversal("portrait");
    }

    // for mobile, activate music, set fullscreen, lock portrait orientation
    $('#view').bind("touchstart tap", setMobileSettings);

    //load background map image
    new Promise(function(resolve) {
        var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);

        if (viewHeight > 1080) {
            var backgroundSource = "./img/johto-kanto-map-3000x1316.jpg";
        } else if (viewHeight > 680) {
            var backgroundSource = "./img/johto-kanto-map-3000x1062.jpg";
        } else {
            var backgroundSource = "./img/johto-kanto-map-1921x680.jpg";
        }

        var background = document.createElement('img') ;
        background.src = backgroundSource;
        background.id = "background";
        background.className = "background";
        background.onload = resolve;
        $("#view").prepend(background);
        $("#background").attr('alt', "A map of the Pokemon world in the background")

    }) // then set horizontal scrolling animation
        .then(function() {

    	var backgroundScrollSpeed = 150;//higher number is slower
    	var backgroundTiming; //time in ms for full scroll of one direction
    	var backgroundTransition; //css transition value used for animation
    	var backgroundMargin; //number of horizontal pixels to scroll each direction
    	var animateBackground; //a setInterval function

    	function updateBackgroundTiming() {	//triggered on load and resize.  also starts/restarts animation
    		backgroundMargin = Math.floor($("#background").width() - document.documentElement.clientWidth);
    		backgroundTiming = backgroundMargin * backgroundScrollSpeed;

    		var backgroundTransition = "transform "+backgroundTiming+"ms linear"
    		var backgroundTransitionObj = {
    			transition: backgroundTransition,
    			"-webkit-transition": backgroundTransition
    		};

    		$("#background").css(backgroundTransitionObj);

    		clearInterval(animateBackground);
    		animateBackgroundFn()
    		animateBackground = window.setInterval(animateBackgroundFn, backgroundTiming * 2);
    	}

    	function animateBackgroundFn(reverse) {
    		var backgroundTranslate = "translate3d(-"+backgroundMargin+"px, 0px, 0px)"
    		if (reverse) {
    			var backgroundTransform = {
    				transform: "",
    				"-webkit-transform": ""
    			}
    		} else {
    			var backgroundTransform = {
    				transform: backgroundTranslate,
    				"-webkit-transform": backgroundTranslate
    			}
    		}
    		$("#background").css(backgroundTransform)

    		if (!reverse) {
    			setTimeout(function() {
    				animateBackgroundFn(true);
    			}, backgroundTiming)

    		}

    	} // end animateBackgroundFn

    	updateBackgroundTiming()
    	$(window).on("resize", updateBackgroundTiming);

    }); // end "then" attached to background image load promise

    splashAnimation();

})
<|endoftext|>


<commit_before>import R from 'ramda';
import And from './and';
import Or from './or';

/**
 * Check if the given object is an object-like `And` conjunction.
 * @param {Object} obj
 * @param {String} obj.type
 * @returns {Boolean}
 */
const objectIsAndConjunction = R.compose(
  R.equals(And.type()),
  R.prop('type')
);

/**
 * Check if the given object is an object-like `Or` conjunction.
 * @param {Object} obj
 * @param {String} obj.type
 * @returns {Boolean}
 */
const objectIsOrConjunction = R.compose(
  R.equals(Or.type()),
  R.prop('type')
);

const create = obj => {
  if (objectIsOrConjunction(obj)) {
    return new Or(obj.mappings);
  } else if (objectIsAndConjunction(obj)) {
    return new And(obj.mappings);
  } else {
    var message = 'Cannot create conjunction based on ' + obj;
    throw new Error(message);
  }
}

export default {
  create,
  And,
  Or
};
<commit_msg>Export Conjunction<commit_after>import R from 'ramda';
import And from './and';
import Or from './or';
import Conjunction from './conjunction';

/**
 * Check if the given object is an object-like `And` conjunction.
 * @param {Object} obj
 * @param {String} obj.type
 * @returns {Boolean}
 */
const objectIsAndConjunction = R.compose(
  R.equals(And.type()),
  R.prop('type')
);

/**
 * Check if the given object is an object-like `Or` conjunction.
 * @param {Object} obj
 * @param {String} obj.type
 * @returns {Boolean}
 */
const objectIsOrConjunction = R.compose(
  R.equals(Or.type()),
  R.prop('type')
);

const create = obj => {
  if (objectIsOrConjunction(obj)) {
    return new Or(obj.mappings);
  } else if (objectIsAndConjunction(obj)) {
    return new And(obj.mappings);
  } else {
    var message = 'Cannot create conjunction based on ' + obj;
    throw new Error(message);
  }
}

export default {
  create,
  And,
  Or,
  Conjunction
};
<|endoftext|>


<commit_before>/* global angular */
/* global mineDatabaseServices */

angular.module('app',['ui.router','ui.bootstrap','ngCookies', 'ngJoyRide', 'ui-rangeSlider', 'angulartics',
    'angulartics.google.analytics', 'ui.select', 'angularMasspecPlotter']);
angular.module('app').factory('sharedFactory', function($state, $cookieStore, $rootScope){
    var factory = {
        dbId: 'KEGG',
        //if the db changes in one of these states, reload the page
        db_dependent_states: ['compounds', 'metabolomicsCompounds', 'structuresres', 'operator', 'acompound.reactants',
            'acompound.products', 'acompound.overview'],
        selected_model: "",
        img_src: "http://webfba.chem-eng.northwestern.edu/MINE_imgs/",
        services: new mineDatabaseServices('https://minedatabase.ci.northwestern.edu/mineserver/'),
        numPerPage: 25, // default number of results to show per page
        setDB: function (db_id) {
            console.log("setDB:" + db_id);
            if (factory.dbId !== db_id) {
                factory.dbId = db_id;
                $cookieStore.put('mine_db', db_id);
                $rootScope.$broadcast("dbUpdated");
                $state.go($state.current, {db:db_id});
            }
        },
        getImagePath: function (id) {
            if (id) {
                var img_root = "http://webfba.chem-eng.northwestern.edu/MINE_imgs/";
                var dir_depth = 4;
                var ext = '.svg';
                for (var i = 0; i < dir_depth; i++) {
                    img_root += id[i] + "/";
                }
                return img_root + id + ext
            }
        },
        downloadFile: function (contents,filename) {
            // Warning: This function may not work with IE!
            var link = document.createElement('a');
            link.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(contents));
            link.setAttribute('download', filename);
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        },
        convertToCSV: function(compounds, fields) {
            var objArray = typeof compounds != 'object' ? JSON.parse(compounds) : compounds;
            var replacer = function(key, value) {
                if (value === null) {return '';}
                if (typeof value === 'object') {return value.join(';');}
                return value;
            };
            var csv = objArray.map(function(row){
              return fields.map(function(fieldName){
                return JSON.stringify(row[fieldName], replacer)
              }).join(',')
            });
            csv.unshift(fields.join(',')); // add header column
            return csv.join('\r\n');
        },
        paginateList: function(list, currentPage, numPerPage){
            var begin = ((currentPage - 1) * numPerPage);
            var end = begin + numPerPage;
            return list.slice(begin, end);
        },
        filterList: function(list, mine, compound, formula) {
            // filtering but we have to handle names carefully (sometimes not present) and use RegEx with formula
            var filteredList = [];
            var f_patt = new RegExp(formula, 'i');
            var c_patt = new RegExp(compound, 'i');
            for (var i = 0; i < list.length; i++) {
                if ((f_patt.test(list[i].Formula.toString())) && (list[i].MINE_id.toString().indexOf(mine) > -1) &&
                    (!compound || (typeof(list[i].Names) != 'undefined') && (c_patt.test(list[i].Names.toString())))) {
                    filteredList.push(list[i])
                }
            }
            return filteredList
        },
        sortList: function(list, attribute, ascending){
            list.sort(function(a,b){
                if (a[attribute]===""||a[attribute]===null) return 1;
                if (b[attribute]===""||a[attribute]===null) return -1;
                var order;
                if (typeof a[attribute] === 'string') {
                        order = a[attribute].localeCompare(b[attribute])
                    }
                    else {order = a[attribute]-b[attribute]}
                return (ascending ? -order : order)
            });
            return list
        }
    };
    return factory
});
if (navigator.userAgent.indexOf('MSIE') > 0 || navigator.appVersion.indexOf('Trident/') > 0) {
   alert("This web application does not officially support Internet Explorer and some elements may not render or " +
       "function correctly in this environment. For best performance, utilize the Chrome browser.")
}

angular.module('app').directive('errSrc', function() {
  return {
    link: function(scope, element, attrs) {
      element.bind('error', function() {
        if (attrs.src !== attrs.errSrc) {
          attrs.$set('src', attrs.errSrc);
        }
      });
    }
  }
});

angular.module('app').controller('cookieCtl',function($scope,$cookieStore) {
    $scope.startGeneralTour = function () {
        var tour = new Tour(generalTour());
        tour.init();
        tour.start();
    };

    $scope.startMetabolomicsTour = function () {
        var tour = new Tour(metabolomicsTour());
        tour.init();
        tour.start();
    };

    var visited = $cookieStore.get('mine');
    if( typeof(visited) == 'undefined') {
        $cookieStore.put('mine', "mine_visitor");
        //$scope.startGeneralTour()
    }
});

angular.module('app').controller('databaseCtl',  function ($scope,$state,sharedFactory,$cookieStore) {
    $scope.databases =  [
        {id:0, name:'KEGG',  db :'KEGGexp2'},
        {id:1, name:'EcoCyc', db : 'EcoCycexp2'},
        {id:2, name:'YMDB', db : 'YMDBexp2'},
        {id:3, name:'Chemical Damage SEED', db : 'CDMINE'},
    ];

    var updateSelection = function() {console.log("ping"); $scope.databases.forEach(
        function (option) {if (sharedFactory.dbId == option.db) $scope.database = $scope.databases[option.id]})};

    var database_id = $cookieStore.get('mine_db');
    if (typeof(database_id) != 'undefined') {sharedFactory.dbId = database_id}
    updateSelection();
    $scope.$on("dbUpdated", updateSelection);

    $scope.$watch('database', function() {
        sharedFactory.setDB($scope.database.db)
    });
});

angular.module('app').config(function($stateProvider, $urlRouterProvider) {

    $urlRouterProvider.otherwise('/home');
    //HOME
    $stateProvider.state('home', {
        url: '/home',
        templateUrl: 'partials/home.html',
        controller: "cookieCtl"
    });
    //FAQ
    $stateProvider.state('faq', {
        url: '/faq',
        templateUrl: 'partials/FAQ.html',
        controller: "cookieCtl"
    });

    // COMPOUNDS QUICK SEARCH see textSearch.js
    $stateProvider.state('compounds', {
        url: '/compounds-:search?db',
        views: {
            '':{
                templateUrl: 'partials/compoundslist.html',
                controller: "compoundsCtl"
                },
            'sidebar':{
                templateUrl: 'partials/models.html',
                controller: "modelsCtl"
            }
        }
    });
    $stateProvider.state('advancedsearch', {
        url: '/advancedsearch',
        views: {
            '':{
                templateUrl: 'partials/advancedsearch.html',
                controller: "advancedSearchCtl"
                },
            'sidebar':{
                templateUrl: 'partials/models.html',
                controller: "modelsCtl"
            }
        }
    });

    // AN INDIVIDUAL COMPOUND see acompound.js
    $stateProvider.state('acompound', {
        url: '/acompound-:id?db',
        templateUrl: 'partials/acompound.html',
        controller: "acompoundCtl"
    });
    $stateProvider.state('acompound.overview', {
        url: '/overview',
        templateUrl: 'partials/overview.html',
        controller: "acompoundCtl"
    });
    $stateProvider.state('acompound.reactants', {
        url: '/reactantIn',
        templateUrl: 'partials/reactions.html',
        controller: "reactantInCtl"
    });
    $stateProvider.state('acompound.products', {
        url: '/productOf',
        templateUrl: 'partials/reactions.html',
        controller: "productOfCtl"
    });

    $stateProvider.state('operator', {
        url: '/operator-:id?db',
        views: {
            '': {
                templateUrl: 'partials/operator.html',
                controller: "operatorCtl"
            },
            'rxns': {
                templateUrl: 'partials/reactions.html',
                controller: "rxnListCtl"
            }
        }
    });

    //METABOLOMICS see metabolomics.js
    $stateProvider.state('msAdductSearch', {

        url: '/msAdductSearch',
        views: {
            '':{
                templateUrl: 'partials/ms-adduct.html',
                controller: "metabolomicsCtl"
            },
            'sidebar':{
                templateUrl: 'partials/models.html',
                controller: "modelsCtl"
            }
        }
    });
    $stateProvider.state('ms2search', {

        url: '/ms2search',
        views: {
            '':{
                templateUrl: 'partials/ms2-search.html',
                controller: "ms2searchCtl"
            },
            'sidebar':{
                templateUrl: 'partials/models.html',
                controller: "modelsCtl"
            }
        }
    });
    $stateProvider.state('metabolomicsCompounds', {
      url: '/metabolomicsCompounds-:search?db',
      views: {
            '':{
                templateUrl: 'partials/metaboliteslist.html',
                controller: "metabolomicsCompoundsCtl"
                },
            'sidebar':{
                templateUrl: 'partials/models.html',
                controller: "modelsCtl"
            }
        }
    });

    // STRUCTURES see structures.js
    $stateProvider.state('structuresres', {
        url: '/structuresres:search?db',
        views: {
            '':{
                templateUrl: 'partials/compoundslist.html',
                controller: "structuresresCtl"
                },
            'sidebar':{
                templateUrl: 'partials/models.html',
                controller: "modelsCtl"
            }
        }

    });
    $stateProvider.state('structure', {
        url: '/structure',
        views: {
            '':{
                templateUrl: 'partials/structureSearch.html',
                controller: "structureCtl"
                },
            'sidebar':{
                templateUrl: 'partials/models.html',
                controller: "modelsCtl"
            }
        }
    });

    //Top 30 damage prone metabolites reaction list
    $stateProvider.state('top30', {
        url: '/top30',
        templateUrl: 'partials/top30.html',
        controller: "cookieCtl"
    });
    $stateProvider.state('top30.s1', {
        url: '/S1:id',
        templateUrl: 'partials/S1.html',
        controller: "s1Ctl"
    });
    $stateProvider.state('top30.s2', {
        url: '/S2',
        templateUrl: 'partials/S2.html',
        controller: "s2Ctl"
    });
});
<commit_msg>Added SSL to server that stores images<commit_after>/* global angular */
/* global mineDatabaseServices */

angular.module('app',['ui.router','ui.bootstrap','ngCookies', 'ngJoyRide', 'ui-rangeSlider', 'angulartics',
    'angulartics.google.analytics', 'ui.select', 'angularMasspecPlotter']);
angular.module('app').factory('sharedFactory', function($state, $cookieStore, $rootScope){
    var factory = {
        dbId: 'KEGG',
        //if the db changes in one of these states, reload the page
        db_dependent_states: ['compounds', 'metabolomicsCompounds', 'structuresres', 'operator', 'acompound.reactants',
            'acompound.products', 'acompound.overview'],
        selected_model: "",
        img_src: "https://webfba.chem-eng.northwestern.edu/MINE_imgs/",
        services: new mineDatabaseServices('https://minedatabase.ci.northwestern.edu/mineserver/'),
        numPerPage: 25, // default number of results to show per page
        setDB: function (db_id) {
            console.log("setDB:" + db_id);
            if (factory.dbId !== db_id) {
                factory.dbId = db_id;
                $cookieStore.put('mine_db', db_id);
                $rootScope.$broadcast("dbUpdated");
                $state.go($state.current, {db:db_id});
            }
        },
        getImagePath: function (id) {
            if (id) {
                var img_root = "https://webfba.chem-eng.northwestern.edu/MINE_imgs/";
                var dir_depth = 4;
                var ext = '.svg';
                for (var i = 0; i < dir_depth; i++) {
                    img_root += id[i] + "/";
                }
                return img_root + id + ext
            }
        },
        downloadFile: function (contents,filename) {
            // Warning: This function may not work with IE!
            var link = document.createElement('a');
            link.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(contents));
            link.setAttribute('download', filename);
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        },
        convertToCSV: function(compounds, fields) {
            var objArray = typeof compounds != 'object' ? JSON.parse(compounds) : compounds;
            var replacer = function(key, value) {
                if (value === null) {return '';}
                if (typeof value === 'object') {return value.join(';');}
                return value;
            };
            var csv = objArray.map(function(row){
              return fields.map(function(fieldName){
                return JSON.stringify(row[fieldName], replacer)
              }).join(',')
            });
            csv.unshift(fields.join(',')); // add header column
            return csv.join('\r\n');
        },
        paginateList: function(list, currentPage, numPerPage){
            var begin = ((currentPage - 1) * numPerPage);
            var end = begin + numPerPage;
            return list.slice(begin, end);
        },
        filterList: function(list, mine, compound, formula) {
            // filtering but we have to handle names carefully (sometimes not present) and use RegEx with formula
            var filteredList = [];
            var f_patt = new RegExp(formula, 'i');
            var c_patt = new RegExp(compound, 'i');
            for (var i = 0; i < list.length; i++) {
                if ((f_patt.test(list[i].Formula.toString())) && (list[i].MINE_id.toString().indexOf(mine) > -1) &&
                    (!compound || (typeof(list[i].Names) != 'undefined') && (c_patt.test(list[i].Names.toString())))) {
                    filteredList.push(list[i])
                }
            }
            return filteredList
        },
        sortList: function(list, attribute, ascending){
            list.sort(function(a,b){
                if (a[attribute]===""||a[attribute]===null) return 1;
                if (b[attribute]===""||a[attribute]===null) return -1;
                var order;
                if (typeof a[attribute] === 'string') {
                        order = a[attribute].localeCompare(b[attribute])
                    }
                    else {order = a[attribute]-b[attribute]}
                return (ascending ? -order : order)
            });
            return list
        }
    };
    return factory
});
if (navigator.userAgent.indexOf('MSIE') > 0 || navigator.appVersion.indexOf('Trident/') > 0) {
   alert("This web application does not officially support Internet Explorer and some elements may not render or " +
       "function correctly in this environment. For best performance, utilize the Chrome browser.")
}

angular.module('app').directive('errSrc', function() {
  return {
    link: function(scope, element, attrs) {
      element.bind('error', function() {
        if (attrs.src !== attrs.errSrc) {
          attrs.$set('src', attrs.errSrc);
        }
      });
    }
  }
});

angular.module('app').controller('cookieCtl',function($scope,$cookieStore) {
    $scope.startGeneralTour = function () {
        var tour = new Tour(generalTour());
        tour.init();
        tour.start();
    };

    $scope.startMetabolomicsTour = function () {
        var tour = new Tour(metabolomicsTour());
        tour.init();
        tour.start();
    };

    var visited = $cookieStore.get('mine');
    if( typeof(visited) == 'undefined') {
        $cookieStore.put('mine', "mine_visitor");
        //$scope.startGeneralTour()
    }
});

angular.module('app').controller('databaseCtl',  function ($scope,$state,sharedFactory,$cookieStore) {
    $scope.databases =  [
        {id:0, name:'KEGG',  db :'KEGGexp2'},
        {id:1, name:'EcoCyc', db : 'EcoCycexp2'},
        {id:2, name:'YMDB', db : 'YMDBexp2'},
        {id:3, name:'Chemical Damage SEED', db : 'CDMINE'},
    ];

    var updateSelection = function() {console.log("ping"); $scope.databases.forEach(
        function (option) {if (sharedFactory.dbId == option.db) $scope.database = $scope.databases[option.id]})};

    var database_id = $cookieStore.get('mine_db');
    if (typeof(database_id) != 'undefined') {sharedFactory.dbId = database_id}
    updateSelection();
    $scope.$on("dbUpdated", updateSelection);

    $scope.$watch('database', function() {
        sharedFactory.setDB($scope.database.db)
    });
});

angular.module('app').config(function($stateProvider, $urlRouterProvider) {

    $urlRouterProvider.otherwise('/home');
    //HOME
    $stateProvider.state('home', {
        url: '/home',
        templateUrl: 'partials/home.html',
        controller: "cookieCtl"
    });
    //FAQ
    $stateProvider.state('faq', {
        url: '/faq',
        templateUrl: 'partials/FAQ.html',
        controller: "cookieCtl"
    });

    // COMPOUNDS QUICK SEARCH see textSearch.js
    $stateProvider.state('compounds', {
        url: '/compounds-:search?db',
        views: {
            '':{
                templateUrl: 'partials/compoundslist.html',
                controller: "compoundsCtl"
                },
            'sidebar':{
                templateUrl: 'partials/models.html',
                controller: "modelsCtl"
            }
        }
    });
    $stateProvider.state('advancedsearch', {
        url: '/advancedsearch',
        views: {
            '':{
                templateUrl: 'partials/advancedsearch.html',
                controller: "advancedSearchCtl"
                },
            'sidebar':{
                templateUrl: 'partials/models.html',
                controller: "modelsCtl"
            }
        }
    });

    // AN INDIVIDUAL COMPOUND see acompound.js
    $stateProvider.state('acompound', {
        url: '/acompound-:id?db',
        templateUrl: 'partials/acompound.html',
        controller: "acompoundCtl"
    });
    $stateProvider.state('acompound.overview', {
        url: '/overview',
        templateUrl: 'partials/overview.html',
        controller: "acompoundCtl"
    });
    $stateProvider.state('acompound.reactants', {
        url: '/reactantIn',
        templateUrl: 'partials/reactions.html',
        controller: "reactantInCtl"
    });
    $stateProvider.state('acompound.products', {
        url: '/productOf',
        templateUrl: 'partials/reactions.html',
        controller: "productOfCtl"
    });

    $stateProvider.state('operator', {
        url: '/operator-:id?db',
        views: {
            '': {
                templateUrl: 'partials/operator.html',
                controller: "operatorCtl"
            },
            'rxns': {
                templateUrl: 'partials/reactions.html',
                controller: "rxnListCtl"
            }
        }
    });

    //METABOLOMICS see metabolomics.js
    $stateProvider.state('msAdductSearch', {

        url: '/msAdductSearch',
        views: {
            '':{
                templateUrl: 'partials/ms-adduct.html',
                controller: "metabolomicsCtl"
            },
            'sidebar':{
                templateUrl: 'partials/models.html',
                controller: "modelsCtl"
            }
        }
    });
    $stateProvider.state('ms2search', {

        url: '/ms2search',
        views: {
            '':{
                templateUrl: 'partials/ms2-search.html',
                controller: "ms2searchCtl"
            },
            'sidebar':{
                templateUrl: 'partials/models.html',
                controller: "modelsCtl"
            }
        }
    });
    $stateProvider.state('metabolomicsCompounds', {
      url: '/metabolomicsCompounds-:search?db',
      views: {
            '':{
                templateUrl: 'partials/metaboliteslist.html',
                controller: "metabolomicsCompoundsCtl"
                },
            'sidebar':{
                templateUrl: 'partials/models.html',
                controller: "modelsCtl"
            }
        }
    });

    // STRUCTURES see structures.js
    $stateProvider.state('structuresres', {
        url: '/structuresres:search?db',
        views: {
            '':{
                templateUrl: 'partials/compoundslist.html',
                controller: "structuresresCtl"
                },
            'sidebar':{
                templateUrl: 'partials/models.html',
                controller: "modelsCtl"
            }
        }

    });
    $stateProvider.state('structure', {
        url: '/structure',
        views: {
            '':{
                templateUrl: 'partials/structureSearch.html',
                controller: "structureCtl"
                },
            'sidebar':{
                templateUrl: 'partials/models.html',
                controller: "modelsCtl"
            }
        }
    });

    //Top 30 damage prone metabolites reaction list
    $stateProvider.state('top30', {
        url: '/top30',
        templateUrl: 'partials/top30.html',
        controller: "cookieCtl"
    });
    $stateProvider.state('top30.s1', {
        url: '/S1:id',
        templateUrl: 'partials/S1.html',
        controller: "s1Ctl"
    });
    $stateProvider.state('top30.s2', {
        url: '/S2',
        templateUrl: 'partials/S2.html',
        controller: "s2Ctl"
    });
});
<|endoftext|>


<commit_before>import React, { Component } from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { Router, Route, IndexRoute, IndexRedirect, Redirect } from "react-router";
import { routerActions } from "react-router-redux";
import { connectedReduxRedirect } from "redux-auth-wrapper/history3/redirect";

import { setConfig } from "./app/config/actions";
import App from "./app/App";
import Layout from "./app/global/Layout";
import LoginController from "./app/views/login/LoginController";
import CollectionsController from "./app/views/collections/CollectionsController";
import TeamsController from "./app/views/teams/TeamsController";
import SelectADataset from "./app/views/datasets-new/DatasetsController";
import DatasetEditionsController from "./app/views/datasets-new/editions/DatasetEditionsController";
import DatasetVersionsController from "./app/views/datasets-new/versions/DatasetVersionsController";
import DatasetMetadataController from "./app/views/datasets-new/edit-metadata/DatasetMetadataController";
import CreateDatasetController from "./app/views/datasets-new/create/CreateDatasetController";
import CreateDatasetTaxonomyController from "./app/views/datasets-new/create/CreateDatasetTaxonomyController";
import CreateVersionController from "./app/views/datasets-new/create/CreateVersionController";
import CreateEditionController from "./app/views/datasets-new/create/CreateEditionController";
import UsersController from "./app/views/users/UsersController";
import UserDetailsController from "./app/views/users/details/UserDetailsController";
import DatasetsController from "./app/views/datasets/DatasetsController";
import DatasetUploadsController from "./app/views/uploads/dataset/DatasetUploadsController";
import DatasetUploadDetails from "./app/views/uploads/dataset/upload-details/DatasetUploadDetails";
import DatasetUploadMetadata from "./app/views/uploads/dataset/upload-details/DatasetUploadMetadata";
import DatasetMetadata from "./app/views/datasets/metadata/DatasetMetadata";
import VersionMetadata from "./app/views/datasets/metadata/VersionMetadata";
import EditHomepageController from "./app/views/homepage/edit/EditHomepageController"
import EditHomepageItem from "./app/views/homepage/edit/EditHomepageItem"

import Logs from "./app/views/logs/Logs";

import auth from "./app/utilities/auth";

import "./scss/main.scss";

import { store, history } from "./app/config/store";

import SelectableTest from "./SelectableTest";
import VersionPreviewController from "./app/views/datasets/preview/VersionPreviewController";
import PreviewController from "./app/views/preview/PreviewController";
import DatasetPreviewController from "./app/views/datasets-new/preview/PreviewController";
import EditMetadataItem from "./app/views/datasets-new/edit-metadata/EditMetadataItem";
import ChangeUserPasswordController from "./app/views/users/change-password/ChangeUserPasswordController";
import ConfirmUserDeleteController from "./app/views/users/confirm-delete/ConfirmUserDeleteController";
import CollectionRoutesWrapper from "./app/global/collection-wrapper/CollectionRoutesWrapper";
import WorkflowPreview from "./app/views/workflow-preview/WorkflowPreview";
import CreateContent from "./app/views/content/CreateContent";

const config = window.getEnv();
store.dispatch(setConfig(config));

const rootPath = store.getState().state.rootPath;

const userIsAuthenticated = connectedReduxRedirect({
    authenticatedSelector: state => {
        return auth.isAuthenticated(state.state.user);
    },
    redirectAction: routerActions.replace,
    wrapperDisplayName: "UserIsAuthenticated",
    redirectPath: `${rootPath}/login`
});

const userIsAdminOrEditor = connectedReduxRedirect({
    authenticatedSelector: state => {
        return auth.isAdminOrEditor(state.state.user);
    },
    redirectAction: routerActions.replace,
    wrapperDisplayName: "userIsAdminOrEditor",
    redirectPath: `${rootPath}/collections`,
    allowRedirectBack: false
});

class UnknownRoute extends Component {
    render() {
        return (

Sorry, this page couldnt be found

        );
    }
}

class Index extends Component {
    render() {
        return (
            <Provider store={store}>
                <Router history={history}>
                    <Route component={App}>
                        <Route component={Layout}>
                            <Redirect from={`${rootPath}`} to={`${rootPath}/collections`} />
                            <Route path={`${rootPath}/collections`} component={userIsAuthenticated(CollectionsController)}>
                                <Route path=":collectionID" component={userIsAuthenticated(CollectionsController)}>
                                    <Route path="edit" component={userIsAuthenticated(CollectionsController)} />
                                    <Route path="restore-content" component={userIsAuthenticated(CollectionsController)} />
                                </Route>
                            </Route>
                            <Route component={CollectionRoutesWrapper}>
                                <Route path={`${rootPath}/collections/:collectionID/homepage`} component={userIsAuthenticated(EditHomepageController)}>
                                    <Route
                                        path={`edit/:homepageDataField/:homepageDataFieldID`}
                                        component={userIsAuthenticated(EditHomepageItem)}
                                    />
                                </Route>
                            </Route>
                            <Route path={`${rootPath}/collections/:collectionID/homepage/preview`} component={userIsAuthenticated(WorkflowPreview)} />

                            <Route path={`${rootPath}/collections/:collectionID/preview`} component={userIsAuthenticated(PreviewController)} />

                            <Route path={`${rootPath}/collections/:collectionID/create`} component={userIsAuthenticated(userIsAdminOrEditor(CreateContent))} />

                            {config.enableDatasetImport === true && (
                                <Route component={CollectionRoutesWrapper}>
                                    <Route path={`${rootPath}/collections/:collectionID/datasets`}>
                                        <IndexRoute component={userIsAuthenticated(SelectADataset)} />
                                        <Route path="create">
                                            <IndexRoute component={userIsAuthenticated(CreateDatasetController)} />
                                            <Route path=":datasetID" component={userIsAuthenticated(CreateDatasetTaxonomyController)} />
                                        </Route>
                                        <Route path=":datasetID">
                                            <IndexRoute component={userIsAuthenticated(DatasetEditionsController)} />
                                            <Route path={`editions`} component={userIsAuthenticated(CreateEditionController)} />
                                            <Route path="editions/:editionID">
                                                <Route path={`instances`} component={userIsAuthenticated(CreateVersionController)} />
                                                <IndexRoute component={userIsAuthenticated(DatasetVersionsController)} />
                                                <Route path={`versions/:versionID`} component={userIsAuthenticated(DatasetMetadataController)}>
                                                    <Route
                                                        path={`edit/:metadataField/:metadataItemID`}
                                                        component={userIsAuthenticated(EditMetadataItem)}
                                                    />
                                                </Route>
                                                <Route path="versions/:versionID/preview" component={userIsAuthenticated(WorkflowPreview)} />
                                            </Route>
                                        </Route>
                                        <Route path="datasets/create" component={userIsAuthenticated(CollectionsController)} />
                                    </Route>
                                </Route>
                            )}

                            <Route path={`${rootPath}/teams`} component={userIsAuthenticated(userIsAdminOrEditor(TeamsController))}>
                                <Route path=":team" component={userIsAuthenticated(TeamsController)}>
                                    <Route path="edit" component={userIsAuthenticated(TeamsController)} />
                                    <Route path="delete" component={userIsAuthenticated(TeamsController)} />
                                </Route>
                            </Route>
                            <Route path={`${rootPath}/users`} component={userIsAuthenticated(userIsAdminOrEditor(UsersController))}>
                                <Route path=":userID" component={userIsAuthenticated(userIsAdminOrEditor(UserDetailsController))}>
                                    <Route
                                        path="change-password"
                                        component={userIsAuthenticated(userIsAdminOrEditor(ChangeUserPasswordController))}
                                    />
                                    <Route path="confirm-delete" component={userIsAuthenticated(userIsAdminOrEditor(ConfirmUserDeleteController))} />
                                </Route>
                            </Route>
                            {config.enableDatasetImport === true && (
                                <Route>
                                    <Route path={`${rootPath}/uploads`}>
                                        <IndexRedirect to="data" />
                                        <Route path="data">
                                            <IndexRoute component={userIsAuthenticated(userIsAdminOrEditor(DatasetUploadsController))} />
                                            <Route path=":jobID">
                                                <IndexRoute component={userIsAuthenticated(userIsAdminOrEditor(DatasetUploadDetails))} />
                                                <Route path="metadata" component={userIsAuthenticated(userIsAdminOrEditor(DatasetUploadMetadata))} />
                                            </Route>
                                        </Route>
                                    </Route>
                                    <Route path={`${rootPath}/datasets`}>
                                        <IndexRoute component={userIsAuthenticated(userIsAdminOrEditor(DatasetsController))} />
                                        <Route path=":datasetID">
                                            <IndexRedirect to={`${rootPath}/datasets`} />
                                            <Route path="preview" component={userIsAuthenticated(userIsAdminOrEditor(DatasetPreviewController))} />
                                            <Route path="metadata" component={userIsAuthenticated(userIsAdminOrEditor(DatasetMetadata))} />
                                            <Route path="editions/:edition/versions/:version">
                                                <IndexRedirect to="metadata" />
                                                <Route path="metadata" component={userIsAuthenticated(userIsAdminOrEditor(VersionMetadata))} />
                                                <Route
                                                    path="preview"
                                                    component={userIsAuthenticated(userIsAdminOrEditor(VersionPreviewController))}
                                                />
                                            </Route>
                                            <Route path="instances">
                                                <IndexRedirect to={`${rootPath}/datasets`} />
                                                <Route
                                                    path=":instanceID/metadata"
                                                    component={userIsAuthenticated(userIsAdminOrEditor(VersionMetadata))}
                                                />
                                            </Route>
                                        </Route>
                                    </Route>
                                </Route>
                            )}
                            <Route path={`${rootPath}/selectable-list`} component={SelectableTest} />
                            <Route path={`${rootPath}/logs`} component={Logs} />
                            <Route path={`${rootPath}/login`} component={LoginController} />
                            <Route path="*" component={UnknownRoute} />
                        </Route>
                    </Route>
                </Router>
            </Provider>
        );
    }
}

ReactDOM.render(<Index />, document.getElementById("app"));
<commit_msg>Remove import of old cmd preview<commit_after>import React, { Component } from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { Router, Route, IndexRoute, IndexRedirect, Redirect } from "react-router";
import { routerActions } from "react-router-redux";
import { connectedReduxRedirect } from "redux-auth-wrapper/history3/redirect";

import { setConfig } from "./app/config/actions";
import App from "./app/App";
import Layout from "./app/global/Layout";
import LoginController from "./app/views/login/LoginController";
import CollectionsController from "./app/views/collections/CollectionsController";
import TeamsController from "./app/views/teams/TeamsController";
import SelectADataset from "./app/views/datasets-new/DatasetsController";
import DatasetEditionsController from "./app/views/datasets-new/editions/DatasetEditionsController";
import DatasetVersionsController from "./app/views/datasets-new/versions/DatasetVersionsController";
import DatasetMetadataController from "./app/views/datasets-new/edit-metadata/DatasetMetadataController";
import CreateDatasetController from "./app/views/datasets-new/create/CreateDatasetController";
import CreateDatasetTaxonomyController from "./app/views/datasets-new/create/CreateDatasetTaxonomyController";
import CreateVersionController from "./app/views/datasets-new/create/CreateVersionController";
import CreateEditionController from "./app/views/datasets-new/create/CreateEditionController";
import UsersController from "./app/views/users/UsersController";
import UserDetailsController from "./app/views/users/details/UserDetailsController";
import DatasetsController from "./app/views/datasets/DatasetsController";
import DatasetUploadsController from "./app/views/uploads/dataset/DatasetUploadsController";
import DatasetUploadDetails from "./app/views/uploads/dataset/upload-details/DatasetUploadDetails";
import DatasetUploadMetadata from "./app/views/uploads/dataset/upload-details/DatasetUploadMetadata";
import DatasetMetadata from "./app/views/datasets/metadata/DatasetMetadata";
import VersionMetadata from "./app/views/datasets/metadata/VersionMetadata";
import EditHomepageController from "./app/views/homepage/edit/EditHomepageController"
import EditHomepageItem from "./app/views/homepage/edit/EditHomepageItem"

import Logs from "./app/views/logs/Logs";

import auth from "./app/utilities/auth";

import "./scss/main.scss";

import { store, history } from "./app/config/store";

import SelectableTest from "./SelectableTest";
import VersionPreviewController from "./app/views/datasets/preview/VersionPreviewController";
import PreviewController from "./app/views/preview/PreviewController";
import EditMetadataItem from "./app/views/datasets-new/edit-metadata/EditMetadataItem";
import ChangeUserPasswordController from "./app/views/users/change-password/ChangeUserPasswordController";
import ConfirmUserDeleteController from "./app/views/users/confirm-delete/ConfirmUserDeleteController";
import CollectionRoutesWrapper from "./app/global/collection-wrapper/CollectionRoutesWrapper";
import WorkflowPreview from "./app/views/workflow-preview/WorkflowPreview";
import CreateContent from "./app/views/content/CreateContent";

const config = window.getEnv();
store.dispatch(setConfig(config));

const rootPath = store.getState().state.rootPath;

const userIsAuthenticated = connectedReduxRedirect({
    authenticatedSelector: state => {
        return auth.isAuthenticated(state.state.user);
    },
    redirectAction: routerActions.replace,
    wrapperDisplayName: "UserIsAuthenticated",
    redirectPath: `${rootPath}/login`
});

const userIsAdminOrEditor = connectedReduxRedirect({
    authenticatedSelector: state => {
        return auth.isAdminOrEditor(state.state.user);
    },
    redirectAction: routerActions.replace,
    wrapperDisplayName: "userIsAdminOrEditor",
    redirectPath: `${rootPath}/collections`,
    allowRedirectBack: false
});

class UnknownRoute extends Component {
    render() {
        return (

Sorry, this page couldnt be found

        );
    }
}

class Index extends Component {
    render() {
        return (
            <Provider store={store}>
                <Router history={history}>
                    <Route component={App}>
                        <Route component={Layout}>
                            <Redirect from={`${rootPath}`} to={`${rootPath}/collections`} />
                            <Route path={`${rootPath}/collections`} component={userIsAuthenticated(CollectionsController)}>
                                <Route path=":collectionID" component={userIsAuthenticated(CollectionsController)}>
                                    <Route path="edit" component={userIsAuthenticated(CollectionsController)} />
                                    <Route path="restore-content" component={userIsAuthenticated(CollectionsController)} />
                                </Route>
                            </Route>
                            <Route component={CollectionRoutesWrapper}>
                                <Route path={`${rootPath}/collections/:collectionID/homepage`} component={userIsAuthenticated(EditHomepageController)}>
                                    <Route
                                        path={`edit/:homepageDataField/:homepageDataFieldID`}
                                        component={userIsAuthenticated(EditHomepageItem)}
                                    />
                                </Route>
                            </Route>
                            <Route path={`${rootPath}/collections/:collectionID/homepage/preview`} component={userIsAuthenticated(WorkflowPreview)} />

                            <Route path={`${rootPath}/collections/:collectionID/preview`} component={userIsAuthenticated(PreviewController)} />

                            <Route path={`${rootPath}/collections/:collectionID/create`} component={userIsAuthenticated(userIsAdminOrEditor(CreateContent))} />

                            {config.enableDatasetImport === true && (
                                <Route component={CollectionRoutesWrapper}>
                                    <Route path={`${rootPath}/collections/:collectionID/datasets`}>
                                        <IndexRoute component={userIsAuthenticated(SelectADataset)} />
                                        <Route path="create">
                                            <IndexRoute component={userIsAuthenticated(CreateDatasetController)} />
                                            <Route path=":datasetID" component={userIsAuthenticated(CreateDatasetTaxonomyController)} />
                                        </Route>
                                        <Route path=":datasetID">
                                            <IndexRoute component={userIsAuthenticated(DatasetEditionsController)} />
                                            <Route path={`editions`} component={userIsAuthenticated(CreateEditionController)} />
                                            <Route path="editions/:editionID">
                                                <Route path={`instances`} component={userIsAuthenticated(CreateVersionController)} />
                                                <IndexRoute component={userIsAuthenticated(DatasetVersionsController)} />
                                                <Route path={`versions/:versionID`} component={userIsAuthenticated(DatasetMetadataController)}>
                                                    <Route
                                                        path={`edit/:metadataField/:metadataItemID`}
                                                        component={userIsAuthenticated(EditMetadataItem)}
                                                    />
                                                </Route>
                                                <Route path="versions/:versionID/preview" component={userIsAuthenticated(WorkflowPreview)} />
                                            </Route>
                                        </Route>
                                        <Route path="datasets/create" component={userIsAuthenticated(CollectionsController)} />
                                    </Route>
                                </Route>
                            )}

                            <Route path={`${rootPath}/teams`} component={userIsAuthenticated(userIsAdminOrEditor(TeamsController))}>
                                <Route path=":team" component={userIsAuthenticated(TeamsController)}>
                                    <Route path="edit" component={userIsAuthenticated(TeamsController)} />
                                    <Route path="delete" component={userIsAuthenticated(TeamsController)} />
                                </Route>
                            </Route>
                            <Route path={`${rootPath}/users`} component={userIsAuthenticated(userIsAdminOrEditor(UsersController))}>
                                <Route path=":userID" component={userIsAuthenticated(userIsAdminOrEditor(UserDetailsController))}>
                                    <Route
                                        path="change-password"
                                        component={userIsAuthenticated(userIsAdminOrEditor(ChangeUserPasswordController))}
                                    />
                                    <Route path="confirm-delete" component={userIsAuthenticated(userIsAdminOrEditor(ConfirmUserDeleteController))} />
                                </Route>
                            </Route>
                            {config.enableDatasetImport === true && (
                                <Route>
                                    <Route path={`${rootPath}/uploads`}>
                                        <IndexRedirect to="data" />
                                        <Route path="data">
                                            <IndexRoute component={userIsAuthenticated(userIsAdminOrEditor(DatasetUploadsController))} />
                                            <Route path=":jobID">
                                                <IndexRoute component={userIsAuthenticated(userIsAdminOrEditor(DatasetUploadDetails))} />
                                                <Route path="metadata" component={userIsAuthenticated(userIsAdminOrEditor(DatasetUploadMetadata))} />
                                            </Route>
                                        </Route>
                                    </Route>
                                    <Route path={`${rootPath}/datasets`}>
                                        <IndexRoute component={userIsAuthenticated(userIsAdminOrEditor(DatasetsController))} />
                                        <Route path=":datasetID">
                                            <IndexRedirect to={`${rootPath}/datasets`} />
                                            <Route path="preview" component={userIsAuthenticated(userIsAdminOrEditor(WorkflowPreview))} />
                                            <Route path="metadata" component={userIsAuthenticated(userIsAdminOrEditor(DatasetMetadata))} />
                                            <Route path="editions/:edition/versions/:version">
                                                <IndexRedirect to="metadata" />
                                                <Route path="metadata" component={userIsAuthenticated(userIsAdminOrEditor(VersionMetadata))} />
                                                <Route
                                                    path="preview"
                                                    component={userIsAuthenticated(userIsAdminOrEditor(VersionPreviewController))}
                                                />
                                            </Route>
                                            <Route path="instances">
                                                <IndexRedirect to={`${rootPath}/datasets`} />
                                                <Route
                                                    path=":instanceID/metadata"
                                                    component={userIsAuthenticated(userIsAdminOrEditor(VersionMetadata))}
                                                />
                                            </Route>
                                        </Route>
                                    </Route>
                                </Route>
                            )}
                            <Route path={`${rootPath}/selectable-list`} component={SelectableTest} />
                            <Route path={`${rootPath}/logs`} component={Logs} />
                            <Route path={`${rootPath}/login`} component={LoginController} />
                            <Route path="*" component={UnknownRoute} />
                        </Route>
                    </Route>
                </Router>
            </Provider>
        );
    }
}

ReactDOM.render(<Index />, document.getElementById("app"));
<|endoftext|>


<commit_before><commit_msg>Update project i18next to 2.0.1<commit_after><|endoftext|>


<commit_before>var fetchValue = require("../fetch/value.coffee"),
    validObject  = require("../../object/validate.coffee"),
    uniqueValues = require("../../util/uniques.coffee");
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Nests and groups the data.
//------------------------------------------------------------------------------
var dataNest = function(vars, flatData, nestingLevels) {

  var nestedData   = d3.nest(),
      groupedData  = [],
      segments     = "temp" in vars ? [ "active" , "temp" , "total" ] : [];

  if (!nestingLevels.length) {
    nestedData.key(function(d){ return true; });
  }
  else {

    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    // Loop through each nesting level.
    //----------------------------------------------------------------------------
    nestingLevels.forEach(function(level, i){

      //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      // Create a nest key for the current level.
      //--------------------------------------------------------------------------
      nestedData.key(function(d){ return fetchValue(vars, d, level); });

    });

  }

  if (vars.axes.discrete) {
    nestedData.key(function(d){
      return fetchValue(vars, d, vars[vars.axes.discrete].value);
    });
  }

  var deepest_is_id = nestingLevels.length && vars.id.nesting.indexOf(nestingLevels[nestingLevels.length - 1]) >= 0;
  var i = nestingLevels.length && deepest_is_id ? nestingLevels.length - 1 : 0;
  var depthKey = deepest_is_id ? vars.id.nesting[i] : vars.depth.value;

  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  // If we're at the deepest level, create the rollup function.
  //----------------------------------------------------------------------------
  nestedData.rollup(function(leaves) {

    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    // If there's only 1 leaf, and it's been processed, return it as-is.
    //--------------------------------------------------------------------------
    if ( leaves.length === 1 && ("d3plus" in leaves[0]) ) {
      groupedData.push(leaves[0]);
      return leaves[0];
    }

    leaves = leaves.reduce(function(arr, ll){
      if (ll.values instanceof Array) {
        return arr.concat(ll.values);
      }
      arr.push(ll);
      return arr;
    }, []);

    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    // Create the "d3plus" object for the return variable, starting with
    // just the current depth.
    //--------------------------------------------------------------------------
    var returnObj = {
      "d3plus": {
        "data": {},
        "depth": i
      }
    };

    var merged = d3.sum(leaves, function(ll){ return "d3plus" in ll && ll.d3plus.merged ? 1 : 0; });

    if (merged === leaves.length) {
      for (var ll = 0; ll < leaves.length; ll++) {
        var l = leaves[ll];
        if (!returnObj.d3plus.merged) returnObj.d3plus.merged = [];
        returnObj.d3plus.merged = returnObj.d3plus.merged.concat(l.d3plus.merged);
        if (l.d3plus.text) returnObj.d3plus.text = l.d3plus.text;
      }
    }

    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    // Create a reference sum for the 3 different "segment" variables.
    //--------------------------------------------------------------------------
    for (var s = 0; s < segments.length; s++) {

      var c = segments[s];
      var segmentAgg = vars.aggs && vars.aggs.value[key] ? vars.aggs.value[key] : "sum";

      if (typeof segmentAgg === "function") {
        returnObj.d3plus[c] = segmentAgg(leaves);
      }
      else {

        returnObj.d3plus[c] = d3[segmentAgg](leaves, function(d) {

          var a = c === "total" ? 1 : 0;
          if (vars[c].value) {
            a = fetchValue(vars, d, vars[c].value);
            if (typeof a !== "number") a = a ? 1 : 0;
          }
          return a;

        });

      }
    }

    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    // Aggregate all values detected in the data.
    //--------------------------------------------------------------------------
    for (var key in vars.data.keys) {

      if (key in returnObj.d3plus.data) {
        returnObj[key] = returnObj.d3plus[key];
      }
      else {

        var agg     = vars.aggs && vars.aggs.value[key] ? vars.aggs.value[key] : "sum",
            aggType = typeof agg,
            keyType = vars.data.keys[key],
            idKey   = vars.id.nesting.indexOf(key) >= 0,
            timeKey = "time" in vars && key === vars.time.value;

        if (key in returnObj.d3plus.data) {
          returnObj[key] = returnObj.d3plus[key];
        }
        if (aggType === "function") {
          returnObj[key] = vars.aggs.value[key](leaves);
        }
        else if (timeKey) {
          returnObj[key] = parseDates(uniqueValues(leaves, key));
        }
        else if (keyType === "number" && aggType === "string" && !idKey) {
          returnObj[key] = d3[agg](leaves.map(function(d){return d[key];}));
        }
        else {

          var testVals = checkVal(leaves, key);
          var keyValues = testVals.length === 1 ? testVals[0][key]
                        : uniqueValues(testVals, key);

          if (testVals.length === 1) {
            returnObj[key] = keyValues;
          }
          else if (keyValues && keyValues.length) {

            if (!(keyValues instanceof Array)) {
              keyValues = [keyValues];
            }

            if (idKey && vars.id.nesting.indexOf(key) > i) {
            // if (idKey && vars.id.nesting.indexOf(key) > i && keyValues.length > 1) {
              // if (nestingLevels.length == 1 && testVals.length > leaves.length) {
              //   var newNesting = nestingLevels.concat(key);
              //   testVals = dataNest(vars,testVals,newNesting);
              // }
              returnObj[key] = testVals;
            }
            else {

              returnObj[key] = keyValues;

            }

          }
          else if (idKey) {
            var endPoint = vars.id.nesting.indexOf(key) - 1;
            if (endPoint >= i && (!("endPoint" in returnObj.d3plus) || returnObj.d3plus.endPoint > i)) {
              returnObj.d3plus.endPoint = i;
            }
          }

        }

      }

      if (key in returnObj && returnObj[key] instanceof Array && returnObj[key].length === 1) {
        returnObj[key] = returnObj[key][0];
      }

    }

    for (var lll = 0; lll < nestingLevels.length; lll++) {
      var level = nestingLevels[lll];
      if (!(level in returnObj)) {
        returnObj[level] = fetchValue(vars, leaves[0], level);
      }
    }

    groupedData.push(returnObj);

    return returnObj;

  });

  var find_keys = function(obj,depth,keys) {
    if (obj.children) {
      if (vars.data.keys[nestingLevels[depth]] == "number") {
        obj.key = parseFloat(obj.key);
      }
      keys[nestingLevels[depth]] = obj.key;
      delete obj.key;
      for ( var k in keys ) {
        obj[k] = keys[k];
      }
      depth++;
      obj.children.forEach(function(c){
        find_keys(c,depth,keys);
      });
    }
  };

  nestedData = nestedData
    .entries(flatData)
    .map(rename_key_value)
    .map(function(obj){
      find_keys(obj,0,{});
      return obj;
    });

  return groupedData;

};

var checkVal = function(leaves, key) {

  var returnVals = [];

  function run(obj) {
    if (obj instanceof Array) {
      obj.forEach(run);
    }
    else if (validObject(obj) && key in obj) {
      if (obj[key] instanceof Array) {
        obj[key].forEach(run);
      }
      else {
        returnVals.push(obj);
      }
    }
  }

  run(leaves);

  return returnVals;

};

var parseDates = function(dateArray) {

  var dates = [];

  function checkDate(arr) {

    for (var i = 0; i < arr.length; i++) {
      var d = arr[i];
      if (d) {
        if (d.constructor === Array) {
          checkDate(d);
        }
        else {
          dates.push(d);
        }
        // if (d.constructor === Date) dates.push(d);
        // else if (d.constructor === Array) {
        //   checkDate(d);
        // }
        // else {
        //   d = new Date(d.toString());
        //   if (d !== "Invalid Date") {
        //     d.setTime( d.getTime() + d.getTimezoneOffset() * 60 * 1000 );
        //     dates.push(d);
        //   }
        // }
      }
    }

  }

  checkDate(dateArray);

  return uniqueValues(dates);

};

var rename_key_value = function(obj) {
  if (obj.values && obj.values.length) {
    obj.children = obj.values.map(function(obj) {
      return rename_key_value(obj);
    });
    delete obj.values;
    return obj;
  }
  else if(obj.values) {
    return obj.values;
  }
  else {
    return obj;
  }
};

module.exports = dataNest;
<commit_msg>fixed forms<commit_after>var fetchValue = require("../fetch/value.coffee"),
    validObject  = require("../../object/validate.coffee"),
    uniqueValues = require("../../util/uniques.coffee");
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Nests and groups the data.
//------------------------------------------------------------------------------
var dataNest = function(vars, flatData, nestingLevels) {

  var nestedData   = d3.nest(),
      groupedData  = [],
      segments     = "temp" in vars ? [ "active" , "temp" , "total" ] : [];

  if (!nestingLevels.length) {
    nestedData.key(function(d){ return true; });
  }
  else {

    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    // Loop through each nesting level.
    //----------------------------------------------------------------------------
    nestingLevels.forEach(function(level, i){

      //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      // Create a nest key for the current level.
      //--------------------------------------------------------------------------
      nestedData.key(function(d){ return fetchValue(vars, d, level); });

    });

  }

  if (vars.axes && vars.axes.discrete) {
    nestedData.key(function(d){
      return fetchValue(vars, d, vars[vars.axes.discrete].value);
    });
  }

  var deepest_is_id = nestingLevels.length && vars.id.nesting.indexOf(nestingLevels[nestingLevels.length - 1]) >= 0;
  var i = nestingLevels.length && deepest_is_id ? nestingLevels.length - 1 : 0;
  var depthKey = deepest_is_id ? vars.id.nesting[i] : vars.depth.value;

  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  // If we're at the deepest level, create the rollup function.
  //----------------------------------------------------------------------------
  nestedData.rollup(function(leaves) {

    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    // If there's only 1 leaf, and it's been processed, return it as-is.
    //--------------------------------------------------------------------------
    if ( leaves.length === 1 && ("d3plus" in leaves[0]) ) {
      groupedData.push(leaves[0]);
      return leaves[0];
    }

    leaves = leaves.reduce(function(arr, ll){
      if (ll.values instanceof Array) {
        return arr.concat(ll.values);
      }
      arr.push(ll);
      return arr;
    }, []);

    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    // Create the "d3plus" object for the return variable, starting with
    // just the current depth.
    //--------------------------------------------------------------------------
    var returnObj = {
      "d3plus": {
        "data": {},
        "depth": i
      }
    };

    var merged = d3.sum(leaves, function(ll){ return "d3plus" in ll && ll.d3plus.merged ? 1 : 0; });

    if (merged === leaves.length) {
      for (var ll = 0; ll < leaves.length; ll++) {
        var l = leaves[ll];
        if (!returnObj.d3plus.merged) returnObj.d3plus.merged = [];
        returnObj.d3plus.merged = returnObj.d3plus.merged.concat(l.d3plus.merged);
        if (l.d3plus.text) returnObj.d3plus.text = l.d3plus.text;
      }
    }

    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    // Create a reference sum for the 3 different "segment" variables.
    //--------------------------------------------------------------------------
    for (var s = 0; s < segments.length; s++) {

      var c = segments[s];
      var segmentAgg = vars.aggs && vars.aggs.value[key] ? vars.aggs.value[key] : "sum";

      if (typeof segmentAgg === "function") {
        returnObj.d3plus[c] = segmentAgg(leaves);
      }
      else {

        returnObj.d3plus[c] = d3[segmentAgg](leaves, function(d) {

          var a = c === "total" ? 1 : 0;
          if (vars[c].value) {
            a = fetchValue(vars, d, vars[c].value);
            if (typeof a !== "number") a = a ? 1 : 0;
          }
          return a;

        });

      }
    }

    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    // Aggregate all values detected in the data.
    //--------------------------------------------------------------------------
    for (var key in vars.data.keys) {

      if (key in returnObj.d3plus.data) {
        returnObj[key] = returnObj.d3plus[key];
      }
      else {

        var agg     = vars.aggs && vars.aggs.value[key] ? vars.aggs.value[key] : "sum",
            aggType = typeof agg,
            keyType = vars.data.keys[key],
            idKey   = vars.id.nesting.indexOf(key) >= 0,
            timeKey = "time" in vars && key === vars.time.value;

        if (key in returnObj.d3plus.data) {
          returnObj[key] = returnObj.d3plus[key];
        }
        if (aggType === "function") {
          returnObj[key] = vars.aggs.value[key](leaves);
        }
        else if (timeKey) {
          returnObj[key] = parseDates(uniqueValues(leaves, key));
        }
        else if (keyType === "number" && aggType === "string" && !idKey) {
          returnObj[key] = d3[agg](leaves.map(function(d){return d[key];}));
        }
        else {

          var testVals = checkVal(leaves, key);
          var keyValues = testVals.length === 1 ? testVals[0][key]
                        : uniqueValues(testVals, key);

          if (testVals.length === 1) {
            returnObj[key] = keyValues;
          }
          else if (keyValues && keyValues.length) {

            if (!(keyValues instanceof Array)) {
              keyValues = [keyValues];
            }

            if (idKey && vars.id.nesting.indexOf(key) > i) {
            // if (idKey && vars.id.nesting.indexOf(key) > i && keyValues.length > 1) {
              // if (nestingLevels.length == 1 && testVals.length > leaves.length) {
              //   var newNesting = nestingLevels.concat(key);
              //   testVals = dataNest(vars,testVals,newNesting);
              // }
              returnObj[key] = testVals;
            }
            else {

              returnObj[key] = keyValues;

            }

          }
          else if (idKey) {
            var endPoint = vars.id.nesting.indexOf(key) - 1;
            if (endPoint >= i && (!("endPoint" in returnObj.d3plus) || returnObj.d3plus.endPoint > i)) {
              returnObj.d3plus.endPoint = i;
            }
          }

        }

      }

      if (key in returnObj && returnObj[key] instanceof Array && returnObj[key].length === 1) {
        returnObj[key] = returnObj[key][0];
      }

    }

    for (var lll = 0; lll < nestingLevels.length; lll++) {
      var level = nestingLevels[lll];
      if (!(level in returnObj)) {
        returnObj[level] = fetchValue(vars, leaves[0], level);
      }
    }

    groupedData.push(returnObj);

    return returnObj;

  });

  var find_keys = function(obj,depth,keys) {
    if (obj.children) {
      if (vars.data.keys[nestingLevels[depth]] == "number") {
        obj.key = parseFloat(obj.key);
      }
      keys[nestingLevels[depth]] = obj.key;
      delete obj.key;
      for ( var k in keys ) {
        obj[k] = keys[k];
      }
      depth++;
      obj.children.forEach(function(c){
        find_keys(c,depth,keys);
      });
    }
  };

  nestedData = nestedData
    .entries(flatData)
    .map(rename_key_value)
    .map(function(obj){
      find_keys(obj,0,{});
      return obj;
    });

  return groupedData;

};

var checkVal = function(leaves, key) {

  var returnVals = [];

  function run(obj) {
    if (obj instanceof Array) {
      obj.forEach(run);
    }
    else if (validObject(obj) && key in obj) {
      if (obj[key] instanceof Array) {
        obj[key].forEach(run);
      }
      else {
        returnVals.push(obj);
      }
    }
  }

  run(leaves);

  return returnVals;

};

var parseDates = function(dateArray) {

  var dates = [];

  function checkDate(arr) {

    for (var i = 0; i < arr.length; i++) {
      var d = arr[i];
      if (d) {
        if (d.constructor === Array) {
          checkDate(d);
        }
        else {
          dates.push(d);
        }
        // if (d.constructor === Date) dates.push(d);
        // else if (d.constructor === Array) {
        //   checkDate(d);
        // }
        // else {
        //   d = new Date(d.toString());
        //   if (d !== "Invalid Date") {
        //     d.setTime( d.getTime() + d.getTimezoneOffset() * 60 * 1000 );
        //     dates.push(d);
        //   }
        // }
      }
    }

  }

  checkDate(dateArray);

  return uniqueValues(dates);

};

var rename_key_value = function(obj) {
  if (obj.values && obj.values.length) {
    obj.children = obj.values.map(function(obj) {
      return rename_key_value(obj);
    });
    delete obj.values;
    return obj;
  }
  else if(obj.values) {
    return obj.values;
  }
  else {
    return obj;
  }
};

module.exports = dataNest;
<|endoftext|>


<commit_before>import Matches from "./matches";

// Maps symbols to matches.
const SYMBOL_MATCHES = {
    "#": Matches.id,
    ".": Matches.className
};

// TODO: Use better variables names.
function ReactShallowQuery(object, query) {
    var fragments = query.split(" ");
    var results = [object];
    var recursive = true;

    // Loop through each fragement.
    // TODO: Use Array.reduce.
    fragments.forEach((fragment, index) => {
        var prefix = fragment.charAt(0);
        var newResults = [];
        var matcher;

        if (fragment == ">")
            return recursive = false;

        // Handle prefix symbols.
        if (SYMBOL_MATCHES[prefix]) {
            matcher = SYMBOL_MATCHES[prefix];
        } else {
            let upperCase = (prefix === prefix.toUpperCase());

            // Handle default and custom React component names.
            matcher = Matches[upperCase ? "displayName" : "type"];
        }

        results.forEach((result) => {
            var objects = (index ? result.props.children : [result]);
            var foundResults = findResults(objects, matcher, fragment, recursive);

            // Append the newly found results to the 'newResults' array.
            newResults.push.apply(newResults, foundResults);
        });

        results = newResults;
    });

    return results;
};

function findResults(objects = [], matcher, fragment, recursive) {
    var results = [];

    // TODO: Use Array.reduce.
    objects.forEach((object) => {
        var {children} = object.props;
        var foundResults;

        if (matcher(object, fragment))
            results.push(object);

        if (!children || !recursive)
            return;

        foundResults = findResults(children, matcher, fragment, recursive);

        // Append the newly found results onto the 'results' array.
        results.push.apply(results, foundResults);
    });

    return results;
}

export default ReactShallowQuery;
<commit_msg>Fixed a bug where props.children wasn't always an array.<commit_after>import Matches from "./matches";

// Maps symbols to matches.
const SYMBOL_MATCHES = {
    "#": Matches.id,
    ".": Matches.className
};

// TODO: Use better variables names.
function ReactShallowQuery(object, query) {
    var fragments = query.split(" ");
    var results = [object];
    var recursive = true;

    // Loop through each fragement.
    // TODO: Use Array.reduce.
    fragments.forEach((fragment, index) => {
        var prefix = fragment.charAt(0);
        var newResults = [];
        var matcher;

        if (fragment == ">")
            return recursive = false;

        // Handle prefix symbols.
        if (SYMBOL_MATCHES[prefix]) {
            matcher = SYMBOL_MATCHES[prefix];
        } else {
            let upperCase = (prefix === prefix.toUpperCase());

            // Handle default and custom React component names.
            matcher = Matches[upperCase ? "displayName" : "type"];
        }

        results.forEach((result) => {
            var objects = (index ? result.props.children : [result]);
            var foundResults = findResults(objects, matcher, fragment, recursive);

            // Append the newly found results to the 'newResults' array.
            newResults.push.apply(newResults, foundResults);
        });

        results = newResults;
    });

    return results;
};

function findResults(objects = [], matcher, fragment, recursive) {
    var results = [];

    // TODO: Use Array.reduce.
    objects.forEach((object) => {
        var children, foundResults;

        // Ignore objects that aren't objects (e.g. text).
        if (typeof object != "object")
            return;

        ({children} = object.props);

        if (matcher(object, fragment))
            results.push(object);

        if (!children || !recursive)
            return;

        if (!Array.isArray(children))
            children = [children];

        foundResults = findResults(children, matcher, fragment, recursive);

        // Append the newly found results onto the 'results' array.
        results.push.apply(results, foundResults);
    });

    return results;
}

export default ReactShallowQuery;
<|endoftext|>


<commit_before>var gutil = require('gulp-util');

class TaskMaker {
  constructor(gulp) {
    this.gulp = gulp;
  }

  defineTask(name, options) {
    if (!options.taskName) {
      options.taskName = name;
    }
    if (!options.taskDeps) {
      options.taskDeps = [];
    }

    try {
      return require('./tasks/' + name + '.js').setOptions(options).defineTask(this.gulp);
    } catch (e) {
      gutil.log(gutil.colors.red(e));
      throw e;
    }
  }
}

class GulpHelpers {
  taskMaker(gulp) {
    if (! this.tm) {
      this.tm = new TaskMaker(gulp);
    }
    return this.tm;
  };

  situation() {
    let sit = process.env.SITUATION || 'development';
    gutil.log(gutil.colors.blue(`Running as: ${sit}`));
    return sit;
  };
}

module.exports = new GulpHelpers();<commit_msg>situation is now a class<commit_after>var gutil = require('gulp-util');

class TaskMaker {
  constructor(gulp) {
    this.gulp = gulp;
  }

  defineTask(name, options) {
    if (!options.taskName) {
      options.taskName = name;
    }
    if (!options.taskDeps) {
      options.taskDeps = [];
    }

    try {
      return require('./tasks/' + name + '.js').setOptions(options).defineTask(this.gulp);
    } catch (e) {
      gutil.log(gutil.colors.red(e));
      throw e;
    }
  }
}

class Situation {
  constructor() {
    this.sit = process.env.SITUATION || 'development';
    gutil.log(gutil.colors.blue(`Running as: ${this.sit}`));
  }

  isProduction() {
    return this.sit === 'production';
  }

  isDevelopment() {
    return this.sit === 'development';
  }

  value() {
    return this.sit;
  }
}

class GulpHelpers {
  constructor() {
    this.sit = new Situation();
  }

  taskMaker(gulp) {
    if (! this.tm) {
      this.tm = new TaskMaker(gulp);
    }
    return this.tm;
  };

  situation() {
    return this.sit;
  };
}

module.exports = new GulpHelpers();<|endoftext|>


<commit_before>import { css } from 'styled-components';
import { pxToEm, pxToRem } from './convertors';

export {
  pxToEm,
  pxToRem
};

/**
 * Default media breakpoints
 * @type {Object}
 */
export const defaultBreakpoints = {
  huge: '1440px',
  large: '1170px',
  medium: '768px',
  small: '450px',
}

/**
 * Media query generator
 * @param {Object} [defaultBreakpoints] breakpoints - Map labels to breakpoint sizes
 * @return {Object} - Media generators for each breakpoint
 */
export function generateMedia(breakpoints = defaultBreakpoints) {
  return Object
    .keys(breakpoints)
    .reduce((acc, label) => {
      const size = breakpoints[label];

      acc.to[label] = (...args) => css`
        @media (max-width: ${size}) {
          ${css(...args)}
        }
      `;

      acc.from[label] = (...args) => css`
        @media (min-width: ${size}) {
          ${css(...args)}
        }
      `;

      return acc;
    },
    { to: {}, from: {} }
  );
}

/**
 * Media object with default breakpoints
 * @return {object} - Media generators for each size
 */
export const media = generateMedia();

/**
 * Usage: styled.div` ${media.from.medium`background: #000;`} `;
 * With this code, background for small and medium sizes will be `default` and for more than medium, will be `#000`
 */
<commit_msg>style: Add extra line<commit_after>import { css } from 'styled-components';
import { pxToEm, pxToRem } from './convertors';

export {
  pxToEm,
  pxToRem
};

/**
 * Default media breakpoints
 * @type {Object}
 */
export const defaultBreakpoints = {
  huge: '1440px',
  large: '1170px',
  medium: '768px',
  small: '450px',
}

/**
 * Media query generator
 * @param {Object} [defaultBreakpoints] breakpoints - Map labels to breakpoint sizes
 * @return {Object} - Media generators for each breakpoint
 */
export function generateMedia(breakpoints = defaultBreakpoints) {
  return Object
    .keys(breakpoints)
    .reduce((acc, label) => {
      const size = breakpoints[label];

      acc.to[label] = (...args) => css`
        @media (max-width: ${size}) {
          ${css(...args)}
        }
      `;

      acc.from[label] = (...args) => css`
        @media (min-width: ${size}) {
          ${css(...args)}
        }
      `;

      return acc;
    },
    { to: {}, from: {} }
  );
}

/**
 * Media object with default breakpoints
 * @return {object} - Media generators for each size
 */

export const media = generateMedia();

/**
 * Usage: styled.div` ${media.from.medium`background: #000;`} `;
 * With this code, background for small and medium sizes will be `default` and for more than medium, will be `#000`
 */
<|endoftext|>


<commit_before>var playerContainer;
$(document).ready(function() {
	// get YT player container
	playerContainer = document.getElementById("player");

	// add YT script tag
	var tag = document.createElement("script");
	var firstScriptTag = document.getElementsByTagName("script")[0];
	tag.src = "https://www.youtube.com/player_api";
	firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

	// scroll to active episode
	if (document.getElementById("active")) {
		$("#sidebar").animate({scrollTop:$("#active").position().top},1000);
	}

	// load comment count
	if (document.getElementById("comments")) {
		$.get("http://www.reddit.com/comments/" + document.getElementById("comments").getAttribute("data-reddit") + ".json", function (data) {
			$("#comments").html(data[0]["data"]["children"][0]["data"]["num_comments"] + " Comments");
		});
	}

	// capture timestamp click events
	$(".timelink").click(function() {
		seekYT($(this).data("timestamp"));
		return false;
	});

	// live search
	var search_timer;
	var previous_search;
	$("#search-field").keyup(function() {
		clearTimeout(search_timer);
		var search_value = this.value;

		search_timer = setTimeout(function() {
			if ($.trim(search_value) != "") {
				if (previous_search != search_value) {
					previous_search = search_value;

					$.getJSON(domain + "search.php?query=" + search_value, function(results_json){
						if (results_json.length > 0) {
							// hide all episodes
							$("#sidebar ul li").each(function(id, li){
								$(li).css("display", "none");
							});
							$.each(results_json, function(result_id) {
								// show only returned episodes
								var episode = "#" + results_json[result_id];
								$(episode).css("display", "block");
							});
						}
					});
				}
			} else {
				// reset episode list
				$("#sidebar ul li").each(function(id, li){
					$(li).css("display", "block");
				});
			}
		}, 200);
	});
});

// load YT player
var player;
function onYouTubePlayerAPIReady() {
	player = new YT.Player("player", {
		height: "400",
		width: "650",
		videoId: playerContainer.getAttribute("data-youtube")
	});
}

// click timestamp to seek video
function seekYT(timestamp) {
	player.seekTo(timestamp);
	document.getElementsByTagName("header")[0].scrollIntoView();
}

// collapsible sidebar
$(function(){
	$(".toggle-menu").click(function(e){
		e.preventDefault();
		$(".sidebar").toggleClass("toggled");
	});
});

// horizontal timeline
function disappear(id){
	document.getElementById(id).style.display = "none";
}
function appear(id){
	document.getElementById(id).style.display = "block";
}<commit_msg>Hide all episodes if there are no search results<commit_after>var playerContainer;
$(document).ready(function() {
	// get YT player container
	playerContainer = document.getElementById("player");

	// add YT script tag
	var tag = document.createElement("script");
	var firstScriptTag = document.getElementsByTagName("script")[0];
	tag.src = "https://www.youtube.com/player_api";
	firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

	// scroll to active episode
	if (document.getElementById("active")) {
		$("#sidebar").animate({scrollTop:$("#active").position().top},1000);
	}

	// load comment count
	if (document.getElementById("comments")) {
		$.get("http://www.reddit.com/comments/" + document.getElementById("comments").getAttribute("data-reddit") + ".json", function (data) {
			$("#comments").html(data[0]["data"]["children"][0]["data"]["num_comments"] + " Comments");
		});
	}

	// capture timestamp click events
	$(".timelink").click(function() {
		seekYT($(this).data("timestamp"));
		return false;
	});

	// live search
	var search_timer;
	var previous_search;
	$("#search-field").keyup(function() {
		clearTimeout(search_timer);
		var search_value = this.value;

		search_timer = setTimeout(function() {
			if ($.trim(search_value) != "") {
				if (previous_search != search_value) {
					previous_search = search_value;

					$.getJSON(domain + "search.php?query=" + search_value, function(results_json){
						// hide all episodes
						$("#sidebar ul li").each(function(id, li){
							$(li).css("display", "none");
						});

						if (results_json.length > 0) {
							$.each(results_json, function(result_id) {
								// show only returned episodes
								var episode = "#" + results_json[result_id];
								$(episode).css("display", "block");
							});
						}
					});
				}
			} else {
				// reset episode list
				$("#sidebar ul li").each(function(id, li){
					$(li).css("display", "block");
				});
			}
		}, 200);
	});
});

// load YT player
var player;
function onYouTubePlayerAPIReady() {
	player = new YT.Player("player", {
		height: "400",
		width: "650",
		videoId: playerContainer.getAttribute("data-youtube")
	});
}

// click timestamp to seek video
function seekYT(timestamp) {
	player.seekTo(timestamp);
	document.getElementsByTagName("header")[0].scrollIntoView();
}

// collapsible sidebar
$(function(){
	$(".toggle-menu").click(function(e){
		e.preventDefault();
		$(".sidebar").toggleClass("toggled");
	});
});

// horizontal timeline
function disappear(id){
	document.getElementById(id).style.display = "none";
}
function appear(id){
	document.getElementById(id).style.display = "block";
}<|endoftext|>