<commit_before>(function (angular) {
    angular
        .module('mediaCenterContent')
        .controller('ContentMediaCtrl', ['$scope', '$window', 'Buildfire', 'DB', 'COLLECTIONS', 'Location', 'media', function ($scope, $window, Buildfire, DB, COLLECTIONS, Location, media) {
            var ContentMedia = this;
            var tmrDelayForMedia = null;
            var MediaContent = new DB(COLLECTIONS.MediaContent);

            function init() {
                var data = {
                    topImage: '',
                    summary: '',
                    body: '',
                    srcUrl: '',
                    audioUrl: '',
                    videoUrl: '',
                    image: '',
                    dateCreated: '',
                    rank: '',
                    links: [] // this will contain action links
                };
                ContentMedia.linksSortableOptions = {
                    handle: '> .handle'
                };
                ContentMedia.bodyContentWYSIWYGOptions = {
                    plugins: 'advlist autolink link image lists charmap print preview',
                    skin: 'lightgray',
                    trusted: true,
                    theme: 'modern'
                };
                updateMasterItem({data: data});
                if (media) {
                    ContentMedia.item = media;
                }
                else {
                    ContentMedia.item = {data: data};
                }
            }

            function updateMasterItem(item) {
                ContentMedia.masterItem = angular.copy(item);
            }

            function resetItem() {
                ContentMedia.item = angular.copy(ContentMedia.masterItem);
            }

            function isChanged(item) {
                var isDescChanged = false;
                if (item.data.body)
                    isDescChanged = !angular.equals(tinymce.editors[0].getContent({format: 'text'}).trim(), "")
                return isDescChanged && !angular.equals(item, ContentMedia.masterItem);
            }
            function updateItemData() {
                MediaContent.update(ContentMedia.item.id, ContentMedia.item.data).then(function (data) {
                    updateMasterItem(ContentMedia.item);
                }, function (err) {
                    resetItem();
                    console.error('Error-------', err);
                });
            }
            function addNewItem() {
                console.log('Add new item');
                MediaContent.insert(ContentMedia.item.data).then(function (data) {
                    MediaContent.getById(data.id).then(function (data) {
                        ContentMedia.item = data;
                        updateMasterItem(data);
                    }, function (err) {
                        resetItem();
                        console.error('Error while getting----------', err);
                    });
                }, function (err) {
                    console.error('---------------Error while inserting data------------', err);
                });
            }

            function updateItemsWithDelay(item) {
                if (tmrDelayForMedia) {
                    clearTimeout(tmrDelayForMedia);
                }
                if (isChanged(ContentMedia.item)) {
                    tmrDelayForMedia = setTimeout(function () {
                        if (item.id) {
                            updateItemData();
                        }
                        else {
                            ContentMedia.item.data.dateCreated = +new Date();
                            addNewItem();
                        }

                    }, 1000);
                }
            }

            var selectImageOptions = {showIcons: false, multiSelection: false};
            var topImagecallback = function (error, result) {
                if (error) {
                    return console.error('Error:', error);
                }
                if (result.selectedFiles && result.selectedFiles.length) {
                    ContentMedia.item.data.topImage = result.selectedFiles[0];
                    $scope.$digest();
                }
            };

            ContentMedia.selectTopImage = function () {
                Buildfire.imageLib.showDialog(selectImageOptions, topImagecallback);
            };

            ContentMedia.removeTopImage = function () {
                ContentMedia.item.data.topImage = '';
            };
            var audioImageCallback = function (error, result) {
                if (error) {
                    return console.error('Error:', error);
                }
                if (result.selectedFiles && result.selectedFiles.length) {
                    ContentMedia.item.data.image = result.selectedFiles[0];
                    $scope.$digest();
                }
            };
            ContentMedia.selectAudioImage = function () {
                Buildfire.imageLib.showDialog(selectImageOptions, audioImageCallback);
            };

            ContentMedia.removeAudioImage = function () {
                ContentMedia.item.data.image = '';
            };

            var linksOptions = {showIcons: false};
            var addLinkCallback = function (error, result) {
                if (error) {
                    return console.error('Error:', error);
                }
                if (!ContentMedia.item.data.links)
                    ContentMedia.item.data.links = [];
                ContentMedia.item.data.links.push(result);
                $scope.$digest();
            };

            ContentMedia.openAddLinkPopup = function () {
                Buildfire.actionItems.showDialog(null, linksOptions, addLinkCallback);
            };

            ContentMedia.openEditLinkPopup = function (link, index) {
                Buildfire.actionItems.showDialog(link, linksOptions, function (error, result) {
                    if (error) {
                        return console.error('Error:', error);
                    }
                    if (!ContentMedia.item.data.links)
                        ContentMedia.item.data.links = [];
                    ContentMedia.item.data.links.splice(index, 1, result);
                    $scope.$digest();
                });
            };

            ContentMedia.removeLink = function (index) {
                if (ContentMedia.item.data && ContentMedia.item.data.links)
                    ContentMedia.item.data.links.splice(index, 1);
            };

            ContentMedia.done = function () {
                if (ContentMedia.item.id) {
                    MediaContent.update(ContentMedia.item.id, ContentMedia.item.data).then(function (data) {
                        Location.goToHome();
                    }, function (err) {
                        console.error('error----', err);
                        //do something on error
                    });
                }

            };

            ContentMedia.delete = function () {
                if (ContentMedia.item.id)
                    MediaContent.delete(ContentMedia.item.id).then(function (data) {
                        Location.goToHome();
                    }, function (err) {
                        console.error('Error while deleting an item-----', err);
                    });
            };

            $scope.$watch(function () {
                return ContentMedia.item;
            }, updateItemsWithDelay, true);

            init();
        }]);
})(window.angular);<commit_msg>BF-017: update database on change<commit_after>(function (angular) {
    angular
        .module('mediaCenterContent')
        .controller('ContentMediaCtrl', ['$scope', '$window', 'Buildfire', 'DB', 'COLLECTIONS', 'Location', 'media', function ($scope, $window, Buildfire, DB, COLLECTIONS, Location, media) {
            var ContentMedia = this;
            var tmrDelayForMedia = null;
            var MediaContent = new DB(COLLECTIONS.MediaContent);

            function init() {
                var data = {
                    topImage: '',
                    summary: '',
                    body: '',
                    bodyHTML: '',
                    srcUrl: '',
                    audioUrl: '',
                    videoUrl: '',
                    image: '',
                    dateCreated: '',
                    rank: '',
                    links: [] // this will contain action links
                };
                ContentMedia.linksSortableOptions = {
                    handle: '> .handle'
                };
                ContentMedia.bodyContentWYSIWYGOptions = {
                    plugins: 'advlist autolink link image lists charmap print preview',
                    skin: 'lightgray',
                    trusted: true,
                    theme: 'modern'
                };
                updateMasterItem({data: data});
                if (media) {
                    ContentMedia.item = media;
                }
                else {
                    ContentMedia.item = {data: data};
                }
            }

            function updateMasterItem(item) {
                ContentMedia.masterItem = angular.copy(item);
            }

            function resetItem() {
                ContentMedia.item = angular.copy(ContentMedia.masterItem);
            }
            function filter(item){
                var newItem=angular.copy(item);
                newItem.data.body='';
                return newItem;
            }

            function isUnChanged(item) {
                if(item.data.body && angular.equals(tinymce.editors[0].getContent({format: 'text'}).trim(), "")){
                    return angular.equals(filter(item),ContentMedia.masterItem);
                }
                else {
                    return angular.equals(item,ContentMedia.masterItem);
                }
            }
            function updateItemData() {
                ContentMedia.item.data.bodyHTML=ContentMedia.item.data.body;
                MediaContent.update(ContentMedia.item.id, ContentMedia.item.data).then(function (data) {
                    updateMasterItem(ContentMedia.item);
                }, function (err) {
                    resetItem();
                    console.error('Error-------', err);
                });
            }
            function addNewItem() {
                ContentMedia.item.data.bodyHTML=ContentMedia.item.data.body;
                MediaContent.insert(ContentMedia.item.data).then(function (data) {
                    MediaContent.getById(data.id).then(function (data) {
                        ContentMedia.item = data;
                        updateMasterItem(data);
                    }, function (err) {
                        resetItem();
                        console.error('Error while getting----------', err);
                    });
                }, function (err) {
                    console.error('---------------Error while inserting data------------', err);
                });
            }

            function updateItemsWithDelay(item) {
                if (tmrDelayForMedia) {
                    clearTimeout(tmrDelayForMedia);
                }
                if (!isUnChanged(ContentMedia.item)) {
                    tmrDelayForMedia = setTimeout(function () {
                        if (item.id) {
                            updateItemData();
                        }
                        else {
                            ContentMedia.item.data.dateCreated = +new Date();
                            addNewItem();
                        }

                    }, 1000);
                }
            }

            var selectImageOptions = {showIcons: false, multiSelection: false};
            var topImagecallback = function (error, result) {
                if (error) {
                    return console.error('Error:', error);
                }
                if (result.selectedFiles && result.selectedFiles.length) {
                    ContentMedia.item.data.topImage = result.selectedFiles[0];
                    $scope.$digest();
                }
            };

            ContentMedia.selectTopImage = function () {
                Buildfire.imageLib.showDialog(selectImageOptions, topImagecallback);
            };

            ContentMedia.removeTopImage = function () {
                ContentMedia.item.data.topImage = '';
            };
            var audioImageCallback = function (error, result) {
                if (error) {
                    return console.error('Error:', error);
                }
                if (result.selectedFiles && result.selectedFiles.length) {
                    ContentMedia.item.data.image = result.selectedFiles[0];
                    $scope.$digest();
                }
            };
            ContentMedia.selectAudioImage = function () {
                Buildfire.imageLib.showDialog(selectImageOptions, audioImageCallback);
            };

            ContentMedia.removeAudioImage = function () {
                ContentMedia.item.data.image = '';
            };

            var linksOptions = {showIcons: false};
            var addLinkCallback = function (error, result) {
                if (error) {
                    return console.error('Error:', error);
                }
                if (!ContentMedia.item.data.links)
                    ContentMedia.item.data.links = [];
                ContentMedia.item.data.links.push(result);
                $scope.$digest();
            };

            ContentMedia.openAddLinkPopup = function () {
                Buildfire.actionItems.showDialog(null, linksOptions, addLinkCallback);
            };

            ContentMedia.openEditLinkPopup = function (link, index) {
                Buildfire.actionItems.showDialog(link, linksOptions, function (error, result) {
                    if (error) {
                        return console.error('Error:', error);
                    }
                    if (!ContentMedia.item.data.links)
                        ContentMedia.item.data.links = [];
                    ContentMedia.item.data.links.splice(index, 1, result);
                    $scope.$digest();
                });
            };

            ContentMedia.removeLink = function (index) {
                if (ContentMedia.item.data && ContentMedia.item.data.links)
                    ContentMedia.item.data.links.splice(index, 1);
            };

            ContentMedia.done = function () {
                        Location.goToHome();
            };

            ContentMedia.delete = function () {
                if (ContentMedia.item.id)
                    MediaContent.delete(ContentMedia.item.id).then(function (data) {
                        Location.goToHome();
                    }, function (err) {
                        console.error('Error while deleting an item-----', err);
                    });
            };

            $scope.$watch(function () {
                return ContentMedia.item;
            }, updateItemsWithDelay, true);

            init();
        }]);
})(window.angular);<|endoftext|>


<commit_before>angular.module('carousel', ['ionic'])
	.directive('carousel', function ($ionicGesture) {
		return {
			scope: {
				ngModel: '=',
				onDrag: '&',
				onDragEnd: '&'
			},
			compile: function (element, attr) {
				var width = element.prop('offsetWidth');
				var strip = element.children()
					.wrap('
')
					.parent()
					.wrap("
")
					.parent()
					.css({ 'transition-property': 'transform' });
				return function (scope, element) {
					var x = 0;
					$ionicGesture.on('drag', function ($event) {
						var x1 = x + $event.gesture.deltaX;
						x1 = resist(x1);
						translate(x1);
						scope.onDrag({ x: x1 });
					}, strip);
					$ionicGesture.on('dragend', function ($event) {
						x = width * nearest(x + $event.gesture.deltaX);
						translate(x, .4);
						scope.onDragEnd({ x: x });
					}, strip);
					scope.$watch('ngModel', function (value) {
						if (!value) return;
						element.children().css('width', width * value.length + 'px');
					});
					function translate(x, duration) {
						strip.css({ 'transition-duration': (duration || 0) + 's' });
						strip.css({ transform: "translateX(" + x + "px)" });
					}
					function nearest(x) {
						var n = scope.ngModel.length;
						x /= width;
						if (x > 0) return 0;
						if (x < -(n - 1)) return -(n - 1);
						var f = Math.floor(x);
						return x < f + .5 ? f : (f + 1);
					}
					function resist(x) {
						var n = scope.ngModel.length;
						if (x > 0)
							x = atan(x);
						else if (x < -width * (n - 1))
							x = -width * (n - 1) - atan(-width * (n - 1) - x);
						return x;
					}
					function atan(x) {
						var a = 120 / (Math.PI / 2);
						return a * Math.atan(x / a);
					}
				};
			}
		};
	})<commit_msg>calculate width in link<commit_after>angular.module('carousel', ['ionic'])
	.directive('carousel', function ($ionicGesture) {
		return {
			scope: {
				ngModel: '=',
				onDrag: '&',
				onDragEnd: '&'
			},
			compile: function (element, attr) {
				var children = element.children()
					.wrap('
')
					.parent();
				var strip = children
					.wrap("
")
					.parent()
					.css({ 'transition-property': 'transform' });
				return function (scope, element) {
					var width = element.prop('offsetWidth');
					children.css('width', width + 'px');
					var x = 0;
					$ionicGesture.on('drag', function ($event) {
						var x1 = x + $event.gesture.deltaX;
						x1 = resist(x1);
						translate(x1);
						scope.onDrag({ x: x1 });
					}, strip);
					$ionicGesture.on('dragend', function ($event) {
						x = width * nearest(x + $event.gesture.deltaX);
						translate(x, .4);
						scope.onDragEnd({ x: x });
					}, strip);
					scope.$watch('ngModel', function (value) {
						if (!value) return;
						element.children().css('width', width * value.length + 'px');
					});
					function translate(x, duration) {
						strip.css({ 'transition-duration': (duration || 0) + 's' });
						strip.css({ transform: "translateX(" + x + "px)" });
					}
					function nearest(x) {
						var n = scope.ngModel.length;
						x /= width;
						if (x > 0) return 0;
						if (x < -(n - 1)) return -(n - 1);
						var f = Math.floor(x);
						return x < f + .5 ? f : (f + 1);
					}
					function resist(x) {
						var n = scope.ngModel.length;
						if (x > 0)
							x = atan(x);
						else if (x < -width * (n - 1))
							x = -width * (n - 1) - atan(-width * (n - 1) - x);
						return x;
					}
					function atan(x) {
						var a = 120 / (Math.PI / 2);
						return a * Math.atan(x / a);
					}
				};
			}
		};
	})<|endoftext|>


<commit_before>'use strict';

var App = Jesm.createClass({

	__construct: function(container){
		this.state = App.states.INITIALIZED;
		this.stages = [];

		var cvs = document.createElement('canvas');
		this.html = {
			canvas: cvs
		};

		// Jesm.addEvento(window, 'resize', this._resize, this);
		this._resize();
		container.appendChild(cvs);

		this.world = new AppWorld(this, cvs);
		this.world.start();
	},

	_resize: function(){
		this.canvasSize = Jesm.Cross.inner();
		this.html.canvas.width = this.canvasSize[0];
		this.html.canvas.height = this.canvasSize[1];
	},

	addStage: function(obj){
		this.stages.push(obj);
	},

	start: function(){
		if(!this.stages.length)
			throw 'There is no stage to play!';

		this.state = App.states.PLAYING;
		this.currentStageIndex = 0;
		this.loadStage(this.stages[this.currentStageIndex]);
	},

	loadStage: function(obj){
		var size = this.canvasSize,
			minorSize = Math.min.apply(Math, size);

		var mainCircle = new CentralCircle(this.world, size[0] / 2, size[1] / 2);
		mainCircle.diameter = minorSize * obj.mainCircleDiameter;
		if('mainCircleColor' in obj)
			mainCircle.background = obj.mainCircleColor;
		mainCircle.display();
	}

});

App.states = {
	INITIALIZED: 1,
	PLAYING: 2
};

App.getAsColorString = function(arr){
	arr = arr.slice();
	for(var len = arr.length; len--;)
		arr[len] = len == 3 ? arr[len].toFixed(4) : Math.round(arr[len]);
	return 'rgb' + (arr.length == 4 ? 'a' : '') + '(' + arr.join(',') + ')';
};

var AppWorld = Jesm.createClass({

	__construct: function(app, canvas){
		this.app = app;
		this.elements = [];

		this._canvas = canvas;
		this._ctxt = canvas.getContext('2d');
	},

	start: function(){
		Jesm.addEvento(this._canvas, 'click', this._processClick, this);

		this.timestamp = {
			now: + new Date()
		};

		this.render();
	},

	addElement: function(obj){
		for(var x = 0, len = this.elements.length; x < len; x++){
			var element = this.elements[x];
			if(element.zIndex < obj.zIndex){
				this.elements.splice(x, 0, obj);
				return;
			}
		}

		this.elements.push(obj);
	},

	_processClick: function(ev){
		var coordinates = Jesm.Cross.getMouse(ev);

		for(var len = this.elements.length; len--;){
			var element = this.elements[len];

			if(Jesm.isFunction(element.processClick) && element.contains(coordinates)){
				element.processClick(coordinates);
				return;
			}
		}
	},

	_sortElements: function(a, b){
		return b.zIndex - a.zIndex;
	},

	render: function(){
		requestAnimationFrame(this.render.bind(this)); // Requests new frame

		var now = + new Date();
		this.timestamp.elapsedTime = now - this.timestamp.now;
		this.timestamp.now = now;

		this._ctxt.clearRect(0, 0, this._canvas.width, this._canvas.height);
		this.elements.sort(this._sortElements);

		for(var len = this.elements.length; len--;){
			var element = this.elements[len];

			if(element._deleteInNextFrame){
				this.elements.splice(len, 1);
				continue;
			}

			element._calculateModifiers(this.timestamp);
			element.draw(this._ctxt);
		}
	}

});

var AppElement = Jesm.createClass({

	__construct: function(world){
		this.world = world;
		this._modifiers = {};
		this.zIndex = 1;
		this._deleteInNextFrame = false;

		this.world.addElement(this);
	},

	// Modifiers related methods

	startModifier: function(str, toValue, duration, callback){
		var arr = str.split('.'),
			currentValue = this._modifier(arr),
			obj = {
				list: [],
				callback: callback
			};

		if(Array.isArray(currentValue)){
			var size = Math.min(currentValue.length, toValue.length);
			for(var len = size; len--;){
				var tmpArr = arr.slice();
				tmpArr.push(len);
				obj.list.push({
					propArr: tmpArr,
					easer: new Jesm.Easer(currentValue[len], toValue[len], duration).start()
				});
			}
		}
		else{
			obj.list.push({
				propArr: arr,
				easer: new Jesm.Easer(currentValue, toValue, duration).start()
			});
		}

		this._modifiers[str] = obj;
	},

	_calculateModifiers: function(timestamp){
		for(var key in this._modifiers){
			var obj = this._modifiers[key],
				arr = obj.list,
				toEnd = arr.length;

			for(var len = arr.length; len--;){
				var mod = arr[len],
					value = mod.easer.gerar(timestamp.now);

				this._modifier(mod.propArr, value);
				if(mod.easer.isComplete()){
					arr.splice(len, 1);
					toEnd--;
				}
			}

			if(!toEnd){
				delete this._modifiers[key];
				if(Jesm.isFunction(obj.callback))
					obj.callback.call(this);
			}
		}
	},

	_modifier: function(arr, value){
		var obj = this, index = 0;
		for(var finalIndex = arr.length - 1; index < finalIndex; index++)
			obj = obj[arr[index]];
		if(value != null)
			obj[arr[index]] = value;
		return obj[arr[index]];
	},

	// Miscellaneous methods

	removeFromCanvas: function(){
		this._deleteInNextFrame = true;
	}

});

var AppCircle = AppElement.extend({

	__construct: function(world, x, y){
		this._super(world);

		this.x = x || 0;
		this.y = y || 0;
		this.diameter = 10;
		this.background = [255, 255, 255, 1];
	},

	// Geometric methods

	contains: function(coordinates){
		return this.distanceTo(coordinates) < 0;
	},

	distanceTo: function(coordinates){
		var distance = Math.sqrt(
			Math.pow(this.x - coordinates[0], 2) +
			Math.pow(this.y - coordinates[1], 2)
		);
		distance -= this.diameter / 2;
		return distance;
	},

	draw: function(ctxt){
		var path = new Path2D();
		path.arc(this.x, this.y, this.diameter, 0, Math.PI * 2, true);
		ctxt.fillStyle = Array.isArray(this.background) ? App.getAsColorString(this.background) : this.background;
		ctxt.fill(path);
	}

});

var CentralCircle = AppCircle.extend({

	__construct: function(world, x, y){
		this._super.apply(this, arguments);
		this.ready = false;
	},

	display: function(){
		var finalDiameter = this.diameter;
		this.diameter = 0;

		this.startModifier('diameter', finalDiameter, 1, this._getReady);
	},

	_getReady: function(){
		this.ready = true;
	}

});<commit_msg>Display the central circle<commit_after>'use strict';

var App = Jesm.createClass({

	__construct: function(container){
		this.state = App.states.INITIALIZED;
		this.stages = [];

		var cvs = document.createElement('canvas');
		this.html = {
			canvas: cvs
		};

		// Jesm.addEvento(window, 'resize', this._resize, this);
		this._resize();
		container.appendChild(cvs);

		this.world = new AppWorld(this, cvs);
		this.world.start();
	},

	_resize: function(){
		this.canvasSize = Jesm.Cross.inner();
		this.html.canvas.width = this.canvasSize[0];
		this.html.canvas.height = this.canvasSize[1];
	},

	addStage: function(obj){
		this.stages.push(obj);
	},

	start: function(){
		if(!this.stages.length)
			throw 'There is no stage to play!';

		this.state = App.states.PLAYING;
		this.currentStageIndex = 0;
		this.loadStage(this.stages[this.currentStageIndex]);
	},

	loadStage: function(obj){
		var size = this.canvasSize,
			minorSize = Math.min.apply(Math, size);

		var mainCircle = new CentralCircle(this.world, size[0] / 2, size[1] / 2, {
			diameter: minorSize * obj.mainCircleDiameter,
			background: obj.mainCircleColor
		});
	}

});

App.states = {
	INITIALIZED: 1,
	PLAYING: 2
};

App.getAsColorString = function(arr){
	arr = arr.slice();
	for(var len = arr.length; len--;)
		arr[len] = len == 3 ? arr[len].toFixed(4) : Math.round(arr[len]);
	return 'rgb' + (arr.length == 4 ? 'a' : '') + '(' + arr.join(',') + ')';
};

var AppWorld = Jesm.createClass({

	__construct: function(app, canvas){
		this.app = app;
		this.elements = [];

		this._canvas = canvas;
		this._ctxt = canvas.getContext('2d');
	},

	start: function(){
		Jesm.addEvento(this._canvas, 'click', this._processClick, this);

		this.timestamp = {
			now: + new Date()
		};

		this.render();
	},

	addElement: function(obj){
		for(var x = 0, len = this.elements.length; x < len; x++){
			var element = this.elements[x];
			if(obj.zIndex >= element.zIndex){
				this.elements.splice(x, 0, obj);
				return;
			}
		}

		this.elements.push(obj);
	},

	_processClick: function(ev){
		var coordinates = Jesm.Cross.getMouse(ev);

		for(var len = this.elements.length; len--;){
			var element = this.elements[len];

			if(Jesm.isFunction(element.processClick) && element.contains(coordinates)){
				element.processClick(coordinates);
				return;
			}
		}
	},

	_sortElements: function(a, b){
		return b.zIndex - a.zIndex;
	},

	render: function(){
		requestAnimationFrame(this.render.bind(this)); // Requests new frame

		var now = + new Date();
		this.timestamp.elapsedTime = now - this.timestamp.now;
		this.timestamp.now = now;

		this._ctxt.clearRect(0, 0, this._canvas.width, this._canvas.height);
		this.elements.sort(this._sortElements);

		for(var len = this.elements.length; len--;){
			var element = this.elements[len];

			if(element._deleteInNextFrame){
				this.elements.splice(len, 1);
				continue;
			}

			element._calculateModifiers(this.timestamp);
			element.draw(this._ctxt);
		}
	}

});

var AppElement = Jesm.createClass({

	__construct: function(world){
		this.world = world;
		this._modifiers = {};
		this.zIndex = 1;
		this._deleteInNextFrame = false;

		this.world.addElement(this);
	},

	// Modifiers related methods

	startModifier: function(str, toValue, duration, callback){
		var arr = str.split('.'),
			currentValue = this._modifier(arr),
			obj = {
				list: [],
				callback: callback
			};

		if(Array.isArray(currentValue)){
			var size = Math.min(currentValue.length, toValue.length);
			for(var len = size; len--;){
				var tmpArr = arr.slice();
				tmpArr.push(len);
				obj.list.push({
					propArr: tmpArr,
					easer: new Jesm.Easer(currentValue[len], toValue[len], duration).start()
				});
			}
		}
		else{
			obj.list.push({
				propArr: arr,
				easer: new Jesm.Easer(currentValue, toValue, duration).start()
			});
		}

		this._modifiers[str] = obj;
	},

	_calculateModifiers: function(timestamp){
		for(var key in this._modifiers){
			var obj = this._modifiers[key],
				arr = obj.list,
				toEnd = arr.length;

			for(var len = arr.length; len--;){
				var mod = arr[len],
					value = mod.easer.gerar(timestamp.now);

				this._modifier(mod.propArr, value);
				if(mod.easer.isComplete()){
					arr.splice(len, 1);
					toEnd--;
				}
			}

			if(!toEnd){
				delete this._modifiers[key];
				if(Jesm.isFunction(obj.callback))
					obj.callback.call(this);
			}
		}
	},

	_modifier: function(arr, value){
		var obj = this, index = 0;
		for(var finalIndex = arr.length - 1; index < finalIndex; index++)
			obj = obj[arr[index]];
		if(value != null)
			obj[arr[index]] = value;
		return obj[arr[index]];
	},

	// Miscellaneous methods

	removeFromCanvas: function(){
		this._deleteInNextFrame = true;
	}

});

var AppCircle = AppElement.extend({

	__construct: function(world, x, y){
		this._super(world);

		this.x = x || 0;
		this.y = y || 0;
		this.diameter = 10;
		this.background = [255, 255, 255, 1];
	},

	// Geometric methods

	contains: function(coordinates){
		return this.distanceTo(coordinates) < 0;
	},

	distanceTo: function(coordinates){
		var distance = Math.sqrt(
			Math.pow(this.x - coordinates[0], 2) +
			Math.pow(this.y - coordinates[1], 2)
		);
		distance -= this.diameter / 2;
		return distance;
	},

	draw: function(ctxt){
		var path = new Path2D();
		path.arc(this.x, this.y, this.diameter, 0, Math.PI * 2, true);
		ctxt.fillStyle = Array.isArray(this.background) ? App.getAsColorString(this.background) : this.background;
		ctxt.fill(path);
	}

});

var CentralCircle = AppCircle.extend({

	__construct: function(world, x, y, obj){
		this._super.apply(this, arguments);

		this.ready = false;
		this.projectiles = [];

		this.diameter = 0;
		if('background' in obj)
			this.background = obj.background;

		this.startModifier('diameter', obj.diameter, 1, this._getReady);
	},

	_getReady: function(){
		this.ready = true;
	},

	processClick: function(position){
		if(!this.ready)
			return;

		var projectile = new Projectile(this.world, position[0], position[1]);

		this.projectiles.push(projectile);
	}

});

var Projectile = AppCircle.extend({

	// __construct: function(){
	// 	this._super.apply(this, arguments);
	// }

});<|endoftext|>


<commit_before>var schnadmin = {}

schnadmin.ui = {}

schnadmin.ui.make_dropdown = function(selector, schema) {
    $(selector).html(schnadmin.ui.dropdown(schema).render())
}

/**
*   A fancy schnadmin dropdown menu
*/
schnadmin.ui.dropdown = function(schema) {

    var self = {}
    self.schema = schema
    self.templates = {
        link: _.template('<%=name%>')
    }
    self.dom = {
        main: $('\

\

\

\

\
        ')
    }
    self.dom.label = self.dom.main.find('.schnadmin-dropdown-label')
    self.dom.links = self.dom.main.find('.schnadmin-dropdown-links')

    self.render = function() {
        self.dom.main.disableSelection()
        self.dom.label.html(self.schema.label)
        if (self.schema.extra_classes)
            self.dom.label.addClass(self.schema.exra_classes)

        self.dom.label.click(function() {
            if (self.dom.links.css('display') === 'none') {
                $('.schnadmin-dropdown-links').hide()
                self.dom.links.show()
            } else {
                self.dom.links.hide()
            }
            return false
        })

        self.dom.links.empty()
        $.each(self.schema.links, function(i, linkconf) {
            var link = $(self.templates.link({'name': linkconf.name}))
            if (linkconf.click != undefined) {
                link.click(linkconf.click())
            } else {
                link.attr('href', linkconf.href)
            }

            if (linkconf.extra_classes = undefined)
                link.attr('class', linkconf.extra_classes)
            self.dom.links.append(link)
        })

        $("body").click(function(e) {
            self.dom.links.hide()
        })

        return self.dom.main
    }

    return self
}

<commit_msg>added schnadmin.ui.message to add messages to django admin ul.messages via javscript<commit_after>var schnadmin = {}

schnadmin.ui = {}

schnadmin.ui.make_dropdown = function(selector, schema) {
    $(selector).html(schnadmin.ui.dropdown(schema).render())
}

schnadmin.ui.message = function(msg) {

    var messagelist = $('.messagelist')

    if (messagelist.length == 0) {
        messagelist = $('

')
        $('.breadcrumbs').after(messagelist)
    }
    messagelist.show()
    messagelist.append('
' + msg + '
')
    schnadmin.ui.message_fadeout()
}

schnadmin.ui.message_fadeout = function() {
    $('ul.messagelist').fadeOut(10000, function() {
        $(this).remove()
    })

}

/**
*   A fancy schnadmin dropdown menu
*/
schnadmin.ui.dropdown = function(schema) {

    var self = {}
    self.schema = schema
    self.templates = {
        link: _.template('<%=name%>')
    }
    self.dom = {
        main: $('\

\

\

\

\
        ')
    }
    self.dom.label = self.dom.main.find('.schnadmin-dropdown-label')
    self.dom.links = self.dom.main.find('.schnadmin-dropdown-links')

    self.render = function() {
        self.dom.main.disableSelection()
        self.dom.label.html(self.schema.label)
        if (self.schema.extra_classes)
            self.dom.label.addClass(self.schema.exra_classes)

        self.dom.label.click(function() {
            if (self.dom.links.css('display') === 'none') {
                $('.schnadmin-dropdown-links').hide()
                self.dom.links.show()
            } else {
                self.dom.links.hide()
            }
            return false
        })

        self.dom.links.empty()
        $.each(self.schema.links, function(i, linkconf) {
            var link = $(self.templates.link({'name': linkconf.name}))
            if (linkconf.click != undefined) {
                link.click(linkconf.click())
            } else {
                link.attr('href', linkconf.href)
            }

            if (linkconf.extra_classes = undefined)
                link.attr('class', linkconf.extra_classes)
            self.dom.links.append(link)
        })

        $("body").click(function(e) {
            self.dom.links.hide()
        })

        return self.dom.main
    }

    return self
}

<|endoftext|>


<commit_before>(function(){
window.FactView = Backbone.View.extend({
  tagName: "div",

  className: "fact-block",

  _currentVisibleDropdown: undefined,

  events: {
    "click a.remove": "removeFactFromChannel",
    "click li.destroy": "destroyFact",
	  "click .controls .supporting, .controls .weakening": "toggleEvidence",
    "click .controls .supporting a.add-button,    .controls .weakening a.add-button": "showAddRelation",
    "click .controls .supporting a.cancel-button, .controls .weakening a.cancel-button": "hideAddRelation"
  },

  initialize: function(opts) {
    this.useTemplate('facts','_fact'); // use after setting this.tmpl
    this.model.bind('destroy', this.remove, this);

    $(this.el).attr('data-fact-id', this.model.id);
  },

  partials: {},

  render: function() {
    $( this.el )
      .html( Mustache.to_html(this.tmpl, this.model.toJSON(), this.partials)).factlink();

    this.initAddToChannel();
    this.initFactRelationsViews();
    this.initUserPassportViews();

    return this;
  },

  remove: function() {
    $(this.el).fadeOut('fast', function() {
      $(this.el).remove();
    });

    // Hides the popup (if necessary)
    if ( parent.remote ) {
      parent.remote.hide();
      parent.remote.stopHighlightingFactlink(this.model.id);
    }
  },

  removeFactFromChannel: function() {
    this.model.destroy({
      error: function() {
        alert("Error while removing Factlink from Channel" );
      },
      forChannel: true
    });
  },

  destroyFact: function() {
    this.model.destroy({
      error: function() {
        alert("Error while removing the Factlink" );
      },
      forChannel: false
    });
  },

  initAddToChannel: function() {
    if ( $(this.el).find('.channel-listing') && typeof currentUser !== "undefined" ) {

      var addToChannelView = new AddToChannelView({
        collection: currentUser.channels,

        el: $(this.el).find('.channel-listing'),

        model: this.model,

        forFact: this.model
      }).render();

      // Channels are in the container
      $('.add-to-channel', this.el)
        .hoverIntent(function(e) {
          addToChannelView.el.fadeIn("fast");
        }, function() {
          addToChannelView.el.delay(600).fadeOut("fast");
        });
    }
  },

  initFactRelationsViews: function() {
    var supportingFactRelations = new SupportingFactRelations([], { fact: this.model } );
    var weakeningFactRelations = new WeakeningFactRelations([], { fact: this.model } );

    this.supportingFactRelationsView = new FactRelationsView({
      collection: supportingFactRelations,
      type: "supporting"
    });

    this.weakeningFactRelationsView = new FactRelationsView({
      collection: weakeningFactRelations,
      type: "weakening"
    });

    $('.dropdown-container', this.el)
      .append( this.supportingFactRelationsView.render().el )
      .append( this.weakeningFactRelationsView.render().el );
  },

  showDropdownContainer: function(className) {
    if (typeof this._currentVisibleDropdown === "undefined") {
      $('.dropdown-container', this.el).slideDown('fast');
    }

    $(this.el).addClass("active");
  },

  hideDropdownContainer: function(className) {
    $(this.el).removeClass("active");

    $('.dropdown-container', this.el).slideUp('fast');
  },

  switchToRelationDropdown: function(type){
    if (type === "supporting") {
      this.weakeningFactRelationsView.hide();
      this.supportingFactRelationsView.showAndFetch();
    } else {
      this.supportingFactRelationsView.hide();
      this.weakeningFactRelationsView.showAndFetch();
    }
  },

  toggleEvidence: function(e) {
    var $target = $(e.target).closest('li');
    var $tabButtons = $(this.el).find('.controls li');
    var type = $target.hasClass('supporting') ? 'supporting' : 'weakening';

    $tabButtons.removeClass("active");

    if ( type !== this._currentVisibleDropdown ) {
      this.showDropdownContainer(type);

      this._currentVisibleDropdown = type;

      this.switchToRelationDropdown(type);

      $target.addClass("active");
    } else {
      this.hideDropdownContainer();

      this._currentVisibleDropdown = undefined;
    }
  },

  showAddRelation: function(e) {
    e.stopPropagation();

    $(e.target).toggleClass('add-button cancel-button');

    if ( this._currentVisibleDropdown === "supporting" ) {
      this.supportingFactRelationsView.showSearch();
    } else {
      this.weakeningFactRelationsView.showSearch();
    }
  },

  hideAddRelation: function(e) {
    e.stopPropagation();

    $(e.target).toggleClass('add-button cancel-button');

    if ( this._currentVisibleDropdown === "supporting" ) {
      this.supportingFactRelationsView.hideSearch();
    } else {
      this.weakeningFactRelationsView.hideSearch();
    }
  },

  initUserPassportViews: function() {
    var self = this;
    $(this.model.get("last_active_users")).each(function()  {
      var el = $("li.user[data-user-id="+ this.graph_id + "]", self.el);
      var model = new User(this);
      var view = new UserPassportView({model: model, el: el}).render();
    });
  }
});
})();
<commit_msg>Also init stuff upon init<commit_after>(function(){
window.FactView = Backbone.View.extend({
  tagName: "div",

  className: "fact-block",

  _currentVisibleDropdown: undefined,

  events: {
    "click a.remove": "removeFactFromChannel",
    "click li.destroy": "destroyFact",
	  "click .controls .supporting, .controls .weakening": "toggleEvidence",
    "click .controls .supporting a.add-button,    .controls .weakening a.add-button": "showAddRelation",
    "click .controls .supporting a.cancel-button, .controls .weakening a.cancel-button": "hideAddRelation"
  },

  initialize: function(opts) {
    this.useTemplate('facts','_fact'); // use after setting this.tmpl
    this.model.bind('destroy', this.remove, this);

    $(this.el).attr('data-fact-id', this.model.id).factlink();

    this.initAddToChannel();
    this.initFactRelationsViews();
    this.initUserPassportViews();
  },

  partials: {},

  render: function() {
    $( this.el )
      .html( Mustache.to_html(this.tmpl, this.model.toJSON(), this.partials)).factlink();

    this.initAddToChannel();
    this.initFactRelationsViews();
    this.initUserPassportViews();

    return this;
  },

  remove: function() {
    $(this.el).fadeOut('fast', function() {
      $(this.el).remove();
    });

    // Hides the popup (if necessary)
    if ( parent.remote ) {
      parent.remote.hide();
      parent.remote.stopHighlightingFactlink(this.model.id);
    }
  },

  removeFactFromChannel: function() {
    this.model.destroy({
      error: function() {
        alert("Error while removing Factlink from Channel" );
      },
      forChannel: true
    });
  },

  destroyFact: function() {
    this.model.destroy({
      error: function() {
        alert("Error while removing the Factlink" );
      },
      forChannel: false
    });
  },

  initAddToChannel: function() {
    if ( $(this.el).find('.channel-listing') && typeof currentUser !== "undefined" ) {

      var addToChannelView = new AddToChannelView({
        collection: currentUser.channels,

        el: $(this.el).find('.channel-listing'),

        model: this.model,

        forFact: this.model
      }).render();

      // Channels are in the container
      $('.add-to-channel', this.el)
        .hoverIntent(function(e) {
          addToChannelView.el.fadeIn("fast");
        }, function() {
          addToChannelView.el.delay(600).fadeOut("fast");
        });
    }
  },

  initFactRelationsViews: function() {
    var supportingFactRelations = new SupportingFactRelations([], { fact: this.model } );
    var weakeningFactRelations = new WeakeningFactRelations([], { fact: this.model } );

    this.supportingFactRelationsView = new FactRelationsView({
      collection: supportingFactRelations,
      type: "supporting"
    });

    this.weakeningFactRelationsView = new FactRelationsView({
      collection: weakeningFactRelations,
      type: "weakening"
    });

    $('.dropdown-container', this.el)
      .append( this.supportingFactRelationsView.render().el )
      .append( this.weakeningFactRelationsView.render().el );
  },

  showDropdownContainer: function(className) {
    if (typeof this._currentVisibleDropdown === "undefined") {
      $('.dropdown-container', this.el).slideDown('fast');
    }

    $(this.el).addClass("active");
  },

  hideDropdownContainer: function(className) {
    $(this.el).removeClass("active");

    $('.dropdown-container', this.el).slideUp('fast');
  },

  switchToRelationDropdown: function(type){
    if (type === "supporting") {
      this.weakeningFactRelationsView.hide();
      this.supportingFactRelationsView.showAndFetch();
    } else {
      this.supportingFactRelationsView.hide();
      this.weakeningFactRelationsView.showAndFetch();
    }
  },

  toggleEvidence: function(e) {
    var $target = $(e.target).closest('li');
    var $tabButtons = $(this.el).find('.controls li');
    var type = $target.hasClass('supporting') ? 'supporting' : 'weakening';

    $tabButtons.removeClass("active");

    if ( type !== this._currentVisibleDropdown ) {
      this.showDropdownContainer(type);

      this._currentVisibleDropdown = type;

      this.switchToRelationDropdown(type);

      $target.addClass("active");
    } else {
      this.hideDropdownContainer();

      this._currentVisibleDropdown = undefined;
    }
  },

  showAddRelation: function(e) {
    e.stopPropagation();

    $(e.target).toggleClass('add-button cancel-button');

    if ( this._currentVisibleDropdown === "supporting" ) {
      this.supportingFactRelationsView.showSearch();
    } else {
      this.weakeningFactRelationsView.showSearch();
    }
  },

  hideAddRelation: function(e) {
    e.stopPropagation();

    $(e.target).toggleClass('add-button cancel-button');

    if ( this._currentVisibleDropdown === "supporting" ) {
      this.supportingFactRelationsView.hideSearch();
    } else {
      this.weakeningFactRelationsView.hideSearch();
    }
  },

  initUserPassportViews: function() {
    var self = this;
    $(this.model.get("last_active_users")).each(function()  {
      var el = $("li.user[data-user-id="+ this.graph_id + "]", self.el);
      var model = new User(this);
      var view = new UserPassportView({model: model, el: el}).render();
    });
  }
});
})();
<|endoftext|>


<commit_before>var where = require("./where.js")

module.exports = findWhere

function findWhere(obj, attrs) {
    return where(obj, attrs, true)
}
<commit_msg>update find-where function<commit_after>var find = require("./find.js")
var matches = require("./matches.js")

module.exports = findWhere

function findWhere(obj, attrs) {
    return find(obj, matches(attrs))
}
<|endoftext|>


<commit_before>module.exports = function(RED) {
	"use strict";
	var https = require("follow-redirects").https;
	var urllib = require("url");
	var querystring = require("querystring");
    var fs = require('fs');

	/**********************************************************************/
	var hasGWE = false;
	var hasGMQ = false;
	try {
		fs.statSync("gwe"); // FIXME: set to correct path
		hasGWE = true;
		// TODO: call `gwe --gateway-cik`
	} catch(err) {
		hasGWE = false;
		//throw "Info : Gateway Engine not presenet.";
		//if we throw, nothing below runs.
	}
	if (hasGWE) {
		try {
			fs.statSync("gmq"); // FIXME: set to correct path
			hasGMQ = true;
		} catch(err) {
			hasGMQ = false;
			//throw "Info : Gateway Message Queueing not presenet.";
		}
	}

    RED.httpAdmin.get('/exosite-config-features',
		RED.auth.needsPermission('exosite-config-features.read'),
		function(req,res) {
        res.json({"GWE":hasGWE, "GMQ":hasGMQ});
    });

	/**********************************************************************/
	function ExositeConfigureClient(config) {
		RED.nodes.createNode(this,config);
		this.productID = config.productID;
		this.serialNumber = config.serialNumber;
		this.connectBy = config.connectBy;

		this.host = function() {
			if (this.connectBy == "GWE") {
				return "localhost";
			} else if (this.connectBy == "GMQ") {
				return "localhost";
			} else {
				return this.productID + ".m2.exosite.com";
			}
		}

		this.configuredOptions = function(node, callback) {
			var Ropts = urllib.parse('https://'+this.host()+'/onep:v1/stack/alias');
			Ropts.headers = {};
			Ropts.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8';
			if (this.credentials.cik != null && this.credentials.cik != "") {
				Ropts.headers['X-Exosite-CIK'] = this.credentials.cik;

				callback(Ropts);
				return;
			}
			// Not yet, Need to activate.
			node.status({fill:"blue",shape:"ring",text:"activating"});
			node.log("Going to activate "+this.productID+"; " + this.serialNumber);
			var opts = urllib.parse('https://'+this.host()+'/provision/activate')
			opts.method = 'POST';
			opts.headers = {};
			opts.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8';
			var payload = querystring.stringify({
				vendor = this.productID,
				model = this.productID,
				sn = this.serialNumber
			});
			opts.headers['content-length'] = Buffer.byteLength(payload);

			var recievedCIK = "";
			var req = https.request(opts, function(result){
				result.on('data', function (chunk) {
					recievedCIK = recievedCIK + chunk;
				});
				result.on('end',function() {
					node.status({});
					this.credentials.cik = recievedCIK;
					Ropts.headers['X-Exosite-CIK'] = this.credentials.cik;
					callback(Ropts);
				});
			});
			req.on('error',function(err) {
				msg.payload = err.toString();
				msg.statusCode = err.code;
				node.send(msg);
				node.status({fill:"red",shape:"ring",text:err.code});
			});
			req.write(payload);
			req.end();
		}

	}

	RED.nodes.registerType("exo-config-client", ExositeConfigureClient, {
		credentials: {
			cik: {type:"password"}
		}
	});

	/**********************************************************************/
	function ExositeWriteClient(config) {
		RED.nodes.createNode(this,config);
		var node = this;
		this.on('input', function(msg) {
			function doWrite(opts) {
				node.status({fill:"blue",shape:"dot",text:"writing"});
				opts.method = 'POST';
				var payload;
				if (typeof(msg.payload) === 'string') {
					if (config.alias != null && config.alias != '') {
						var f={};
						f[config.alias] = msg.payload;
						payload = querystring.stringify(f);
					} else {
						payload = msg.payload;
					}
				} else if (typeof msg.payload === "number") {
					if (config.alias != null && config.alias != '') {
						var f={};
						f[config.alias] = msg.payload+"";
						payload = querystring.stringify(f);
					} else {
						// this will fail.
						payload = msg.payload+"";
						// FIXME: log an error (status will be updated when call errors)
					}
				} else {
					payload = querystring.stringify(msg.payload);
				}
				opts.headers['content-length'] = Buffer.byteLength(payload);

				var req = https.request(opts, function(result){
					result.on('data', function (chunk) {});
					result.on('end',function() {
						node.status({});
					});
				});
				req.on('error',function(err) {
					msg.payload = err.toString();
					msg.statusCode = err.code;
					node.send(msg);
					node.status({fill:"red",shape:"ring",text:err.code});
				});
				req.write(payload);
				req.end();
			}

			var device = RED.nodes.getNode(config.device);
			if (device) {
				device.configuredOptions(doWrite);
			} else {
				// Old style
				var opts = urllib.parse('https://'+productID+'m2.exosite.com/onep:v1/stack/alias');
				opts.headers = {};
				opts.headers['X-Exosite-CIK'] = this.credentials.cik;
				opts.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8';
				doWrite(opts);
			}

		});
	}
	RED.nodes.registerType("exo-write-client", ExositeWriteClient, {
		credentials: {
			cik: {type:"password"}
		}
	});

	/**********************************************************************/
	function ExositeReadClient(config) {
		RED.nodes.createNode(this,config);
		var node = this;
		this.on('input', function(msg) {
			node.status({fill:"blue",shape:"dot",text:"reading"});

			var productID = "";
			var device = RED.nodes.getNode(config.device);
			if (device) {
				this.credentials.cik = device.credentials.cik; // XXX
				productID = device.productID + ".";
			}

			var opts = urllib.parse('https://'+productID+'m2.exosite.com/onep:v1/stack/alias');
			opts.method = 'GET';
			opts.headers = {};
			opts.headers['X-Exosite-CIK'] = this.credentials.cik;
			opts.headers['Accept'] = 'application/x-www-form-urlencoded; charset=utf-8';

			var payload;
			if (typeof(msg.payload) === 'string' || typeof msg.payload === "number") {
				payload = msg.payload + '';
			} else {
				if ( msg.payload.length ) {
					payload = msg.payload;
				} else {
					payload = [];
					for (var key in msg.payload) {
						payload.push(key);
					}
				}
				payload = payload.join('&');
			}
			opts.query = payload;
			opts.path = opts.path + '?' + payload;

			//node.log(JSON.stringify(opts));
			var req = https.request(opts, function(result){
				var allData = '';
				result.on('data', function (chunk) {
					allData = allData + chunk;
				});
				result.on('end',function() {
					msg.payload = querystring.parse(allData);
					node.send(msg);
					node.status({});
				});
			});
			req.on('error',function(err) {
				msg.payload = err.toString();
				msg.statusCode = err.code;
				node.send(msg);
				node.status({fill:"red",shape:"ring",text:err.code});
			});
			req.end();
		});
	}
	RED.nodes.registerType("exo-read-client", ExositeReadClient, {
		credentials: {
			cik: {type:"password"}
		}
	});

	/**********************************************************************/
	// TODO: add 'exo watch' which does a Long-Poll on a device & aliases.
}

/*	vim: set cin sw=4 ts=4 : */
<commit_msg>Update paths for gwe and gmq.<commit_after>module.exports = function(RED) {
	"use strict";
	var https = require("follow-redirects").https;
	var urllib = require("url");
	var querystring = require("querystring");
    var fs = require('fs');

	/**********************************************************************/
	var hasGWE = false;
	var hasGMQ = false;
	try {
		fs.statSync("/usr/local/bin/gwe");
		hasGWE = true;
		// TODO: call `gwe --gateway-cik` ?here or in config?
	} catch(err) {
		hasGWE = false;
	}
	if (hasGWE) {
		try {
			fs.statSync("/usr/local/bin/gmq");
			hasGMQ = true;
		} catch(err) {
			hasGMQ = false;
		}
	}

    RED.httpAdmin.get('/exosite-config-features',
		RED.auth.needsPermission('exosite-config-features.read'),
		function(req,res) {
        res.json({"GWE":hasGWE, "GMQ":hasGMQ});
    });

	/**********************************************************************/
	function ExositeConfigureClient(config) {
		RED.nodes.createNode(this,config);
		this.productID = config.productID;
		this.serialNumber = config.serialNumber;
		this.connectBy = config.connectBy;

		this.host = function() {
			if (this.connectBy == "GWE") {
				return "localhost";
			} else if (this.connectBy == "GMQ") {
				return "localhost";
			} else {
				return this.productID + ".m2.exosite.com";
			}
		}

		this.configuredOptions = function(node, callback) {
			var Ropts = urllib.parse('https://'+this.host()+'/onep:v1/stack/alias');
			Ropts.headers = {};
			Ropts.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8';
			if (this.credentials.cik != null && this.credentials.cik != "") {
				Ropts.headers['X-Exosite-CIK'] = this.credentials.cik;

				callback(Ropts);
				return;
			}
			// Not yet, Need to activate.
			node.status({fill:"blue",shape:"ring",text:"activating"});
			node.log("Going to activate "+this.productID+"; " + this.serialNumber);
			var opts = urllib.parse('https://'+this.host()+'/provision/activate')
			opts.method = 'POST';
			opts.headers = {};
			opts.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8';
			var payload = querystring.stringify({
				vendor = this.productID,
				model = this.productID,
				sn = this.serialNumber
			});
			opts.headers['content-length'] = Buffer.byteLength(payload);

			var recievedCIK = "";
			var req = https.request(opts, function(result){
				result.on('data', function (chunk) {
					recievedCIK = recievedCIK + chunk;
				});
				result.on('end',function() {
					node.status({});
					this.credentials.cik = recievedCIK;
					Ropts.headers['X-Exosite-CIK'] = this.credentials.cik;
					callback(Ropts);
				});
			});
			req.on('error',function(err) {
				msg.payload = err.toString();
				msg.statusCode = err.code;
				node.send(msg);
				node.status({fill:"red",shape:"ring",text:err.code});
			});
			req.write(payload);
			req.end();
		}

	}

	RED.nodes.registerType("exo-config-client", ExositeConfigureClient, {
		credentials: {
			cik: {type:"password"}
		}
	});

	/**********************************************************************/
	function ExositeWriteClient(config) {
		RED.nodes.createNode(this,config);
		var node = this;
		this.on('input', function(msg) {
			function doWrite(opts) {
				node.status({fill:"blue",shape:"dot",text:"writing"});
				opts.method = 'POST';
				var payload;
				if (typeof(msg.payload) === 'string') {
					if (config.alias != null && config.alias != '') {
						var f={};
						f[config.alias] = msg.payload;
						payload = querystring.stringify(f);
					} else {
						payload = msg.payload;
					}
				} else if (typeof msg.payload === "number") {
					if (config.alias != null && config.alias != '') {
						var f={};
						f[config.alias] = msg.payload+"";
						payload = querystring.stringify(f);
					} else {
						// this will fail.
						payload = msg.payload+"";
						// FIXME: log an error (status will be updated when call errors)
					}
				} else {
					payload = querystring.stringify(msg.payload);
				}
				opts.headers['content-length'] = Buffer.byteLength(payload);

				var req = https.request(opts, function(result){
					result.on('data', function (chunk) {});
					result.on('end',function() {
						node.status({});
					});
				});
				req.on('error',function(err) {
					msg.payload = err.toString();
					msg.statusCode = err.code;
					node.send(msg);
					node.status({fill:"red",shape:"ring",text:err.code});
				});
				req.write(payload);
				req.end();
			}

			var device = RED.nodes.getNode(config.device);
			if (device) {
				device.configuredOptions(doWrite);
			} else {
				// Old style
				var opts = urllib.parse('https://'+productID+'m2.exosite.com/onep:v1/stack/alias');
				opts.headers = {};
				opts.headers['X-Exosite-CIK'] = this.credentials.cik;
				opts.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8';
				doWrite(opts);
			}

		});
	}
	RED.nodes.registerType("exo-write-client", ExositeWriteClient, {
		credentials: {
			cik: {type:"password"}
		}
	});

	/**********************************************************************/
	function ExositeReadClient(config) {
		RED.nodes.createNode(this,config);
		var node = this;
		this.on('input', function(msg) {
			node.status({fill:"blue",shape:"dot",text:"reading"});

			var productID = "";
			var device = RED.nodes.getNode(config.device);
			if (device) {
				this.credentials.cik = device.credentials.cik; // XXX
				productID = device.productID + ".";
			}

			var opts = urllib.parse('https://'+productID+'m2.exosite.com/onep:v1/stack/alias');
			opts.method = 'GET';
			opts.headers = {};
			opts.headers['X-Exosite-CIK'] = this.credentials.cik;
			opts.headers['Accept'] = 'application/x-www-form-urlencoded; charset=utf-8';

			var payload;
			if (typeof(msg.payload) === 'string' || typeof msg.payload === "number") {
				payload = msg.payload + '';
			} else {
				if ( msg.payload.length ) {
					payload = msg.payload;
				} else {
					payload = [];
					for (var key in msg.payload) {
						payload.push(key);
					}
				}
				payload = payload.join('&');
			}
			opts.query = payload;
			opts.path = opts.path + '?' + payload;

			//node.log(JSON.stringify(opts));
			var req = https.request(opts, function(result){
				var allData = '';
				result.on('data', function (chunk) {
					allData = allData + chunk;
				});
				result.on('end',function() {
					msg.payload = querystring.parse(allData);
					node.send(msg);
					node.status({});
				});
			});
			req.on('error',function(err) {
				msg.payload = err.toString();
				msg.statusCode = err.code;
				node.send(msg);
				node.status({fill:"red",shape:"ring",text:err.code});
			});
			req.end();
		});
	}
	RED.nodes.registerType("exo-read-client", ExositeReadClient, {
		credentials: {
			cik: {type:"password"}
		}
	});

	/**********************************************************************/
	// TODO: add 'exo watch' which does a Long-Poll on a device & aliases.
}

/*	vim: set cin sw=4 ts=4 : */
<|endoftext|>


<commit_before>describe("PreloadJS.LoadQueue", function () {

	beforeEach(function () {
		jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;

		this.queue = new createjs.LoadQueue();

		var _this = this;
		this.loadFile = function (fileObj, useXHR) {
			if (useXHR === false || useXHR === true) {
				_this.queue.useXHR = useXHR;
			}

			if (typeof fileObj == "string") {
				_this.queue.loadFile(this.getFilePath(fileObj));
			} else {
				fileObj.src = this.getFilePath(fileObj.src);
				_this.queue.loadFile(fileObj);
			}
		}
	});

	describe("Tag Loading", function () {
		it("should load JSONp", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof Object).toBe(true);
				done();
			});
			this.loadFile({
							  src: "static/jsonpSample.json",
							  callback: "x",
							  type: createjs.LoadQueue.JSONP
						  }, false);
		});

		it("should load and execute Javascript (tag)", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(window.foo).toBe(true);
				done();
			});
			this.loadFile("static/scriptExample.js", false);
		});

		it("should load svg", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(typeof evt.result).toBe("object");
				done();
			});
			this.loadFile("art/gbot.svg", false);
		});

		it("should load sounds", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof HTMLMediaElement).toBe(true);
				done();
			});

			this.loadFile({
							  src: "audio/Thunder.mp3",
							  type: createjs.AbstractLoader.SOUND
						  }, false);
		});

		it("should load video", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof HTMLMediaElement).toBe(true);
				done();
			});

			this.loadFile({
							  src: "static/video.mp4",
							  type: createjs.AbstractLoader.VIDEO
						  }, false);
		});

		it("should load an existing video tag", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result == tag).toBe(true);
				done();
			});

			var tag = document.createElement("video");
			tag.src = "static/video.mp4";

			this.queue.loadFile(tag);
		});

		it("should load an existing sound tag", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result == tag).toBe(true);
				done();
			});

			var tag = document.createElement("audio");
			tag.src = "audio/Thunder.mp3";
			this.queue.loadFile(tag);
		});

		it("tag sound loading send progress events.", function (done) {
			var _this = this;
			var callback = function (evt) {
				expect(true).toBe(true);
				sound.removeEventListener("progress", callback);
				done();
			};

			var sound = new createjs.SoundLoader({
													 src: "audio/Thunder.mp3",
													 type: createjs.LoadQueue.SOUND
												 });
			sound.addEventListener("progress", callback);
			sound.load();
		});

		it("should load images (tag)", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof HTMLImageElement).toBe(true);
				done();
			});
			this.loadFile("art/image0.jpg", false);
		});

		it("should load an existing image tag", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result === tag).toBe(true);
				done();
			});

			var tag = document.createElement("img");
			tag.src = "art/image0.jpg";
			this.queue.loadFile(tag);
		});
	});

	describe("XHR Loading", function () {
		it("should load XML", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof Document).toBe(true);
				done();
			});
			this.loadFile("static/grant.xml");
		});

		it("should load JSON", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof Object).toBe(true);
				done();
			});
			this.loadFile("static/grant.json");
		});

		it("should load and execute Javascript (xhr)", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(window.foo).toBe(true);
				done();
			});
			this.loadFile("static/scriptExample.js", true);
		});

		it("should load css", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof HTMLElement).toBe(true);
				done();
			});
			this.loadFile("static/font.css");
		});

		it("should load images (xhr)", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof HTMLImageElement).toBe(true);
				done();
			});
			this.loadFile("art/Autumn.png", true);
		});

		it("should load binary data", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof ArrayBuffer).toBe(true);
				done();
			});
			this.loadFile({
							  src: "audio/Thunder.mp3",
							  type: createjs.AbstractLoader.BINARY
						  });
		});

		it("should load svg (xhr)", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(typeof evt.result).toBe("object");
				done();
			});
			this.loadFile("art/gbot.svg", true);
		});

		it("should load text", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(typeof evt.result).toBe("string");
				done();
			});
			this.loadFile({src: "art/gbot.svg", type: createjs.LoadQueue.TEXT});
		});

		it("should load sounds (xhr)", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof HTMLMediaElement).toBe(true);
				done();
			});

			this.loadFile({
							  src: "audio/Thunder.mp3",
							  type: createjs.AbstractLoader.SOUND
						  }, true);
		});
	});

	// This fails in Opera and IE (expected, as crossOrigin is not supported)
	it("images should allow crossOrigin access", function (done) {
		this.queue.addEventListener("fileload", function (evt) {
			var canvas = document.createElement("canvas");
			var stage = new createjs.Stage(canvas);
			var bmp = new createjs.Bitmap(evt.result);

			stage.addChild(bmp);
			stage.update();

			expect(stage.hitTest(35, 25)).toBe(true);
			done();
		});

		//this.queue.preferXHR = false;
		this.queue._crossOrigin = true;
		this.queue.loadFile({src:"http://dev.gskinner.com/createjs/cors/daisy.png", crossOrigin:true});
	});

	xit("should load a manifest and its children", function (done) {
		var fileCount = 0;

		this.queue.addEventListener("fileload", function (evt) {
			fileCount++;
		});

		this.queue.addEventListener("complete", function (evt) {
			expect(fileCount).toBe(10);
			done();
		});
		this.loadFile({
						  src: "static/ManifestTest.json",
						  callback: "maps",
						  type: createjs.LoadQueue.MANIFEST
					  });
	});

	it("should send progress events.", function (done) {
		var _this = this;
		var callback = function (evt) {
			expect(true).toBe(true);
			_this.queue.removeEventListener("progress", callback);
			done();
		};
		this.queue.addEventListener("progress", callback);
		this.loadFile({
						  src: "audio/Thunder.mp3",
						  type: createjs.LoadQueue.BINARY
					  });
	});

	it("should error on a 404", function (done) {
		this.queue.addEventListener("error", function (evt) {
			expect(evt.title).toBe("FILE_LOAD_ERROR");
			done();
		});
		this.loadFile("This_file_does_not_EXIST_.no");
	});

	it("should pass data through to the complete handler", function (done) {
		this.queue.addEventListener("fileload", function (evt) {
			expect(evt.item.data).toBe("foo");
			done();
		});
		this.loadFile({
						  src: "art/gbot.svg",
						  type: createjs.LoadQueue.TEXT,
						  data: "foo"
					  });
	});

	it("should have custom plugins", function (done) {
		var SamplePlugin = function () {
		}
		var s = SamplePlugin;
		s.getPreloadHandlers = function () {
			return {
				callback: s.preloadHandler, // Proxy the method to maintain scope
				types: [createjs.LoadQueue.JSON],
				extensions: ["json"]
			}
		};

		s.preloadHandler = function (loadItem) {
			var options = {};

			// Tell PreloadJS to skip this file
			if (options.stopDownload) { return false; }

			// Tell PreloadJS to continue normally
			if (options.doNothing) { return true; }

			loadItem.id = "foo";
			loadItem.data = "foo";

			return true; // Allow the loader to load this.
		};

		this.queue.installPlugin(SamplePlugin);

		this.queue.addEventListener("fileload", function (evt) {
			expect(evt.item.id).toBe("foo");
			expect(evt.item.data).toBe("foo");
			done();
		});
		this.loadFile("static/grant.json");
	});

	it("should POST data.", function (done) {
		var value = {foo: "bar"};
		this.queue.addEventListener("fileload", function (evt) {
			expect(evt.result).toBe(JSON.stringify(value));
			done();
		});

		// the grunt server will echo back whatever we send it.
		this.loadFile({
						  src: "",
						  method: createjs.LoadQueue.POST,
						  values: value
					  });
	});

	it("destory() should remove all references in a LoadQueue", function () {
		this.queue.addEventListener("fileload", function (evt) { });
		this.loadFile({
						  src: "art/gbot.svg",
						  type: createjs.LoadQueue.TEXT,
						  data: "foo"
					  });

		this.queue.destroy();
		expect(this.queue.hasEventListener("fileload")).toBe(false);
		expect(this.queue.getItem()).not.toBeDefined();
		expect(this.queue.getItem(true)).not.toBeDefined();
	});

	it("removeAll() should remove all the items in a LoadQueue", function () {
		this.queue.loadFile("foo.baz", false);
		this.queue.loadFile("baz.foo", false);

		this.queue.removeAll();

		this.queue.load();

		expect(this.queue._numItems).toBe(0);
	});

	it("remove('foo') should remove foo from the LoadQueue", function (done) {
		var _this = this;

		this.queue.addEventListener("complete", function (evt) {
			expect(_this.queue.getItem("foo")).toBeDefined();
			_this.queue.remove("foo");
			expect(_this.queue.getItem("foo")).not.toBeDefined();
			done();
		});

		this.loadFile({
						  src: "art/gbot.svg",
						  id:"foo",
						  type: createjs.LoadQueue.TEXT,
						  data: "foo"
					  });
	});

});
<commit_msg>Added test for JSONp timeout handeling.<commit_after>describe("PreloadJS.LoadQueue", function () {

	beforeEach(function () {
		jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;

		this.queue = new createjs.LoadQueue();

		var _this = this;
		this.loadFile = function (fileObj, preferXHR) {
			if (preferXHR === false || preferXHR === true) {
				_this.queue.preferXHR = preferXHR;
			}

			if (typeof fileObj == "string") {
				_this.queue.loadFile(this.getFilePath(fileObj));
			} else {
				fileObj.src = this.getFilePath(fileObj.src);
				_this.queue.loadFile(fileObj);
			}
		}
	});

	describe("Tag Loading", function () {
		beforeEach(function() {
			this.queue.setPreferXHR(false);
			jasmine.DEFAULT_TIMEOUT_INTERVAL = 9000;
		});

		it("should load JSONp", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof Object).toBe(true);
				done();
			});
			this.loadFile({
							  src: "static/jsonpSample.json",
							  callback: "x",
							  type: createjs.LoadQueue.JSONP
						  }, false);
		});

		it("should load and execute Javascript (tag)", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(window.foo).toBe(true);
				done();
			});
			this.loadFile("static/scriptExample.js", false);
		});

		it("should load svg", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(typeof evt.result).toBe("object");
				done();
			});
			this.loadFile("art/gbot.svg", false);
		});

		it("should load sounds", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof HTMLMediaElement).toBe(true);
				done();
			});

			this.loadFile({
							  src: "audio/Thunder.mp3",
							  type: createjs.AbstractLoader.SOUND
						  }, false);
		});

		it("should load video", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof HTMLMediaElement).toBe(true);
				done();
			});

			this.loadFile({
							  src: "static/video.mp4",
							  type: createjs.AbstractLoader.VIDEO
						  }, false);
		});

		it("should load an existing video tag", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result == tag).toBe(true);
				done();
			});

			var tag = document.createElement("video");
			tag.src = "static/video.mp4";

			this.queue.loadFile(tag);
		});

		it("should load an existing sound tag", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result == tag).toBe(true);
				done();
			});

			var tag = document.createElement("audio");
			tag.src = "audio/Thunder.mp3";
			this.queue.loadFile(tag);
		});

		it("tag sound loading send progress events.", function (done) {
			var _this = this;
			var callback = function (evt) {
				expect(true).toBe(true);
				sound.removeEventListener("progress", callback);
				done();
			};

			var sound = new createjs.SoundLoader({
													 src: "audio/Thunder.mp3",
													 type: createjs.LoadQueue.SOUND
												 });
			sound.addEventListener("progress", callback);
			sound.load();
		});

		it("should load images (tag)", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof HTMLImageElement).toBe(true);
				done();
			});
			this.loadFile("art/image0.jpg", false);
		});

		it("should load an existing image tag", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result === tag).toBe(true);
				done();
			});

			var tag = document.createElement("img");
			tag.src = "art/image0.jpg";
			this.queue.loadFile(tag);
		});

		it("jsonP should error on a 404", function (done) {
			this.queue.addEventListener("error", function (evt) {
				expect(true).toBe(true);
				done();
			});
			this.loadFile({
							  src: "static/no_jsonp_here.json",
							  callback: "x",
							  type: createjs.LoadQueue.JSONP
						  }, false);
		});
	});

	describe("XHR Loading", function () {
		it("should load XML", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof Document).toBe(true);
				done();
			});
			this.loadFile("static/grant.xml");
		});

		it("should load JSON", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof Object).toBe(true);
				done();
			});
			this.loadFile("static/grant.json");
		});

		it("should load and execute Javascript (xhr)", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(window.foo).toBe(true);
				done();
			});
			this.loadFile("static/scriptExample.js", true);
		});

		it("should load css", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof HTMLElement).toBe(true);
				done();
			});
			this.loadFile("static/font.css");
		});

		it("should load images (xhr)", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof HTMLImageElement).toBe(true);
				done();
			});
			this.loadFile("art/Autumn.png", true);
		});

		it("should load binary data", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof ArrayBuffer).toBe(true);
				done();
			});
			this.loadFile({
							  src: "audio/Thunder.mp3",
							  type: createjs.AbstractLoader.BINARY
						  });
		});

		it("should load svg (xhr)", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(typeof evt.result).toBe("object");
				done();
			});
			this.loadFile("art/gbot.svg", true);
		});

		it("should load text", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(typeof evt.result).toBe("string");
				done();
			});
			this.loadFile({src: "art/gbot.svg", type: createjs.LoadQueue.TEXT});
		});

		it("should load sounds (xhr)", function (done) {
			this.queue.addEventListener("fileload", function (evt) {
				expect(evt.result instanceof HTMLMediaElement).toBe(true);
				done();
			});

			this.loadFile({
							  src: "audio/Thunder.mp3",
							  type: createjs.AbstractLoader.SOUND
						  }, true);
		});
	});

	// This fails in Opera and IE (expected, as crossOrigin is not supported)
	it("images should allow crossOrigin access", function (done) {
		this.queue.addEventListener("fileload", function (evt) {
			var canvas = document.createElement("canvas");
			var stage = new createjs.Stage(canvas);
			var bmp = new createjs.Bitmap(evt.result);

			stage.addChild(bmp);
			stage.update();

			expect(stage.hitTest(35, 25)).toBe(true);
			done();
		});

		//this.queue.preferXHR = false;
		this.queue._crossOrigin = true;
		this.queue.loadFile({src:"http://dev.gskinner.com/createjs/cors/daisy.png", crossOrigin:true});
	});

	xit("should load a manifest and its children", function (done) {
		var fileCount = 0;

		this.queue.addEventListener("fileload", function (evt) {
			fileCount++;
		});

		this.queue.addEventListener("complete", function (evt) {
			expect(fileCount).toBe(10);
			done();
		});
		this.loadFile({
						  src: "static/ManifestTest.json",
						  callback: "maps",
						  type: createjs.LoadQueue.MANIFEST
					  });
	});

	it("should send progress events.", function (done) {
		var _this = this;
		var callback = function (evt) {
			expect(true).toBe(true);
			_this.queue.removeEventListener("progress", callback);
			done();
		};
		this.queue.addEventListener("progress", callback);
		this.loadFile({
						  src: "audio/Thunder.mp3",
						  type: createjs.LoadQueue.BINARY
					  });
	});

	it("XHR should error on a 404", function (done) {
		this.queue.addEventListener("error", function (evt) {
			expect(evt.title).toBe("FILE_LOAD_ERROR");
			done();
		});
		this.loadFile("This_file_does_not_EXIST_.no");
	});

	it("should pass data through to the complete handler", function (done) {
		this.queue.addEventListener("fileload", function (evt) {
			expect(evt.item.data).toBe("foo");
			done();
		});
		this.loadFile({
						  src: "art/gbot.svg",
						  type: createjs.LoadQueue.TEXT,
						  data: "foo"
					  });
	});

	it("should have custom plugins", function (done) {
		var SamplePlugin = function () {
		}
		var s = SamplePlugin;
		s.getPreloadHandlers = function () {
			return {
				callback: s.preloadHandler, // Proxy the method to maintain scope
				types: [createjs.LoadQueue.JSON],
				extensions: ["json"]
			}
		};

		s.preloadHandler = function (loadItem) {
			var options = {};

			// Tell PreloadJS to skip this file
			if (options.stopDownload) { return false; }

			// Tell PreloadJS to continue normally
			if (options.doNothing) { return true; }

			loadItem.id = "foo";
			loadItem.data = "foo";

			return true; // Allow the loader to load this.
		};

		this.queue.installPlugin(SamplePlugin);

		this.queue.addEventListener("fileload", function (evt) {
			expect(evt.item.id).toBe("foo");
			expect(evt.item.data).toBe("foo");
			done();
		});
		this.loadFile("static/grant.json");
	});

	it("should POST data.", function (done) {
		var value = {foo: "bar"};
		this.queue.addEventListener("fileload", function (evt) {
			expect(evt.result).toBe(JSON.stringify(value));
			done();
		});

		// the grunt server will echo back whatever we send it.
		this.loadFile({
						  src: "",
						  method: createjs.LoadQueue.POST,
						  values: value
					  });
	});

	it("destory() should remove all references in a LoadQueue", function () {
		this.queue.addEventListener("fileload", function (evt) { });
		this.loadFile({
						  src: "art/gbot.svg",
						  type: createjs.LoadQueue.TEXT,
						  data: "foo"
					  });

		this.queue.destroy();
		expect(this.queue.hasEventListener("fileload")).toBe(false);
		expect(this.queue.getItem()).not.toBeDefined();
		expect(this.queue.getItem(true)).not.toBeDefined();
	});

	it("removeAll() should remove all the items in a LoadQueue", function () {
		this.queue.loadFile("foo.baz", false);
		this.queue.loadFile("baz.foo", false);

		this.queue.removeAll();

		this.queue.load();

		expect(this.queue._numItems).toBe(0);
	});

	it("remove('foo') should remove foo from the LoadQueue", function (done) {
		var _this = this;

		this.queue.addEventListener("complete", function (evt) {
			expect(_this.queue.getItem("foo")).toBeDefined();
			_this.queue.remove("foo");
			expect(_this.queue.getItem("foo")).not.toBeDefined();
			done();
		});

		this.loadFile({
						  src: "art/gbot.svg",
						  id:"foo",
						  type: createjs.LoadQueue.TEXT,
						  data: "foo"
					  });
	});

});
<|endoftext|>