<commit_before>//////// Module Definition ////////////
define([
	'view/view.module',
	'view/view.service',
	'ngRoute',
	'i18n/translate.config',
	'util/sparql.service',
	'util/util.service',
	'util/htmlCache.service',
	'util/sqidStatementTable.directive',
	'util/sqidCompile.directive',
	'util/map.directive',
	'proposals/proposals.service',
	'proposals/primarySources.service',
	'rules/rules.service',
	'data/properties.service',
	'data/classes.service',
	'oauth/oauth.service',
	'i18n/i18n.service'
], function() {
///////////////////////////////////////

/* eslint angular/di: 0 */
angular.module('view').controller('ViewController', [
    '$scope', '$route', '$sce', '$translate', 'view', 'classes', 'properties', 'oauth', 'sparql', 'util', 'i18n', 'htmlCache', 'proposals', 'primarySources', 'rules', '$q',
    function($scope, $route, $sce, $translate, View, Classes, Properties, oauth, sparql, util, i18n, htmlCache, proposals, primarySources, rules, $q){
	var MAX_EXAMPLE_INSTANCES = 20;
	var MAX_DIRECT_SUBCLASSES = 10;
	var MAX_PROP_SUBJECTS = 10;
	var MAX_PROP_VALUES = 20;
	var RELATED_PROPERTIES_THRESHOLD = 5;

	i18n.checkCacheSize();

	htmlCache.reset();
	$scope.getCachedHtml = htmlCache.getValue;

	$scope.lang = i18n.getLanguage();

	$scope.translations = {};

	$translate(['SEC_CLASSIFICATION.INSTANCE_SUBCLASSES_HINT', 'SEC_CLASSIFICATION.SUBCLASS_SUBCLASSES_HINT', 'SEC_CLASSIFICATION.ALL_SUBCLASSES_HINT', 'TYPICAL_PROPS.HINT_CLASS', 'TYPICAL_PROPS.HINT_PROP', 'SEC_PROP_USE.ENTITIES_HINT', 'SEC_PROP_USE.VALUES_HINT', 'SEC_PROP_USE.STATEMENTS_HINT', 'SEC_PROP_USE.QUALIFIERS_HINT', 'MODALS.EMPTY_FIELDS_ERROR', 'MODALS.EXECUTION_ERROR', 'MODALS.EXECUTION_SUCCESSFUL']).then( function(translations) {
		$scope.translations['SUBCLASS_SUBCLASSES_HINT'] = translations['SEC_CLASSIFICATION.SUBCLASS_SUBCLASSES_HINT'];
		$scope.translations['INSTANCE_SUBCLASSES_HINT'] = translations['SEC_CLASSIFICATION.INSTANCE_SUBCLASSES_HINT'];
		$scope.translations['ALL_SUBCLASSES_HINT'] = translations['SEC_CLASSIFICATION.ALL_SUBCLASSES_HINT'];
		$scope.translations['TYPICAL_PROPS_HINT_CLASS'] = translations['TYPICAL_PROPS.HINT_CLASS'];
		$scope.translations['TYPICAL_PROPS_HINT_PROP'] = translations['TYPICAL_PROPS.HINT_PROP'];
		$scope.translations['PROP_ENTITIES_HINT'] = translations['SEC_PROP_USE.ENTITIES_HINT'];
		$scope.translations['PROP_VALUES_HINT'] = translations['SEC_PROP_USE.VALUES_HINT'];
		$scope.translations['PROP_STATEMENTS_HINT'] = translations['SEC_PROP_USE.STATEMENTS_HINT'];
		$scope.translations['PROP_QUALIFIERS_HINT'] = translations['SEC_PROP_USE.QUALIFIERS_HINT'];
		$scope.translations['MODALS_EMPTY_FIELDS_ERROR'] = translations['MODALS.EMPTY_FIELDS_ERROR'];
		$scope.translations['MODALS_EXECUTION_ERROR'] = translations['MODALS.EXECUTION_ERROR'];
		$scope.translations['MODALS_EXECUTION_SUCCESSFUL'] = translations['MODALS.EXECUTION_SUCCESSFUL'];
	});

	$scope.classes = null;
	$scope.properties = null;
	$scope.entityData = null;
	$scope.banner = null;
	$scope.homepage = null;
	$scope.urlWikipedia = null;
	$scope.images = [];
	$scope.entityInData = null;
	$scope.richDescription = null;

	$scope.exampleInstances = null;
	$scope.exampleSubclasses = null;
	$scope.superClassCount = -1;
	$scope.instanceClassCount = -1;

	$scope.examplePropertyItems = null;
	$scope.examplePropertyValues = null;
	$scope.superPropertyCount = -1;

	$scope.directInstances = 0;
	$scope.directSubclasses = 0;
	$scope.allInstances = 0;
	$scope.allSubclasses = 0;
	$scope.nonemptySubclasses = null;
	$scope.propertyStatementCount = 0;
	$scope.propertyAverageStatements = 0;
	$scope.propertyQualifierCount = 0;
	$scope.propertyReferenceCount = 0;
	$scope.propertyDatatype = null;

	$scope.modalResponse = null;
	$scope.modalResponseClass = null;

	$scope.hasEditRights = false;

	$scope.alertText = '';

	$scope.proposalsWatcher = null;
	$scope.proposalsPromises = [];

	oauth.userinfo().then(function(data){
		if (data){
			if (!View.hasEditRights()){
				View.clearEntityDataCache();
			}
			View.setEditRights(true);
			$scope.hasEditRights = true;
		}else{
			if (View.hasEditRights){
				View.clearEntityDataCache();
			}
			$scope.hasEditRights = false;
			View.setEditRights(false);
		}
	});

	View.updateId().then(function() {
		console.log('updated id')
		return View.getEntityInlinks();
	}).then(function(data) {
		$scope.entityInData = data;
	});

	var refreshContent = function(useCache){
		var func = useCache ? View.getEntityData : View.getEntityDataUncached;
		func().then(function(data) {
			$scope.entityData = data;
			$scope.images = View.getImages(data.statements);
			$scope.banner = View.getBanner(data.statements);
			$scope.homepage = View.getHomepage(data.statements);
			$scope.urlWikipedia = View.getUrlWikipedia(data.sitelinks);
			$scope.richDescription = $sce.trustAsHtml(i18n.autoLinkText($scope.entityData.description));
			data.waitForPropertyLabels().then( function() {
				$scope.instanceOfUrl = i18n.getEntityUrl("P31");
				$scope.instanceOfLabel = i18n.getPropertyLabel("P31");
				$scope.subclassOfUrl = i18n.getEntityUrl("P279");
				$scope.subclassOfLabel = i18n.getPropertyLabel("P279");
				$scope.subpropertyOfUrl = i18n.getEntityUrl("P1647");
				$scope.subpropertyOfLabel = i18n.getPropertyLabel("P1647");
			});

			Classes.then(function(classes){
				View.getValueList(data, 'P31', classes).then( function(instanceClasses) {
					$scope.instanceClassCount = instanceClasses.length;
					$scope.instanceClassesHtml = View.getValueListTrustedHtml(instanceClasses, false);
				});
				if ($scope.isItem) {
					View.getValueList(data, 'P279', classes).then( function(superClasses) {
						$scope.superClassCount = superClasses.length;
						$scope.superClassesHtml = View.getValueListTrustedHtml(superClasses, false);
						$scope.superClassesHtmlWithCounts = View.getValueListTrustedHtml(superClasses, true);
					});
				}
			});
        });
    };

	var createAlert = function(message){
		$scope.alertText = message;
		$('#alert-message').css('display', 'block');
		window.setTimeout(function(){
			$('#alert-message').css('display', 'none');
		}, 2000);
	};

	primarySources.setRefreshFunction(refreshContent);
	primarySources.setAlertFunction(createAlert);

	View.updateId().then(function(){
		$scope.id = View.getId();
		console.log('updateId')
		refreshContent(true);
		console.log('after refresh')

		var numId = $scope.id.substring(1);
		$scope.isItem = ( $scope.id.substring(0,1) != 'P' );

		// unregister old proposal watcher
		if (angular.isFunction($scope.proposalsWatcher)) {
			$scope.proposalsWatcher();
		}

		// register a watcher that updates proposals when statements and inlinks arrive
		$scope.proposalsWatcher = $scope.$watchGroup([
			'entityData',
			'entityInData'
		], proposals.getEntityDataListener($scope.id));

		Properties.then(function(properties){
			if (!$scope.isItem) {
				View.getEntityData().then(function(data) {
					View.getValueList(data, 'P1647', properties).then( function(superProperties) {
						$scope.superPropertyCount = superProperties.length;
						$scope.superPropertiesHtml = View.getValueListTrustedHtml(superProperties, false);
					});
				});

				View.formatPropertyMap(properties.getRelatedProperties(numId), RELATED_PROPERTIES_THRESHOLD).then( function(formattedProperties) {
					$scope.relatedProperties = formattedProperties;
				});

				$scope.propertyItemCount = properties.getItemCount(numId);
				$scope.propertyStatementCount = properties.getStatementCount(numId);
				$scope.propertyAverageStatements = Math.round($scope.propertyStatementCount/$scope.propertyItemCount*100)/100;
				$scope.propertyQualifierCount = properties.getQualifierCount(numId);
				$scope.propertyReferenceCount = properties.getReferenceCount(numId);
				$scope.propertyDatatype = properties.getDatatype(numId);

				View.formatPropertyMap(properties.getQualifiers(numId), null).then( function(formattedProperties) {
					$scope.propertyQualifiers = formattedProperties;
				});

				if ($scope.propertyItemCount > 0) {
					sparql.getPropertySubjects($scope.id, null, MAX_PROP_SUBJECTS + 1).then(function(result) {
						$scope.examplePropertyItems = result;
					});
				}
				if ($scope.propertyDatatype == 'WikibaseItem' || $scope.propertyDatatype == 'WikibaseProperty') {
					sparql.getPropertyObjects(null, $scope.id, MAX_PROP_VALUES + 1).then(function(result) {
						$scope.examplePropertyValues = result;
					});
				}
			}
		});
		$scope.url = 'https://www.wikidata.org/wiki/' +
			( $scope.isItem ? '' : 'Property:' ) +
			$scope.id +
			( i18n.fixedLanguage() ? ('?uselang=' + i18n.getLanguage()) : '' );
		$scope.urlReasonator = 'https://tools.wmflabs.org/reasonator/?q=' + $scope.id +
			( i18n.fixedLanguage() ? ('?lang=' + i18n.getLanguage()) : '' );
		Classes.then(function(classes){
			if ($scope.isItem) {
				View.formatPropertyMap(classes.getRelatedProperties(numId), RELATED_PROPERTIES_THRESHOLD).then( function(formattedProperties) {
					$scope.relatedProperties = formattedProperties;
				});
				$scope.directInstances = classes.getDirectInstanceCount(numId);
				$scope.directSubclasses = classes.getDirectSubclassCount(numId);
				$scope.allInstances = classes.getAllInstanceCount(numId);
				$scope.allSubclasses = classes.getAllSubclassCount(numId);
				$translate('SEC_INSTANCES.ALL_INSTANCES_HINT', { subclassCount : $scope.allSubclasses } ).then( function(result) {
					$scope.translations['ALL_INSTANCES_HINT'] = result;
				});

				View.formatNonemptySubclasses(numId, classes, classes.getAllInstanceCount).then( function(subclasses) {
					$scope.instanceSubclasses = subclasses;
					View.formatNonemptySubclasses(numId, classes, classes.getAllSubclassCount).then( function(subclasses) {
						$scope.subclassSubclasses = subclasses;
						if ($scope.instanceSubclasses.length > 0) {
							$scope.subclassActiveTab = 0;
						} else if ($scope.subclassSubclasses.length > 0) {
							$scope.subclassActiveTab = 1;
						} else {
							$scope.subclassActiveTab = 2;
						}
					});
				});

				if ($scope.directInstances > 0) {
					sparql.getPropertySubjects("P31", $scope.id, MAX_EXAMPLE_INSTANCES + 1).then(function(result) {
						$scope.exampleInstances = result;
					});
				}
				if ($scope.directSubclasses > 0) {
					sparql.getPropertySubjects("P279", $scope.id, MAX_DIRECT_SUBCLASSES + 1).then(function(result) {
						$scope.exampleSubclasses = result;
					});
				}
			}
		});
		$scope.editLabel = function(){
			var modalId = '#editLabelModal';
			var newLabel = $scope.newLabel;
			var lang = i18n.getLanguage();
			var id = $scope.id;
			if (newLabel){
				var response = oauth.setLabel(id, newLabel, lang);
				response.then(function(data){
					if (data.data.error == "OK"){
						// $scope.modalResponse = $scope.translations['MODALS_EXECUTION_SUCCESSFUL'];
						// $scope.modalResponseClass = "text-success";
						$(modalId).modal('hide');
						$scope.closeModal();
						refreshContent(false);
					}else{

						$scope.modalResponse = $scope.translations['MODALS_EXECUTION_ERROR'] +
							( (data.data.error) ? ("</br>" + String(data.data.error)) : "");
						$scope.modalResponseClass = "text-danger";
					}
				});
			}else{
				$scope.modalResponse = $scope.translations['MODALS_EMPTY_FIELDS_ERROR'];
				$scope.modalResponseClass = "text-danger";
			}
		}

	});
	$scope.closeModal = function(){
		$scope.modalResponse = null;
		$scope.modalResponseClass = null;
	}
}]);

return {};}); // module definition end
<commit_msg>Impart ordering on ID update actions<commit_after>//////// Module Definition ////////////
define([
	'view/view.module',
	'view/view.service',
	'ngRoute',
	'i18n/translate.config',
	'util/sparql.service',
	'util/util.service',
	'util/htmlCache.service',
	'util/sqidStatementTable.directive',
	'util/sqidCompile.directive',
	'util/map.directive',
	'proposals/proposals.service',
	'proposals/primarySources.service',
	'rules/rules.service',
	'data/properties.service',
	'data/classes.service',
	'oauth/oauth.service',
	'i18n/i18n.service'
], function() {
///////////////////////////////////////

/* eslint angular/di: 0 */
angular.module('view').controller('ViewController', [
    '$scope', '$route', '$sce', '$translate', 'view', 'classes', 'properties', 'oauth', 'sparql', 'util', 'i18n', 'htmlCache', 'proposals', 'primarySources', 'rules', '$q',
    function($scope, $route, $sce, $translate, View, Classes, Properties, oauth, sparql, util, i18n, htmlCache, proposals, primarySources, rules, $q){
	var MAX_EXAMPLE_INSTANCES = 20;
	var MAX_DIRECT_SUBCLASSES = 10;
	var MAX_PROP_SUBJECTS = 10;
	var MAX_PROP_VALUES = 20;
	var RELATED_PROPERTIES_THRESHOLD = 5;

	i18n.checkCacheSize();

	htmlCache.reset();
	$scope.getCachedHtml = htmlCache.getValue;

	$scope.lang = i18n.getLanguage();

	$scope.translations = {};

	$translate(['SEC_CLASSIFICATION.INSTANCE_SUBCLASSES_HINT', 'SEC_CLASSIFICATION.SUBCLASS_SUBCLASSES_HINT', 'SEC_CLASSIFICATION.ALL_SUBCLASSES_HINT', 'TYPICAL_PROPS.HINT_CLASS', 'TYPICAL_PROPS.HINT_PROP', 'SEC_PROP_USE.ENTITIES_HINT', 'SEC_PROP_USE.VALUES_HINT', 'SEC_PROP_USE.STATEMENTS_HINT', 'SEC_PROP_USE.QUALIFIERS_HINT', 'MODALS.EMPTY_FIELDS_ERROR', 'MODALS.EXECUTION_ERROR', 'MODALS.EXECUTION_SUCCESSFUL']).then( function(translations) {
		$scope.translations['SUBCLASS_SUBCLASSES_HINT'] = translations['SEC_CLASSIFICATION.SUBCLASS_SUBCLASSES_HINT'];
		$scope.translations['INSTANCE_SUBCLASSES_HINT'] = translations['SEC_CLASSIFICATION.INSTANCE_SUBCLASSES_HINT'];
		$scope.translations['ALL_SUBCLASSES_HINT'] = translations['SEC_CLASSIFICATION.ALL_SUBCLASSES_HINT'];
		$scope.translations['TYPICAL_PROPS_HINT_CLASS'] = translations['TYPICAL_PROPS.HINT_CLASS'];
		$scope.translations['TYPICAL_PROPS_HINT_PROP'] = translations['TYPICAL_PROPS.HINT_PROP'];
		$scope.translations['PROP_ENTITIES_HINT'] = translations['SEC_PROP_USE.ENTITIES_HINT'];
		$scope.translations['PROP_VALUES_HINT'] = translations['SEC_PROP_USE.VALUES_HINT'];
		$scope.translations['PROP_STATEMENTS_HINT'] = translations['SEC_PROP_USE.STATEMENTS_HINT'];
		$scope.translations['PROP_QUALIFIERS_HINT'] = translations['SEC_PROP_USE.QUALIFIERS_HINT'];
		$scope.translations['MODALS_EMPTY_FIELDS_ERROR'] = translations['MODALS.EMPTY_FIELDS_ERROR'];
		$scope.translations['MODALS_EXECUTION_ERROR'] = translations['MODALS.EXECUTION_ERROR'];
		$scope.translations['MODALS_EXECUTION_SUCCESSFUL'] = translations['MODALS.EXECUTION_SUCCESSFUL'];
	});

	$scope.classes = null;
	$scope.properties = null;
	$scope.entityData = null;
	$scope.banner = null;
	$scope.homepage = null;
	$scope.urlWikipedia = null;
	$scope.images = [];
	$scope.entityInData = null;
	$scope.richDescription = null;

	$scope.exampleInstances = null;
	$scope.exampleSubclasses = null;
	$scope.superClassCount = -1;
	$scope.instanceClassCount = -1;

	$scope.examplePropertyItems = null;
	$scope.examplePropertyValues = null;
	$scope.superPropertyCount = -1;

	$scope.directInstances = 0;
	$scope.directSubclasses = 0;
	$scope.allInstances = 0;
	$scope.allSubclasses = 0;
	$scope.nonemptySubclasses = null;
	$scope.propertyStatementCount = 0;
	$scope.propertyAverageStatements = 0;
	$scope.propertyQualifierCount = 0;
	$scope.propertyReferenceCount = 0;
	$scope.propertyDatatype = null;

	$scope.modalResponse = null;
	$scope.modalResponseClass = null;

	$scope.hasEditRights = false;

	$scope.alertText = '';

	$scope.proposalsWatcher = null;
	$scope.proposalsPromises = [];

	oauth.userinfo().then(function(data){
		if (data){
			if (!View.hasEditRights()){
				View.clearEntityDataCache();
			}
			View.setEditRights(true);
			$scope.hasEditRights = true;
		}else{
			if (View.hasEditRights){
				View.clearEntityDataCache();
			}
			$scope.hasEditRights = false;
			View.setEditRights(false);
		}
	});

	var refreshContent = function(useCache){
		var func = useCache ? View.getEntityData : View.getEntityDataUncached;
		func().then(function(data) {
			$scope.entityData = data;
			$scope.images = View.getImages(data.statements);
			$scope.banner = View.getBanner(data.statements);
			$scope.homepage = View.getHomepage(data.statements);
			$scope.urlWikipedia = View.getUrlWikipedia(data.sitelinks);
			$scope.richDescription = $sce.trustAsHtml(i18n.autoLinkText($scope.entityData.description));
			data.waitForPropertyLabels().then( function() {
				$scope.instanceOfUrl = i18n.getEntityUrl("P31");
				$scope.instanceOfLabel = i18n.getPropertyLabel("P31");
				$scope.subclassOfUrl = i18n.getEntityUrl("P279");
				$scope.subclassOfLabel = i18n.getPropertyLabel("P279");
				$scope.subpropertyOfUrl = i18n.getEntityUrl("P1647");
				$scope.subpropertyOfLabel = i18n.getPropertyLabel("P1647");
			});

			Classes.then(function(classes){
				View.getValueList(data, 'P31', classes).then( function(instanceClasses) {
					$scope.instanceClassCount = instanceClasses.length;
					$scope.instanceClassesHtml = View.getValueListTrustedHtml(instanceClasses, false);
				});
				if ($scope.isItem) {
					View.getValueList(data, 'P279', classes).then( function(superClasses) {
						$scope.superClassCount = superClasses.length;
						$scope.superClassesHtml = View.getValueListTrustedHtml(superClasses, false);
						$scope.superClassesHtmlWithCounts = View.getValueListTrustedHtml(superClasses, true);
					});
				}
			});
        });
    };

	var createAlert = function(message){
		$scope.alertText = message;
		$('#alert-message').css('display', 'block');
		window.setTimeout(function(){
			$('#alert-message').css('display', 'none');
		}, 2000);
	};

	primarySources.setRefreshFunction(refreshContent);
	primarySources.setAlertFunction(createAlert);

	View.updateId().then(function() {
		//View.clearEntityDataCache();
		return View.getEntityInlinks();
	}).then(function(data) {
		$scope.entityInData = data;
	}).then(function() {
		$scope.id = View.getId();
		console.log('updateId')
		refreshContent(true);
		console.log('after refresh')

		var numId = $scope.id.substring(1);
		$scope.isItem = ( $scope.id.substring(0,1) != 'P' );

		// unregister old proposal watcher
		if (angular.isFunction($scope.proposalsWatcher)) {
			$scope.proposalsWatcher();
		}

		// register a watcher that updates proposals when statements and inlinks arrive
		$scope.proposalsWatcher = $scope.$watchGroup([
			'entityData',
			'entityInData'
		], proposals.getEntityDataListener($scope.id));

		Properties.then(function(properties){
			if (!$scope.isItem) {
				View.getEntityData().then(function(data) {
					View.getValueList(data, 'P1647', properties).then( function(superProperties) {
						$scope.superPropertyCount = superProperties.length;
						$scope.superPropertiesHtml = View.getValueListTrustedHtml(superProperties, false);
					});
				});

				View.formatPropertyMap(properties.getRelatedProperties(numId), RELATED_PROPERTIES_THRESHOLD).then( function(formattedProperties) {
					$scope.relatedProperties = formattedProperties;
				});

				$scope.propertyItemCount = properties.getItemCount(numId);
				$scope.propertyStatementCount = properties.getStatementCount(numId);
				$scope.propertyAverageStatements = Math.round($scope.propertyStatementCount/$scope.propertyItemCount*100)/100;
				$scope.propertyQualifierCount = properties.getQualifierCount(numId);
				$scope.propertyReferenceCount = properties.getReferenceCount(numId);
				$scope.propertyDatatype = properties.getDatatype(numId);

				View.formatPropertyMap(properties.getQualifiers(numId), null).then( function(formattedProperties) {
					$scope.propertyQualifiers = formattedProperties;
				});

				if ($scope.propertyItemCount > 0) {
					sparql.getPropertySubjects($scope.id, null, MAX_PROP_SUBJECTS + 1).then(function(result) {
						$scope.examplePropertyItems = result;
					});
				}
				if ($scope.propertyDatatype == 'WikibaseItem' || $scope.propertyDatatype == 'WikibaseProperty') {
					sparql.getPropertyObjects(null, $scope.id, MAX_PROP_VALUES + 1).then(function(result) {
						$scope.examplePropertyValues = result;
					});
				}
			}
		});
		$scope.url = 'https://www.wikidata.org/wiki/' +
			( $scope.isItem ? '' : 'Property:' ) +
			$scope.id +
			( i18n.fixedLanguage() ? ('?uselang=' + i18n.getLanguage()) : '' );
		$scope.urlReasonator = 'https://tools.wmflabs.org/reasonator/?q=' + $scope.id +
			( i18n.fixedLanguage() ? ('?lang=' + i18n.getLanguage()) : '' );
		Classes.then(function(classes){
			if ($scope.isItem) {
				View.formatPropertyMap(classes.getRelatedProperties(numId), RELATED_PROPERTIES_THRESHOLD).then( function(formattedProperties) {
					$scope.relatedProperties = formattedProperties;
				});
				$scope.directInstances = classes.getDirectInstanceCount(numId);
				$scope.directSubclasses = classes.getDirectSubclassCount(numId);
				$scope.allInstances = classes.getAllInstanceCount(numId);
				$scope.allSubclasses = classes.getAllSubclassCount(numId);
				$translate('SEC_INSTANCES.ALL_INSTANCES_HINT', { subclassCount : $scope.allSubclasses } ).then( function(result) {
					$scope.translations['ALL_INSTANCES_HINT'] = result;
				});

				View.formatNonemptySubclasses(numId, classes, classes.getAllInstanceCount).then( function(subclasses) {
					$scope.instanceSubclasses = subclasses;
					View.formatNonemptySubclasses(numId, classes, classes.getAllSubclassCount).then( function(subclasses) {
						$scope.subclassSubclasses = subclasses;
						if ($scope.instanceSubclasses.length > 0) {
							$scope.subclassActiveTab = 0;
						} else if ($scope.subclassSubclasses.length > 0) {
							$scope.subclassActiveTab = 1;
						} else {
							$scope.subclassActiveTab = 2;
						}
					});
				});

				if ($scope.directInstances > 0) {
					sparql.getPropertySubjects("P31", $scope.id, MAX_EXAMPLE_INSTANCES + 1).then(function(result) {
						$scope.exampleInstances = result;
					});
				}
				if ($scope.directSubclasses > 0) {
					sparql.getPropertySubjects("P279", $scope.id, MAX_DIRECT_SUBCLASSES + 1).then(function(result) {
						$scope.exampleSubclasses = result;
					});
				}
			}
		});
		$scope.editLabel = function(){
			var modalId = '#editLabelModal';
			var newLabel = $scope.newLabel;
			var lang = i18n.getLanguage();
			var id = $scope.id;
			if (newLabel){
				var response = oauth.setLabel(id, newLabel, lang);
				response.then(function(data){
					if (data.data.error == "OK"){
						// $scope.modalResponse = $scope.translations['MODALS_EXECUTION_SUCCESSFUL'];
						// $scope.modalResponseClass = "text-success";
						$(modalId).modal('hide');
						$scope.closeModal();
						refreshContent(false);
					}else{

						$scope.modalResponse = $scope.translations['MODALS_EXECUTION_ERROR'] +
							( (data.data.error) ? ("</br>" + String(data.data.error)) : "");
						$scope.modalResponseClass = "text-danger";
					}
				});
			}else{
				$scope.modalResponse = $scope.translations['MODALS_EMPTY_FIELDS_ERROR'];
				$scope.modalResponseClass = "text-danger";
			}
		}

	});
	$scope.closeModal = function(){
		$scope.modalResponse = null;
		$scope.modalResponseClass = null;
	}
}]);

return {};}); // module definition end
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');
var moment = require('moment');
var execSync = require('child_process').execSync;

// path to the lineup file
var running_dir = process.argv[2];
var lineupFilePath = fs.readFileSync(running_dir + "/lineups/current", 'utf8');
var media_dir = process.argv[3];
var currentClipFilePath = process.argv[4];

var lineup = null;

var findClip = function(programIdx, clipAbsolutePath) {
	var program = lineup.Programs[programIdx];

	if (program.PreShow) {
		for (var i = 0; i < program.PreShow.Clips.length; i++) {
			var cAbsolutePath = path.resolve(media_dir, program.PreShow.Clips[i].Path);
			if (clipAbsolutePath == cAbsolutePath) {
				return program.PreShow.Clips[i];
			}
		}
	}
	for (var i = 0; i < program.Show.Clips.length; i++) {
		var cAbsolutePath = path.resolve(media_dir, program.Show.Clips[i].Path);
		if (clipAbsolutePath == cAbsolutePath) {
			return program.Show.Clips[i];
		}
	}

	return null;
}

if (fs.existsSync(lineupFilePath)) {
	lineup = JSON.parse(fs.readFileSync(lineupFilePath, 'utf8'));
	var currentProgramIdx = parseInt(fs.readFileSync(lineupFilePath + ".program.iter", 'utf8'));

	clip = findClip(currentProgramIdx, currentClipFilePath);

	// might be
	if (!clip) {
		upcomingClipAbsolutePath = path.resolve(media_dir, lineup.Programs[currentProgramIdx + 1].Show.Clips[0].Path)
		if (lineup.Programs[currentProgramIdx + 1] &&
			currentClipFilePath == upcomingClipAbsolutePath) {
			// In case of back-to-back programs, we need to move program iter when the first
			// media of the next program begins to play.
			// Lets shift the current program iterator
			currentProgramIdx++;
			clip = findClip(currentProgramIdx, currentClipFilePath);
			// TODO
			// fs.writeFileSync(lineupFilePath + ".program.iter", currentProgramIdx);
		}
	}

	if (clip) {
		// We have program playing
		status = {};
		status.isCurrentlyPlaying = true;
		status.currentProgram = lineup.Programs[currentProgramIdx].Title;
		status.currentClip = clip.Description ? clip.Description : "";

		fs.writeFileSync(running_dir + "/web/status.json", JSON.stringify(status));

	} else {
		// No programs right now! Instead publish the countdown
		status = {};
		status.isCurrentlyPlaying = false;
		status.currentProgram = "BLANK";
		status.now = moment().format();

		if (lineup.Programs[currentProgramIdx + 1]) {

			nextProgram = lineup.Programs[currentProgramIdx + 1];
			status.nextBoxId = nextProgram.BoxId;
			status.nextBoxStartTime = nextProgram.PreShow ?
										nextProgram.PreShow.Meta.TentativeStartTime :
										nextProgram.Show.Meta.TentativeStartTime;
		} else {
			// TODO
			// Todays programs is over, we should check the next days lineup
		}

		fs.writeFileSync(running_dir + "/web/status.json", JSON.stringify(status));
	}
}
<commit_msg>minor improvement<commit_after>var fs = require('fs');
var path = require('path');
var moment = require('moment');
var execSync = require('child_process').execSync;

// path to the lineup file
var running_dir = process.argv[2];
var lineupFilePath = fs.readFileSync(running_dir + "/lineups/current", 'utf8');
var media_dir = process.argv[3];
var currentClipFilePath = process.argv[4];

var lineup = null;

var findClip = function(programIdx, clipAbsolutePath) {
	var program = lineup.Programs[programIdx];

	if (program.PreShow) {
		for (var i = 0; i < program.PreShow.Clips.length; i++) {
			var cAbsolutePath = path.resolve(media_dir, program.PreShow.Clips[i].Path);
			if (clipAbsolutePath == cAbsolutePath) {
				return program.PreShow.Clips[i];
			}
		}
		// it might be the filler clip
		if (program.PreShow.FillerClip) {
			var cAbsolutePath = path.resolve(media_dir, program.PreShow.Clips[i].Path);
			if (clipAbsolutePath == cAbsolutePath) {
				return program.PreShow.Clips[i];
			}
		}

	}
	for (var i = 0; i < program.Show.Clips.length; i++) {
		var cAbsolutePath = path.resolve(media_dir, program.Show.Clips[i].Path);
		if (clipAbsolutePath == cAbsolutePath) {
			return program.Show.Clips[i];
		}
	}

	return null;
}

if (fs.existsSync(lineupFilePath)) {
	lineup = JSON.parse(fs.readFileSync(lineupFilePath, 'utf8'));
	var currentProgramIdx = parseInt(fs.readFileSync(lineupFilePath + ".program.iter", 'utf8'));

	clip = findClip(currentProgramIdx, currentClipFilePath);

	// might be
	if (!clip) {
		upcomingClipAbsolutePath = path.resolve(media_dir, lineup.Programs[currentProgramIdx + 1].Show.Clips[0].Path)
		if (lineup.Programs[currentProgramIdx + 1] &&
			currentClipFilePath == upcomingClipAbsolutePath) {
			// In case of back-to-back programs, we need to move program iter when the first
			// media of the next program begins to play.
			// Lets shift the current program iterator
			currentProgramIdx++;
			clip = findClip(currentProgramIdx, currentClipFilePath);
			// TODO
			// fs.writeFileSync(lineupFilePath + ".program.iter", currentProgramIdx);
		}
	}

	if (clip) {
		// We have program playing
		status = {};
		status.isCurrentlyPlaying = true;
		status.currentProgram = lineup.Programs[currentProgramIdx].Title;
		status.currentClip = clip.Description ? clip.Description : "";

		fs.writeFileSync(running_dir + "/web/status.json", JSON.stringify(status));

	} else {
		// No programs right now! Instead publish the countdown
		status = {};
		status.isCurrentlyPlaying = false;
		status.currentProgram = "BLANK";

		if (lineup.Programs[currentProgramIdx + 1]) {

			nextProgram = lineup.Programs[currentProgramIdx + 1];
			status.nextBoxId = nextProgram.BoxId;
			status.nextBoxStartTime = nextProgram.PreShow ?
										nextProgram.PreShow.Meta.TentativeStartTime :
										nextProgram.Show.Meta.TentativeStartTime;
		} else {
			// TODO
			// Todays programs is over, we should check the next days lineup
		}

		fs.writeFileSync(running_dir + "/web/status.json", JSON.stringify(status));
	}
}
<|endoftext|>


<commit_before>function unflatten(ff, $$$mptypes) {
  if (ff.$flattened$)return ff.$flattened$;
  if (ff.jsc$)ff=ff.jsc$;
  var mm=getrtmm$$(ff);
  if (mm && mm.ps) {
    var ru=function ru(seq,$mptypes) {
      if (seq===undefined || seq.size === 0) { return ff(); }
      var pmeta = mm.ps;
      var _lim=Math.max(pmeta.length,seq.size);
      var a = [];
      for (var i = 0; i < _lim; i++) {
        if (pmeta[i]&&pmeta[i]['seq']) {
          a.push(seq.skip(i).sequence());
          break;//we're done
        } else if (seq.size > i) {
          a.push(seq.$_get(i));
        }
      }
      if ($mptypes && mm.tp)a.push($mptypes);
      return ff.apply(ru, a);
    }
    ru.$crtmm$={$t:mm.$t,ps:[{$t:{t:'T',l:[]}}]};
    for (var i=0;i<mm.ps.length;i++){
      ru.$crtmm$.ps[0].$t.l.push(mm.ps[i].$t);
    }
  } else {
    var ru=function ru(seq) {
      if (seq===undefined || seq.size === 0) { return ff(); }
      var a = [];
      for (var i = 0; i < seq.size; i++) {
        a[i] = seq.$_get(i);
      }
      a[i]=ru.$$targs$$;
      return ff.apply(ru, a);
    }
  }
  ru.$unflattened$=ff;
  ru.$$targs$$={Return$Callable:$$$mptypes.Return$unflatten,Arguments$Callable:{t:'T',l:[$$$mptypes.Args$unflatten]}};
  return ru;
}
<commit_msg>optimize unflatten<commit_after>function unflatten(ff, $$$mptypes) {
  if (ff.$flattened$)return ff.$flattened$;
  if (ff.jsc$)ff=ff.jsc$;
  var mm=getrtmm$$(ff);
  if (mm && mm.ps) {
    if (mm.ps.length===0)return ff;
    var last=mm.ps[mm.ps.length-1];
    var iadic=variadicness(mm.ps[mm.ps.length-1].$t);
    if (is$(last,{t:Tuple}))iadic=0;
    var ru;
    if (iadic && mm.ps.length===1) {
      //Single variadic parm, passed as sequence
      ru=function rus(seq,$mptypes) {
        if (seq===undefined || seq.size === 0)seq=empty();
        return ff(seq,$mptypes);
      }
      ru.$crtmm$={$t:mm.$t,ps:[{$t:{t:last.$t.t,a:last.$t.a}}]};
    } else if (iadic) {
      //Args and variadic, gets unfinished Tuple
      var cut=mm.ps.length-1;
      ru=function ruv(seq,$mptypes) {
        var a=[];
        for (var i=0;i<Math.min(seq.size,cut);i++) {
          a.push(seq.$_get(i));
        }
        if (seq.size<=cut) {
          //Fill positions of defaulted args
          for (var i=seq.size;i<cut;i++)a.push(undefined);
          a.push(empty());
        } else {
          var s=[];
          for (var i=cut;i<seq.size;i++)s.push(seq.$_get(i));
          a.push(ArraySequence(s,{Element$ArraySequence:last.$t}));
        }
        if ($mptypes)a.push($mptypes);
        return ff.apply(0,a);
      }
    } else {
      ru=function rut(tup,$mptypes) {
        var a=[];
        for (var i=0;i<tup.size;i++) {
          a.push(tup.$_get(i));
        }
        //Fill positions of defaulted args
        for (var i=tup.size;i<mm.ps.length;i++)a.push(undefined);
        if ($mptypes)a.push($mptypes);
        return ff.apply(0,a);
      }
    }
    if (!ru.$crtmm$) {
      ru.$crtmm$={$t:mm.$t,ps:[{$t:{t:'T',l:[]}}]};
      for (var i=0;i<mm.ps.length;i++){
        ru.$crtmm$.ps[0].$t.l.push(mm.ps[i].$t);
      }
    }
  } else {
    var ru=function ru(seq) {
      if (seq===undefined || seq.size === 0) { return ff(); }
      var a = [];
      for (var i = 0; i < seq.size; i++) {
        a[i] = seq.$_get(i);
      }
      a[i]=ru.$$targs$$;
      return ff.apply(ru, a);
    }
  }
  ru.$unflattened$=ff;
  ru.$$targs$$={Return$Callable:$$$mptypes.Return$unflatten,Arguments$Callable:{t:'T',l:[$$$mptypes.Args$unflatten]}};
  return ru;
}
<|endoftext|>


<commit_before>// @flow

import React from 'react'
import {StyleSheet, RefreshControl, Platform} from 'react-native'
import {SearchableAlphabetListView} from '../components/searchable-alphabet-listview'
import {Column} from '../components/layout'
import {
  Detail,
  Title,
  ListRow,
  ListSectionHeader,
  ListSeparator,
} from '../components/list'
import delay from 'delay'
import {reportNetworkProblem} from '../../lib/report-network-problem'
import type {WordType} from './types'
import type {TopLevelViewPropsType} from '../types'
import {tracker} from '../../analytics'
import groupBy from 'lodash/groupBy'
import head from 'lodash/head'
import uniq from 'lodash/uniq'
import words from 'lodash/words'
import deburr from 'lodash/deburr'
import * as defaultData from '../../../docs/dictionary.json'

const GITHUB_URL = 'https://stodevx.github.io/AAO-React-Native/dictionary.json'
const ROW_HEIGHT = Platform.OS === 'ios' ? 76 : 89
const SECTION_HEADER_HEIGHT = Platform.OS === 'ios' ? 33 : 41

const splitToArray = (str: string) => words(deburr(str.toLowerCase()))

const termToArray = (term: WordType) =>
  uniq([...splitToArray(term.word), ...splitToArray(term.definition)])

const styles = StyleSheet.create({
  row: {
    height: ROW_HEIGHT,
  },
  rowSectionHeader: {
    height: SECTION_HEADER_HEIGHT,
  },
  rowDetailText: {
    fontSize: 14,
  },
})

type Props = TopLevelViewPropsType

type State = {
  results: {[key: string]: Array<WordType>},
  allTerms: Array<WordType>,
  loading: boolean,
}

export class DictionaryView extends React.PureComponent<void, Props, State> {
  static navigationOptions = {
    title: 'Campus Dictionary',
    headerBackTitle: 'Dictionary',
  }

  state = {
    results: defaultData.data,
    allTerms: defaultData.data,
    loading: true,
  }

  componentWillMount() {
    this.refresh()
  }

  refresh = async () => {
    const start = Date.now()
    this.setState(() => ({loading: true}))

    await this.fetchData()

    // wait 0.5 seconds – if we let it go at normal speed, it feels broken.
    const elapsed = Date.now() - start
    if (elapsed < 500) {
      await delay(500 - elapsed)
    }

    this.setState(() => ({loading: false}))
  }

  fetchData = async () => {
    let {data: allTerms} = await fetchJson(GITHUB_URL).catch(err => {
      reportNetworkProblem(err)
      return defaultData
    })

    if (process.env.NODE_ENV === 'development') {
      allTerms = defaultData.data
    }

    this.setState(() => ({allTerms}))
  }

  onPressRow = (data: WordType) => {
    tracker.trackEvent('dictionary', data.word)
    this.props.navigation.navigate('DictionaryDetailView', {item: data})
  }

  renderRow = ({item}: {item: WordType}) =>
    <ListRow
      onPress={() => this.onPressRow(item)}
      contentContainerStyle={styles.row}
      arrowPosition="none"
    >
      <Column>
        <Title lines={1}>{item.word}</Title>
        <Detail lines={2} style={styles.rowDetailText}>
          {item.definition}
        </Detail>
      </Column>
    </ListRow>

  renderSectionHeader = ({title}: {title: string}) =>
    <ListSectionHeader title={title} style={styles.rowSectionHeader} />

  renderSeparator = (sectionId: string, rowId: string) =>
    <ListSeparator key={`${sectionId}-${rowId}`} />

  performSearch = (text: ?string) => {
    if (!text) {
      this.setState(state => ({results: state.allTerms}))
      return
    }

    const query = text.toLowerCase()
    this.setState(state => ({
      results: state.allTerms.filter(term =>
        termToArray(term).some(word => word.startsWith(query)),
      ),
    }))
  }

  render() {
    return (
      <SearchableAlphabetListView
        cell={this.renderRow}
        cellHeight={
          ROW_HEIGHT +
          (Platform.OS === 'ios' ? 11 / 12 * StyleSheet.hairlineWidth : 0)
        }
        data={groupBy(this.state.results, item => head(item.word))}
        onSearch={this.performSearch}
        renderSeparator={this.renderSeparator}
        sectionHeader={this.renderSectionHeader}
        sectionHeaderHeight={SECTION_HEADER_HEIGHT}
      />
    )
  }
}
<commit_msg>Remove import from dictionary<commit_after>// @flow

import React from 'react'
import {StyleSheet, Platform} from 'react-native'
import {SearchableAlphabetListView} from '../components/searchable-alphabet-listview'
import {Column} from '../components/layout'
import {
  Detail,
  Title,
  ListRow,
  ListSectionHeader,
  ListSeparator,
} from '../components/list'
import delay from 'delay'
import {reportNetworkProblem} from '../../lib/report-network-problem'
import type {WordType} from './types'
import type {TopLevelViewPropsType} from '../types'
import {tracker} from '../../analytics'
import groupBy from 'lodash/groupBy'
import head from 'lodash/head'
import uniq from 'lodash/uniq'
import words from 'lodash/words'
import deburr from 'lodash/deburr'
import * as defaultData from '../../../docs/dictionary.json'

const GITHUB_URL = 'https://stodevx.github.io/AAO-React-Native/dictionary.json'
const ROW_HEIGHT = Platform.OS === 'ios' ? 76 : 89
const SECTION_HEADER_HEIGHT = Platform.OS === 'ios' ? 33 : 41

const splitToArray = (str: string) => words(deburr(str.toLowerCase()))

const termToArray = (term: WordType) =>
  uniq([...splitToArray(term.word), ...splitToArray(term.definition)])

const styles = StyleSheet.create({
  row: {
    height: ROW_HEIGHT,
  },
  rowSectionHeader: {
    height: SECTION_HEADER_HEIGHT,
  },
  rowDetailText: {
    fontSize: 14,
  },
})

type Props = TopLevelViewPropsType

type State = {
  results: {[key: string]: Array<WordType>},
  allTerms: Array<WordType>,
  loading: boolean,
}

export class DictionaryView extends React.PureComponent<void, Props, State> {
  static navigationOptions = {
    title: 'Campus Dictionary',
    headerBackTitle: 'Dictionary',
  }

  state = {
    results: defaultData.data,
    allTerms: defaultData.data,
    loading: true,
  }

  componentWillMount() {
    this.refresh()
  }

  refresh = async () => {
    const start = Date.now()
    this.setState(() => ({loading: true}))

    await this.fetchData()

    // wait 0.5 seconds – if we let it go at normal speed, it feels broken.
    const elapsed = Date.now() - start
    if (elapsed < 500) {
      await delay(500 - elapsed)
    }

    this.setState(() => ({loading: false}))
  }

  fetchData = async () => {
    let {data: allTerms} = await fetchJson(GITHUB_URL).catch(err => {
      reportNetworkProblem(err)
      return defaultData
    })

    if (process.env.NODE_ENV === 'development') {
      allTerms = defaultData.data
    }

    this.setState(() => ({allTerms}))
  }

  onPressRow = (data: WordType) => {
    tracker.trackEvent('dictionary', data.word)
    this.props.navigation.navigate('DictionaryDetailView', {item: data})
  }

  renderRow = ({item}: {item: WordType}) =>
    <ListRow
      onPress={() => this.onPressRow(item)}
      contentContainerStyle={styles.row}
      arrowPosition="none"
    >
      <Column>
        <Title lines={1}>{item.word}</Title>
        <Detail lines={2} style={styles.rowDetailText}>
          {item.definition}
        </Detail>
      </Column>
    </ListRow>

  renderSectionHeader = ({title}: {title: string}) =>
    <ListSectionHeader title={title} style={styles.rowSectionHeader} />

  renderSeparator = (sectionId: string, rowId: string) =>
    <ListSeparator key={`${sectionId}-${rowId}`} />

  performSearch = (text: ?string) => {
    if (!text) {
      this.setState(state => ({results: state.allTerms}))
      return
    }

    const query = text.toLowerCase()
    this.setState(state => ({
      results: state.allTerms.filter(term =>
        termToArray(term).some(word => word.startsWith(query)),
      ),
    }))
  }

  render() {
    return (
      <SearchableAlphabetListView
        cell={this.renderRow}
        cellHeight={
          ROW_HEIGHT +
          (Platform.OS === 'ios' ? 11 / 12 * StyleSheet.hairlineWidth : 0)
        }
        data={groupBy(this.state.results, item => head(item.word))}
        onSearch={this.performSearch}
        renderSeparator={this.renderSeparator}
        sectionHeader={this.renderSectionHeader}
        sectionHeaderHeight={SECTION_HEADER_HEIGHT}
      />
    )
  }
}
<|endoftext|>


<commit_before>/**
 * Copyright 2017 Google Inc. 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.
 */

'use strict';
var TraceLabels = require('./trace-labels.js');
var cls = require('./cls.js');
var constants = require('./constants.js');
var is = require('is');

/**
 * This file describes an interface for third-party plugins to enable tracing
 * for arbitrary modules.
 */

/**
 * An object that is associated with a single child span. It exposes
 * functions for adding labels to or closing the associated span.
 * @param {TraceAgent} agent The underlying trace agent object.
 * @param {SpanData} span An object containing information about the child span.
 */
function ChildSpan(agent, span) {
  this.agent_ = agent;
  this.span_ = span;
  this.serializedTraceContext_ = agent.generateTraceContext(span, true);
}

/**
 * Adds a label to the underlying span.
 * @param {string} key The name of the label to add.
 * @param {*} value The value of the label to add.
 */
ChildSpan.prototype.addLabel = function(key, value) {
  this.span_.addLabel(key, value);
};

/**
 * Ends the underlying span. This function should only be called once.
 */
ChildSpan.prototype.endSpan = function() {
  this.span_.close();
};

/**
 * Gets the trace context serialized as a string. This string can be set as the
 * 'x-cloud-trace-context' field in an HTTP request header to support
 * distributed tracing.
 */
ChildSpan.prototype.getTraceContext = function() {
  return this.serializedTraceContext_;
};

/**
 * An object that is associated with a single root span. It exposes
 * functions for adding labels to or closing the associated span.
 * @param {TraceAgent} agent The underlying trace agent object.
 * @param {SpanData} context An object containing information about the
 * root span.
 */
function Transaction(agent, context) {
  this.agent_ = agent;
  this.context_ = context;
  this.serializedTraceContext_ = agent.generateTraceContext(context, true);
}

/**
 * Adds a label to the underlying span.
 * @param {string} key The name of the label to add.
 * @param {*} value The value of the label to add.
 */
Transaction.prototype.addLabel = function(key, value) {
  this.context_.addLabel(key, value);
};

/**
 * Ends the underlying span. This function should only be called once.
 */
Transaction.prototype.endSpan = function() {
  this.context_.close();
};

/**
 * Gets the trace context serialized as a string. This string can be set as the
 * 'x-cloud-trace-context' field in an HTTP request header to support
 * distributed tracing.
 */
Transaction.prototype.getTraceContext = function() {
  return this.serializedTraceContext_;
};

/**
 * Runs the given function in a child span, passing it an object that
 * exposes an interface for adding labels and closing the span.
 * @param {object} options An object that specifies options for how the child
 * span is created and propogated.
 * @param {string} options.name The name to apply to the child span.
 * @param {?string} options.traceContext The serialized form of an object that
 * contains information about an existing trace context.
 * @param {?number} options.skipFrames The number of stack frames to skip when
 * collecting call stack information for the child span, starting from the top;
 * this should be set to avoid including frames in the plugin. Defaults to 0.
 * @param {function(ChildSpan)} fn A function that will be called exactly
 * once, with a ChildSpan object exposing an interface operating on the child
 * span.
 * @returns The return value of calling fn.
 */
Transaction.prototype.runInChildSpan = function(options, fn) {
  options = options || {};
  var childContext = this.agent_.startSpan(options.name, {},
    options.skipFrames ? options.skipFrames + 1 : 1);
  return fn(new ChildSpan(this.agent_, childContext));
};

/**
 * PluginAPI constructor. Don't call directly - a plugin object will be passed to
 * plugin themselves
 * TODO(kjin): Should be called something else
 */
function PluginAPI(agent) {
  this.agent_ = agent;
  this.logger_ = agent.logger;
}

/**
 * Gets the value of enhancedDatabaseReporting in the trace agent's
 * configuration object.
 * @returns A boolean value indicating whether the trace agent was configured
 * to have an enhanced level of reporting enabled.
 */
PluginAPI.prototype.enhancedDatabaseReportingEnabled = function() {
  return this.agent_.config_.enhancedDatabaseReporting;
};

/**
 * Creates a new Transaction object corresponding to an incoming request, which
 * exposes methods operating on the root span.
 * @param {object} options An object that specifies options for how the root
 * span is created and propogated.
 * @param {string} options.name The name to apply to the root span.
 * @param {?string} options.url A URL associated with the root span, if
 * applicable.
 * @param {?string} options.traceContext The serialized form of an object that
 * contains information about an existing trace context.
 * @param {?number} options.skipFrames The number of stack frames to skip when
 * collecting call stack information for the root span, starting from the top;
 * this should be set to avoid including frames in the plugin. Defaults to 0.
 * @returns A new Transaction object, or null if the trace agent's policy has
 * disabled tracing for the given set of options.
 */
PluginAPI.prototype.createTransaction = function(options) {
  var skipFrames = options.skipFrames ? options.skipFrames + 1 : 1;
  return createTransaction_(this, options, skipFrames);
};

/**
 * Returns a Transaction object that corresponds to a root span started earlier
 * in the same context, or null if one doesn't exist.
 * @returns A new Transaction object, or null if a root span doesn't exist in
 * the current context.
 */
PluginAPI.prototype.getTransaction = function() {
  if (cls.getRootContext()) {
    return new Transaction(this.agent_, cls.getRootContext());
  } else {
    this.logger_.warn('Attempted to get transaction handle when it doesn\'t' +
      ' exist');
    return null;
  }
};

/**
 * Runs the given function in a root span corresponding to an incoming request,
 * possibly passing it an object that exposes an interface for adding labels
 * and closing the span.
 * @param {object} options An object that specifies options for how the root
 * span is created and propogated. @see PluginAPI.prototype.createTransaction
 * @param {function(?Transaction)} fn A function that will be called exactly
 * once. If the incoming request should be traced, a root span will be created,
 * and this function will be called with a Transaction object exposing functions
 * operating on the root span; otherwise, it will be called with null as an
 * argument.
 * @returns The return value of calling fn.
 */
PluginAPI.prototype.runInRootSpan = function(options, fn) {
  var that = this;
  if (!this.agent_.namespace) {
    this.logger_.warn('Trace agent: CLS namespace not present; not running in' +
      'root span.');
    return fn(null);
  }
  return this.agent_.namespace.runAndReturn(function() {
    var skipFrames = options.skipFrames ? options.skipFrames + 2 : 2;
    var transaction = createTransaction_(that, options, skipFrames);
    return fn(transaction);
  });
};

/**
 * Convenience method which obtains a Transaction object with getTransaction()
 * and calls its runInChildSpan function on the given arguments. If there is
 * no current Transaction object, the provided function will be called with
 * null as an argument.
 * @param {object} options An object that specifies options for how the root
 * span is created and propogated. @see Transaction.prototype.runInChildSpan
 * @param {function(?Transaction)} fn A function that will be called exactly
 * once. @see Transaction.prototype.runInChildSpan
 * @returns The return value of calling fn.
 */
PluginAPI.prototype.runInChildSpan = function(options, fn) {
  var transaction = this.getTransaction();
  if (transaction) {
    options = options || {};
    var childContext = transaction.agent_.startSpan(options.name, {},
      options.skipFrames ? options.skipFrames + 1 : 1);
    return fn(new ChildSpan(transaction.agent_, childContext));
  } else {
    this.logger_.warn(options.name + ': Attempted to run in child span ' +
      'without root');
    return fn(null);
  }
};

/**
 * Binds the trace context to the given function.
 * This is necessary in order to create child spans correctly in functions
 * that are called asynchronously (for example, in a network response handler).
 * @param {function} fn A function to which to bind the trace context.
 */
PluginAPI.prototype.wrap = function(fn) {
  if (!this.agent_.namespace) {
    this.logger_.warn('Trace agent: No CLS namespace to bind function to');
    return fn;
  }
  return this.agent_.namespace.bind(fn);
};

/**
 * Binds the trace context to the given event emitter.
 * This is necessary in order to create child spans correctly in event handlers.
 * @param {EventEmitter} emitter An event emitter whose handlers should have
 * the trace context binded to them.
 */
PluginAPI.prototype.wrapEmitter = function(emitter) {
  if (!this.agent_.namespace) {
    this.logger_.warn('Trace agent: No CLS namespace to bind emitter to');
  }
  this.agent_.namespace.bindEmitter(emitter);
};

PluginAPI.prototype.constants = constants;

PluginAPI.prototype.labels = TraceLabels;

module.exports = PluginAPI;

// Module-private functions

function createTransaction_(api, options, skipFrames) {
  options = options || {};
  // If the options object passed in has the getTraceContext field set,
  // try to retrieve the header field containing incoming trace metadata.
  var incomingTraceContext;
  if (is.string(options.traceContext)) {
    incomingTraceContext = api.agent_.parseContextFromHeader(options.traceContext);
  }
  incomingTraceContext = incomingTraceContext || {};
  if (options.url && !api.agent_.shouldTrace(options.url, incomingTraceContext.options)) {
    return null;
  }
  var rootContext = api.agent_.createRootSpanData(options.name,
    incomingTraceContext.traceId,
    incomingTraceContext.spanId,
    skipFrames + 1);
  return new Transaction(api.agent_, rootContext);
}
<commit_msg>Plugin API: Add createChildSpan (#373)<commit_after>/**
 * Copyright 2017 Google Inc. 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.
 */

'use strict';
var TraceLabels = require('./trace-labels.js');
var cls = require('./cls.js');
var constants = require('./constants.js');
var is = require('is');

/**
 * This file describes an interface for third-party plugins to enable tracing
 * for arbitrary modules.
 */

/**
 * An object that is associated with a single child span. It exposes
 * functions for adding labels to or closing the associated span.
 * @param {TraceAgent} agent The underlying trace agent object.
 * @param {SpanData} span An object containing information about the child span.
 */
function ChildSpan(agent, span) {
  this.agent_ = agent;
  this.span_ = span;
  this.serializedTraceContext_ = agent.generateTraceContext(span, true);
}

/**
 * Adds a label to the underlying span.
 * @param {string} key The name of the label to add.
 * @param {*} value The value of the label to add.
 */
ChildSpan.prototype.addLabel = function(key, value) {
  this.span_.addLabel(key, value);
};

/**
 * Ends the underlying span. This function should only be called once.
 */
ChildSpan.prototype.endSpan = function() {
  this.span_.close();
};

/**
 * Gets the trace context serialized as a string. This string can be set as the
 * 'x-cloud-trace-context' field in an HTTP request header to support
 * distributed tracing.
 */
ChildSpan.prototype.getTraceContext = function() {
  return this.serializedTraceContext_;
};

/**
 * An object that is associated with a single root span. It exposes
 * functions for adding labels to or closing the associated span.
 * @param {TraceAgent} agent The underlying trace agent object.
 * @param {SpanData} context An object containing information about the
 * root span.
 */
function Transaction(agent, context) {
  this.agent_ = agent;
  this.context_ = context;
  this.serializedTraceContext_ = agent.generateTraceContext(context, true);
}

/**
 * Adds a label to the underlying span.
 * @param {string} key The name of the label to add.
 * @param {*} value The value of the label to add.
 */
Transaction.prototype.addLabel = function(key, value) {
  this.context_.addLabel(key, value);
};

/**
 * Ends the underlying span. This function should only be called once.
 */
Transaction.prototype.endSpan = function() {
  this.context_.close();
};

/**
 * Gets the trace context serialized as a string. This string can be set as the
 * 'x-cloud-trace-context' field in an HTTP request header to support
 * distributed tracing.
 */
Transaction.prototype.getTraceContext = function() {
  return this.serializedTraceContext_;
};

/**
 * PluginAPI constructor. Don't call directly - a plugin object will be passed to
 * plugin themselves
 * TODO(kjin): Should be called something else
 */
function PluginAPI(agent) {
  this.agent_ = agent;
  this.logger_ = agent.logger;
}

/**
 * Gets the value of enhancedDatabaseReporting in the trace agent's
 * configuration object.
 * @returns A boolean value indicating whether the trace agent was configured
 * to have an enhanced level of reporting enabled.
 */
PluginAPI.prototype.enhancedDatabaseReportingEnabled = function() {
  return this.agent_.config_.enhancedDatabaseReporting;
};

/**
 * Creates a new Transaction object corresponding to an incoming request, which
 * exposes methods operating on the root span.
 * @param {object} options An object that specifies options for how the root
 * span is created and propogated.
 * @param {string} options.name The name to apply to the root span.
 * @param {?string} options.url A URL associated with the root span, if
 * applicable.
 * @param {?string} options.traceContext The serialized form of an object that
 * contains information about an existing trace context.
 * @param {?number} options.skipFrames The number of stack frames to skip when
 * collecting call stack information for the root span, starting from the top;
 * this should be set to avoid including frames in the plugin. Defaults to 0.
 * @returns A new Transaction object, or null if the trace agent's policy has
 * disabled tracing for the given set of options.
 */
PluginAPI.prototype.createTransaction = function(options) {
  var skipFrames = options.skipFrames ? options.skipFrames + 1 : 1;
  return createTransaction_(this, options, skipFrames);
};

/**
 * Returns a Transaction object that corresponds to a root span started earlier
 * in the same context, or null if one doesn't exist.
 * @returns A new Transaction object, or null if a root span doesn't exist in
 * the current context.
 */
PluginAPI.prototype.getTransaction = function() {
  if (cls.getRootContext()) {
    return new Transaction(this.agent_, cls.getRootContext());
  } else {
    this.logger_.warn('Attempted to get transaction handle when it doesn\'t' +
      ' exist');
    return null;
  }
};

/**
 * Runs the given function in a root span corresponding to an incoming request,
 * possibly passing it an object that exposes an interface for adding labels
 * and closing the span.
 * @param {object} options An object that specifies options for how the root
 * span is created and propogated. @see PluginAPI.prototype.createTransaction
 * @param {function(?Transaction)} fn A function that will be called exactly
 * once. If the incoming request should be traced, a root span will be created,
 * and this function will be called with a Transaction object exposing functions
 * operating on the root span; otherwise, it will be called with null as an
 * argument.
 * @returns The return value of calling fn.
 */
PluginAPI.prototype.runInRootSpan = function(options, fn) {
  var that = this;
  if (!this.agent_.namespace) {
    this.logger_.warn('Trace agent: CLS namespace not present; not running in' +
      'root span.');
    return fn(null);
  }
  return this.agent_.namespace.runAndReturn(function() {
    var skipFrames = options.skipFrames ? options.skipFrames + 2 : 2;
    var transaction = createTransaction_(that, options, skipFrames);
    return fn(transaction);
  });
};

/**
 * Convenience method which obtains a Transaction object with getTransaction()
 * and creates a new child span nested within this transaction. If there is
 * no current Transaction object, this function returns null.
 * @param {object} options An object that specifies options for how the child
 * span is created and propogated. @see Transaction.prototype.createChildSpan
 * @returns A new ChildSpan object, or null if there is no active root span.
 */
PluginAPI.prototype.createChildSpan = function(options) {
  var transaction = this.getTransaction();
  if (transaction) {
    options = options || {};
    var childContext = this.agent_.startSpan(options.name, {},
      options.skipFrames ? options.skipFrames + 1 : 1);
    return new ChildSpan(this.agent_, childContext);
  } else {
    this.logger_.warn(options.name + ': Attempted to create child span ' +
      'without root');
    return null;
  }
};

/**
 * Binds the trace context to the given function.
 * This is necessary in order to create child spans correctly in functions
 * that are called asynchronously (for example, in a network response handler).
 * @param {function} fn A function to which to bind the trace context.
 */
PluginAPI.prototype.wrap = function(fn) {
  if (!this.agent_.namespace) {
    this.logger_.warn('Trace agent: No CLS namespace to bind function to');
    return fn;
  }
  return this.agent_.namespace.bind(fn);
};

/**
 * Binds the trace context to the given event emitter.
 * This is necessary in order to create child spans correctly in event handlers.
 * @param {EventEmitter} emitter An event emitter whose handlers should have
 * the trace context binded to them.
 */
PluginAPI.prototype.wrapEmitter = function(emitter) {
  if (!this.agent_.namespace) {
    this.logger_.warn('Trace agent: No CLS namespace to bind emitter to');
  }
  this.agent_.namespace.bindEmitter(emitter);
};

PluginAPI.prototype.constants = constants;

PluginAPI.prototype.labels = TraceLabels;

module.exports = PluginAPI;

// Module-private functions

function createTransaction_(api, options, skipFrames) {
  options = options || {};
  // If the options object passed in has the getTraceContext field set,
  // try to retrieve the header field containing incoming trace metadata.
  var incomingTraceContext;
  if (is.string(options.traceContext)) {
    incomingTraceContext = api.agent_.parseContextFromHeader(options.traceContext);
  }
  incomingTraceContext = incomingTraceContext || {};
  if (options.url && !api.agent_.shouldTrace(options.url, incomingTraceContext.options)) {
    return null;
  }
  var rootContext = api.agent_.createRootSpanData(options.name,
    incomingTraceContext.traceId,
    incomingTraceContext.spanId,
    skipFrames + 1);
  return new Transaction(api.agent_, rootContext);
}
<|endoftext|>


<commit_before>(function() {
    'use strict';

    ALLOY.Core = function () {
        var readyque = [];

        var config = {
            animation: {
                interval : 780;
            },
            arc : {
                center: [285,185],
                radius: 100,
                start: 30,
                end: 200,
                dir: -1
            }
        };

        var _ready = function(callback) {
            // https://developer.mozilla.org/en-US/docs/Web/API/document.readyState
            var readyState = document.readyState;

            if(readyState === "complete" || readyState === "loaded") {
                callback();
            } else {
                document.addEventListener("ALLOYDocumentReady", callback);
            }
        };

        var _hide = function() {

        };

    	var _init = function() {
            // add config to the ALLOY Namespace
            var config = ALLOY.config;
            pageSetup();
            ALLOY.Logger.startup('ALLOY.Core Started');
    	};

    	var pageSetup = function() {
    	    window.$ = $;
    		$("html").removeClass("no-js");
    	};

        var output = {
            ready: _ready,
            init: _init
        };

        return output;

    }();

    ALLOY.Core.ready(function() {
        ALLOY.Logger.trace('ALLOY.Core Initializing');
        ALLOY.Core.init();
    });
})();
<commit_msg>fixed issue with core on interval<commit_after>(function() {
    'use strict';

    ALLOY.Core = function () {
        var readyque = [];

        var config = {
            animation: {
                interval : 780
            },
            arc : {
                center: [285,185],
                radius: 100,
                start: 30,
                end: 200,
                dir: -1
            }
        };

        var _ready = function(callback) {
            // https://developer.mozilla.org/en-US/docs/Web/API/document.readyState
            var readyState = document.readyState;

            if(readyState === "complete" || readyState === "loaded") {
                callback();
            } else {
                document.addEventListener("ALLOYDocumentReady", callback);
            }
        };

        var _hide = function() {

        };

    	var _init = function() {
            // add config to the ALLOY Namespace
            var config = ALLOY.config;
            pageSetup();
            ALLOY.Logger.startup('ALLOY.Core Started');
    	};

    	var pageSetup = function() {
    	    window.$ = $;
    		$("html").removeClass("no-js");
    	};

        var output = {
            ready: _ready,
            init: _init
        };

        return output;

    }();

    ALLOY.Core.ready(function() {
        ALLOY.Logger.trace('ALLOY.Core Initializing');
        ALLOY.Core.init();
    });
})();
<|endoftext|>


<commit_before>/*
Flot plugin for plotting images, e.g. useful for putting ticks on a
prerendered complex visualization.

The data syntax is [[image, x1, y1, x2, y2], ...] where (x1, y1) and
(x2, y2) are where you intend the two opposite corners of the image to
end up in the plot. Image must be a fully loaded Javascript image (you
can make one with new Image()). If the image is not complete, it's
skipped when plotting.

There are two helpers included for retrieving images. The easiest work
the way that you put in URLs instead of images in the data (like
["myimage.png", 0, 0, 10, 10]), then call $.plot.image.loadData(data,
options, callback) where data and options are the same as you pass in
to $.plot. This loads the images, replaces the URLs in the data with
the corresponding images and calls "callback" when all images are
loaded (or failed loading). In the callback, you can then call $.plot
with the data set. See the included example.

A more low-level helper, $.plot.image.load(urls, callback) is also
included. Given a list of URLs, it calls callback with an object
mapping from URL to Image object when all images are loaded or have
failed loading.

Options for the plugin are

  series: {
      images: {
          show: boolean
          anchor: "corner" or "center"
      }
  }

which can be specified for a specific series

  $.plot($("#placeholder"), [{ data: [ ... ], images: { ... } ])

Note that because the data format is different from usual data points,
you can't use images with anything else in a specific data series.

Setting "anchor" to "center" causes the pixels in the image to be
anchored at the pixel centers inside of at the corners, effectively
letting half a pixel stick out as border.

A possible future direction could be support for tiling for large
images (like Google Maps).

*/

(function ($) {
    var options = {
        series: {
            images: {
                show: false,
                anchor: "corner" // or "center"
            }
        }
    };

    $.plot.image = {};

    $.plot.image.loadDataImages = function (series, options, callback) {
        var urls = [], points = [];

        var defaultShow = options.series.images.show;

        $.each(series, function (i, s) {
            if (!(defaultShow || s.images.show))
                return;

            if (s.data)
                s = s.data;

            $.each(s, function (i, p) {
                if (typeof p[0] == "string") {
                    urls.push(p[0]);
                    points.push(p);
                }
            });
        });

        $.plot.image.load(urls, function (loadedImages) {
            $.each(points, function (i, p) {
                var url = p[0];
                if (loadedImages[url])
                    p[0] = loadedImages[url];
            });

            callback();
        });
    }

    $.plot.image.load = function (urls, callback) {
        var missing = urls.length, loaded = {};
        if (missing == 0)
            callback({});

        $.each(urls, function (i, url) {
            var handler = function () {
                --missing;

                loaded[url] = this;

                if (missing == 0)
                    callback(loaded);
            };

            $('<img />').load(handler).error(handler).attr('src', url);
        });
    }

    function draw(plot, ctx) {
        var plotOffset = plot.getPlotOffset();

        $.each(plot.getData(), function (i, series) {
            var points = series.datapoints.points,
                ps = series.datapoints.pointsize;

            for (var i = 0; i < points.length; i += ps) {
                var img = points[i],
                    x1 = points[i + 1], y1 = points[i + 2],
                    x2 = points[i + 3], y2 = points[i + 4],
                    xaxis = series.xaxis, yaxis = series.yaxis,
                    tmp;

                // actually we should check img.complete, but it
                // appears to be a somewhat unreliable indicator in
                // IE6 (false even after load event)
                if (!img || img.width <= 0 || img.height <= 0)
                    continue;

                if (x1 > x2) {
                    tmp = x2;
                    x2 = x1;
                    x1 = tmp;
                }
                if (y1 > y2) {
                    tmp = y2;
                    y2 = y1;
                    y1 = tmp;
                }

                // clip
                if (x1 == x2 || y1 == y2 ||
                    x1 >= xaxis.max || x2 <= xaxis.min ||
                    y1 >= yaxis.max || y2 <= yaxis.min)
                    continue;

                var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height;
                if (series.images.anchor == "center") {
                    sx1 += 0.5;
                    sy1 += 0.5;
                    sx2 -= 0.5;
                    sy2 -= 0.5;
                }

                if (x1 < xaxis.min) {
                    sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1);
                    x1 = xaxis.min;
                }

                if (x2 > xaxis.max) {
                    sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1);
                    x2 = xaxis.max;
                }

                if (y1 < yaxis.min) {
                    sy1 += (sy2 - sy1) * (yaxis.min - y1) / (y2 - y1);
                    y1 = yaxis.min;
                }

                if (y2 > yaxis.max) {
                    sy2 += (sy2 - sy1) * (yaxis.max - y2) / (y2 - y1);
                    y2 = yaxis.max;
                }

                x1 = xaxis.p2c(x1);
                x2 = xaxis.p2c(x2);
                y1 = yaxis.p2c(y1);
                y2 = yaxis.p2c(y2);

                // the transformation may have swapped us
                if (x1 > x2) {
                    tmp = x2;
                    x2 = x1;
                    x1 = tmp;
                }
                if (y1 > y2) {
                    tmp = y2;
                    y2 = y1;
                    y1 = tmp;
                }

                ctx.drawImage(img,
                              sx1, sy1, sx2 - sx1, sy2 - sy1,
                              x1 + plotOffset.left, y1 + plotOffset.top,
                              x2 - x1, y2 - y1);
            }
        });
    }

    function processRawData(plot, series, data, datapoints) {
        if (!series.images.show)
            return;

        // format is Image, x1, y1, x2, y2 (opposite corners)
        datapoints.format = [
            { required: true },
            { x: true, number: true, required: true },
            { y: true, number: true, required: true },
            { x: true, number: true, required: true },
            { y: true, number: true, required: true }
        ];
    }

    function init(plot) {
        plot.hooks.processRawData.push(processRawData);
        plot.hooks.draw.push(draw);
    }

    $.plot.plugins.push({
        init: init,
        options: options,
        name: 'image',
        version: '1.0'
    });
})(jQuery);
<commit_msg>Swap y axis coordinates to fix bug<commit_after>/*
Flot plugin for plotting images, e.g. useful for putting ticks on a
prerendered complex visualization.

The data syntax is [[image, x1, y1, x2, y2], ...] where (x1, y1) and
(x2, y2) are where you intend the two opposite corners of the image to
end up in the plot. Image must be a fully loaded Javascript image (you
can make one with new Image()). If the image is not complete, it's
skipped when plotting.

There are two helpers included for retrieving images. The easiest work
the way that you put in URLs instead of images in the data (like
["myimage.png", 0, 0, 10, 10]), then call $.plot.image.loadData(data,
options, callback) where data and options are the same as you pass in
to $.plot. This loads the images, replaces the URLs in the data with
the corresponding images and calls "callback" when all images are
loaded (or failed loading). In the callback, you can then call $.plot
with the data set. See the included example.

A more low-level helper, $.plot.image.load(urls, callback) is also
included. Given a list of URLs, it calls callback with an object
mapping from URL to Image object when all images are loaded or have
failed loading.

Options for the plugin are

  series: {
      images: {
          show: boolean
          anchor: "corner" or "center"
      }
  }

which can be specified for a specific series

  $.plot($("#placeholder"), [{ data: [ ... ], images: { ... } ])

Note that because the data format is different from usual data points,
you can't use images with anything else in a specific data series.

Setting "anchor" to "center" causes the pixels in the image to be
anchored at the pixel centers inside of at the corners, effectively
letting half a pixel stick out as border.

A possible future direction could be support for tiling for large
images (like Google Maps).

*/

(function ($) {
    var options = {
        series: {
            images: {
                show: false,
                anchor: "corner" // or "center"
            }
        }
    };

    $.plot.image = {};

    $.plot.image.loadDataImages = function (series, options, callback) {
        var urls = [], points = [];

        var defaultShow = options.series.images.show;

        $.each(series, function (i, s) {
            if (!(defaultShow || s.images.show))
                return;

            if (s.data)
                s = s.data;

            $.each(s, function (i, p) {
                if (typeof p[0] == "string") {
                    urls.push(p[0]);
                    points.push(p);
                }
            });
        });

        $.plot.image.load(urls, function (loadedImages) {
            $.each(points, function (i, p) {
                var url = p[0];
                if (loadedImages[url])
                    p[0] = loadedImages[url];
            });

            callback();
        });
    }

    $.plot.image.load = function (urls, callback) {
        var missing = urls.length, loaded = {};
        if (missing == 0)
            callback({});

        $.each(urls, function (i, url) {
            var handler = function () {
                --missing;

                loaded[url] = this;

                if (missing == 0)
                    callback(loaded);
            };

            $('<img />').load(handler).error(handler).attr('src', url);
        });
    }

    function draw(plot, ctx) {
        var plotOffset = plot.getPlotOffset();

        $.each(plot.getData(), function (i, series) {
            var points = series.datapoints.points,
                ps = series.datapoints.pointsize;

            for (var i = 0; i < points.length; i += ps) {
                var img = points[i],
                    x1 = points[i + 1], y1 = points[i + 2],
                    x2 = points[i + 3], y2 = points[i + 4],
                    xaxis = series.xaxis, yaxis = series.yaxis,
                    tmp;

                // actually we should check img.complete, but it
                // appears to be a somewhat unreliable indicator in
                // IE6 (false even after load event)
                if (!img || img.width <= 0 || img.height <= 0)
                    continue;

                if (x1 > x2) {
                    tmp = x2;
                    x2 = x1;
                    x1 = tmp;
                }
                if (y1 > y2) {
                    tmp = y2;
                    y2 = y1;
                    y1 = tmp;
                }

                // clip
                if (x1 == x2 || y1 == y2 ||
                    x1 >= xaxis.max || x2 <= xaxis.min ||
                    y1 >= yaxis.max || y2 <= yaxis.min)
                    continue;

                var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height;
                if (series.images.anchor == "center") {
                    sx1 += 0.5;
                    sy1 += 0.5;
                    sx2 -= 0.5;
                    sy2 -= 0.5;
                }

                if (x1 < xaxis.min) {
                    sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1);
                    x1 = xaxis.min;
                }

                if (x2 > xaxis.max) {
                    sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1);
                    x2 = xaxis.max;
                }

                if (y1 < yaxis.min) {
                    sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1);
                    y1 = yaxis.min;
                }

                if (y2 > yaxis.max) {
                    sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1);
                    y2 = yaxis.max;
                }

                x1 = xaxis.p2c(x1);
                x2 = xaxis.p2c(x2);
                y1 = yaxis.p2c(y1);
                y2 = yaxis.p2c(y2);

                // the transformation may have swapped us
                if (x1 > x2) {
                    tmp = x2;
                    x2 = x1;
                    x1 = tmp;
                }
                if (y1 > y2) {
                    tmp = y2;
                    y2 = y1;
                    y1 = tmp;
                }

                ctx.drawImage(img,
                              sx1, sy1, sx2 - sx1, sy2 - sy1,
                              x1 + plotOffset.left, y1 + plotOffset.top,
                              x2 - x1, y2 - y1);
            }
        });
    }

    function processRawData(plot, series, data, datapoints) {
        if (!series.images.show)
            return;

        // format is Image, x1, y1, x2, y2 (opposite corners)
        datapoints.format = [
            { required: true },
            { x: true, number: true, required: true },
            { y: true, number: true, required: true },
            { x: true, number: true, required: true },
            { y: true, number: true, required: true }
        ];
    }

    function init(plot) {
        plot.hooks.processRawData.push(processRawData);
        plot.hooks.draw.push(draw);
    }

    $.plot.plugins.push({
        init: init,
        options: options,
        name: 'image',
        version: '1.0'
    });
})(jQuery);
<|endoftext|>


<commit_before>/*
 *  SettingScene.js
 *  2014/06/25
 *  @auther minimo
 *  This Program is MIT license.
 *
 */

tm.define("shotgun.SettingScene", {
    superClass: tm.app.Scene,

    bgm: null,
    se: null,

    //ラベル用フォントパラメータ
    labelParam: {fontFamily:"azuki", align: "center", baseline:"middle", outlineWidth:2 },

    init: function() {
        this.superInit();
        this.background = "rgba(0, 0, 0, 0.0)";
        var that = this;

        //バックグラウンド
        tm.display.Shape(SC_W, SC_H)
            .addChildTo(this)
            .setPosition(SC_W*0.5, SC_H*0.5)
            .renderRectangle({fillStyle: appMain.bgColor, strokeStyle: appMain.bgColor});

        tm.display.OutlineLabel("OPTION", 60)
            .addChildTo(this)
            .setParam(this.labelParam)
            .setPosition(SC_W*0.5, SC_H*0.1);

        tm.display.OutlineLabel("SOUND VOLUME", 50)
            .addChildTo(this)
            .setParam(this.labelParam)
            .setPosition(SC_W*0.5, SC_H*0.2);

        //ＢＧＭ音量
        var volBGM = appMain.sounds.volumeBGM;
        tm.display.OutlineLabel("BGM", 60)
            .addChildTo(this)
            .setParam(this.labelParam)
            .setPosition(SC_W*0.1, SC_H*0.3);
        this.bgm = [];
        for (var i = 0; i < 10; i++) {
            this.bgm[i] = tm.display.Sprite("card", CARD_W, CARD_H)
                .addChildTo(this)
                .setScale(0.3)
                .setPosition(SC_W*0.25+i*44, SC_H*0.3)
            this.bgm[i].num = i;
            if (i < volBGM) {
                this.bgm[i].setFrameIndex(i);
            } else {
                this.bgm[i].setFrameIndex(52);
            }
        }

        //ＳＥ音量
        var volSE = appMain.sounds.volumeSE;
        tm.display.OutlineLabel("SE", 60)
            .addChildTo(this)
            .setParam(this.labelParam)
            .setPosition(SC_W*0.1, SC_H*0.4);
        this.se = [];
        for (var i = 0; i < 10; i++) {
            this.se[i] = tm.display.Sprite("card", CARD_W, CARD_H)
                .addChildTo(this)
                .setScale(0.3)
                .setPosition(SC_W*0.25+i*44, SC_H*0.4)
            this.se[i].num = i;
            if (i < volSE) {
                this.se[i].setFrameIndex(i+13*3);
            } else {
                this.se[i].setFrameIndex(53);
            }
        }

        //戻るボタン
        var width = 300, height = 70;
        shotgun.Button(width, height, "RETURN")
            .addChildTo(this)
            .setPosition(SC_W*0.5, SC_H*0.9)
            .addEventListener("pushed", function() {
                that.mask.tweener.clear().fadeOut(200);
                appMain.saveConfig();
                appMain.popScene();
            });

        //目隠し
        this.mask = tm.display.Shape(SC_W, SC_H)
            .addChildTo(this)
            .setPosition(SC_W*0.5, SC_H*0.5)
            .renderRectangle({fillStyle: "rgba(0, 0, 0, 1.0)", strokeStyle: "rgba(0, 0, 0, 1.0)"});
        this.mask.tweener.clear().fadeOut(200);

        //サウンドテスト
//        this.addSountTestButton();

        this.time = 0;
    },

    setVolumeBGM: function(vol) {
        vol = Math.clamp(vol, 0, 10);
        appMain.sounds.volumeBGM = vol;
        for (var i = 0; i < 10; i++) {
            if (i < vol) {
                this.bgm[i].setFrameIndex(i);
            } else {
                this.bgm[i].setFrameIndex(52);
            }
        }
    },

    setVolumeSE: function(vol) {
        vol = Math.clamp(vol, 0, 10);
        if (vol != appMain.sounds.volumeSE) appMain.playSE("hand");

        appMain.sounds.volumeSE = vol;
        for (var i = 0; i < 10; i++) {
            if (i < vol) {
                this.se[i].setFrameIndex(i+13*3);
            } else {
                this.se[i].setFrameIndex(53);
            }
        }
    },

    //サウンドテストボタン追加
    addSoundTestButton: function() {
        var width = 150, height = 70;
        shotgun.Button(width, height, "BGM1")
            .addChildTo(this)
            .setPosition(SC_W*0.2, SC_H*0.7)
            .addEventListener("pushed", function() {
                tm.asset.AssetManager.get("titleBGM").clone().play();
            });
        shotgun.Button(width, height, "BGM2")
            .addChildTo(this)
            .setPosition(SC_W*0.5, SC_H*0.7)
            .addEventListener("pushed", function() {
                tm.asset.AssetManager.get("mainBGM").clone().play();
            });
        shotgun.Button(width, height, "BGM3")
            .addChildTo(this)
            .setPosition(SC_W*0.8, SC_H*0.7)
            .addEventListener("pushed", function() {
                tm.asset.AssetManager.get("tutorialBGM").clone().play();
            });

        var width = 100, height = 70;
        shotgun.Button(width, height, "SE1")
            .addChildTo(this)
            .setPosition(SC_W*0.1, SC_H*0.8)
            .addEventListener("pushed", function() {
                tm.asset.AssetManager.get("countdown").clone().play();
            });
        shotgun.Button(width, height, "SE2")
            .addChildTo(this)
            .setPosition(SC_W*0.3, SC_H*0.8)
            .addEventListener("pushed", function() {
                tm.asset.AssetManager.get("deal").clone().play();
            });
        shotgun.Button(width, height, "SE3")
            .addChildTo(this)
            .setPosition(SC_W*0.5, SC_H*0.8)
            .addEventListener("pushed", function() {
                tm.asset.AssetManager.get("dist").clone().play();
            });
        shotgun.Button(width, height, "SE4")
            .addChildTo(this)
            .setPosition(SC_W*0.7, SC_H*0.8)
            .addEventListener("pushed", function() {
                tm.asset.AssetManager.get("hand").clone().play();
            });
        shotgun.Button(width, height, "SE5")
            .addChildTo(this)
            .setPosition(SC_W*0.9, SC_H*0.8)
            .addEventListener("pushed", function() {
                tm.asset.AssetManager.get("nopair").clone().play();
            });
    },

    update: function() {
        this.time++;
    },

    //タッチorクリック開始処理
    ontouchstart: function(e) {
    },

    //タッチorクリック移動処理
    ontouchmove: function(e) {
        var sx = e.pointing.x;
        var sy = e.pointing.y;

        sx += 22;
        if (SC_W*0.10 < sx && sx < SC_W*0.25+440) {
            var x = ~~((sx-(SC_W*0.25))/44)+1;
            //ＢＧＭボリューム
            if ( SC_H*0.25 < sy && sy < SC_H*0.35) {
                if (sx < SC_W*0.25) {
                    this.setVolumeBGM(0);
                } else {
                    this.setVolumeBGM(x);
                }
            }

            //ＳＥボリューム
            if ( SC_H*0.35 < sy && sy < SC_H*0.45) {
                if (sx < SC_W*0.25) {
                    this.setVolumeSE(0);
                } else {
                    this.setVolumeSE(x);
                }
            }
        }
    },

    //タッチorクリック終了処理
    ontouchend: function(e) {
    },
});

<commit_msg>音量設定修正<commit_after>/*
 *  SettingScene.js
 *  2014/06/25
 *  @auther minimo
 *  This Program is MIT license.
 *
 */

tm.define("shotgun.SettingScene", {
    superClass: tm.app.Scene,

    bgm: null,
    se: null,

    //ラベル用フォントパラメータ
    labelParam: {fontFamily:"azuki", align: "center", baseline:"middle", outlineWidth:2 },

    init: function() {
        this.superInit();
        this.background = "rgba(0, 0, 0, 0.0)";
        var that = this;

        //バックグラウンド
        tm.display.Shape(SC_W, SC_H)
            .addChildTo(this)
            .setPosition(SC_W*0.5, SC_H*0.5)
            .renderRectangle({fillStyle: appMain.bgColor, strokeStyle: appMain.bgColor});

        tm.display.OutlineLabel("OPTION", 60)
            .addChildTo(this)
            .setParam(this.labelParam)
            .setPosition(SC_W*0.5, SC_H*0.1);

        tm.display.OutlineLabel("SOUND VOLUME", 50)
            .addChildTo(this)
            .setParam(this.labelParam)
            .setPosition(SC_W*0.5, SC_H*0.2);

        //ＢＧＭ音量
        var volBGM = appMain.sounds.volumeBGM;
        tm.display.OutlineLabel("BGM", 60)
            .addChildTo(this)
            .setParam(this.labelParam)
            .setPosition(SC_W*0.1, SC_H*0.3);
        this.bgm = [];
        for (var i = 0; i < 10; i++) {
            this.bgm[i] = tm.display.Sprite("card", CARD_W, CARD_H)
                .addChildTo(this)
                .setScale(0.3)
                .setPosition(SC_W*0.25+i*44, SC_H*0.3)
            this.bgm[i].num = i;
            if (i < volBGM) {
                this.bgm[i].setFrameIndex(i);
            } else {
                this.bgm[i].setFrameIndex(52);
            }
        }

        //ＳＥ音量
        var volSE = appMain.sounds.volumeSE;
        tm.display.OutlineLabel("SE", 60)
            .addChildTo(this)
            .setParam(this.labelParam)
            .setPosition(SC_W*0.1, SC_H*0.4);
        this.se = [];
        for (var i = 0; i < 10; i++) {
            this.se[i] = tm.display.Sprite("card", CARD_W, CARD_H)
                .addChildTo(this)
                .setScale(0.3)
                .setPosition(SC_W*0.25+i*44, SC_H*0.4)
            this.se[i].num = i;
            if (i < volSE) {
                this.se[i].setFrameIndex(i+13*3);
            } else {
                this.se[i].setFrameIndex(53);
            }
        }

        //戻るボタン
        var width = 300, height = 70;
        shotgun.Button(width, height, "RETURN")
            .addChildTo(this)
            .setPosition(SC_W*0.5, SC_H*0.9)
            .addEventListener("pushed", function() {
                that.mask.tweener.clear().fadeOut(200);
                appMain.saveConfig();
                appMain.popScene();
            });

        //目隠し
        this.mask = tm.display.Shape(SC_W, SC_H)
            .addChildTo(this)
            .setPosition(SC_W*0.5, SC_H*0.5)
            .renderRectangle({fillStyle: "rgba(0, 0, 0, 1.0)", strokeStyle: "rgba(0, 0, 0, 1.0)"});
        this.mask.tweener.clear().fadeOut(200);

        //サウンドテスト
//        this.addSountTestButton();

        this.time = 0;
    },

    setVolumeBGM: function(vol) {
        vol = Math.clamp(vol, 0, 10);
        appMain.sounds.volumeBGM = vol;
        for (var i = 0; i < 10; i++) {
            this.bgm[i].setFrameIndex(52).setScale(0.3);
            if (i == vol-1) {
                this.bgm[i].remove().addChildTo(this);
                this.bgm[i].setFrameIndex(i).setScale(0.5);
            } else {
                this.bgm[i].setFrameIndex(52).setScale(0.3);
            }
        }
    },

    setVolumeSE: function(vol) {
        vol = Math.clamp(vol, 0, 10);
        if (vol != appMain.sounds.volumeSE) appMain.playSE("hand");
        appMain.sounds.volumeSE = vol;
        for (var i = 0; i < 10; i++) {
            this.se[i].setFrameIndex(53).setScale(0.3);
            if (i < vol) {
                this.se[i].remove().addChildTo(this);
                this.se[i].setFrameIndex(i).setScale(0.5);
            } else {
                this.se[i].setFrameIndex(53).setScale(0.3);
            }
        }
    },

    //サウンドテストボタン追加
    addSoundTestButton: function() {
        var width = 150, height = 70;
        shotgun.Button(width, height, "BGM1")
            .addChildTo(this)
            .setPosition(SC_W*0.2, SC_H*0.7)
            .addEventListener("pushed", function() {
                tm.asset.AssetManager.get("titleBGM").clone().play();
            });
        shotgun.Button(width, height, "BGM2")
            .addChildTo(this)
            .setPosition(SC_W*0.5, SC_H*0.7)
            .addEventListener("pushed", function() {
                tm.asset.AssetManager.get("mainBGM").clone().play();
            });
        shotgun.Button(width, height, "BGM3")
            .addChildTo(this)
            .setPosition(SC_W*0.8, SC_H*0.7)
            .addEventListener("pushed", function() {
                tm.asset.AssetManager.get("tutorialBGM").clone().play();
            });

        var width = 100, height = 70;
        shotgun.Button(width, height, "SE1")
            .addChildTo(this)
            .setPosition(SC_W*0.1, SC_H*0.8)
            .addEventListener("pushed", function() {
                tm.asset.AssetManager.get("countdown").clone().play();
            });
        shotgun.Button(width, height, "SE2")
            .addChildTo(this)
            .setPosition(SC_W*0.3, SC_H*0.8)
            .addEventListener("pushed", function() {
                tm.asset.AssetManager.get("deal").clone().play();
            });
        shotgun.Button(width, height, "SE3")
            .addChildTo(this)
            .setPosition(SC_W*0.5, SC_H*0.8)
            .addEventListener("pushed", function() {
                tm.asset.AssetManager.get("dist").clone().play();
            });
        shotgun.Button(width, height, "SE4")
            .addChildTo(this)
            .setPosition(SC_W*0.7, SC_H*0.8)
            .addEventListener("pushed", function() {
                tm.asset.AssetManager.get("hand").clone().play();
            });
        shotgun.Button(width, height, "SE5")
            .addChildTo(this)
            .setPosition(SC_W*0.9, SC_H*0.8)
            .addEventListener("pushed", function() {
                tm.asset.AssetManager.get("nopair").clone().play();
            });
    },

    update: function() {
        this.time++;
    },

    //タッチorクリック開始処理
    ontouchstart: function(e) {
    },

    //タッチorクリック移動処理
    ontouchmove: function(e) {
        var sx = e.pointing.x;
        var sy = e.pointing.y;

        sx += 22;
        if (SC_W*0.10 < sx && sx < SC_W*0.25+440) {
            sx -= SC_W*0.25;
            var x = ~~(sx/44)+1;
            //ＢＧＭボリューム
            if ( SC_H*0.25 < sy && sy < SC_H*0.35) {
                if (sx < 0) {
                    this.setVolumeBGM(0);
                } else {
                    this.setVolumeBGM(x);
                }
            }

            //ＳＥボリューム
            if ( SC_H*0.35 < sy && sy < SC_H*0.45) {
                if (sx < 0) {
                    this.setVolumeSE(0);
                } else {
                    this.setVolumeSE(x);
                }
            }
        }
    },

    //タッチorクリック終了処理
    ontouchend: function(e) {
    },
});

<|endoftext|>


<commit_before>////////////////////////////////////////////////
/*   Provided Code - Please Don't Edit   */
////////////////////////////////////////////////
'use strict';

function getInput() {
    console.log("Please choose either 'rock', 'paper', or 'scissors'.")
    return prompt();
}
function randomPlay() {
    var randomNumber = Math.random();
    if (randomNumber < 0.33) {
        return "rock";
    } else if (randomNumber < 0.66) {
        return "paper";
    } else {
        return "scissors";
    }
}
////////////////////////////////////////////////
/*           Write Your Code Below            */
////////////////////////////////////////////////

function getPlayerMove(move) {
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `getInput()`.
    return
    var move;
    move = move || getInput()
    ;

}

function getComputerMove(move) {
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `randomPlay()`.
    return
    var move;
    move = move || getInput()
    ;
}

function getWinner(playerMove,computerMove) {
    var winner;
    // Write code that will set winner to either 'player', 'computer', or 'tie' based on the values of playerMove and computerMove.
    // Assume that the only values playerMove and computerMove can have are 'rock', 'paper', and 'scissors'.
    // The rules of the game are that 'rock' beats 'scissors', 'scissors' beats 'paper', and 'paper' beats 'rock'.
    /* YOUR CODE HERE */

    return winner;
}

function playToFive() {
    console.log("Let's play Rock, Paper, Scissors");
    var playerWins = 0;
    var computerWins = 0;
    // Write code that plays 'Rock, Paper, Scissors' until either the player or the computer has won five times.
    /* YOUR CODE HERE */
    return [playerWins, computerWins];
}

<commit_msg>loop added for win to 5 - some uncertainties here<commit_after>////////////////////////////////////////////////
/*   Provided Code - Please Don't Edit   */
////////////////////////////////////////////////
'use strict';

function getInput() {
    console.log("Please choose either 'rock', 'paper', or 'scissors'.")
    return prompt();
}
function randomPlay() {
    var randomNumber = Math.random();
    if (randomNumber < 0.33) {
        return "rock";
    } else if (randomNumber < 0.66) {
        return "paper";
    } else {
        return "scissors";
    }
}
////////////////////////////////////////////////
/*           Write Your Code Below            */
////////////////////////////////////////////////

function getPlayerMove(move) {
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `getInput()`.
    return
    var move;
    move = move || getInput()
    ;

}

function getComputerMove(move) {
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `randomPlay()`.
    return
    var move;
    move = move || getInput()
    ;
}

function getWinner(playerMove,computerMove) {
    var winner;
    // Write code that will set winner to either 'player', 'computer', or 'tie' based on the values of playerMove and computerMove.
    // Assume that the only values playerMove and computerMove can have are 'rock', 'paper', and 'scissors'.
    // The rules of the game are that 'rock' beats 'scissors', 'scissors' beats 'paper', and 'paper' beats 'rock'.
    /* YOUR CODE HERE */
    {
    if (ComputerMove===PlayerMove){
        result='Draw';
        console.log(result);
    }
    else if(ComputerMove==='Scissors'&&PlayerMove==='Paper'){
        result='Computer';
        console.log(result);
    }
    else if(ComputerMove==='Rock'&&PlayerMove==='Scissors'){
        result='Computer';
        console.log(result);
    }
    else if(ComputerMove==='Paper'&&PlayerMove==='Rock'){
        result='Computer';
        console.log(result);
    }
    else if(PlayerMove==='Scissors'&&ComputerMove==='Paper'){
        result='Player';
        console.log(result);
    }
    else if(PlayerMove==='Rock'&&ComputerMove==='Scissors'){
        result='Player';
        console.log(result);
    }
    else{
        result='Player';
        console.log(result)
    }
}
    return winner;
}

function playToFive() {
    console.log("Let's play Rock, Paper, Scissors");
    var playerWins = 0;
    var computerWins = 0;
    // Write code that plays 'Rock, Paper, Scissors' until either the player or the computer has won five times.
    /* YOUR CODE HERE */
    for (var i=1; i<5; i+=1){
        if (winner==='Player'){
            result = playerWins +1;

        if (winner=== 'Computer')
            result = computerWins +1;

        }
    }
    return [playerWins, computerWins];
}

<|endoftext|>