<commit_before>/*
 * Copyright (C) 2013 salesforce.com, inc.
 *
 * 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.
 */

/*jslint sub: true */

/**
 * Construct a SecureWindow.
 *
 * @public
 * @class
 * @constructor
 *
 * @param {Object}
 *            win - the DOM window
 * @param {Object}
 *            key - the key to apply to the secure window
 */
function SecureWindow(win, key, globalAttributeWhitelist) {
	"use strict";

    var hostedDefinedGlobals = ["alert", "clearInterval", "clearTimeout", "confirm", "console", "DOMParser", "FileReader",
                                "location", "Node", "requestAnimationFrame", "cancelAnimationFrame"];

	var o = Object.create(null, {
		document: {
			enumerable: true,
			value: SecureDocument(win.document, key)
		},
		"$A": {
			enumerable: true,
			value: SecureAura(win['$A'], key)
		},
		window: {
			enumerable: true,
			get: function () {
				// circular window references to match DOM API
				return o;
			}
		},
		navigator: {
			enumerable: true,
			value: SecureNavigator(win.navigator, key)
		},
		XMLHttpRequest: {
			enumerable: true,
			value: SecureXMLHttpRequest(key)
		},
		setTimeout: {
			enumerable: true,
			value: function (callback) {
				setTimeout.apply(win, [SecureObject.FunctionPrototypeBind.call(callback, o)].concat(SecureObject.ArrayPrototypeSlice.call(arguments, 1)));
			}
		},
		setInterval: {
			enumerable: true,
			value: function (callback) {
				setInterval.apply(win, [SecureObject.FunctionPrototypeBind.call(callback, o)].concat(SecureObject.ArrayPrototypeSlice.call(arguments, 1)));
			}
		},
		toString: {
			value: function() {
				return "SecureWindow: " + win + "{ key: " + JSON.stringify(key) + " }";
			}
		}
	});

	[ "outerHeight", "outerWidth" ].forEach(function(name) {
		SecureObject.addPropertyIfSupported(o, win, name, {
			filterOpaque : true
		});
	});

	[ "getComputedStyle", "scroll", "scrollBy", "scrollTo" ].forEach(function(name) {
		SecureObject.addMethodIfSupported(o, win, name, {
			filterOpaque : true
		});
	});

	SecureElement.addSecureGlobalEventHandlers(o, win, key);
	SecureElement.addEventTargetMethods(o, win, key);

    // Salesforce API entry points (first phase) - W-3046191 is tracking adding $A.lockerService.publish() API enhancement where we will move these
    // to their respective javascript/container architectures
    ["sforce", "Sfdc"].forEach(function(name) {
		SecureObject.addPropertyIfSupported(o, win, name);
	});

	setLockerSecret(o, "key", key);
	setLockerSecret(o, "ref", win);

	// Has to happen last because it depends on the secure getters defined above that require the object to be keyed
	globalAttributeWhitelist.forEach(function(name) {
		// These are direct passthrough's and should never be wrapped in a SecureObject
		Object.defineProperty(o, name, {
			enumerable: true,
			value: win[name]
		});
	});

	hostedDefinedGlobals.forEach(function(name) {
		if (!(name in o) && (name in win)) {
			// These are direct passthrough's and should never be wrapped in a SecureObject
			var value = win[name];
			Object.defineProperty(o, name, {
				enumerable: true,
				value: value.bind ? value.bind(win) : value
			});
		}
	});

	return o;
}
<commit_msg>Locker Service - window.btoa() and window.atob() not supported<commit_after>/*
 * Copyright (C) 2013 salesforce.com, inc.
 *
 * 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.
 */

/*jslint sub: true */

/**
 * Construct a SecureWindow.
 *
 * @public
 * @class
 * @constructor
 *
 * @param {Object}
 *            win - the DOM window
 * @param {Object}
 *            key - the key to apply to the secure window
 */
function SecureWindow(win, key, globalAttributeWhitelist) {
	"use strict";

    var hostedDefinedGlobals = ["alert", "clearInterval", "clearTimeout", "confirm", "console", "DOMParser", "FileReader",
                                "location", "Node", "requestAnimationFrame", "cancelAnimationFrame", "atob", "btoa"];

	var o = Object.create(null, {
		document: {
			enumerable: true,
			value: SecureDocument(win.document, key)
		},
		"$A": {
			enumerable: true,
			value: SecureAura(win['$A'], key)
		},
		window: {
			enumerable: true,
			get: function () {
				// circular window references to match DOM API
				return o;
			}
		},
		navigator: {
			enumerable: true,
			value: SecureNavigator(win.navigator, key)
		},
		XMLHttpRequest: {
			enumerable: true,
			value: SecureXMLHttpRequest(key)
		},
		setTimeout: {
			enumerable: true,
			value: function (callback) {
				setTimeout.apply(win, [SecureObject.FunctionPrototypeBind.call(callback, o)].concat(SecureObject.ArrayPrototypeSlice.call(arguments, 1)));
			}
		},
		setInterval: {
			enumerable: true,
			value: function (callback) {
				setInterval.apply(win, [SecureObject.FunctionPrototypeBind.call(callback, o)].concat(SecureObject.ArrayPrototypeSlice.call(arguments, 1)));
			}
		},
		toString: {
			value: function() {
				return "SecureWindow: " + win + "{ key: " + JSON.stringify(key) + " }";
			}
		}
	});

	[ "outerHeight", "outerWidth" ].forEach(function(name) {
		SecureObject.addPropertyIfSupported(o, win, name, {
			filterOpaque : true
		});
	});

	[ "getComputedStyle", "scroll", "scrollBy", "scrollTo" ].forEach(function(name) {
		SecureObject.addMethodIfSupported(o, win, name, {
			filterOpaque : true
		});
	});

	SecureElement.addSecureGlobalEventHandlers(o, win, key);
	SecureElement.addEventTargetMethods(o, win, key);

    // Salesforce API entry points (first phase) - W-3046191 is tracking adding $A.lockerService.publish() API enhancement where we will move these
    // to their respective javascript/container architectures
    ["sforce", "Sfdc"].forEach(function(name) {
		SecureObject.addPropertyIfSupported(o, win, name);
	});

	setLockerSecret(o, "key", key);
	setLockerSecret(o, "ref", win);

	// Has to happen last because it depends on the secure getters defined above that require the object to be keyed
	globalAttributeWhitelist.forEach(function(name) {
		// These are direct passthrough's and should never be wrapped in a SecureObject
		Object.defineProperty(o, name, {
			enumerable: true,
			value: win[name]
		});
	});

	hostedDefinedGlobals.forEach(function(name) {
		if (!(name in o) && (name in win)) {
			// These are direct passthrough's and should never be wrapped in a SecureObject
			var value = win[name];
			Object.defineProperty(o, name, {
				enumerable: true,
				value: value.bind ? value.bind(win) : value
			});
		}
	});

	return o;
}
<|endoftext|>


<commit_before>'use strict'
var fs = require('fs');
var _ = require('lodash');

            // let result = {
            //     fileDescription: fileDescription,
            //     videos: videos,
            //     caches: caches,
            //     requests: requests,
            //     endpoints: endpoints
            // };
			        //             caches.push({
                    //     id: i,
                    //     size: fileDescription.cacheSize,
                    //     remainingSize: fileDescription.cacheSize
					                        // videos: []
                    // });

                    // videos.push({
                    //     id: i,
                    //     size: +videoSizeResult[i + 1]
                    // });

function process(data, outputFile){
	dispatchVideos(data);
	writeOutput(transformToResult(data), outputFile);
}

function dispatchVideos(data) {
	let currentCacheIndex = 0;
	let currentCache = data.caches[currentCacheIndex];
	data.videos.forEach((video) => {
		if(currentCache.remainingSize >= video.size) {
			currentCache.videos.push(video);
			currentCache.remainingSize -= video.size;
		} else {
			currentCacheIndex++;
			if(currentCacheIndex >= data.caches.length) {
				return;
			}
			currentCache = data.caches[currentCacheIndex];
		}
	});
}

function transformToResult(data) {
	let nbUsedCaches = 0;
	let result = {
		nbCacheServers: 0,
		cacheServers: []
	};

	data.caches.forEach((cache) => {
		if(cache.videos.length > 0) {
			nbUsedCaches++;
			result.cacheServers.push({
				id: cache.id,
				videoIds: _.map(cache.videos, (video) => video.id)
			});
		}
	});

	result.nbCacheServers = nbUsedCaches;
	return result;
}

function writeOutput(result, fileName) {
	var outputFile = fs.createWriteStream('outputs/'+(fileName ? fileName : 'output.out'));
	outputFile.write(`${result.nbCacheServers} \n`) // append string to your file
	result.cacheServers.forEach((cache) => {
		let join = cache.videoIds.join(' ');
		outputFile.write(`${cache.id} ${join}\n`); // again
	});
	outputFile.end();
}

module.exports = {
	process : process
}<commit_msg>v1 crade : score 2 109 779<commit_after>'use strict'
var fs = require('fs');
var _ = require('lodash');

            // let result = {
            //     fileDescription: fileDescription,
            //     videos: videos,
            //     caches: caches,
            //     requests: requests,
            //     endpoints: endpoints
            // };
			        //             caches.push({
                    //     id: i,
                    //     size: fileDescription.cacheSize,
                    //     remainingSize: fileDescription.cacheSize
					                        // videos: []
                    // });

                    // videos.push({
                    //     id: i,
                    //     size: +videoSizeResult[i + 1]
                    // });
                // endpoints[endPointIndex] = {
                //     id: endPointIndex,
                //     datacenterLatency: +endPointRegexResult[1],
                //     caches: []
                // };

					//                     requests.push({
                    //     videoId: +requestRegexResult[1],
                    //     endpointId: +requestRegexResult[2],
                    //     nbRequests: +requestRegexResult[3]
                    // });
                // endpoints[endPointIndex - 1].caches.push({
                //     id: +endpointCacheRegexResult[1],
                //     cacheLatency: +endpointCacheRegexResult[2]
                // });

function process(data, outputFile){
	let sortedVideosByLatencyPerEndpointId = assignVideosToEndpoint(data);
	let sortedCachesByLatencyPerEndpointId = assignCachesToEndpoint(data);
	let sortedVideosEndpointCombinations = getMostExpensiveVideos(sortedVideosByLatencyPerEndpointId);

	dispatchVideos(data, sortedVideosEndpointCombinations, sortedCachesByLatencyPerEndpointId);
	writeOutput(transformToResult(data), outputFile);
}

function assignVideosToEndpoint(data) {
	let requestsByEndpointId = _.groupBy(data.requests, 'endpointId');
	let totalLatencyToDatacenterPerVideoPerEndpointId = {};
	_.forIn(requestsByEndpointId, (endpointRequests, endpointId) => {
		totalLatencyToDatacenterPerVideoPerEndpointId[endpointId] = _.mapValues(_.groupBy(endpointRequests, 'videoId'), (requestsPerVideo) => {
			return {
				endpointId: endpointId,
				videoLatency: _.sumBy(requestsPerVideo, 'nbRequests') * data.endpoints[endpointId].datacenterLatency
			};
		});
	});

	let sortedVideosByLatencyPerEndpointId = _.mapValues(totalLatencyToDatacenterPerVideoPerEndpointId, (endpointVideoLatencies) => {
		let array = [];
		_.forIn(endpointVideoLatencies, (videoLatencyWithEndpointId, videoId) => {
			array.push({
				videoId: videoId,
				videoLatency: videoLatencyWithEndpointId.videoLatency,
				endpointId: videoLatencyWithEndpointId.endpointId
			});

		});

		return _.orderBy(array, 'videoLatency', 'desc');
	});
	return sortedVideosByLatencyPerEndpointId;
}

function assignCachesToEndpoint(data) {
	let sortedCachesByLatencyPerEndpointId = {};
	_.each(data.endpoints, (endpoint) => {
		sortedCachesByLatencyPerEndpointId[endpoint.id] = _.orderBy(endpoint.caches, 'cacheLatency', 'asc');
	});
	return sortedCachesByLatencyPerEndpointId;
}

function getMostExpensiveVideos(sortedVideosByLatencyPerEndpointId) {
	// _.map()
	// console.log(sortedVideosByLatencyPerEndpointId);
	return _.orderBy(_.flatten(_.values(sortedVideosByLatencyPerEndpointId)), 'videoLatency', 'desc');
}
function sortCachesForEndpoint() {

}

function sortMostExpensiveVideosForEndpoint() {

}
function dispatchVideos(inputData, sortedVideosEndpointCombinations, sortedCachesByLatencyPerEndpointId) {
	// console.log(sortedVideosEndpointCombinations);
	_.mapValues(sortedVideosEndpointCombinations,(videoEndpointCombination) => {
		// console.log(videoEndpointCombination)
		chooseBestCache(inputData, sortedCachesByLatencyPerEndpointId[videoEndpointCombination.endpointId], videoEndpointCombination.videoId);
// ca peut retourner null

	});
	// let currentCacheIndex = 0;
	// let currentCache = data.caches[currentCacheIndex];
	// data.videos.forEach((video) => {
	// 	if(currentCache.remainingSize >= video.size) {
	// 		currentCache.videos.push(video);
	// 		currentCache.remainingSize -= video.size;
	// 	} else {
	// 		currentCacheIndex++;
	// 		if(currentCacheIndex >= data.caches.length) {
	// 			return;
	// 		}
	// 		currentCache = data.caches[currentCacheIndex];
	// 	}
	// });
}

function chooseBestCache(inputData, sortedCachesForEndpoint, videoId) {
	// console.log(inputData);
	let video = inputData.videos[videoId];
	let bestCache = null;
// console.log(videoId);
	_.each(sortedCachesForEndpoint, (cacheInfo) => {
		// console.log(cacheId);
		let cache = inputData.caches[cacheInfo.id];
		let videoAlreadyInCache = _.find(cache.videos, (video) => {
			return videoId == video.id;
		});
		// console.log("cacheId:" + cacheInfo.id +  " videoId:" + videoId + " foundincache:" + videoAlreadyInCache)

		if(videoAlreadyInCache) {
			return false;
		} else {
			if(cache.remainingSize >= video.size) {
				cache.videos.push(video);
				cache.remainingSize -= video.size;
				bestCache = cache;
				return false;
			}
		}

	});
}

function transformToResult(data) {
	let nbUsedCaches = 0;
	let result = {
		nbCacheServers: 0,
		cacheServers: []
	};

	data.caches.forEach((cache) => {
		if(cache.videos.length > 0) {
			nbUsedCaches++;
			result.cacheServers.push({
				id: cache.id,
				videoIds: _.map(cache.videos, (video) => video.id)
			});
		}
	});

	result.nbCacheServers = nbUsedCaches;
	return result;
}

function writeOutput(result, fileName) {
	var outputFile = fs.createWriteStream('outputs/'+(fileName ? fileName : 'output.out'));
	outputFile.write(`${result.nbCacheServers} \n`) // append string to your file
	result.cacheServers.forEach((cache) => {
		let join = cache.videoIds.join(' ');
		outputFile.write(`${cache.id} ${join}\n`); // again
	});
	outputFile.end();
}

module.exports = {
	process : process
}<|endoftext|>


<commit_before>'use strict';
var query_wizard = angular.module('cliffhanger.query_wizard', ['ngRoute', 'ngSanitize', 'ngCsv']);
query_wizard.controller('QueryWizardCtrl', function ($scope, $uibModalInstance, $log, datasets, queryService) {
    $scope.query = {}; //container for query
    $scope.alerts = [];
    $scope.tableResult = {};
    $scope.selected = {};
    $scope.step = 1; //which step in the modal is on
    $scope.maxSteps = 5; //number of steps in modal
    $scope.datasets = datasets;
    $scope.tags = []; //TODO load based upon datasets
    $scope.addJoinColumn = false; //whether to include joined column in select
    $scope.selectedDatasets = []; //datasets selected to be joined
    $scope.selectedTags = []; //selected join tags
    $scope.selectedColumns = []; //select columns for query
    //for save query dropdown
    $scope.isCollapsed = true;
    $scope.download = false;
    $scope.loadingPreview = false;
    //method responsible for handling changes due to checkboxes
    //d -> item selected/deselected
    //selections -> array to add/remove item
    $scope.change = function (d, selections) {
            if (d.selected) {
                selections.push(d);
            }
            else {
                for (var i = 0; i < selections.length; i++) {
                    $log.debug(selections[i]);
                    if (selections[i].name == d.name) {
                        selections.splice(i, 1);
                    }
                }
            }
            $log.debug(selections);
        }
        //method responsible for handling changes due to checkboxes
        //d -> item selected/deselected
        //selections -> array to add/remove item
    $scope.changeColumns = function (column, selections, dataset) {
            if (column.selected) {
                column.db_table_name = dataset.db_table_name;
                selections.push(column);
            }
            else {
                for (var i = 0; i < selections.length; i++) {
                    $log.debug(selections[i]);
                    if (selections[i].name == column.name) {
                        selections.splice(i, 1);
                    }
                }
            }
            $log.debug(selections);
        }
        //load the joinable tags only in the selected datasets
    $scope.loadTags = function () {
            for (var i = 0; i < $scope.selectedDatasets[0].tags.length; i++) {
                var tagA = $scope.selectedDatasets[0].tags[i];
                for (var j = 0; j < $scope.selectedDatasets[1].tags.length; j++) {
                    var tagB = $scope.selectedDatasets[1].tags[j];
                    //if tags match, aren't EMPTY and are not a duplicate
                    if (tagA.name == tagB.name && tagA.name != '<EMPTY>' && $scope.tags.indexOf(tagA) == -1) {
                        $scope.tags.push(tagA);
                        break;
                    }
                }
            }
            $log.debug($scope.tags);
        }
        //advance the modal to the next step
    $scope.next = function () {
        $scope.step++;
        if ($scope.step == 2) {
            $scope.loadTags();
        }
        else if ($scope.step == 4) $scope.buildQuery();
        else if ($scope.step == 5) {
            $scope.runQuery($scope.query);
        }
    };
    //go back a step in the modal
    $scope.previous = function () {
        $scope.step--;
        if ($scope.step < $scope.maxSteps) {
            $scope.progressType = null;
            $scope.tableResult = null;
        }
    };
    $scope.selectAllFromDataset = function (dataset) {
            for (var i = 0; i < dataset.attributes.length; i++) {
                var a = dataset.attributes[i];
                if ($scope.selected[dataset.name]) {
                    if (a.tag.name != $scope.selectedTags[0].name) {
                        a.db_table_name = dataset.db_table_name;
                        a.selected = true;
                        $scope.selectedColumns.push(a);
                    }
                }
                else {
                    a.selected = false;
                    for (var j = 0; j < $scope.selectedColumns.length; j++) {
                        if ($scope.selectedColumns[j].name == a.name) {
                            $scope.selectedColumns.splice(j, 1);
                        }
                    }
                }
            }
        }
        //dismiss the modal
    $scope.cancel = function () {
        $uibModalInstance.dismiss('cancel');
    };
    //add where and limit clause to SQL query string
    $scope.addToQuery = function () {
        if (($scope.statement.where == null && $scope.statement.limit == null) || ($scope.statement.where == "" && $scope.statement.limit == "") || ($scope.statement.where == null && $scope.statement.limit == "") || ($scope.statement.where == "" && $scope.statement.limit == null)) {
            $scope.query = $scope.query.replace(";", "");
            $scope.statement.text = ";";
        }
        //adding both WHERE and LIMIT statement
        else if ($scope.statement.where != null && $scope.statement.limit != null) {
            $scope.query = $scope.query.replace(";", "");
            $scope.statement.text = "\nWHERE " + $scope.statement.where + "\n" + "LIMIT " + $scope.statement.limit + ";";
        }
        //adding WHERE and not LIMIT
        else if (($scope.statement.where != null && $scope.statement.limit == null) || ($scope.statement.where != null && $scope.statement.limit == "")) {
            $scope.query = $scope.query.replace(";", "");
            $scope.statement.text = "\nWHERE " + $scope.statement.where + ";";
        }
        //adding LIMIT and not WHERE
        else if (($scope.statement.where == null && $scope.statement.limit != null) || ($scope.statement.where == "" && $scope.statement.limit != null)) {
            $scope.query = $scope.query.replace(";", "");
            $scope.statement.text = "\nLIMIT " + $scope.statement.limit + ";";
        }
        $log.debug($scope.statement);
    };
    //build a new query given the user's choices
    $scope.buildQuery = function () {
        //query input packaged
        var queryInput = {
            datasets: $scope.selectedDatasets
            , joinTag: $scope.selectedTags
            , addJoinColumn: $scope.addJoinColumn
            , columns: $scope.selectedColumns
        }
        queryService.buildQuery(queryInput).then(function (response) {
            //success callback
            if (response.status == 'Success') {
                $scope.query = response.data;
                $scope.progressType = 'success';
                //failure callback
            }
            else {
                $scope.progressType = 'danger';
                $scope.buildQueryError = true;
                $log.error(response.data);
            }
        });
    };
    //complete the modal
    $scope.save = function () {
        if ($scope.statement.text != null) {
            $scope.newQuery.sqlString = $scope.query + $scope.statement.text;
        }
        else {
            $scope.newQuery.sqlString = $scope.query;
        }
        queryService.saveQuery($scope.newQuery).then(function (data) {
            if (data.status == 'Success') {
                $log.debug(data);
            }
            else {
                $scope.alerts.push({
                    msg: data
                    , type: 'danger'
                });
            }
        }, function (data) {
            $scope.alerts.push({
                msg: 'Failed to create Query'
                , type: 'danger'
            });
        })
    };
    $scope.runQuery = function () {
        $scope.loadingPreview = true;
        var query = $scope.query;
        queryService.runQuery(query).then(function (response) { //success callback
                $scope.loadingPreview = false;
                $scope.tableResult = response;
                $scope.progressType = 'success';
            }, //failure to connect
            function (data) {
                $scope.loadingPreview = false;
                $scope.progressType = 'danger';
                $scope.runQueryError = true;
                $log.error('Failed to connect to server');
            });
    };
});
//need savequery controller<commit_msg>working on queries view<commit_after>'use strict';
var query_wizard = angular.module('cliffhanger.query_wizard', ['ngRoute', 'ngSanitize', 'ngCsv']);
query_wizard.controller('QueryWizardCtrl', function ($scope, $uibModalInstance, $log, datasets, queryService) {
            $scope.query = {}; //container for query
            $scope.alerts = [];
            $scope.tableResult = {};
            $scope.selected = {};
            $scope.step = 1; //which step in the modal is on
            $scope.maxSteps = 5; //number of steps in modal
            $scope.datasets = datasets;
            $scope.tags = []; //TODO load based upon datasets
            $scope.addJoinColumn = false; //whether to include joined column in select
            $scope.selectedDatasets = []; //datasets selected to be joined
            $scope.selectedTags = []; //selected join tags
            $scope.selectedColumns = []; //select columns for query
            //for save query dropdown
            $scope.isCollapsed = true;
            $scope.download = false;
            $scope.loadingPreview = false;
            //method responsible for handling changes due to checkboxes
            //d -> item selected/deselected
            //selections -> array to add/remove item
            $scope.change = function (d, selections) {
                    if (d.selected) {
                        selections.push(d);
                    }
                    else {
                        for (var i = 0; i < selections.length; i++) {
                            $log.debug(selections[i]);
                            if (selections[i].name == d.name) {
                                selections.splice(i, 1);
                            }
                        }
                    }
                    $log.debug(selections);
                }
                //method responsible for handling changes due to checkboxes
                //d -> item selected/deselected
                //selections -> array to add/remove item
            $scope.changeColumns = function (column, selections, dataset) {
                    if (column.selected) {
                        column.db_table_name = dataset.db_table_name;
                        selections.push(column);
                    }
                    else {
                        for (var i = 0; i < selections.length; i++) {
                            $log.debug(selections[i]);
                            if (selections[i].name == column.name) {
                                selections.splice(i, 1);
                            }
                        }
                    }
                    $log.debug(selections);
                }
                //load the joinable tags only in the selected datasets
            $scope.loadTags = function () {
                    for (var i = 0; i < $scope.selectedDatasets[0].tags.length; i++) {
                        var tagA = $scope.selectedDatasets[0].tags[i];
                        for (var j = 0; j < $scope.selectedDatasets[1].tags.length; j++) {
                            var tagB = $scope.selectedDatasets[1].tags[j];
                            //if tags match, aren't EMPTY and are not a duplicate
                            if (tagA.name == tagB.name && tagA.name != '<EMPTY>' && $scope.tags.indexOf(tagA) == -1) {
                                $scope.tags.push(tagA);
                                break;
                            }
                        }
                    }
                    $log.debug($scope.tags);
                }
                //advance the modal to the next step
            $scope.next = function () {
                $scope.step++;
                if ($scope.step == 2) {
                    $scope.loadTags();
                }
                else if ($scope.step == 4) $scope.buildQuery();
                else if ($scope.step == 5) {
                    $scope.runQuery($scope.query);
                }
            };
            //go back a step in the modal
            $scope.previous = function () {
                $scope.step--;
                if ($scope.step < $scope.maxSteps) {
                    $scope.progressType = null;
                    $scope.tableResult = null;
                }
            };
            $scope.selectAllFromDataset = function (dataset) {
                for (var i = 0; i < dataset.attributes.length; i++) {
                    var a = dataset.attributes[i];
                    //select all
                    if ($scope.selected[dataset.name]) {
                        //add column to selection
                        if (a.tag.name != $scope.selectedTags[0].name) {
                            a.db_table_name = dataset.db_table_name;
                            a.selected = true;
                            $scope.selectedColumns.push(a);
                        }
                    }
                    //deselect all
                    else {
                        a.selected = false;
                        //remove column from selection
                        for (var j = 0; j < $scope.selectedColumns.length; j++) {
                            if ($scope.selectedColumns[j].name == a.name) {
                                $scope.selectedColumns.splice(j, 1);
                            }
                        }
                    }
                }
                //dismiss the modal
                $scope.cancel = function () {
                    $uibModalInstance.dismiss('cancel');
                };
                //add where and limit clause to SQL query string
                $scope.addToQuery = function () {
                    if (($scope.statement.where == null && $scope.statement.limit == null) || ($scope.statement.where == "" && $scope.statement.limit == "") || ($scope.statement.where == null && $scope.statement.limit == "") || ($scope.statement.where == "" && $scope.statement.limit == null)) {
                        $scope.query = $scope.query.replace(";", "");
                        $scope.statement.text = ";";
                    }
                    //adding both WHERE and LIMIT statement
                    else if ($scope.statement.where != null && $scope.statement.limit != null) {
                        $scope.query = $scope.query.replace(";", "");
                        $scope.statement.text = "\nWHERE " + $scope.statement.where + "\n" + "LIMIT " + $scope.statement.limit + ";";
                    }
                    //adding WHERE and not LIMIT
                    else if (($scope.statement.where != null && $scope.statement.limit == null) || ($scope.statement.where != null && $scope.statement.limit == "")) {
                        $scope.query = $scope.query.replace(";", "");
                        $scope.statement.text = "\nWHERE " + $scope.statement.where + ";";
                    }
                    //adding LIMIT and not WHERE
                    else if (($scope.statement.where == null && $scope.statement.limit != null) || ($scope.statement.where == "" && $scope.statement.limit != null)) {
                        $scope.query = $scope.query.replace(";", "");
                        $scope.statement.text = "\nLIMIT " + $scope.statement.limit + ";";
                    }
                    $log.debug($scope.statement);
                };
                //build a new query given the user's choices
                $scope.buildQuery = function () {
                    //query input packaged
                    var queryInput = {
                        datasets: $scope.selectedDatasets
                        , joinTag: $scope.selectedTags
                        , addJoinColumn: $scope.addJoinColumn
                        , columns: $scope.selectedColumns
                    }
                    queryService.buildQuery(queryInput).then(function (response) {
                        //success callback
                        if (response.status == 'Success') {
                            $scope.query = response.data;
                            $scope.progressType = 'success';
                            //failure callback
                        }
                        else {
                            $scope.progressType = 'danger';
                            $scope.buildQueryError = true;
                            $log.error(response.data);
                        }
                    });
                };
                //complete the modal
                $scope.save = function () {
                    if ($scope.statement.text != null) {
                        $scope.newQuery.sqlString = $scope.query + $scope.statement.text;
                    }
                    else {
                        $scope.newQuery.sqlString = $scope.query;
                    }
                    queryService.saveQuery($scope.newQuery).then(function (data) {
                        if (data.status == 'Success') {
                            $log.debug(data);
                        }
                        else {
                            $scope.alerts.push({
                                msg: data
                                , type: 'danger'
                            });
                        }
                    }, function (data) {
                        $scope.alerts.push({
                            msg: 'Failed to create Query'
                            , type: 'danger'
                        });
                    })
                };
                $scope.runQuery = function () {
                    $scope.loadingPreview = true;
                    var query = $scope.query;
                    queryService.runQuery(query).then(function (response) { //success callback
                            $scope.loadingPreview = false;
                            $scope.tableResult = response;
                            $scope.progressType = 'success';
                        }, //failure to connect
                        function (data) {
                            $scope.loadingPreview = false;
                            $scope.progressType = 'danger';
                            $scope.runQueryError = true;
                            $log.error('Failed to connect to server');
                        });
                };
            });
        //need savequery controller<|endoftext|>


<commit_before>var THREEx = THREEx || {}

THREEx.ArToolkitSource = function(parameters){
	// handle default parameters
	this.parameters = {
		// type of source - ['webcam', 'image', 'video']
		sourceType : parameters.sourceType !== undefined ? parameters.sourceType : 'webcam',
		// url of the source - valid if sourceType = image|video
		sourceUrl : parameters.sourceUrl !== undefined ? parameters.sourceUrl : null,

		// resolution of at which we initialize in the source image
		sourceWidth: parameters.sourceWidth !== undefined ? parameters.sourceWidth : 640,
		sourceHeight: parameters.sourceHeight !== undefined ? parameters.sourceHeight : 480,
		// resolution displayed for the source
		displayWidth: parameters.displayWidth !== undefined ? parameters.displayWidth : 640,
		displayHeight: parameters.displayHeight !== undefined ? parameters.displayHeight : 480,
	}

	this.ready = false
        this.domElement = null
}

//////////////////////////////////////////////////////////////////////////////
//		Code Separator
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitSource.prototype.init = function(onReady){
	var _this = this

        if( this.parameters.sourceType === 'image' ){
                var domElement = this._initSourceImage(onSourceReady)
        }else if( this.parameters.sourceType === 'video' ){
                var domElement = this._initSourceVideo(onSourceReady)
        }else if( this.parameters.sourceType === 'webcam' ){
                var domElement = this._initSourceWebcam(onSourceReady)
        }else{
                console.assert(false)
        }

	// attach
        this.domElement = domElement
        this.domElement.style.position = 'absolute'
        this.domElement.style.top = '0px'
        this.domElement.style.zIndex = '-2'
        this.domElement.style.zIndex = '-2'

	return this
        function onSourceReady(){
		document.body.appendChild(_this.domElement);

		_this.ready = true

		onReady && onReady()
        }
}

////////////////////////////////////////////////////////////////////////////////
//          init image source
////////////////////////////////////////////////////////////////////////////////

THREEx.ArToolkitSource.prototype._initSourceImage = function(onReady) {
	// TODO make it static
        var domElement = document.createElement('img')
	domElement.src = this.parameters.sourceUrl

	domElement.width = this.parameters.sourceWidth
	domElement.height = this.parameters.sourceHeight
	domElement.style.width = this.parameters.displayWidth+'px'
	domElement.style.height = this.parameters.displayHeight+'px'

	// wait until the video stream is ready
	var interval = setInterval(function() {
		if (!domElement.naturalWidth)	return;
		onReady()
		clearInterval(interval)
	}, 1000/50);

	return domElement
}

////////////////////////////////////////////////////////////////////////////////
//          init video source
////////////////////////////////////////////////////////////////////////////////

THREEx.ArToolkitSource.prototype._initSourceVideo = function(onReady) {
	// TODO make it static
	var domElement = document.createElement('video');
	domElement.src = this.parameters.sourceUrl

	domElement.style.objectFit = 'initial'

	domElement.autoplay = true;
	domElement.webkitPlaysinline = true;
	domElement.controls = false;
	domElement.loop = true;
	domElement.muted = true

	// trick to trigger the video on android
	document.body.addEventListener('click', function onClick(){
		document.body.removeEventListener('click', onClick);
		domElement.play()
	})

	domElement.width = this.parameters.sourceWidth
	domElement.height = this.parameters.sourceHeight
	domElement.style.width = this.parameters.displayWidth+'px'
	domElement.style.height = this.parameters.displayHeight+'px'

	// wait until the video stream is ready
	var interval = setInterval(function() {
		if (!domElement.videoWidth)	return;
		onReady()
		clearInterval(interval)
	}, 1000/50);
	return domElement
}

////////////////////////////////////////////////////////////////////////////////
//          handle webcam source
////////////////////////////////////////////////////////////////////////////////

THREEx.ArToolkitSource.prototype._initSourceWebcam = function(onReady) {
	var _this = this
	// TODO make it static
	navigator.getUserMedia  = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;

	var domElement = document.createElement('video');
	domElement.style.width = this.parameters.displayWidth+'px'
	domElement.style.height = this.parameters.displayHeight+'px'

	if (navigator.getUserMedia === undefined ){
		alert("WebRTC issue! navigator.getUserMedia not present in your browser");
	}
	if (navigator.mediaDevices === undefined || navigator.mediaDevices.enumerateDevices === undefined ){
		alert("WebRTC issue! navigator.mediaDevices.enumerateDevices not present in your browser");
	}

	navigator.mediaDevices.enumerateDevices().then(function(devices) {
                // define getUserMedia() constraints
                var constraints = {
			audio: false,
			video: {
				mandatory: {
					maxWidth: _this.parameters.sourceWidth,
					maxHeight: _this.parameters.sourceHeight
		    		}
		  	}
                }

		devices.forEach(function(device) {
			if( device.kind !== 'videoinput' )	return
			if( constraints.video.optional !== undefined )	return
			constraints.video.optional = [{sourceId: device.deviceId}]
		});

		// OLD API
                // it it finds the videoSource 'environment', modify constraints.video
                // for (var i = 0; i != sourceInfos.length; ++i) {
                //         var sourceInfo = sourceInfos[i];
                //         if(sourceInfo.kind == "video" && sourceInfo.facing == "environment") {
                //                 constraints.video.optional = [{sourceId: sourceInfo.id}]
                //         }
                // }

		navigator.getUserMedia(constraints, function success(stream) {
			// console.log('success', stream);
			domElement.src = window.URL.createObjectURL(stream);
			// to start the video, when it is possible to start it only on userevent. like in android
			document.body.addEventListener('click', function(){
				domElement.play();
			})
			// domElement.play();

			// wait until the video stream is ready
			var interval = setInterval(function() {
				if (!domElement.videoWidth)	return;
				onReady()
				clearInterval(interval)
			}, 1000/50);
		}, function(error) {
			console.log("Can't access user media", error);
			alert("Can't access user media :()");
		});
	}).catch(function(err) {
		console.log(err.name + ": " + err.message);
	});

	return domElement
}

////////////////////////////////////////////////////////////////////////////////
//          handle resize
////////////////////////////////////////////////////////////////////////////////

THREEx.ArToolkitSource.prototype.onResize = function(mirrorDomElements){
	var _this = this
	var screenWidth = window.innerWidth
	var screenHeight = window.innerHeight

	// compute sourceWidth, sourceHeight
	if( this.domElement.nodeName === "IMG" ){
		var sourceWidth = this.domElement.naturalWidth
		var sourceHeight = this.domElement.naturalHeight
	}else if( this.domElement.nodeName === "VIDEO" ){
		var sourceWidth = this.domElement.videoWidth
		var sourceHeight = this.domElement.videoHeight
	}else{
		console.assert(false)
	}

	// compute sourceAspect
	var sourceAspect = sourceWidth / sourceHeight
	// compute screenAspect
	var screenAspect = screenWidth / screenHeight

	// if screenAspect < sourceAspect, then change the width, else change the height
	if( screenAspect < sourceAspect ){
		// compute newWidth and set .width/.marginLeft
		var newWidth = sourceAspect * screenHeight
		this.domElement.style.width = newWidth+'px'
		this.domElement.style.marginLeft = -(newWidth-screenWidth)/2+'px'

		// init style.height/.marginTop to normal value
		this.domElement.style.height = screenHeight+'px'
		this.domElement.style.marginTop = '0px'
	}else{
		// compute newHeight and set .height/.marginTop
		var newHeight = 1 / (sourceAspect / screenWidth)
		this.domElement.style.height = newHeight+'px'
		this.domElement.style.marginTop = -(newHeight-screenHeight)/2+'px'

		// init style.width/.marginLeft to normal value
		this.domElement.style.width = screenWidth+'px'
		this.domElement.style.marginLeft = '0px'
	}

	// honor default parameters
	if( mirrorDomElements === undefined )	mirrorDomElements = []
	if( mirrorDomElements instanceof Array === false )	mirrorDomElements = [mirrorDomElements]

	// Mirror _this.domElement.style to mirrorDomElements
	mirrorDomElements.forEach(function(domElement){
		domElement.style.width = _this.domElement.style.width
		domElement.style.height = _this.domElement.style.height
		domElement.style.marginLeft = _this.domElement.style.marginLeft
		domElement.style.marginTop = _this.domElement.style.marginTop
	})
}
<commit_msg>more work<commit_after>var THREEx = THREEx || {}

THREEx.ArToolkitSource = function(parameters){
	// handle default parameters
	this.parameters = {
		// type of source - ['webcam', 'image', 'video']
		sourceType : parameters.sourceType !== undefined ? parameters.sourceType : 'webcam',
		// url of the source - valid if sourceType = image|video
		sourceUrl : parameters.sourceUrl !== undefined ? parameters.sourceUrl : null,

		// resolution of at which we initialize in the source image
		sourceWidth: parameters.sourceWidth !== undefined ? parameters.sourceWidth : 640,
		sourceHeight: parameters.sourceHeight !== undefined ? parameters.sourceHeight : 480,
		// resolution displayed for the source
		displayWidth: parameters.displayWidth !== undefined ? parameters.displayWidth : 640,
		displayHeight: parameters.displayHeight !== undefined ? parameters.displayHeight : 480,
	}

	this.ready = false
        this.domElement = null
}

//////////////////////////////////////////////////////////////////////////////
//		Code Separator
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitSource.prototype.init = function(onReady){
	var _this = this

        if( this.parameters.sourceType === 'image' ){
                var domElement = this._initSourceImage(onSourceReady)
        }else if( this.parameters.sourceType === 'video' ){
                var domElement = this._initSourceVideo(onSourceReady)
        }else if( this.parameters.sourceType === 'webcam' ){
                var domElement = this._initSourceWebcam(onSourceReady)
        }else{
                console.assert(false)
        }

	// attach
        this.domElement = domElement
        this.domElement.style.position = 'absolute'
        this.domElement.style.top = '0px'
        this.domElement.style.zIndex = '-2'
        this.domElement.style.zIndex = '-2'

	return this
        function onSourceReady(){
		document.body.appendChild(_this.domElement);

		_this.ready = true

		onReady && onReady()
        }
}

////////////////////////////////////////////////////////////////////////////////
//          init image source
////////////////////////////////////////////////////////////////////////////////

THREEx.ArToolkitSource.prototype._initSourceImage = function(onReady) {
	// TODO make it static
        var domElement = document.createElement('img')
	domElement.src = this.parameters.sourceUrl

	domElement.width = this.parameters.sourceWidth
	domElement.height = this.parameters.sourceHeight
	domElement.style.width = this.parameters.displayWidth+'px'
	domElement.style.height = this.parameters.displayHeight+'px'

	// wait until the video stream is ready
	var interval = setInterval(function() {
		if (!domElement.naturalWidth)	return;
		onReady()
		clearInterval(interval)
	}, 1000/50);

	return domElement
}

////////////////////////////////////////////////////////////////////////////////
//          init video source
////////////////////////////////////////////////////////////////////////////////

THREEx.ArToolkitSource.prototype._initSourceVideo = function(onReady) {
	// TODO make it static
	var domElement = document.createElement('video');
	domElement.src = this.parameters.sourceUrl

	domElement.style.objectFit = 'initial'

	domElement.autoplay = true;
	domElement.webkitPlaysinline = true;
	domElement.controls = false;
	domElement.loop = true;
	domElement.muted = true

	// trick to trigger the video on android
	document.body.addEventListener('click', function onClick(){
		document.body.removeEventListener('click', onClick);
		domElement.play()
	})

	domElement.width = this.parameters.sourceWidth
	domElement.height = this.parameters.sourceHeight
	domElement.style.width = this.parameters.displayWidth+'px'
	domElement.style.height = this.parameters.displayHeight+'px'

	// wait until the video stream is ready
	var interval = setInterval(function() {
		if (!domElement.videoWidth)	return;
		onReady()
		clearInterval(interval)
	}, 1000/50);
	return domElement
}

////////////////////////////////////////////////////////////////////////////////
//          handle webcam source
////////////////////////////////////////////////////////////////////////////////

THREEx.ArToolkitSource.prototype._initSourceWebcam = function(onReady) {
	var _this = this
	// TODO make it static
	navigator.getUserMedia  = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;

	var domElement = document.createElement('video');
	domElement.style.width = this.parameters.displayWidth+'px'
	domElement.style.height = this.parameters.displayHeight+'px'

	if (navigator.getUserMedia === undefined ){
		alert("WebRTC issue! navigator.getUserMedia not present in your browser");
	}
	if (navigator.mediaDevices === undefined || navigator.mediaDevices.enumerateDevices === undefined ){
		alert("WebRTC issue! navigator.mediaDevices.enumerateDevices not present in your browser");
	}

	navigator.mediaDevices.enumerateDevices().then(function(devices) {
                // define getUserMedia() constraints
                var constraints = {
			audio: false,
			video: {
				mandatory: {
					maxWidth: _this.parameters.sourceWidth,
					maxHeight: _this.parameters.sourceHeight
		    		}
		  	}
                }
console.log('mediaDevices')
console.dir(devices)
		devices.forEach(function(device) {
			if( device.kind !== 'videoinput' )	return
			// if( constraints.video.optional !== undefined )	return
			constraints.video.optional = [{sourceId: device.deviceId}]
		});

		// OLD API
                // it it finds the videoSource 'environment', modify constraints.video
                // for (var i = 0; i != sourceInfos.length; ++i) {
                //         var sourceInfo = sourceInfos[i];
                //         if(sourceInfo.kind == "video" && sourceInfo.facing == "environment") {
                //                 constraints.video.optional = [{sourceId: sourceInfo.id}]
                //         }
                // }

		navigator.getUserMedia(constraints, function success(stream) {
			// console.log('success', stream);
			domElement.src = window.URL.createObjectURL(stream);
			// to start the video, when it is possible to start it only on userevent. like in android
			document.body.addEventListener('click', function(){
				domElement.play();
			})
			// domElement.play();

			// wait until the video stream is ready
			var interval = setInterval(function() {
				if (!domElement.videoWidth)	return;
				onReady()
				clearInterval(interval)
			}, 1000/50);
		}, function(error) {
			console.log("Can't access user media", error);
			alert("Can't access user media :()");
		});
	}).catch(function(err) {
		console.log(err.name + ": " + err.message);
	});

	return domElement
}

////////////////////////////////////////////////////////////////////////////////
//          handle resize
////////////////////////////////////////////////////////////////////////////////

THREEx.ArToolkitSource.prototype.onResize = function(mirrorDomElements){
	var _this = this
	var screenWidth = window.innerWidth
	var screenHeight = window.innerHeight

	// compute sourceWidth, sourceHeight
	if( this.domElement.nodeName === "IMG" ){
		var sourceWidth = this.domElement.naturalWidth
		var sourceHeight = this.domElement.naturalHeight
	}else if( this.domElement.nodeName === "VIDEO" ){
		var sourceWidth = this.domElement.videoWidth
		var sourceHeight = this.domElement.videoHeight
	}else{
		console.assert(false)
	}

	// compute sourceAspect
	var sourceAspect = sourceWidth / sourceHeight
	// compute screenAspect
	var screenAspect = screenWidth / screenHeight

	// if screenAspect < sourceAspect, then change the width, else change the height
	if( screenAspect < sourceAspect ){
		// compute newWidth and set .width/.marginLeft
		var newWidth = sourceAspect * screenHeight
		this.domElement.style.width = newWidth+'px'
		this.domElement.style.marginLeft = -(newWidth-screenWidth)/2+'px'

		// init style.height/.marginTop to normal value
		this.domElement.style.height = screenHeight+'px'
		this.domElement.style.marginTop = '0px'
	}else{
		// compute newHeight and set .height/.marginTop
		var newHeight = 1 / (sourceAspect / screenWidth)
		this.domElement.style.height = newHeight+'px'
		this.domElement.style.marginTop = -(newHeight-screenHeight)/2+'px'

		// init style.width/.marginLeft to normal value
		this.domElement.style.width = screenWidth+'px'
		this.domElement.style.marginLeft = '0px'
	}

	// honor default parameters
	if( mirrorDomElements === undefined )	mirrorDomElements = []
	if( mirrorDomElements instanceof Array === false )	mirrorDomElements = [mirrorDomElements]

	// Mirror _this.domElement.style to mirrorDomElements
	mirrorDomElements.forEach(function(domElement){
		domElement.style.width = _this.domElement.style.width
		domElement.style.height = _this.domElement.style.height
		domElement.style.marginLeft = _this.domElement.style.marginLeft
		domElement.style.marginTop = _this.domElement.style.marginTop
	})
}
<|endoftext|>


<commit_before>var THREEx = THREEx || {}

THREEx.ArToolkitSource = function(parameters){
	// handle default parameters
	this.parameters = {
		// type of source - ['webcam', 'image', 'video']
		sourceType : parameters.sourceType !== undefined ? parameters.sourceType : 'webcam',
		// url of the source - valid if sourceType = image|video
		sourceUrl : parameters.sourceUrl !== undefined ? parameters.sourceUrl : null,

		// resolution of at which we initialize in the source image
		sourceWidth: parameters.sourceWidth !== undefined ? parameters.sourceWidth : 640,
		sourceHeight: parameters.sourceHeight !== undefined ? parameters.sourceHeight : 480,
		// resolution displayed for the source
		displayWidth: parameters.displayWidth !== undefined ? parameters.displayWidth : 640,
		displayHeight: parameters.displayHeight !== undefined ? parameters.displayHeight : 480,
	}

	this.ready = false
        this.domElement = null
}

//////////////////////////////////////////////////////////////////////////////
//		Code Separator
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitSource.prototype.init = function(onReady){
	var _this = this

        if( this.parameters.sourceType === 'image' ){
                var domElement = this._initSourceImage(onSourceReady)
        }else if( this.parameters.sourceType === 'video' ){
                var domElement = this._initSourceVideo(onSourceReady)
        }else if( this.parameters.sourceType === 'webcam' ){
                var domElement = this._initSourceWebcam(onSourceReady)
        }else{
                console.assert(false)
        }

	// attach
        this.domElement = domElement
        this.domElement.style.position = 'absolute'
        this.domElement.style.top = '0px'
        this.domElement.style.left = '0px'
        this.domElement.style.zIndex = '-2'
        this.domElement.style.zIndex = '-2'

	return this
        function onSourceReady(){
		document.body.appendChild(_this.domElement);

		_this.ready = true

		onReady && onReady()
        }
}

////////////////////////////////////////////////////////////////////////////////
//          init image source
////////////////////////////////////////////////////////////////////////////////

THREEx.ArToolkitSource.prototype._initSourceImage = function(onReady) {
	// TODO make it static
        var domElement = document.createElement('img')
	domElement.src = this.parameters.sourceUrl

	domElement.width = this.parameters.sourceWidth
	domElement.height = this.parameters.sourceHeight
	domElement.style.width = this.parameters.displayWidth+'px'
	domElement.style.height = this.parameters.displayHeight+'px'

	// wait until the video stream is ready
	var interval = setInterval(function() {
		if (!domElement.naturalWidth)	return;
		onReady()
		clearInterval(interval)
	}, 1000/50);

	return domElement
}

////////////////////////////////////////////////////////////////////////////////
//          init video source
////////////////////////////////////////////////////////////////////////////////

THREEx.ArToolkitSource.prototype._initSourceVideo = function(onReady) {
	// TODO make it static
	var domElement = document.createElement('video');
	domElement.src = this.parameters.sourceUrl

	domElement.style.objectFit = 'initial'

	domElement.autoplay = true;
	domElement.webkitPlaysinline = true;
	domElement.controls = false;
	domElement.loop = true;
	domElement.muted = true

	// trick to trigger the video on android
	document.body.addEventListener('click', function onClick(){
		document.body.removeEventListener('click', onClick);
		domElement.play()
	})

	domElement.width = this.parameters.sourceWidth
	domElement.height = this.parameters.sourceHeight
	domElement.style.width = this.parameters.displayWidth+'px'
	domElement.style.height = this.parameters.displayHeight+'px'

	// wait until the video stream is ready
	var interval = setInterval(function() {
		if (!domElement.videoWidth)	return;
		onReady()
		clearInterval(interval)
	}, 1000/50);
	return domElement
}

////////////////////////////////////////////////////////////////////////////////
//          handle webcam source
////////////////////////////////////////////////////////////////////////////////

THREEx.ArToolkitSource.prototype._initSourceWebcam = function(onReady) {
	var _this = this
	// TODO make it static
	navigator.getUserMedia  = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;

	var domElement = document.createElement('video');
	domElement.style.width = this.parameters.displayWidth+'px'
	domElement.style.height = this.parameters.displayHeight+'px'

	if (navigator.getUserMedia === undefined ){
		alert("WebRTC issue! navigator.getUserMedia not present in your browser");
	}
	if (navigator.mediaDevices === undefined || navigator.mediaDevices.enumerateDevices === undefined ){
		alert("WebRTC issue! navigator.mediaDevices.enumerateDevices not present in your browser");
	}

	navigator.mediaDevices.enumerateDevices().then(function(devices) {
                // define getUserMedia() constraints
                var constraints = {
			audio: false,
			video: {
				mandatory: {
					maxWidth: _this.parameters.sourceWidth,
					maxHeight: _this.parameters.sourceHeight
		    		}
		  	}
                }

		// TODO super unclear how to get the backward facing camera...
		// use heuristic - on chrome android current algo is working
		//
		// on macosx it isnt. figure out the algo, and do if(macosx)
		// - with one or two camera
		//
		// some issue on window

		/**
		 * how to test
		 * - one or two camera on macbook
		 * - my phone
		 */
		var runOnMobile = 'ontouchstart' in window ? true : false
		if( runOnMobile === true ){
			pickDeviceAndroid()
		}else{
			pickDeviceMacosx()
		}

		function pickDeviceAndroid(){
			devices.forEach(function(device) {
				if( device.kind !== 'videoinput' )	return
				constraints.video.optional = [{sourceId: device.deviceId}]
			});
		}
		function pickDeviceMacosx(){
			devices.forEach(function(device) {
				if( device.kind !== 'videoinput' )	return

				if( constraints.video.optional !== undefined )	return
				constraints.video.optional = [{sourceId: device.deviceId}]
			});
		}

		// OLD API
                // it it finds the videoSource 'environment', modify constraints.video
                // for (var i = 0; i != sourceInfos.length; ++i) {
                //         var sourceInfo = sourceInfos[i];
                //         if(sourceInfo.kind == "video" && sourceInfo.facing == "environment") {
                //                 constraints.video.optional = [{sourceId: sourceInfo.id}]
                //         }
                // }

		navigator.getUserMedia(constraints, function success(stream) {
			// console.log('success', stream);
			domElement.src = window.URL.createObjectURL(stream);
			// to start the video, when it is possible to start it only on userevent. like in android
			document.body.addEventListener('click', function(){
				domElement.play();
			})
			// domElement.play();

			// wait until the video stream is ready
			var interval = setInterval(function() {
				if (!domElement.videoWidth)	return;
				onReady()
				clearInterval(interval)
			}, 1000/50);
		}, function(error) {
			console.log("Can't access user media", error);
			alert("Can't access user media :()");
		});
	}).catch(function(err) {
		console.log(err.name + ": " + err.message);
	});

	return domElement
}

////////////////////////////////////////////////////////////////////////////////
//          handle resize
////////////////////////////////////////////////////////////////////////////////

THREEx.ArToolkitSource.prototype.onResize = function(mirrorDomElements){
	var _this = this
	var screenWidth = window.innerWidth
	var screenHeight = window.innerHeight

	// compute sourceWidth, sourceHeight
	if( this.domElement.nodeName === "IMG" ){
		var sourceWidth = this.domElement.naturalWidth
		var sourceHeight = this.domElement.naturalHeight
	}else if( this.domElement.nodeName === "VIDEO" ){
		var sourceWidth = this.domElement.videoWidth
		var sourceHeight = this.domElement.videoHeight
	}else{
		console.assert(false)
	}

	// compute sourceAspect
	var sourceAspect = sourceWidth / sourceHeight
	// compute screenAspect
	var screenAspect = screenWidth / screenHeight

	// if screenAspect < sourceAspect, then change the width, else change the height
	if( screenAspect < sourceAspect ){
		// compute newWidth and set .width/.marginLeft
		var newWidth = sourceAspect * screenHeight
		this.domElement.style.width = newWidth+'px'
		this.domElement.style.marginLeft = -(newWidth-screenWidth)/2+'px'

		// init style.height/.marginTop to normal value
		this.domElement.style.height = screenHeight+'px'
		this.domElement.style.marginTop = '0px'
	}else{
		// compute newHeight and set .height/.marginTop
		var newHeight = 1 / (sourceAspect / screenWidth)
		this.domElement.style.height = newHeight+'px'
		this.domElement.style.marginTop = -(newHeight-screenHeight)/2+'px'

		// init style.width/.marginLeft to normal value
		this.domElement.style.width = screenWidth+'px'
		this.domElement.style.marginLeft = '0px'
	}

	// honor default parameters
	if( mirrorDomElements === undefined )	mirrorDomElements = []
	if( mirrorDomElements instanceof Array === false )	mirrorDomElements = [mirrorDomElements]

	// Mirror _this.domElement.style to mirrorDomElements
	mirrorDomElements.forEach(function(domElement){
		domElement.style.width = _this.domElement.style.width
		domElement.style.height = _this.domElement.style.height
		domElement.style.marginLeft = _this.domElement.style.marginLeft
		domElement.style.marginTop = _this.domElement.style.marginTop
	})
}
<commit_msg>more work<commit_after>var THREEx = THREEx || {}

THREEx.ArToolkitSource = function(parameters){
	// handle default parameters
	this.parameters = {
		// type of source - ['webcam', 'image', 'video']
		sourceType : parameters.sourceType !== undefined ? parameters.sourceType : 'webcam',
		// url of the source - valid if sourceType = image|video
		sourceUrl : parameters.sourceUrl !== undefined ? parameters.sourceUrl : null,

		// resolution of at which we initialize in the source image
		sourceWidth: parameters.sourceWidth !== undefined ? parameters.sourceWidth : 640,
		sourceHeight: parameters.sourceHeight !== undefined ? parameters.sourceHeight : 480,
		// resolution displayed for the source
		displayWidth: parameters.displayWidth !== undefined ? parameters.displayWidth : 640,
		displayHeight: parameters.displayHeight !== undefined ? parameters.displayHeight : 480,
	}

	this.ready = false
        this.domElement = null
}

//////////////////////////////////////////////////////////////////////////////
//		Code Separator
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitSource.prototype.init = function(onReady){
	var _this = this

        if( this.parameters.sourceType === 'image' ){
                var domElement = this._initSourceImage(onSourceReady)
        }else if( this.parameters.sourceType === 'video' ){
                var domElement = this._initSourceVideo(onSourceReady)
        }else if( this.parameters.sourceType === 'webcam' ){
                var domElement = this._initSourceWebcam(onSourceReady)
        }else{
                console.assert(false)
        }

	// attach
        this.domElement = domElement
        this.domElement.style.position = 'absolute'
        this.domElement.style.top = '0px'
        this.domElement.style.left = '0px'
        this.domElement.style.zIndex = '-2'

	return this
        function onSourceReady(){
		document.body.appendChild(_this.domElement);

		_this.ready = true

		onReady && onReady()
        }
}

////////////////////////////////////////////////////////////////////////////////
//          init image source
////////////////////////////////////////////////////////////////////////////////

THREEx.ArToolkitSource.prototype._initSourceImage = function(onReady) {
	// TODO make it static
        var domElement = document.createElement('img')
	domElement.src = this.parameters.sourceUrl

	domElement.width = this.parameters.sourceWidth
	domElement.height = this.parameters.sourceHeight
	domElement.style.width = this.parameters.displayWidth+'px'
	domElement.style.height = this.parameters.displayHeight+'px'

	// wait until the video stream is ready
	var interval = setInterval(function() {
		if (!domElement.naturalWidth)	return;
		onReady()
		clearInterval(interval)
	}, 1000/50);

	return domElement
}

////////////////////////////////////////////////////////////////////////////////
//          init video source
////////////////////////////////////////////////////////////////////////////////

THREEx.ArToolkitSource.prototype._initSourceVideo = function(onReady) {
	// TODO make it static
	var domElement = document.createElement('video');
	domElement.src = this.parameters.sourceUrl

	domElement.style.objectFit = 'initial'

	domElement.autoplay = true;
	domElement.webkitPlaysinline = true;
	domElement.controls = false;
	domElement.loop = true;
	domElement.muted = true

	// trick to trigger the video on android
	document.body.addEventListener('click', function onClick(){
		document.body.removeEventListener('click', onClick);
		domElement.play()
	})

	domElement.width = this.parameters.sourceWidth
	domElement.height = this.parameters.sourceHeight
	domElement.style.width = this.parameters.displayWidth+'px'
	domElement.style.height = this.parameters.displayHeight+'px'

	// wait until the video stream is ready
	var interval = setInterval(function() {
		if (!domElement.videoWidth)	return;
		onReady()
		clearInterval(interval)
	}, 1000/50);
	return domElement
}

////////////////////////////////////////////////////////////////////////////////
//          handle webcam source
////////////////////////////////////////////////////////////////////////////////

THREEx.ArToolkitSource.prototype._initSourceWebcam = function(onReady) {
	var _this = this
	// TODO make it static
	navigator.getUserMedia  = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;

	var domElement = document.createElement('video');
	domElement.style.width = this.parameters.displayWidth+'px'
	domElement.style.height = this.parameters.displayHeight+'px'

	if (navigator.getUserMedia === undefined ){
		alert("WebRTC issue! navigator.getUserMedia not present in your browser");
	}
	if (navigator.mediaDevices === undefined || navigator.mediaDevices.enumerateDevices === undefined ){
		alert("WebRTC issue! navigator.mediaDevices.enumerateDevices not present in your browser");
	}

	navigator.mediaDevices.enumerateDevices().then(function(devices) {
                // define getUserMedia() constraints
                var constraints = {
			audio: false,
			video: {
				mandatory: {
					maxWidth: _this.parameters.sourceWidth,
					maxHeight: _this.parameters.sourceHeight
		    		}
		  	}
                }

		// TODO super unclear how to get the backward facing camera...
		// use heuristic - on chrome android current algo is working
		//
		// on macosx it isnt. figure out the algo, and do if(macosx)
		// - with one or two camera
		//
		// some issue on window

		/**
		 * how to test
		 * - one or two camera on macbook
		 * - my phone
		 */
		var runOnMobile = 'ontouchstart' in window ? true : false
		if( runOnMobile === true ){
			pickDeviceAndroid()
		}else{
			pickDeviceMacosx()
		}

		function pickDeviceAndroid(){
			devices.forEach(function(device) {
				if( device.kind !== 'videoinput' )	return
				constraints.video.optional = [{sourceId: device.deviceId}]
			});
		}
		function pickDeviceMacosx(){
			devices.forEach(function(device) {
				if( device.kind !== 'videoinput' )	return

				if( constraints.video.optional !== undefined )	return
				constraints.video.optional = [{sourceId: device.deviceId}]
			});
		}

		// OLD API
                // it it finds the videoSource 'environment', modify constraints.video
                // for (var i = 0; i != sourceInfos.length; ++i) {
                //         var sourceInfo = sourceInfos[i];
                //         if(sourceInfo.kind == "video" && sourceInfo.facing == "environment") {
                //                 constraints.video.optional = [{sourceId: sourceInfo.id}]
                //         }
                // }

		navigator.getUserMedia(constraints, function success(stream) {
			// console.log('success', stream);
			domElement.src = window.URL.createObjectURL(stream);
			// to start the video, when it is possible to start it only on userevent. like in android
			document.body.addEventListener('click', function(){
				domElement.play();
			})
			// domElement.play();

			// wait until the video stream is ready
			var interval = setInterval(function() {
				if (!domElement.videoWidth)	return;
				onReady()
				clearInterval(interval)
			}, 1000/50);
		}, function(error) {
			console.log("Can't access user media", error);
			alert("Can't access user media :()");
		});
	}).catch(function(err) {
		console.log(err.name + ": " + err.message);
	});

	return domElement
}

////////////////////////////////////////////////////////////////////////////////
//          handle resize
////////////////////////////////////////////////////////////////////////////////

THREEx.ArToolkitSource.prototype.onResize = function(mirrorDomElements){
	var _this = this
	var screenWidth = window.innerWidth
	var screenHeight = window.innerHeight

	// compute sourceWidth, sourceHeight
	if( this.domElement.nodeName === "IMG" ){
		var sourceWidth = this.domElement.naturalWidth
		var sourceHeight = this.domElement.naturalHeight
	}else if( this.domElement.nodeName === "VIDEO" ){
		var sourceWidth = this.domElement.videoWidth
		var sourceHeight = this.domElement.videoHeight
	}else{
		console.assert(false)
	}

	// compute sourceAspect
	var sourceAspect = sourceWidth / sourceHeight
	// compute screenAspect
	var screenAspect = screenWidth / screenHeight

	// if screenAspect < sourceAspect, then change the width, else change the height
	if( screenAspect < sourceAspect ){
		// compute newWidth and set .width/.marginLeft
		var newWidth = sourceAspect * screenHeight
		this.domElement.style.width = newWidth+'px'
		this.domElement.style.marginLeft = -(newWidth-screenWidth)/2+'px'

		// init style.height/.marginTop to normal value
		this.domElement.style.height = screenHeight+'px'
		this.domElement.style.marginTop = '0px'
	}else{
		// compute newHeight and set .height/.marginTop
		var newHeight = 1 / (sourceAspect / screenWidth)
		this.domElement.style.height = newHeight+'px'
		this.domElement.style.marginTop = -(newHeight-screenHeight)/2+'px'

		// init style.width/.marginLeft to normal value
		this.domElement.style.width = screenWidth+'px'
		this.domElement.style.marginLeft = '0px'
	}

	// honor default parameters
	if( mirrorDomElements === undefined )	mirrorDomElements = []
	if( mirrorDomElements instanceof Array === false )	mirrorDomElements = [mirrorDomElements]

	// Mirror _this.domElement.style to mirrorDomElements
	mirrorDomElements.forEach(function(domElement){
		domElement.style.width = _this.domElement.style.width
		domElement.style.height = _this.domElement.style.height
		domElement.style.marginLeft = _this.domElement.style.marginLeft
		domElement.style.marginTop = _this.domElement.style.marginTop
	})
}
<|endoftext|>


<commit_before>---
content_type: json
layout: none
posts_per_page: 9999
single_page: true
format: none
posts_filters:
    not:
        has_tags: draft
---
{"pages": [
    {% for post in pagination.posts %}
    {% include 'searchdata.json' %}
    {% endfor %}
    {"title": "", "text": "", "tags": "", "loc": ""}
]}
<commit_msg>Update tipuesearch_content.js<commit_after>var tipuesearch = {"pages": [
 {"title": "Tipue", "text": "", "tags": "jQuery HTML5 CSS", "url": "http://www.tipue.com"},
     {"title": "Tipue Search, a site search engine jQuery plugin", "text": "Tipue Search is a site search engine jQuery plugin. It's free, open source, responsive and fast. Tipue Search only needs a browser that supports jQuery. It doesn't need MySQL or similar. In Static mode it doesn't even need a web server.", "tags": "JavaScript", "url": "http://www.tipue.com/search"},
     {"title": "Tipue Search Documentation", "text": "Tipue Search is a site search engine jQuery plugin. It's free, open source and responsive. Tipue Search uses various modes for loading content. Static mode uses a JavaScript object, while JSON mode uses JSON. Live mode grabs content from a list of pages dynamically.", "tags": "docs", "url": "http://www.tipue.com/search/docs"},
     {"title": "Tipue Search Static mode demo", "text": "Tipue Search is a site search engine jQuery plugin. This is a demo of Static mode. Enter tipue into the search box above.", "tags": "", "url": "http://www.tipue.com/search/demos/static"},
     {"title": "Tipue Search Live mode demo", "text": "Tipue Search is a site search engine jQuery plugin. This is a demo of Live mode. Enter tipue into the search box above.", "tags": "", "url": "http://www.tipue.com/search/demos/live"},
     {"title": "Tipue jQuery plugins Support", "text": "If you're stuck we offer a range of flexible support plans for our jQuery plugins.", "tags": "", "url": "http://www.tipue.com/support"},
     {"title": "Tipr, a small and simple jQuery tooltip plugin", "text": "Tipr is a small and simple jQuery tooltip plugin. It's free and open source. Tipr displays attractive tooltips, and it's a shade under 4KB, CSS included.", "tags": "JavaScript", "url": "http://www.tipue.com/tipr"},
     {"title": "The Tipue blog", "text": "An occasional blog covering CSS, web development, etc.", "tags": "HTML5", "url": "http://www.tipue.com/?d=2"},
     {"title": "About Tipue", "text": "Tipue is a small web development studio based in North London. We've been around for well over a decade. We design innovative add-ins, plugins, code and features with heavy-duty Perl, MySQL and jQuery.", "tags": "", "url": "http://www.tipue.com/about"},
     {"title": "The Tipue blog - The complete guide to centering a div", "text": "Every new developer inevitably finds that centering a div isn't as obvious as you'd expect. Centering what's inside a div is easy enough by giving the text-align property a value of center, but then things tend to get a bit sticky. When you get to centering a div vertically, you can end up in a world of CSS hurt.", "tags": "HTML", "url": "http://www.tipue.com/blog/center-a-div"},
     {"title": "The Tipue blog - Native HTML5 autocomplete with input list", "text": "This article shows how with the HTML5 input list attribute and datalist element you can easily set up an input box with a custom autocomplete without jQuery, JavaScript or similar.", "tags": "", "url": "http://www.tipue.com/blog/input-list"},
     {"title": "The Tipue blog - The really simple guide to z-index", "text": "The CSS z-index property often trips up new and even experienced developers. The aim of this article is to boil down a somewhat-complex specification to 3 major points, which should ease most z-index pain.", "tags": "", "url": "http://www.tipue.com/z-index"}

]};
<|endoftext|>


<commit_before>
  function FileSizeUtils() {

    var unitSize = 1024;
    var byteSize = 1;
    var kiloSize = byteSize * unitSize;
    var megaSize = kiloSize * unitSize;
    var gigaSize = megaSize * unitSize;
    var teraSize = gigaSize * unitSize;
    var petaSize = teraSize * unitSize;
    var exaSize = petaSize * unitSize;

    var bytePostfix = "B";
    var kiloPostfix = "KB";
    var megaPostfix = "MB";
    var gigaPostfix = "GB";
    var teraPostfix = "TB";
    var petaPostfix = "PB";
    var exaPostfix = "EB";

    this.toHumanUnit = function(size) {
      if (size == null) {
        return bytePostfix;
      }
      if (size >= exaSize) {
        return exaPostfix;
      } else if (size >= petaSize) {
        return petaPostfix;
      } else if (size >= teraSize) {
        return teraPostfix;
      } else if (size >= gigaSize) {
        return gigaPostfix;
      } else if (size >= megaSize) {
        return megaPostfix;
      } else if (size >= kiloSize) {
        return kiloPostfix;
      } else {
        return bytePostfix;
      }
    }

    this.getByteSize = function(unit) {
      if (exaPostfix.equals(unit)) {
        return exaSize;
      } else if (petaPostfix == unit) {
        return petaSize;
      } else if (teraPostfix == unit) {
        return teraSize;
      } else if (petaPostfix == unit) {
        return petaSize;
      } else if (gigaPostfix == unit) {
        return gigaSize;
      } else if (megaPostfix == unit) {
        return megaSize;
      } else if (kiloPostfix == unit) {
        return kiloSize;
      } else if (bytePostfix == unit) {
        return byteSize;
      } else {
        return byteSize;
      }
    }
  }
<commit_msg>fix bug in FileSizeUtils.js<commit_after>
  function FileSizeUtils() {

    var unitSize = 1024;
    var byteSize = 1;
    var kiloSize = byteSize * unitSize;
    var megaSize = kiloSize * unitSize;
    var gigaSize = megaSize * unitSize;
    var teraSize = gigaSize * unitSize;
    var petaSize = teraSize * unitSize;
    var exaSize = petaSize * unitSize;

    var bytePostfix = "B";
    var kiloPostfix = "KB";
    var megaPostfix = "MB";
    var gigaPostfix = "GB";
    var teraPostfix = "TB";
    var petaPostfix = "PB";
    var exaPostfix = "EB";

    this.toHumanUnit = function(size) {
      if (size == null) {
        return bytePostfix;
      }
      if (size >= exaSize) {
        return exaPostfix;
      } else if (size >= petaSize) {
        return petaPostfix;
      } else if (size >= teraSize) {
        return teraPostfix;
      } else if (size >= gigaSize) {
        return gigaPostfix;
      } else if (size >= megaSize) {
        return megaPostfix;
      } else if (size >= kiloSize) {
        return kiloPostfix;
      } else {
        return bytePostfix;
      }
    }

    this.getByteSize = function(unit) {
      if (exaPostfix == unit) {
        return exaSize;
      } else if (petaPostfix == unit) {
        return petaSize;
      } else if (teraPostfix == unit) {
        return teraSize;
      } else if (petaPostfix == unit) {
        return petaSize;
      } else if (gigaPostfix == unit) {
        return gigaSize;
      } else if (megaPostfix == unit) {
        return megaSize;
      } else if (kiloPostfix == unit) {
        return kiloSize;
      } else if (bytePostfix == unit) {
        return byteSize;
      } else {
        return byteSize;
      }
    }
  }
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

cr.define('options', function() {
  /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
  /** @const */ var List = cr.ui.List;
  /** @const */ var ListItem = cr.ui.ListItem;
  /** @const */ var DeletableItem = options.DeletableItem;
  /** @const */ var DeletableItemList = options.DeletableItemList;

  /**
   * Creates a new ignored protocol / content handler list item.
   *
   * Accepts values in the form
   *   ['mailto', 'http://www.thesite.com/%s', 'www.thesite.com'],
   * @param {Object} entry A dictionary describing the handlers for a given
   *     protocol.
   * @constructor
   * @extends {options.DeletableItem}
   */
  function IgnoredHandlersListItem(entry) {
    var el = cr.doc.createElement('div');
    el.dataItem = entry;
    el.__proto__ = IgnoredHandlersListItem.prototype;
    el.decorate();
    return el;
  }

  IgnoredHandlersListItem.prototype = {
    __proto__: DeletableItem.prototype,

    /** @override */
    decorate: function() {
      DeletableItem.prototype.decorate.call(this);

      // Protocol.
      var protocolElement = document.createElement('div');
      protocolElement.textContent = this.dataItem[0];
      protocolElement.className = 'handlers-type-column';
      this.contentElement_.appendChild(protocolElement);

      // Host name.
      var hostElement = document.createElement('div');
      hostElement.textContent = this.dataItem[2];
      hostElement.className = 'handlers-site-column';
      hostElement.title = this.dataItem[1];
      this.contentElement_.appendChild(hostElement);
    },
  };

  /**
   * @constructor
   * @extends {options.DeletableItemList}
   */
  var IgnoredHandlersList = cr.ui.define('list');

  IgnoredHandlersList.prototype = {
    __proto__: DeletableItemList.prototype,

    /**
     * @override
     * @param {Object} entry
     */
    createItem: function(entry) {
      return new IgnoredHandlersListItem(entry);
    },

    deleteItemAtIndex: function(index) {
      chrome.send('removeIgnoredHandler', [this.dataModel.item(index)]);
    },

    /**
     * The length of the list.
     */
    get length() {
      return this.dataModel.length;
    },

    /**
     * Set the protocol handlers displayed by this list.  See
     * IgnoredHandlersListItem for an example of the format the list should
     * take.
     *
     * @param {!Array} list A list of ignored protocol handlers.
     */
    setHandlers: function(list) {
      this.dataModel = new ArrayDataModel(list);
    },
  };

  /**
   * Creates a new protocol / content handler list item.
   *
   * Accepts values in the form
   * { protocol: 'mailto',
   *   handlers: [
   *     ['mailto', 'http://www.thesite.com/%s', 'www.thesite.com'],
   *     ...,
   *   ],
   * }
   * @param {Object} entry A dictionary describing the handlers for a given
   *     protocol.
   * @constructor
   * @extends {cr.ui.ListItem}
   */
  function HandlerListItem(entry) {
    var el = cr.doc.createElement('div');
    el.dataItem = entry;
    el.__proto__ = HandlerListItem.prototype;
    el.decorate();
    return el;
  }

  HandlerListItem.prototype = {
    __proto__: ListItem.prototype,

    /**
     * @param {Handlers} data
     * @param {{removeHandler: Function, setDefault: Function,
     *          clearDefault: Function}} delegate
     */
    buildWidget_: function(data, delegate) {
      // Protocol.
      var protocolElement = document.createElement('div');
      protocolElement.textContent = data.protocol;
      protocolElement.className = 'handlers-type-column';
      this.appendChild(protocolElement);

      // Handler selection.
      var handlerElement = document.createElement('div');
      var selectElement = document.createElement('select');
      var defaultOptionElement = document.createElement('option');
      defaultOptionElement.selected = data.default_handler == -1;
      defaultOptionElement.textContent =
          loadTimeData.getString('handlers_none_handler');
      defaultOptionElement.value = -1;
      selectElement.appendChild(defaultOptionElement);

      for (var i = 0; i < data.handlers.length; ++i) {
        var optionElement = document.createElement('option');
        optionElement.selected = i == data.default_handler;
        optionElement.textContent = data.handlers[i][2];
        optionElement.value = i;
        selectElement.appendChild(optionElement);
      }

      selectElement.addEventListener('change', function(e) {
        var index = e.target.value;
        if (index == -1) {
          this.classList.add('none');
          delegate.clearDefault(data.protocol);
        } else {
          handlerElement.classList.remove('none');
          delegate.setDefault(data.handlers[index]);
        }
      });
      handlerElement.appendChild(selectElement);
      handlerElement.className = 'handlers-site-column';
      if (data.default_handler == -1)
        this.classList.add('none');
      this.appendChild(handlerElement);

      if (data.has_policy_recommendations) {
        // Create an indicator to show that the handler has policy
        // recommendations.
        var indicator = new options.ControlledSettingIndicator();
        if (data.is_default_handler_set_by_user || data.default_handler == -1) {
          // The default handler is registered by the user or set to none, which
          // indicates that the user setting has overridden a policy
          // recommendation. Show the appropriate bubble.
          indicator.controlledBy = 'hasRecommendation';
          indicator.resetHandler = function() {
            // If there is a policy recommendation, data.handlers.length >= 1.
            // Setting the default handler to 0 ensures that it won't be 'none',
            // and there *is* a user registered handler created by setDefault,
            // which is required for a change notification.
            // The user-registered handlers are removed in a loop. Note that if
            // a handler is installed by policy, removeHandler does nothing.
            delegate.setDefault(data.handlers[0]);
            for (var i = 0; i < data.handlers.length; ++i) {
              delegate.removeHandler(i, data.handlers[i]);
            }
          };
        } else {
          indicator.controlledBy = 'recommended';
        }
        this.appendChild(indicator);
      }

      if (data.registered_by_user) {
        // Remove link.
        var removeElement = document.createElement('div');
        removeElement.textContent =
            loadTimeData.getString('handlers_remove_link');
        removeElement.addEventListener('click', function(e) {
          var value = selectElement ? selectElement.value : 0;
          delegate.removeHandler(value, data.handlers[value]);
        });
        removeElement.className =
            'handlers-remove-column handlers-remove-link';
        this.appendChild(removeElement);
      }
    },

    /** @override */
    decorate: function() {
      ListItem.prototype.decorate.call(this);

      var delegate = {
        removeHandler: function(index, handler) {
          chrome.send('removeHandler', [handler]);
        },
        setDefault: function(handler) {
          chrome.send('setDefault', [handler]);
        },
        clearDefault: function(protocol) {
          chrome.send('clearDefault', [protocol]);
        },
      };

      this.buildWidget_(this.dataItem, delegate);
    },
  };

  /**
   * Create a new passwords list.
   * @constructor
   * @extends {cr.ui.List}
   */
  var HandlersList = cr.ui.define('list');

  HandlersList.prototype = {
    __proto__: List.prototype,

    /**
     * @override
     * @param {Object} entry
     */
    createItem: function(entry) {
      return new HandlerListItem(entry);
    },

    /**
     * The length of the list.
     */
    get length() {
      return this.dataModel.length;
    },

    /**
     * Set the protocol handlers displayed by this list.
     * See HandlerListItem for an example of the format the list should take.
     *
     * @param {!Array} list A list of protocols with their registered handlers.
     */
    setHandlers: function(list) {
      this.dataModel = new ArrayDataModel(list);
    },
  };

  return {
    IgnoredHandlersListItem: IgnoredHandlersListItem,
    IgnoredHandlersList: IgnoredHandlersList,
    HandlerListItem: HandlerListItem,
    HandlersList: HandlersList,
  };
});
<commit_msg>Fix the missing remove-link UI in protocol handler settings<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

cr.define('options', function() {
  /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
  /** @const */ var List = cr.ui.List;
  /** @const */ var ListItem = cr.ui.ListItem;
  /** @const */ var DeletableItem = options.DeletableItem;
  /** @const */ var DeletableItemList = options.DeletableItemList;

  /**
   * Creates a new ignored protocol / content handler list item.
   *
   * Accepts values in the form
   *   ['mailto', 'http://www.thesite.com/%s', 'www.thesite.com'],
   * @param {Object} entry A dictionary describing the handlers for a given
   *     protocol.
   * @constructor
   * @extends {options.DeletableItem}
   */
  function IgnoredHandlersListItem(entry) {
    var el = cr.doc.createElement('div');
    el.dataItem = entry;
    el.__proto__ = IgnoredHandlersListItem.prototype;
    el.decorate();
    return el;
  }

  IgnoredHandlersListItem.prototype = {
    __proto__: DeletableItem.prototype,

    /** @override */
    decorate: function() {
      DeletableItem.prototype.decorate.call(this);

      // Protocol.
      var protocolElement = document.createElement('div');
      protocolElement.textContent = this.dataItem[0];
      protocolElement.className = 'handlers-type-column';
      this.contentElement_.appendChild(protocolElement);

      // Host name.
      var hostElement = document.createElement('div');
      hostElement.textContent = this.dataItem[2];
      hostElement.className = 'handlers-site-column';
      hostElement.title = this.dataItem[1];
      this.contentElement_.appendChild(hostElement);
    },
  };

  /**
   * @constructor
   * @extends {options.DeletableItemList}
   */
  var IgnoredHandlersList = cr.ui.define('list');

  IgnoredHandlersList.prototype = {
    __proto__: DeletableItemList.prototype,

    /**
     * @override
     * @param {Object} entry
     */
    createItem: function(entry) {
      return new IgnoredHandlersListItem(entry);
    },

    deleteItemAtIndex: function(index) {
      chrome.send('removeIgnoredHandler', [this.dataModel.item(index)]);
    },

    /**
     * The length of the list.
     */
    get length() {
      return this.dataModel.length;
    },

    /**
     * Set the protocol handlers displayed by this list.  See
     * IgnoredHandlersListItem for an example of the format the list should
     * take.
     *
     * @param {!Array} list A list of ignored protocol handlers.
     */
    setHandlers: function(list) {
      this.dataModel = new ArrayDataModel(list);
    },
  };

  /**
   * Creates a new protocol / content handler list item.
   *
   * Accepts values in the form
   * { protocol: 'mailto',
   *   handlers: [
   *     ['mailto', 'http://www.thesite.com/%s', 'www.thesite.com'],
   *     ...,
   *   ],
   * }
   * @param {Object} entry A dictionary describing the handlers for a given
   *     protocol.
   * @constructor
   * @extends {cr.ui.ListItem}
   */
  function HandlerListItem(entry) {
    var el = cr.doc.createElement('div');
    el.dataItem = entry;
    el.__proto__ = HandlerListItem.prototype;
    el.decorate();
    return el;
  }

  HandlerListItem.prototype = {
    __proto__: ListItem.prototype,

    /**
     * @param {Handlers} data
     * @param {{removeHandler: Function, setDefault: Function,
     *          clearDefault: Function}} delegate
     */
    buildWidget_: function(data, delegate) {
      // Protocol.
      var protocolElement = document.createElement('div');
      protocolElement.textContent = data.protocol;
      protocolElement.className = 'handlers-type-column';
      this.appendChild(protocolElement);

      // Handler selection.
      var handlerElement = document.createElement('div');
      var selectElement = document.createElement('select');
      var defaultOptionElement = document.createElement('option');
      defaultOptionElement.selected = data.default_handler == -1;
      defaultOptionElement.textContent =
          loadTimeData.getString('handlers_none_handler');
      defaultOptionElement.value = -1;
      selectElement.appendChild(defaultOptionElement);

      for (var i = 0; i < data.handlers.length; ++i) {
        var optionElement = document.createElement('option');
        optionElement.selected = i == data.default_handler;
        optionElement.textContent = data.handlers[i][2];
        optionElement.value = i;
        selectElement.appendChild(optionElement);
      }

      selectElement.addEventListener('change', function(e) {
        var index = e.target.value;
        if (index == -1) {
          this.classList.add('none');
          delegate.clearDefault(data.protocol);
        } else {
          handlerElement.classList.remove('none');
          delegate.setDefault(data.handlers[index]);
        }
      });
      handlerElement.appendChild(selectElement);
      handlerElement.className = 'handlers-site-column';
      if (data.default_handler == -1)
        this.classList.add('none');
      this.appendChild(handlerElement);

      if (data.has_policy_recommendations) {
        // Create an indicator to show that the handler has policy
        // recommendations.
        var indicator = new options.ControlledSettingIndicator();
        if (data.is_default_handler_set_by_user || data.default_handler == -1) {
          // The default handler is registered by the user or set to none, which
          // indicates that the user setting has overridden a policy
          // recommendation. Show the appropriate bubble.
          indicator.controlledBy = 'hasRecommendation';
          indicator.resetHandler = function() {
            // If there is a policy recommendation, data.handlers.length >= 1.
            // Setting the default handler to 0 ensures that it won't be 'none',
            // and there *is* a user registered handler created by setDefault,
            // which is required for a change notification.
            // The user-registered handlers are removed in a loop. Note that if
            // a handler is installed by policy, removeHandler does nothing.
            delegate.setDefault(data.handlers[0]);
            for (var i = 0; i < data.handlers.length; ++i) {
              delegate.removeHandler(i, data.handlers[i]);
            }
          };
        } else {
          indicator.controlledBy = 'recommended';
        }
        this.appendChild(indicator);
      }

      if (data.is_default_handler_set_by_user) {
        // Remove link.
        var removeElement = document.createElement('div');
        removeElement.textContent =
            loadTimeData.getString('handlers_remove_link');
        removeElement.addEventListener('click', function(e) {
          var value = selectElement ? selectElement.value : 0;
          delegate.removeHandler(value, data.handlers[value]);
        });
        removeElement.className =
            'handlers-remove-column handlers-remove-link';
        this.appendChild(removeElement);
      }
    },

    /** @override */
    decorate: function() {
      ListItem.prototype.decorate.call(this);

      var delegate = {
        removeHandler: function(index, handler) {
          chrome.send('removeHandler', [handler]);
        },
        setDefault: function(handler) {
          chrome.send('setDefault', [handler]);
        },
        clearDefault: function(protocol) {
          chrome.send('clearDefault', [protocol]);
        },
      };

      this.buildWidget_(this.dataItem, delegate);
    },
  };

  /**
   * Create a new passwords list.
   * @constructor
   * @extends {cr.ui.List}
   */
  var HandlersList = cr.ui.define('list');

  HandlersList.prototype = {
    __proto__: List.prototype,

    /**
     * @override
     * @param {Object} entry
     */
    createItem: function(entry) {
      return new HandlerListItem(entry);
    },

    /**
     * The length of the list.
     */
    get length() {
      return this.dataModel.length;
    },

    /**
     * Set the protocol handlers displayed by this list.
     * See HandlerListItem for an example of the format the list should take.
     *
     * @param {!Array} list A list of protocols with their registered handlers.
     */
    setHandlers: function(list) {
      this.dataModel = new ArrayDataModel(list);
    },
  };

  return {
    IgnoredHandlersListItem: IgnoredHandlersListItem,
    IgnoredHandlersList: IgnoredHandlersList,
    HandlerListItem: HandlerListItem,
    HandlersList: HandlersList,
  };
});
<|endoftext|>


<commit_before>function cleanURL () {
    var url = $('#url').val();
    url = url.replace('https://', '');
    url = url.replace('http://', '');
    url = url.replace('www.', '');
    url = url.replace('.html', '');
    url = url.replace('.htm', '');
    url = url.replace('.php', '');
    url = url.replace('.aspx', '');
    url = url.replace('.asp', '');
    url = url.replace('.cfm', '');
    url = url.split('.').join(' ');
    url = url.split('/').join(' ');
    url = url.split('?').join(' ');
    url = url.split('&').join(' ');
    url = url.split('|').join(' ');
    url = url.split('=').join(' ');
    url = url.split('*').join(' ');
    url = url.split('\\').join(' ');
    url = url.split('"').join(' ');
    url = url.split(':').join(' ');
    url = url.split('<').join(' ');
    url = url.split('>').join(' ');
    return url;
}

module.exports = cleanURL;
<commit_msg>add jquery require statement<commit_after>var jquery = require('../ven.jquery-2.1.1.min.js');

function cleanURL () {
    var url = $('#url').val();
    url = url.replace('https://', '');
    url = url.replace('http://', '');
    url = url.replace('www.', '');
    url = url.replace('.html', '');
    url = url.replace('.htm', '');
    url = url.replace('.php', '');
    url = url.replace('.aspx', '');
    url = url.replace('.asp', '');
    url = url.replace('.cfm', '');
    url = url.split('.').join(' ');
    url = url.split('/').join(' ');
    url = url.split('?').join(' ');
    url = url.split('&').join(' ');
    url = url.split('|').join(' ');
    url = url.split('=').join(' ');
    url = url.split('*').join(' ');
    url = url.split('\\').join(' ');
    url = url.split('"').join(' ');
    url = url.split(':').join(' ');
    url = url.split('<').join(' ');
    url = url.split('>').join(' ');
    return url;
}

module.exports = cleanURL;
<|endoftext|>