Utils conversion, minus _l

This commit is contained in:
Dannon Baker
2017-10-24 18:07:41 -04:00
parent 9fb8b3d78d
commit 2eed28cf74
38 changed files with 2227 additions and 2284 deletions
+34 -40
View File
@@ -1,45 +1,39 @@
define([], function() {
//==============================================================================
var LOGGING_FNS = ["log", "debug", "info", "warn", "error", "metric"];
/** adds logging functions to an obj.prototype (or obj directly) adding a namespace for filtering
//==============================================================================
var LOGGING_FNS = ["log", "debug", "info", "warn", "error", "metric"];
/** adds logging functions to an obj.prototype (or obj directly) adding a namespace for filtering
* @param {Object} obj
* @param {String} namespace
*/
function addLogging(obj, namespace) {
var addTo = obj.prototype !== undefined ? obj.prototype : obj;
if (namespace !== undefined) {
addTo._logNamespace = namespace;
}
//yagni?: without this, may not capture Galaxy.config.debug and add Galaxy.logger properly
// if( window.Galaxy && window.Galaxy.config && window.Galaxy.config.debug ){
// addTo.logger = window.Galaxy.logger;
// }
// give the object each
LOGGING_FNS.forEach(function(logFn) {
addTo[logFn] = function() {
if (!this.logger) {
return undefined;
}
if (this.logger.emit) {
return this.logger.emit(
logFn,
this._logNamespace,
arguments
);
}
if (this.logger[logFn]) {
//TODO:! there has to be a way to get the lineno/file into this
// http://stackoverflow.com/questions/13815640/a-proper-wrapper-for-console-log-with-correct-line-number
// http://www.paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
return this.logger[logFn].apply(this.logger, arguments);
}
return undefined;
};
});
return obj;
function addLogging(obj, namespace) {
var addTo = obj.prototype !== undefined ? obj.prototype : obj;
if (namespace !== undefined) {
addTo._logNamespace = namespace;
}
//yagni?: without this, may not capture Galaxy.config.debug and add Galaxy.logger properly
// if( window.Galaxy && window.Galaxy.config && window.Galaxy.config.debug ){
// addTo.logger = window.Galaxy.logger;
// }
//==============================================================================
return addLogging;
});
// give the object each
LOGGING_FNS.forEach(function(logFn) {
addTo[logFn] = function() {
if (!this.logger) {
return undefined;
}
if (this.logger.emit) {
return this.logger.emit(logFn, this._logNamespace, arguments);
}
if (this.logger[logFn]) {
//TODO:! there has to be a way to get the lineno/file into this
// http://stackoverflow.com/questions/13815640/a-proper-wrapper-for-console-log-with-correct-line-number
// http://www.paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
return this.logger[logFn].apply(this.logger, arguments);
}
return undefined;
};
});
return obj;
}
//==============================================================================
export default addLogging;
+147 -149
View File
@@ -1,7 +1,6 @@
define([], function() {
//ASSUMES: jquery
//=============================================================================
/** @class AjaxQueue
//ASSUMES: jquery
//=============================================================================
/** @class AjaxQueue
* Class that allows queueing functions that return jQuery promises (such
* as ajax calls). Each function waits for the previous to complete before
* being called
@@ -9,121 +8,121 @@ define([], function() {
* @constructor accepts a list of functions and automatically begins
* processing them
*/
function AjaxQueue(initialFunctions) {
//TODO: possibly rename to DeferredQueue
var self = this;
/** the main deferred for the entire queue - note: also sends notifications of progress */
self.deferred = jQuery.Deferred();
/** the queue array of functions */
self.queue = [];
/** cache the response from each deferred call - error or success */
self.responses = [];
/** total number of fn's to process */
self.numToProcess = 0;
/** is the queue processing/waiting for any calls to return? */
self.running = false;
function AjaxQueue(initialFunctions) {
//TODO: possibly rename to DeferredQueue
var self = this;
/** the main deferred for the entire queue - note: also sends notifications of progress */
self.deferred = jQuery.Deferred();
/** the queue array of functions */
self.queue = [];
/** cache the response from each deferred call - error or success */
self.responses = [];
/** total number of fn's to process */
self.numToProcess = 0;
/** is the queue processing/waiting for any calls to return? */
self.running = false;
self.init(initialFunctions || []);
self.start();
self.init(initialFunctions || []);
self.start();
return self;
return self;
}
/** add all fns in initialFunctions (if any) to the queue */
AjaxQueue.prototype.init = function init(initialFunctions) {
var self = this;
initialFunctions.forEach(function(fn) {
self.add(fn);
});
};
/** add a fn to the queue */
AjaxQueue.prototype.add = function add(fn) {
//console.debug( 'AjaxQueue.prototype.add:', fn );
var self = this,
index = this.queue.length;
this.numToProcess += 1;
this.queue.push(function() {
var fnIndex = index,
xhr = fn();
// if successful, notify using the deferred to allow tracking progress
xhr.done(function(response) {
self.deferred.notify({
curr: fnIndex,
total: self.numToProcess,
response: response
});
});
// (regardless of previous error or success) if not last ajax call, shift and call the next
// if last fn, resolve deferred
xhr.always(function(response) {
self.responses.push(response);
if (self.queue.length) {
self.queue.shift()();
} else {
self.stop();
}
});
});
return this;
};
/** start processing the queue */
AjaxQueue.prototype.start = function start() {
if (this.queue.length) {
this.running = true;
this.queue.shift()();
}
return this;
};
/** add all fns in initialFunctions (if any) to the queue */
AjaxQueue.prototype.init = function init(initialFunctions) {
var self = this;
initialFunctions.forEach(function(fn) {
self.add(fn);
});
};
/** add a fn to the queue */
AjaxQueue.prototype.add = function add(fn) {
//console.debug( 'AjaxQueue.prototype.add:', fn );
var self = this,
index = this.queue.length;
this.numToProcess += 1;
this.queue.push(function() {
var fnIndex = index,
xhr = fn();
// if successful, notify using the deferred to allow tracking progress
xhr.done(function(response) {
self.deferred.notify({
curr: fnIndex,
total: self.numToProcess,
response: response
});
});
// (regardless of previous error or success) if not last ajax call, shift and call the next
// if last fn, resolve deferred
xhr.always(function(response) {
self.responses.push(response);
if (self.queue.length) {
self.queue.shift()();
} else {
self.stop();
}
});
});
return this;
};
/** start processing the queue */
AjaxQueue.prototype.start = function start() {
if (this.queue.length) {
this.running = true;
this.queue.shift()();
}
return this;
};
/** stop the queue
/** stop the queue
* @param {boolean} causeFail cause an error/fail on the main deferred
* @param {String} msg message to send when rejecting the main deferred
*/
AjaxQueue.prototype.stop = function stop(causeFail, msg) {
//TODO: doesn't abort current call
this.running = false;
this.queue = [];
if (causeFail) {
//TODO: spliced args instead
this.deferred.reject(msg);
} else {
this.deferred.resolve(this.responses);
}
this.numToProcess = 0;
this.deferred = jQuery.Deferred();
return this;
};
AjaxQueue.prototype.stop = function stop(causeFail, msg) {
//TODO: doesn't abort current call
this.running = false;
this.queue = [];
if (causeFail) {
//TODO: spliced args instead
this.deferred.reject(msg);
} else {
this.deferred.resolve(this.responses);
}
this.numToProcess = 0;
this.deferred = jQuery.Deferred();
return this;
};
// only a handful of the deferred interface for now - possible YAGNI
/** implement done from the jq deferred interface */
AjaxQueue.prototype.done = function done(fn) {
return this.deferred.done(fn);
};
/** implement fail from the jq deferred interface */
AjaxQueue.prototype.fail = function fail(fn) {
return this.deferred.fail(fn);
};
/** implement always from the jq deferred interface */
AjaxQueue.prototype.always = function always(fn) {
return this.deferred.always(fn);
};
/** implement progress from the jq deferred interface */
AjaxQueue.prototype.progress = function progress(fn) {
return this.deferred.progress(fn);
};
// only a handful of the deferred interface for now - possible YAGNI
/** implement done from the jq deferred interface */
AjaxQueue.prototype.done = function done(fn) {
return this.deferred.done(fn);
};
/** implement fail from the jq deferred interface */
AjaxQueue.prototype.fail = function fail(fn) {
return this.deferred.fail(fn);
};
/** implement always from the jq deferred interface */
AjaxQueue.prototype.always = function always(fn) {
return this.deferred.always(fn);
};
/** implement progress from the jq deferred interface */
AjaxQueue.prototype.progress = function progress(fn) {
return this.deferred.progress(fn);
};
/** shortcut constructor / fire and forget
/** shortcut constructor / fire and forget
* @returns {Deferred} the queue's main deferred
*/
AjaxQueue.create = function create(initialFunctions) {
return new AjaxQueue(initialFunctions).deferred;
};
AjaxQueue.create = function create(initialFunctions) {
return new AjaxQueue(initialFunctions).deferred;
};
//=============================================================================
/** @class NamedAjaxQueue
//=============================================================================
/** @class NamedAjaxQueue
* @augments AjaxQueue
* Allows associating a name with a deferring fn and prevents adding deferring
* fns if the name has already been used. Useful to prevent build up of duplicate
@@ -133,51 +132,50 @@ define([], function() {
* { name: some unique id,
* fn: the deferring fn or ajax call }
*/
function NamedAjaxQueue(initialFunctions) {
var self = this;
self.names = {};
AjaxQueue.call(this, initialFunctions);
return self;
function NamedAjaxQueue(initialFunctions) {
var self = this;
self.names = {};
AjaxQueue.call(this, initialFunctions);
return self;
}
NamedAjaxQueue.prototype = new AjaxQueue();
NamedAjaxQueue.prototype.constructor = NamedAjaxQueue;
/** add the obj.fn to the queue if obj.name hasn't been used before */
NamedAjaxQueue.prototype.add = function add(obj) {
//console.debug( 'NamedAjaxQueue.adding:', obj )
//console.debug( 'NamedAjaxQueue.prototype.add:', obj );
if (!(obj.hasOwnProperty("name") && obj.hasOwnProperty("fn"))) {
throw new Error(
'NamedAjaxQueue.add requires an object with both "name" and "fn": ' +
JSON.stringify(obj)
);
}
NamedAjaxQueue.prototype = new AjaxQueue();
NamedAjaxQueue.prototype.constructor = NamedAjaxQueue;
if (this.names.hasOwnProperty(obj.name)) {
//console.warn( 'name has been used:', obj.name );
return;
}
this.names[obj.name] = true;
//console.debug( '\t names: ', this.names )
return AjaxQueue.prototype.add.call(this, obj.fn);
//console.debug( '\t queue: ', this.queue.length );
};
/** add the obj.fn to the queue if obj.name hasn't been used before */
NamedAjaxQueue.prototype.add = function add(obj) {
//console.debug( 'NamedAjaxQueue.adding:', obj )
//console.debug( 'NamedAjaxQueue.prototype.add:', obj );
if (!(obj.hasOwnProperty("name") && obj.hasOwnProperty("fn"))) {
throw new Error(
'NamedAjaxQueue.add requires an object with both "name" and "fn": ' +
JSON.stringify(obj)
);
}
if (this.names.hasOwnProperty(obj.name)) {
//console.warn( 'name has been used:', obj.name );
return;
}
this.names[obj.name] = true;
//console.debug( '\t names: ', this.names )
return AjaxQueue.prototype.add.call(this, obj.fn);
//console.debug( '\t queue: ', this.queue.length );
};
/** override to remove names */
NamedAjaxQueue.prototype.clear = function clear() {
this.names = {};
return this;
};
/** override to remove names */
NamedAjaxQueue.prototype.clear = function clear() {
this.names = {};
return this;
};
/** shortcut constructor / fire and forget
/** shortcut constructor / fire and forget
* @returns {Deferred} the queue's main deferred
*/
NamedAjaxQueue.create = function create(initialFunctions) {
return new NamedAjaxQueue(initialFunctions).deferred;
};
NamedAjaxQueue.create = function create(initialFunctions) {
return new NamedAjaxQueue(initialFunctions).deferred;
};
//=============================================================================
return {
AjaxQueue: AjaxQueue,
NamedAjaxQueue: NamedAjaxQueue
};
});
//=============================================================================
export default {
AjaxQueue: AjaxQueue,
NamedAjaxQueue: NamedAjaxQueue
};
+98 -101
View File
@@ -1,106 +1,103 @@
define(["jquery"], function(jQuery) {
"use_strict";
import jQuery from "jquery";
("use_strict");
var $ = jQuery;
// ============================================================================
/**
var $ = jQuery;
// ============================================================================
/**
* Edit and save text asynchronously.
*/
function async_save_text(
click_to_edit_elt,
text_elt_id,
save_url,
text_parm_name,
num_cols,
use_textarea,
num_rows,
on_start,
on_finish
) {
// Set defaults if necessary.
if (num_cols === undefined) {
num_cols = 30;
}
if (num_rows === undefined) {
num_rows = 4;
}
// Set up input element.
$("#" + click_to_edit_elt).click(function() {
// Check if this is already active
if ($("#renaming-active").length > 0) {
return;
}
var text_elt = $("#" + text_elt_id),
old_text = text_elt.text(),
t;
if (use_textarea) {
t = $("<textarea></textarea>")
.attr({ rows: num_rows, cols: num_cols })
.text($.trim(old_text));
} else {
t = $("<input type='text'></input>").attr({
value: $.trim(old_text),
size: num_cols
});
}
t.attr("id", "renaming-active");
t.blur(function() {
$(this).remove();
text_elt.show();
if (on_finish) {
on_finish(t);
}
});
t.keyup(function(e) {
if (e.keyCode === 27) {
// Escape key
$(this).trigger("blur");
} else if (e.keyCode === 13) {
// Enter key submits
var ajax_data = {};
ajax_data[text_parm_name] = $(this).val();
$(this).trigger("blur");
$.ajax({
url: save_url,
data: ajax_data,
error: function() {
alert(
"Text editing for elt " +
text_elt_id +
" failed"
);
// TODO: call finish or no? For now, let's not because error occurred.
},
success: function(processed_text) {
// Set new text and call finish method.
if (processed_text !== "") {
text_elt.text(processed_text);
} else {
text_elt.html("<em>None</em>");
}
if (on_finish) {
on_finish(t);
}
}
});
}
});
if (on_start) {
on_start(t);
}
// Replace text with input object and focus & select.
text_elt.hide();
t.insertAfter(text_elt);
t.focus();
t.select();
return;
});
function async_save_text(
click_to_edit_elt,
text_elt_id,
save_url,
text_parm_name,
num_cols,
use_textarea,
num_rows,
on_start,
on_finish
) {
// Set defaults if necessary.
if (num_cols === undefined) {
num_cols = 30;
}
if (num_rows === undefined) {
num_rows = 4;
}
// ============================================================================
return async_save_text;
});
// Set up input element.
$("#" + click_to_edit_elt).click(function() {
// Check if this is already active
if ($("#renaming-active").length > 0) {
return;
}
var text_elt = $("#" + text_elt_id),
old_text = text_elt.text(),
t;
if (use_textarea) {
t = $("<textarea></textarea>")
.attr({ rows: num_rows, cols: num_cols })
.text($.trim(old_text));
} else {
t = $("<input type='text'></input>").attr({
value: $.trim(old_text),
size: num_cols
});
}
t.attr("id", "renaming-active");
t.blur(function() {
$(this).remove();
text_elt.show();
if (on_finish) {
on_finish(t);
}
});
t.keyup(function(e) {
if (e.keyCode === 27) {
// Escape key
$(this).trigger("blur");
} else if (e.keyCode === 13) {
// Enter key submits
var ajax_data = {};
ajax_data[text_parm_name] = $(this).val();
$(this).trigger("blur");
$.ajax({
url: save_url,
data: ajax_data,
error: function() {
alert(
"Text editing for elt " + text_elt_id + " failed"
);
// TODO: call finish or no? For now, let's not because error occurred.
},
success: function(processed_text) {
// Set new text and call finish method.
if (processed_text !== "") {
text_elt.text(processed_text);
} else {
text_elt.html("<em>None</em>");
}
if (on_finish) {
on_finish(t);
}
}
});
}
});
if (on_start) {
on_start(t);
}
// Replace text with input object and focus & select.
text_elt.hide();
t.insertAfter(text_elt);
t.focus();
t.select();
return;
});
}
// ============================================================================
export default async_save_text;
+374 -384
View File
@@ -1,448 +1,438 @@
define(["libs/underscore", "viz/trackster/util", "utils/config"], function(
_,
util_mod,
config_mod
) {
/**
import _ from "libs/underscore";
import util_mod from "viz/trackster/util";
import config_mod from "utils/config";
/**
* A configuration setting. Currently key is used as id.
*/
var ConfigSetting = Backbone.Model.extend({
initialize: function(options) {
// Use key as id for now.
var key = this.get("key");
this.set("id", key);
var ConfigSetting = Backbone.Model.extend({
initialize: function(options) {
// Use key as id for now.
var key = this.get("key");
this.set("id", key);
// Set defaults based on key.
var defaults = _.find(
[
{
key: "name",
label: "Name",
type: "text",
default_value: ""
},
{
key: "color",
label: "Color",
type: "color",
default_value: null
},
{
key: "min_value",
label: "Min Value",
type: "float",
default_value: null
},
{
key: "max_value",
label: "Max Value",
type: "float",
default_value: null
},
{
key: "mode",
type: "string",
default_value: this.mode,
hidden: true
},
{
key: "height",
type: "int",
default_value: 32,
hidden: true
},
{
key: "pos_color",
label: "Positive Color",
type: "color",
default_value: "#FF8C00"
},
{
key: "neg_color",
label: "Negative Color",
type: "color",
default_value: "#4169E1"
},
{
key: "block_color",
label: "Block color",
type: "color",
default_value: null
},
{
key: "label_color",
label: "Label color",
type: "color",
default_value: "black"
},
{
key: "show_insertions",
label: "Show insertions",
type: "bool",
default_value: false
},
{
key: "show_counts",
label: "Show summary counts",
type: "bool",
default_value: true
},
{
key: "reverse_strand_color",
label: "Antisense strand color",
type: "color",
default_value: null
},
{
key: "show_differences",
label: "Show differences only",
type: "bool",
default_value: true
}
],
function(s) {
return s.key === key;
// Set defaults based on key.
var defaults = _.find(
[
{
key: "name",
label: "Name",
type: "text",
default_value: ""
},
{
key: "color",
label: "Color",
type: "color",
default_value: null
},
{
key: "min_value",
label: "Min Value",
type: "float",
default_value: null
},
{
key: "max_value",
label: "Max Value",
type: "float",
default_value: null
},
{
key: "mode",
type: "string",
default_value: this.mode,
hidden: true
},
{
key: "height",
type: "int",
default_value: 32,
hidden: true
},
{
key: "pos_color",
label: "Positive Color",
type: "color",
default_value: "#FF8C00"
},
{
key: "neg_color",
label: "Negative Color",
type: "color",
default_value: "#4169E1"
},
{
key: "block_color",
label: "Block color",
type: "color",
default_value: null
},
{
key: "label_color",
label: "Label color",
type: "color",
default_value: "black"
},
{
key: "show_insertions",
label: "Show insertions",
type: "bool",
default_value: false
},
{
key: "show_counts",
label: "Show summary counts",
type: "bool",
default_value: true
},
{
key: "reverse_strand_color",
label: "Antisense strand color",
type: "color",
default_value: null
},
{
key: "show_differences",
label: "Show differences only",
type: "bool",
default_value: true
}
);
if (defaults) {
this.set(_.extend({}, defaults, options));
],
function(s) {
return s.key === key;
}
);
if (defaults) {
this.set(_.extend({}, defaults, options));
}
if (
this.get("value") === undefined &&
this.get("default_value") !== undefined
) {
// Use default to set value (if present).
this.set_value(this.get("default_value"));
if (
this.get("value") === undefined &&
this.get("default_value") !== undefined
) {
// Use default to set value (if present).
this.set_value(this.get("default_value"));
// If no default value for color config, set random color.
if (!this.get("value") && this.get("type") === "color") {
// For color setting, set random color.
this.set("value", util_mod.get_random_color());
}
// If no default value for color config, set random color.
if (!this.get("value") && this.get("type") === "color") {
// For color setting, set random color.
this.set("value", util_mod.get_random_color());
}
},
}
},
/**
/**
* Cast and set value. This should be instead of
* setting.set('value', new_value)
*/
set_value: function(value, options) {
var type = this.get("type");
set_value: function(value, options) {
var type = this.get("type");
if (type === "float") {
value = parseFloat(value);
} else if (type === "int") {
value = parseInt(value, 10);
}
// TODO: handle casting from string to bool?
this.set({ value: value }, options);
if (type === "float") {
value = parseFloat(value);
} else if (type === "int") {
value = parseInt(value, 10);
}
});
// TODO: handle casting from string to bool?
/**
this.set({ value: value }, options);
}
});
/**
* Collection of config settings.
*/
var ConfigSettingCollection = Backbone.Collection.extend(
{
model: ConfigSetting,
var ConfigSettingCollection = Backbone.Collection.extend(
{
model: ConfigSetting,
/**
/**
* Save settings as a dictionary of key-value pairs.
* This function is needed for backwards compatibility.
*/
to_key_value_dict: function() {
var rval = {};
this.each(function(setting) {
rval[setting.get("key")] = setting.get("value");
});
to_key_value_dict: function() {
var rval = {};
this.each(function(setting) {
rval[setting.get("key")] = setting.get("value");
});
return rval;
},
return rval;
},
/**
/**
* Returns value for a given key. Returns undefined if there is no setting with the specified key.
*/
get_value: function(key) {
var s = this.get(key);
if (s) {
return s.get("value");
}
get_value: function(key) {
var s = this.get(key);
if (s) {
return s.get("value");
}
return undefined;
},
return undefined;
},
/**
/**
* Set value for a setting.
*/
set_value: function(key, value, options) {
var s = this.get(key);
if (s) {
return s.set_value(value, options);
}
set_value: function(key, value, options) {
var s = this.get(key);
if (s) {
return s.set_value(value, options);
}
return undefined;
},
return undefined;
},
/**
/**
* Set default value for a setting.
*/
set_default_value: function(key, default_value) {
var s = this.get(key);
if (s) {
return s.set("default_value", default_value);
}
return undefined;
set_default_value: function(key, default_value) {
var s = this.get(key);
if (s) {
return s.set("default_value", default_value);
}
},
{
/**
return undefined;
}
},
{
/**
* Utility function that creates a ConfigSettingsCollection from a set of models
* and a saved_values dictionary.
*/
from_models_and_saved_values: function(models, saved_values) {
// If there are saved values, copy models and update with saved values.
if (saved_values) {
models = _.map(models, function(m) {
return _.extend({}, m, { value: saved_values[m.key] });
});
}
return new ConfigSettingCollection(models);
from_models_and_saved_values: function(models, saved_values) {
// If there are saved values, copy models and update with saved values.
if (saved_values) {
models = _.map(models, function(m) {
return _.extend({}, m, { value: saved_values[m.key] });
});
}
}
);
/**
return new ConfigSettingCollection(models);
}
}
);
/**
* Viewer for config settings collection.
*/
var ConfigSettingCollectionView = Backbone.View.extend({
className: "config-settings-view",
var ConfigSettingCollectionView = Backbone.View.extend({
className: "config-settings-view",
/**
/**
* Renders form for editing configuration settings.
*/
render: function() {
var container = this.$el;
render: function() {
var container = this.$el;
this.collection.each(function(param, index) {
// Hidden params have no representation in the form
if (param.get("hidden")) {
return;
}
this.collection.each(function(param, index) {
// Hidden params have no representation in the form
if (param.get("hidden")) {
return;
}
// Build row for param.
var id = "param_" + index,
type = param.get("type"),
value = param.get("value");
var row = $("<div class='form-row' />").appendTo(container);
// Build row for param.
var id = "param_" + index,
type = param.get("type"),
value = param.get("value");
var row = $("<div class='form-row' />").appendTo(container);
row.append(
$("<label />")
.attr("for", id)
.text(param.get("label") + ":")
);
// Draw parameter as checkbox
if (type === "bool") {
row.append(
$("<label />")
.attr("for", id)
.text(param.get("label") + ":")
$('<input type="checkbox" />')
.attr("id", id)
.attr("name", id)
.attr("checked", value)
);
// Draw parameter as checkbox
if (type === "bool") {
row.append(
$('<input type="checkbox" />')
.attr("id", id)
.attr("name", id)
.attr("checked", value)
);
} else if (type === "text") {
// Draw parameter as textbox
row.append(
$('<input type="text"/>')
.attr("id", id)
.val(value)
.click(function() {
$(this).select();
})
);
} else if (type === "select") {
// Draw parameter as select area
var select = $("<select />").attr("id", id);
_.each(param.get("options"), function(option) {
$("<option/>")
.text(option.label)
.attr("value", option.value)
.appendTo(select);
});
select.val(value);
row.append(select);
} else if (type === "color") {
// Draw parameter as color picker
var container_div = $("<div/>").appendTo(row),
input = $("<input />")
.attr("id", id)
.attr("name", id)
.val(value)
.css("float", "left")
.appendTo(container_div)
.click(function(e) {
// Hide other pickers.
$(".tooltip").removeClass("in");
} else if (type === "text") {
// Draw parameter as textbox
row.append(
$('<input type="text"/>')
.attr("id", id)
.val(value)
.click(function() {
$(this).select();
})
);
} else if (type === "select") {
// Draw parameter as select area
var select = $("<select />").attr("id", id);
_.each(param.get("options"), function(option) {
$("<option/>")
.text(option.label)
.attr("value", option.value)
.appendTo(select);
});
select.val(value);
row.append(select);
} else if (type === "color") {
// Draw parameter as color picker
var container_div = $("<div/>").appendTo(row),
input = $("<input />")
.attr("id", id)
.attr("name", id)
.val(value)
.css("float", "left")
.appendTo(container_div)
.click(function(e) {
// Hide other pickers.
$(".tooltip").removeClass("in");
// Show input's color picker.
var tip = $(this)
.siblings(".tooltip")
.addClass("in");
tip
.css({
// left: $(this).position().left + ( $(input).width() / 2 ) - 60,
// top: $(this).position().top + $(this.height)
left:
$(this).position().left +
$(this).width() +
5,
top:
$(this).position().top -
$(tip).height() / 2 +
$(this).height() / 2
})
.show();
// Show input's color picker.
var tip = $(this)
.siblings(".tooltip")
.addClass("in");
tip
.css({
// left: $(this).position().left + ( $(input).width() / 2 ) - 60,
// top: $(this).position().top + $(this.height)
left:
$(this).position().left +
$(this).width() +
5,
top:
$(this).position().top -
$(tip).height() / 2 +
$(this).height() / 2
})
.show();
// Click management:
// Click management:
// Keep showing tip if clicking in tip.
tip.click(function(e) {
e.stopPropagation();
});
// Hide tip if clicking outside of tip.
$(document).bind(
"click.color-picker",
function() {
tip.hide();
$(document).unbind(
"click.color-picker"
);
}
);
// No propagation to avoid triggering document click (and tip hiding) above.
// Keep showing tip if clicking in tip.
tip.click(function(e) {
e.stopPropagation();
}),
// Icon for setting a new random color; behavior set below.
new_color_icon = $("<a href='javascript:void(0)'/>")
.addClass("icon-button arrow-circle")
.appendTo(container_div)
.attr("title", "Set new random color")
.tooltip(),
// Color picker in tool tip style.
tip = $(
"<div class='tooltip right' style='position: absolute;' />"
)
.appendTo(container_div)
.hide(),
// Inner div for padding purposes
tip_inner = $(
"<div class='tooltip-inner' style='text-align: inherit'></div>"
).appendTo(tip),
tip_arrow = $(
"<div class='tooltip-arrow'></div>"
).appendTo(tip),
farb_obj = $.farbtastic(tip_inner, {
width: 100,
height: 100,
callback: input,
color: value
});
});
// Clear floating.
container_div.append($("<div/>").css("clear", "both"));
// Hide tip if clicking outside of tip.
$(document).bind("click.color-picker", function() {
tip.hide();
$(document).unbind("click.color-picker");
});
// Use function to fix farb_obj value.
(function(fixed_farb_obj) {
new_color_icon.click(function() {
fixed_farb_obj.setColor(
util_mod.get_random_color()
);
});
})(farb_obj);
} else {
row.append(
$("<input />")
.attr("id", id)
.attr("name", id)
.val(value)
);
}
// Help text
if (param.help) {
row.append($("<div class='help'/>").text(param.help));
}
});
// No propagation to avoid triggering document click (and tip hiding) above.
e.stopPropagation();
}),
// Icon for setting a new random color; behavior set below.
new_color_icon = $("<a href='javascript:void(0)'/>")
.addClass("icon-button arrow-circle")
.appendTo(container_div)
.attr("title", "Set new random color")
.tooltip(),
// Color picker in tool tip style.
tip = $(
"<div class='tooltip right' style='position: absolute;' />"
)
.appendTo(container_div)
.hide(),
// Inner div for padding purposes
tip_inner = $(
"<div class='tooltip-inner' style='text-align: inherit'></div>"
).appendTo(tip),
tip_arrow = $("<div class='tooltip-arrow'></div>").appendTo(
tip
),
farb_obj = $.farbtastic(tip_inner, {
width: 100,
height: 100,
callback: input,
color: value
});
return this;
},
// Clear floating.
container_div.append($("<div/>").css("clear", "both"));
/**
// Use function to fix farb_obj value.
(function(fixed_farb_obj) {
new_color_icon.click(function() {
fixed_farb_obj.setColor(util_mod.get_random_color());
});
})(farb_obj);
} else {
row.append(
$("<input />")
.attr("id", id)
.attr("name", id)
.val(value)
);
}
// Help text
if (param.help) {
row.append($("<div class='help'/>").text(param.help));
}
});
return this;
},
/**
* Render view in modal.
*/
render_in_modal: function(title) {
// Set up handlers for cancel, ok button and for handling esc key.
var self = this,
cancel_fn = function() {
Galaxy.modal.hide();
$(window).unbind("keypress.check_enter_esc");
},
ok_fn = function() {
Galaxy.modal.hide();
$(window).unbind("keypress.check_enter_esc");
self.update_from_form();
},
check_enter_esc = function(e) {
if ((e.keyCode || e.which) === 27) {
// Escape key
cancel_fn();
} else if ((e.keyCode || e.which) === 13) {
// Enter key
ok_fn();
}
};
// Set keypress handler.
$(window).bind("keypress.check_enter_esc", check_enter_esc);
// Show modal.
if (this.$el.children().length === 0) {
this.render();
}
Galaxy.modal.show({
title: title || "Configure",
body: this.$el,
buttons: {
Cancel: cancel_fn,
OK: ok_fn
render_in_modal: function(title) {
// Set up handlers for cancel, ok button and for handling esc key.
var self = this,
cancel_fn = function() {
Galaxy.modal.hide();
$(window).unbind("keypress.check_enter_esc");
},
ok_fn = function() {
Galaxy.modal.hide();
$(window).unbind("keypress.check_enter_esc");
self.update_from_form();
},
check_enter_esc = function(e) {
if ((e.keyCode || e.which) === 27) {
// Escape key
cancel_fn();
} else if ((e.keyCode || e.which) === 13) {
// Enter key
ok_fn();
}
});
},
};
/**
// Set keypress handler.
$(window).bind("keypress.check_enter_esc", check_enter_esc);
// Show modal.
if (this.$el.children().length === 0) {
this.render();
}
Galaxy.modal.show({
title: title || "Configure",
body: this.$el,
buttons: {
Cancel: cancel_fn,
OK: ok_fn
}
});
},
/**
* Update settings with new values entered via form.
*/
update_from_form: function() {
var self = this;
this.collection.each(function(setting, index) {
if (!setting.get("hidden")) {
// Set value from view.
var id = "param_" + index;
var value = self.$el.find("#" + id).val();
if (setting.get("type") === "bool") {
value = self.$el.find("#" + id).is(":checked");
}
setting.set_value(value);
update_from_form: function() {
var self = this;
this.collection.each(function(setting, index) {
if (!setting.get("hidden")) {
// Set value from view.
var id = "param_" + index;
var value = self.$el.find("#" + id).val();
if (setting.get("type") === "bool") {
value = self.$el.find("#" + id).is(":checked");
}
});
}
});
return {
ConfigSetting: ConfigSetting,
ConfigSettingCollection: ConfigSettingCollection,
ConfigSettingCollectionView: ConfigSettingCollectionView
};
setting.set_value(value);
}
});
}
});
export default {
ConfigSetting: ConfigSetting,
ConfigSettingCollection: ConfigSettingCollection,
ConfigSettingCollectionView: ConfigSettingCollectionView
};
+52 -56
View File
@@ -1,70 +1,66 @@
/**
* This class defines a queue to ensure that multiple deferred callbacks are executed sequentially.
*/
define(["utils/utils"], function(Utils) {
return Backbone.Model.extend({
initialize: function() {
this.active = {};
this.last = null;
},
import Utils from "utils/utils";
export default Backbone.Model.extend({
initialize: function() {
this.active = {};
this.last = null;
},
/** Adds a callback to the queue. Upon execution a deferred object is parsed to the callback i.e. callback( deferred ).
/** Adds a callback to the queue. Upon execution a deferred object is parsed to the callback i.e. callback( deferred ).
* If the callback does not take any arguments, the deferred is resolved instantly.
*/
execute: function(callback) {
var self = this;
var id = Utils.uid();
var has_deferred = callback.length > 0;
execute: function(callback) {
var self = this;
var id = Utils.uid();
var has_deferred = callback.length > 0;
// register process
this.active[id] = true;
// register process
this.active[id] = true;
// deferred process
var process = $.Deferred();
process.promise().always(function() {
delete self.active[id];
// deferred process
var process = $.Deferred();
process.promise().always(function() {
delete self.active[id];
has_deferred &&
Galaxy.emit.debug(
"deferred::execute()",
this.state()
.charAt(0)
.toUpperCase() +
this.state().slice(1) +
" " +
id
);
});
// deferred queue
$.when(this.last).always(function() {
if (self.active[id]) {
has_deferred &&
Galaxy.emit.debug(
"deferred::execute()",
this.state()
.charAt(0)
.toUpperCase() +
this.state().slice(1) +
" " +
id
);
});
// deferred queue
$.when(this.last).always(function() {
if (self.active[id]) {
has_deferred &&
Galaxy.emit.debug(
"deferred::execute()",
"Running " + id
);
callback(process);
!has_deferred && process.resolve();
} else {
process.reject();
}
});
this.last = process.promise();
},
/** Resets the promise queue. All currently queued but unexecuted callbacks/promises will be rejected.
*/
reset: function() {
Galaxy.emit.debug("deferred::execute()", "Reset");
for (var i in this.active) {
this.active[i] = false;
Galaxy.emit.debug("deferred::execute()", "Running " + id);
callback(process);
!has_deferred && process.resolve();
} else {
process.reject();
}
},
});
this.last = process.promise();
},
/** Returns true if all processes are done.
/** Resets the promise queue. All currently queued but unexecuted callbacks/promises will be rejected.
*/
ready: function() {
return $.isEmptyObject(this.active);
reset: function() {
Galaxy.emit.debug("deferred::execute()", "Reset");
for (var i in this.active) {
this.active[i] = false;
}
});
},
/** Returns true if all processes are done.
*/
ready: function() {
return $.isEmptyObject(this.active);
}
});
File diff suppressed because it is too large Load Diff
+47 -49
View File
@@ -1,6 +1,5 @@
define([], function() {
//=============================================================================
/**
//=============================================================================
/**
(Imported for edit distance algorith. From: https://gist.github.com/andrei-m/982927)
Copyright (c) 2011 Andrei Mackenzie
@@ -17,51 +16,50 @@ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEM
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
// Compute the edit distance between the two given strings
//exports.getEditDistance = function(a, b){
function levenshteinDistance(a, b) {
if (a.length === 0) {
return b.length;
}
if (b.length === 0) {
return a.length;
}
var matrix = [];
// increment along the first column of each row
var i;
for (i = 0; i <= b.length; i++) {
matrix[i] = [i];
}
// increment each column in the first row
var j;
for (j = 0; j <= a.length; j++) {
matrix[0][j] = j;
}
// Fill in the rest of the matrix
for (i = 1; i <= b.length; i++) {
for (j = 1; j <= a.length; j++) {
if (b.charAt(i - 1) === a.charAt(j - 1)) {
matrix[i][j] = matrix[i - 1][j - 1];
} else {
matrix[i][j] = Math.min(
matrix[i - 1][j - 1] + 1, // substitution
Math.min(
matrix[i][j - 1] + 1, // insertion
matrix[i - 1][j] + 1
)
); // deletion
}
}
}
//console.debug( '\t\t levenshteinDistance', a, b, matrix[b.length][a.length] );
return matrix[b.length][a.length];
// Compute the edit distance between the two given strings
//exports.getEditDistance = function(a, b){
function levenshteinDistance(a, b) {
if (a.length === 0) {
return b.length;
}
if (b.length === 0) {
return a.length;
}
//=============================================================================
return levenshteinDistance;
});
var matrix = [];
// increment along the first column of each row
var i;
for (i = 0; i <= b.length; i++) {
matrix[i] = [i];
}
// increment each column in the first row
var j;
for (j = 0; j <= a.length; j++) {
matrix[0][j] = j;
}
// Fill in the rest of the matrix
for (i = 1; i <= b.length; i++) {
for (j = 1; j <= a.length; j++) {
if (b.charAt(i - 1) === a.charAt(j - 1)) {
matrix[i][j] = matrix[i - 1][j - 1];
} else {
matrix[i][j] = Math.min(
matrix[i - 1][j - 1] + 1, // substitution
Math.min(
matrix[i][j - 1] + 1, // insertion
matrix[i - 1][j] + 1
)
); // deletion
}
}
}
//console.debug( '\t\t levenshteinDistance', a, b, matrix[b.length][a.length] );
return matrix[b.length][a.length];
}
//=============================================================================
export default levenshteinDistance;
+455 -466
View File
@@ -1,6 +1,5 @@
define([], function() {
/*global window, jQuery, console */
/*=============================================================================
/*global window, jQuery, console */
/*=============================================================================
TODO:
while anon: logs saved to 'logs-null' - this will never post
unless we manually do so at/after login
@@ -8,7 +7,7 @@ TODO:
wire up _delayPost and test
=============================================================================*/
/** @class MetricsLogger
/** @class MetricsLogger
*
* Object to cache, output, and post log/metric messages to the server.
* Meant to be attached to the Galaxy object.
@@ -28,528 +27,518 @@ TODO:
* > panel.metric( 'something weird with window', { window : window })
* !'Metrics logger could not stringify logArguments: ...'
*/
function MetricsLogger(options) {
options = options || {};
var self = this;
function MetricsLogger(options) {
options = options || {};
var self = this;
///** get the current user's id from bootstrapped data or options */
self.userId =
window.bootstrapped && window.bootstrapped.user
? window.bootstrapped.user.id
: null;
self.userId = self.userId || options.userId || null;
///** get the current user's id from bootstrapped data or options */
self.userId =
window.bootstrapped && window.bootstrapped.user
? window.bootstrapped.user.id
: null;
self.userId = self.userId || options.userId || null;
/** the (optional) console to emit logs to */
self.consoleLogger = options.consoleLogger || null;
/** the (optional) console to emit logs to */
self.consoleLogger = options.consoleLogger || null;
self._init(options);
return self;
}
self._init(options);
return self;
}
//----------------------------------------------------------------------------- defaults and constants
// see: python std lib, logging
MetricsLogger.ALL = 0;
MetricsLogger.LOG = 0;
MetricsLogger.DEBUG = 10;
MetricsLogger.INFO = 20;
MetricsLogger.WARN = 30;
MetricsLogger.ERROR = 40;
// metrics levels here?
//MetricsLogger.MinorEvent = 45;
//MetricsLogger.MajorEvent = 50;
MetricsLogger.METRIC = 50;
MetricsLogger.NONE = 100;
//----------------------------------------------------------------------------- defaults and constants
// see: python std lib, logging
MetricsLogger.ALL = 0;
MetricsLogger.LOG = 0;
MetricsLogger.DEBUG = 10;
MetricsLogger.INFO = 20;
MetricsLogger.WARN = 30;
MetricsLogger.ERROR = 40;
// metrics levels here?
//MetricsLogger.MinorEvent = 45;
//MetricsLogger.MajorEvent = 50;
MetricsLogger.METRIC = 50;
MetricsLogger.NONE = 100;
/** default options - override these through the constructor */
MetricsLogger.defaultOptions = {
/** if an incoming message has a level >= this, it will be cached - can also be a string (e.g. 'debug') */
logLevel: MetricsLogger.NONE,
/** if an incoming message has a level >= this, it will be output to the console */
consoleLevel: MetricsLogger.NONE,
/** the default 'namespace' or label associated with an incoming message (if none is passed) */
defaultNamespace: "Galaxy",
/** the namespaces output to the console (all namespaces will be output if this is falsy)
/** default options - override these through the constructor */
MetricsLogger.defaultOptions = {
/** if an incoming message has a level >= this, it will be cached - can also be a string (e.g. 'debug') */
logLevel: MetricsLogger.NONE,
/** if an incoming message has a level >= this, it will be output to the console */
consoleLevel: MetricsLogger.NONE,
/** the default 'namespace' or label associated with an incoming message (if none is passed) */
defaultNamespace: "Galaxy",
/** the namespaces output to the console (all namespaces will be output if this is falsy)
* note: applies only to the console (not the event/metrics log/cache)
*/
consoleNamespaceWhitelist: null,
/** the prefix attached to client-side logs to distinguish them in the metrics db */
clientPrefix: "client.",
consoleNamespaceWhitelist: null,
/** the prefix attached to client-side logs to distinguish them in the metrics db */
clientPrefix: "client.",
/** the maximum number of messages the cache should hold; if exceeded older messages are removed first */
maxCacheSize: 3000,
/** the number of messages accumulate before posting to the server; should be <= maxCacheSize */
postSize: 1000,
/** T/F whether to add a timestamp to incoming cached messages */
addTime: true,
/** string to prefix to userid for cache web storage */
cacheKeyPrefix: "logs-",
/** the maximum number of messages the cache should hold; if exceeded older messages are removed first */
maxCacheSize: 3000,
/** the number of messages accumulate before posting to the server; should be <= maxCacheSize */
postSize: 1000,
/** T/F whether to add a timestamp to incoming cached messages */
addTime: true,
/** string to prefix to userid for cache web storage */
cacheKeyPrefix: "logs-",
/** the relative url to post messages to */
postUrl: "/api/metrics",
/** delay before trying post again after two failures */
delayPostInMs: 1000 * 60 * 10,
/** the relative url to post messages to */
postUrl: "/api/metrics",
/** delay before trying post again after two failures */
delayPostInMs: 1000 * 60 * 10,
/** an (optional) function that should return an object; used to send additional data with the metrics */
getPingData: undefined,
/** an (optional) function that will handle the servers response after successfully posting messages */
onServerResponse: undefined
};
/** an (optional) function that should return an object; used to send additional data with the metrics */
getPingData: undefined,
/** an (optional) function that will handle the servers response after successfully posting messages */
onServerResponse: undefined
};
//----------------------------------------------------------------------------- set up
/** initialize the logger with options, set up instance vars and cache, and add onpageunload to window */
MetricsLogger.prototype._init = function _init(options) {
var self = this;
self.options = {};
for (var k in MetricsLogger.defaultOptions) {
if (MetricsLogger.defaultOptions.hasOwnProperty(k)) {
self.options[k] = options.hasOwnProperty(k)
? options[k]
: MetricsLogger.defaultOptions[k];
}
//----------------------------------------------------------------------------- set up
/** initialize the logger with options, set up instance vars and cache, and add onpageunload to window */
MetricsLogger.prototype._init = function _init(options) {
var self = this;
self.options = {};
for (var k in MetricsLogger.defaultOptions) {
if (MetricsLogger.defaultOptions.hasOwnProperty(k)) {
self.options[k] = options.hasOwnProperty(k)
? options[k]
: MetricsLogger.defaultOptions[k];
}
self.options.logLevel = self._parseLevel(self.options.logLevel);
self.options.consoleLevel = self._parseLevel(self.options.consoleLevel);
//self._emitToConsole( 'debug', 'MetricsLogger', 'MetricsLogger.options:', self.options );
}
self.options.logLevel = self._parseLevel(self.options.logLevel);
self.options.consoleLevel = self._parseLevel(self.options.consoleLevel);
//self._emitToConsole( 'debug', 'MetricsLogger', 'MetricsLogger.options:', self.options );
/** is the logger currently sending? */
self._sending = false;
/** the setTimeout id if the logger POST has failed more than once */
self._waiting = null;
/** the current number of entries to send in a POST */
self._postSize = self.options.postSize;
/** is the logger currently sending? */
self._sending = false;
/** the setTimeout id if the logger POST has failed more than once */
self._waiting = null;
/** the current number of entries to send in a POST */
self._postSize = self.options.postSize;
self._initCache();
self._initCache();
return self;
};
return self;
};
/** initialize the cache */
MetricsLogger.prototype._initCache = function _initCache() {
try {
this.cache = new LoggingCache({
maxSize: this.options.maxCacheSize,
key: this.options.cacheKeyPrefix + this.userId
});
} catch (err) {
this._emitToConsole("warn", "MetricsLogger", [
"Could not intitialize logging cache:",
err
]);
this.options.logLevel = MetricsLogger.NONE;
}
};
/** return the numeric log level if level in 'none, debug, log, info, warn, error' */
MetricsLogger.prototype._parseLevel = function _parseLevel(level) {
var type = typeof level;
if (type === "number") {
return level;
}
if (type === "string") {
var upper = level.toUpperCase();
if (MetricsLogger.hasOwnProperty(upper)) {
return MetricsLogger[upper];
}
}
throw new Error("Unknown log level: " + level);
};
//----------------------------------------------------------------------------- main entry point
/** record a log/message's arguments to the cache and/or the console based on level and namespace */
MetricsLogger.prototype.emit = function emit(
level,
namespace,
logArguments
) {
//this._emitToConsole( 'debug', 'MetricsLogger', [ 'emit:', level, namespace, logArguments ]);
var self = this;
namespace = namespace || self.options.defaultNamespace;
if (!level || !logArguments) {
return self;
}
// add to cache if proper level
//TODO: respect do not track?
//if( !navigator.doNotTrack && level >= self.options.logLevel ){
level = self._parseLevel(level);
if (level >= self.options.logLevel) {
self._addToCache(level, namespace, logArguments);
}
// also emit to consoleLogger if proper level for that
if (self.consoleLogger && level >= self.options.consoleLevel) {
self._emitToConsole(level, namespace, logArguments);
}
return self;
};
//----------------------------------------------------------------------------- cache
/** add a message to the cache and if messages.length is high enough post them to the server */
MetricsLogger.prototype._addToCache = function _addToCache(
level,
namespace,
logArguments
) {
this._emitToConsole("debug", "MetricsLogger", [
"_addToCache:",
arguments,
this.options.addTime,
this.cache.length()
/** initialize the cache */
MetricsLogger.prototype._initCache = function _initCache() {
try {
this.cache = new LoggingCache({
maxSize: this.options.maxCacheSize,
key: this.options.cacheKeyPrefix + this.userId
});
} catch (err) {
this._emitToConsole("warn", "MetricsLogger", [
"Could not intitialize logging cache:",
err
]);
//this._emitToConsole( 'debug', 'MetricsLogger', [ '\t logArguments:', logArguments ]);
var self = this;
// try add to the cache and if we've got _postSize number of entries, attempt to post them to the server
try {
var newLength = self.cache.add(
self._buildEntry(level, namespace, logArguments)
);
if (newLength >= self._postSize) {
self._postCache();
}
// discard entry if an error occurs, but warn if level set to do so
} catch (err) {
self._emitToConsole("warn", "MetricsLogger", [
"Metrics logger could not stringify logArguments:",
namespace,
logArguments
]);
self._emitToConsole("error", "MetricsLogger", [err]);
this.options.logLevel = MetricsLogger.NONE;
}
};
/** return the numeric log level if level in 'none, debug, log, info, warn, error' */
MetricsLogger.prototype._parseLevel = function _parseLevel(level) {
var type = typeof level;
if (type === "number") {
return level;
}
if (type === "string") {
var upper = level.toUpperCase();
if (MetricsLogger.hasOwnProperty(upper)) {
return MetricsLogger[upper];
}
}
throw new Error("Unknown log level: " + level);
};
//----------------------------------------------------------------------------- main entry point
/** record a log/message's arguments to the cache and/or the console based on level and namespace */
MetricsLogger.prototype.emit = function emit(level, namespace, logArguments) {
//this._emitToConsole( 'debug', 'MetricsLogger', [ 'emit:', level, namespace, logArguments ]);
var self = this;
namespace = namespace || self.options.defaultNamespace;
if (!level || !logArguments) {
return self;
};
}
// add to cache if proper level
//TODO: respect do not track?
//if( !navigator.doNotTrack && level >= self.options.logLevel ){
level = self._parseLevel(level);
if (level >= self.options.logLevel) {
self._addToCache(level, namespace, logArguments);
}
// also emit to consoleLogger if proper level for that
if (self.consoleLogger && level >= self.options.consoleLevel) {
self._emitToConsole(level, namespace, logArguments);
}
return self;
};
/** build a log cache entry object from the given level, namespace, and arguments (optionally adding timestamp */
MetricsLogger.prototype._buildEntry = function _buildEntry(
level,
namespace,
logArguments
) {
this._emitToConsole("debug", "MetricsLogger", [
"_buildEntry:",
arguments
]);
var entry = {
level: level,
namespace: this.options.clientPrefix + namespace,
args: logArguments
};
if (this.options.addTime) {
entry.time = new Date().toISOString();
//----------------------------------------------------------------------------- cache
/** add a message to the cache and if messages.length is high enough post them to the server */
MetricsLogger.prototype._addToCache = function _addToCache(
level,
namespace,
logArguments
) {
this._emitToConsole("debug", "MetricsLogger", [
"_addToCache:",
arguments,
this.options.addTime,
this.cache.length()
]);
//this._emitToConsole( 'debug', 'MetricsLogger', [ '\t logArguments:', logArguments ]);
var self = this;
// try add to the cache and if we've got _postSize number of entries, attempt to post them to the server
try {
var newLength = self.cache.add(
self._buildEntry(level, namespace, logArguments)
);
if (newLength >= self._postSize) {
self._postCache();
}
return entry;
};
// discard entry if an error occurs, but warn if level set to do so
} catch (err) {
self._emitToConsole("warn", "MetricsLogger", [
"Metrics logger could not stringify logArguments:",
namespace,
logArguments
]);
self._emitToConsole("error", "MetricsLogger", [err]);
}
return self;
};
/** post _postSize messages from the cache to the server, removing them if successful
/** build a log cache entry object from the given level, namespace, and arguments (optionally adding timestamp */
MetricsLogger.prototype._buildEntry = function _buildEntry(
level,
namespace,
logArguments
) {
this._emitToConsole("debug", "MetricsLogger", ["_buildEntry:", arguments]);
var entry = {
level: level,
namespace: this.options.clientPrefix + namespace,
args: logArguments
};
if (this.options.addTime) {
entry.time = new Date().toISOString();
}
return entry;
};
/** post _postSize messages from the cache to the server, removing them if successful
* if the post fails, wait until maxCacheSize is accumulated instead and try again then
* in addition to the messages from the cache ('metrics'), any info from getPingData (if set) will be sent
* onServerResponse will be called (if set) with any response from the server
*/
MetricsLogger.prototype._postCache = function _postCache(options) {
options = options || {};
this._emitToConsole("info", "MetricsLogger", [
"_postCache",
options,
this._postSize
]);
MetricsLogger.prototype._postCache = function _postCache(options) {
options = options || {};
this._emitToConsole("info", "MetricsLogger", [
"_postCache",
options,
this._postSize
]);
// short circuit if we're already sending
if (!this.options.postUrl || this._sending) {
return jQuery.when({});
}
// short circuit if we're already sending
if (!this.options.postUrl || this._sending) {
return jQuery.when({});
}
var self = this,
postSize = options.count || self._postSize,
// do not splice - remove after *successful* post
entries = self.cache.get(postSize),
entriesLength = entries.length,
// use the optional getPingData to add any extra info we may want to send
postData =
typeof self.options.getPingData === "function"
? self.options.getPingData()
: {};
//console.debug( postSize, entriesLength );
var self = this,
postSize = options.count || self._postSize,
// do not splice - remove after *successful* post
entries = self.cache.get(postSize),
entriesLength = entries.length,
// use the optional getPingData to add any extra info we may want to send
postData =
typeof self.options.getPingData === "function"
? self.options.getPingData()
: {};
//console.debug( postSize, entriesLength );
// add the metrics and send
postData.metrics = JSON.stringify(entries);
//console.debug( postData.metrics );
self._sending = true;
return jQuery
.post(self.options.postUrl, postData)
.always(function() {
self._sending = false;
})
.fail(function(xhr, status, message) {
// if we failed the previous time, set the next post target to the max num of entries
self._postSize = self.options.maxCacheSize;
//TODO:??
// log this failure to explain any gap in metrics
self.emit("error", "MetricsLogger", [
"_postCache error:",
xhr.readyState,
xhr.status,
xhr.responseJSON || xhr.responseText
]);
//TODO: still doesn't solve the problem that when cache == max, post will be tried on every emit
//TODO: see _delayPost
})
.done(function(response) {
if (typeof self.options.onServerResponse === "function") {
self.options.onServerResponse(response);
}
// only remove if post successful
self.cache.remove(entriesLength);
//console.debug( 'removed entries:', entriesLength, 'size now:', self.cache.length() );
// if we succeeded, reset the post target to the normal num of entries
self._postSize = self.options.postSize;
});
// return the xhr promise
};
// add the metrics and send
postData.metrics = JSON.stringify(entries);
//console.debug( postData.metrics );
self._sending = true;
return jQuery
.post(self.options.postUrl, postData)
.always(function() {
self._sending = false;
})
.fail(function(xhr, status, message) {
// if we failed the previous time, set the next post target to the max num of entries
self._postSize = self.options.maxCacheSize;
//TODO:??
// log this failure to explain any gap in metrics
self.emit("error", "MetricsLogger", [
"_postCache error:",
xhr.readyState,
xhr.status,
xhr.responseJSON || xhr.responseText
]);
//TODO: still doesn't solve the problem that when cache == max, post will be tried on every emit
//TODO: see _delayPost
})
.done(function(response) {
if (typeof self.options.onServerResponse === "function") {
self.options.onServerResponse(response);
}
// only remove if post successful
self.cache.remove(entriesLength);
//console.debug( 'removed entries:', entriesLength, 'size now:', self.cache.length() );
// if we succeeded, reset the post target to the normal num of entries
self._postSize = self.options.postSize;
});
// return the xhr promise
};
/** set _waiting to true and, after delayPostInMs, set it back to false */
MetricsLogger.prototype._delayPost = function _delayPost() {
//TODO: this won't work between pages
var self = this;
self._waiting = setTimeout(function() {
self._waiting = null;
}, self.options.delayPostInMs);
};
/** set _waiting to true and, after delayPostInMs, set it back to false */
MetricsLogger.prototype._delayPost = function _delayPost() {
//TODO: this won't work between pages
var self = this;
self._waiting = setTimeout(function() {
self._waiting = null;
}, self.options.delayPostInMs);
};
//----------------------------------------------------------------------------- console
/** output message to console based on level and consoleLogger type */
MetricsLogger.prototype._emitToConsole = function _emitToConsole(
level,
namespace,
logArguments
) {
//console.debug( '_emitToConsole:', level, namespace, logArguments );
var self = this,
whitelist = self.options.consoleNamespaceWhitelist;
if (!self.consoleLogger) {
return self;
}
// if a whitelist for namespaces is set, bail if this namespace is not in the list
if (whitelist && whitelist.indexOf(namespace) === -1) {
return self;
}
var args = Array.prototype.slice.call(logArguments, 0);
args.unshift(namespace);
//TODO: script location and/or source maps?
//TODO: branch on navigator.userAgent == AIIEEE - it only has log
if (
level >= MetricsLogger.METRIC &&
typeof self.consoleLogger.info === "function"
) {
return self.consoleLogger.info.apply(self.consoleLogger, args);
} else if (
level >= MetricsLogger.ERROR &&
typeof self.consoleLogger.error === "function"
) {
return self.consoleLogger.error.apply(self.consoleLogger, args);
} else if (
level >= MetricsLogger.WARN &&
typeof self.consoleLogger.warn === "function"
) {
self.consoleLogger.warn.apply(self.consoleLogger, args);
} else if (
level >= MetricsLogger.INFO &&
typeof self.consoleLogger.info === "function"
) {
self.consoleLogger.info.apply(self.consoleLogger, args);
} else if (
level >= MetricsLogger.DEBUG &&
typeof self.consoleLogger.debug === "function"
) {
self.consoleLogger.debug.apply(self.consoleLogger, args);
} else if (typeof self.consoleLogger.log === "function") {
self.consoleLogger.log.apply(self.consoleLogger, args);
}
//----------------------------------------------------------------------------- console
/** output message to console based on level and consoleLogger type */
MetricsLogger.prototype._emitToConsole = function _emitToConsole(
level,
namespace,
logArguments
) {
//console.debug( '_emitToConsole:', level, namespace, logArguments );
var self = this,
whitelist = self.options.consoleNamespaceWhitelist;
if (!self.consoleLogger) {
return self;
};
}
// if a whitelist for namespaces is set, bail if this namespace is not in the list
if (whitelist && whitelist.indexOf(namespace) === -1) {
return self;
}
//----------------------------------------------------------------------------- shortcuts
// generic functions when logging from non-namespaced object (e.g. templates)
/** log to default namespace */
MetricsLogger.prototype.log = function log() {
this.emit(
1,
this.options.defaultNamespace,
Array.prototype.slice.call(arguments, 0)
);
};
var args = Array.prototype.slice.call(logArguments, 0);
args.unshift(namespace);
//TODO: script location and/or source maps?
//TODO: branch on navigator.userAgent == AIIEEE - it only has log
if (
level >= MetricsLogger.METRIC &&
typeof self.consoleLogger.info === "function"
) {
return self.consoleLogger.info.apply(self.consoleLogger, args);
} else if (
level >= MetricsLogger.ERROR &&
typeof self.consoleLogger.error === "function"
) {
return self.consoleLogger.error.apply(self.consoleLogger, args);
} else if (
level >= MetricsLogger.WARN &&
typeof self.consoleLogger.warn === "function"
) {
self.consoleLogger.warn.apply(self.consoleLogger, args);
} else if (
level >= MetricsLogger.INFO &&
typeof self.consoleLogger.info === "function"
) {
self.consoleLogger.info.apply(self.consoleLogger, args);
} else if (
level >= MetricsLogger.DEBUG &&
typeof self.consoleLogger.debug === "function"
) {
self.consoleLogger.debug.apply(self.consoleLogger, args);
} else if (typeof self.consoleLogger.log === "function") {
self.consoleLogger.log.apply(self.consoleLogger, args);
}
return self;
};
/** debug to default namespace */
MetricsLogger.prototype.debug = function debug() {
this.emit(
MetricsLogger.DEBUG,
this.options.defaultNamespace,
Array.prototype.slice.call(arguments, 0)
);
};
//----------------------------------------------------------------------------- shortcuts
// generic functions when logging from non-namespaced object (e.g. templates)
/** log to default namespace */
MetricsLogger.prototype.log = function log() {
this.emit(
1,
this.options.defaultNamespace,
Array.prototype.slice.call(arguments, 0)
);
};
/** info to default namespace */
MetricsLogger.prototype.info = function info() {
this.emit(
MetricsLogger.INFO,
this.options.defaultNamespace,
Array.prototype.slice.call(arguments, 0)
);
};
/** debug to default namespace */
MetricsLogger.prototype.debug = function debug() {
this.emit(
MetricsLogger.DEBUG,
this.options.defaultNamespace,
Array.prototype.slice.call(arguments, 0)
);
};
/** warn to default namespace */
MetricsLogger.prototype.warn = function warn() {
this.emit(
MetricsLogger.WARN,
this.options.defaultNamespace,
Array.prototype.slice.call(arguments, 0)
);
};
/** info to default namespace */
MetricsLogger.prototype.info = function info() {
this.emit(
MetricsLogger.INFO,
this.options.defaultNamespace,
Array.prototype.slice.call(arguments, 0)
);
};
/** error to default namespace */
MetricsLogger.prototype.error = function error() {
this.emit(
MetricsLogger.ERROR,
this.options.defaultNamespace,
Array.prototype.slice.call(arguments, 0)
);
};
/** warn to default namespace */
MetricsLogger.prototype.warn = function warn() {
this.emit(
MetricsLogger.WARN,
this.options.defaultNamespace,
Array.prototype.slice.call(arguments, 0)
);
};
/** metric to default namespace */
MetricsLogger.prototype.metric = function metric() {
this.emit(
MetricsLogger.METRIC,
this.options.defaultNamespace,
Array.prototype.slice.call(arguments, 0)
);
};
/** error to default namespace */
MetricsLogger.prototype.error = function error() {
this.emit(
MetricsLogger.ERROR,
this.options.defaultNamespace,
Array.prototype.slice.call(arguments, 0)
);
};
/* ============================================================================
/** metric to default namespace */
MetricsLogger.prototype.metric = function metric() {
this.emit(
MetricsLogger.METRIC,
this.options.defaultNamespace,
Array.prototype.slice.call(arguments, 0)
);
};
/* ============================================================================
TODO:
need a performance pass - the JSON un/parsing is a bit much
============================================================================ */
/** @class LoggingCache
/** @class LoggingCache
* Simple implementation of cache wrapping an array.
*
* Formats an entry before it's cached and only keeps options.maxSize number
* of entries. Older entries are deleted first.
*/
function LoggingCache(options) {
var self = this;
return self._init(options || {});
function LoggingCache(options) {
var self = this;
return self._init(options || {});
}
/** default options */
LoggingCache.defaultOptions = {
/** maximum number of entries to keep before discarding oldest */
maxSize: 5000
};
/** initialize with options */
LoggingCache.prototype._init = function _init(options) {
if (!this._hasStorage()) {
//TODO: fall back to jstorage
throw new Error("LoggingCache needs localStorage");
}
if (!options.key) {
throw new Error("LoggingCache needs key for localStorage");
}
this.key = options.key;
this._initStorage();
/** default options */
LoggingCache.defaultOptions = {
/** maximum number of entries to keep before discarding oldest */
maxSize: 5000
};
this.maxSize = options.maxSize || LoggingCache.defaultOptions.maxSize;
return this;
};
/** initialize with options */
LoggingCache.prototype._init = function _init(options) {
if (!this._hasStorage()) {
//TODO: fall back to jstorage
throw new Error("LoggingCache needs localStorage");
}
if (!options.key) {
throw new Error("LoggingCache needs key for localStorage");
}
this.key = options.key;
this._initStorage();
/** tests for localStorage fns */
LoggingCache.prototype._hasStorage = function _hasStorage() {
//TODO: modernizr
var test = "test";
try {
localStorage.setItem(test, test);
localStorage.removeItem(test);
return true;
} catch (e) {
return false;
}
};
this.maxSize = options.maxSize || LoggingCache.defaultOptions.maxSize;
return this;
};
/** if no localStorage set for key, initialize to empty array */
LoggingCache.prototype._initStorage = function _initStorage() {
if (localStorage.getItem(this.key) === null) {
return this.empty();
}
return this;
};
/** tests for localStorage fns */
LoggingCache.prototype._hasStorage = function _hasStorage() {
//TODO: modernizr
var test = "test";
try {
localStorage.setItem(test, test);
localStorage.removeItem(test);
return true;
} catch (e) {
return false;
}
};
/** add an entry to the cache, removing the oldest beforehand if size >= maxSize */
LoggingCache.prototype.add = function add(entry) {
var self = this,
_cache = self._fetchAndParse(),
overage = _cache.length + 1 - self.maxSize;
if (overage > 0) {
_cache.splice(0, overage);
}
_cache.push(entry);
self._unparseAndStore(_cache);
return _cache.length;
};
/** if no localStorage set for key, initialize to empty array */
LoggingCache.prototype._initStorage = function _initStorage() {
if (localStorage.getItem(this.key) === null) {
return this.empty();
}
return this;
};
/** get the entries from localStorage and parse them */
LoggingCache.prototype._fetchAndParse = function _fetchAndParse() {
var self = this;
return JSON.parse(localStorage.getItem(self.key));
};
/** add an entry to the cache, removing the oldest beforehand if size >= maxSize */
LoggingCache.prototype.add = function add(entry) {
var self = this,
_cache = self._fetchAndParse(),
overage = _cache.length + 1 - self.maxSize;
if (overage > 0) {
_cache.splice(0, overage);
}
_cache.push(entry);
self._unparseAndStore(_cache);
return _cache.length;
};
/** stringify the entries and put them in localStorage */
LoggingCache.prototype._unparseAndStore = function _unparseAndStore(entries) {
var self = this;
return localStorage.setItem(self.key, JSON.stringify(entries));
};
/** get the entries from localStorage and parse them */
LoggingCache.prototype._fetchAndParse = function _fetchAndParse() {
var self = this;
return JSON.parse(localStorage.getItem(self.key));
};
///** process the entry before caching */
//LoggingCache.prototype._preprocessEntry = function _preprocessEntry( entry ){
// return JSON.stringify( entry );
//};
/** stringify the entries and put them in localStorage */
LoggingCache.prototype._unparseAndStore = function _unparseAndStore(
entries
) {
var self = this;
return localStorage.setItem(self.key, JSON.stringify(entries));
};
/** return the length --- oh, getters where are you? */
LoggingCache.prototype.length = function length() {
return this._fetchAndParse().length;
};
///** process the entry before caching */
//LoggingCache.prototype._preprocessEntry = function _preprocessEntry( entry ){
// return JSON.stringify( entry );
//};
/** get count number of entries starting with the oldest */
LoggingCache.prototype.get = function get(count) {
return this._fetchAndParse().slice(0, count);
};
/** return the length --- oh, getters where are you? */
LoggingCache.prototype.length = function length() {
return this._fetchAndParse().length;
};
/** remove count number of entries starting with the oldest */
LoggingCache.prototype.remove = function remove(count) {
var _cache = this._fetchAndParse(),
removed = _cache.splice(0, count);
this._unparseAndStore(_cache);
return removed;
};
/** get count number of entries starting with the oldest */
LoggingCache.prototype.get = function get(count) {
return this._fetchAndParse().slice(0, count);
};
/** empty/clear the entire cache */
LoggingCache.prototype.empty = function empty() {
localStorage.setItem(this.key, "[]");
return this;
};
/** remove count number of entries starting with the oldest */
LoggingCache.prototype.remove = function remove(count) {
var _cache = this._fetchAndParse(),
removed = _cache.splice(0, count);
this._unparseAndStore(_cache);
return removed;
};
/** stringify count number of entries (but do not remove) */
LoggingCache.prototype.stringify = function stringify(count) {
return JSON.stringify(this.get(count));
};
/** empty/clear the entire cache */
LoggingCache.prototype.empty = function empty() {
localStorage.setItem(this.key, "[]");
return this;
};
/** outputs entire cache to console */
LoggingCache.prototype.print = function print() {
// popup? (really, carl? a popup?) - easier to copy/paste
console.log(JSON.stringify(this._fetchAndParse(), null, " "));
};
/** stringify count number of entries (but do not remove) */
LoggingCache.prototype.stringify = function stringify(count) {
return JSON.stringify(this.get(count));
};
/** outputs entire cache to console */
LoggingCache.prototype.print = function print() {
// popup? (really, carl? a popup?) - easier to copy/paste
console.log(JSON.stringify(this._fetchAndParse(), null, " "));
};
//=============================================================================
return {
MetricsLogger: MetricsLogger,
LoggingCache: LoggingCache
};
});
//=============================================================================
export default {
MetricsLogger: MetricsLogger,
LoggingCache: LoggingCache
};
+35 -37
View File
@@ -1,40 +1,38 @@
define([], function() {
// Alphanumeric/natural sort fn
function naturalSort(a, b) {
// setup temp-scope variables for comparison evauluation
var re = /(-?[0-9\.]+)/g,
x = a.toString().toLowerCase() || "",
y = b.toString().toLowerCase() || "",
nC = String.fromCharCode(0),
xN = x.replace(re, nC + "$1" + nC).split(nC),
yN = y.replace(re, nC + "$1" + nC).split(nC),
xD = new Date(x).getTime(),
yD = xD ? new Date(y).getTime() : null;
// natural sorting of dates
if (yD) {
if (xD < yD) {
return -1;
} else if (xD > yD) {
return 1;
}
// Alphanumeric/natural sort fn
function naturalSort(a, b) {
// setup temp-scope variables for comparison evauluation
var re = /(-?[0-9\.]+)/g,
x = a.toString().toLowerCase() || "",
y = b.toString().toLowerCase() || "",
nC = String.fromCharCode(0),
xN = x.replace(re, nC + "$1" + nC).split(nC),
yN = y.replace(re, nC + "$1" + nC).split(nC),
xD = new Date(x).getTime(),
yD = xD ? new Date(y).getTime() : null;
// natural sorting of dates
if (yD) {
if (xD < yD) {
return -1;
} else if (xD > yD) {
return 1;
}
// natural sorting through split numeric strings and default strings
var oFxNcL, oFyNcL;
for (
var cLoc = 0, numS = Math.max(xN.length, yN.length);
cLoc < numS;
cLoc++
) {
oFxNcL = parseFloat(xN[cLoc]) || xN[cLoc];
oFyNcL = parseFloat(yN[cLoc]) || yN[cLoc];
if (oFxNcL < oFyNcL) {
return -1;
} else if (oFxNcL > oFyNcL) {
return 1;
}
}
return 0;
}
// natural sorting through split numeric strings and default strings
var oFxNcL, oFyNcL;
for (
var cLoc = 0, numS = Math.max(xN.length, yN.length);
cLoc < numS;
cLoc++
) {
oFxNcL = parseFloat(xN[cLoc]) || xN[cLoc];
oFyNcL = parseFloat(yN[cLoc]) || yN[cLoc];
if (oFxNcL < oFyNcL) {
return -1;
} else if (oFxNcL > oFyNcL) {
return 1;
}
}
return 0;
}
return naturalSort;
});
export default naturalSort;
@@ -1,39 +1,37 @@
define([], function() {
// ============================================================================
function get(key, queryString) {
queryString = queryString || window.location.search.substr(1);
var keyRegex = new RegExp(key + "=([^&#$]+)", "g");
var matches = queryString.match(keyRegex);
if (!matches || !matches.length) {
return undefined;
}
matches = _.map(matches, function(match) {
return decodeURIComponent(
match.substr(key.length + 1).replace(/\+/g, " ")
);
});
if (matches.length === 1) {
return matches[0];
}
return matches;
// ============================================================================
function get(key, queryString) {
queryString = queryString || window.location.search.substr(1);
var keyRegex = new RegExp(key + "=([^&#$]+)", "g");
var matches = queryString.match(keyRegex);
if (!matches || !matches.length) {
return undefined;
}
function parse(queryString) {
if (!queryString) {
return {};
}
var parsed = {},
split = queryString.split("&");
split.forEach(function(pairString) {
var pair = pairString.split("=");
parsed[pair[0]] = decodeURI(pair[1]);
});
return parsed;
matches = _.map(matches, function(match) {
return decodeURIComponent(
match.substr(key.length + 1).replace(/\+/g, " ")
);
});
if (matches.length === 1) {
return matches[0];
}
return matches;
}
// ============================================================================
return {
get: get,
parse: parse
};
});
function parse(queryString) {
if (!queryString) {
return {};
}
var parsed = {},
split = queryString.split("&");
split.forEach(function(pairString) {
var pair = pairString.split("=");
parsed[pair[0]] = decodeURI(pair[1]);
});
return parsed;
}
// ============================================================================
export default {
get: get,
parse: parse
};
+306 -309
View File
@@ -2,158 +2,157 @@
* Galaxy utilities comprises small functions, which at this point
* do not require their own classes/files
*/
define(["utils/localization"], function(_l) {
/** Builds a basic iframe */
function iframe(src) {
return (
'<iframe src="' +
src +
'" frameborder="0" style="width: 100%; height: 100%;"/>'
);
}
import _l from "utils/localization";
/** Builds a basic iframe */
function iframe(src) {
return (
'<iframe src="' +
src +
'" frameborder="0" style="width: 100%; height: 100%;"/>'
);
}
/** Traverse through json */
function deepeach(dict, callback) {
for (var i in dict) {
var d = dict[i];
if (_.isObject(d)) {
var new_dict = callback(d);
new_dict && (dict[i] = new_dict);
deepeach(d, callback);
}
/** Traverse through json */
function deepeach(dict, callback) {
for (var i in dict) {
var d = dict[i];
if (_.isObject(d)) {
var new_dict = callback(d);
new_dict && (dict[i] = new_dict);
deepeach(d, callback);
}
}
}
/** Identifies urls and replaces them with anchors */
function linkify(inputText) {
var replacedText, replacePattern1, replacePattern2, replacePattern3;
/** Identifies urls and replaces them with anchors */
function linkify(inputText) {
var replacedText, replacePattern1, replacePattern2, replacePattern3;
// URLs starting with http://, https://, or ftp://
replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
replacedText = inputText.replace(
replacePattern1,
'<a href="$1" target="_blank">$1</a>'
);
// URLs starting with http://, https://, or ftp://
replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
replacedText = inputText.replace(
replacePattern1,
'<a href="$1" target="_blank">$1</a>'
);
// URLs starting with "www." (without // before it, or it'd re-link the ones done above).
replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
replacedText = replacedText.replace(
replacePattern2,
'$1<a href="http://$2" target="_blank">$2</a>'
);
// URLs starting with "www." (without // before it, or it'd re-link the ones done above).
replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
replacedText = replacedText.replace(
replacePattern2,
'$1<a href="http://$2" target="_blank">$2</a>'
);
// Change email addresses to mailto:: links.
replacePattern3 = /(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim;
replacedText = replacedText.replace(
replacePattern3,
'<a href="mailto:$1">$1</a>'
);
// Change email addresses to mailto:: links.
replacePattern3 = /(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim;
replacedText = replacedText.replace(
replacePattern3,
'<a href="mailto:$1">$1</a>'
);
return replacedText;
}
return replacedText;
}
/** Clone */
function clone(obj) {
return JSON.parse(JSON.stringify(obj) || null);
}
/** Clone */
function clone(obj) {
return JSON.parse(JSON.stringify(obj) || null);
}
/**
/**
* Check if a string is a json string
* @param{String} text - Content to be validated
*/
function isJSON(text) {
return /^[\],:{}\s]*$/.test(
text
.replace(/\\["\\\/bfnrtu]/g, "@")
.replace(
/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
"]"
)
.replace(/(?:^|:|,)(?:\s*\[)+/g, "")
);
}
function isJSON(text) {
return /^[\],:{}\s]*$/.test(
text
.replace(/\\["\\\/bfnrtu]/g, "@")
.replace(
/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
"]"
)
.replace(/(?:^|:|,)(?:\s*\[)+/g, "")
);
}
/**
/**
* Sanitize/escape a string
* @param{String} content - Content to be sanitized
*/
function sanitize(content) {
return $("<div/>")
.text(content)
.html();
}
function sanitize(content) {
return $("<div/>")
.text(content)
.html();
}
/**
/**
* Checks if a value or list of values is `empty`
* usually used for selectable options
* @param{String} value - Value or list to be validated
*/
function isEmpty(value) {
if (!(value instanceof Array)) {
value = [value];
}
if (value.length === 0) {
function isEmpty(value) {
if (!(value instanceof Array)) {
value = [value];
}
if (value.length === 0) {
return true;
}
for (var i in value) {
if (
["__null__", "__undefined__", null, undefined].indexOf(value[i]) >
-1
) {
return true;
}
for (var i in value) {
if (
["__null__", "__undefined__", null, undefined].indexOf(
value[i]
) > -1
) {
return true;
}
}
return false;
}
return false;
}
/**
/**
* Convert list to pretty string
* @param{String} lst - List of strings to be converted in human readable list sentence
*/
function textify(lst) {
if ($.isArray(lst)) {
var lst = lst.toString().replace(/,/g, ", ");
var pos = lst.lastIndexOf(", ");
if (pos != -1) {
lst = lst.substr(0, pos) + " or " + lst.substr(pos + 2);
}
return lst;
function textify(lst) {
if ($.isArray(lst)) {
var lst = lst.toString().replace(/,/g, ", ");
var pos = lst.lastIndexOf(", ");
if (pos != -1) {
lst = lst.substr(0, pos) + " or " + lst.substr(pos + 2);
}
return "";
return lst;
}
return "";
}
/**
/**
* Request handler for GET
* @param{String} url - Url request is made to
* @param{Function} success - Callback on success
* @param{Function} error - Callback on error
* @param{Boolean} cache - Use cached data if available
*/
function get(options) {
top.__utils__get__ = top.__utils__get__ || {};
var cache_key = JSON.stringify(options);
if (options.cache && top.__utils__get__[cache_key]) {
options.success && options.success(top.__utils__get__[cache_key]);
window.console.debug(
"utils.js::get() - Fetching from cache [" + options.url + "]."
);
} else {
request({
url: options.url,
data: options.data,
success: function(response) {
top.__utils__get__[cache_key] = response;
options.success && options.success(response);
},
error: function(response, status) {
options.error && options.error(response, status);
}
});
}
function get(options) {
top.__utils__get__ = top.__utils__get__ || {};
var cache_key = JSON.stringify(options);
if (options.cache && top.__utils__get__[cache_key]) {
options.success && options.success(top.__utils__get__[cache_key]);
window.console.debug(
"utils.js::get() - Fetching from cache [" + options.url + "]."
);
} else {
request({
url: options.url,
data: options.data,
success: function(response) {
top.__utils__get__[cache_key] = response;
options.success && options.success(response);
},
error: function(response, status) {
options.error && options.error(response, status);
}
});
}
}
/**
/**
* Request handler
* @param{String} method - Request method ['GET', 'POST', 'DELETE', 'PUT']
* @param{String} url - Url request is made to
@@ -161,237 +160,235 @@ define(["utils/localization"], function(_l) {
* @param{Function} success - Callback on success
* @param{Function} error - Callback on error
*/
function request(options) {
// prepare ajax
var ajaxConfig = {
contentType: "application/json",
type: options.type || "GET",
data: options.data || {},
url: options.url
};
// encode data into url
if (ajaxConfig.type == "GET" || ajaxConfig.type == "DELETE") {
if (!$.isEmptyObject(ajaxConfig.data)) {
ajaxConfig.url += ajaxConfig.url.indexOf("?") == -1 ? "?" : "&";
ajaxConfig.url += $.param(ajaxConfig.data, true);
}
ajaxConfig.data = null;
} else {
ajaxConfig.dataType = "json";
ajaxConfig.url = ajaxConfig.url;
ajaxConfig.data = JSON.stringify(ajaxConfig.data);
function request(options) {
// prepare ajax
var ajaxConfig = {
contentType: "application/json",
type: options.type || "GET",
data: options.data || {},
url: options.url
};
// encode data into url
if (ajaxConfig.type == "GET" || ajaxConfig.type == "DELETE") {
if (!$.isEmptyObject(ajaxConfig.data)) {
ajaxConfig.url += ajaxConfig.url.indexOf("?") == -1 ? "?" : "&";
ajaxConfig.url += $.param(ajaxConfig.data, true);
}
// make request
$.ajax(ajaxConfig)
.done(function(response) {
if (typeof response === "string") {
try {
response = response.replace("Infinity,", '"Infinity",');
response = jQuery.parseJSON(response);
} catch (e) {
console.debug(e);
}
}
options.success && options.success(response);
})
.fail(function(response) {
var response_text = null;
try {
response_text = jQuery.parseJSON(response.responseText);
} catch (e) {
response_text = response.responseText;
}
options.error && options.error(response_text, response.status);
})
.always(function() {
options.complete && options.complete();
});
ajaxConfig.data = null;
} else {
ajaxConfig.dataType = "json";
ajaxConfig.url = ajaxConfig.url;
ajaxConfig.data = JSON.stringify(ajaxConfig.data);
}
/**
// make request
$.ajax(ajaxConfig)
.done(function(response) {
if (typeof response === "string") {
try {
response = response.replace("Infinity,", '"Infinity",');
response = jQuery.parseJSON(response);
} catch (e) {
console.debug(e);
}
}
options.success && options.success(response);
})
.fail(function(response) {
var response_text = null;
try {
response_text = jQuery.parseJSON(response.responseText);
} catch (e) {
response_text = response.responseText;
}
options.error && options.error(response_text, response.status);
})
.always(function() {
options.complete && options.complete();
});
}
/**
* Read a property value from CSS
* @param{String} classname - CSS class
* @param{String} name - CSS property
*/
function cssGetAttribute(classname, name) {
var el = $('<div class="' + classname + '"></div>');
el.appendTo(":eq(0)");
var value = el.css(name);
el.remove();
return value;
}
function cssGetAttribute(classname, name) {
var el = $('<div class="' + classname + '"></div>');
el.appendTo(":eq(0)");
var value = el.css(name);
el.remove();
return value;
}
/**
/**
* Load a CSS file
* @param{String} url - Url of CSS file
*/
function cssLoadFile(url) {
if (!$('link[href^="' + url + '"]').length) {
$(
'<link href="' + Galaxy.root + url + '" rel="stylesheet">'
).appendTo("head");
}
function cssLoadFile(url) {
if (!$('link[href^="' + url + '"]').length) {
$('<link href="' + Galaxy.root + url + '" rel="stylesheet">').appendTo(
"head"
);
}
}
/**
/**
* Safely merge to dictionaries
* @param{Object} options - Target dictionary
* @param{Object} optionsDefault - Source dictionary
*/
function merge(options, optionsDefault) {
if (options) {
return _.defaults(options, optionsDefault);
} else {
return optionsDefault;
}
function merge(options, optionsDefault) {
if (options) {
return _.defaults(options, optionsDefault);
} else {
return optionsDefault;
}
}
/**
/**
* Round floaing point 'number' to 'numPlaces' number of decimal places.
* @param{Object} number a floaing point number
* @param{Object} numPlaces number of decimal places
*/
function roundToDecimalPlaces(number, numPlaces) {
var placesMultiplier = 1;
for (var i = 0; i < numPlaces; i++) {
placesMultiplier *= 10;
}
return Math.round(number * placesMultiplier) / placesMultiplier;
function roundToDecimalPlaces(number, numPlaces) {
var placesMultiplier = 1;
for (var i = 0; i < numPlaces; i++) {
placesMultiplier *= 10;
}
return Math.round(number * placesMultiplier) / placesMultiplier;
}
// calculate on import
var kb = 1024,
mb = kb * kb,
gb = mb * kb,
tb = gb * kb;
/**
// calculate on import
var kb = 1024,
mb = kb * kb,
gb = mb * kb,
tb = gb * kb;
/**
* Format byte size to string with units
* @param{Integer} size - Size in bytes
* @param{Boolean} normal_font - Switches font between normal and bold
*/
function bytesToString(size, normal_font, numberPlaces) {
numberPlaces = numberPlaces !== undefined ? numberPlaces : 1;
// identify unit
var unit = "";
if (size >= tb) {
size = size / tb;
unit = "TB";
} else if (size >= gb) {
size = size / gb;
unit = "GB";
} else if (size >= mb) {
size = size / mb;
unit = "MB";
} else if (size >= kb) {
size = size / kb;
unit = "KB";
} else if (size > 0) {
unit = "b";
} else {
return normal_font ? "0 b" : "<strong>-</strong>";
}
// return formatted string
var rounded =
unit == "b" ? size : roundToDecimalPlaces(size, numberPlaces);
if (normal_font) {
return rounded + " " + unit;
} else {
return "<strong>" + rounded + "</strong> " + unit;
}
function bytesToString(size, normal_font, numberPlaces) {
numberPlaces = numberPlaces !== undefined ? numberPlaces : 1;
// identify unit
var unit = "";
if (size >= tb) {
size = size / tb;
unit = "TB";
} else if (size >= gb) {
size = size / gb;
unit = "GB";
} else if (size >= mb) {
size = size / mb;
unit = "MB";
} else if (size >= kb) {
size = size / kb;
unit = "KB";
} else if (size > 0) {
unit = "b";
} else {
return normal_font ? "0 b" : "<strong>-</strong>";
}
/** Create a unique id */
function uid() {
top.__utils__uid__ = top.__utils__uid__ || 0;
return "uid-" + top.__utils__uid__++;
// return formatted string
var rounded = unit == "b" ? size : roundToDecimalPlaces(size, numberPlaces);
if (normal_font) {
return rounded + " " + unit;
} else {
return "<strong>" + rounded + "</strong> " + unit;
}
}
/** Create a time stamp */
function time() {
var d = new Date();
var hours = (d.getHours() < 10 ? "0" : "") + d.getHours();
var minutes = (d.getMinutes() < 10 ? "0" : "") + d.getMinutes();
return (datetime =
d.getDate() +
"/" +
(d.getMonth() + 1) +
"/" +
d.getFullYear() +
", " +
hours +
":" +
minutes);
/** Create a unique id */
function uid() {
top.__utils__uid__ = top.__utils__uid__ || 0;
return "uid-" + top.__utils__uid__++;
}
/** Create a time stamp */
function time() {
var d = new Date();
var hours = (d.getHours() < 10 ? "0" : "") + d.getHours();
var minutes = (d.getMinutes() < 10 ? "0" : "") + d.getMinutes();
return (datetime =
d.getDate() +
"/" +
(d.getMonth() + 1) +
"/" +
d.getFullYear() +
", " +
hours +
":" +
minutes);
}
/** Append script and style tags to Galaxy main application */
function appendScriptStyle(data) {
// create a script tag inside head tag
if (data.script && data.script !== "") {
$("<script/>", { type: "text/javascript" })
.text(data.script)
.appendTo("head");
}
/** Append script and style tags to Galaxy main application */
function appendScriptStyle(data) {
// create a script tag inside head tag
if (data.script && data.script !== "") {
$("<script/>", { type: "text/javascript" })
.text(data.script)
.appendTo("head");
}
// create a style tag inside head tag
if (data.styles && data.styles !== "") {
$("<style/>", { type: "text/css" })
.text(data.styles)
.appendTo("head");
}
// create a style tag inside head tag
if (data.styles && data.styles !== "") {
$("<style/>", { type: "text/css" })
.text(data.styles)
.appendTo("head");
}
}
/** Get querystrings from url */
function getQueryString(key) {
return decodeURIComponent(
window.location.search.replace(
new RegExp(
"^(?:.*[&\\?]" +
encodeURIComponent(key).replace(/[\.\+\*]/g, "\\$&") +
"(?:\\=([^&]*))?)?.*$",
"i"
),
"$1"
)
);
/** Get querystrings from url */
function getQueryString(key) {
return decodeURIComponent(
window.location.search.replace(
new RegExp(
"^(?:.*[&\\?]" +
encodeURIComponent(key).replace(/[\.\+\*]/g, "\\$&") +
"(?:\\=([^&]*))?)?.*$",
"i"
),
"$1"
)
);
}
function setWindowTitle(title) {
if (title) {
window.document.title =
"Galaxy " +
(window.Galaxy.config.brand
? " | " + window.Galaxy.config.brand
: "") +
" | " +
_l(title);
} else {
window.document.title =
"Galaxy " +
(window.Galaxy.config.brand
? " | " + window.Galaxy.config.brand
: "");
}
}
function setWindowTitle(title) {
if (title) {
window.document.title =
"Galaxy " +
(window.Galaxy.config.brand
? " | " + window.Galaxy.config.brand
: "") +
" | " +
_l(title);
} else {
window.document.title =
"Galaxy " +
(window.Galaxy.config.brand
? " | " + window.Galaxy.config.brand
: "");
}
}
return {
cssLoadFile: cssLoadFile,
cssGetAttribute: cssGetAttribute,
get: get,
merge: merge,
iframe: iframe,
bytesToString: bytesToString,
uid: uid,
time: time,
request: request,
sanitize: sanitize,
textify: textify,
isEmpty: isEmpty,
deepeach: deepeach,
isJSON: isJSON,
clone: clone,
linkify: linkify,
appendScriptStyle: appendScriptStyle,
getQueryString: getQueryString,
setWindowTitle: setWindowTitle
};
});
export default {
cssLoadFile: cssLoadFile,
cssGetAttribute: cssGetAttribute,
get: get,
merge: merge,
iframe: iframe,
bytesToString: bytesToString,
uid: uid,
time: time,
request: request,
sanitize: sanitize,
textify: textify,
isEmpty: isEmpty,
deepeach: deepeach,
isJSON: isJSON,
clone: clone,
linkify: linkify,
appendScriptStyle: appendScriptStyle,
getQueryString: getQueryString,
setWindowTitle: setWindowTitle
};
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["utils/add-logging.js"],"names":["define","LOGGING_FNS","obj","namespace","addTo","undefined","prototype","addLogging","forEach","logFn","this","logger","arguments","apply"],"mappings":"kCAAAA,UAAW,WAEP,IAAIC,GAAe,MAAO,QAAS,OAAQ,OAAQ,QAAS,UA0C/D,OArCG,SAAoBC,EAAKC,GACrB,IAAIC,OAA0BC,IAAlBH,EAAII,UAA0BJ,EAAII,UAAYJ,EAgC7D,YA/BqBG,IAAdF,IAFRC,EAASG,cAAgBJ,GAQrBF,EAAAO,QAAA,SAAAC,GAIIL,EAAMK,GAAS,WAFnB,GAAAC,KAAAC,OAGQ,OAAAD,KAAKC,OAAKA,KACND,KAAOL,OAAAA,KACVI,EACGC,KAAKC,cACLC,WAOAF,KAAAC,OAAAF,GAIHC,KAAAC,OAAAF,GAAAI,MAAAH,KAAAC,OAAAC,gBAJG,KASfV","file":"../../scripts/utils/add-logging.js","sourcesContent":["define([], function() {\n //==============================================================================\n var LOGGING_FNS = [\"log\", \"debug\", \"info\", \"warn\", \"error\", \"metric\"];\n /** adds logging functions to an obj.prototype (or obj directly) adding a namespace for filtering\n * @param {Object} obj\n * @param {String} namespace\n */\n function addLogging(obj, namespace) {\n var addTo = obj.prototype !== undefined ? obj.prototype : obj;\n if (namespace !== undefined) {\n addTo._logNamespace = namespace;\n }\n //yagni?: without this, may not capture Galaxy.config.debug and add Galaxy.logger properly\n // if( window.Galaxy && window.Galaxy.config && window.Galaxy.config.debug ){\n // addTo.logger = window.Galaxy.logger;\n // }\n\n // give the object each\n LOGGING_FNS.forEach(function(logFn) {\n addTo[logFn] = function() {\n if (!this.logger) {\n return undefined;\n }\n if (this.logger.emit) {\n return this.logger.emit(\n logFn,\n this._logNamespace,\n arguments\n );\n }\n if (this.logger[logFn]) {\n //TODO:! there has to be a way to get the lineno/file into this\n // http://stackoverflow.com/questions/13815640/a-proper-wrapper-for-console-log-with-correct-line-number\n // http://www.paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/\n return this.logger[logFn].apply(this.logger, arguments);\n }\n return undefined;\n };\n });\n return obj;\n }\n\n //==============================================================================\n return addLogging;\n});\n"]}
{"version":3,"sources":["utils/add-logging.js"],"names":["LOGGING_FNS","obj","namespace","undefined","prototype","addTo","_logNamespace","forEach","logFn","this","logger","emit","arguments"],"mappings":"6FACA,IAAIA,GAAe,MAAO,QAAS,OAAQ,OAAQ,QAAS,oBAD5D,SAAAC,EAAAC,GACA,IAAIF,OAAsBG,IAAtBH,EAAAA,UAAcC,EAAyBG,UAAzBH,EA2BF,YA1BhBE,IAAAD,IAOQG,EAAMC,cAAgBJ,GAE1BF,EAAAO,QAAA,SAAAC,GACAH,EAAAG,GAAA,WACA,GAAAC,KAAAC,OAGA,OAAAD,KAAAC,OAAAC,KACYJ,KAAQG,OAAAC,KAASH,EAAOC,KAAAH,cAAAM,WAE5BH,KAAKC,OAAKA,GAIND,KAAOC,OAAKA,GAAOC,MAAKH,KAAOE,OAAKJ,gBAJxC,KASIL","file":"../../scripts/utils/add-logging.js","sourcesContent":["//==============================================================================\nvar LOGGING_FNS = [\"log\", \"debug\", \"info\", \"warn\", \"error\", \"metric\"];\n/** adds logging functions to an obj.prototype (or obj directly) adding a namespace for filtering\n * @param {Object} obj\n * @param {String} namespace\n */\nfunction addLogging(obj, namespace) {\n var addTo = obj.prototype !== undefined ? obj.prototype : obj;\n if (namespace !== undefined) {\n addTo._logNamespace = namespace;\n }\n //yagni?: without this, may not capture Galaxy.config.debug and add Galaxy.logger properly\n // if( window.Galaxy && window.Galaxy.config && window.Galaxy.config.debug ){\n // addTo.logger = window.Galaxy.logger;\n // }\n\n // give the object each\n LOGGING_FNS.forEach(function(logFn) {\n addTo[logFn] = function() {\n if (!this.logger) {\n return undefined;\n }\n if (this.logger.emit) {\n return this.logger.emit(logFn, this._logNamespace, arguments);\n }\n if (this.logger[logFn]) {\n //TODO:! there has to be a way to get the lineno/file into this\n // http://stackoverflow.com/questions/13815640/a-proper-wrapper-for-console-log-with-correct-line-number\n // http://www.paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/\n return this.logger[logFn].apply(this.logger, arguments);\n }\n return undefined;\n };\n });\n return obj;\n}\n\n//==============================================================================\nexport default addLogging;\n"]}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["utils/deferred.js"],"names":["define","Utils","Backbone","Model","extend","initialize","this","active","execute","callback","self","id","uid","has_deferred","process","promise","always","debug","charAt","toUpperCase","state","slice","last","reject","resolve","reset","Galaxy","emit","i","ready","$","isEmptyObject"],"mappings":"kCAAAA,QAAA,eAAA,SAAAC,GAII,OAAOC,SAASC,MAAMC,QAClBC,WAAY,WAFZC,KAAAC,UACJD,KAAOJ,KAASC,MAMZK,QAAA,SAAAC,GAII,IAAIC,EAAOJ,KACPK,EAAKV,EAAMW,MAFnBJ,EAASC,EAASA,OAAU,EAGxBH,KAAAC,OAAIM,IAAAA,EAGJ,IAAAC,EAAKP,EAAOI,WAIZG,EAAQC,UAAUC,OAAO,kBAFzBN,EAAAH,OAAAI,GACAE,GACAC,OAAQC,KAARE,MACI,sBACAJ,KAAAA,QAFJK,OAAA,GAOiBC,cAOjBb,KAAAc,QAAAC,MAAA,GACYC,IACJZ,KASAI,EAAAA,KAAAA,KAAAA,MAAAA,OAAQS,WACXb,EAAAH,OAAAI,IAXLE,GAaKS,OAAOR,KAAQC,MA/CC,sBAuCL,WAAaJ,GAErBF,EAASK,IAWdD,GAAWC,EAAAU,WAEdV,EAAAS,WAGHjB,KAzDwBgB,KAAAR,EAAAC,WA8DrBU,MAAA,WACHC,OAAAC,KAAAV,MAAA,sBAAA,SA/DL,IAAA,IAAAW,KAAAtB,KAAAC,OADJD,KAAAC,OAAAqB,IAAA,GA8DQC,MAAO,WACH,OAAOC,EAAEC,cAAczB,KAAKC","file":"../../scripts/utils/deferred.js","sourcesContent":["/**\n * This class defines a queue to ensure that multiple deferred callbacks are executed sequentially.\n */\ndefine([\"utils/utils\"], function(Utils) {\n return Backbone.Model.extend({\n initialize: function() {\n this.active = {};\n this.last = null;\n },\n\n /** Adds a callback to the queue. Upon execution a deferred object is parsed to the callback i.e. callback( deferred ).\n * If the callback does not take any arguments, the deferred is resolved instantly.\n */\n execute: function(callback) {\n var self = this;\n var id = Utils.uid();\n var has_deferred = callback.length > 0;\n\n // register process\n this.active[id] = true;\n\n // deferred process\n var process = $.Deferred();\n process.promise().always(function() {\n delete self.active[id];\n has_deferred &&\n Galaxy.emit.debug(\n \"deferred::execute()\",\n this.state()\n .charAt(0)\n .toUpperCase() +\n this.state().slice(1) +\n \" \" +\n id\n );\n });\n\n // deferred queue\n $.when(this.last).always(function() {\n if (self.active[id]) {\n has_deferred &&\n Galaxy.emit.debug(\n \"deferred::execute()\",\n \"Running \" + id\n );\n callback(process);\n !has_deferred && process.resolve();\n } else {\n process.reject();\n }\n });\n this.last = process.promise();\n },\n\n /** Resets the promise queue. All currently queued but unexecuted callbacks/promises will be rejected.\n */\n reset: function() {\n Galaxy.emit.debug(\"deferred::execute()\", \"Reset\");\n for (var i in this.active) {\n this.active[i] = false;\n }\n },\n\n /** Returns true if all processes are done.\n */\n ready: function() {\n return $.isEmptyObject(this.active);\n }\n });\n});\n"]}
{"version":3,"sources":["utils/deferred.js"],"names":["Backbone","Model","extend","initialize","this","active","last","execute","callback","self","id","_utils2","default","length","process","$","Deferred","promise","always","has_deferred","emit","debug","state","charAt","slice","when","resolve","reject","reset","Galaxy","i","ready","isEmptyObject"],"mappings":"kLAIeA,SAASC,MAAMC,QAC1BC,WAAY,WACRC,KAAKC,UACLD,KAAKE,KAAO,MAMhBC,QAAS,SAASC,GACd,IAAIC,EAAOL,KACPM,EAAKC,EAAAC,QAXFZ,MACXG,EAAYK,EAAAK,OAAW,EAGtBT,KAJgCC,OAAAK,IAAA,EAkB7B,IAAII,EAAUC,EAAEC,WAChBF,EAAQG,UAAUC,OAAO,kBAVpBT,EAAAJ,OAAAK,GACLS,GACIT,OAAKU,KAAAC,MACLF,sBAYQf,KAAKkB,QAVjBC,OAAA,GACYb,cAYIN,KAAKkB,QAAQE,MAAM,GAVnC,IACIV,KAgBJC,EAAEU,KAAKrB,KAAKE,MAAMY,OAAO,WADzBT,EAAAJ,OAAAK,IACEe,GACMhB,OAAKJ,KAAOK,MAAK,sBAAA,WAAAA,GACjBS,EAAAA,IAEAX,GAASM,EAATY,WAEHZ,EAAMa,WAGVvB,KATDE,KAAAQ,EAAAG,WAeJW,MAAO,WAAPA,OAAOR,KAAAC,MAAA,sBAAW,SACdQ,IAAAA,IAAAA,KAAOT,KAAKC,OACZjB,KAAKC,OAALyB,IAAc,GAOlBC,MAAO,WAAPA,OAAOhB,EAAAiB,cAAA5B,KAAWC","file":"../../scripts/utils/deferred.js","sourcesContent":["/**\n * This class defines a queue to ensure that multiple deferred callbacks are executed sequentially.\n */\nimport Utils from \"utils/utils\";\nexport default Backbone.Model.extend({\n initialize: function() {\n this.active = {};\n this.last = null;\n },\n\n /** Adds a callback to the queue. Upon execution a deferred object is parsed to the callback i.e. callback( deferred ).\n * If the callback does not take any arguments, the deferred is resolved instantly.\n */\n execute: function(callback) {\n var self = this;\n var id = Utils.uid();\n var has_deferred = callback.length > 0;\n\n // register process\n this.active[id] = true;\n\n // deferred process\n var process = $.Deferred();\n process.promise().always(function() {\n delete self.active[id];\n has_deferred &&\n Galaxy.emit.debug(\n \"deferred::execute()\",\n this.state()\n .charAt(0)\n .toUpperCase() +\n this.state().slice(1) +\n \" \" +\n id\n );\n });\n\n // deferred queue\n $.when(this.last).always(function() {\n if (self.active[id]) {\n has_deferred &&\n Galaxy.emit.debug(\"deferred::execute()\", \"Running \" + id);\n callback(process);\n !has_deferred && process.resolve();\n } else {\n process.reject();\n }\n });\n this.last = process.promise();\n },\n\n /** Resets the promise queue. All currently queued but unexecuted callbacks/promises will be rejected.\n */\n reset: function() {\n Galaxy.emit.debug(\"deferred::execute()\", \"Reset\");\n for (var i in this.active) {\n this.active[i] = false;\n }\n },\n\n /** Returns true if all processes are done.\n */\n ready: function() {\n return $.isEmptyObject(this.active);\n }\n});\n"]}
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["utils/levenshtein.js"],"names":["define","levenshteinDistance","b","a","length","i","matrix","j","charAt","Math","min"],"mappings":"kCAAAA,UAAW,WAiEP,OA5CA,SAASC,EAATC,GACI,GAAI,IAAJC,EAAAC,OACI,OAAAF,EAAAE,OAEJ,GAAI,IAAJF,EAAAE,OACI,OAAAD,EAAAC,OAGJ,IAGAC,EAHAC,KAIA,IAAAD,EAAKA,EAAAA,GAAOA,EAAAA,OAAOD,IACfE,EAAAA,IAAAD,GAIJ,IAAAE,EACA,IAAAA,EAAKA,EAAAA,GAAOA,EAAAA,OAAOH,IACfE,EAAAA,GAAAA,GAAAC,EAIJ,IAAAF,EAAKA,EAAAA,GAAOA,EAAAA,OAAOD,IACf,IAAAG,EAAKA,EAAAA,GAAOA,EAAAA,OAAOH,IACfF,EAAAM,OAAMA,EAAOH,KAATF,EAAAK,OAAsBA,EAAOD,GAC7BD,EAAAA,GAAAA,GAAAA,EAAeA,EAAOD,GAAAA,EAAOE,GAE7BD,EAAAA,GAAAA,GAAAG,KAAeA,IAEXA,EAAKC,EACDJ,GAAAA,EAAA,GAAc,EACdA,KAAAA,IAGXA,EAAAD,GAAAE,EAAA,GAAA,EACJD,EAAAD,EAAA,GAAAE,GAAA,IAQT,OAAON,EAAAA,EAAAA,QAAAA,EAAPG","file":"../../scripts/utils/levenshtein.js","sourcesContent":["define([], function() {\n //=============================================================================\n /**\n(Imported for edit distance algorith. From: https://gist.github.com/andrei-m/982927)\nCopyright (c) 2011 Andrei Mackenzie\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated\ndocumentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the\nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit\npersons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the\nSoftware.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\nWARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n // Compute the edit distance between the two given strings\n //exports.getEditDistance = function(a, b){\n function levenshteinDistance(a, b) {\n if (a.length === 0) {\n return b.length;\n }\n if (b.length === 0) {\n return a.length;\n }\n\n var matrix = [];\n\n // increment along the first column of each row\n var i;\n for (i = 0; i <= b.length; i++) {\n matrix[i] = [i];\n }\n\n // increment each column in the first row\n var j;\n for (j = 0; j <= a.length; j++) {\n matrix[0][j] = j;\n }\n\n // Fill in the rest of the matrix\n for (i = 1; i <= b.length; i++) {\n for (j = 1; j <= a.length; j++) {\n if (b.charAt(i - 1) === a.charAt(j - 1)) {\n matrix[i][j] = matrix[i - 1][j - 1];\n } else {\n matrix[i][j] = Math.min(\n matrix[i - 1][j - 1] + 1, // substitution\n Math.min(\n matrix[i][j - 1] + 1, // insertion\n matrix[i - 1][j] + 1\n )\n ); // deletion\n }\n }\n }\n\n //console.debug( '\\t\\t levenshteinDistance', a, b, matrix[b.length][a.length] );\n return matrix[b.length][a.length];\n }\n\n //=============================================================================\n return levenshteinDistance;\n});\n"]}
{"version":3,"sources":["utils/levenshtein.js"],"names":["a","b","length","i","matrix","j","charAt","Math","min"],"mappings":"uGAoBA,SAA6BA,EAAGC,GAC5B,GAAiB,IAAbD,EAAEE,OACF,OAAOD,EAAEC,OAJjB,GAAA,IAAAD,EAAAC,OACA,OAAAF,EAAAE,OAGQ,IAGAC,EAHAC,KAIH,IAAAD,EAAA,EAAAA,GAAAF,EAAAC,OAAAC,IAOGC,EAAOD,IAAMA,GAFjB,IAAAE,EACA,IAAAA,EAAKF,EAAAA,GAAOA,EAAAA,OAAOD,IACfE,EAAAA,GAAAA,GAAAC,EAIJ,IAAAF,EAAA,EAAAA,GAAAF,EAAAC,OAAAC,IACA,IAAKE,EAAI,EAAGA,GAAKL,EAAEE,OAAQG,IACvBD,EAAAA,OAAAD,EAAA,KAAAH,EAAAM,OAAAD,EAAA,GACHD,EAAAD,GAAAE,GAAAD,EAAAD,EAAA,GAAAE,EAAA,GAEDD,EAAAD,GAAAE,GAAAE,KAAAC,IACYL,EAAOD,EAAAA,GAAnBG,EAAA,GAAgC,EACvBA,KAAOA,IACFC,EAAOH,GAATE,EAAA,GAAsBC,EACtBF,EAAAD,EAAeC,GAAAA,GAAOD,IAclC,OAAOC,EAAOH,EAAEC,QAAQF,EAAEE","file":"../../scripts/utils/levenshtein.js","sourcesContent":["//=============================================================================\n/**\n(Imported for edit distance algorith. From: https://gist.github.com/andrei-m/982927)\nCopyright (c) 2011 Andrei Mackenzie\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated\ndocumentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the\nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit\npersons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the\nSoftware.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\nWARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n// Compute the edit distance between the two given strings\n//exports.getEditDistance = function(a, b){\nfunction levenshteinDistance(a, b) {\n if (a.length === 0) {\n return b.length;\n }\n if (b.length === 0) {\n return a.length;\n }\n\n var matrix = [];\n\n // increment along the first column of each row\n var i;\n for (i = 0; i <= b.length; i++) {\n matrix[i] = [i];\n }\n\n // increment each column in the first row\n var j;\n for (j = 0; j <= a.length; j++) {\n matrix[0][j] = j;\n }\n\n // Fill in the rest of the matrix\n for (i = 1; i <= b.length; i++) {\n for (j = 1; j <= a.length; j++) {\n if (b.charAt(i - 1) === a.charAt(j - 1)) {\n matrix[i][j] = matrix[i - 1][j - 1];\n } else {\n matrix[i][j] = Math.min(\n matrix[i - 1][j - 1] + 1, // substitution\n Math.min(\n matrix[i][j - 1] + 1, // insertion\n matrix[i - 1][j] + 1\n )\n ); // deletion\n }\n }\n }\n\n //console.debug( '\\t\\t levenshteinDistance', a, b, matrix[b.length][a.length] );\n return matrix[b.length][a.length];\n}\n\n//=============================================================================\nexport default levenshteinDistance;\n"]}
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["utils/natural-sort.js"],"names":["define","a","b","re","x","naturalSort","y","toString","toLowerCase","nC","fromCharCode","xN","split","yN","xD","String","yD","replace","getTime","oFxNcL","oFyNcL","cLoc","numS","Math","max","length","parseFloat"],"mappings":"kCAAAA,UAAW,WAuCV,OArCG,SAAqBC,EAAGC,GADxB,IAAAC,EAAA,gBACAC,EAAAH,EAASI,WAAYJ,eAAM,GACvBK,EAAAJ,EAAAK,WAAAC,eAAA,GACAC,EAAIN,OAAKO,aAAT,GAAAC,EACIP,EAAAA,QAAMG,EAAFE,EAAaD,KAAAA,GAAbI,MADRH,GAAAI,EAEIP,EAAAA,QAAMC,EAAFE,EAAaD,KAAAA,GAAbI,MAFRH,GAAAK,EAGIL,IAAKM,KAAAA,GAAOL,UAHhBM,EAIIL,EAAKP,IAAEa,KAAQd,GAAVe,UAAc,KAJvB,GAAAF,EAMIF,CANJ,GAOIE,EAAKF,EACT,OAAA,EACA,GAAQA,EAAAE,EACJ,OAAIF,EAKP,IACD,IAFKK,EAAAC,EAELC,EAAA,EAAAC,EAAAC,KAAAC,IAAAb,EAAAc,OAAAZ,EAAAY,QACAJ,EAAIF,EACJE,IAKIF,CAGI,GAFJC,EAAAA,WAASM,EAAAA,KAAAf,EAAAU,GACTD,EAAID,WAASC,EAAbC,KAAqBR,EAAAQ,GACjBF,EAAAC,EACH,OAAM,EACH,GAAAD,EAAAC,EACH,OAAA,EAGR,OAAA","file":"../../scripts/utils/natural-sort.js","sourcesContent":["define([], function() {\n // Alphanumeric/natural sort fn\n function naturalSort(a, b) {\n // setup temp-scope variables for comparison evauluation\n var re = /(-?[0-9\\.]+)/g,\n x = a.toString().toLowerCase() || \"\",\n y = b.toString().toLowerCase() || \"\",\n nC = String.fromCharCode(0),\n xN = x.replace(re, nC + \"$1\" + nC).split(nC),\n yN = y.replace(re, nC + \"$1\" + nC).split(nC),\n xD = new Date(x).getTime(),\n yD = xD ? new Date(y).getTime() : null;\n // natural sorting of dates\n if (yD) {\n if (xD < yD) {\n return -1;\n } else if (xD > yD) {\n return 1;\n }\n }\n // natural sorting through split numeric strings and default strings\n var oFxNcL, oFyNcL;\n for (\n var cLoc = 0, numS = Math.max(xN.length, yN.length);\n cLoc < numS;\n cLoc++\n ) {\n oFxNcL = parseFloat(xN[cLoc]) || xN[cLoc];\n oFyNcL = parseFloat(yN[cLoc]) || yN[cLoc];\n if (oFxNcL < oFyNcL) {\n return -1;\n } else if (oFxNcL > oFyNcL) {\n return 1;\n }\n }\n return 0;\n }\n\n return naturalSort;\n});\n"]}
{"version":3,"sources":["utils/natural-sort.js"],"names":["a","b","re","x","toString","toLowerCase","y","nC","String","fromCharCode","xN","naturalSort","split","yN","replace","xD","Date","getTime","yD","oFxNcL","oFyNcL","cLoc","numS","Math","max","length","parseFloat"],"mappings":"uGACA,SAAqBA,EAAGC,GAEpB,IAAIC,EAAK,gBACLC,EAAIH,EAAEI,WAAWC,eAAiB,GAClCC,EAAIL,EAAEG,WAAWC,eAAiB,GAL1CE,EAAAC,OAAAC,aAAA,GACAC,EAASC,EAAAA,QAAAA,EAATJ,EAA2B,KAAAA,GAAAK,MAAAL,GACvBM,EAAAP,EAAAQ,QAAAZ,EAAAK,EAAA,KAAAA,GAAAK,MAAAL,GACAQ,EAAIb,IAAKc,KAAAb,GAAAc,UAATC,EACIf,EAAMC,IAAAA,KAAFE,GAAaD,UAAb,KADR,GAAAa,EAGIX,CAHJ,GAIIG,EAAKP,EACLU,OAAOC,EACPC,GAAKA,EAAIC,EACTE,OAAKH,EAKJ,IACG,IAFAI,EAAAC,EAEAC,EAAA,EAAAC,EAAAC,KAAAC,IAAAd,EAAAe,OAAAZ,EAAAY,QACHJ,EAAAC,EACJD,IACD,CAOIF,GANJA,EAAIA,WAAJT,EAAAW,KAAAX,EAAAW,GACAD,EACQC,WAAUC,EAAAA,KAAYE,EAAId,GAI9BS,EAASO,EACTN,OAAAA,EACA,GAAID,EAASC,EACT,OAAA,EAGH,OAAA","file":"../../scripts/utils/natural-sort.js","sourcesContent":["// Alphanumeric/natural sort fn\nfunction naturalSort(a, b) {\n // setup temp-scope variables for comparison evauluation\n var re = /(-?[0-9\\.]+)/g,\n x = a.toString().toLowerCase() || \"\",\n y = b.toString().toLowerCase() || \"\",\n nC = String.fromCharCode(0),\n xN = x.replace(re, nC + \"$1\" + nC).split(nC),\n yN = y.replace(re, nC + \"$1\" + nC).split(nC),\n xD = new Date(x).getTime(),\n yD = xD ? new Date(y).getTime() : null;\n // natural sorting of dates\n if (yD) {\n if (xD < yD) {\n return -1;\n } else if (xD > yD) {\n return 1;\n }\n }\n // natural sorting through split numeric strings and default strings\n var oFxNcL, oFyNcL;\n for (\n var cLoc = 0, numS = Math.max(xN.length, yN.length);\n cLoc < numS;\n cLoc++\n ) {\n oFxNcL = parseFloat(xN[cLoc]) || xN[cLoc];\n oFyNcL = parseFloat(yN[cLoc]) || yN[cLoc];\n if (oFxNcL < oFyNcL) {\n return -1;\n } else if (oFxNcL > oFyNcL) {\n return 1;\n }\n }\n return 0;\n}\n\nexport default naturalSort;\n"]}
@@ -1 +1 @@
{"version":3,"sources":["utils/query-string-parsing.js"],"names":["define","get","key","queryString","window","location","search","substr","keyRegex","RegExp","matches","length","decodeURIComponent","match","replace","parsed","split","forEach","pairString","pair"],"mappings":"kCAAAA,UAAW,WAiCP,OACAC,IAhCA,SAAaC,EAAKC,GAFtBH,EAAWG,GAAWC,OAAAC,SAAAC,OAAAC,OAAA,GAClB,IAAAC,EAAA,IAAAC,OAAAP,EAAA,aAAA,KACAQ,EAAaR,EAAKC,MAAaK,GAC3BL,GAAAA,GAAAA,EAAcA,OAUb,OAJD,KAHAO,EAAKA,EAAAA,IAADA,EAAaA,SAAQC,GACrB,OAAAC,mBACHC,EAAAN,OAAAL,EAAAS,OAAA,GAAAG,QAAA,MAAA,SACDH,OAKID,EAAQC,GAEXD,GAmBDT,MAfJ,SAAeE,GAAf,IAAAA,EACI,SAEC,IAAAY,KAMA,OALGA,EAAJC,MAAA,KAAAC,QACID,SAAQb,GACZa,IAAAA,EAAMC,EAAQD,MAASE,KACnBH,EAAAI,EAAIA,IAAOD,UAAWF,EAAM,MADhCD","file":"../../scripts/utils/query-string-parsing.js","sourcesContent":["define([], function() {\n // ============================================================================\n function get(key, queryString) {\n queryString = queryString || window.location.search.substr(1);\n var keyRegex = new RegExp(key + \"=([^&#$]+)\", \"g\");\n var matches = queryString.match(keyRegex);\n if (!matches || !matches.length) {\n return undefined;\n }\n matches = _.map(matches, function(match) {\n return decodeURIComponent(\n match.substr(key.length + 1).replace(/\\+/g, \" \")\n );\n });\n if (matches.length === 1) {\n return matches[0];\n }\n return matches;\n }\n\n function parse(queryString) {\n if (!queryString) {\n return {};\n }\n var parsed = {},\n split = queryString.split(\"&\");\n split.forEach(function(pairString) {\n var pair = pairString.split(\"=\");\n parsed[pair[0]] = decodeURI(pair[1]);\n });\n return parsed;\n }\n\n // ============================================================================\n return {\n get: get,\n parse: parse\n };\n});\n"]}
{"version":3,"sources":["utils/query-string-parsing.js"],"names":["get","key","queryString","window","location","search","substr","keyRegex","RegExp","matches","match","length","parse","parsed","split","forEach","pairString","pair","decodeURI"],"mappings":"wGA8BCA,IA7BD,SAAaC,EAAKC,GACdA,EAAcA,GAAeC,OAAOC,SAASC,OAAOC,OAAO,GAC3D,IAAIC,EAAW,IAAIC,OAAOP,EAAM,aAAc,KAC1CQ,EAAUP,EAAYQ,MAAMH,GAChC,GAAKE,GAAYA,EAAQE,OAExB,OAAA,KALDT,EAAAA,EAAAA,IAAAA,EAAcA,SAAeC,GAC7B,OAAII,mBACAE,EAAAA,OAAUP,EAAAA,OAAYQ,GAAMH,QAAhC,MAAA,SAGCI,OACDF,EAAU,GAAVA,GA2BAG,MApBC,SAAAV,GACD,IAAAA,EACH,SAED,IAAAW,KAMIC,OALKZ,EAAaY,MAAA,KACdC,QAAA,SAAAC,GACH,IAAAC,EAAAD,EAAAF,MAAA,KACDD,EAAIA,EAAAA,IAAJK,UAAAD,EAAA,MAEAH","file":"../../scripts/utils/query-string-parsing.js","sourcesContent":["// ============================================================================\nfunction get(key, queryString) {\n queryString = queryString || window.location.search.substr(1);\n var keyRegex = new RegExp(key + \"=([^&#$]+)\", \"g\");\n var matches = queryString.match(keyRegex);\n if (!matches || !matches.length) {\n return undefined;\n }\n matches = _.map(matches, function(match) {\n return decodeURIComponent(\n match.substr(key.length + 1).replace(/\\+/g, \" \")\n );\n });\n if (matches.length === 1) {\n return matches[0];\n }\n return matches;\n}\n\nfunction parse(queryString) {\n if (!queryString) {\n return {};\n }\n var parsed = {},\n split = queryString.split(\"&\");\n split.forEach(function(pairString) {\n var pair = pairString.split(\"=\");\n parsed[pair[0]] = decodeURI(pair[1]);\n });\n return parsed;\n}\n\n// ============================================================================\nexport default {\n get: get,\n parse: parse\n};\n"]}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,2 +1,2 @@
define([],function(){"use strict";define([],function(){var e=["log","debug","info","warn","error","metric"];return function(o,t){var i=void 0!==o.prototype?o.prototype:o;return void 0!==t&&(i._logNamespace=t),e.forEach(function(e){i[e]=function(){if(this.logger)return this.logger.emit?this.logger.emit(e,this._logNamespace,arguments):this.logger[e]?this.logger[e].apply(this.logger,arguments):void 0}}),o}})});
define(["exports"],function(e){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=["log","debug","info","warn","error","metric"];e.default=function(e,t){var r=void 0!==e.prototype?e.prototype:e;return void 0!==t&&(r._logNamespace=t),o.forEach(function(e){r[e]=function(){if(this.logger)return this.logger.emit?this.logger.emit(e,this._logNamespace,arguments):this.logger[e]?this.logger[e].apply(this.logger,arguments):void 0}}),e}});
//# sourceMappingURL=../../maps/utils/add-logging.js.map
+1 -1
View File
@@ -1,2 +1,2 @@
define([],function(){"use strict";define([],function(){function e(e){var t=this;return t.deferred=jQuery.Deferred(),t.queue=[],t.responses=[],t.numToProcess=0,t.running=!1,t.init(e||[]),t.start(),t}function t(t){var r=this;return r.names={},e.call(this,t),r}return e.prototype.init=function(e){var t=this;e.forEach(function(e){t.add(e)})},e.prototype.add=function(e){var t=this,r=this.queue.length;return this.numToProcess+=1,this.queue.push(function(){var n=r,o=e();o.done(function(e){t.deferred.notify({curr:n,total:t.numToProcess,response:e})}),o.always(function(e){t.responses.push(e),t.queue.length?t.queue.shift()():t.stop()})}),this},e.prototype.start=function(){return this.queue.length&&(this.running=!0,this.queue.shift()()),this},e.prototype.stop=function(e,t){return this.running=!1,this.queue=[],e?this.deferred.reject(t):this.deferred.resolve(this.responses),this.numToProcess=0,this.deferred=jQuery.Deferred(),this},e.prototype.done=function(e){return this.deferred.done(e)},e.prototype.fail=function(e){return this.deferred.fail(e)},e.prototype.always=function(e){return this.deferred.always(e)},e.prototype.progress=function(e){return this.deferred.progress(e)},e.create=function(t){return new e(t).deferred},t.prototype=new e,t.prototype.constructor=t,t.prototype.add=function(t){if(!t.hasOwnProperty("name")||!t.hasOwnProperty("fn"))throw new Error('NamedAjaxQueue.add requires an object with both "name" and "fn": '+JSON.stringify(t));if(!this.names.hasOwnProperty(t.name))return this.names[t.name]=!0,e.prototype.add.call(this,t.fn)},t.prototype.clear=function(){return this.names={},this},t.create=function(e){return new t(e).deferred},{AjaxQueue:e,NamedAjaxQueue:t}})});
define(["exports"],function(e){"use strict";function t(e){var t=this;return t.deferred=jQuery.Deferred(),t.queue=[],t.responses=[],t.numToProcess=0,t.running=!1,t.init(e||[]),t.start(),t}function r(e){var r=this;return r.names={},t.call(this,e),r}Object.defineProperty(e,"__esModule",{value:!0}),t.prototype.init=function(e){var t=this;e.forEach(function(e){t.add(e)})},t.prototype.add=function(e){var t=this,r=this.queue.length;return this.numToProcess+=1,this.queue.push(function(){var n=r,s=e();s.done(function(e){t.deferred.notify({curr:n,total:t.numToProcess,response:e})}),s.always(function(e){t.responses.push(e),t.queue.length?t.queue.shift()():t.stop()})}),this},t.prototype.start=function(){return this.queue.length&&(this.running=!0,this.queue.shift()()),this},t.prototype.stop=function(e,t){return this.running=!1,this.queue=[],e?this.deferred.reject(t):this.deferred.resolve(this.responses),this.numToProcess=0,this.deferred=jQuery.Deferred(),this},t.prototype.done=function(e){return this.deferred.done(e)},t.prototype.fail=function(e){return this.deferred.fail(e)},t.prototype.always=function(e){return this.deferred.always(e)},t.prototype.progress=function(e){return this.deferred.progress(e)},t.create=function(e){return new t(e).deferred},(r.prototype=new t).constructor=r,r.prototype.add=function(e){if(!e.hasOwnProperty("name")||!e.hasOwnProperty("fn"))throw new Error('NamedAjaxQueue.add requires an object with both "name" and "fn": '+JSON.stringify(e));if(!this.names.hasOwnProperty(e.name))return this.names[e.name]=!0,t.prototype.add.call(this,e.fn)},r.prototype.clear=function(){return this.names={},this},r.create=function(e){return new r(e).deferred},e.default={AjaxQueue:t,NamedAjaxQueue:r}});
//# sourceMappingURL=../../maps/utils/ajax-queue.js.map
+1 -1
View File
@@ -1,2 +1,2 @@
define([],function(){"use strict";define(["jquery"],function(t){"use_strict";var e=t;return function(t,i,r,n,a,u,o,c,s){void 0===a&&(a=30),void 0===o&&(o=4),e("#"+t).click(function(){if(!(e("#renaming-active").length>0)){var t,f=e("#"+i),l=f.text();(t=u?e("<textarea></textarea>").attr({rows:o,cols:a}).text(e.trim(l)):e("<input type='text'></input>").attr({value:e.trim(l),size:a})).attr("id","renaming-active"),t.blur(function(){e(this).remove(),f.show(),s&&s(t)}),t.keyup(function(a){if(27===a.keyCode)e(this).trigger("blur");else if(13===a.keyCode){var u={};u[n]=e(this).val(),e(this).trigger("blur"),e.ajax({url:r,data:u,error:function(){alert("Text editing for elt "+i+" failed")},success:function(e){""!==e?f.text(e):f.html("<em>None</em>"),s&&s(t)}})}}),c&&c(t),f.hide(),t.insertAfter(f),t.focus(),t.select()}})}})});
define(["exports","jquery"],function(e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=function(e){return e&&e.__esModule?e:{default:e}}(t).default;e.default=function(e,t,r,n,u,a,o,l,f){void 0===u&&(u=30),void 0===o&&(o=4),i("#"+e).click(function(){if(!(i("#renaming-active").length>0)){var e,s=i("#"+t),c=s.text();(e=a?i("<textarea></textarea>").attr({rows:o,cols:u}).text(i.trim(c)):i("<input type='text'></input>").attr({value:i.trim(c),size:u})).attr("id","renaming-active"),e.blur(function(){i(this).remove(),s.show(),f&&f(e)}),e.keyup(function(u){if(27===u.keyCode)i(this).trigger("blur");else if(13===u.keyCode){var a={};a[n]=i(this).val(),i(this).trigger("blur"),i.ajax({url:r,data:a,error:function(){alert("Text editing for elt "+t+" failed")},success:function(t){""!==t?s.text(t):s.html("<em>None</em>"),f&&f(e)}})}}),l&&l(e),s.hide(),e.insertAfter(s),e.focus(),e.select()}})}});
//# sourceMappingURL=../../maps/utils/async-save-text.js.map
+1 -1
View File
@@ -1,2 +1,2 @@
define([],function(){"use strict";define(["libs/underscore","viz/trackster/util","utils/config"],function(e,t,l){var o=Backbone.Model.extend({initialize:function(l){var o=this.get("key");this.set("id",o);var i=e.find([{key:"name",label:"Name",type:"text",default_value:""},{key:"color",label:"Color",type:"color",default_value:null},{key:"min_value",label:"Min Value",type:"float",default_value:null},{key:"max_value",label:"Max Value",type:"float",default_value:null},{key:"mode",type:"string",default_value:this.mode,hidden:!0},{key:"height",type:"int",default_value:32,hidden:!0},{key:"pos_color",label:"Positive Color",type:"color",default_value:"#FF8C00"},{key:"neg_color",label:"Negative Color",type:"color",default_value:"#4169E1"},{key:"block_color",label:"Block color",type:"color",default_value:null},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:!1},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:!0},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:null},{key:"show_differences",label:"Show differences only",type:"bool",default_value:!0}],function(e){return e.key===o});i&&this.set(e.extend({},i,l)),void 0===this.get("value")&&void 0!==this.get("default_value")&&(this.set_value(this.get("default_value")),this.get("value")||"color"!==this.get("type")||this.set("value",t.get_random_color()))},set_value:function(e,t){var l=this.get("type");"float"===l?e=parseFloat(e):"int"===l&&(e=parseInt(e,10)),this.set({value:e},t)}}),i=Backbone.Collection.extend({model:o,to_key_value_dict:function(){var e={};return this.each(function(t){e[t.get("key")]=t.get("value")}),e},get_value:function(e){var t=this.get(e);if(t)return t.get("value")},set_value:function(e,t,l){var o=this.get(e);if(o)return o.set_value(t,l)},set_default_value:function(e,t){var l=this.get(e);if(l)return l.set("default_value",t)}},{from_models_and_saved_values:function(t,l){return l&&(t=e.map(t,function(t){return e.extend({},t,{value:l[t.key]})})),new i(t)}}),a=Backbone.View.extend({className:"config-settings-view",render:function(){var l=this.$el;return this.collection.each(function(o,i){if(!o.get("hidden")){var a="param_"+i,n=o.get("type"),r=o.get("value"),s=$("<div class='form-row' />").appendTo(l);if(s.append($("<label />").attr("for",a).text(o.get("label")+":")),"bool"===n)s.append($('<input type="checkbox" />').attr("id",a).attr("name",a).attr("checked",r));else if("text"===n)s.append($('<input type="text"/>').attr("id",a).val(r).click(function(){$(this).select()}));else if("select"===n){var c=$("<select />").attr("id",a);e.each(o.get("options"),function(e){$("<option/>").text(e.label).attr("value",e.value).appendTo(c)}),c.val(r),s.append(c)}else if("color"===n){var u=$("<div/>").appendTo(s),d=$("<input />").attr("id",a).attr("name",a).val(r).css("float","left").appendTo(u).click(function(e){$(".tooltip").removeClass("in");var t=$(this).siblings(".tooltip").addClass("in");t.css({left:$(this).position().left+$(this).width()+5,top:$(this).position().top-$(t).height()/2+$(this).height()/2}).show(),t.click(function(e){e.stopPropagation()}),$(document).bind("click.color-picker",function(){t.hide(),$(document).unbind("click.color-picker")}),e.stopPropagation()}),p=$("<a href='javascript:void(0)'/>").addClass("icon-button arrow-circle").appendTo(u).attr("title","Set new random color").tooltip(),f=$("<div class='tooltip right' style='position: absolute;' />").appendTo(u).hide(),h=$("<div class='tooltip-inner' style='text-align: inherit'></div>").appendTo(f),v=($("<div class='tooltip-arrow'></div>").appendTo(f),$.farbtastic(h,{width:100,height:100,callback:d,color:r}));u.append($("<div/>").css("clear","both")),function(e){p.click(function(){e.setColor(t.get_random_color())})}(v)}else s.append($("<input />").attr("id",a).attr("name",a).val(r));o.help&&s.append($("<div class='help'/>").text(o.help))}}),this},render_in_modal:function(e){var t=this,l=function(){Galaxy.modal.hide(),$(window).unbind("keypress.check_enter_esc")},o=function(){Galaxy.modal.hide(),$(window).unbind("keypress.check_enter_esc"),t.update_from_form()};$(window).bind("keypress.check_enter_esc",function(e){27===(e.keyCode||e.which)?l():13===(e.keyCode||e.which)&&o()}),0===this.$el.children().length&&this.render(),Galaxy.modal.show({title:e||"Configure",body:this.$el,buttons:{Cancel:l,OK:o}})},update_from_form:function(){var e=this;this.collection.each(function(t,l){if(!t.get("hidden")){var o="param_"+l,i=e.$el.find("#"+o).val();"bool"===t.get("type")&&(i=e.$el.find("#"+o).is(":checked")),t.set_value(i)}})}});return{ConfigSetting:o,ConfigSettingCollection:i,ConfigSettingCollectionView:a}})});
define(["exports","libs/underscore","viz/trackster/util","utils/config"],function(e,t,l,o){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(e,"__esModule",{value:!0});var i=a(t),n=a(l),r=(a(o),Backbone.Model.extend({initialize:function(e){var t=this.get("key");this.set("id",t);var l=i.default.find([{key:"name",label:"Name",type:"text",default_value:""},{key:"color",label:"Color",type:"color",default_value:null},{key:"min_value",label:"Min Value",type:"float",default_value:null},{key:"max_value",label:"Max Value",type:"float",default_value:null},{key:"mode",type:"string",default_value:this.mode,hidden:!0},{key:"height",type:"int",default_value:32,hidden:!0},{key:"pos_color",label:"Positive Color",type:"color",default_value:"#FF8C00"},{key:"neg_color",label:"Negative Color",type:"color",default_value:"#4169E1"},{key:"block_color",label:"Block color",type:"color",default_value:null},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:!1},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:!0},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:null},{key:"show_differences",label:"Show differences only",type:"bool",default_value:!0}],function(e){return e.key===t});l&&this.set(i.default.extend({},l,e)),void 0===this.get("value")&&void 0!==this.get("default_value")&&(this.set_value(this.get("default_value")),this.get("value")||"color"!==this.get("type")||this.set("value",n.default.get_random_color()))},set_value:function(e,t){var l=this.get("type");"float"===l?e=parseFloat(e):"int"===l&&(e=parseInt(e,10)),this.set({value:e},t)}})),s=Backbone.Collection.extend({model:r,to_key_value_dict:function(){var e={};return this.each(function(t){e[t.get("key")]=t.get("value")}),e},get_value:function(e){var t=this.get(e);if(t)return t.get("value")},set_value:function(e,t,l){var o=this.get(e);if(o)return o.set_value(t,l)},set_default_value:function(e,t){var l=this.get(e);if(l)return l.set("default_value",t)}},{from_models_and_saved_values:function(e,t){return t&&(e=i.default.map(e,function(e){return i.default.extend({},e,{value:t[e.key]})})),new s(e)}}),c=Backbone.View.extend({className:"config-settings-view",render:function(){var e=this.$el;return this.collection.each(function(t,l){if(!t.get("hidden")){var o="param_"+l,a=t.get("type"),r=t.get("value"),s=$("<div class='form-row' />").appendTo(e);if(s.append($("<label />").attr("for",o).text(t.get("label")+":")),"bool"===a)s.append($('<input type="checkbox" />').attr("id",o).attr("name",o).attr("checked",r));else if("text"===a)s.append($('<input type="text"/>').attr("id",o).val(r).click(function(){$(this).select()}));else if("select"===a){var c=$("<select />").attr("id",o);i.default.each(t.get("options"),function(e){$("<option/>").text(e.label).attr("value",e.value).appendTo(c)}),c.val(r),s.append(c)}else if("color"===a){var u=$("<div/>").appendTo(s),d=$("<input />").attr("id",o).attr("name",o).val(r).css("float","left").appendTo(u).click(function(e){$(".tooltip").removeClass("in");var t=$(this).siblings(".tooltip").addClass("in");t.css({left:$(this).position().left+$(this).width()+5,top:$(this).position().top-$(t).height()/2+$(this).height()/2}).show(),t.click(function(e){e.stopPropagation()}),$(document).bind("click.color-picker",function(){t.hide(),$(document).unbind("click.color-picker")}),e.stopPropagation()}),f=$("<a href='javascript:void(0)'/>").addClass("icon-button arrow-circle").appendTo(u).attr("title","Set new random color").tooltip(),p=$("<div class='tooltip right' style='position: absolute;' />").appendTo(u).hide(),h=$("<div class='tooltip-inner' style='text-align: inherit'></div>").appendTo(p),v=($("<div class='tooltip-arrow'></div>").appendTo(p),$.farbtastic(h,{width:100,height:100,callback:d,color:r}));u.append($("<div/>").css("clear","both")),function(e){f.click(function(){e.setColor(n.default.get_random_color())})}(v)}else s.append($("<input />").attr("id",o).attr("name",o).val(r));t.help&&s.append($("<div class='help'/>").text(t.help))}}),this},render_in_modal:function(e){var t=this,l=function(){Galaxy.modal.hide(),$(window).unbind("keypress.check_enter_esc")},o=function(){Galaxy.modal.hide(),$(window).unbind("keypress.check_enter_esc"),t.update_from_form()};$(window).bind("keypress.check_enter_esc",function(e){27===(e.keyCode||e.which)?l():13===(e.keyCode||e.which)&&o()}),0===this.$el.children().length&&this.render(),Galaxy.modal.show({title:e||"Configure",body:this.$el,buttons:{Cancel:l,OK:o}})},update_from_form:function(){var e=this;this.collection.each(function(t,l){if(!t.get("hidden")){var o="param_"+l,a=e.$el.find("#"+o).val();"bool"===t.get("type")&&(a=e.$el.find("#"+o).is(":checked")),t.set_value(a)}})}});e.default={ConfigSetting:r,ConfigSettingCollection:s,ConfigSettingCollectionView:c}});
//# sourceMappingURL=../../maps/utils/config.js.map
+1 -1
View File
@@ -1,2 +1,2 @@
define([],function(){"use strict";define(["utils/utils"],function(e){return Backbone.Model.extend({initialize:function(){this.active={},this.last=null},execute:function(t){var i=this,a=e.uid(),n=t.length>0;this.active[a]=!0;var s=$.Deferred();s.promise().always(function(){delete i.active[a],n&&Galaxy.emit.debug("deferred::execute()",this.state().charAt(0).toUpperCase()+this.state().slice(1)+" "+a)}),$.when(this.last).always(function(){i.active[a]?(n&&Galaxy.emit.debug("deferred::execute()","Running "+a),t(s),!n&&s.resolve()):s.reject()}),this.last=s.promise()},reset:function(){Galaxy.emit.debug("deferred::execute()","Reset");for(var e in this.active)this.active[e]=!1},ready:function(){return $.isEmptyObject(this.active)}})})});
define(["exports","utils/utils"],function(e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=function(e){return e&&e.__esModule?e:{default:e}}(t);e.default=Backbone.Model.extend({initialize:function(){this.active={},this.last=null},execute:function(e){var t=this,a=i.default.uid(),s=e.length>0;this.active[a]=!0;var n=$.Deferred();n.promise().always(function(){delete t.active[a],s&&Galaxy.emit.debug("deferred::execute()",this.state().charAt(0).toUpperCase()+this.state().slice(1)+" "+a)}),$.when(this.last).always(function(){t.active[a]?(s&&Galaxy.emit.debug("deferred::execute()","Running "+a),e(n),!s&&n.resolve()):n.reject()}),this.last=n.promise()},reset:function(){Galaxy.emit.debug("deferred::execute()","Reset");for(var e in this.active)this.active[e]=!1},ready:function(){return $.isEmptyObject(this.active)}})});
//# sourceMappingURL=../../maps/utils/deferred.js.map
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,2 +1,2 @@
define([],function(){"use strict";define([],function(){return function(n,t){if(0===n.length)return t.length;if(0===t.length)return n.length;var e,r=[];for(e=0;e<=t.length;e++)r[e]=[e];var h;for(h=0;h<=n.length;h++)r[0][h]=h;for(e=1;e<=t.length;e++)for(h=1;h<=n.length;h++)t.charAt(e-1)===n.charAt(h-1)?r[e][h]=r[e-1][h-1]:r[e][h]=Math.min(r[e-1][h-1]+1,Math.min(r[e][h-1]+1,r[e-1][h]+1));return r[t.length][n.length]}})});
define(["exports"],function(e){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e,t){if(0===e.length)return t.length;if(0===t.length)return e.length;var n,r=[];for(n=0;n<=t.length;n++)r[n]=[n];var h;for(h=0;h<=e.length;h++)r[0][h]=h;for(n=1;n<=t.length;n++)for(h=1;h<=e.length;h++)t.charAt(n-1)===e.charAt(h-1)?r[n][h]=r[n-1][h-1]:r[n][h]=Math.min(r[n-1][h-1]+1,Math.min(r[n][h-1]+1,r[n-1][h]+1));return r[t.length][e.length]}});
//# sourceMappingURL=../../maps/utils/levenshtein.js.map
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,2 +1,2 @@
define([],function(){"use strict";define([],function(){return function(e,t){var r=/(-?[0-9\.]+)/g,n=e.toString().toLowerCase()||"",i=t.toString().toLowerCase()||"",a=String.fromCharCode(0),o=n.replace(r,a+"$1"+a).split(a),f=i.replace(r,a+"$1"+a).split(a),u=new Date(n).getTime(),l=u?new Date(i).getTime():null;if(l){if(u<l)return-1;if(u>l)return 1}for(var g,s,c=0,p=Math.max(o.length,f.length);c<p;c++){if(g=parseFloat(o[c])||o[c],s=parseFloat(f[c])||f[c],g<s)return-1;if(g>s)return 1}return 0}})});
define(["exports"],function(e){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e,t){var r=/(-?[0-9\.]+)/g,n=e.toString().toLowerCase()||"",a=t.toString().toLowerCase()||"",i=String.fromCharCode(0),o=n.replace(r,i+"$1"+i).split(i),l=a.replace(r,i+"$1"+i).split(i),f=new Date(n).getTime(),u=f?new Date(a).getTime():null;if(u){if(f<u)return-1;if(f>u)return 1}for(var s,g,p=0,c=Math.max(o.length,l.length);p<c;p++){if(s=parseFloat(o[p])||o[p],g=parseFloat(l[p])||l[p],s<g)return-1;if(s>g)return 1}return 0}});
//# sourceMappingURL=../../maps/utils/natural-sort.js.map
+1 -1
View File
@@ -1,2 +1,2 @@
define([],function(){"use strict";define([],function(){return{get:function(n,e){e=e||window.location.search.substr(1);var t=new RegExp(n+"=([^&#$]+)","g"),r=e.match(t);if(r&&r.length)return 1===(r=_.map(r,function(e){return decodeURIComponent(e.substr(n.length+1).replace(/\+/g," "))})).length?r[0]:r},parse:function(n){if(!n)return{};var e={};return n.split("&").forEach(function(n){var t=n.split("=");e[t[0]]=decodeURI(t[1])}),e}}})});
define(["exports"],function(e){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={get:function(e,t){t=t||window.location.search.substr(1);var n=new RegExp(e+"=([^&#$]+)","g"),r=t.match(n);if(r&&r.length)return 1===(r=_.map(r,function(t){return decodeURIComponent(t.substr(e.length+1).replace(/\+/g," "))})).length?r[0]:r},parse:function(e){if(!e)return{};var t={};return e.split("&").forEach(function(e){var n=e.split("=");t[n[0]]=decodeURI(n[1])}),t}}});
//# sourceMappingURL=../../maps/utils/query-string-parsing.js.map
View File
+1 -1
View File
@@ -1,2 +1,2 @@
define([],function(){"use strict";define(["utils/localization"],function(t){function e(t,n){for(var r in t){var i=t[r];if(_.isObject(i)){var a=n(i);a&&(t[r]=a),e(i,n)}}}function n(t){var e={contentType:"application/json",type:t.type||"GET",data:t.data||{},url:t.url};"GET"==e.type||"DELETE"==e.type?($.isEmptyObject(e.data)||(e.url+=-1==e.url.indexOf("?")?"?":"&",e.url+=$.param(e.data,!0)),e.data=null):(e.dataType="json",e.url=e.url,e.data=JSON.stringify(e.data)),$.ajax(e).done(function(e){if("string"==typeof e)try{e=e.replace("Infinity,",'"Infinity",'),e=jQuery.parseJSON(e)}catch(t){console.debug(t)}t.success&&t.success(e)}).fail(function(e){var n=null;try{n=jQuery.parseJSON(e.responseText)}catch(t){n=e.responseText}t.error&&t.error(n,e.status)}).always(function(){t.complete&&t.complete()})}function r(t,e){for(var n=1,r=0;r<e;r++)n*=10;return Math.round(t*n)/n}var i=1024,a=i*i,s=a*i,o=s*i;return{cssLoadFile:function(t){$('link[href^="'+t+'"]').length||$('<link href="'+Galaxy.root+t+'" rel="stylesheet">').appendTo("head")},cssGetAttribute:function(t,e){var n=$('<div class="'+t+'"></div>');n.appendTo(":eq(0)");var r=n.css(e);return n.remove(),r},get:function(t){top.__utils__get__=top.__utils__get__||{};var e=JSON.stringify(t);t.cache&&top.__utils__get__[e]?(t.success&&t.success(top.__utils__get__[e]),window.console.debug("utils.js::get() - Fetching from cache ["+t.url+"].")):n({url:t.url,data:t.data,success:function(n){top.__utils__get__[e]=n,t.success&&t.success(n)},error:function(e,n){t.error&&t.error(e,n)}})},merge:function(t,e){return t?_.defaults(t,e):e},iframe:function(t){return'<iframe src="'+t+'" frameborder="0" style="width: 100%; height: 100%;"/>'},bytesToString:function(t,e,n){n=void 0!==n?n:1;var u="";if(t>=o)t/=o,u="TB";else if(t>=s)t/=s,u="GB";else if(t>=a)t/=a,u="MB";else if(t>=i)t/=i,u="KB";else{if(!(t>0))return e?"0 b":"<strong>-</strong>";u="b"}var c="b"==u?t:r(t,n);return e?c+" "+u:"<strong>"+c+"</strong> "+u},uid:function(){return top.__utils__uid__=top.__utils__uid__||0,"uid-"+top.__utils__uid__++},time:function(){var t=new Date,e=(t.getHours()<10?"0":"")+t.getHours(),n=(t.getMinutes()<10?"0":"")+t.getMinutes();return datetime=t.getDate()+"/"+(t.getMonth()+1)+"/"+t.getFullYear()+", "+e+":"+n},request:n,sanitize:function(t){return $("<div/>").text(t).html()},textify:function(t){if($.isArray(t)){var e=(t=t.toString().replace(/,/g,", ")).lastIndexOf(", ");return-1!=e&&(t=t.substr(0,e)+" or "+t.substr(e+2)),t}return""},isEmpty:function(t){if(t instanceof Array||(t=[t]),0===t.length)return!0;for(var e in t)if(["__null__","__undefined__",null,void 0].indexOf(t[e])>-1)return!0;return!1},deepeach:e,isJSON:function(t){return/^[\],:{}\s]*$/.test(t.replace(/\\["\\\/bfnrtu]/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))},clone:function(t){return JSON.parse(JSON.stringify(t)||null)},linkify:function(t){var e,n,r,i;return n=/(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim,e=t.replace(n,'<a href="$1" target="_blank">$1</a>'),r=/(^|[^\/])(www\.[\S]+(\b|$))/gim,e=e.replace(r,'$1<a href="http://$2" target="_blank">$2</a>'),i=/(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim,e=e.replace(i,'<a href="mailto:$1">$1</a>')},appendScriptStyle:function(t){t.script&&""!==t.script&&$("<script/>",{type:"text/javascript"}).text(t.script).appendTo("head"),t.styles&&""!==t.styles&&$("<style/>",{type:"text/css"}).text(t.styles).appendTo("head")},getQueryString:function(t){return decodeURIComponent(window.location.search.replace(new RegExp("^(?:.*[&\\?]"+encodeURIComponent(t).replace(/[\.\+\*]/g,"\\$&")+"(?:\\=([^&]*))?)?.*$","i"),"$1"))},setWindowTitle:function(e){window.document.title=e?"Galaxy "+(window.Galaxy.config.brand?" | "+window.Galaxy.config.brand:"")+" | "+t(e):"Galaxy "+(window.Galaxy.config.brand?" | "+window.Galaxy.config.brand:"")}}})});
define(["exports","utils/localization"],function(e,t){"use strict";function r(e,t){for(var n in e){var i=e[n];if(_.isObject(i)){var a=t(i);a&&(e[n]=a),r(i,t)}}}function n(e){var t={contentType:"application/json",type:e.type||"GET",data:e.data||{},url:e.url};"GET"==t.type||"DELETE"==t.type?($.isEmptyObject(t.data)||(t.url+=-1==t.url.indexOf("?")?"?":"&",t.url+=$.param(t.data,!0)),t.data=null):(t.dataType="json",t.url=t.url,t.data=JSON.stringify(t.data)),$.ajax(t).done(function(t){if("string"==typeof t)try{t=t.replace("Infinity,",'"Infinity",'),t=jQuery.parseJSON(t)}catch(e){console.debug(e)}e.success&&e.success(t)}).fail(function(t){var r=null;try{r=jQuery.parseJSON(t.responseText)}catch(e){r=t.responseText}e.error&&e.error(r,t.status)}).always(function(){e.complete&&e.complete()})}function i(e,t){for(var r=1,n=0;n<t;n++)r*=10;return Math.round(e*r)/r}Object.defineProperty(e,"__esModule",{value:!0});var a=function(e){return e&&e.__esModule?e:{default:e}}(t),s=1024,u=s*s,o=u*s,l=o*s;e.default={cssLoadFile:function(e){$('link[href^="'+e+'"]').length||$('<link href="'+Galaxy.root+e+'" rel="stylesheet">').appendTo("head")},cssGetAttribute:function(e,t){var r=$('<div class="'+e+'"></div>');r.appendTo(":eq(0)");var n=r.css(t);return r.remove(),n},get:function(e){top.__utils__get__=top.__utils__get__||{};var t=JSON.stringify(e);e.cache&&top.__utils__get__[t]?(e.success&&e.success(top.__utils__get__[t]),window.console.debug("utils.js::get() - Fetching from cache ["+e.url+"].")):n({url:e.url,data:e.data,success:function(r){top.__utils__get__[t]=r,e.success&&e.success(r)},error:function(t,r){e.error&&e.error(t,r)}})},merge:function(e,t){return e?_.defaults(e,t):t},iframe:function(e){return'<iframe src="'+e+'" frameborder="0" style="width: 100%; height: 100%;"/>'},bytesToString:function(e,t,r){r=void 0!==r?r:1;var n="";if(e>=l)e/=l,n="TB";else if(e>=o)e/=o,n="GB";else if(e>=u)e/=u,n="MB";else if(e>=s)e/=s,n="KB";else{if(!(e>0))return t?"0 b":"<strong>-</strong>";n="b"}var a="b"==n?e:i(e,r);return t?a+" "+n:"<strong>"+a+"</strong> "+n},uid:function(){return top.__utils__uid__=top.__utils__uid__||0,"uid-"+top.__utils__uid__++},time:function(){var e=new Date,t=(e.getHours()<10?"0":"")+e.getHours(),r=(e.getMinutes()<10?"0":"")+e.getMinutes();return datetime=e.getDate()+"/"+(e.getMonth()+1)+"/"+e.getFullYear()+", "+t+":"+r},request:n,sanitize:function(e){return $("<div/>").text(e).html()},textify:function(e){if($.isArray(e)){var t=(e=e.toString().replace(/,/g,", ")).lastIndexOf(", ");return-1!=t&&(e=e.substr(0,t)+" or "+e.substr(t+2)),e}return""},isEmpty:function(e){if(e instanceof Array||(e=[e]),0===e.length)return!0;for(var t in e)if(["__null__","__undefined__",null,void 0].indexOf(e[t])>-1)return!0;return!1},deepeach:r,isJSON:function(e){return/^[\],:{}\s]*$/.test(e.replace(/\\["\\\/bfnrtu]/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))},clone:function(e){return JSON.parse(JSON.stringify(e)||null)},linkify:function(e){var t,r,n,i;return r=/(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim,t=e.replace(r,'<a href="$1" target="_blank">$1</a>'),n=/(^|[^\/])(www\.[\S]+(\b|$))/gim,t=t.replace(n,'$1<a href="http://$2" target="_blank">$2</a>'),i=/(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim,t=t.replace(i,'<a href="mailto:$1">$1</a>')},appendScriptStyle:function(e){e.script&&""!==e.script&&$("<script/>",{type:"text/javascript"}).text(e.script).appendTo("head"),e.styles&&""!==e.styles&&$("<style/>",{type:"text/css"}).text(e.styles).appendTo("head")},getQueryString:function(e){return decodeURIComponent(window.location.search.replace(new RegExp("^(?:.*[&\\?]"+encodeURIComponent(e).replace(/[\.\+\*]/g,"\\$&")+"(?:\\=([^&]*))?)?.*$","i"),"$1"))},setWindowTitle:function(e){window.document.title=e?"Galaxy "+(window.Galaxy.config.brand?" | "+window.Galaxy.config.brand:"")+" | "+(0,a.default)(e):"Galaxy "+(window.Galaxy.config.brand?" | "+window.Galaxy.config.brand:"")}}});
//# sourceMappingURL=../../maps/utils/utils.js.map