<commit_before>'use strict';

import createHistory from 'history/lib/createBrowserHistory';
import useQueries from 'history/lib/useQueries';
import Store from 'store-prototype';
import List from '../lib/List';

const history = useQueries(createHistory)();

let _location = null;
let _ready = false;
let _loading = false;
let _items = {};
let _itemsResultsClone = [];

const _list = new List(Keystone.list);

const active = {
	columns: _list.expandColumns(_list.defaultColumns),
	filters: [],
	search: '',
	sort: _list.expandSort(_list.defaultSort),
};

let page = defaultPage();

function defaultPage () {
	return {
		size: _list.perPage,
		index: 1,
	};
}

// TODO: This is pretty messy; state variables should not be set by defaulters
// Needs to be reviewed & cleaned up

let drag;
function defaultDrag () {
	drag = {
		page: 1,
		item: false,
		clonedItems: false,
		index: false,
	};
	return drag;
}
defaultDrag();

var _rowAlert;
function defaultRowAlert () {
	_rowAlert = {
		success: false,
		fail: false,
	};
	return _rowAlert;
}
defaultRowAlert();

function updateQueryParams (params, replace) {
	if (!_location) return;
	const newParams = Object.assign({}, _location.query);
	Object.keys(params).forEach(i => {
		if (params[i]) {
			newParams[i] = params[i];
			if (typeof newParams[i] === 'object') {
				newParams[i] = JSON.stringify(newParams[i]);
			}
		} else {
			delete newParams[i];
		}
	});
	history[replace ? 'replaceState' : 'pushState'](null, _location.pathname, newParams);
}

const CurrentListStore = new Store({
	getList () {
		return _list;
	},
	getDragBase () {
		return drag;
	},
	setDragBase (item, index) {
		drag.page = page.index;
		drag.clonedItems = _itemsResultsClone.slice(0);
		if (item) {
			drag.item = item;
			if (index) {
				drag.index = index;
			}
		}
		return drag;
	},
	getAvailableColumns () {
		return _list.columns;
	},
	getActiveColumns () {
		return active.columns;
	},
	setActiveColumns (columns) {
		if (Array.isArray(columns)) columns = columns.join(',');
		if (columns === _list.defaultColumnPaths) columns = undefined;
		updateQueryParams({ columns });
	},
	getActiveSearch () {
		return active.search;
	},
	setActiveSearch (str) {
		// starting or clearing a search pushes a new history state, but updating
		// the current search replaces it for nicer history navigation support
		const replace = (str && this.getActiveSearch());
		updateQueryParams({ search: str }, replace);
	},
	getActiveSort () {
		return active.sort;
	},
	setActiveSort (sort) {
		if (sort === _list.defaultSort) sort = undefined;
		updateQueryParams({ sort });
	},
	getAvailableFilters () {
		return _list.columns.filter(col => col.field && col.field.hasFilterMethod);
	},
	getActiveFilters () {
		return active.filters;
	},
	getFilter (path) {
		return active.filters.filter(i => i.field.path === path)[0];
	},
	setFilter (path, value) {
		let filter = this.getFilter(path);
		if (filter) {
			filter.value = value;
		} else {
			const field = _list.fields[path];
			if (!field) {
				console.warn('Invalid Filter path specified:', path);
				return;
			}
			filter = { field, value };
			active.filters.push(filter);
		}
		this.setCurrentPage(1);
		this.notifyChange();
	},
	clearFilter (path) {
		var filter = active.filters.filter(i => i.field.path === path)[0];
		if (!filter) return;
		active.filters.splice(active.filters.indexOf(filter), 1);
		this.loadItems();
		this.notifyChange();
	},
	clearAllFilters () {
		active.filters = [];
		this.loadItems();
		this.notifyChange();
	},
	getPageSize () {
		return page.size;
	},
	getCurrentPage () {
		return page.index;
	},
	setCurrentPage (index) {
		if (index === 1) index = undefined;
		updateQueryParams({ page: index });
	},
	isLoading () {
		return _loading;
	},
	isReady () {
		return _ready;
	},
	loadItems (options = {}) {
		_loading = true;
		defaultRowAlert();
		_list.loadItems({
			search: active.search,
			filters: active.filters,
			sort: active.sort,
			columns: active.columns,
			page: page,
		}, (err, items) => {
			_loading = false;
			// TODO: graceful error handling
			if (items) {
				_ready = true;
				_items = items;

				if (page.index !== drag.page && drag.item) {
					// add the dragging item
					if (page.index > drag.page) {
						_items.results.unshift(drag.item);
					} else {
						_items.results.push(drag.item);
					}
				}
				_itemsResultsClone = items.results.slice(0);

				if (options.success && options.id) {
					// flashes a success background on the row
					_rowAlert.success = options.id;
				}
				if (options.fail && options.id) {
					// flashes a failure background on the row
					_rowAlert.fail = options.id;
				}

			}
			this.notifyChange();
		});
	},
	getItems () {
		return _items;
	},
	deleteItem (itemId) {
		_list.deleteItem(itemId, (err, data) => {
			// TODO: graceful error handling
			if (err) {
				return this.resetItems(this.findItemById[itemId]);
			}
			this.loadItems();
		});
	},
	deleteItems (itemIds) {
		_list.deleteItems(itemIds, (err, data) => {
			// TODO: graceful error handling
			this.loadItems();
		});
	},
	downloadItems (format, columns) {
		var url = _list.getDownloadURL({
			search: active.search,
			filters: active.filters,
			sort: active.sort,
			columns: columns ? _list.expandColumns(columns) : active.columns,
			format: format,
		});
		window.open(url);
	},
	rowAlert (reset = false) {
		//  reset the alerts or return the object
		if (reset) {
			defaultRowAlert();
			return this.notifyChange();
		}
		return _rowAlert;
	},
	dragDropChangePage (page) {
		this.setCurrentPage(page);
	},
	moveItem (prevIndex, newIndex, options) {
		// moves an item up/down in the list
		if (options.manageMode) {
			// TODO: option to use manageMode for sortOrder
			_items.results.splice(newIndex, 0, _items.results.splice(prevIndex, 1)[0]);
		} else {
			_items.results.splice(newIndex, 0, _items.results.splice(prevIndex, 1)[0]);
		}

		this.notifyChange();
	},
	reorderItems (item, prevSortOrder, newSortOrder, goToPage) {
		// reset drag
		defaultDrag();
		// set the new page data
		page = {
			size: page.size,
			index: goToPage || page.index,
		};

		// send the item, previous sortOrder and the new sortOrder
		// we should get the proper list and new page results in return
		_list.reorderItems(
			item,
			prevSortOrder,
			newSortOrder,
			{
				search: active.search,
				filters: active.filters,
				sort: active.sort,
				columns: active.columns,
				page,
			},
			(err, items) => {
				// if err flash the row alert
				if (err) {
					return this.resetItems(this.findItemById[item.id]);
				}
				if (typeof items !== 'object' && items.results) {
					_items = items;
					_itemsResultsClone = items.results.slice(0);
					_rowAlert.success = item.id;
				}
				return this.notifyChange();
			}
		);
	},
	findClonedItemById (id) {
		// find an item in the clone by id
		const item = _itemsResultsClone.filter(c => c.id === id)[0];
		return {
			item,
			index: _itemsResultsClone.indexOf(item),
		};
	},
	findClonedItemByIndex (index) {
		// find an item in the clone by index
		return _itemsResultsClone[index];
	},
	resetItems (itemIndex) {

		if (page.index !== drag.page) {
			// we are not on the original page so we need to move back to it
			page.index = drag.page;
			this.loadItems({
				fail: true,
				id: this.findClonedItemByIndex(itemIndex).id,
			});
			// reset drag
			return defaultDrag();
		}

		// reset the list if dragout or error
		_rowAlert = {
			success: false,
			fail: this.findClonedItemByIndex(itemIndex).id,
		};
		// we use the cached clone since this is the same page
		// the clone contains the proper index numbers which get overwritten on drag
		_items.results = drag.clonedItems;
		defaultDrag();
		this.notifyChange();
	},
});

history.listen(function (location) {
	_location = location;
	active.columns = _list.expandColumns(location.query.columns || _list.defaultColumns);
	active.search = location.query.search || '';
	active.sort = _list.expandSort(location.query.sort || _list.defaultSort);
	page.index = Number(location.query.page);
	if (isNaN(page.index)) page.index = 1;
	CurrentListStore.loadItems();
	CurrentListStore.notifyChange();
});

module.exports = CurrentListStore;
<commit_msg>Display categories in filter list in admin ui<commit_after>'use strict';

import createHistory from 'history/lib/createBrowserHistory';
import useQueries from 'history/lib/useQueries';
import Store from 'store-prototype';
import List from '../lib/List';

const history = useQueries(createHistory)();

let _location = null;
let _ready = false;
let _loading = false;
let _items = {};
let _itemsResultsClone = [];

const _list = new List(Keystone.list);

const active = {
	columns: _list.expandColumns(_list.defaultColumns),
	filters: [],
	search: '',
	sort: _list.expandSort(_list.defaultSort),
};

let page = defaultPage();

function defaultPage () {
	return {
		size: _list.perPage,
		index: 1,
	};
}

// TODO: This is pretty messy; state variables should not be set by defaulters
// Needs to be reviewed & cleaned up

let drag;
function defaultDrag () {
	drag = {
		page: 1,
		item: false,
		clonedItems: false,
		index: false,
	};
	return drag;
}
defaultDrag();

var _rowAlert;
function defaultRowAlert () {
	_rowAlert = {
		success: false,
		fail: false,
	};
	return _rowAlert;
}
defaultRowAlert();

function updateQueryParams (params, replace) {
	if (!_location) return;
	const newParams = Object.assign({}, _location.query);
	Object.keys(params).forEach(i => {
		if (params[i]) {
			newParams[i] = params[i];
			if (typeof newParams[i] === 'object') {
				newParams[i] = JSON.stringify(newParams[i]);
			}
		} else {
			delete newParams[i];
		}
	});
	history[replace ? 'replaceState' : 'pushState'](null, _location.pathname, newParams);
}

const CurrentListStore = new Store({
	getList () {
		return _list;
	},
	getDragBase () {
		return drag;
	},
	setDragBase (item, index) {
		drag.page = page.index;
		drag.clonedItems = _itemsResultsClone.slice(0);
		if (item) {
			drag.item = item;
			if (index) {
				drag.index = index;
			}
		}
		return drag;
	},
	getAvailableColumns () {
		return _list.columns;
	},
	getActiveColumns () {
		return active.columns;
	},
	setActiveColumns (columns) {
		if (Array.isArray(columns)) columns = columns.join(',');
		if (columns === _list.defaultColumnPaths) columns = undefined;
		updateQueryParams({ columns });
	},
	getActiveSearch () {
		return active.search;
	},
	setActiveSearch (str) {
		// starting or clearing a search pushes a new history state, but updating
		// the current search replaces it for nicer history navigation support
		const replace = (str && this.getActiveSearch());
		updateQueryParams({ search: str }, replace);
	},
	getActiveSort () {
		return active.sort;
	},
	setActiveSort (sort) {
		if (sort === _list.defaultSort) sort = undefined;
		updateQueryParams({ sort });
	},
	getAvailableFilters () {
		return _list.columns.filter(col => (col.field && col.field.hasFilterMethod) || col.type === 'heading');
	},
	getActiveFilters () {
		return active.filters;
	},
	getFilter (path) {
		return active.filters.filter(i => i.field.path === path)[0];
	},
	setFilter (path, value) {
		let filter = this.getFilter(path);
		if (filter) {
			filter.value = value;
		} else {
			const field = _list.fields[path];
			if (!field) {
				console.warn('Invalid Filter path specified:', path);
				return;
			}
			filter = { field, value };
			active.filters.push(filter);
		}
		this.setCurrentPage(1);
		this.notifyChange();
	},
	clearFilter (path) {
		var filter = active.filters.filter(i => i.field.path === path)[0];
		if (!filter) return;
		active.filters.splice(active.filters.indexOf(filter), 1);
		this.loadItems();
		this.notifyChange();
	},
	clearAllFilters () {
		active.filters = [];
		this.loadItems();
		this.notifyChange();
	},
	getPageSize () {
		return page.size;
	},
	getCurrentPage () {
		return page.index;
	},
	setCurrentPage (index) {
		if (index === 1) index = undefined;
		updateQueryParams({ page: index });
	},
	isLoading () {
		return _loading;
	},
	isReady () {
		return _ready;
	},
	loadItems (options = {}) {
		_loading = true;
		defaultRowAlert();
		_list.loadItems({
			search: active.search,
			filters: active.filters,
			sort: active.sort,
			columns: active.columns,
			page: page,
		}, (err, items) => {
			_loading = false;
			// TODO: graceful error handling
			if (items) {
				_ready = true;
				_items = items;

				if (page.index !== drag.page && drag.item) {
					// add the dragging item
					if (page.index > drag.page) {
						_items.results.unshift(drag.item);
					} else {
						_items.results.push(drag.item);
					}
				}
				_itemsResultsClone = items.results.slice(0);

				if (options.success && options.id) {
					// flashes a success background on the row
					_rowAlert.success = options.id;
				}
				if (options.fail && options.id) {
					// flashes a failure background on the row
					_rowAlert.fail = options.id;
				}

			}
			this.notifyChange();
		});
	},
	getItems () {
		return _items;
	},
	deleteItem (itemId) {
		_list.deleteItem(itemId, (err, data) => {
			// TODO: graceful error handling
			if (err) {
				return this.resetItems(this.findItemById[itemId]);
			}
			this.loadItems();
		});
	},
	deleteItems (itemIds) {
		_list.deleteItems(itemIds, (err, data) => {
			// TODO: graceful error handling
			this.loadItems();
		});
	},
	downloadItems (format, columns) {
		var url = _list.getDownloadURL({
			search: active.search,
			filters: active.filters,
			sort: active.sort,
			columns: columns ? _list.expandColumns(columns) : active.columns,
			format: format,
		});
		window.open(url);
	},
	rowAlert (reset = false) {
		//  reset the alerts or return the object
		if (reset) {
			defaultRowAlert();
			return this.notifyChange();
		}
		return _rowAlert;
	},
	dragDropChangePage (page) {
		this.setCurrentPage(page);
	},
	moveItem (prevIndex, newIndex, options) {
		// moves an item up/down in the list
		if (options.manageMode) {
			// TODO: option to use manageMode for sortOrder
			_items.results.splice(newIndex, 0, _items.results.splice(prevIndex, 1)[0]);
		} else {
			_items.results.splice(newIndex, 0, _items.results.splice(prevIndex, 1)[0]);
		}

		this.notifyChange();
	},
	reorderItems (item, prevSortOrder, newSortOrder, goToPage) {
		// reset drag
		defaultDrag();
		// set the new page data
		page = {
			size: page.size,
			index: goToPage || page.index,
		};

		// send the item, previous sortOrder and the new sortOrder
		// we should get the proper list and new page results in return
		_list.reorderItems(
			item,
			prevSortOrder,
			newSortOrder,
			{
				search: active.search,
				filters: active.filters,
				sort: active.sort,
				columns: active.columns,
				page,
			},
			(err, items) => {
				// if err flash the row alert
				if (err) {
					return this.resetItems(this.findItemById[item.id]);
				}
				if (typeof items !== 'object' && items.results) {
					_items = items;
					_itemsResultsClone = items.results.slice(0);
					_rowAlert.success = item.id;
				}
				return this.notifyChange();
			}
		);
	},
	findClonedItemById (id) {
		// find an item in the clone by id
		const item = _itemsResultsClone.filter(c => c.id === id)[0];
		return {
			item,
			index: _itemsResultsClone.indexOf(item),
		};
	},
	findClonedItemByIndex (index) {
		// find an item in the clone by index
		return _itemsResultsClone[index];
	},
	resetItems (itemIndex) {

		if (page.index !== drag.page) {
			// we are not on the original page so we need to move back to it
			page.index = drag.page;
			this.loadItems({
				fail: true,
				id: this.findClonedItemByIndex(itemIndex).id,
			});
			// reset drag
			return defaultDrag();
		}

		// reset the list if dragout or error
		_rowAlert = {
			success: false,
			fail: this.findClonedItemByIndex(itemIndex).id,
		};
		// we use the cached clone since this is the same page
		// the clone contains the proper index numbers which get overwritten on drag
		_items.results = drag.clonedItems;
		defaultDrag();
		this.notifyChange();
	},
});

history.listen(function (location) {
	_location = location;
	active.columns = _list.expandColumns(location.query.columns || _list.defaultColumns);
	active.search = location.query.search || '';
	active.sort = _list.expandSort(location.query.sort || _list.defaultSort);
	page.index = Number(location.query.page);
	if (isNaN(page.index)) page.index = 1;
	CurrentListStore.loadItems();
	CurrentListStore.notifyChange();
});

module.exports = CurrentListStore;
<|endoftext|>


<commit_before>'use strict';

// Controller Module
var contactControllers = angular.module('contactControllers', []);
// Controller for displaying the list of teams, with 2 second timeout delay
contactControllers.controller('contactListController', [ "$scope", "$timeout", "contactService",
  function ($scope, $timeout, contactService) {
    $timeout(function(){
      contactService.contactsList(function(data){
        $scope.contact = data;
        $scope.loading = false;
      });
    }, 2000);
  $scope.sortField = 'lname';
  $scope.reverse = false;
}]);
// Controller for displaying the details of the team when the name is clicked, with 3 second timeout delay
contactControllers.controller('contactDetailController', ["$scope", "$timeout", "$routeParams", "contactService",
	function ($scope, $timeout, $routeParams, contactService){
    $timeout(function(){
      contactService.contactsDetails($routeParams.contactId, function(data){
        $scope.contact = data;
        $scope.loading = false;
      });
    }, 2000);
}]);
// Controller that handles the add team page and how the data is passed to the PHP file.
contactControllers.controller('addContactController', ["$scope", "$http", "$location", "contactService", "assembleFormDataService",
  function ($scope, $http, $location, contactService, assembleFormDataService){
    $scope.addContact = function(){
     var readyFormData = assembleFormDataService.populateFormData($scope.fname, $scope.lname, $scope.address, $scope.city, $scope.zipcode, $scope.mnumber, $scope.lnumber, $scope.relation, $scope.photoSubmit);
      contactService.addContacts(readyFormData, function(){
        $location.path('/contacts');
      });
    };
}]);
//Controller that handles the edit team page and how the data is pulled/pushed to the DB
contactControllers.controller('editContactController', ["$scope", "$routeParams", "$http", "$location", "contactService", "assembleFormDataService",
  function ($scope, $routeParams, $http, $location, contactService, assembleFormDataService){
    contactService.contactsDetails($routeParams.contactId, function(data){
      $scope.contactedit = data;
    });
  $scope.editContact = function(){
    var readyFormData = assembleFormDataService.populateFormData($scope.contactedit.fname, $scope.contactedit.lname, $scope.contactedit.address, $scope.contactedit.city, $scope.contactedit.zipcode, $scope.contactedit.mnumber, $scope.contactedit.lnumber, $scope.contactedit.relation, $scope.contactedit.email, $scope.contactedit.photo);
      contactService.editContact($routeParams.contactId, readyFormData, function(){
        $location.path('/contacts');
    });
  };
}]);
// Controller that handles the team deletion
contactControllers.controller('deleteContactController', ["$scope", "$routeParams", "$http", "$location", "contactService",
  function ($scope, $routeParams, $http, $location, contactService){
    contactService.contactsDetails($routeParams.contactId, function(data){
      $scope.contactdelete = data;
    });
    $scope.deleteContact = function(){
      contactService.deleteContact($routeParams.contactId, function(data){
        $location.path('/contacts');
      });
    };
}]);
// Handles which nav bar element is in an active state
function HeaderController($scope, $location)
{
    $scope.isActive = function (viewLocation) {
        return viewLocation === $location.path();
    };
}
<commit_msg>testing<commit_after>'use strict';

// Controller Module
var contactControllers = angular.module('contactControllers', []);
// Controller for displaying the list of teams, with 2 second timeout delay
contactControllers.controller('contactListController', [ "$scope", "$timeout", "contactService",
  function ($scope, $timeout, contactService) {
    $timeout(function(){
      contactService.contactsList(function(data){
        $scope.contact = data;
        $scope.loading = false;
      });
    }, 2000);
  $scope.sortField = 'lname';
  $scope.reverse = false;
}]);
// Controller for displaying the details of the team when the name is clicked, with 3 second timeout delay
contactControllers.controller('contactDetailController', ["$scope", "$timeout", "$routeParams", "contactService",
	function ($scope, $timeout, $routeParams, contactService){
    $timeout(function(){
      contactService.contactsDetails($routeParams.contactId, function(data){
        $scope.contact = data;
        $scope.loading = false;
      });
    }, 2000);
}]);
// Controller that handles the add team page and how the data is passed to the PHP file.
contactControllers.controller('addContactController', ["$scope", "$http", "$location", "contactService", "assembleFormDataService",
  function ($scope, $http, $location, contactService, assembleFormDataService){
    $scope.addContact = function(){
     var readyFormData = assembleFormDataService.populateFormData($scope.fname, $scope.lname, $scope.address, $scope.city, $scope.zipcode, $scope.mnumber, $scope.lnumber, $scope.relation, $scope.email, $scope.photoSubmit);
      contactService.addContacts(readyFormData, function(){
        $location.path('/contacts');
      });
    };
}]);
//Controller that handles the edit team page and how the data is pulled/pushed to the DB
contactControllers.controller('editContactController', ["$scope", "$routeParams", "$http", "$location", "contactService", "assembleFormDataService",
  function ($scope, $routeParams, $http, $location, contactService, assembleFormDataService){
    contactService.contactsDetails($routeParams.contactId, function(data){
      $scope.contactedit = data;
    });
  $scope.editContact = function(){
    var readyFormData = assembleFormDataService.populateFormData($scope.contactedit.fname, $scope.contactedit.lname, $scope.contactedit.address, $scope.contactedit.city, $scope.contactedit.zipcode, $scope.contactedit.mnumber, $scope.contactedit.lnumber, $scope.contactedit.relation, $scope.contactedit.email, $scope.contactedit.photo);
      contactService.editContact($routeParams.contactId, readyFormData, function(){
        $location.path('/contacts');
    });
  };
}]);
// Controller that handles the team deletion
contactControllers.controller('deleteContactController', ["$scope", "$routeParams", "$http", "$location", "contactService",
  function ($scope, $routeParams, $http, $location, contactService){
    contactService.contactsDetails($routeParams.contactId, function(data){
      $scope.contactdelete = data;
    });
    $scope.deleteContact = function(){
      contactService.deleteContact($routeParams.contactId, function(data){
        $location.path('/contacts');
      });
    };
}]);
// Handles which nav bar element is in an active state
function HeaderController($scope, $location)
{
    $scope.isActive = function (viewLocation) {
        return viewLocation === $location.path();
    };
}
<|endoftext|>


<commit_before>Ensembl.HCManager = new Base();

Ensembl.HCManager.extend({
  initialize: function () {
    this.base();

    var self = this;

    this.constant = {
      classes:            ['hc-comment-link'],
      infoBoxClass:       'hc-infobox',
      configDivClass:     'hc-config',
      localTools:         'tool_buttons',
      manualOkClass:      'hc-oked-link',
      notNewClass:        'hc-notnew-link',
      noFailsClass:       'hc-nofailsrow',
      failsClass:         'hc-failsrow',
      tableHeadingClass:  'hc-dbheading',
      evenOddClasses:     ['bg1', 'bg2'],
      filterTableClass:   '_filter_table',
      hilightedCell:      'hc-cell-highlight',
      isIE6:              $('body').hasClass('ie6'),
      info:               ["Double click on any 'Select' or 'Deselect' to respectively select or deselect all reports for multi-annotation."]
    };

    this.tables   = [];
    this.configs  = false;
    this.evenRow  = '';
    this.oddRow   = '';

    //if details page, create selectors
    for (var i in this.constant.classes) {

      $('.' + this.constant.classes[i]).each(function () {
          new HCSelector(self, $('a', this)[0]);
      });
    }

    //update info, checkboxes etc if selectors created if it has selectors
    if (this.tables.length) {

      this.configs = {};
      this.configs[this.constant.notNewClass] = {
        label:      ' Show new reports only',
        flag:       false,
        cookieName: 'a'
      };
      this.configs[this.constant.manualOkClass] = {
        label:      " Exclude 'manual ok' reports",
        flag:       false,
        cookieName: 'b'
      };

      var infoDiv = $('.' + this.constant.infoBoxClass).first();
      for (var i in this.constant.info) {
        infoDiv.append($(document.createElement('p')).html(this.constant.info[i]));
      }

      for (var i in this.tables) {
        if (this.tables[i].selectors[0]) {
          this.evenRow = this.tables[i].selectors[0].row.attr('class');
        }
        if (this.tables[i].selectors[1]) {
          this.oddRow = this.tables[i].selectors[1].row.attr('class');
          break;
        }
      }
    }

    //if summary page
    if ($('.' + this.constant.failsClass + ', .' + this.constant.noFailsClass).length) {

      this.configs = {};
      this.configs[this.constant.noFailsClass] = {
        label:      " Exclude 'no fail' rows",
        flag:       false,
        cookieName: 'c'
      };
      $('.' + this.constant.noFailsClass).parents('table').addClass(this.constant.filterTableClass);
      $('.' + this.constant.noFailsClass).parents('tr').addClass(this.constant.noFailsClass);
    }

    //create config checkboxes
    if (this.configs) {

      var configDiv = $(document.createElement('div'))
        .addClass(this.constant.configDivClass)
        .insertAfter($('.' + this.constant.localTools)[0])
        .keepOnPage({marginTop: 3});

      for (var i in this.configs) {

        this.configs[i].checkbox = $(document.createElement('input'))
          .attr({type: 'checkbox', id: i})
          .bind('change', function () {
            self.configs[this.id].flag = this.checked;
            self.updateCookie();
            self.filterRows();
          })
          .prependTo($(document.createElement('p'))
            .append($(document.createElement('label')).attr('for', i).html(this.configs[i].label))
            .appendTo(configDiv)
          );
      }

      this.updateFromCookie();
      this.filterRows();
    }
  },

  getTable: function (num) {

    return this.tables[num] = this.tables[num] || new HCTable(this);
  },

  changeLinks: function () {

    var tablesAffected = [];

    for (var i in this.tables) {

      if (
        this.tables[i].selectedIds === false ||  //coz a link in it has been changed
        this.tables[i].selectedIds.length > 0    //coz it has links that need to be changed
      ) {
        tablesAffected.push(this.tables[i]);
      }
    }

    var rid = [];
    for (var i in this.tables) {
      var ridTable = this.tables[i].getSelectedIds();
      if (ridTable != '') {
        rid.push(ridTable);
      }
    }
    rid = rid.join(',');
    for (var i in tablesAffected) {
      tablesAffected[i].changeLinks(rid);
    }
  },

  filterRows: function () {
    var self = this;

    var rowsToHide = [];
    for (var i in this.configs) {
      if (this.configs[i].flag) {
        rowsToHide.push('tr.' + i);
      }
    }

    $('table.' + this.constant.filterTableClass + ' tr').show().data('hidden', false);
    if (rowsToHide.length) {
      $(rowsToHide.join(', ')).hide().data('hidden', true);
    }

    $('table.' + this.constant.filterTableClass + ' tbody').each(function () {

      var classes = self.constant.evenOddClasses.slice(0);
      $('tr', this).each(function () {

        if (!$(this).data('hidden')) {
          classes = classes.reverse();
          $(this).removeClass(classes[0]).addClass(classes[1]);
        }
      });
    });
  },

  cookie: {
    data: {},

    set: function (name, value) {
      this.data[name] = value;

      var ck = [];
      for (var i in this.data) {
        ck.push(i + '-' + this.data[i]);
      }

      Ensembl.cookie.set('hcconfig', ck.join('.'));
    },

    get: function(name) {
      var ck = Ensembl.cookie.get('hcconfig').split('.');
      for (var i in ck) {
        if (ck[i]) {
          var val = ck[i].split('-');
          this.data[val[0]] = val[1];
        }
      }

      return this.data[name];
    }
  },

  updateCookie: function () {
    var j = 2;
    for (var i in this.configs) {
      this.cookie.set(this.configs[i].cookieName, this.configs[i].flag * 1);
    }
  },

  updateFromCookie: function () {

    for (var i in this.configs) {

      this.configs[i].flag = !!parseInt(this.cookie.get(this.configs[i].cookieName));

      if (this.configs[i].checkbox) {
        this.configs[i].checkbox.attr('checked', this.configs[i].flag);
      }
    }

  }
});

function HCTable(manager) {
  var self = this;

  this.manager = manager;
  this.selectors = [];
  this.selectedIds = []; //false if any selection changed - empty array if none selected - array of ids of reports if selected
  this.table = false;

  this.add = function (selector) {

    this.selectors.push(selector);

    if (!this.table) {
      this.table = selector.row.parents('table').first().addClass(this.manager.constant.filterTableClass);
      this.table.prev('h3').append(
        $(document.createElement('a'))
          .attr('href', '#showHide')
          .html('Hide')
          .bind('click', function (e) {
            e.preventDefault();
            this.innerHTML = this.innerHTML == 'Hide' ? 'Show' : 'Hide';
            self.table.toggle();
          })
      );
    }

    selector.table = this;
  };

  this.changeLinks = function(rid) {
    for (var i in this.selectors) {
      this.selectors[i].changeLink(rid);
    }
  };

  this.selectAll = function(flag) {
    for (var i in this.selectors) {
      this.selectors[i].select(flag);
    }
  };

  this.getSelectedIds = function() {
    if (this.selectedIds === false) {
      this.selectedIds = [];
      for (var i in this.selectors) {
        if (this.selectors[i].selected) {
          this.selectedIds.push(this.selectors[i].rid);
        }
      }
    }
    return this.selectedIds.join(',');
  };
}

function HCSelector(manager, a) {
  var self = this;

  this.a = $(a);
  this.manager = manager;
  this.row = this.a.parents('tr').first().addClass(this.a.attr('class'));
  this.manager.getTable(a.rel).add(this); //link it to it's table & vice versa
  this.defaultText = a.innerHTML;
  this.defaultLink = a.href;
  this.selected = false;
  this.link = a.href.split('=')[0];
  this.rid = parseInt(a.href.split('=')[1]);

  this.a1 = $(document.createElement('a'))
    .html('Select')
    .attr({title: 'Select for multi-annotation', href: '#Select'})
    .appendTo(a.parentNode)
    .bind({
      click: function (e) {
        e.preventDefault();
        self.select(!self.selected); //reverse selection
        self.dblclickFlag = self.selected;
        self.table.selectedIds = false;
        self.manager.changeLinks();
      },
      dblclick: function (e) {
        e.preventDefault();
        self.table.selectAll(self.manager.constant.isIE6 ? self.dblclickFlag : !self.selected);
        self.table.selectedIds = false;
        self.manager.changeLinks();
      }
    });

  this.select = function(flag) {
    if (flag && !!this.row.data('hidden')) {
      return;
    }
    this.selected = flag;
    this.a1.html(flag ? 'Deselect' : 'Select');
  };

  this.changeLink = function(rid) {
    this.a.html(this.selected ? 'Multi Annotate' : this.defaultText).attr('href', this.selected ? this.link + '=' + rid : this.defaultLink);
    this.highlight();
  };

  this.highlight = function() {
    $('td', this.row).attr('class', this.selected ? this.manager.constant.hilightedCell : '');
  };
}<commit_msg>change info box class to javascript form (with underscore)<commit_after>Ensembl.HCManager = new Base();

Ensembl.HCManager.extend({
  initialize: function () {
    this.base();

    var self = this;

    this.constant = {
      classes:            ['hc-comment-link'],
      infoBoxClass:       '_hc_infobox',
      configDivClass:     'hc-config',
      localTools:         'tool_buttons',
      manualOkClass:      'hc-oked-link',
      notNewClass:        'hc-notnew-link',
      noFailsClass:       'hc-nofailsrow',
      failsClass:         'hc-failsrow',
      tableHeadingClass:  'hc-dbheading',
      evenOddClasses:     ['bg1', 'bg2'],
      filterTableClass:   '_filter_table',
      hilightedCell:      'hc-cell-highlight',
      isIE6:              $('body').hasClass('ie6'),
      info:               ["Double click on any 'Select' or 'Deselect' to respectively select or deselect all reports for multi-annotation."]
    };

    this.tables   = [];
    this.configs  = false;
    this.evenRow  = '';
    this.oddRow   = '';

    //if details page, create selectors
    for (var i in this.constant.classes) {

      $('.' + this.constant.classes[i]).each(function () {
          new HCSelector(self, $('a', this)[0]);
      });
    }

    //update info, checkboxes etc if selectors created if it has selectors
    if (this.tables.length) {

      this.configs = {};
      this.configs[this.constant.notNewClass] = {
        label:      ' Show new reports only',
        flag:       false,
        cookieName: 'a'
      };
      this.configs[this.constant.manualOkClass] = {
        label:      " Exclude 'manual ok' reports",
        flag:       false,
        cookieName: 'b'
      };

      var infoDiv = $('.' + this.constant.infoBoxClass).first();
      for (var i in this.constant.info) {
        infoDiv.append($(document.createElement('p')).html(this.constant.info[i]));
      }

      for (var i in this.tables) {
        if (this.tables[i].selectors[0]) {
          this.evenRow = this.tables[i].selectors[0].row.attr('class');
        }
        if (this.tables[i].selectors[1]) {
          this.oddRow = this.tables[i].selectors[1].row.attr('class');
          break;
        }
      }
    }

    //if summary page
    if ($('.' + this.constant.failsClass + ', .' + this.constant.noFailsClass).length) {

      this.configs = {};
      this.configs[this.constant.noFailsClass] = {
        label:      " Exclude 'no fail' rows",
        flag:       false,
        cookieName: 'c'
      };
      $('.' + this.constant.noFailsClass).parents('table').addClass(this.constant.filterTableClass);
      $('.' + this.constant.noFailsClass).parents('tr').addClass(this.constant.noFailsClass);
    }

    //create config checkboxes
    if (this.configs) {

      var configDiv = $(document.createElement('div'))
        .addClass(this.constant.configDivClass)
        .insertAfter($('.' + this.constant.localTools)[0])
        .keepOnPage({marginTop: 3});

      for (var i in this.configs) {

        this.configs[i].checkbox = $(document.createElement('input'))
          .attr({type: 'checkbox', id: i})
          .bind('change', function () {
            self.configs[this.id].flag = this.checked;
            self.updateCookie();
            self.filterRows();
          })
          .prependTo($(document.createElement('p'))
            .append($(document.createElement('label')).attr('for', i).html(this.configs[i].label))
            .appendTo(configDiv)
          );
      }

      this.updateFromCookie();
      this.filterRows();
    }
  },

  getTable: function (num) {

    return this.tables[num] = this.tables[num] || new HCTable(this);
  },

  changeLinks: function () {

    var tablesAffected = [];

    for (var i in this.tables) {

      if (
        this.tables[i].selectedIds === false ||  //coz a link in it has been changed
        this.tables[i].selectedIds.length > 0    //coz it has links that need to be changed
      ) {
        tablesAffected.push(this.tables[i]);
      }
    }

    var rid = [];
    for (var i in this.tables) {
      var ridTable = this.tables[i].getSelectedIds();
      if (ridTable != '') {
        rid.push(ridTable);
      }
    }
    rid = rid.join(',');
    for (var i in tablesAffected) {
      tablesAffected[i].changeLinks(rid);
    }
  },

  filterRows: function () {
    var self = this;

    var rowsToHide = [];
    for (var i in this.configs) {
      if (this.configs[i].flag) {
        rowsToHide.push('tr.' + i);
      }
    }

    $('table.' + this.constant.filterTableClass + ' tr').show().data('hidden', false);
    if (rowsToHide.length) {
      $(rowsToHide.join(', ')).hide().data('hidden', true);
    }

    $('table.' + this.constant.filterTableClass + ' tbody').each(function () {

      var classes = self.constant.evenOddClasses.slice(0);
      $('tr', this).each(function () {

        if (!$(this).data('hidden')) {
          classes = classes.reverse();
          $(this).removeClass(classes[0]).addClass(classes[1]);
        }
      });
    });
  },

  cookie: {
    data: {},

    set: function (name, value) {
      this.data[name] = value;

      var ck = [];
      for (var i in this.data) {
        ck.push(i + '-' + this.data[i]);
      }

      Ensembl.cookie.set('hcconfig', ck.join('.'));
    },

    get: function(name) {
      var ck = Ensembl.cookie.get('hcconfig').split('.');
      for (var i in ck) {
        if (ck[i]) {
          var val = ck[i].split('-');
          this.data[val[0]] = val[1];
        }
      }

      return this.data[name];
    }
  },

  updateCookie: function () {
    var j = 2;
    for (var i in this.configs) {
      this.cookie.set(this.configs[i].cookieName, this.configs[i].flag * 1);
    }
  },

  updateFromCookie: function () {

    for (var i in this.configs) {

      this.configs[i].flag = !!parseInt(this.cookie.get(this.configs[i].cookieName));

      if (this.configs[i].checkbox) {
        this.configs[i].checkbox.attr('checked', this.configs[i].flag);
      }
    }

  }
});

function HCTable(manager) {
  var self = this;

  this.manager = manager;
  this.selectors = [];
  this.selectedIds = []; //false if any selection changed - empty array if none selected - array of ids of reports if selected
  this.table = false;

  this.add = function (selector) {

    this.selectors.push(selector);

    if (!this.table) {
      this.table = selector.row.parents('table').first().addClass(this.manager.constant.filterTableClass);
      this.table.prev('h3').append(
        $(document.createElement('a'))
          .attr('href', '#showHide')
          .html('Hide')
          .bind('click', function (e) {
            e.preventDefault();
            this.innerHTML = this.innerHTML == 'Hide' ? 'Show' : 'Hide';
            self.table.toggle();
          })
      );
    }

    selector.table = this;
  };

  this.changeLinks = function(rid) {
    for (var i in this.selectors) {
      this.selectors[i].changeLink(rid);
    }
  };

  this.selectAll = function(flag) {
    for (var i in this.selectors) {
      this.selectors[i].select(flag);
    }
  };

  this.getSelectedIds = function() {
    if (this.selectedIds === false) {
      this.selectedIds = [];
      for (var i in this.selectors) {
        if (this.selectors[i].selected) {
          this.selectedIds.push(this.selectors[i].rid);
        }
      }
    }
    return this.selectedIds.join(',');
  };
}

function HCSelector(manager, a) {
  var self = this;

  this.a = $(a);
  this.manager = manager;
  this.row = this.a.parents('tr').first().addClass(this.a.attr('class'));
  this.manager.getTable(a.rel).add(this); //link it to it's table & vice versa
  this.defaultText = a.innerHTML;
  this.defaultLink = a.href;
  this.selected = false;
  this.link = a.href.split('=')[0];
  this.rid = parseInt(a.href.split('=')[1]);

  this.a1 = $(document.createElement('a'))
    .html('Select')
    .attr({title: 'Select for multi-annotation', href: '#Select'})
    .appendTo(a.parentNode)
    .bind({
      click: function (e) {
        e.preventDefault();
        self.select(!self.selected); //reverse selection
        self.dblclickFlag = self.selected;
        self.table.selectedIds = false;
        self.manager.changeLinks();
      },
      dblclick: function (e) {
        e.preventDefault();
        self.table.selectAll(self.manager.constant.isIE6 ? self.dblclickFlag : !self.selected);
        self.table.selectedIds = false;
        self.manager.changeLinks();
      }
    });

  this.select = function(flag) {
    if (flag && !!this.row.data('hidden')) {
      return;
    }
    this.selected = flag;
    this.a1.html(flag ? 'Deselect' : 'Select');
  };

  this.changeLink = function(rid) {
    this.a.html(this.selected ? 'Multi Annotate' : this.defaultText).attr('href', this.selected ? this.link + '=' + rid : this.defaultLink);
    this.highlight();
  };

  this.highlight = function() {
    $('td', this.row).attr('class', this.selected ? this.manager.constant.hilightedCell : '');
  };
}<|endoftext|>


<commit_before>var m = require('mithril');
var util = require('chessground').util;

function initialize(ctrl, el) {
  var $div = $(el);
  var save = $.fp.debounce(function() {
    var $form = $div.find('form');
    $.ajax({
      url: $form.attr('action'),
      data: $form.serialize(),
      type: 'POST',
      success: function(filter) {
        ctrl.setFilter(filter);
      }
    });
  }, 200);
  $div.find('input').change(save);
  $div.find('button.reset').click(function() {
    $div.find('label input').prop('checked', true).trigger('change');
    $div.find('.rating_range').each(function() {
      var s = $(this);
      s.slider('values', [s.slider('option', 'min'), s.slider('option', 'max')]).trigger('change');
    });
  });
  $div.find('button').click(function() {
    ctrl.toggleFilter();
    m.redraw();
    return false;
  });
  $div.find('.rating_range').each(function() {
    var $this = $(this);
    var $input = $this.find("input");
    var $span = $this.siblings(".range");
    var min = $input.data("min");
    var max = $input.data("max");
    var values = $input.val() ? $input.val().split("-") : [min, max];
    $span.text(values.join(' - '));

    function change() {
      var values = $this.slider('values');
      $input.val(values[0] + "-" + values[1]);
      $span.text(values[0] + " - " + values[1]);
      save();
    }
    $this.slider({
      range: true,
      min: min,
      max: max,
      values: values,
      step: 50,
      slide: change
    }).change(change);
  });
}

module.exports = {
  toggle: function(ctrl, nbFiltered) {
    return m('span', {
      class: 'filter_toggle' + (ctrl.vm.filterOpen ? ' active' : ''),
      onclick: util.partial(ctrl.toggleFilter)
    }, [
      ctrl.vm.filterOpen ? m('span[data-icon=L]') : m('span', {
        class: 'hint--bottom-left',
        'data-hint': ctrl.trans('filterGames'),
      }, m('span[data-icon=%]')),
      nbFiltered > 0 ? m('span.number', nbFiltered) : null
    ]);
  },
  render: function(ctrl) {
    return m('div.hook_filter', {
      config: function(el, isUpdate, ctx) {
        if (ctx.loaded) return;
        $.ajax({
          url: '/setup/filter',
          cache: false,
          success: function(html) {
            el.innerHTML = html;
            ctx.loaded = true;
            initialize(ctrl, el);
          }
        });
      }
    });
  }
};
<commit_msg>fix lobby filter rating range - resolves #207<commit_after>var m = require('mithril');
var util = require('chessground').util;

function initialize(ctrl, el) {
  var $div = $(el);
  var $ratingRange = $div.find('.rating_range');
  var save = $.fp.debounce(function() {
    var $form = $div.find('form');
    $.ajax({
      url: $form.attr('action'),
      data: $form.serialize(),
      type: 'POST',
      success: function(filter) {
        ctrl.setFilter(filter);
      }
    });
  }, 200);
  function changeRatingRange(values) {
    $ratingRange.find('input').val(values[0] + "-" + values[1]);
    $ratingRange.siblings('.range').text(values[0] + " - " + values[1]);
    save();
  }
  $div.find('input').change(save);
  $div.find('button.reset').click(function() {
    $div.find('label input').prop('checked', true).trigger('change');
    $div.find('.rating_range').each(function() {
      var s = $(this);
      var values = [s.slider('option', 'min'), s.slider('option', 'max')];
      s.slider('values', values);
      changeRatingRange(values);
    });
  });
  $div.find('button').click(function() {
    ctrl.toggleFilter();
    m.redraw();
    return false;
  });
  $ratingRange.each(function() {
    var $this = $(this);
    var $input = $this.find("input");
    var $span = $this.siblings(".range");
    var min = $input.data("min");
    var max = $input.data("max");
    var values = $input.val() ? $input.val().split("-") : [min, max];
    $span.text(values.join(' - '));

    $this.slider({
      range: true,
      min: min,
      max: max,
      values: values,
      step: 50,
      slide: function(e, ui) {
        changeRatingRange(ui.values);
      }
    });
  });
}

module.exports = {
  toggle: function(ctrl, nbFiltered) {
    return m('span', {
      class: 'filter_toggle' + (ctrl.vm.filterOpen ? ' active' : ''),
      onclick: util.partial(ctrl.toggleFilter)
    }, [
      ctrl.vm.filterOpen ? m('span[data-icon=L]') : m('span', {
        class: 'hint--bottom-left',
        'data-hint': ctrl.trans('filterGames'),
      }, m('span[data-icon=%]')),
      nbFiltered > 0 ? m('span.number', nbFiltered) : null
    ]);
  },
  render: function(ctrl) {
    return m('div.hook_filter', {
      config: function(el, isUpdate, ctx) {
        if (ctx.loaded) return;
        $.ajax({
          url: '/setup/filter',
          cache: false,
          success: function(html) {
            el.innerHTML = html;
            ctx.loaded = true;
            initialize(ctrl, el);
          }
        });
      }
    });
  }
};
<|endoftext|>


<commit_before>var items = require('../demos').filter(function(d) {
    return !d.norender
})
var template = require('./item.hbs')
var domify = require('domify')

var animate = require('gsap-promise')

var urljoin = require('url-join')
var path = require('path')

function render(item) {
    item.link = item.outfile || (item.folder+'-'+item.name)
    item.url = urljoin('/', path.basename(item.link, '.html')+'.html')
    item.src = source(item)
    return template(item)
}

function append(e, parent) {
    var el = (parent||document.body).appendChild(domify(e))
    return el
}

function source(d) {
    var base = 'https://github.com/mattdesl/frontend-npm-goodies/blob/master/'
    return urljoin(base, d.folder, d.name+'.js')
}

module.exports = function(parent) {
    var elements = items
            .map(render)
            .map( e => append(e, parent) )

    animate.staggerFromTo(elements, 0.5, {
        alpha: 0
    }, {
        alpha: 1.0, delay: 0.1, ease: "easeOutQuad"
    }, 0.03)
}<commit_msg>updating<commit_after>var items = require('../demos').filter(function(d) {
    return !d.norender
})
var template = require('./item.hbs')
var domify = require('domify')

var animate = require('gsap-promise')

var urljoin = require('url-join')
var path = require('path')

function render(item) {
    item.link = item.outfile || (item.folder+'-'+item.name)
    item.url = path.basename(item.link, '.html')+'.html'
    item.src = source(item)
    return template(item)
}

function append(e, parent) {
    var el = (parent||document.body).appendChild(domify(e))
    return el
}

function source(d) {
    var base = 'https://github.com/mattdesl/frontend-npm-goodies/blob/master/'
    return urljoin(base, d.folder, d.name+'.js')
}

module.exports = function(parent) {
    var elements = items
            .map(render)
            .map( e => append(e, parent) )

    animate.staggerFromTo(elements, 0.5, {
        alpha: 0
    }, {
        alpha: 1.0, delay: 0.1, ease: "easeOutQuad"
    }, 0.03)
}<|endoftext|>


<commit_before>
environment = 'node';

var Sugar = require('../../../release/sugar-edge');

// Test suite
require('../../javascripts/setup.js');
require('../../javascripts/date_helper.js');
require('../../javascripts/object_helper.js');

// Tests
require('../sugar/object.js');
require('../sugar/string.js');
require('../sugar/array.js');
require('../sugar/number.js');
require('../sugar/date.js');
require('../sugar/regexp.js');
require('../sugar/function.js');
require('../sugar/es5.js');
require('../sugar/equals.js');
require('../sugar/date_zh_cn.js')
require('../sugar/date_zh_tw.js')
require('../sugar/date_ko.js')
require('../sugar/date_ru.js')
require('../sugar/date_es.js')
require('../sugar/date_pt.js')
require('../sugar/date_fr.js')
require('../sugar/date_it.js')
require('../sugar/date_de.js')
require('../sugar/date_ja.js')
require('../sugar/date_sv.js')
require('../sugar/date_range.js');
require('../sugar/inflections.js');
require('../sugar/language.js');

syncTestsFinished();
<commit_msg>test.js runs from release/<commit_after>
environment = 'node';

var Sugar = require('../../../release/sugar-full.development');

// Test suite
require('../../javascripts/setup.js');
require('../../javascripts/date_helper.js');
require('../../javascripts/object_helper.js');

// Tests
require('../sugar/object.js');
require('../sugar/string.js');
require('../sugar/array.js');
require('../sugar/number.js');
require('../sugar/date.js');
require('../sugar/regexp.js');
require('../sugar/function.js');
require('../sugar/es5.js');
require('../sugar/equals.js');
require('../sugar/date_zh_cn.js')
require('../sugar/date_zh_tw.js')
require('../sugar/date_ko.js')
require('../sugar/date_ru.js')
require('../sugar/date_es.js')
require('../sugar/date_pt.js')
require('../sugar/date_fr.js')
require('../sugar/date_it.js')
require('../sugar/date_de.js')
require('../sugar/date_ja.js')
require('../sugar/date_sv.js')
require('../sugar/date_range.js');
require('../sugar/inflections.js');
require('../sugar/language.js');

syncTestsFinished();
<|endoftext|>


<commit_before>var GridMap = function() {
    this.initHook();
    this.initPaper();
    this.initDispatcher();

    this.updateGeometry();
    this.repaint();

    this.registerEventHandlers();

    this.startX = 10;
    this.startY = 10;
    this.endX = 20;
    this.endY = 10;
    this.queue = [];
    this.interval = 2;
};

GridMap.prototype = {
    // initialize the hook for path-finding algorithms.
    initHook: function() {
        var self = this;

        // add hook on the `set' method of PF.Node
        var orig = PF.Node.prototype.set;
        PF.Node.prototype.set = function() {
            orig.apply(this, arguments);
            self.queue.push([this.x, this.y, arguments]);
        };
    },

    // register the event handlers.
    registerEventHandlers: function() {
        var self = this;

        $('#draw_area').mousedown(function(event) {
            var coord, x, y;
            self.isDrawing = true;

            coord = self.toGridCoordinate(event.pageX, event.pageY);
            x = coord[0]; y = coord[1];

            self.drawStatus = self.grid.isWalkableAt(x, y) ? 'block' : 'clear';

            self.toggleNodeAt(x, y);

        }).mousemove(function(event) {
            var coord, x, y;

            if (!self.isDrawing) {
                return;
            }

            coord = self.toGridCoordinate(event.pageX, event.pageY);
            x = coord[0]; y = coord[1];

            self.toggleNodeAt(x, y);

        }).mouseup(function(event) {
            self.isDrawing = false;
        });
    },

    // initialize the drawing area
    initPaper: function() {
        this.paper = Raphael('draw_area', 0, 0);
        this.gridSize = 30;
    },

    // colorize the node at the given position in the given color
    colorizeNode: function(x, y, color) {
        this.rects[y][x].animate({
            fill: color,
        }, 10);
    },

    toggleNodeAt: function(x, y) {
        if (this.drawStatus == 'block') {
            this.grid.setWalkableAt(x, y, false);
            this.colorizeNode(x, y, 'grey');
        } else {
            this.grid.setWalkableAt(x, y, true);
            this.colorizeNode(x, y, 'white');
        }
    },

    // initialize the dispatcher for path-finding operations
    initDispatcher: function() {
        var colorizeNode,
            drawParent,
            self = this;

        // draw a line pointing from a node to its parent
        drawParent = function(x, y, parentCoord) {
            var path = self.buildSvgPath([[x, y], parentCoord]);
            self.paper.path(path).attr({
                opacity: 0.4,
            });
        };

        // dispatcher for path-finding operations
        this.dispatcher = {
            opened: function(x, y) {
                self.colorizeNode(x, y, '#98fb98');
            },
            closed: function(x, y) {
                self.colorizeNode(x, y, '#afeeee');
            },
            parent: drawParent,
        };
    },

    // convert the page coordinate to grid coordinate
    toGridCoordinate: function(pageX, pageY) {
        var size = this.gridSize;
        return [Math.floor(pageX / size), Math.floor(pageY / size)];
    },

    /**
     * Re-calculate the geometry of the drawing area.
     * This method will be called at initiation and
     * when the window geometry is modified.
     */
    updateGeometry: function() {
        var width, height,
            paperWidth, paperHeight,
            numRows, numCols,
            gridSize = this.gridSize;

        width = $(window).width();
        height = $(window).height();

        numCols = Math.ceil(width / gridSize);
        numRows = Math.ceil(height / gridSize);

        paperWidth = numCols * gridSize;
        paperHeight = numRows * gridSize;

        // update geometry
        this.paper.setSize(paperWidth, paperHeight);

        // update grid
        this.grid = new PF.Grid(numCols, numRows);
    },

    // repaint the grids according to walkability.
    repaint: function() {
        var i, j,
            x, y,
            size = this.gridSize,
            paper = this.paper,
            grid = this.grid,
            rect,
            color,
            rects = [];

        for (i = 0; i < grid.height; ++i) {
            rects[i] = [];

            for (j = 0; j < grid.width; ++j) {
                x = j * size;
                y = i * size;

                color = grid.isWalkableAt(j, i) ? 'white' : 'grey';

                rect = paper.rect(x, y, size, size);
                rect.attr({
                    fill: color,
                    'stroke-opacity': 0.2,
                });
                rects[i][j] = rect;
            }
        }

        this.rects = rects;
    },

    // set the finder for the algorithm.
    setFinder: function(finder) {
        this.finder = finder;
    },

    // start the path-finding procedure.
    start: function() {
        // find the path
        console.time('path-fiding');
        this.path = this.finder.findPath(
            this.startX, this.startY,
            this.endX, this.endY,
            this.grid
        );
        console.timeEnd('path-finding');

        // replay the procedure
        this.replay();
    },

    // replay the path-finding procedure according to
    // the records stored in `this.queue'
    replay: function() {
        var self = this;

        this.timer = setInterval(function() {
            self.step(function() {
                clearInterval(self.timer);
                self.drawPath();
            });
        }, this.interval);

    },

    // step the replay procedure
    step: function(callback) {
        console.log('step');
        var queue, front,
            rects,
            dispatcher,
            func,
            x, y,
            attr, value,

        dispatcher = this.dispatcher;
        rects = this.rects;
        queue = this.queue;

        do {
            if (!queue.length) {
                callback();
                return;
            }
            front = queue.shift();
            x = front[0];
            y = front[1];
            attr = front[2][0];
            value = front[2][1];

            func = dispatcher[attr];
        } while (!func);

        func(x, y, value);
    },

    // draw the path.
    drawPath: function() {
        var path = this.buildSvgPath(this.path);
        this.paper.path(path).attr({
            stroke: 'yellow',
            'stroke-width': 3,
        });
    },

    // given a path, build its SVG represention.
    buildSvgPath: function(path) {
        var i, strs = [], size = this.gridSize;

        strs.push('M' + (path[0][0] * size + size / 2) + ' '
                  + (path[0][1] * size + size / 2));
        for (i = 1; i < path.length; ++i) {
            strs.push('L' + (path[i][0] * size + size / 2) + ' '
                    + (path[i][1] * size + size / 2));
        }

        return strs.join('');
    },
};

var Control = function(gridMap) {
    this.gridMap = gridMap;

    this.initFinderDispatcher();
    this.initUI();
    this.updateGeometry();
};

Control.prototype = {
    initFinderDispatcher: function() {
        this.finderDispatcher = {

        };
    },

    initUI: function() {
        var self = this;

        $('.control_panel').draggable();

        $('#start_button').click(function() {
            self.gridMap.finder = new PF.AStarFinder(PF.AStarFinder.euclidean);
            self.gridMap.start();
        });

        $('.accordion').accordion({
            collapsible: false,
        });
    },

    // update the widgets' geometries on window resize
    updateGeometry: function() {
        var BOTTOM_MARGIN = 40;
        (function($ele) {
            $ele.css('top', $(window).height() - $ele.outerHeight() - BOTTOM_MARGIN + 'px');
        })($('#play_panel'));
    },
}

$(function() {
    var gridMap = new GridMap();
    var control = new Control(gridMap);

    // suppress select events
    $(window).bind('selectstart', function(event) {
        event.preventDefault();
    });

    // update geometry on window resize
    $(window).resize(function() {
        gridMap.updateGeometry();
        control.updateGeometry();
    });
});
<commit_msg>add: zooming effect while toggling node walkability<commit_after>var GridMap = function() {
    this.initHook();
    this.initPaper();
    this.initDispatcher();

    this.registerEventHandlers();

    this.startX = 10;
    this.startY = 10;
    this.endX = 20;
    this.endY = 10;
    this.queue = [];
    this.interval = 2;
};

GridMap.prototype = {
    // initialize the hook for path-finding algorithms.
    initHook: function() {
        var self = this;

        // add hook on the `set' method of PF.Node
        var orig = PF.Node.prototype.set;
        PF.Node.prototype.set = function() {
            orig.apply(this, arguments);
            self.queue.push([this.x, this.y, arguments]);
        };
    },

    // register the event handlers.
    registerEventHandlers: function() {
        var self = this;

        $('#draw_area').mousedown(function(event) {
            var coord, x, y;
            self.isDrawing = true;

            coord = self.toGridCoordinate(event.pageX, event.pageY);
            x = coord[0]; y = coord[1];

            self.drawStatus = self.grid.isWalkableAt(x, y) ? 'block' : 'clear';

            self.toggleNodeAt(x, y);

        }).mousemove(function(event) {
            var coord, x, y;

            if (!self.isDrawing) {
                return;
            }

            coord = self.toGridCoordinate(event.pageX, event.pageY);
            x = coord[0]; y = coord[1];

            self.toggleNodeAt(x, y);

        }).mouseup(function(event) {
            self.isDrawing = false;
        });
    },

    // initialize the drawing area
    initPaper: function() {
        this.paper = Raphael('draw_area', 0, 0);
        this.gridSize = 30;

        this.updateGeometry();
        this.repaint();
    },

    // colorize the node at the given position in the given color
    colorizeNode: function(x, y, color) {
        this.rects[y][x].animate({
            fill: color,
        }, 50);
    },

    toggleNodeAt: function(x, y) {
        if (this.drawStatus == 'block') {
            this.grid.setWalkableAt(x, y, false);
            this.colorizeNode(x, y, 'grey');
        } else {
            this.grid.setWalkableAt(x, y, true);
            this.colorizeNode(x, y, 'white');
        }

        this.zoomNodeAt(x, y);
    },

    zoomNodeAt: function(x, y) {
        var gridSize = this.gridSize,
            rect = this.rects[y][x];
        window.rect = rect;

        rect.toFront().attr({
            transform: 's1.2',
        }).animate({
            transform: 's1.0',
        }, 100)
    },

    // initialize the dispatcher for path-finding operations
    initDispatcher: function() {
        var colorizeNode,
            drawParent,
            self = this;

        // draw a line pointing from a node to its parent
        drawParent = function(x, y, parentCoord) {
            var path = self.buildSvgPath([[x, y], parentCoord]);
            self.paper.path(path).attr({
                opacity: 0.4,
            });
        };

        // dispatcher for path-finding operations
        this.dispatcher = {
            opened: function(x, y) {
                self.colorizeNode(x, y, '#98fb98');
            },
            closed: function(x, y) {
                self.colorizeNode(x, y, '#afeeee');
            },
            parent: drawParent,
        };
    },

    // convert the page coordinate to grid coordinate
    toGridCoordinate: function(pageX, pageY) {
        var size = this.gridSize;
        return [Math.floor(pageX / size), Math.floor(pageY / size)];
    },

    /**
     * Re-calculate the geometry of the drawing area.
     * This method will be called at initiation and
     * when the window geometry is modified.
     */
    updateGeometry: function() {
        var width, height,
            paperWidth, paperHeight,
            numRows, numCols,
            gridSize = this.gridSize;

        width = $(window).width();
        height = $(window).height();

        numCols = Math.ceil(width / gridSize);
        numRows = Math.ceil(height / gridSize);

        paperWidth = numCols * gridSize;
        paperHeight = numRows * gridSize;

        // update geometry
        this.paper.setSize(paperWidth, paperHeight);

        // update grid
        this.grid = new PF.Grid(numCols, numRows);
    },

    // repaint the grids according to walkability.
    repaint: function() {
        var i, j,
            x, y,
            size = this.gridSize,
            paper = this.paper,
            grid = this.grid,
            rect,
            color,
            rects = [];

        for (i = 0; i < grid.height; ++i) {
            rects[i] = [];

            for (j = 0; j < grid.width; ++j) {
                x = j * size;
                y = i * size;

                color = grid.isWalkableAt(j, i) ? 'white' : 'grey';

                rect = paper.rect(x, y, size, size);
                rect.attr({
                    fill: color,
                    'stroke-opacity': 0.2,
                });
                rects[i][j] = rect;
            }
        }

        this.rects = rects;
    },

    // set the finder for the algorithm.
    setFinder: function(finder) {
        this.finder = finder;
    },

    // start the path-finding procedure.
    start: function() {
        // find the path
        console.time('path-fiding');
        this.path = this.finder.findPath(
            this.startX, this.startY,
            this.endX, this.endY,
            this.grid
        );
        console.timeEnd('path-finding');

        // replay the procedure
        this.replay();
    },

    // replay the path-finding procedure according to
    // the records stored in `this.queue'
    replay: function() {
        var self = this;

        this.timer = setInterval(function() {
            self.step(function() {
                clearInterval(self.timer);
                self.drawPath();
            });
        }, this.interval);

    },

    // step the replay procedure
    step: function(callback) {
        console.log('step');
        var queue, front,
            rects,
            dispatcher,
            handler,
            x, y,
            attr, value,

        dispatcher = this.dispatcher;
        rects = this.rects;
        queue = this.queue;

        // take the operation element from the queue.
        // If the operation is not defined in the dispatcher
        // then take the next one, until we find a match or the
        // queue is empty.
        do {
            if (!queue.length) {
                callback();
                return;
            }
            front = queue.shift();
            x = front[0];
            y = front[1];
            attr = front[2][0];
            value = front[2][1];

            handler = dispatcher[attr];
        } while (!handler);

        handler(x, y, value);
    },

    // draw the path.
    drawPath: function() {
        var path = this.buildSvgPath(this.path);
        this.paper.path(path).attr({
            stroke: 'yellow',
            'stroke-width': 3,
        });
    },

    // given a path, build its SVG represention.
    buildSvgPath: function(path) {
        var i, strs = [], size = this.gridSize;

        strs.push('M' + (path[0][0] * size + size / 2) + ' '
                  + (path[0][1] * size + size / 2));
        for (i = 1; i < path.length; ++i) {
            strs.push('L' + (path[i][0] * size + size / 2) + ' '
                    + (path[i][1] * size + size / 2));
        }

        return strs.join('');
    },
};

var Control = function(gridMap) {
    this.gridMap = gridMap;

    this.initFinderDispatcher();
    this.initUI();
};

Control.prototype = {
    initFinderDispatcher: function() {
        this.finderDispatcher = {

        };
    },

    initUI: function() {
        var self = this;

        $('.control_panel').draggable();

        $('#start_button').click(function() {
            self.gridMap.finder = new PF.AStarFinder(PF.AStarFinder.euclidean);
            self.gridMap.start();
        });

        $('.accordion').accordion({
            collapsible: false,
        });

        this.updateGeometry();
    },

    // update the widgets' geometries on window resize
    updateGeometry: function() {
        var BOTTOM_MARGIN = 40;
        (function($ele) {
            $ele.css('top', $(window).height() - $ele.outerHeight() - BOTTOM_MARGIN + 'px');
        })($('#play_panel'));
    },
}

$(function() {
    var gridMap = new GridMap();
    var control = new Control(gridMap);

    // suppress select events
    $(window).bind('selectstart', function(event) {
        event.preventDefault();
    });

    // update geometry on window resize
    $(window).resize(function() {
        gridMap.updateGeometry();
        control.updateGeometry();
    });
});
<|endoftext|>


<commit_before>/* Modernizr 2.8.2 (Custom Build) | MIT & BSD
 * Build: http://modernizr.com/download/#-flexbox-history-inputtypes-localstorage-svg-touch-mq-cssclasses-teststyles-testprop-testallprops-prefixes-domprefixes-cssclassprefix:supports!
 */
;

window.Modernizr = (function( window, document, undefined ) {

  var version = '2.8.2',

      Modernizr = {},

      enableClasses = true,

      docElement = document.documentElement,

      mod = 'modernizr',
      modElem = document.createElement(mod),
      mStyle = modElem.style,

      inputElem  = document.createElement('input')  ,

      smile = ':)',

      toString = {}.toString,

      prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),

      omPrefixes = 'Webkit Moz O ms',

      cssomPrefixes = omPrefixes.split(' '),

      domPrefixes = omPrefixes.toLowerCase().split(' '),

      ns = {'svg': 'http://www.w3.org/2000/svg'},

      tests = {},
      inputs = {},
      attrs = {},

      classes = [],

      slice = classes.slice,

      featureName,

      injectElementWithStyles = function( rule, callback, nodes, testnames ) {

        var style, ret, node, docOverflow,
            div = document.createElement('div'),
            body = document.body,
            fakeBody = body || document.createElement('body');

        if ( parseInt(nodes, 10) ) {
          while ( nodes-- ) {
            node = document.createElement('div');
            node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
            div.appendChild(node);
          }
        }

        style = ['','<style id="s', mod, '">', rule, '</style>'].join('');
        div.id = mod;
        (body ? div : fakeBody).innerHTML += style;
        fakeBody.appendChild(div);
        if ( !body ) {
          fakeBody.style.background = '';
          fakeBody.style.overflow = 'hidden';
          docOverflow = docElement.style.overflow;
          docElement.style.overflow = 'hidden';
          docElement.appendChild(fakeBody);
        }

        ret = callback(div, rule);
        if ( !body ) {
          fakeBody.parentNode.removeChild(fakeBody);
          docElement.style.overflow = docOverflow;
        } else {
          div.parentNode.removeChild(div);
        }

        return !!ret;

      },

      testMediaQuery = function( mq ) {

        var matchMedia = window.matchMedia || window.msMatchMedia;
        if ( matchMedia ) {
          return matchMedia(mq) && matchMedia(mq).matches || false;
        }

        var bool;

        injectElementWithStyles('@media ' + mq + ' { #' + mod + ' { position: absolute; } }', function( node ) {
          bool = (window.getComputedStyle ?
              getComputedStyle(node, null) :
              node.currentStyle)['position'] == 'absolute';
        });

        return bool;

      },
      _hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;

  if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) {
    hasOwnProp = function (object, property) {
      return _hasOwnProperty.call(object, property);
    };
  }
  else {
    hasOwnProp = function (object, property) {
      return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
    };
  }

  if (!Function.prototype.bind) {
    Function.prototype.bind = function bind(that) {

      var target = this;

      if (typeof target != "function") {
        throw new TypeError();
      }

      var args = slice.call(arguments, 1),
          bound = function () {

            if (this instanceof bound) {

              var F = function(){};
              F.prototype = target.prototype;
              var self = new F();

              var result = target.apply(
                  self,
                  args.concat(slice.call(arguments))
              );
              if (Object(result) === result) {
                return result;
              }
              return self;

            } else {

              return target.apply(
                  that,
                  args.concat(slice.call(arguments))
              );

            }

          };

      return bound;
    };
  }

  function setCss( str ) {
    mStyle.cssText = str;
  }

  function setCssAll( str1, str2 ) {
    return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
  }

  function is( obj, type ) {
    return typeof obj === type;
  }

  function contains( str, substr ) {
    return !!~('' + str).indexOf(substr);
  }

  function testProps( props, prefixed ) {
    for ( var i in props ) {
      var prop = props[i];
      if ( !contains(prop, "-") && mStyle[prop] !== undefined ) {
        return prefixed == 'pfx' ? prop : true;
      }
    }
    return false;
  }

  function testDOMProps( props, obj, elem ) {
    for ( var i in props ) {
      var item = obj[props[i]];
      if ( item !== undefined) {

        if (elem === false) return props[i];

        if (is(item, 'function')){
          return item.bind(elem || obj);
        }

        return item;
      }
    }
    return false;
  }

  function testPropsAll( prop, prefixed, elem ) {

    var ucProp  = prop.charAt(0).toUpperCase() + prop.slice(1),
        props   = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');

    if(is(prefixed, "string") || is(prefixed, "undefined")) {
      return testProps(props, prefixed);

    } else {
      props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
      return testDOMProps(props, prefixed, elem);
    }
  }    tests['flexbox'] = function() {
    return testPropsAll('flexWrap');
  };
  tests['touch'] = function() {
    var bool;

    if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
      bool = true;
    } else {
      injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''), function( node ) {
        bool = node.offsetTop === 9;
      });
    }

    return bool;
  };
  tests['history'] = function() {
    return !!(window.history && history.pushState);
  };

  tests['localstorage'] = function() {
    try {
      localStorage.setItem(mod, mod);
      localStorage.removeItem(mod);
      return true;
    } catch(e) {
      return false;
    }
  };

  tests['svg'] = function() {
    return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect;
  };
  function webforms() {
    Modernizr['inputtypes'] = (function(props) {

      for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) {

        inputElem.setAttribute('type', inputElemType = props[i]);
        bool = inputElem.type !== 'text';

        if ( bool ) {

          inputElem.value         = smile;
          inputElem.style.cssText = 'position:absolute;visibility:hidden;';

          if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) {

            docElement.appendChild(inputElem);
            defaultView = document.defaultView;

            bool =  defaultView.getComputedStyle &&
                defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
                (inputElem.offsetHeight !== 0);

            docElement.removeChild(inputElem);

          } else if ( /^(search|tel)$/.test(inputElemType) ){
          } else if ( /^(url|email)$/.test(inputElemType) ) {
            bool = inputElem.checkValidity && inputElem.checkValidity() === false;

          } else {
            bool = inputElem.value != smile;
          }
        }

        inputs[ props[i] ] = !!bool;
      }
      return inputs;
    })('search tel url email datetime date month week time datetime-local number range color'.split(' '));
  }
  for ( var feature in tests ) {
    if ( hasOwnProp(tests, feature) ) {
      featureName  = feature.toLowerCase();
      Modernizr[featureName] = tests[feature]();

      classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
    }
  }

  Modernizr.input || webforms();

  Modernizr.addTest = function ( feature, test ) {
    if ( typeof feature == 'object' ) {
      for ( var key in feature ) {
        if ( hasOwnProp( feature, key ) ) {
          Modernizr.addTest( key, feature[ key ] );
        }
      }
    } else {

      feature = feature.toLowerCase();

      if ( Modernizr[feature] !== undefined ) {
        return Modernizr;
      }

      test = typeof test == 'function' ? test() : test;

      if (typeof enableClasses !== "undefined" && enableClasses) {
        docElement.className+=" supports-" + (test ? '' : 'no-') + feature;
      }
      Modernizr[feature] = test;

    }

    return Modernizr;
  };

  setCss('');
  modElem = inputElem = null;

  Modernizr._version      = version;

  Modernizr._prefixes     = prefixes;
  Modernizr._domPrefixes  = domPrefixes;
  Modernizr._cssomPrefixes  = cssomPrefixes;

  Modernizr.mq            = testMediaQuery;

  Modernizr.testProp      = function(prop){
    return testProps([prop]);
  };

  Modernizr.testAllProps  = testPropsAll;

  Modernizr.testStyles    = injectElementWithStyles;    docElement.className = docElement.className.replace(/(^|\s)no-js(\s|$)/, '$1$2') +

      (enableClasses ? " supports-js supports-"+classes.join(" supports-") : '');

  return Modernizr;

})(this, this.document);
;
<commit_msg>Minify Modernizr script<commit_after>/* Modernizr 2.8.2 (Custom Build) | MIT & BSD
 * Build: http://modernizr.com/download/#-flexbox-history-inputtypes-localstorage-svg-touch-mq-cssclasses-teststyles-testprop-testallprops-prefixes-domprefixes-cssclassprefix:supports!
 */
;window.Modernizr=function(a,b,c){function C(a){j.cssText=a}function D(a,b){return C(n.join(a+";")+(b||""))}function E(a,b){return typeof a===b}function F(a,b){return!!~(""+a).indexOf(b)}function G(a,b){for(var d in a){var e=a[d];if(!F(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function H(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:E(f,"function")?f.bind(d||b):f}return!1}function I(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+p.join(d+" ")+d).split(" ");return E(b,"string")||E(b,"undefined")?G(e,b):(e=(a+" "+q.join(d+" ")+d).split(" "),H(e,b,c))}function J(){e.inputtypes=function(a){for(var d=0,e,f,h,i=a.length;d<i;d++)k.setAttribute("type",f=a[d]),e=k.type!=="text",e&&(k.value=l,k.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(f)&&k.style.WebkitAppearance!==c?(g.appendChild(k),h=b.defaultView,e=h.getComputedStyle&&h.getComputedStyle(k,null).WebkitAppearance!=="textfield"&&k.offsetHeight!==0,g.removeChild(k)):/^(search|tel)$/.test(f)||(/^(url|email)$/.test(f)?e=k.checkValidity&&k.checkValidity()===!1:e=k.value!=l)),t[a[d]]=!!e;return t}("search tel url email datetime date month week time datetime-local number range color".split(" "))}var d="2.8.2",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k=b.createElement("input"),l=":)",m={}.toString,n=" -webkit- -moz- -o- -ms- ".split(" "),o="Webkit Moz O ms",p=o.split(" "),q=o.toLowerCase().split(" "),r={svg:"http://www.w3.org/2000/svg"},s={},t={},u={},v=[],w=v.slice,x,y=function(a,c,d,e){var f,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:h+(d+1),l.appendChild(j);return f=["",'<style id="s',h,'">',a,"</style>"].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},z=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b)&&c(b).matches||!1;var d;return y("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},A={}.hasOwnProperty,B;!E(A,"undefined")&&!E(A.call,"undefined")?B=function(a,b){return A.call(a,b)}:B=function(a,b){return b in a&&E(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=w.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e}),s.flexbox=function(){return I("flexWrap")},s.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:y(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},s.history=function(){return!!a.history&&!!history.pushState},s.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},s.svg=function(){return!!b.createElementNS&&!!b.createElementNS(r.svg,"svg").createSVGRect};for(var K in s)B(s,K)&&(x=K.toLowerCase(),e[x]=s[K](),v.push((e[x]?"":"no-")+x));return e.input||J(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)B(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" supports-"+(b?"":"no-")+a),e[a]=b}return e},C(""),i=k=null,e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=z,e.testProp=function(a){return G([a])},e.testAllProps=I,e.testStyles=y,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" supports-js supports-"+v.join(" supports-"):""),e}(this,this.document);
<|endoftext|>