<commit_before>/**
 * Created by swhite on 6/9/14.
 */

var app = angular.module(
    'ReFlowApp',
    [
        'ngSanitize',
        'ngCookies',
        'ngResource',
        'ui.router',
        'ui.bootstrap',
        'ui.select2',
        'ncy-angular-breadcrumb',
        'angularFileUpload',
        'tableSort'
    ]
);

app.factory('LoginRedirectInterceptor', function($q, $window) {
    return {
        responseError: function(rejection) {
            if (rejection.status == 401) {
                $window.location.assign('/login');
            } else {
                return $q.reject(rejection);
            }
        }
    };
});

var MODAL_URLS = {
    'SUBJECT_GROUP':      'static/ng-app/partials/subject-group-form.html',
    'SUBJECT':            'static/ng-app/partials/subject-form.html',
    'PROJECT':            'static/ng-app/partials/project-form.html',
    'SITE':               'static/ng-app/partials/site-form.html',
    'CYTOMETER':          'static/ng-app/partials/cytometer-form.html',
    'VISIT_TYPE':         'static/ng-app/partials/visit-type-form.html',
    'CELL_SUBSET_LABEL':  'static/ng-app/partials/cell-subset-label-form.html',
    'STIMULATION':        'static/ng-app/partials/stimulation-form.html',
    'SAMPLE_PARAMETERS':  'static/ng-app/partials/sample-parameters-list.html',
    'SAMPLE_METADATA':    'static/ng-app/partials/sample-metadata-list.html',
    'SAMPLE':             'static/ng-app/partials/sample-form.html',
    'COMPENSATION':       'static/ng-app/partials/compensation-form.html',
    'COMPENSATION_MATRIX': 'static/ng-app/partials/compensation-matrix.html',
    'PROJECT_USER':       'static/ng-app/partials/project-user-form.html',
    'CHOOSE_USER':        'static/ng-app/partials/user-choose.html',
    'CHANGE_PASSWORD':    'static/ng-app/partials/user-change-password-form.html',

    // delete modals
    'SAMPLE_DELETE':      'static/ng-app/partials/sample-delete.html',
    'BEAD_SAMPLE_DELETE': 'static/ng-app/partials/bead-sample-delete.html',
    'COMPENSATION_DELETE': 'static/ng-app/partials/compensation-delete.html',
    'CYTOMETER_DELETE':   'static/ng-app/partials/cytometer-delete.html',
    'CELL_SUBSET_LABEL_DELETE': 'static/ng-app/partials/cell-subset-label-delete.html',
    'STIMULATION_DELETE': 'static/ng-app/partials/stimulation-delete.html',
    'VISIT_TYPE_DELETE':  'static/ng-app/partials/visit-type-delete.html',
    'SITE_DELETE':        'static/ng-app/partials/site-delete.html',
    'PANEL_DELETE':       'static/ng-app/partials/panel-template-delete.html',
    'SITE_PANEL_DELETE':  'static/ng-app/partials/site-panel-delete.html',
    'SUBJECT_DELETE':     'static/ng-app/partials/subject-delete.html',
    'SUBJECT_GROUP_DELETE': 'static/ng-app/partials/subject-group-delete.html',
    'PROJECT_DELETE':     'static/ng-app/partials/project-delete.html',
    'PROCESS_REQUEST_DELETE': 'static/ng-app/partials/process-request-delete.html',

    // admin modals
    'USER':               'static/ng-app/partials/user-form.html',
    'USER_DELETE':        'static/ng-app/partials/user-delete.html',
    'SPECIMEN':           'static/ng-app/partials/specimen-form.html',
    'SPECIMEN_DELETE':    'static/ng-app/partials/specimen-delete.html',
    'MARKER':             'static/ng-app/partials/marker-form.html',
    'MARKER_DELETE':      'static/ng-app/partials/marker-delete.html',
    'FLUOROCHROME':       'static/ng-app/partials/fluorochrome-form.html',
    'FLUOROCHROME_DELETE': 'static/ng-app/partials/fluorochrome-delete.html',
    'WORKER':             'static/ng-app/partials/worker-form.html',
    'WORKER_DELETE':      'static/ng-app/partials/worker-delete.html'
};

app.config(function ($stateProvider, $urlRouterProvider, $httpProvider) {
    $httpProvider.interceptors.push('LoginRedirectInterceptor');

    $urlRouterProvider.otherwise("/");

    $stateProvider.state({
        name: 'home',
        url: '/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/home.html'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Projects'
        }
    }).state({
        name: 'user-profile',
        parent: 'home',
        url: 'user_profile/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/user_profile.html'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'User Profile'
        }
    }).state({
        name: 'admin',
        parent: 'home',
        url: 'admin/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/admin.html'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Admin'
        }
    }).state({
        name: 'specimen-list',
        parent: 'admin',
        url: 'specimens/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/specimen-list.html',
                controller: 'SpecimenController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Specimens'
        }
    }).state({
        name: 'marker-list',
        parent: 'admin',
        url: 'markers/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/marker-list.html',
                controller: 'MarkerController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Markers'
        }
    }).state({
        name: 'fluorochrome-list',
        parent: 'admin',
        url: 'fluorochromes/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/fluorochrome-list.html',
                controller: 'FluorochromeController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Fluorochromes'
        }
    }).state({
        name: 'user-list',
        parent: 'admin',
        url: 'users/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/user-list.html',
                controller: 'UserController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Users'
        }
    }).state({
        name: 'worker-list',
        parent: 'admin',
        url: 'workers/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/worker-list.html',
                controller: 'WorkerController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Workers'
        }
    }).state({
        name: 'project-detail',
        parent: 'home',
        url: 'project/:projectId',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/project-detail.html',
                controller: 'ProjectDetailController'
            }
        },
        data: {
            ncyBreadcrumbLabel: '{{current_project.project_name}}'
        }
    }).state({
        name: 'process-request-list',
        parent: 'project-detail',
        url: '/process_request/',
        views: {
            '@': {
            templateUrl: '/static/ng-app/partials/process-request-list.html',
            controller: 'ProcessRequestController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Process Requests'
        }
    }).state({
        name: 'process-request-form',
        parent: 'project-detail',
        url: '/process_request/create',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/pr/process-request-form.html',
                controller: 'ProcessRequestFormController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Process Request'
        }
    }).state({
        name: 'process-request-detail',
        parent: 'process-request-list',
        url: ':requestId',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/process-request-detail.html',
                controller: 'ProcessRequestDetailController'
            }
        },
        data: {
            ncyBreadcrumbLabel: '{{process_request.description}}'
        }
    }).state({
        name: 'pr-visualization-detail',
        parent: 'process-request-detail',
        url: '/visualize',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/pr-visualization-detail.html',
                controller: 'PRVisualizationDetailController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Visualize'
        }
    }).state({
        name: 'project-user-list',
        parent: 'project-detail',
        url: '/users/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/project-user-list.html',
                controller: 'ProjectUserController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Users'
        }
    }).state({
        name: 'subject-group-list',
        parent: 'project-detail',
        url: '/subject-groups/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/subject-group-list.html',
                controller: 'SubjectGroupController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Subject Groups'
        }
    }).state({
        name: 'subject-list',
        parent: 'project-detail',
        url: '/subjects/',
        views: {
            '@': {
            templateUrl: '/static/ng-app/partials/subject-list.html',
            controller: 'SubjectController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Subjects'
        }
    }).state({
        name: 'site-list',
        parent: 'project-detail',
        url: '/sites/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/site-list.html',
                controller: 'SiteController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Sites'
        }
    }).state({
        name: 'cytometer-list',
        parent: 'project-detail',
        url: '/cytometers/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/cytometer-list.html',
                controller: 'CytometerController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Cytometers'
        }
    }).state({
        name: 'site-panel-list',
        parent: 'project-detail',
        url: '/sample-annotations/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/site-panel-list.html',
                controller: 'SitePanelController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Sample Annotations'
        }
    }).state({
        name: 'visit-type-list',
        parent: 'project-detail',
        url: '/visit-types/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/visit-type-list.html',
                controller: 'VisitTypeController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Visit Types'
        }
    }).state({
        name: 'stimulation-list',
        parent: 'project-detail',
        url: '/stimulations/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/stimulation-list.html',
                controller: 'StimulationController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Stimulations'
        }
    }).state({
        name: 'cell-subset-label-list',
        parent: 'project-detail',
        url: '/cell-subset-labels/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/cell-subset-label-list.html',
                controller: 'CellSubsetLabelController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Cell Subset Labels'
        }
    }).state({
        name: 'panel-template-list',
        parent: 'project-detail',
        url: '/panel-templates/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/panel-template-list.html',
                controller: 'PanelTemplateController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Panel Templates'
        }
    }).state({
        name: 'panel-template-create',
        parent: 'panel-template-list',
        url: 'create',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/panel-template-create.html',
                controller: 'PanelTemplateCreateController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Create'
        }
    }).state({
        name: 'panel-template-edit',
        parent: 'panel-template-list',
        url: ':templateID/edit',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/panel-template-create.html',
                controller: 'PanelTemplateCreateController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Edit'
        }
    }).state({
        name: 'sample-list',
        parent: 'project-detail',
        url: '/samples/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/sample-list.html',
                controller: 'SampleController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Samples'
        }
    }).state({
        name: 'sample-upload',
        parent: 'sample-list',
        url: 'upload',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/sample-upload.html',
                controller: 'MainSampleUploadController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Upload'
        }
    }).state({
        name: 'bead-sample-list',
        parent: 'project-detail',
        url: '/bead-samples/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/bead-sample-list.html',
                controller: 'BeadSampleController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Bead Samples'
        }
    }).state({
        name: 'bead-sample-upload',
        parent: 'bead-sample-list',
        url: '/bead-samples/upload',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/bead-sample-upload.html',
                controller: 'MainSampleUploadController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Upload'
        }
    }).state({
        name: 'compensation-list',
        parent: 'project-detail',
        url: '/compensations/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/compensation-list.html',
                controller: 'CompensationController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Compensation Matrices'
        }
    });
});

app.run(function ($http, $cookies) {
    $http.defaults.headers.common['X-CSRFToken'] = $cookies['csrftoken'];
});

app.filter('bytes', function() {
	return function(bytes, precision) {
		if (isNaN(parseFloat(bytes)) || !isFinite(bytes)) return '-';
		if (typeof precision === 'undefined') precision = 1;
		var units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],
			number = Math.floor(Math.log(bytes) / Math.log(1024));
		return (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) +  ' ' + units[number];
	}
});

app.directive('closeModal', function (){
   return function(scope, elem, attrs) {
     scope.$watch('close_modal', function(val) {
        if(val) {
           elem.modal('hide');
        }
     });
   }
});<commit_msg>update app.js with ui-select module<commit_after>/**
 * Created by swhite on 6/9/14.
 */

var app = angular.module(
    'ReFlowApp',
    [
        'ngSanitize',
        'ngCookies',
        'ngResource',
        'ui.router',
        'ui.bootstrap',
        'ui.select',
        'ncy-angular-breadcrumb',
        'angularFileUpload',
        'tableSort'
    ]
);

app.factory('LoginRedirectInterceptor', function($q, $window) {
    return {
        responseError: function(rejection) {
            if (rejection.status == 401) {
                $window.location.assign('/login');
            } else {
                return $q.reject(rejection);
            }
        }
    };
});

var MODAL_URLS = {
    'SUBJECT_GROUP':      'static/ng-app/partials/subject-group-form.html',
    'SUBJECT':            'static/ng-app/partials/subject-form.html',
    'PROJECT':            'static/ng-app/partials/project-form.html',
    'SITE':               'static/ng-app/partials/site-form.html',
    'CYTOMETER':          'static/ng-app/partials/cytometer-form.html',
    'VISIT_TYPE':         'static/ng-app/partials/visit-type-form.html',
    'CELL_SUBSET_LABEL':  'static/ng-app/partials/cell-subset-label-form.html',
    'STIMULATION':        'static/ng-app/partials/stimulation-form.html',
    'SAMPLE_PARAMETERS':  'static/ng-app/partials/sample-parameters-list.html',
    'SAMPLE_METADATA':    'static/ng-app/partials/sample-metadata-list.html',
    'SAMPLE':             'static/ng-app/partials/sample-form.html',
    'COMPENSATION':       'static/ng-app/partials/compensation-form.html',
    'COMPENSATION_MATRIX': 'static/ng-app/partials/compensation-matrix.html',
    'PROJECT_USER':       'static/ng-app/partials/project-user-form.html',
    'CHOOSE_USER':        'static/ng-app/partials/user-choose.html',
    'CHANGE_PASSWORD':    'static/ng-app/partials/user-change-password-form.html',

    // delete modals
    'SAMPLE_DELETE':      'static/ng-app/partials/sample-delete.html',
    'BEAD_SAMPLE_DELETE': 'static/ng-app/partials/bead-sample-delete.html',
    'COMPENSATION_DELETE': 'static/ng-app/partials/compensation-delete.html',
    'CYTOMETER_DELETE':   'static/ng-app/partials/cytometer-delete.html',
    'CELL_SUBSET_LABEL_DELETE': 'static/ng-app/partials/cell-subset-label-delete.html',
    'STIMULATION_DELETE': 'static/ng-app/partials/stimulation-delete.html',
    'VISIT_TYPE_DELETE':  'static/ng-app/partials/visit-type-delete.html',
    'SITE_DELETE':        'static/ng-app/partials/site-delete.html',
    'PANEL_DELETE':       'static/ng-app/partials/panel-template-delete.html',
    'SITE_PANEL_DELETE':  'static/ng-app/partials/site-panel-delete.html',
    'SUBJECT_DELETE':     'static/ng-app/partials/subject-delete.html',
    'SUBJECT_GROUP_DELETE': 'static/ng-app/partials/subject-group-delete.html',
    'PROJECT_DELETE':     'static/ng-app/partials/project-delete.html',
    'PROCESS_REQUEST_DELETE': 'static/ng-app/partials/process-request-delete.html',

    // admin modals
    'USER':               'static/ng-app/partials/user-form.html',
    'USER_DELETE':        'static/ng-app/partials/user-delete.html',
    'SPECIMEN':           'static/ng-app/partials/specimen-form.html',
    'SPECIMEN_DELETE':    'static/ng-app/partials/specimen-delete.html',
    'MARKER':             'static/ng-app/partials/marker-form.html',
    'MARKER_DELETE':      'static/ng-app/partials/marker-delete.html',
    'FLUOROCHROME':       'static/ng-app/partials/fluorochrome-form.html',
    'FLUOROCHROME_DELETE': 'static/ng-app/partials/fluorochrome-delete.html',
    'WORKER':             'static/ng-app/partials/worker-form.html',
    'WORKER_DELETE':      'static/ng-app/partials/worker-delete.html'
};

app.config(function ($stateProvider, $urlRouterProvider, $httpProvider) {
    $httpProvider.interceptors.push('LoginRedirectInterceptor');

    $urlRouterProvider.otherwise("/");

    $stateProvider.state({
        name: 'home',
        url: '/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/home.html'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Projects'
        }
    }).state({
        name: 'user-profile',
        parent: 'home',
        url: 'user_profile/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/user_profile.html'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'User Profile'
        }
    }).state({
        name: 'admin',
        parent: 'home',
        url: 'admin/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/admin.html'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Admin'
        }
    }).state({
        name: 'specimen-list',
        parent: 'admin',
        url: 'specimens/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/specimen-list.html',
                controller: 'SpecimenController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Specimens'
        }
    }).state({
        name: 'marker-list',
        parent: 'admin',
        url: 'markers/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/marker-list.html',
                controller: 'MarkerController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Markers'
        }
    }).state({
        name: 'fluorochrome-list',
        parent: 'admin',
        url: 'fluorochromes/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/fluorochrome-list.html',
                controller: 'FluorochromeController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Fluorochromes'
        }
    }).state({
        name: 'user-list',
        parent: 'admin',
        url: 'users/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/user-list.html',
                controller: 'UserController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Users'
        }
    }).state({
        name: 'worker-list',
        parent: 'admin',
        url: 'workers/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/worker-list.html',
                controller: 'WorkerController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Workers'
        }
    }).state({
        name: 'project-detail',
        parent: 'home',
        url: 'project/:projectId',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/project-detail.html',
                controller: 'ProjectDetailController'
            }
        },
        data: {
            ncyBreadcrumbLabel: '{{current_project.project_name}}'
        }
    }).state({
        name: 'process-request-list',
        parent: 'project-detail',
        url: '/process_request/',
        views: {
            '@': {
            templateUrl: '/static/ng-app/partials/process-request-list.html',
            controller: 'ProcessRequestController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Process Requests'
        }
    }).state({
        name: 'process-request-form',
        parent: 'project-detail',
        url: '/process_request/create',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/pr/process-request-form.html',
                controller: 'ProcessRequestFormController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Process Request'
        }
    }).state({
        name: 'process-request-detail',
        parent: 'process-request-list',
        url: ':requestId',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/process-request-detail.html',
                controller: 'ProcessRequestDetailController'
            }
        },
        data: {
            ncyBreadcrumbLabel: '{{process_request.description}}'
        }
    }).state({
        name: 'pr-visualization-detail',
        parent: 'process-request-detail',
        url: '/visualize',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/pr-visualization-detail.html',
                controller: 'PRVisualizationDetailController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Visualize'
        }
    }).state({
        name: 'project-user-list',
        parent: 'project-detail',
        url: '/users/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/project-user-list.html',
                controller: 'ProjectUserController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Users'
        }
    }).state({
        name: 'subject-group-list',
        parent: 'project-detail',
        url: '/subject-groups/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/subject-group-list.html',
                controller: 'SubjectGroupController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Subject Groups'
        }
    }).state({
        name: 'subject-list',
        parent: 'project-detail',
        url: '/subjects/',
        views: {
            '@': {
            templateUrl: '/static/ng-app/partials/subject-list.html',
            controller: 'SubjectController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Subjects'
        }
    }).state({
        name: 'site-list',
        parent: 'project-detail',
        url: '/sites/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/site-list.html',
                controller: 'SiteController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Sites'
        }
    }).state({
        name: 'cytometer-list',
        parent: 'project-detail',
        url: '/cytometers/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/cytometer-list.html',
                controller: 'CytometerController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Cytometers'
        }
    }).state({
        name: 'site-panel-list',
        parent: 'project-detail',
        url: '/sample-annotations/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/site-panel-list.html',
                controller: 'SitePanelController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Sample Annotations'
        }
    }).state({
        name: 'visit-type-list',
        parent: 'project-detail',
        url: '/visit-types/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/visit-type-list.html',
                controller: 'VisitTypeController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Visit Types'
        }
    }).state({
        name: 'stimulation-list',
        parent: 'project-detail',
        url: '/stimulations/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/stimulation-list.html',
                controller: 'StimulationController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Stimulations'
        }
    }).state({
        name: 'cell-subset-label-list',
        parent: 'project-detail',
        url: '/cell-subset-labels/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/cell-subset-label-list.html',
                controller: 'CellSubsetLabelController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Cell Subset Labels'
        }
    }).state({
        name: 'panel-template-list',
        parent: 'project-detail',
        url: '/panel-templates/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/panel-template-list.html',
                controller: 'PanelTemplateController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Panel Templates'
        }
    }).state({
        name: 'panel-template-create',
        parent: 'panel-template-list',
        url: 'create',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/panel-template-create.html',
                controller: 'PanelTemplateCreateController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Create'
        }
    }).state({
        name: 'panel-template-edit',
        parent: 'panel-template-list',
        url: ':templateID/edit',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/panel-template-create.html',
                controller: 'PanelTemplateCreateController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Edit'
        }
    }).state({
        name: 'sample-list',
        parent: 'project-detail',
        url: '/samples/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/sample-list.html',
                controller: 'SampleController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Samples'
        }
    }).state({
        name: 'sample-upload',
        parent: 'sample-list',
        url: 'upload',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/sample-upload.html',
                controller: 'MainSampleUploadController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Upload'
        }
    }).state({
        name: 'bead-sample-list',
        parent: 'project-detail',
        url: '/bead-samples/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/bead-sample-list.html',
                controller: 'BeadSampleController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Bead Samples'
        }
    }).state({
        name: 'bead-sample-upload',
        parent: 'bead-sample-list',
        url: '/bead-samples/upload',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/bead-sample-upload.html',
                controller: 'MainSampleUploadController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Upload'
        }
    }).state({
        name: 'compensation-list',
        parent: 'project-detail',
        url: '/compensations/',
        views: {
            '@': {
                templateUrl: '/static/ng-app/partials/compensation-list.html',
                controller: 'CompensationController'
            }
        },
        data: {
            ncyBreadcrumbLabel: 'Compensation Matrices'
        }
    });
});

app.run(function ($http, $cookies) {
    $http.defaults.headers.common['X-CSRFToken'] = $cookies['csrftoken'];
});

app.filter('bytes', function() {
	return function(bytes, precision) {
		if (isNaN(parseFloat(bytes)) || !isFinite(bytes)) return '-';
		if (typeof precision === 'undefined') precision = 1;
		var units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],
			number = Math.floor(Math.log(bytes) / Math.log(1024));
		return (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) +  ' ' + units[number];
	}
});

app.directive('closeModal', function (){
   return function(scope, elem, attrs) {
     scope.$watch('close_modal', function(val) {
        if(val) {
           elem.modal('hide');
        }
     });
   }
});<|endoftext|>


<commit_before>import { PersistentStorage } from 'api/storage';
import { MockedRequest } from 'api/models/mocked-request';

export class MockedRequests {

  constructor() {
    this.loadFromStorage();
  }

  loadFromStorage() {
    this.mockedRequests = PersistentStorage.dataTree.mockedRequests
      .map((mockedRequest) => new MockedRequest(mockedRequest));

    PersistentStorage.dataTree.mockedRequests = this.mockedRequests;
  }

  addMockedRequest(capturedRequest) {
    const sameRequestHash = this.getByHash(capturedRequest.requestHash);

    if (sameRequestHash) {
      return;
    }

    this.mockedRequests.push(
      new MockedRequest(capturedRequest.buildMockedRequestData())
    );

    PersistentStorage.persist();
  }

  getByHash(hash) {
    return this.mockedRequests
      .find((request) => request.requestHash === hash);
  }

  mergeMockedRequests(mockedRequests) {
    for (let mockedRequest of mockedRequests) {
      let existingMockedRequest = this.getByHash(mockedRequest.requestHash);
      if (existingMockedRequest) {
        Object.assign(existingMockedRequest, mockedRequest);
      } else {
        this.mockedRequests.push(new MockedRequest(mockedRequest));
      }
    }
  }

}

export default new MockedRequests();
<commit_msg>add a blank line<commit_after>import { PersistentStorage } from 'api/storage';
import { MockedRequest } from 'api/models/mocked-request';

export class MockedRequests {

  constructor() {
    this.loadFromStorage();
  }

  loadFromStorage() {
    this.mockedRequests = PersistentStorage.dataTree.mockedRequests
      .map((mockedRequest) => new MockedRequest(mockedRequest));

    PersistentStorage.dataTree.mockedRequests = this.mockedRequests;
  }

  addMockedRequest(capturedRequest) {
    const sameRequestHash = this.getByHash(capturedRequest.requestHash);

    if (sameRequestHash) {
      return;
    }

    this.mockedRequests.push(
      new MockedRequest(capturedRequest.buildMockedRequestData())
    );

    PersistentStorage.persist();
  }

  getByHash(hash) {
    return this.mockedRequests
      .find((request) => request.requestHash === hash);
  }

  mergeMockedRequests(mockedRequests) {
    for (let mockedRequest of mockedRequests) {
      let existingMockedRequest = this.getByHash(mockedRequest.requestHash);

      if (existingMockedRequest) {
        Object.assign(existingMockedRequest, mockedRequest);
      } else {
        this.mockedRequests.push(new MockedRequest(mockedRequest));
      }
    }
  }

}

export default new MockedRequests();
<|endoftext|>


<commit_before>import Feature from 'core/feature';
import * as toolkitHelper from 'helpers/toolkit';

export default class DisplayTargetGoalAmount extends Feature {
  constructor() {
    super();
  }

  shouldInvoke() {
    return toolkitHelper.getCurrentRouteName().indexOf('budget') !== -1;
  }

  invoke() {
    $('.budget-table-header .budget-table-cell-name').css('position', 'relative');
    $('.budget-table-row.is-sub-category li.budget-table-cell-name').css('position', 'relative');

    $('.budget-table-header .budget-table-cell-name').append(
      $('<div>', { class: 'budget-table-cell-goal' }).css(
        { position: 'absolute', right: 0, top: '6px' }).append('GOAL')
    );

    $('.budget-table-row.is-sub-category li.budget-table-cell-name').append(
      $('<div>', { class: 'budget-table-cell-goal' }).css({
        background: '-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 10%,rgba(255,255,255,1) 100%)', position: 'absolute', 'font-size': '80%', 'padding-left': '.75em', 'padding-right': '1px', 'line-height': '2.55em'
      })
    );

    $('.budget-table-row.is-sub-category').each((index, element) => {
      const emberId = element.id;
      const viewData = toolkitHelper.getEmberView(emberId).data;
      const { subCategory } = viewData;
      const { monthlySubCategoryBudget } = viewData;
      const { monthlySubCategoryBudgetCalculation } = viewData;
      const goalType = subCategory.get('goalType');
      const monthlyFunding = subCategory.get('monthlyFunding');
      const targetBalance = subCategory.get('targetBalance');
      const targetBalanceDate = monthlySubCategoryBudgetCalculation.get('goalTarget');
      const budgetedAmount = monthlySubCategoryBudget.get('budgeted');
      if (goalType === 'MF') {
        $('#' + emberId + '.budget-table-row.is-sub-category div.budget-table-cell-goal').text(toolkitHelper.formatCurrency(monthlyFunding));
        if (budgetedAmount <= monthlyFunding) {
          $('#' + emberId + '.budget-table-row.is-sub-category div.budget-table-cell-goal').css({ color: 'grey' });
        } else {
          $('#' + emberId + '.budget-table-row.is-sub-category div.budget-table-cell-goal').css({ color: '#ff4545' });
        }
      } else if (goalType === 'TB') {
        $('#' + emberId + '.budget-table-row.is-sub-category div.budget-table-cell-goal').text(toolkitHelper.formatCurrency(targetBalance));
        if (budgetedAmount <= targetBalance) {
          $('#' + emberId + '.budget-table-row.is-sub-category div.budget-table-cell-goal').css({ color: 'grey' });
        } else {
          $('#' + emberId + '.budget-table-row.is-sub-category div.budget-table-cell-goal').css({ color: '#ff4545' });
        }
      } else if (goalType === 'TBD') {
        $('#' + emberId + '.budget-table-row.is-sub-category div.budget-table-cell-goal').text(toolkitHelper.formatCurrency(targetBalanceDate));
        if (budgetedAmount <= targetBalanceDate) {
          $('#' + emberId + '.budget-table-row.is-sub-category div.budget-table-cell-goal').css({ color: 'grey' });
        } else {
          $('#' + emberId + '.budget-table-row.is-sub-category div.budget-table-cell-goal').css({ color: '#ff4545' });
        }
      }
    });
  }

  observe(changedNodes) {
    if (!this.shouldInvoke()) return;
    if (changedNodes.has('budget-table-cell-budgeted')) {
      $('.budget-table-cell-goal').remove();
      this.invoke();
    }

    if (changedNodes.has('budget-table-row is-sub-category') || changedNodes.has('budget-table-row is-sub-category is-checked') || changedNodes.has('budget-table-cell-goal')) {
      $('.budget-table-row.is-sub-category li.budget-table-cell-name .budget-table-cell-goal').css({
        background: '-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 10%,rgba(255,255,255,1) 100%)' });
      $('.budget-table-row.is-checked li.budget-table-cell-name .budget-table-cell-goal').css({ background: '#005a6e' });
    }
  }

  onRouteChanged() {
    if (!this.shouldInvoke()) return;
    this.invoke();
  }
}
<commit_msg>Make work with privacy mode toolkit feature<commit_after>import Feature from 'core/feature';
import * as toolkitHelper from 'helpers/toolkit';

export default class DisplayTargetGoalAmount extends Feature {
  constructor() {
    super();
  }

  shouldInvoke() {
    return toolkitHelper.getCurrentRouteName().indexOf('budget') !== -1;
  }

  invoke() {
    $('.budget-table-header .budget-table-cell-name').css('position', 'relative');
    $('.budget-table-row.is-sub-category li.budget-table-cell-name').css('position', 'relative');

    $('.budget-table-header .budget-table-cell-name').append(
      $('<div>', { class: 'budget-table-cell-goal' }).css(
        { position: 'absolute', right: 0, top: '6px' }).append('GOAL')
    );

    $('.budget-table-row.is-sub-category li.budget-table-cell-name').append(
      $('<div>', { class: 'budget-table-cell-goal currency' }).css({
        background: '-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 10%,rgba(255,255,255,1) 100%)', position: 'absolute', 'font-size': '80%', 'padding-left': '.75em', 'padding-right': '1px', 'line-height': '2.55em'
      })
    );

    $('.budget-table-row.is-sub-category').each((index, element) => {
      const emberId = element.id;
      const viewData = toolkitHelper.getEmberView(emberId).data;
      const { subCategory } = viewData;
      const { monthlySubCategoryBudget } = viewData;
      const { monthlySubCategoryBudgetCalculation } = viewData;
      const goalType = subCategory.get('goalType');
      const monthlyFunding = subCategory.get('monthlyFunding');
      const targetBalance = subCategory.get('targetBalance');
      const targetBalanceDate = monthlySubCategoryBudgetCalculation.get('goalTarget');
      const budgetedAmount = monthlySubCategoryBudget.get('budgeted');
      if (goalType === 'MF') {
        $('#' + emberId + '.budget-table-row.is-sub-category div.budget-table-cell-goal').text(toolkitHelper.formatCurrency(monthlyFunding));
        if (budgetedAmount <= monthlyFunding) {
          $('#' + emberId + '.budget-table-row.is-sub-category div.budget-table-cell-goal').css({ color: 'grey' });
        } else {
          $('#' + emberId + '.budget-table-row.is-sub-category div.budget-table-cell-goal').css({ color: '#ff4545' });
        }
      } else if (goalType === 'TB') {
        $('#' + emberId + '.budget-table-row.is-sub-category div.budget-table-cell-goal').text(toolkitHelper.formatCurrency(targetBalance));
        if (budgetedAmount <= targetBalance) {
          $('#' + emberId + '.budget-table-row.is-sub-category div.budget-table-cell-goal').css({ color: 'grey' });
        } else {
          $('#' + emberId + '.budget-table-row.is-sub-category div.budget-table-cell-goal').css({ color: '#ff4545' });
        }
      } else if (goalType === 'TBD') {
        $('#' + emberId + '.budget-table-row.is-sub-category div.budget-table-cell-goal').text(toolkitHelper.formatCurrency(targetBalanceDate));
        if (budgetedAmount <= targetBalanceDate) {
          $('#' + emberId + '.budget-table-row.is-sub-category div.budget-table-cell-goal').css({ color: 'grey' });
        } else {
          $('#' + emberId + '.budget-table-row.is-sub-category div.budget-table-cell-goal').css({ color: '#ff4545' });
        }
      }
    });
  }

  observe(changedNodes) {
    if (!this.shouldInvoke()) return;
    if (changedNodes.has('budget-table-cell-budgeted')) {
      $('.budget-table-cell-goal').remove();
      this.invoke();
    }

    if (changedNodes.has('budget-table-row is-sub-category') || changedNodes.has('budget-table-row is-sub-category is-checked') || changedNodes.has('budget-table-cell-goal')) {
      $('.budget-table-row.is-sub-category li.budget-table-cell-name .budget-table-cell-goal').css({
        background: '-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 10%,rgba(255,255,255,1) 100%)' });
      $('.budget-table-row.is-checked li.budget-table-cell-name .budget-table-cell-goal').css({ background: '#005a6e' });
    }
  }

  onRouteChanged() {
    if (!this.shouldInvoke()) return;
    this.invoke();
  }
}
<|endoftext|>


<commit_before>/* global goog, lime, obacht */
/* jshint strict: false, devel:true */

goog.provide('obacht.Collision');

/**
 * Collision Detector
 *
 * @constructor
 */
obacht.Collision = function () {
    "use strict";
};

obacht.Collision.prototype = {
    rect: function (object1, object2) {
        "use strict";
        /*Object Position*/
        this.object1pos = object1.character.getPosition();
        this.object2pos = object2.character.getPosition();

        /*Size Object1*/
        this.obj1w = object1.character.getSize().width;
        this.obj1h = object1.character.getSize().height;

        /*Size Object2*/
        this.obj2w = object2.character.getSize().width;
        this.obj2h = object2.character.getSize().height;

        /*Left Top Corner*/
        this.obj1x = Math.round(this.object1pos.x / 10) * 10 - (this.obj1w / 2);
        this.obj1y = Math.round(this.object1pos.y / 10) * 10 - (this.obj1h / 2);

        /*Left Top Corner*/
        this.obj2x = Math.round(this.object2pos.x / 10) * 10 - (this.obj2w / 2);
        this.obj2y = Math.round(this.object2pos.y / 10) * 10 - (this.obj2h / 2);
        return this.obj1x < this.obj2x + this.obj2w  &&
            this.obj2x < this.obj1x + this.obj1w  &&
            this.obj1y < this.obj2y + this.obj2h &&
            this.obj2y < this.obj1y + this.obj1h;
    }
};
<commit_msg>Collision clean<commit_after>/* global goog, lime, obacht */
/* jshint strict: false, devel:true */

goog.provide('obacht.Collision');
goog.require('obacht.themes');
//goog.require('obacht.Game');

/**
 * Collision Detector
 *
 * @constructor
 */
obacht.Collision = function () {
    "use strict";
};

obacht.Collision.prototype = {
    rect: function (player, trap) {
        "use strict";
        /*Object Position*/
        this.object1pos = player.character.getPosition();
        this.object2pos = trap.character.getPosition();

        /*Size Object1*/
        this.obj1w = player.character.getSize().width;
        this.obj1h = player.character.getSize().height;

        /*Size Object2*/
        this.obj2w = trap.character.getSize().width;
        this.obj2h = trap.character.getSize().height;

        /*Left Top Corner Player*/
        this.obj1x = Math.round(this.object1pos.x / 10) * 10 - (this.obj1w / 2);
        this.obj1y = Math.round(this.object1pos.y / 10) * 10 - (this.obj1h / 2);

        this.obj2x = Math.round(this.object2pos.x / 10) * 10 - (this.obj2w / 2);
        this.obj2y = Math.round(this.object2pos.y / 10) * 10 - (this.obj2h / 2);

        return this.obj1x < this.obj2x + this.obj2w  &&
            this.obj2x < this.obj1x + this.obj1w  &&
            this.obj1y < this.obj2y + this.obj2h &&
            this.obj2y < this.obj1y + this.obj1h;
    }
};
<|endoftext|>


<commit_before>var handlebars = require('handlebars');
var helpers = require('handlebars-helpers');
var _ = require('lodash');

var plugin = function() {
  'use strict';

  var init = function(options) {
    // register built-in helpers
    helpers.register(handlebars, options);
  };

  var compile = function(src, options, callback) {
    var tmpl;
    try {
      tmpl = handlebars.compile(src, options);
    } catch(ex) {
      callback(ex, null);
    }
    callback(null, tmpl);
  };

  var render = function(tmpl, options, callback) {
    var content;
    try {
      if(typeof tmpl === 'string') {
        tmpl = handlebars.compile(tmpl, options);
      }
      content = tmpl(options);
    } catch (ex) {
      callback(ex, null);
    }
    callback(null, content);
  };

  var registerFunctions = function(helperFunctions) {
    if(helperFunctions) {
      _.forOwn(helperFunctions, function(fn, key) {
        handlebars.registerHelper(key, fn);
      });
    }
  };

  var registerPartial = function(filename, content) {
    var tmpl;
    try {
      handlebars.registerPartial(filename, content);
    } catch (ex) {}
  };

  return {
    init: init,
    compile: compile,
    render: render,
    registerFunctions: registerFunctions,
    registerPartial: registerPartial,
    handlebars: handlebars
  };

};

module.exports = exports = plugin();
<commit_msg>remove unused var tmpl in registerPartial<commit_after>var handlebars = require('handlebars');
var helpers = require('handlebars-helpers');
var _ = require('lodash');

var plugin = function() {
  'use strict';

  var init = function(options) {
    // register built-in helpers
    helpers.register(handlebars, options);
  };

  var compile = function(src, options, callback) {
    var tmpl;
    try {
      tmpl = handlebars.compile(src, options);
    } catch(ex) {
      callback(ex, null);
    }
    callback(null, tmpl);
  };

  var render = function(tmpl, options, callback) {
    var content;
    try {
      if(typeof tmpl === 'string') {
        tmpl = handlebars.compile(tmpl, options);
      }
      content = tmpl(options);
    } catch (ex) {
      callback(ex, null);
    }
    callback(null, content);
  };

  var registerFunctions = function(helperFunctions) {
    if(helperFunctions) {
      _.forOwn(helperFunctions, function(fn, key) {
        handlebars.registerHelper(key, fn);
      });
    }
  };

  var registerPartial = function(filename, content) {
    try {
      handlebars.registerPartial(filename, content);
    } catch (ex) {}
  };

  return {
    init: init,
    compile: compile,
    render: render,
    registerFunctions: registerFunctions,
    registerPartial: registerPartial,
    handlebars: handlebars
  };

};

module.exports = exports = plugin();
<|endoftext|>


<commit_before>'use strict';

exports = module.exports = function(app, passport) {
  var LocalStrategy = require('passport-local').Strategy,
      TwitterStrategy = require('passport-twitter').Strategy,
      GitHubStrategy = require('passport-github').Strategy,
      FacebookStrategy = require('passport-facebook').Strategy,
      GoogleStrategy = require('passport-google-oauth').OAuth2Strategy,
      TumblrStrategy = require('passport-tumblr').Strategy;

  passport.use(new LocalStrategy(
    function(username, password, done) {

      if (username.indexOf('@') === -1) {
        //conditions.username = username;
        var conditions = { isActive: 'yes', username: username };
      }
      else {
        //conditions.email = username.toLowerCase();
        var conditions = { isActive: 'yes', email: username.toLowerCase() };
      }

      //console.dir(app);

      //mongo
      /*app.db.models.User.findOne(conditions, function(err, user) {

        if (err) {
          return done(err);
        }

        if (!user) {
          return done(null, false, { message: 'Unknown user' });
        }

        app.db.models.User.validatePassword(password, user.password, function(err, isValid) {
          if (err) {
            return done(err);
          }

          if (!isValid) {
            return done(null, false, { message: 'Invalid password' });
          }

          return done(null, user);
        });
      });*/

      //mysql
      app.db.models.User.findOne({
          where: conditions
       }).then(function(user) {
          //console.log('User returned.');
          //console.dir(user);

          if (!user) {
            return done(null, false, { message: 'Unknown user' });
          }

          app.db.models.User.validatePassword(password, user.password, function(err, isValid) {
            if (err) {
              return done(err);
            }

            if (!isValid) {
              return done(null, false, { message: 'Invalid password' });
            }

            return done(null, user);
          });

      });

    }
  ));

  if (app.config.oauth.twitter.key) {
    passport.use(new TwitterStrategy({
        consumerKey: app.config.oauth.twitter.key,
        consumerSecret: app.config.oauth.twitter.secret
      },
      function(token, tokenSecret, profile, done) {
        done(null, false, {
          token: token,
          tokenSecret: tokenSecret,
          profile: profile
        });
      }
    ));
  }

  if (app.config.oauth.github.key) {
    passport.use(new GitHubStrategy({
        clientID: app.config.oauth.github.key,
        clientSecret: app.config.oauth.github.secret,
        customHeaders: { "User-Agent": app.config.projectName }
      },
      function(accessToken, refreshToken, profile, done) {
        done(null, false, {
          accessToken: accessToken,
          refreshToken: refreshToken,
          profile: profile
        });
      }
    ));
  }

  if (app.config.oauth.facebook.key) {
    passport.use(new FacebookStrategy({
        clientID: app.config.oauth.facebook.key,
        clientSecret: app.config.oauth.facebook.secret
      },
      function(accessToken, refreshToken, profile, done) {
        done(null, false, {
          accessToken: accessToken,
          refreshToken: refreshToken,
          profile: profile
        });
      }
    ));
  }

  if (app.config.oauth.google.key) {
    passport.use(new GoogleStrategy({
        clientID: app.config.oauth.google.key,
        clientSecret: app.config.oauth.google.secret
      },
      function(accessToken, refreshToken, profile, done) {
        done(null, false, {
          accessToken: accessToken,
          refreshToken: refreshToken,
          profile: profile
        });
      }
    ));
  }

  if (app.config.oauth.tumblr.key) {
    passport.use(new TumblrStrategy({
        consumerKey: app.config.oauth.tumblr.key,
        consumerSecret: app.config.oauth.tumblr.secret
      },
      function(token, tokenSecret, profile, done) {
        done(null, false, {
          token: token,
          tokenSecret: tokenSecret,
          profile: profile
        });
      }
    ));
  }

  passport.serializeUser(function(user, done) {
    done(null, user.id);
  });

  passport.deserializeUser(function(id, done) {
    //mongo
    /*app.db.models.User.findOne({ _id: id }).populate('roles.admin').populate('roles.account').exec(function(err, user) {

      if (user && user.roles && user.roles.admin) {
        user.roles.admin.populate("groups", function(err, admin) {
          done(err, user);
        });
      }
      else {
        done(err, user);
      }
    });*/

    //mysql
    app.db.models.User.findOne({
        where: {id: id}
     })
    .then(function(err, user) {
        console.log('User deserialized.');
        console.dir(user);

        done(err, user);

    });

  });
};
<commit_msg>function changed for sequelize not mongo<commit_after>'use strict';

exports = module.exports = function(app, passport) {
  var LocalStrategy = require('passport-local').Strategy,
      TwitterStrategy = require('passport-twitter').Strategy,
      GitHubStrategy = require('passport-github').Strategy,
      FacebookStrategy = require('passport-facebook').Strategy,
      GoogleStrategy = require('passport-google-oauth').OAuth2Strategy,
      TumblrStrategy = require('passport-tumblr').Strategy;

  passport.use(new LocalStrategy(
    function(username, password, done) {

      if (username.indexOf('@') === -1) {
        //conditions.username = username;
        var conditions = { isActive: 'yes', username: username };
      }
      else {
        //conditions.email = username.toLowerCase();
        var conditions = { isActive: 'yes', email: username.toLowerCase() };
      }

      //console.dir(app);

      //mongo
      /*app.db.models.User.findOne(conditions, function(err, user) {

        if (err) {
          return done(err);
        }

        if (!user) {
          return done(null, false, { message: 'Unknown user' });
        }

        app.db.models.User.validatePassword(password, user.password, function(err, isValid) {
          if (err) {
            return done(err);
          }

          if (!isValid) {
            return done(null, false, { message: 'Invalid password' });
          }

          return done(null, user);
        });
      });*/

      //mysql
      app.db.models.User.findOne({
          where: conditions
       }).then(function(user) {
          //console.log('User returned.');
          //console.dir(user);

          if (!user) {
            return done(null, false, { message: 'Unknown user' });
          }

          app.db.models.User.validatePassword(password, user.password, function(err, isValid) {
            if (err) {
              return done(err);
            }

            if (!isValid) {
              return done(null, false, { message: 'Invalid password' });
            }

            return done(null, user);
          });

      });

    }
  ));

  if (app.config.oauth.twitter.key) {
    passport.use(new TwitterStrategy({
        consumerKey: app.config.oauth.twitter.key,
        consumerSecret: app.config.oauth.twitter.secret
      },
      function(token, tokenSecret, profile, done) {
        done(null, false, {
          token: token,
          tokenSecret: tokenSecret,
          profile: profile
        });
      }
    ));
  }

  if (app.config.oauth.github.key) {
    passport.use(new GitHubStrategy({
        clientID: app.config.oauth.github.key,
        clientSecret: app.config.oauth.github.secret,
        customHeaders: { "User-Agent": app.config.projectName }
      },
      function(accessToken, refreshToken, profile, done) {
        done(null, false, {
          accessToken: accessToken,
          refreshToken: refreshToken,
          profile: profile
        });
      }
    ));
  }

  if (app.config.oauth.facebook.key) {
    passport.use(new FacebookStrategy({
        clientID: app.config.oauth.facebook.key,
        clientSecret: app.config.oauth.facebook.secret
      },
      function(accessToken, refreshToken, profile, done) {
        done(null, false, {
          accessToken: accessToken,
          refreshToken: refreshToken,
          profile: profile
        });
      }
    ));
  }

  if (app.config.oauth.google.key) {
    passport.use(new GoogleStrategy({
        clientID: app.config.oauth.google.key,
        clientSecret: app.config.oauth.google.secret
      },
      function(accessToken, refreshToken, profile, done) {
        done(null, false, {
          accessToken: accessToken,
          refreshToken: refreshToken,
          profile: profile
        });
      }
    ));
  }

  if (app.config.oauth.tumblr.key) {
    passport.use(new TumblrStrategy({
        consumerKey: app.config.oauth.tumblr.key,
        consumerSecret: app.config.oauth.tumblr.secret
      },
      function(token, tokenSecret, profile, done) {
        done(null, false, {
          token: token,
          tokenSecret: tokenSecret,
          profile: profile
        });
      }
    ));
  }

  passport.serializeUser(function(user, done) {
    done(null, user.id);
  });

  passport.deserializeUser(function(id, done) {
    //mongo
    /*app.db.models.User.findOne({ _id: id }).populate('roles.admin').populate('roles.account').exec(function(err, user) {

      if (user && user.roles && user.roles.admin) {
        user.roles.admin.populate("groups", function(err, admin) {
          done(err, user);
        });
      }
      else {
        done(err, user);
      }
    });*/

    //mysql
    app.db.models.User.findOne({
        where: {id: id}
     })
    .then(function(user) {
        console.log('User deserialized.');
        console.dir(user);

        done(err, user);

    });

  });
};
<|endoftext|>


<commit_before>'use strict';

var Map              = require('es6-map')
  , memoize          = require('memoizee/plain')
  , defineStringLine = require('dbjs-ext/string/string-line')
  , _                = require('mano').i18n.bind('Model: Submissions')
  , defineDocument   = require('../document')
  , defineCost       = require('../document');

module.exports = memoize(function (db) {
	var StringLine = defineStringLine(db)
	  , Document = defineDocument(db)
	  , Cost = defineCost(db);

	var RejectReason = StringLine.createEnum('RejectReason', new Map([
		["illegible", {
			label: _("The document is unreadable")
		}],
		["invalid", {
			label: _("The loaded document does not match the required document")
		}],
		["other", {
			label: _("Other") + "..."
		}]
	]));

	return db.Object.extend('Submission', {
		document: { type: Document, nested: true },
		approved: { type: db.Boolean, required: true, trueLabel: _("Valid"), falseLabel: _("Invalid") },
		// If upload concerns payment receipt, this links cost it corresponds
		correspondingCost: { type: Cost },
		matchesOriginal: { type: db.Boolean, required: true },
		rejectReasonType: { type: RejectReason, required: true, label: _("Reject document") },
		rejectReasonMemo: { type: db.String, required: true, label: _("Explanation") },
		rejectReason: { type: db.String, label: _("Reject document"), required: true,
			value: function () {
				var type = this.rejectReasonType;
				if (type == null) return type;
				if (type === 'other') return (this.rejectReasonMemo || null);
				return this.database.RejectReason.meta[type].label;
			}, selectField: 'rejectReasonType', otherField: 'rejectReasonMemo' },
		isApproved: { type: db.Boolean, value: function (_observe) {
			if (this.approved == null) return null;
			if (this.approved) {
				if (this.correspondingCost) {
					return _observe(this.correspondingCost._isPaid) || null;
				}
				return true;
			}
			if (this.rejectReason == null) return null;
			return false;
		} },
		validateWithOriginal: { type: db.Boolean, required: true, value: false }
	});
}, { normalizer: require('memoizee/normalizers/get-1')() });
<commit_msg>Issue #682, fix submission's correspondingCost.<commit_after>'use strict';

var Map              = require('es6-map')
  , memoize          = require('memoizee/plain')
  , defineStringLine = require('dbjs-ext/string/string-line')
  , _                = require('mano').i18n.bind('Model: Submissions')
  , defineDocument   = require('../document')
  , defineCost       = require('../cost');

module.exports = memoize(function (db) {
	var StringLine = defineStringLine(db)
	  , Document = defineDocument(db)
	  , Cost = defineCost(db);

	var RejectReason = StringLine.createEnum('RejectReason', new Map([
		["illegible", {
			label: _("The document is unreadable")
		}],
		["invalid", {
			label: _("The loaded document does not match the required document")
		}],
		["other", {
			label: _("Other") + "..."
		}]
	]));

	return db.Object.extend('Submission', {
		document: { type: Document, nested: true },
		approved: { type: db.Boolean, required: true, trueLabel: _("Valid"), falseLabel: _("Invalid") },
		// If upload concerns payment receipt, this links cost it corresponds
		correspondingCost: { type: Cost },
		matchesOriginal: { type: db.Boolean, required: true },
		rejectReasonType: { type: RejectReason, required: true, label: _("Reject document") },
		rejectReasonMemo: { type: db.String, required: true, label: _("Explanation") },
		rejectReason: { type: db.String, label: _("Reject document"), required: true,
			value: function () {
				var type = this.rejectReasonType;
				if (type == null) return type;
				if (type === 'other') return (this.rejectReasonMemo || null);
				return this.database.RejectReason.meta[type].label;
			}, selectField: 'rejectReasonType', otherField: 'rejectReasonMemo' },
		isApproved: { type: db.Boolean, value: function (_observe) {
			if (this.approved == null) return null;
			if (this.approved) {
				if (this.correspondingCost) {
					return _observe(this.correspondingCost._isPaid) || null;
				}
				return true;
			}
			if (this.rejectReason == null) return null;
			return false;
		} },
		validateWithOriginal: { type: db.Boolean, required: true, value: false }
	});
}, { normalizer: require('memoizee/normalizers/get-1')() });
<|endoftext|>


<commit_before>//= require Chart.bundle
//= require chartkick
//= require moment
//= require EpicEditor
//= require jquery-sortable/jquery-sortable
//= require bootstrap-daterangepicker
//= require jquery.fix.clone
//= require admin/file_uploads
//= require admin/s3_uploads.js
//= require admin/email_tabulation
//= require s3_cors_fileupload
//= require bootstrap-sass/bootstrap/tab
//= require bootstrap-responsive-tabs

var editor;

$(document).on('ready', function() {

  editor = initEpicEditor('action-page-description', 'description');
  var editor2 = initEpicEditor('action-page-what-to-say', 'what-to-say');
  var editor3 = initEpicEditor('epic-petition-description', 'petition-description');
  var editor4 = initEpicEditor('epic-action-summary', 'action-summary');
  var editor5 = initEpicEditor('epic-email-text', 'email-text');
  var editor6 = initEpicEditor('epic-victory-message', 'victory-message');

  $("#date_control_container").each(function() {
    var date_start = $(this).data("date-start");
    var date_end = $(this).data("date-end");

    var action = $(".date_submit", this)[0];
    var base_url = window.location.pathname;
    action.href = base_url + "?date_start=" + date_start + "&date_end=" + date_end + window.location.hash;

    $("input#date_range", this).daterangepicker({
      format: "YYYY-MM-DD",
      startDate: date_start,
      endDate: date_end
    });

    $("input#date_range", this).on('apply.daterangepicker', function(ev, picker){
      date_start = picker.startDate.format("YYYY-MM-DD");
      date_end = picker.endDate.format("YYYY-MM-DD");
      action.href = base_url + "?date_start=" + date_start + "&date_end=" + date_end + window.location.hash;
      $('.daterangepicker').hide();
    });

    $("input#date_range", this).on('cancel.daterangepicker', function(ev, picker){
      $('.daterangepicker').hide();
    });
  });

  $(".edit-action .panel-heading").click(function(){
    setTimeout(function() {editor2.reflow()}, 100);
  });

  // This is a hack to make the "edit petition description" Epiceditor display at the right height when the panel is openened.
  $("#action_page_enable_petition").change(function(){
    setTimeout(function(){editor3.reflow()}, 100);
  });

  $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
    if(typeof editor5 != 'undefined'){
      editor5.reflow();
      editor6.reflow();
    }
  });

  $('.thumbnail').on('click', function (ev) {
    var image = $(ev.currentTarget);
    var md  = image.attr('src');
    $('.markdown-image-code').text(md);
    return false;
  });

  // the campaign tag should mirror the title, unless changed
  // this is for tracking analytics and will be delivered to congress-forms
  var campaign_tag_changed = false;
  var $title = $('#action_page_title');
  var campaign_tag_selector = '#action_page_email_campaign_attributes_campaign_tag';
  var $campaign_tag = $(campaign_tag_selector);
  if($title.val() != $campaign_tag.val())
    campaign_tag_changed = true;
  $title.keyup(function(e){
    var $campaign_tag = $(campaign_tag_selector);
    if(!campaign_tag_changed){
      $campaign_tag.val($title.val());
      console.log($campaign_tag.val());
    }
  });
  $campaign_tag.on("change keyup",function(){
    campaign_tag_changed = true;
  });

  if (window.location.hash.length) {
    $('a[data-tab="'+window.location.hash.slice(1)+'"]').tab('show');
    window.scrollTo(0, 0); // Otherwise page starts scrolled to initial tab location
  }
  $('.edit-action .nav-tabs a').on('show.bs.tab', function(e) {
    var anchor = $(e.target).data('tab');
    $('#anchor').val(anchor);
    history.pushState(null,null,'#' + anchor);
  });
  $('.action_pages-index .nav-tabs a').on('show.bs.tab', function(e) {
    var anchor = $(e.target).data('tab');
    $('#anchor').val(anchor);
    history.pushState(null,null,'#' + anchor);
  });

  var updated_at = $('#action_page_updated_at');
  if (updated_at.length > 0) {
    var t = window.setInterval(function() {
      $.get(updated_at.data('url'), { updated_at: updated_at.val() },
        function(data) {
          if (data.updated) {
            $('#action-page-form').submit(function(e) {
              if (confirm('Are you sure? This page has been updated since you started editing.')) {
                return;
              }
              e.preventDefault();
            });
            window.clearInterval(t);
          }
        }
      );
    }, 10000);
  }

  var preview_button = $('#action-page-preview').click(function() {
    $('#action-page-form').clone().attr('action', preview_button.attr('href')).
                                   attr('target', '_blank').
                                   submit();
    return false;
  });

  var $target_house = $('#action_page_email_campaign_attributes_target_house');
  var $target_senate = $('#action_page_email_campaign_attributes_target_senate');
  var $target_email = $('#action_page_email_campaign_attributes_target_email');
  var $addresses = $('#action_page_email_campaign_attributes_email_addresses');
  var $target_bioguide_id = $('#action_page_email_campaign_attributes_target_bioguide_id');
  var $bioguide_id = $('#action_page_email_campaign_attributes_bioguide_id');
  var $topic_category = $('#topic_category_form_group');
  var $campaign_tag = $('#campaign_tag_form_group');
  var $text_replacement = $('#text_replacement_form_group');

  function setup_target_ux($target_checkbox, $text_field, hide_cf_fields, show_alt_text_fields){
    if($target_checkbox.is(':checked')){
      $target_house.prop('disabled', true);
      $target_senate.prop('disabled', true);
      $target_bioguide_id.prop('disabled', true);
      $target_email.prop('disabled', true);
      $bioguide_id.hide();
      $addresses.hide();

      if(hide_cf_fields){
        $topic_category.hide();
        $campaign_tag.hide();
      }
      if(show_alt_text_fields){
        $text_replacement.show();
      }

      $text_field.show();
      $target_checkbox.prop('disabled', false);
    }
  }

  function create_target_listener($target_checkbox, $text_field, toggle_cf_fields, toggle_alt_text_fields){
    $target_checkbox.change(function(e){
      if($(this).is(':checked')){
        $target_house.prop('checked', false);
        $target_house.prop('disabled', true);
        $target_senate.prop('checked', false);
        $target_senate.prop('disabled', true);
        $target_bioguide_id.prop('checked', false);
        $target_bioguide_id.prop('disabled', true);
        $target_email.prop('checked', false);
        $target_email.prop('disabled', true);

        $target_checkbox.prop('checked', true);
        $target_checkbox.prop('disabled', false);

        if(toggle_cf_fields){
          $topic_category.hide();
          $campaign_tag.hide();
        }

        if(toggle_alt_text_fields){
          $text_replacement.show();
        }

        $text_field.show();
      } else {
        $target_house.prop('disabled', false);
        $target_senate.prop('disabled', false);
        $target_bioguide_id.prop('disabled', false);
        $target_email.prop('disabled', false);

        if(toggle_cf_fields){
          $topic_category.show();
          $campaign_tag.show();
        }

        if(toggle_alt_text_fields){
          $text_replacement.hide();
        }

        $text_field.hide();
      }
    });
  }

  create_target_listener($target_email, $addresses, true, false);
  create_target_listener($target_bioguide_id, $bioguide_id, false, true);

  setup_target_ux($target_email, $addresses, true, false);
  setup_target_ux($target_bioguide_id, $bioguide_id, false, true);
});

// Bootstrap popovers and tooltips
$('.action_pages-index i.has-tooltip').tooltip();

var popovers = "#protip2, #protip3, .photo-specs-popover, .photo-popover";
$(popovers).popover();

$(popovers).on('shown.bs.popover', function(){
  $(".popover").click(function(e){
    e.stopPropagation();
  });
  $("body").click(function(){
    $(popovers).popover('hide');
    $("body").off('click');
  });
});

// Prevent scrolling to the top of the page when clicking on protip popovers.
$( 'a[href="#"]' ).click( function(e) {
      e.preventDefault();
   } );

// Make chart.js redraw charts when we resize the browser
Chart.defaults.global.responsive = true;

// Bootstrap responsive tabs: https://github.com/openam/bootstrap-responsive-tabs
fakewaffle.responsiveTabs(['xs']);
<commit_msg>Form needs to be on page for submit to be triggered<commit_after>//= require Chart.bundle
//= require chartkick
//= require moment
//= require EpicEditor
//= require jquery-sortable/jquery-sortable
//= require bootstrap-daterangepicker
//= require jquery.fix.clone
//= require admin/file_uploads
//= require admin/s3_uploads.js
//= require admin/email_tabulation
//= require s3_cors_fileupload
//= require bootstrap-sass/bootstrap/tab
//= require bootstrap-responsive-tabs

var editor;

$(document).on('ready', function() {

  editor = initEpicEditor('action-page-description', 'description');
  var editor2 = initEpicEditor('action-page-what-to-say', 'what-to-say');
  var editor3 = initEpicEditor('epic-petition-description', 'petition-description');
  var editor4 = initEpicEditor('epic-action-summary', 'action-summary');
  var editor5 = initEpicEditor('epic-email-text', 'email-text');
  var editor6 = initEpicEditor('epic-victory-message', 'victory-message');

  $("#date_control_container").each(function() {
    var date_start = $(this).data("date-start");
    var date_end = $(this).data("date-end");

    var action = $(".date_submit", this)[0];
    var base_url = window.location.pathname;
    action.href = base_url + "?date_start=" + date_start + "&date_end=" + date_end + window.location.hash;

    $("input#date_range", this).daterangepicker({
      format: "YYYY-MM-DD",
      startDate: date_start,
      endDate: date_end
    });

    $("input#date_range", this).on('apply.daterangepicker', function(ev, picker){
      date_start = picker.startDate.format("YYYY-MM-DD");
      date_end = picker.endDate.format("YYYY-MM-DD");
      action.href = base_url + "?date_start=" + date_start + "&date_end=" + date_end + window.location.hash;
      $('.daterangepicker').hide();
    });

    $("input#date_range", this).on('cancel.daterangepicker', function(ev, picker){
      $('.daterangepicker').hide();
    });
  });

  $(".edit-action .panel-heading").click(function(){
    setTimeout(function() {editor2.reflow()}, 100);
  });

  // This is a hack to make the "edit petition description" Epiceditor display at the right height when the panel is openened.
  $("#action_page_enable_petition").change(function(){
    setTimeout(function(){editor3.reflow()}, 100);
  });

  $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
    if(typeof editor5 != 'undefined'){
      editor5.reflow();
      editor6.reflow();
    }
  });

  $('.thumbnail').on('click', function (ev) {
    var image = $(ev.currentTarget);
    var md  = image.attr('src');
    $('.markdown-image-code').text(md);
    return false;
  });

  // the campaign tag should mirror the title, unless changed
  // this is for tracking analytics and will be delivered to congress-forms
  var campaign_tag_changed = false;
  var $title = $('#action_page_title');
  var campaign_tag_selector = '#action_page_email_campaign_attributes_campaign_tag';
  var $campaign_tag = $(campaign_tag_selector);
  if($title.val() != $campaign_tag.val())
    campaign_tag_changed = true;
  $title.keyup(function(e){
    var $campaign_tag = $(campaign_tag_selector);
    if(!campaign_tag_changed){
      $campaign_tag.val($title.val());
      console.log($campaign_tag.val());
    }
  });
  $campaign_tag.on("change keyup",function(){
    campaign_tag_changed = true;
  });

  if (window.location.hash.length) {
    $('a[data-tab="'+window.location.hash.slice(1)+'"]').tab('show');
    window.scrollTo(0, 0); // Otherwise page starts scrolled to initial tab location
  }
  $('.edit-action .nav-tabs a').on('show.bs.tab', function(e) {
    var anchor = $(e.target).data('tab');
    $('#anchor').val(anchor);
    history.pushState(null,null,'#' + anchor);
  });
  $('.action_pages-index .nav-tabs a').on('show.bs.tab', function(e) {
    var anchor = $(e.target).data('tab');
    $('#anchor').val(anchor);
    history.pushState(null,null,'#' + anchor);
  });

  var updated_at = $('#action_page_updated_at');
  if (updated_at.length > 0) {
    var t = window.setInterval(function() {
      $.get(updated_at.data('url'), { updated_at: updated_at.val() },
        function(data) {
          if (data.updated) {
            $('#action-page-form').submit(function(e) {
              if (confirm('Are you sure? This page has been updated since you started editing.')) {
                return;
              }
              e.preventDefault();
            });
            window.clearInterval(t);
          }
        }
      );
    }, 10000);
  }

  var preview_button = $('#action-page-preview').click(function() {
    var form = $('#action-page-form').clone()
                 .attr("id", null).css("display", "none")
                 .attr('action', preview_button.attr('href'))
                 .attr('target', '_blank');
    $("body").append(form);
    form.submit();
    return false;
  });

  var $target_house = $('#action_page_email_campaign_attributes_target_house');
  var $target_senate = $('#action_page_email_campaign_attributes_target_senate');
  var $target_email = $('#action_page_email_campaign_attributes_target_email');
  var $addresses = $('#action_page_email_campaign_attributes_email_addresses');
  var $target_bioguide_id = $('#action_page_email_campaign_attributes_target_bioguide_id');
  var $bioguide_id = $('#action_page_email_campaign_attributes_bioguide_id');
  var $topic_category = $('#topic_category_form_group');
  var $campaign_tag = $('#campaign_tag_form_group');
  var $text_replacement = $('#text_replacement_form_group');

  function setup_target_ux($target_checkbox, $text_field, hide_cf_fields, show_alt_text_fields){
    if($target_checkbox.is(':checked')){
      $target_house.prop('disabled', true);
      $target_senate.prop('disabled', true);
      $target_bioguide_id.prop('disabled', true);
      $target_email.prop('disabled', true);
      $bioguide_id.hide();
      $addresses.hide();

      if(hide_cf_fields){
        $topic_category.hide();
        $campaign_tag.hide();
      }
      if(show_alt_text_fields){
        $text_replacement.show();
      }

      $text_field.show();
      $target_checkbox.prop('disabled', false);
    }
  }

  function create_target_listener($target_checkbox, $text_field, toggle_cf_fields, toggle_alt_text_fields){
    $target_checkbox.change(function(e){
      if($(this).is(':checked')){
        $target_house.prop('checked', false);
        $target_house.prop('disabled', true);
        $target_senate.prop('checked', false);
        $target_senate.prop('disabled', true);
        $target_bioguide_id.prop('checked', false);
        $target_bioguide_id.prop('disabled', true);
        $target_email.prop('checked', false);
        $target_email.prop('disabled', true);

        $target_checkbox.prop('checked', true);
        $target_checkbox.prop('disabled', false);

        if(toggle_cf_fields){
          $topic_category.hide();
          $campaign_tag.hide();
        }

        if(toggle_alt_text_fields){
          $text_replacement.show();
        }

        $text_field.show();
      } else {
        $target_house.prop('disabled', false);
        $target_senate.prop('disabled', false);
        $target_bioguide_id.prop('disabled', false);
        $target_email.prop('disabled', false);

        if(toggle_cf_fields){
          $topic_category.show();
          $campaign_tag.show();
        }

        if(toggle_alt_text_fields){
          $text_replacement.hide();
        }

        $text_field.hide();
      }
    });
  }

  create_target_listener($target_email, $addresses, true, false);
  create_target_listener($target_bioguide_id, $bioguide_id, false, true);

  setup_target_ux($target_email, $addresses, true, false);
  setup_target_ux($target_bioguide_id, $bioguide_id, false, true);
});

// Bootstrap popovers and tooltips
$('.action_pages-index i.has-tooltip').tooltip();

var popovers = "#protip2, #protip3, .photo-specs-popover, .photo-popover";
$(popovers).popover();

$(popovers).on('shown.bs.popover', function(){
  $(".popover").click(function(e){
    e.stopPropagation();
  });
  $("body").click(function(){
    $(popovers).popover('hide');
    $("body").off('click');
  });
});

// Prevent scrolling to the top of the page when clicking on protip popovers.
$( 'a[href="#"]' ).click( function(e) {
      e.preventDefault();
   } );

// Make chart.js redraw charts when we resize the browser
Chart.defaults.global.responsive = true;

// Bootstrap responsive tabs: https://github.com/openam/bootstrap-responsive-tabs
fakewaffle.responsiveTabs(['xs']);
<|endoftext|>


<commit_before>var than = 5;

YmplayerIniter = function() {
    if (ymplayer = document.getElementsByTagName("ymplayer"), 0 != ymplayer.length) for (var a = 0; a < ymplayer.length; a++) {
        if (tempSrc = ymplayer[a].attributes.src.value, tempID = ymplayer[a].getAttribute("name"),
        artist = ymplayer[a].getAttribute("artist"), song = ymplayer[a].getAttribute("song"),
        cover = ymplayer[a].getAttribute("cover"), audioEle = document.createElement("audio"),
        ymplayer[a].setAttribute("init", "no"), audioEle.setAttribute("id", tempID), audioEle.setAttribute("src", tempSrc),
        audioEle.setAttribute("preload", "no"), proEle = document.createElement("div"),
        proEle.setAttribute("class", "ym-progress"), proEle.id = tempID + "-progress", proEle.innerHTML = '
00:00

' + '00:00
',
        conEle = document.createElement("div"), conEle.setAttribute("class", "player-container"),
        coverEle = document.createElement("div"), coverEle.setAttribute("class", "ym-songinfo"),
        coverEle.innerHTML = '

' + song + '

' + artist + "

",
        coverEle.getElementsByClassName("ym-cover-image")[0].style.backgroundImage = "url(" + cover + ")",
        ctEle = document.createElement("div"), ctEle.setAttribute("class", "ym-controller"),
        ctEle.id = tempID + "-controller", ctEle.innerHTML = '
\n" + '\n' + '\n' + '\n' + '
\n' + '

',
        conEle.appendChild(coverEle), conEle.appendChild(ctEle), ymplayer[a].appendChild(audioEle),
        lrcbox = document.createElement("div"), lrcbox.id = tempID + "lrcbox", lrcbox.setAttribute("class", "ym-lrcbox"),
        lrcbox.innerHTML = '

', lrcContainer = lrcbox.getElementsByClassName("lrc-container")[0],
        lrc = ymplayer[a].getElementsByTagName("lrc"), "null" != typeof lrc && 0 != lrc.length) {
            lyric = lrc[0].innerHTML, lyric = lyric.replace(/(\\n)/g, "\n"), lyric = lyric.split("\n"),
            timeline = Array(), lrcContent = Array();
            for (var b in lyric) lyric[b].match(/(ti:|ar:)/) || "" != lyric[b] && (tempLrc = lyric[b].match(/([0-9]{2})\:([0-9]{2}\.[0-9]{2})/),
            tempContent = lyric[b].match(/\[.*?\](.*?)$/), null != typeof tempLrc && (minute = 60 * tempLrc[1],
            sec = minute + parseFloat(tempLrc[2]), lrcEle = document.createElement("lyric"),
            lrcEle.setAttribute("timeline", sec), lrcEle.innerHTML = "
" + tempContent[1] + "
",
            lrcContainer.appendChild(lrcEle)));
            ymplayer[a].setAttribute("currentLrc", 0);
        } else lrcEle = document.createElement("lyric"), lrcEle.setAttribute("timeline", 0),
        lrcEle.innerHTML = "
404 Not Found

 看来这首歌是没有填词的纯音乐……

 或者说歌词没有被填写。
",
        lrcContainer.appendChild(lrcEle);
        ymplayer[a].appendChild(lrcbox), ymplayer[a].appendChild(proEle), ymplayer[a].appendChild(conEle),
        lrc = ymplayer[a].getElementsByTagName("lrc");
    }
};

var Ymplayer = new Object();

Ymplayer.Play = function(a) {
    audioElement = document.getElementById(a), 0 != audioElement.paused ? (audioElement.play(),
    btn = document.getElementById(a + "-controller").getElementsByClassName("play-button"),
    btn[0].innerHTML = '', par = audioElement.parentNode,
    "no" == par.getAttribute("init") && (setInterval("Ymplayer.Change(" + a + ")", 1e3),
    currentTime = audioElement.currentTime, duration = "0" + parseInt(audioElement.duration / 60) + ":",
    inter = parseInt(audioElement.duration - 60 * parseInt(audioElement.duration / 60)),
    10 > inter && (inter = "0" + inter), duration += inter, par.getElementsByClassName("duration-time")[0].innerHTML = duration),
    null != par.getAttribute("currentLrc") && setInterval(function() {
        Ymplayer.Lrc(a);
    }, 20)) :(audioElement.pause(), btn = document.getElementById(a + "-controller").getElementsByClassName("play-button"),
    btn[0].innerHTML = '');
}, Ymplayer.Stop = function(a) {
    audioElement = document.getElementById(a), parent = audioElement.parentNode, audioElement.pause(),
    audioElement.currentTime = 0, btn = document.getElementById(a + "-controller").getElementsByClassName("play-button"),
    btn[0].innerHTML = '', parent.getElementsByClassName("ym-played")[0].style.width = "0%";
}, Ymplayer.Loop = function(a) {
    audioElement = document.getElementById(a), ymParent = audioElement.parentNode, loopbtn = document.getElementById(a + "-controller").getElementsByClassName("loop-button")[0],
    "no" == ymParent.getAttribute("loop") ? (ymParent.setAttribute("loop", "yes"), addClass(loopbtn, "looping")) :(ymParent.setAttribute("loop", "no"),
    removeClass(loopbtn, "looping"));
}, Ymplayer.Change = function(a) {
    return ae = "object" == typeof a ? a :document.getElementById(a), ae.currentTime == ae.duration ? ("yes" == ae.parentNode.getAttribute("loop") && (ae.currentTime = 0,
    ae.parentNode.setAttribute("currentLrc", 0), ae.parentNode.getElementsByClassName("lrc-container")[0].style.margin = "0px"),
    void 0) :(now = ae.currentTime / ae.duration, percent = 100 * now + "%", current = "0" + parseInt(ae.currentTime / 60) + ":",
    inter = parseInt(ae.currentTime - 60 * parseInt(ae.currentTime / 60)), 10 > inter && (inter = "0" + inter),
    current += inter, ae.parentNode.getElementsByClassName("ym-played")[0].style.width = percent,
    ae.parentNode.getElementsByClassName("current-time")[0].innerHTML = current, void 0);
}, Ymplayer.LrcBox = function(a) {
    audioElement = "object" == typeof a ? a :document.getElementById(a), player = audioElement.parentNode,
    lrcbox = player.getElementsByClassName("ym-lrcbox")[0], "showed" != player.getAttribute("inited") ? (player.style.height = "400px",
    lrcbox.style.height = "290px", player.setAttribute("inited", "showed")) :(player.style.height = "120px",
    lrcbox.style.height = "0px", player.setAttribute("inited", "hidden"));
}, Ymplayer.Skip = function(a,event) {
    a = audioElement = "object" == typeof a ? a :document.getElementById(a), pbarEle = audioElement.parentNode.getElementsByClassName("ym-pgbar")[0],
    playedEle = audioElement.parentNode.getElementsByClassName("ym-played")[0], clickarea = event.clientX,
    awayleft = audioElement.parentNode.offsetLeft + pbarEle.offsetLeft, divwidth = pbarEle.offsetWidth,
    clickwidth = clickarea - awayleft, pro = clickwidth / divwidth, a.currentTime = a.duration * pro,
    propercent = 100 * pro + "%", playedEle.style.width = propercent;
}, Ymplayer.ChangeVol = function(a) {
    a = audioElement = "object" == typeof a ? a :document.getElementById(a), barEle = audioElement.parentNode.getElementsByClassName("volume-bar")[0],
    currentEle = audioElement.parentNode.getElementsByClassName("volume-current")[0],
    clickarea = event.clientX, awayleft = getRect(barEle).left, divwidth = barEle.offsetWidth,
    clickwidth = clickarea - awayleft, pro = clickwidth / divwidth, pro > 1 && (pro = 1),
    a.volume = pro, propercent = 100 * pro + "%", currentEle.style.width = propercent;
}, Ymplayer.Novol = function(a) {
    a = document.getElementById(a), 0 == a.volume ? (a.volume = 1, btn = a.parentNode.getElementsByClassName("vol-button"),
    btn[0].innerHTML = '') :(a.volume = 0, btn = a.parentNode.getElementsByClassName("vol-button"),
    btn[0].innerHTML = '');
}, Ymplayer.Lrc = function(a) {
    if (audioElement = document.getElementById(a), parent = audioElement.parentNode,
    0 == audioElement.paused) {
        if (time = audioElement.currentTime, all = audioElement.duration, lrcEle = parent.getElementsByTagName("lyric"),
        long = lrcEle.length, currentLrc = parseInt(parent.getAttribute("currentLrc")),
        lrccontainer = parent.getElementsByClassName("lrc-container")[0], time > lrcEle[long - 1].getAttribute("timeline")) return !1;
        if (time >= lrcEle[currentLrc].getAttribute("timeline")) {
            if (long - 1 > currentLrc && time > lrcEle[parseInt(currentLrc) + 1].getAttribute("timeline")) {
                if (active = lrccontainer.getElementsByClassName("ym-active"), "null" != typeof active) for (leng = active.length,
                o = 0; leng > o; ) removeClass(active[o], "ym-active"), o++;
                for (var b = 0 in lrcEle) time > lrcEle[currentLrc].getAttribute("timeline") ? b++ :(marginHeight = lrcEle[than - 1].offsetTop - lrcEle[currentLrc].offsetTop,
                lrccontainer.style.marginTop = marginHeight + "px", parent.setAttribute("currentLrc", b),
                Ymplayer.Lrc(a));
            }
            0 != currentLrc && removeClass(lrcEle[currentLrc - 1], "ym-active"), addClass(lrcEle[currentLrc], "ym-active"),
            currentLrc >= than && (marginHeight = lrcEle[than - 1].offsetTop - lrcEle[currentLrc].offsetTop,
            lrccontainer.style.marginTop = marginHeight + "px"), parent.setAttribute("currentLrc", currentLrc + 1);
        } else if (0 != currentLrc && time < lrcEle[currentLrc - 1].getAttribute("timeline")) {
            if (active = lrccontainer.getElementsByClassName("ym-active"), "null" != typeof active) for (leng = active.length,
            o = 0; leng > o; ) removeClass(active[o], "ym-active"), o++;
            for (var c = 0 in lrcEle) {
                if (time < lrcEle[0].getAttribute("timeline")) {
                    lrccontainer.style.marginTop = "0px";
                    break;
                }
                if (time > lrcEle[c].getAttribute("timeline")) {
                    than >= c ? lrccontainer.style.marginTop = "0px" :(marginHeight = lrcEle[than - 1].offsetTop - lrcEle[currentLrc].offsetTop,
                    lrccontainer.style.marginTop = marginHeight + "px"), addClass(lrcEle[c], "ym-active"),
                    parent.setAttribute("currentLrc", c), Ymplayer.Lrc(a);
                    break;
                }
                c++;
            }
        }
    }
};

function hasClass(a, b) {
    return a.className.match(new RegExp("(\\s|^)" + b + "(\\s|$)"));
}

function addClass(a, b) {
    this.hasClass(a, b) || (a.className += " " + b);
}

function removeClass(a, b) {
    if (hasClass(a, b)) {
        var c = new RegExp("(\\s|^)" + b + "(\\s|$)");
        a.className = a.className.replace(c, " ");
    }
}

function getRect(a) {
    var b = a.getBoundingClientRect(), c = document.documentElement.clientTop, d = document.documentElement.clientLeft;
    return {
        top:b.top - c,
        bottom:b.bottom - c,
        left:b.left - d,
        right:b.right - d
    };
}

window.onload = function() {
    YmplayerIniter();
};
<commit_msg>Update ymplayer.min.js<commit_after>var than = 5;

YmplayerIniter = function() {
    if (ymplayer = document.getElementsByTagName("ymplayer"), 0 != ymplayer.length) for (var a = 0; a < ymplayer.length; a++) {
        if (tempSrc = ymplayer[a].attributes.src.value, tempID = ymplayer[a].getAttribute("name"),
        artist = ymplayer[a].getAttribute("artist"), song = ymplayer[a].getAttribute("song"),
        cover = ymplayer[a].getAttribute("cover"), audioEle = document.createElement("audio"),
        ymplayer[a].setAttribute("init", "no"), audioEle.setAttribute("id", tempID), audioEle.setAttribute("src", tempSrc),
        audioEle.setAttribute("preload", "no"), proEle = document.createElement("div"),
        proEle.setAttribute("class", "ym-progress"), proEle.id = tempID + "-progress", proEle.innerHTML = '
00:00

' + '00:00
',
        conEle = document.createElement("div"), conEle.setAttribute("class", "player-container"),
        coverEle = document.createElement("div"), coverEle.setAttribute("class", "ym-songinfo"),
        coverEle.innerHTML = '

' + song + '

' + artist + "

",
        coverEle.getElementsByClassName("ym-cover-image")[0].style.backgroundImage = "url(" + cover + ")",
        ctEle = document.createElement("div"), ctEle.setAttribute("class", "ym-controller"),
        ctEle.id = tempID + "-controller", ctEle.innerHTML = '
\n" + '\n' + '\n' + '\n' + '
\n' + '

',
        conEle.appendChild(coverEle), conEle.appendChild(ctEle), ymplayer[a].appendChild(audioEle),
        lrcbox = document.createElement("div"), lrcbox.id = tempID + "lrcbox", lrcbox.setAttribute("class", "ym-lrcbox"),
        lrcbox.innerHTML = '

', lrcContainer = lrcbox.getElementsByClassName("lrc-container")[0],
        lrc = ymplayer[a].getElementsByTagName("lrc"), "null" != typeof lrc && 0 != lrc.length) {
            lyric = lrc[0].innerHTML, lyric = lyric.replace(/(\\n)/g, "\n"), lyric = lyric.split("\n"),
            timeline = Array(), lrcContent = Array();
            for (var b in lyric) lyric[b].match(/(ti:|ar:)/) || "" != lyric[b] && (tempLrc = lyric[b].match(/([0-9]{2})\:([0-9]{2}\.[0-9]{2})/),
            tempContent = lyric[b].match(/\[.*?\](.*?)$/), null != typeof tempLrc && (minute = 60 * tempLrc[1],
            sec = minute + parseFloat(tempLrc[2]), lrcEle = document.createElement("lyric"),
            lrcEle.setAttribute("timeline", sec), lrcEle.innerHTML = "
" + tempContent[1] + "
",
            lrcContainer.appendChild(lrcEle)));
            ymplayer[a].setAttribute("currentLrc", 0);
        } else lrcEle = document.createElement("lyric"), lrcEle.setAttribute("timeline", 0),
        lrcEle.innerHTML = "
404 Not Found

 看来这首歌是没有填词的纯音乐……

 或者说歌词没有被填写。
",
        lrcContainer.appendChild(lrcEle);
        ymplayer[a].appendChild(lrcbox), ymplayer[a].appendChild(proEle), ymplayer[a].appendChild(conEle),
        lrc = ymplayer[a].getElementsByTagName("lrc");
    }
};

var Ymplayer = new Object();

Ymplayer.Play = function(a) {
    audioElement = document.getElementById(a), 0 != audioElement.paused ? (audioElement.play(),
    btn = document.getElementById(a + "-controller").getElementsByClassName("play-button"),
    btn[0].innerHTML = '', par = audioElement.parentNode,
    "no" == par.getAttribute("init") && (setInterval("Ymplayer.Change(" + a + ")", 1e3),
    currentTime = audioElement.currentTime, duration = "0" + parseInt(audioElement.duration / 60) + ":",
    inter = parseInt(audioElement.duration - 60 * parseInt(audioElement.duration / 60)),
    10 > inter && (inter = "0" + inter), duration += inter, par.getElementsByClassName("duration-time")[0].innerHTML = duration),
    null != par.getAttribute("currentLrc") && setInterval(function() {
        Ymplayer.Lrc(a);
    }, 20)) :(audioElement.pause(), btn = document.getElementById(a + "-controller").getElementsByClassName("play-button"),
    btn[0].innerHTML = '');
}, Ymplayer.Stop = function(a) {
    audioElement = document.getElementById(a), parent = audioElement.parentNode, audioElement.pause(),
    audioElement.currentTime = 0, btn = document.getElementById(a + "-controller").getElementsByClassName("play-button"),
    btn[0].innerHTML = '', parent.getElementsByClassName("ym-played")[0].style.width = "0%";
}, Ymplayer.Loop = function(a) {
    audioElement = document.getElementById(a), ymParent = audioElement.parentNode, loopbtn = document.getElementById(a + "-controller").getElementsByClassName("loop-button")[0],
    "no" == ymParent.getAttribute("loop") ? (ymParent.setAttribute("loop", "yes"), addClass(loopbtn, "looping")) :(ymParent.setAttribute("loop", "no"),
    removeClass(loopbtn, "looping"));
}, Ymplayer.Change = function(a) {
    return ae = "object" == typeof a ? a :document.getElementById(a), ae.currentTime == ae.duration ? ("yes" == ae.parentNode.getAttribute("loop") && (ae.currentTime = 0,
    ae.parentNode.setAttribute("currentLrc", 0), ae.parentNode.getElementsByClassName("lrc-container")[0].style.margin = "0px"),
    void 0) :(now = ae.currentTime / ae.duration, percent = 100 * now + "%", current = "0" + parseInt(ae.currentTime / 60) + ":",
    inter = parseInt(ae.currentTime - 60 * parseInt(ae.currentTime / 60)), 10 > inter && (inter = "0" + inter),
    current += inter, ae.parentNode.getElementsByClassName("ym-played")[0].style.width = percent,
    ae.parentNode.getElementsByClassName("current-time")[0].innerHTML = current, void 0);
}, Ymplayer.LrcBox = function(a) {
    audioElement = "object" == typeof a ? a :document.getElementById(a), player = audioElement.parentNode,
    lrcbox = player.getElementsByClassName("ym-lrcbox")[0], "showed" != player.getAttribute("inited") ? (player.style.height = "400px",
    lrcbox.style.height = "290px", player.setAttribute("inited", "showed")) :(player.style.height = "120px",
    lrcbox.style.height = "0px", player.setAttribute("inited", "hidden"));
}, Ymplayer.Skip = function(a,event) {
    a = audioElement = "object" == typeof a ? a :document.getElementById(a), pbarEle = audioElement.parentNode.getElementsByClassName("ym-pgbar")[0],
    playedEle = audioElement.parentNode.getElementsByClassName("ym-played")[0], clickarea = event.clientX,
    awayleft = audioElement.parentNode.offsetLeft + pbarEle.offsetLeft, divwidth = pbarEle.offsetWidth,
    clickwidth = clickarea - awayleft, pro = clickwidth / divwidth, a.currentTime = a.duration * pro,
    propercent = 100 * pro + "%", playedEle.style.width = propercent;
}, Ymplayer.ChangeVol = function(a,event) {
    a = audioElement = "object" == typeof a ? a :document.getElementById(a), barEle = audioElement.parentNode.getElementsByClassName("volume-bar")[0],
    currentEle = audioElement.parentNode.getElementsByClassName("volume-current")[0],
    clickarea = event.clientX, awayleft = getRect(barEle).left, divwidth = barEle.offsetWidth,
    clickwidth = clickarea - awayleft, pro = clickwidth / divwidth, pro > 1 && (pro = 1),
    a.volume = pro, propercent = 100 * pro + "%", currentEle.style.width = propercent;
}, Ymplayer.Novol = function(a) {
    a = document.getElementById(a), 0 == a.volume ? (a.volume = 1, btn = a.parentNode.getElementsByClassName("vol-button"),
    btn[0].innerHTML = '') :(a.volume = 0, btn = a.parentNode.getElementsByClassName("vol-button"),
    btn[0].innerHTML = '');
}, Ymplayer.Lrc = function(a) {
    if (audioElement = document.getElementById(a), parent = audioElement.parentNode,
    0 == audioElement.paused) {
        if (time = audioElement.currentTime, all = audioElement.duration, lrcEle = parent.getElementsByTagName("lyric"),
        long = lrcEle.length, currentLrc = parseInt(parent.getAttribute("currentLrc")),
        lrccontainer = parent.getElementsByClassName("lrc-container")[0], time > lrcEle[long - 1].getAttribute("timeline")) return !1;
        if (time >= lrcEle[currentLrc].getAttribute("timeline")) {
            if (long - 1 > currentLrc && time > lrcEle[parseInt(currentLrc) + 1].getAttribute("timeline")) {
                if (active = lrccontainer.getElementsByClassName("ym-active"), "null" != typeof active) for (leng = active.length,
                o = 0; leng > o; ) removeClass(active[o], "ym-active"), o++;
                for (var b = 0 in lrcEle) time > lrcEle[currentLrc].getAttribute("timeline") ? b++ :(marginHeight = lrcEle[than - 1].offsetTop - lrcEle[currentLrc].offsetTop,
                lrccontainer.style.marginTop = marginHeight + "px", parent.setAttribute("currentLrc", b),
                Ymplayer.Lrc(a));
            }
            0 != currentLrc && removeClass(lrcEle[currentLrc - 1], "ym-active"), addClass(lrcEle[currentLrc], "ym-active"),
            currentLrc >= than && (marginHeight = lrcEle[than - 1].offsetTop - lrcEle[currentLrc].offsetTop,
            lrccontainer.style.marginTop = marginHeight + "px"), parent.setAttribute("currentLrc", currentLrc + 1);
        } else if (0 != currentLrc && time < lrcEle[currentLrc - 1].getAttribute("timeline")) {
            if (active = lrccontainer.getElementsByClassName("ym-active"), "null" != typeof active) for (leng = active.length,
            o = 0; leng > o; ) removeClass(active[o], "ym-active"), o++;
            for (var c = 0 in lrcEle) {
                if (time < lrcEle[0].getAttribute("timeline")) {
                    lrccontainer.style.marginTop = "0px";
                    break;
                }
                if (time > lrcEle[c].getAttribute("timeline")) {
                    than >= c ? lrccontainer.style.marginTop = "0px" :(marginHeight = lrcEle[than - 1].offsetTop - lrcEle[currentLrc].offsetTop,
                    lrccontainer.style.marginTop = marginHeight + "px"), addClass(lrcEle[c], "ym-active"),
                    parent.setAttribute("currentLrc", c), Ymplayer.Lrc(a);
                    break;
                }
                c++;
            }
        }
    }
};

function hasClass(a, b) {
    return a.className.match(new RegExp("(\\s|^)" + b + "(\\s|$)"));
}

function addClass(a, b) {
    this.hasClass(a, b) || (a.className += " " + b);
}

function removeClass(a, b) {
    if (hasClass(a, b)) {
        var c = new RegExp("(\\s|^)" + b + "(\\s|$)");
        a.className = a.className.replace(c, " ");
    }
}

function getRect(a) {
    var b = a.getBoundingClientRect(), c = document.documentElement.clientTop, d = document.documentElement.clientLeft;
    return {
        top:b.top - c,
        bottom:b.bottom - c,
        left:b.left - d,
        right:b.right - d
    };
}

window.onload = function() {
    YmplayerIniter();
};
<|endoftext|>