diff --git a/client/package-lock.json b/client/package-lock.json
index f72364428..57e04090b 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -17,6 +17,7 @@
"backgrid": "0.3.8",
"backgrid-paginator": "0.3.9",
"backgrid-select-all": "0.3.5",
+ "caman-dist-only": "^4.1.3",
"ci": "^2.2.0",
"csv-file-validator": "^2.2.0",
"d3-scale": "^4.0.2",
@@ -25,6 +26,7 @@
"flot-axislabels": "^1.0.0",
"flot-pie": "^1.0.0",
"font-awesome": "^4.2.0",
+ "heatmap.js": "^2.0.5",
"jquery": "^1.12.4",
"jquery-color": "^3.0.0-alpha.1",
"jquery-flot-resize": "^1.0.0",
@@ -4561,6 +4563,14 @@
"node": ">=6"
}
},
+ "node_modules/caman-dist-only": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/caman-dist-only/-/caman-dist-only-4.1.3.tgz",
+ "integrity": "sha512-ZDp51L4H00H79W3LC3Qf/lkokz2XrL7i3754Cl6aT+3BN80ysAGt0/a3teQ7ZCF0fIVR434KcfqeAaDuJpDipw==",
+ "engines": {
+ "node": ">= 0.6.18"
+ }
+ },
"node_modules/camel-case": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz",
@@ -7920,6 +7930,11 @@
"he": "bin/he"
}
},
+ "node_modules/heatmap.js": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/heatmap.js/-/heatmap.js-2.0.5.tgz",
+ "integrity": "sha512-CG2gYFP5Cv9IQCXEg3ZRxnJDyAilhWnQlAuHYGuWVzv6mFtQelS1bR9iN80IyDmFECbFPbg6I0LR5uAFHgCthw=="
+ },
"node_modules/hsluv": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/hsluv/-/hsluv-0.0.3.tgz",
diff --git a/client/package.json b/client/package.json
index b7aa5f526..b13f7480e 100644
--- a/client/package.json
+++ b/client/package.json
@@ -65,6 +65,7 @@
"backgrid": "0.3.8",
"backgrid-paginator": "0.3.9",
"backgrid-select-all": "0.3.5",
+ "caman-dist-only": "^4.1.3",
"ci": "^2.2.0",
"csv-file-validator": "^2.2.0",
"d3-scale": "^4.0.2",
@@ -73,6 +74,7 @@
"flot-axislabels": "^1.0.0",
"flot-pie": "^1.0.0",
"font-awesome": "^4.2.0",
+ "heatmap.js": "^2.0.5",
"jquery": "^1.12.4",
"jquery-color": "^3.0.0-alpha.1",
"jquery-flot-resize": "^1.0.0",
diff --git a/client/src/js/modules/dc/views/gridplot.js b/client/src/js/modules/dc/views/gridplot.js
index ccf36d6ec..cf93fec85 100644
--- a/client/src/js/modules/dc/views/gridplot.js
+++ b/client/src/js/modules/dc/views/gridplot.js
@@ -7,7 +7,7 @@ define(['jquery', 'marionette',
'utils/canvas',
'modules/dc/views/viridis',
'templates/dc/gridplot.html',
- 'heatmap',
+ 'heatmap.js',
'utils',
'utils/xhrimage',
'jquery-ui',
diff --git a/client/src/js/modules/dc/views/imageviewer.js b/client/src/js/modules/dc/views/imageviewer.js
index a6152470f..293490393 100644
--- a/client/src/js/modules/dc/views/imageviewer.js
+++ b/client/src/js/modules/dc/views/imageviewer.js
@@ -3,14 +3,14 @@ define(['jquery', 'marionette',
'utils/canvas',
'templates/dc/imageviewer.html',
'templates/dc/imageviewer_embedded.html',
- 'caman',
+ 'caman-dist-only',
'utils',
'utils/xhrimage',
'jquery-ui/ui/widgets/progressbar'
], function($, Marionette, CanvasMixin, template, embed, caman, utils, XHRImage) {
+
+ const Caman = window.Caman
- // Note we do not import the caman libray as Caman.
- // This is because Caman is added to the window global object
return Marionette.ItemView.extend(_.extend({}, CanvasMixin, {
className: function() {
return 'content' + (this.getOption('embed') ? ' embed' : '')
diff --git a/client/src/js/modules/imaging/views/imageviewer.js b/client/src/js/modules/imaging/views/imageviewer.js
index 6ea6bf3f2..534bf6276 100644
--- a/client/src/js/modules/imaging/views/imageviewer.js
+++ b/client/src/js/modules/imaging/views/imageviewer.js
@@ -14,7 +14,7 @@ define(['marionette',
'utils/editable',
'utils',
'utils/xhrimage',
- 'heatmap',
+ 'heatmap.js',
'templates/imaging/imageviewer.html',
'backbone-validation',
], function(Marionette,
diff --git a/client/src/js/vendor/backbone/backbone.syphon.js b/client/src/js/vendor/backbone/backbone.syphon.js
deleted file mode 100755
index a8ca441ea..000000000
--- a/client/src/js/vendor/backbone/backbone.syphon.js
+++ /dev/null
@@ -1,479 +0,0 @@
-// Backbone.Syphon, v0.4.1
-// Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
-// Distributed under MIT license
-// http://github.com/derickbailey/backbone.syphon
-(function (root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['underscore', "jquery", "backbone"], factory);
- }
-}(this, function (_, jQuery, Backbone) {
- Backbone.Syphon = (function(Backbone, $, _){
- var Syphon = {};
-
- // Ignore Element Types
- // --------------------
-
- // Tell Syphon to ignore all elements of these types. You can
- // push new types to ignore directly in to this array.
- Syphon.ignoredTypes = ["button", "submit", "reset", "fieldset"];
-
- // Syphon
- // ------
-
- // Get a JSON object that represents
- // all of the form inputs, in this view.
- // Alternately, pass a form element directly
- // in place of the view.
- Syphon.serialize = function(view, options){
- var data = {};
-
- // Build the configuration
- var config = buildConfig(options);
-
- // Get all of the elements to process
- var elements = getInputElements(view, config);
-
- // Process all of the elements
- _.each(elements, function(el){
- var $el = $(el);
- var type = getElementType($el);
-
- // Get the key for the input
- var keyExtractor = config.keyExtractors.get(type);
- var key = keyExtractor($el);
-
- // Get the value for the input
- var inputReader = config.inputReaders.get(type);
- var value = inputReader($el);
-
- // Get the key assignment validator and make sure
- // it's valid before assigning the value to the key
- var validKeyAssignment = config.keyAssignmentValidators.get(type);
- if (validKeyAssignment($el, key, value)){
- var keychain = config.keySplitter(key);
- data = assignKeyValue(data, keychain, value);
- }
- });
-
- // Done; send back the results.
- return data;
- };
-
- // Use the given JSON object to populate
- // all of the form inputs, in this view.
- // Alternately, pass a form element directly
- // in place of the view.
- Syphon.deserialize = function(view, data, options){
- // Build the configuration
- var config = buildConfig(options);
-
- // Get all of the elements to process
- var elements = getInputElements(view, config);
-
- // Flatten the data structure that we are deserializing
- var flattenedData = flattenData(config, data);
-
- // Process all of the elements
- _.each(elements, function(el){
- var $el = $(el);
- var type = getElementType($el);
-
- // Get the key for the input
- var keyExtractor = config.keyExtractors.get(type);
- var key = keyExtractor($el);
-
- // Get the input writer and the value to write
- var inputWriter = config.inputWriters.get(type);
- var value = flattenedData[key];
-
- // Write the value to the input
- inputWriter($el, value);
- });
- };
-
- // Helpers
- // -------
-
- // Retrieve all of the form inputs
- // from the form
- var getInputElements = function(view, config){
- var form = getForm(view);
- var elements = form.elements;
-
- elements = _.reject(elements, function(el){
- var reject;
- var type = getElementType(el);
- var extractor = config.keyExtractors.get(type);
- var identifier = extractor($(el));
-
- var foundInIgnored = _.include(config.ignoredTypes, type);
- var foundInInclude = _.include(config.include, identifier);
- var foundInExclude = _.include(config.exclude, identifier);
-
- if (foundInInclude){
- reject = false;
- } else {
- if (config.include){
- reject = true;
- } else {
- reject = (foundInExclude || foundInIgnored);
- }
- }
-
- return reject;
- });
-
- return elements;
- };
-
- // Determine what type of element this is. It
- // will either return the `type` attribute of
- // an `` element, or the `tagName` of
- // the element when the element is not an ``.
- var getElementType = function(el){
- var typeAttr;
- var $el = $(el);
- var tagName = $el[0].tagName;
- var type = tagName;
-
- if (tagName.toLowerCase() === "input"){
- typeAttr = $el.attr("type");
- if (typeAttr){
- type = typeAttr;
- } else {
- type = "text";
- }
- }
-
- // Always return the type as lowercase
- // so it can be matched to lowercase
- // type registrations.
- return type.toLowerCase();
- };
-
- // If a form element is given, just return it.
- // Otherwise, get the form element from the view.
- var getForm = function(viewOrForm){
- if (_.isUndefined(viewOrForm.$el) && viewOrForm.tagName.toLowerCase() === 'form'){
- return viewOrForm;
- } else {
- return viewOrForm.$el.is("form") ? viewOrForm.el : viewOrForm.$("form")[0];
- }
- };
-
- // Build a configuration object and initialize
- // default values.
- var buildConfig = function(options){
- var config = _.clone(options) || {};
-
- config.ignoredTypes = _.clone(Syphon.ignoredTypes);
- config.inputReaders = config.inputReaders || Syphon.InputReaders;
- config.inputWriters = config.inputWriters || Syphon.InputWriters;
- config.keyExtractors = config.keyExtractors || Syphon.KeyExtractors;
- config.keySplitter = config.keySplitter || Syphon.KeySplitter;
- config.keyJoiner = config.keyJoiner || Syphon.KeyJoiner;
- config.keyAssignmentValidators = config.keyAssignmentValidators || Syphon.KeyAssignmentValidators;
-
- return config;
- };
-
- // Assigns `value` to a parsed JSON key.
- //
- // The first parameter is the object which will be
- // modified to store the key/value pair.
- //
- // The second parameter accepts an array of keys as a
- // string with an option array containing a
- // single string as the last option.
- //
- // The third parameter is the value to be assigned.
- //
- // Examples:
- //
- // `["foo", "bar", "baz"] => {foo: {bar: {baz: "value"}}}`
- //
- // `["foo", "bar", ["baz"]] => {foo: {bar: {baz: ["value"]}}}`
- //
- // When the final value is an array with a string, the key
- // becomes an array, and values are pushed in to the array,
- // allowing multiple fields with the same name to be
- // assigned to the array.
- var assignKeyValue = function(obj, keychain, value) {
- if (!keychain){ return obj; }
-
- var key = keychain.shift();
-
- // build the current object we need to store data
- if (!obj[key]){
- obj[key] = _.isArray(key) ? [] : {};
- }
-
- // if it's the last key in the chain, assign the value directly
- if (keychain.length === 0){
- if (_.isArray(obj[key])){
- obj[key].push(value);
- } else {
- obj[key] = value;
- }
- }
-
- // recursive parsing of the array, depth-first
- if (keychain.length > 0){
- assignKeyValue(obj[key], keychain, value);
- }
-
- return obj;
- };
-
- // Flatten the data structure in to nested strings, using the
- // provided `KeyJoiner` function.
- //
- // Example:
- //
- // This input:
- //
- // ```js
- // {
- // widget: "wombat",
- // foo: {
- // bar: "baz",
- // baz: {
- // quux: "qux"
- // },
- // quux: ["foo", "bar"]
- // }
- // }
- // ```
- //
- // With a KeyJoiner that uses [ ] square brackets,
- // should produce this output:
- //
- // ```js
- // {
- // "widget": "wombat",
- // "foo[bar]": "baz",
- // "foo[baz][quux]": "qux",
- // "foo[quux]": ["foo", "bar"]
- // }
- // ```
- var flattenData = function(config, data, parentKey){
- var flatData = {};
-
- _.each(data, function(value, keyName){
- var hash = {};
-
- // If there is a parent key, join it with
- // the current, child key.
- if (parentKey){
- keyName = config.keyJoiner(parentKey, keyName);
- }
-
- if (_.isArray(value)){
- keyName += "[]";
- hash[keyName] = value;
- } else if (_.isObject(value)){
- hash = flattenData(config, value, keyName);
- } else {
- hash[keyName] = value;
- }
-
- // Store the resulting key/value pairs in the
- // final flattened data object
- _.extend(flatData, hash);
- });
-
- return flatData;
- };
-
- return Syphon;
- })(Backbone, jQuery, _);
-
- // Type Registry
- // -------------
-
- // Type Registries allow you to register something to
- // an input type, and retrieve either the item registered
- // for a specific type or the default registration
- Backbone.Syphon.TypeRegistry = function(){
- this.registeredTypes = {};
- };
-
- // Borrow Backbone's `extend` keyword for our TypeRegistry
- Backbone.Syphon.TypeRegistry.extend = Backbone.Model.extend;
-
- _.extend(Backbone.Syphon.TypeRegistry.prototype, {
-
- // Get the registered item by type. If nothing is
- // found for the specified type, the default is
- // returned.
- get: function(type){
- var item = this.registeredTypes[type];
-
- if (!item){
- item = this.registeredTypes["default"];
- }
-
- return item;
- },
-
- // Register a new item for a specified type
- register: function(type, item){
- this.registeredTypes[type] = item;
- },
-
- // Register a default item to be used when no
- // item for a specified type is found
- registerDefault: function(item){
- this.registeredTypes["default"] = item;
- },
-
- // Remove an item from a given type registration
- unregister: function(type){
- if (this.registeredTypes[type]){
- delete this.registeredTypes[type];
- }
- }
- });
-
-
-
-
- // Key Extractors
- // --------------
-
- // Key extractors produce the "key" in `{key: "value"}`
- // pairs, when serializing.
- Backbone.Syphon.KeyExtractorSet = Backbone.Syphon.TypeRegistry.extend();
-
- // Built-in Key Extractors
- Backbone.Syphon.KeyExtractors = new Backbone.Syphon.KeyExtractorSet();
-
- // The default key extractor, which uses the
- // input element's "id" attribute
- Backbone.Syphon.KeyExtractors.registerDefault(function($el){
- return $el.prop("name");
- });
-
-
- // Input Readers
- // -------------
-
- // Input Readers are used to extract the value from
- // an input element, for the serialized object result
- Backbone.Syphon.InputReaderSet = Backbone.Syphon.TypeRegistry.extend();
-
- // Built-in Input Readers
- Backbone.Syphon.InputReaders = new Backbone.Syphon.InputReaderSet();
-
- // The default input reader, which uses an input
- // element's "value"
- Backbone.Syphon.InputReaders.registerDefault(function($el){
- return $el.val();
- });
-
- // Checkbox reader, returning a boolean value for
- // whether or not the checkbox is checked.
- Backbone.Syphon.InputReaders.register("checkbox", function($el){
- var checked = $el.prop("checked");
- return checked;
- });
-
-
- // Input Writers
- // -------------
-
- // Input Writers are used to insert a value from an
- // object into an input element.
- Backbone.Syphon.InputWriterSet = Backbone.Syphon.TypeRegistry.extend();
-
- // Built-in Input Writers
- Backbone.Syphon.InputWriters = new Backbone.Syphon.InputWriterSet();
-
- // The default input writer, which sets an input
- // element's "value"
- Backbone.Syphon.InputWriters.registerDefault(function($el, value){
- $el.val(value);
- });
-
- // Checkbox writer, set whether or not the checkbox is checked
- // depending on the boolean value.
- Backbone.Syphon.InputWriters.register("checkbox", function($el, value){
- $el.prop("checked", value);
- });
-
- // Radio button writer, set whether or not the radio button is
- // checked. The button should only be checked if it's value
- // equals the given value.
- Backbone.Syphon.InputWriters.register("radio", function($el, value){
- $el.prop("checked", $el.val() === value);
- });
-
- // Key Assignment Validators
- // -------------------------
-
- // Key Assignment Validators are used to determine whether or not a
- // key should be assigned to a value, after the key and value have been
- // extracted from the element. This is the last opportunity to prevent
- // bad data from getting serialized to your object.
-
- Backbone.Syphon.KeyAssignmentValidatorSet = Backbone.Syphon.TypeRegistry.extend();
-
- // Build-in Key Assignment Validators
- Backbone.Syphon.KeyAssignmentValidators = new Backbone.Syphon.KeyAssignmentValidatorSet();
-
- // Everything is valid by default
- Backbone.Syphon.KeyAssignmentValidators.registerDefault(function(){ return true; });
-
- // But only the "checked" radio button for a given
- // radio button group is valid
- Backbone.Syphon.KeyAssignmentValidators.register("radio", function($el, key, value){
- return $el.prop("checked");
- });
-
-
- // Backbone.Syphon.KeySplitter
- // ---------------------------
-
- // This function is used to split DOM element keys in to an array
- // of parts, which are then used to create a nested result structure.
- // returning `["foo", "bar"]` results in `{foo: { bar: "value" }}`.
- //
- // Override this method to use a custom key splitter, such as:
- // ``, `return key.split(".")`
- Backbone.Syphon.KeySplitter = function(key){
- var matches = key.match(/[^\[\]]+/g);
-
- if (key.indexOf("[]") === key.length - 2){
- lastKey = matches.pop();
- matches.push([lastKey]);
- }
-
- return matches;
- }
-
-
- // Backbone.Syphon.KeyJoiner
- // -------------------------
-
- // Take two segments of a key and join them together, to create the
- // de-normalized key name, when deserializing a data structure back
- // in to a form.
- //
- // Example:
- //
- // With this data strucutre `{foo: { bar: {baz: "value", quux: "another"} } }`,
- // the key joiner will be called with these parameters, and assuming the
- // join happens with "[ ]" square brackets, the specified output:
- //
- // `KeyJoiner("foo", "bar")` //=> "foo[bar]"
- // `KeyJoiner("foo[bar]", "baz")` //=> "foo[bar][baz]"
- // `KeyJoiner("foo[bar]", "quux")` //=> "foo[bar][quux]"
-
- Backbone.Syphon.KeyJoiner = function(parentKey, childKey){
- return parentKey + "[" + childKey + "]";
- }
-
-
- return Backbone.Syphon;
-}));
\ No newline at end of file
diff --git a/client/src/js/vendor/caman.min.js b/client/src/js/vendor/caman.min.js
deleted file mode 100755
index ee527ed97..000000000
--- a/client/src/js/vendor/caman.min.js
+++ /dev/null
@@ -1,204 +0,0 @@
-
-(function(){var $,Analyze,Blender,Calculate,Caman,CamanParser,Canvas,Convert,Event,Fiber,Filter,IO,Image,Layer,Log,Module,Pixel,Plugin,Renderer,Root,Store,Util,fs,http,moduleKeywords,slice,__indexOf=[].indexOf||function(item){for(var i=0,l=this.length;i255){return 255;}
-return val;};Util.copyAttributes=function(from,to,opts){var attr,_i,_len,_ref,_ref1,_results;if(opts==null){opts={};}
-_ref=from.attributes;_results=[];for(_i=0,_len=_ref.length;_i<_len;_i++){attr=_ref[_i];if((opts.except!=null)&&(_ref1=attr.nodeName,__indexOf.call(opts.except,_ref1)>=0)){continue;}
-_results.push(to.setAttribute(attr.nodeName,attr.nodeValue));}
-return _results;};Util.dataArray=function(length){if(length==null){length=0;}
-if(Caman.NodeJS||(window.Uint8Array!=null)){return new Uint8Array(length);}
-return new Array(length);};return Util;})();if(typeof exports!=="undefined"&&exports!==null){Root=exports;Canvas=require('canvas');Image=Canvas.Image;Fiber=require('fibers');fs=require('fs');http=require('http');}else{Root=window;}
-Caman=(function(_super){__extends(Caman,_super);Caman.version={release:"4.1.2",date:"7/27/2013"};Caman.DEBUG=false;Caman.allowRevert=true;Caman.crossOrigin="anonymous";Caman.remoteProxy="";Caman.proxyParam="camanProxyUrl";Caman.NodeJS=typeof exports!=="undefined"&&exports!==null;Caman.autoload=!Caman.NodeJS;Caman.toString=function(){return"Version "+Caman.version.release+", Released "+Caman.version.date;};Caman.getAttrId=function(canvas){if(Caman.NodeJS){return true;}
-if(typeof canvas==="string"){canvas=$(canvas);}
-if(!((canvas!=null)&&(canvas.getAttribute!=null))){return null;}
-return canvas.getAttribute('data-caman-id');};function Caman(){this.nodeFileReady=__bind(this.nodeFileReady,this);var args,callback,id,_this=this;if(arguments.length===0){throw"Invalid arguments";}
-if(this instanceof Caman){this.finishInit=this.finishInit.bind(this);this.imageLoaded=this.imageLoaded.bind(this);args=arguments[0];if(!Caman.NodeJS){id=parseInt(Caman.getAttrId(args[0]),10);callback=typeof args[1]==="function"?args[1]:typeof args[2]==="function"?args[2]:function(){};if(!isNaN(id)&&Store.has(id)){return Store.execute(id,callback);}}
-this.id=Util.uniqid.get();this.initializedPixelData=this.originalPixelData=null;this.cropCoordinates={x:0,y:0};this.cropped=false;this.resized=false;this.pixelStack=[];this.layerStack=[];this.canvasQueue=[];this.currentLayer=null;this.scaled=false;this.analyze=new Analyze(this);this.renderer=new Renderer(this);this.domIsLoaded(function(){_this.parseArguments(args);return _this.setup();});return this;}else{return new Caman(arguments);}}
-Caman.prototype.domIsLoaded=function(cb){var listener,_this=this;if(Caman.NodeJS){return setTimeout(function(){return cb.call(_this);},0);}else{if(document.readyState==="complete"){Log.debug("DOM initialized");return setTimeout(function(){return cb.call(_this);},0);}else{listener=function(){if(document.readyState==="complete"){Log.debug("DOM initialized");return cb.call(_this);}};return document.addEventListener("readystatechange",listener,false);}}};Caman.prototype.parseArguments=function(args){var key,val,_ref,_results;if(args.length===0){throw"Invalid arguments given";}
-this.initObj=null;this.initType=null;this.imageUrl=null;this.callback=function(){};this.setInitObject(args[0]);if(args.length===1){return;}
-switch(typeof args[1]){case"string":this.imageUrl=args[1];break;case"function":this.callback=args[1];}
-if(args.length===2){return;}
-this.callback=args[2];if(args.length===4){_ref=args[4];_results=[];for(key in _ref){if(!__hasProp.call(_ref,key))continue;val=_ref[key];_results.push(this.options[key]=val);}
-return _results;}};Caman.prototype.setInitObject=function(obj){if(Caman.NodeJS){this.initObj=obj;this.initType='node';return;}
-if(typeof obj==="object"){this.initObj=obj;}else{this.initObj=$(obj);}
-if(this.initObj==null){throw"Could not find image or canvas for initialization.";}
-return this.initType=this.initObj.nodeName.toLowerCase();};Caman.prototype.setup=function(){switch(this.initType){case"node":return this.initNode();case"img":return this.initImage();case"canvas":return this.initCanvas();}};Caman.prototype.initNode=function(){Log.debug("Initializing for NodeJS");if(typeof this.initObj==="string"&&this.initObj.match(/^https?:\/\//)){return this.readFromHttp(this.initObj,this.nodeFileReady);}else if(typeof this.initObj==="string"){return fs.readFile(this.initObj,this.nodeFileReady);}else{return this.nodeFileReady(null,this.initObj);}};Caman.prototype.readFromHttp=function(url,callback){var req;Log.debug("Fetching image from "+url);req=http.get(url,function(res){var buf;buf='';res.setEncoding('binary');res.on('data',function(chunk){return buf+=chunk;});return res.on('end',function(){return callback(null,new Buffer(buf,'binary'));});});return req.on('error',callback);};Caman.prototype.nodeFileReady=function(err,data){if(err){throw err;}
-this.image=new Image();this.image.src=data;Log.debug("Image loaded. Width = "+(this.imageWidth())+", Height = "+(this.imageHeight()));this.canvas=new Canvas(this.imageWidth(),this.imageHeight());return this.finishInit();};Caman.prototype.initImage=function(){this.image=this.initObj;this.canvas=document.createElement('canvas');this.context=this.canvas.getContext('2d');Util.copyAttributes(this.image,this.canvas,{except:['src']});if(this.image.parentNode!=null){this.image.parentNode.replaceChild(this.canvas,this.image);}
-this.imageAdjustments();return this.waitForImageLoaded();};Caman.prototype.initCanvas=function(){this.canvas=this.initObj;this.context=this.canvas.getContext('2d');if(this.imageUrl!=null){this.image=document.createElement('img');this.image.src=this.imageUrl;this.imageAdjustments();return this.waitForImageLoaded();}else{return this.finishInit();}};Caman.prototype.imageAdjustments=function(){if(this.needsHiDPISwap()){Log.debug(this.image.src,"->",this.hiDPIReplacement());this.swapped=true;this.image.src=this.hiDPIReplacement();}
-if(IO.isRemote(this.image)){this.image.src=IO.proxyUrl(this.image.src);return Log.debug("Remote image detected, using URL = "+this.image.src);}};Caman.prototype.waitForImageLoaded=function(){if(this.isImageLoaded()){return this.imageLoaded();}else{return this.image.onload=this.imageLoaded;}};Caman.prototype.isImageLoaded=function(){if(!this.image.complete){return false;}
-if((this.image.naturalWidth!=null)&&this.image.naturalWidth===0){return false;}
-return true;};Caman.prototype.imageWidth=function(){return this.image.width||this.image.naturalWidth;};Caman.prototype.imageHeight=function(){return this.image.height||this.image.naturalHeight;};Caman.prototype.imageLoaded=function(){Log.debug("Image loaded. Width = "+(this.imageWidth())+", Height = "+(this.imageHeight()));if(this.swapped){this.canvas.width=this.imageWidth()/this.hiDPIRatio();this.canvas.height=this.imageHeight()/this.hiDPIRatio();}else{this.canvas.width=this.imageWidth();this.canvas.height=this.imageHeight();}
-return this.finishInit();};Caman.prototype.finishInit=function(){var i,pixel,_i,_len,_ref;if(this.context==null){this.context=this.canvas.getContext('2d');}
-this.originalWidth=this.preScaledWidth=this.width=this.canvas.width;this.originalHeight=this.preScaledHeight=this.height=this.canvas.height;this.hiDPIAdjustments();if(!this.hasId()){this.assignId();}
-if(this.image!=null){this.context.drawImage(this.image,0,0,this.imageWidth(),this.imageHeight(),0,0,this.preScaledWidth,this.preScaledHeight);}
-this.imageData=this.context.getImageData(0,0,this.canvas.width,this.canvas.height);this.pixelData=this.imageData.data;if(Caman.allowRevert){this.initializedPixelData=Util.dataArray(this.pixelData.length);this.originalPixelData=Util.dataArray(this.pixelData.length);_ref=this.pixelData;for(i=_i=0,_len=_ref.length;_i<_len;i=++_i){pixel=_ref[i];this.initializedPixelData[i]=pixel;this.originalPixelData[i]=pixel;}}
-this.dimensions={width:this.canvas.width,height:this.canvas.height};if(!Caman.NodeJS){Store.put(this.id,this);}
-this.callback.call(this,this);return this.callback=function(){};};Caman.prototype.reloadCanvasData=function(){this.imageData=this.context.getImageData(0,0,this.canvas.width,this.canvas.height);return this.pixelData=this.imageData.data;};Caman.prototype.resetOriginalPixelData=function(){var i,pixel,_i,_len,_ref,_results;if(!Caman.allowRevert){throw"Revert disabled";}
-this.originalPixelData=Util.dataArray(this.pixelData.length);_ref=this.pixelData;_results=[];for(i=_i=0,_len=_ref.length;_i<_len;i=++_i){pixel=_ref[i];_results.push(this.originalPixelData[i]=pixel);}
-return _results;};Caman.prototype.hasId=function(){return Caman.getAttrId(this.canvas)!=null;};Caman.prototype.assignId=function(){if(Caman.NodeJS||this.canvas.getAttribute('data-caman-id')){return;}
-return this.canvas.setAttribute('data-caman-id',this.id);};Caman.prototype.hiDPIDisabled=function(){return this.canvas.getAttribute('data-caman-hidpi-disabled')!==null;};Caman.prototype.hiDPIAdjustments=function(){var ratio;if(Caman.NodeJS||!this.needsHiDPISwap()){return;}
-ratio=this.hiDPIRatio();if(ratio!==1){Log.debug("HiDPI ratio = "+ratio);this.scaled=true;this.preScaledWidth=this.canvas.width;this.preScaledHeight=this.canvas.height;this.canvas.width=this.preScaledWidth*ratio;this.canvas.height=this.preScaledHeight*ratio;this.canvas.style.width=""+this.preScaledWidth+"px";this.canvas.style.height=""+this.preScaledHeight+"px";this.context.scale(ratio,ratio);this.width=this.originalWidth=this.canvas.width;return this.height=this.originalHeight=this.canvas.height;}};Caman.prototype.hiDPIRatio=function(){var backingStoreRatio,devicePixelRatio;devicePixelRatio=window.devicePixelRatio||1;backingStoreRatio=this.context.webkitBackingStorePixelRatio||this.context.mozBackingStorePixelRatio||this.context.msBackingStorePixelRatio||this.context.oBackingStorePixelRatio||this.context.backingStorePixelRatio||1;return devicePixelRatio/backingStoreRatio;};Caman.prototype.hiDPICapable=function(){return(window.devicePixelRatio!=null)&&window.devicePixelRatio!==1;};Caman.prototype.needsHiDPISwap=function(){if(this.hiDPIDisabled()||!this.hiDPICapable()){return false;}
-return this.hiDPIReplacement()!==null;};Caman.prototype.hiDPIReplacement=function(){if(this.image==null){return null;}
-return this.image.getAttribute('data-caman-hidpi');};Caman.prototype.replaceCanvas=function(newCanvas){var oldCanvas;oldCanvas=this.canvas;this.canvas=newCanvas;this.context=this.canvas.getContext('2d');if(!Caman.NodeJS){oldCanvas.parentNode.replaceChild(this.canvas,oldCanvas);}
-this.width=this.canvas.width;this.height=this.canvas.height;this.reloadCanvasData();return this.dimensions={width:this.canvas.width,height:this.canvas.height};};Caman.prototype.render=function(callback){var _this=this;if(callback==null){callback=function(){};}
-Event.trigger(this,"renderStart");return this.renderer.execute(function(){_this.context.putImageData(_this.imageData,0,0);return callback.call(_this);});};Caman.prototype.revert=function(updateContext){var i,pixel,_i,_len,_ref;if(updateContext==null){updateContext=true;}
-if(!Caman.allowRevert){throw"Revert disabled";}
-_ref=this.originalVisiblePixels();for(i=_i=0,_len=_ref.length;_i<_len;i=++_i){pixel=_ref[i];this.pixelData[i]=pixel;}
-if(updateContext){return this.context.putImageData(this.imageData,0,0);}};Caman.prototype.reset=function(){var canvas,ctx,i,imageData,pixel,pixelData,_i,_len,_ref;canvas=document.createElement('canvas');Util.copyAttributes(this.canvas,canvas);canvas.width=this.originalWidth;canvas.height=this.originalHeight;ctx=canvas.getContext('2d');imageData=ctx.getImageData(0,0,canvas.width,canvas.height);pixelData=imageData.data;_ref=this.initializedPixelData;for(i=_i=0,_len=_ref.length;_i<_len;i=++_i){pixel=_ref[i];pixelData[i]=pixel;}
-ctx.putImageData(imageData,0,0);this.cropCoordinates={x:0,y:0};this.resized=false;return this.replaceCanvas(canvas);};Caman.prototype.originalVisiblePixels=function(){var canvas,coord,ctx,endX,endY,i,imageData,pixel,pixelData,pixels,scaledCanvas,startX,startY,width,_i,_j,_len,_ref,_ref1,_ref2,_ref3;if(!Caman.allowRevert){throw"Revert disabled";}
-pixels=[];startX=this.cropCoordinates.x;endX=startX+this.width;startY=this.cropCoordinates.y;endY=startY+this.height;if(this.resized){canvas=document.createElement('canvas');canvas.width=this.originalWidth;canvas.height=this.originalHeight;ctx=canvas.getContext('2d');imageData=ctx.getImageData(0,0,canvas.width,canvas.height);pixelData=imageData.data;_ref=this.originalPixelData;for(i=_i=0,_len=_ref.length;_i<_len;i=++_i){pixel=_ref[i];pixelData[i]=pixel;}
-ctx.putImageData(imageData,0,0);scaledCanvas=document.createElement('canvas');scaledCanvas.width=this.width;scaledCanvas.height=this.height;ctx=scaledCanvas.getContext('2d');ctx.drawImage(canvas,0,0,this.originalWidth,this.originalHeight,0,0,this.width,this.height);pixelData=ctx.getImageData(0,0,this.width,this.height).data;width=this.width;}else{pixelData=this.originalPixelData;width=this.originalWidth;}
-for(i=_j=0,_ref1=pixelData.length;_j<_ref1;i=_j+=4){coord=Pixel.locationToCoordinates(i,width);if(((startX<=(_ref2=coord.x)&&_ref2_ref;i=0<=_ref?++_i:--_i){divisor+=adjust[i];}}
-this.renderer.add({type:Filter.Type.Kernel,name:name,adjust:adjust,divisor:divisor,bias:bias});return this;};Caman.prototype.processPlugin=function(plugin,args){this.renderer.add({type:Filter.Type.Plugin,plugin:plugin,args:args});return this;};Caman.prototype.newLayer=function(callback){var layer;layer=new Layer(this);this.canvasQueue.push(layer);this.renderer.add({type:Filter.Type.LayerDequeue});callback.call(layer);this.renderer.add({type:Filter.Type.LayerFinished});return this;};Caman.prototype.executeLayer=function(layer){return this.pushContext(layer);};Caman.prototype.pushContext=function(layer){this.layerStack.push(this.currentLayer);this.pixelStack.push(this.pixelData);this.currentLayer=layer;return this.pixelData=layer.pixelData;};Caman.prototype.popContext=function(){this.pixelData=this.pixelStack.pop();return this.currentLayer=this.layerStack.pop();};Caman.prototype.applyCurrentLayer=function(){return this.currentLayer.applyToParent();};return Caman;})(Module);Root.Caman=Caman;Caman.Analyze=(function(){function Analyze(c){this.c=c;}
-Analyze.prototype.calculateLevels=function(){var i,levels,numPixels,_i,_j,_k,_ref;levels={r:{},g:{},b:{}};for(i=_i=0;_i<=255;i=++_i){levels.r[i]=0;levels.g[i]=0;levels.b[i]=0;}
-for(i=_j=0,_ref=this.c.pixelData.length;_j<_ref;i=_j+=4){levels.r[this.c.pixelData[i]]++;levels.g[this.c.pixelData[i+1]]++;levels.b[this.c.pixelData[i+2]]++;}
-numPixels=this.c.pixelData.length/4;for(i=_k=0;_k<=255;i=++_k){levels.r[i]/=numPixels;levels.g[i]/=numPixels;levels.b[i]/=numPixels;}
-return levels;};return Analyze;})();Analyze=Caman.Analyze;Caman.DOMUpdated=function(){var img,imgs,parser,_i,_len,_results;imgs=document.querySelectorAll("img[data-caman]");if(!(imgs.length>0)){return;}
-_results=[];for(_i=0,_len=imgs.length;_i<_len;_i++){img=imgs[_i];_results.push(parser=new CamanParser(img,function(){this.parse();return this.execute();}));}
-return _results;};if(Caman.autoload){(function(){if(document.readyState==="complete"){return Caman.DOMUpdated();}else{return document.addEventListener("DOMContentLoaded",Caman.DOMUpdated,false);}})();}
-CamanParser=(function(){var INST_REGEX;INST_REGEX="(\\w+)\\((.*?)\\)";function CamanParser(ele,ready){this.dataStr=ele.getAttribute('data-caman');this.caman=Caman(ele,ready.bind(this));}
-CamanParser.prototype.parse=function(){var args,e,filter,func,inst,instFunc,m,r,unparsedInstructions,_i,_len,_ref,_results;this.ele=this.caman.canvas;r=new RegExp(INST_REGEX,'g');unparsedInstructions=this.dataStr.match(r);if(!(unparsedInstructions.length>0)){return;}
-r=new RegExp(INST_REGEX);_results=[];for(_i=0,_len=unparsedInstructions.length;_i<_len;_i++){inst=unparsedInstructions[_i];_ref=inst.match(r),m=_ref[0],filter=_ref[1],args=_ref[2];instFunc=new Function("return function() { this."+filter+"("+args+"); };");try{func=instFunc();_results.push(func.call(this.caman));}catch(_error){e=_error;_results.push(Log.debug(e));}}
-return _results;};CamanParser.prototype.execute=function(){var ele;ele=this.ele;return this.caman.render(function(){return ele.parentNode.replaceChild(this.toImage(),ele);});};return CamanParser;})();Caman.Blender=(function(){function Blender(){}
-Blender.blenders={};Blender.register=function(name,func){return this.blenders[name]=func;};Blender.execute=function(name,rgbaLayer,rgbaParent){return this.blenders[name](rgbaLayer,rgbaParent);};return Blender;})();Blender=Caman.Blender;Caman.Calculate=(function(){function Calculate(){}
-Calculate.distance=function(x1,y1,x2,y2){return Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2));};Calculate.randomRange=function(min,max,getFloat){var rand;if(getFloat==null){getFloat=false;}
-rand=min+(Math.random()*(max-min));if(getFloat){return rand.toFixed(getFloat);}else{return Math.round(rand);}};Calculate.luminance=function(rgba){return(0.299*rgba.r)+(0.587*rgba.g)+(0.114*rgba.b);};Calculate.bezier=function(start,ctrl1,ctrl2,end,lowBound,highBound){var bezier,clamp,controlPoints,endX,i,j,lerp,next,prev,t,_i,_j,_ref;if(lowBound==null){lowBound=0;}
-if(highBound==null){highBound=255;}
-if(start[0]instanceof Array){controlPoints=start;lowBound=ctrl1;highBound=ctrl2;}else{controlPoints=[start,ctrl1,ctrl2,end];}
-if(controlPoints.length<2){throw"Invalid number of arguments to bezier";}
-bezier={};lerp=function(a,b,t){return a*(1-t)+b*t;};clamp=function(a,min,max){return Math.min(Math.max(a,min),max);};for(i=_i=0;_i<1000;i=++_i){t=i/1000;prev=controlPoints;while(prev.length>1){next=[];for(j=_j=0,_ref=prev.length-2;0<=_ref?_j<=_ref:_j>=_ref;j=0<=_ref?++_j:--_j){next.push([lerp(prev[j][0],prev[j+1][0],t),lerp(prev[j][1],prev[j+1][1],t)]);}
-prev=next;}
-bezier[Math.round(prev[0][0])]=Math.round(clamp(prev[0][1],lowBound,highBound));}
-endX=controlPoints[controlPoints.length-1][0];bezier=Caman.Calculate.missingValues(bezier,endX);if(bezier[endX]==null){bezier[endX]=bezier[endX-1];}
-return bezier;};Calculate.hermite=function(controlPoints,lowBound,highBound){var add,clamp,count,endX,fac0,fac1,fac2,fac3,i,j,lerp,m0,m1,mul,p,p0,p1,pointsPerSegment,pointsPerStep,pos,ret,sub,t,_i,_j,_ref,_this=this;if(controlPoints.length<2){throw"Invalid number of arguments to hermite";}
-ret={};lerp=function(a,b,t){return a*(1-t)+b*t;};add=function(a,b,c,d){return[a[0]+b[0]+c[0]+d[0],a[1]+b[1]+c[1]+d[1]];};mul=function(a,b){return[a[0]*b[0],a[1]*b[1]];};sub=function(a,b){return[a[0]-b[0],a[1]-b[1]];};clamp=function(a,min,max){return Math.min(Math.max(a,min),max);};count=0;for(i=_i=0,_ref=controlPoints.length-2;0<=_ref?_i<=_ref:_i>=_ref;i=0<=_ref?++_i:--_i){p0=controlPoints[i];p1=controlPoints[i+1];pointsPerSegment=p1[0]-p0[0];pointsPerStep=1/pointsPerSegment;if(i===controlPoints.length-2){pointsPerStep=1/(pointsPerSegment-1);}
-p=i>0?controlPoints[i-1]:p0;m0=mul(sub(p1,p),[0.5,0.5]);p=i=pointsPerSegment;j=0<=pointsPerSegment?++_j:--_j){t=j*pointsPerStep;fac0=2.0*t*t*t-3.0*t*t+1.0;fac1=t*t*t-2.0*t*t+t;fac2=-2.0*t*t*t+3.0*t*t;fac3=t*t*t-t*t;pos=add(mul(p0,[fac0,fac0]),mul(m0,[fac1,fac1]),mul(p1,[fac2,fac2]),mul(m1,[fac3,fac3]));ret[Math.round(pos[0])]=Math.round(clamp(pos[1],lowBound,highBound));count+=1;}}
-endX=controlPoints[controlPoints.length-1][0];ret=Caman.Calculate.missingValues(ret,endX);return ret;};Calculate.missingValues=function(values,endX){var i,j,leftCoord,ret,rightCoord,_i,_j;if(Object.keys(values).length=endX;i=0<=endX?++_i:--_i){if(values[i]!=null){ret[i]=values[i];}else{leftCoord=[i-1,ret[i-1]];for(j=_j=i;i<=endX?_j<=endX:_j>=endX;j=i<=endX?++_j:--_j){if(values[j]!=null){rightCoord=[j,values[j]];break;}}
-ret[i]=leftCoord[1]+((rightCoord[1]-leftCoord[1])/(rightCoord[0]-leftCoord[0]))*(i-leftCoord[0]);}}
-return ret;}
-return values;};return Calculate;})();Calculate=Caman.Calculate;Caman.Convert=(function(){function Convert(){}
-Convert.hexToRGB=function(hex){var b,g,r;if(hex.charAt(0)==="#"){hex=hex.substr(1);}
-r=parseInt(hex.substr(0,2),16);g=parseInt(hex.substr(2,2),16);b=parseInt(hex.substr(4,2),16);return{r:r,g:g,b:b};};Convert.rgbToHSL=function(r,g,b){var d,h,l,max,min,s;if(typeof r==="object"){g=r.g;b=r.b;r=r.r;}
-r/=255;g/=255;b/=255;max=Math.max(r,g,b);min=Math.min(r,g,b);l=(max+min)/2;if(max===min){h=s=0;}else{d=max-min;s=l>0.5?d/(2-max-min):d/(max+min);h=(function(){switch(max){case r:return(g-b)/d+(g1){t-=1;}
-if(t<1/6){return p+(q-p)*6*t;}
-if(t<1/2){return q;}
-if(t<2/3){return p+(q-p)*(2/3-t)*6;}
-return p;};Convert.rgbToHSV=function(r,g,b){var d,h,max,min,s,v;r/=255;g/=255;b/=255;max=Math.max(r,g,b);min=Math.min(r,g,b);v=max;d=max-min;s=max===0?0:d/max;if(max===min){h=0;}else{h=(function(){switch(max){case r:return(g-b)/d+(g0.04045){r=Math.pow((r+0.055)/1.055,2.4);}else{r/=12.92;}
-if(g>0.04045){g=Math.pow((g+0.055)/1.055,2.4);}else{g/=12.92;}
-if(b>0.04045){b=Math.pow((b+0.055)/1.055,2.4);}else{b/=12.92;}
-x=r*0.4124+g*0.3576+b*0.1805;y=r*0.2126+g*0.7152+b*0.0722;z=r*0.0193+g*0.1192+b*0.9505;return{x:x*100,y:y*100,z:z*100};};Convert.xyzToRGB=function(x,y,z){var b,g,r;x/=100;y/=100;z/=100;r=(3.2406*x)+(-1.5372*y)+(-0.4986*z);g=(-0.9689*x)+(1.8758*y)+(0.0415*z);b=(0.0557*x)+(-0.2040*y)+(1.0570*z);if(r>0.0031308){r=(1.055*Math.pow(r,0.4166666667))-0.055;}else{r*=12.92;}
-if(g>0.0031308){g=(1.055*Math.pow(g,0.4166666667))-0.055;}else{g*=12.92;}
-if(b>0.0031308){b=(1.055*Math.pow(b,0.4166666667))-0.055;}else{b*=12.92;}
-return{r:r*255,g:g*255,b:b*255};};Convert.xyzToLab=function(x,y,z){var a,b,l,whiteX,whiteY,whiteZ;if(typeof x==="object"){y=x.y;z=x.z;x=x.x;}
-whiteX=95.047;whiteY=100.0;whiteZ=108.883;x/=whiteX;y/=whiteY;z/=whiteZ;if(x>0.008856451679){x=Math.pow(x,0.3333333333);}else{x=(7.787037037*x)+0.1379310345;}
-if(y>0.008856451679){y=Math.pow(y,0.3333333333);}else{y=(7.787037037*y)+0.1379310345;}
-if(z>0.008856451679){z=Math.pow(z,0.3333333333);}else{z=(7.787037037*z)+0.1379310345;}
-l=116*y-16;a=500*(x-y);b=200*(y-z);return{l:l,a:a,b:b};};Convert.labToXYZ=function(l,a,b){var x,y,z;if(typeof l==="object"){a=l.a;b=l.b;l=l.l;}
-y=(l+16)/116;x=y+(a/500);z=y-(b/200);if(x>0.2068965517){x=x*x*x;}else{x=0.1284185493*(x-0.1379310345);}
-if(y>0.2068965517){y=y*y*y;}else{y=0.1284185493*(y-0.1379310345);}
-if(z>0.2068965517){z=z*z*z;}else{z=0.1284185493*(z-0.1379310345);}
-return{x:x*95.047,y:y*100.0,z:z*108.883};};Convert.rgbToLab=function(r,g,b){var xyz;if(typeof r==="object"){g=r.g;b=r.b;r=r.r;}
-xyz=this.rgbToXYZ(r,g,b);return this.xyzToLab(xyz);};Convert.labToRGB=function(l,a,b){};return Convert;})();Convert=Caman.Convert;Caman.Event=(function(){function Event(){}
-Event.events={};Event.types=["processStart","processComplete","renderStart","renderFinished","blockStarted","blockFinished"];Event.trigger=function(target,type,data){var event,_i,_len,_ref,_results;if(data==null){data=null;}
-if(this.events[type]&&this.events[type].length){_ref=this.events[type];_results=[];for(_i=0,_len=_ref.length;_i<_len;_i++){event=_ref[_i];if(event.target===null||target.id===event.target.id){_results.push(event.fn.call(target,data));}else{_results.push(void 0);}}
-return _results;}};Event.listen=function(target,type,fn){var _fn,_type;if(typeof target==="string"){_type=target;_fn=type;target=null;type=_type;fn=_fn;}
-if(__indexOf.call(this.types,type)<0){return false;}
-if(!this.events[type]){this.events[type]=[];}
-this.events[type].push({target:target,fn:fn});return true;};return Event;})();Event=Caman.Event;Caman.Filter=(function(){function Filter(){}
-Filter.Type={Single:1,Kernel:2,LayerDequeue:3,LayerFinished:4,LoadOverlay:5,Plugin:6};Filter.register=function(name,filterFunc){return Caman.prototype[name]=filterFunc;};return Filter;})();Filter=Caman.Filter;Caman.IO=(function(){function IO(){}
-IO.domainRegex=/(?:(?:http|https):\/\/)((?:\w+)\.(?:(?:\w|\.)+))/;IO.isRemote=function(img){if(img==null){return false;}
-if(this.corsEnabled(img)){return false;}
-return this.isURLRemote(img.src);};IO.corsEnabled=function(img){var _ref;return(img.crossOrigin!=null)&&((_ref=img.crossOrigin.toLowerCase())==='anonymous'||_ref==='use-credentials');};IO.isURLRemote=function(url){var matches;matches=url.match(this.domainRegex);if(matches){return matches[1]!==document.domain;}else{return false;}};IO.remoteCheck=function(src){if(this.isURLRemote(src)){if(!Caman.remoteProxy.length){Log.info("Attempting to load a remote image without a configured proxy. URL: "+src);}else{if(Caman.isURLRemote(Caman.remoteProxy)){Log.info("Cannot use a remote proxy for loading images.");return;}
-return this.proxyUrl(src);}}};IO.proxyUrl=function(src){return""+Caman.remoteProxy+"?"+Caman.proxyParam+"="+(encodeURIComponent(src));};IO.useProxy=function(lang){var langToExt;langToExt={ruby:'rb',python:'py',perl:'pl',javascript:'js'};lang=lang.toLowerCase();if(langToExt[lang]!=null){lang=langToExt[lang];}
-return"proxies/caman_proxy."+lang;};return IO;})();Caman.prototype.save=function(){if(typeof exports!=="undefined"&&exports!==null){return this.nodeSave.apply(this,arguments);}else{return this.browserSave.apply(this,arguments);}};Caman.prototype.browserSave=function(type){var image;if(type==null){type="png";}
-type=type.toLowerCase();image=this.toBase64(type).replace("image/"+type,"image/octet-stream");return document.location.href=image;};Caman.prototype.nodeSave=function(file,overwrite){var e,stats;if(overwrite==null){overwrite=true;}
-try{stats=fs.statSync(file);if(stats.isFile()&&!overwrite){return false;}}catch(_error){e=_error;Log.debug("Creating output file "+file);}
-return fs.writeFile(file,this.canvas.toBuffer(),function(){return Log.debug("Finished writing to "+file);});};Caman.prototype.toImage=function(type){var img;img=document.createElement('img');img.src=this.toBase64(type);img.width=this.dimensions.width;img.height=this.dimensions.height;if(window.devicePixelRatio){img.width/=window.devicePixelRatio;img.height/=window.devicePixelRatio;}
-return img;};Caman.prototype.toBase64=function(type){if(type==null){type="png";}
-type=type.toLowerCase();return this.canvas.toDataURL("image/"+type);};IO=Caman.IO;Caman.Layer=(function(){function Layer(c){this.c=c;this.filter=this.c;this.options={blendingMode:'normal',opacity:1.0};this.layerID=Util.uniqid.get();this.canvas=typeof exports!=="undefined"&&exports!==null?new Canvas():document.createElement('canvas');this.canvas.width=this.c.dimensions.width;this.canvas.height=this.c.dimensions.height;this.context=this.canvas.getContext('2d');this.context.createImageData(this.canvas.width,this.canvas.height);this.imageData=this.context.getImageData(0,0,this.canvas.width,this.canvas.height);this.pixelData=this.imageData.data;}
-Layer.prototype.newLayer=function(cb){return this.c.newLayer.call(this.c,cb);};Layer.prototype.setBlendingMode=function(mode){this.options.blendingMode=mode;return this;};Layer.prototype.opacity=function(opacity){this.options.opacity=opacity/100;return this;};Layer.prototype.copyParent=function(){var i,parentData,_i,_ref;parentData=this.c.pixelData;for(i=_i=0,_ref=this.c.pixelData.length;_i<_ref;i=_i+=4){this.pixelData[i]=parentData[i];this.pixelData[i+1]=parentData[i+1];this.pixelData[i+2]=parentData[i+2];this.pixelData[i+3]=parentData[i+3];}
-return this;};Layer.prototype.fillColor=function(){return this.c.fillColor.apply(this.c,arguments);};Layer.prototype.overlayImage=function(image){if(typeof image==="object"){image=image.src;}else if(typeof image==="string"&&image[0]==="#"){image=$(image).src;}
-if(!image){return this;}
-this.c.renderer.renderQueue.push({type:Filter.Type.LoadOverlay,src:image,layer:this});return this;};Layer.prototype.applyToParent=function(){var i,layerData,parentData,result,rgbaLayer,rgbaParent,_i,_ref,_results;parentData=this.c.pixelStack[this.c.pixelStack.length-1];layerData=this.c.pixelData;_results=[];for(i=_i=0,_ref=layerData.length;_i<_ref;i=_i+=4){rgbaParent={r:parentData[i],g:parentData[i+1],b:parentData[i+2],a:parentData[i+3]};rgbaLayer={r:layerData[i],g:layerData[i+1],b:layerData[i+2],a:layerData[i+3]};result=Blender.execute(this.options.blendingMode,rgbaLayer,rgbaParent);result.r=Util.clampRGB(result.r);result.g=Util.clampRGB(result.g);result.b=Util.clampRGB(result.b);if(result.a==null){result.a=rgbaLayer.a;}
-parentData[i]=rgbaParent.r-((rgbaParent.r-result.r)*(this.options.opacity*(result.a/255)));parentData[i+1]=rgbaParent.g-((rgbaParent.g-result.g)*(this.options.opacity*(result.a/255)));_results.push(parentData[i+2]=rgbaParent.b-((rgbaParent.b-result.b)*(this.options.opacity*(result.a/255))));}
-return _results;};return Layer;})();Layer=Caman.Layer;Caman.Logger=(function(){function Logger(){var name,_i,_len,_ref;_ref=['log','info','warn','error'];for(_i=0,_len=_ref.length;_i<_len;_i++){name=_ref[_i];this[name]=(function(name){return function(){var args,e;args=1<=arguments.length?__slice.call(arguments,0):[];if(!Caman.DEBUG){return;}
-try{return console[name].apply(console,args);}catch(_error){e=_error;return console[name](args);}};})(name);}
-this.debug=this.log;}
-return Logger;})();Log=new Caman.Logger();Caman.Pixel=(function(){Pixel.coordinatesToLocation=function(x,y,width){return(y*width+x)*4;};Pixel.locationToCoordinates=function(loc,width){var x,y;y=Math.floor(loc/(width*4));x=(loc%(width*4))/4;return{x:x,y:y};};function Pixel(r,g,b,a,c){this.r=r!=null?r:0;this.g=g!=null?g:0;this.b=b!=null?b:0;this.a=a!=null?a:255;this.c=c!=null?c:null;this.loc=0;}
-Pixel.prototype.setContext=function(c){return this.c=c;};Pixel.prototype.locationXY=function(){var x,y;if(this.c==null){throw"Requires a CamanJS context";}
-y=this.c.dimensions.height-Math.floor(this.loc/(this.c.dimensions.width*4));x=(this.loc%(this.c.dimensions.width*4))/4;return{x:x,y:y};};Pixel.prototype.pixelAtLocation=function(loc){if(this.c==null){throw"Requires a CamanJS context";}
-return new Pixel(this.c.pixelData[loc],this.c.pixelData[loc+1],this.c.pixelData[loc+2],this.c.pixelData[loc+3],this.c);};Pixel.prototype.getPixelRelative=function(horiz,vert){var newLoc;if(this.c==null){throw"Requires a CamanJS context";}
-newLoc=this.loc+(this.c.dimensions.width*4*(vert*-1))+(4*horiz);if(newLoc>this.c.pixelData.length||newLoc<0){return new Pixel(0,0,0,255,this.c);}
-return this.pixelAtLocation(newLoc);};Pixel.prototype.putPixelRelative=function(horiz,vert,rgba){var nowLoc;if(this.c==null){throw"Requires a CamanJS context";}
-nowLoc=this.loc+(this.c.dimensions.width*4*(vert*-1))+(4*horiz);if(newLoc>this.c.pixelData.length||newLoc<0){return;}
-this.c.pixelData[newLoc]=rgba.r;this.c.pixelData[newLoc+1]=rgba.g;this.c.pixelData[newLoc+2]=rgba.b;this.c.pixelData[newLoc+3]=rgba.a;return true;};Pixel.prototype.getPixel=function(x,y){var loc;if(this.c==null){throw"Requires a CamanJS context";}
-loc=this.coordinatesToLocation(x,y,this.width);return this.pixelAtLocation(loc);};Pixel.prototype.putPixel=function(x,y,rgba){var loc;if(this.c==null){throw"Requires a CamanJS context";}
-loc=this.coordinatesToLocation(x,y,this.width);this.c.pixelData[loc]=rgba.r;this.c.pixelData[loc+1]=rgba.g;this.c.pixelData[loc+2]=rgba.b;return this.c.pixelData[loc+3]=rgba.a;};Pixel.prototype.toString=function(){return this.toKey();};Pixel.prototype.toHex=function(includeAlpha){var hex;if(includeAlpha==null){includeAlpha=false;}
-hex='#'+this.r.toString(16)+this.g.toString(16)+this.b.toString(16);if(includeAlpha){return hex+this.a.toString(16);}else{return hex;}};return Pixel;})();Pixel=Caman.Pixel;Caman.Plugin=(function(){function Plugin(){}
-Plugin.plugins={};Plugin.register=function(name,plugin){return this.plugins[name]=plugin;};Plugin.execute=function(context,name,args){return this.plugins[name].apply(context,args);};return Plugin;})();Plugin=Caman.Plugin;Caman.Renderer=(function(){Renderer.Blocks=Caman.NodeJS?require('os').cpus().length:4;function Renderer(c){this.c=c;this.processNext=__bind(this.processNext,this);this.renderQueue=[];this.modPixelData=null;}
-Renderer.prototype.add=function(job){if(job==null){return;}
-return this.renderQueue.push(job);};Renderer.prototype.processNext=function(){var layer;if(this.renderQueue.length===0){Event.trigger(this,"renderFinished");if(this.finishedFn!=null){this.finishedFn.call(this.c);}
-return this;}
-this.currentJob=this.renderQueue.shift();switch(this.currentJob.type){case Filter.Type.LayerDequeue:layer=this.c.canvasQueue.shift();this.c.executeLayer(layer);return this.processNext();case Filter.Type.LayerFinished:this.c.applyCurrentLayer();this.c.popContext();return this.processNext();case Filter.Type.LoadOverlay:return this.loadOverlay(this.currentJob.layer,this.currentJob.src);case Filter.Type.Plugin:return this.executePlugin();default:return this.executeFilter();}};Renderer.prototype.execute=function(callback){this.finishedFn=callback;this.modPixelData=Util.dataArray(this.c.pixelData.length);return this.processNext();};Renderer.prototype.eachBlock=function(fn){var blockN,blockPixelLength,bnum,end,f,i,lastBlockN,n,start,_i,_ref,_results,_this=this;this.blocksDone=0;n=this.c.pixelData.length;blockPixelLength=Math.floor((n/4)/Renderer.Blocks);blockN=blockPixelLength*4;lastBlockN=blockN+((n/4)%Renderer.Blocks)*4;_results=[];for(i=_i=0,_ref=Renderer.Blocks;0<=_ref?_i<_ref:_i>_ref;i=0<=_ref?++_i:--_i){start=i*blockN;end=start+(i===Renderer.Blocks-1?lastBlockN:blockN);if(Caman.NodeJS){f=Fiber(function(){return fn.call(_this,i,start,end);});bnum=f.run();_results.push(this.blockFinished(bnum));}else{_results.push(setTimeout((function(i,start,end){return function(){return fn.call(_this,i,start,end);};})(i,start,end),0));}}
-return _results;};Renderer.prototype.executeFilter=function(){Event.trigger(this.c,"processStart",this.currentJob);if(this.currentJob.type===Filter.Type.Single){return this.eachBlock(this.renderBlock);}else{return this.eachBlock(this.renderKernel);}};Renderer.prototype.executePlugin=function(){Log.debug("Executing plugin "+this.currentJob.plugin);Plugin.execute(this.c,this.currentJob.plugin,this.currentJob.args);Log.debug("Plugin "+this.currentJob.plugin+" finished!");return this.processNext();};Renderer.prototype.renderBlock=function(bnum,start,end){var i,pixel,_i;Log.debug("Block #"+bnum+" - Filter: "+this.currentJob.name+", Start: "+start+", End: "+end);Event.trigger(this.c,"blockStarted",{blockNum:bnum,totalBlocks:Renderer.Blocks,startPixel:start,endPixel:end});pixel=new Pixel();pixel.setContext(this.c);for(i=_i=start;_i=builder;j=-builder<=builder?++_j:--_j){for(k=_k=builder;builder<=-builder?_k<=-builder:_k>=-builder;k=builder<=-builder?++_k:--_k){p=pixel.getPixelRelative(j,k);kernel[builderIndex*3]=p.r;kernel[builderIndex*3+1]=p.g;kernel[builderIndex*3+2]=p.b;builderIndex++;}}
-res=this.processKernel(adjust,kernel,divisor,bias);this.modPixelData[i]=Util.clampRGB(res.r);this.modPixelData[i+1]=Util.clampRGB(res.g);this.modPixelData[i+2]=Util.clampRGB(res.b);this.modPixelData[i+3]=this.c.pixelData[i+3];}
-if(Caman.NodeJS){return Fiber["yield"](bnum);}else{return this.blockFinished(bnum);}};Renderer.prototype.blockFinished=function(bnum){var i,_i,_ref;if(bnum>=0){Log.debug("Block #"+bnum+" finished! Filter: "+this.currentJob.name);}
-this.blocksDone++;Event.trigger(this.c,"blockFinished",{blockNum:bnum,blocksFinished:this.blocksDone,totalBlocks:Renderer.Blocks});if(this.blocksDone===Renderer.Blocks){if(this.currentJob.type===Filter.Type.Kernel){for(i=_i=0,_ref=this.c.pixelData.length;0<=_ref?_i<_ref:_i>_ref;i=0<=_ref?++_i:--_i){this.c.pixelData[i]=this.modPixelData[i];}}
-if(bnum>=0){Log.debug("Filter "+this.currentJob.name+" finished!");}
-Event.trigger(this.c,"processComplete",this.currentJob);return this.processNext();}};Renderer.prototype.processKernel=function(adjust,kernel,divisor,bias){var i,val,_i,_ref;val={r:0,g:0,b:0};for(i=_i=0,_ref=adjust.length;0<=_ref?_i<_ref:_i>_ref;i=0<=_ref?++_i:--_i){val.r+=adjust[i]*kernel[i*3];val.g+=adjust[i]*kernel[i*3+1];val.b+=adjust[i]*kernel[i*3+2];}
-val.r=(val.r/divisor)+bias;val.g=(val.g/divisor)+bias;val.b=(val.b/divisor)+bias;return val;};Renderer.prototype.loadOverlay=function(layer,src){var img,proxyUrl,_this=this;img=document.createElement('img');img.onload=function(){layer.context.drawImage(img,0,0,_this.c.dimensions.width,_this.c.dimensions.height);layer.imageData=layer.context.getImageData(0,0,_this.c.dimensions.width,_this.c.dimensions.height);layer.pixelData=layer.imageData.data;_this.c.pixelData=layer.pixelData;return _this.processNext();};proxyUrl=IO.remoteCheck(src);return img.src=proxyUrl!=null?proxyUrl:src;};return Renderer;})();Renderer=Caman.Renderer;Caman.Store=(function(){function Store(){}
-Store.items={};Store.has=function(search){return this.items[search]!=null;};Store.get=function(search){return this.items[search];};Store.put=function(name,obj){return this.items[name]=obj;};Store.execute=function(search,callback){var _this=this;setTimeout(function(){return callback.call(_this.get(search),_this.get(search));},0);return this.get(search);};Store.flush=function(name){if(name==null){name=false;}
-if(name){return delete this.items[name];}else{return this.items={};}};return Store;})();Store=Caman.Store;Blender.register("normal",function(rgbaLayer,rgbaParent){return{r:rgbaLayer.r,g:rgbaLayer.g,b:rgbaLayer.b};});Blender.register("multiply",function(rgbaLayer,rgbaParent){return{r:(rgbaLayer.r*rgbaParent.r)/255,g:(rgbaLayer.g*rgbaParent.g)/255,b:(rgbaLayer.b*rgbaParent.b)/255};});Blender.register("screen",function(rgbaLayer,rgbaParent){return{r:255-(((255-rgbaLayer.r)*(255-rgbaParent.r))/255),g:255-(((255-rgbaLayer.g)*(255-rgbaParent.g))/255),b:255-(((255-rgbaLayer.b)*(255-rgbaParent.b))/255)};});Blender.register("overlay",function(rgbaLayer,rgbaParent){var result;result={};result.r=rgbaParent.r>128?255-2*(255-rgbaLayer.r)*(255-rgbaParent.r)/255:(rgbaParent.r*rgbaLayer.r*2)/255;result.g=rgbaParent.g>128?255-2*(255-rgbaLayer.g)*(255-rgbaParent.g)/255:(rgbaParent.g*rgbaLayer.g*2)/255;result.b=rgbaParent.b>128?255-2*(255-rgbaLayer.b)*(255-rgbaParent.b)/255:(rgbaParent.b*rgbaLayer.b*2)/255;return result;});Blender.register("difference",function(rgbaLayer,rgbaParent){return{r:rgbaLayer.r-rgbaParent.r,g:rgbaLayer.g-rgbaParent.g,b:rgbaLayer.b-rgbaParent.b};});Blender.register("addition",function(rgbaLayer,rgbaParent){return{r:rgbaParent.r+rgbaLayer.r,g:rgbaParent.g+rgbaLayer.g,b:rgbaParent.b+rgbaLayer.b};});Blender.register("exclusion",function(rgbaLayer,rgbaParent){return{r:128-2*(rgbaParent.r-128)*(rgbaLayer.r-128)/255,g:128-2*(rgbaParent.g-128)*(rgbaLayer.g-128)/255,b:128-2*(rgbaParent.b-128)*(rgbaLayer.b-128)/255};});Blender.register("softLight",function(rgbaLayer,rgbaParent){var result;result={};result.r=rgbaParent.r>128?255-((255-rgbaParent.r)*(255-(rgbaLayer.r-128)))/255:(rgbaParent.r*(rgbaLayer.r+128))/255;result.g=rgbaParent.g>128?255-((255-rgbaParent.g)*(255-(rgbaLayer.g-128)))/255:(rgbaParent.g*(rgbaLayer.g+128))/255;result.b=rgbaParent.b>128?255-((255-rgbaParent.b)*(255-(rgbaLayer.b-128)))/255:(rgbaParent.b*(rgbaLayer.b+128))/255;return result;});Blender.register("lighten",function(rgbaLayer,rgbaParent){return{r:rgbaParent.r>rgbaLayer.r?rgbaParent.r:rgbaLayer.r,g:rgbaParent.g>rgbaLayer.g?rgbaParent.g:rgbaLayer.g,b:rgbaParent.b>rgbaLayer.b?rgbaParent.b:rgbaLayer.b};});Blender.register("darken",function(rgbaLayer,rgbaParent){return{r:rgbaParent.r>rgbaLayer.r?rgbaLayer.r:rgbaParent.r,g:rgbaParent.g>rgbaLayer.g?rgbaLayer.g:rgbaParent.g,b:rgbaParent.b>rgbaLayer.b?rgbaLayer.b:rgbaParent.b};});Filter.register("fillColor",function(){var color;if(arguments.length===1){color=Convert.hexToRGB(arguments[0]);}else{color={r:arguments[0],g:arguments[1],b:arguments[2]};}
-return this.process("fillColor",function(rgba){rgba.r=color.r;rgba.g=color.g;rgba.b=color.b;rgba.a=255;return rgba;});});Filter.register("brightness",function(adjust){adjust=Math.floor(255*(adjust/100));return this.process("brightness",function(rgba){rgba.r+=adjust;rgba.g+=adjust;rgba.b+=adjust;return rgba;});});Filter.register("saturation",function(adjust){adjust*=-0.01;return this.process("saturation",function(rgba){var max;max=Math.max(rgba.r,rgba.g,rgba.b);if(rgba.r!==max){rgba.r+=(max-rgba.r)*adjust;}
-if(rgba.g!==max){rgba.g+=(max-rgba.g)*adjust;}
-if(rgba.b!==max){rgba.b+=(max-rgba.b)*adjust;}
-return rgba;});});Filter.register("vibrance",function(adjust){adjust*=-1;return this.process("vibrance",function(rgba){var amt,avg,max;max=Math.max(rgba.r,rgba.g,rgba.b);avg=(rgba.r+rgba.g+rgba.b)/3;amt=((Math.abs(max-avg)*2/255)*adjust)/100;if(rgba.r!==max){rgba.r+=(max-rgba.r)*amt;}
-if(rgba.g!==max){rgba.g+=(max-rgba.g)*amt;}
-if(rgba.b!==max){rgba.b+=(max-rgba.b)*amt;}
-return rgba;});});Filter.register("greyscale",function(adjust){return this.process("greyscale",function(rgba){var avg;avg=Calculate.luminance(rgba);rgba.r=avg;rgba.g=avg;rgba.b=avg;return rgba;});});Filter.register("contrast",function(adjust){adjust=Math.pow((adjust+100)/100,2);return this.process("contrast",function(rgba){rgba.r/=255;rgba.r-=0.5;rgba.r*=adjust;rgba.r+=0.5;rgba.r*=255;rgba.g/=255;rgba.g-=0.5;rgba.g*=adjust;rgba.g+=0.5;rgba.g*=255;rgba.b/=255;rgba.b-=0.5;rgba.b*=adjust;rgba.b+=0.5;rgba.b*=255;return rgba;});});Filter.register("hue",function(adjust){return this.process("hue",function(rgba){var b,g,h,hsv,r,_ref;hsv=Convert.rgbToHSV(rgba.r,rgba.g,rgba.b);h=hsv.h*100;h+=Math.abs(adjust);h=h%100;h/=100;hsv.h=h;_ref=Convert.hsvToRGB(hsv.h,hsv.s,hsv.v),r=_ref.r,g=_ref.g,b=_ref.b;rgba.r=r;rgba.g=g;rgba.b=b;return rgba;});});Filter.register("colorize",function(){var level,rgb;if(arguments.length===2){rgb=Convert.hexToRGB(arguments[0]);level=arguments[1];}else if(arguments.length===4){rgb={r:arguments[0],g:arguments[1],b:arguments[2]};level=arguments[3];}
-return this.process("colorize",function(rgba){rgba.r-=(rgba.r-rgb.r)*(level/100);rgba.g-=(rgba.g-rgb.g)*(level/100);rgba.b-=(rgba.b-rgb.b)*(level/100);return rgba;});});Filter.register("invert",function(){return this.process("invert",function(rgba){rgba.r=255-rgba.r;rgba.g=255-rgba.g;rgba.b=255-rgba.b;return rgba;});});Filter.register("sepia",function(adjust){if(adjust==null){adjust=100;}
-adjust/=100;return this.process("sepia",function(rgba){rgba.r=Math.min(255,(rgba.r*(1-(0.607*adjust)))+(rgba.g*(0.769*adjust))+(rgba.b*(0.189*adjust)));rgba.g=Math.min(255,(rgba.r*(0.349*adjust))+(rgba.g*(1-(0.314*adjust)))+(rgba.b*(0.168*adjust)));rgba.b=Math.min(255,(rgba.r*(0.272*adjust))+(rgba.g*(0.534*adjust))+(rgba.b*(1-(0.869*adjust))));return rgba;});});Filter.register("gamma",function(adjust){return this.process("gamma",function(rgba){rgba.r=Math.pow(rgba.r/255,adjust)*255;rgba.g=Math.pow(rgba.g/255,adjust)*255;rgba.b=Math.pow(rgba.b/255,adjust)*255;return rgba;});});Filter.register("noise",function(adjust){adjust=Math.abs(adjust)*2.55;return this.process("noise",function(rgba){var rand;rand=Calculate.randomRange(adjust*-1,adjust);rgba.r+=rand;rgba.g+=rand;rgba.b+=rand;return rgba;});});Filter.register("clip",function(adjust){adjust=Math.abs(adjust)*2.55;return this.process("clip",function(rgba){if(rgba.r>255-adjust){rgba.r=255;}else if(rgba.r255-adjust){rgba.g=255;}else if(rgba.g255-adjust){rgba.b=255;}else if(rgba.b0){rgba.r+=(255-rgba.r)*options.red;}else{rgba.r-=rgba.r*Math.abs(options.red);}}
-if(options.green!=null){if(options.green>0){rgba.g+=(255-rgba.g)*options.green;}else{rgba.g-=rgba.g*Math.abs(options.green);}}
-if(options.blue!=null){if(options.blue>0){rgba.b+=(255-rgba.b)*options.blue;}else{rgba.b-=rgba.b*Math.abs(options.blue);}}
-return rgba;});});Filter.register("curves",function(){var algo,bezier,chans,cps,end,i,last,start,_i,_j,_ref,_ref1;chans=arguments[0],cps=2<=arguments.length?__slice.call(arguments,1):[];last=cps[cps.length-1];if(typeof last==="function"){algo=last;cps.pop();}else if(typeof last==="string"){algo=Calculate[last];cps.pop();}else{algo=Calculate.bezier;}
-if(typeof chans==="string"){chans=chans.split("");}
-if(chans[0]==="v"){chans=['r','g','b'];}
-if(cps.length<2){throw"Invalid number of arguments to curves filter";}
-bezier=algo(cps,0,255);start=cps[0];if(start[0]>0){for(i=_i=0,_ref=start[0];0<=_ref?_i<_ref:_i>_ref;i=0<=_ref?++_i:--_i){bezier[i]=start[1];}}
-end=cps[cps.length-1];if(end[0]<255){for(i=_j=_ref1=end[0];_ref1<=255?_j<=255:_j>=255;i=_ref1<=255?++_j:--_j){bezier[i]=end[1];}}
-return this.process("curves",function(rgba){var _k,_ref2;for(i=_k=0,_ref2=chans.length;0<=_ref2?_k<_ref2:_k>_ref2;i=0<=_ref2?++_k:--_k){rgba[chans[i]]=bezier[rgba[chans[i]]];}
-return rgba;});});Filter.register("exposure",function(adjust){var ctrl1,ctrl2,p;p=Math.abs(adjust)/100;ctrl1=[0,255*p];ctrl2=[255-(255*p),255];if(adjust<0){ctrl1=ctrl1.reverse();ctrl2=ctrl2.reverse();}
-return this.curves('rgb',[0,0],ctrl1,ctrl2,[255,255]);});Caman.Plugin.register("crop",function(width,height,x,y){var canvas,ctx;if(x==null){x=0;}
-if(y==null){y=0;}
-if(typeof exports!=="undefined"&&exports!==null){canvas=new Canvas(width,height);}else{canvas=document.createElement('canvas');Util.copyAttributes(this.canvas,canvas);canvas.width=width;canvas.height=height;}
-ctx=canvas.getContext('2d');ctx.drawImage(this.canvas,x,y,width,height,0,0,width,height);this.cropCoordinates={x:x,y:y};this.cropped=true;return this.replaceCanvas(canvas);});Caman.Plugin.register("resize",function(newDims){var canvas,ctx;if(newDims==null){newDims=null;}
-if(newDims===null||((newDims.width==null)&&(newDims.height==null))){Log.error("Invalid or missing dimensions given for resize");return;}
-if(newDims.width==null){newDims.width=this.canvas.width*newDims.height/this.canvas.height;}else if(newDims.height==null){newDims.height=this.canvas.height*newDims.width/this.canvas.width;}
-if(typeof exports!=="undefined"&&exports!==null){canvas=new Canvas(newDims.width,newDims.height);}else{canvas=document.createElement('canvas');Util.copyAttributes(this.canvas,canvas);canvas.width=newDims.width;canvas.height=newDims.height;}
-ctx=canvas.getContext('2d');ctx.drawImage(this.canvas,0,0,this.canvas.width,this.canvas.height,0,0,newDims.width,newDims.height);this.resized=true;return this.replaceCanvas(canvas);});Caman.Filter.register("crop",function(){return this.processPlugin("crop",Array.prototype.slice.call(arguments,0));});Caman.Filter.register("resize",function(){return this.processPlugin("resize",Array.prototype.slice.call(arguments,0));});}).call(this);
\ No newline at end of file
diff --git a/client/src/js/vendor/hmap.js b/client/src/js/vendor/hmap.js
deleted file mode 100755
index dc0c1ba09..000000000
--- a/client/src/js/vendor/hmap.js
+++ /dev/null
@@ -1,701 +0,0 @@
-/*
- * heatmap.js v2.0.0 | JavaScript Heatmap Library
- *
- * Copyright 2008-2014 Patrick Wied - All rights reserved.
- * Dual licensed under MIT and Beerware license
- *
- * :: 2014-10-31 21:16
- */
-;(function (name, context, factory) {
-
- // Supports UMD. AMD, CommonJS/Node.js and browser context
- if (typeof module !== "undefined" && module.exports) {
- module.exports = factory();
- } else if (typeof define === "function" && define.amd) {
- define(factory);
- } else {
- context[name] = factory();
- }
-
-})("h337", this, function () {
-
-// Heatmap Config stores default values and will be merged with instance config
-var HeatmapConfig = {
- defaultRadius: 40,
- defaultRenderer: 'canvas2d',
- defaultGradient: { 0.25: "rgb(0,0,255)", 0.55: "rgb(0,255,0)", 0.85: "yellow", 1.0: "rgb(255,0,0)"},
- defaultMaxOpacity: 1,
- defaultMinOpacity: 0,
- defaultBlur: .85,
- defaultXField: 'x',
- defaultYField: 'y',
- defaultValueField: 'value',
- plugins: {}
-};
-var Store = (function StoreClosure() {
-
- var Store = function Store(config) {
- this._coordinator = {};
- this._data = [];
- this._radi = [];
- this._min = 0;
- this._max = 1;
- this._xField = config['xField'] || config.defaultXField;
- this._yField = config['yField'] || config.defaultYField;
- this._valueField = config['valueField'] || config.defaultValueField;
-
- if (config["radius"]) {
- this._cfgRadius = config["radius"];
- }
- };
-
- var defaultRadius = HeatmapConfig.defaultRadius;
-
- Store.prototype = {
- // when forceRender = false -> called from setData, omits renderall event
- _organiseData: function(dataPoint, forceRender) {
- var x = dataPoint[this._xField];
- var y = dataPoint[this._yField];
- var radi = this._radi;
- var store = this._data;
- var max = this._max;
- var min = this._min;
- var value = dataPoint[this._valueField] || 1;
- var radius = dataPoint.radius || this._cfgRadius || defaultRadius;
-
- if (!store[x]) {
- store[x] = [];
- radi[x] = [];
- }
-
- if (!store[x][y]) {
- store[x][y] = value;
- radi[x][y] = radius;
- } else {
- store[x][y] += value;
- }
-
- if (store[x][y] > max) {
- if (!forceRender) {
- this._max = store[x][y];
- } else {
- this.setDataMax(store[x][y]);
- }
- return false;
- } else{
- return {
- x: x,
- y: y,
- value: value,
- radius: radius,
- min: min,
- max: max
- };
- }
- },
- _unOrganizeData: function() {
- var unorganizedData = [];
- var data = this._data;
- var radi = this._radi;
-
- for (var x in data) {
- for (var y in data[x]) {
-
- unorganizedData.push({
- x: x,
- y: y,
- radius: radi[x][y],
- value: data[x][y]
- });
-
- }
- }
- return {
- min: this._min,
- max: this._max,
- data: unorganizedData
- };
- },
- _onExtremaChange: function() {
- this._coordinator.emit('extremachange', {
- min: this._min,
- max: this._max
- });
- },
- addData: function() {
- if (arguments[0].length > 0) {
- var dataArr = arguments[0];
- var dataLen = dataArr.length;
- while (dataLen--) {
- this.addData.call(this, dataArr[dataLen]);
- }
- } else {
- // add to store
- var organisedEntry = this._organiseData(arguments[0], true);
- if (organisedEntry) {
- this._coordinator.emit('renderpartial', {
- min: this._min,
- max: this._max,
- data: [organisedEntry]
- });
- }
- }
- return this;
- },
- setData: function(data) {
- var dataPoints = data.data;
- var pointsLen = dataPoints.length;
-
-
- // reset data arrays
- this._data = [];
- this._radi = [];
-
- for(var i = 0; i < pointsLen; i++) {
- this._organiseData(dataPoints[i], false);
- }
- this._max = data.max;
- this._min = data.min || 0;
-
- this._onExtremaChange();
- this._coordinator.emit('renderall', this._getInternalData());
- return this;
- },
- removeData: function() {
- // TODO: implement
- },
- setDataMax: function(max) {
- this._max = max;
- this._onExtremaChange();
- this._coordinator.emit('renderall', this._getInternalData());
- return this;
- },
- setDataMin: function(min) {
- this._min = min;
- this._onExtremaChange();
- this._coordinator.emit('renderall', this._getInternalData());
- return this;
- },
- setCoordinator: function(coordinator) {
- this._coordinator = coordinator;
- },
- _getInternalData: function() {
- return {
- max: this._max,
- min: this._min,
- data: this._data,
- radi: this._radi
- };
- },
- getData: function() {
- return this._unOrganizeData();
- }/*,
-
- TODO: rethink.
-
- getValueAt: function(point) {
- var value;
- var radius = 100;
- var x = point.x;
- var y = point.y;
- var data = this._data;
-
- if (data[x] && data[x][y]) {
- return data[x][y];
- } else {
- var values = [];
- // radial search for datapoints based on default radius
- for(var distance = 1; distance < radius; distance++) {
- var neighbors = distance * 2 +1;
- var startX = x - distance;
- var startY = y - distance;
-
- for(var i = 0; i < neighbors; i++) {
- for (var o = 0; o < neighbors; o++) {
- if ((i == 0 || i == neighbors-1) || (o == 0 || o == neighbors-1)) {
- if (data[startY+i] && data[startY+i][startX+o]) {
- values.push(data[startY+i][startX+o]);
- }
- } else {
- continue;
- }
- }
- }
- }
- if (values.length > 0) {
- return Math.max.apply(Math, values);
- }
- }
- return false;
- }*/
- };
-
-
- return Store;
-})();
-
-var Canvas2dRenderer = (function Canvas2dRendererClosure() {
-
- var _getColorPalette = function(config) {
- var gradientConfig = config.gradient || config.defaultGradient;
- var paletteCanvas = document.createElement('canvas');
- var paletteCtx = paletteCanvas.getContext('2d');
-
- paletteCanvas.width = 256;
- paletteCanvas.height = 1;
-
- var gradient = paletteCtx.createLinearGradient(0, 0, 256, 1);
- for (var key in gradientConfig) {
- gradient.addColorStop(key, gradientConfig[key]);
- }
-
- paletteCtx.fillStyle = gradient;
- paletteCtx.fillRect(0, 0, 256, 1);
-
- return paletteCtx.getImageData(0, 0, 256, 1).data;
- };
-
- var _getPointTemplate = function(radius, blurFactor) {
- var tplCanvas = document.createElement('canvas');
- var tplCtx = tplCanvas.getContext('2d');
- var x = radius;
- var y = radius;
- tplCanvas.width = tplCanvas.height = radius*2;
-
- if (blurFactor == 1) {
- tplCtx.beginPath();
- tplCtx.arc(x, y, radius, 0, 2 * Math.PI, false);
- tplCtx.fillStyle = 'rgba(0,0,0,1)';
- tplCtx.fill();
- } else {
- var gradient = tplCtx.createRadialGradient(x, y, radius*blurFactor, x, y, radius);
- gradient.addColorStop(0, 'rgba(0,0,0,1)');
- gradient.addColorStop(1, 'rgba(0,0,0,0)');
- tplCtx.fillStyle = gradient;
- tplCtx.fillRect(0, 0, 2*radius, 2*radius);
- }
-
-
-
- return tplCanvas;
- };
-
- var _prepareData = function(data) {
- var renderData = [];
- var min = data.min;
- var max = data.max;
- var radi = data.radi;
- var data = data.data;
-
- var xValues = Object.keys(data);
- var xValuesLen = xValues.length;
-
- while(xValuesLen--) {
- var xValue = xValues[xValuesLen];
- var yValues = Object.keys(data[xValue]);
- var yValuesLen = yValues.length;
- while(yValuesLen--) {
- var yValue = yValues[yValuesLen];
- var value = data[xValue][yValue];
- var radius = radi[xValue][yValue];
- renderData.push({
- x: xValue,
- y: yValue,
- value: value,
- radius: radius
- });
- }
- }
-
- return {
- min: min,
- max: max,
- data: renderData
- };
- };
-
-
- function Canvas2dRenderer(config) {
- var container = config.container;
- var shadowCanvas = this.shadowCanvas = document.createElement('canvas');
- var canvas = this.canvas = config.canvas || document.createElement('canvas');
- var renderBoundaries = this._renderBoundaries = [10000, 10000, 0, 0];
-
- var computed = getComputedStyle(config.container) || {};
-
- canvas.className = 'heatmap-canvas';
-
- this._width = canvas.width = shadowCanvas.width = +(computed.width.replace(/px/,''));
- this._height = canvas.height = shadowCanvas.height = +(computed.height.replace(/px/,''));
-
- this.shadowCtx = shadowCanvas.getContext('2d');
- this.ctx = canvas.getContext('2d');
-
- // @TODO:
- // conditional wrapper
-
- canvas.style.cssText = shadowCanvas.style.cssText = 'position:absolute;left:0;top:0;';
-
- container.style.position = 'relative';
- container.appendChild(canvas);
-
- this._palette = _getColorPalette(config);
- this._templates = {};
-
- this._setStyles(config);
- };
-
- Canvas2dRenderer.prototype = {
- renderPartial: function(data) {
- this._drawAlpha(data);
- this._colorize();
- },
- renderAll: function(data) {
- // reset render boundaries
- this._clear();
- this._drawAlpha(_prepareData(data));
- this._colorize();
- },
- _updateGradient: function(config) {
- this._palette = _getColorPalette(config);
- },
- updateConfig: function(config) {
- if (config['gradient']) {
- this._updateGradient(config);
- }
- this._setStyles(config);
- },
- setDimensions: function(width, height) {
- this._width = width;
- this._height = height;
- this.canvas.width = this.shadowCanvas.width = width;
- this.canvas.height = this.shadowCanvas.height = height;
- },
- _clear: function() {
- this.shadowCtx.clearRect(0, 0, this._width, this._height);
- this.ctx.clearRect(0, 0, this._width, this._height);
- },
- _setStyles: function(config) {
- this._blur = (config.blur == 0)?0:(config.blur || config.defaultBlur);
-
- if (config.backgroundColor) {
- this.canvas.style.backgroundColor = config.backgroundColor;
- }
-
- this._opacity = (config.opacity || 0) * 255;
- this._maxOpacity = (config.maxOpacity || config.defaultMaxOpacity) * 255;
- this._minOpacity = (config.minOpacity || config.defaultMinOpacity) * 255;
- this._useGradientOpacity = !!config.useGradientOpacity;
- },
- _drawAlpha: function(data) {
- var min = this._min = data.min;
- var max = this._max = data.max;
- var data = data.data || [];
- var dataLen = data.length;
- // on a point basis?
- var blur = 1 - this._blur;
-
- while(dataLen--) {
-
- var point = data[dataLen];
-
- var x = point.x;
- var y = point.y;
- var radius = point.radius;
- // if value is bigger than max
- // use max as value
- var value = Math.min(point.value, max);
- var rectX = x - radius;
- var rectY = y - radius;
- var shadowCtx = this.shadowCtx;
-
-
-
-
- var tpl;
- if (!this._templates[radius]) {
- this._templates[radius] = tpl = _getPointTemplate(radius, blur);
- } else {
- tpl = this._templates[radius];
- }
- // value from minimum / value range
- // => [0, 1]
- shadowCtx.globalAlpha = (value-min)/(max-min);
-
- shadowCtx.drawImage(tpl, rectX, rectY);
-
- // update renderBoundaries
- if (rectX < this._renderBoundaries[0]) {
- this._renderBoundaries[0] = rectX;
- }
- if (rectY < this._renderBoundaries[1]) {
- this._renderBoundaries[1] = rectY;
- }
- if (rectX + 2*radius > this._renderBoundaries[2]) {
- this._renderBoundaries[2] = rectX + 2*radius;
- }
- if (rectY + 2*radius > this._renderBoundaries[3]) {
- this._renderBoundaries[3] = rectY + 2*radius;
- }
-
- }
- },
- _colorize: function() {
- var x = this._renderBoundaries[0];
- var y = this._renderBoundaries[1];
- var width = this._renderBoundaries[2] - x;
- var height = this._renderBoundaries[3] - y;
- var maxWidth = this._width;
- var maxHeight = this._height;
- var opacity = this._opacity;
- var maxOpacity = this._maxOpacity;
- var minOpacity = this._minOpacity;
- var useGradientOpacity = this._useGradientOpacity;
-
- if (x < 0) {
- x = 0;
- }
- if (y < 0) {
- y = 0;
- }
- if (x + width > maxWidth) {
- width = maxWidth - x;
- }
- if (y + height > maxHeight) {
- height = maxHeight - y;
- }
-
- var img = this.shadowCtx.getImageData(x, y, width, height);
- var imgData = img.data;
- var len = imgData.length;
- var palette = this._palette;
-
-
- for (var i = 3; i < len; i+= 4) {
- var alpha = imgData[i];
- var offset = alpha * 4;
-
-
- if (!offset) {
- continue;
- }
-
- var finalAlpha;
- if (opacity > 0) {
- finalAlpha = opacity;
- } else {
- if (alpha < maxOpacity) {
- if (alpha < minOpacity) {
- finalAlpha = minOpacity;
- } else {
- finalAlpha = alpha;
- }
- } else {
- finalAlpha = maxOpacity;
- }
- }
-
- imgData[i-3] = palette[offset];
- imgData[i-2] = palette[offset + 1];
- imgData[i-1] = palette[offset + 2];
- imgData[i] = useGradientOpacity ? palette[offset + 3] : finalAlpha;
-
- }
-
- img.data = imgData;
- this.ctx.putImageData(img, x, y);
-
- this._renderBoundaries = [1000, 1000, 0, 0];
-
- },
- getValueAt: function(point) {
- var value;
- var shadowCtx = this.shadowCtx;
- var img = shadowCtx.getImageData(point.x, point.y, 1, 1);
- var data = img.data[3];
- var max = this._max;
- var min = this._min;
-
- value = (Math.abs(max-min) * (data/255)) >> 0;
-
- return value;
- },
- getDataURL: function() {
- return this.canvas.toDataURL();
- }
- };
-
-
- return Canvas2dRenderer;
-})();
-
-var Renderer = (function RendererClosure() {
-
- var rendererFn = false;
-
- if (HeatmapConfig['defaultRenderer'] === 'canvas2d') {
- rendererFn = Canvas2dRenderer;
- }
-
- return rendererFn;
-})();
-
-
-var Util = {
- merge: function() {
- var merged = {};
- var argsLen = arguments.length;
- for (var i = 0; i < argsLen; i++) {
- var obj = arguments[i]
- for (var key in obj) {
- merged[key] = obj[key];
- }
- }
- return merged;
- }
-};
-// Heatmap Constructor
-var Heatmap = (function HeatmapClosure() {
-
- var Coordinator = (function CoordinatorClosure() {
-
- function Coordinator() {
- this.cStore = {};
- };
-
- Coordinator.prototype = {
- on: function(evtName, callback, scope) {
- var cStore = this.cStore;
-
- if (!cStore[evtName]) {
- cStore[evtName] = [];
- }
- cStore[evtName].push((function(data) {
- return callback.call(scope, data);
- }));
- },
- emit: function(evtName, data) {
- var cStore = this.cStore;
- if (cStore[evtName]) {
- var len = cStore[evtName].length;
- for (var i=0; i ({
},
resolve: {
fallback: {
- util: require.resolve("util/")
+ util: require.resolve("util/"),
+ http: false,
+ fs: false,
},
alias: {
marionette: 'backbone.marionette/lib/backbone.marionette.min',
@@ -59,19 +61,11 @@ module.exports = (env, argv) => ({
'jquery.editable': 'vendor/jquery/jquery.jeditable.min',
'jquery.editable.datepicker': 'vendor/jquery/jquery.jeditable.datepicker',
- // Caman npm depends on fibers, canvas, fs which we don't want...
- // So use direct downloaded dependency
- caman: 'vendor/caman.min',
-
- // heatmap in npm has dependency on canvas/node-gyp... so use old one for now
- heatmap: 'vendor/hmap',
-
markdown: 'markdown/lib/markdown',
// Vue packages from npm (vee-validate requires promise polyfill - also npm)
vue: 'vue/dist/vue.min',
veevalidate: 'vee-validate/dist/vee-validate.min',
- luxon: 'luxon',
js: path.resolve(__dirname, 'src/js'),
css: path.resolve(__dirname, 'src/css'),
@@ -155,7 +149,7 @@ module.exports = (env, argv) => ({
// Caman adds to the window object within a browser
// The import loader ensures it it recognised as browser env not NodeJS
{
- test: /caman\.min\.js$/,
+ test: require.resolve('caman-dist-only/dist/caman.full.js'),
use: "imports-loader?exports=>undefined,require=>false,this=>window"
},
{