<commit_before>// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $uibModal service used above.

function ModalInstanceCtrl($scope, $modalInstance, items, ContactList,SettingsByKey,SendVaccineMessages) {
    SettingsByKey.get({key: 'LATE_RNR_NOTIFICATION_EMAIL_TEMPLATE'}, function (data) {
        $scope.email_template = data.settings.value;
    });
    $scope.items = items;
    $scope.show_email = false;
    $scope.contacts = [];
    function loadFacilityContacts() {
        for (i = 0; i < items.length; i++) {
            if (items[i].hascontacts && items[i].checked) {
                var aa = {type: 'email', facilityId: items[i].facility_id};
                ContactList.get(aa, function (aa, i) {

                    return function (data) {
                        var index = aa.facilityId;

                        //$scope.contacts = data.contacts;
                        angular.forEach(data.contacts, function (contact) {
                            $scope.contacts.push(contact);
                        });

                    }
                }(aa, i));
            }
        }
    };

    $scope.itemChecked = function (_index) {
        var value = !$scope.items[_index].checked;
        $scope.items[_index].checked = value;

    };
    $scope.emailForNonReportingFacilities = function () {
        var len = $scope.items.length;
        $scope.show_email = true;
        loadFacilityContacts();

    };
    $scope.getBackGroundColor = function (_index) {
        var bgColor = '';

        if (_index % 2 == 0) {
            bgColor = 'lightGreen';
        } else {
            bgColor = 'white';
        }

        return bgColor;
    };
    $scope.ok = function () {
        $modalInstance.close();
    };

    $scope.cancel = function () {
        $modalInstance.dismiss('cancel');
    };
    $scope.sendVaccineFacilityEmail = function () {

        var messages = constructMessage();

        SendVaccineMessages.post({messages: messages}, function () {
            $scope.sent_confirmation = true;
        });
    };

    var constructMessage = function () {
        // construct the messages here
        var messages = [];

        for (var i = 0; i < $scope.contacts.length; i++) {
            var template =  $scope.email_template;
            var contact = $scope.contacts[i];

            template = template.replace('{name}', contact.name);
            template = template.replace('{facility_name}', "");
            template = template.replace('{period}', "");
            messages.push({
                type: 'email',
                facilityId: "14254",
                contact: contact.contact,
                message: template
            });
        }
        return messages;
    };
}<commit_msg>fix js error<commit_after>// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $uibModal service used above.

function ModalInstanceCtrl($scope, $modalInstance, items, ContactList,SettingsByKey,SendVaccineMessages) {
    SettingsByKey.get({key: 'LATE_RNR_NOTIFICATION_EMAIL_TEMPLATE'}, function (data) {
        $scope.email_template = data.settings.value;
    });
    $scope.items = items;
    $scope.show_email = false;
    $scope.contacts = [];
    var contactsCallBack=function (aa,i) {
        ContactList.get(aa, function (aa, i) {

            return function (data) {
                var index = aa.facilityId;

                //$scope.contacts = data.contacts;
                angular.forEach(data.contacts, function (contact) {
                    $scope.contacts.push(contact);
                });

            };
        }(aa, i));

    };
    function loadFacilityContacts() {
        for (i = 0; i < items.length; i++) {
            if (items[i].hascontacts && items[i].checked) {
                var aa = {type: 'email', facilityId: items[i].facility_id};
                contactsCallBack(aa,i);
            }
        }
    }

    $scope.itemChecked = function (_index) {
        var value = !$scope.items[_index].checked;
        $scope.items[_index].checked = value;

    };
    $scope.emailForNonReportingFacilities = function () {
        var len = $scope.items.length;
        $scope.show_email = true;
        loadFacilityContacts();

    };
    $scope.getBackGroundColor = function (_index) {
        var bgColor = '';

        if (_index % 2 === 0) {
            bgColor = 'lightGreen';
        } else {
            bgColor = 'white';
        }

        return bgColor;
    };
    $scope.ok = function () {
        $modalInstance.close();
    };

    $scope.cancel = function () {
        $modalInstance.dismiss('cancel');
    };
    $scope.sendVaccineFacilityEmail = function () {

        var messages = constructMessage();

        SendVaccineMessages.post({messages: messages}, function () {
            $scope.sent_confirmation = true;
        });
    };

    var constructMessage = function () {
        // construct the messages here
        var messages = [];

        for (var i = 0; i < $scope.contacts.length; i++) {
            var template =  $scope.email_template;
            var contact = $scope.contacts[i];

            template = template.replace('{name}', contact.name);
            template = template.replace('{facility_name}', "");
            template = template.replace('{period}', "");
            messages.push({
                type: 'email',
                facilityId: "14254",
                contact: contact.contact,
                message: template
            });
        }
        return messages;
    };
}<|endoftext|>


<commit_before>"use strict";

angular.module("smlBootzooka.session").factory('UserSessionService', function ($resource, $cookies) {

    var self = this;

    self.userResource = $resource('rest/users/', {}, {
        login: {method: 'POST'},
        valid: {method: 'GET'}
    }, {});

    self.logoutResource = $resource('rest/users/logout', {}, {}, {});

    var userSessionService = {
        loggedUser: null
    };

    userSessionService.isLogged = function () {
        if (userSessionService.loggedUser !== null) {
            return true;

        }
        if (!angular.isUndefined($cookies["scentry.auth.default.user"])) {
            return true;
        }
        return false;
    };

    userSessionService.isNotLogged = function () {
        return !userSessionService.isLogged();
    };

    userSessionService.login = function (user, successFunction, errorFunction) {
        self.userResource.login(angular.toJson(user), function (data) {
            userSessionService.loggedUser = data;
            if (typeof successFunction === "function") {
                successFunction(data);
            }
        }, errorFunction);
    };

    userSessionService.logout = function (successFunction) {
        self.logoutResource.query(null, function (data) {
            userSessionService.loggedUser = null;
            delete $cookies["scentry.auth.default.user"];
            if (typeof successFunction === "function") {
                successFunction(data);
            }
        });
    };

    userSessionService.validate = function (successFunction) {
        self.userResource.valid(function (data) {
            userSessionService.loggedUser = data;
            if (typeof successFunction === "function") {
                successFunction(data);
            }
        });
    };

    userSessionService.getLoggedUserName = function () {
        if (userSessionService.loggedUser) {
            return userSessionService.loggedUser.login;
        } else {
            return "";
        }
    };

    if (userSessionService.loggedUser === null && $cookies["scentry.auth.default.user"] !== null) {
        userSessionService.validate();
    }

    return userSessionService;
});<commit_msg>Phantom login fix removed, since JS unit tests are failing<commit_after>"use strict";

angular.module("smlBootzooka.session").factory('UserSessionService', function ($resource, $cookies) {

    var self = this;

    self.userResource = $resource('rest/users/', {}, {
        login: {method: 'POST'},
        valid: {method: 'GET'}
    }, {});

    self.logoutResource = $resource('rest/users/logout', {}, {}, {});

    var userSessionService = {
        loggedUser: null
    };

    userSessionService.isLogged = function () {
        if (userSessionService.loggedUser !== null) {
            return true;

        }
        if (!angular.isUndefined($cookies["scentry.auth.default.user"])) {
            return true;
        }
        return false;
    };

    userSessionService.isNotLogged = function () {
        return !userSessionService.isLogged();
    };

    userSessionService.login = function (user, successFunction, errorFunction) {
        self.userResource.login(angular.toJson(user), function (data) {
            userSessionService.loggedUser = data;
            if (typeof successFunction === "function") {
                successFunction(data);
            }
        }, errorFunction);
    };

    userSessionService.logout = function (successFunction) {
        self.logoutResource.query(null, function (data) {
            userSessionService.loggedUser = null;
            delete $cookies["scentry.auth.default.user"];
            if (typeof successFunction === "function") {
                successFunction(data);
            }
        });
    };

    userSessionService.validate = function (successFunction) {
        self.userResource.valid(function (data) {
            userSessionService.loggedUser = data;
            if (typeof successFunction === "function") {
                successFunction(data);
            }
        });
    };

    userSessionService.getLoggedUserName = function () {
        if (userSessionService.loggedUser) {
            return userSessionService.loggedUser.login;
        } else {
            return "";
        }
    };

    return userSessionService;
});<|endoftext|>


<commit_before>$(function() {
	// handle opening and closing the menu
	$('#game-selected').click(function() {
		$('#games').toggle();
	});
	// handle switching games
	$('#games li').live('click', function() {
		$('#game-selected').html(this.innerHTML);
		$('#verdict').html('Submit Verdict');
		$('#games').hide();

		loadGame(this.value);
	});
	// handle showing the verdict options
	$('#verdict').click(function() {
		$('#game,#submit').toggle();
		$('#loading').hide();

		if ($('#game').is(':visible')) {
			$('#verdict').html('Submit Verdict');
		} else {
			$('#verdict').html('Show Game');
		}
	});

	// handle showing inventory details
	$('#inventory img').live('click', function() {
		var data = $(this).data('info');
		// TODO replace this alert with a popover div that looks nice
		alert(data.name + "\n" + data.description);
	});
	// handle chat log filters
	$('#chat-filter').change(function() {
		$('#chat').removeClass('only-all hide-enemy hide-allied only-reported').addClass(this.value);
	});
	// handle champonly checkbox
	$('#champ-only').change(function() {
		$('#chat').toggleClass('champ-only');
	});
	// handle refreshing captcha
	$('#refresh-captcha').click(function() {
		// ajax load captcha, then in the callback:
		$('#captcha').attr('src', base64string);
	});
	// handle verdict timer
	var interval, timeLeft = 60;
	interval = window.setInterval(function() {
		if ($('#game').is(':visible')) timeLeft -= 1;
		$('#timer-message time').html(timeLeft);
		if (timeLeft < 1) {
			window.clearInterval(interval);
			$('#timer-message').detach();
		}
	}, 1000);
	// handle submitting a verdict
	$('#pardon,#punish,#skip').click(function(event) {
		event.preventDefault();
		if (timeLeft > 0) {
			alert('Please spend more time reviewing the case');
			return;
		}
		// maybe this should just do a regular form submission?
		// (nope, because we should validate the response from riot and report errors without leaving the page)
	});

	// load the total number of games and populate our game list
	loadCase();
	window.captchaLoaded = false;
	window.captchaIsLoading = false;
});

function reloadCaptcha() {
	if (!window.captchaIsLoading) {
		window.captchaIsLoading = true;
		$.ajax({
			type: 'POST',
			dataType: 'text',
			url: '/ajax.php',
			data: { cmd: 'getCaptcha' },
			success: function(data) {
				$('#captcha').attr('src',data);
				window.captchaIsLoading = false;
			}
		});
	}
}

function loadCase() {
	$('#game,#submit').hide();
	$('#loading').show();

	$.ajax({
		type: 'POST',
		dataType: 'text',
		url: '/ajax.php',
		data: { cmd: 'getCase' },
		success: function (data) {
			var num = Number(data);
			if (num < 1) return alert('Could not get case data from Riot');
			for (var i=1; i<=num; i++) {
				$('

').attr('value',i).html('Case '+i).appendTo('#games');
			}
			loadGame('1');
		}
	});
}

function loadGame(gameNumber) {
	$('#game,#submit').hide();
	$('#loading').show();

	$.ajax({
		type: 'POST',
		dataType: 'json',
		url: '/ajax.php',
		data: { cmd: 'getGame', game: gameNumber },
		success: applyData
	});
}

function applyData(gameData) {
	// if we are loading for the first time, grab a new captcha in the background
	if (!window.captchaLoaded) reloadCaptcha();

	// expand the data into the #game div
	$('#summoner-name').html('"' + gameData.summoner + '"');
	$('#portrait img').attr('src', gameData.champion);

	var stats = gameData.stats[0];
	$('#level').html(stats.LEVEL);
	$('#time').html(stats.TIME_PLAYED + ':00'); //fudge the time because riot only gives minutes
	$('#kills').html(stats.SCORES[0]);
	$('#deaths').html(stats.SCORES[1]);
	$('#assists').html(stats.SCORES[2]);
	$('#outcome').html(stats.WIN);
	$('#creep-score').html(stats.MINIONS_KILLED);
	$('#dps-out').html(stats.TOTAL_DAMAGE_DEALT);
	$('#dps-in').html(stats.TOTAL_DAMAGE_RECEIVED);

	// setup inventory-container
	$('#inventory-container').empty();
	for (var i=0; i<gameData.items.length; i++) {
		var item = gameData.items[i];
		$('')
			.attr('src', item.icon)
			.attr('title', item.name)
			.attr('alt', item.name)
			.data('info', item)
			.appendTo('#inventory-container');
	}

	// add reports
	$('#reports').empty();
	$('#allied-report-count').html(gameData.allied_report_count);
	for (var i=0; i<gameData.allied_report_count; i++) {
		var report = gameData.allycomments[i];
		var reason = gameData.allyreportreasons[i];
		$('

').html(report).append($('

').html(reason)).appendTo('#reports');
	}
	$('#enemy-report-count').html(gameData.enemy_report_count);
	for (var i=0; i<gameData.enemy_report_count; i++) {
		var report = gameData.enemycomments[i];
		var reason = gameData.enemyreportreasons[i];
		$('

').html(report).append($('

').html(reason)).appendTo('#reports');
	}

	// build chat log
	var $chat = $('#chat').removeClass().empty();
	var chatLength = gameData.chatlogtext.length;
	for (var i=0; i<chatLength; i++) {
		var summoner = gameData.chatlogusers[i];
		var champion = gameData.chatlogchampions[i];
		var timestamp = gameData.chatloggametime[i];
		var message = gameData.chatlogtext[i];
		var classes = gameData.chatlogteams[i];
		if (classes === 'reported') classes += ' allied';
		if (gameData.chatlogsentto[i] === 'All') classes += ' all';
		$('

').addClass(classes)
			.append(
				$('')
					.append($('').html(summoner))
					.append($('').html(champion))
			)
			.append($('<time></time>').html(timestamp))
			.append(': '+message)
			.appendTo($chat);
	}

	// reset chat filter controls
	$('#chat-filter')[0].selectedIndex = 0;
	$('#champ-only')[0].checked = false;

	// show our handywork
	$('#loading').hide();
	$('#game').show();
	window.scroll(0,0);
}
<commit_msg>Add an onclick handler to the generated game list so that iOS Safari will make them clickable.<commit_after>$(function() {
	// handle opening and closing the menu
	$('#game-selected').click(function() {
		$('#games').toggle();
	});
	// handle switching games
	$('#games li').live('click', function() {
		$('#game-selected').html(this.innerHTML);
		$('#verdict').html('Submit Verdict');
		$('#games').hide();

		loadGame(this.value);
	});
	// handle showing the verdict options
	$('#verdict').click(function() {
		$('#game,#submit').toggle();
		$('#loading').hide();

		if ($('#game').is(':visible')) {
			$('#verdict').html('Submit Verdict');
		} else {
			$('#verdict').html('Show Game');
		}
	});

	// handle showing inventory details
	$('#inventory img').live('click', function() {
		var data = $(this).data('info');
		// TODO replace this alert with a popover div that looks nice
		alert(data.name + "\n" + data.description);
	});
	// handle chat log filters
	$('#chat-filter').change(function() {
		$('#chat').removeClass('only-all hide-enemy hide-allied only-reported').addClass(this.value);
	});
	// handle champonly checkbox
	$('#champ-only').change(function() {
		$('#chat').toggleClass('champ-only');
	});
	// handle refreshing captcha
	$('#refresh-captcha').click(function() {
		// ajax load captcha, then in the callback:
		$('#captcha').attr('src', base64string);
	});
	// handle verdict timer
	var interval, timeLeft = 60;
	interval = window.setInterval(function() {
		if ($('#game').is(':visible')) timeLeft -= 1;
		$('#timer-message time').html(timeLeft);
		if (timeLeft < 1) {
			window.clearInterval(interval);
			$('#timer-message').detach();
		}
	}, 1000);
	// handle submitting a verdict
	$('#pardon,#punish,#skip').click(function(event) {
		event.preventDefault();
		if (timeLeft > 0) {
			alert('Please spend more time reviewing the case');
			return;
		}
		// maybe this should just do a regular form submission?
		// (nope, because we should validate the response from riot and report errors without leaving the page)
	});

	// load the total number of games and populate our game list
	loadCase();
	window.captchaLoaded = false;
	window.captchaIsLoading = false;
});

function reloadCaptcha() {
	if (!window.captchaIsLoading) {
		window.captchaIsLoading = true;
		$.ajax({
			type: 'POST',
			dataType: 'text',
			url: '/ajax.php',
			data: { cmd: 'getCaptcha' },
			success: function(data) {
				$('#captcha').attr('src',data);
				window.captchaIsLoading = false;
			}
		});
	}
}

function loadCase() {
	$('#game,#submit').hide();
	$('#loading').show();

	$.ajax({
		type: 'POST',
		dataType: 'text',
		url: '/ajax.php',
		data: { cmd: 'getCase' },
		success: function (data) {
			var num = Number(data);
			if (num < 1) return alert('Could not get case data from Riot');
			for (var i=1; i<=num; i++) {
				$('

').attr('value',i).html('Case '+i).appendTo('#games');
			}
			loadGame('1');
		}
	});
}

function loadGame(gameNumber) {
	$('#game,#submit').hide();
	$('#loading').show();

	$.ajax({
		type: 'POST',
		dataType: 'json',
		url: '/ajax.php',
		data: { cmd: 'getGame', game: gameNumber },
		success: applyData
	});
}

function applyData(gameData) {
	// if we are loading for the first time, grab a new captcha in the background
	if (!window.captchaLoaded) reloadCaptcha();

	// expand the data into the #game div
	$('#summoner-name').html('"' + gameData.summoner + '"');
	$('#portrait img').attr('src', gameData.champion);

	var stats = gameData.stats[0];
	$('#level').html(stats.LEVEL);
	$('#time').html(stats.TIME_PLAYED + ':00'); //fudge the time because riot only gives minutes
	$('#kills').html(stats.SCORES[0]);
	$('#deaths').html(stats.SCORES[1]);
	$('#assists').html(stats.SCORES[2]);
	$('#outcome').html(stats.WIN);
	$('#creep-score').html(stats.MINIONS_KILLED);
	$('#dps-out').html(stats.TOTAL_DAMAGE_DEALT);
	$('#dps-in').html(stats.TOTAL_DAMAGE_RECEIVED);

	// setup inventory-container
	$('#inventory-container').empty();
	for (var i=0; i<gameData.items.length; i++) {
		var item = gameData.items[i];
		$('')
			.attr('src', item.icon)
			.attr('title', item.name)
			.attr('alt', item.name)
			.data('info', item)
			.appendTo('#inventory-container');
	}

	// add reports
	$('#reports').empty();
	$('#allied-report-count').html(gameData.allied_report_count);
	for (var i=0; i<gameData.allied_report_count; i++) {
		var report = gameData.allycomments[i];
		var reason = gameData.allyreportreasons[i];
		$('

').html(report).append($('

').html(reason)).appendTo('#reports');
	}
	$('#enemy-report-count').html(gameData.enemy_report_count);
	for (var i=0; i<gameData.enemy_report_count; i++) {
		var report = gameData.enemycomments[i];
		var reason = gameData.enemyreportreasons[i];
		$('

').html(report).append($('

').html(reason)).appendTo('#reports');
	}

	// build chat log
	var $chat = $('#chat').removeClass().empty();
	var chatLength = gameData.chatlogtext.length;
	for (var i=0; i<chatLength; i++) {
		var summoner = gameData.chatlogusers[i];
		var champion = gameData.chatlogchampions[i];
		var timestamp = gameData.chatloggametime[i];
		var message = gameData.chatlogtext[i];
		var classes = gameData.chatlogteams[i];
		if (classes === 'reported') classes += ' allied';
		if (gameData.chatlogsentto[i] === 'All') classes += ' all';
		$('

').addClass(classes)
			.append(
				$('')
					.append($('').html(summoner))
					.append($('').html(champion))
			)
			.append($('<time></time>').html(timestamp))
			.append(': '+message)
			.appendTo($chat);
	}

	// reset chat filter controls
	$('#chat-filter')[0].selectedIndex = 0;
	$('#champ-only')[0].checked = false;

	// show our handywork
	$('#loading').hide();
	$('#game').show();
	window.scroll(0,0);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2013 - present Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, version 3 of the License.
 *
 * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

// manage groups is for the add_group_category dialog
import ready from '@instructure/ready'
import Assignment from '@canvas/assignments/backbone/models/Assignment.coffee'
import EditHeaderView from './backbone/views/EditHeaderView.coffee'
import EditView from './backbone/views/EditView.coffee'
import SectionCollection from '@canvas/sections/backbone/collections/SectionCollection'
import DueDateList from '@canvas/due-dates/backbone/models/DueDateList'
import DueDateOverride from '@canvas/due-dates'
import AssignmentGroupSelector from '@canvas/assignments/backbone/views/AssignmentGroupSelector.coffee'
import GradingTypeSelector from '@canvas/assignments/backbone/views/GradingTypeSelector.coffee'
import GroupCategorySelector from '@canvas/groups/backbone/views/GroupCategorySelector.coffee'
import PeerReviewsSelector from '@canvas/assignments/backbone/views/PeerReviewsSelector.coffee'
import '@canvas/grading-standards'
import LockManager from '@canvas/blueprint-courses/react/components/LockManager/index'

const lockManager = new LockManager()
lockManager.init({itemType: 'assignment', page: 'edit'})
const lockedItems = lockManager.isChildContent() ? lockManager.getItemLocks() : {}

ENV.ASSIGNMENT.assignment_overrides = ENV.ASSIGNMENT_OVERRIDES

const userIsAdmin = ENV.current_user_roles.includes('admin')

const assignment = new Assignment(ENV.ASSIGNMENT)
assignment.urlRoot = ENV.URL_ROOT

const sectionList = new SectionCollection(ENV.SECTION_LIST)
const dueDateList = new DueDateList(assignment.get('assignment_overrides'), sectionList, assignment)

const assignmentGroupSelector = new AssignmentGroupSelector({
  parentModel: assignment,
  assignmentGroups:
    (typeof ENV !== 'undefined' && ENV !== null ? ENV.ASSIGNMENT_GROUPS : undefined) || []
})
const gradingTypeSelector = new GradingTypeSelector({
  parentModel: assignment,
  preventNotGraded: assignment.submissionTypesFrozen(),
  lockedItems
})
const groupCategorySelector = new GroupCategorySelector({
  parentModel: assignment,
  groupCategories:
    (typeof ENV !== 'undefined' && ENV !== null ? ENV.GROUP_CATEGORIES : undefined) || [],
  inClosedGradingPeriod: assignment.inClosedGradingPeriod()
})
const peerReviewsSelector = new PeerReviewsSelector({
  parentModel: assignment
})

const editView = new EditView({
  el: '#edit_assignment_form',
  model: assignment,
  assignmentGroupSelector,
  gradingTypeSelector,
  groupCategorySelector,
  peerReviewsSelector,
  views: {
    'js-assignment-overrides': new DueDateOverride({
      model: dueDateList,
      views: {},
      postToSIS: assignment.postToSIS(),
      dueDatesReadonly: !!lockedItems.due_dates,
      availabilityDatesReadonly: !!lockedItems.availability_dates
    })
  },
  lockedItems: assignment.id ? lockedItems : {} // if no id, creating a new assignment
})

const editHeaderView = new EditHeaderView({
  el: '#edit_assignment_header',
  model: assignment,
  userIsAdmin,
  views: {
    edit_assignment_form: editView
  }
})

ready(() => {
  editHeaderView.render()
})
<commit_msg>fix assignment edit dom-ready initialization<commit_after>/*
 * Copyright (C) 2013 - present Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, version 3 of the License.
 *
 * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

// manage groups is for the add_group_category dialog
import ready from '@instructure/ready'
import Assignment from '@canvas/assignments/backbone/models/Assignment.coffee'
import EditHeaderView from './backbone/views/EditHeaderView.coffee'
import EditView from './backbone/views/EditView.coffee'
import SectionCollection from '@canvas/sections/backbone/collections/SectionCollection'
import DueDateList from '@canvas/due-dates/backbone/models/DueDateList'
import DueDateOverride from '@canvas/due-dates'
import AssignmentGroupSelector from '@canvas/assignments/backbone/views/AssignmentGroupSelector.coffee'
import GradingTypeSelector from '@canvas/assignments/backbone/views/GradingTypeSelector.coffee'
import GroupCategorySelector from '@canvas/groups/backbone/views/GroupCategorySelector.coffee'
import PeerReviewsSelector from '@canvas/assignments/backbone/views/PeerReviewsSelector.coffee'
import '@canvas/grading-standards'
import LockManager from '@canvas/blueprint-courses/react/components/LockManager/index'

ready(() => {
  const lockManager = new LockManager()
  lockManager.init({itemType: 'assignment', page: 'edit'})
  const lockedItems = lockManager.isChildContent() ? lockManager.getItemLocks() : {}

  ENV.ASSIGNMENT.assignment_overrides = ENV.ASSIGNMENT_OVERRIDES

  const userIsAdmin = ENV.current_user_roles.includes('admin')

  const assignment = new Assignment(ENV.ASSIGNMENT)
  assignment.urlRoot = ENV.URL_ROOT

  const sectionList = new SectionCollection(ENV.SECTION_LIST)
  const dueDateList = new DueDateList(
    assignment.get('assignment_overrides'),
    sectionList,
    assignment
  )

  const assignmentGroupSelector = new AssignmentGroupSelector({
    parentModel: assignment,
    assignmentGroups:
      (typeof ENV !== 'undefined' && ENV !== null ? ENV.ASSIGNMENT_GROUPS : undefined) || []
  })
  const gradingTypeSelector = new GradingTypeSelector({
    parentModel: assignment,
    preventNotGraded: assignment.submissionTypesFrozen(),
    lockedItems
  })
  const groupCategorySelector = new GroupCategorySelector({
    parentModel: assignment,
    groupCategories:
      (typeof ENV !== 'undefined' && ENV !== null ? ENV.GROUP_CATEGORIES : undefined) || [],
    inClosedGradingPeriod: assignment.inClosedGradingPeriod()
  })
  const peerReviewsSelector = new PeerReviewsSelector({
    parentModel: assignment
  })

  const editView = new EditView({
    el: '#edit_assignment_form',
    model: assignment,
    assignmentGroupSelector,
    gradingTypeSelector,
    groupCategorySelector,
    peerReviewsSelector,
    views: {
      'js-assignment-overrides': new DueDateOverride({
        model: dueDateList,
        views: {},
        postToSIS: assignment.postToSIS(),
        dueDatesReadonly: !!lockedItems.due_dates,
        availabilityDatesReadonly: !!lockedItems.availability_dates
      })
    },
    lockedItems: assignment.id ? lockedItems : {} // if no id, creating a new assignment
  })

  const editHeaderView = new EditHeaderView({
    el: '#edit_assignment_header',
    model: assignment,
    userIsAdmin,
    views: {
      edit_assignment_form: editView
    }
  })
  editHeaderView.render()
})
<|endoftext|>


<commit_before>// Module dependencies
var express = require('express'),
    routes = require('./routes'),
    http = require('http'),
    path = require('path');

var app = express();

// Configurations
app.configure(function(){
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.cookieParser('secret'));
  app.use(express.session());
  app.use(function(req, res, next) {
    res.locals.session = req.session;
    next();
  });

  app.use(app.router);
  app.use(require('less-middleware')({src: __dirname + '/public'}));
  app.use(express.static(path.join(__dirname, 'public')));
});

app.configure('development', function(){
  app.use(express.errorHandler());
});

// Routes
app.get('/', routes.index);
app.get('/oauth', routes.oauth);
app.get('/oauth_callback', routes.oauth_callback);
app.get('/clear', routes.clear);

// Run
http.createServer(app).listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});
<commit_msg>Fixed less-middleware and jade deprecated options<commit_after>// Module dependencies
var express = require('express'),
    routes = require('./routes'),
    http = require('http'),
    path = require('path');

var app = express();

// Configurations
app.configure(function(){
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.cookieParser('secret'));
  app.use(express.session());
  app.use(function(req, res, next) {
    res.locals.session = req.session;
    next();
  });

  app.use(app.router);
  app.use(require('less-middleware')(path.join(__dirname, '/public')));
  app.use(express.static(path.join(__dirname, 'public')));
});

app.configure('development', function(){
  app.use(express.errorHandler());
});

// Routes
app.get('/', routes.index);
app.get('/oauth', routes.oauth);
app.get('/oauth_callback', routes.oauth_callback);
app.get('/clear', routes.clear);

// Run
http.createServer(app).listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});
<|endoftext|>


<commit_before>/**
 * jQuery.browser.mobile (http://detectmobilebrowser.com/)
 *
 * jQuery.browser.mobile will be true if the browser is a mobile device
 *
 **/
(function(a){jQuery.browser.mobile=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))})(navigator.userAgent||navigator.vendor||window.opera);
<commit_msg>Update document for 0.1.2<commit_after><|endoftext|>


<commit_before>var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

var playerInfoList = [];

$(document).ready(function(){
  $('[id^="player-"]').each(function() {

    var height = $(this).data('height') ? $(this).data('height') : 390,
        width = $(this).data('width') ? $(this).data('width') : 640,
        ytKey = $(this).attr('id').replace('player-', '');

    playerInfoList.push({
      id: $(this).attr('id'),
      height: height,
      width: $(this).data('width'),
      videoId: ytKey,
      videoTitle: getVideoTitle(ytKey)
    });
  });

});

function getVideoTitle(vID) {
  var result = '';

  $.ajax({
    url: '//gdata.youtube.com/feeds/api/videos/' + vID + '?v=2&alt=json',
    async: false,
    success:function(data) {
      result = data.entry.title.$t;
    }
  });

  return result;
}

function onYouTubeIframeAPIReady() {
  if(typeof playerInfoList === 'undefined') {
    return;
  }
  for(var i = 0; i < playerInfoList.length;i++) {
    var curplayer = createPlayer(playerInfoList[i]);
  }
}
function createPlayer(playerInfo) {
  return new YT.Player('player-' + playerInfo.videoId, {
    height: playerInfo.height,
    width: playerInfo.width,
    videoId: playerInfo.videoId,
    events: {
      'onStateChange': onPlayerStateChange
    }
  });
}
function onPlayerStateChange(event) {
  var curId = $(event.target.c).attr('id'),
      curTitle,
      curEventData;

  for(var i = 0; i < playerInfoList.length; i++) {
    if (curId === playerInfoList[i].id) {
      curTitle = playerInfoList[i].videoTitle;
    }
  }

  if (event.data === -1) {
    curEventData = 'Unstarted';
  } else if (event.data === 0) {
    curEventData = 'Ended';
  } else if (event.data === 1) {
    curEventData = 'Playing';
  } else if (event.data === 2) {
    curEventData = 'Paused';
  } else if (event.data === 3) {
    curEventData = 'Buffering';
  } else if (event.data === 5) {
    curEventData = 'Video cued';
  }

  console.log('send, event, Videos, ' + curTitle + ', ' + curEventData + ' (' + event.data + '), ' + parseInt(event.target.getCurrentTime()) );
  //ga('send', 'event', 'Videos', curTitle, curEventData + ' (' + event.data + ')', parseInt(event.target.getCurrentTime()) );
}
<commit_msg>Updated script with tracking<commit_after>var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

var playerInfoList = [];

$(document).ready(function(){
  $('[id^="player-"]').each(function() {

    var height = $(this).data('height') ? $(this).data('height') : 390,
        width = $(this).data('width') ? $(this).data('width') : 640,
        ytKey = $(this).attr('id').replace('player-', '');

    playerInfoList.push({
      id: $(this).attr('id'),
      height: height,
      width: $(this).data('width'),
      videoId: ytKey,
      videoTitle: getVideoTitle(ytKey)
    });
  });
});

function getVideoTitle(vID) {
  var result = '';

  $.ajax({
      url: '//gdata.youtube.com/feeds/api/videos/' + vID + '?v=2&alt=json',
      async: false
  }).done(function (data) {
      result = data.entry.title.$t;
  });

  return result;
}

function onYouTubeIframeAPIReady() {
  if(typeof playerInfoList === 'undefined') {
    return;
  }
  for(var i = 0; i < playerInfoList.length;i++) {
    var curplayer = createPlayer(playerInfoList[i]);
  }
}
function createPlayer(playerInfo) {
  return new YT.Player('player-' + playerInfo.videoId, {
    height: playerInfo.height,
    width: playerInfo.width,
    videoId: playerInfo.videoId,
    events: {
      'onStateChange': onPlayerStateChange
    }
  });
}

var curId,
    curTitle,
    curEventData,
    videoTimer;

function onPlayerStateChange(event) {
  curId = $(event.target.c).attr('id');

  for(var i = 0; i < playerInfoList.length; i++) {
    if (curId === playerInfoList[i].id) {
      curTitle = playerInfoList[i].videoTitle;
    }
  }

    if (event.data === -1) {
      curEventData = 'Unstarted';
    } else if (event.data === 0) {
      curEventData = 'Ended';
    } else if (event.data === 1) {
      curEventData = 'Playing';
    } else if (event.data === 2) {
      clearTimeout(videoTimer);

      videoTimer = setTimeout(function() {
        pausedState(event, event.target.getCurrentTime());
      }, 2000);
    } else if (event.data === 3) {
      curEventData = 'Buffering';
    } else if (event.data === 5) {
      curEventData = 'Video cued';
    }

    if (event.data !== 2) {
      pushTrack(event.data, event.target.getCurrentTime());
    }
}

function pushTrack(videoState, videoCurTime) {
  console.log('send, event, Videos, ' + curTitle + ', ' + curEventData + ' (' + videoState + '), ' + parseInt(videoCurTime) );
  //ga('send', 'event', 'Videos', curTitle, curEventData + ' (' + event.data + ')', parseInt(event.target.getCurrentTime()) );
}

function pausedState(videoState, videoCurTime) {
  if (videoState.data === 2) {
    curEventData = 'Paused';
    pushTrack(videoState.data, videoCurTime);
  }
}
<|endoftext|>


<commit_before>// Copyright 2017 The TIE Author, s. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Question data for Unknown Alphabet.
 */

globalData.questions['findAlphabet'] = {  // eslint-disable-line dot-notation
  title: 'Unknown Alphabet',
  starterCode: {
    python:
`def findAlphabet(words):
    return ""`
  },
  auxiliaryCode: {
    python:
`class AuxiliaryCode(object):
  @classmethod
  def failsOnNoSolution(cls, words):
    """
      The dictionary 'edges' stores pairs of characters in which the second character
      has higher rank than the first one. These pairs can be represented as
      a graph's edges. 'edges[ch]' is a list of letters that have higher rank than
      ch's rank. The dictionary 'degree' stores the in-degree in the graph of each letter.
      For each letter 'ch', there are 'degree[ch]' letters which point to ch.
    """
    edges = {}
    degree = {}
    for word in words:
      for ch in word:
        ch = ch.lower()
        if(not edges.has_key(ch)):
          edges[ch] = []
          degree[ch] = 0
    for wordIndex in range(len(words) - 1):
      for letterIndex in range(min(len(words[wordIndex]), len(words[wordIndex + 1]))):
        letterOne = words[wordIndex][letterIndex].lower()
        letterTwo = words[wordIndex + 1][letterIndex].lower()
        if(letterOne != letterTwo):
          edges[letterOne].append(letterTwo)
          degree[letterTwo] = degree[letterTwo] + 1
          break
    answer  = ""
    hasZeroDegreeLetter = True
    while hasZeroDegreeLetter:
      hasZeroDegreeLetter = False
      for key in degree:
        if degree[key] == 0:
          hasZeroDegreeLetter = True
          answer = answer + key
          for nextLetter in edges[key]:
            degree[nextLetter] = degree[nextLetter] - 1
          del degree[key]
      if not hasZeroDegreeLetter:
        break
    return answer

  @classmethod
  def failsOnUppercase(cls, words):
    edges = {}
    degree = {}
    for word in words:
      for ch in word:
        if(not edges.has_key(ch)):
          edges[ch] = []
          degree[ch] = 0
    for wordIndex in range(len(words) - 1):
      for letterIndex in range(min(len(words[wordIndex]), len(words[wordIndex + 1]))):
        letterOne = words[wordIndex][letterIndex]
        letterTwo = words[wordIndex + 1][letterIndex]
        if letterOne != letterTwo:
          edges[letterOne].append(letterTwo)
          degree[letterTwo] = degree[letterTwo] + 1
          break
    answer  = ""
    hasZeroDegreeLetter = True
    while hasZeroDegreeLetter:
      hasZeroDegreeLetter = False
      for key in degree:
        if degree[key] == 0:
          hasZeroDegreeLetter = True
          answer = answer + key
          for nextLetter in edges[key]:
            degree[nextLetter] = degree[nextLetter] - 1
          del degree[key]
      if not hasZeroDegreeLetter:
        break
    if degree:
      return ""
    return answer
`

  },
  tasks: [{
    instructions: [
      {
        content: [
          'Given a dictionary (a list of words in lexicographic order) of all',
          'words in an unknown or invented language, write a function ',
          'findAlphabet that returns the alphabet (an alphabetically sorted ',
          'list of characters) of that language.'
        ].join(''),
        type: 'text'
      },
      {
        content: 'Input: ["art", "rat", "cat", "car"]\nOutput: "atrc"',
        type: 'code'
      }
    ],
    prerequisiteSkills: ['Topological Sorting', 'String Manipulation'],
    acquiredSkills: ['String Manipulation'],
    inputFunctionName: null,
    outputFunctionName: null,
    mainFunctionName: 'findAlphabet',
    correctnessTests: [{
      input: [
        "a",
        "ab",
        "b"
      ],
      allowedOutputs: ['ab']
    }, {
      input: [
        "aaec",
        "aaed",
        "aac",
        "abe",
        "abc",
        "bed",
        "bea",
        "bcc",
        "bcd"
      ],
      allowedOutputs: ['ecdab']
    }, {
      input: [
        "egdi",
        "egdb",
        "egej",
        "egei",
        "ebjj",
        "ebjg",
        "ebgh",
        "ebgj",
        "igac",
        "igae",
        "igia",
        "igif",
        "idcf",
        "idcc",
        "idh"
      ],
      allowedOutputs: ['afchjgdeib']
    },
    {
      input: [
        "curwfe",
        "curwfe",
        "curwst",
        "curwsw",
        "curuyc",
        "curuyf",
        "curuga",
        "curugs",
        "cuxdeh",
        "cuxdeu",
        "cuxdbv",
        "cuxdbn",
        "cuxolc",
        "cuxolb",
        "cuxojd",
        "cuxojs",
        "cpcnow",
        "cpcnob",
        "cpcnqu",
        "cpcnqp",
        "cpctkj",
        "cpctkd",
        "cpctfg",
        "cpctfa",
        "cpbjeq",
        "cpbjec",
        "cpbjz",
        "cpbhx",
        "cpbhc",
        "khjzs",
        "khjzu",
        "khjis",
        "khjiv",
        "khfax",
        "khfay",
        "khftg",
        "khftq",
        "kmima",
        "kmimd",
        "kmiej",
        "kmies",
        "kmrbm",
        "kmrbr",
        "kmrus",
        "kmrut"
      ],
      allowedOutputs: ['ljhmezirxygadoqckfsvntwbup']
    }],
    buggyOutputTests: [],
    performanceTests: []
  }, {
    instructions: [
      {
        content: [
          'Next, make sure your code handles unexpected cases, such as a test ',
          'case with no solution or a test case with more than ',
          'one correct answer.'
        ].join(''),
        type: 'text'
      },
      {
        content: [
          'For the test case that has no solution, just return "". If ',
          'multiple letters have the same frequency, return them in ',
          'alphabetical order.'
        ].join(''),
        type: 'text'
      },
      {
        content: 'Input: [a, b, a]\nOutput: ""\nInput: [cba]\nOutput: "abc"',
        type: 'code'
      }
    ],
    prerequisiteSkills: ['Topological Sorting', 'String Manipulation'],
    acquiredSkills: ['String Manipulation'],
    inputFunctionName: null,
    outputFunctionName: null,
    mainFunctionName: 'findAlphabet',
    correctnessTests: [{
      input: [
        "a",
        "b",
        "a"
      ],
      allowedOutputs: ['']
    }, {
      input: [
        "c",
        "a",
        "b",
        "a"
      ],
      allowedOutputs: ['']
    }, {
      input: [
        "cab",
        "bc"
      ],
      allowedOutputs: ['acb']
    }],
    buggyOutputTests: [{
      buggyFunctionName: 'AuxiliaryCode.failsOnNoSolution',
      messages: [
        [
          'Try running your function on ["c", "a", "b", "a"] on paper. ',
          'Is your result what you expect?'
        ].join(''),
        [
          'For the case ["c", "a", "b", "a"], your code returns "c", even ',
          'though "a" appears both before and after "b". It should ',
          'return no solution.'
        ].join('')
      ]
    }],
    performanceTests: []
  }, {
    instructions: [
      {
        content: [
          'Finally, modify your code to handle strings with a mix of ',
          'lowercase and uppercase letters. Assume that a lowercase and ',
          'uppercase version of a letter is the same with regards to ',
          'lexicographic ordering. Your answer, though, should be lowercase.'
        ].join(''),
        type: 'text'
      },
      {
        content: 'Input: ["b", "Ba"]\nOutput: "ab"',
        type: 'code'
      }
    ],
    prerequisiteSkills: ['Topological Sorting', 'String Manipulation'],
    acquiredSkills: ['String Manipulation'],
    inputFunctionName: null,
    outputFunctionName: null,
    mainFunctionName: 'findAlphabet',
    correctnessTests: [{
      input: [
        "ab",
        "Aba",
        "b"
      ],
      allowedOutputs: ['ab']
    }],
    buggyOutputTests: [{
      buggyFunctionName: 'AuxiliaryCode.failsOnUppercase',
      messages: [
        [
          'Try running your code over ["a", "Ab", "b"]. Do you get the result ',
          'you expected?'
        ].join(''),
        'How does your code handle uppercase letters?',
        [
          'The answer to the test case ["a", "Ab", "b"] should be "ab". It ',
          'looks like you returned a string with some uppercase letters.'
        ].join('')
      ]
    }],
    // TODO: Time complexity is O(m), which is non-linear. Fix in the future.
    performanceTests: []
  }],
  styleTests: [{
    evaluationFunctionName: 'allowOnlyOneFunction',
    expectedOutput: true,
    message: [
      'You should only be writing code in an findAlphabet function. While ',
      "decomposition is generally a good idea, you shouldn't need more than ",
      'just this function for this question.'
    ].join('')
  }]
};
<commit_msg>Address issue #253. (#254)<commit_after>// Copyright 2017 The TIE Author, s. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Question data for Unknown Alphabet.
 */

globalData.questions['findAlphabet'] = {  // eslint-disable-line dot-notation
  title: 'Unknown Alphabet',
  starterCode: {
    python:
`def findAlphabet(words):
    return ""`
  },
  auxiliaryCode: {
    python:
`class AuxiliaryCode(object):
  @classmethod
  def failsOnNoSolution(cls, words):
    """
      The dictionary 'edges' stores pairs of characters in which the second character
      has higher rank than the first one. These pairs can be represented as
      a graph's edges. 'edges[ch]' is a list of letters that have higher rank than
      ch's rank. The dictionary 'degree' stores the in-degree in the graph of each letter.
      For each letter 'ch', there are 'degree[ch]' letters which point to ch.
    """
    edges = {}
    degree = {}
    for word in words:
      for ch in word:
        ch = ch.lower()
        if(not edges.has_key(ch)):
          edges[ch] = []
          degree[ch] = 0
    for wordIndex in range(len(words) - 1):
      for letterIndex in range(min(len(words[wordIndex]), len(words[wordIndex + 1]))):
        letterOne = words[wordIndex][letterIndex].lower()
        letterTwo = words[wordIndex + 1][letterIndex].lower()
        if(letterOne != letterTwo):
          edges[letterOne].append(letterTwo)
          degree[letterTwo] = degree[letterTwo] + 1
          break
    answer  = ""
    hasZeroDegreeLetter = True
    while hasZeroDegreeLetter:
      hasZeroDegreeLetter = False
      for key in degree:
        if degree[key] == 0:
          hasZeroDegreeLetter = True
          answer = answer + key
          for nextLetter in edges[key]:
            degree[nextLetter] = degree[nextLetter] - 1
          del degree[key]
      if not hasZeroDegreeLetter:
        break
    return answer

  @classmethod
  def failsOnUppercase(cls, words):
    edges = {}
    degree = {}
    for word in words:
      for ch in word:
        if(not edges.has_key(ch)):
          edges[ch] = []
          degree[ch] = 0
    for wordIndex in range(len(words) - 1):
      for letterIndex in range(min(len(words[wordIndex]), len(words[wordIndex + 1]))):
        letterOne = words[wordIndex][letterIndex]
        letterTwo = words[wordIndex + 1][letterIndex]
        if letterOne != letterTwo:
          edges[letterOne].append(letterTwo)
          degree[letterTwo] = degree[letterTwo] + 1
          break
    answer  = ""
    hasZeroDegreeLetter = True
    while hasZeroDegreeLetter:
      hasZeroDegreeLetter = False
      for key in degree:
        if degree[key] == 0:
          hasZeroDegreeLetter = True
          answer = answer + key
          for nextLetter in edges[key]:
            degree[nextLetter] = degree[nextLetter] - 1
          del degree[key]
      if not hasZeroDegreeLetter:
        break
    if degree:
      return ""
    return answer
`

  },
  tasks: [{
    instructions: [
      {
        content: [
          'Given a dictionary (a list of words in lexicographic order) of all',
          'words in an unknown or invented language, write a function ',
          'findAlphabet that returns the alphabet (an alphabetically sorted ',
          'list of characters) of that language.'
        ].join(''),
        type: 'text'
      },
      {
        content: 'Input: ["art", "rat", "cat", "car"]\nOutput: "atrc"',
        type: 'code'
      }
    ],
    prerequisiteSkills: ['Topological Sorting', 'String Manipulation'],
    acquiredSkills: ['String Manipulation'],
    inputFunctionName: null,
    outputFunctionName: null,
    mainFunctionName: 'findAlphabet',
    correctnessTests: [{
      input: [
        "a",
        "ab",
        "b"
      ],
      allowedOutputs: ['ab']
    }, {
      input: [
        "aaec",
        "aaed",
        "aac",
        "abe",
        "abc",
        "bed",
        "bea",
        "bcc",
        "bcd"
      ],
      allowedOutputs: ['ecdab']
    }, {
      input: [
        "egdi",
        "egdb",
        "egej",
        "egei",
        "ebjj",
        "ebjg",
        "ebgh",
        "ebgj",
        "igac",
        "igae",
        "igia",
        "igif",
        "idcf",
        "idcc",
        "idh"
      ],
      allowedOutputs: ['afchjgdeib']
    },
    {
      input: [
        "curwfe",
        "curwfe",
        "curwst",
        "curwsw",
        "curuyc",
        "curuyf",
        "curuga",
        "curugs",
        "cuxdeh",
        "cuxdeu",
        "cuxdbv",
        "cuxdbn",
        "cuxolc",
        "cuxolb",
        "cuxojd",
        "cuxojs",
        "cpcnow",
        "cpcnob",
        "cpcnqu",
        "cpcnqp",
        "cpctkj",
        "cpctkd",
        "cpctfg",
        "cpctfa",
        "cpbjeq",
        "cpbjec",
        "cpbjz",
        "cpbhx",
        "cpbhc",
        "khjzs",
        "khjzu",
        "khjis",
        "khjiv",
        "khfax",
        "khfay",
        "khftg",
        "khftq",
        "kmima",
        "kmimd",
        "kmiej",
        "kmies",
        "kmrbm",
        "kmrbr",
        "kmrus",
        "kmrut"
      ],
      allowedOutputs: ['ljhmezirxygadoqckfsvntwbup']
    }],
    buggyOutputTests: [],
    performanceTests: []
  }, {
    instructions: [
      {
        content: [
          'Next, make sure your code handles unexpected cases, such as a test ',
          'case with no solution or a test case with more than ',
          'one correct answer.'
        ].join(''),
        type: 'text'
      },
      {
        content: [
          'If the test case has no solution, return "". If there is not ',
          'enough information to order multiple characters, return them in ',
          'standard alphabetical order.'
        ].join(''),
        type: 'text'
      },
      {
        content: 'Input: [a, b, a]\nOutput: ""\nInput: [cba]\nOutput: "abc"',
        type: 'code'
      }
    ],
    prerequisiteSkills: ['Topological Sorting', 'String Manipulation'],
    acquiredSkills: ['String Manipulation'],
    inputFunctionName: null,
    outputFunctionName: null,
    mainFunctionName: 'findAlphabet',
    correctnessTests: [{
      input: [
        "a",
        "b",
        "a"
      ],
      allowedOutputs: ['']
    }, {
      input: [
        "c",
        "a",
        "b",
        "a"
      ],
      allowedOutputs: ['']
    }, {
      input: [
        "cab",
        "bc"
      ],
      allowedOutputs: ['acb']
    }],
    buggyOutputTests: [{
      buggyFunctionName: 'AuxiliaryCode.failsOnNoSolution',
      messages: [
        [
          'Try running your function on ["c", "a", "b", "a"] on paper. ',
          'Is your result what you expect?'
        ].join(''),
        [
          'For the case ["c", "a", "b", "a"], your code returns "c", even ',
          'though "a" appears both before and after "b". It should ',
          'return no solution.'
        ].join('')
      ]
    }],
    performanceTests: []
  }, {
    instructions: [
      {
        content: [
          'Finally, modify your code to handle strings with a mix of ',
          'lowercase and uppercase letters. Assume that a lowercase and ',
          'uppercase version of a letter is the same with regards to ',
          'lexicographic ordering. Your answer, though, should be lowercase.'
        ].join(''),
        type: 'text'
      },
      {
        content: 'Input: ["b", "Ba"]\nOutput: "ab"',
        type: 'code'
      }
    ],
    prerequisiteSkills: ['Topological Sorting', 'String Manipulation'],
    acquiredSkills: ['String Manipulation'],
    inputFunctionName: null,
    outputFunctionName: null,
    mainFunctionName: 'findAlphabet',
    correctnessTests: [{
      input: [
        "ab",
        "Aba",
        "b"
      ],
      allowedOutputs: ['ab']
    }],
    buggyOutputTests: [{
      buggyFunctionName: 'AuxiliaryCode.failsOnUppercase',
      messages: [
        [
          'Try running your code over ["a", "Ab", "b"]. Do you get the result ',
          'you expected?'
        ].join(''),
        'How does your code handle uppercase letters?',
        [
          'The answer to the test case ["a", "Ab", "b"] should be "ab". It ',
          'looks like you returned a string with some uppercase letters.'
        ].join('')
      ]
    }],
    // TODO: Time complexity is O(m), which is non-linear. Fix in the future.
    performanceTests: []
  }],
  styleTests: [{
    evaluationFunctionName: 'allowOnlyOneFunction',
    expectedOutput: true,
    message: [
      'You should only be writing code in an findAlphabet function. While ',
      "decomposition is generally a good idea, you shouldn't need more than ",
      'just this function for this question.'
    ].join('')
  }]
};
<|endoftext|>


<commit_before>import React, {PropTypes} from 'react';
import FlashMessages from 'shared/components/FlashMessages';

export const HostsPage = React.createClass({
  propTypes: {
    dataNodes: PropTypes.arrayOf(React.PropTypes.object),
  },

  render() {
    const {dataNodes} = this.props;

    return (

                Hosts

                        Hostname
                        Status
                        CPU
                        Load
                        Apps

                      {
                        dataNodes.map(({name, id}) => {
                          return (

                              <a href={`/host/${id}`}>{name}
                              UP
                              98%
                              1.12
                              influxdb, ntp, system

                          );
                        })
                      }

    );
  },

});

export default FlashMessages(HostsPage);
<commit_msg>make host link more restful<commit_after>import React, {PropTypes} from 'react';
import FlashMessages from 'shared/components/FlashMessages';

export const HostsPage = React.createClass({
  propTypes: {
    dataNodes: PropTypes.arrayOf(React.PropTypes.object),
  },

  render() {
    const {dataNodes} = this.props;

    return (

                Hosts

                        Hostname
                        Status
                        CPU
                        Load
                        Apps

                      {
                        dataNodes.map(({name, id}) => {
                          return (

                              <a href={`/hosts/${id}`}>{name}
                              UP
                              98%
                              1.12
                              influxdb, ntp, system

                          );
                        })
                      }

    );
  },

});

export default FlashMessages(HostsPage);
<|endoftext|>


<commit_before>import { mainLizmap, mainEventDispatcher } from '../modules/Globals.js';

import Feature from 'ol/Feature';

import Point from 'ol/geom/Point';
import LineString from 'ol/geom/LineString';
import Polygon from 'ol/geom/Polygon';

import GeoJSON from 'ol/format/GeoJSON';
import GPX from 'ol/format/GPX';
import KML from 'ol/format/KML';

export default class Digitizing {

    constructor() {

        this._tools = ['deactivate', 'point', 'line', 'polygon', 'box', 'circle', 'freehand'];
        this._toolSelected = this._tools[0];

        // Set draw color to value in local storage if any or default (red)
        this._drawColor = localStorage.getItem('drawColor') || '#ff0000';

        this._featureDrawnVisibility = true;

        this._isEdited = false;

        // Draw tools style
        const drawStyle = new OpenLayers.Style({
            pointRadius: 7,
            fillColor: this._drawColor,
            fillOpacity: 0.2,
            strokeColor: this._drawColor,
            strokeOpacity: 1,
            strokeWidth: 2
        });

        const drawStyleTemp = new OpenLayers.Style({
            pointRadius: 7,
            fillColor: this._drawColor,
            fillOpacity: 0.3,
            strokeColor: this._drawColor,
            strokeOpacity: 1,
            strokeWidth: 3
        });

        const drawStyleSelect = new OpenLayers.Style({
            pointRadius: 7,
            fillColor: 'blue',
            fillOpacity: 0.3,
            strokeColor: 'blue',
            strokeOpacity: 1,
            strokeWidth: 3
        });

        const drawStyleMap = new OpenLayers.StyleMap({
            'default': drawStyle,
            'temporary': drawStyleTemp,
            'select': drawStyleSelect
        });

        this._drawLayer = new OpenLayers.Layer.Vector(
            'drawLayer', {
                styleMap: drawStyleMap
            }
        );

        this._drawLayer.events.on({
            'featureadded': () => {
                // Save features drawn in localStorage
                this.saveFeatureDrawn();

                mainEventDispatcher.dispatch('digitizing.featureDrawn');
            }
        });

        mainLizmap.lizmap3.map.addLayer(this._drawLayer);

        // Disable getFeatureInfo when drawing with clicks
        const drawAndGetFeatureInfoMutuallyExclusive = (event) => {
            if (lizMap.controls.hasOwnProperty('featureInfo') && lizMap.controls.featureInfo){
                if (event.type === 'activate' && lizMap.controls.featureInfo.active) {
                    lizMap.controls.featureInfo.deactivate();
                }
                else if (event.type === 'deactivate' && !lizMap.controls.featureInfo.active) {
                    lizMap.controls.featureInfo.activate();
                }
            }
        };

        /**
         * Point
         * @type @new;OpenLayers.Control.DrawFeature
         */
        this._drawPointLayerCtrl = new OpenLayers.Control.DrawFeature(
            this._drawLayer,
            OpenLayers.Handler.Point,
            {
                styleMap: drawStyleMap,
                eventListeners: {
                    'activate': drawAndGetFeatureInfoMutuallyExclusive,
                    'deactivate': drawAndGetFeatureInfoMutuallyExclusive
                }
            }
        );

        /**
         * Line
         * @type @new;OpenLayers.Control.DrawFeature
         */
        this._drawLineLayerCtrl = new OpenLayers.Control.DrawFeature(
            this._drawLayer,
            OpenLayers.Handler.Path,
            {
                styleMap: drawStyleMap,
                eventListeners: {
                    'activate': drawAndGetFeatureInfoMutuallyExclusive,
                    'deactivate': drawAndGetFeatureInfoMutuallyExclusive
                }
            }
        );

        /**
         * Polygon
         * @type @new;OpenLayers.Control.DrawFeature
         */
        this._drawPolygonLayerCtrl = new OpenLayers.Control.DrawFeature(
            this._drawLayer,
            OpenLayers.Handler.Polygon,
            {
                styleMap: drawStyleMap,
                eventListeners: {
                    'activate': drawAndGetFeatureInfoMutuallyExclusive,
                    'deactivate': drawAndGetFeatureInfoMutuallyExclusive
                }
            }
        );

        /**
         * Box
         * @type @new;OpenLayers.Control.DrawFeature
         */
        this._drawBoxLayerCtrl = new OpenLayers.Control.DrawFeature(this._drawLayer,
            OpenLayers.Handler.RegularPolygon,
            { handlerOptions: { sides: 4, irregular: true }}
        );

        /**
         * Circle
         * @type @new;OpenLayers.Control.DrawFeature
         */
        this._drawCircleLayerCtrl = new OpenLayers.Control.DrawFeature(this._drawLayer,
            OpenLayers.Handler.RegularPolygon,
            { handlerOptions: { sides: 40 } }
        );

        /**
         * Freehand
         * @type @new;OpenLayers.Control.DrawFeature
         */
        this._drawFreehandLayerCtrl = new OpenLayers.Control.DrawFeature(this._drawLayer,
            OpenLayers.Handler.Polygon, {
            styleMap: drawStyleMap,
            handlerOptions: { freehand: true }
        });

        this._drawCtrls = [this._drawPointLayerCtrl, this._drawLineLayerCtrl, this._drawPolygonLayerCtrl, this._drawBoxLayerCtrl, this._drawCircleLayerCtrl, this._drawFreehandLayerCtrl];

        this._editCtrl = new OpenLayers.Control.ModifyFeature(this._drawLayer);

        // Add draw and modification controls to map
        mainLizmap.lizmap3.map.addControls(this._drawCtrls);
        mainLizmap.lizmap3.map.addControl(this._editCtrl);

        // Display saved feature if any
        this.savedFeatureDrawnToMap();
    }

    get drawLayer(){
        return this._drawLayer;
    }

    get toolSelected() {
        return this._toolSelected;
    }

    set toolSelected(tool) {
        if (this._tools.includes(tool)) {
            // Disable all tools
            for (const drawControl of this._drawCtrls) {
                drawControl.deactivate();
            }

            // If current selected tool is selected again => unactivate
            if(this._toolSelected === tool){
                this._toolSelected = this._tools[0];
            }else{
                switch (tool) {
                    case this._tools[1]:
                        this._drawPointLayerCtrl.activate();
                        break;
                    case this._tools[2]:
                        this._drawLineLayerCtrl.activate();
                        break;
                    case this._tools[3]:
                        this._drawPolygonLayerCtrl.activate();
                        break;
                    case this._tools[4]:
                        this._drawBoxLayerCtrl.activate();
                        break;
                    case this._tools[5]:
                        this._drawCircleLayerCtrl.activate();
                        break;
                    case this._tools[6]:
                        this._drawFreehandLayerCtrl.activate();
                        break;
                }

                this._toolSelected = tool;
            }

            // Disable edition when tool changes
            if (this._toolSelected !== this._tools[0]){
                this.isEdited = false;
            }

            mainEventDispatcher.dispatch('digitizing.toolSelected');
        }
    }

    get drawColor(){
        return this._drawColor;
    }

    set drawColor(color){
        this._drawColor = color;

        // Update default and temporary draw styles
        const drawStyles = this._drawLayer.styleMap.styles;

        drawStyles.default.defaultStyle.fillColor = color;
        drawStyles.default.defaultStyle.strokeColor = color;

        drawStyles.temporary.defaultStyle.fillColor = color;
        drawStyles.temporary.defaultStyle.strokeColor = color;

        mainEventDispatcher.dispatch('digitizing.drawColor');
    }

    get featureDrawn() {
        if (this._drawLayer.features.length){
            return this._drawLayer.features;
        }
        return null;
    }

    get featureDrawnVisibility() {
        return this._featureDrawnVisibility;
    }

    get featureDrawnSLD() {
        if(this.featureDrawn){
            const style = this.featureDrawn.layer.styleMap.styles.default.defaultStyle;
            let symbolizer = '';
            let strokeAndFill =     `<Stroke>
                                        <SvgParameter name="stroke">${style.strokeColor}</SvgParameter>
                                        <SvgParameter name="stroke-opacity">${style.strokeOpacity}</SvgParameter>
                                        <SvgParameter name="stroke-width">${style.strokeWidth}</SvgParameter>
                                    </Stroke>
                                    <Fill>
                                        <SvgParameter name="fill">${style.fillColor}</SvgParameter>
                                        <SvgParameter name="fill-opacity">${style.fillOpacity}</SvgParameter>
                                    </Fill>`;

            // We consider LINESTRING and POLYGON together currently
            if (this.featureDrawn.geometry.CLASS_NAME === 'OpenLayers.Geometry.Point'){
                symbolizer = `<PointSymbolizer>
                                <Graphic>
                                    <Mark>
                                        <WellKnownName>circle</WellKnownName>
                                        ${strokeAndFill}
                                    </Mark>
                                    <Size>${2 * style.pointRadius}</Size>
                                </Graphic>
                            </PointSymbolizer>`;

            }else{
                symbolizer =    `<PolygonSymbolizer>
                                    ${strokeAndFill}
                                </PolygonSymbolizer>`;

            }
            return `<?xml version="1.0" encoding="UTF-8"?>
                    <StyledLayerDescriptor xmlns="http://www.opengis.net/sld"
                        xmlns:ogc="http://www.opengis.net/ogc"
                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1.0"
                        xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd"
                        xmlns:se="http://www.opengis.net/se">
                        <UserStyle>
                            <FeatureTypeStyle>
                                <Rule>
                                    ${symbolizer}
                                </Rule>
                            </FeatureTypeStyle>
                        </UserStyle>
                    </StyledLayerDescriptor>`;
        }
        return null;
    }

    get isEdited() {
        return this._isEdited;
    }

    set isEdited(edited) {
        if(this._isEdited !== edited){
            this._isEdited = edited;

            if (this._isEdited) {
                this._editCtrl.activate();
                this.toolSelected = 'deactivate';
            } else {
                this._editCtrl.deactivate();
                this.saveFeatureDrawn();
            }

            mainEventDispatcher.dispatch('digitizing.edit');
        }
    }

    toggleFeatureDrawnVisibility() {
        this._featureDrawnVisibility = !this._featureDrawnVisibility;

        this._drawLayer.setVisibility(this._featureDrawnVisibility);

        mainEventDispatcher.dispatch('digitizing.featureDrawnVisibility');
    }

    toggleEdit() {
        this.isEdited = !this.isEdited;
    }

    erase() {
        this._drawLayer.destroyFeatures();

        localStorage.removeItem('drawLayer');

        this.isEdited = false;

        mainEventDispatcher.dispatch('digitizing.erase');
    }

    saveFeatureDrawn() {
        const formatWKT = new OpenLayers.Format.WKT();

        // Save features in WKT format
        if (this.featureDrawn){
            localStorage.setItem('drawLayer', formatWKT.write(this.featureDrawn));
        }

        // Save color
        localStorage.setItem('drawColor', this._drawColor);
    }

    savedFeatureDrawnToMap() {
        const formatWKT = new OpenLayers.Format.WKT();

        const drawLayerWKT = localStorage.getItem('drawLayer');

        if (drawLayerWKT){
            this._drawLayer.addFeatures(formatWKT.read(drawLayerWKT));
            this._drawLayer.redraw(true);
        }
    }

    download(format){
        if (this.featureDrawn){
            // Create OL6 feature with OL2 feature coordinates
            const featureGeometry = this.featureDrawn.geometry;
            let OL6feature;

            if (featureGeometry.CLASS_NAME === 'OpenLayers.Geometry.Point'){
                OL6feature = new Feature(new Point([featureGeometry.x, featureGeometry.y]));
            }
            else if (featureGeometry.CLASS_NAME === 'OpenLayers.Geometry.LineString'){
                let coordinates = [];
                for (const component of featureGeometry.components) {
                    coordinates.push([component.x, component.y]);
                }
                OL6feature = new Feature(new LineString(coordinates));
            }
            else if (featureGeometry.CLASS_NAME === 'OpenLayers.Geometry.Polygon'){
                let coordinates = [];
                for (const component of featureGeometry.components[0].components) {
                    coordinates.push([component.x, component.y]);
                }
                OL6feature = new Feature(new Polygon([coordinates]));
            }

            // Reproject to EPSG:4326
            OL6feature.getGeometry().transform(mainLizmap.projection, 'EPSG:4326');

            if(format === 'geojson'){
                const geoJSON = (new GeoJSON()).writeFeature(OL6feature);

                this._downloadString(geoJSON, 'application/geo+json', 'export.geojson');
            }
            else if(format === 'gpx'){
                const gpx = (new GPX()).writeFeatures([OL6feature]);

                this._downloadString(gpx, 'application/gpx+xml', 'export.gpx');
            } else if (format === 'kml') {
                const kml = (new KML()).writeFeatures([OL6feature]);

                this._downloadString(kml, 'application/vnd.google-earth.kml+xml', 'export.kml');
            }
        }
    }

    _downloadString(text, fileType, fileName) {
        var blob = new Blob([text], { type: fileType });

        var a = document.createElement('a');
        a.download = fileName;
        a.href = URL.createObjectURL(blob);
        a.dataset.downloadurl = [fileType, a.download, a.href].join(':');
        a.style.display = "none";
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        setTimeout(function () { URL.revokeObjectURL(a.href); }, 1500);
    }

    import(file){
        const reader = new FileReader();

        reader.onload = ((aThis) => {
            return (e) => {
                const fileContent = e.target.result;
                let OL6feature;

                // Handle GeoJSON, GPX or KML strings
                try {
                    if (fileContent[0] === '{') {
                        OL6feature = (new GeoJSON()).readFeatures(fileContent);
                    } else if (fileContent.slice(0, 4) === '<gpx') {
                        OL6feature = (new GPX()).readFeatures(fileContent);

                    } else if (fileContent.slice(0, 4) === '<kml') {
                        OL6feature = (new KML()).readFeatures(fileContent);
                    }
                } catch (error) {
                    lizMap.addMessage(error, 'error', true)
                }

                if (OL6feature){
                    // Erase previous feature
                    aThis.erase();

                    // If there are multiple features we only take the first and inform user
                    if(OL6feature.length > 1){
                        lizMap.addMessage(lizDict['digitizing.import.inform.singleFeature'], 'info', true)
                    }

                    // Draw loaded feature
                    const importedGeom = OL6feature[0].getGeometry();
                    const importedGeomType = importedGeom.getType();

                    // Convert from EPSG:4326 to current projection
                    importedGeom.transform('EPSG:4326', mainLizmap.projection);
                    const importedGeomCoordinates = importedGeom.getCoordinates();

                    const importedGeomAsArrayOfPoints = [];
                    let geomToDraw;

                    if (importedGeomType === 'Point') {
                        geomToDraw = new OpenLayers.Geometry.Point(importedGeomCoordinates[0], importedGeomCoordinates[1]);
                    }else if (importedGeomType === 'LineString'){
                        for (const coordinate of importedGeomCoordinates) {
                            importedGeomAsArrayOfPoints.push(new OpenLayers.Geometry.Point(coordinate[0], coordinate[1]));
                        }

                        geomToDraw = new OpenLayers.Geometry.LineString(importedGeomAsArrayOfPoints);
                    } else if (importedGeomType === 'Polygon') {
                        for (const coordinate of importedGeomCoordinates[0]) {
                            importedGeomAsArrayOfPoints.push(new OpenLayers.Geometry.Point(coordinate[0], coordinate[1]));
                        }

                        geomToDraw = new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(importedGeomAsArrayOfPoints)]);
                    }

                    if(geomToDraw){
                        this._drawLayer.addFeatures(new OpenLayers.Feature.Vector(geomToDraw));
                        this._drawLayer.redraw(true);
                    }
                }
            };
        })(this);

        reader.readAsText(file);
    }
}
<commit_msg>Digitizing. Download multiple geometries<commit_after>import { mainLizmap, mainEventDispatcher } from '../modules/Globals.js';

import Feature from 'ol/Feature';

import Point from 'ol/geom/Point';
import LineString from 'ol/geom/LineString';
import Polygon from 'ol/geom/Polygon';

import GeoJSON from 'ol/format/GeoJSON';
import GPX from 'ol/format/GPX';
import KML from 'ol/format/KML';

export default class Digitizing {

    constructor() {

        this._tools = ['deactivate', 'point', 'line', 'polygon', 'box', 'circle', 'freehand'];
        this._toolSelected = this._tools[0];

        // Set draw color to value in local storage if any or default (red)
        this._drawColor = localStorage.getItem('drawColor') || '#ff0000';

        this._featureDrawnVisibility = true;

        this._isEdited = false;

        // Draw tools style
        const drawStyle = new OpenLayers.Style({
            pointRadius: 7,
            fillColor: this._drawColor,
            fillOpacity: 0.2,
            strokeColor: this._drawColor,
            strokeOpacity: 1,
            strokeWidth: 2
        });

        const drawStyleTemp = new OpenLayers.Style({
            pointRadius: 7,
            fillColor: this._drawColor,
            fillOpacity: 0.3,
            strokeColor: this._drawColor,
            strokeOpacity: 1,
            strokeWidth: 3
        });

        const drawStyleSelect = new OpenLayers.Style({
            pointRadius: 7,
            fillColor: 'blue',
            fillOpacity: 0.3,
            strokeColor: 'blue',
            strokeOpacity: 1,
            strokeWidth: 3
        });

        const drawStyleMap = new OpenLayers.StyleMap({
            'default': drawStyle,
            'temporary': drawStyleTemp,
            'select': drawStyleSelect
        });

        this._drawLayer = new OpenLayers.Layer.Vector(
            'drawLayer', {
                styleMap: drawStyleMap
            }
        );

        this._drawLayer.events.on({
            'featureadded': () => {
                // Save features drawn in localStorage
                this.saveFeatureDrawn();

                mainEventDispatcher.dispatch('digitizing.featureDrawn');
            }
        });

        mainLizmap.lizmap3.map.addLayer(this._drawLayer);

        // Disable getFeatureInfo when drawing with clicks
        const drawAndGetFeatureInfoMutuallyExclusive = (event) => {
            if (lizMap.controls.hasOwnProperty('featureInfo') && lizMap.controls.featureInfo){
                if (event.type === 'activate' && lizMap.controls.featureInfo.active) {
                    lizMap.controls.featureInfo.deactivate();
                }
                else if (event.type === 'deactivate' && !lizMap.controls.featureInfo.active) {
                    lizMap.controls.featureInfo.activate();
                }
            }
        };

        /**
         * Point
         * @type @new;OpenLayers.Control.DrawFeature
         */
        this._drawPointLayerCtrl = new OpenLayers.Control.DrawFeature(
            this._drawLayer,
            OpenLayers.Handler.Point,
            {
                styleMap: drawStyleMap,
                eventListeners: {
                    'activate': drawAndGetFeatureInfoMutuallyExclusive,
                    'deactivate': drawAndGetFeatureInfoMutuallyExclusive
                }
            }
        );

        /**
         * Line
         * @type @new;OpenLayers.Control.DrawFeature
         */
        this._drawLineLayerCtrl = new OpenLayers.Control.DrawFeature(
            this._drawLayer,
            OpenLayers.Handler.Path,
            {
                styleMap: drawStyleMap,
                eventListeners: {
                    'activate': drawAndGetFeatureInfoMutuallyExclusive,
                    'deactivate': drawAndGetFeatureInfoMutuallyExclusive
                }
            }
        );

        /**
         * Polygon
         * @type @new;OpenLayers.Control.DrawFeature
         */
        this._drawPolygonLayerCtrl = new OpenLayers.Control.DrawFeature(
            this._drawLayer,
            OpenLayers.Handler.Polygon,
            {
                styleMap: drawStyleMap,
                eventListeners: {
                    'activate': drawAndGetFeatureInfoMutuallyExclusive,
                    'deactivate': drawAndGetFeatureInfoMutuallyExclusive
                }
            }
        );

        /**
         * Box
         * @type @new;OpenLayers.Control.DrawFeature
         */
        this._drawBoxLayerCtrl = new OpenLayers.Control.DrawFeature(this._drawLayer,
            OpenLayers.Handler.RegularPolygon,
            { handlerOptions: { sides: 4, irregular: true }}
        );

        /**
         * Circle
         * @type @new;OpenLayers.Control.DrawFeature
         */
        this._drawCircleLayerCtrl = new OpenLayers.Control.DrawFeature(this._drawLayer,
            OpenLayers.Handler.RegularPolygon,
            { handlerOptions: { sides: 40 } }
        );

        /**
         * Freehand
         * @type @new;OpenLayers.Control.DrawFeature
         */
        this._drawFreehandLayerCtrl = new OpenLayers.Control.DrawFeature(this._drawLayer,
            OpenLayers.Handler.Polygon, {
            styleMap: drawStyleMap,
            handlerOptions: { freehand: true }
        });

        this._drawCtrls = [this._drawPointLayerCtrl, this._drawLineLayerCtrl, this._drawPolygonLayerCtrl, this._drawBoxLayerCtrl, this._drawCircleLayerCtrl, this._drawFreehandLayerCtrl];

        this._editCtrl = new OpenLayers.Control.ModifyFeature(this._drawLayer);

        // Add draw and modification controls to map
        mainLizmap.lizmap3.map.addControls(this._drawCtrls);
        mainLizmap.lizmap3.map.addControl(this._editCtrl);

        // Display saved feature if any
        this.savedFeatureDrawnToMap();
    }

    get drawLayer(){
        return this._drawLayer;
    }

    get toolSelected() {
        return this._toolSelected;
    }

    set toolSelected(tool) {
        if (this._tools.includes(tool)) {
            // Disable all tools
            for (const drawControl of this._drawCtrls) {
                drawControl.deactivate();
            }

            // If current selected tool is selected again => unactivate
            if(this._toolSelected === tool){
                this._toolSelected = this._tools[0];
            }else{
                switch (tool) {
                    case this._tools[1]:
                        this._drawPointLayerCtrl.activate();
                        break;
                    case this._tools[2]:
                        this._drawLineLayerCtrl.activate();
                        break;
                    case this._tools[3]:
                        this._drawPolygonLayerCtrl.activate();
                        break;
                    case this._tools[4]:
                        this._drawBoxLayerCtrl.activate();
                        break;
                    case this._tools[5]:
                        this._drawCircleLayerCtrl.activate();
                        break;
                    case this._tools[6]:
                        this._drawFreehandLayerCtrl.activate();
                        break;
                }

                this._toolSelected = tool;
            }

            // Disable edition when tool changes
            if (this._toolSelected !== this._tools[0]){
                this.isEdited = false;
            }

            mainEventDispatcher.dispatch('digitizing.toolSelected');
        }
    }

    get drawColor(){
        return this._drawColor;
    }

    set drawColor(color){
        this._drawColor = color;

        // Update default and temporary draw styles
        const drawStyles = this._drawLayer.styleMap.styles;

        drawStyles.default.defaultStyle.fillColor = color;
        drawStyles.default.defaultStyle.strokeColor = color;

        drawStyles.temporary.defaultStyle.fillColor = color;
        drawStyles.temporary.defaultStyle.strokeColor = color;

        mainEventDispatcher.dispatch('digitizing.drawColor');
    }

    get featureDrawn() {
        if (this._drawLayer.features.length){
            return this._drawLayer.features;
        }
        return null;
    }

    get featureDrawnVisibility() {
        return this._featureDrawnVisibility;
    }

    get featureDrawnSLD() {
        if(this.featureDrawn){
            const style = this.featureDrawn.layer.styleMap.styles.default.defaultStyle;
            let symbolizer = '';
            let strokeAndFill =     `<Stroke>
                                        <SvgParameter name="stroke">${style.strokeColor}</SvgParameter>
                                        <SvgParameter name="stroke-opacity">${style.strokeOpacity}</SvgParameter>
                                        <SvgParameter name="stroke-width">${style.strokeWidth}</SvgParameter>
                                    </Stroke>
                                    <Fill>
                                        <SvgParameter name="fill">${style.fillColor}</SvgParameter>
                                        <SvgParameter name="fill-opacity">${style.fillOpacity}</SvgParameter>
                                    </Fill>`;

            // We consider LINESTRING and POLYGON together currently
            if (this.featureDrawn.geometry.CLASS_NAME === 'OpenLayers.Geometry.Point'){
                symbolizer = `<PointSymbolizer>
                                <Graphic>
                                    <Mark>
                                        <WellKnownName>circle</WellKnownName>
                                        ${strokeAndFill}
                                    </Mark>
                                    <Size>${2 * style.pointRadius}</Size>
                                </Graphic>
                            </PointSymbolizer>`;

            }else{
                symbolizer =    `<PolygonSymbolizer>
                                    ${strokeAndFill}
                                </PolygonSymbolizer>`;

            }
            return `<?xml version="1.0" encoding="UTF-8"?>
                    <StyledLayerDescriptor xmlns="http://www.opengis.net/sld"
                        xmlns:ogc="http://www.opengis.net/ogc"
                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1.0"
                        xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd"
                        xmlns:se="http://www.opengis.net/se">
                        <UserStyle>
                            <FeatureTypeStyle>
                                <Rule>
                                    ${symbolizer}
                                </Rule>
                            </FeatureTypeStyle>
                        </UserStyle>
                    </StyledLayerDescriptor>`;
        }
        return null;
    }

    get isEdited() {
        return this._isEdited;
    }

    set isEdited(edited) {
        if(this._isEdited !== edited){
            this._isEdited = edited;

            if (this._isEdited) {
                this._editCtrl.activate();
                this.toolSelected = 'deactivate';
            } else {
                this._editCtrl.deactivate();
                this.saveFeatureDrawn();
            }

            mainEventDispatcher.dispatch('digitizing.edit');
        }
    }

    toggleFeatureDrawnVisibility() {
        this._featureDrawnVisibility = !this._featureDrawnVisibility;

        this._drawLayer.setVisibility(this._featureDrawnVisibility);

        mainEventDispatcher.dispatch('digitizing.featureDrawnVisibility');
    }

    toggleEdit() {
        this.isEdited = !this.isEdited;
    }

    erase() {
        this._drawLayer.destroyFeatures();

        localStorage.removeItem('drawLayer');

        this.isEdited = false;

        mainEventDispatcher.dispatch('digitizing.erase');
    }

    saveFeatureDrawn() {
        const formatWKT = new OpenLayers.Format.WKT();

        // Save features in WKT format
        if (this.featureDrawn){
            localStorage.setItem('drawLayer', formatWKT.write(this.featureDrawn));
        }

        // Save color
        localStorage.setItem('drawColor', this._drawColor);
    }

    savedFeatureDrawnToMap() {
        const formatWKT = new OpenLayers.Format.WKT();

        const drawLayerWKT = localStorage.getItem('drawLayer');

        if (drawLayerWKT){
            this._drawLayer.addFeatures(formatWKT.read(drawLayerWKT));
            this._drawLayer.redraw(true);
        }
    }

    download(format){
        if (this.featureDrawn){
            const OL6Allfeatures = [];

            // Create OL6 features with OL2 features coordinates
            for (const featureDrawn of this.featureDrawn) {
                const featureGeometry = featureDrawn.geometry;
                let OL6feature;

                if (featureGeometry.CLASS_NAME === 'OpenLayers.Geometry.Point') {
                    OL6feature = new Feature(new Point([featureGeometry.x, featureGeometry.y]));
                }
                else if (featureGeometry.CLASS_NAME === 'OpenLayers.Geometry.LineString') {
                    let coordinates = [];
                    for (const component of featureGeometry.components) {
                        coordinates.push([component.x, component.y]);
                    }
                    OL6feature = new Feature(new LineString(coordinates));
                }
                else if (featureGeometry.CLASS_NAME === 'OpenLayers.Geometry.Polygon') {
                    let coordinates = [];
                    for (const component of featureGeometry.components[0].components) {
                        coordinates.push([component.x, component.y]);
                    }
                    OL6feature = new Feature(new Polygon([coordinates]));
                }

                // Reproject to EPSG:4326
                OL6feature.getGeometry().transform(mainLizmap.projection, 'EPSG:4326');

                OL6Allfeatures.push(OL6feature);
            }

            if(format === 'geojson'){
                const geoJSON = (new GeoJSON()).writeFeatures(OL6Allfeatures);
                this._downloadString(geoJSON, 'application/geo+json', 'export.geojson');
            }
            else if(format === 'gpx'){
                const gpx = (new GPX()).writeFeatures(OL6Allfeatures);
                this._downloadString(gpx, 'application/gpx+xml', 'export.gpx');
            } else if (format === 'kml') {
                const kml = (new KML()).writeFeatures(OL6Allfeatures);
                this._downloadString(kml, 'application/vnd.google-earth.kml+xml', 'export.kml');
            }
        }
    }

    _downloadString(text, fileType, fileName) {
        var blob = new Blob([text], { type: fileType });

        var a = document.createElement('a');
        a.download = fileName;
        a.href = URL.createObjectURL(blob);
        a.dataset.downloadurl = [fileType, a.download, a.href].join(':');
        a.style.display = "none";
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        setTimeout(function () { URL.revokeObjectURL(a.href); }, 1500);
    }

    import(file){
        const reader = new FileReader();

        reader.onload = ((aThis) => {
            return (e) => {
                const fileContent = e.target.result;
                let OL6feature;

                // Handle GeoJSON, GPX or KML strings
                try {
                    if (fileContent[0] === '{') {
                        OL6feature = (new GeoJSON()).readFeatures(fileContent);
                    } else if (fileContent.slice(0, 4) === '<gpx') {
                        OL6feature = (new GPX()).readFeatures(fileContent);

                    } else if (fileContent.slice(0, 4) === '<kml') {
                        OL6feature = (new KML()).readFeatures(fileContent);
                    }
                } catch (error) {
                    lizMap.addMessage(error, 'error', true)
                }

                if (OL6feature){
                    // Erase previous feature
                    aThis.erase();

                    // If there are multiple features we only take the first and inform user
                    if(OL6feature.length > 1){
                        lizMap.addMessage(lizDict['digitizing.import.inform.singleFeature'], 'info', true)
                    }

                    // Draw loaded feature
                    const importedGeom = OL6feature[0].getGeometry();
                    const importedGeomType = importedGeom.getType();

                    // Convert from EPSG:4326 to current projection
                    importedGeom.transform('EPSG:4326', mainLizmap.projection);
                    const importedGeomCoordinates = importedGeom.getCoordinates();

                    const importedGeomAsArrayOfPoints = [];
                    let geomToDraw;

                    if (importedGeomType === 'Point') {
                        geomToDraw = new OpenLayers.Geometry.Point(importedGeomCoordinates[0], importedGeomCoordinates[1]);
                    }else if (importedGeomType === 'LineString'){
                        for (const coordinate of importedGeomCoordinates) {
                            importedGeomAsArrayOfPoints.push(new OpenLayers.Geometry.Point(coordinate[0], coordinate[1]));
                        }

                        geomToDraw = new OpenLayers.Geometry.LineString(importedGeomAsArrayOfPoints);
                    } else if (importedGeomType === 'Polygon') {
                        for (const coordinate of importedGeomCoordinates[0]) {
                            importedGeomAsArrayOfPoints.push(new OpenLayers.Geometry.Point(coordinate[0], coordinate[1]));
                        }

                        geomToDraw = new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(importedGeomAsArrayOfPoints)]);
                    }

                    if(geomToDraw){
                        this._drawLayer.addFeatures(new OpenLayers.Feature.Vector(geomToDraw));
                        this._drawLayer.redraw(true);
                    }
                }
            };
        })(this);

        reader.readAsText(file);
    }
}
<|endoftext|>


<commit_before>import {
  ruleTester,
  warningFreeBasics,
} from "../../../testUtils"
import rule, { ruleName, messages } from ".."

const testRule = ruleTester(rule, ruleName)

testRule(undefined, tr => {
  warningFreeBasics(tr)

  tr.ok("a { /* color: pink; */ }", "regular comment around declaration")
  tr.ok("/* a { color: pink; } */", "regular comment around rule")
  tr.ok("a { background: url(//foo.com/bar.png) }", "url with double slash")

  tr.notOk(
    "a { // color: pink; }",
    {
      message: messages.rejected,
      line: 1,
      column: 8,
    },
    "before declaration"
  )

  tr.notOk(
    "// a { color: pink; }",
    {
      message: messages.rejected,
      line: 1,
      column: 19,
    },
    "before rule"
  )

  tr.notOk(
    "a, // div { color: pink; }",
    {
      message: messages.rejected,
      line: 1,
      column: 19,
    },
    "between rules"
  )

  tr.notOk(
    "// @media { }",
    {
      message: messages.rejected,
      line: 1,
      column: 19,
    },
    "before media rule"
  )
})

<commit_msg>Add test for Scss-syntax-based rule<commit_after>import {
  ruleTester,
  warningFreeBasics,
} from "../../../testUtils"
import rule, { ruleName, messages } from ".."

import scssSyntax from "postcss-scss"

const testRule = ruleTester(rule, ruleName)

testRule(undefined, tr => {
  warningFreeBasics(tr)

  tr.ok("a { /* color: pink; */ }", "regular comment around declaration")
  tr.ok("/* a { color: pink; } */", "regular comment around rule")
  tr.ok("a { background: url(//foo.com/bar.png) }", "url with double slash")

  tr.notOk(
    "a { // color: pink; }",
    {
      message: messages.rejected,
      line: 1,
      column: 8,
    },
    "before declaration"
  )

  tr.notOk(
    "// a { color: pink; }",
    {
      message: messages.rejected,
      line: 1,
      column: 19,
    },
    "before rule"
  )

  tr.notOk(
    "a, // div { color: pink; }",
    {
      message: messages.rejected,
      line: 1,
      column: 19,
    },
    "between rules"
  )

  tr.notOk(
    "// @media { }",
    {
      message: messages.rejected,
      line: 1,
      column: 19,
    },
    "before media rule"
  )
})

const testRuleScss = ruleTester(rule, ruleName, {
  postcssOptions: {
    syntax: scssSyntax,
  },
})

testRuleScss(undefined, tr => {
  tr.ok("// a { color: pink }", "single-line comment ignored")
})

testRuleScss(undefined, tr => {
  tr.ok("a { \n// color: pink;\n }", "single-line comment ignored")
})
<|endoftext|>


<commit_before>module.exports = {
  entry: {
    index: './src/page/index/client',
    index_ssr: './src/page/index/server',
  },
  output: {
    path: 'public/build',
    filename: '[name].bundle.js',
  },
  plugins: [
  ],
  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        loaders: ['babel-loader'],
        exclude: /node_modules/,
      },
    ]
  },
  resolve: {
    extensions: ['.js', '.jsx'],
  },
};
<commit_msg>remove plugins section<commit_after>module.exports = {
  entry: {
    index: './src/page/index/client',
    index_ssr: './src/page/index/server',
  },
  output: {
    path: 'public/build',
    filename: '[name].bundle.js',
  },
  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        loaders: ['babel-loader'],
        exclude: /node_modules/,
      },
    ]
  },
  resolve: {
    extensions: ['.js', '.jsx'],
  },
};
<|endoftext|>